ctxo-mcp 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/language/tree-sitter-adapter.ts","../src/adapters/language/go-adapter.ts","../src/adapters/language/csharp-adapter.ts","../src/cli/index-command.ts","../src/core/staleness/content-hasher.ts","../src/adapters/language/ts-morph-adapter.ts","../src/adapters/language/language-adapter-registry.ts","../src/adapters/storage/json-index-writer.ts","../src/adapters/storage/schema-manager.ts","../src/cli/sync-command.ts","../src/cli/status-command.ts","../src/cli/verify-command.ts","../src/cli/init-command.ts","../src/cli/watch-command.ts","../src/adapters/watcher/chokidar-watcher-adapter.ts","../src/cli/stats-command.ts","../src/cli/cli-router.ts"],"sourcesContent":["import Parser from 'tree-sitter';\nimport type { Tree, SyntaxNode } from 'tree-sitter';\ntype Language = Parameters<InstanceType<typeof Parser>['setLanguage']>[0];\nimport { extname } from 'node:path';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind } from '../../core/types.js';\nimport type { ILanguageAdapter } from '../../ports/i-language-adapter.js';\n\nexport abstract class TreeSitterAdapter implements ILanguageAdapter {\n abstract readonly extensions: readonly string[];\n readonly tier = 'syntax' as const;\n\n protected parser: Parser;\n protected symbolRegistry = new Map<string, SymbolKind>();\n\n constructor(language: Language) {\n this.parser = new Parser();\n this.parser.setLanguage(language);\n }\n\n isSupported(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return (this.extensions as readonly string[]).includes(ext);\n }\n\n setSymbolRegistry(registry: Map<string, SymbolKind>): void {\n this.symbolRegistry = registry;\n }\n\n protected parse(source: string): Tree {\n return this.parser.parse(source);\n }\n\n protected buildSymbolId(filePath: string, name: string, kind: SymbolKind): string {\n return `${filePath}::${name}::${kind}`;\n }\n\n protected nodeToLineRange(node: SyntaxNode): {\n startLine: number;\n endLine: number;\n startOffset: number;\n endOffset: number;\n } {\n return {\n startLine: node.startPosition.row,\n endLine: node.endPosition.row,\n startOffset: node.startIndex,\n endOffset: node.endIndex,\n };\n }\n\n protected countCyclomaticComplexity(node: SyntaxNode, branchTypes: string[]): number {\n let complexity = 1;\n const visit = (n: SyntaxNode) => {\n if (branchTypes.includes(n.type)) {\n complexity++;\n }\n for (let i = 0; i < n.childCount; i++) {\n visit(n.child(i)!);\n }\n };\n visit(node);\n return complexity;\n }\n\n abstract extractSymbols(filePath: string, source: string): SymbolNode[];\n abstract extractEdges(filePath: string, source: string): GraphEdge[];\n abstract extractComplexity(filePath: string, source: string): ComplexityMetrics[];\n}\n","import GoLanguage from 'tree-sitter-go';\nimport type { SyntaxNode } from 'tree-sitter';\nimport { TreeSitterAdapter } from './tree-sitter-adapter.js';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics } from '../../core/types.js';\n\nconst GO_BRANCH_TYPES = [\n 'if_statement', 'for_statement',\n 'expression_switch_statement', 'type_switch_statement',\n 'expression_case', 'type_case',\n 'select_statement', 'communication_case',\n];\n\nexport class GoAdapter extends TreeSitterAdapter {\n readonly extensions = ['.go'] as const;\n\n constructor() {\n super(GoLanguage);\n }\n\n extractSymbols(filePath: string, source: string): SymbolNode[] {\n try {\n const tree = this.parse(source);\n const symbols: SymbolNode[] = [];\n\n for (let i = 0; i < tree.rootNode.childCount; i++) {\n const node = tree.rootNode.child(i)!;\n\n if (node.type === 'function_declaration') {\n const name = node.childForFieldName('name')?.text;\n if (!name || !this.isExported(name)) continue;\n const range = this.nodeToLineRange(node);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, name, 'function'),\n name,\n kind: 'function',\n ...range,\n });\n }\n\n if (node.type === 'method_declaration') {\n const methodName = node.childForFieldName('name')?.text;\n if (!methodName || !this.isExported(methodName)) continue;\n const receiverType = this.extractReceiverType(node);\n const qualifiedName = receiverType ? `${receiverType}.${methodName}` : methodName;\n const range = this.nodeToLineRange(node);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, 'method'),\n name: qualifiedName,\n kind: 'method',\n ...range,\n });\n }\n\n if (node.type === 'type_declaration') {\n this.extractTypeSymbols(node, filePath, symbols);\n }\n }\n\n return symbols;\n } catch (err) {\n console.error(`[ctxo:go] Symbol extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n extractEdges(filePath: string, source: string): GraphEdge[] {\n try {\n const tree = this.parse(source);\n const edges: GraphEdge[] = [];\n const firstExportedSymbol = this.findFirstExportedSymbolId(tree.rootNode, filePath);\n if (!firstExportedSymbol) return edges;\n\n for (let i = 0; i < tree.rootNode.childCount; i++) {\n const node = tree.rootNode.child(i)!;\n\n if (node.type === 'import_declaration') {\n this.extractImportEdges(node, filePath, firstExportedSymbol, edges);\n }\n }\n\n return edges;\n } catch (err) {\n console.error(`[ctxo:go] Edge extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n extractComplexity(filePath: string, source: string): ComplexityMetrics[] {\n try {\n const tree = this.parse(source);\n const metrics: ComplexityMetrics[] = [];\n\n for (let i = 0; i < tree.rootNode.childCount; i++) {\n const node = tree.rootNode.child(i)!;\n\n if (node.type === 'function_declaration') {\n const name = node.childForFieldName('name')?.text;\n if (!name || !this.isExported(name)) continue;\n metrics.push({\n symbolId: this.buildSymbolId(filePath, name, 'function'),\n cyclomatic: this.countCyclomaticComplexity(node, GO_BRANCH_TYPES),\n });\n }\n\n if (node.type === 'method_declaration') {\n const methodName = node.childForFieldName('name')?.text;\n if (!methodName || !this.isExported(methodName)) continue;\n const receiverType = this.extractReceiverType(node);\n const qualifiedName = receiverType ? `${receiverType}.${methodName}` : methodName;\n metrics.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, 'method'),\n cyclomatic: this.countCyclomaticComplexity(node, GO_BRANCH_TYPES),\n });\n }\n }\n\n return metrics;\n } catch (err) {\n console.error(`[ctxo:go] Complexity extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n // ── Private helpers ─────────────────────────────────────────\n\n private isExported(name: string): boolean {\n return name.length > 0 && name[0]! === name[0]!.toUpperCase() && name[0]! !== name[0]!.toLowerCase();\n }\n\n private extractReceiverType(methodNode: SyntaxNode): string | undefined {\n // method_declaration has parameter_list as first child (receiver)\n const params = methodNode.child(1);\n if (params?.type !== 'parameter_list') return undefined;\n\n for (let i = 0; i < params.childCount; i++) {\n const param = params.child(i)!;\n if (param.type === 'parameter_declaration') {\n // Find type identifier — may be pointer (*Type) or plain (Type)\n const typeNode = param.childForFieldName('type');\n if (typeNode) {\n const text = typeNode.text;\n return text.replace(/^\\*/, '');\n }\n }\n }\n return undefined;\n }\n\n private extractTypeSymbols(typeDecl: SyntaxNode, filePath: string, symbols: SymbolNode[]): void {\n for (let i = 0; i < typeDecl.childCount; i++) {\n const spec = typeDecl.child(i)!;\n if (spec.type !== 'type_spec') continue;\n\n const name = spec.childForFieldName('name')?.text;\n if (!name || !this.isExported(name)) continue;\n\n // Determine kind from the type body\n const typeBody = spec.childForFieldName('type');\n let kind: 'class' | 'interface' | 'type' = 'type';\n if (typeBody?.type === 'struct_type') kind = 'class';\n else if (typeBody?.type === 'interface_type') kind = 'interface';\n\n const range = this.nodeToLineRange(spec);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, name, kind),\n name,\n kind,\n ...range,\n });\n }\n }\n\n private extractImportEdges(\n importDecl: SyntaxNode,\n _filePath: string,\n fromSymbol: string,\n edges: GraphEdge[],\n ): void {\n const visit = (node: SyntaxNode) => {\n if (node.type === 'import_spec') {\n const pathNode = node.childForFieldName('path') ?? node.child(0);\n if (pathNode) {\n const importPath = pathNode.text.replace(/\"/g, '');\n edges.push({\n from: fromSymbol,\n to: `${importPath}::${importPath.split('/').pop()}::variable`,\n kind: 'imports',\n });\n }\n }\n for (let i = 0; i < node.childCount; i++) {\n visit(node.child(i)!);\n }\n };\n visit(importDecl);\n }\n\n private findFirstExportedSymbolId(rootNode: SyntaxNode, filePath: string): string | undefined {\n for (let i = 0; i < rootNode.childCount; i++) {\n const node = rootNode.child(i)!;\n\n if (node.type === 'function_declaration') {\n const name = node.childForFieldName('name')?.text;\n if (name && this.isExported(name)) return this.buildSymbolId(filePath, name, 'function');\n }\n if (node.type === 'type_declaration') {\n for (let j = 0; j < node.childCount; j++) {\n const spec = node.child(j)!;\n if (spec.type === 'type_spec') {\n const name = spec.childForFieldName('name')?.text;\n if (name && this.isExported(name)) {\n const typeBody = spec.childForFieldName('type');\n const kind = typeBody?.type === 'struct_type' ? 'class' : typeBody?.type === 'interface_type' ? 'interface' : 'type';\n return this.buildSymbolId(filePath, name, kind);\n }\n }\n }\n }\n }\n return undefined;\n }\n}\n","import CSharpLanguage from 'tree-sitter-c-sharp';\nimport type { SyntaxNode } from 'tree-sitter';\nimport { TreeSitterAdapter } from './tree-sitter-adapter.js';\nimport type { SymbolNode, GraphEdge, ComplexityMetrics, SymbolKind } from '../../core/types.js';\n\nconst CSHARP_BRANCH_TYPES = [\n 'if_statement', 'for_statement', 'foreach_statement',\n 'while_statement', 'do_statement', 'switch_section',\n 'catch_clause', 'conditional_expression',\n];\n\nexport class CSharpAdapter extends TreeSitterAdapter {\n readonly extensions = ['.cs'] as const;\n\n constructor() {\n super(CSharpLanguage);\n }\n\n extractSymbols(filePath: string, source: string): SymbolNode[] {\n try {\n const tree = this.parse(source);\n const symbols: SymbolNode[] = [];\n this.visitSymbols(tree.rootNode, filePath, '', symbols);\n return symbols;\n } catch (err) {\n console.error(`[ctxo:csharp] Symbol extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n extractEdges(filePath: string, source: string): GraphEdge[] {\n try {\n const tree = this.parse(source);\n const edges: GraphEdge[] = [];\n const symbols = this.extractSymbols(filePath, source);\n const firstSymbol = symbols.length > 0 ? symbols[0]!.symbolId : undefined;\n if (!firstSymbol) return edges;\n\n this.visitEdges(tree.rootNode, filePath, firstSymbol, '', edges);\n return edges;\n } catch (err) {\n console.error(`[ctxo:csharp] Edge extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n extractComplexity(filePath: string, source: string): ComplexityMetrics[] {\n try {\n const tree = this.parse(source);\n const metrics: ComplexityMetrics[] = [];\n this.visitComplexity(tree.rootNode, filePath, '', metrics);\n return metrics;\n } catch (err) {\n console.error(`[ctxo:csharp] Complexity extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n }\n }\n\n // ── Symbol visitor ──────────────────────────────────────────\n\n private visitSymbols(\n node: SyntaxNode,\n filePath: string,\n namespace: string,\n symbols: SymbolNode[],\n ): void {\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, ns, symbols);\n }\n return;\n }\n\n if (node.type === 'declaration_list') {\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, namespace, symbols);\n }\n return;\n }\n\n const typeMapping: Record<string, SymbolKind> = {\n class_declaration: 'class',\n struct_declaration: 'class',\n record_declaration: 'class',\n interface_declaration: 'interface',\n enum_declaration: 'type',\n };\n\n const kind = typeMapping[node.type];\n if (kind) {\n if (!this.isPublic(node)) return;\n const name = node.childForFieldName('name')?.text;\n if (!name) return;\n\n const qualifiedName = namespace ? `${namespace}.${name}` : name;\n const range = this.nodeToLineRange(node);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, kind),\n name: qualifiedName,\n kind,\n ...range,\n });\n\n // Extract methods inside the class/struct/record\n if (kind === 'class') {\n this.extractMethodSymbols(node, filePath, qualifiedName, symbols);\n }\n return;\n }\n\n // Recurse into compilation_unit and other containers\n for (let i = 0; i < node.childCount; i++) {\n this.visitSymbols(node.child(i)!, filePath, namespace, symbols);\n }\n }\n\n private extractMethodSymbols(\n classNode: SyntaxNode,\n filePath: string,\n className: string,\n symbols: SymbolNode[],\n ): void {\n const declList = classNode.children.find(c => c.type === 'declaration_list');\n if (!declList) return;\n\n for (let i = 0; i < declList.childCount; i++) {\n const child = declList.child(i)!;\n if (child.type !== 'method_declaration' && child.type !== 'constructor_declaration') continue;\n if (!this.isPublic(child)) continue;\n\n const name = child.childForFieldName('name')?.text;\n if (!name) continue;\n\n const paramCount = this.countParameters(child);\n const qualifiedName = `${className}.${name}(${paramCount})`;\n const range = this.nodeToLineRange(child);\n symbols.push({\n symbolId: this.buildSymbolId(filePath, qualifiedName, 'method'),\n name: qualifiedName,\n kind: 'method',\n ...range,\n });\n }\n }\n\n // ── Edge visitor ────────────────────────────────────────────\n\n private visitEdges(\n node: SyntaxNode,\n filePath: string,\n fromSymbol: string,\n namespace: string,\n edges: GraphEdge[],\n ): void {\n if (node.type === 'using_directive') {\n const nameNode = node.children.find(c => c.type === 'identifier' || c.type === 'qualified_name');\n if (nameNode) {\n edges.push({\n from: fromSymbol,\n to: `${nameNode.text}::${nameNode.text.split('.').pop()}::variable`,\n kind: 'imports',\n });\n }\n return;\n }\n\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitEdges(node.child(i)!, filePath, fromSymbol, ns, edges);\n }\n return;\n }\n\n if (node.type === 'class_declaration' || node.type === 'struct_declaration') {\n if (!this.isPublic(node)) return;\n const name = node.childForFieldName('name')?.text;\n if (!name) return;\n\n const qualifiedName = namespace ? `${namespace}.${name}` : name;\n const classSymbolId = this.buildSymbolId(filePath, qualifiedName, 'class');\n\n // Check base_list for extends/implements\n const baseList = node.children.find(c => c.type === 'base_list');\n if (baseList) {\n for (let i = 0; i < baseList.childCount; i++) {\n const child = baseList.child(i)!;\n if (child.type === 'identifier' || child.type === 'qualified_name') {\n const baseName = child.text;\n // Heuristic: I-prefix = interface → implements, otherwise extends\n const edgeKind = baseName.match(/^I[A-Z]/) ? 'implements' : 'extends';\n const targetKind = edgeKind === 'implements' ? 'interface' : 'class';\n edges.push({\n from: classSymbolId,\n to: this.resolveBaseType(baseName, namespace, targetKind),\n kind: edgeKind,\n });\n }\n }\n }\n }\n\n for (let i = 0; i < node.childCount; i++) {\n this.visitEdges(node.child(i)!, filePath, fromSymbol, namespace, edges);\n }\n }\n\n // ── Complexity visitor ──────────────────────────────────────\n\n private visitComplexity(\n node: SyntaxNode,\n filePath: string,\n namespace: string,\n metrics: ComplexityMetrics[],\n ): void {\n if (node.type === 'namespace_declaration') {\n const name = node.childForFieldName('name')?.text ?? '';\n const ns = namespace ? `${namespace}.${name}` : name;\n for (let i = 0; i < node.childCount; i++) {\n this.visitComplexity(node.child(i)!, filePath, ns, metrics);\n }\n return;\n }\n\n const typeMapping: Record<string, true> = {\n class_declaration: true,\n struct_declaration: true,\n record_declaration: true,\n };\n\n if (typeMapping[node.type]) {\n if (!this.isPublic(node)) return;\n const className = node.childForFieldName('name')?.text;\n if (!className) return;\n\n const qualifiedClass = namespace ? `${namespace}.${className}` : className;\n const declList = node.children.find(c => c.type === 'declaration_list');\n if (!declList) return;\n\n for (let i = 0; i < declList.childCount; i++) {\n const child = declList.child(i)!;\n if (child.type !== 'method_declaration') continue;\n if (!this.isPublic(child)) continue;\n\n const methodName = child.childForFieldName('name')?.text;\n if (!methodName) continue;\n\n const paramCount = this.countParameters(child);\n metrics.push({\n symbolId: this.buildSymbolId(filePath, `${qualifiedClass}.${methodName}(${paramCount})`, 'method'),\n cyclomatic: this.countCyclomaticComplexity(child, CSHARP_BRANCH_TYPES),\n });\n }\n return;\n }\n\n for (let i = 0; i < node.childCount; i++) {\n this.visitComplexity(node.child(i)!, filePath, namespace, metrics);\n }\n }\n\n // ── Helpers ─────────────────────────────────────────────────\n\n private countParameters(methodNode: SyntaxNode): number {\n const paramList = methodNode.childForFieldName('parameters');\n if (!paramList) return 0;\n let count = 0;\n for (let i = 0; i < paramList.childCount; i++) {\n if (paramList.child(i)!.type === 'parameter') count++;\n }\n return count;\n }\n\n private isPublic(node: SyntaxNode): boolean {\n for (let i = 0; i < node.childCount; i++) {\n const child = node.child(i)!;\n if (child.type === 'modifier' && child.text === 'public') return true;\n }\n return false;\n }\n\n private resolveBaseType(baseName: string, namespace: string, defaultKind: SymbolKind): string {\n // Check symbol registry first\n const prefix = namespace ? `${namespace}.${baseName}` : baseName;\n for (const [id] of this.symbolRegistry) {\n if (id.includes(`::${prefix}::`)) return id;\n if (id.includes(`::${baseName}::`)) return id;\n }\n // Fallback: assume same namespace\n const qualifiedName = namespace ? `${namespace}.${baseName}` : baseName;\n return `${qualifiedName}::${baseName}::${defaultKind}`;\n }\n}\n","import { execFileSync } from 'node:child_process';\nimport { readFileSync, writeFileSync, existsSync, statSync, readdirSync } from 'node:fs';\nimport { join, relative, extname } from 'node:path';\nimport { ContentHasher } from '../core/staleness/content-hasher.js';\nimport { TsMorphAdapter } from '../adapters/language/ts-morph-adapter.js';\nimport { LanguageAdapterRegistry } from '../adapters/language/language-adapter-registry.js';\nimport { JsonIndexWriter } from '../adapters/storage/json-index-writer.js';\nimport { SqliteStorageAdapter } from '../adapters/storage/sqlite-storage-adapter.js';\nimport { SchemaManager } from '../adapters/storage/schema-manager.js';\nimport { SimpleGitAdapter } from '../adapters/git/simple-git-adapter.js';\nimport { RevertDetector } from '../core/why-context/revert-detector.js';\nimport { aggregateCoChanges } from '../core/co-change/co-change-analyzer.js';\nimport type { FileIndex, SymbolKind } from '../core/types.js';\n\nexport class IndexCommand {\n private readonly projectRoot: string;\n ctxoRoot: string;\n private supportedExtensions: Set<string>;\n\n constructor(projectRoot: string, ctxoRoot?: string) {\n this.projectRoot = projectRoot;\n this.ctxoRoot = ctxoRoot ?? join(projectRoot, '.ctxo');\n this.supportedExtensions = new Set(['.ts', '.tsx', '.js', '.jsx', '.go', '.cs']);\n }\n\n async run(options: { file?: string; check?: boolean; skipSideEffects?: boolean; skipHistory?: boolean; maxHistory?: number } = {}): Promise<void> {\n if (options.check) {\n // Delegate to verify logic: hash-based freshness check\n return this.runCheck();\n }\n\n // Set up adapters\n const registry = new LanguageAdapterRegistry();\n const tsMorphAdapter = new TsMorphAdapter();\n registry.register(tsMorphAdapter);\n this.registerTreeSitterAdapters(registry);\n this.supportedExtensions = registry.getSupportedExtensions();\n\n const writer = new JsonIndexWriter(this.ctxoRoot);\n const schemaManager = new SchemaManager(this.ctxoRoot);\n const hasher = new ContentHasher();\n const gitAdapter = new SimpleGitAdapter(this.projectRoot);\n const revertDetector = new RevertDetector();\n\n // Discover files (single file, monorepo workspaces, or full project)\n let files: string[];\n if (options.file) {\n const fullPath = join(this.projectRoot, options.file);\n files = [fullPath];\n console.error(`[ctxo] Incremental re-index: ${options.file}`);\n } else {\n // Check for monorepo workspaces — discover files across all roots\n const workspaces = this.discoverWorkspaces();\n files = [];\n for (const ws of workspaces) {\n const wsFiles = this.discoverFilesIn(ws);\n files.push(...wsFiles);\n }\n console.error(`[ctxo] Building codebase index... Found ${files.length} source files`);\n }\n\n // Phase 1a: Extract symbols (CPU-bound, builds symbol registry for edge resolution)\n const symbolRegistry = new Map<string, SymbolKind>();\n const pendingIndices: Array<{\n relativePath: string;\n source: string;\n fileIndex: FileIndex;\n }> = [];\n let processed = 0;\n\n for (const filePath of files) {\n const adapter = registry.getAdapter(filePath);\n if (!adapter) continue;\n\n const relativePath = relative(this.projectRoot, filePath).replace(/\\\\/g, '/');\n\n try {\n const source = readFileSync(filePath, 'utf-8');\n const lastModified = Math.floor(Date.now() / 1000);\n\n const symbols = adapter.extractSymbols(relativePath, source);\n const complexity = adapter.extractComplexity(relativePath, source);\n\n // Build symbol registry for accurate edge resolution\n for (const sym of symbols) {\n symbolRegistry.set(sym.symbolId, sym.kind);\n }\n\n pendingIndices.push({\n relativePath,\n source,\n fileIndex: {\n file: relativePath,\n lastModified,\n contentHash: hasher.hash(source),\n symbols,\n edges: [],\n complexity,\n intent: [],\n antiPatterns: [],\n },\n });\n\n processed++;\n if (processed % 50 === 0) {\n console.error(`[ctxo] Processed ${processed}/${files.length} files (symbols)`);\n }\n } catch (err) {\n console.error(`[ctxo] Skipped ${relativePath}: ${(err as Error).message}`);\n }\n }\n\n // Pre-load all sources into ts-morph for cross-file resolution\n const allSources = new Map<string, string>();\n for (const entry of pendingIndices) {\n allSources.set(entry.relativePath, entry.source);\n }\n tsMorphAdapter.loadProjectSources(allSources);\n\n // Phase 1b: Extract edges (uses symbol registry for correct kind resolution)\n for (const entry of pendingIndices) {\n const adapter = registry.getAdapter(entry.relativePath);\n if (!adapter) continue;\n\n try {\n adapter.setSymbolRegistry?.(symbolRegistry);\n entry.fileIndex.edges = adapter.extractEdges(entry.relativePath, entry.source);\n } catch (err) {\n console.error(`[ctxo] Edge extraction failed for ${entry.relativePath}: ${(err as Error).message}`);\n }\n }\n\n // Clean up pre-loaded sources\n tsMorphAdapter.clearProjectSources();\n\n // Phase 2: Batch git history (single git call for all files)\n if (!options.skipHistory && pendingIndices.length > 0) {\n const maxHistory = options.maxHistory ?? 20;\n const batchHistory = await gitAdapter.getBatchHistory?.(maxHistory) ?? new Map<string, import('../core/types.js').CommitRecord[]>();\n\n for (const { relativePath, fileIndex } of pendingIndices) {\n const commits = batchHistory.get(relativePath) ?? [];\n fileIndex.intent = commits.map((c) => ({\n hash: c.hash,\n message: c.message,\n date: c.date,\n kind: 'commit' as const,\n }));\n fileIndex.antiPatterns = revertDetector.detect(commits);\n }\n }\n\n // Phase 2b: Aggregate co-change data from git history\n if (!options.skipHistory && pendingIndices.length > 0) {\n const fileIndices = pendingIndices.map(e => e.fileIndex);\n const coChangeMatrix = aggregateCoChanges(fileIndices);\n writer.writeCoChanges(coChangeMatrix);\n console.error(`[ctxo] Co-change analysis: ${coChangeMatrix.entries.length} file pairs detected`);\n }\n\n // Phase 3: Write all indices\n const indices: FileIndex[] = [];\n for (const { fileIndex } of pendingIndices) {\n writer.write(fileIndex);\n indices.push(fileIndex);\n }\n\n // Write schema version\n schemaManager.writeVersion();\n\n // Populate SQLite cache (skip rebuildFromJson since we just wrote the JSON)\n const storage = new SqliteStorageAdapter(this.ctxoRoot);\n try {\n await storage.initEmpty();\n storage.bulkWrite(indices);\n } finally {\n storage.close();\n }\n\n // Ensure .ctxo/.cache/ is in .gitignore (skip during verify runs)\n if (!options.skipSideEffects) {\n this.ensureGitignore();\n }\n\n console.error(`[ctxo] Index complete: ${processed} files indexed`);\n }\n\n private registerTreeSitterAdapters(registry: LanguageAdapterRegistry): void {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { GoAdapter } = require('../adapters/language/go-adapter.js');\n registry.register(new GoAdapter());\n } catch {\n console.error('[ctxo] Go adapter unavailable (tree-sitter-go not installed)');\n }\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { CSharpAdapter } = require('../adapters/language/csharp-adapter.js');\n registry.register(new CSharpAdapter());\n } catch {\n console.error('[ctxo] C# adapter unavailable (tree-sitter-c-sharp not installed)');\n }\n }\n\n private discoverFilesIn(root: string): string[] {\n try {\n const output = execFileSync('git', ['ls-files', '--cached', '--others', '--exclude-standard'], {\n cwd: root,\n encoding: 'utf-8',\n maxBuffer: 10 * 1024 * 1024,\n });\n\n return output\n .split('\\n')\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .filter((line) => this.isSupportedExtension(line))\n .map((line) => join(root, line));\n } catch {\n console.error(`[ctxo] git ls-files failed for ${root}`);\n return [];\n }\n }\n\n private discoverWorkspaces(): string[] {\n const pkgPath = join(this.projectRoot, 'package.json');\n if (!existsSync(pkgPath)) return [this.projectRoot];\n\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));\n const workspaces: string[] | undefined = Array.isArray(pkg.workspaces)\n ? pkg.workspaces\n : pkg.workspaces?.packages;\n\n if (!workspaces || workspaces.length === 0) return [this.projectRoot];\n\n // Resolve workspace patterns (supports simple globs like packages/*)\n const resolved: string[] = [];\n for (const ws of workspaces) {\n if (ws.endsWith('/*') || ws.endsWith('\\\\*')) {\n // Glob: packages/* → list subdirectories of packages/\n const parentDir = join(this.projectRoot, ws.slice(0, -2));\n if (existsSync(parentDir)) {\n for (const entry of readdirSync(parentDir, { withFileTypes: true })) {\n if (entry.isDirectory()) {\n resolved.push(join(parentDir, entry.name));\n }\n }\n }\n } else {\n // Literal path\n const wsPath = join(this.projectRoot, ws);\n if (existsSync(wsPath)) {\n resolved.push(wsPath);\n }\n }\n }\n\n if (resolved.length === 0) return [this.projectRoot];\n\n console.error(`[ctxo] Monorepo detected: ${resolved.length} workspace(s)`);\n return resolved;\n } catch {\n return [this.projectRoot];\n }\n }\n\n private isSupportedExtension(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return this.supportedExtensions.has(ext);\n }\n\n private async runCheck(): Promise<void> {\n console.error('[ctxo] Checking index freshness...');\n\n // Register adapters so supportedExtensions includes .go/.cs\n const registry = new LanguageAdapterRegistry();\n registry.register(new TsMorphAdapter());\n this.registerTreeSitterAdapters(registry);\n this.supportedExtensions = registry.getSupportedExtensions();\n\n const hasher = new ContentHasher();\n const files = this.discoverFilesIn(this.projectRoot);\n const reader = new (await import('../adapters/storage/json-index-reader.js')).JsonIndexReader(this.ctxoRoot);\n const indices = reader.readAll();\n const indexedMap = new Map(indices.map((i) => [i.file, i]));\n\n let staleCount = 0;\n\n for (const filePath of files) {\n if (!this.isSupportedExtension(filePath)) continue;\n\n const relativePath = relative(this.projectRoot, filePath).replace(/\\\\/g, '/');\n const indexed = indexedMap.get(relativePath);\n\n if (!indexed) {\n console.error(`[ctxo] NOT INDEXED: ${relativePath}`);\n staleCount++;\n continue;\n }\n\n // Guard: file may be deleted from disk but still tracked by git\n if (!existsSync(filePath)) {\n console.error(`[ctxo] DELETED: ${relativePath}`);\n staleCount++;\n continue;\n }\n\n // Fast path: mtime check (skip hash if mtime hasn't changed)\n const mtime = Math.floor(statSync(filePath).mtimeMs / 1000);\n if (mtime <= indexed.lastModified) continue;\n\n // Slow path: hash-based verification (handles git checkout, cp -p, CI)\n if (indexed.contentHash) {\n const source = readFileSync(filePath, 'utf-8');\n const currentHash = hasher.hash(source);\n if (currentHash === indexed.contentHash) continue;\n }\n\n console.error(`[ctxo] STALE: ${relativePath}`);\n staleCount++;\n }\n\n if (staleCount > 0) {\n console.error(`[ctxo] ${staleCount} file(s) need re-indexing. Run \"ctxo index\"`);\n process.exit(1);\n }\n\n console.error('[ctxo] Index is up to date');\n }\n\n private ensureGitignore(): void {\n const gitignorePath = join(this.projectRoot, '.gitignore');\n const cachePattern = '.ctxo/.cache/';\n const suffix = `\\n# Ctxo local cache (never committed)\\n${cachePattern}\\n`;\n\n // Read-modify-write atomically to avoid TOCTOU race\n const existing = existsSync(gitignorePath) ? readFileSync(gitignorePath, 'utf-8') : '';\n if (existing.includes(cachePattern)) return;\n\n writeFileSync(gitignorePath, existing + suffix, 'utf-8');\n console.error('[ctxo] Added .ctxo/.cache/ to .gitignore');\n }\n}\n","import { createHash } from 'node:crypto';\n\nexport class ContentHasher {\n hash(content: string): string {\n return createHash('sha256').update(content, 'utf-8').digest('hex');\n }\n}\n","import {\n Project,\n SyntaxKind,\n Node,\n type SourceFile,\n type FunctionDeclaration,\n type MethodDeclaration,\n ScriptTarget,\n} from 'ts-morph';\nimport { extname, dirname, join, normalize } from 'node:path';\nimport { type SymbolNode, type GraphEdge, type ComplexityMetrics, type SymbolKind, SYMBOL_KINDS } from '../../core/types.js';\nimport type { ILanguageAdapter } from '../../ports/i-language-adapter.js';\n\nconst SUPPORTED_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx'] as const;\n\nexport class TsMorphAdapter implements ILanguageAdapter {\n readonly extensions = SUPPORTED_EXTENSIONS;\n readonly tier = 'full' as const;\n\n private readonly project: Project;\n private symbolRegistry = new Map<string, SymbolKind>();\n private projectPreloaded = false;\n\n constructor() {\n this.project = new Project({\n compilerOptions: {\n target: ScriptTarget.ES2022,\n allowJs: true,\n jsx: 2, // React\n skipLibCheck: true,\n },\n useInMemoryFileSystem: true,\n });\n }\n\n isSupported(filePath: string): boolean {\n const ext = extname(filePath).toLowerCase();\n return (SUPPORTED_EXTENSIONS as readonly string[]).includes(ext);\n }\n\n setSymbolRegistry(registry: Map<string, SymbolKind>): void {\n this.symbolRegistry = registry;\n }\n\n loadProjectSources(files: Map<string, string>): void {\n for (const [filePath, source] of files) {\n try {\n const existing = this.project.getSourceFile(filePath);\n if (existing) this.project.removeSourceFile(existing);\n this.project.createSourceFile(filePath, source, { overwrite: true });\n } catch (err) {\n console.error(`[ctxo:ts-morph] Failed to preload ${filePath}: ${(err as Error).message}`);\n }\n }\n this.projectPreloaded = true;\n }\n\n clearProjectSources(): void {\n for (const sf of this.project.getSourceFiles()) {\n this.project.removeSourceFile(sf);\n }\n this.projectPreloaded = false;\n }\n\n extractSymbols(filePath: string, source: string): SymbolNode[] {\n const sourceFile = this.parseSource(filePath, source);\n if (!sourceFile) return [];\n\n try {\n const symbols: SymbolNode[] = [];\n\n this.extractFunctions(sourceFile, filePath, symbols);\n this.extractClasses(sourceFile, filePath, symbols);\n this.extractInterfaces(sourceFile, filePath, symbols);\n this.extractTypeAliases(sourceFile, filePath, symbols);\n this.extractVariables(sourceFile, filePath, symbols);\n\n return symbols;\n } catch (err) {\n console.error(`[ctxo:ts-morph] Symbol extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n } finally {\n this.cleanupSourceFile(filePath);\n }\n }\n\n extractEdges(filePath: string, source: string): GraphEdge[] {\n const sourceFile = this.parseSource(filePath, source);\n if (!sourceFile) return [];\n\n try {\n const edges: GraphEdge[] = [];\n\n this.extractImportEdges(sourceFile, filePath, edges);\n this.extractInheritanceEdges(sourceFile, filePath, edges);\n this.extractCallEdges(sourceFile, filePath, edges);\n this.extractReferenceEdges(sourceFile, filePath, edges);\n\n return edges;\n } catch (err) {\n console.error(`[ctxo:ts-morph] Edge extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n } finally {\n if (!this.projectPreloaded) {\n this.cleanupSourceFile(filePath);\n }\n }\n }\n\n extractComplexity(filePath: string, source: string): ComplexityMetrics[] {\n const sourceFile = this.parseSource(filePath, source);\n if (!sourceFile) return [];\n\n try {\n const metrics: ComplexityMetrics[] = [];\n\n for (const fn of sourceFile.getFunctions()) {\n if (!this.isExported(fn)) continue;\n const name = fn.getName();\n if (!name) continue;\n const symbolId = this.buildSymbolId(filePath, name, 'function');\n metrics.push({ symbolId, cyclomatic: this.countCyclomaticComplexity(fn) });\n }\n\n for (const cls of sourceFile.getClasses()) {\n const className = cls.getName();\n if (!className || !this.isExported(cls)) continue;\n\n for (const method of cls.getMethods()) {\n const methodName = method.getName();\n const symbolId = this.buildSymbolId(filePath, `${className}.${methodName}`, 'method');\n metrics.push({ symbolId, cyclomatic: this.countCyclomaticComplexity(method) });\n }\n }\n\n return metrics;\n } catch (err) {\n console.error(`[ctxo:ts-morph] Complexity extraction failed for ${filePath}: ${(err as Error).message}`);\n return [];\n } finally {\n this.cleanupSourceFile(filePath);\n }\n }\n\n // ── Symbol Extraction ───────────────────────────────────────\n\n private extractFunctions(\n sourceFile: SourceFile,\n filePath: string,\n symbols: SymbolNode[],\n ): void {\n for (const fn of sourceFile.getFunctions()) {\n if (!this.isExported(fn)) continue;\n const name = fn.getName();\n if (!name) continue;\n\n symbols.push({\n symbolId: this.buildSymbolId(filePath, name, 'function'),\n name,\n kind: 'function',\n startLine: fn.getStartLineNumber() - 1,\n endLine: fn.getEndLineNumber() - 1,\n startOffset: fn.getStart(),\n endOffset: fn.getEnd(),\n });\n }\n }\n\n private extractClasses(\n sourceFile: SourceFile,\n filePath: string,\n symbols: SymbolNode[],\n ): void {\n for (const cls of sourceFile.getClasses()) {\n const name = cls.getName();\n if (!name || !this.isExported(cls)) continue;\n\n symbols.push({\n symbolId: this.buildSymbolId(filePath, name, 'class'),\n name,\n kind: 'class',\n startLine: cls.getStartLineNumber() - 1,\n endLine: cls.getEndLineNumber() - 1,\n startOffset: cls.getStart(),\n endOffset: cls.getEnd(),\n });\n\n // Extract methods\n for (const method of cls.getMethods()) {\n const methodName = method.getName();\n symbols.push({\n symbolId: this.buildSymbolId(filePath, `${name}.${methodName}`, 'method'),\n name: `${name}.${methodName}`,\n kind: 'method',\n startLine: method.getStartLineNumber() - 1,\n endLine: method.getEndLineNumber() - 1,\n startOffset: method.getStart(),\n endOffset: method.getEnd(),\n });\n }\n }\n }\n\n private extractInterfaces(\n sourceFile: SourceFile,\n filePath: string,\n symbols: SymbolNode[],\n ): void {\n for (const iface of sourceFile.getInterfaces()) {\n if (!this.isExported(iface)) continue;\n const name = iface.getName();\n\n symbols.push({\n symbolId: this.buildSymbolId(filePath, name, 'interface'),\n name,\n kind: 'interface',\n startLine: iface.getStartLineNumber() - 1,\n endLine: iface.getEndLineNumber() - 1,\n startOffset: iface.getStart(),\n endOffset: iface.getEnd(),\n });\n }\n }\n\n private extractTypeAliases(\n sourceFile: SourceFile,\n filePath: string,\n symbols: SymbolNode[],\n ): void {\n for (const typeAlias of sourceFile.getTypeAliases()) {\n if (!this.isExported(typeAlias)) continue;\n const name = typeAlias.getName();\n\n symbols.push({\n symbolId: this.buildSymbolId(filePath, name, 'type'),\n name,\n kind: 'type',\n startLine: typeAlias.getStartLineNumber() - 1,\n endLine: typeAlias.getEndLineNumber() - 1,\n startOffset: typeAlias.getStart(),\n endOffset: typeAlias.getEnd(),\n });\n }\n }\n\n private extractVariables(\n sourceFile: SourceFile,\n filePath: string,\n symbols: SymbolNode[],\n ): void {\n for (const stmt of sourceFile.getVariableStatements()) {\n if (!this.isExported(stmt)) continue;\n\n for (const decl of stmt.getDeclarations()) {\n const name = decl.getName();\n\n symbols.push({\n symbolId: this.buildSymbolId(filePath, name, 'variable'),\n name,\n kind: 'variable',\n startLine: stmt.getStartLineNumber() - 1,\n endLine: stmt.getEndLineNumber() - 1,\n startOffset: decl.getStart(),\n endOffset: decl.getEnd(),\n });\n }\n }\n }\n\n // ── Edge Extraction ─────────────────────────────────────────\n\n private extractImportEdges(\n sourceFile: SourceFile,\n filePath: string,\n edges: GraphEdge[],\n ): void {\n // BUG-1 FIX: use sourceFile directly instead of project lookup (file may be cleaned up)\n const fileSymbolId = this.buildSymbolId(filePath, sourceFile.getBaseName().replace(/\\.[^.]+$/, ''), 'variable');\n const fromSymbols = this.getExportedSymbolIds(sourceFile, filePath);\n const fromSymbol = fromSymbols.length > 0 ? fromSymbols[0]! : fileSymbolId;\n\n for (const imp of sourceFile.getImportDeclarations()) {\n const moduleSpecifier = imp.getModuleSpecifierValue();\n\n // Only track local imports (relative paths)\n if (!moduleSpecifier.startsWith('.') && !moduleSpecifier.startsWith('/')) {\n continue;\n }\n\n // Resolve relative import to project-relative path\n const normalizedTarget = this.resolveRelativeImport(filePath, moduleSpecifier);\n\n // SCHEMA-40 FIX: detect type-only imports\n const isTypeOnly = imp.isTypeOnly();\n\n for (const named of imp.getNamedImports()) {\n const importedName = named.getName();\n const edge: GraphEdge = {\n from: fromSymbol,\n to: this.resolveImportTarget(normalizedTarget, importedName),\n kind: 'imports',\n };\n if (isTypeOnly || named.isTypeOnly()) edge.typeOnly = true;\n edges.push(edge);\n }\n\n const defaultImport = imp.getDefaultImport();\n if (defaultImport) {\n const edge: GraphEdge = {\n from: fromSymbol,\n to: this.resolveImportTarget(normalizedTarget, defaultImport.getText()),\n kind: 'imports',\n };\n if (isTypeOnly) edge.typeOnly = true;\n edges.push(edge);\n }\n\n // GAP-3 FIX: namespace imports (import * as X from './mod')\n const nsImport = imp.getNamespaceImport();\n if (nsImport) {\n const edge: GraphEdge = {\n from: fromSymbol,\n to: this.buildSymbolId(normalizedTarget, nsImport.getText(), 'variable'),\n kind: 'imports',\n };\n if (isTypeOnly) edge.typeOnly = true;\n edges.push(edge);\n }\n }\n }\n\n private extractInheritanceEdges(\n sourceFile: SourceFile,\n filePath: string,\n edges: GraphEdge[],\n ): void {\n for (const cls of sourceFile.getClasses()) {\n const className = cls.getName();\n if (!className || !this.isExported(cls)) continue;\n\n const classSymbolId = this.buildSymbolId(filePath, className, 'class');\n\n // extends\n const baseClass = cls.getExtends();\n if (baseClass) {\n // BUG-17 FIX: strip generic type arguments (Base<string> → Base)\n const baseName = baseClass.getExpression().getText().replace(/<.*>$/, '');\n edges.push({\n from: classSymbolId,\n to: this.resolveSymbolReference(sourceFile, baseName, 'class'),\n kind: 'extends',\n });\n }\n\n // implements\n for (const impl of cls.getImplements()) {\n // BUG-18 FIX: strip generic type arguments (IRepo<User> → IRepo)\n const ifaceName = impl.getExpression().getText().replace(/<.*>$/, '');\n edges.push({\n from: classSymbolId,\n to: this.resolveSymbolReference(sourceFile, ifaceName, 'interface'),\n kind: 'implements',\n });\n }\n }\n }\n\n private extractCallEdges(\n sourceFile: SourceFile,\n filePath: string,\n edges: GraphEdge[],\n ): void {\n // Extract function call edges from exported functions and methods\n for (const fn of sourceFile.getFunctions()) {\n if (!this.isExported(fn)) continue;\n const fnName = fn.getName();\n if (!fnName) continue;\n\n const fnSymbolId = this.buildSymbolId(filePath, fnName, 'function');\n\n for (const call of fn.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const calledName = call.getExpression().getText().split('.').pop();\n if (!calledName || calledName === fnName) continue;\n\n const resolved = this.resolveLocalCallTarget(sourceFile, filePath, calledName);\n if (resolved) {\n edges.push({ from: fnSymbolId, to: resolved, kind: 'calls' });\n }\n }\n\n // GAP-11 FIX: constructor calls (new Foo())\n for (const newExpr of fn.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const calledName = newExpr.getExpression().getText().split('.').pop();\n if (!calledName) continue;\n\n const resolved = this.resolveLocalCallTarget(sourceFile, filePath, calledName);\n if (resolved) {\n edges.push({ from: fnSymbolId, to: resolved, kind: 'calls' });\n }\n }\n }\n\n // Extract calls from class methods\n for (const cls of sourceFile.getClasses()) {\n const className = cls.getName();\n if (!className || !this.isExported(cls)) continue;\n\n for (const method of cls.getMethods()) {\n const methodName = method.getName();\n const methodSymbolId = this.buildSymbolId(filePath, `${className}.${methodName}`, 'method');\n\n for (const call of method.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const calledText = call.getExpression().getText();\n const calledName = calledText.split('.').pop();\n if (!calledName || calledName === methodName) continue;\n\n let resolved: string | undefined;\n if (calledText.startsWith('this.')) {\n resolved = this.resolveThisMethodCall(sourceFile, filePath, className, calledName);\n } else {\n resolved = this.resolveLocalCallTarget(sourceFile, filePath, calledName);\n }\n if (resolved) {\n edges.push({ from: methodSymbolId, to: resolved, kind: 'calls' });\n }\n }\n\n // GAP-11 FIX: constructor calls from methods (new Foo())\n for (const newExpr of method.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const calledText = newExpr.getExpression().getText();\n const calledName = calledText.split('.').pop();\n if (!calledName) continue;\n\n let resolved: string | undefined;\n if (calledText.startsWith('this.')) {\n resolved = this.resolveThisMethodCall(sourceFile, filePath, className, calledName);\n } else {\n resolved = this.resolveLocalCallTarget(sourceFile, filePath, calledName);\n }\n if (resolved) {\n edges.push({ from: methodSymbolId, to: resolved, kind: 'calls' });\n }\n }\n }\n }\n }\n\n private extractReferenceEdges(\n sourceFile: SourceFile,\n filePath: string,\n edges: GraphEdge[],\n ): void {\n // Build map of all named imports from local modules: importedName → resolved symbolId\n const importMap = new Map<string, string>();\n for (const imp of sourceFile.getImportDeclarations()) {\n const mod = imp.getModuleSpecifierValue();\n if (!mod.startsWith('.') && !mod.startsWith('/')) continue;\n const targetFile = this.resolveRelativeImport(filePath, mod);\n for (const named of imp.getNamedImports()) {\n importMap.set(named.getName(), this.resolveImportTarget(targetFile, named.getName()));\n }\n const defaultImport = imp.getDefaultImport();\n if (defaultImport) {\n importMap.set(defaultImport.getText(), this.resolveImportTarget(targetFile, defaultImport.getText()));\n }\n }\n if (importMap.size === 0) return;\n\n // Scan each exported symbol's body for identifier references to imports\n for (const fn of sourceFile.getFunctions()) {\n if (!this.isExported(fn)) continue;\n const fnName = fn.getName();\n if (!fnName) continue;\n const fromId = this.buildSymbolId(filePath, fnName, 'function');\n this.emitUsesEdges(fn, fromId, importMap, edges);\n }\n\n for (const cls of sourceFile.getClasses()) {\n if (!this.isExported(cls)) continue;\n const className = cls.getName();\n if (!className) continue;\n\n // Class-level references (property types, constructor params)\n const classId = this.buildSymbolId(filePath, className, 'class');\n this.emitUsesEdges(cls, classId, importMap, edges);\n }\n }\n\n private emitUsesEdges(\n node: Node,\n fromId: string,\n importMap: Map<string, string>,\n edges: GraphEdge[],\n ): void {\n const seen = new Set<string>();\n for (const id of node.getDescendantsOfKind(SyntaxKind.Identifier)) {\n const name = id.getText();\n if (seen.has(name)) continue;\n const target = importMap.get(name);\n if (target) {\n seen.add(name);\n edges.push({ from: fromId, to: target, kind: 'uses' });\n }\n }\n }\n\n private resolveLocalCallTarget(\n sourceFile: SourceFile,\n filePath: string,\n calledName: string,\n ): string | undefined {\n // Check if the called name is imported from a local module\n for (const imp of sourceFile.getImportDeclarations()) {\n const moduleSpecifier = imp.getModuleSpecifierValue();\n if (!moduleSpecifier.startsWith('.') && !moduleSpecifier.startsWith('/')) continue;\n\n for (const named of imp.getNamedImports()) {\n if (named.getName() === calledName) {\n const targetFile = this.resolveRelativeImport(filePath, moduleSpecifier);\n return this.resolveImportTarget(targetFile, calledName);\n }\n }\n }\n\n // Check if it's a locally defined function in the same file\n for (const fn of sourceFile.getFunctions()) {\n if (fn.getName() === calledName) {\n return this.buildSymbolId(filePath, calledName, 'function');\n }\n }\n\n return undefined;\n }\n\n private resolveThisMethodCall(\n sourceFile: SourceFile,\n filePath: string,\n className: string,\n calledName: string,\n ): string | undefined {\n for (const cls of sourceFile.getClasses()) {\n if (cls.getName() !== className) continue;\n for (const method of cls.getMethods()) {\n if (method.getName() === calledName) {\n return this.buildSymbolId(filePath, `${className}.${calledName}`, 'method');\n }\n }\n }\n return undefined;\n }\n\n // ── Helpers ─────────────────────────────────────────────────\n\n private parseSource(filePath: string, source: string): SourceFile | undefined {\n try {\n const existing = this.project.getSourceFile(filePath);\n if (existing && this.projectPreloaded) {\n return existing;\n }\n if (existing) {\n this.project.removeSourceFile(existing);\n }\n return this.project.createSourceFile(filePath, source, { overwrite: true });\n } catch (err) {\n console.error(`[ctxo:ts-morph] Parse failed for ${filePath}: ${(err as Error).message}`);\n return undefined;\n }\n }\n\n private cleanupSourceFile(filePath: string): void {\n const existing = this.project.getSourceFile(filePath);\n if (existing) {\n this.project.removeSourceFile(existing);\n }\n }\n\n private buildSymbolId(filePath: string, name: string, kind: SymbolKind): string {\n return `${filePath}::${name}::${kind}`;\n }\n\n private resolveRelativeImport(fromFile: string, moduleSpecifier: string): string {\n // Convert relative import like '../types.js' to project-relative 'src/core/types.ts'\n const fromDir = dirname(fromFile);\n let resolved = normalize(join(fromDir, moduleSpecifier)).replace(/\\\\/g, '/');\n\n // Strip .js extension (TypeScript imports use .js but source files are .ts)\n if (resolved.endsWith('.js')) {\n resolved = resolved.slice(0, -3) + '.ts';\n } else if (resolved.endsWith('.jsx')) {\n resolved = resolved.slice(0, -4) + '.tsx';\n } else if (!extname(resolved)) {\n resolved += '.ts';\n }\n\n return resolved;\n }\n\n private resolveImportTarget(targetFile: string, name: string): string {\n // BUG-8/9 FIX: check symbol registry first (populated from Phase 1 of indexing)\n const prefix = `${targetFile}::${name}::`;\n for (const kind of SYMBOL_KINDS) {\n if (this.symbolRegistry.has(`${prefix}${kind}`)) {\n return `${prefix}${kind}`;\n }\n }\n\n // Try to find the symbol in the already-parsed project to get the correct kind\n const targetSourceFile = this.project.getSourceFile(targetFile);\n if (targetSourceFile) {\n for (const fn of targetSourceFile.getFunctions()) {\n if (fn.getName() === name && this.isExported(fn)) {\n return this.buildSymbolId(targetFile, name, 'function');\n }\n }\n for (const cls of targetSourceFile.getClasses()) {\n if (cls.getName() === name && this.isExported(cls)) {\n return this.buildSymbolId(targetFile, name, 'class');\n }\n }\n for (const iface of targetSourceFile.getInterfaces()) {\n if (iface.getName() === name && this.isExported(iface)) {\n return this.buildSymbolId(targetFile, name, 'interface');\n }\n }\n for (const t of targetSourceFile.getTypeAliases()) {\n if (t.getName() === name && this.isExported(t)) {\n return this.buildSymbolId(targetFile, name, 'type');\n }\n }\n }\n // Fallback: infer kind from naming conventions\n const kind = this.inferSymbolKind(name);\n return `${targetFile}::${name}::${kind}`;\n }\n\n private resolveSymbolReference(\n sourceFile: SourceFile,\n name: string,\n defaultKind: SymbolKind,\n ): string {\n // Check if the name is imported\n for (const imp of sourceFile.getImportDeclarations()) {\n const moduleSpecifier = imp.getModuleSpecifierValue();\n if (!moduleSpecifier.startsWith('.') && !moduleSpecifier.startsWith('/')) continue;\n\n for (const named of imp.getNamedImports()) {\n if (named.getName() === name) {\n const resolved = imp.getModuleSpecifierSourceFile()?.getFilePath();\n if (resolved) {\n return `${this.normalizeFilePath(resolved)}::${name}::${defaultKind}`;\n }\n // Fallback: resolve relative module specifier manually\n const sourceDir = dirname(this.normalizeFilePath(sourceFile.getFilePath()));\n const resolvedPath = normalize(join(sourceDir, moduleSpecifier))\n .replace(/\\\\/g, '/')\n .replace(/\\.jsx$/, '.tsx')\n .replace(/\\.js$/, '.ts');\n return `${resolvedPath}::${name}::${defaultKind}`;\n }\n }\n }\n\n // Assume it's in the same file\n return `${sourceFile.getFilePath()}::${name}::${defaultKind}`;\n }\n\n private inferSymbolKind(name: string): SymbolKind {\n // Interface: starts with I followed by uppercase (IStoragePort, IGitPort)\n if (/^I[A-Z]/.test(name) && name.length > 2) return 'interface';\n // All caps with underscores: variable/constant (MAX_AMOUNT, EDGE_KINDS)\n if (/^[A-Z][A-Z_0-9]+$/.test(name)) return 'variable';\n // PascalCase: could be class, interface, or type — default to class\n if (/^[A-Z]/.test(name)) return 'class';\n // camelCase: function\n return 'function';\n }\n\n private normalizeFilePath(filePath: string): string {\n // Remove leading / from in-memory file system paths\n return filePath.replace(/^\\//, '');\n }\n\n private getExportedSymbolIds(sourceFile: SourceFile, filePath: string): string[] {\n const ids: string[] = [];\n for (const fn of sourceFile.getFunctions()) {\n if (!this.isExported(fn)) continue;\n const name = fn.getName();\n if (name) ids.push(this.buildSymbolId(filePath, name, 'function'));\n }\n for (const cls of sourceFile.getClasses()) {\n if (!this.isExported(cls)) continue;\n const name = cls.getName();\n if (name) ids.push(this.buildSymbolId(filePath, name, 'class'));\n }\n for (const iface of sourceFile.getInterfaces()) {\n if (!this.isExported(iface)) continue;\n ids.push(this.buildSymbolId(filePath, iface.getName(), 'interface'));\n }\n for (const t of sourceFile.getTypeAliases()) {\n if (!this.isExported(t)) continue;\n ids.push(this.buildSymbolId(filePath, t.getName(), 'type'));\n }\n for (const stmt of sourceFile.getVariableStatements()) {\n if (!this.isExported(stmt)) continue;\n for (const decl of stmt.getDeclarations()) {\n ids.push(this.buildSymbolId(filePath, decl.getName(), 'variable'));\n }\n }\n return ids;\n }\n\n private isExported(node: Node): boolean {\n if (Node.isExportable(node)) {\n return node.isExported();\n }\n return false;\n }\n\n private countCyclomaticComplexity(node: FunctionDeclaration | MethodDeclaration): number {\n let complexity = 1;\n\n node.forEachDescendant((child) => {\n switch (child.getKind()) {\n case SyntaxKind.IfStatement:\n case SyntaxKind.ConditionalExpression:\n case SyntaxKind.ForStatement:\n case SyntaxKind.ForInStatement:\n case SyntaxKind.ForOfStatement:\n case SyntaxKind.WhileStatement:\n case SyntaxKind.DoStatement:\n case SyntaxKind.CaseClause:\n case SyntaxKind.CatchClause:\n case SyntaxKind.BinaryExpression: {\n const text = child.getText();\n if (child.getKind() === SyntaxKind.BinaryExpression) {\n if (text.includes('&&') || text.includes('||') || text.includes('??')) {\n complexity++;\n }\n } else {\n complexity++;\n }\n break;\n }\n }\n });\n\n return complexity;\n }\n}\n","import { extname } from 'node:path';\nimport type { ILanguageAdapter } from '../../ports/i-language-adapter.js';\n\nexport class LanguageAdapterRegistry {\n private readonly adaptersByExtension = new Map<string, ILanguageAdapter>();\n\n register(adapter: ILanguageAdapter): void {\n for (const ext of adapter.extensions) {\n this.adaptersByExtension.set(ext.toLowerCase(), adapter);\n }\n }\n\n getSupportedExtensions(): Set<string> {\n return new Set(this.adaptersByExtension.keys());\n }\n\n getAdapter(filePath: string): ILanguageAdapter | undefined {\n if (!filePath) return undefined;\n\n const ext = extname(filePath).toLowerCase();\n if (!ext) return undefined;\n\n return this.adaptersByExtension.get(ext);\n }\n}\n","import { writeFileSync, renameSync, mkdirSync, unlinkSync, existsSync } from 'node:fs';\nimport { dirname, join, resolve, sep } from 'node:path';\nimport type { FileIndex, CoChangeMatrix } from '../../core/types.js';\n\nexport class JsonIndexWriter {\n private readonly indexDir: string;\n\n constructor(ctxoRoot: string) {\n this.indexDir = join(ctxoRoot, 'index');\n }\n\n write(fileIndex: FileIndex): void {\n if (!fileIndex.file) {\n throw new Error('FileIndex.file must not be empty');\n }\n\n const targetPath = this.resolveIndexPath(fileIndex.file);\n mkdirSync(dirname(targetPath), { recursive: true });\n\n const sorted = this.sortKeys(fileIndex);\n const json = JSON.stringify(sorted, null, 2);\n this.atomicWrite(targetPath, json);\n }\n\n writeCoChanges(matrix: CoChangeMatrix): void {\n mkdirSync(this.indexDir, { recursive: true });\n const targetPath = join(this.indexDir, 'co-changes.json');\n this.atomicWrite(targetPath, JSON.stringify(matrix, null, 2));\n }\n\n private atomicWrite(targetPath: string, content: string): void {\n const tmpPath = `${targetPath}.${process.pid}.tmp`;\n writeFileSync(tmpPath, content, 'utf-8');\n renameSync(tmpPath, targetPath);\n }\n\n delete(relativePath: string): void {\n const targetPath = this.resolveIndexPath(relativePath);\n if (existsSync(targetPath)) {\n unlinkSync(targetPath);\n }\n }\n\n private resolveIndexPath(relativePath: string): string {\n const resolved = resolve(this.indexDir, `${relativePath}.json`);\n const normalizedDir = resolve(this.indexDir) + sep;\n if (!resolved.startsWith(normalizedDir)) {\n throw new Error(`Path traversal detected: ${relativePath}`);\n }\n return resolved;\n }\n\n private sortKeys(obj: unknown): unknown {\n if (Array.isArray(obj)) {\n return obj.map((item) => this.sortKeys(item));\n }\n if (obj !== null && typeof obj === 'object') {\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(obj).sort()) {\n sorted[key] = this.sortKeys((obj as Record<string, unknown>)[key]);\n }\n return sorted;\n }\n return obj;\n }\n}\n","import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';\nimport { join, dirname } from 'node:path';\n\nconst CURRENT_SCHEMA_VERSION = '1.0.0';\n\nexport class SchemaManager {\n private readonly versionFilePath: string;\n\n constructor(ctxoRoot: string) {\n this.versionFilePath = join(ctxoRoot, 'index', 'schema-version');\n }\n\n currentVersion(): string {\n return CURRENT_SCHEMA_VERSION;\n }\n\n readStoredVersion(): string | undefined {\n if (!existsSync(this.versionFilePath)) {\n return undefined;\n }\n return readFileSync(this.versionFilePath, 'utf-8').trim();\n }\n\n writeVersion(): void {\n mkdirSync(dirname(this.versionFilePath), { recursive: true });\n writeFileSync(this.versionFilePath, CURRENT_SCHEMA_VERSION, 'utf-8');\n }\n\n isCompatible(): boolean {\n const stored = this.readStoredVersion();\n if (!stored) return false;\n return stored === CURRENT_SCHEMA_VERSION;\n }\n}\n","import { join } from 'node:path';\nimport { SqliteStorageAdapter } from '../adapters/storage/sqlite-storage-adapter.js';\n\nexport class SyncCommand {\n private readonly ctxoRoot: string;\n\n constructor(projectRoot: string) {\n this.ctxoRoot = join(projectRoot, '.ctxo');\n }\n\n async run(): Promise<void> {\n console.error('[ctxo] Rebuilding SQLite cache from committed JSON index...');\n\n const storage = new SqliteStorageAdapter(this.ctxoRoot);\n try {\n await storage.init();\n } finally {\n storage.close();\n }\n\n console.error('[ctxo] Sync complete');\n }\n}\n","import { join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { execFileSync } from 'node:child_process';\nimport { JsonIndexReader } from '../adapters/storage/json-index-reader.js';\nimport { SchemaManager } from '../adapters/storage/schema-manager.js';\n\nexport class StatusCommand {\n private readonly projectRoot: string;\n private readonly ctxoRoot: string;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n this.ctxoRoot = join(projectRoot, '.ctxo');\n }\n\n run(): void {\n const indexDir = join(this.ctxoRoot, 'index');\n\n if (!existsSync(indexDir)) {\n console.error('[ctxo] No index found. Run \"ctxo index\" first.');\n return;\n }\n\n const schemaManager = new SchemaManager(this.ctxoRoot);\n const version = schemaManager.readStoredVersion() ?? 'unknown';\n\n const reader = new JsonIndexReader(this.ctxoRoot);\n const indices = reader.readAll();\n\n const totalSymbols = indices.reduce((sum, idx) => sum + idx.symbols.length, 0);\n const totalEdges = indices.reduce((sum, idx) => sum + idx.edges.length, 0);\n\n console.error(`[ctxo] Index Status`);\n console.error(` Schema version: ${version}`);\n console.error(` Indexed files: ${indices.length}`);\n console.error(` Total symbols: ${totalSymbols}`);\n console.error(` Total edges: ${totalEdges}`);\n\n const cacheExists = existsSync(join(this.ctxoRoot, '.cache', 'symbols.db'));\n console.error(` SQLite cache: ${cacheExists ? 'present' : 'missing (run ctxo sync)'}`);\n\n // Per-file listing with timestamps\n if (indices.length > 0) {\n console.error('');\n console.error(' Files:');\n\n // Get source files to detect orphans\n const sourceFiles = this.getSourceFiles();\n\n for (const idx of indices.sort((a, b) => a.file.localeCompare(b.file))) {\n const ts = new Date(idx.lastModified * 1000).toISOString();\n const isOrphaned = sourceFiles.size > 0 && !sourceFiles.has(idx.file);\n const badge = isOrphaned ? ' [orphaned]' : '';\n console.error(` ${idx.file} ${ts} (${idx.symbols.length} symbols, ${idx.edges.length} edges)${badge}`);\n }\n }\n }\n\n private getSourceFiles(): Set<string> {\n try {\n const output = execFileSync('git', ['ls-files', '--cached', '--others', '--exclude-standard'], {\n cwd: this.projectRoot,\n encoding: 'utf-8',\n });\n return new Set(output.split('\\n').map((l) => l.trim()).filter((l) => l.length > 0));\n } catch {\n return new Set();\n }\n }\n}\n","import { mkdtempSync, rmSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { IndexCommand } from './index-command.js';\nimport { JsonIndexReader } from '../adapters/storage/json-index-reader.js';\n\nexport class VerifyCommand {\n private readonly projectRoot: string;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n }\n\n async run(): Promise<void> {\n console.error('[ctxo] Verifying index freshness...');\n\n // Build index into a temp directory to avoid overwriting committed index\n const tempDir = mkdtempSync(join(tmpdir(), 'ctxo-verify-'));\n\n try {\n const tempCtxo = join(tempDir, '.ctxo');\n\n // Run index into temp .ctxo (does not touch committed index)\n const indexCmd = new IndexCommand(this.projectRoot, tempCtxo);\n await indexCmd.run({ skipSideEffects: true });\n\n // Compare temp index with committed index\n const committedReader = new JsonIndexReader(join(this.projectRoot, '.ctxo'));\n const freshReader = new JsonIndexReader(tempCtxo);\n\n const committedIndices = committedReader.readAll();\n const freshIndices = freshReader.readAll();\n\n // Compare full index: symbols + edges + intent + antiPatterns\n const serialize = (i: { symbols: unknown; edges: unknown; intent: unknown; antiPatterns: unknown }) =>\n JSON.stringify({ symbols: i.symbols, edges: i.edges, intent: i.intent, antiPatterns: i.antiPatterns });\n\n const committedMap = new Map(committedIndices.map((i) => [i.file, serialize(i)]));\n const freshMap = new Map(freshIndices.map((i) => [i.file, serialize(i)]));\n\n let stale = false;\n\n // Check for files that changed or were added\n for (const [file, freshData] of freshMap) {\n const committed = committedMap.get(file);\n if (committed !== freshData) {\n console.error(`[ctxo] STALE: ${file}`);\n stale = true;\n }\n }\n\n // Check for files that were removed\n for (const file of committedMap.keys()) {\n if (!freshMap.has(file)) {\n console.error(`[ctxo] REMOVED: ${file}`);\n stale = true;\n }\n }\n\n if (stale) {\n console.error('[ctxo] Index is STALE — run \"ctxo index\" and commit .ctxo/index/');\n process.exit(1);\n }\n\n console.error('[ctxo] Index is up to date');\n } finally {\n rmSync(tempDir, { recursive: true, force: true });\n }\n }\n}\n","import { join } from 'node:path';\nimport { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync } from 'node:fs';\n\nconst CTXO_START = '# ctxo-start';\nconst CTXO_END = '# ctxo-end';\n\nconst POST_COMMIT_CONTENT = `\n${CTXO_START}\n# Incremental re-index on commit (only changed files)\nif command -v ctxo >/dev/null 2>&1; then\n for file in $(git diff --name-only HEAD~1 HEAD 2>/dev/null); do\n ctxo index --file \"$file\" 2>/dev/null || true\n done\nfi\n${CTXO_END}\n`.trim();\n\nconst POST_MERGE_CONTENT = `\n${CTXO_START}\n# Rebuild SQLite cache after merge (index updated via git pull)\nif command -v ctxo >/dev/null 2>&1; then\n ctxo sync 2>/dev/null || true\nfi\n${CTXO_END}\n`.trim();\n\nexport class InitCommand {\n private readonly projectRoot: string;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n }\n\n run(): void {\n const hooksDir = join(this.projectRoot, '.git', 'hooks');\n\n if (!existsSync(join(this.projectRoot, '.git'))) {\n console.error('[ctxo] Not a git repository. Run \"git init\" first.');\n process.exit(1);\n }\n\n mkdirSync(hooksDir, { recursive: true });\n\n this.installHook(hooksDir, 'post-commit', POST_COMMIT_CONTENT);\n this.installHook(hooksDir, 'post-merge', POST_MERGE_CONTENT);\n\n console.error('[ctxo] Git hooks installed (post-commit, post-merge)');\n }\n\n private installHook(hooksDir: string, hookName: string, hookContent: string): void {\n const hookPath = join(hooksDir, hookName);\n\n let existing = '';\n if (existsSync(hookPath)) {\n existing = readFileSync(hookPath, 'utf-8');\n\n // Already installed — idempotent\n if (existing.includes(CTXO_START)) {\n console.error(`[ctxo] ${hookName} hook already has ctxo block — skipping`);\n return;\n }\n } else {\n existing = '#!/bin/sh\\n';\n }\n\n // Append ctxo block\n const updated = existing.endsWith('\\n')\n ? existing + '\\n' + hookContent + '\\n'\n : existing + '\\n\\n' + hookContent + '\\n';\n\n writeFileSync(hookPath, updated, 'utf-8');\n chmodSync(hookPath, 0o755);\n }\n}\n","import { join, extname, relative } from 'node:path';\nimport { readFileSync } from 'node:fs';\nimport { TsMorphAdapter } from '../adapters/language/ts-morph-adapter.js';\nimport { LanguageAdapterRegistry } from '../adapters/language/language-adapter-registry.js';\nimport { JsonIndexWriter } from '../adapters/storage/json-index-writer.js';\nimport { SqliteStorageAdapter } from '../adapters/storage/sqlite-storage-adapter.js';\nimport { ChokidarWatcherAdapter } from '../adapters/watcher/chokidar-watcher-adapter.js';\nimport { ContentHasher } from '../core/staleness/content-hasher.js';\nimport { SimpleGitAdapter } from '../adapters/git/simple-git-adapter.js';\nimport { RevertDetector } from '../core/why-context/revert-detector.js';\nimport type { FileIndex, CommitIntent, AntiPattern } from '../core/types.js';\n\nconst DEBOUNCE_MS = 300;\n\nexport class WatchCommand {\n private readonly projectRoot: string;\n private readonly ctxoRoot: string;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n this.ctxoRoot = join(projectRoot, '.ctxo');\n }\n\n async run(): Promise<void> {\n console.error('[ctxo] Starting file watcher...');\n\n const registry = new LanguageAdapterRegistry();\n registry.register(new TsMorphAdapter());\n this.registerTreeSitterAdapters(registry);\n const supportedExtensions = registry.getSupportedExtensions();\n\n const writer = new JsonIndexWriter(this.ctxoRoot);\n const storage = new SqliteStorageAdapter(this.ctxoRoot);\n await storage.init();\n const hasher = new ContentHasher();\n\n const gitAdapter = new SimpleGitAdapter(this.projectRoot);\n const revertDetector = new RevertDetector();\n const watcher = new ChokidarWatcherAdapter(this.projectRoot);\n const pendingFiles = new Map<string, NodeJS.Timeout>();\n\n const reindexFile = async (filePath: string) => {\n const adapter = registry.getAdapter(filePath);\n if (!adapter) return;\n\n const relativePath = relative(this.projectRoot, filePath).replace(/\\\\/g, '/');\n\n try {\n const source = readFileSync(filePath, 'utf-8');\n const lastModified = Math.floor(Date.now() / 1000);\n\n const symbols = adapter.extractSymbols(relativePath, source);\n const edges = adapter.extractEdges(relativePath, source);\n const complexity = adapter.extractComplexity(relativePath, source);\n\n // Git history and anti-patterns\n const commits = await gitAdapter.getCommitHistory(relativePath);\n const intent: CommitIntent[] = commits.map((c) => ({\n hash: c.hash, message: c.message, date: c.date, kind: 'commit' as const,\n }));\n const antiPatterns: AntiPattern[] = revertDetector.detect(commits);\n\n const fileIndex: FileIndex = {\n file: relativePath,\n lastModified,\n contentHash: hasher.hash(source),\n symbols,\n edges,\n complexity,\n intent,\n antiPatterns,\n };\n\n writer.write(fileIndex);\n storage.writeSymbolFile(fileIndex);\n console.error(`[ctxo] Re-indexed: ${relativePath}`);\n } catch (err) {\n console.error(`[ctxo] Failed to re-index ${relativePath}: ${(err as Error).message}`);\n }\n };\n\n const debouncedReindex = (filePath: string) => {\n const existing = pendingFiles.get(filePath);\n if (existing) clearTimeout(existing);\n\n pendingFiles.set(\n filePath,\n setTimeout(() => {\n pendingFiles.delete(filePath);\n reindexFile(filePath);\n }, DEBOUNCE_MS),\n );\n };\n\n watcher.start((event, filePath) => {\n if (event === 'unlink') {\n const ext = extname(filePath).toLowerCase();\n if (!supportedExtensions.has(ext)) return;\n\n const relativePath = relative(this.projectRoot, filePath).replace(/\\\\/g, '/');\n writer.delete(relativePath);\n storage.deleteSymbolFile(relativePath);\n console.error(`[ctxo] Removed from index: ${relativePath}`);\n } else {\n debouncedReindex(filePath);\n }\n });\n\n console.error('[ctxo] Watching for file changes... (Ctrl+C to stop)');\n\n const cleanup = () => {\n console.error('\\n[ctxo] Stopping watcher...');\n for (const timeout of pendingFiles.values()) {\n clearTimeout(timeout);\n }\n watcher.stop().then(() => {\n storage.close();\n console.error('[ctxo] Watcher stopped');\n process.exit(0);\n });\n };\n\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n }\n\n private registerTreeSitterAdapters(registry: LanguageAdapterRegistry): void {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { GoAdapter } = require('../adapters/language/go-adapter.js');\n registry.register(new GoAdapter());\n } catch {\n console.error('[ctxo] Go adapter unavailable (tree-sitter-go not installed)');\n }\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { CSharpAdapter } = require('../adapters/language/csharp-adapter.js');\n registry.register(new CSharpAdapter());\n } catch {\n console.error('[ctxo] C# adapter unavailable (tree-sitter-c-sharp not installed)');\n }\n }\n}\n","import { watch, type FSWatcher } from 'chokidar';\nimport type { IWatcherPort, FileChangeHandler } from '../../ports/i-watcher-port.js';\n\nconst DEFAULT_IGNORED = [\n '**/node_modules/**',\n '**/.git/**',\n '**/.ctxo/**',\n '**/dist/**',\n '**/coverage/**',\n];\n\nexport class ChokidarWatcherAdapter implements IWatcherPort {\n private readonly projectRoot: string;\n private readonly ignored: string[];\n private watcher: FSWatcher | undefined;\n\n constructor(projectRoot: string, ignored?: string[]) {\n this.projectRoot = projectRoot;\n this.ignored = ignored ?? DEFAULT_IGNORED;\n }\n\n start(handler: FileChangeHandler): void {\n if (this.watcher) {\n throw new Error('Watcher already started. Call stop() before starting again.');\n }\n\n this.watcher = watch(this.projectRoot, {\n ignored: this.ignored,\n persistent: true,\n ignoreInitial: true,\n });\n\n this.watcher.on('add', (path) => handler('add', path));\n this.watcher.on('change', (path) => handler('change', path));\n this.watcher.on('unlink', (path) => handler('unlink', path));\n }\n\n async stop(): Promise<void> {\n if (this.watcher) {\n await this.watcher.close();\n this.watcher = undefined;\n }\n }\n}\n","import { join } from 'node:path';\nimport { existsSync, readFileSync } from 'node:fs';\nimport initSqlJs from 'sql.js';\nimport { SessionRecorderAdapter } from '../adapters/stats/session-recorder-adapter.js';\nimport type { AggregatedStats } from '../ports/i-session-recorder-port.js';\nimport type { StatsReport } from '../core/stats/stats-types.js';\n\nexport class StatsCommand {\n private readonly ctxoRoot: string;\n\n constructor(projectRoot: string) {\n this.ctxoRoot = join(projectRoot, '.ctxo');\n }\n\n async run(options: { days?: number; json?: boolean; clear?: boolean }): Promise<void> {\n // Check if stats are enabled\n if (!this.isStatsEnabled()) {\n console.error('[ctxo] Stats collection is disabled in .ctxo/config.yaml');\n return;\n }\n\n const dbPath = join(this.ctxoRoot, '.cache', 'symbols.db');\n if (!existsSync(dbPath)) {\n if (options.json) {\n process.stdout.write(JSON.stringify(this.emptyReport(options.days)) + '\\n');\n } else {\n console.error('[ctxo] No usage data yet. Start using Ctxo MCP tools to collect stats.');\n }\n return;\n }\n\n // Open DB\n const SQL = await initSqlJs();\n const buffer = readFileSync(dbPath);\n const db = new SQL.Database(buffer);\n const recorder = new SessionRecorderAdapter(db);\n\n try {\n if (options.clear) {\n recorder.clear();\n // Persist cleared DB\n const data = db.export();\n const { writeFileSync } = await import('node:fs');\n writeFileSync(dbPath, Buffer.from(data));\n console.error('[ctxo] Session data cleared.');\n return;\n }\n\n // Validate --days\n if (options.days != null) {\n if (!Number.isInteger(options.days) || options.days <= 0) {\n console.error('[ctxo] --days must be a positive integer');\n process.exit(1);\n return;\n }\n }\n\n const stats = recorder.queryStats(options.days);\n\n if (stats.totalCalls === 0) {\n if (options.json) {\n process.stdout.write(JSON.stringify(this.emptyReport(options.days)) + '\\n');\n } else {\n console.error('[ctxo] No usage data yet. Start using Ctxo MCP tools to collect stats.');\n }\n return;\n }\n\n if (options.json) {\n process.stdout.write(JSON.stringify(this.buildReport(stats, options.days), null, 2) + '\\n');\n } else {\n this.printHumanReadable(stats, options.days);\n }\n } finally {\n db.close();\n }\n }\n\n private isStatsEnabled(): boolean {\n const configPath = join(this.ctxoRoot, 'config.yaml');\n if (!existsSync(configPath)) return true;\n\n try {\n const raw = readFileSync(configPath, 'utf-8');\n const match = raw.match(/stats:\\s*\\n\\s*enabled:\\s*(true|false)/);\n if (match) return match[1] !== 'false';\n return true;\n } catch {\n return true;\n }\n }\n\n private buildReport(stats: AggregatedStats, days?: number): StatsReport {\n const now = new Date().toISOString();\n const from = days != null\n ? new Date(Date.now() - days * 86400000).toISOString()\n : null;\n\n return {\n timeRange: { from, to: now, daysFilter: days ?? null },\n summary: {\n totalCalls: stats.totalCalls,\n totalTokensServed: stats.totalTokensServed,\n },\n topTools: stats.topTools,\n topSymbols: stats.topSymbols,\n detailLevelDistribution: stats.detailLevelDistribution.map((d) => ({\n level: d.level,\n count: d.count,\n percentage: d.percentage,\n })),\n };\n }\n\n private emptyReport(days?: number): StatsReport {\n return this.buildReport({\n totalCalls: 0,\n totalTokensServed: 0,\n topTools: [],\n topSymbols: [],\n detailLevelDistribution: [],\n }, days);\n }\n\n private printHumanReadable(stats: AggregatedStats, days?: number): void {\n const header = days != null ? `last ${days} days` : 'all time';\n\n console.error('');\n console.error(` Usage Summary (${header})`);\n console.error(' ────────────────────────────────────────');\n console.error(` Total tool calls: ${this.formatNumber(stats.totalCalls)}`);\n console.error(` Total tokens served: ${this.formatTokens(stats.totalTokensServed)}`);\n\n if (stats.topTools.length > 0) {\n console.error('');\n console.error(' Top Tools');\n console.error(' ────────────────────────────────────────');\n for (const t of stats.topTools) {\n const name = t.tool.padEnd(24);\n const calls = `${this.formatNumber(t.calls)} calls`.padEnd(14);\n console.error(` ${name}${calls}avg ${this.formatNumber(t.avgTokens)} tokens`);\n }\n }\n\n if (stats.topSymbols.length > 0) {\n console.error('');\n console.error(' Top Queried Symbols');\n console.error(' ────────────────────────────────────────');\n for (const s of stats.topSymbols) {\n const name = s.name.padEnd(32);\n console.error(` ${name}${this.formatNumber(s.queries)} queries`);\n }\n }\n\n if (stats.detailLevelDistribution.length > 0) {\n console.error('');\n console.error(' Detail Level Distribution');\n console.error(' ────────────────────────────────────────');\n for (const d of stats.detailLevelDistribution) {\n const bar = this.renderBar(d.percentage);\n const pct = `${d.percentage}%`.padStart(4);\n console.error(` ${d.level}: ${bar} ${pct}`);\n }\n }\n\n console.error('');\n }\n\n private renderBar(percentage: number): string {\n const filled = Math.round(percentage / 10);\n const empty = 10 - filled;\n return '█'.repeat(filled) + '░'.repeat(empty);\n }\n\n private formatNumber(n: number): string {\n return n.toLocaleString('en-US');\n }\n\n private formatTokens(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;\n return String(n);\n }\n}\n","import { IndexCommand } from './index-command.js';\nimport { SyncCommand } from './sync-command.js';\nimport { StatusCommand } from './status-command.js';\nimport { VerifyCommand } from './verify-command.js';\nimport { InitCommand } from './init-command.js';\nimport { WatchCommand } from './watch-command.js';\nimport { StatsCommand } from './stats-command.js';\n\nexport class CliRouter {\n private readonly projectRoot: string;\n\n constructor(projectRoot: string) {\n this.projectRoot = projectRoot;\n }\n\n async route(args: string[]): Promise<void> {\n const command = args[0];\n\n if (!command || command === '--help' || command === '-h') {\n this.printHelp();\n return;\n }\n\n switch (command) {\n case 'index': {\n const fileIdx = args.indexOf('--file');\n const fileArg = fileIdx !== -1 ? args[fileIdx + 1] : undefined;\n if (fileIdx !== -1 && (!fileArg || fileArg.startsWith('--'))) {\n console.error('[ctxo] --file requires a path argument');\n process.exit(1);\n return;\n }\n const checkArg = args.includes('--check');\n const skipHistory = args.includes('--skip-history');\n const maxHistoryIdx = args.indexOf('--max-history');\n const maxHistoryArg = maxHistoryIdx !== -1 ? Number(args[maxHistoryIdx + 1]) : undefined;\n if (maxHistoryIdx !== -1 && (!maxHistoryArg || isNaN(maxHistoryArg) || maxHistoryArg < 1)) {\n console.error('[ctxo] --max-history requires a positive integer');\n process.exit(1);\n return;\n }\n await new IndexCommand(this.projectRoot).run({ file: fileArg, check: checkArg, skipHistory, maxHistory: maxHistoryArg });\n break;\n }\n\n case 'sync':\n await new SyncCommand(this.projectRoot).run();\n break;\n\n case 'watch':\n await new WatchCommand(this.projectRoot).run();\n break;\n\n case 'verify-index':\n await new VerifyCommand(this.projectRoot).run();\n break;\n\n case 'status':\n new StatusCommand(this.projectRoot).run();\n break;\n\n case 'init':\n new InitCommand(this.projectRoot).run();\n break;\n\n case 'stats': {\n const daysIdx = args.indexOf('--days');\n const daysArg = daysIdx !== -1 ? Number(args[daysIdx + 1]) : undefined;\n const jsonArg = args.includes('--json');\n const clearArg = args.includes('--clear');\n await new StatsCommand(this.projectRoot).run({ days: daysArg, json: jsonArg, clear: clearArg });\n break;\n }\n\n default:\n console.error(`[ctxo] Unknown command: \"${command}\". Run \"ctxo --help\" for usage.`);\n process.exit(1);\n return;\n }\n }\n\n private printHelp(): void {\n console.error(`\nctxo — MCP server for dependency-aware codebase context\n\nUsage:\n ctxo Start MCP server (stdio transport)\n ctxo index Build full codebase index (--max-history N, default 20)\n ctxo sync Rebuild SQLite cache from committed JSON index\n ctxo watch Start file watcher for incremental re-indexing\n ctxo verify-index CI gate: fail if index is stale\n ctxo status Show index manifest\n ctxo init Install git hooks\n ctxo stats Show usage statistics (--json, --days N, --clear)\n ctxo --help Show this help message\n`.trim());\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA,OAAO,YAAY;AAGnB,SAAS,WAAAA,gBAAe;AAHxB,IAOsB;AAPtB;AAAA;AAAA;AAOO,IAAe,oBAAf,MAA6D;AAAA,MAEzD,OAAO;AAAA,MAEN;AAAA,MACA,iBAAiB,oBAAI,IAAwB;AAAA,MAEvD,YAAY,UAAoB;AAC9B,aAAK,SAAS,IAAI,OAAO;AACzB,aAAK,OAAO,YAAY,QAAQ;AAAA,MAClC;AAAA,MAEA,YAAY,UAA2B;AACrC,cAAM,MAAMA,SAAQ,QAAQ,EAAE,YAAY;AAC1C,eAAQ,KAAK,WAAiC,SAAS,GAAG;AAAA,MAC5D;AAAA,MAEA,kBAAkB,UAAyC;AACzD,aAAK,iBAAiB;AAAA,MACxB;AAAA,MAEU,MAAM,QAAsB;AACpC,eAAO,KAAK,OAAO,MAAM,MAAM;AAAA,MACjC;AAAA,MAEU,cAAc,UAAkB,MAAc,MAA0B;AAChF,eAAO,GAAG,QAAQ,KAAK,IAAI,KAAK,IAAI;AAAA,MACtC;AAAA,MAEU,gBAAgB,MAKxB;AACA,eAAO;AAAA,UACL,WAAW,KAAK,cAAc;AAAA,UAC9B,SAAS,KAAK,YAAY;AAAA,UAC1B,aAAa,KAAK;AAAA,UAClB,WAAW,KAAK;AAAA,QAClB;AAAA,MACF;AAAA,MAEU,0BAA0B,MAAkB,aAA+B;AACnF,YAAI,aAAa;AACjB,cAAM,QAAQ,CAAC,MAAkB;AAC/B,cAAI,YAAY,SAAS,EAAE,IAAI,GAAG;AAChC;AAAA,UACF;AACA,mBAAS,IAAI,GAAG,IAAI,EAAE,YAAY,KAAK;AACrC,kBAAM,EAAE,MAAM,CAAC,CAAE;AAAA,UACnB;AAAA,QACF;AACA,cAAM,IAAI;AACV,eAAO;AAAA,MACT;AAAA,IAKF;AAAA;AAAA;;;ACnEA;AAAA;AAAA;AAAA;AAAA,OAAO,gBAAgB;AAAvB,IAKM,iBAOO;AAZb;AAAA;AAAA;AAEA;AAGA,IAAM,kBAAkB;AAAA,MACtB;AAAA,MAAgB;AAAA,MAChB;AAAA,MAA+B;AAAA,MAC/B;AAAA,MAAmB;AAAA,MACnB;AAAA,MAAoB;AAAA,IACtB;AAEO,IAAM,YAAN,cAAwB,kBAAkB;AAAA,MACtC,aAAa,CAAC,KAAK;AAAA,MAE5B,cAAc;AACZ,cAAM,UAAU;AAAA,MAClB;AAAA,MAEA,eAAe,UAAkB,QAA8B;AAC7D,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,gBAAM,UAAwB,CAAC;AAE/B,mBAAS,IAAI,GAAG,IAAI,KAAK,SAAS,YAAY,KAAK;AACjD,kBAAM,OAAO,KAAK,SAAS,MAAM,CAAC;AAElC,gBAAI,KAAK,SAAS,wBAAwB;AACxC,oBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,kBAAI,CAAC,QAAQ,CAAC,KAAK,WAAW,IAAI,EAAG;AACrC,oBAAM,QAAQ,KAAK,gBAAgB,IAAI;AACvC,sBAAQ,KAAK;AAAA,gBACX,UAAU,KAAK,cAAc,UAAU,MAAM,UAAU;AAAA,gBACvD;AAAA,gBACA,MAAM;AAAA,gBACN,GAAG;AAAA,cACL,CAAC;AAAA,YACH;AAEA,gBAAI,KAAK,SAAS,sBAAsB;AACtC,oBAAM,aAAa,KAAK,kBAAkB,MAAM,GAAG;AACnD,kBAAI,CAAC,cAAc,CAAC,KAAK,WAAW,UAAU,EAAG;AACjD,oBAAM,eAAe,KAAK,oBAAoB,IAAI;AAClD,oBAAM,gBAAgB,eAAe,GAAG,YAAY,IAAI,UAAU,KAAK;AACvE,oBAAM,QAAQ,KAAK,gBAAgB,IAAI;AACvC,sBAAQ,KAAK;AAAA,gBACX,UAAU,KAAK,cAAc,UAAU,eAAe,QAAQ;AAAA,gBAC9D,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,GAAG;AAAA,cACL,CAAC;AAAA,YACH;AAEA,gBAAI,KAAK,SAAS,oBAAoB;AACpC,mBAAK,mBAAmB,MAAM,UAAU,OAAO;AAAA,YACjD;AAAA,UACF;AAEA,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,kBAAQ,MAAM,0CAA0C,QAAQ,KAAM,IAAc,OAAO,EAAE;AAC7F,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEA,aAAa,UAAkB,QAA6B;AAC1D,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,gBAAM,QAAqB,CAAC;AAC5B,gBAAM,sBAAsB,KAAK,0BAA0B,KAAK,UAAU,QAAQ;AAClF,cAAI,CAAC,oBAAqB,QAAO;AAEjC,mBAAS,IAAI,GAAG,IAAI,KAAK,SAAS,YAAY,KAAK;AACjD,kBAAM,OAAO,KAAK,SAAS,MAAM,CAAC;AAElC,gBAAI,KAAK,SAAS,sBAAsB;AACtC,mBAAK,mBAAmB,MAAM,UAAU,qBAAqB,KAAK;AAAA,YACpE;AAAA,UACF;AAEA,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,kBAAQ,MAAM,wCAAwC,QAAQ,KAAM,IAAc,OAAO,EAAE;AAC3F,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEA,kBAAkB,UAAkB,QAAqC;AACvE,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,gBAAM,UAA+B,CAAC;AAEtC,mBAAS,IAAI,GAAG,IAAI,KAAK,SAAS,YAAY,KAAK;AACjD,kBAAM,OAAO,KAAK,SAAS,MAAM,CAAC;AAElC,gBAAI,KAAK,SAAS,wBAAwB;AACxC,oBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,kBAAI,CAAC,QAAQ,CAAC,KAAK,WAAW,IAAI,EAAG;AACrC,sBAAQ,KAAK;AAAA,gBACX,UAAU,KAAK,cAAc,UAAU,MAAM,UAAU;AAAA,gBACvD,YAAY,KAAK,0BAA0B,MAAM,eAAe;AAAA,cAClE,CAAC;AAAA,YACH;AAEA,gBAAI,KAAK,SAAS,sBAAsB;AACtC,oBAAM,aAAa,KAAK,kBAAkB,MAAM,GAAG;AACnD,kBAAI,CAAC,cAAc,CAAC,KAAK,WAAW,UAAU,EAAG;AACjD,oBAAM,eAAe,KAAK,oBAAoB,IAAI;AAClD,oBAAM,gBAAgB,eAAe,GAAG,YAAY,IAAI,UAAU,KAAK;AACvE,sBAAQ,KAAK;AAAA,gBACX,UAAU,KAAK,cAAc,UAAU,eAAe,QAAQ;AAAA,gBAC9D,YAAY,KAAK,0BAA0B,MAAM,eAAe;AAAA,cAClE,CAAC;AAAA,YACH;AAAA,UACF;AAEA,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,kBAAQ,MAAM,8CAA8C,QAAQ,KAAM,IAAc,OAAO,EAAE;AACjG,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA;AAAA,MAIQ,WAAW,MAAuB;AACxC,eAAO,KAAK,SAAS,KAAK,KAAK,CAAC,MAAO,KAAK,CAAC,EAAG,YAAY,KAAK,KAAK,CAAC,MAAO,KAAK,CAAC,EAAG,YAAY;AAAA,MACrG;AAAA,MAEQ,oBAAoB,YAA4C;AAEtE,cAAM,SAAS,WAAW,MAAM,CAAC;AACjC,YAAI,QAAQ,SAAS,iBAAkB,QAAO;AAE9C,iBAAS,IAAI,GAAG,IAAI,OAAO,YAAY,KAAK;AAC1C,gBAAM,QAAQ,OAAO,MAAM,CAAC;AAC5B,cAAI,MAAM,SAAS,yBAAyB;AAE1C,kBAAM,WAAW,MAAM,kBAAkB,MAAM;AAC/C,gBAAI,UAAU;AACZ,oBAAM,OAAO,SAAS;AACtB,qBAAO,KAAK,QAAQ,OAAO,EAAE;AAAA,YAC/B;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MAEQ,mBAAmB,UAAsB,UAAkB,SAA6B;AAC9F,iBAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,gBAAM,OAAO,SAAS,MAAM,CAAC;AAC7B,cAAI,KAAK,SAAS,YAAa;AAE/B,gBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,cAAI,CAAC,QAAQ,CAAC,KAAK,WAAW,IAAI,EAAG;AAGrC,gBAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,cAAI,OAAuC;AAC3C,cAAI,UAAU,SAAS,cAAe,QAAO;AAAA,mBACpC,UAAU,SAAS,iBAAkB,QAAO;AAErD,gBAAM,QAAQ,KAAK,gBAAgB,IAAI;AACvC,kBAAQ,KAAK;AAAA,YACX,UAAU,KAAK,cAAc,UAAU,MAAM,IAAI;AAAA,YACjD;AAAA,YACA;AAAA,YACA,GAAG;AAAA,UACL,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MAEQ,mBACN,YACA,WACA,YACA,OACM;AACN,cAAM,QAAQ,CAAC,SAAqB;AAClC,cAAI,KAAK,SAAS,eAAe;AAC/B,kBAAM,WAAW,KAAK,kBAAkB,MAAM,KAAK,KAAK,MAAM,CAAC;AAC/D,gBAAI,UAAU;AACZ,oBAAM,aAAa,SAAS,KAAK,QAAQ,MAAM,EAAE;AACjD,oBAAM,KAAK;AAAA,gBACT,MAAM;AAAA,gBACN,IAAI,GAAG,UAAU,KAAK,WAAW,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,gBACjD,MAAM;AAAA,cACR,CAAC;AAAA,YACH;AAAA,UACF;AACA,mBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,kBAAM,KAAK,MAAM,CAAC,CAAE;AAAA,UACtB;AAAA,QACF;AACA,cAAM,UAAU;AAAA,MAClB;AAAA,MAEQ,0BAA0B,UAAsB,UAAsC;AAC5F,iBAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,gBAAM,OAAO,SAAS,MAAM,CAAC;AAE7B,cAAI,KAAK,SAAS,wBAAwB;AACxC,kBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,gBAAI,QAAQ,KAAK,WAAW,IAAI,EAAG,QAAO,KAAK,cAAc,UAAU,MAAM,UAAU;AAAA,UACzF;AACA,cAAI,KAAK,SAAS,oBAAoB;AACpC,qBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,oBAAM,OAAO,KAAK,MAAM,CAAC;AACzB,kBAAI,KAAK,SAAS,aAAa;AAC7B,sBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,oBAAI,QAAQ,KAAK,WAAW,IAAI,GAAG;AACjC,wBAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,wBAAM,OAAO,UAAU,SAAS,gBAAgB,UAAU,UAAU,SAAS,mBAAmB,cAAc;AAC9G,yBAAO,KAAK,cAAc,UAAU,MAAM,IAAI;AAAA,gBAChD;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA;;;AC7NA;AAAA;AAAA;AAAA;AAAA,OAAO,oBAAoB;AAA3B,IAKM,qBAMO;AAXb;AAAA;AAAA;AAEA;AAGA,IAAM,sBAAsB;AAAA,MAC1B;AAAA,MAAgB;AAAA,MAAiB;AAAA,MACjC;AAAA,MAAmB;AAAA,MAAgB;AAAA,MACnC;AAAA,MAAgB;AAAA,IAClB;AAEO,IAAM,gBAAN,cAA4B,kBAAkB;AAAA,MAC1C,aAAa,CAAC,KAAK;AAAA,MAE5B,cAAc;AACZ,cAAM,cAAc;AAAA,MACtB;AAAA,MAEA,eAAe,UAAkB,QAA8B;AAC7D,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,gBAAM,UAAwB,CAAC;AAC/B,eAAK,aAAa,KAAK,UAAU,UAAU,IAAI,OAAO;AACtD,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,kBAAQ,MAAM,8CAA8C,QAAQ,KAAM,IAAc,OAAO,EAAE;AACjG,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEA,aAAa,UAAkB,QAA6B;AAC1D,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,gBAAM,QAAqB,CAAC;AAC5B,gBAAM,UAAU,KAAK,eAAe,UAAU,MAAM;AACpD,gBAAM,cAAc,QAAQ,SAAS,IAAI,QAAQ,CAAC,EAAG,WAAW;AAChE,cAAI,CAAC,YAAa,QAAO;AAEzB,eAAK,WAAW,KAAK,UAAU,UAAU,aAAa,IAAI,KAAK;AAC/D,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,kBAAQ,MAAM,4CAA4C,QAAQ,KAAM,IAAc,OAAO,EAAE;AAC/F,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEA,kBAAkB,UAAkB,QAAqC;AACvE,YAAI;AACF,gBAAM,OAAO,KAAK,MAAM,MAAM;AAC9B,gBAAM,UAA+B,CAAC;AACtC,eAAK,gBAAgB,KAAK,UAAU,UAAU,IAAI,OAAO;AACzD,iBAAO;AAAA,QACT,SAAS,KAAK;AACZ,kBAAQ,MAAM,kDAAkD,QAAQ,KAAM,IAAc,OAAO,EAAE;AACrG,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA;AAAA,MAIQ,aACN,MACA,UACA,WACA,SACM;AACN,YAAI,KAAK,SAAS,yBAAyB;AACzC,gBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG,QAAQ;AACrD,gBAAM,KAAK,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAChD,mBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,iBAAK,aAAa,KAAK,MAAM,CAAC,GAAI,UAAU,IAAI,OAAO;AAAA,UACzD;AACA;AAAA,QACF;AAEA,YAAI,KAAK,SAAS,oBAAoB;AACpC,mBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,iBAAK,aAAa,KAAK,MAAM,CAAC,GAAI,UAAU,WAAW,OAAO;AAAA,UAChE;AACA;AAAA,QACF;AAEA,cAAM,cAA0C;AAAA,UAC9C,mBAAmB;AAAA,UACnB,oBAAoB;AAAA,UACpB,oBAAoB;AAAA,UACpB,uBAAuB;AAAA,UACvB,kBAAkB;AAAA,QACpB;AAEA,cAAM,OAAO,YAAY,KAAK,IAAI;AAClC,YAAI,MAAM;AACR,cAAI,CAAC,KAAK,SAAS,IAAI,EAAG;AAC1B,gBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,cAAI,CAAC,KAAM;AAEX,gBAAM,gBAAgB,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAC3D,gBAAM,QAAQ,KAAK,gBAAgB,IAAI;AACvC,kBAAQ,KAAK;AAAA,YACX,UAAU,KAAK,cAAc,UAAU,eAAe,IAAI;AAAA,YAC1D,MAAM;AAAA,YACN;AAAA,YACA,GAAG;AAAA,UACL,CAAC;AAGD,cAAI,SAAS,SAAS;AACpB,iBAAK,qBAAqB,MAAM,UAAU,eAAe,OAAO;AAAA,UAClE;AACA;AAAA,QACF;AAGA,iBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,eAAK,aAAa,KAAK,MAAM,CAAC,GAAI,UAAU,WAAW,OAAO;AAAA,QAChE;AAAA,MACF;AAAA,MAEQ,qBACN,WACA,UACA,WACA,SACM;AACN,cAAM,WAAW,UAAU,SAAS,KAAK,OAAK,EAAE,SAAS,kBAAkB;AAC3E,YAAI,CAAC,SAAU;AAEf,iBAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,gBAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,cAAI,MAAM,SAAS,wBAAwB,MAAM,SAAS,0BAA2B;AACrF,cAAI,CAAC,KAAK,SAAS,KAAK,EAAG;AAE3B,gBAAM,OAAO,MAAM,kBAAkB,MAAM,GAAG;AAC9C,cAAI,CAAC,KAAM;AAEX,gBAAM,aAAa,KAAK,gBAAgB,KAAK;AAC7C,gBAAM,gBAAgB,GAAG,SAAS,IAAI,IAAI,IAAI,UAAU;AACxD,gBAAM,QAAQ,KAAK,gBAAgB,KAAK;AACxC,kBAAQ,KAAK;AAAA,YACX,UAAU,KAAK,cAAc,UAAU,eAAe,QAAQ;AAAA,YAC9D,MAAM;AAAA,YACN,MAAM;AAAA,YACN,GAAG;AAAA,UACL,CAAC;AAAA,QACH;AAAA,MACF;AAAA;AAAA,MAIQ,WACN,MACA,UACA,YACA,WACA,OACM;AACN,YAAI,KAAK,SAAS,mBAAmB;AACnC,gBAAM,WAAW,KAAK,SAAS,KAAK,OAAK,EAAE,SAAS,gBAAgB,EAAE,SAAS,gBAAgB;AAC/F,cAAI,UAAU;AACZ,kBAAM,KAAK;AAAA,cACT,MAAM;AAAA,cACN,IAAI,GAAG,SAAS,IAAI,KAAK,SAAS,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,cACvD,MAAM;AAAA,YACR,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAEA,YAAI,KAAK,SAAS,yBAAyB;AACzC,gBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG,QAAQ;AACrD,gBAAM,KAAK,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAChD,mBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,iBAAK,WAAW,KAAK,MAAM,CAAC,GAAI,UAAU,YAAY,IAAI,KAAK;AAAA,UACjE;AACA;AAAA,QACF;AAEA,YAAI,KAAK,SAAS,uBAAuB,KAAK,SAAS,sBAAsB;AAC3E,cAAI,CAAC,KAAK,SAAS,IAAI,EAAG;AAC1B,gBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG;AAC7C,cAAI,CAAC,KAAM;AAEX,gBAAM,gBAAgB,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAC3D,gBAAM,gBAAgB,KAAK,cAAc,UAAU,eAAe,OAAO;AAGzE,gBAAM,WAAW,KAAK,SAAS,KAAK,OAAK,EAAE,SAAS,WAAW;AAC/D,cAAI,UAAU;AACZ,qBAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,oBAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,kBAAI,MAAM,SAAS,gBAAgB,MAAM,SAAS,kBAAkB;AAClE,sBAAM,WAAW,MAAM;AAEvB,sBAAM,WAAW,SAAS,MAAM,SAAS,IAAI,eAAe;AAC5D,sBAAM,aAAa,aAAa,eAAe,cAAc;AAC7D,sBAAM,KAAK;AAAA,kBACT,MAAM;AAAA,kBACN,IAAI,KAAK,gBAAgB,UAAU,WAAW,UAAU;AAAA,kBACxD,MAAM;AAAA,gBACR,CAAC;AAAA,cACH;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,iBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,eAAK,WAAW,KAAK,MAAM,CAAC,GAAI,UAAU,YAAY,WAAW,KAAK;AAAA,QACxE;AAAA,MACF;AAAA;AAAA,MAIQ,gBACN,MACA,UACA,WACA,SACM;AACN,YAAI,KAAK,SAAS,yBAAyB;AACzC,gBAAM,OAAO,KAAK,kBAAkB,MAAM,GAAG,QAAQ;AACrD,gBAAM,KAAK,YAAY,GAAG,SAAS,IAAI,IAAI,KAAK;AAChD,mBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,iBAAK,gBAAgB,KAAK,MAAM,CAAC,GAAI,UAAU,IAAI,OAAO;AAAA,UAC5D;AACA;AAAA,QACF;AAEA,cAAM,cAAoC;AAAA,UACxC,mBAAmB;AAAA,UACnB,oBAAoB;AAAA,UACpB,oBAAoB;AAAA,QACtB;AAEA,YAAI,YAAY,KAAK,IAAI,GAAG;AAC1B,cAAI,CAAC,KAAK,SAAS,IAAI,EAAG;AAC1B,gBAAM,YAAY,KAAK,kBAAkB,MAAM,GAAG;AAClD,cAAI,CAAC,UAAW;AAEhB,gBAAM,iBAAiB,YAAY,GAAG,SAAS,IAAI,SAAS,KAAK;AACjE,gBAAM,WAAW,KAAK,SAAS,KAAK,OAAK,EAAE,SAAS,kBAAkB;AACtE,cAAI,CAAC,SAAU;AAEf,mBAAS,IAAI,GAAG,IAAI,SAAS,YAAY,KAAK;AAC5C,kBAAM,QAAQ,SAAS,MAAM,CAAC;AAC9B,gBAAI,MAAM,SAAS,qBAAsB;AACzC,gBAAI,CAAC,KAAK,SAAS,KAAK,EAAG;AAE3B,kBAAM,aAAa,MAAM,kBAAkB,MAAM,GAAG;AACpD,gBAAI,CAAC,WAAY;AAEjB,kBAAM,aAAa,KAAK,gBAAgB,KAAK;AAC7C,oBAAQ,KAAK;AAAA,cACX,UAAU,KAAK,cAAc,UAAU,GAAG,cAAc,IAAI,UAAU,IAAI,UAAU,KAAK,QAAQ;AAAA,cACjG,YAAY,KAAK,0BAA0B,OAAO,mBAAmB;AAAA,YACvE,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAEA,iBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,eAAK,gBAAgB,KAAK,MAAM,CAAC,GAAI,UAAU,WAAW,OAAO;AAAA,QACnE;AAAA,MACF;AAAA;AAAA,MAIQ,gBAAgB,YAAgC;AACtD,cAAM,YAAY,WAAW,kBAAkB,YAAY;AAC3D,YAAI,CAAC,UAAW,QAAO;AACvB,YAAI,QAAQ;AACZ,iBAAS,IAAI,GAAG,IAAI,UAAU,YAAY,KAAK;AAC7C,cAAI,UAAU,MAAM,CAAC,EAAG,SAAS,YAAa;AAAA,QAChD;AACA,eAAO;AAAA,MACT;AAAA,MAEQ,SAAS,MAA2B;AAC1C,iBAAS,IAAI,GAAG,IAAI,KAAK,YAAY,KAAK;AACxC,gBAAM,QAAQ,KAAK,MAAM,CAAC;AAC1B,cAAI,MAAM,SAAS,cAAc,MAAM,SAAS,SAAU,QAAO;AAAA,QACnE;AACA,eAAO;AAAA,MACT;AAAA,MAEQ,gBAAgB,UAAkB,WAAmB,aAAiC;AAE5F,cAAM,SAAS,YAAY,GAAG,SAAS,IAAI,QAAQ,KAAK;AACxD,mBAAW,CAAC,EAAE,KAAK,KAAK,gBAAgB;AACtC,cAAI,GAAG,SAAS,KAAK,MAAM,IAAI,EAAG,QAAO;AACzC,cAAI,GAAG,SAAS,KAAK,QAAQ,IAAI,EAAG,QAAO;AAAA,QAC7C;AAEA,cAAM,gBAAgB,YAAY,GAAG,SAAS,IAAI,QAAQ,KAAK;AAC/D,eAAO,GAAG,aAAa,KAAK,QAAQ,KAAK,WAAW;AAAA,MACtD;AAAA,IACF;AAAA;AAAA;;;ACvSA,SAAS,oBAAoB;AAC7B,SAAS,gBAAAC,eAAc,iBAAAC,gBAAe,cAAAC,aAAY,UAAU,mBAAmB;AAC/E,SAAS,QAAAC,OAAM,UAAU,WAAAC,gBAAe;;;ACFxC,SAAS,kBAAkB;AAEpB,IAAM,gBAAN,MAAoB;AAAA,EACzB,KAAK,SAAyB;AAC5B,WAAO,WAAW,QAAQ,EAAE,OAAO,SAAS,OAAO,EAAE,OAAO,KAAK;AAAA,EACnE;AACF;;;ACNA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EAIA;AAAA,OACK;AACP,SAAS,SAAS,SAAS,MAAM,iBAAiB;AAIlD,IAAM,uBAAuB,CAAC,OAAO,QAAQ,OAAO,MAAM;AAEnD,IAAM,iBAAN,MAAiD;AAAA,EAC7C,aAAa;AAAA,EACb,OAAO;AAAA,EAEC;AAAA,EACT,iBAAiB,oBAAI,IAAwB;AAAA,EAC7C,mBAAmB;AAAA,EAE3B,cAAc;AACZ,SAAK,UAAU,IAAI,QAAQ;AAAA,MACzB,iBAAiB;AAAA,QACf,QAAQ,aAAa;AAAA,QACrB,SAAS;AAAA,QACT,KAAK;AAAA;AAAA,QACL,cAAc;AAAA,MAChB;AAAA,MACA,uBAAuB;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,UAA2B;AACrC,UAAM,MAAM,QAAQ,QAAQ,EAAE,YAAY;AAC1C,WAAQ,qBAA2C,SAAS,GAAG;AAAA,EACjE;AAAA,EAEA,kBAAkB,UAAyC;AACzD,SAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,mBAAmB,OAAkC;AACnD,eAAW,CAAC,UAAU,MAAM,KAAK,OAAO;AACtC,UAAI;AACF,cAAM,WAAW,KAAK,QAAQ,cAAc,QAAQ;AACpD,YAAI,SAAU,MAAK,QAAQ,iBAAiB,QAAQ;AACpD,aAAK,QAAQ,iBAAiB,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,MACrE,SAAS,KAAK;AACZ,gBAAQ,MAAM,qCAAqC,QAAQ,KAAM,IAAc,OAAO,EAAE;AAAA,MAC1F;AAAA,IACF;AACA,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,sBAA4B;AAC1B,eAAW,MAAM,KAAK,QAAQ,eAAe,GAAG;AAC9C,WAAK,QAAQ,iBAAiB,EAAE;AAAA,IAClC;AACA,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,eAAe,UAAkB,QAA8B;AAC7D,UAAM,aAAa,KAAK,YAAY,UAAU,MAAM;AACpD,QAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,QAAI;AACF,YAAM,UAAwB,CAAC;AAE/B,WAAK,iBAAiB,YAAY,UAAU,OAAO;AACnD,WAAK,eAAe,YAAY,UAAU,OAAO;AACjD,WAAK,kBAAkB,YAAY,UAAU,OAAO;AACpD,WAAK,mBAAmB,YAAY,UAAU,OAAO;AACrD,WAAK,iBAAiB,YAAY,UAAU,OAAO;AAEnD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,gDAAgD,QAAQ,KAAM,IAAc,OAAO,EAAE;AACnG,aAAO,CAAC;AAAA,IACV,UAAE;AACA,WAAK,kBAAkB,QAAQ;AAAA,IACjC;AAAA,EACF;AAAA,EAEA,aAAa,UAAkB,QAA6B;AAC1D,UAAM,aAAa,KAAK,YAAY,UAAU,MAAM;AACpD,QAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,QAAI;AACF,YAAM,QAAqB,CAAC;AAE5B,WAAK,mBAAmB,YAAY,UAAU,KAAK;AACnD,WAAK,wBAAwB,YAAY,UAAU,KAAK;AACxD,WAAK,iBAAiB,YAAY,UAAU,KAAK;AACjD,WAAK,sBAAsB,YAAY,UAAU,KAAK;AAEtD,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,8CAA8C,QAAQ,KAAM,IAAc,OAAO,EAAE;AACjG,aAAO,CAAC;AAAA,IACV,UAAE;AACA,UAAI,CAAC,KAAK,kBAAkB;AAC1B,aAAK,kBAAkB,QAAQ;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,kBAAkB,UAAkB,QAAqC;AACvE,UAAM,aAAa,KAAK,YAAY,UAAU,MAAM;AACpD,QAAI,CAAC,WAAY,QAAO,CAAC;AAEzB,QAAI;AACF,YAAM,UAA+B,CAAC;AAEtC,iBAAW,MAAM,WAAW,aAAa,GAAG;AAC1C,YAAI,CAAC,KAAK,WAAW,EAAE,EAAG;AAC1B,cAAM,OAAO,GAAG,QAAQ;AACxB,YAAI,CAAC,KAAM;AACX,cAAM,WAAW,KAAK,cAAc,UAAU,MAAM,UAAU;AAC9D,gBAAQ,KAAK,EAAE,UAAU,YAAY,KAAK,0BAA0B,EAAE,EAAE,CAAC;AAAA,MAC3E;AAEA,iBAAW,OAAO,WAAW,WAAW,GAAG;AACzC,cAAM,YAAY,IAAI,QAAQ;AAC9B,YAAI,CAAC,aAAa,CAAC,KAAK,WAAW,GAAG,EAAG;AAEzC,mBAAW,UAAU,IAAI,WAAW,GAAG;AACrC,gBAAM,aAAa,OAAO,QAAQ;AAClC,gBAAM,WAAW,KAAK,cAAc,UAAU,GAAG,SAAS,IAAI,UAAU,IAAI,QAAQ;AACpF,kBAAQ,KAAK,EAAE,UAAU,YAAY,KAAK,0BAA0B,MAAM,EAAE,CAAC;AAAA,QAC/E;AAAA,MACF;AAEA,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,oDAAoD,QAAQ,KAAM,IAAc,OAAO,EAAE;AACvG,aAAO,CAAC;AAAA,IACV,UAAE;AACA,WAAK,kBAAkB,QAAQ;AAAA,IACjC;AAAA,EACF;AAAA;AAAA,EAIQ,iBACN,YACA,UACA,SACM;AACN,eAAW,MAAM,WAAW,aAAa,GAAG;AAC1C,UAAI,CAAC,KAAK,WAAW,EAAE,EAAG;AAC1B,YAAM,OAAO,GAAG,QAAQ;AACxB,UAAI,CAAC,KAAM;AAEX,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK,cAAc,UAAU,MAAM,UAAU;AAAA,QACvD;AAAA,QACA,MAAM;AAAA,QACN,WAAW,GAAG,mBAAmB,IAAI;AAAA,QACrC,SAAS,GAAG,iBAAiB,IAAI;AAAA,QACjC,aAAa,GAAG,SAAS;AAAA,QACzB,WAAW,GAAG,OAAO;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,eACN,YACA,UACA,SACM;AACN,eAAW,OAAO,WAAW,WAAW,GAAG;AACzC,YAAM,OAAO,IAAI,QAAQ;AACzB,UAAI,CAAC,QAAQ,CAAC,KAAK,WAAW,GAAG,EAAG;AAEpC,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK,cAAc,UAAU,MAAM,OAAO;AAAA,QACpD;AAAA,QACA,MAAM;AAAA,QACN,WAAW,IAAI,mBAAmB,IAAI;AAAA,QACtC,SAAS,IAAI,iBAAiB,IAAI;AAAA,QAClC,aAAa,IAAI,SAAS;AAAA,QAC1B,WAAW,IAAI,OAAO;AAAA,MACxB,CAAC;AAGD,iBAAW,UAAU,IAAI,WAAW,GAAG;AACrC,cAAM,aAAa,OAAO,QAAQ;AAClC,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK,cAAc,UAAU,GAAG,IAAI,IAAI,UAAU,IAAI,QAAQ;AAAA,UACxE,MAAM,GAAG,IAAI,IAAI,UAAU;AAAA,UAC3B,MAAM;AAAA,UACN,WAAW,OAAO,mBAAmB,IAAI;AAAA,UACzC,SAAS,OAAO,iBAAiB,IAAI;AAAA,UACrC,aAAa,OAAO,SAAS;AAAA,UAC7B,WAAW,OAAO,OAAO;AAAA,QAC3B,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,kBACN,YACA,UACA,SACM;AACN,eAAW,SAAS,WAAW,cAAc,GAAG;AAC9C,UAAI,CAAC,KAAK,WAAW,KAAK,EAAG;AAC7B,YAAM,OAAO,MAAM,QAAQ;AAE3B,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK,cAAc,UAAU,MAAM,WAAW;AAAA,QACxD;AAAA,QACA,MAAM;AAAA,QACN,WAAW,MAAM,mBAAmB,IAAI;AAAA,QACxC,SAAS,MAAM,iBAAiB,IAAI;AAAA,QACpC,aAAa,MAAM,SAAS;AAAA,QAC5B,WAAW,MAAM,OAAO;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,mBACN,YACA,UACA,SACM;AACN,eAAW,aAAa,WAAW,eAAe,GAAG;AACnD,UAAI,CAAC,KAAK,WAAW,SAAS,EAAG;AACjC,YAAM,OAAO,UAAU,QAAQ;AAE/B,cAAQ,KAAK;AAAA,QACX,UAAU,KAAK,cAAc,UAAU,MAAM,MAAM;AAAA,QACnD;AAAA,QACA,MAAM;AAAA,QACN,WAAW,UAAU,mBAAmB,IAAI;AAAA,QAC5C,SAAS,UAAU,iBAAiB,IAAI;AAAA,QACxC,aAAa,UAAU,SAAS;AAAA,QAChC,WAAW,UAAU,OAAO;AAAA,MAC9B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,iBACN,YACA,UACA,SACM;AACN,eAAW,QAAQ,WAAW,sBAAsB,GAAG;AACrD,UAAI,CAAC,KAAK,WAAW,IAAI,EAAG;AAE5B,iBAAW,QAAQ,KAAK,gBAAgB,GAAG;AACzC,cAAM,OAAO,KAAK,QAAQ;AAE1B,gBAAQ,KAAK;AAAA,UACX,UAAU,KAAK,cAAc,UAAU,MAAM,UAAU;AAAA,UACvD;AAAA,UACA,MAAM;AAAA,UACN,WAAW,KAAK,mBAAmB,IAAI;AAAA,UACvC,SAAS,KAAK,iBAAiB,IAAI;AAAA,UACnC,aAAa,KAAK,SAAS;AAAA,UAC3B,WAAW,KAAK,OAAO;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIQ,mBACN,YACA,UACA,OACM;AAEN,UAAM,eAAe,KAAK,cAAc,UAAU,WAAW,YAAY,EAAE,QAAQ,YAAY,EAAE,GAAG,UAAU;AAC9G,UAAM,cAAc,KAAK,qBAAqB,YAAY,QAAQ;AAClE,UAAM,aAAa,YAAY,SAAS,IAAI,YAAY,CAAC,IAAK;AAE9D,eAAW,OAAO,WAAW,sBAAsB,GAAG;AACpD,YAAM,kBAAkB,IAAI,wBAAwB;AAGpD,UAAI,CAAC,gBAAgB,WAAW,GAAG,KAAK,CAAC,gBAAgB,WAAW,GAAG,GAAG;AACxE;AAAA,MACF;AAGA,YAAM,mBAAmB,KAAK,sBAAsB,UAAU,eAAe;AAG7E,YAAM,aAAa,IAAI,WAAW;AAElC,iBAAW,SAAS,IAAI,gBAAgB,GAAG;AACzC,cAAM,eAAe,MAAM,QAAQ;AACnC,cAAM,OAAkB;AAAA,UACtB,MAAM;AAAA,UACN,IAAI,KAAK,oBAAoB,kBAAkB,YAAY;AAAA,UAC3D,MAAM;AAAA,QACR;AACA,YAAI,cAAc,MAAM,WAAW,EAAG,MAAK,WAAW;AACtD,cAAM,KAAK,IAAI;AAAA,MACjB;AAEA,YAAM,gBAAgB,IAAI,iBAAiB;AAC3C,UAAI,eAAe;AACjB,cAAM,OAAkB;AAAA,UACtB,MAAM;AAAA,UACN,IAAI,KAAK,oBAAoB,kBAAkB,cAAc,QAAQ,CAAC;AAAA,UACtE,MAAM;AAAA,QACR;AACA,YAAI,WAAY,MAAK,WAAW;AAChC,cAAM,KAAK,IAAI;AAAA,MACjB;AAGA,YAAM,WAAW,IAAI,mBAAmB;AACxC,UAAI,UAAU;AACZ,cAAM,OAAkB;AAAA,UACtB,MAAM;AAAA,UACN,IAAI,KAAK,cAAc,kBAAkB,SAAS,QAAQ,GAAG,UAAU;AAAA,UACvE,MAAM;AAAA,QACR;AACA,YAAI,WAAY,MAAK,WAAW;AAChC,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,wBACN,YACA,UACA,OACM;AACN,eAAW,OAAO,WAAW,WAAW,GAAG;AACzC,YAAM,YAAY,IAAI,QAAQ;AAC9B,UAAI,CAAC,aAAa,CAAC,KAAK,WAAW,GAAG,EAAG;AAEzC,YAAM,gBAAgB,KAAK,cAAc,UAAU,WAAW,OAAO;AAGrE,YAAM,YAAY,IAAI,WAAW;AACjC,UAAI,WAAW;AAEb,cAAM,WAAW,UAAU,cAAc,EAAE,QAAQ,EAAE,QAAQ,SAAS,EAAE;AACxE,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,KAAK,uBAAuB,YAAY,UAAU,OAAO;AAAA,UAC7D,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAGA,iBAAW,QAAQ,IAAI,cAAc,GAAG;AAEtC,cAAM,YAAY,KAAK,cAAc,EAAE,QAAQ,EAAE,QAAQ,SAAS,EAAE;AACpE,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,KAAK,uBAAuB,YAAY,WAAW,WAAW;AAAA,UAClE,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBACN,YACA,UACA,OACM;AAEN,eAAW,MAAM,WAAW,aAAa,GAAG;AAC1C,UAAI,CAAC,KAAK,WAAW,EAAE,EAAG;AAC1B,YAAM,SAAS,GAAG,QAAQ;AAC1B,UAAI,CAAC,OAAQ;AAEb,YAAM,aAAa,KAAK,cAAc,UAAU,QAAQ,UAAU;AAElE,iBAAW,QAAQ,GAAG,qBAAqB,WAAW,cAAc,GAAG;AACrE,cAAM,aAAa,KAAK,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,IAAI;AACjE,YAAI,CAAC,cAAc,eAAe,OAAQ;AAE1C,cAAM,WAAW,KAAK,uBAAuB,YAAY,UAAU,UAAU;AAC7E,YAAI,UAAU;AACZ,gBAAM,KAAK,EAAE,MAAM,YAAY,IAAI,UAAU,MAAM,QAAQ,CAAC;AAAA,QAC9D;AAAA,MACF;AAGA,iBAAW,WAAW,GAAG,qBAAqB,WAAW,aAAa,GAAG;AACvE,cAAM,aAAa,QAAQ,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,EAAE,IAAI;AACpE,YAAI,CAAC,WAAY;AAEjB,cAAM,WAAW,KAAK,uBAAuB,YAAY,UAAU,UAAU;AAC7E,YAAI,UAAU;AACZ,gBAAM,KAAK,EAAE,MAAM,YAAY,IAAI,UAAU,MAAM,QAAQ,CAAC;AAAA,QAC9D;AAAA,MACF;AAAA,IACF;AAGA,eAAW,OAAO,WAAW,WAAW,GAAG;AACzC,YAAM,YAAY,IAAI,QAAQ;AAC9B,UAAI,CAAC,aAAa,CAAC,KAAK,WAAW,GAAG,EAAG;AAEzC,iBAAW,UAAU,IAAI,WAAW,GAAG;AACrC,cAAM,aAAa,OAAO,QAAQ;AAClC,cAAM,iBAAiB,KAAK,cAAc,UAAU,GAAG,SAAS,IAAI,UAAU,IAAI,QAAQ;AAE1F,mBAAW,QAAQ,OAAO,qBAAqB,WAAW,cAAc,GAAG;AACzE,gBAAM,aAAa,KAAK,cAAc,EAAE,QAAQ;AAChD,gBAAM,aAAa,WAAW,MAAM,GAAG,EAAE,IAAI;AAC7C,cAAI,CAAC,cAAc,eAAe,WAAY;AAE9C,cAAI;AACJ,cAAI,WAAW,WAAW,OAAO,GAAG;AAClC,uBAAW,KAAK,sBAAsB,YAAY,UAAU,WAAW,UAAU;AAAA,UACnF,OAAO;AACL,uBAAW,KAAK,uBAAuB,YAAY,UAAU,UAAU;AAAA,UACzE;AACA,cAAI,UAAU;AACZ,kBAAM,KAAK,EAAE,MAAM,gBAAgB,IAAI,UAAU,MAAM,QAAQ,CAAC;AAAA,UAClE;AAAA,QACF;AAGA,mBAAW,WAAW,OAAO,qBAAqB,WAAW,aAAa,GAAG;AAC3E,gBAAM,aAAa,QAAQ,cAAc,EAAE,QAAQ;AACnD,gBAAM,aAAa,WAAW,MAAM,GAAG,EAAE,IAAI;AAC7C,cAAI,CAAC,WAAY;AAEjB,cAAI;AACJ,cAAI,WAAW,WAAW,OAAO,GAAG;AAClC,uBAAW,KAAK,sBAAsB,YAAY,UAAU,WAAW,UAAU;AAAA,UACnF,OAAO;AACL,uBAAW,KAAK,uBAAuB,YAAY,UAAU,UAAU;AAAA,UACzE;AACA,cAAI,UAAU;AACZ,kBAAM,KAAK,EAAE,MAAM,gBAAgB,IAAI,UAAU,MAAM,QAAQ,CAAC;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,sBACN,YACA,UACA,OACM;AAEN,UAAM,YAAY,oBAAI,IAAoB;AAC1C,eAAW,OAAO,WAAW,sBAAsB,GAAG;AACpD,YAAM,MAAM,IAAI,wBAAwB;AACxC,UAAI,CAAC,IAAI,WAAW,GAAG,KAAK,CAAC,IAAI,WAAW,GAAG,EAAG;AAClD,YAAM,aAAa,KAAK,sBAAsB,UAAU,GAAG;AAC3D,iBAAW,SAAS,IAAI,gBAAgB,GAAG;AACzC,kBAAU,IAAI,MAAM,QAAQ,GAAG,KAAK,oBAAoB,YAAY,MAAM,QAAQ,CAAC,CAAC;AAAA,MACtF;AACA,YAAM,gBAAgB,IAAI,iBAAiB;AAC3C,UAAI,eAAe;AACjB,kBAAU,IAAI,cAAc,QAAQ,GAAG,KAAK,oBAAoB,YAAY,cAAc,QAAQ,CAAC,CAAC;AAAA,MACtG;AAAA,IACF;AACA,QAAI,UAAU,SAAS,EAAG;AAG1B,eAAW,MAAM,WAAW,aAAa,GAAG;AAC1C,UAAI,CAAC,KAAK,WAAW,EAAE,EAAG;AAC1B,YAAM,SAAS,GAAG,QAAQ;AAC1B,UAAI,CAAC,OAAQ;AACb,YAAM,SAAS,KAAK,cAAc,UAAU,QAAQ,UAAU;AAC9D,WAAK,cAAc,IAAI,QAAQ,WAAW,KAAK;AAAA,IACjD;AAEA,eAAW,OAAO,WAAW,WAAW,GAAG;AACzC,UAAI,CAAC,KAAK,WAAW,GAAG,EAAG;AAC3B,YAAM,YAAY,IAAI,QAAQ;AAC9B,UAAI,CAAC,UAAW;AAGhB,YAAM,UAAU,KAAK,cAAc,UAAU,WAAW,OAAO;AAC/D,WAAK,cAAc,KAAK,SAAS,WAAW,KAAK;AAAA,IACnD;AAAA,EACF;AAAA,EAEQ,cACN,MACA,QACA,WACA,OACM;AACN,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,MAAM,KAAK,qBAAqB,WAAW,UAAU,GAAG;AACjE,YAAM,OAAO,GAAG,QAAQ;AACxB,UAAI,KAAK,IAAI,IAAI,EAAG;AACpB,YAAM,SAAS,UAAU,IAAI,IAAI;AACjC,UAAI,QAAQ;AACV,aAAK,IAAI,IAAI;AACb,cAAM,KAAK,EAAE,MAAM,QAAQ,IAAI,QAAQ,MAAM,OAAO,CAAC;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,uBACN,YACA,UACA,YACoB;AAEpB,eAAW,OAAO,WAAW,sBAAsB,GAAG;AACpD,YAAM,kBAAkB,IAAI,wBAAwB;AACpD,UAAI,CAAC,gBAAgB,WAAW,GAAG,KAAK,CAAC,gBAAgB,WAAW,GAAG,EAAG;AAE1E,iBAAW,SAAS,IAAI,gBAAgB,GAAG;AACzC,YAAI,MAAM,QAAQ,MAAM,YAAY;AAClC,gBAAM,aAAa,KAAK,sBAAsB,UAAU,eAAe;AACvE,iBAAO,KAAK,oBAAoB,YAAY,UAAU;AAAA,QACxD;AAAA,MACF;AAAA,IACF;AAGA,eAAW,MAAM,WAAW,aAAa,GAAG;AAC1C,UAAI,GAAG,QAAQ,MAAM,YAAY;AAC/B,eAAO,KAAK,cAAc,UAAU,YAAY,UAAU;AAAA,MAC5D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,sBACN,YACA,UACA,WACA,YACoB;AACpB,eAAW,OAAO,WAAW,WAAW,GAAG;AACzC,UAAI,IAAI,QAAQ,MAAM,UAAW;AACjC,iBAAW,UAAU,IAAI,WAAW,GAAG;AACrC,YAAI,OAAO,QAAQ,MAAM,YAAY;AACnC,iBAAO,KAAK,cAAc,UAAU,GAAG,SAAS,IAAI,UAAU,IAAI,QAAQ;AAAA,QAC5E;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAIQ,YAAY,UAAkB,QAAwC;AAC5E,QAAI;AACF,YAAM,WAAW,KAAK,QAAQ,cAAc,QAAQ;AACpD,UAAI,YAAY,KAAK,kBAAkB;AACrC,eAAO;AAAA,MACT;AACA,UAAI,UAAU;AACZ,aAAK,QAAQ,iBAAiB,QAAQ;AAAA,MACxC;AACA,aAAO,KAAK,QAAQ,iBAAiB,UAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAAA,IAC5E,SAAS,KAAK;AACZ,cAAQ,MAAM,oCAAoC,QAAQ,KAAM,IAAc,OAAO,EAAE;AACvF,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,kBAAkB,UAAwB;AAChD,UAAM,WAAW,KAAK,QAAQ,cAAc,QAAQ;AACpD,QAAI,UAAU;AACZ,WAAK,QAAQ,iBAAiB,QAAQ;AAAA,IACxC;AAAA,EACF;AAAA,EAEQ,cAAc,UAAkB,MAAc,MAA0B;AAC9E,WAAO,GAAG,QAAQ,KAAK,IAAI,KAAK,IAAI;AAAA,EACtC;AAAA,EAEQ,sBAAsB,UAAkB,iBAAiC;AAE/E,UAAM,UAAU,QAAQ,QAAQ;AAChC,QAAI,WAAW,UAAU,KAAK,SAAS,eAAe,CAAC,EAAE,QAAQ,OAAO,GAAG;AAG3E,QAAI,SAAS,SAAS,KAAK,GAAG;AAC5B,iBAAW,SAAS,MAAM,GAAG,EAAE,IAAI;AAAA,IACrC,WAAW,SAAS,SAAS,MAAM,GAAG;AACpC,iBAAW,SAAS,MAAM,GAAG,EAAE,IAAI;AAAA,IACrC,WAAW,CAAC,QAAQ,QAAQ,GAAG;AAC7B,kBAAY;AAAA,IACd;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,oBAAoB,YAAoB,MAAsB;AAEpE,UAAM,SAAS,GAAG,UAAU,KAAK,IAAI;AACrC,eAAWC,SAAQ,cAAc;AAC/B,UAAI,KAAK,eAAe,IAAI,GAAG,MAAM,GAAGA,KAAI,EAAE,GAAG;AAC/C,eAAO,GAAG,MAAM,GAAGA,KAAI;AAAA,MACzB;AAAA,IACF;AAGA,UAAM,mBAAmB,KAAK,QAAQ,cAAc,UAAU;AAC9D,QAAI,kBAAkB;AACpB,iBAAW,MAAM,iBAAiB,aAAa,GAAG;AAChD,YAAI,GAAG,QAAQ,MAAM,QAAQ,KAAK,WAAW,EAAE,GAAG;AAChD,iBAAO,KAAK,cAAc,YAAY,MAAM,UAAU;AAAA,QACxD;AAAA,MACF;AACA,iBAAW,OAAO,iBAAiB,WAAW,GAAG;AAC/C,YAAI,IAAI,QAAQ,MAAM,QAAQ,KAAK,WAAW,GAAG,GAAG;AAClD,iBAAO,KAAK,cAAc,YAAY,MAAM,OAAO;AAAA,QACrD;AAAA,MACF;AACA,iBAAW,SAAS,iBAAiB,cAAc,GAAG;AACpD,YAAI,MAAM,QAAQ,MAAM,QAAQ,KAAK,WAAW,KAAK,GAAG;AACtD,iBAAO,KAAK,cAAc,YAAY,MAAM,WAAW;AAAA,QACzD;AAAA,MACF;AACA,iBAAW,KAAK,iBAAiB,eAAe,GAAG;AACjD,YAAI,EAAE,QAAQ,MAAM,QAAQ,KAAK,WAAW,CAAC,GAAG;AAC9C,iBAAO,KAAK,cAAc,YAAY,MAAM,MAAM;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAEA,UAAM,OAAO,KAAK,gBAAgB,IAAI;AACtC,WAAO,GAAG,UAAU,KAAK,IAAI,KAAK,IAAI;AAAA,EACxC;AAAA,EAEQ,uBACN,YACA,MACA,aACQ;AAER,eAAW,OAAO,WAAW,sBAAsB,GAAG;AACpD,YAAM,kBAAkB,IAAI,wBAAwB;AACpD,UAAI,CAAC,gBAAgB,WAAW,GAAG,KAAK,CAAC,gBAAgB,WAAW,GAAG,EAAG;AAE1E,iBAAW,SAAS,IAAI,gBAAgB,GAAG;AACzC,YAAI,MAAM,QAAQ,MAAM,MAAM;AAC5B,gBAAM,WAAW,IAAI,6BAA6B,GAAG,YAAY;AACjE,cAAI,UAAU;AACZ,mBAAO,GAAG,KAAK,kBAAkB,QAAQ,CAAC,KAAK,IAAI,KAAK,WAAW;AAAA,UACrE;AAEA,gBAAM,YAAY,QAAQ,KAAK,kBAAkB,WAAW,YAAY,CAAC,CAAC;AAC1E,gBAAM,eAAe,UAAU,KAAK,WAAW,eAAe,CAAC,EAC5D,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,MAAM,EACxB,QAAQ,SAAS,KAAK;AACzB,iBAAO,GAAG,YAAY,KAAK,IAAI,KAAK,WAAW;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAGA,WAAO,GAAG,WAAW,YAAY,CAAC,KAAK,IAAI,KAAK,WAAW;AAAA,EAC7D;AAAA,EAEQ,gBAAgB,MAA0B;AAEhD,QAAI,UAAU,KAAK,IAAI,KAAK,KAAK,SAAS,EAAG,QAAO;AAEpD,QAAI,oBAAoB,KAAK,IAAI,EAAG,QAAO;AAE3C,QAAI,SAAS,KAAK,IAAI,EAAG,QAAO;AAEhC,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,UAA0B;AAElD,WAAO,SAAS,QAAQ,OAAO,EAAE;AAAA,EACnC;AAAA,EAEQ,qBAAqB,YAAwB,UAA4B;AAC/E,UAAM,MAAgB,CAAC;AACvB,eAAW,MAAM,WAAW,aAAa,GAAG;AAC1C,UAAI,CAAC,KAAK,WAAW,EAAE,EAAG;AAC1B,YAAM,OAAO,GAAG,QAAQ;AACxB,UAAI,KAAM,KAAI,KAAK,KAAK,cAAc,UAAU,MAAM,UAAU,CAAC;AAAA,IACnE;AACA,eAAW,OAAO,WAAW,WAAW,GAAG;AACzC,UAAI,CAAC,KAAK,WAAW,GAAG,EAAG;AAC3B,YAAM,OAAO,IAAI,QAAQ;AACzB,UAAI,KAAM,KAAI,KAAK,KAAK,cAAc,UAAU,MAAM,OAAO,CAAC;AAAA,IAChE;AACA,eAAW,SAAS,WAAW,cAAc,GAAG;AAC9C,UAAI,CAAC,KAAK,WAAW,KAAK,EAAG;AAC7B,UAAI,KAAK,KAAK,cAAc,UAAU,MAAM,QAAQ,GAAG,WAAW,CAAC;AAAA,IACrE;AACA,eAAW,KAAK,WAAW,eAAe,GAAG;AAC3C,UAAI,CAAC,KAAK,WAAW,CAAC,EAAG;AACzB,UAAI,KAAK,KAAK,cAAc,UAAU,EAAE,QAAQ,GAAG,MAAM,CAAC;AAAA,IAC5D;AACA,eAAW,QAAQ,WAAW,sBAAsB,GAAG;AACrD,UAAI,CAAC,KAAK,WAAW,IAAI,EAAG;AAC5B,iBAAW,QAAQ,KAAK,gBAAgB,GAAG;AACzC,YAAI,KAAK,KAAK,cAAc,UAAU,KAAK,QAAQ,GAAG,UAAU,CAAC;AAAA,MACnE;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,MAAqB;AACtC,QAAI,KAAK,aAAa,IAAI,GAAG;AAC3B,aAAO,KAAK,WAAW;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,0BAA0B,MAAuD;AACvF,QAAI,aAAa;AAEjB,SAAK,kBAAkB,CAAC,UAAU;AAChC,cAAQ,MAAM,QAAQ,GAAG;AAAA,QACvB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW;AAAA,QAChB,KAAK,WAAW,kBAAkB;AAChC,gBAAM,OAAO,MAAM,QAAQ;AAC3B,cAAI,MAAM,QAAQ,MAAM,WAAW,kBAAkB;AACnD,gBAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG;AACrE;AAAA,YACF;AAAA,UACF,OAAO;AACL;AAAA,UACF;AACA;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,WAAO;AAAA,EACT;AACF;;;AC5uBA,SAAS,WAAAC,gBAAe;AAGjB,IAAM,0BAAN,MAA8B;AAAA,EAClB,sBAAsB,oBAAI,IAA8B;AAAA,EAEzE,SAAS,SAAiC;AACxC,eAAW,OAAO,QAAQ,YAAY;AACpC,WAAK,oBAAoB,IAAI,IAAI,YAAY,GAAG,OAAO;AAAA,IACzD;AAAA,EACF;AAAA,EAEA,yBAAsC;AACpC,WAAO,IAAI,IAAI,KAAK,oBAAoB,KAAK,CAAC;AAAA,EAChD;AAAA,EAEA,WAAW,UAAgD;AACzD,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,MAAMA,SAAQ,QAAQ,EAAE,YAAY;AAC1C,QAAI,CAAC,IAAK,QAAO;AAEjB,WAAO,KAAK,oBAAoB,IAAI,GAAG;AAAA,EACzC;AACF;;;ACxBA,SAAS,eAAe,YAAY,WAAW,YAAY,kBAAkB;AAC7E,SAAS,WAAAC,UAAS,QAAAC,OAAM,SAAS,WAAW;AAGrC,IAAM,kBAAN,MAAsB;AAAA,EACV;AAAA,EAEjB,YAAY,UAAkB;AAC5B,SAAK,WAAWA,MAAK,UAAU,OAAO;AAAA,EACxC;AAAA,EAEA,MAAM,WAA4B;AAChC,QAAI,CAAC,UAAU,MAAM;AACnB,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AAEA,UAAM,aAAa,KAAK,iBAAiB,UAAU,IAAI;AACvD,cAAUD,SAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;AAElD,UAAM,SAAS,KAAK,SAAS,SAAS;AACtC,UAAM,OAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AAC3C,SAAK,YAAY,YAAY,IAAI;AAAA,EACnC;AAAA,EAEA,eAAe,QAA8B;AAC3C,cAAU,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,UAAM,aAAaC,MAAK,KAAK,UAAU,iBAAiB;AACxD,SAAK,YAAY,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA,EAC9D;AAAA,EAEQ,YAAY,YAAoB,SAAuB;AAC7D,UAAM,UAAU,GAAG,UAAU,IAAI,QAAQ,GAAG;AAC5C,kBAAc,SAAS,SAAS,OAAO;AACvC,eAAW,SAAS,UAAU;AAAA,EAChC;AAAA,EAEA,OAAO,cAA4B;AACjC,UAAM,aAAa,KAAK,iBAAiB,YAAY;AACrD,QAAI,WAAW,UAAU,GAAG;AAC1B,iBAAW,UAAU;AAAA,IACvB;AAAA,EACF;AAAA,EAEQ,iBAAiB,cAA8B;AACrD,UAAM,WAAW,QAAQ,KAAK,UAAU,GAAG,YAAY,OAAO;AAC9D,UAAM,gBAAgB,QAAQ,KAAK,QAAQ,IAAI;AAC/C,QAAI,CAAC,SAAS,WAAW,aAAa,GAAG;AACvC,YAAM,IAAI,MAAM,4BAA4B,YAAY,EAAE;AAAA,IAC5D;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,SAAS,KAAuB;AACtC,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,aAAO,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC;AAAA,IAC9C;AACA,QAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,YAAM,SAAkC,CAAC;AACzC,iBAAW,OAAO,OAAO,KAAK,GAAG,EAAE,KAAK,GAAG;AACzC,eAAO,GAAG,IAAI,KAAK,SAAU,IAAgC,GAAG,CAAC;AAAA,MACnE;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;;;ACjEA,SAAS,cAAc,iBAAAC,gBAAe,cAAAC,aAAY,aAAAC,kBAAiB;AACnE,SAAS,QAAAC,OAAM,WAAAC,gBAAe;AAE9B,IAAM,yBAAyB;AAExB,IAAM,gBAAN,MAAoB;AAAA,EACR;AAAA,EAEjB,YAAY,UAAkB;AAC5B,SAAK,kBAAkBD,MAAK,UAAU,SAAS,gBAAgB;AAAA,EACjE;AAAA,EAEA,iBAAyB;AACvB,WAAO;AAAA,EACT;AAAA,EAEA,oBAAwC;AACtC,QAAI,CAACF,YAAW,KAAK,eAAe,GAAG;AACrC,aAAO;AAAA,IACT;AACA,WAAO,aAAa,KAAK,iBAAiB,OAAO,EAAE,KAAK;AAAA,EAC1D;AAAA,EAEA,eAAqB;AACnB,IAAAC,WAAUE,SAAQ,KAAK,eAAe,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5D,IAAAJ,eAAc,KAAK,iBAAiB,wBAAwB,OAAO;AAAA,EACrE;AAAA,EAEA,eAAwB;AACtB,UAAM,SAAS,KAAK,kBAAkB;AACtC,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,WAAW;AAAA,EACpB;AACF;;;ALnBO,IAAM,eAAN,MAAmB;AAAA,EACP;AAAA,EACjB;AAAA,EACQ;AAAA,EAER,YAAY,aAAqB,UAAmB;AAClD,SAAK,cAAc;AACnB,SAAK,WAAW,YAAYK,MAAK,aAAa,OAAO;AACrD,SAAK,sBAAsB,oBAAI,IAAI,CAAC,OAAO,QAAQ,OAAO,QAAQ,OAAO,KAAK,CAAC;AAAA,EACjF;AAAA,EAEA,MAAM,IAAI,UAAqH,CAAC,GAAkB;AAChJ,QAAI,QAAQ,OAAO;AAEjB,aAAO,KAAK,SAAS;AAAA,IACvB;AAGA,UAAM,WAAW,IAAI,wBAAwB;AAC7C,UAAM,iBAAiB,IAAI,eAAe;AAC1C,aAAS,SAAS,cAAc;AAChC,SAAK,2BAA2B,QAAQ;AACxC,SAAK,sBAAsB,SAAS,uBAAuB;AAE3D,UAAM,SAAS,IAAI,gBAAgB,KAAK,QAAQ;AAChD,UAAM,gBAAgB,IAAI,cAAc,KAAK,QAAQ;AACrD,UAAM,SAAS,IAAI,cAAc;AACjC,UAAM,aAAa,IAAI,iBAAiB,KAAK,WAAW;AACxD,UAAM,iBAAiB,IAAI,eAAe;AAG1C,QAAI;AACJ,QAAI,QAAQ,MAAM;AAChB,YAAM,WAAWA,MAAK,KAAK,aAAa,QAAQ,IAAI;AACpD,cAAQ,CAAC,QAAQ;AACjB,cAAQ,MAAM,gCAAgC,QAAQ,IAAI,EAAE;AAAA,IAC9D,OAAO;AAEL,YAAM,aAAa,KAAK,mBAAmB;AAC3C,cAAQ,CAAC;AACT,iBAAW,MAAM,YAAY;AAC3B,cAAM,UAAU,KAAK,gBAAgB,EAAE;AACvC,cAAM,KAAK,GAAG,OAAO;AAAA,MACvB;AACA,cAAQ,MAAM,2CAA2C,MAAM,MAAM,eAAe;AAAA,IACtF;AAGA,UAAM,iBAAiB,oBAAI,IAAwB;AACnD,UAAM,iBAID,CAAC;AACN,QAAI,YAAY;AAEhB,eAAW,YAAY,OAAO;AAC5B,YAAM,UAAU,SAAS,WAAW,QAAQ;AAC5C,UAAI,CAAC,QAAS;AAEd,YAAM,eAAe,SAAS,KAAK,aAAa,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAE5E,UAAI;AACF,cAAM,SAASC,cAAa,UAAU,OAAO;AAC7C,cAAM,eAAe,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAEjD,cAAM,UAAU,QAAQ,eAAe,cAAc,MAAM;AAC3D,cAAM,aAAa,QAAQ,kBAAkB,cAAc,MAAM;AAGjE,mBAAW,OAAO,SAAS;AACzB,yBAAe,IAAI,IAAI,UAAU,IAAI,IAAI;AAAA,QAC3C;AAEA,uBAAe,KAAK;AAAA,UAClB;AAAA,UACA;AAAA,UACA,WAAW;AAAA,YACT,MAAM;AAAA,YACN;AAAA,YACA,aAAa,OAAO,KAAK,MAAM;AAAA,YAC/B;AAAA,YACA,OAAO,CAAC;AAAA,YACR;AAAA,YACA,QAAQ,CAAC;AAAA,YACT,cAAc,CAAC;AAAA,UACjB;AAAA,QACF,CAAC;AAED;AACA,YAAI,YAAY,OAAO,GAAG;AACxB,kBAAQ,MAAM,oBAAoB,SAAS,IAAI,MAAM,MAAM,kBAAkB;AAAA,QAC/E;AAAA,MACF,SAAS,KAAK;AACZ,gBAAQ,MAAM,kBAAkB,YAAY,KAAM,IAAc,OAAO,EAAE;AAAA,MAC3E;AAAA,IACF;AAGA,UAAM,aAAa,oBAAI,IAAoB;AAC3C,eAAW,SAAS,gBAAgB;AAClC,iBAAW,IAAI,MAAM,cAAc,MAAM,MAAM;AAAA,IACjD;AACA,mBAAe,mBAAmB,UAAU;AAG5C,eAAW,SAAS,gBAAgB;AAClC,YAAM,UAAU,SAAS,WAAW,MAAM,YAAY;AACtD,UAAI,CAAC,QAAS;AAEd,UAAI;AACF,gBAAQ,oBAAoB,cAAc;AAC1C,cAAM,UAAU,QAAQ,QAAQ,aAAa,MAAM,cAAc,MAAM,MAAM;AAAA,MAC/E,SAAS,KAAK;AACZ,gBAAQ,MAAM,qCAAqC,MAAM,YAAY,KAAM,IAAc,OAAO,EAAE;AAAA,MACpG;AAAA,IACF;AAGA,mBAAe,oBAAoB;AAGnC,QAAI,CAAC,QAAQ,eAAe,eAAe,SAAS,GAAG;AACrD,YAAM,aAAa,QAAQ,cAAc;AACzC,YAAM,eAAe,MAAM,WAAW,kBAAkB,UAAU,KAAK,oBAAI,IAAuD;AAElI,iBAAW,EAAE,cAAc,UAAU,KAAK,gBAAgB;AACxD,cAAM,UAAU,aAAa,IAAI,YAAY,KAAK,CAAC;AACnD,kBAAU,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,UACrC,MAAM,EAAE;AAAA,UACR,SAAS,EAAE;AAAA,UACX,MAAM,EAAE;AAAA,UACR,MAAM;AAAA,QACR,EAAE;AACF,kBAAU,eAAe,eAAe,OAAO,OAAO;AAAA,MACxD;AAAA,IACF;AAGA,QAAI,CAAC,QAAQ,eAAe,eAAe,SAAS,GAAG;AACrD,YAAM,cAAc,eAAe,IAAI,OAAK,EAAE,SAAS;AACvD,YAAM,iBAAiB,mBAAmB,WAAW;AACrD,aAAO,eAAe,cAAc;AACpC,cAAQ,MAAM,8BAA8B,eAAe,QAAQ,MAAM,sBAAsB;AAAA,IACjG;AAGA,UAAM,UAAuB,CAAC;AAC9B,eAAW,EAAE,UAAU,KAAK,gBAAgB;AAC1C,aAAO,MAAM,SAAS;AACtB,cAAQ,KAAK,SAAS;AAAA,IACxB;AAGA,kBAAc,aAAa;AAG3B,UAAM,UAAU,IAAI,qBAAqB,KAAK,QAAQ;AACtD,QAAI;AACF,YAAM,QAAQ,UAAU;AACxB,cAAQ,UAAU,OAAO;AAAA,IAC3B,UAAE;AACA,cAAQ,MAAM;AAAA,IAChB;AAGA,QAAI,CAAC,QAAQ,iBAAiB;AAC5B,WAAK,gBAAgB;AAAA,IACvB;AAEA,YAAQ,MAAM,0BAA0B,SAAS,gBAAgB;AAAA,EACnE;AAAA,EAEQ,2BAA2B,UAAyC;AAC1E,QAAI;AAEF,YAAM,EAAE,WAAAC,WAAU,IAAI;AACtB,eAAS,SAAS,IAAIA,WAAU,CAAC;AAAA,IACnC,QAAQ;AACN,cAAQ,MAAM,8DAA8D;AAAA,IAC9E;AACA,QAAI;AAEF,YAAM,EAAE,eAAAC,eAAc,IAAI;AAC1B,eAAS,SAAS,IAAIA,eAAc,CAAC;AAAA,IACvC,QAAQ;AACN,cAAQ,MAAM,mEAAmE;AAAA,IACnF;AAAA,EACF;AAAA,EAEQ,gBAAgB,MAAwB;AAC9C,QAAI;AACF,YAAM,SAAS,aAAa,OAAO,CAAC,YAAY,YAAY,YAAY,oBAAoB,GAAG;AAAA,QAC7F,KAAK;AAAA,QACL,UAAU;AAAA,QACV,WAAW,KAAK,OAAO;AAAA,MACzB,CAAC;AAED,aAAO,OACJ,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,EACzB,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,OAAO,CAAC,SAAS,KAAK,qBAAqB,IAAI,CAAC,EAChD,IAAI,CAAC,SAASH,MAAK,MAAM,IAAI,CAAC;AAAA,IACnC,QAAQ;AACN,cAAQ,MAAM,kCAAkC,IAAI,EAAE;AACtD,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA,EAEQ,qBAA+B;AACrC,UAAM,UAAUA,MAAK,KAAK,aAAa,cAAc;AACrD,QAAI,CAACI,YAAW,OAAO,EAAG,QAAO,CAAC,KAAK,WAAW;AAElD,QAAI;AACF,YAAM,MAAM,KAAK,MAAMH,cAAa,SAAS,OAAO,CAAC;AACrD,YAAM,aAAmC,MAAM,QAAQ,IAAI,UAAU,IACjE,IAAI,aACJ,IAAI,YAAY;AAEpB,UAAI,CAAC,cAAc,WAAW,WAAW,EAAG,QAAO,CAAC,KAAK,WAAW;AAGpE,YAAM,WAAqB,CAAC;AAC5B,iBAAW,MAAM,YAAY;AAC3B,YAAI,GAAG,SAAS,IAAI,KAAK,GAAG,SAAS,KAAK,GAAG;AAE3C,gBAAM,YAAYD,MAAK,KAAK,aAAa,GAAG,MAAM,GAAG,EAAE,CAAC;AACxD,cAAII,YAAW,SAAS,GAAG;AACzB,uBAAW,SAAS,YAAY,WAAW,EAAE,eAAe,KAAK,CAAC,GAAG;AACnE,kBAAI,MAAM,YAAY,GAAG;AACvB,yBAAS,KAAKJ,MAAK,WAAW,MAAM,IAAI,CAAC;AAAA,cAC3C;AAAA,YACF;AAAA,UACF;AAAA,QACF,OAAO;AAEL,gBAAM,SAASA,MAAK,KAAK,aAAa,EAAE;AACxC,cAAII,YAAW,MAAM,GAAG;AACtB,qBAAS,KAAK,MAAM;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAEA,UAAI,SAAS,WAAW,EAAG,QAAO,CAAC,KAAK,WAAW;AAEnD,cAAQ,MAAM,6BAA6B,SAAS,MAAM,eAAe;AACzE,aAAO;AAAA,IACT,QAAQ;AACN,aAAO,CAAC,KAAK,WAAW;AAAA,IAC1B;AAAA,EACF;AAAA,EAEQ,qBAAqB,UAA2B;AACtD,UAAM,MAAMC,SAAQ,QAAQ,EAAE,YAAY;AAC1C,WAAO,KAAK,oBAAoB,IAAI,GAAG;AAAA,EACzC;AAAA,EAEA,MAAc,WAA0B;AACtC,YAAQ,MAAM,oCAAoC;AAGlD,UAAM,WAAW,IAAI,wBAAwB;AAC7C,aAAS,SAAS,IAAI,eAAe,CAAC;AACtC,SAAK,2BAA2B,QAAQ;AACxC,SAAK,sBAAsB,SAAS,uBAAuB;AAE3D,UAAM,SAAS,IAAI,cAAc;AACjC,UAAM,QAAQ,KAAK,gBAAgB,KAAK,WAAW;AACnD,UAAM,SAAS,KAAK,MAAM,OAAO,iCAA0C,GAAG,gBAAgB,KAAK,QAAQ;AAC3G,UAAM,UAAU,OAAO,QAAQ;AAC/B,UAAM,aAAa,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1D,QAAI,aAAa;AAEjB,eAAW,YAAY,OAAO;AAC5B,UAAI,CAAC,KAAK,qBAAqB,QAAQ,EAAG;AAE1C,YAAM,eAAe,SAAS,KAAK,aAAa,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAC5E,YAAM,UAAU,WAAW,IAAI,YAAY;AAE3C,UAAI,CAAC,SAAS;AACZ,gBAAQ,MAAM,uBAAuB,YAAY,EAAE;AACnD;AACA;AAAA,MACF;AAGA,UAAI,CAACD,YAAW,QAAQ,GAAG;AACzB,gBAAQ,MAAM,mBAAmB,YAAY,EAAE;AAC/C;AACA;AAAA,MACF;AAGA,YAAM,QAAQ,KAAK,MAAM,SAAS,QAAQ,EAAE,UAAU,GAAI;AAC1D,UAAI,SAAS,QAAQ,aAAc;AAGnC,UAAI,QAAQ,aAAa;AACvB,cAAM,SAASH,cAAa,UAAU,OAAO;AAC7C,cAAM,cAAc,OAAO,KAAK,MAAM;AACtC,YAAI,gBAAgB,QAAQ,YAAa;AAAA,MAC3C;AAEA,cAAQ,MAAM,iBAAiB,YAAY,EAAE;AAC7C;AAAA,IACF;AAEA,QAAI,aAAa,GAAG;AAClB,cAAQ,MAAM,UAAU,UAAU,6CAA6C;AAC/E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,MAAM,4BAA4B;AAAA,EAC5C;AAAA,EAEQ,kBAAwB;AAC9B,UAAM,gBAAgBD,MAAK,KAAK,aAAa,YAAY;AACzD,UAAM,eAAe;AACrB,UAAM,SAAS;AAAA;AAAA,EAA2C,YAAY;AAAA;AAGtE,UAAM,WAAWI,YAAW,aAAa,IAAIH,cAAa,eAAe,OAAO,IAAI;AACpF,QAAI,SAAS,SAAS,YAAY,EAAG;AAErC,IAAAK,eAAc,eAAe,WAAW,QAAQ,OAAO;AACvD,YAAQ,MAAM,0CAA0C;AAAA,EAC1D;AACF;;;AMvVA,SAAS,QAAAC,aAAY;AAGd,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EAEjB,YAAY,aAAqB;AAC/B,SAAK,WAAWC,MAAK,aAAa,OAAO;AAAA,EAC3C;AAAA,EAEA,MAAM,MAAqB;AACzB,YAAQ,MAAM,6DAA6D;AAE3E,UAAM,UAAU,IAAI,qBAAqB,KAAK,QAAQ;AACtD,QAAI;AACF,YAAM,QAAQ,KAAK;AAAA,IACrB,UAAE;AACA,cAAQ,MAAM;AAAA,IAChB;AAEA,YAAQ,MAAM,sBAAsB;AAAA,EACtC;AACF;;;ACtBA,SAAS,QAAAC,aAAY;AACrB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,gBAAAC,qBAAoB;AAItB,IAAM,gBAAN,MAAoB;AAAA,EACR;AAAA,EACA;AAAA,EAEjB,YAAY,aAAqB;AAC/B,SAAK,cAAc;AACnB,SAAK,WAAWC,MAAK,aAAa,OAAO;AAAA,EAC3C;AAAA,EAEA,MAAY;AACV,UAAM,WAAWA,MAAK,KAAK,UAAU,OAAO;AAE5C,QAAI,CAACC,YAAW,QAAQ,GAAG;AACzB,cAAQ,MAAM,gDAAgD;AAC9D;AAAA,IACF;AAEA,UAAM,gBAAgB,IAAI,cAAc,KAAK,QAAQ;AACrD,UAAM,UAAU,cAAc,kBAAkB,KAAK;AAErD,UAAM,SAAS,IAAI,gBAAgB,KAAK,QAAQ;AAChD,UAAM,UAAU,OAAO,QAAQ;AAE/B,UAAM,eAAe,QAAQ,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,QAAQ,QAAQ,CAAC;AAC7E,UAAM,aAAa,QAAQ,OAAO,CAAC,KAAK,QAAQ,MAAM,IAAI,MAAM,QAAQ,CAAC;AAEzE,YAAQ,MAAM,qBAAqB;AACnC,YAAQ,MAAM,qBAAqB,OAAO,EAAE;AAC5C,YAAQ,MAAM,qBAAqB,QAAQ,MAAM,EAAE;AACnD,YAAQ,MAAM,qBAAqB,YAAY,EAAE;AACjD,YAAQ,MAAM,qBAAqB,UAAU,EAAE;AAE/C,UAAM,cAAcA,YAAWD,MAAK,KAAK,UAAU,UAAU,YAAY,CAAC;AAC1E,YAAQ,MAAM,qBAAqB,cAAc,YAAY,yBAAyB,EAAE;AAGxF,QAAI,QAAQ,SAAS,GAAG;AACtB,cAAQ,MAAM,EAAE;AAChB,cAAQ,MAAM,UAAU;AAGxB,YAAM,cAAc,KAAK,eAAe;AAExC,iBAAW,OAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,GAAG;AACtE,cAAM,KAAK,IAAI,KAAK,IAAI,eAAe,GAAI,EAAE,YAAY;AACzD,cAAM,aAAa,YAAY,OAAO,KAAK,CAAC,YAAY,IAAI,IAAI,IAAI;AACpE,cAAM,QAAQ,aAAa,gBAAgB;AAC3C,gBAAQ,MAAM,OAAO,IAAI,IAAI,KAAK,EAAE,MAAM,IAAI,QAAQ,MAAM,aAAa,IAAI,MAAM,MAAM,UAAU,KAAK,EAAE;AAAA,MAC5G;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iBAA8B;AACpC,QAAI;AACF,YAAM,SAASE,cAAa,OAAO,CAAC,YAAY,YAAY,YAAY,oBAAoB,GAAG;AAAA,QAC7F,KAAK,KAAK;AAAA,QACV,UAAU;AAAA,MACZ,CAAC;AACD,aAAO,IAAI,IAAI,OAAO,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAAA,IACpF,QAAQ;AACN,aAAO,oBAAI,IAAI;AAAA,IACjB;AAAA,EACF;AACF;;;ACrEA,SAAS,aAAa,cAAc;AACpC,SAAS,QAAAC,aAAY;AACrB,SAAS,cAAc;AAIhB,IAAM,gBAAN,MAAoB;AAAA,EACR;AAAA,EAEjB,YAAY,aAAqB;AAC/B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,MAAqB;AACzB,YAAQ,MAAM,qCAAqC;AAGnD,UAAM,UAAU,YAAYC,MAAK,OAAO,GAAG,cAAc,CAAC;AAE1D,QAAI;AACF,YAAM,WAAWA,MAAK,SAAS,OAAO;AAGtC,YAAM,WAAW,IAAI,aAAa,KAAK,aAAa,QAAQ;AAC5D,YAAM,SAAS,IAAI,EAAE,iBAAiB,KAAK,CAAC;AAG5C,YAAM,kBAAkB,IAAI,gBAAgBA,MAAK,KAAK,aAAa,OAAO,CAAC;AAC3E,YAAM,cAAc,IAAI,gBAAgB,QAAQ;AAEhD,YAAM,mBAAmB,gBAAgB,QAAQ;AACjD,YAAM,eAAe,YAAY,QAAQ;AAGzC,YAAM,YAAY,CAAC,MACjB,KAAK,UAAU,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,OAAO,QAAQ,EAAE,QAAQ,cAAc,EAAE,aAAa,CAAC;AAEvG,YAAM,eAAe,IAAI,IAAI,iBAAiB,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC;AAChF,YAAM,WAAW,IAAI,IAAI,aAAa,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC,CAAC;AAExE,UAAI,QAAQ;AAGZ,iBAAW,CAAC,MAAM,SAAS,KAAK,UAAU;AACxC,cAAM,YAAY,aAAa,IAAI,IAAI;AACvC,YAAI,cAAc,WAAW;AAC3B,kBAAQ,MAAM,iBAAiB,IAAI,EAAE;AACrC,kBAAQ;AAAA,QACV;AAAA,MACF;AAGA,iBAAW,QAAQ,aAAa,KAAK,GAAG;AACtC,YAAI,CAAC,SAAS,IAAI,IAAI,GAAG;AACvB,kBAAQ,MAAM,mBAAmB,IAAI,EAAE;AACvC,kBAAQ;AAAA,QACV;AAAA,MACF;AAEA,UAAI,OAAO;AACT,gBAAQ,MAAM,uEAAkE;AAChF,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,cAAQ,MAAM,4BAA4B;AAAA,IAC5C,UAAE;AACA,aAAO,SAAS,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IAClD;AAAA,EACF;AACF;;;ACrEA,SAAS,QAAAC,aAAY;AACrB,SAAS,cAAAC,aAAY,gBAAAC,eAAc,iBAAAC,gBAAe,aAAAC,YAAW,iBAAiB;AAE9E,IAAM,aAAa;AACnB,IAAM,WAAW;AAEjB,IAAM,sBAAsB;AAAA,EAC1B,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOV,QAAQ;AAAA,EACR,KAAK;AAEP,IAAM,qBAAqB;AAAA,EACzB,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA,EAKV,QAAQ;AAAA,EACR,KAAK;AAEA,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EAEjB,YAAY,aAAqB;AAC/B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAY;AACV,UAAM,WAAWJ,MAAK,KAAK,aAAa,QAAQ,OAAO;AAEvD,QAAI,CAACC,YAAWD,MAAK,KAAK,aAAa,MAAM,CAAC,GAAG;AAC/C,cAAQ,MAAM,oDAAoD;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,IAAAI,WAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAEvC,SAAK,YAAY,UAAU,eAAe,mBAAmB;AAC7D,SAAK,YAAY,UAAU,cAAc,kBAAkB;AAE3D,YAAQ,MAAM,sDAAsD;AAAA,EACtE;AAAA,EAEQ,YAAY,UAAkB,UAAkB,aAA2B;AACjF,UAAM,WAAWJ,MAAK,UAAU,QAAQ;AAExC,QAAI,WAAW;AACf,QAAIC,YAAW,QAAQ,GAAG;AACxB,iBAAWC,cAAa,UAAU,OAAO;AAGzC,UAAI,SAAS,SAAS,UAAU,GAAG;AACjC,gBAAQ,MAAM,UAAU,QAAQ,8CAAyC;AACzE;AAAA,MACF;AAAA,IACF,OAAO;AACL,iBAAW;AAAA,IACb;AAGA,UAAM,UAAU,SAAS,SAAS,IAAI,IAClC,WAAW,OAAO,cAAc,OAChC,WAAW,SAAS,cAAc;AAEtC,IAAAC,eAAc,UAAU,SAAS,OAAO;AACxC,cAAU,UAAU,GAAK;AAAA,EAC3B;AACF;;;ACzEA,SAAS,QAAAE,OAAM,WAAAC,UAAS,YAAAC,iBAAgB;AACxC,SAAS,gBAAAC,qBAAoB;;;ACD7B,SAAS,aAA6B;AAGtC,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,yBAAN,MAAqD;AAAA,EACzC;AAAA,EACA;AAAA,EACT;AAAA,EAER,YAAY,aAAqB,SAAoB;AACnD,SAAK,cAAc;AACnB,SAAK,UAAU,WAAW;AAAA,EAC5B;AAAA,EAEA,MAAM,SAAkC;AACtC,QAAI,KAAK,SAAS;AAChB,YAAM,IAAI,MAAM,6DAA6D;AAAA,IAC/E;AAEA,SAAK,UAAU,MAAM,KAAK,aAAa;AAAA,MACrC,SAAS,KAAK;AAAA,MACd,YAAY;AAAA,MACZ,eAAe;AAAA,IACjB,CAAC;AAED,SAAK,QAAQ,GAAG,OAAO,CAAC,SAAS,QAAQ,OAAO,IAAI,CAAC;AACrD,SAAK,QAAQ,GAAG,UAAU,CAAC,SAAS,QAAQ,UAAU,IAAI,CAAC;AAC3D,SAAK,QAAQ,GAAG,UAAU,CAAC,SAAS,QAAQ,UAAU,IAAI,CAAC;AAAA,EAC7D;AAAA,EAEA,MAAM,OAAsB;AAC1B,QAAI,KAAK,SAAS;AAChB,YAAM,KAAK,QAAQ,MAAM;AACzB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AACF;;;AD/BA,IAAM,cAAc;AAEb,IAAM,eAAN,MAAmB;AAAA,EACP;AAAA,EACA;AAAA,EAEjB,YAAY,aAAqB;AAC/B,SAAK,cAAc;AACnB,SAAK,WAAWC,MAAK,aAAa,OAAO;AAAA,EAC3C;AAAA,EAEA,MAAM,MAAqB;AACzB,YAAQ,MAAM,iCAAiC;AAE/C,UAAM,WAAW,IAAI,wBAAwB;AAC7C,aAAS,SAAS,IAAI,eAAe,CAAC;AACtC,SAAK,2BAA2B,QAAQ;AACxC,UAAM,sBAAsB,SAAS,uBAAuB;AAE5D,UAAM,SAAS,IAAI,gBAAgB,KAAK,QAAQ;AAChD,UAAM,UAAU,IAAI,qBAAqB,KAAK,QAAQ;AACtD,UAAM,QAAQ,KAAK;AACnB,UAAM,SAAS,IAAI,cAAc;AAEjC,UAAM,aAAa,IAAI,iBAAiB,KAAK,WAAW;AACxD,UAAM,iBAAiB,IAAI,eAAe;AAC1C,UAAM,UAAU,IAAI,uBAAuB,KAAK,WAAW;AAC3D,UAAM,eAAe,oBAAI,IAA4B;AAErD,UAAM,cAAc,OAAO,aAAqB;AAC9C,YAAM,UAAU,SAAS,WAAW,QAAQ;AAC5C,UAAI,CAAC,QAAS;AAEd,YAAM,eAAeC,UAAS,KAAK,aAAa,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAE5E,UAAI;AACF,cAAM,SAASC,cAAa,UAAU,OAAO;AAC7C,cAAM,eAAe,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAEjD,cAAM,UAAU,QAAQ,eAAe,cAAc,MAAM;AAC3D,cAAM,QAAQ,QAAQ,aAAa,cAAc,MAAM;AACvD,cAAM,aAAa,QAAQ,kBAAkB,cAAc,MAAM;AAGjE,cAAM,UAAU,MAAM,WAAW,iBAAiB,YAAY;AAC9D,cAAM,SAAyB,QAAQ,IAAI,CAAC,OAAO;AAAA,UACjD,MAAM,EAAE;AAAA,UAAM,SAAS,EAAE;AAAA,UAAS,MAAM,EAAE;AAAA,UAAM,MAAM;AAAA,QACxD,EAAE;AACF,cAAM,eAA8B,eAAe,OAAO,OAAO;AAEjE,cAAM,YAAuB;AAAA,UAC3B,MAAM;AAAA,UACN;AAAA,UACA,aAAa,OAAO,KAAK,MAAM;AAAA,UAC/B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,eAAO,MAAM,SAAS;AACtB,gBAAQ,gBAAgB,SAAS;AACjC,gBAAQ,MAAM,sBAAsB,YAAY,EAAE;AAAA,MACpD,SAAS,KAAK;AACZ,gBAAQ,MAAM,6BAA6B,YAAY,KAAM,IAAc,OAAO,EAAE;AAAA,MACtF;AAAA,IACF;AAEA,UAAM,mBAAmB,CAAC,aAAqB;AAC7C,YAAM,WAAW,aAAa,IAAI,QAAQ;AAC1C,UAAI,SAAU,cAAa,QAAQ;AAEnC,mBAAa;AAAA,QACX;AAAA,QACA,WAAW,MAAM;AACf,uBAAa,OAAO,QAAQ;AAC5B,sBAAY,QAAQ;AAAA,QACtB,GAAG,WAAW;AAAA,MAChB;AAAA,IACF;AAEA,YAAQ,MAAM,CAAC,OAAO,aAAa;AACjC,UAAI,UAAU,UAAU;AACtB,cAAM,MAAMC,SAAQ,QAAQ,EAAE,YAAY;AAC1C,YAAI,CAAC,oBAAoB,IAAI,GAAG,EAAG;AAEnC,cAAM,eAAeF,UAAS,KAAK,aAAa,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAC5E,eAAO,OAAO,YAAY;AAC1B,gBAAQ,iBAAiB,YAAY;AACrC,gBAAQ,MAAM,8BAA8B,YAAY,EAAE;AAAA,MAC5D,OAAO;AACL,yBAAiB,QAAQ;AAAA,MAC3B;AAAA,IACF,CAAC;AAED,YAAQ,MAAM,sDAAsD;AAEpE,UAAM,UAAU,MAAM;AACpB,cAAQ,MAAM,8BAA8B;AAC5C,iBAAW,WAAW,aAAa,OAAO,GAAG;AAC3C,qBAAa,OAAO;AAAA,MACtB;AACA,cAAQ,KAAK,EAAE,KAAK,MAAM;AACxB,gBAAQ,MAAM;AACd,gBAAQ,MAAM,wBAAwB;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB,CAAC;AAAA,IACH;AAEA,YAAQ,GAAG,UAAU,OAAO;AAC5B,YAAQ,GAAG,WAAW,OAAO;AAAA,EAC/B;AAAA,EAEQ,2BAA2B,UAAyC;AAC1E,QAAI;AAEF,YAAM,EAAE,WAAAG,WAAU,IAAI;AACtB,eAAS,SAAS,IAAIA,WAAU,CAAC;AAAA,IACnC,QAAQ;AACN,cAAQ,MAAM,8DAA8D;AAAA,IAC9E;AACA,QAAI;AAEF,YAAM,EAAE,eAAAC,eAAc,IAAI;AAC1B,eAAS,SAAS,IAAIA,eAAc,CAAC;AAAA,IACvC,QAAQ;AACN,cAAQ,MAAM,mEAAmE;AAAA,IACnF;AAAA,EACF;AACF;;;AE9IA,SAAS,QAAAC,cAAY;AACrB,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,OAAO,eAAe;AAKf,IAAM,eAAN,MAAmB;AAAA,EACP;AAAA,EAEjB,YAAY,aAAqB;AAC/B,SAAK,WAAWC,OAAK,aAAa,OAAO;AAAA,EAC3C;AAAA,EAEA,MAAM,IAAI,SAA4E;AAEpF,QAAI,CAAC,KAAK,eAAe,GAAG;AAC1B,cAAQ,MAAM,0DAA0D;AACxE;AAAA,IACF;AAEA,UAAM,SAASA,OAAK,KAAK,UAAU,UAAU,YAAY;AACzD,QAAI,CAACC,YAAW,MAAM,GAAG;AACvB,UAAI,QAAQ,MAAM;AAChB,gBAAQ,OAAO,MAAM,KAAK,UAAU,KAAK,YAAY,QAAQ,IAAI,CAAC,IAAI,IAAI;AAAA,MAC5E,OAAO;AACL,gBAAQ,MAAM,wEAAwE;AAAA,MACxF;AACA;AAAA,IACF;AAGA,UAAM,MAAM,MAAM,UAAU;AAC5B,UAAM,SAASC,cAAa,MAAM;AAClC,UAAM,KAAK,IAAI,IAAI,SAAS,MAAM;AAClC,UAAM,WAAW,IAAI,uBAAuB,EAAE;AAE9C,QAAI;AACF,UAAI,QAAQ,OAAO;AACjB,iBAAS,MAAM;AAEf,cAAM,OAAO,GAAG,OAAO;AACvB,cAAM,EAAE,eAAAC,eAAc,IAAI,MAAM,OAAO,IAAS;AAChD,QAAAA,eAAc,QAAQ,OAAO,KAAK,IAAI,CAAC;AACvC,gBAAQ,MAAM,8BAA8B;AAC5C;AAAA,MACF;AAGA,UAAI,QAAQ,QAAQ,MAAM;AACxB,YAAI,CAAC,OAAO,UAAU,QAAQ,IAAI,KAAK,QAAQ,QAAQ,GAAG;AACxD,kBAAQ,MAAM,0CAA0C;AACxD,kBAAQ,KAAK,CAAC;AACd;AAAA,QACF;AAAA,MACF;AAEA,YAAM,QAAQ,SAAS,WAAW,QAAQ,IAAI;AAE9C,UAAI,MAAM,eAAe,GAAG;AAC1B,YAAI,QAAQ,MAAM;AAChB,kBAAQ,OAAO,MAAM,KAAK,UAAU,KAAK,YAAY,QAAQ,IAAI,CAAC,IAAI,IAAI;AAAA,QAC5E,OAAO;AACL,kBAAQ,MAAM,wEAAwE;AAAA,QACxF;AACA;AAAA,MACF;AAEA,UAAI,QAAQ,MAAM;AAChB,gBAAQ,OAAO,MAAM,KAAK,UAAU,KAAK,YAAY,OAAO,QAAQ,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI;AAAA,MAC5F,OAAO;AACL,aAAK,mBAAmB,OAAO,QAAQ,IAAI;AAAA,MAC7C;AAAA,IACF,UAAE;AACA,SAAG,MAAM;AAAA,IACX;AAAA,EACF;AAAA,EAEQ,iBAA0B;AAChC,UAAM,aAAaH,OAAK,KAAK,UAAU,aAAa;AACpD,QAAI,CAACC,YAAW,UAAU,EAAG,QAAO;AAEpC,QAAI;AACF,YAAM,MAAMC,cAAa,YAAY,OAAO;AAC5C,YAAM,QAAQ,IAAI,MAAM,uCAAuC;AAC/D,UAAI,MAAO,QAAO,MAAM,CAAC,MAAM;AAC/B,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,YAAY,OAAwB,MAA4B;AACtE,UAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,UAAM,OAAO,QAAQ,OACjB,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAQ,EAAE,YAAY,IACnD;AAEJ,WAAO;AAAA,MACL,WAAW,EAAE,MAAM,IAAI,KAAK,YAAY,QAAQ,KAAK;AAAA,MACrD,SAAS;AAAA,QACP,YAAY,MAAM;AAAA,QAClB,mBAAmB,MAAM;AAAA,MAC3B;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,YAAY,MAAM;AAAA,MAClB,yBAAyB,MAAM,wBAAwB,IAAI,CAAC,OAAO;AAAA,QACjE,OAAO,EAAE;AAAA,QACT,OAAO,EAAE;AAAA,QACT,YAAY,EAAE;AAAA,MAChB,EAAE;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,YAAY,MAA4B;AAC9C,WAAO,KAAK,YAAY;AAAA,MACtB,YAAY;AAAA,MACZ,mBAAmB;AAAA,MACnB,UAAU,CAAC;AAAA,MACX,YAAY,CAAC;AAAA,MACb,yBAAyB,CAAC;AAAA,IAC5B,GAAG,IAAI;AAAA,EACT;AAAA,EAEQ,mBAAmB,OAAwB,MAAqB;AACtE,UAAM,SAAS,QAAQ,OAAO,QAAQ,IAAI,UAAU;AAEpD,YAAQ,MAAM,EAAE;AAChB,YAAQ,MAAM,oBAAoB,MAAM,GAAG;AAC3C,YAAQ,MAAM,oPAA4C;AAC1D,YAAQ,MAAM,4BAA4B,KAAK,aAAa,MAAM,UAAU,CAAC,EAAE;AAC/E,YAAQ,MAAM,4BAA4B,KAAK,aAAa,MAAM,iBAAiB,CAAC,EAAE;AAEtF,QAAI,MAAM,SAAS,SAAS,GAAG;AAC7B,cAAQ,MAAM,EAAE;AAChB,cAAQ,MAAM,aAAa;AAC3B,cAAQ,MAAM,oPAA4C;AAC1D,iBAAW,KAAK,MAAM,UAAU;AAC9B,cAAM,OAAO,EAAE,KAAK,OAAO,EAAE;AAC7B,cAAM,QAAQ,GAAG,KAAK,aAAa,EAAE,KAAK,CAAC,SAAS,OAAO,EAAE;AAC7D,gBAAQ,MAAM,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK,aAAa,EAAE,SAAS,CAAC,SAAS;AAAA,MAC/E;AAAA,IACF;AAEA,QAAI,MAAM,WAAW,SAAS,GAAG;AAC/B,cAAQ,MAAM,EAAE;AAChB,cAAQ,MAAM,uBAAuB;AACrC,cAAQ,MAAM,oPAA4C;AAC1D,iBAAW,KAAK,MAAM,YAAY;AAChC,cAAM,OAAO,EAAE,KAAK,OAAO,EAAE;AAC7B,gBAAQ,MAAM,KAAK,IAAI,GAAG,KAAK,aAAa,EAAE,OAAO,CAAC,UAAU;AAAA,MAClE;AAAA,IACF;AAEA,QAAI,MAAM,wBAAwB,SAAS,GAAG;AAC5C,cAAQ,MAAM,EAAE;AAChB,cAAQ,MAAM,6BAA6B;AAC3C,cAAQ,MAAM,oPAA4C;AAC1D,iBAAW,KAAK,MAAM,yBAAyB;AAC7C,cAAM,MAAM,KAAK,UAAU,EAAE,UAAU;AACvC,cAAM,MAAM,GAAG,EAAE,UAAU,IAAI,SAAS,CAAC;AACzC,gBAAQ,MAAM,KAAK,EAAE,KAAK,KAAK,GAAG,KAAK,GAAG,EAAE;AAAA,MAC9C;AAAA,IACF;AAEA,YAAQ,MAAM,EAAE;AAAA,EAClB;AAAA,EAEQ,UAAU,YAA4B;AAC5C,UAAM,SAAS,KAAK,MAAM,aAAa,EAAE;AACzC,UAAM,QAAQ,KAAK;AACnB,WAAO,SAAI,OAAO,MAAM,IAAI,SAAI,OAAO,KAAK;AAAA,EAC9C;AAAA,EAEQ,aAAa,GAAmB;AACtC,WAAO,EAAE,eAAe,OAAO;AAAA,EACjC;AAAA,EAEQ,aAAa,GAAmB;AACtC,QAAI,KAAK,IAAW,QAAO,IAAI,IAAI,KAAW,QAAQ,CAAC,CAAC;AACxD,QAAI,KAAK,IAAO,QAAO,IAAI,IAAI,KAAO,QAAQ,CAAC,CAAC;AAChD,WAAO,OAAO,CAAC;AAAA,EACjB;AACF;;;AC/KO,IAAM,YAAN,MAAgB;AAAA,EACJ;AAAA,EAEjB,YAAY,aAAqB;AAC/B,SAAK,cAAc;AAAA,EACrB;AAAA,EAEA,MAAM,MAAM,MAA+B;AACzC,UAAM,UAAU,KAAK,CAAC;AAEtB,QAAI,CAAC,WAAW,YAAY,YAAY,YAAY,MAAM;AACxD,WAAK,UAAU;AACf;AAAA,IACF;AAEA,YAAQ,SAAS;AAAA,MACf,KAAK,SAAS;AACZ,cAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,cAAM,UAAU,YAAY,KAAK,KAAK,UAAU,CAAC,IAAI;AACrD,YAAI,YAAY,OAAO,CAAC,WAAW,QAAQ,WAAW,IAAI,IAAI;AAC5D,kBAAQ,MAAM,wCAAwC;AACtD,kBAAQ,KAAK,CAAC;AACd;AAAA,QACF;AACA,cAAM,WAAW,KAAK,SAAS,SAAS;AACxC,cAAM,cAAc,KAAK,SAAS,gBAAgB;AAClD,cAAM,gBAAgB,KAAK,QAAQ,eAAe;AAClD,cAAM,gBAAgB,kBAAkB,KAAK,OAAO,KAAK,gBAAgB,CAAC,CAAC,IAAI;AAC/E,YAAI,kBAAkB,OAAO,CAAC,iBAAiB,MAAM,aAAa,KAAK,gBAAgB,IAAI;AACzF,kBAAQ,MAAM,kDAAkD;AAChE,kBAAQ,KAAK,CAAC;AACd;AAAA,QACF;AACA,cAAM,IAAI,aAAa,KAAK,WAAW,EAAE,IAAI,EAAE,MAAM,SAAS,OAAO,UAAU,aAAa,YAAY,cAAc,CAAC;AACvH;AAAA,MACF;AAAA,MAEA,KAAK;AACH,cAAM,IAAI,YAAY,KAAK,WAAW,EAAE,IAAI;AAC5C;AAAA,MAEF,KAAK;AACH,cAAM,IAAI,aAAa,KAAK,WAAW,EAAE,IAAI;AAC7C;AAAA,MAEF,KAAK;AACH,cAAM,IAAI,cAAc,KAAK,WAAW,EAAE,IAAI;AAC9C;AAAA,MAEF,KAAK;AACH,YAAI,cAAc,KAAK,WAAW,EAAE,IAAI;AACxC;AAAA,MAEF,KAAK;AACH,YAAI,YAAY,KAAK,WAAW,EAAE,IAAI;AACtC;AAAA,MAEF,KAAK,SAAS;AACZ,cAAM,UAAU,KAAK,QAAQ,QAAQ;AACrC,cAAM,UAAU,YAAY,KAAK,OAAO,KAAK,UAAU,CAAC,CAAC,IAAI;AAC7D,cAAM,UAAU,KAAK,SAAS,QAAQ;AACtC,cAAM,WAAW,KAAK,SAAS,SAAS;AACxC,cAAM,IAAI,aAAa,KAAK,WAAW,EAAE,IAAI,EAAE,MAAM,SAAS,MAAM,SAAS,OAAO,SAAS,CAAC;AAC9F;AAAA,MACF;AAAA,MAEA;AACE,gBAAQ,MAAM,4BAA4B,OAAO,iCAAiC;AAClF,gBAAQ,KAAK,CAAC;AACd;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,YAAkB;AACxB,YAAQ,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAahB,KAAK,CAAC;AAAA,EACN;AACF;","names":["extname","readFileSync","writeFileSync","existsSync","join","extname","kind","extname","dirname","join","writeFileSync","existsSync","mkdirSync","join","dirname","join","readFileSync","GoAdapter","CSharpAdapter","existsSync","extname","writeFileSync","join","join","join","existsSync","execFileSync","join","existsSync","execFileSync","join","join","join","existsSync","readFileSync","writeFileSync","mkdirSync","join","extname","relative","readFileSync","join","relative","readFileSync","extname","GoAdapter","CSharpAdapter","join","existsSync","readFileSync","join","existsSync","readFileSync","writeFileSync"]}
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  RevertDetector,
4
+ SessionRecorderAdapter,
4
5
  SimpleGitAdapter,
5
6
  SqliteStorageAdapter,
6
7
  createLogger,
7
8
  loadCoChangeMap
8
- } from "./chunk-BMB6SQIR.js";
9
+ } from "./chunk-WZKXGKKI.js";
9
10
  import {
10
11
  DetailLevelSchema,
11
12
  JsonIndexReader
@@ -2849,6 +2850,52 @@ function handleGetPrImpact(storage, git, masking, staleness, ctxoRoot = ".ctxo")
2849
2850
  };
2850
2851
  }
