@caoguo/maplibre-ai 0.0.2 → 0.0.4

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/debug/aiDebug.ts","../src/stylegen/styleGenerator.ts"],"names":["r","g","b"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * AI Debug 工具(PRD phase-3 §7)\n *\n * 功能点:\n * - AD-1 性能 Profiler 分析:分析渲染瓶颈\n * - AD-2 瓦片加载监控:实时显示瓦片请求/命中率/加载时间\n * - AD-3 内存泄漏检测:监控 GeoJSON/瓦片资源内存占用趋势\n * - AD-4 优化建议引擎:基于规则匹配常见问题\n *\n * 全部为纯函数,输入指标快照,输出诊断报告。\n */\n\n// ============================================================\n// 一、性能 Profiler 指标\n// ============================================================\nexport interface ProfilerMetrics {\n /** 帧率(fps) */\n fps?: number;\n /** Draw call 数量 */\n drawCalls?: number;\n /** 活动图层数 */\n activeLayers?: number;\n /** 主线程长任务数(>50ms) */\n longTasks?: number;\n /** 渲染耗时(ms) */\n renderTimeMs?: number;\n}\n\nexport interface ProfilerIssue {\n severity: 'info' | 'warning' | 'error';\n title: string;\n detail: string;\n suggestion: string;\n}\n\n/**\n * AD-1 性能 Profiler 分析\n */\nexport function analyzePerformance(m: ProfilerMetrics): ProfilerIssue[] {\n const issues: ProfilerIssue[] = [];\n\n if (m.fps !== undefined && m.fps < 30) {\n issues.push({\n severity: 'error',\n title: '帧率过低',\n detail: `当前 FPS=${m.fps},低于流畅阈值 30`,\n suggestion: '减少图层数量、启用 LOD 按需加载、降低数据密度',\n });\n } else if (m.fps !== undefined && m.fps < 60) {\n issues.push({\n severity: 'warning',\n title: '帧率偏低',\n detail: `当前 FPS=${m.fps},未达满帧`,\n suggestion: '检查是否有频繁 setData 或 re-render',\n });\n }\n\n if (m.drawCalls !== undefined && m.drawCalls > 100) {\n issues.push({\n severity: 'warning',\n title: 'Draw call 数量异常',\n detail: `Draw calls=${m.drawCalls}`,\n suggestion: '合并图层,减少 paint 属性复杂度(PRD §7.2 Shader 过复杂)',\n });\n }\n\n if (m.activeLayers !== undefined && m.activeLayers > 50) {\n issues.push({\n severity: 'warning',\n title: '活动图层过多',\n detail: `活动图层=${m.activeLayers}`,\n suggestion: '合并同类图层,减少图层数量',\n });\n }\n\n if (m.longTasks !== undefined && m.longTasks > 5) {\n issues.push({\n severity: 'warning',\n title: '主线程长任务过多',\n detail: `长任务数=${m.longTasks}`,\n suggestion: '检查静态数据是否意外触发 re-render(PRD §7.2 频繁重绘)',\n });\n }\n\n return issues;\n}\n\n// ============================================================\n// 二、瓦片加载监控(AD-2)\n// ============================================================\nexport interface TileMetrics {\n /** 已请求瓦片数 */\n requested: number;\n /** 命中缓存数 */\n cached: number;\n /** 总加载时间(ms) */\n totalLoadMs: number;\n}\n\nexport interface TileMonitorReport {\n /** 缓存命中率 */\n hitRate: number;\n /** 平均加载时间 */\n avgLoadMs: number;\n /** 是否瓦片过载 */\n overloaded: boolean;\n}\n\n/**\n * AD-2 瓦片加载监控\n */\nexport function analyzeTiles(m: TileMetrics, overloadThreshold = 200): TileMonitorReport {\n const hitRate = m.requested > 0 ? m.cached / m.requested : 0;\n const avgLoadMs = m.requested > 0 ? m.totalLoadMs / m.requested : 0;\n return {\n hitRate,\n avgLoadMs,\n overloaded: m.requested > overloadThreshold,\n };\n}\n\n// ============================================================\n// 三、内存泄漏检测(AD-3)\n// ============================================================\nexport interface MemorySnapshot {\n /** 时间戳 */\n timestamp: number;\n /** 占用字节 */\n bytes: number;\n}\n\nexport interface MemoryLeakReport {\n /** 是否疑似泄漏 */\n suspectedLeak: boolean;\n /** 增长率(bytes/ms) */\n growthRate: number;\n /** 快照数 */\n snapshotCount: number;\n}\n\n/**\n * AD-3 内存泄漏检测:分析内存占用趋势\n */\nexport function detectMemoryLeak(snapshots: MemorySnapshot[]): MemoryLeakReport {\n if (snapshots.length < 2) {\n return { suspectedLeak: false, growthRate: 0, snapshotCount: snapshots.length };\n }\n const sorted = [...snapshots].sort((a, b) => a.timestamp - b.timestamp);\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n const dt = last.timestamp - first.timestamp;\n const growthRate = dt > 0 ? (last.bytes - first.bytes) / dt : 0;\n\n // 持续增长 + 增长率 > 0 视为疑似泄漏\n let monotonic = true;\n for (let i = 1; i < sorted.length; i++) {\n if (sorted[i].bytes < sorted[i - 1].bytes) {\n monotonic = false;\n break;\n }\n }\n\n return {\n suspectedLeak: monotonic && growthRate > 0 && sorted.length >= 3,\n growthRate,\n snapshotCount: sorted.length,\n };\n}\n\n// ============================================================\n// 四、优化建议引擎(AD-4)\n// ============================================================\n/**\n * PRD §7.2 常见问题诊断规则\n */\nexport const DIAGNOSIS_RULES: Array<{\n id: string;\n /** 规则描述 */\n problem: string;\n /** 检测函数 */\n detect: (m: ProfilerMetrics & Partial<TileMetrics>) => boolean;\n /** 建议 */\n suggestion: string;\n}> = [\n {\n id: 'tile_overload',\n problem: '瓦片过载',\n detect: (m) => (m.requested ?? 0) > 200,\n suggestion: '增加 simplification tolerance',\n },\n {\n id: 'shader_complex',\n problem: 'Shader 过复杂',\n detect: (m) => (m.drawCalls ?? 0) > 100,\n suggestion: '合并图层,减少 paint 属性复杂度',\n },\n {\n id: 'frequent_rerender',\n problem: '频繁重绘',\n detect: (m) => (m.longTasks ?? 0) > 5,\n suggestion: '检查 data/source 是否意外更新',\n },\n {\n id: 'label_overlap',\n problem: '标注压盖',\n detect: (m) => (m.activeLayers ?? 0) > 50,\n suggestion: '启用文字避让或降低标注密度',\n },\n];\n\n/**\n * AD-4 优化建议引擎:运行规则匹配,返回命中的建议\n */\nexport function suggestOptimizations(\n m: ProfilerMetrics & Partial<TileMetrics>\n): Array<{ id: string; problem: string; suggestion: string }> {\n return DIAGNOSIS_RULES.filter((r) => r.detect(m)).map((r) => ({\n id: r.id,\n problem: r.problem,\n suggestion: r.suggestion,\n }));\n}\n\n/** 综合诊断(AD-1~AD-4 汇总) */\nexport interface DebugReport {\n perfIssues: ProfilerIssue[];\n tiles?: TileMonitorReport;\n memory?: MemoryLeakReport;\n suggestions: Array<{ id: string; problem: string; suggestion: string }>;\n}\n\nexport function diagnose(opts: {\n perf: ProfilerMetrics;\n tiles?: TileMetrics;\n memory?: MemorySnapshot[];\n}): DebugReport {\n const perfIssues = analyzePerformance(opts.perf);\n const suggestions = suggestOptimizations({\n ...opts.perf,\n ...(opts.tiles ?? {}),\n });\n return {\n perfIssues,\n tiles: opts.tiles ? analyzeTiles(opts.tiles) : undefined,\n memory: opts.memory ? detectMemoryLeak(opts.memory) : undefined,\n suggestions,\n };\n}\n","/**\n * 样式生成器 v2(PRD phase-3 §8)\n *\n * 功能点:\n * - SG-1 色板提取:上传图片 → 提取主色调 → 生成配色方案\n * - SG-2 风格模板:预置 6 套行业模板(管网/电网/水网/交通/算力/通信)\n * - SG-3 品牌定制:输入品牌色 → 自动生成全套地图样式\n * - SG-4 运营商主题:三大运营商预设主题 + 自定义\n * - SG-5 昼夜切换:一键切换亮色/暗色模式\n */\n\n/** 行业风格模板类型(六张网) */\nexport type IndustryStyle = 'pipeline' | 'grid' | 'water' | 'transport' | 'compute' | 'telecom';\n\n/** 配色方案 */\nexport interface ColorScheme {\n /** 主色 */\n primary: string;\n /** 辅助色 */\n secondary: string;\n /** 强调色 */\n accent: string;\n /** 背景色 */\n background: string;\n /** 名称 */\n name: string;\n}\n\n/** 生成的地图样式(简化 style.json 配色片段) */\nexport interface GeneratedMapStyle {\n scheme: ColorScheme;\n /** 线要素配色 */\n lineColor: string;\n /** 点要素配色 */\n pointColor: string;\n /** 面要素配色 */\n fillColor: string;\n /** 底图背景 */\n background: string;\n /** 模式 */\n mode: 'light' | 'dark';\n}\n\n// ============================================================\n// SG-2 风格模板:6 套行业模板\n// ============================================================\nexport const INDUSTRY_TEMPLATES: Record<IndustryStyle, ColorScheme> = {\n pipeline: { name: '管网', primary: '#f59e0b', secondary: '#3b82f6', accent: '#ef4444', background: '#0b1320' },\n grid: { name: '电网', primary: '#f59e0b', secondary: '#ef4444', accent: '#3b82f6', background: '#0b1320' },\n water: { name: '水网', primary: '#3b82f6', secondary: '#22d3ee', accent: '#4ade80', background: '#0b1320' },\n transport: { name: '交通', primary: '#f59e0b', secondary: '#ef4444', accent: '#22d3ee', background: '#0b1320' },\n compute: { name: '算力', primary: '#a78bfa', secondary: '#3b82f6', accent: '#4ade80', background: '#0b1320' },\n telecom: { name: '通信', primary: '#3b82f6', secondary: '#4ade80', accent: '#ef4444', background: '#0b1320' },\n};\n\n// ============================================================\n// SG-4 运营商主题\n// ============================================================\nexport const CARRIER_STYLES: Record<string, ColorScheme> = {\n '中国移动': { name: '中国移动', primary: '#4ade80', secondary: '#166534', accent: '#22c55e', background: '#0b1320' },\n '中国联通': { name: '中国联通', primary: '#ef4444', secondary: '#991b1b', accent: '#f87171', background: '#0b1320' },\n '中国电信': { name: '中国电信', primary: '#3b82f6', secondary: '#1e40af', accent: '#60a5fa', background: '#0b1320' },\n '中国广电': { name: '中国广电', primary: '#f59e0b', secondary: '#92400e', accent: '#fbbf24', background: '#0b1320' },\n};\n\n// ============================================================\n// SG-1 色板提取\n// ============================================================\n/**\n * 从图片像素数据提取主色调。\n * @param pixels RGBA 像素数组(每 4 个值一个像素)\n * @returns 主色 hex(出现频率最高的量化色)\n */\nexport function extractDominantColor(pixels: Uint8ClampedArray): string {\n if (pixels.length < 4) return '#000000';\n const bucket = new Map<string, number>();\n // 采样(每 4px 取一个,提升性能)\n for (let i = 0; i < pixels.length; i += 16) {\n const r = pixels[i];\n const g = pixels[i + 1];\n const b = pixels[i + 2];\n const a = pixels[i + 3];\n if (a === 0) continue;\n // 量化到 32 级\n const key = `${r >> 3},${g >> 3},${b >> 3}`;\n bucket.set(key, (bucket.get(key) ?? 0) + 1);\n }\n let bestKey = '';\n let bestCount = -1;\n for (const [k, c] of bucket) {\n if (c > bestCount) {\n bestCount = c;\n bestKey = k;\n }\n }\n if (!bestKey) return '#000000';\n // 还原量化桶中心值(每桶 8 级,中心偏移 +4)\n const [r, g, b] = bestKey.split(',').map((v) => (parseInt(v) << 3) + 4);\n return rgbToHex(r, g, b);\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => v.toString(16).padStart(2, '0')).join('');\n}\n\n/** 调整颜色亮度(用于生成辅助色) */\nexport function adjustBrightness(hex: string, factor: number): string {\n const { r, g, b } = hexToRgb(hex);\n const nr = clamp(Math.round(r * factor));\n const ng = clamp(Math.round(g * factor));\n const nb = clamp(Math.round(b * factor));\n return rgbToHex(nr, ng, nb);\n}\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\n const h = hex.replace('#', '');\n return {\n r: parseInt(h.slice(0, 2), 16),\n g: parseInt(h.slice(2, 4), 16),\n b: parseInt(h.slice(4, 6), 16),\n };\n}\n\nfunction clamp(v: number): number {\n return Math.max(0, Math.min(255, v));\n}\n\n// ============================================================\n// SG-3 品牌定制:输入品牌色 → 生成全套样式\n// ============================================================\nexport interface BrandStyleOptions {\n /** 品牌主色(hex) */\n brandColor: string;\n /** 模式 */\n mode?: 'light' | 'dark';\n /** 名称 */\n name?: string;\n}\n\nexport function generateBrandStyle(opts: BrandStyleOptions): GeneratedMapStyle {\n const mode = opts.mode ?? 'dark';\n const primary = opts.brandColor;\n const secondary = adjustBrightness(primary, 0.6);\n const accent = adjustBrightness(primary, 1.4);\n const background = mode === 'dark' ? '#0b1320' : '#f8fafc';\n return {\n scheme: {\n name: opts.name ?? '自定义品牌',\n primary,\n secondary,\n accent,\n background,\n },\n lineColor: primary,\n pointColor: accent,\n fillColor: primary,\n background,\n mode,\n };\n}\n\n/** 从行业模板生成样式 */\nexport function generateIndustryStyle(industry: IndustryStyle, mode: 'light' | 'dark' = 'dark'): GeneratedMapStyle {\n const scheme = INDUSTRY_TEMPLATES[industry];\n const background = mode === 'dark' ? '#0b1320' : '#f8fafc';\n return {\n scheme: { ...scheme, background },\n lineColor: scheme.primary,\n pointColor: scheme.accent,\n fillColor: scheme.secondary,\n background,\n mode,\n };\n}\n\n/** 从运营商主题生成样式 */\nexport function generateCarrierStyle(carrier: string, mode: 'light' | 'dark' = 'dark'): GeneratedMapStyle {\n const scheme = CARRIER_STYLES[carrier] ?? CARRIER_STYLES['中国移动'];\n const background = mode === 'dark' ? '#0b1320' : '#f8fafc';\n return {\n scheme: { ...scheme, background },\n lineColor: scheme.primary,\n pointColor: scheme.accent,\n fillColor: scheme.secondary,\n background,\n mode,\n };\n}\n\n// ============================================================\n// SG-5 昼夜切换\n// ============================================================\nexport function toggleMode(style: GeneratedMapStyle): GeneratedMapStyle {\n const nextMode: 'light' | 'dark' = style.mode === 'dark' ? 'light' : 'dark';\n return {\n ...style,\n mode: nextMode,\n background: nextMode === 'dark' ? '#0b1320' : '#f8fafc',\n scheme: { ...style.scheme, background: nextMode === 'dark' ? '#0b1320' : '#f8fafc' },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/debug/aiDebug.ts","../src/stylegen/styleGenerator.ts","../src/copilot/copilot.ts","../src/copilot/llmCopilot.ts","../src/geoai/addressParser.ts","../src/geoai/headerDetector.ts","../src/geoai/crsDetector.ts","../src/geoai/geocoder.ts","../src/geoai/dataImporter.ts","../src/nlpg/sqlGenerator.ts","../src/nlpg/sqlValidator.ts","../src/nlpg/nlpg.ts","../src/nlpg/llmNlpg.ts","../src/llm/deepseek.ts"],"names":["r","g","b","code","SYSTEM_PROMPT"],"mappings":";;;AAsCO,SAAS,mBAAmB,CAAA,EAAqC;AACtE,EAAA,MAAM,SAA0B,EAAC;AAEjC,EAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,MAAA,IAAa,CAAA,CAAE,MAAM,EAAA,EAAI;AACrC,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,QAAA,EAAU,OAAA;AAAA,MACV,KAAA,EAAO,0BAAA;AAAA,MACP,MAAA,EAAQ,CAAA,iBAAA,EAAU,CAAA,CAAE,GAAG,CAAA,6CAAA,CAAA;AAAA,MACvB,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH,WAAW,CAAA,CAAE,GAAA,KAAQ,MAAA,IAAa,CAAA,CAAE,MAAM,EAAA,EAAI;AAC5C,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,QAAA,EAAU,SAAA;AAAA,MACV,KAAA,EAAO,0BAAA;AAAA,MACP,MAAA,EAAQ,CAAA,iBAAA,EAAU,CAAA,CAAE,GAAG,CAAA,8BAAA,CAAA;AAAA,MACvB,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,CAAA,CAAE,SAAA,KAAc,MAAA,IAAa,CAAA,CAAE,YAAY,GAAA,EAAK;AAClD,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,QAAA,EAAU,SAAA;AAAA,MACV,KAAA,EAAO,oCAAA;AAAA,MACP,MAAA,EAAQ,CAAA,WAAA,EAAc,CAAA,CAAE,SAAS,CAAA,CAAA;AAAA,MACjC,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,CAAA,CAAE,YAAA,KAAiB,MAAA,IAAa,CAAA,CAAE,eAAe,EAAA,EAAI;AACvD,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,QAAA,EAAU,SAAA;AAAA,MACV,KAAA,EAAO,sCAAA;AAAA,MACP,MAAA,EAAQ,CAAA,yBAAA,EAAQ,CAAA,CAAE,YAAY,CAAA,CAAA;AAAA,MAC9B,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,IAAI,CAAA,CAAE,SAAA,KAAc,MAAA,IAAa,CAAA,CAAE,YAAY,CAAA,EAAG;AAChD,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,QAAA,EAAU,SAAA;AAAA,MACV,KAAA,EAAO,kDAAA;AAAA,MACP,MAAA,EAAQ,CAAA,yBAAA,EAAQ,CAAA,CAAE,SAAS,CAAA,CAAA;AAAA,MAC3B,UAAA,EAAY;AAAA,KACb,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;AA0BO,SAAS,YAAA,CAAa,CAAA,EAAgB,iBAAA,GAAoB,GAAA,EAAwB;AACvF,EAAA,MAAM,UAAU,CAAA,CAAE,SAAA,GAAY,IAAI,CAAA,CAAE,MAAA,GAAS,EAAE,SAAA,GAAY,CAAA;AAC3D,EAAA,MAAM,YAAY,CAAA,CAAE,SAAA,GAAY,IAAI,CAAA,CAAE,WAAA,GAAc,EAAE,SAAA,GAAY,CAAA;AAClE,EAAA,OAAO;AAAA,IACL,OAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA,EAAY,EAAE,SAAA,GAAY;AAAA,GAC5B;AACF;AAwBO,SAAS,iBAAiB,SAAA,EAA+C;AAC9E,EAAA,IAAI,SAAA,CAAU,SAAS,CAAA,EAAG;AACxB,IAAA,OAAO,EAAE,aAAA,EAAe,KAAA,EAAO,YAAY,CAAA,EAAG,aAAA,EAAe,UAAU,MAAA,EAAO;AAAA,EAChF;AACA,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,SAAS,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,SAAA,GAAY,CAAA,CAAE,SAAS,CAAA;AACtE,EAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AACtB,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,MAAA,CAAO,MAAA,GAAS,CAAC,CAAA;AACrC,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,SAAA,GAAY,KAAA,CAAM,SAAA;AAClC,EAAA,MAAM,aAAa,EAAA,GAAK,CAAA,GAAA,CAAK,KAAK,KAAA,GAAQ,KAAA,CAAM,SAAS,EAAA,GAAK,CAAA;AAG9D,EAAA,IAAI,SAAA,GAAY,IAAA;AAChB,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACtC,IAAA,IAAI,MAAA,CAAO,CAAC,CAAA,CAAE,KAAA,GAAQ,OAAO,CAAA,GAAI,CAAC,EAAE,KAAA,EAAO;AACzC,MAAA,SAAA,GAAY,KAAA;AACZ,MAAA;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,SAAA,IAAa,UAAA,GAAa,CAAA,IAAK,OAAO,MAAA,IAAU,CAAA;AAAA,IAC/D,UAAA;AAAA,IACA,eAAe,MAAA,CAAO;AAAA,GACxB;AACF;AAQO,IAAM,eAAA,GAQR;AAAA,EACH;AAAA,IACE,EAAA,EAAI,eAAA;AAAA,IACJ,OAAA,EAAS,0BAAA;AAAA,IACT,MAAA,EAAQ,CAAC,CAAA,KAAA,CAAO,CAAA,CAAE,aAAa,CAAA,IAAK,GAAA;AAAA,IACpC,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,gBAAA;AAAA,IACJ,OAAA,EAAS,2BAAA;AAAA,IACT,MAAA,EAAQ,CAAC,CAAA,KAAA,CAAO,CAAA,CAAE,aAAa,CAAA,IAAK,GAAA;AAAA,IACpC,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,mBAAA;AAAA,IACJ,OAAA,EAAS,0BAAA;AAAA,IACT,MAAA,EAAQ,CAAC,CAAA,KAAA,CAAO,CAAA,CAAE,aAAa,CAAA,IAAK,CAAA;AAAA,IACpC,UAAA,EAAY;AAAA,GACd;AAAA,EACA;AAAA,IACE,EAAA,EAAI,eAAA;AAAA,IACJ,OAAA,EAAS,0BAAA;AAAA,IACT,MAAA,EAAQ,CAAC,CAAA,KAAA,CAAO,CAAA,CAAE,gBAAgB,CAAA,IAAK,EAAA;AAAA,IACvC,UAAA,EAAY;AAAA;AAEhB;AAKO,SAAS,qBACd,CAAA,EAC4D;AAC5D,EAAA,OAAO,eAAA,CAAgB,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,CAAO,CAAC,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,MAAO;AAAA,IAC5D,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,SAAS,CAAA,CAAE,OAAA;AAAA,IACX,YAAY,CAAA,CAAE;AAAA,GAChB,CAAE,CAAA;AACJ;AAUO,SAAS,SAAS,IAAA,EAIT;AACd,EAAA,MAAM,UAAA,GAAa,kBAAA,CAAmB,IAAA,CAAK,IAAI,CAAA;AAC/C,EAAA,MAAM,cAAc,oBAAA,CAAqB;AAAA,IACvC,GAAG,IAAA,CAAK,IAAA;AAAA,IACR,GAAI,IAAA,CAAK,KAAA,IAAS;AAAC,GACpB,CAAA;AACD,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,OAAO,IAAA,CAAK,KAAA,GAAQ,YAAA,CAAa,IAAA,CAAK,KAAK,CAAA,GAAI,MAAA;AAAA,IAC/C,QAAQ,IAAA,CAAK,MAAA,GAAS,gBAAA,CAAiB,IAAA,CAAK,MAAM,CAAA,GAAI,MAAA;AAAA,IACtD;AAAA,GACF;AACF;;;ACzMO,IAAM,kBAAA,GAAyD;AAAA,EACpE,QAAA,EAAU,EAAE,IAAA,EAAM,cAAA,EAAM,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EAC3G,IAAA,EAAM,EAAE,IAAA,EAAM,cAAA,EAAM,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EACvG,KAAA,EAAO,EAAE,IAAA,EAAM,cAAA,EAAM,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EACxG,SAAA,EAAW,EAAE,IAAA,EAAM,cAAA,EAAM,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EAC5G,OAAA,EAAS,EAAE,IAAA,EAAM,cAAA,EAAM,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EAC1G,OAAA,EAAS,EAAE,IAAA,EAAM,cAAA,EAAM,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA;AAClG;AAKO,IAAM,cAAA,GAA8C;AAAA,EACzD,0BAAA,EAAQ,EAAE,IAAA,EAAM,0BAAA,EAAQ,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EAC3G,0BAAA,EAAQ,EAAE,IAAA,EAAM,0BAAA,EAAQ,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EAC3G,0BAAA,EAAQ,EAAE,IAAA,EAAM,0BAAA,EAAQ,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA,EAAU;AAAA,EAC3G,0BAAA,EAAQ,EAAE,IAAA,EAAM,0BAAA,EAAQ,OAAA,EAAS,SAAA,EAAW,SAAA,EAAW,SAAA,EAAW,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,SAAA;AACnG;AAUO,SAAS,qBAAqB,MAAA,EAAmC;AACtE,EAAA,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,OAAO,SAAA;AAC9B,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAoB;AAEvC,EAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,MAAA,CAAO,MAAA,EAAQ,KAAK,EAAA,EAAI;AAC1C,IAAA,MAAMA,EAAAA,GAAI,OAAO,CAAC,CAAA;AAClB,IAAA,MAAMC,EAAAA,GAAI,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA;AACtB,IAAA,MAAMC,EAAAA,GAAI,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA;AACtB,IAAA,MAAM,CAAA,GAAI,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA;AACtB,IAAA,IAAI,MAAM,CAAA,EAAG;AAEb,IAAA,MAAM,GAAA,GAAM,GAAGF,EAAAA,IAAK,CAAC,IAAIC,EAAAA,IAAK,CAAC,CAAA,CAAA,EAAIC,EAAAA,IAAK,CAAC,CAAA,CAAA;AACzC,IAAA,MAAA,CAAO,IAAI,GAAA,EAAA,CAAM,MAAA,CAAO,IAAI,GAAG,CAAA,IAAK,KAAK,CAAC,CAAA;AAAA,EAC5C;AACA,EAAA,IAAI,OAAA,GAAU,EAAA;AACd,EAAA,IAAI,SAAA,GAAY,EAAA;AAChB,EAAA,KAAA,MAAW,CAAC,CAAA,EAAG,CAAC,CAAA,IAAK,MAAA,EAAQ;AAC3B,IAAA,IAAI,IAAI,SAAA,EAAW;AACjB,MAAA,SAAA,GAAY,CAAA;AACZ,MAAA,OAAA,GAAU,CAAA;AAAA,IACZ;AAAA,EACF;AACA,EAAA,IAAI,CAAC,SAAS,OAAO,SAAA;AAErB,EAAA,MAAM,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GAAI,QAAQ,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,KAAK,CAAC,CAAA;AACtE,EAAA,OAAO,QAAA,CAAS,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACzB;AAEA,SAAS,QAAA,CAAS,CAAA,EAAW,CAAA,EAAW,CAAA,EAAmB;AACzD,EAAA,OAAO,MAAM,CAAC,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,IAAI,CAAC,CAAA,KAAM,EAAE,QAAA,CAAS,EAAE,EAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,KAAK,EAAE,CAAA;AAC5E;AAGO,SAAS,gBAAA,CAAiB,KAAa,MAAA,EAAwB;AACpE,EAAA,MAAM,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE,GAAI,SAAS,GAAG,CAAA;AAChC,EAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,MAAM,CAAC,CAAA;AACvC,EAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,MAAM,CAAC,CAAA;AACvC,EAAA,MAAM,KAAK,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,MAAM,CAAC,CAAA;AACvC,EAAA,OAAO,QAAA,CAAS,EAAA,EAAI,EAAA,EAAI,EAAE,CAAA;AAC5B;AAEA,SAAS,SAAS,GAAA,EAAkD;AAClE,EAAA,MAAM,CAAA,GAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,EAAE,CAAA;AAC7B,EAAA,OAAO;AAAA,IACL,GAAG,QAAA,CAAS,CAAA,CAAE,MAAM,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAAA,IAC7B,GAAG,QAAA,CAAS,CAAA,CAAE,MAAM,CAAA,EAAG,CAAC,GAAG,EAAE,CAAA;AAAA,IAC7B,GAAG,QAAA,CAAS,CAAA,CAAE,MAAM,CAAA,EAAG,CAAC,GAAG,EAAE;AAAA,GAC/B;AACF;AAEA,SAAS,MAAM,CAAA,EAAmB;AAChC,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,GAAA,EAAK,CAAC,CAAC,CAAA;AACrC;AAcO,SAAS,mBAAmB,IAAA,EAA4C;AAC7E,EAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,MAAA;AAC1B,EAAA,MAAM,UAAU,IAAA,CAAK,UAAA;AACrB,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAC/C,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAA,EAAS,GAAG,CAAA;AAC5C,EAAA,MAAM,UAAA,GAAa,IAAA,KAAS,MAAA,GAAS,SAAA,GAAY,SAAA;AACjD,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ;AAAA,MACN,IAAA,EAAM,KAAK,IAAA,IAAQ,gCAAA;AAAA,MACnB,OAAA;AAAA,MACA,SAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA,SAAA,EAAW,OAAA;AAAA,IACX,UAAA,EAAY,MAAA;AAAA,IACZ,SAAA,EAAW,OAAA;AAAA,IACX,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAGO,SAAS,qBAAA,CAAsB,QAAA,EAAyB,IAAA,GAAyB,MAAA,EAA2B;AACjH,EAAA,MAAM,MAAA,GAAS,mBAAmB,QAAQ,CAAA;AAC1C,EAAA,MAAM,UAAA,GAAa,IAAA,KAAS,MAAA,GAAS,SAAA,GAAY,SAAA;AACjD,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,EAAE,GAAG,MAAA,EAAQ,UAAA,EAAW;AAAA,IAChC,WAAW,MAAA,CAAO,OAAA;AAAA,IAClB,YAAY,MAAA,CAAO,MAAA;AAAA,IACnB,WAAW,MAAA,CAAO,SAAA;AAAA,IAClB,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAGO,SAAS,oBAAA,CAAqB,OAAA,EAAiB,IAAA,GAAyB,MAAA,EAA2B;AACxG,EAAA,MAAM,MAAA,GAAS,cAAA,CAAe,OAAO,CAAA,IAAK,eAAe,0BAAM,CAAA;AAC/D,EAAA,MAAM,UAAA,GAAa,IAAA,KAAS,MAAA,GAAS,SAAA,GAAY,SAAA;AACjD,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,EAAE,GAAG,MAAA,EAAQ,UAAA,EAAW;AAAA,IAChC,WAAW,MAAA,CAAO,OAAA;AAAA,IAClB,YAAY,MAAA,CAAO,MAAA;AAAA,IACnB,WAAW,MAAA,CAAO,SAAA;AAAA,IAClB,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,SAAS,WAAW,KAAA,EAA6C;AACtE,EAAA,MAAM,QAAA,GAA6B,KAAA,CAAM,IAAA,KAAS,MAAA,GAAS,OAAA,GAAU,MAAA;AACrE,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,IAAA,EAAM,QAAA;AAAA,IACN,UAAA,EAAY,QAAA,KAAa,MAAA,GAAS,SAAA,GAAY,SAAA;AAAA,IAC9C,MAAA,EAAQ,EAAE,GAAG,KAAA,CAAM,QAAQ,UAAA,EAAY,QAAA,KAAa,MAAA,GAAS,SAAA,GAAY,SAAA;AAAU,GACrF;AACF;;;AC1IO,IAAM,iBAAA,GAAsD;AAAA,EACjE,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,KAAK,CAAA;AAAA,EACnB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,KAAK,CAAA;AAAA,EACnB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,MAAA,EAAQ,MAAM,CAAA;AAAA,EACnB,YAAA,EAAI,CAAC,KAAA,EAAO,MAAM;AACpB;AAGO,IAAM,WAAA,GAAsC;AAAA,EACjD,MAAA,EAAG,SAAA;AAAA,EACH,YAAA,EAAI,SAAA;AAAA,EACJ,MAAA,EAAG,SAAA;AAAA,EACH,YAAA,EAAI,SAAA;AAAA,EACJ,MAAA,EAAG,SAAA;AAAA,EACH,YAAA,EAAI,SAAA;AAAA,EACJ,MAAA,EAAG,SAAA;AAAA,EACH,YAAA,EAAI,SAAA;AAAA,EACJ,MAAA,EAAG,SAAA;AAAA,EACH,YAAA,EAAI,SAAA;AAAA,EACJ,MAAA,EAAG,SAAA;AAAA,EACH,MAAA,EAAG,SAAA;AAAA,EACH,YAAA,EAAI,SAAA;AAAA,EACJ,MAAA,EAAG,SAAA;AAAA,EACH,MAAA,EAAG,SAAA;AAAA,EACH,YAAA,EAAI,SAAA;AAAA,EACJ,YAAA,EAAI;AACN;AAGA,IAAM,eAAA,GAAoF;AAAA,EACxF,EAAE,MAAA,EAAQ,mBAAA,EAAqB,EAAA,EAAI,yCAAA,EAA2C,YAAY,IAAA,EAAK;AAAA,EAC/F,EAAE,MAAA,EAAQ,SAAA,EAAW,EAAA,EAAI,sBAAA,EAAwB,YAAY,GAAA,EAAI;AAAA,EACjE,EAAE,MAAA,EAAQ,kBAAA,EAAoB,EAAA,EAAI,qDAAA,EAAuD,YAAY,IAAA,EAAK;AAAA,EAC1G,EAAE,MAAA,EAAQ,YAAA,EAAc,EAAA,EAAI,0BAAA,EAA4B,YAAY,IAAA,EAAK;AAAA,EACzE,EAAE,MAAA,EAAQ,YAAA,EAAc,EAAA,EAAI,wBAAA,EAA0B,YAAY,GAAA;AACpE,CAAA;AAKO,SAAS,eAAe,KAAA,EAA8D;AAC3F,EAAA,IAAI,IAAA,GAAsD,EAAE,MAAA,EAAQ,SAAA,EAAW,YAAY,CAAA,EAAE;AAC7F,EAAA,KAAA,MAAW,KAAK,eAAA,EAAiB;AAC/B,IAAA,MAAM,CAAA,GAAI,KAAA,CAAM,KAAA,CAAM,CAAA,CAAE,EAAE,CAAA;AAC1B,IAAA,IAAI,CAAA,EAAG;AACL,MAAA,MAAM,CAAA,GAAI,CAAA,CAAE,UAAA,IAAc,CAAA,GAAI,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,CAAC,CAAA,CAAE,MAAA,GAAS,KAAA,CAAM,QAAQ,CAAC,CAAA,CAAA;AAC3E,MAAA,IAAI,CAAA,GAAI,IAAA,CAAK,UAAA,EAAY,IAAA,GAAO,EAAE,MAAA,EAAQ,CAAA,CAAE,MAAA,EAAQ,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAA,EAAE;AAAA,IACjF;AAAA,EACF;AACA,EAAA,OAAO,IAAA;AACT;AAKO,SAAS,aAAA,CAAc,OAAe,MAAA,EAAsC;AACjF,EAAA,MAAM,SAAwB,EAAC;AAG/B,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,EAAG;AAC7D,IAAA,IAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG;AACxB,MAAA,MAAA,CAAO,KAAA,GAAQ,IAAA;AACf,MAAA,MAAA,CAAO,MAAA,GAAS,KAAA;AAChB,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,iDAAiD,CAAA;AAC/E,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,SAAA,CAAU,CAAC,CAAA,IAAK,UAAU,CAAC,CAAA,IAAK,SAAA,CAAU,CAAC,CAAC,CAAA;AAC/D,IAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA,IAAK,KAAK,CAAA,IAAK,CAAA,IAAK,EAAA,EAAI,MAAA,CAAO,IAAA,GAAO,CAAA;AAAA,EAC3D;AAGA,EAAA,IAAI,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAA,SAAU,KAAA,GAAQ,aAAA;AAAA,OAAA,IAC1C,mBAAA,CAAoB,IAAA,CAAK,KAAK,CAAA,SAAU,KAAA,GAAQ,cAAA;AAGzD,EAAA,KAAA,MAAW,CAAC,IAAA,EAAM,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,WAAW,CAAA,EAAG;AACrD,IAAA,IAAI,KAAA,CAAM,QAAA,CAAS,IAAI,CAAA,EAAG;AACxB,MAAA,MAAA,CAAO,KAAA,GAAQ,GAAA;AACf,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,kCAAkC,CAAA;AAChE,EAAA,IAAI,WAAW,MAAA,CAAO,IAAA,GAAO,QAAA,CAAS,SAAA,CAAU,CAAC,CAAC,CAAA;AAGlD,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,KAAA,CAAM,oCAAoC,CAAA;AACnE,EAAA,IAAI,UAAA,EAAY,MAAA,CAAO,OAAA,GAAU,UAAA,CAAW,CAAC,CAAA;AAG7C,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,qBAAqB,CAAA;AACnD,EAAA,IAAI,SAAA,EAAW,MAAA,CAAO,IAAA,GAAO,SAAA,CAAU,CAAC,CAAA;AAExC,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,YAAA,CAAa,QAAuB,CAAA,EAA0B;AAC5E,EAAA,MAAM,MAAA,GAAS,CAAA,CAAE,MAAA,IAAU,CAAC,SAAS,MAAM,CAAA;AAC3C,EAAA,MAAM,IAAA,GAAO,EAAE,IAAA,IAAQ,EAAA;AACvB,EAAA,MAAM,KAAA,GAAQ,EAAE,KAAA,IAAS,aAAA;AACzB,EAAA,MAAM,KAAA,GAAQ,EAAE,KAAA,IAAS,SAAA;AACzB,EAAA,MAAM,IAAA,GAAO,EAAE,IAAA,IAAQ,CAAA;AACvB,EAAA,MAAM,OAAA,GAAU,EAAE,OAAA,IAAW,UAAA;AAE7B,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,YAAA;AACH,MAAA,OAAO;AAAA,QACL,CAAA,+BAAA,CAAA;AAAA,QACA,CAAA,mBAAA,CAAA;AAAA,QACA,cAAc,MAAA,CAAO,CAAC,CAAC,CAAA,EAAA,EAAK,MAAA,CAAO,CAAC,CAAC,CAAA,EAAA,CAAA;AAAA,QACrC,WAAW,IAAI,CAAA,CAAA,CAAA;AAAA,QACf,aAAa,KAAK,CAAA,EAAA,CAAA;AAAA,QAClB,CAAA,GAAA;AAAA,OACF,CAAE,KAAK,IAAI,CAAA;AAAA,IAEb,KAAK,YAAA;AACH,MAAA,OAAO;AAAA,QACL,CAAA,6BAAA,CAAA;AAAA,QACA,CAAA,kBAAA,CAAA;AAAA,QACA,uEAAuE,MAAA,CAAO,CAAC,CAAC,CAAA,EAAA,EAAK,MAAA,CAAO,CAAC,CAAC,CAAA,sBAAA,CAAA;AAAA,QAC9F,CAAA,GAAA,CAAA;AAAA,QACA,CAAA,cAAA,CAAA;AAAA,QACA,UAAU,OAAO,CAAA,EAAA,CAAA;AAAA,QACjB,CAAA,iBAAA,CAAA;AAAA,QACA,CAAA,uBAAA,CAAA;AAAA,QACA,CAAA,4BAAA,EAA+B,IAAI,CAAA,mBAAA,EAAsB,KAAK,CAAA,IAAA,CAAA;AAAA,QAC9D,CAAA,GAAA;AAAA,OACF,CAAE,KAAK,IAAI,CAAA;AAAA,IAEb,KAAK,kBAAA;AACH,MAAA,OAAO;AAAA,QACL,CAAA,2BAAA,CAAA;AAAA,QACA,CAAA,kBAAA,CAAA;AAAA,QACA,CAAA,0EAAA,EAA6E,OAAO,CAAC,CAAC,KAAK,MAAA,CAAO,CAAC,CAAC,CAAA,IAAA,EAAA,CAAQ,MAAA,CAAO,CAAC,IAAI,IAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,EAAA,CAAM,MAAA,CAAO,CAAC,CAAA,GAAI,IAAA,EAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,uBAAA,CAAA;AAAA,QAC1K,CAAA,GAAA,CAAA;AAAA,QACA,CAAA,cAAA,CAAA;AAAA,QACA,UAAU,OAAO,CAAA,EAAA,CAAA;AAAA,QACjB,CAAA,eAAA,CAAA;AAAA,QACA,CAAA,qBAAA,CAAA;AAAA,QACA,6BAA6B,KAAK,CAAA,iBAAA,EAAoB,KAAK,GAAA,CAAI,CAAA,EAAG,IAAI,CAAC,CAAA,GAAA,CAAA;AAAA,QACvE,CAAA,GAAA;AAAA,OACF,CAAE,KAAK,IAAI,CAAA;AAAA,IAEb,KAAK,SAAA;AACH,MAAA,OAAO;AAAA,QACL,CAAA,2BAAA,CAAA;AAAA,QACA,CAAA,kBAAA,CAAA;AAAA,QACA,CAAA,oDAAA,CAAA;AAAA,QACA,CAAA,GAAA,CAAA;AAAA,QACA,CAAA,cAAA,CAAA;AAAA,QACA,UAAU,OAAO,CAAA,EAAA,CAAA;AAAA,QACjB,CAAA,kBAAA,CAAA;AAAA,QACA,CAAA,qBAAA,CAAA;AAAA,QACA,CAAA,UAAA,CAAA;AAAA,QACA,CAAA,wBAAA,CAAA;AAAA,QACA,wGAAwG,KAAK,CAAA,wBAAA,CAAA;AAAA,QAC7G,yBAAyB,IAAA,CAAK,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,CAAC,CAAC,CAAA,CAAA,CAAA;AAAA,QAC/C,CAAA,IAAA,CAAA;AAAA,QACA,CAAA,GAAA;AAAA,OACF,CAAE,KAAK,IAAI,CAAA;AAAA,IAEb,KAAK,mBAAA;AACH,MAAA,OAAO;AAAA,QACL,oBAAoB,OAAO,CAAA,WAAA,CAAA;AAAA,QAC3B,CAAA,4DAAA,CAAA;AAAA,QACA,CAAA,wBAAA,CAAA;AAAA,QACA,CAAA,sBAAA,CAAA;AAAA,QACA,CAAA,cAAA,EAAiB,CAAA,CAAE,IAAA,IAAQ,0BAAM,CAAA,EAAA,CAAA;AAAA,QACjC,CAAA,yBAAA,CAAA;AAAA,QACA,CAAA,GAAA;AAAA,OACF,CAAE,KAAK,IAAI,CAAA;AAAA,IAEb;AACE,MAAA,OAAO,sDAAc,MAAM,CAAA,CAAA;AAAA;AAEjC;AAKO,SAAS,kBAAkB,KAAA,EAA8B;AAC9D,EAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAW,GAAI,eAAe,KAAK,CAAA;AACnD,EAAA,MAAM,MAAA,GAAS,aAAA,CAAc,KAAa,CAAA;AAC1C,EAAA,MAAM,IAAA,GAAO,YAAA,CAAa,MAAA,EAAQ,MAAM,CAAA;AACxC,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA,EAAa,gBAAA,CAAiB,MAAA,EAAQ,MAAM;AAAA,GAC9C;AACF;AAEA,SAAS,gBAAA,CAAiB,QAAuB,CAAA,EAA0B;AACzE,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,YAAA;AACH,MAAA,KAAA,CAAM,KAAK,sCAAQ,CAAA;AACnB,MAAA;AAAA,IACF,KAAK,YAAA;AACH,MAAA,KAAA,CAAM,KAAK,gCAAO,CAAA;AAClB,MAAA;AAAA,IACF,KAAK,kBAAA;AACH,MAAA,KAAA,CAAM,KAAK,uCAAS,CAAA;AACpB,MAAA;AAAA,IACF,KAAK,SAAA;AACH,MAAA,KAAA,CAAM,KAAK,gCAAO,CAAA;AAClB,MAAA;AAAA,IACF,KAAK,mBAAA;AACH,MAAA,KAAA,CAAM,KAAK,sCAAQ,CAAA;AACnB,MAAA;AAAA,IACF;AACE,MAAA,KAAA,CAAM,KAAK,0BAAM,CAAA;AAAA;AAErB,EAAA,IAAI,EAAE,KAAA,EAAO,KAAA,CAAM,KAAK,CAAA,aAAA,EAAM,CAAA,CAAE,KAAK,CAAA,CAAE,CAAA;AACvC,EAAA,IAAI,EAAE,KAAA,EAAO,KAAA,CAAM,KAAK,CAAA,aAAA,EAAM,CAAA,CAAE,KAAK,CAAA,CAAE,CAAA;AACvC,EAAA,OAAO,KAAA,CAAM,KAAK,GAAG,CAAA;AACvB;AAUO,IAAM,aAAN,MAAiB;AAAA,EACd,UAAA,GAA4B,YAAA;AAAA,EAC5B,aAA4B,EAAC;AAAA;AAAA,EAGrC,SAAS,KAAA,EAA8B;AACrC,IAAA,MAAM,EAAE,MAAA,EAAQ,UAAA,EAAW,GAAI,eAAe,KAAK,CAAA;AACnD,IAAA,MAAM,cAAA,GAAiB,qBAAA,CAAsB,IAAA,CAAK,KAAK,CAAA;AAEvD,IAAA,IAAI,cAAA,IAAkB,IAAA,CAAK,UAAA,KAAe,SAAA,EAAW;AAEnD,MAAA,MAAM,KAAA,GAAQ,aAAA,CAAc,KAAA,EAAO,IAAA,CAAK,UAAU,CAAA;AAClD,MAAA,IAAA,CAAK,aAAa,EAAE,GAAG,IAAA,CAAK,UAAA,EAAY,GAAG,KAAA,EAAM;AACjD,MAAA,MAAMC,KAAAA,GAAO,YAAA,CAAa,IAAA,CAAK,UAAA,EAAY,KAAK,UAAU,CAAA;AAC1D,MAAA,OAAO;AAAA,QACL,QAAQ,IAAA,CAAK,UAAA;AAAA,QACb,MAAA,EAAQ,EAAE,GAAG,IAAA,CAAK,UAAA,EAAW;AAAA,QAC7B,IAAA,EAAAA,KAAAA;AAAA,QACA,UAAA;AAAA,QACA,WAAA,EAAa,gBAAA,CAAiB,IAAA,CAAK,UAAA,EAAY,KAAK,UAAU;AAAA,OAChE;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,UAAA,GAAa,MAAA;AAClB,IAAA,IAAA,CAAK,UAAA,GAAa,aAAA,CAAc,KAAa,CAAA;AAC7C,IAAA,MAAM,IAAA,GAAO,YAAA,CAAa,MAAA,EAAQ,IAAA,CAAK,UAAU,CAAA;AACjD,IAAA,OAAO;AAAA,MACL,MAAA;AAAA,MACA,MAAA,EAAQ,EAAE,GAAG,IAAA,CAAK,UAAA,EAAW;AAAA,MAC7B,IAAA;AAAA,MACA,UAAA;AAAA,MACA,WAAA,EAAa,gBAAA,CAAiB,MAAA,EAAQ,IAAA,CAAK,UAAU;AAAA,KACvD;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,UAAA,GAAa,YAAA;AAClB,IAAA,IAAA,CAAK,aAAa,EAAC;AAAA,EACrB;AAAA;AAAA,EAGA,IAAI,OAAA,GAA4D;AAC9D,IAAA,OAAO,EAAE,QAAQ,IAAA,CAAK,UAAA,EAAY,QAAQ,EAAE,GAAG,IAAA,CAAK,UAAA,EAAW,EAAE;AAAA,EACnE;AACF;;;ACnUA,IAAM,aAAA,GAAgB,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA,iFAAA,CAAA;AAef,IAAM,gBAAN,MAAoB;AAAA,EACjB,MAAA;AAAA,EACA,OAAA;AAAA,EAER,YAAY,MAAA,EAA0B;AACpC,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,IAAA;AAAA,EACnC;AAAA;AAAA,EAGA,MAAM,SAAS,KAAA,EAAuC;AACpD,IAAA,IAAI,CAAC,KAAK,OAAA,EAAS;AACjB,MAAA,OAAO,kBAAkB,KAAK,CAAA;AAAA,IAChC;AACA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,CAAK,eAAA,CAAgB,KAAK,CAAA;AAAA,IACzC,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAO,kBAAkB,KAAK,CAAA;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAc,gBAAgB,KAAA,EAAuC;AACnE,IAAA,MAAM,QAAA,GAA0B;AAAA,MAC9B,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAAS,aAAA,EAAc;AAAA,MACzC,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,KAAA;AAAM,KACjC;AACA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,MAAA,CAAO,SAA2B,QAAQ,CAAA;AAEtE,IAAA,MAAM,MAAA,GAAU,KAAK,MAAA,IAAU,SAAA;AAC/B,IAAA,MAAM,IAAA,GAAO,KAAK,IAAA,IAAQ,EAAA;AAE1B,IAAA,IAAI,MAAA,KAAW,SAAA,IAAa,CAAC,IAAA,CAAK,MAAK,EAAG;AACxC,MAAA,OAAO,kBAAkB,KAAK,CAAA;AAAA,IAChC;AACA,IAAA,OAAO;AAAA,MACL,MAAA;AAAA,MACA,QAAQ,EAAC;AAAA,MACT,IAAA;AAAA,MACA,UAAA,EAAY,GAAA;AAAA,MACZ,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,CAAA,sBAAA,EAAU,MAAM,CAAA,MAAA;AAAA,KACnD;AAAA,EACF;AACF;;;ACzDA,IAAM,SAAA,GAAY;AAAA,EAChB,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAClB,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,oBAAA;AAAA,EACxB,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAC9B,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EACxB,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAC9B,oBAAA;AAAA,EAAO,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EACzB,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM;AACd,CAAA;AAEA,IAAM,MAAA,GAAmC;AAAA,EACvC,cAAI,CAAC,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAI,CAAA;AAAA,EACnG,YAAA,EAAI,CAAC,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAI,CAAA;AAAA,EACjF,YAAA,EAAI,CAAC,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,oBAAA,EAAO,gBAAM,cAAI,CAAA;AAAA,EAClF,YAAA,EAAI,CAAC,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAI,CAAA;AAAA,EACrE,YAAA,EAAI,CAAC,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAI;AACjE,CAAA;AAGA,IAAM,WAAA,GAAc;AAAA,EAClB,GAAG,MAAA,CAAO,MAAA,CAAO,MAAM,EAAE,IAAA,EAAK;AAAA,EAC9B,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM;AACpB,CAAA;AAGA,IAAM,eAAA,GAAkB;AAAA,EACtB,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAC1C,0BAAA;AAAA,EAAQ,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO;AACtC,CAAA;AAMA,IAAM,QAAA,GAAW;AAAA,EACf,cAAA;AAAA,EAAM,0BAAA;AAAA,EAAQ,gCAAA;AAAA,EAAS,gCAAA;AAAA,EAAS,oBAAA;AAAA,EAAO,0BAAA;AAAA,EACvC,0BAAA;AAAA,EAAQ,sCAAA;AAAA,EAAU,oBAAA;AAAA,EAAO,cAAA;AAAA,EAAM,0BAAA;AAAA,EAAQ,oBAAA;AAAA,EACvC,0BAAA;AAAA,EAAQ,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,cAAA;AAAA,EAAM,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAC1C,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO,oBAAA;AAAA,EAAO;AACvB,CAAA;AAaO,SAAS,aAAa,GAAA,EAA4B;AACvD,EAAA,MAAM,KAAA,GAAA,CAAS,GAAA,IAAO,EAAA,EAAI,IAAA,EAAK;AAC/B,EAAA,IAAI,CAAC,OAAO,OAAO,EAAE,KAAK,KAAA,EAAO,UAAA,EAAY,EAAA,EAAI,UAAA,EAAY,CAAA,EAAE;AAE/D,EAAA,MAAM,SAAwB,EAAE,GAAA,EAAK,OAAO,UAAA,EAAY,KAAA,EAAO,YAAY,GAAA,EAAI;AAC/E,EAAA,IAAI,OAAA,GAAU,CAAA;AAGd,EAAA,KAAA,MAAW,KAAK,SAAA,EAAW;AACzB,IAAA,IAAI,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,EAAG;AACrB,MAAA,MAAA,CAAO,QAAA,GAAW,CAAA;AAClB,MAAA,OAAA,EAAA;AACA,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,IAAI,OAAO,QAAA,EAAU;AACnB,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,QAAQ,KAAK,EAAC;AACnD,IAAA,KAAA,MAAW,KAAK,cAAA,EAAgB;AAC9B,MAAA,IAAI,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,EAAG;AACrB,QAAA,MAAA,CAAO,IAAA,GAAO,CAAA;AACd,QAAA,OAAA,EAAA;AACA,QAAA;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,MAAA,CAAO,IAAA,IAAQ,CAAC,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,cAAI,CAAA,CAAE,QAAA,CAAS,MAAA,CAAO,QAAQ,CAAA,EAAG;AACtE,MAAA,MAAA,CAAO,OAAO,MAAA,CAAO,QAAA;AACrB,MAAA,OAAA,EAAA;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,CAAC,OAAO,IAAA,EAAM;AAChB,IAAA,KAAA,MAAW,KAAK,WAAA,EAAa;AAC3B,MAAA,IAAI,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,EAAG;AACrB,QAAA,MAAA,CAAO,IAAA,GAAO,CAAA;AACd,QAAA,OAAA,EAAA;AACA,QAAA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,KAAK,eAAA,EAAiB;AAC/B,IAAA,IAAI,KAAA,CAAM,QAAA,CAAS,CAAC,CAAA,EAAG;AACrB,MAAA,MAAA,CAAO,QAAA,GAAW,CAAA;AAClB,MAAA,OAAA,EAAA;AACA,MAAA;AAAA,IACF;AAAA,EACF;AACA,EAAA,IAAI,CAAC,OAAO,QAAA,EAAU;AACpB,IAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,KAAA,CAAM,2BAA2B,CAAA;AAC7D,IAAA,IAAI,iBAAiB,CAAC,aAAA,CAAc,CAAC,CAAA,CAAE,UAAA,CAAW,cAAI,CAAA,EAAG;AACvD,MAAA,MAAA,CAAO,QAAA,GAAW,cAAc,CAAC,CAAA;AACjC,MAAA,OAAA,EAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,IAAA,IAAI,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG;AACvB,MAAA,MAAA,CAAO,GAAA,GAAM,GAAA;AACb,MAAA,OAAA,EAAA;AACA,MAAA;AAAA,IACF;AAAA,EACF;AAGA,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,KAAA,CAAM,qCAAqC,CAAA;AACrE,EAAA,IAAI,WAAA,EAAa;AACf,IAAA,MAAA,CAAO,MAAA,GAAS,YAAY,CAAC,CAAA;AAC7B,IAAA,OAAA,EAAA;AAAA,EACF;AAGA,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,KAAA,CAAM,WAAW,CAAA;AACxC,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,MAAA,CAAO,MAAA,GAAS,SAAS,CAAC,CAAA;AAC1B,IAAA,OAAA,EAAA;AAAA,EACF;AAGA,EAAA,MAAA,CAAO,UAAA,GAAa;AAAA,IAClB,MAAA,CAAO,QAAA;AAAA,IACP,OAAO,IAAA,IAAQ,MAAA,CAAO,SAAS,MAAA,CAAO,QAAA,GAAW,OAAO,IAAA,GAAO,EAAA;AAAA,IAC/D,MAAA,CAAO,QAAA;AAAA,IACP,MAAA,CAAO,GAAA;AAAA,IACP,MAAA,CAAO,MAAA;AAAA,IACP,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,MAAA,CAAO,MAAM,CAAA,MAAA,CAAA,GAAM;AAAA,GACxC,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,KAAK,EAAE,CAAA;AAEzB,EAAA,MAAA,CAAO,aAAa,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,GAAA,GAAM,UAAU,IAAI,CAAA;AACvD,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,eAAe,MAAA,EAAgC;AAC7D,EAAA,OAAO,OAAA,CAAQ,OAAO,QAAA,IAAY,MAAA,CAAO,QAAQ,MAAA,CAAO,QAAA,IAAY,OAAO,GAAG,CAAA;AAChF;;;ACzJA,IAAM,YAAA,GAAe;AAAA,EACnB,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,cAAA;AAAA,EAAM,oBAAA;AAAA,EAAO,0BAAA;AAAA,EAAQ,cAAA;AAAA,EAAM,0BAAA;AAAA,EAAQ,0BAAA;AAAA,EAC/C,SAAA;AAAA,EAAW,MAAA;AAAA,EAAQ,UAAA;AAAA,EAAY;AACjC,CAAA;AAGA,IAAM,SAAA,GAAY,CAAC,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAA,EAAM,cAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,OAAO,CAAA;AAG/E,IAAM,aAAA,GAAgB,CAAC,cAAA,EAAM,cAAA,EAAM,cAAA,EAAM,gBAAM,cAAA,EAAM,UAAA,EAAY,MAAA,EAAQ,MAAA,EAAQ,OAAO,CAAA;AAGxF,IAAM,QAAA,GAAW,CAAC,cAAA,EAAM,KAAA,EAAO,OAAO,WAAA,EAAa,eAAA,EAAO,0BAAA,EAAQ,MAAA,EAAQ,GAAG,CAAA;AAG7E,IAAM,WAAW,CAAC,cAAA,EAAM,OAAO,UAAA,EAAY,eAAA,EAAO,4BAAQ,GAAG,CAAA;AAG7D,SAAS,UAAU,CAAA,EAAmB;AACpC,EAAA,OAAO,EAAE,IAAA,EAAK,CAAE,aAAY,CAAE,OAAA,CAAQ,YAAY,EAAE,CAAA;AACtD;AAGA,SAAS,WAAA,CAAY,SAAmB,IAAA,EAAwB;AAC9D,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA;AACxC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,UAAA,CAAW,QAAQ,CAAA,EAAA,EAAK;AAC1C,IAAA,MAAM,CAAA,GAAI,WAAW,CAAC,CAAA;AACtB,IAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,MAAA,IAAI,CAAA,KAAM,UAAU,CAAC,CAAA,IAAK,EAAE,QAAA,CAAS,SAAA,CAAU,CAAC,CAAC,CAAA,EAAG;AAClD,QAAA,OAAO,CAAA;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,EAAA,OAAO,EAAA;AACT;AAMO,SAAS,cAAc,OAAA,EAAoC;AAChE,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,OAAA,EAAS,YAAY,CAAA;AACpD,EAAA,MAAM,OAAA,GAAU,WAAA,CAAY,OAAA,EAAS,SAAS,CAAA;AAC9C,EAAA,MAAM,WAAA,GAAc,WAAA,CAAY,OAAA,EAAS,aAAa,CAAA;AACtD,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,OAAA,EAAS,QAAQ,CAAA;AAC5C,EAAA,MAAM,MAAA,GAAS,WAAA,CAAY,OAAA,EAAS,QAAQ,CAAA;AAE5C,EAAA,MAAM,SAAiC,EAAC;AACxC,EAAA,IAAI,UAAA,IAAc,CAAA,EAAG,MAAA,CAAO,OAAA,GAAU,QAAQ,UAAU,CAAA;AACxD,EAAA,IAAI,OAAA,IAAW,CAAA,EAAG,MAAA,CAAO,IAAA,GAAO,QAAQ,OAAO,CAAA;AAC/C,EAAA,IAAI,WAAA,IAAe,CAAA,EAAG,MAAA,CAAO,QAAA,GAAW,QAAQ,WAAW,CAAA;AAC3D,EAAA,IAAI,MAAA,IAAU,CAAA,EAAG,MAAA,CAAO,GAAA,GAAM,QAAQ,MAAM,CAAA;AAC5C,EAAA,IAAI,MAAA,IAAU,CAAA,EAAG,MAAA,CAAO,GAAA,GAAM,QAAQ,MAAM,CAAA;AAE5C,EAAA,OAAO,EAAE,UAAA,EAAY,OAAA,EAAS,WAAA,EAAa,MAAA,EAAQ,QAAQ,MAAA,EAAO;AACpE;;;ACtEO,IAAM,YAAA,GAAe;AAAA,EAC1B,MAAA,EAAQ,EAAA;AAAA,EACR,MAAA,EAAQ,GAAA;AAAA,EACR,MAAA,EAAQ,EAAA;AAAA,EACR,MAAA,EAAQ;AACV;AAGA,IAAM,CAAA,GAAI,OAAA;AACV,IAAM,EAAA,GAAK,oBAAA;AAEX,SAAS,UAAA,CAAW,KAAa,GAAA,EAAsB;AACrD,EAAA,OAAO,GAAA,GAAM,YAAA,CAAa,MAAA,IAAU,GAAA,GAAM,YAAA,CAAa,UAAU,GAAA,GAAM,YAAA,CAAa,MAAA,IAAU,GAAA,GAAM,YAAA,CAAa,MAAA;AACnH;AAEA,SAAS,YAAA,CAAa,GAAW,CAAA,EAAmB;AAClD,EAAA,IAAI,MAAM,IAAA,GAAS,CAAA,GAAM,IAAI,CAAA,GAAM,CAAA,GAAI,MAAM,CAAA,GAAI,CAAA,GAAI,GAAA,GAAM,CAAA,GAAI,IAAI,GAAA,GAAM,IAAA,CAAK,KAAK,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AAC9F,EAAA,GAAA,IAAA,CAAS,KAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAM,CAAA,GAAI,KAAK,EAAE,CAAA,GAAI,EAAA,GAAO,IAAA,CAAK,IAAI,CAAA,GAAM,CAAA,GAAI,IAAA,CAAK,EAAE,KAAK,CAAA,GAAO,CAAA;AAC3F,EAAA,GAAA,IAAA,CAAS,EAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,KAAK,EAAE,CAAA,GAAI,EAAA,GAAO,IAAA,CAAK,IAAK,CAAA,GAAI,CAAA,GAAO,IAAA,CAAK,EAAE,KAAK,CAAA,GAAO,CAAA;AACvF,EAAA,GAAA,IAAA,CAAS,MAAQ,IAAA,CAAK,GAAA,CAAK,CAAA,GAAI,EAAA,GAAQ,KAAK,EAAE,CAAA,GAAI,GAAA,GAAM,IAAA,CAAK,IAAK,CAAA,GAAI,IAAA,CAAK,EAAA,GAAM,EAAI,KAAK,CAAA,GAAO,CAAA;AACjG,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,YAAA,CAAa,GAAW,CAAA,EAAmB;AAClD,EAAA,IAAI,MAAM,GAAA,GAAQ,CAAA,GAAI,CAAA,GAAM,CAAA,GAAI,MAAM,CAAA,GAAI,CAAA,GAAI,GAAA,GAAM,CAAA,GAAI,IAAI,GAAA,GAAM,IAAA,CAAK,KAAK,IAAA,CAAK,GAAA,CAAI,CAAC,CAAC,CAAA;AACvF,EAAA,GAAA,IAAA,CAAS,KAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAM,CAAA,GAAI,KAAK,EAAE,CAAA,GAAI,EAAA,GAAO,IAAA,CAAK,IAAI,CAAA,GAAM,CAAA,GAAI,IAAA,CAAK,EAAE,KAAK,CAAA,GAAO,CAAA;AAC3F,EAAA,GAAA,IAAA,CAAS,EAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,KAAK,EAAE,CAAA,GAAI,EAAA,GAAO,IAAA,CAAK,IAAK,CAAA,GAAI,CAAA,GAAO,IAAA,CAAK,EAAE,KAAK,CAAA,GAAO,CAAA;AACvF,EAAA,GAAA,IAAA,CAAS,MAAQ,IAAA,CAAK,GAAA,CAAK,CAAA,GAAI,EAAA,GAAQ,KAAK,EAAE,CAAA,GAAI,GAAA,GAAQ,IAAA,CAAK,IAAK,CAAA,GAAI,EAAA,GAAQ,IAAA,CAAK,EAAE,KAAK,CAAA,GAAO,CAAA;AACnG,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,YAAA,CAAa,KAAa,GAAA,EAA+B;AACvE,EAAA,IAAI,WAAW,GAAA,EAAK,GAAG,GAAG,OAAO,CAAC,KAAK,GAAG,CAAA;AAC1C,EAAA,IAAI,IAAA,GAAO,YAAA,CAAa,GAAA,GAAM,GAAA,EAAO,MAAM,EAAI,CAAA;AAC/C,EAAA,IAAI,IAAA,GAAO,YAAA,CAAa,GAAA,GAAM,GAAA,EAAO,MAAM,EAAI,CAAA;AAC/C,EAAA,MAAM,MAAA,GAAU,GAAA,GAAM,GAAA,GAAS,IAAA,CAAK,EAAA;AACpC,EAAA,IAAI,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AAC3B,EAAA,KAAA,GAAQ,CAAA,GAAI,KAAK,KAAA,GAAQ,KAAA;AACzB,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA;AACjC,EAAA,IAAA,GAAQ,OAAO,GAAA,IAAY,CAAA,IAAK,IAAI,EAAA,CAAA,IAAQ,KAAA,GAAQ,aAAc,IAAA,CAAK,EAAA,CAAA;AACvE,EAAA,IAAA,GAAQ,IAAA,GAAO,OAAW,CAAA,GAAI,SAAA,GAAa,KAAK,GAAA,CAAI,MAAM,IAAI,IAAA,CAAK,EAAA,CAAA;AACnE,EAAA,OAAO,CAAC,GAAA,GAAM,IAAA,EAAM,GAAA,GAAM,IAAI,CAAA;AAChC;AAGO,SAAS,YAAA,CAAa,KAAa,GAAA,EAA+B;AACvE,EAAA,IAAI,WAAW,GAAA,EAAK,GAAG,GAAG,OAAO,CAAC,KAAK,GAAG,CAAA;AAC1C,EAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,CAAA,GAAI,CAAC,KAAK,GAAG,CAAA;AAChC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK;AAC1B,IAAA,MAAM,CAAC,IAAA,EAAM,IAAI,CAAA,GAAI,YAAA,CAAa,QAAQ,MAAM,CAAA;AAChD,IAAA,MAAM,OAAO,IAAA,GAAO,GAAA;AACpB,IAAA,MAAM,OAAO,IAAA,GAAO,GAAA;AACpB,IAAA,MAAA,IAAU,IAAA;AACV,IAAA,MAAA,IAAU,IAAA;AAAA,EACZ;AACA,EAAA,OAAO,CAAC,QAAQ,MAAM,CAAA;AACxB;AAGO,SAAS,SAAA,CAAU,KAAa,GAAA,EAAsB;AAC3D,EAAA,OAAO,CAAC,UAAA,CAAW,GAAA,EAAK,GAAG,CAAA;AAC7B;AAOO,SAAS,SAAA,CACd,MAAA,EACA,MAAA,GAAkC,EAAC,EACtB;AAEb,EAAA,MAAM,CAAA,GAAA,CAAK,MAAA,IAAU,EAAA,EAAI,WAAA,EAAY;AACrC,EAAA,IAAI,2BAAA,CAA4B,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,OAAA;AAChD,EAAA,IAAI,0BAAA,CAA2B,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,UAAA;AAC/C,EAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,CAAC,CAAA,EAAG,OAAO,OAAA;AAGrC,EAAA,IAAI,MAAA,CAAO,SAAS,CAAA,EAAG;AACrB,IAAA,IAAI,YAAA,GAAe,CAAA;AAEnB,IAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,CAAA,IAAK,MAAA,EAAQ;AAC/B,MAAA,IAAI,SAAA,CAAU,GAAA,EAAK,GAAG,CAAA,EAAG;AACvB,QAAA,YAAA,EAAA;AACU,MACZ;AAAA,IACF;AAEA,IAAA,IAAI,OAAO,MAAA,GAAS,CAAA,IAAK,eAAe,MAAA,CAAO,MAAA,GAAS,KAAK,OAAO,OAAA;AAC/D,EACP;AAGA,EAAA,OAAO,OAAA;AACT;;;AClGO,IAAM,YAAA,GAAiD;AAAA;AAAA,EAE5D,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,KAAK,CAAA;AAAA,EACnB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,OAAA,EAAS,KAAK,CAAA;AAAA,EACnB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,YAAA,EAAI,CAAC,MAAA,EAAQ,MAAM,CAAA;AAAA,EACnB,YAAA,EAAI,CAAC,KAAA,EAAO,MAAM,CAAA;AAAA;AAAA,EAGlB,kBAAA,EAAK,CAAC,MAAA,EAAQ,IAAI,CAAA;AAAA,EAClB,kBAAA,EAAK,CAAC,MAAA,EAAQ,IAAI,CAAA;AAAA,EAClB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,IAAI,CAAA;AAAA,EAClB,wBAAA,EAAM,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACpB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,KAAA,EAAO,KAAK,CAAA;AAAA;AAAA,EAGlB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,wBAAA,EAAM,CAAC,KAAA,EAAO,MAAM,CAAA;AAAA,EACpB,8BAAA,EAAO,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACvB,8BAAA,EAAO,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACvB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,wBAAA,EAAM,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACtB,wBAAA,EAAM,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACtB,oCAAA,EAAQ,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACxB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,YAAA,EAAI,CAAC,KAAA,EAAO,KAAK,CAAA;AAAA,EACjB,wBAAA,EAAM,CAAC,OAAA,EAAS,KAAK,CAAA;AAAA,EACrB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,wBAAA,EAAM,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACtB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,YAAA,EAAI,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACpB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,kBAAA,EAAK,CAAC,OAAA,EAAS,MAAM,CAAA;AAAA,EACrB,kBAAA,EAAK,CAAC,KAAA,EAAO,KAAK,CAAA;AAAA,EAClB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,kBAAA,EAAK,CAAC,MAAA,EAAQ,KAAK,CAAA;AAAA,EACnB,8BAAA,EAAO,CAAC,MAAA,EAAQ,KAAK;AACvB;AAsBO,SAAS,QAAQ,MAAA,EAA6C;AAEnE,EAAA,IAAI,MAAA,CAAO,GAAA,IAAO,YAAA,CAAa,MAAA,CAAO,GAAG,CAAA,EAAG;AAC1C,IAAA,MAAM,CAAA,GAAI,YAAA,CAAa,MAAA,CAAO,GAAG,CAAA;AACjC,IAAA,OAAO,EAAE,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,OAAA,EAAS,MAAA,CAAO,GAAA,EAAK,YAAY,IAAA,EAAK;AAAA,EACvE;AAGA,EAAA,IAAI,MAAA,CAAO,QAAA,IAAY,YAAA,CAAa,MAAA,CAAO,QAAQ,CAAA,EAAG;AACpD,IAAA,MAAM,CAAA,GAAI,YAAA,CAAa,MAAA,CAAO,QAAQ,CAAA;AACtC,IAAA,OAAO,EAAE,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,OAAA,EAAS,MAAA,CAAO,QAAA,EAAU,YAAY,GAAA,EAAI;AAAA,EAC3E;AAGA,EAAA,IAAI,MAAA,CAAO,IAAA,IAAQ,YAAA,CAAa,MAAA,CAAO,IAAI,CAAA,EAAG;AAC5C,IAAA,MAAM,CAAA,GAAI,YAAA,CAAa,MAAA,CAAO,IAAI,CAAA;AAClC,IAAA,OAAO,EAAE,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,OAAA,EAAS,MAAA,CAAO,IAAA,EAAM,YAAY,GAAA,EAAI;AAAA,EACvE;AAGA,EAAA,IAAI,MAAA,CAAO,QAAA,IAAY,YAAA,CAAa,MAAA,CAAO,QAAQ,CAAA,EAAG;AACpD,IAAA,MAAM,CAAA,GAAI,YAAA,CAAa,MAAA,CAAO,QAAQ,CAAA;AACtC,IAAA,OAAO,EAAE,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,GAAA,EAAK,CAAA,CAAE,CAAC,CAAA,EAAG,OAAA,EAAS,MAAA,CAAO,QAAA,EAAU,YAAY,GAAA,EAAI;AAAA,EAC3E;AAEA,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,YAAY,IAAA,EAAuB;AACjD,EAAA,OAAO,IAAA,IAAQ,YAAA;AACjB;AAyBO,SAAS,YAAA,CACd,MACA,KAAA,EACsB;AACtB,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,KAAQ;AAEvB,IAAA,IAAI,OAAO,GAAA,CAAI,GAAA,KAAQ,YAAY,OAAO,GAAA,CAAI,QAAQ,QAAA,IAAY,CAAC,OAAO,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,IAAK,CAAC,OAAO,KAAA,CAAM,GAAA,CAAI,GAAG,CAAA,EAAG;AAClH,MAAA,OAAO,EAAE,GAAA,EAAK,GAAA,CAAI,GAAA,EAAK,GAAA,EAAK,IAAI,GAAA,EAAK,MAAA,EAAQ,UAAA,EAAY,UAAA,EAAY,CAAA,EAAE;AAAA,IACzE;AAEA,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA;AAChC,IAAA,MAAM,GAAA,GAAM,QAAQ,MAAM,CAAA;AAC1B,IAAA,IAAI,GAAA,EAAK;AACP,MAAA,OAAO,EAAE,GAAA,EAAK,GAAA,CAAI,GAAA,EAAK,KAAK,GAAA,CAAI,GAAA,EAAK,MAAA,EAAQ,UAAA,EAAY,OAAA,EAAS,GAAA,CAAI,OAAA,EAAS,UAAA,EAAY,IAAI,UAAA,EAAW;AAAA,IAC5G;AACA,IAAA,OAAO,EAAE,KAAK,CAAA,EAAG,GAAA,EAAK,GAAG,MAAA,EAAQ,QAAA,EAAU,YAAY,CAAA,EAAE;AAAA,EAC3D,CAAC,CAAA;AACH;;;ACpGO,SAAS,eAAA,CACd,OAAA,EACA,IAAA,EACA,IAAA,GAAsB,EAAC,EACT;AACd,EAAA,MAAM,EAAA,GAAK,OAAO,WAAA,KAAgB,WAAA,GAAc,YAAY,GAAA,EAAI,GAAI,KAAK,GAAA,EAAI;AAC7E,EAAA,MAAM,KAAA,GAAQ,KAAK,KAAA,IAAS,YAAA;AAE5B,EAAA,MAAM,GAAA,GAAM,cAAc,OAAO,CAAA;AACjC,EAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAS,WAAA,EAAa,MAAA,EAAQ,QAAO,GAAI,GAAA;AAG7D,EAAA,MAAM,UAAmC,EAAC;AAC1C,EAAA,IAAI,MAAA,IAAU,CAAA,IAAK,MAAA,IAAU,CAAA,EAAG;AAC9B,IAAA,KAAA,MAAW,GAAA,IAAO,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA,EAAG;AACnC,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,GAAA,CAAI,MAAM,CAAC,CAAA;AAC9B,MAAA,MAAM,GAAA,GAAM,MAAA,CAAO,GAAA,CAAI,MAAM,CAAC,CAAA;AAC9B,MAAA,IAAI,CAAC,MAAA,CAAO,KAAA,CAAM,GAAG,KAAK,CAAC,MAAA,CAAO,KAAA,CAAM,GAAG,GAAG,OAAA,CAAQ,IAAA,CAAK,CAAC,GAAA,EAAK,GAAG,CAAC,CAAA;AAAA,IACvE;AAAA,EACF;AACA,EAAA,MAAM,GAAA,GAAM,SAAA,CAAU,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAA;AAG1C,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,MAAS;AAAA,IACtC,OAAA,EAAS,MAAA,CAAO,GAAA,CAAI,UAAU,KAAK,EAAE,CAAA;AAAA,IACrC,KAAK,MAAA,IAAU,CAAA,GAAI,OAAO,GAAA,CAAI,MAAM,CAAC,CAAA,GAAI,MAAA;AAAA,IACzC,KAAK,MAAA,IAAU,CAAA,GAAI,OAAO,GAAA,CAAI,MAAM,CAAC,CAAA,GAAI;AAAA,GAC3C,CAAE,CAAA;AACF,EAAA,MAAM,KAAA,GAAQ,YAAA,CAAa,YAAA,EAAc,KAAK,CAAA;AAG9C,EAAA,MAAM,QAAA,GAA8B,IAAA,CAAK,GAAA,CAAI,CAAC,KAAK,CAAA,KAAM;AACvD,IAAA,MAAM,CAAA,GAAI,MAAM,CAAC,CAAA;AACjB,IAAA,IAAI,MAAM,CAAA,CAAE,GAAA;AACZ,IAAA,IAAI,MAAM,CAAA,CAAE,GAAA;AAEZ,IAAA,IAAI,CAAA,CAAE,MAAA,KAAW,QAAA,IAAY,GAAA,KAAQ,OAAA,EAAS;AAC5C,MAAA,CAAC,GAAA,EAAK,GAAG,CAAA,GAAI,YAAA,CAAa,KAAK,GAAG,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,aAAsC,EAAC;AAC7C,IAAA,IAAI,OAAA,IAAW,CAAA,EAAG,UAAA,CAAW,IAAA,GAAO,IAAI,OAAO,CAAA;AAC/C,IAAA,IAAI,WAAA,IAAe,CAAA,EAAG,UAAA,CAAW,QAAA,GAAW,IAAI,WAAW,CAAA;AAE3D,IAAA,IAAI,UAAA,IAAc,CAAA,EAAG,UAAA,CAAW,OAAA,GAAU,IAAI,UAAU,CAAA;AACxD,IAAA,IAAI,CAAA,CAAE,OAAA,EAAS,UAAA,CAAW,YAAA,GAAe,CAAA,CAAE,OAAA;AAE3C,IAAA,MAAM,WACJ,CAAA,CAAE,MAAA,KAAW,WACT,EAAE,IAAA,EAAM,SAAS,WAAA,EAAa,CAAC,GAAA,EAAK,GAAG,GAAE,GACzC,EAAE,MAAM,OAAA,EAAS,WAAA,EAAa,EAAC,EAAE;AAEvC,IAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,QAAA,EAAU,UAAA,EAAW;AAAA,EACjD,CAAC,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,MAAA,KAAW,QAAQ,CAAA,CAAE,MAAA;AAC3D,EAAA,MAAM,UAAA,GAAA,CAAc,OAAO,WAAA,KAAgB,WAAA,GAAc,YAAY,GAAA,EAAI,GAAI,IAAA,CAAK,GAAA,EAAI,IAAK,EAAA;AAE3F,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,mBAAA;AAAA,IACN,QAAA;AAAA,IACA,KAAA,EAAO;AAAA,MACL,OAAO,IAAA,CAAK,MAAA;AAAA,MACZ,OAAA;AAAA,MACA,MAAA,EAAQ,KAAK,MAAA,GAAS,OAAA;AAAA,MACtB,aAAa,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,OAAA,GAAU,KAAK,MAAA,GAAS,CAAA;AAAA,MACvD,OAAA,EAAS,GAAA;AAAA,MACT;AAAA;AACF,GACF;AACF;;;ACzEA,IAAM,aAAA,GAAsD;AAAA,EAC1D,EAAE,KAAA,EAAO,UAAA,EAAY,EAAA,EAAI,+BAAA,EAAgC;AAAA,EACzD,EAAE,KAAA,EAAO,UAAA,EAAY,EAAA,EAAI,cAAA,EAAe;AAAA,EACxC,EAAE,KAAA,EAAO,UAAA,EAAY,EAAA,EAAI,aAAA,EAAc;AAAA,EACvC,EAAE,KAAA,EAAO,QAAA,EAAU,EAAA,EAAI,gBAAA,EAAiB;AAAA,EACxC,EAAE,KAAA,EAAO,cAAA,EAAgB,EAAA,EAAI,eAAA,EAAgB;AAAA,EAC7C,EAAE,KAAA,EAAO,KAAA,EAAO,EAAA,EAAI,qCAAA,EAAsC;AAAA,EAC1D,EAAE,KAAA,EAAO,SAAA,EAAW,EAAA,EAAI,YAAA,EAAa;AAAA,EACrC,EAAE,KAAA,EAAO,WAAA,EAAa,EAAA,EAAI,mBAAA,EAAoB;AAAA,EAC9C,EAAE,KAAA,EAAO,YAAA,EAAc,EAAA,EAAI,KAAA,EAAM;AAAA,EACjC,EAAE,KAAA,EAAO,WAAA,EAAa,EAAA,EAAI,OAAA,EAAQ;AAAA,EAClC,EAAE,KAAA,EAAO,aAAA,EAAe,EAAA,EAAI,IAAA,EAAK;AAAA,EACjC,EAAE,KAAA,EAAO,cAAA,EAAgB,EAAA,EAAI,QAAA,EAAS;AAAA,EACtC,EAAE,KAAA,EAAO,MAAA,EAAQ,EAAA,EAAI,cAAA;AACvB,CAAA;AAGA,IAAM,aAAA,GAAsD;AAAA,EAC1D,EAAE,KAAA,EAAO,WAAA,EAAa,EAAA,EAAI,qCAAA,EAAsC;AAAA,EAChE,EAAE,KAAA,EAAO,OAAA,EAAS,EAAA,EAAI,gBAAA,EAAiB;AAAA,EACvC,EAAE,KAAA,EAAO,OAAA,EAAS,EAAA,EAAI,gBAAA,EAAiB;AAAA,EACvC,EAAE,KAAA,EAAO,SAAA,EAAW,EAAA,EAAI,iBAAA,EAAkB;AAAA,EAC1C,EAAE,KAAA,EAAO,WAAA,EAAa,EAAA,EAAI,WAAA,EAAY;AAAA,EACtC,EAAE,KAAA,EAAO,aAAA,EAAe,EAAA,EAAI,cAAA,EAAe;AAAA,EAC3C,EAAE,KAAA,EAAO,eAAA,EAAiB,EAAA,EAAI,aAAA,EAAc;AAAA,EAC5C,EAAE,KAAA,EAAO,QAAA,EAAU,EAAA,EAAI,aAAA,EAAc;AAAA,EACrC,EAAE,KAAA,EAAO,YAAA,EAAc,EAAA,EAAI,OAAA,EAAQ;AAAA,EACnC,EAAE,KAAA,EAAO,QAAA,EAAU,EAAA,EAAI,UAAA,EAAW;AAAA,EAClC,EAAE,KAAA,EAAO,MAAA,EAAQ,EAAA,EAAI,eAAA;AACvB,CAAA;AAGA,IAAM,UAAA,GAAkE;AAAA,EACtE,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,WAAA,EAAa,IAAI,IAAA,EAAK;AAAA,EAClD,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,cAAA,EAAgB,IAAI,IAAA,EAAK;AAAA,EACrD,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,OAAA,EAAS,IAAI,QAAA,EAAS;AAAA,EAClD,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,IAAA,EAAM,IAAI,IAAA,EAAK;AAAA,EAC3C,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,KAAA,EAAO,IAAI,KAAA,EAAM;AAAA,EAC7C,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,MAAA,EAAQ,IAAI,MAAA,EAAO;AAAA,EAC/C,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,QAAA,EAAU,IAAI,IAAA,EAAK;AAAA,EAC7C,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,OAAA,EAAS,IAAI,IAAA,EAAK;AAAA,EAC5C,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,aAAA,EAAe,IAAI,OAAA,EAAQ;AAAA,EACrD,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,OAAA,EAAS,IAAI,IAAA;AACzC,CAAA;AAGA,SAAS,eAAe,IAAA,EAAwB;AAC9C,EAAA,IAAI,oBAAA,CAAqB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA,CAAK,QAAA,CAAS,cAAI,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,oBAAK,IAAI,IAAA,GAAO,GAAA;AACjG,EAAA,IAAI,gBAAA,CAAiB,KAAK,IAAI,CAAA,SAAU,IAAA,CAAK,QAAA,CAAS,cAAI,CAAA,GAAI,IAAA,GAAO,GAAA;AACrE,EAAA,IAAI,iBAAA,CAAkB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,GAAA;AACzC,EAAA,IAAI,UAAA,CAAW,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAClC,EAAA,IAAI,SAAA,CAAU,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,MAAA;AACjC,EAAA,OAAO,GAAA;AACT;AAKO,SAAS,YAAY,IAAA,EAAsB;AAChD,EAAA,KAAA,MAAW,KAAK,aAAA,EAAe;AAC7B,IAAA,IAAI,EAAE,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,SAAU,CAAA,CAAE,KAAA;AAAA,EAChC;AACA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,YAAY,IAAA,EAA6B;AACvD,EAAA,KAAA,MAAW,KAAK,aAAA,EAAe;AAC7B,IAAA,IAAI,EAAE,EAAA,CAAG,IAAA,CAAK,IAAI,CAAA,SAAU,CAAA,CAAE,KAAA;AAAA,EAChC;AACA,EAAA,OAAO,IAAA;AACT;AAEO,SAAS,WAAA,CAAY,MAAc,KAAA,EAAuC;AAE/E,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,IAAA,IAAI,CAAA,CAAE,UAAU,KAAA,IAAS,CAAA,CAAE,GAAG,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,CAAA,CAAE,KAAA;AAAA,EACrD;AAEA,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,wDAAwD,CAAA;AACpF,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,IAAI,KAAA,GAAQ,UAAA,CAAW,QAAA,CAAS,CAAC,CAAC,CAAA;AAClC,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,CAAC,CAAA,IAAK,EAAA;AAC5B,IAAA,IAAI,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,EAAG,KAAA,IAAS,GAAA;AACjC,IAAA,IAAI,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,EAAG,KAAA,IAAS,GAAA;AAC/B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,KAAA,CAAM,oCAAoC,CAAA;AACjE,EAAA,IAAI,SAAA,EAAW,OAAO,SAAA,CAAU,CAAC,CAAA;AACjC,EAAA,OAAO,IAAA;AACT;AAKO,SAAS,aAAA,CAAc,IAAA,EAAc,cAAA,GAAiB,MAAA,EAAiC;AAE5F,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,uDAAuD,CAAA;AACjF,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,IAAI,MAAA,GAAS,UAAA,CAAW,MAAA,CAAO,CAAC,CAAC,CAAA;AACjC,IAAA,IAAI,WAAW,IAAA,CAAK,MAAA,CAAO,CAAC,CAAC,GAAG,MAAA,IAAU,GAAA;AAC1C,IAAA,OAAO,EAAE,QAAA,EAAU,SAAA,EAAW,MAAA,EAAQ,cAAA,EAAe;AAAA,EACvD;AAEA,EAAA,IAAI,sBAAA,CAAuB,IAAA,CAAK,IAAI,CAAA,EAAG;AACrC,IAAA,OAAO,EAAE,QAAA,EAAU,QAAA,EAAU,cAAA,EAAe;AAAA,EAC9C;AAEA,EAAA,IAAI,uBAAA,CAAwB,IAAA,CAAK,IAAI,CAAA,EAAG;AACtC,IAAA,OAAO,EAAE,QAAA,EAAU,QAAA,EAAU,cAAA,EAAe;AAAA,EAC9C;AAEA,EAAA,IAAI,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA,EAAG;AAC5B,IAAA,OAAO,EAAE,QAAA,EAAU,YAAA,EAAc,cAAA,EAAe;AAAA,EAClD;AACA,EAAA,OAAO,IAAA;AACT;AAKA,SAAS,WAAW,CAAA,EAA4B;AAC9C,EAAA,OAAO,OAAO,CAAA,KAAM,QAAA,GAAW,CAAA,CAAA,EAAI,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,MAAA,CAAO,CAAC,CAAA;AACxE;AAEA,SAAS,UAAA,CAAW,YAAkC,OAAA,EAA0C;AAC9F,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,MAAW,KAAK,UAAA,EAAY;AAC1B,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,CAAA,CAAE,KAAK,CAAA,CAAA,EAAI,CAAA,CAAE,QAAQ,CAAA,CAAA,EAAI,UAAA,CAAW,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE,CAAA;AAAA,EAC9D;AACA,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,IAAI,QAAQ,QAAA,KAAa,SAAA,IAAa,QAAQ,KAAA,IAAS,OAAA,CAAQ,WAAW,MAAA,EAAW;AACnF,MAAA,KAAA,CAAM,KAAK,CAAA,WAAA,EAAc,OAAA,CAAQ,cAAc,CAAA,0BAAA,EAA6B,QAAQ,KAAA,CAAM,CAAC,CAAC,CAAA,EAAA,EAAK,QAAQ,KAAA,CAAM,CAAC,CAAC,CAAA,UAAA,EAAa,OAAA,CAAQ,MAAM,CAAA,CAAA,CAAG,CAAA;AAAA,IACjJ,CAAA,MAAA,IAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,EAAU;AACxC,MAAA,KAAA,CAAM,KAAK,CAAA,cAAA,EAAiB,OAAA,CAAQ,cAAc,CAAA,YAAA,EAAe,OAAA,CAAQ,cAAc,CAAA,KAAA,CAAO,CAAA;AAAA,IAChG,CAAA,MAAA,IAAW,OAAA,CAAQ,QAAA,KAAa,QAAA,EAAU;AACxC,MAAA,KAAA,CAAM,KAAK,CAAA,UAAA,EAAa,OAAA,CAAQ,cAAc,CAAA,EAAA,EAAK,OAAA,CAAQ,cAAc,CAAA,CAAA,CAAG,CAAA;AAAA,IAC9E,CAAA,MAAA,IAAW,OAAA,CAAQ,QAAA,KAAa,YAAA,EAAc;AAC5C,MAAA,KAAA,CAAM,KAAK,CAAA,cAAA,EAAiB,OAAA,CAAQ,cAAc,CAAA,EAAA,EAAK,OAAA,CAAQ,cAAc,CAAA,CAAA,CAAG,CAAA;AAAA,IAClF;AAAA,EACF;AACA,EAAA,OAAO,KAAA,CAAM,SAAS,CAAA,GAAI,CAAA,MAAA,EAAS,MAAM,IAAA,CAAK,OAAO,CAAC,CAAA,CAAA,GAAK,EAAA;AAC7D;AAYO,SAAS,oBAAA,CAAqB,IAAA,EAAc,IAAA,GAAwB,EAAC,EAAmB;AAC7F,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,IAAU,CAAC,SAAS,MAAM,CAAA;AAC9C,EAAA,MAAM,cAAA,GAAiB,KAAK,cAAA,IAAkB,MAAA;AAE9C,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,MAAM,OAAA,GAAU,aAAA,CAAc,IAAA,EAAM,cAAc,CAAA;AAElD,EAAA,IAAI,WAAW,OAAA,CAAQ,QAAA,KAAa,SAAA,IAAa,CAAC,QAAQ,KAAA,EAAO;AAC/D,IAAA,OAAA,CAAQ,KAAA,GAAQ,MAAA;AAAA,EAClB;AAGA,EAAA,MAAM,aAAmC,EAAC;AAC1C,EAAA,MAAM,KAAA,GAAQ,YAAY,IAAI,CAAA;AAC9B,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,IAAA,EAAM,KAAK,CAAA;AACrC,IAAA,IAAI,UAAU,IAAA,EAAM;AAClB,MAAA,UAAA,CAAW,IAAA,CAAK,EAAE,KAAA,EAAO,QAAA,EAAU,eAAe,IAAI,CAAA,EAAG,OAAO,CAAA;AAAA,IAClE;AAAA,EACF;AAGA,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,OAAA,IAAW,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,MAAA,GAAS,OAAA;AAAA,OAAA,IACtC,OAAA,EAAS,MAAA,GAAS,OAAA,CAAQ,QAAA,KAAa,YAAY,gBAAA,GAAmB,gBAAA;AAAA,OAAA,IACtE,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,MAAA,GAAS,kBAAA;AAAA,OACpC,MAAA,GAAS,SAAA;AAEd,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,UAAA,EAAY,OAAO,CAAA;AAC5C,EAAA,MAAM,MAAM,CAAA,cAAA,EAAiB,KAAK,CAAA,CAAA,EAAI,KAAK,GAAG,IAAA,EAAK;AAGnD,EAAA,IAAI,UAAA,GAAa,GAAA;AACjB,EAAA,IAAI,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,UAAA,IAAc,GAAA;AACzC,EAAA,IAAI,SAAS,UAAA,IAAc,GAAA;AAC3B,EAAA,IAAI,KAAA,KAAU,QAAQ,UAAA,IAAc,GAAA;AACpC,EAAA,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,UAAU,CAAA;AAEtC,EAAA,OAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,UAAA,EAAY,OAAA,EAAS,KAAK,UAAA,EAAW;AAC/D;;;AC/NA,IAAM,kBAAA,GAAqB;AAAA,EACzB,MAAA;AAAA,EAAQ,QAAA;AAAA,EAAU,QAAA;AAAA,EAAU,QAAA;AAAA,EAAU,OAAA;AAAA,EAAS,UAAA;AAAA,EAAY,OAAA;AAAA,EAAS,QAAA;AAAA,EACpE,OAAA;AAAA,EAAS,QAAA;AAAA,EAAU,SAAA;AAAA,EAAW,MAAA;AAAA,EAAQ,SAAA;AAAA,EAAW,MAAA;AAAA,EAAQ,MAAA;AAAA,EAAQ,MAAA;AAAA,EACjE,MAAA;AAAA,EAAQ,KAAA;AAAA,EAAO,OAAA;AAAA,EAAS,QAAA;AAAA,EAAU,QAAA;AAAA,EAAU,QAAA;AAAA,EAAU,QAAA;AAAA,EAAU;AAClE,CAAA;AAGA,IAAM,kBAAA,GAAqB;AAAA,EACzB,IAAA;AAAA;AAAA,EACA,MAAA;AAAA;AAAA,EACA,iDAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,aAAA;AAAA;AAAA,EACA,yBAAA;AAAA;AAAA,EACA,2BAAA;AAAA;AAAA,EACA;AACF,CAAA;AAGO,IAAM,sBAAA,GAAyB;AAAA,EACpC,WAAA;AAAA,EAAa,OAAA;AAAA,EAAS,OAAA;AAAA,EAAS,SAAA;AAAA,EAAW,WAAA;AAAA,EAAa,aAAA;AAAA,EACvD,eAAA;AAAA,EAAiB,QAAA;AAAA,EAAU,YAAA;AAAA,EAAc,QAAA;AAAA,EAAU;AACrD;AAGA,IAAM,yBAAA,GAA4B;AAAA,EAChC,YAAA;AAAA,EAAc,WAAA;AAAA,EAAa,eAAA;AAAA,EAAiB,aAAA;AAAA,EAAe,WAAA;AAAA,EAC3D,cAAA;AAAA,EAAgB,YAAA;AAAA,EAAc,aAAA;AAAA,EAAe,cAAA;AAAA,EAAgB;AAC/D,CAAA;AAOO,SAAS,WAAA,CAAY,GAAA,EAAa,aAAA,GAA0B,sBAAA,EAA0C;AAC3G,EAAA,MAAM,SAA4B,EAAC;AACnC,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,WAAA,EAAY,CAAE,IAAA,EAAK;AAGrC,EAAA,IAAI,CAAC,GAAA,CAAI,IAAA,EAAK,EAAG;AACf,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,MAAM,WAAA,EAAa,OAAA,EAAS,gCAAY,CAAA;AACzE,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,MAAA,EAAO;AAAA,EAChC;AAGA,EAAA,IAAI,CAAC,KAAA,CAAM,UAAA,CAAW,QAAQ,CAAA,EAAG;AAC/B,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,MAAM,WAAA,EAAa,OAAA,EAAS,sDAAmB,CAAA;AAAA,EAClF;AAGA,EAAA,KAAA,MAAW,MAAM,kBAAA,EAAoB;AAEnC,IAAA,MAAM,KAAK,IAAI,MAAA,CAAO,CAAA,GAAA,EAAM,EAAE,OAAO,GAAG,CAAA;AACxC,IAAA,IAAI,EAAA,CAAG,IAAA,CAAK,GAAG,CAAA,IAAK,EAAE,OAAO,KAAA,IAAS,aAAA,CAAc,IAAA,CAAK,GAAG,CAAA,CAAA,EAAI;AAC9D,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,IAAA,EAAM,qBAAqB,OAAA,EAAS,CAAA,iDAAA,EAAY,EAAE,CAAA,CAAA,EAAI,CAAA;AAAA,IACzF;AAAA,EACF;AAGA,EAAA,KAAA,MAAW,KAAK,kBAAA,EAAoB;AAClC,IAAA,IAAI,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,EAAG;AACf,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,MAAM,WAAA,EAAa,OAAA,EAAS,mDAAgB,CAAA;AAAA,IAC/E;AAAA,EACF;AAGA,EAAA,MAAM,SAAA,GAAY,KAAA,CAAM,KAAA,CAAM,yBAAyB,CAAA;AACvD,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,CAAC,CAAA,CAAE,WAAA,EAAY;AACvC,IAAA,IAAI,CAAC,aAAA,CAAc,QAAA,CAAS,KAAK,CAAA,EAAG;AAClC,MAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,IAAA,EAAM,mBAAmB,OAAA,EAAS,CAAA,OAAA,EAAK,KAAK,CAAA,iDAAA,CAAA,EAAa,CAAA;AAAA,IAC5F;AAAA,EACF;AAGA,EAAA,MAAM,gBAAgB,GAAA,CAAI,KAAA,CAAM,IAAI,CAAA,IAAK,EAAC,EAAG,MAAA;AAC7C,EAAA,IAAI,YAAA,GAAe,MAAM,CAAA,EAAG;AAC1B,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,MAAM,QAAA,EAAU,OAAA,EAAS,wCAAU,CAAA;AAAA,EACtE;AACA,EAAA,MAAM,aAAa,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,IAAK,EAAC,EAAG,MAAA;AAC3C,EAAA,MAAM,cAAc,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,IAAK,EAAC,EAAG,MAAA;AAC5C,EAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,IAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,MAAM,QAAA,EAAU,OAAA,EAAS,kCAAS,CAAA;AAAA,EACrE;AAGA,EAAA,KAAA,MAAW,EAAA,IAAM,CAAC,KAAK,CAAA,EAAG;AACxB,IAAA,MAAM,OAAA,GAAU,GAAA,CAAI,KAAA,CAAM,WAAW,KAAK,EAAC;AAC3C,IAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,MAAA,IAAI,CAAC,yBAAA,CAA0B,QAAA,CAAS,CAAC,CAAA,EAAG;AAC1C,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,QAAA,EAAU,OAAA,EAAS,IAAA,EAAM,qBAAqB,OAAA,EAAS,CAAA,yBAAA,EAAQ,CAAC,CAAA,qCAAA,CAAA,EAAW,CAAA;AAAA,MAC3F;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,CAAC,MAAM,CAAA,CAAE,QAAA,KAAa,OAAO,CAAA,EAAG,MAAA,EAAO;AACtE;AAGO,SAAS,aAAa,GAAA,EAAgD;AAC3E,EAAA,MAAM,SAAmB,EAAC;AAC1B,EAAA,MAAM,MAAM,GAAA,CAAI,OAAA,CAAQ,YAAA,EAAc,CAAC,IAAI,CAAA,KAAc;AACvD,IAAA,MAAA,CAAO,KAAK,CAAC,CAAA;AACb,IAAA,OAAO,CAAA,CAAA,EAAI,OAAO,MAAM,CAAA,CAAA;AAAA,EAC1B,CAAC,CAAA;AACD,EAAA,OAAO,EAAE,GAAA,EAAK,GAAA,EAAK,MAAA,EAAO;AAC5B;;;ACxGO,SAAS,SAAA,CAAU,IAAA,EAAc,IAAA,GAAwB,EAAC,EAAe;AAC9E,EAAA,MAAM,KAAA,GAAQ,oBAAA,CAAqB,IAAA,EAAM,IAAI,CAAA;AAC7C,EAAA,MAAM,UAAA,GAAa,WAAA,CAAY,KAAA,CAAM,GAAG,CAAA;AACxC,EAAA,MAAM,QAAQ,UAAA,CAAW,KAAA;AACzB,EAAA,MAAM,aAAA,GAAgB,KAAA,GAAQ,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,GAAI,MAAA;AAExD,EAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,UAAA,EAAY,aAAA,EAAc;AACnD;;;ACVA,IAAMC,cAAAA,GAAgB,CAAA;;AAAA;AAAA;AAAA,2EAAA,EAIL,sBAAA,CAAuB,IAAA,CAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,iFAAA,CAAA;AAM3C,IAAM,UAAN,MAAc;AAAA,EACX,MAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EAER,YAAY,MAAA,EAAuB;AACjC,IAAA,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA;AACrB,IAAA,IAAA,CAAK,OAAA,GAAU,OAAO,OAAA,IAAW,IAAA;AACjC,IAAA,IAAA,CAAK,aAAA,GAAgB,OAAO,aAAA,IAAiB,sBAAA;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAM,IAAA,EAAqH;AAC/H,IAAA,IAAI,KAAK,OAAA,EAAS;AAChB,MAAA,IAAI;AACF,QAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,YAAA,CAAa,IAAI,CAAA;AAC9C,QAAA,IAAI,WAAW,OAAO,SAAA;AAAA,MACxB,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,OAAO,IAAA,CAAK,eAAe,IAAI,CAAA;AAAA,EACjC;AAAA,EAEA,MAAc,aACZ,IAAA,EAC8G;AAC9G,IAAA,MAAM,QAAA,GAA0B;AAAA,MAC9B,EAAE,IAAA,EAAM,QAAA,EAAU,OAAA,EAASA,cAAAA,EAAc;AAAA,MACzC,EAAE,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,IAAA;AAAK,KAChC;AACA,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,MAAA,CAAO,SAAuB,QAAQ,CAAA;AAClE,IAAA,MAAM,GAAA,GAAA,CAAO,IAAA,CAAK,GAAA,IAAO,EAAA,EAAI,IAAA,EAAK;AAClC,IAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AAGjB,IAAA,MAAM,UAAA,GAAa,WAAA,CAAY,GAAA,EAAK,IAAA,CAAK,aAAa,CAAA;AACtD,IAAA,IAAI,CAAC,UAAA,CAAW,KAAA,EAAO,OAAO,IAAA;AAE9B,IAAA,MAAM,KAAA,GAAwB;AAAA,MAC5B,MAAA,EAAQ,OAAA;AAAA,MACR,KAAA,EAAO,KAAK,KAAA,IAAS,MAAA;AAAA,MACrB,YAAY,EAAC;AAAA,MACb,OAAA,EAAS,IAAA;AAAA,MACT,GAAA;AAAA,MACA,UAAA,EAAY;AAAA,KACd;AACA,IAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,MAAM,aAAA,EAAe,YAAA,CAAa,GAAG,CAAA,EAAE;AAAA,EAChE;AAAA,EAEQ,eACN,IAAA,EAC8F;AAC9F,IAAA,MAAM,KAAA,GAAQ,qBAAqB,IAAI,CAAA;AACvC,IAAA,MAAM,UAAA,GAAa,WAAA,CAAY,KAAA,CAAM,GAAA,EAAK,KAAK,aAAa,CAAA;AAC5D,IAAA,OAAO;AAAA,MACL,KAAA;AAAA,MACA,OAAO,UAAA,CAAW,KAAA;AAAA,MAClB,eAAe,UAAA,CAAW,KAAA,GAAQ,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,GAAI;AAAA,KAC9D;AAAA,EACF;AACF;;;ACpCA,IAAM,gBAAA,GAAmB,0BAAA;AACzB,IAAM,aAAA,GAAgB,eAAA;AAGtB,SAAS,eAAe,IAAA,EAAqB;AAC3C,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,IAAA,IAAQ,uCAAmB,CAAA;AACjD,EAAA,GAAA,CAAI,IAAA,GAAO,eAAA;AACX,EAAA,OAAO,GAAA;AACT;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAClB,MAAA;AAAA,EACA,aAAA,GAAgB,CAAA;AAAA,EAExB,YAAY,MAAA,EAAwB;AAClC,IAAA,IAAI,CAAC,MAAA,CAAO,MAAA,EAAQ,MAAM,IAAI,MAAM,iDAA6B,CAAA;AACjE,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,UAAU,MAAA,CAAO,OAAA,IAAW,gBAAA,EAAkB,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAAA,MAChE,KAAA,EAAO,OAAO,KAAA,IAAS,aAAA;AAAA,MACvB,WAAA,EAAa,OAAO,WAAA,IAAe,GAAA;AAAA,MACnC,SAAA,EAAW,OAAO,SAAA,IAAa,IAAA;AAAA,MAC/B,SAAA,EAAW,OAAO,SAAA,IAAa,GAAA;AAAA,MAC/B,OAAA,EAAS,OAAO,OAAA,IAAW,CAAA;AAAA,MAC3B,SAAA,EAAW,MAAA,CAAO,SAAA,KAAe,UAAA,CAAwC,KAAA,IAAS,KAAA;AAAA,KACpF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,IAAA,CAAK,QAAA,EAAyB,IAAA,GAAoB,EAAC,EAAwB;AAC/E,IAAA,OAAO,IAAA,CAAK,gBAAA,CAAiB,QAAA,EAAU,IAAI,CAAA;AAAA,EAC7C;AAAA;AAAA,EAGA,MAAM,SAAY,QAAA,EAAqD;AACrE,IAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,IAAA,CAAK,UAAU,EAAE,IAAA,EAAM,MAAM,CAAA;AACvD,IAAA,MAAM,GAAA,GAAM,MAAA,CAAO,OAAA,CAAQ,IAAA,EAAK;AAEhC,IAAA,MAAM,OAAA,GAAU,IAAI,OAAA,CAAQ,mBAAA,EAAqB,EAAE,CAAA,CAAE,OAAA,CAAQ,WAAW,EAAE,CAAA;AAC1E,IAAA,IAAI,IAAA;AACJ,IAAA,IAAI;AACF,MAAA,IAAA,GAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,IAC3B,SAAS,CAAA,EAAG;AAEV,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,yBAAyB,CAAA;AACrD,MAAA,IAAI,KAAA,EAAO;AACT,QAAA,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,MAAM,IAAI,MAAM,CAAA,qDAAA,EAA0B,GAAA,CAAI,MAAM,CAAA,EAAG,GAAG,CAAC,CAAA,CAAE,CAAA;AAAA,MAC/D;AAAA,IACF;AACA,IAAA,OAAO,EAAE,IAAA,EAAM,GAAA,EAAK,KAAA,EAAO,OAAO,KAAA,EAAM;AAAA,EAC1C;AAAA,EAEA,MAAc,gBAAA,CAAiB,QAAA,EAAyB,IAAA,EAAwC;AAC9F,IAAA,IAAI,SAAA,GAA0B,IAAA;AAC9B,IAAA,KAAA,IAAS,UAAU,CAAA,EAAG,OAAA,IAAW,IAAA,CAAK,MAAA,CAAO,SAAS,OAAA,EAAA,EAAW;AAC/D,MAAA,IAAI;AACF,QAAA,OAAO,MAAM,IAAA,CAAK,WAAA,CAAY,QAAA,EAAU,IAAI,CAAA;AAAA,MAC9C,SAAS,CAAA,EAAG;AACV,QAAA,SAAA,GAAY,CAAA;AAEZ,QAAA,MAAM,SAAA,GAAY,EAAE,CAAA,YAAa,KAAA,CAAA,IAAU,CAAC,CAAA,CAAE,IAAA,CAAK,QAAA,CAAS,UAAU,CAAA,IAAK,IAAA,CAAK,WAAA,CAAY,CAAU,CAAA;AACtG,QAAA,IAAI,CAAC,SAAA,IAAa,CAAC,IAAA,CAAK,WAAA,CAAY,CAAU,CAAA,EAAG;AACjD,QAAA,IAAI,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,OAAA,EAAS;AACjC,UAAA,MAAM,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA,CAAI,MAAO,CAAA,IAAK,OAAA,EAAS,GAAI,CAAC,CAAA;AAAA,QACtD;AAAA,MACF;AAAA,IACF;AACA,IAAA,MAAM,SAAA,IAAa,IAAI,KAAA,CAAM,mCAAe,CAAA;AAAA,EAC9C;AAAA,EAEQ,YAAY,GAAA,EAAqB;AACvC,IAAA,MAAM,GAAA,GAAM,IAAI,OAAA,IAAW,EAAA;AAC3B,IAAA,OAAO,+DAAA,CAAgE,KAAK,GAAG,CAAA;AAAA,EACjF;AAAA,EAEA,MAAc,WAAA,CAAY,QAAA,EAAyB,IAAA,EAAwC;AACzF,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,IAAA,CAAK,MAAA;AAC3B,IAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,IAAA,MAAM,KAAA,GAAQ,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,IAAA,CAAK,OAAO,SAAS,CAAA;AAExE,IAAA,MAAM,IAAA,GAAgC;AAAA,MACpC,KAAA,EAAO,KAAK,MAAA,CAAO,KAAA;AAAA,MACnB,QAAA;AAAA,MACA,WAAA,EAAa,KAAK,MAAA,CAAO,WAAA;AAAA,MACzB,UAAA,EAAY,KAAK,MAAA,CAAO,SAAA;AAAA,MACxB,MAAA,EAAQ,OAAA,CAAQ,IAAA,CAAK,OAAO;AAAA,KAC9B;AACA,IAAA,IAAI,KAAK,IAAA,EAAM;AACb,MAAA,IAAA,CAAK,eAAA,GAAkB,EAAE,IAAA,EAAM,aAAA,EAAc;AAAA,IAC/C;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,SAAA,CAAU,GAAG,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA,iBAAA,CAAA,EAAqB;AAAA,QACrE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,cAAA,EAAgB,kBAAA;AAAA,UAChB,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,MAAA,CAAO,MAAM,CAAA;AAAA,SAC7C;AAAA,QACA,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAAA,QACzB,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AAED,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,OAAO,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AAC5C,QAAA,MAAM,eAAe,CAAA,cAAA,EAAiB,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AAAA,MAC7D;AAGA,MAAA,IAAI,IAAA,CAAK,OAAA,IAAW,GAAA,CAAI,IAAA,EAAM;AAC5B,QAAA,OAAO,IAAA,CAAK,WAAA,CAAY,GAAA,CAAI,IAAA,EAAM,KAAK,OAAO,CAAA;AAAA,MAChD;AAGA,MAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,EAAK;AAK7B,MAAA,MAAM,UAAU,IAAA,CAAK,OAAA,GAAU,CAAC,CAAA,EAAG,SAAS,OAAA,IAAW,EAAA;AACvD,MAAA,OAAO;AAAA,QACL,OAAA;AAAA,QACA,KAAA,EAAO,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,MAAA,CAAO,KAAA;AAAA,QACjC,OAAO,IAAA,CAAK,KAAA,GACR,EAAE,YAAA,EAAc,KAAK,KAAA,CAAM,aAAA,EAAe,gBAAA,EAAkB,IAAA,CAAK,MAAM,iBAAA,EAAmB,WAAA,EAAa,IAAA,CAAK,KAAA,CAAM,cAAa,GAC/H,KAAA;AAAA,OACN;AAAA,IACF,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF;AAAA;AAAA,EAGA,MAAc,WAAA,CACZ,IAAA,EACA,OAAA,EACqB;AACrB,IAAA,MAAM,MAAA,GAAS,KAAK,SAAA,EAAU;AAC9B,IAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,IAAA,IAAI,OAAA,GAAU,EAAA;AACd,IAAA,IAAI,MAAA,GAAS,EAAA;AAEb,IAAA,OAAO,IAAA,EAAM;AACX,MAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,MAAM,OAAO,IAAA,EAAK;AAC1C,MAAA,IAAI,IAAA,EAAM;AACV,MAAA,MAAA,IAAU,QAAQ,MAAA,CAAO,KAAA,EAAO,EAAE,MAAA,EAAQ,MAAM,CAAA;AAChD,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,KAAA,CAAM,IAAI,CAAA;AAC/B,MAAA,MAAA,GAAS,KAAA,CAAM,KAAI,IAAK,EAAA;AACxB,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAC1B,QAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,OAAO,CAAA,EAAG;AAClC,QAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,CAAC,EAAE,IAAA,EAAK;AACnC,QAAA,IAAI,SAAS,QAAA,EAAU;AACvB,QAAA,IAAI;AACF,UAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC5B,UAAA,MAAM,QAAQ,IAAA,CAAK,OAAA,GAAU,CAAC,CAAA,EAAG,OAAO,OAAA,IAAW,EAAA;AACnD,UAAA,IAAI,KAAA,EAAO;AACT,YAAA,OAAA,IAAW,KAAA;AACX,YAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,UACf;AAAA,QACF,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF;AAAA,IACF;AACA,IAAA,OAAO,EAAE,OAAA,EAAS,KAAA,EAAO,IAAA,CAAK,OAAO,KAAA,EAAM;AAAA,EAC7C;AAAA,EAEQ,MAAM,EAAA,EAA2B;AACvC,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,MAAM,UAAA,CAAW,CAAA,EAAG,EAAE,CAAC,CAAA;AAAA,EAC7C;AACF;AAGO,SAAS,qBAAqB,MAAA,EAAwC;AAC3E,EAAA,OAAO,IAAI,eAAe,MAAM,CAAA;AAClC","file":"index.cjs","sourcesContent":["/**\n * AI Debug 工具(PRD phase-3 §7)\n *\n * 功能点:\n * - AD-1 性能 Profiler 分析:分析渲染瓶颈\n * - AD-2 瓦片加载监控:实时显示瓦片请求/命中率/加载时间\n * - AD-3 内存泄漏检测:监控 GeoJSON/瓦片资源内存占用趋势\n * - AD-4 优化建议引擎:基于规则匹配常见问题\n *\n * 全部为纯函数,输入指标快照,输出诊断报告。\n */\n\n// ============================================================\n// 一、性能 Profiler 指标\n// ============================================================\nexport interface ProfilerMetrics {\n /** 帧率(fps) */\n fps?: number;\n /** Draw call 数量 */\n drawCalls?: number;\n /** 活动图层数 */\n activeLayers?: number;\n /** 主线程长任务数(>50ms) */\n longTasks?: number;\n /** 渲染耗时(ms) */\n renderTimeMs?: number;\n}\n\nexport interface ProfilerIssue {\n severity: 'info' | 'warning' | 'error';\n title: string;\n detail: string;\n suggestion: string;\n}\n\n/**\n * AD-1 性能 Profiler 分析\n */\nexport function analyzePerformance(m: ProfilerMetrics): ProfilerIssue[] {\n const issues: ProfilerIssue[] = [];\n\n if (m.fps !== undefined && m.fps < 30) {\n issues.push({\n severity: 'error',\n title: '帧率过低',\n detail: `当前 FPS=${m.fps},低于流畅阈值 30`,\n suggestion: '减少图层数量、启用 LOD 按需加载、降低数据密度',\n });\n } else if (m.fps !== undefined && m.fps < 60) {\n issues.push({\n severity: 'warning',\n title: '帧率偏低',\n detail: `当前 FPS=${m.fps},未达满帧`,\n suggestion: '检查是否有频繁 setData 或 re-render',\n });\n }\n\n if (m.drawCalls !== undefined && m.drawCalls > 100) {\n issues.push({\n severity: 'warning',\n title: 'Draw call 数量异常',\n detail: `Draw calls=${m.drawCalls}`,\n suggestion: '合并图层,减少 paint 属性复杂度(PRD §7.2 Shader 过复杂)',\n });\n }\n\n if (m.activeLayers !== undefined && m.activeLayers > 50) {\n issues.push({\n severity: 'warning',\n title: '活动图层过多',\n detail: `活动图层=${m.activeLayers}`,\n suggestion: '合并同类图层,减少图层数量',\n });\n }\n\n if (m.longTasks !== undefined && m.longTasks > 5) {\n issues.push({\n severity: 'warning',\n title: '主线程长任务过多',\n detail: `长任务数=${m.longTasks}`,\n suggestion: '检查静态数据是否意外触发 re-render(PRD §7.2 频繁重绘)',\n });\n }\n\n return issues;\n}\n\n// ============================================================\n// 二、瓦片加载监控(AD-2)\n// ============================================================\nexport interface TileMetrics {\n /** 已请求瓦片数 */\n requested: number;\n /** 命中缓存数 */\n cached: number;\n /** 总加载时间(ms) */\n totalLoadMs: number;\n}\n\nexport interface TileMonitorReport {\n /** 缓存命中率 */\n hitRate: number;\n /** 平均加载时间 */\n avgLoadMs: number;\n /** 是否瓦片过载 */\n overloaded: boolean;\n}\n\n/**\n * AD-2 瓦片加载监控\n */\nexport function analyzeTiles(m: TileMetrics, overloadThreshold = 200): TileMonitorReport {\n const hitRate = m.requested > 0 ? m.cached / m.requested : 0;\n const avgLoadMs = m.requested > 0 ? m.totalLoadMs / m.requested : 0;\n return {\n hitRate,\n avgLoadMs,\n overloaded: m.requested > overloadThreshold,\n };\n}\n\n// ============================================================\n// 三、内存泄漏检测(AD-3)\n// ============================================================\nexport interface MemorySnapshot {\n /** 时间戳 */\n timestamp: number;\n /** 占用字节 */\n bytes: number;\n}\n\nexport interface MemoryLeakReport {\n /** 是否疑似泄漏 */\n suspectedLeak: boolean;\n /** 增长率(bytes/ms) */\n growthRate: number;\n /** 快照数 */\n snapshotCount: number;\n}\n\n/**\n * AD-3 内存泄漏检测:分析内存占用趋势\n */\nexport function detectMemoryLeak(snapshots: MemorySnapshot[]): MemoryLeakReport {\n if (snapshots.length < 2) {\n return { suspectedLeak: false, growthRate: 0, snapshotCount: snapshots.length };\n }\n const sorted = [...snapshots].sort((a, b) => a.timestamp - b.timestamp);\n const first = sorted[0];\n const last = sorted[sorted.length - 1];\n const dt = last.timestamp - first.timestamp;\n const growthRate = dt > 0 ? (last.bytes - first.bytes) / dt : 0;\n\n // 持续增长 + 增长率 > 0 视为疑似泄漏\n let monotonic = true;\n for (let i = 1; i < sorted.length; i++) {\n if (sorted[i].bytes < sorted[i - 1].bytes) {\n monotonic = false;\n break;\n }\n }\n\n return {\n suspectedLeak: monotonic && growthRate > 0 && sorted.length >= 3,\n growthRate,\n snapshotCount: sorted.length,\n };\n}\n\n// ============================================================\n// 四、优化建议引擎(AD-4)\n// ============================================================\n/**\n * PRD §7.2 常见问题诊断规则\n */\nexport const DIAGNOSIS_RULES: Array<{\n id: string;\n /** 规则描述 */\n problem: string;\n /** 检测函数 */\n detect: (m: ProfilerMetrics & Partial<TileMetrics>) => boolean;\n /** 建议 */\n suggestion: string;\n}> = [\n {\n id: 'tile_overload',\n problem: '瓦片过载',\n detect: (m) => (m.requested ?? 0) > 200,\n suggestion: '增加 simplification tolerance',\n },\n {\n id: 'shader_complex',\n problem: 'Shader 过复杂',\n detect: (m) => (m.drawCalls ?? 0) > 100,\n suggestion: '合并图层,减少 paint 属性复杂度',\n },\n {\n id: 'frequent_rerender',\n problem: '频繁重绘',\n detect: (m) => (m.longTasks ?? 0) > 5,\n suggestion: '检查 data/source 是否意外更新',\n },\n {\n id: 'label_overlap',\n problem: '标注压盖',\n detect: (m) => (m.activeLayers ?? 0) > 50,\n suggestion: '启用文字避让或降低标注密度',\n },\n];\n\n/**\n * AD-4 优化建议引擎:运行规则匹配,返回命中的建议\n */\nexport function suggestOptimizations(\n m: ProfilerMetrics & Partial<TileMetrics>\n): Array<{ id: string; problem: string; suggestion: string }> {\n return DIAGNOSIS_RULES.filter((r) => r.detect(m)).map((r) => ({\n id: r.id,\n problem: r.problem,\n suggestion: r.suggestion,\n }));\n}\n\n/** 综合诊断(AD-1~AD-4 汇总) */\nexport interface DebugReport {\n perfIssues: ProfilerIssue[];\n tiles?: TileMonitorReport;\n memory?: MemoryLeakReport;\n suggestions: Array<{ id: string; problem: string; suggestion: string }>;\n}\n\nexport function diagnose(opts: {\n perf: ProfilerMetrics;\n tiles?: TileMetrics;\n memory?: MemorySnapshot[];\n}): DebugReport {\n const perfIssues = analyzePerformance(opts.perf);\n const suggestions = suggestOptimizations({\n ...opts.perf,\n ...(opts.tiles ?? {}),\n });\n return {\n perfIssues,\n tiles: opts.tiles ? analyzeTiles(opts.tiles) : undefined,\n memory: opts.memory ? detectMemoryLeak(opts.memory) : undefined,\n suggestions,\n };\n}\n","/**\n * 样式生成器 v2(PRD phase-3 §8)\n *\n * 功能点:\n * - SG-1 色板提取:上传图片 → 提取主色调 → 生成配色方案\n * - SG-2 风格模板:预置 6 套行业模板(管网/电网/水网/交通/算力/通信)\n * - SG-3 品牌定制:输入品牌色 → 自动生成全套地图样式\n * - SG-4 运营商主题:三大运营商预设主题 + 自定义\n * - SG-5 昼夜切换:一键切换亮色/暗色模式\n */\n\n/** 行业风格模板类型(六张网) */\nexport type IndustryStyle = 'pipeline' | 'grid' | 'water' | 'transport' | 'compute' | 'telecom';\n\n/** 配色方案 */\nexport interface ColorScheme {\n /** 主色 */\n primary: string;\n /** 辅助色 */\n secondary: string;\n /** 强调色 */\n accent: string;\n /** 背景色 */\n background: string;\n /** 名称 */\n name: string;\n}\n\n/** 生成的地图样式(简化 style.json 配色片段) */\nexport interface GeneratedMapStyle {\n scheme: ColorScheme;\n /** 线要素配色 */\n lineColor: string;\n /** 点要素配色 */\n pointColor: string;\n /** 面要素配色 */\n fillColor: string;\n /** 底图背景 */\n background: string;\n /** 模式 */\n mode: 'light' | 'dark';\n}\n\n// ============================================================\n// SG-2 风格模板:6 套行业模板\n// ============================================================\nexport const INDUSTRY_TEMPLATES: Record<IndustryStyle, ColorScheme> = {\n pipeline: { name: '管网', primary: '#f59e0b', secondary: '#3b82f6', accent: '#ef4444', background: '#0b1320' },\n grid: { name: '电网', primary: '#f59e0b', secondary: '#ef4444', accent: '#3b82f6', background: '#0b1320' },\n water: { name: '水网', primary: '#3b82f6', secondary: '#22d3ee', accent: '#4ade80', background: '#0b1320' },\n transport: { name: '交通', primary: '#f59e0b', secondary: '#ef4444', accent: '#22d3ee', background: '#0b1320' },\n compute: { name: '算力', primary: '#a78bfa', secondary: '#3b82f6', accent: '#4ade80', background: '#0b1320' },\n telecom: { name: '通信', primary: '#3b82f6', secondary: '#4ade80', accent: '#ef4444', background: '#0b1320' },\n};\n\n// ============================================================\n// SG-4 运营商主题\n// ============================================================\nexport const CARRIER_STYLES: Record<string, ColorScheme> = {\n '中国移动': { name: '中国移动', primary: '#4ade80', secondary: '#166534', accent: '#22c55e', background: '#0b1320' },\n '中国联通': { name: '中国联通', primary: '#ef4444', secondary: '#991b1b', accent: '#f87171', background: '#0b1320' },\n '中国电信': { name: '中国电信', primary: '#3b82f6', secondary: '#1e40af', accent: '#60a5fa', background: '#0b1320' },\n '中国广电': { name: '中国广电', primary: '#f59e0b', secondary: '#92400e', accent: '#fbbf24', background: '#0b1320' },\n};\n\n// ============================================================\n// SG-1 色板提取\n// ============================================================\n/**\n * 从图片像素数据提取主色调。\n * @param pixels RGBA 像素数组(每 4 个值一个像素)\n * @returns 主色 hex(出现频率最高的量化色)\n */\nexport function extractDominantColor(pixels: Uint8ClampedArray): string {\n if (pixels.length < 4) return '#000000';\n const bucket = new Map<string, number>();\n // 采样(每 4px 取一个,提升性能)\n for (let i = 0; i < pixels.length; i += 16) {\n const r = pixels[i];\n const g = pixels[i + 1];\n const b = pixels[i + 2];\n const a = pixels[i + 3];\n if (a === 0) continue;\n // 量化到 32 级\n const key = `${r >> 3},${g >> 3},${b >> 3}`;\n bucket.set(key, (bucket.get(key) ?? 0) + 1);\n }\n let bestKey = '';\n let bestCount = -1;\n for (const [k, c] of bucket) {\n if (c > bestCount) {\n bestCount = c;\n bestKey = k;\n }\n }\n if (!bestKey) return '#000000';\n // 还原量化桶中心值(每桶 8 级,中心偏移 +4)\n const [r, g, b] = bestKey.split(',').map((v) => (parseInt(v) << 3) + 4);\n return rgbToHex(r, g, b);\n}\n\nfunction rgbToHex(r: number, g: number, b: number): string {\n return '#' + [r, g, b].map((v) => v.toString(16).padStart(2, '0')).join('');\n}\n\n/** 调整颜色亮度(用于生成辅助色) */\nexport function adjustBrightness(hex: string, factor: number): string {\n const { r, g, b } = hexToRgb(hex);\n const nr = clamp(Math.round(r * factor));\n const ng = clamp(Math.round(g * factor));\n const nb = clamp(Math.round(b * factor));\n return rgbToHex(nr, ng, nb);\n}\n\nfunction hexToRgb(hex: string): { r: number; g: number; b: number } {\n const h = hex.replace('#', '');\n return {\n r: parseInt(h.slice(0, 2), 16),\n g: parseInt(h.slice(2, 4), 16),\n b: parseInt(h.slice(4, 6), 16),\n };\n}\n\nfunction clamp(v: number): number {\n return Math.max(0, Math.min(255, v));\n}\n\n// ============================================================\n// SG-3 品牌定制:输入品牌色 → 生成全套样式\n// ============================================================\nexport interface BrandStyleOptions {\n /** 品牌主色(hex) */\n brandColor: string;\n /** 模式 */\n mode?: 'light' | 'dark';\n /** 名称 */\n name?: string;\n}\n\nexport function generateBrandStyle(opts: BrandStyleOptions): GeneratedMapStyle {\n const mode = opts.mode ?? 'dark';\n const primary = opts.brandColor;\n const secondary = adjustBrightness(primary, 0.6);\n const accent = adjustBrightness(primary, 1.4);\n const background = mode === 'dark' ? '#0b1320' : '#f8fafc';\n return {\n scheme: {\n name: opts.name ?? '自定义品牌',\n primary,\n secondary,\n accent,\n background,\n },\n lineColor: primary,\n pointColor: accent,\n fillColor: primary,\n background,\n mode,\n };\n}\n\n/** 从行业模板生成样式 */\nexport function generateIndustryStyle(industry: IndustryStyle, mode: 'light' | 'dark' = 'dark'): GeneratedMapStyle {\n const scheme = INDUSTRY_TEMPLATES[industry];\n const background = mode === 'dark' ? '#0b1320' : '#f8fafc';\n return {\n scheme: { ...scheme, background },\n lineColor: scheme.primary,\n pointColor: scheme.accent,\n fillColor: scheme.secondary,\n background,\n mode,\n };\n}\n\n/** 从运营商主题生成样式 */\nexport function generateCarrierStyle(carrier: string, mode: 'light' | 'dark' = 'dark'): GeneratedMapStyle {\n const scheme = CARRIER_STYLES[carrier] ?? CARRIER_STYLES['中国移动'];\n const background = mode === 'dark' ? '#0b1320' : '#f8fafc';\n return {\n scheme: { ...scheme, background },\n lineColor: scheme.primary,\n pointColor: scheme.accent,\n fillColor: scheme.secondary,\n background,\n mode,\n };\n}\n\n// ============================================================\n// SG-5 昼夜切换\n// ============================================================\nexport function toggleMode(style: GeneratedMapStyle): GeneratedMapStyle {\n const nextMode: 'light' | 'dark' = style.mode === 'dark' ? 'light' : 'dark';\n return {\n ...style,\n mode: nextMode,\n background: nextMode === 'dark' ? '#0b1320' : '#f8fafc',\n scheme: { ...style.scheme, background: nextMode === 'dark' ? '#0b1320' : '#f8fafc' },\n };\n}\n","/**\n * MapCopilot v1(PRD phase-0 §5.5)\n *\n * 自然语言 → 草果地图 API 代码生成。\n *\n * v1 采用「意图识别 + 参数提取 + 模板生成」的规则引擎方案(不依赖大模型),\n * 覆盖 PRD 定义的 5 类核心交互意图:\n * I-1 create_map 创建基础地图\n * I-2 add_marker 添加点标记\n * I-3 add_line_polygon 添加线/面\n * I-4 heatmap 数据可视化(热力图)\n * I-5 popup_interaction 交互功能(点击弹窗)\n *\n * 全部为纯函数,可离线运行。支持上下文增量修改(\"把颜色改成红色\")。\n */\n\n// ============================================================\n// 一、类型定义\n// ============================================================\nexport type CopilotIntent =\n | 'create_map'\n | 'add_marker'\n | 'add_line_polygon'\n | 'heatmap'\n | 'popup_interaction'\n | 'unknown';\n\n/** 提取出的地图参数 */\nexport interface CopilotParams {\n /** 城市/地点名(用于映射中心坐标) */\n place?: string;\n /** 地图中心 [lng, lat] */\n center?: [number, number];\n /** 缩放级别 */\n zoom?: number;\n /** 主题样式 */\n style?: 'caoguo-dark' | 'caoguo-light';\n /** 要素颜色(hex) */\n color?: string;\n /** 线宽 / 半径 */\n size?: number;\n /** 图层 ID(用于交互意图) */\n layerId?: string;\n /** 文本内容(弹窗等) */\n text?: string;\n}\n\nexport interface CopilotResult {\n intent: CopilotIntent;\n params: CopilotParams;\n /** 生成的代码 */\n code: string;\n /** 识别置信度 0-1 */\n confidence: number;\n /** 可读说明 */\n description: string;\n}\n\n// ============================================================\n// 二、知识库(城市坐标 / 颜色 / 意图关键词)\n// ============================================================\n/** 常见城市/地点中心坐标(WGS84) */\nexport const PLACE_COORDINATES: Record<string, [number, number]> = {\n 武汉: [114.305, 30.593],\n 光谷: [114.428, 30.507],\n 汉口: [114.268, 30.586],\n 武昌: [114.316, 30.554],\n 北京: [116.407, 39.904],\n 上海: [121.474, 31.23],\n 广州: [113.264, 23.129],\n 深圳: [114.058, 22.543],\n 成都: [104.067, 30.573],\n 杭州: [120.155, 30.274],\n 南京: [118.796, 32.06],\n 重庆: [106.551, 29.563],\n 西安: [108.94, 34.341],\n 天津: [117.2, 39.084],\n};\n\n/** 颜色名 → hex */\nexport const COLOR_NAMES: Record<string, string> = {\n 红: '#ef4444',\n 红色: '#ef4444',\n 橙: '#f97316',\n 橙色: '#f97316',\n 黄: '#f59e0b',\n 黄色: '#f59e0b',\n 绿: '#22c55e',\n 绿色: '#22c55e',\n 青: '#22d3ee',\n 蓝色: '#3b82f6',\n 蓝: '#3b82f6',\n 紫: '#8b5cf6',\n 紫色: '#8b5cf6',\n 粉: '#ec4899',\n 灰: '#6b7280',\n 黑色: '#111827',\n 白色: '#ffffff',\n};\n\n/** 意图关键词(按优先级匹配) */\nconst INTENT_PATTERNS: Array<{ intent: CopilotIntent; re: RegExp; confidence: number }> = [\n { intent: 'popup_interaction', re: /弹窗|信息窗|弹出|popup|点击.*?显示|点击.*?弹出|点击.*?信息/, confidence: 0.92 },\n { intent: 'heatmap', re: /热力|heatmap|热度|密度图|热图/, confidence: 0.9 },\n { intent: 'add_line_polygon', re: /路线|连线|线段|画.{0,2}(线|面)|多边形|折线|面要素|LineString|polygon/, confidence: 0.88 },\n { intent: 'add_marker', re: /标记|marker|点标记|加点|标注|mark/, confidence: 0.86 },\n { intent: 'create_map', re: /地图|初始化|创建|生成|画布|渲染|map/, confidence: 0.8 },\n];\n\n// ============================================================\n// 三、意图识别\n// ============================================================\nexport function classifyIntent(query: string): { intent: CopilotIntent; confidence: number } {\n let best: { intent: CopilotIntent; confidence: number } = { intent: 'unknown', confidence: 0 };\n for (const p of INTENT_PATTERNS) {\n const m = query.match(p.re);\n if (m) {\n const c = p.confidence * (1 + 0.03 * Math.min(m[0].length / query.length, 1));\n if (c > best.confidence) best = { intent: p.intent, confidence: Math.min(c, 1) };\n }\n }\n return best;\n}\n\n// ============================================================\n// 四、参数提取\n// ============================================================\nexport function extractParams(query: string, intent: CopilotIntent): CopilotParams {\n const params: CopilotParams = {};\n\n // 地点 → 中心坐标\n for (const [name, coord] of Object.entries(PLACE_COORDINATES)) {\n if (query.includes(name)) {\n params.place = name;\n params.center = coord;\n break;\n }\n }\n\n // 缩放级别\n const zoomMatch = query.match(/缩放\\s*(\\d{1,2})|zoom\\s*(\\d{1,2})|级别\\s*(\\d{1,2})/i);\n if (zoomMatch) {\n const z = parseInt(zoomMatch[1] ?? zoomMatch[2] ?? zoomMatch[3]);\n if (!Number.isNaN(z) && z >= 0 && z <= 22) params.zoom = z;\n }\n\n // 主题\n if (/暗色|暗黑|深色|dark|夜间/.test(query)) params.style = 'caoguo-dark';\n else if (/亮色|浅色|白色|light|白天/.test(query)) params.style = 'caoguo-light';\n\n // 颜色\n for (const [name, hex] of Object.entries(COLOR_NAMES)) {\n if (query.includes(name)) {\n params.color = hex;\n break;\n }\n }\n\n // 尺寸(线宽/半径)\n const sizeMatch = query.match(/(?:宽度|半径|大小|width|size)\\s*(\\d+)/i);\n if (sizeMatch) params.size = parseInt(sizeMatch[1]);\n\n // 图层 ID(交互意图用)\n const layerMatch = query.match(/(?:图层|layer)\\s*[\"']?([\\w-]+)[\"']?/i);\n if (layerMatch) params.layerId = layerMatch[1];\n\n // 文本内容(弹窗用)\n const textMatch = query.match(/[\"「『]([^\"」』]+)[\"」』]/);\n if (textMatch) params.text = textMatch[1];\n\n return params;\n}\n\n// ============================================================\n// 五、代码模板生成\n// ============================================================\nexport function generateCode(intent: CopilotIntent, p: CopilotParams): string {\n const center = p.center ?? [114.305, 30.593];\n const zoom = p.zoom ?? 12;\n const style = p.style ?? 'caoguo-dark';\n const color = p.color ?? '#ef4444';\n const size = p.size ?? 8;\n const layerId = p.layerId ?? 'my-layer';\n\n switch (intent) {\n case 'create_map':\n return [\n `const map = new CaoguoMap.Map({`,\n ` container: 'map',`,\n ` center: [${center[0]}, ${center[1]}],`,\n ` zoom: ${zoom},`,\n ` style: '${style}',`,\n `});`,\n ].join('\\n');\n\n case 'add_marker':\n return [\n `map.addSource('marker-src', {`,\n ` type: 'geojson',`,\n ` data: { type: 'Feature', geometry: { type: 'Point', coordinates: [${center[0]}, ${center[1]}] }, properties: {} },`,\n `});`,\n `map.addLayer({`,\n ` id: '${layerId}',`,\n ` type: 'circle',`,\n ` source: 'marker-src',`,\n ` paint: { 'circle-radius': ${size}, 'circle-color': '${color}' },`,\n `});`,\n ].join('\\n');\n\n case 'add_line_polygon':\n return [\n `map.addSource('line-src', {`,\n ` type: 'geojson',`,\n ` data: { type: 'Feature', geometry: { type: 'LineString', coordinates: [[${center[0]}, ${center[1]}], [${(center[0] + 0.05).toFixed(3)}, ${(center[1] + 0.03).toFixed(3)}]] }, properties: {} },`,\n `});`,\n `map.addLayer({`,\n ` id: '${layerId}',`,\n ` type: 'line',`,\n ` source: 'line-src',`,\n ` paint: { 'line-color': '${color}', 'line-width': ${Math.max(2, size)} },`,\n `});`,\n ].join('\\n');\n\n case 'heatmap':\n return [\n `map.addSource('heat-src', {`,\n ` type: 'geojson',`,\n ` data: { type: 'FeatureCollection', features: [] },`,\n `});`,\n `map.addLayer({`,\n ` id: '${layerId}',`,\n ` type: 'heatmap',`,\n ` source: 'heat-src',`,\n ` paint: {`,\n ` 'heatmap-weight': 1,`,\n ` 'heatmap-color': ['interpolate', ['linear'], ['heatmap-density'], 0, 'rgba(33,102,172,0)', 0.5, '${color}', 1, 'rgb(239,68,68)'],`,\n ` 'heatmap-radius': ${Math.max(20, size * 4)},`,\n ` },`,\n `});`,\n ].join('\\n');\n\n case 'popup_interaction':\n return [\n `map.on('click', '${layerId}', (e) => {`,\n ` const coords = e.features[0].geometry.coordinates.slice();`,\n ` new maplibregl.Popup()`,\n ` .setLngLat(coords)`,\n ` .setHTML('${p.text ?? '要素信息'}')`,\n ` .addTo(map.instance);`,\n `});`,\n ].join('\\n');\n\n default:\n return `// 无法识别的意图:${intent}`;\n }\n}\n\n// ============================================================\n// 六、MapCopilot 主入口(含上下文增量修改)\n// ============================================================\nexport function generateFromQuery(query: string): CopilotResult {\n const { intent, confidence } = classifyIntent(query);\n const params = extractParams(query, intent);\n const code = generateCode(intent, params);\n return {\n intent,\n params,\n code,\n confidence,\n description: buildDescription(intent, params),\n };\n}\n\nfunction buildDescription(intent: CopilotIntent, p: CopilotParams): string {\n const parts: string[] = [];\n switch (intent) {\n case 'create_map':\n parts.push('创建基础地图');\n break;\n case 'add_marker':\n parts.push('添加点标记');\n break;\n case 'add_line_polygon':\n parts.push('添加线/面要素');\n break;\n case 'heatmap':\n parts.push('生成热力图');\n break;\n case 'popup_interaction':\n parts.push('绑定点击弹窗');\n break;\n default:\n parts.push('未知意图');\n }\n if (p.place) parts.push(`地点:${p.place}`);\n if (p.color) parts.push(`颜色:${p.color}`);\n return parts.join(' ');\n}\n\n/**\n * MapCopilot 组件类:维护当前会话上下文,支持增量修改。\n *\n * 用法:\n * const copilot = new MapCopilot();\n * copilot.generate('创建一个武汉地图,暗色主题,缩放 12'); // → 代码\n * copilot.generate('把颜色改成红色'); // → 增量修改后代码\n */\nexport class MapCopilot {\n private lastIntent: CopilotIntent = 'create_map';\n private lastParams: CopilotParams = {};\n\n /** 生成代码(支持上下文增量修改) */\n generate(query: string): CopilotResult {\n const { intent, confidence } = classifyIntent(query);\n const isModification = /改成|改为|换成|变成|调整为|设置成/.test(query);\n\n if (isModification && this.lastIntent !== 'unknown') {\n // 增量修改:提取新参数,合并到上一轮参数\n const delta = extractParams(query, this.lastIntent);\n this.lastParams = { ...this.lastParams, ...delta };\n const code = generateCode(this.lastIntent, this.lastParams);\n return {\n intent: this.lastIntent,\n params: { ...this.lastParams },\n code,\n confidence,\n description: buildDescription(this.lastIntent, this.lastParams),\n };\n }\n\n // 全新意图\n this.lastIntent = intent;\n this.lastParams = extractParams(query, intent);\n const code = generateCode(intent, this.lastParams);\n return {\n intent,\n params: { ...this.lastParams },\n code,\n confidence,\n description: buildDescription(intent, this.lastParams),\n };\n }\n\n /** 重置上下文 */\n reset(): void {\n this.lastIntent = 'create_map';\n this.lastParams = {};\n }\n\n /** 获取当前上下文 */\n get context(): { intent: CopilotIntent; params: CopilotParams } {\n return { intent: this.lastIntent, params: { ...this.lastParams } };\n }\n}\n","/**\n * MapCopilot LLM 模式(PRD phase-0 §5.5 I-6「LLM 增强」)\n *\n * 在规则引擎(copilot.ts)基础上,接入 DeepSeek 大模型实现:\n * - 自然语言 → 地图代码生成的「自由意图」支持(突破 5 类模板限制)\n * - LLM 优先,失败自动降级到规则引擎\n *\n * 安全设计:\n * - 生成的代码片段仅返回文本,由上层决定是否执行(不在本模块 eval)\n * - 通过 system prompt 约束输出格式与 API 白名单\n */\n\nimport type { DeepSeekClient, ChatMessage } from '../llm/deepseek';\nimport { generateFromQuery, type CopilotResult, type CopilotIntent } from './copilot';\n\nexport interface LlmCopilotConfig {\n /** DeepSeek 客户端 */\n client: DeepSeekClient;\n /** 是否启用 LLM(false 则退化为纯规则引擎) */\n enabled?: boolean;\n}\n\n/** LLM 返回的代码生成结果结构 */\ninterface LlmCopilotOutput {\n intent?: string;\n code: string;\n description?: string;\n}\n\n/** 系统提示词:约束模型只生成草果地图 API 代码 */\nconst SYSTEM_PROMPT = `你是\"草果地图\"(CaoguoMap) 的地图代码生成助手。用户用自然语言描述地图需求,你生成对应的 MapLibre GL JS 代码片段。\n\n草果地图 API 约定:\n- 地图实例:new CaoguoMap.Map({ container, center, zoom, style })\n- 添加点:map.addSource + map.addLayer({ type: 'circle' })\n- 添加线:map.addLayer({ type: 'line' })\n- 热力图:map.addLayer({ type: 'heatmap' })\n- 弹窗:map.on('click', layerId, cb) + new maplibregl.Popup()\n\n要求:\n1. 只返回 JSON,格式:{\"intent\":\"create_map|add_marker|add_line_polygon|heatmap|popup_interaction\",\"code\":\"...\",\"description\":\"...\"}\n2. code 必须是可直接运行的 JavaScript 代码片段(不含 import),禁止包含任何 fetch/网络请求/文件系统/危险操作。\n3. 若需求超出地图代码范畴,返回 {\"intent\":\"unknown\",\"code\":\"\",\"description\":\"无法识别的需求\"}。\n4. 不要输出 JSON 以外的任何文字。`;\n\nexport class LlmMapCopilot {\n private client: DeepSeekClient;\n private enabled: boolean;\n\n constructor(config: LlmCopilotConfig) {\n this.client = config.client;\n this.enabled = config.enabled ?? true;\n }\n\n /** 生成代码:LLM 优先,失败降级规则引擎 */\n async generate(query: string): Promise<CopilotResult> {\n if (!this.enabled) {\n return generateFromQuery(query);\n }\n try {\n return await this.generateWithLlm(query);\n } catch {\n // LLM 失败降级到规则引擎\n return generateFromQuery(query);\n }\n }\n\n private async generateWithLlm(query: string): Promise<CopilotResult> {\n const messages: ChatMessage[] = [\n { role: 'system', content: SYSTEM_PROMPT },\n { role: 'user', content: query },\n ];\n const { data } = await this.client.chatJson<LlmCopilotOutput>(messages);\n\n const intent = (data.intent ?? 'unknown') as CopilotIntent;\n const code = data.code ?? '';\n // 若 LLM 返回未知意图或空代码,降级规则引擎\n if (intent === 'unknown' || !code.trim()) {\n return generateFromQuery(query);\n }\n return {\n intent,\n params: {},\n code,\n confidence: 0.9,\n description: data.description ?? `LLM 生成(${intent})`,\n };\n }\n}\n","/**\n * GeoAI 中文地址解析(PRD phase-0 §5.6 G-2)\n *\n * 将非标准中文地址(含口语化、简称)解析为标准化结构:\n * province / city / district / street / poi / number\n *\n * 采用「词典匹配 + 规则」的传统 NLP 方案(不依赖大模型),保证速度与可控性。\n */\n\nexport interface ParsedAddress {\n /** 原始输入 */\n raw: string;\n /** 省 */\n province?: string;\n /** 市 */\n city?: string;\n /** 区/县 */\n district?: string;\n /** 街道/路/道 */\n street?: string;\n /** 门牌号 */\n number?: string;\n /** 地标/POI(如\"光谷\"\"汉口火车站\") */\n poi?: string;\n /** 标准化地址(可读拼接) */\n normalized: string;\n /** 解析置信度 0-1 */\n confidence: number;\n}\n\n/** 行政区词典(省/市/区) */\nconst PROVINCES = [\n '北京', '上海', '天津', '重庆',\n '河北', '山西', '辽宁', '吉林', '黑龙江',\n '江苏', '浙江', '安徽', '福建', '江西', '山东',\n '河南', '湖北', '湖南', '广东', '海南',\n '四川', '贵州', '云南', '陕西', '甘肃', '青海',\n '内蒙古', '广西', '西藏', '宁夏', '新疆',\n '香港', '澳门', '台湾',\n];\n\nconst CITIES: Record<string, string[]> = {\n 湖北: ['武汉', '黄石', '襄阳', '宜昌', '荆州', '十堰', '孝感', '黄冈', '咸宁', '随州', '恩施', '鄂州', '荆门', '仙桃', '天门', '潜江'],\n 广东: ['广州', '深圳', '珠海', '佛山', '东莞', '中山', '惠州', '江门', '湛江', '茂名', '肇庆', '汕头', '韶关'],\n 江苏: ['南京', '苏州', '无锡', '常州', '南通', '徐州', '扬州', '镇江', '泰州', '盐城', '连云港', '淮安', '宿迁'],\n 浙江: ['杭州', '宁波', '温州', '嘉兴', '湖州', '绍兴', '金华', '衢州', '舟山', '台州', '丽水'],\n 四川: ['成都', '绵阳', '德阳', '宜宾', '泸州', '南充', '达州', '乐山', '内江', '自贡'],\n};\n\n/** 扁平城市列表(含直辖市,用于无省名时的城市识别) */\nconst FLAT_CITIES = [\n ...Object.values(CITIES).flat(),\n '北京', '上海', '天津', '重庆',\n];\n\n/** 武汉各区(项目背景城市,优先覆盖) */\nconst WUHAN_DISTRICTS = [\n '江岸区', '江汉区', '硚口区', '汉阳区', '武昌区', '青山区', '洪山区',\n '东西湖区', '汉南区', '蔡甸区', '江夏区', '黄陂区', '新洲区',\n];\n\n/** 通用区县后缀 */\nconst DISTRICT_SUFFIX = /(区|县|市)$/;\n\n/** 常见地标/POI 词典(用于口语化地址识别) */\nconst POI_DICT = [\n '光谷', '光谷广场', '汉口火车站', '武昌火车站', '武汉站', '天河机场',\n '武汉大学', '华中科技大学', '黄鹤楼', '东湖', '长江大桥', '江汉路',\n '楚河汉街', '街道口', '中南路', '徐东', '王家湾', '钟家村', '汉正街',\n '软件园', '金融港', '生物城', '未来科技城',\n];\n\n/** 街道通名 */\nconst STREET_SUFFIX = /(路|街|道|大道|大街|巷|里|弄|街坊|桥|港)$/;\n\n/**\n * 解析中文地址。\n *\n * 覆盖:\n * - 完整地址:\"湖北省武汉市洪山区光谷大道 1 号\"\n * - 简称:\"武汉光谷\"、\"洪山区\"\n * - 口语化:\"光谷那边\"、\"汉口火车站附近\"\n */\nexport function parseAddress(raw: string): ParsedAddress {\n const input = (raw ?? '').trim();\n if (!input) return { raw: input, normalized: '', confidence: 0 };\n\n const result: ParsedAddress = { raw: input, normalized: input, confidence: 0.3 };\n let matched = 0;\n\n // 1) 省\n for (const p of PROVINCES) {\n if (input.includes(p)) {\n result.province = p;\n matched++;\n break;\n }\n }\n\n // 2) 市(先按省匹配,无省则从扁平城市列表匹配)\n if (result.province) {\n const provinceCities = CITIES[result.province] ?? [];\n for (const c of provinceCities) {\n if (input.includes(c)) {\n result.city = c;\n matched++;\n break;\n }\n }\n // 直辖市本身即市\n if (!result.city && ['北京', '上海', '天津', '重庆'].includes(result.province)) {\n result.city = result.province;\n matched++;\n }\n }\n if (!result.city) {\n for (const c of FLAT_CITIES) {\n if (input.includes(c)) {\n result.city = c;\n matched++;\n break;\n }\n }\n }\n\n // 3) 区/县\n for (const d of WUHAN_DISTRICTS) {\n if (input.includes(d)) {\n result.district = d;\n matched++;\n break;\n }\n }\n if (!result.district) {\n const districtMatch = input.match(/[\\u4e00-\\u9fa5]{2,4}(区|县)/);\n if (districtMatch && !districtMatch[0].startsWith('武汉')) {\n result.district = districtMatch[0];\n matched++;\n }\n }\n\n // 4) 地标/POI(口语化识别)\n for (const poi of POI_DICT) {\n if (input.includes(poi)) {\n result.poi = poi;\n matched++;\n break;\n }\n }\n\n // 5) 街道/路/道\n const streetMatch = input.match(/[\\u4e00-\\u9fa5]{2,8}(?:路|街|道|大道|大街)/);\n if (streetMatch) {\n result.street = streetMatch[0];\n matched++;\n }\n\n // 6) 门牌号\n const numMatch = input.match(/(\\d+)\\s*号/);\n if (numMatch) {\n result.number = numMatch[1];\n matched++;\n }\n\n // 标准化拼接 + 置信度\n result.normalized = [\n result.province,\n result.city && result.city !== result.province ? result.city : '',\n result.district,\n result.poi,\n result.street,\n result.number ? `${result.number}号` : '',\n ].filter(Boolean).join('');\n\n result.confidence = Math.min(0.95, 0.3 + matched * 0.15);\n return result;\n}\n\n/** 判断是否为有效地址(至少命中省/市/区/POI 之一) */\nexport function isValidAddress(parsed: ParsedAddress): boolean {\n return Boolean(parsed.province || parsed.city || parsed.district || parsed.poi);\n}\n","/**\n * GeoAI 表头自动识别(PRD phase-0 §5.6 G-1)\n *\n * 从 CSV/Excel 表头中自动识别:\n * - 地址列(addressCol)\n * - 名称列(nameCol)\n * - 分类列(categoryCol)\n * - 经度列(lngCol)/ 纬度列(latCol)\n *\n * 采用「列名语义 + 正则匹配」方案,命中率目标 ≥ 90%。\n */\n\nexport interface HeaderDetection {\n /** 地址列索引(-1 表示未识别) */\n addressCol: number;\n /** 名称列索引 */\n nameCol: number;\n /** 分类列索引 */\n categoryCol: number;\n /** 经度列索引 */\n lngCol: number;\n /** 纬度列索引 */\n latCol: number;\n /** 识别详情(供上层展示/纠错) */\n detail: Record<string, string>;\n}\n\n/** 地址列候选关键词 */\nconst ADDRESS_KEYS = [\n '地址', '位置', '地点', '所在地', '详细地址', '住址', '地理位置', '联系地址',\n 'address', 'addr', 'location', 'place',\n];\n\n/** 名称列候选关键词 */\nconst NAME_KEYS = ['名称', '名字', '单位', '机构', '站点', '场所', 'name', 'title', 'label'];\n\n/** 分类列候选关键词 */\nconst CATEGORY_KEYS = ['类型', '分类', '类别', '行业', '业态', 'category', 'type', 'kind', 'class'];\n\n/** 经度列候选关键词 */\nconst LNG_KEYS = ['经度', 'lng', 'lon', 'longitude', 'x坐标', '经度坐标', 'long', 'x'];\n\n/** 纬度列候选关键词 */\nconst LAT_KEYS = ['纬度', 'lat', 'latitude', 'y坐标', '纬度坐标', 'y'];\n\n/** 归一化:去空白、去下划线/连字符、转小写 */\nfunction normalize(h: string): string {\n return h.trim().toLowerCase().replace(/[\\s_-]+/g, '');\n}\n\n/** 在表头中匹配指定关键词集合,返回首个命中索引 */\nfunction matchHeader(headers: string[], keys: string[]): number {\n const normalized = headers.map(normalize);\n for (let i = 0; i < normalized.length; i++) {\n const h = normalized[i];\n for (const k of keys) {\n if (h === normalize(k) || h.includes(normalize(k))) {\n return i;\n }\n }\n }\n return -1;\n}\n\n/**\n * 识别表头。\n * @param headers 表头数组(CSV 首行 / Excel 首行)\n */\nexport function detectHeaders(headers: string[]): HeaderDetection {\n const addressCol = matchHeader(headers, ADDRESS_KEYS);\n const nameCol = matchHeader(headers, NAME_KEYS);\n const categoryCol = matchHeader(headers, CATEGORY_KEYS);\n const lngCol = matchHeader(headers, LNG_KEYS);\n const latCol = matchHeader(headers, LAT_KEYS);\n\n const detail: Record<string, string> = {};\n if (addressCol >= 0) detail.address = headers[addressCol];\n if (nameCol >= 0) detail.name = headers[nameCol];\n if (categoryCol >= 0) detail.category = headers[categoryCol];\n if (lngCol >= 0) detail.lng = headers[lngCol];\n if (latCol >= 0) detail.lat = headers[latCol];\n\n return { addressCol, nameCol, categoryCol, lngCol, latCol, detail };\n}\n","/**\n * GeoAI 坐标系判断(PRD phase-0 §5.6 G-3)\n *\n * 判断数据坐标所属坐标系:WGS84 / GCJ-02 / CGCS2000。\n *\n * 说明:单点无法 100% 判定坐标系(GCJ-02 偏移仅数百米),\n * 本模块采用「范围校验 + 数据来源推断 + 中国境外判定」的组合启发式,\n * 并提供 GCJ-02 ↔ WGS84 双向纠偏转换。\n */\n\nexport type DetectedCRS = 'wgs84' | 'gcj02' | 'cgcs2000' | 'unknown';\n\n/** 中国经纬度范围(粗判) */\nexport const CHINA_BOUNDS = {\n lngMin: 73,\n lngMax: 135,\n latMin: 18,\n latMax: 54,\n};\n\n/** GCJ-02 → WGS84 纠偏常量 */\nconst A = 6378245.0;\nconst EE = 0.00669342162296594323;\n\nfunction outOfChina(lng: number, lat: number): boolean {\n return lng < CHINA_BOUNDS.lngMin || lng > CHINA_BOUNDS.lngMax || lat < CHINA_BOUNDS.latMin || lat > CHINA_BOUNDS.latMax;\n}\n\nfunction transformLat(x: number, y: number): number {\n let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));\n ret += ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0;\n ret += ((20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin((y / 3.0) * Math.PI)) * 2.0) / 3.0;\n ret += ((160.0 * Math.sin((y / 12.0) * Math.PI) + 320 * Math.sin((y * Math.PI) / 30.0)) * 2.0) / 3.0;\n return ret;\n}\n\nfunction transformLng(x: number, y: number): number {\n let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));\n ret += ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0;\n ret += ((20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin((x / 3.0) * Math.PI)) * 2.0) / 3.0;\n ret += ((150.0 * Math.sin((x / 12.0) * Math.PI) + 300.0 * Math.sin((x / 30.0) * Math.PI)) * 2.0) / 3.0;\n return ret;\n}\n\n/** WGS84 → GCJ-02(加密偏移) */\nexport function wgs84ToGcj02(lng: number, lat: number): [number, number] {\n if (outOfChina(lng, lat)) return [lng, lat];\n let dLat = transformLat(lng - 105.0, lat - 35.0);\n let dLng = transformLng(lng - 105.0, lat - 35.0);\n const radLat = (lat / 180.0) * Math.PI;\n let magic = Math.sin(radLat);\n magic = 1 - EE * magic * magic;\n const sqrtMagic = Math.sqrt(magic);\n dLat = (dLat * 180.0) / (((A * (1 - EE)) / (magic * sqrtMagic)) * Math.PI);\n dLng = (dLng * 180.0) / ((A / sqrtMagic) * Math.cos(radLat) * Math.PI);\n return [lng + dLng, lat + dLat];\n}\n\n/** GCJ-02 → WGS84(纠偏,迭代逼近) */\nexport function gcj02ToWgs84(lng: number, lat: number): [number, number] {\n if (outOfChina(lng, lat)) return [lng, lat];\n let [wgsLng, wgsLat] = [lng, lat];\n for (let i = 0; i < 5; i++) {\n const [gLng, gLat] = wgs84ToGcj02(wgsLng, wgsLat);\n const dLng = gLng - lng;\n const dLat = gLat - lat;\n wgsLng -= dLng;\n wgsLat -= dLat;\n }\n return [wgsLng, wgsLat];\n}\n\n/** 坐标是否在中国境内 */\nexport function isInChina(lng: number, lat: number): boolean {\n return !outOfChina(lng, lat);\n}\n\n/**\n * 判断坐标系。\n * @param source 数据来源标注(如 '高德' / '腾讯' / '天地图' / 'GPS' / undefined)\n * @param sample 抽样坐标对\n */\nexport function detectCRS(\n source: string | undefined,\n sample: Array<[number, number]> = []\n): DetectedCRS {\n // 1) 来源推断优先\n const s = (source ?? '').toLowerCase();\n if (/(高德|腾讯|amap|qqmap|gcj|火星)/.test(s)) return 'gcj02';\n if (/(天地图|tianditu|cgcs|2000)/.test(s)) return 'cgcs2000';\n if (/(gps|wgs84|84)/.test(s)) return 'wgs84';\n\n // 2) 坐标范围粗判\n if (sample.length > 0) {\n let inChinaCount = 0;\n let inChina = false;\n for (const [lng, lat] of sample) {\n if (isInChina(lng, lat)) {\n inChinaCount++;\n inChina = true;\n }\n }\n // 多数坐标在中国境外 → 判定为 WGS84(GCJ 只对境内加密)\n if (sample.length > 0 && inChinaCount / sample.length < 0.5) return 'wgs84';\n void inChina;\n }\n\n // 3) 无来源标注且无法判定 → 默认 WGS84(保守,避免二次纠偏)\n return 'wgs84';\n}\n","/**\n * GeoAI 批量地理编码(PRD phase-0 §5.6 G-4)\n *\n * 将解析后的中文地址编码为坐标 [lng, lat]。\n * v1 使用「本地坐标库 + 模糊匹配」(离线、不依赖天地图/高德 API),\n * 命中率目标:标准地址 ≥ 90%,口语化地址 ≥ 60%。\n */\n\nimport type { ParsedAddress } from './addressParser';\n\n/** 本地地理坐标库:地名 → [lng, lat](WGS84) */\nexport const LOCAL_GEO_DB: Record<string, [number, number]> = {\n // 主要城市\n 武汉: [114.305, 30.593],\n 北京: [116.407, 39.904],\n 上海: [121.474, 31.23],\n 广州: [113.264, 23.129],\n 深圳: [114.058, 22.543],\n 成都: [104.067, 30.573],\n 杭州: [120.155, 30.274],\n 南京: [118.796, 32.06],\n 重庆: [106.551, 29.563],\n 西安: [108.94, 34.341],\n 天津: [117.2, 39.084],\n\n // 武汉各区\n 江岸区: [114.31, 30.6],\n 江汉区: [114.27, 30.6],\n 硚口区: [114.21, 30.58],\n 汉阳区: [114.22, 30.55],\n 武昌区: [114.32, 30.55],\n 青山区: [114.39, 30.63],\n 洪山区: [114.34, 30.5],\n 东西湖区: [114.14, 30.62],\n 汉南区: [114.08, 30.31],\n 蔡甸区: [114.03, 30.58],\n 江夏区: [114.32, 30.35],\n 黄陂区: [114.38, 30.88],\n 新洲区: [114.8, 30.85],\n\n // 常见 POI(口语化地址兜底)\n 光谷: [114.428, 30.507],\n 光谷广场: [114.4, 30.507],\n 汉口火车站: [114.255, 30.618],\n 武昌火车站: [114.317, 30.531],\n 武汉站: [114.424, 30.607],\n 天河机场: [114.208, 30.774],\n 武汉大学: [114.362, 30.541],\n 华中科技大学: [114.418, 30.513],\n 黄鹤楼: [114.302, 30.544],\n 东湖: [114.4, 30.55],\n 长江大桥: [114.294, 30.55],\n 江汉路: [114.278, 30.581],\n 楚河汉街: [114.337, 30.561],\n 街道口: [114.351, 30.531],\n 中南路: [114.331, 30.539],\n 徐东: [114.348, 30.583],\n 王家湾: [114.204, 30.557],\n 钟家村: [114.246, 30.549],\n 汉正街: [114.272, 30.573],\n 软件园: [114.4, 30.47],\n 金融港: [114.42, 30.47],\n 生物城: [114.48, 30.49],\n 未来科技城: [114.47, 30.44],\n};\n\nexport interface GeocodeResult {\n lng: number;\n lat: number;\n /** 匹配到的地名 */\n matched: string;\n /** 置信度 0-1 */\n confidence: number;\n}\n\n/**\n * 地理编码:地址 → 坐标。\n *\n * 匹配优先级:\n * 1. POI(最精确)\n * 2. 区/县\n * 3. 城市\n * 4. 省(降级)\n *\n * 无法匹配返回 null。\n */\nexport function geocode(parsed: ParsedAddress): GeocodeResult | null {\n // 1) POI\n if (parsed.poi && LOCAL_GEO_DB[parsed.poi]) {\n const c = LOCAL_GEO_DB[parsed.poi];\n return { lng: c[0], lat: c[1], matched: parsed.poi, confidence: 0.95 };\n }\n\n // 2) 区/县\n if (parsed.district && LOCAL_GEO_DB[parsed.district]) {\n const c = LOCAL_GEO_DB[parsed.district];\n return { lng: c[0], lat: c[1], matched: parsed.district, confidence: 0.8 };\n }\n\n // 3) 城市\n if (parsed.city && LOCAL_GEO_DB[parsed.city]) {\n const c = LOCAL_GEO_DB[parsed.city];\n return { lng: c[0], lat: c[1], matched: parsed.city, confidence: 0.6 };\n }\n\n // 4) 省(直辖市/省会)\n if (parsed.province && LOCAL_GEO_DB[parsed.province]) {\n const c = LOCAL_GEO_DB[parsed.province];\n return { lng: c[0], lat: c[1], matched: parsed.province, confidence: 0.4 };\n }\n\n return null;\n}\n\n/** 查询本地库是否存在某地名 */\nexport function hasLocalGeo(name: string): boolean {\n return name in LOCAL_GEO_DB;\n}\n\nexport interface BatchGeocodeInput {\n /** 原始地址字符串 */\n address: string;\n /** 已有经度(可选,优先级最高) */\n lng?: number;\n /** 已有纬度(可选) */\n lat?: number;\n}\n\nexport interface BatchGeocodeOutput {\n lng: number;\n lat: number;\n /** 坐标来源:'provided' | 'geocoded' | 'failed' */\n source: 'provided' | 'geocoded' | 'failed';\n matched?: string;\n confidence: number;\n}\n\n/**\n * 批量地理编码:对一批记录并行编码。\n *\n * 优先级:已有经纬度 > 地址解析 + 本地库编码。\n */\nexport function batchGeocode(\n rows: BatchGeocodeInput[],\n parse: (raw: string) => ParsedAddress\n): BatchGeocodeOutput[] {\n return rows.map((row) => {\n // 已有经纬度直接使用\n if (typeof row.lng === 'number' && typeof row.lat === 'number' && !Number.isNaN(row.lng) && !Number.isNaN(row.lat)) {\n return { lng: row.lng, lat: row.lat, source: 'provided', confidence: 1 };\n }\n // 地址解析 + 编码\n const parsed = parse(row.address);\n const geo = geocode(parsed);\n if (geo) {\n return { lng: geo.lng, lat: geo.lat, source: 'geocoded', matched: geo.matched, confidence: geo.confidence };\n }\n return { lng: 0, lat: 0, source: 'failed', confidence: 0 };\n });\n}\n","/**\n * GeoAI 数据入图主入口(PRD phase-0 §5.6)\n *\n * 完整管线:\n * CSV/Excel 表头 → 表头识别 → 逐行地址解析 → 地理编码 / 坐标纠偏 → GeoJSON\n *\n * 用法:\n * const result = importToGeoJSON(headers, rows);\n * result.features // GeoJSON FeatureCollection\n * result.stats // 命中率 / 编码耗时等\n */\n\nimport type { ParsedAddress } from './addressParser';\nimport { parseAddress } from './addressParser';\nimport { detectHeaders, type HeaderDetection } from './headerDetector';\nimport { batchGeocode } from './geocoder';\nimport { detectCRS, gcj02ToWgs84 } from './crsDetector';\n\nexport interface ImportedFeature {\n type: 'Feature';\n geometry:\n | { type: 'Point'; coordinates: [number, number] }\n | { type: 'Point'; coordinates: [] };\n properties: Record<string, unknown>;\n}\n\nexport interface ImportStats {\n /** 总记录数 */\n total: number;\n /** 成功编码数 */\n success: number;\n /** 失败数 */\n failed: number;\n /** 成功率 0-1 */\n successRate: number;\n /** 识别出的表头 */\n headers: HeaderDetection;\n /** 编码耗时(ms) */\n durationMs: number;\n}\n\nexport interface ImportResult {\n type: 'FeatureCollection';\n features: ImportedFeature[];\n stats: ImportStats;\n}\n\nexport interface ImportOptions {\n /** 数据来源标注(用于坐标系判断,如 '高德'/'GPS') */\n source?: string;\n /** 自定义地址解析函数(默认内置 parseAddress) */\n parse?: (raw: string) => ParsedAddress;\n}\n\n/**\n * 表格式数据 → GeoJSON。\n * @param headers 表头数组\n * @param rows 数据行(二维数组,与 headers 对齐)\n */\nexport function importToGeoJSON(\n headers: string[],\n rows: Array<Array<string | number>>,\n opts: ImportOptions = {}\n): ImportResult {\n const t0 = typeof performance !== 'undefined' ? performance.now() : Date.now();\n const parse = opts.parse ?? parseAddress;\n\n const det = detectHeaders(headers);\n const { addressCol, nameCol, categoryCol, lngCol, latCol } = det;\n\n // 抽样已有坐标,判断坐标系\n const samples: Array<[number, number]> = [];\n if (lngCol >= 0 && latCol >= 0) {\n for (const row of rows.slice(0, 50)) {\n const lng = Number(row[lngCol]);\n const lat = Number(row[latCol]);\n if (!Number.isNaN(lng) && !Number.isNaN(lat)) samples.push([lng, lat]);\n }\n }\n const crs = detectCRS(opts.source, samples);\n\n // 批量编码\n const geocodeInput = rows.map((row) => ({\n address: String(row[addressCol] ?? ''),\n lng: lngCol >= 0 ? Number(row[lngCol]) : undefined,\n lat: latCol >= 0 ? Number(row[latCol]) : undefined,\n }));\n const coded = batchGeocode(geocodeInput, parse);\n\n // 组装 GeoJSON\n const features: ImportedFeature[] = rows.map((row, i) => {\n const c = coded[i];\n let lng = c.lng;\n let lat = c.lat;\n // 坐标系纠偏:GCJ-02 → WGS84\n if (c.source !== 'failed' && crs === 'gcj02') {\n [lng, lat] = gcj02ToWgs84(lng, lat);\n }\n\n const properties: Record<string, unknown> = {};\n if (nameCol >= 0) properties.name = row[nameCol];\n if (categoryCol >= 0) properties.category = row[categoryCol];\n // 保留原始地址与匹配信息\n if (addressCol >= 0) properties.address = row[addressCol];\n if (c.matched) properties.matchedPlace = c.matched;\n\n const geometry: ImportedFeature['geometry'] =\n c.source !== 'failed'\n ? { type: 'Point', coordinates: [lng, lat] }\n : { type: 'Point', coordinates: [] };\n\n return { type: 'Feature', geometry, properties };\n });\n\n const success = coded.filter((c) => c.source !== 'failed').length;\n const durationMs = (typeof performance !== 'undefined' ? performance.now() : Date.now()) - t0;\n\n return {\n type: 'FeatureCollection',\n features,\n stats: {\n total: rows.length,\n success,\n failed: rows.length - success,\n successRate: rows.length > 0 ? success / rows.length : 0,\n headers: det,\n durationMs,\n },\n };\n}\n","/**\n * NLPG 自然语言 → PostGIS SQL 生成(PRD phase-0 §5.7 N-1/N-2/N-3)\n *\n * 支持:\n * - 属性过滤(字段 + 操作符 + 值,AND/OR 组合)\n * - 空间关系(ST_DWithin / ST_Within / ST_Intersects / ST_Contains / ST_Buffer)\n * - 混合查询(空间 + 属性)\n *\n * v1 采用「字段词典 + 规则匹配」方案(不依赖大模型),SQL 生成后必须经\n * `validateSql` 安全校验层通过方可执行(见 sqlValidator.ts)。\n */\n\n// ============================================================\n// 一、类型定义\n// ============================================================\nexport type NlpgIntent = 'attribute_filter' | 'spatial_nearby' | 'spatial_within' | 'mixed' | 'unknown';\n\nexport type Operator = '>' | '<' | '>=' | '<=' | '=' | '!=' | 'LIKE';\n\nexport interface AttributeCondition {\n /** 字段名(白名单字段) */\n field: string;\n operator: Operator;\n /** 字面量值 */\n value: string | number;\n}\n\nexport interface SpatialCondition {\n /** 空间关系 */\n relation: 'dwithin' | 'within' | 'intersects' | 'contains' | 'buffer';\n /** 参考点 [lng, lat](dwithin/buffer 用) */\n point?: [number, number];\n /** 距离(米,dwithin 用) */\n radius?: number;\n /** 目标几何字段 */\n geometryColumn: string;\n}\n\nexport interface GeneratedQuery {\n intent: NlpgIntent;\n /** 目标表(白名单表) */\n table: string;\n /** 属性条件 */\n conditions: AttributeCondition[];\n /** 空间条件 */\n spatial: SpatialCondition | null;\n /** 生成的 SQL */\n sql: string;\n /** 置信度 0-1 */\n confidence: number;\n}\n\n// ============================================================\n// 二、字段与表词典\n// ============================================================\n/** 字段别名 → 规范字段名 */\nconst FIELD_ALIASES: Array<{ field: string; re: RegExp }> = [\n { field: 'material', re: /材质|材料|铸铁|钢管|PE|PVC|球墨|HDPE|铜管/ },\n { field: 'pressure', re: /压力|水压|气压|MPa/ },\n { field: 'diameter', re: /管径|直径|口径|DN/ },\n { field: 'status', re: /状态|运行|停运|故障|检修/ },\n { field: 'install_date', re: /安装日期|投运|建成|敷设/ },\n { field: 'age', re: /年限|使用.{0,2}年|超过.{0,2}年|.{0,2}年以上|年代/ },\n { field: 'voltage', re: /电压|kV|kv|伏/ },\n { field: 'load_rate', re: /负载率|负荷率|利用率|负载|负荷/ },\n { field: 'fault_rate', re: /故障率/ },\n { field: 'flow_rate', re: /流量|流速/ },\n { field: 'water_level', re: /水位/ },\n { field: 'storage_rate', re: /蓄水率|库容/ },\n { field: 'rsrp', re: /RSRP|信号强度|信号/ },\n];\n\n/** 表别名 → 规范表名 */\nconst TABLE_ALIASES: Array<{ table: string; re: RegExp }> = [\n { table: 'pipelines', re: /管段|管线|管道|管网|燃气管|供水管|排水管|供热管|电力管|通信管/ },\n { table: 'nodes', re: /节点|阀门|泵站|表|井|闸/ },\n { table: 'users', re: /用户|居民|小区|住户|建筑/ },\n { table: 'schools', re: /学校|小学|中学|大学|幼儿园/ },\n { table: 'hospitals', re: /医院|卫生院|诊所/ },\n { table: 'substations', re: /变电站|配变|台区|电站/ },\n { table: 'base_stations', re: /基站|宏站|微站|室分/ },\n { table: 'rivers', re: /河流|水系|河段|支流/ },\n { table: 'reservoirs', re: /水库|大坝/ },\n { table: 'alarms', re: /报警|告警|警报/ },\n { table: 'pois', re: /POI|兴趣点|场所|设施/ },\n];\n\n/** 字段值词典(材质/状态等) */\nconst VALUE_DICT: Array<{ field: string; value: string; re: RegExp }> = [\n { field: 'material', value: 'cast_iron', re: /铸铁/ },\n { field: 'material', value: 'ductile_iron', re: /球墨/ },\n { field: 'material', value: 'steel', re: /钢(?!筋)/ },\n { field: 'material', value: 'pe', re: /PE/ },\n { field: 'material', value: 'pvc', re: /PVC/ },\n { field: 'material', value: 'hdpe', re: /HDPE/ },\n { field: 'status', value: 'normal', re: /正常/ },\n { field: 'status', value: 'fault', re: /故障/ },\n { field: 'status', value: 'maintenance', re: /检修|维修/ },\n { field: 'status', value: 'aging', re: /老化/ },\n];\n\n/** 操作符识别 */\nfunction detectOperator(text: string): Operator {\n if (/超过|高于|大于|超出|以上|不小于/.test(text)) return text.includes('以上') || text.includes('不小于') ? '>=' : '>';\n if (/低于|小于|不到|以下|不足/.test(text)) return text.includes('以下') ? '<=' : '<';\n if (/等于|正好|恰好|为\\s*\\d/.test(text)) return '=';\n if (/不是|非|不等于/.test(text)) return '!=';\n if (/包含|含有|含/.test(text)) return 'LIKE';\n return '=';\n}\n\n// ============================================================\n// 三、表名 / 字段 / 值识别\n// ============================================================\nexport function detectTable(text: string): string {\n for (const t of TABLE_ALIASES) {\n if (t.re.test(text)) return t.table;\n }\n return 'pois';\n}\n\nexport function detectField(text: string): string | null {\n for (const f of FIELD_ALIASES) {\n if (f.re.test(text)) return f.field;\n }\n return null;\n}\n\nexport function detectValue(text: string, field: string): string | number | null {\n // 词典值(材质/状态)\n for (const v of VALUE_DICT) {\n if (v.field === field && v.re.test(text)) return v.value;\n }\n // 数值 + 单位\n const numMatch = text.match(/(\\d+(?:\\.\\d+)?)\\s*(MPa|mpa|kV|kv|米|m|公里|km|%|%|方|立方米)?/);\n if (numMatch) {\n let value = parseFloat(numMatch[1]);\n const unit = numMatch[2] ?? '';\n if (/公里|km/.test(unit)) value *= 1000; // 距离转米\n if (/%|%/.test(unit)) value /= 100; // 百分比转 0-1\n return value;\n }\n // 日期\n const dateMatch = text.match(/(\\d{4}-\\d{2}-\\d{2}|\\d{4}年\\d{1,2}月)/);\n if (dateMatch) return dateMatch[1];\n return null;\n}\n\n// ============================================================\n// 四、空间关系识别\n// ============================================================\nexport function detectSpatial(text: string, geometryColumn = 'geom'): SpatialCondition | null {\n // N 米/公里 内\n const nearby = text.match(/(\\d+(?:\\.\\d+)?)\\s*(米|m|公里|km|千米)\\s*(?:内|以内|范围内|附近|周边)/);\n if (nearby) {\n let radius = parseFloat(nearby[1]);\n if (/公里|km|千米/.test(nearby[2])) radius *= 1000;\n return { relation: 'dwithin', radius, geometryColumn };\n }\n // 缓冲/范围内\n if (/缓冲区|缓冲|范围内|区域.{0,2}内/.test(text)) {\n return { relation: 'buffer', geometryColumn };\n }\n // 包含\n if (/包含|覆盖.{0,2}内|在.{0,2}内/.test(text)) {\n return { relation: 'within', geometryColumn };\n }\n // 相交/叠加\n if (/相交|叠加|重叠|交叉/.test(text)) {\n return { relation: 'intersects', geometryColumn };\n }\n return null;\n}\n\n// ============================================================\n// 五、SQL 组装\n// ============================================================\nfunction quoteValue(v: string | number): string {\n return typeof v === 'string' ? `'${v.replace(/'/g, \"''\")}'` : String(v);\n}\n\nfunction buildWhere(conditions: AttributeCondition[], spatial: SpatialCondition | null): string {\n const parts: string[] = [];\n for (const c of conditions) {\n parts.push(`${c.field} ${c.operator} ${quoteValue(c.value)}`);\n }\n if (spatial) {\n if (spatial.relation === 'dwithin' && spatial.point && spatial.radius !== undefined) {\n parts.push(`ST_DWithin(${spatial.geometryColumn}, ST_SetSRID(ST_MakePoint(${spatial.point[0]}, ${spatial.point[1]}), 4326), ${spatial.radius})`);\n } else if (spatial.relation === 'buffer') {\n parts.push(`ST_Intersects(${spatial.geometryColumn}, ST_Buffer(${spatial.geometryColumn}, 0))`);\n } else if (spatial.relation === 'within') {\n parts.push(`ST_Within(${spatial.geometryColumn}, ${spatial.geometryColumn})`);\n } else if (spatial.relation === 'intersects') {\n parts.push(`ST_Intersects(${spatial.geometryColumn}, ${spatial.geometryColumn})`);\n }\n }\n return parts.length > 0 ? `WHERE ${parts.join(' AND ')}` : '';\n}\n\n// ============================================================\n// 六、主入口\n// ============================================================\nexport interface GenerateOptions {\n /** 参考点(空间查询用,默认武汉中心) */\n center?: [number, number];\n /** 目标几何字段 */\n geometryColumn?: string;\n}\n\nexport function generatePostGISQuery(text: string, opts: GenerateOptions = {}): GeneratedQuery {\n const center = opts.center ?? [114.305, 30.593];\n const geometryColumn = opts.geometryColumn ?? 'geom';\n\n const table = detectTable(text);\n const spatial = detectSpatial(text, geometryColumn);\n // 空间查询需要参考点:默认使用中心坐标\n if (spatial && spatial.relation === 'dwithin' && !spatial.point) {\n spatial.point = center;\n }\n\n // 属性条件提取\n const conditions: AttributeCondition[] = [];\n const field = detectField(text);\n if (field) {\n const value = detectValue(text, field);\n if (value !== null) {\n conditions.push({ field, operator: detectOperator(text), value });\n }\n }\n\n // 意图判定\n let intent: NlpgIntent;\n if (spatial && conditions.length > 0) intent = 'mixed';\n else if (spatial) intent = spatial.relation === 'dwithin' ? 'spatial_nearby' : 'spatial_within';\n else if (conditions.length > 0) intent = 'attribute_filter';\n else intent = 'unknown';\n\n const where = buildWhere(conditions, spatial);\n const sql = `SELECT * FROM ${table} ${where}`.trim();\n\n // 置信度\n let confidence = 0.3;\n if (conditions.length > 0) confidence += 0.3;\n if (spatial) confidence += 0.3;\n if (table !== 'pois') confidence += 0.1;\n confidence = Math.min(0.95, confidence);\n\n return { intent, table, conditions, spatial, sql, confidence };\n}\n","/**\n * NLPG SQL 安全校验层(PRD phase-0 §5.7 N-5 / §5.7.3)\n *\n * 所有 LLM/规则生成的 SQL 必须经过以下校验方可执行:\n * 1. 语法校验(引号/括号配对、非空)\n * 2. 白名单表检查(只允许查询授权表)\n * 3. 危险操作拦截(DROP/DELETE/UPDATE/INSERT/ALTER/TRUNCATE/GRANT 等全部拒绝)\n * 4. 仅允许 SELECT 只读查询\n * 5. 参数化占位(防止 SQL 注入的字面量转义)\n *\n * 纯函数,可在 Node/浏览器两侧运行。\n */\n\nexport interface ValidationIssue {\n severity: 'error' | 'warning';\n rule: string;\n message: string;\n}\n\nexport interface ValidationResult {\n /** 是否通过(无 error 级问题) */\n valid: boolean;\n issues: ValidationIssue[];\n}\n\n/** 危险关键字(拒绝执行) */\nconst DANGEROUS_KEYWORDS = [\n 'DROP', 'DELETE', 'UPDATE', 'INSERT', 'ALTER', 'TRUNCATE', 'GRANT', 'REVOKE',\n 'MERGE', 'CREATE', 'REPLACE', 'EXEC', 'EXECUTE', 'CALL', 'COPY', 'LOAD',\n 'INTO', 'SET', 'UNION', 'ATTACH', 'DETACH', 'PRAGMA', 'VACUUM', 'REINDEX',\n];\n\n/** 危险注释/注入特征 */\nconst INJECTION_PATTERNS = [\n /--/, // SQL 注释\n /\\/\\*/, // 块注释\n /;\\s*(DROP|DELETE|UPDATE|INSERT|ALTER|TRUNCATE)/i, // 多语句注入\n /'\\s*OR\\s*'/i, // ' OR ' 恒真注入(含 ' OR '1'='1')\n /\"\\s*OR\\s*\"/i, // \" OR \" 恒真注入\n /\\bOR\\s+\\d+\\s*=\\s*\\d+\\b/i, // OR 1=1 恒真\n /\\bOR\\s+'\\w*'\\s*=\\s*'\\w*'/i, // OR 'a'='a' 恒真\n /UNION\\s+SELECT/i,\n];\n\n/** 默认白名单表(只读授权) */\nexport const DEFAULT_ALLOWED_TABLES = [\n 'pipelines', 'nodes', 'users', 'schools', 'hospitals', 'substations',\n 'base_stations', 'rivers', 'reservoirs', 'alarms', 'pois',\n];\n\n/** 允许的空间函数 */\nconst ALLOWED_SPATIAL_FUNCTIONS = [\n 'ST_DWithin', 'ST_Within', 'ST_Intersects', 'ST_Contains', 'ST_Buffer',\n 'ST_MakePoint', 'ST_SetSRID', 'ST_Distance', 'ST_AsGeoJSON', 'ST_Transform',\n];\n\n/**\n * 校验 SQL。\n * @param sql 待校验 SQL\n * @param allowedTables 白名单表(默认 DEFAULT_ALLOWED_TABLES)\n */\nexport function validateSql(sql: string, allowedTables: string[] = DEFAULT_ALLOWED_TABLES): ValidationResult {\n const issues: ValidationIssue[] = [];\n const upper = sql.toUpperCase().trim();\n\n // 1) 非空\n if (!sql.trim()) {\n issues.push({ severity: 'error', rule: 'non_empty', message: 'SQL 不能为空' });\n return { valid: false, issues };\n }\n\n // 2) 必须以 SELECT 开头(只读)\n if (!upper.startsWith('SELECT')) {\n issues.push({ severity: 'error', rule: 'read_only', message: '仅允许 SELECT 只读查询' });\n }\n\n // 3) 危险操作拦截\n for (const kw of DANGEROUS_KEYWORDS) {\n // 用词边界匹配,避免误伤字段名(如 \"status\" 含 \"set\" 的误判)\n const re = new RegExp(`\\\\b${kw}\\\\b`, 'i');\n if (re.test(sql) && !(kw === 'SET' && /ST_SetSRID/i.test(sql))) {\n issues.push({ severity: 'error', rule: 'dangerous_keyword', message: `检测到危险关键字 ${kw}` });\n }\n }\n\n // 4) 注入特征拦截\n for (const p of INJECTION_PATTERNS) {\n if (p.test(sql)) {\n issues.push({ severity: 'error', rule: 'injection', message: '检测到 SQL 注入特征' });\n }\n }\n\n // 5) 白名单表检查\n const fromMatch = upper.match(/FROM\\s+([A-Za-z_][\\w]*)/);\n if (fromMatch) {\n const table = fromMatch[1].toLowerCase();\n if (!allowedTables.includes(table)) {\n issues.push({ severity: 'error', rule: 'table_whitelist', message: `表 ${table} 不在授权白名单内` });\n }\n }\n\n // 6) 引号/括号配对\n const singleQuotes = (sql.match(/'/g) ?? []).length;\n if (singleQuotes % 2 !== 0) {\n issues.push({ severity: 'error', rule: 'syntax', message: '单引号未配对' });\n }\n const openParen = (sql.match(/\\(/g) ?? []).length;\n const closeParen = (sql.match(/\\)/g) ?? []).length;\n if (openParen !== closeParen) {\n issues.push({ severity: 'error', rule: 'syntax', message: '括号未配对' });\n }\n\n // 7) 空间函数白名单检查(若用到空间函数)\n for (const fn of ['ST_']) {\n const fnMatch = sql.match(/ST_(\\w+)/g) ?? [];\n for (const m of fnMatch) {\n if (!ALLOWED_SPATIAL_FUNCTIONS.includes(m)) {\n issues.push({ severity: 'error', rule: 'spatial_whitelist', message: `空间函数 ${m} 不在白名单内` });\n }\n }\n }\n\n return { valid: issues.every((i) => i.severity !== 'error'), issues };\n}\n\n/** 参数化:把 SQL 中的字符串字面量替换为 $n 占位符(防注入) */\nexport function parameterize(sql: string): { sql: string; params: string[] } {\n const params: string[] = [];\n const out = sql.replace(/'([^']*)'/g, (_m, v: string) => {\n params.push(v);\n return `$${params.length}`;\n });\n return { sql: out, params };\n}\n","/**\n * NLPG v1 主入口(PRD phase-0 §5.7)\n *\n * 自然语言 → PostGIS SQL → 安全校验 → 可执行结果。\n *\n * 用法:\n * const result = nlpgQuery('查出使用超过 20 年的铸铁燃气管');\n * result.sql // 生成的 SQL\n * result.valid // 是否通过安全校验\n * result.validation // 校验详情\n */\n\nimport { generatePostGISQuery, type GeneratedQuery, type GenerateOptions } from './sqlGenerator';\nimport { validateSql, parameterize, type ValidationResult } from './sqlValidator';\n\nexport interface NlpgResult {\n /** 生成的查询 */\n query: GeneratedQuery;\n /** 是否通过安全校验 */\n valid: boolean;\n /** 校验详情 */\n validation: ValidationResult;\n /** 参数化后的 SQL($n 占位符) */\n parameterized?: { sql: string; params: string[] };\n}\n\n/**\n * 自然语言查询入口。\n */\nexport function nlpgQuery(text: string, opts: GenerateOptions = {}): NlpgResult {\n const query = generatePostGISQuery(text, opts);\n const validation = validateSql(query.sql);\n const valid = validation.valid;\n const parameterized = valid ? parameterize(query.sql) : undefined;\n\n return { query, valid, validation, parameterized };\n}\n\nexport type { GeneratedQuery, GenerateOptions };\nexport { generatePostGISQuery, validateSql, parameterize };\n","/**\n * NLPG LLM 模式(PRD phase-0 §5.7 N-6「LLM 生成 SQL」)\n *\n * 在规则引擎(sqlGenerator.ts)基础上,接入 DeepSeek 实现:\n * - 复杂自然语言 → PostGIS SQL(突破固定字段/空间模板)\n * - LLM 优先,失败自动降级规则引擎\n * - 生成的 SQL 必经 sqlValidator 安全校验层方可执行\n */\n\nimport type { DeepSeekClient, ChatMessage } from '../llm/deepseek';\nimport { generatePostGISQuery, type GeneratedQuery } from './sqlGenerator';\nimport { validateSql, parameterize, DEFAULT_ALLOWED_TABLES } from './sqlValidator';\n\nexport interface LlmNlpgConfig {\n client: DeepSeekClient;\n enabled?: boolean;\n /** 授权表白名单(传给校验层) */\n allowedTables?: string[];\n}\n\ninterface LlmSqlOutput {\n sql?: string;\n table?: string;\n intent?: string;\n}\n\nconst SYSTEM_PROMPT = `你是\"草果地图\"管网自然语言查询助手。用户用中文描述数据查询需求,你生成 PostGIS SQL(仅 SELECT)。\n\n规则:\n1. 只返回 JSON:{\"sql\":\"SELECT ...\",\"table\":\"...\",\"intent\":\"...\"}\n2. 表名只能来自以下白名单:${DEFAULT_ALLOWED_TABLES.join(', ')}\n3. 空间查询可用 ST_DWithin / ST_Within / ST_Intersects / ST_Contains / ST_Buffer / ST_MakePoint / ST_SetSRID / ST_Distance / ST_AsGeoJSON / ST_Transform\n4. 只生成 SELECT 语句,禁止 DROP/DELETE/UPDATE/INSERT/ALTER 等写操作\n5. 字段名使用 snake_case,坐标使用 WGS84(SRID 4326)\n6. 不要输出 JSON 以外的任何文字。`;\n\nexport class LlmNlpg {\n private client: DeepSeekClient;\n private enabled: boolean;\n private allowedTables: string[];\n\n constructor(config: LlmNlpgConfig) {\n this.client = config.client;\n this.enabled = config.enabled ?? true;\n this.allowedTables = config.allowedTables ?? DEFAULT_ALLOWED_TABLES;\n }\n\n /**\n * 自然语言查询。\n * LLM 优先,失败或校验不过时降级到规则引擎。\n */\n async query(text: string): Promise<{ query: GeneratedQuery; valid: boolean; parameterized?: { sql: string; params: string[] } }> {\n if (this.enabled) {\n try {\n const llmResult = await this.queryWithLlm(text);\n if (llmResult) return llmResult;\n } catch {\n // 降级规则引擎\n }\n }\n return this.queryWithRules(text);\n }\n\n private async queryWithLlm(\n text: string\n ): Promise<{ query: GeneratedQuery; valid: boolean; parameterized?: { sql: string; params: string[] } } | null> {\n const messages: ChatMessage[] = [\n { role: 'system', content: SYSTEM_PROMPT },\n { role: 'user', content: text },\n ];\n const { data } = await this.client.chatJson<LlmSqlOutput>(messages);\n const sql = (data.sql ?? '').trim();\n if (!sql) return null;\n\n // 必经安全校验层\n const validation = validateSql(sql, this.allowedTables);\n if (!validation.valid) return null;\n\n const query: GeneratedQuery = {\n intent: 'mixed',\n table: data.table ?? 'pois',\n conditions: [],\n spatial: null,\n sql,\n confidence: 0.9,\n };\n return { query, valid: true, parameterized: parameterize(sql) };\n }\n\n private queryWithRules(\n text: string\n ): { query: GeneratedQuery; valid: boolean; parameterized?: { sql: string; params: string[] } } {\n const query = generatePostGISQuery(text);\n const validation = validateSql(query.sql, this.allowedTables);\n return {\n query,\n valid: validation.valid,\n parameterized: validation.valid ? parameterize(query.sql) : undefined,\n };\n }\n}\n","/**\n * DeepSeek LLM 客户端(PRD phase-0 §5.5 / §5.7 的 v1 后端能力)\n *\n * DeepSeek API 与 OpenAI Chat Completions 协议兼容:\n * base_url: https://api.deepseek.com\n * 模型: deepseek-chat(通用对话)/ deepseek-reasoner(深度推理)\n * 鉴权: Authorization: Bearer <API_KEY>\n *\n * 设计:\n * - 依赖注入的 fetch(浏览器/Node 均可运行,Node 18+ 原生 fetch)\n * - 自动重试(指数退避)\n * - 失败降级(可传入 fallback,规则引擎兜底)\n * - 支持流式(onChunk 回调)与 JSON 输出\n */\n\nexport interface DeepSeekConfig {\n /** API Key */\n apiKey: string;\n /** 基础地址,默认 https://api.deepseek.com */\n baseUrl?: string;\n /** 模型,默认 deepseek-chat */\n model?: 'deepseek-chat' | 'deepseek-reasoner' | (string & {});\n /** 温度 0-2 */\n temperature?: number;\n /** 最大 token */\n maxTokens?: number;\n /** 超时(ms),默认 30s */\n timeoutMs?: number;\n /** 重试次数,默认 2 */\n retries?: number;\n /** 注入 fetch(测试/Node 环境),默认 globalThis.fetch */\n fetchImpl?: typeof fetch;\n}\n\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface ChatOptions {\n /** 是否启用 JSON 模式(要求模型返回纯 JSON) */\n json?: boolean;\n /** 流式回调 */\n onChunk?: (delta: string) => void;\n}\n\nexport interface ChatResult {\n /** 完整回复文本 */\n content: string;\n /** 消耗 token */\n usage?: { promptTokens: number; completionTokens: number; totalTokens: number };\n /** 使用的模型 */\n model: string;\n}\n\n/** 已解析的 JSON 回复 */\nexport interface JsonChatResult<T> {\n /** 解析出的 JSON 对象 */\n data: T;\n /** 原始文本 */\n raw: string;\n model: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.deepseek.com';\nconst DEFAULT_MODEL = 'deepseek-chat';\n\n/** 把中文异常文案简化为错误码 */\nfunction normalizeError(body: string): Error {\n const err = new Error(body || 'DeepSeek API 请求失败');\n err.name = 'DeepSeekError';\n return err;\n}\n\nexport class DeepSeekClient {\n private config: Required<Omit<DeepSeekConfig, 'fetchImpl'>> & { fetchImpl: typeof fetch };\n private lastRequestId = 0;\n\n constructor(config: DeepSeekConfig) {\n if (!config.apiKey) throw new Error('DeepSeekClient: apiKey 不能为空');\n this.config = {\n apiKey: config.apiKey,\n baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, ''),\n model: config.model ?? DEFAULT_MODEL,\n temperature: config.temperature ?? 0.3,\n maxTokens: config.maxTokens ?? 2048,\n timeoutMs: config.timeoutMs ?? 30000,\n retries: config.retries ?? 2,\n fetchImpl: config.fetchImpl ?? ((globalThis as { fetch?: typeof fetch }).fetch ?? fetch),\n };\n }\n\n /** 发起一次聊天补全 */\n async chat(messages: ChatMessage[], opts: ChatOptions = {}): Promise<ChatResult> {\n return this.requestWithRetry(messages, opts);\n }\n\n /** 聊天 + JSON 解析 */\n async chatJson<T>(messages: ChatMessage[]): Promise<JsonChatResult<T>> {\n const result = await this.chat(messages, { json: true });\n const raw = result.content.trim();\n // 去除可能的 ```json 围栏\n const cleaned = raw.replace(/^```(?:json)?\\s*/i, '').replace(/\\s*```$/, '');\n let data: T;\n try {\n data = JSON.parse(cleaned) as T;\n } catch (e) {\n // 尝试从文本中提取首个 JSON 对象\n const match = cleaned.match(/\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\]/);\n if (match) {\n data = JSON.parse(match[0]) as T;\n } else {\n throw new Error(`DeepSeek 返回了非 JSON 内容: ${raw.slice(0, 200)}`);\n }\n }\n return { data, raw, model: result.model };\n }\n\n private async requestWithRetry(messages: ChatMessage[], opts: ChatOptions): Promise<ChatResult> {\n let lastError: Error | null = null;\n for (let attempt = 0; attempt <= this.config.retries; attempt++) {\n try {\n return await this.requestOnce(messages, opts);\n } catch (e) {\n lastError = e as Error;\n // 仅对可重试错误(网络/429/5xx)重试\n const retryable = !(e instanceof Error) || !e.name.includes('DeepSeek') || this.isRetryable(e as Error);\n if (!retryable && !this.isRetryable(e as Error)) break;\n if (attempt < this.config.retries) {\n await this.sleep(Math.min(1000 * 2 ** attempt, 8000));\n }\n }\n }\n throw lastError ?? new Error('DeepSeek 请求失败');\n }\n\n private isRetryable(err: Error): boolean {\n const msg = err.message ?? '';\n return /429|500|502|503|504|timeout|network|ECONN|abort|fetch failed/i.test(msg);\n }\n\n private async requestOnce(messages: ChatMessage[], opts: ChatOptions): Promise<ChatResult> {\n const { fetchImpl } = this.config;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.config.timeoutMs);\n\n const body: Record<string, unknown> = {\n model: this.config.model,\n messages,\n temperature: this.config.temperature,\n max_tokens: this.config.maxTokens,\n stream: Boolean(opts.onChunk),\n };\n if (opts.json) {\n body.response_format = { type: 'json_object' };\n }\n\n try {\n const res = await fetchImpl(`${this.config.baseUrl}/chat/completions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.config.apiKey}`,\n },\n body: JSON.stringify(body),\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n throw normalizeError(`DeepSeek HTTP ${res.status}: ${text}`);\n }\n\n // 流式\n if (opts.onChunk && res.body) {\n return this.parseStream(res.body, opts.onChunk);\n }\n\n // 非流式\n const json = (await res.json()) as {\n choices: Array<{ message: { content: string } }>;\n usage?: { prompt_tokens: number; completion_tokens: number; total_tokens: number };\n model?: string;\n };\n const content = json.choices?.[0]?.message?.content ?? '';\n return {\n content,\n model: json.model ?? this.config.model,\n usage: json.usage\n ? { promptTokens: json.usage.prompt_tokens, completionTokens: json.usage.completion_tokens, totalTokens: json.usage.total_tokens }\n : undefined,\n };\n } finally {\n clearTimeout(timer);\n }\n }\n\n /** 解析 SSE 流式响应 */\n private async parseStream(\n body: ReadableStream<Uint8Array>,\n onChunk: (delta: string) => void\n ): Promise<ChatResult> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let content = '';\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('data:')) continue;\n const data = trimmed.slice(5).trim();\n if (data === '[DONE]') continue;\n try {\n const json = JSON.parse(data) as { choices?: Array<{ delta?: { content?: string } }> };\n const delta = json.choices?.[0]?.delta?.content ?? '';\n if (delta) {\n content += delta;\n onChunk(delta);\n }\n } catch {\n // 忽略无法解析的行\n }\n }\n }\n return { content, model: this.config.model };\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n }\n}\n\n/** 便捷工厂:创建默认配置的客户端 */\nexport function createDeepSeekClient(config: DeepSeekConfig): DeepSeekClient {\n return new DeepSeekClient(config);\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,2 +1,6 @@
1
1
  export { DIAGNOSIS_RULES, DebugReport, MemoryLeakReport, MemorySnapshot, ProfilerIssue, ProfilerMetrics, TileMetrics, TileMonitorReport, analyzePerformance, analyzeTiles, detectMemoryLeak, diagnose, suggestOptimizations } from './debug/index.cjs';
2
2
  export { BrandStyleOptions, CARRIER_STYLES, ColorScheme, GeneratedMapStyle, INDUSTRY_TEMPLATES, IndustryStyle, adjustBrightness, extractDominantColor, generateBrandStyle, generateCarrierStyle, generateIndustryStyle, toggleMode } from './stylegen/index.cjs';
3
+ export { COLOR_NAMES, CopilotIntent, CopilotParams, CopilotResult, LlmCopilotConfig, LlmMapCopilot, MapCopilot, PLACE_COORDINATES, classifyIntent, extractParams, generateCode, generateFromQuery } from './copilot/index.cjs';
4
+ export { BatchGeocodeInput, BatchGeocodeOutput, CHINA_BOUNDS, DetectedCRS, GeocodeResult, HeaderDetection, ImportOptions, ImportResult, ImportStats, ImportedFeature, LOCAL_GEO_DB, ParsedAddress, batchGeocode, detectCRS, detectHeaders, gcj02ToWgs84, geocode, hasLocalGeo, importToGeoJSON, isInChina, isValidAddress, parseAddress, wgs84ToGcj02 } from './geoai/index.cjs';
5
+ export { AttributeCondition, DEFAULT_ALLOWED_TABLES, GenerateOptions, GeneratedQuery, LlmNlpg, LlmNlpgConfig, NlpgIntent, NlpgResult, Operator, SpatialCondition, ValidationIssue, ValidationResult, detectField, detectSpatial, detectTable, detectValue, generatePostGISQuery, nlpgQuery, parameterize, validateSql } from './nlpg/index.cjs';
6
+ export { ChatMessage, ChatOptions, ChatResult, DeepSeekClient, DeepSeekConfig, JsonChatResult, createDeepSeekClient } from './llm/index.cjs';
package/dist/index.d.ts CHANGED
@@ -1,2 +1,6 @@
1
1
  export { DIAGNOSIS_RULES, DebugReport, MemoryLeakReport, MemorySnapshot, ProfilerIssue, ProfilerMetrics, TileMetrics, TileMonitorReport, analyzePerformance, analyzeTiles, detectMemoryLeak, diagnose, suggestOptimizations } from './debug/index.js';
2
2
  export { BrandStyleOptions, CARRIER_STYLES, ColorScheme, GeneratedMapStyle, INDUSTRY_TEMPLATES, IndustryStyle, adjustBrightness, extractDominantColor, generateBrandStyle, generateCarrierStyle, generateIndustryStyle, toggleMode } from './stylegen/index.js';
3
+ export { COLOR_NAMES, CopilotIntent, CopilotParams, CopilotResult, LlmCopilotConfig, LlmMapCopilot, MapCopilot, PLACE_COORDINATES, classifyIntent, extractParams, generateCode, generateFromQuery } from './copilot/index.js';
4
+ export { BatchGeocodeInput, BatchGeocodeOutput, CHINA_BOUNDS, DetectedCRS, GeocodeResult, HeaderDetection, ImportOptions, ImportResult, ImportStats, ImportedFeature, LOCAL_GEO_DB, ParsedAddress, batchGeocode, detectCRS, detectHeaders, gcj02ToWgs84, geocode, hasLocalGeo, importToGeoJSON, isInChina, isValidAddress, parseAddress, wgs84ToGcj02 } from './geoai/index.js';
5
+ export { AttributeCondition, DEFAULT_ALLOWED_TABLES, GenerateOptions, GeneratedQuery, LlmNlpg, LlmNlpgConfig, NlpgIntent, NlpgResult, Operator, SpatialCondition, ValidationIssue, ValidationResult, detectField, detectSpatial, detectTable, detectValue, generatePostGISQuery, nlpgQuery, parameterize, validateSql } from './nlpg/index.js';
6
+ export { ChatMessage, ChatOptions, ChatResult, DeepSeekClient, DeepSeekConfig, JsonChatResult, createDeepSeekClient } from './llm/index.js';
package/dist/index.js CHANGED
@@ -1,4 +1,8 @@
1
1
  export { DIAGNOSIS_RULES, analyzePerformance, analyzeTiles, detectMemoryLeak, diagnose, suggestOptimizations } from './chunk-KDLFIBBY.js';
2
2
  export { CARRIER_STYLES, INDUSTRY_TEMPLATES, adjustBrightness, extractDominantColor, generateBrandStyle, generateCarrierStyle, generateIndustryStyle, toggleMode } from './chunk-KNL3QRD2.js';
3
+ export { COLOR_NAMES, LlmMapCopilot, MapCopilot, PLACE_COORDINATES, classifyIntent, extractParams, generateCode, generateFromQuery } from './chunk-55G7QUFA.js';
4
+ export { CHINA_BOUNDS, LOCAL_GEO_DB, batchGeocode, detectCRS, detectHeaders, gcj02ToWgs84, geocode, hasLocalGeo, importToGeoJSON, isInChina, isValidAddress, parseAddress, wgs84ToGcj02 } from './chunk-HF3HJPXD.js';
5
+ export { DEFAULT_ALLOWED_TABLES, LlmNlpg, detectField, detectSpatial, detectTable, detectValue, generatePostGISQuery, nlpgQuery, parameterize, validateSql } from './chunk-ARYB2X4B.js';
6
+ export { DeepSeekClient, createDeepSeekClient } from './chunk-ZI6ZF26Q.js';
3
7
  //# sourceMappingURL=index.js.map
4
8
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,152 @@
1
+ 'use strict';
2
+
3
+ // src/llm/deepseek.ts
4
+ var DEFAULT_BASE_URL = "https://api.deepseek.com";
5
+ var DEFAULT_MODEL = "deepseek-chat";
6
+ function normalizeError(body) {
7
+ const err = new Error(body || "DeepSeek API \u8BF7\u6C42\u5931\u8D25");
8
+ err.name = "DeepSeekError";
9
+ return err;
10
+ }
11
+ var DeepSeekClient = class {
12
+ config;
13
+ lastRequestId = 0;
14
+ constructor(config) {
15
+ if (!config.apiKey) throw new Error("DeepSeekClient: apiKey \u4E0D\u80FD\u4E3A\u7A7A");
16
+ this.config = {
17
+ apiKey: config.apiKey,
18
+ baseUrl: (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, ""),
19
+ model: config.model ?? DEFAULT_MODEL,
20
+ temperature: config.temperature ?? 0.3,
21
+ maxTokens: config.maxTokens ?? 2048,
22
+ timeoutMs: config.timeoutMs ?? 3e4,
23
+ retries: config.retries ?? 2,
24
+ fetchImpl: config.fetchImpl ?? (globalThis.fetch ?? fetch)
25
+ };
26
+ }
27
+ /** 发起一次聊天补全 */
28
+ async chat(messages, opts = {}) {
29
+ return this.requestWithRetry(messages, opts);
30
+ }
31
+ /** 聊天 + JSON 解析 */
32
+ async chatJson(messages) {
33
+ const result = await this.chat(messages, { json: true });
34
+ const raw = result.content.trim();
35
+ const cleaned = raw.replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
36
+ let data;
37
+ try {
38
+ data = JSON.parse(cleaned);
39
+ } catch (e) {
40
+ const match = cleaned.match(/\{[\s\S]*\}|\[[\s\S]*\]/);
41
+ if (match) {
42
+ data = JSON.parse(match[0]);
43
+ } else {
44
+ throw new Error(`DeepSeek \u8FD4\u56DE\u4E86\u975E JSON \u5185\u5BB9: ${raw.slice(0, 200)}`);
45
+ }
46
+ }
47
+ return { data, raw, model: result.model };
48
+ }
49
+ async requestWithRetry(messages, opts) {
50
+ let lastError = null;
51
+ for (let attempt = 0; attempt <= this.config.retries; attempt++) {
52
+ try {
53
+ return await this.requestOnce(messages, opts);
54
+ } catch (e) {
55
+ lastError = e;
56
+ const retryable = !(e instanceof Error) || !e.name.includes("DeepSeek") || this.isRetryable(e);
57
+ if (!retryable && !this.isRetryable(e)) break;
58
+ if (attempt < this.config.retries) {
59
+ await this.sleep(Math.min(1e3 * 2 ** attempt, 8e3));
60
+ }
61
+ }
62
+ }
63
+ throw lastError ?? new Error("DeepSeek \u8BF7\u6C42\u5931\u8D25");
64
+ }
65
+ isRetryable(err) {
66
+ const msg = err.message ?? "";
67
+ return /429|500|502|503|504|timeout|network|ECONN|abort|fetch failed/i.test(msg);
68
+ }
69
+ async requestOnce(messages, opts) {
70
+ const { fetchImpl } = this.config;
71
+ const controller = new AbortController();
72
+ const timer = setTimeout(() => controller.abort(), this.config.timeoutMs);
73
+ const body = {
74
+ model: this.config.model,
75
+ messages,
76
+ temperature: this.config.temperature,
77
+ max_tokens: this.config.maxTokens,
78
+ stream: Boolean(opts.onChunk)
79
+ };
80
+ if (opts.json) {
81
+ body.response_format = { type: "json_object" };
82
+ }
83
+ try {
84
+ const res = await fetchImpl(`${this.config.baseUrl}/chat/completions`, {
85
+ method: "POST",
86
+ headers: {
87
+ "Content-Type": "application/json",
88
+ Authorization: `Bearer ${this.config.apiKey}`
89
+ },
90
+ body: JSON.stringify(body),
91
+ signal: controller.signal
92
+ });
93
+ if (!res.ok) {
94
+ const text = await res.text().catch(() => "");
95
+ throw normalizeError(`DeepSeek HTTP ${res.status}: ${text}`);
96
+ }
97
+ if (opts.onChunk && res.body) {
98
+ return this.parseStream(res.body, opts.onChunk);
99
+ }
100
+ const json = await res.json();
101
+ const content = json.choices?.[0]?.message?.content ?? "";
102
+ return {
103
+ content,
104
+ model: json.model ?? this.config.model,
105
+ usage: json.usage ? { promptTokens: json.usage.prompt_tokens, completionTokens: json.usage.completion_tokens, totalTokens: json.usage.total_tokens } : void 0
106
+ };
107
+ } finally {
108
+ clearTimeout(timer);
109
+ }
110
+ }
111
+ /** 解析 SSE 流式响应 */
112
+ async parseStream(body, onChunk) {
113
+ const reader = body.getReader();
114
+ const decoder = new TextDecoder();
115
+ let content = "";
116
+ let buffer = "";
117
+ while (true) {
118
+ const { done, value } = await reader.read();
119
+ if (done) break;
120
+ buffer += decoder.decode(value, { stream: true });
121
+ const lines = buffer.split("\n");
122
+ buffer = lines.pop() ?? "";
123
+ for (const line of lines) {
124
+ const trimmed = line.trim();
125
+ if (!trimmed.startsWith("data:")) continue;
126
+ const data = trimmed.slice(5).trim();
127
+ if (data === "[DONE]") continue;
128
+ try {
129
+ const json = JSON.parse(data);
130
+ const delta = json.choices?.[0]?.delta?.content ?? "";
131
+ if (delta) {
132
+ content += delta;
133
+ onChunk(delta);
134
+ }
135
+ } catch {
136
+ }
137
+ }
138
+ }
139
+ return { content, model: this.config.model };
140
+ }
141
+ sleep(ms) {
142
+ return new Promise((r) => setTimeout(r, ms));
143
+ }
144
+ };
145
+ function createDeepSeekClient(config) {
146
+ return new DeepSeekClient(config);
147
+ }
148
+
149
+ exports.DeepSeekClient = DeepSeekClient;
150
+ exports.createDeepSeekClient = createDeepSeekClient;
151
+ //# sourceMappingURL=index.cjs.map
152
+ //# sourceMappingURL=index.cjs.map