2851
2852
 
2853
+ // src/adapters/stats/with-recording.ts
2854
+ function withRecording(toolName, handler, recorder) {
2855
+ if (!recorder) return handler;
2856
+ return (args) => {
2857
+ const start = performance.now();
2858
+ const resultOrPromise = handler(args);
2859
+ if (resultOrPromise instanceof Promise) {
2860
+ return resultOrPromise.then((result) => {
2861
+ recordEvent(toolName, args, result, performance.now() - start, recorder);
2862
+ return result;
2863
+ });
2864
+ }
2865
+ const latencyMs = performance.now() - start;
2866
+ recordEvent(toolName, args, resultOrPromise, latencyMs, recorder);
2867
+ return resultOrPromise;
2868
+ };
2869
+ }
2870
+ function recordEvent(toolName, args, result, latencyMs, recorder) {
2871
+ try {
2872
+ const responseText = result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
2873
+ let truncated = false;
2874
+ try {
2875
+ const parsed = JSON.parse(responseText);
2876
+ truncated = parsed?._meta?.truncated ?? false;
2877
+ } catch {
2878
+ }
2879
+ const responseBytes = Buffer.byteLength(responseText, "utf-8");
2880
+ const rawLevel = args["level"];
2881
+ let detailLevel = null;
2882
+ if (typeof rawLevel === "number" && rawLevel >= 1 && rawLevel <= 4) {
2883
+ detailLevel = `L${rawLevel}`;
2884
+ }
2885
+ const event = {
2886
+ tool: toolName,
2887
+ symbolId: typeof args["symbolId"] === "string" ? args["symbolId"] : null,
2888
+ detailLevel,
2889
+ responseTokens: Math.ceil(responseBytes / 4),
2890
+ responseBytes,
2891
+ latencyMs,
2892
+ truncated
2893
+ };
2894
+ recorder.record(event);
2895
+ } catch {
2896
+ }
2897
+ }
2898
+
2852
2899
  // src/index.ts
2853
2900
  var log4 = createLogger("ctxo:mcp");
2854
2901
  function loadMaskingConfig(ctxoRoot) {
@@ -2865,11 +2912,23 @@ function loadMaskingConfig(ctxoRoot) {
2865
2912
  }
2866
2913
  return new MaskingPipeline();
2867
2914
  }
2915
+ function readStatsEnabled(ctxoRoot) {
2916
+ const configPath = join2(ctxoRoot, "config.yaml");
2917
+ if (!existsSync2(configPath)) return true;
2918
+ try {
2919
+ const raw = readFileSync2(configPath, "utf-8");
2920
+ const match = raw.match(/stats:\s*\n\s*enabled:\s*(true|false)/);
2921
+ if (match) return match[1] !== "false";
2922
+ return true;
2923
+ } catch {
2924
+ return true;
2925
+ }
2926
+ }
2868
2927
  async function main() {
2869
2928
  const args = process.argv.slice(2);
2870
2929
  const httpPortStr = process.env.CTXO_HTTP_PORT || (args.includes("--http") ? args[args.indexOf("--port") + 1] || "3001" : null);
2871
2930
  if (!httpPortStr && args.length > 0) {
2872
- const { CliRouter } = await import("./cli-router-Z5CSD6QN.js");
2931
+ const { CliRouter } = await import("./cli-router-H557TJAM.js");
2873
2932
  const router = new CliRouter(process.cwd());
2874
2933
  await router.route(args);
2875
2934
  return;
@@ -2879,14 +2938,15 @@ async function main() {
2879
2938
  await storage.init();
2880
2939
  const masking = loadMaskingConfig(ctxoRoot);
2881
2940
  const git = new SimpleGitAdapter(process.cwd());
2941
+ const recorder = readStatsEnabled(ctxoRoot) ? new SessionRecorderAdapter(storage.getDb(), () => storage.persist()) : null;
2882
2942
  const server = new McpServer({ name: "ctxo", version: "0.1.0" });
2883
2943
  const { StalenessDetector } = await import("./staleness-detector-VSDPTPX7.js");
2884
2944
  const staleness = new StalenessDetector(process.cwd(), ctxoRoot);
2885
- registerTools(server, storage, masking, git, staleness, ctxoRoot);
2945
+ registerTools(server, storage, masking, git, staleness, recorder, ctxoRoot);
2886
2946
  if (httpPortStr) {
2887
2947
  await startHttpTransport(async () => {
2888
2948
  const s = new McpServer({ name: "ctxo", version: "0.1.0" });
2889
- registerTools(s, storage, masking, git, staleness, ctxoRoot);
2949
+ registerTools(s, storage, masking, git, staleness, recorder, ctxoRoot);
2890
2950
  return s;
2891
2951
  }, parseInt(httpPortStr, 10));
2892
2952
  } else {
@@ -2894,16 +2954,16 @@ async function main() {
2894
2954
  await server.connect(transport);
2895
2955
  }
2896
2956
  }
2897
- function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ctxo") {
2957
+ function registerTools(server, storage, masking, git, staleness, recorder, ctxoRoot = ".ctxo") {
2898
2958
  const toolAnnotations = {
2899
2959
  readOnlyHint: true,
2900
2960
  destructiveHint: false,
2901
2961
  idempotentHint: true,
2902
2962
  openWorldHint: false
2903
2963
  };
2904
- const logicSliceHandler = handleGetLogicSlice(storage, masking, staleness, ctxoRoot);
2905
- const whyContextHandler = handleGetWhyContext(storage, git, masking, staleness, ctxoRoot);
2906
- const changeIntelligenceHandler = handleGetChangeIntelligence(storage, git, masking, staleness, ctxoRoot);
2964
+ const logicSliceHandler = withRecording("get_logic_slice", handleGetLogicSlice(storage, masking, staleness, ctxoRoot), recorder);
2965
+ const whyContextHandler = withRecording("get_why_context", handleGetWhyContext(storage, git, masking, staleness, ctxoRoot), recorder);
2966
+ const changeIntelligenceHandler = withRecording("get_change_intelligence", handleGetChangeIntelligence(storage, git, masking, staleness, ctxoRoot), recorder);
2907
2967
  server.registerTool(
2908
2968
  "get_logic_slice",
2909
2969
  {
@@ -2941,7 +3001,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
2941
3001
  },
2942
3002
  (args) => changeIntelligenceHandler(args)
2943
3003
  );
2944
- const blastRadiusHandler = handleGetBlastRadius(storage, masking, staleness, ctxoRoot);
3004
+ const blastRadiusHandler = withRecording("get_blast_radius", handleGetBlastRadius(storage, masking, staleness, ctxoRoot), recorder);
2945
3005
  server.registerTool(
2946
3006
  "get_blast_radius",
2947
3007
  {
@@ -2955,7 +3015,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
2955
3015
  },
2956
3016
  (args) => blastRadiusHandler(args)
2957
3017
  );
2958
- const overlayHandler = handleGetArchitecturalOverlay(storage, masking, staleness);
3018
+ const overlayHandler = withRecording("get_architectural_overlay", handleGetArchitecturalOverlay(storage, masking, staleness), recorder);
2959
3019
  server.registerTool(
2960
3020
  "get_architectural_overlay",
2961
3021
  {
@@ -2967,7 +3027,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
2967
3027
  },
2968
3028
  (args) => overlayHandler(args)
2969
3029
  );
2970
- const deadCodeHandler = handleFindDeadCode(storage, masking, staleness, ctxoRoot);
3030
+ const deadCodeHandler = withRecording("find_dead_code", handleFindDeadCode(storage, masking, staleness, ctxoRoot), recorder);
2971
3031
  server.registerTool(
2972
3032
  "find_dead_code",
2973
3033
  {
@@ -2980,7 +3040,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
2980
3040
  },
2981
3041
  (args) => deadCodeHandler(args)
2982
3042
  );
2983
- const contextForTaskHandler = handleGetContextForTask(storage, masking, staleness, ctxoRoot);
3043
+ const contextForTaskHandler = withRecording("get_context_for_task", handleGetContextForTask(storage, masking, staleness, ctxoRoot), recorder);
2984
3044
  server.registerTool(
2985
3045
  "get_context_for_task",
2986
3046
  {
@@ -2994,7 +3054,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
2994
3054
  },
2995
3055
  (args) => contextForTaskHandler(args)
2996
3056
  );
2997
- const rankedContextHandler = handleGetRankedContext(storage, masking, staleness, ctxoRoot);
3057
+ const rankedContextHandler = withRecording("get_ranked_context", handleGetRankedContext(storage, masking, staleness, ctxoRoot), recorder);
2998
3058
  server.registerTool(
2999
3059
  "get_ranked_context",
3000
3060
  {
@@ -3008,7 +3068,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
3008
3068
  },
3009
3069
  (args) => rankedContextHandler(args)
3010
3070
  );
3011
- const searchSymbolsHandler = handleSearchSymbols(storage, masking, staleness, ctxoRoot);
3071
+ const searchSymbolsHandler = withRecording("search_symbols", handleSearchSymbols(storage, masking, staleness, ctxoRoot), recorder);
3012
3072
  server.registerTool(
3013
3073
  "search_symbols",
3014
3074
  {
@@ -3023,7 +3083,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
3023
3083
  },
3024
3084
  (args) => searchSymbolsHandler(args)
3025
3085
  );
3026
- const changedSymbolsHandler = handleGetChangedSymbols(storage, git, masking, staleness, ctxoRoot);
3086
+ const changedSymbolsHandler = withRecording("get_changed_symbols", handleGetChangedSymbols(storage, git, masking, staleness, ctxoRoot), recorder);
3027
3087
  server.registerTool(
3028
3088
  "get_changed_symbols",
3029
3089
  {
@@ -3036,7 +3096,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
3036
3096
  },
3037
3097
  (args) => changedSymbolsHandler(args)
3038
3098
  );
3039
- const findImportersHandler = handleFindImporters(storage, masking, staleness, ctxoRoot);
3099
+ const findImportersHandler = withRecording("find_importers", handleFindImporters(storage, masking, staleness, ctxoRoot), recorder);
3040
3100
  server.registerTool(
3041
3101
  "find_importers",
3042
3102
  {
@@ -3052,7 +3112,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
3052
3112
  },
3053
3113
  (args) => findImportersHandler(args)
3054
3114
  );
3055
- const classHierarchyHandler = handleGetClassHierarchy(storage, masking, staleness, ctxoRoot);
3115
+ const classHierarchyHandler = withRecording("get_class_hierarchy", handleGetClassHierarchy(storage, masking, staleness, ctxoRoot), recorder);
3056
3116
  server.registerTool(
3057
3117
  "get_class_hierarchy",
3058
3118
  {
@@ -3065,7 +3125,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
3065
3125
  },
3066
3126
  (args) => classHierarchyHandler(args)
3067
3127
  );
3068
- const symbolImportanceHandler = handleGetSymbolImportance(storage, masking, staleness, ctxoRoot);
3128
+ const symbolImportanceHandler = withRecording("get_symbol_importance", handleGetSymbolImportance(storage, masking, staleness, ctxoRoot), recorder);
3069
3129
  server.registerTool(
3070
3130
  "get_symbol_importance",
3071
3131
  {
@@ -3080,7 +3140,7 @@ function registerTools(server, storage, masking, git, staleness, ctxoRoot = ".ct
3080
3140
  },
3081
3141
  (args) => symbolImportanceHandler(args)
3082
3142
  );
3083
- const prImpactHandler = handleGetPrImpact(storage, git, masking, staleness, ctxoRoot);
3143
+ const prImpactHandler = withRecording("get_pr_impact", handleGetPrImpact(storage, git, masking, staleness, ctxoRoot), recorder);
3084
3144
  server.registerTool(
3085
3145
  "get_pr_impact",
3086
3146
  {