@fragments-sdk/mcp 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from 'module'; const require = createRequire(import.meta.url);
3
3
  import {
4
4
  startMcpServer
5
- } from "./chunk-RUZV6VLE.js";
5
+ } from "./chunk-OQOBENAX.js";
6
6
  import "./chunk-7OMNY6JX.js";
7
7
 
8
8
  // src/bin.ts
@@ -13,8 +13,8 @@ import {
13
13
  ListToolsRequestSchema
14
14
  } from "@modelcontextprotocol/sdk/types.js";
15
15
  import { readFile } from "fs/promises";
16
- import { existsSync } from "fs";
17
- import { join } from "path";
16
+ import { existsSync, readFileSync } from "fs";
17
+ import { join, dirname, resolve } from "path";
18
18
 
19
19
  // src/utils.ts
20
20
  function projectFields(obj, fields) {
@@ -378,18 +378,66 @@ function createMcpServer(config) {
378
378
  let storageManager = null;
379
379
  let diffEngine = null;
380
380
  let isPoolWarming = false;
381
+ function findFragmentsJson(startDir) {
382
+ const found = [];
383
+ const resolvedStart = resolve(startDir);
384
+ let dir = resolvedStart;
385
+ while (true) {
386
+ const candidate = join(dir, BRAND.outFile);
387
+ if (existsSync(candidate)) {
388
+ found.push(candidate);
389
+ break;
390
+ }
391
+ const parent = dirname(dir);
392
+ if (parent === dir) break;
393
+ dir = parent;
394
+ }
395
+ const pkgJsonPath = join(resolvedStart, "package.json");
396
+ if (existsSync(pkgJsonPath)) {
397
+ try {
398
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
399
+ const allDeps = {
400
+ ...pkgJson.dependencies,
401
+ ...pkgJson.devDependencies
402
+ };
403
+ for (const depName of Object.keys(allDeps)) {
404
+ const depPkgPath = join(resolvedStart, "node_modules", depName, "package.json");
405
+ if (!existsSync(depPkgPath)) continue;
406
+ try {
407
+ const depPkg = JSON.parse(readFileSync(depPkgPath, "utf-8"));
408
+ if (depPkg.fragments) {
409
+ const fragmentsPath = join(resolvedStart, "node_modules", depName, depPkg.fragments);
410
+ if (existsSync(fragmentsPath) && !found.includes(fragmentsPath)) {
411
+ found.push(fragmentsPath);
412
+ }
413
+ }
414
+ } catch {
415
+ }
416
+ }
417
+ } catch {
418
+ }
419
+ }
420
+ return found;
421
+ }
381
422
  async function loadSegments() {
382
423
  if (segmentsData) {
383
424
  return segmentsData;
384
425
  }
385
- const segmentsPath = join(config.projectRoot, BRAND.outFile);
386
- if (!existsSync(segmentsPath)) {
426
+ const paths = findFragmentsJson(config.projectRoot);
427
+ if (paths.length === 0) {
387
428
  throw new Error(
388
- `No ${BRAND.outFile} found. Run \`${BRAND.cliCommand} build\` first.`
429
+ `No ${BRAND.outFile} found. Searched ${config.projectRoot} and package.json dependencies. Either run \`${BRAND.cliCommand} build\` or install a package with a "fragments" field in its package.json.`
389
430
  );
390
431
  }
391
- const content = await readFile(segmentsPath, "utf-8");
432
+ const content = await readFile(paths[0], "utf-8");
392
433
  segmentsData = JSON.parse(content);
434
+ for (let i = 1; i < paths.length; i++) {
435
+ const extra = JSON.parse(await readFile(paths[i], "utf-8"));
436
+ Object.assign(segmentsData.segments, extra.segments);
437
+ if (extra.recipes) {
438
+ segmentsData.recipes = { ...segmentsData.recipes, ...extra.recipes };
439
+ }
440
+ }
393
441
  return segmentsData;
394
442
  }
395
443
  async function getPackageName() {
@@ -1261,4 +1309,4 @@ export {
1261
1309
  createMcpServer,
1262
1310
  startMcpServer
1263
1311
  };
1264
- //# sourceMappingURL=chunk-RUZV6VLE.js.map
1312
+ //# sourceMappingURL=chunk-OQOBENAX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.ts","../src/utils.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n BRAND,\n DEFAULTS,\n generateContext,\n type CompiledSegmentsFile,\n type VerifyResult,\n type Theme,\n} from '@fragments/core';\n// @fragments/service is lazy-imported to avoid requiring playwright at startup.\n// Visual tools (verify, render, compare, fix) load it on first use.\ntype ServiceModule = typeof import('@fragments/service');\nlet _service: ServiceModule | null = null;\nasync function getService(): Promise<ServiceModule> {\n if (!_service) {\n try {\n _service = await import('@fragments/service');\n } catch {\n throw new Error(\n 'Visual tools require playwright. Install it with: npm install playwright'\n );\n }\n }\n return _service;\n}\nimport { readFile } from 'node:fs/promises';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join, dirname, resolve } from 'node:path';\nimport { projectFields } from './utils.js';\n\n/**\n * MCP Tool names - derived from BRAND constants\n */\nconst TOOL_NAMES = {\n list: `${BRAND.nameLower}_list`,\n suggest: `${BRAND.nameLower}_suggest`,\n get: `${BRAND.nameLower}_get`,\n guidelines: `${BRAND.nameLower}_guidelines`,\n alternatives: `${BRAND.nameLower}_alternatives`,\n example: `${BRAND.nameLower}_example`,\n verify: `${BRAND.nameLower}_verify`,\n context: `${BRAND.nameLower}_context`,\n render: `${BRAND.nameLower}_render`,\n compare: `${BRAND.nameLower}_compare`,\n fix: `${BRAND.nameLower}_fix`,\n recipe: `${BRAND.nameLower}_recipe`,\n} as const;\n\n/**\n * Placeholder patterns to filter out from usage text.\n * These are auto-generated and provide no value to AI agents.\n */\nconst PLACEHOLDER_PATTERNS = [\n /^\\w+ component is needed$/i,\n /^Alternative component is more appropriate$/i,\n /^Use \\w+ when you need/i,\n];\n\n/**\n * Filter out placeholder text from usage arrays\n */\nfunction filterPlaceholders(items: string[] | undefined): string[] {\n if (!items) return [];\n return items.filter(item =>\n !PLACEHOLDER_PATTERNS.some(pattern => pattern.test(item.trim()))\n );\n}\n\n/**\n * MCP Server configuration\n */\nexport interface McpServerConfig {\n /** Project root directory */\n projectRoot: string;\n\n /** Viewer base URL */\n viewerUrl?: string;\n\n /** Default theme for verification */\n theme?: Theme;\n\n /** Diff threshold percentage */\n threshold?: number;\n}\n\n/**\n * Tool definitions for the MCP server\n */\nconst TOOLS: Tool[] = [\n {\n name: TOOL_NAMES.list,\n description: `List all available component fragments in the design system. Returns component names, categories, descriptions, and variant counts. Use this FIRST to discover what components exist before implementing any UI.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n category: {\n type: 'string',\n description: 'Filter by category (e.g., \"actions\", \"forms\", \"layout\")',\n },\n search: {\n type: 'string',\n description: 'Search term to filter by name, description, or tags',\n },\n status: {\n type: 'string',\n enum: ['stable', 'beta', 'deprecated', 'experimental'],\n description: 'Filter by component status',\n },\n },\n },\n },\n {\n name: TOOL_NAMES.suggest,\n description: `Given a use case or UI requirement, suggest the most appropriate component(s) from the design system. Use this when you're unsure which component to use for a specific task. Returns ranked suggestions with explanations.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n useCase: {\n type: 'string',\n description: 'Description of what you want to build (e.g., \"form for user email input\", \"button to submit data\", \"display a list of items\")',\n },\n context: {\n type: 'string',\n description: 'Additional context (e.g., \"in a modal\", \"for mobile\", \"destructive action\")',\n },\n },\n required: ['useCase'],\n },\n },\n {\n name: TOOL_NAMES.get,\n description: `Get detailed information about a specific component fragment including props, usage guidelines, and variants. Use this AFTER fragments_list or fragments_suggest to understand a component's API and best practices before implementing. Use 'fields' to request only specific data for token efficiency.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n fields: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific fields to return (e.g., [\"meta\", \"usage.when\", \"contract.propsSummary\", \"props\"]). If omitted, returns all fields. Supports dot notation for nested fields.',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.guidelines,\n description: `Get the usage guidelines for a component - when to use it, when NOT to use it, and best practices. Use this to make the right component choice and avoid common mistakes. Use 'fields' to request only specific data for token efficiency.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n fields: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific fields to return (e.g., [\"when\", \"whenNot\", \"accessibility\"]). If omitted, returns all guideline fields.',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.alternatives,\n description: `Get alternative and related components for a given component. Use this when a component might not be the right fit, or to understand the component ecosystem.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name to find alternatives for',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.example,\n description: `Get example code for a component variant. Returns ready-to-use code with props demonstrated. Use this when you need to see HOW to implement a component, not just what props it accepts.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n variant: {\n type: 'string',\n description: 'Variant name (e.g., \"Default\", \"Primary\"). If omitted, returns all variants.',\n },\n maxExamples: {\n type: 'number',\n description: 'Maximum number of examples to return (default: all)',\n },\n maxLines: {\n type: 'number',\n description: 'Maximum lines per code example (truncates longer examples)',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.verify,\n description: `Verify a component render against the baseline screenshot. Use this AFTER implementing or modifying a component to ensure visual consistency with the design system. Returns a diff percentage and visual comparison.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name to verify',\n },\n variant: {\n type: 'string',\n description: 'Variant name to verify',\n },\n theme: {\n type: 'string',\n enum: ['light', 'dark'],\n description: 'Theme to verify (default: light)',\n },\n threshold: {\n type: 'number',\n description: 'Diff threshold percentage (default: 5)',\n },\n },\n required: ['component', 'variant'],\n },\n },\n {\n name: TOOL_NAMES.context,\n description: `Get the complete design system context in a single call. Use this FIRST before any implementation to understand all available components in a token-efficient format. Returns a summary of all components with their categories, usage guidelines, props, and variants.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n format: {\n type: 'string',\n enum: ['markdown', 'json'],\n description: 'Output format (default: markdown)',\n },\n compact: {\n type: 'boolean',\n description: 'If true, returns minimal output (just component names and categories)',\n },\n includeCode: {\n type: 'boolean',\n description: 'If true, includes code examples for each variant',\n },\n includeRelations: {\n type: 'boolean',\n description: 'If true, includes component relationships',\n },\n },\n },\n },\n {\n name: TOOL_NAMES.render,\n description: `Render a design system component with specific props and return a screenshot. Use this to VERIFY your UI implementation looks correct. The AI can see what the component looks like and iterate until it's right.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Card\", \"Input\")',\n },\n props: {\n type: 'object',\n description: 'Props to pass to the component (e.g., { \"variant\": \"primary\", \"children\": \"Click me\" })',\n },\n viewport: {\n type: 'object',\n properties: {\n width: { type: 'number', description: 'Viewport width (default: 800)' },\n height: { type: 'number', description: 'Viewport height (default: 600)' },\n },\n description: 'Optional viewport size for the render',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.compare,\n description: `Compare a rendered component against its Figma design. Returns diff percentage and highlighted differences. Use this to verify your implementation matches the design spec. If the component has a figma URL in its fragment definition, no URL is needed.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n variant: {\n type: 'string',\n description: 'Variant name (optional, uses first variant if not specified)',\n },\n props: {\n type: 'object',\n description: 'Props to render with',\n },\n figmaUrl: {\n type: 'string',\n description: 'Figma frame URL (optional if segment has figma link)',\n },\n threshold: {\n type: 'number',\n description: 'Max acceptable diff percentage (default: 1.0)',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.fix,\n description: `Generate patches to fix token compliance issues in a component. Returns unified diff patches that replace hardcoded CSS values with design token references. Use this after fragments_verify identifies issues to automatically fix them.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name to generate fixes for (e.g., \"Button\", \"Card\")',\n },\n variant: {\n type: 'string',\n description: 'Specific variant to fix (optional, fixes all variants if omitted)',\n },\n fixType: {\n type: 'string',\n enum: ['token', 'all'],\n description: 'Type of fixes to generate: \"token\" for hardcoded→token replacements, \"all\" for all available fixes (default: \"all\")',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.recipe,\n description: `Search and retrieve composition recipes — named patterns showing how design system components wire together for common use cases (e.g., \"Login Form\", \"Settings Page\"). Returns the recipe with its code pattern.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n name: {\n type: 'string',\n description: 'Exact recipe name to retrieve (e.g., \"Login Form\")',\n },\n search: {\n type: 'string',\n description: 'Free-text search across recipe names, descriptions, tags, and components',\n },\n component: {\n type: 'string',\n description: 'Filter recipes that use a specific component (e.g., \"Button\")',\n },\n },\n },\n },\n];\n\n/**\n * Create and configure the MCP server\n */\nexport function createMcpServer(config: McpServerConfig): Server {\n const server = new Server(\n {\n name: `${BRAND.nameLower}-mcp`,\n version: '0.0.1',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // Lazy-loaded resources\n let segmentsData: CompiledSegmentsFile | null = null;\n let packageName: string | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- lazy-loaded from @fragments/service\n let browserPool: any = null;\n let storageManager: any = null;\n let diffEngine: any = null;\n let isPoolWarming = false;\n\n /**\n * Find fragments.json files:\n * 1. Walk up from projectRoot (for library authors with a local build)\n * 2. Read package.json deps and resolve packages with a \"fragments\" field\n */\n function findFragmentsJson(startDir: string): string[] {\n const found: string[] = [];\n const resolvedStart = resolve(startDir);\n\n // 1. Walk upward from startDir (library author flow)\n let dir = resolvedStart;\n while (true) {\n const candidate = join(dir, BRAND.outFile);\n if (existsSync(candidate)) {\n found.push(candidate);\n break;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n // 2. Read package.json and resolve deps with \"fragments\" field\n const pkgJsonPath = join(resolvedStart, 'package.json');\n if (existsSync(pkgJsonPath)) {\n try {\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));\n const allDeps = {\n ...pkgJson.dependencies,\n ...pkgJson.devDependencies,\n };\n for (const depName of Object.keys(allDeps)) {\n const depPkgPath = join(resolvedStart, 'node_modules', depName, 'package.json');\n if (!existsSync(depPkgPath)) continue;\n try {\n const depPkg = JSON.parse(readFileSync(depPkgPath, 'utf-8'));\n if (depPkg.fragments) {\n const fragmentsPath = join(resolvedStart, 'node_modules', depName, depPkg.fragments);\n if (existsSync(fragmentsPath) && !found.includes(fragmentsPath)) {\n found.push(fragmentsPath);\n }\n }\n } catch {\n // Skip unreadable package\n }\n }\n } catch {\n // No package.json or unreadable\n }\n }\n\n return found;\n }\n\n async function loadSegments(): Promise<CompiledSegmentsFile> {\n if (segmentsData) {\n return segmentsData;\n }\n\n const paths = findFragmentsJson(config.projectRoot);\n\n if (paths.length === 0) {\n throw new Error(\n `No ${BRAND.outFile} found. Searched ${config.projectRoot} and package.json dependencies. ` +\n `Either run \\`${BRAND.cliCommand} build\\` or install a package with a \"fragments\" field in its package.json.`\n );\n }\n\n // Load and merge all found fragments files\n const content = await readFile(paths[0], 'utf-8');\n segmentsData = JSON.parse(content) as CompiledSegmentsFile;\n\n for (let i = 1; i < paths.length; i++) {\n const extra = JSON.parse(await readFile(paths[i], 'utf-8')) as CompiledSegmentsFile;\n Object.assign(segmentsData.segments, extra.segments);\n if (extra.recipes) {\n segmentsData.recipes = { ...segmentsData.recipes, ...extra.recipes };\n }\n }\n\n return segmentsData;\n }\n\n /**\n * Get the package name from package.json for import statements\n */\n async function getPackageName(): Promise<string> {\n if (packageName) {\n return packageName;\n }\n\n const packageJsonPath = join(config.projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content) as { name?: string };\n if (pkg.name) {\n packageName = pkg.name;\n return packageName;\n }\n } catch {\n // Fall through to default\n }\n }\n\n // Default fallback\n packageName = 'your-component-library';\n return packageName;\n }\n\n /**\n * Get or create browser pool with extended idle timeout for MCP\n */\n async function getBrowserPool() {\n if (!browserPool) {\n const { BrowserPool } = await getService();\n browserPool = new BrowserPool({\n viewport: DEFAULTS.viewport,\n // 30 minute idle timeout for MCP - server runs continuously\n idleTimeoutMs: 30 * 60 * 1000,\n poolSize: 2, // Keep 2 contexts warm for faster captures\n });\n }\n return browserPool;\n }\n\n /**\n * Pre-warm browser pool in background (non-blocking)\n */\n function warmBrowserPool(): void {\n if (isPoolWarming || browserPool?.isReady) {\n return;\n }\n isPoolWarming = true;\n\n // Warm in background - don't await\n getBrowserPool().then((pool) => {\n pool.warmup().then(() => {\n isPoolWarming = false;\n }).catch(() => {\n isPoolWarming = false;\n });\n }).catch(() => {\n isPoolWarming = false;\n });\n }\n\n /**\n * Get or create storage manager\n */\n async function getStorageManager() {\n if (!storageManager) {\n const { StorageManager } = await getService();\n storageManager = new StorageManager({\n projectRoot: config.projectRoot,\n });\n await storageManager.initialize();\n }\n return storageManager;\n }\n\n /**\n * Get or create diff engine\n */\n async function getDiffEngine() {\n if (!diffEngine) {\n const { DiffEngine } = await getService();\n diffEngine = new DiffEngine(config.threshold ?? DEFAULTS.diffThreshold);\n }\n return diffEngine;\n }\n\n // Register tool listing\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: TOOLS };\n });\n\n // Register tool execution\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case TOOL_NAMES.list: {\n const data = await loadSegments();\n const category = (args?.category as string) ?? undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const status = (args?.status as string) ?? undefined;\n\n const segments = Object.values(data.segments)\n .filter((s) => {\n // Category filter\n if (category && s.meta.category !== category) return false;\n\n // Status filter\n if (status && (s.meta.status ?? 'stable') !== status) return false;\n\n // Search filter - matches name, description, or tags\n if (search) {\n const nameMatch = s.meta.name.toLowerCase().includes(search);\n const descMatch = s.meta.description?.toLowerCase().includes(search);\n const tagMatch = s.meta.tags?.some((t) => t.toLowerCase().includes(search));\n if (!nameMatch && !descMatch && !tagMatch) return false;\n }\n\n return true;\n })\n .map((s) => ({\n name: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n status: s.meta.status ?? 'stable',\n variantCount: s.variants.length,\n tags: s.meta.tags ?? [],\n }));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n total: segments.length,\n segments,\n categories: [...new Set(segments.map((s) => s.category))],\n hint: segments.length === 0\n ? 'No components found. Try broader search terms or check available categories.'\n : segments.length > 5\n ? 'Use fragments_suggest for use-case based recommendations, or fragments_get for details on a specific component.'\n : undefined,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.suggest: {\n const data = await loadSegments();\n const useCase = (args?.useCase as string)?.toLowerCase() ?? '';\n const context = (args?.context as string)?.toLowerCase() ?? '';\n\n if (!useCase) {\n throw new Error('useCase is required');\n }\n\n // Build search terms from use case and context\n const searchTerms = `${useCase} ${context}`.split(/\\s+/).filter(Boolean);\n\n // Common synonyms and related terms for better matching\n const synonymMap: Record<string, string[]> = {\n 'form': ['input', 'field', 'submit', 'validation'],\n 'input': ['form', 'field', 'text', 'entry'],\n 'button': ['action', 'click', 'submit', 'trigger'],\n 'action': ['button', 'click', 'trigger'],\n 'alert': ['notification', 'message', 'warning', 'error', 'feedback'],\n 'notification': ['alert', 'message', 'toast'],\n 'card': ['container', 'panel', 'box', 'content'],\n 'toggle': ['switch', 'checkbox', 'boolean', 'on/off'],\n 'switch': ['toggle', 'checkbox', 'boolean'],\n 'badge': ['tag', 'label', 'status', 'indicator'],\n 'status': ['badge', 'indicator', 'state'],\n 'login': ['auth', 'signin', 'authentication', 'form'],\n 'auth': ['login', 'signin', 'authentication'],\n };\n\n // Expand search terms with synonyms\n const expandedTerms = new Set(searchTerms);\n searchTerms.forEach(term => {\n const synonyms = synonymMap[term];\n if (synonyms) {\n synonyms.forEach(syn => expandedTerms.add(syn));\n }\n });\n\n // Score each component based on relevance\n const scored = Object.values(data.segments).map((s) => {\n let score = 0;\n const reasons: string[] = [];\n\n // Check name match (exact terms get higher score)\n const nameLower = s.meta.name.toLowerCase();\n if (searchTerms.some((term) => nameLower.includes(term))) {\n score += 15;\n reasons.push(`Name matches search`);\n } else if (Array.from(expandedTerms).some((term) => nameLower.includes(term))) {\n score += 8;\n reasons.push(`Name matches related term`);\n }\n\n // Check description match\n const desc = s.meta.description?.toLowerCase() ?? '';\n const descMatches = searchTerms.filter((term) => desc.includes(term));\n if (descMatches.length > 0) {\n score += descMatches.length * 6;\n reasons.push(`Description matches: ${descMatches.join(', ')}`);\n }\n\n // Check tags match\n const tags = s.meta.tags?.map((t) => t.toLowerCase()) ?? [];\n const tagMatches = searchTerms.filter((term) =>\n tags.some((tag) => tag.includes(term))\n );\n if (tagMatches.length > 0) {\n score += tagMatches.length * 4;\n reasons.push(`Tags match: ${tagMatches.join(', ')}`);\n }\n\n // Check usage.when match (high weight - this is semantic intent)\n const whenUsed = s.usage?.when?.join(' ').toLowerCase() ?? '';\n const whenMatches = searchTerms.filter((term) => whenUsed.includes(term));\n if (whenMatches.length > 0) {\n score += whenMatches.length * 10;\n reasons.push(`Use cases match: \"${whenMatches.join(', ')}\"`);\n }\n\n // Also check expanded terms in usage.when\n const expandedWhenMatches = Array.from(expandedTerms).filter(\n (term) => !searchTerms.includes(term) && whenUsed.includes(term)\n );\n if (expandedWhenMatches.length > 0) {\n score += expandedWhenMatches.length * 5;\n reasons.push(`Related use cases: \"${expandedWhenMatches.join(', ')}\"`);\n }\n\n // Check category match (higher weight for category relevance)\n const category = s.meta.category?.toLowerCase() ?? '';\n if (searchTerms.some((term) => category.includes(term))) {\n score += 8;\n reasons.push(`Category: ${s.meta.category}`);\n }\n\n // Check variant names and descriptions for additional context\n const variantText = s.variants\n .map(v => `${v.name} ${v.description || ''}`.toLowerCase())\n .join(' ');\n const variantMatches = searchTerms.filter(term => variantText.includes(term));\n if (variantMatches.length > 0) {\n score += variantMatches.length * 3;\n reasons.push(`Variants match: ${variantMatches.join(', ')}`);\n }\n\n // Boost stable components\n if (s.meta.status === 'stable') {\n score += 5;\n reasons.push('Stable component');\n } else if (s.meta.status === 'beta') {\n score += 2;\n }\n\n // Penalize deprecated components\n if (s.meta.status === 'deprecated') {\n score -= 25;\n reasons.push('Deprecated - consider alternatives');\n }\n\n // Filter placeholder text from usage\n const filteredWhen = filterPlaceholders(s.usage?.when).slice(0, 3);\n const filteredWhenNot = filterPlaceholders(s.usage?.whenNot).slice(0, 2);\n\n // Calculate confidence level\n let confidence: 'high' | 'medium' | 'low';\n if (score >= 25) {\n confidence = 'high';\n } else if (score >= 15) {\n confidence = 'medium';\n } else {\n confidence = 'low';\n }\n\n return {\n component: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n score,\n confidence,\n reasons,\n usage: {\n when: filteredWhen,\n whenNot: filteredWhenNot,\n },\n variantCount: s.variants.length,\n status: s.meta.status,\n };\n });\n\n // Sort by score and filter out low-relevance results\n const MIN_SCORE = 8;\n const filtered = scored\n .filter((s) => s.score >= MIN_SCORE)\n .sort((a, b) => b.score - a.score);\n\n // Ensure category diversity - max 2 from same category in top results\n const suggestions: typeof filtered = [];\n const categoryCount: Record<string, number> = {};\n for (const item of filtered) {\n const cat = item.category || 'uncategorized';\n const count = categoryCount[cat] || 0;\n if (count < 2 || suggestions.length < 3) {\n suggestions.push(item);\n categoryCount[cat] = count + 1;\n if (suggestions.length >= 5) break;\n }\n }\n\n // Build composition hint for AI agents\n const compositionHint = suggestions.length >= 2\n ? `These components work well together. For example, ${suggestions[0].component} can be combined with ${suggestions.slice(1, 3).map(s => s.component).join(' and ')}.`\n : undefined;\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n useCase,\n context: context || undefined,\n suggestions: suggestions.map(({ score, ...rest }) => rest),\n recommendation: suggestions.length > 0\n ? `Best match: ${suggestions[0].component} (${suggestions[0].confidence} confidence) - ${suggestions[0].description}`\n : 'No matching components found. Try different keywords or browse with fragments_list.',\n compositionHint,\n nextStep: suggestions.length > 0\n ? `Use fragments_get(\"${suggestions[0].component}\") for full details, or fragments_guidelines(\"${suggestions[0].component}\") for usage rules.`\n : undefined,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.get: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const fields = args?.fields as string[] | undefined;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Apply field projection if specified\n const result = fields && fields.length > 0\n ? projectFields(segment as unknown as Record<string, unknown>, fields)\n : segment;\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case TOOL_NAMES.guidelines: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const fields = args?.fields as string[] | undefined;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Extract just the guidelines-relevant information (filter placeholder text)\n const guidelines = {\n component: segment.meta.name,\n description: segment.meta.description,\n status: segment.meta.status ?? 'stable',\n when: filterPlaceholders(segment.usage?.when),\n whenNot: filterPlaceholders(segment.usage?.whenNot),\n guidelines: segment.usage?.guidelines ?? [],\n accessibility: segment.usage?.accessibility ?? [],\n // Include prop constraints as they're often important guidelines\n propConstraints: Object.entries(segment.props ?? {})\n .filter(([, prop]) => prop.constraints && prop.constraints.length > 0)\n .map(([name, prop]) => ({\n prop: name,\n constraints: prop.constraints,\n })),\n // Include alternatives from relations\n alternatives: segment.relations\n ?.filter((r) => r.relationship === 'alternative')\n .map((r) => ({\n component: r.component,\n note: r.note,\n })) ?? [],\n };\n\n // Apply field projection if specified\n const result = fields && fields.length > 0\n ? projectFields(guidelines as unknown as Record<string, unknown>, fields)\n : guidelines;\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case TOOL_NAMES.alternatives: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Get direct relations\n const relations = segment.relations ?? [];\n\n // Also find components that reference this one\n const referencedBy = Object.values(data.segments)\n .filter((s) =>\n s.relations?.some((r) => r.component.toLowerCase() === componentName.toLowerCase())\n )\n .map((s) => ({\n component: s.meta.name,\n relationship: s.relations?.find(\n (r) => r.component.toLowerCase() === componentName.toLowerCase()\n )?.relationship,\n note: s.relations?.find(\n (r) => r.component.toLowerCase() === componentName.toLowerCase()\n )?.note,\n }));\n\n // Find components in the same category\n const sameCategory = Object.values(data.segments)\n .filter(\n (s) =>\n s.meta.category === segment.meta.category &&\n s.meta.name.toLowerCase() !== componentName.toLowerCase()\n )\n .map((s) => ({\n component: s.meta.name,\n description: s.meta.description,\n }));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n component: segment.meta.name,\n category: segment.meta.category,\n directRelations: relations,\n referencedBy,\n sameCategory,\n suggestion: relations.find((r) => r.relationship === 'alternative')\n ? `Consider ${relations.find((r) => r.relationship === 'alternative')?.component}: ${relations.find((r) => r.relationship === 'alternative')?.note}`\n : undefined,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.example: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const maxExamples = args?.maxExamples as number | undefined;\n const maxLines = args?.maxLines as number | undefined;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Filter variants if specific one requested\n let variants = segment.variants;\n if (variantName) {\n const filtered = variants.filter(\n (v) => v.name.toLowerCase() === variantName.toLowerCase()\n );\n if (filtered.length === 0) {\n throw new Error(\n `Variant \"${variantName}\" not found for ${componentName}. Available: ${variants.map((v) => v.name).join(', ')}`\n );\n }\n variants = filtered;\n }\n\n // Limit number of examples if specified\n if (maxExamples && maxExamples > 0) {\n variants = variants.slice(0, maxExamples);\n }\n\n // Helper to truncate code to max lines\n const truncateCode = (code: string): string => {\n if (!maxLines || maxLines <= 0) return code;\n const lines = code.split('\\n');\n if (lines.length <= maxLines) return code;\n return lines.slice(0, maxLines).join('\\n') + '\\n// ... truncated';\n };\n\n // Generate example code for each variant\n const examples = variants.map((variant) => {\n // Use provided code if available, otherwise generate a basic example\n if (variant.code) {\n return {\n variant: variant.name,\n description: variant.description,\n code: truncateCode(variant.code),\n };\n }\n\n // Generate a basic example if no code provided\n // Derive props from the variant name and component props\n const basicCode = `<${segment.meta.name} />`;\n\n return {\n variant: variant.name,\n description: variant.description,\n code: basicCode,\n note: 'No code example provided in fragment. Refer to props for customization.',\n };\n });\n\n // Include import statement with real package name\n const pkgName = await getPackageName();\n const importStatement = `import { ${segment.meta.name} } from '${pkgName}';`;\n\n // Build props reference\n const propsReference = Object.entries(segment.props ?? {}).map(([propName, prop]) => ({\n name: propName,\n type: prop.type,\n required: prop.required,\n default: prop.default,\n description: prop.description,\n }));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n component: segment.meta.name,\n import: importStatement,\n examples,\n propsReference,\n tip: 'Use the propsReference to customize components. Examples show documented variants.',\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.context: {\n const data = await loadSegments();\n const format = (args?.format as 'markdown' | 'json') ?? 'markdown';\n const compact = (args?.compact as boolean) ?? false;\n const includeCode = (args?.includeCode as boolean) ?? false;\n const includeRelations = (args?.includeRelations as boolean) ?? false;\n\n const segments = Object.values(data.segments);\n const recipes = Object.values(data.recipes ?? {});\n\n const { content, tokenEstimate } = generateContext(segments, {\n format,\n compact,\n include: {\n code: includeCode,\n relations: includeRelations,\n },\n }, recipes);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: content,\n },\n ],\n // Include token estimate in a way that doesn't pollute the main content\n _meta: {\n tokenEstimate,\n },\n };\n }\n\n case TOOL_NAMES.render: {\n const componentName = args?.component as string;\n const props = (args?.props as Record<string, unknown>) ?? {};\n const viewport = args?.viewport as { width?: number; height?: number } | undefined;\n\n if (!componentName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: component name is required',\n },\n ],\n isError: true,\n };\n }\n\n // Call the HTTP render endpoint\n const baseUrl = config.viewerUrl ?? 'http://localhost:6006';\n const renderUrl = `${baseUrl}/fragments/render`;\n\n try {\n const response = await fetch(renderUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: componentName,\n props,\n viewport: viewport ?? { width: 800, height: 600 },\n }),\n });\n\n const result = await response.json() as { screenshot?: string; error?: string };\n\n if (!response.ok || result.error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Render error: ${result.error ?? 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n\n // Return the screenshot as an image\n return {\n content: [\n {\n type: 'image' as const,\n data: result.screenshot!.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n },\n {\n type: 'text' as const,\n text: `Successfully rendered ${componentName} with props: ${JSON.stringify(props)}`,\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to render component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n },\n ],\n isError: true,\n };\n }\n }\n\n case TOOL_NAMES.compare: {\n const componentName = args?.component as string;\n const variantName = args?.variant as string | undefined;\n const props = (args?.props as Record<string, unknown>) ?? {};\n const figmaUrl = args?.figmaUrl as string | undefined;\n const threshold = (args?.threshold as number) ?? 1.0;\n\n if (!componentName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: component name is required',\n },\n ],\n isError: true,\n };\n }\n\n // Call the HTTP compare endpoint\n const baseUrl = config.viewerUrl ?? 'http://localhost:6006';\n const compareUrl = `${baseUrl}/fragments/compare`;\n\n try {\n const response = await fetch(compareUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: componentName,\n variant: variantName,\n props,\n figmaUrl,\n threshold,\n }),\n });\n\n interface CompareResult {\n match?: boolean;\n diffPercentage?: number;\n threshold?: number;\n rendered?: string;\n figma?: string;\n diff?: string;\n figmaUrl?: string;\n changedRegions?: Array<{ x: number; y: number; width: number; height: number }>;\n error?: string;\n suggestion?: string;\n }\n\n const result = await response.json() as CompareResult;\n\n if (!response.ok || result.error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Compare error: ${result.error ?? 'Unknown error'}${result.suggestion ? `\\nSuggestion: ${result.suggestion}` : ''}`,\n },\n ],\n isError: true,\n };\n }\n\n // Build response with diff image if available\n const content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> = [];\n\n // Add summary text\n const summaryText = result.match\n ? `✅ MATCH: ${componentName} matches Figma design (${result.diffPercentage}% diff, threshold: ${result.threshold}%)`\n : `❌ MISMATCH: ${componentName} differs from Figma design by ${result.diffPercentage}% (threshold: ${result.threshold}%)`;\n\n content.push({\n type: 'text' as const,\n text: summaryText,\n });\n\n // Add diff image if there are differences\n if (result.diff && !result.match) {\n content.push({\n type: 'image' as const,\n data: result.diff.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n });\n content.push({\n type: 'text' as const,\n text: `Diff image above shows visual differences (red highlights). Changed regions: ${result.changedRegions?.length ?? 0}`,\n });\n }\n\n // Add detailed info\n content.push({\n type: 'text' as const,\n text: JSON.stringify({\n match: result.match,\n diffPercentage: result.diffPercentage,\n threshold: result.threshold,\n figmaUrl: result.figmaUrl,\n changedRegions: result.changedRegions,\n }, null, 2),\n });\n\n return { content };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to compare component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running and FIGMA_ACCESS_TOKEN is set.`,\n },\n ],\n isError: true,\n };\n }\n }\n\n case TOOL_NAMES.fix: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const fixType = (args?.fixType as 'token' | 'all') ?? 'all';\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Call the HTTP fix endpoint on the dev server\n const baseUrl = config.viewerUrl ?? 'http://localhost:6006';\n const fixUrl = `${baseUrl}/fragments/fix`;\n\n try {\n const response = await fetch(fixUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: componentName,\n variant: variantName,\n fixType,\n }),\n });\n\n interface FixResult {\n patches: Array<{ file: string; diff: string }>;\n summary: string;\n error?: string;\n }\n\n const result = await response.json() as FixResult;\n\n if (!response.ok || result.error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Fix generation error: ${result.error ?? 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({\n component: componentName,\n variant: variantName ?? 'all',\n fixType,\n patches: result.patches,\n summary: result.summary,\n patchCount: result.patches.length,\n nextStep: result.patches.length > 0\n ? 'Apply patches using your editor or `patch` command, then run fragments_verify to confirm fixes.'\n : undefined,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to generate fixes: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n },\n ],\n isError: true,\n };\n }\n }\n\n case TOOL_NAMES.recipe: {\n const data = await loadSegments();\n const recipeName = args?.name as string | undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const component = (args?.component as string)?.toLowerCase() ?? undefined;\n\n const allRecipes = Object.values(data.recipes ?? {});\n\n if (allRecipes.length === 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: 0,\n recipes: [],\n hint: `No recipes found. Run \\`${BRAND.cliCommand} build\\` after adding .recipe.ts files.`,\n }, null, 2),\n }],\n };\n }\n\n let filtered = allRecipes;\n\n // Exact name match\n if (recipeName) {\n filtered = filtered.filter(\n r => r.name.toLowerCase() === recipeName.toLowerCase()\n );\n }\n\n // Free-text search\n if (search) {\n filtered = filtered.filter(r => {\n const haystack = [\n r.name,\n r.description,\n ...(r.tags ?? []),\n ...r.components,\n r.category,\n ].join(' ').toLowerCase();\n return haystack.includes(search);\n });\n }\n\n // Component filter\n if (component) {\n filtered = filtered.filter(r =>\n r.components.some(c => c.toLowerCase() === component)\n );\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: filtered.length,\n recipes: filtered,\n }, null, 2),\n }],\n };\n }\n\n case TOOL_NAMES.verify: {\n const { Timer, CaptureEngine: CE, bufferToBase64Url: toBase64 } = await getService();\n const timer = new Timer();\n const componentName = args?.component as string;\n const variantName = args?.variant as string;\n const theme = (args?.theme as Theme) ?? config.theme ?? DEFAULTS.theme;\n const threshold = (args?.threshold as number) ?? config.threshold ?? DEFAULTS.diffThreshold;\n\n if (!componentName || !variantName) {\n throw new Error('component and variant are required');\n }\n\n const storage = await getStorageManager();\n const pool = await getBrowserPool();\n const diff = await getDiffEngine();\n\n // Load baseline\n const baseline = await storage.loadBaseline(componentName, variantName, theme);\n\n if (!baseline) {\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n verdict: 'error',\n matches: false,\n diffPercentage: 0,\n screenshot: '',\n baseline: '',\n notes: [],\n error: `No baseline found for ${componentName}/${variantName}. Run \\`${BRAND.cliCommand} screenshot\\` first.`,\n timing: { renderMs: 0, captureMs: 0, diffMs: 0, totalMs: timer.elapsed() },\n } satisfies VerifyResult,\n null,\n 2\n ),\n },\n ],\n };\n }\n\n // Capture current\n const viewerUrl = config.viewerUrl ?? `http://localhost:${DEFAULTS.port}`;\n const captureEngine = new CE(pool, viewerUrl);\n\n const current = await captureEngine.captureVariant(componentName, variantName, {\n theme,\n delay: DEFAULTS.captureDelayMs,\n });\n\n // Compare\n let diffResult;\n let matches = false;\n\n if (diff.areIdentical(current, baseline)) {\n matches = true;\n diffResult = {\n matches: true,\n diffPercentage: 0,\n diffPixelCount: 0,\n totalPixels: current.viewport.width * current.viewport.height,\n changedRegions: [],\n diffTimeMs: 0,\n };\n } else {\n diffResult = diff.compare(current, baseline, { threshold });\n matches = diffResult.matches;\n }\n\n const result: VerifyResult = {\n verdict: matches ? 'pass' : 'fail',\n matches,\n diffPercentage: diffResult.diffPercentage,\n screenshot: toBase64(current.data),\n baseline: toBase64(baseline.data),\n diffImage: diffResult.diffImage\n ? toBase64(diffResult.diffImage)\n : undefined,\n notes: matches\n ? ['Screenshot matches baseline within threshold']\n : [\n `Diff percentage (${diffResult.diffPercentage}%) exceeds threshold (${threshold}%)`,\n `${diffResult.changedRegions.length} changed region(s) detected`,\n ],\n timing: {\n renderMs: current.metadata.renderTimeMs,\n captureMs: current.metadata.captureTimeMs,\n diffMs: diffResult.diffTimeMs,\n totalMs: timer.elapsed(),\n },\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n }),\n },\n ],\n isError: true,\n };\n }\n });\n\n // Cleanup on close\n server.onclose = async () => {\n if (browserPool) {\n await browserPool.shutdown();\n }\n };\n\n return server;\n}\n\n/**\n * Start the MCP server with stdio transport\n */\nexport async function startMcpServer(config: McpServerConfig): Promise<void> {\n const server = createMcpServer(config);\n const transport = new StdioServerTransport();\n\n await server.connect(transport);\n}\n","/**\n * Utility functions for the MCP server\n */\n\n/**\n * Extract specific fields from an object using dot notation paths.\n * E.g., projectFields(obj, ['meta.name', 'usage.when']) returns { meta: { name: ... }, usage: { when: ... } }\n *\n * @param obj - The source object to extract fields from\n * @param fields - Array of field paths (supports dot notation for nested fields)\n * @returns A new object containing only the requested fields\n */\nexport function projectFields<T extends Record<string, unknown>>(\n obj: T,\n fields: string[]\n): Partial<T> {\n if (!fields || fields.length === 0) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const field of fields) {\n const parts = field.split('.');\n let source: unknown = obj;\n let target = result;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const isLast = i === parts.length - 1;\n\n if (source === null || source === undefined || typeof source !== 'object') {\n break;\n }\n\n const sourceObj = source as Record<string, unknown>;\n const value = sourceObj[part];\n\n if (isLast) {\n // Set the final value\n target[part] = value;\n } else {\n // Create nested object if needed\n if (!(part in target)) {\n target[part] = {};\n }\n target = target[part] as Record<string, unknown>;\n source = value;\n }\n }\n }\n\n return result as Partial<T>;\n}\n"],"mappings":"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","names":["name"]}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { createRequire } from 'module'; const require = createRequire(import.met
2
2
  import {
3
3
  createMcpServer,
4
4
  startMcpServer
5
- } from "./chunk-RUZV6VLE.js";
5
+ } from "./chunk-OQOBENAX.js";
6
6
  import "./chunk-7OMNY6JX.js";
7
7
  export {
8
8
  createMcpServer,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fragments-sdk/mcp",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "MCP server for AI agent integration with Fragments",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/server.ts","../src/utils.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n type Tool,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n BRAND,\n DEFAULTS,\n generateContext,\n type CompiledSegmentsFile,\n type VerifyResult,\n type Theme,\n} from '@fragments/core';\n// @fragments/service is lazy-imported to avoid requiring playwright at startup.\n// Visual tools (verify, render, compare, fix) load it on first use.\ntype ServiceModule = typeof import('@fragments/service');\nlet _service: ServiceModule | null = null;\nasync function getService(): Promise<ServiceModule> {\n if (!_service) {\n try {\n _service = await import('@fragments/service');\n } catch {\n throw new Error(\n 'Visual tools require playwright. Install it with: npm install playwright'\n );\n }\n }\n return _service;\n}\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { projectFields } from './utils.js';\n\n/**\n * MCP Tool names - derived from BRAND constants\n */\nconst TOOL_NAMES = {\n list: `${BRAND.nameLower}_list`,\n suggest: `${BRAND.nameLower}_suggest`,\n get: `${BRAND.nameLower}_get`,\n guidelines: `${BRAND.nameLower}_guidelines`,\n alternatives: `${BRAND.nameLower}_alternatives`,\n example: `${BRAND.nameLower}_example`,\n verify: `${BRAND.nameLower}_verify`,\n context: `${BRAND.nameLower}_context`,\n render: `${BRAND.nameLower}_render`,\n compare: `${BRAND.nameLower}_compare`,\n fix: `${BRAND.nameLower}_fix`,\n recipe: `${BRAND.nameLower}_recipe`,\n} as const;\n\n/**\n * Placeholder patterns to filter out from usage text.\n * These are auto-generated and provide no value to AI agents.\n */\nconst PLACEHOLDER_PATTERNS = [\n /^\\w+ component is needed$/i,\n /^Alternative component is more appropriate$/i,\n /^Use \\w+ when you need/i,\n];\n\n/**\n * Filter out placeholder text from usage arrays\n */\nfunction filterPlaceholders(items: string[] | undefined): string[] {\n if (!items) return [];\n return items.filter(item =>\n !PLACEHOLDER_PATTERNS.some(pattern => pattern.test(item.trim()))\n );\n}\n\n/**\n * MCP Server configuration\n */\nexport interface McpServerConfig {\n /** Project root directory */\n projectRoot: string;\n\n /** Viewer base URL */\n viewerUrl?: string;\n\n /** Default theme for verification */\n theme?: Theme;\n\n /** Diff threshold percentage */\n threshold?: number;\n}\n\n/**\n * Tool definitions for the MCP server\n */\nconst TOOLS: Tool[] = [\n {\n name: TOOL_NAMES.list,\n description: `List all available component fragments in the design system. Returns component names, categories, descriptions, and variant counts. Use this FIRST to discover what components exist before implementing any UI.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n category: {\n type: 'string',\n description: 'Filter by category (e.g., \"actions\", \"forms\", \"layout\")',\n },\n search: {\n type: 'string',\n description: 'Search term to filter by name, description, or tags',\n },\n status: {\n type: 'string',\n enum: ['stable', 'beta', 'deprecated', 'experimental'],\n description: 'Filter by component status',\n },\n },\n },\n },\n {\n name: TOOL_NAMES.suggest,\n description: `Given a use case or UI requirement, suggest the most appropriate component(s) from the design system. Use this when you're unsure which component to use for a specific task. Returns ranked suggestions with explanations.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n useCase: {\n type: 'string',\n description: 'Description of what you want to build (e.g., \"form for user email input\", \"button to submit data\", \"display a list of items\")',\n },\n context: {\n type: 'string',\n description: 'Additional context (e.g., \"in a modal\", \"for mobile\", \"destructive action\")',\n },\n },\n required: ['useCase'],\n },\n },\n {\n name: TOOL_NAMES.get,\n description: `Get detailed information about a specific component fragment including props, usage guidelines, and variants. Use this AFTER fragments_list or fragments_suggest to understand a component's API and best practices before implementing. Use 'fields' to request only specific data for token efficiency.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n fields: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific fields to return (e.g., [\"meta\", \"usage.when\", \"contract.propsSummary\", \"props\"]). If omitted, returns all fields. Supports dot notation for nested fields.',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.guidelines,\n description: `Get the usage guidelines for a component - when to use it, when NOT to use it, and best practices. Use this to make the right component choice and avoid common mistakes. Use 'fields' to request only specific data for token efficiency.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n fields: {\n type: 'array',\n items: { type: 'string' },\n description: 'Specific fields to return (e.g., [\"when\", \"whenNot\", \"accessibility\"]). If omitted, returns all guideline fields.',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.alternatives,\n description: `Get alternative and related components for a given component. Use this when a component might not be the right fit, or to understand the component ecosystem.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name to find alternatives for',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.example,\n description: `Get example code for a component variant. Returns ready-to-use code with props demonstrated. Use this when you need to see HOW to implement a component, not just what props it accepts.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n variant: {\n type: 'string',\n description: 'Variant name (e.g., \"Default\", \"Primary\"). If omitted, returns all variants.',\n },\n maxExamples: {\n type: 'number',\n description: 'Maximum number of examples to return (default: all)',\n },\n maxLines: {\n type: 'number',\n description: 'Maximum lines per code example (truncates longer examples)',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.verify,\n description: `Verify a component render against the baseline screenshot. Use this AFTER implementing or modifying a component to ensure visual consistency with the design system. Returns a diff percentage and visual comparison.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name to verify',\n },\n variant: {\n type: 'string',\n description: 'Variant name to verify',\n },\n theme: {\n type: 'string',\n enum: ['light', 'dark'],\n description: 'Theme to verify (default: light)',\n },\n threshold: {\n type: 'number',\n description: 'Diff threshold percentage (default: 5)',\n },\n },\n required: ['component', 'variant'],\n },\n },\n {\n name: TOOL_NAMES.context,\n description: `Get the complete design system context in a single call. Use this FIRST before any implementation to understand all available components in a token-efficient format. Returns a summary of all components with their categories, usage guidelines, props, and variants.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n format: {\n type: 'string',\n enum: ['markdown', 'json'],\n description: 'Output format (default: markdown)',\n },\n compact: {\n type: 'boolean',\n description: 'If true, returns minimal output (just component names and categories)',\n },\n includeCode: {\n type: 'boolean',\n description: 'If true, includes code examples for each variant',\n },\n includeRelations: {\n type: 'boolean',\n description: 'If true, includes component relationships',\n },\n },\n },\n },\n {\n name: TOOL_NAMES.render,\n description: `Render a design system component with specific props and return a screenshot. Use this to VERIFY your UI implementation looks correct. The AI can see what the component looks like and iterate until it's right.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Card\", \"Input\")',\n },\n props: {\n type: 'object',\n description: 'Props to pass to the component (e.g., { \"variant\": \"primary\", \"children\": \"Click me\" })',\n },\n viewport: {\n type: 'object',\n properties: {\n width: { type: 'number', description: 'Viewport width (default: 800)' },\n height: { type: 'number', description: 'Viewport height (default: 600)' },\n },\n description: 'Optional viewport size for the render',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.compare,\n description: `Compare a rendered component against its Figma design. Returns diff percentage and highlighted differences. Use this to verify your implementation matches the design spec. If the component has a figma URL in its fragment definition, no URL is needed.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name (e.g., \"Button\", \"Input\")',\n },\n variant: {\n type: 'string',\n description: 'Variant name (optional, uses first variant if not specified)',\n },\n props: {\n type: 'object',\n description: 'Props to render with',\n },\n figmaUrl: {\n type: 'string',\n description: 'Figma frame URL (optional if segment has figma link)',\n },\n threshold: {\n type: 'number',\n description: 'Max acceptable diff percentage (default: 1.0)',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.fix,\n description: `Generate patches to fix token compliance issues in a component. Returns unified diff patches that replace hardcoded CSS values with design token references. Use this after fragments_verify identifies issues to automatically fix them.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n component: {\n type: 'string',\n description: 'Component name to generate fixes for (e.g., \"Button\", \"Card\")',\n },\n variant: {\n type: 'string',\n description: 'Specific variant to fix (optional, fixes all variants if omitted)',\n },\n fixType: {\n type: 'string',\n enum: ['token', 'all'],\n description: 'Type of fixes to generate: \"token\" for hardcoded→token replacements, \"all\" for all available fixes (default: \"all\")',\n },\n },\n required: ['component'],\n },\n },\n {\n name: TOOL_NAMES.recipe,\n description: `Search and retrieve composition recipes — named patterns showing how design system components wire together for common use cases (e.g., \"Login Form\", \"Settings Page\"). Returns the recipe with its code pattern.`,\n inputSchema: {\n type: 'object' as const,\n properties: {\n name: {\n type: 'string',\n description: 'Exact recipe name to retrieve (e.g., \"Login Form\")',\n },\n search: {\n type: 'string',\n description: 'Free-text search across recipe names, descriptions, tags, and components',\n },\n component: {\n type: 'string',\n description: 'Filter recipes that use a specific component (e.g., \"Button\")',\n },\n },\n },\n },\n];\n\n/**\n * Create and configure the MCP server\n */\nexport function createMcpServer(config: McpServerConfig): Server {\n const server = new Server(\n {\n name: `${BRAND.nameLower}-mcp`,\n version: '0.0.1',\n },\n {\n capabilities: {\n tools: {},\n },\n }\n );\n\n // Lazy-loaded resources\n let segmentsData: CompiledSegmentsFile | null = null;\n let packageName: string | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- lazy-loaded from @fragments/service\n let browserPool: any = null;\n let storageManager: any = null;\n let diffEngine: any = null;\n let isPoolWarming = false;\n\n /**\n * Load compiled segments data\n */\n async function loadSegments(): Promise<CompiledSegmentsFile> {\n if (segmentsData) {\n return segmentsData;\n }\n\n const segmentsPath = join(config.projectRoot, BRAND.outFile);\n\n if (!existsSync(segmentsPath)) {\n throw new Error(\n `No ${BRAND.outFile} found. Run \\`${BRAND.cliCommand} build\\` first.`\n );\n }\n\n const content = await readFile(segmentsPath, 'utf-8');\n segmentsData = JSON.parse(content) as CompiledSegmentsFile;\n return segmentsData;\n }\n\n /**\n * Get the package name from package.json for import statements\n */\n async function getPackageName(): Promise<string> {\n if (packageName) {\n return packageName;\n }\n\n const packageJsonPath = join(config.projectRoot, 'package.json');\n if (existsSync(packageJsonPath)) {\n try {\n const content = await readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content) as { name?: string };\n if (pkg.name) {\n packageName = pkg.name;\n return packageName;\n }\n } catch {\n // Fall through to default\n }\n }\n\n // Default fallback\n packageName = 'your-component-library';\n return packageName;\n }\n\n /**\n * Get or create browser pool with extended idle timeout for MCP\n */\n async function getBrowserPool() {\n if (!browserPool) {\n const { BrowserPool } = await getService();\n browserPool = new BrowserPool({\n viewport: DEFAULTS.viewport,\n // 30 minute idle timeout for MCP - server runs continuously\n idleTimeoutMs: 30 * 60 * 1000,\n poolSize: 2, // Keep 2 contexts warm for faster captures\n });\n }\n return browserPool;\n }\n\n /**\n * Pre-warm browser pool in background (non-blocking)\n */\n function warmBrowserPool(): void {\n if (isPoolWarming || browserPool?.isReady) {\n return;\n }\n isPoolWarming = true;\n\n // Warm in background - don't await\n getBrowserPool().then((pool) => {\n pool.warmup().then(() => {\n isPoolWarming = false;\n }).catch(() => {\n isPoolWarming = false;\n });\n }).catch(() => {\n isPoolWarming = false;\n });\n }\n\n /**\n * Get or create storage manager\n */\n async function getStorageManager() {\n if (!storageManager) {\n const { StorageManager } = await getService();\n storageManager = new StorageManager({\n projectRoot: config.projectRoot,\n });\n await storageManager.initialize();\n }\n return storageManager;\n }\n\n /**\n * Get or create diff engine\n */\n async function getDiffEngine() {\n if (!diffEngine) {\n const { DiffEngine } = await getService();\n diffEngine = new DiffEngine(config.threshold ?? DEFAULTS.diffThreshold);\n }\n return diffEngine;\n }\n\n // Register tool listing\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return { tools: TOOLS };\n });\n\n // Register tool execution\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case TOOL_NAMES.list: {\n const data = await loadSegments();\n const category = (args?.category as string) ?? undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const status = (args?.status as string) ?? undefined;\n\n const segments = Object.values(data.segments)\n .filter((s) => {\n // Category filter\n if (category && s.meta.category !== category) return false;\n\n // Status filter\n if (status && (s.meta.status ?? 'stable') !== status) return false;\n\n // Search filter - matches name, description, or tags\n if (search) {\n const nameMatch = s.meta.name.toLowerCase().includes(search);\n const descMatch = s.meta.description?.toLowerCase().includes(search);\n const tagMatch = s.meta.tags?.some((t) => t.toLowerCase().includes(search));\n if (!nameMatch && !descMatch && !tagMatch) return false;\n }\n\n return true;\n })\n .map((s) => ({\n name: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n status: s.meta.status ?? 'stable',\n variantCount: s.variants.length,\n tags: s.meta.tags ?? [],\n }));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n total: segments.length,\n segments,\n categories: [...new Set(segments.map((s) => s.category))],\n hint: segments.length === 0\n ? 'No components found. Try broader search terms or check available categories.'\n : segments.length > 5\n ? 'Use fragments_suggest for use-case based recommendations, or fragments_get for details on a specific component.'\n : undefined,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.suggest: {\n const data = await loadSegments();\n const useCase = (args?.useCase as string)?.toLowerCase() ?? '';\n const context = (args?.context as string)?.toLowerCase() ?? '';\n\n if (!useCase) {\n throw new Error('useCase is required');\n }\n\n // Build search terms from use case and context\n const searchTerms = `${useCase} ${context}`.split(/\\s+/).filter(Boolean);\n\n // Common synonyms and related terms for better matching\n const synonymMap: Record<string, string[]> = {\n 'form': ['input', 'field', 'submit', 'validation'],\n 'input': ['form', 'field', 'text', 'entry'],\n 'button': ['action', 'click', 'submit', 'trigger'],\n 'action': ['button', 'click', 'trigger'],\n 'alert': ['notification', 'message', 'warning', 'error', 'feedback'],\n 'notification': ['alert', 'message', 'toast'],\n 'card': ['container', 'panel', 'box', 'content'],\n 'toggle': ['switch', 'checkbox', 'boolean', 'on/off'],\n 'switch': ['toggle', 'checkbox', 'boolean'],\n 'badge': ['tag', 'label', 'status', 'indicator'],\n 'status': ['badge', 'indicator', 'state'],\n 'login': ['auth', 'signin', 'authentication', 'form'],\n 'auth': ['login', 'signin', 'authentication'],\n };\n\n // Expand search terms with synonyms\n const expandedTerms = new Set(searchTerms);\n searchTerms.forEach(term => {\n const synonyms = synonymMap[term];\n if (synonyms) {\n synonyms.forEach(syn => expandedTerms.add(syn));\n }\n });\n\n // Score each component based on relevance\n const scored = Object.values(data.segments).map((s) => {\n let score = 0;\n const reasons: string[] = [];\n\n // Check name match (exact terms get higher score)\n const nameLower = s.meta.name.toLowerCase();\n if (searchTerms.some((term) => nameLower.includes(term))) {\n score += 15;\n reasons.push(`Name matches search`);\n } else if (Array.from(expandedTerms).some((term) => nameLower.includes(term))) {\n score += 8;\n reasons.push(`Name matches related term`);\n }\n\n // Check description match\n const desc = s.meta.description?.toLowerCase() ?? '';\n const descMatches = searchTerms.filter((term) => desc.includes(term));\n if (descMatches.length > 0) {\n score += descMatches.length * 6;\n reasons.push(`Description matches: ${descMatches.join(', ')}`);\n }\n\n // Check tags match\n const tags = s.meta.tags?.map((t) => t.toLowerCase()) ?? [];\n const tagMatches = searchTerms.filter((term) =>\n tags.some((tag) => tag.includes(term))\n );\n if (tagMatches.length > 0) {\n score += tagMatches.length * 4;\n reasons.push(`Tags match: ${tagMatches.join(', ')}`);\n }\n\n // Check usage.when match (high weight - this is semantic intent)\n const whenUsed = s.usage?.when?.join(' ').toLowerCase() ?? '';\n const whenMatches = searchTerms.filter((term) => whenUsed.includes(term));\n if (whenMatches.length > 0) {\n score += whenMatches.length * 10;\n reasons.push(`Use cases match: \"${whenMatches.join(', ')}\"`);\n }\n\n // Also check expanded terms in usage.when\n const expandedWhenMatches = Array.from(expandedTerms).filter(\n (term) => !searchTerms.includes(term) && whenUsed.includes(term)\n );\n if (expandedWhenMatches.length > 0) {\n score += expandedWhenMatches.length * 5;\n reasons.push(`Related use cases: \"${expandedWhenMatches.join(', ')}\"`);\n }\n\n // Check category match (higher weight for category relevance)\n const category = s.meta.category?.toLowerCase() ?? '';\n if (searchTerms.some((term) => category.includes(term))) {\n score += 8;\n reasons.push(`Category: ${s.meta.category}`);\n }\n\n // Check variant names and descriptions for additional context\n const variantText = s.variants\n .map(v => `${v.name} ${v.description || ''}`.toLowerCase())\n .join(' ');\n const variantMatches = searchTerms.filter(term => variantText.includes(term));\n if (variantMatches.length > 0) {\n score += variantMatches.length * 3;\n reasons.push(`Variants match: ${variantMatches.join(', ')}`);\n }\n\n // Boost stable components\n if (s.meta.status === 'stable') {\n score += 5;\n reasons.push('Stable component');\n } else if (s.meta.status === 'beta') {\n score += 2;\n }\n\n // Penalize deprecated components\n if (s.meta.status === 'deprecated') {\n score -= 25;\n reasons.push('Deprecated - consider alternatives');\n }\n\n // Filter placeholder text from usage\n const filteredWhen = filterPlaceholders(s.usage?.when).slice(0, 3);\n const filteredWhenNot = filterPlaceholders(s.usage?.whenNot).slice(0, 2);\n\n // Calculate confidence level\n let confidence: 'high' | 'medium' | 'low';\n if (score >= 25) {\n confidence = 'high';\n } else if (score >= 15) {\n confidence = 'medium';\n } else {\n confidence = 'low';\n }\n\n return {\n component: s.meta.name,\n category: s.meta.category,\n description: s.meta.description,\n score,\n confidence,\n reasons,\n usage: {\n when: filteredWhen,\n whenNot: filteredWhenNot,\n },\n variantCount: s.variants.length,\n status: s.meta.status,\n };\n });\n\n // Sort by score and filter out low-relevance results\n const MIN_SCORE = 8;\n const filtered = scored\n .filter((s) => s.score >= MIN_SCORE)\n .sort((a, b) => b.score - a.score);\n\n // Ensure category diversity - max 2 from same category in top results\n const suggestions: typeof filtered = [];\n const categoryCount: Record<string, number> = {};\n for (const item of filtered) {\n const cat = item.category || 'uncategorized';\n const count = categoryCount[cat] || 0;\n if (count < 2 || suggestions.length < 3) {\n suggestions.push(item);\n categoryCount[cat] = count + 1;\n if (suggestions.length >= 5) break;\n }\n }\n\n // Build composition hint for AI agents\n const compositionHint = suggestions.length >= 2\n ? `These components work well together. For example, ${suggestions[0].component} can be combined with ${suggestions.slice(1, 3).map(s => s.component).join(' and ')}.`\n : undefined;\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n useCase,\n context: context || undefined,\n suggestions: suggestions.map(({ score, ...rest }) => rest),\n recommendation: suggestions.length > 0\n ? `Best match: ${suggestions[0].component} (${suggestions[0].confidence} confidence) - ${suggestions[0].description}`\n : 'No matching components found. Try different keywords or browse with fragments_list.',\n compositionHint,\n nextStep: suggestions.length > 0\n ? `Use fragments_get(\"${suggestions[0].component}\") for full details, or fragments_guidelines(\"${suggestions[0].component}\") for usage rules.`\n : undefined,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.get: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const fields = args?.fields as string[] | undefined;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Apply field projection if specified\n const result = fields && fields.length > 0\n ? projectFields(segment as unknown as Record<string, unknown>, fields)\n : segment;\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case TOOL_NAMES.guidelines: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const fields = args?.fields as string[] | undefined;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Extract just the guidelines-relevant information (filter placeholder text)\n const guidelines = {\n component: segment.meta.name,\n description: segment.meta.description,\n status: segment.meta.status ?? 'stable',\n when: filterPlaceholders(segment.usage?.when),\n whenNot: filterPlaceholders(segment.usage?.whenNot),\n guidelines: segment.usage?.guidelines ?? [],\n accessibility: segment.usage?.accessibility ?? [],\n // Include prop constraints as they're often important guidelines\n propConstraints: Object.entries(segment.props ?? {})\n .filter(([, prop]) => prop.constraints && prop.constraints.length > 0)\n .map(([name, prop]) => ({\n prop: name,\n constraints: prop.constraints,\n })),\n // Include alternatives from relations\n alternatives: segment.relations\n ?.filter((r) => r.relationship === 'alternative')\n .map((r) => ({\n component: r.component,\n note: r.note,\n })) ?? [],\n };\n\n // Apply field projection if specified\n const result = fields && fields.length > 0\n ? projectFields(guidelines as unknown as Record<string, unknown>, fields)\n : guidelines;\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n case TOOL_NAMES.alternatives: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Get direct relations\n const relations = segment.relations ?? [];\n\n // Also find components that reference this one\n const referencedBy = Object.values(data.segments)\n .filter((s) =>\n s.relations?.some((r) => r.component.toLowerCase() === componentName.toLowerCase())\n )\n .map((s) => ({\n component: s.meta.name,\n relationship: s.relations?.find(\n (r) => r.component.toLowerCase() === componentName.toLowerCase()\n )?.relationship,\n note: s.relations?.find(\n (r) => r.component.toLowerCase() === componentName.toLowerCase()\n )?.note,\n }));\n\n // Find components in the same category\n const sameCategory = Object.values(data.segments)\n .filter(\n (s) =>\n s.meta.category === segment.meta.category &&\n s.meta.name.toLowerCase() !== componentName.toLowerCase()\n )\n .map((s) => ({\n component: s.meta.name,\n description: s.meta.description,\n }));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n component: segment.meta.name,\n category: segment.meta.category,\n directRelations: relations,\n referencedBy,\n sameCategory,\n suggestion: relations.find((r) => r.relationship === 'alternative')\n ? `Consider ${relations.find((r) => r.relationship === 'alternative')?.component}: ${relations.find((r) => r.relationship === 'alternative')?.note}`\n : undefined,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.example: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const maxExamples = args?.maxExamples as number | undefined;\n const maxLines = args?.maxLines as number | undefined;\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Filter variants if specific one requested\n let variants = segment.variants;\n if (variantName) {\n const filtered = variants.filter(\n (v) => v.name.toLowerCase() === variantName.toLowerCase()\n );\n if (filtered.length === 0) {\n throw new Error(\n `Variant \"${variantName}\" not found for ${componentName}. Available: ${variants.map((v) => v.name).join(', ')}`\n );\n }\n variants = filtered;\n }\n\n // Limit number of examples if specified\n if (maxExamples && maxExamples > 0) {\n variants = variants.slice(0, maxExamples);\n }\n\n // Helper to truncate code to max lines\n const truncateCode = (code: string): string => {\n if (!maxLines || maxLines <= 0) return code;\n const lines = code.split('\\n');\n if (lines.length <= maxLines) return code;\n return lines.slice(0, maxLines).join('\\n') + '\\n// ... truncated';\n };\n\n // Generate example code for each variant\n const examples = variants.map((variant) => {\n // Use provided code if available, otherwise generate a basic example\n if (variant.code) {\n return {\n variant: variant.name,\n description: variant.description,\n code: truncateCode(variant.code),\n };\n }\n\n // Generate a basic example if no code provided\n // Derive props from the variant name and component props\n const basicCode = `<${segment.meta.name} />`;\n\n return {\n variant: variant.name,\n description: variant.description,\n code: basicCode,\n note: 'No code example provided in fragment. Refer to props for customization.',\n };\n });\n\n // Include import statement with real package name\n const pkgName = await getPackageName();\n const importStatement = `import { ${segment.meta.name} } from '${pkgName}';`;\n\n // Build props reference\n const propsReference = Object.entries(segment.props ?? {}).map(([propName, prop]) => ({\n name: propName,\n type: prop.type,\n required: prop.required,\n default: prop.default,\n description: prop.description,\n }));\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n component: segment.meta.name,\n import: importStatement,\n examples,\n propsReference,\n tip: 'Use the propsReference to customize components. Examples show documented variants.',\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n case TOOL_NAMES.context: {\n const data = await loadSegments();\n const format = (args?.format as 'markdown' | 'json') ?? 'markdown';\n const compact = (args?.compact as boolean) ?? false;\n const includeCode = (args?.includeCode as boolean) ?? false;\n const includeRelations = (args?.includeRelations as boolean) ?? false;\n\n const segments = Object.values(data.segments);\n const recipes = Object.values(data.recipes ?? {});\n\n const { content, tokenEstimate } = generateContext(segments, {\n format,\n compact,\n include: {\n code: includeCode,\n relations: includeRelations,\n },\n }, recipes);\n\n return {\n content: [\n {\n type: 'text' as const,\n text: content,\n },\n ],\n // Include token estimate in a way that doesn't pollute the main content\n _meta: {\n tokenEstimate,\n },\n };\n }\n\n case TOOL_NAMES.render: {\n const componentName = args?.component as string;\n const props = (args?.props as Record<string, unknown>) ?? {};\n const viewport = args?.viewport as { width?: number; height?: number } | undefined;\n\n if (!componentName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: component name is required',\n },\n ],\n isError: true,\n };\n }\n\n // Call the HTTP render endpoint\n const baseUrl = config.viewerUrl ?? 'http://localhost:6006';\n const renderUrl = `${baseUrl}/fragments/render`;\n\n try {\n const response = await fetch(renderUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: componentName,\n props,\n viewport: viewport ?? { width: 800, height: 600 },\n }),\n });\n\n const result = await response.json() as { screenshot?: string; error?: string };\n\n if (!response.ok || result.error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Render error: ${result.error ?? 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n\n // Return the screenshot as an image\n return {\n content: [\n {\n type: 'image' as const,\n data: result.screenshot!.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n },\n {\n type: 'text' as const,\n text: `Successfully rendered ${componentName} with props: ${JSON.stringify(props)}`,\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to render component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n },\n ],\n isError: true,\n };\n }\n }\n\n case TOOL_NAMES.compare: {\n const componentName = args?.component as string;\n const variantName = args?.variant as string | undefined;\n const props = (args?.props as Record<string, unknown>) ?? {};\n const figmaUrl = args?.figmaUrl as string | undefined;\n const threshold = (args?.threshold as number) ?? 1.0;\n\n if (!componentName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: component name is required',\n },\n ],\n isError: true,\n };\n }\n\n // Call the HTTP compare endpoint\n const baseUrl = config.viewerUrl ?? 'http://localhost:6006';\n const compareUrl = `${baseUrl}/fragments/compare`;\n\n try {\n const response = await fetch(compareUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: componentName,\n variant: variantName,\n props,\n figmaUrl,\n threshold,\n }),\n });\n\n interface CompareResult {\n match?: boolean;\n diffPercentage?: number;\n threshold?: number;\n rendered?: string;\n figma?: string;\n diff?: string;\n figmaUrl?: string;\n changedRegions?: Array<{ x: number; y: number; width: number; height: number }>;\n error?: string;\n suggestion?: string;\n }\n\n const result = await response.json() as CompareResult;\n\n if (!response.ok || result.error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Compare error: ${result.error ?? 'Unknown error'}${result.suggestion ? `\\nSuggestion: ${result.suggestion}` : ''}`,\n },\n ],\n isError: true,\n };\n }\n\n // Build response with diff image if available\n const content: Array<{ type: string; text?: string; data?: string; mimeType?: string }> = [];\n\n // Add summary text\n const summaryText = result.match\n ? `✅ MATCH: ${componentName} matches Figma design (${result.diffPercentage}% diff, threshold: ${result.threshold}%)`\n : `❌ MISMATCH: ${componentName} differs from Figma design by ${result.diffPercentage}% (threshold: ${result.threshold}%)`;\n\n content.push({\n type: 'text' as const,\n text: summaryText,\n });\n\n // Add diff image if there are differences\n if (result.diff && !result.match) {\n content.push({\n type: 'image' as const,\n data: result.diff.replace('data:image/png;base64,', ''),\n mimeType: 'image/png',\n });\n content.push({\n type: 'text' as const,\n text: `Diff image above shows visual differences (red highlights). Changed regions: ${result.changedRegions?.length ?? 0}`,\n });\n }\n\n // Add detailed info\n content.push({\n type: 'text' as const,\n text: JSON.stringify({\n match: result.match,\n diffPercentage: result.diffPercentage,\n threshold: result.threshold,\n figmaUrl: result.figmaUrl,\n changedRegions: result.changedRegions,\n }, null, 2),\n });\n\n return { content };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to compare component: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running and FIGMA_ACCESS_TOKEN is set.`,\n },\n ],\n isError: true,\n };\n }\n }\n\n case TOOL_NAMES.fix: {\n const data = await loadSegments();\n const componentName = args?.component as string;\n const variantName = (args?.variant as string) ?? undefined;\n const fixType = (args?.fixType as 'token' | 'all') ?? 'all';\n\n if (!componentName) {\n throw new Error('component is required');\n }\n\n const segment = Object.values(data.segments).find(\n (s) => s.meta.name.toLowerCase() === componentName.toLowerCase()\n );\n\n if (!segment) {\n throw new Error(`Component \"${componentName}\" not found. Use fragments_list to see available components.`);\n }\n\n // Call the HTTP fix endpoint on the dev server\n const baseUrl = config.viewerUrl ?? 'http://localhost:6006';\n const fixUrl = `${baseUrl}/fragments/fix`;\n\n try {\n const response = await fetch(fixUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n component: componentName,\n variant: variantName,\n fixType,\n }),\n });\n\n interface FixResult {\n patches: Array<{ file: string; diff: string }>;\n summary: string;\n error?: string;\n }\n\n const result = await response.json() as FixResult;\n\n if (!response.ok || result.error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Fix generation error: ${result.error ?? 'Unknown error'}`,\n },\n ],\n isError: true,\n };\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({\n component: componentName,\n variant: variantName ?? 'all',\n fixType,\n patches: result.patches,\n summary: result.summary,\n patchCount: result.patches.length,\n nextStep: result.patches.length > 0\n ? 'Apply patches using your editor or `patch` command, then run fragments_verify to confirm fixes.'\n : undefined,\n }, null, 2),\n },\n ],\n };\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Failed to generate fixes: ${error instanceof Error ? error.message : 'Unknown error'}. Make sure the Fragments dev server is running.`,\n },\n ],\n isError: true,\n };\n }\n }\n\n case TOOL_NAMES.recipe: {\n const data = await loadSegments();\n const recipeName = args?.name as string | undefined;\n const search = (args?.search as string)?.toLowerCase() ?? undefined;\n const component = (args?.component as string)?.toLowerCase() ?? undefined;\n\n const allRecipes = Object.values(data.recipes ?? {});\n\n if (allRecipes.length === 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: 0,\n recipes: [],\n hint: `No recipes found. Run \\`${BRAND.cliCommand} build\\` after adding .recipe.ts files.`,\n }, null, 2),\n }],\n };\n }\n\n let filtered = allRecipes;\n\n // Exact name match\n if (recipeName) {\n filtered = filtered.filter(\n r => r.name.toLowerCase() === recipeName.toLowerCase()\n );\n }\n\n // Free-text search\n if (search) {\n filtered = filtered.filter(r => {\n const haystack = [\n r.name,\n r.description,\n ...(r.tags ?? []),\n ...r.components,\n r.category,\n ].join(' ').toLowerCase();\n return haystack.includes(search);\n });\n }\n\n // Component filter\n if (component) {\n filtered = filtered.filter(r =>\n r.components.some(c => c.toLowerCase() === component)\n );\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n total: filtered.length,\n recipes: filtered,\n }, null, 2),\n }],\n };\n }\n\n case TOOL_NAMES.verify: {\n const { Timer, CaptureEngine: CE, bufferToBase64Url: toBase64 } = await getService();\n const timer = new Timer();\n const componentName = args?.component as string;\n const variantName = args?.variant as string;\n const theme = (args?.theme as Theme) ?? config.theme ?? DEFAULTS.theme;\n const threshold = (args?.threshold as number) ?? config.threshold ?? DEFAULTS.diffThreshold;\n\n if (!componentName || !variantName) {\n throw new Error('component and variant are required');\n }\n\n const storage = await getStorageManager();\n const pool = await getBrowserPool();\n const diff = await getDiffEngine();\n\n // Load baseline\n const baseline = await storage.loadBaseline(componentName, variantName, theme);\n\n if (!baseline) {\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n {\n verdict: 'error',\n matches: false,\n diffPercentage: 0,\n screenshot: '',\n baseline: '',\n notes: [],\n error: `No baseline found for ${componentName}/${variantName}. Run \\`${BRAND.cliCommand} screenshot\\` first.`,\n timing: { renderMs: 0, captureMs: 0, diffMs: 0, totalMs: timer.elapsed() },\n } satisfies VerifyResult,\n null,\n 2\n ),\n },\n ],\n };\n }\n\n // Capture current\n const viewerUrl = config.viewerUrl ?? `http://localhost:${DEFAULTS.port}`;\n const captureEngine = new CE(pool, viewerUrl);\n\n const current = await captureEngine.captureVariant(componentName, variantName, {\n theme,\n delay: DEFAULTS.captureDelayMs,\n });\n\n // Compare\n let diffResult;\n let matches = false;\n\n if (diff.areIdentical(current, baseline)) {\n matches = true;\n diffResult = {\n matches: true,\n diffPercentage: 0,\n diffPixelCount: 0,\n totalPixels: current.viewport.width * current.viewport.height,\n changedRegions: [],\n diffTimeMs: 0,\n };\n } else {\n diffResult = diff.compare(current, baseline, { threshold });\n matches = diffResult.matches;\n }\n\n const result: VerifyResult = {\n verdict: matches ? 'pass' : 'fail',\n matches,\n diffPercentage: diffResult.diffPercentage,\n screenshot: toBase64(current.data),\n baseline: toBase64(baseline.data),\n diffImage: diffResult.diffImage\n ? toBase64(diffResult.diffImage)\n : undefined,\n notes: matches\n ? ['Screenshot matches baseline within threshold']\n : [\n `Diff percentage (${diffResult.diffPercentage}%) exceeds threshold (${threshold}%)`,\n `${diffResult.changedRegions.length} changed region(s) detected`,\n ],\n timing: {\n renderMs: current.metadata.renderTimeMs,\n captureMs: current.metadata.captureTimeMs,\n diffMs: diffResult.diffTimeMs,\n totalMs: timer.elapsed(),\n },\n };\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({\n error: error instanceof Error ? error.message : String(error),\n }),\n },\n ],\n isError: true,\n };\n }\n });\n\n // Cleanup on close\n server.onclose = async () => {\n if (browserPool) {\n await browserPool.shutdown();\n }\n };\n\n return server;\n}\n\n/**\n * Start the MCP server with stdio transport\n */\nexport async function startMcpServer(config: McpServerConfig): Promise<void> {\n const server = createMcpServer(config);\n const transport = new StdioServerTransport();\n\n await server.connect(transport);\n}\n","/**\n * Utility functions for the MCP server\n */\n\n/**\n * Extract specific fields from an object using dot notation paths.\n * E.g., projectFields(obj, ['meta.name', 'usage.when']) returns { meta: { name: ... }, usage: { when: ... } }\n *\n * @param obj - The source object to extract fields from\n * @param fields - Array of field paths (supports dot notation for nested fields)\n * @returns A new object containing only the requested fields\n */\nexport function projectFields<T extends Record<string, unknown>>(\n obj: T,\n fields: string[]\n): Partial<T> {\n if (!fields || fields.length === 0) {\n return obj;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const field of fields) {\n const parts = field.split('.');\n let source: unknown = obj;\n let target = result;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const isLast = i === parts.length - 1;\n\n if (source === null || source === undefined || typeof source !== 'object') {\n break;\n }\n\n const sourceObj = source as Record<string, unknown>;\n const value = sourceObj[part];\n\n if (isLast) {\n // Set the final value\n target[part] = value;\n } else {\n // Create nested object if needed\n if (!(part in target)) {\n target[part] = {};\n }\n target = target[part] as Record<string, unknown>;\n source = value;\n }\n }\n }\n\n return result as Partial<T>;\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAyBP,SAAS,gBAAgB;AACzB,SAAS,kBAAkB;AAC3B,SAAS,YAAY;;;ACrBd,SAAS,cACd,KACA,QACY;AACZ,MAAI,CAAC,UAAU,OAAO,WAAW,GAAG;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,SAAkC,CAAC;AAEzC,aAAW,SAAS,QAAQ;AAC1B,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,QAAI,SAAkB;AACtB,QAAI,SAAS;AAEb,aAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,YAAM,OAAO,MAAM,CAAC;AACpB,YAAM,SAAS,MAAM,MAAM,SAAS;AAEpC,UAAI,WAAW,QAAQ,WAAW,UAAa,OAAO,WAAW,UAAU;AACzE;AAAA,MACF;AAEA,YAAM,YAAY;AAClB,YAAM,QAAQ,UAAU,IAAI;AAE5B,UAAI,QAAQ;AAEV,eAAO,IAAI,IAAI;AAAA,MACjB,OAAO;AAEL,YAAI,EAAE,QAAQ,SAAS;AACrB,iBAAO,IAAI,IAAI,CAAC;AAAA,QAClB;AACA,iBAAS,OAAO,IAAI;AACpB,iBAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ADnCA,IAAI,WAAiC;AACrC,eAAe,aAAqC;AAClD,MAAI,CAAC,UAAU;AACb,QAAI;AACF,iBAAW,MAAM,OAAO,oBAAoB;AAAA,IAC9C,QAAQ;AACN,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AASA,IAAM,aAAa;AAAA,EACjB,MAAM,GAAG,MAAM,SAAS;AAAA,EACxB,SAAS,GAAG,MAAM,SAAS;AAAA,EAC3B,KAAK,GAAG,MAAM,SAAS;AAAA,EACvB,YAAY,GAAG,MAAM,SAAS;AAAA,EAC9B,cAAc,GAAG,MAAM,SAAS;AAAA,EAChC,SAAS,GAAG,MAAM,SAAS;AAAA,EAC3B,QAAQ,GAAG,MAAM,SAAS;AAAA,EAC1B,SAAS,GAAG,MAAM,SAAS;AAAA,EAC3B,QAAQ,GAAG,MAAM,SAAS;AAAA,EAC1B,SAAS,GAAG,MAAM,SAAS;AAAA,EAC3B,KAAK,GAAG,MAAM,SAAS;AAAA,EACvB,QAAQ,GAAG,MAAM,SAAS;AAC5B;AAMA,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AACF;AAKA,SAAS,mBAAmB,OAAuC;AACjE,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO,MAAM;AAAA,IAAO,UAClB,CAAC,qBAAqB,KAAK,aAAW,QAAQ,KAAK,KAAK,KAAK,CAAC,CAAC;AAAA,EACjE;AACF;AAsBA,IAAM,QAAgB;AAAA,EACpB;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,UAAU;AAAA,UACR,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,MAAM,CAAC,UAAU,QAAQ,cAAc,cAAc;AAAA,UACrD,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,OAAO,EAAE,MAAM,SAAS;AAAA,UACxB,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,UAAU;AAAA,UACR,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM,CAAC,SAAS,MAAM;AAAA,UACtB,aAAa;AAAA,QACf;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,aAAa,SAAS;AAAA,IACnC;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,MAAM,CAAC,YAAY,MAAM;AAAA,UACzB,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,aAAa;AAAA,UACX,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,kBAAkB;AAAA,UAChB,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,UAAU;AAAA,UACR,MAAM;AAAA,UACN,YAAY;AAAA,YACV,OAAO,EAAE,MAAM,UAAU,aAAa,gCAAgC;AAAA,YACtE,QAAQ,EAAE,MAAM,UAAU,aAAa,iCAAiC;AAAA,UAC1E;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,UAAU;AAAA,UACR,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,MAAM,CAAC,SAAS,KAAK;AAAA,UACrB,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,WAAW;AAAA,IACxB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM,WAAW;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM;AAAA,UACJ,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAKO,SAAS,gBAAgB,QAAiC;AAC/D,QAAM,SAAS,IAAI;AAAA,IACjB;AAAA,MACE,MAAM,GAAG,MAAM,SAAS;AAAA,MACxB,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,cAAc;AAAA,QACZ,OAAO,CAAC;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAGA,MAAI,eAA4C;AAChD,MAAI,cAA6B;AAEjC,MAAI,cAAmB;AACvB,MAAI,iBAAsB;AAC1B,MAAI,aAAkB;AACtB,MAAI,gBAAgB;AAKpB,iBAAe,eAA8C;AAC3D,QAAI,cAAc;AAChB,aAAO;AAAA,IACT;AAEA,UAAM,eAAe,KAAK,OAAO,aAAa,MAAM,OAAO;AAE3D,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,YAAM,IAAI;AAAA,QACR,MAAM,MAAM,OAAO,iBAAiB,MAAM,UAAU;AAAA,MACtD;AAAA,IACF;AAEA,UAAM,UAAU,MAAM,SAAS,cAAc,OAAO;AACpD,mBAAe,KAAK,MAAM,OAAO;AACjC,WAAO;AAAA,EACT;AAKA,iBAAe,iBAAkC;AAC/C,QAAI,aAAa;AACf,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,KAAK,OAAO,aAAa,cAAc;AAC/D,QAAI,WAAW,eAAe,GAAG;AAC/B,UAAI;AACF,cAAM,UAAU,MAAM,SAAS,iBAAiB,OAAO;AACvD,cAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,YAAI,IAAI,MAAM;AACZ,wBAAc,IAAI;AAClB,iBAAO;AAAA,QACT;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAGA,kBAAc;AACd,WAAO;AAAA,EACT;AAKA,iBAAe,iBAAiB;AAC9B,QAAI,CAAC,aAAa;AAChB,YAAM,EAAE,YAAY,IAAI,MAAM,WAAW;AACzC,oBAAc,IAAI,YAAY;AAAA,QAC5B,UAAU,SAAS;AAAA;AAAA,QAEnB,eAAe,KAAK,KAAK;AAAA,QACzB,UAAU;AAAA;AAAA,MACZ,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAKA,WAAS,kBAAwB;AAC/B,QAAI,iBAAiB,aAAa,SAAS;AACzC;AAAA,IACF;AACA,oBAAgB;AAGhB,mBAAe,EAAE,KAAK,CAAC,SAAS;AAC9B,WAAK,OAAO,EAAE,KAAK,MAAM;AACvB,wBAAgB;AAAA,MAClB,CAAC,EAAE,MAAM,MAAM;AACb,wBAAgB;AAAA,MAClB,CAAC;AAAA,IACH,CAAC,EAAE,MAAM,MAAM;AACb,sBAAgB;AAAA,IAClB,CAAC;AAAA,EACH;AAKA,iBAAe,oBAAoB;AACjC,QAAI,CAAC,gBAAgB;AACnB,YAAM,EAAE,eAAe,IAAI,MAAM,WAAW;AAC5C,uBAAiB,IAAI,eAAe;AAAA,QAClC,aAAa,OAAO;AAAA,MACtB,CAAC;AACD,YAAM,eAAe,WAAW;AAAA,IAClC;AACA,WAAO;AAAA,EACT;AAKA,iBAAe,gBAAgB;AAC7B,QAAI,CAAC,YAAY;AACf,YAAM,EAAE,WAAW,IAAI,MAAM,WAAW;AACxC,mBAAa,IAAI,WAAW,OAAO,aAAa,SAAS,aAAa;AAAA,IACxE;AACA,WAAO;AAAA,EACT;AAGA,SAAO,kBAAkB,wBAAwB,YAAY;AAC3D,WAAO,EAAE,OAAO,MAAM;AAAA,EACxB,CAAC;AAGD,SAAO,kBAAkB,uBAAuB,OAAO,YAAY;AACjE,UAAM,EAAE,MAAM,WAAW,KAAK,IAAI,QAAQ;AAE1C,QAAI;AACF,cAAQ,MAAM;AAAA,QACZ,KAAK,WAAW,MAAM;AACpB,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,WAAY,MAAM,YAAuB;AAC/C,gBAAM,SAAU,MAAM,QAAmB,YAAY,KAAK;AAC1D,gBAAM,SAAU,MAAM,UAAqB;AAE3C,gBAAM,WAAW,OAAO,OAAO,KAAK,QAAQ,EACzC,OAAO,CAAC,MAAM;AAEb,gBAAI,YAAY,EAAE,KAAK,aAAa,SAAU,QAAO;AAGrD,gBAAI,WAAW,EAAE,KAAK,UAAU,cAAc,OAAQ,QAAO;AAG7D,gBAAI,QAAQ;AACV,oBAAM,YAAY,EAAE,KAAK,KAAK,YAAY,EAAE,SAAS,MAAM;AAC3D,oBAAM,YAAY,EAAE,KAAK,aAAa,YAAY,EAAE,SAAS,MAAM;AACnE,oBAAM,WAAW,EAAE,KAAK,MAAM,KAAK,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,MAAM,CAAC;AAC1E,kBAAI,CAAC,aAAa,CAAC,aAAa,CAAC,SAAU,QAAO;AAAA,YACpD;AAEA,mBAAO;AAAA,UACT,CAAC,EACA,IAAI,CAAC,OAAO;AAAA,YACX,MAAM,EAAE,KAAK;AAAA,YACb,UAAU,EAAE,KAAK;AAAA,YACjB,aAAa,EAAE,KAAK;AAAA,YACpB,QAAQ,EAAE,KAAK,UAAU;AAAA,YACzB,cAAc,EAAE,SAAS;AAAA,YACzB,MAAM,EAAE,KAAK,QAAQ,CAAC;AAAA,UACxB,EAAE;AAEJ,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK;AAAA,kBACT;AAAA,oBACE,OAAO,SAAS;AAAA,oBAChB;AAAA,oBACA,YAAY,CAAC,GAAG,IAAI,IAAI,SAAS,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AAAA,oBACxD,MAAM,SAAS,WAAW,IACtB,iFACA,SAAS,SAAS,IAChB,oHACA;AAAA,kBACR;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,SAAS;AACvB,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,UAAW,MAAM,SAAoB,YAAY,KAAK;AAC5D,gBAAM,UAAW,MAAM,SAAoB,YAAY,KAAK;AAE5D,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,qBAAqB;AAAA,UACvC;AAGA,gBAAM,cAAc,GAAG,OAAO,IAAI,OAAO,GAAG,MAAM,KAAK,EAAE,OAAO,OAAO;AAGvE,gBAAM,aAAuC;AAAA,YAC3C,QAAQ,CAAC,SAAS,SAAS,UAAU,YAAY;AAAA,YACjD,SAAS,CAAC,QAAQ,SAAS,QAAQ,OAAO;AAAA,YAC1C,UAAU,CAAC,UAAU,SAAS,UAAU,SAAS;AAAA,YACjD,UAAU,CAAC,UAAU,SAAS,SAAS;AAAA,YACvC,SAAS,CAAC,gBAAgB,WAAW,WAAW,SAAS,UAAU;AAAA,YACnE,gBAAgB,CAAC,SAAS,WAAW,OAAO;AAAA,YAC5C,QAAQ,CAAC,aAAa,SAAS,OAAO,SAAS;AAAA,YAC/C,UAAU,CAAC,UAAU,YAAY,WAAW,QAAQ;AAAA,YACpD,UAAU,CAAC,UAAU,YAAY,SAAS;AAAA,YAC1C,SAAS,CAAC,OAAO,SAAS,UAAU,WAAW;AAAA,YAC/C,UAAU,CAAC,SAAS,aAAa,OAAO;AAAA,YACxC,SAAS,CAAC,QAAQ,UAAU,kBAAkB,MAAM;AAAA,YACpD,QAAQ,CAAC,SAAS,UAAU,gBAAgB;AAAA,UAC9C;AAGA,gBAAM,gBAAgB,IAAI,IAAI,WAAW;AACzC,sBAAY,QAAQ,UAAQ;AAC1B,kBAAM,WAAW,WAAW,IAAI;AAChC,gBAAI,UAAU;AACZ,uBAAS,QAAQ,SAAO,cAAc,IAAI,GAAG,CAAC;AAAA,YAChD;AAAA,UACF,CAAC;AAGD,gBAAM,SAAS,OAAO,OAAO,KAAK,QAAQ,EAAE,IAAI,CAAC,MAAM;AACrD,gBAAI,QAAQ;AACZ,kBAAM,UAAoB,CAAC;AAG3B,kBAAM,YAAY,EAAE,KAAK,KAAK,YAAY;AAC1C,gBAAI,YAAY,KAAK,CAAC,SAAS,UAAU,SAAS,IAAI,CAAC,GAAG;AACxD,uBAAS;AACT,sBAAQ,KAAK,qBAAqB;AAAA,YACpC,WAAW,MAAM,KAAK,aAAa,EAAE,KAAK,CAAC,SAAS,UAAU,SAAS,IAAI,CAAC,GAAG;AAC7E,uBAAS;AACT,sBAAQ,KAAK,2BAA2B;AAAA,YAC1C;AAGA,kBAAM,OAAO,EAAE,KAAK,aAAa,YAAY,KAAK;AAClD,kBAAM,cAAc,YAAY,OAAO,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC;AACpE,gBAAI,YAAY,SAAS,GAAG;AAC1B,uBAAS,YAAY,SAAS;AAC9B,sBAAQ,KAAK,wBAAwB,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,YAC/D;AAGA,kBAAM,OAAO,EAAE,KAAK,MAAM,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC;AAC1D,kBAAM,aAAa,YAAY;AAAA,cAAO,CAAC,SACrC,KAAK,KAAK,CAAC,QAAQ,IAAI,SAAS,IAAI,CAAC;AAAA,YACvC;AACA,gBAAI,WAAW,SAAS,GAAG;AACzB,uBAAS,WAAW,SAAS;AAC7B,sBAAQ,KAAK,eAAe,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,YACrD;AAGA,kBAAM,WAAW,EAAE,OAAO,MAAM,KAAK,GAAG,EAAE,YAAY,KAAK;AAC3D,kBAAM,cAAc,YAAY,OAAO,CAAC,SAAS,SAAS,SAAS,IAAI,CAAC;AACxE,gBAAI,YAAY,SAAS,GAAG;AAC1B,uBAAS,YAAY,SAAS;AAC9B,sBAAQ,KAAK,qBAAqB,YAAY,KAAK,IAAI,CAAC,GAAG;AAAA,YAC7D;AAGA,kBAAM,sBAAsB,MAAM,KAAK,aAAa,EAAE;AAAA,cACpD,CAAC,SAAS,CAAC,YAAY,SAAS,IAAI,KAAK,SAAS,SAAS,IAAI;AAAA,YACjE;AACA,gBAAI,oBAAoB,SAAS,GAAG;AAClC,uBAAS,oBAAoB,SAAS;AACtC,sBAAQ,KAAK,uBAAuB,oBAAoB,KAAK,IAAI,CAAC,GAAG;AAAA,YACvE;AAGA,kBAAM,WAAW,EAAE,KAAK,UAAU,YAAY,KAAK;AACnD,gBAAI,YAAY,KAAK,CAAC,SAAS,SAAS,SAAS,IAAI,CAAC,GAAG;AACvD,uBAAS;AACT,sBAAQ,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAE;AAAA,YAC7C;AAGA,kBAAM,cAAc,EAAE,SACnB,IAAI,OAAK,GAAG,EAAE,IAAI,IAAI,EAAE,eAAe,EAAE,GAAG,YAAY,CAAC,EACzD,KAAK,GAAG;AACX,kBAAM,iBAAiB,YAAY,OAAO,UAAQ,YAAY,SAAS,IAAI,CAAC;AAC5E,gBAAI,eAAe,SAAS,GAAG;AAC7B,uBAAS,eAAe,SAAS;AACjC,sBAAQ,KAAK,mBAAmB,eAAe,KAAK,IAAI,CAAC,EAAE;AAAA,YAC7D;AAGA,gBAAI,EAAE,KAAK,WAAW,UAAU;AAC9B,uBAAS;AACT,sBAAQ,KAAK,kBAAkB;AAAA,YACjC,WAAW,EAAE,KAAK,WAAW,QAAQ;AACnC,uBAAS;AAAA,YACX;AAGA,gBAAI,EAAE,KAAK,WAAW,cAAc;AAClC,uBAAS;AACT,sBAAQ,KAAK,oCAAoC;AAAA,YACnD;AAGA,kBAAM,eAAe,mBAAmB,EAAE,OAAO,IAAI,EAAE,MAAM,GAAG,CAAC;AACjE,kBAAM,kBAAkB,mBAAmB,EAAE,OAAO,OAAO,EAAE,MAAM,GAAG,CAAC;AAGvE,gBAAI;AACJ,gBAAI,SAAS,IAAI;AACf,2BAAa;AAAA,YACf,WAAW,SAAS,IAAI;AACtB,2BAAa;AAAA,YACf,OAAO;AACL,2BAAa;AAAA,YACf;AAEA,mBAAO;AAAA,cACL,WAAW,EAAE,KAAK;AAAA,cAClB,UAAU,EAAE,KAAK;AAAA,cACjB,aAAa,EAAE,KAAK;AAAA,cACpB;AAAA,cACA;AAAA,cACA;AAAA,cACA,OAAO;AAAA,gBACL,MAAM;AAAA,gBACN,SAAS;AAAA,cACX;AAAA,cACA,cAAc,EAAE,SAAS;AAAA,cACzB,QAAQ,EAAE,KAAK;AAAA,YACjB;AAAA,UACF,CAAC;AAGD,gBAAM,YAAY;AAClB,gBAAM,WAAW,OACd,OAAO,CAAC,MAAM,EAAE,SAAS,SAAS,EAClC,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK;AAGnC,gBAAM,cAA+B,CAAC;AACtC,gBAAM,gBAAwC,CAAC;AAC/C,qBAAW,QAAQ,UAAU;AAC3B,kBAAM,MAAM,KAAK,YAAY;AAC7B,kBAAM,QAAQ,cAAc,GAAG,KAAK;AACpC,gBAAI,QAAQ,KAAK,YAAY,SAAS,GAAG;AACvC,0BAAY,KAAK,IAAI;AACrB,4BAAc,GAAG,IAAI,QAAQ;AAC7B,kBAAI,YAAY,UAAU,EAAG;AAAA,YAC/B;AAAA,UACF;AAGA,gBAAM,kBAAkB,YAAY,UAAU,IAC1C,qDAAqD,YAAY,CAAC,EAAE,SAAS,yBAAyB,YAAY,MAAM,GAAG,CAAC,EAAE,IAAI,OAAK,EAAE,SAAS,EAAE,KAAK,OAAO,CAAC,MACjK;AAEJ,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK;AAAA,kBACT;AAAA,oBACE;AAAA,oBACA,SAAS,WAAW;AAAA,oBACpB,aAAa,YAAY,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,MAAM,IAAI;AAAA,oBACzD,gBAAgB,YAAY,SAAS,IACjC,eAAe,YAAY,CAAC,EAAE,SAAS,KAAK,YAAY,CAAC,EAAE,UAAU,kBAAkB,YAAY,CAAC,EAAE,WAAW,KACjH;AAAA,oBACJ;AAAA,oBACA,UAAU,YAAY,SAAS,IAC3B,sBAAsB,YAAY,CAAC,EAAE,SAAS,iDAAiD,YAAY,CAAC,EAAE,SAAS,wBACvH;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,KAAK;AACnB,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,SAAS,MAAM;AAErB,cAAI,CAAC,eAAe;AAClB,kBAAM,IAAI,MAAM,uBAAuB;AAAA,UACzC;AAEA,gBAAM,UAAU,OAAO,OAAO,KAAK,QAAQ,EAAE;AAAA,YAC3C,CAAC,MAAM,EAAE,KAAK,KAAK,YAAY,MAAM,cAAc,YAAY;AAAA,UACjE;AAEA,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,cAAc,aAAa,8DAA8D;AAAA,UAC3G;AAGA,gBAAM,SAAS,UAAU,OAAO,SAAS,IACrC,cAAc,SAA+C,MAAM,IACnE;AAEJ,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,cACtC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,YAAY;AAC1B,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,SAAS,MAAM;AAErB,cAAI,CAAC,eAAe;AAClB,kBAAM,IAAI,MAAM,uBAAuB;AAAA,UACzC;AAEA,gBAAM,UAAU,OAAO,OAAO,KAAK,QAAQ,EAAE;AAAA,YAC3C,CAAC,MAAM,EAAE,KAAK,KAAK,YAAY,MAAM,cAAc,YAAY;AAAA,UACjE;AAEA,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,cAAc,aAAa,8DAA8D;AAAA,UAC3G;AAGA,gBAAM,aAAa;AAAA,YACjB,WAAW,QAAQ,KAAK;AAAA,YACxB,aAAa,QAAQ,KAAK;AAAA,YAC1B,QAAQ,QAAQ,KAAK,UAAU;AAAA,YAC/B,MAAM,mBAAmB,QAAQ,OAAO,IAAI;AAAA,YAC5C,SAAS,mBAAmB,QAAQ,OAAO,OAAO;AAAA,YAClD,YAAY,QAAQ,OAAO,cAAc,CAAC;AAAA,YAC1C,eAAe,QAAQ,OAAO,iBAAiB,CAAC;AAAA;AAAA,YAEhD,iBAAiB,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAChD,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,eAAe,KAAK,YAAY,SAAS,CAAC,EACpE,IAAI,CAAC,CAACA,OAAM,IAAI,OAAO;AAAA,cACtB,MAAMA;AAAA,cACN,aAAa,KAAK;AAAA,YACpB,EAAE;AAAA;AAAA,YAEJ,cAAc,QAAQ,WAClB,OAAO,CAAC,MAAM,EAAE,iBAAiB,aAAa,EAC/C,IAAI,CAAC,OAAO;AAAA,cACX,WAAW,EAAE;AAAA,cACb,MAAM,EAAE;AAAA,YACV,EAAE,KAAK,CAAC;AAAA,UACZ;AAGA,gBAAM,SAAS,UAAU,OAAO,SAAS,IACrC,cAAc,YAAkD,MAAM,IACtE;AAEJ,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,cACtC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,cAAc;AAC5B,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,gBAAgB,MAAM;AAE5B,cAAI,CAAC,eAAe;AAClB,kBAAM,IAAI,MAAM,uBAAuB;AAAA,UACzC;AAEA,gBAAM,UAAU,OAAO,OAAO,KAAK,QAAQ,EAAE;AAAA,YAC3C,CAAC,MAAM,EAAE,KAAK,KAAK,YAAY,MAAM,cAAc,YAAY;AAAA,UACjE;AAEA,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,cAAc,aAAa,8DAA8D;AAAA,UAC3G;AAGA,gBAAM,YAAY,QAAQ,aAAa,CAAC;AAGxC,gBAAM,eAAe,OAAO,OAAO,KAAK,QAAQ,EAC7C;AAAA,YAAO,CAAC,MACP,EAAE,WAAW,KAAK,CAAC,MAAM,EAAE,UAAU,YAAY,MAAM,cAAc,YAAY,CAAC;AAAA,UACpF,EACC,IAAI,CAAC,OAAO;AAAA,YACX,WAAW,EAAE,KAAK;AAAA,YAClB,cAAc,EAAE,WAAW;AAAA,cACzB,CAAC,MAAM,EAAE,UAAU,YAAY,MAAM,cAAc,YAAY;AAAA,YACjE,GAAG;AAAA,YACH,MAAM,EAAE,WAAW;AAAA,cACjB,CAAC,MAAM,EAAE,UAAU,YAAY,MAAM,cAAc,YAAY;AAAA,YACjE,GAAG;AAAA,UACL,EAAE;AAGJ,gBAAM,eAAe,OAAO,OAAO,KAAK,QAAQ,EAC7C;AAAA,YACC,CAAC,MACC,EAAE,KAAK,aAAa,QAAQ,KAAK,YACjC,EAAE,KAAK,KAAK,YAAY,MAAM,cAAc,YAAY;AAAA,UAC5D,EACC,IAAI,CAAC,OAAO;AAAA,YACX,WAAW,EAAE,KAAK;AAAA,YAClB,aAAa,EAAE,KAAK;AAAA,UACtB,EAAE;AAEJ,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK;AAAA,kBACT;AAAA,oBACE,WAAW,QAAQ,KAAK;AAAA,oBACxB,UAAU,QAAQ,KAAK;AAAA,oBACvB,iBAAiB;AAAA,oBACjB;AAAA,oBACA;AAAA,oBACA,YAAY,UAAU,KAAK,CAAC,MAAM,EAAE,iBAAiB,aAAa,IAC9D,YAAY,UAAU,KAAK,CAAC,MAAM,EAAE,iBAAiB,aAAa,GAAG,SAAS,KAAK,UAAU,KAAK,CAAC,MAAM,EAAE,iBAAiB,aAAa,GAAG,IAAI,KAChJ;AAAA,kBACN;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,SAAS;AACvB,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,cAAe,MAAM,WAAsB;AACjD,gBAAM,cAAc,MAAM;AAC1B,gBAAM,WAAW,MAAM;AAEvB,cAAI,CAAC,eAAe;AAClB,kBAAM,IAAI,MAAM,uBAAuB;AAAA,UACzC;AAEA,gBAAM,UAAU,OAAO,OAAO,KAAK,QAAQ,EAAE;AAAA,YAC3C,CAAC,MAAM,EAAE,KAAK,KAAK,YAAY,MAAM,cAAc,YAAY;AAAA,UACjE;AAEA,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,cAAc,aAAa,8DAA8D;AAAA,UAC3G;AAGA,cAAI,WAAW,QAAQ;AACvB,cAAI,aAAa;AACf,kBAAM,WAAW,SAAS;AAAA,cACxB,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,YAAY,YAAY;AAAA,YAC1D;AACA,gBAAI,SAAS,WAAW,GAAG;AACzB,oBAAM,IAAI;AAAA,gBACR,YAAY,WAAW,mBAAmB,aAAa,gBAAgB,SAAS,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,cAC/G;AAAA,YACF;AACA,uBAAW;AAAA,UACb;AAGA,cAAI,eAAe,cAAc,GAAG;AAClC,uBAAW,SAAS,MAAM,GAAG,WAAW;AAAA,UAC1C;AAGA,gBAAM,eAAe,CAAC,SAAyB;AAC7C,gBAAI,CAAC,YAAY,YAAY,EAAG,QAAO;AACvC,kBAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,gBAAI,MAAM,UAAU,SAAU,QAAO;AACrC,mBAAO,MAAM,MAAM,GAAG,QAAQ,EAAE,KAAK,IAAI,IAAI;AAAA,UAC/C;AAGA,gBAAM,WAAW,SAAS,IAAI,CAAC,YAAY;AAEzC,gBAAI,QAAQ,MAAM;AAChB,qBAAO;AAAA,gBACL,SAAS,QAAQ;AAAA,gBACjB,aAAa,QAAQ;AAAA,gBACrB,MAAM,aAAa,QAAQ,IAAI;AAAA,cACjC;AAAA,YACF;AAIA,kBAAM,YAAY,IAAI,QAAQ,KAAK,IAAI;AAEvC,mBAAO;AAAA,cACL,SAAS,QAAQ;AAAA,cACjB,aAAa,QAAQ;AAAA,cACrB,MAAM;AAAA,cACN,MAAM;AAAA,YACR;AAAA,UACF,CAAC;AAGD,gBAAM,UAAU,MAAM,eAAe;AACrC,gBAAM,kBAAkB,YAAY,QAAQ,KAAK,IAAI,YAAY,OAAO;AAGxE,gBAAM,iBAAiB,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,UAAU,IAAI,OAAO;AAAA,YACpF,MAAM;AAAA,YACN,MAAM,KAAK;AAAA,YACX,UAAU,KAAK;AAAA,YACf,SAAS,KAAK;AAAA,YACd,aAAa,KAAK;AAAA,UACpB,EAAE;AAEF,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK;AAAA,kBACT;AAAA,oBACE,WAAW,QAAQ,KAAK;AAAA,oBACxB,QAAQ;AAAA,oBACR;AAAA,oBACA;AAAA,oBACA,KAAK;AAAA,kBACP;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,SAAS;AACvB,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,SAAU,MAAM,UAAkC;AACxD,gBAAM,UAAW,MAAM,WAAuB;AAC9C,gBAAM,cAAe,MAAM,eAA2B;AACtD,gBAAM,mBAAoB,MAAM,oBAAgC;AAEhE,gBAAM,WAAW,OAAO,OAAO,KAAK,QAAQ;AAC5C,gBAAM,UAAU,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC;AAEhD,gBAAM,EAAE,SAAS,cAAc,IAAI,gBAAgB,UAAU;AAAA,YAC3D;AAAA,YACA;AAAA,YACA,SAAS;AAAA,cACP,MAAM;AAAA,cACN,WAAW;AAAA,YACb;AAAA,UACF,GAAG,OAAO;AAEV,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM;AAAA,cACR;AAAA,YACF;AAAA;AAAA,YAEA,OAAO;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,QAAQ;AACtB,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,QAAS,MAAM,SAAqC,CAAC;AAC3D,gBAAM,WAAW,MAAM;AAEvB,cAAI,CAAC,eAAe;AAClB,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM;AAAA,gBACR;AAAA,cACF;AAAA,cACA,SAAS;AAAA,YACX;AAAA,UACF;AAGA,gBAAM,UAAU,OAAO,aAAa;AACpC,gBAAM,YAAY,GAAG,OAAO;AAE5B,cAAI;AACF,kBAAM,WAAW,MAAM,MAAM,WAAW;AAAA,cACtC,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,cAC9C,MAAM,KAAK,UAAU;AAAA,gBACnB,WAAW;AAAA,gBACX;AAAA,gBACA,UAAU,YAAY,EAAE,OAAO,KAAK,QAAQ,IAAI;AAAA,cAClD,CAAC;AAAA,YACH,CAAC;AAED,kBAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,gBAAI,CAAC,SAAS,MAAM,OAAO,OAAO;AAChC,qBAAO;AAAA,gBACL,SAAS;AAAA,kBACP;AAAA,oBACE,MAAM;AAAA,oBACN,MAAM,iBAAiB,OAAO,SAAS,eAAe;AAAA,kBACxD;AAAA,gBACF;AAAA,gBACA,SAAS;AAAA,cACX;AAAA,YACF;AAGA,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,OAAO,WAAY,QAAQ,0BAA0B,EAAE;AAAA,kBAC7D,UAAU;AAAA,gBACZ;AAAA,gBACA;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,yBAAyB,aAAa,gBAAgB,KAAK,UAAU,KAAK,CAAC;AAAA,gBACnF;AAAA,cACF;AAAA,YACF;AAAA,UACF,SAAS,OAAO;AACd,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,+BAA+B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,gBAC/F;AAAA,cACF;AAAA,cACA,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,SAAS;AACvB,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,cAAc,MAAM;AAC1B,gBAAM,QAAS,MAAM,SAAqC,CAAC;AAC3D,gBAAM,WAAW,MAAM;AACvB,gBAAM,YAAa,MAAM,aAAwB;AAEjD,cAAI,CAAC,eAAe;AAClB,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM;AAAA,gBACR;AAAA,cACF;AAAA,cACA,SAAS;AAAA,YACX;AAAA,UACF;AAGA,gBAAM,UAAU,OAAO,aAAa;AACpC,gBAAM,aAAa,GAAG,OAAO;AAE7B,cAAI;AACF,kBAAM,WAAW,MAAM,MAAM,YAAY;AAAA,cACvC,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,cAC9C,MAAM,KAAK,UAAU;AAAA,gBACnB,WAAW;AAAA,gBACX,SAAS;AAAA,gBACT;AAAA,gBACA;AAAA,gBACA;AAAA,cACF,CAAC;AAAA,YACH,CAAC;AAeD,kBAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,gBAAI,CAAC,SAAS,MAAM,OAAO,OAAO;AAChC,qBAAO;AAAA,gBACL,SAAS;AAAA,kBACP;AAAA,oBACE,MAAM;AAAA,oBACN,MAAM,kBAAkB,OAAO,SAAS,eAAe,GAAG,OAAO,aAAa;AAAA,cAAiB,OAAO,UAAU,KAAK,EAAE;AAAA,kBACzH;AAAA,gBACF;AAAA,gBACA,SAAS;AAAA,cACX;AAAA,YACF;AAGA,kBAAM,UAAoF,CAAC;AAG3F,kBAAM,cAAc,OAAO,QACvB,iBAAY,aAAa,0BAA0B,OAAO,cAAc,sBAAsB,OAAO,SAAS,OAC9G,oBAAe,aAAa,iCAAiC,OAAO,cAAc,iBAAiB,OAAO,SAAS;AAEvH,oBAAQ,KAAK;AAAA,cACX,MAAM;AAAA,cACN,MAAM;AAAA,YACR,CAAC;AAGD,gBAAI,OAAO,QAAQ,CAAC,OAAO,OAAO;AAChC,sBAAQ,KAAK;AAAA,gBACX,MAAM;AAAA,gBACN,MAAM,OAAO,KAAK,QAAQ,0BAA0B,EAAE;AAAA,gBACtD,UAAU;AAAA,cACZ,CAAC;AACD,sBAAQ,KAAK;AAAA,gBACX,MAAM;AAAA,gBACN,MAAM,gFAAgF,OAAO,gBAAgB,UAAU,CAAC;AAAA,cAC1H,CAAC;AAAA,YACH;AAGA,oBAAQ,KAAK;AAAA,cACX,MAAM;AAAA,cACN,MAAM,KAAK,UAAU;AAAA,gBACnB,OAAO,OAAO;AAAA,gBACd,gBAAgB,OAAO;AAAA,gBACvB,WAAW,OAAO;AAAA,gBAClB,UAAU,OAAO;AAAA,gBACjB,gBAAgB,OAAO;AAAA,cACzB,GAAG,MAAM,CAAC;AAAA,YACZ,CAAC;AAED,mBAAO,EAAE,QAAQ;AAAA,UACnB,SAAS,OAAO;AACd,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,gCAAgC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,gBAChG;AAAA,cACF;AAAA,cACA,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,KAAK;AACnB,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,cAAe,MAAM,WAAsB;AACjD,gBAAM,UAAW,MAAM,WAA+B;AAEtD,cAAI,CAAC,eAAe;AAClB,kBAAM,IAAI,MAAM,uBAAuB;AAAA,UACzC;AAEA,gBAAM,UAAU,OAAO,OAAO,KAAK,QAAQ,EAAE;AAAA,YAC3C,CAAC,MAAM,EAAE,KAAK,KAAK,YAAY,MAAM,cAAc,YAAY;AAAA,UACjE;AAEA,cAAI,CAAC,SAAS;AACZ,kBAAM,IAAI,MAAM,cAAc,aAAa,8DAA8D;AAAA,UAC3G;AAGA,gBAAM,UAAU,OAAO,aAAa;AACpC,gBAAM,SAAS,GAAG,OAAO;AAEzB,cAAI;AACF,kBAAM,WAAW,MAAM,MAAM,QAAQ;AAAA,cACnC,QAAQ;AAAA,cACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,cAC9C,MAAM,KAAK,UAAU;AAAA,gBACnB,WAAW;AAAA,gBACX,SAAS;AAAA,gBACT;AAAA,cACF,CAAC;AAAA,YACH,CAAC;AAQD,kBAAM,SAAS,MAAM,SAAS,KAAK;AAEnC,gBAAI,CAAC,SAAS,MAAM,OAAO,OAAO;AAChC,qBAAO;AAAA,gBACL,SAAS;AAAA,kBACP;AAAA,oBACE,MAAM;AAAA,oBACN,MAAM,yBAAyB,OAAO,SAAS,eAAe;AAAA,kBAChE;AAAA,gBACF;AAAA,gBACA,SAAS;AAAA,cACX;AAAA,YACF;AAEA,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,KAAK,UAAU;AAAA,oBACnB,WAAW;AAAA,oBACX,SAAS,eAAe;AAAA,oBACxB;AAAA,oBACA,SAAS,OAAO;AAAA,oBAChB,SAAS,OAAO;AAAA,oBAChB,YAAY,OAAO,QAAQ;AAAA,oBAC3B,UAAU,OAAO,QAAQ,SAAS,IAC9B,oGACA;AAAA,kBACN,GAAG,MAAM,CAAC;AAAA,gBACZ;AAAA,cACF;AAAA,YACF;AAAA,UACF,SAAS,OAAO;AACd,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,6BAA6B,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,gBAC7F;AAAA,cACF;AAAA,cACA,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,QAAQ;AACtB,gBAAM,OAAO,MAAM,aAAa;AAChC,gBAAM,aAAa,MAAM;AACzB,gBAAM,SAAU,MAAM,QAAmB,YAAY,KAAK;AAC1D,gBAAM,YAAa,MAAM,WAAsB,YAAY,KAAK;AAEhE,gBAAM,aAAa,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC;AAEnD,cAAI,WAAW,WAAW,GAAG;AAC3B,mBAAO;AAAA,cACL,SAAS,CAAC;AAAA,gBACR,MAAM;AAAA,gBACN,MAAM,KAAK,UAAU;AAAA,kBACnB,OAAO;AAAA,kBACP,SAAS,CAAC;AAAA,kBACV,MAAM,2BAA2B,MAAM,UAAU;AAAA,gBACnD,GAAG,MAAM,CAAC;AAAA,cACZ,CAAC;AAAA,YACH;AAAA,UACF;AAEA,cAAI,WAAW;AAGf,cAAI,YAAY;AACd,uBAAW,SAAS;AAAA,cAClB,OAAK,EAAE,KAAK,YAAY,MAAM,WAAW,YAAY;AAAA,YACvD;AAAA,UACF;AAGA,cAAI,QAAQ;AACV,uBAAW,SAAS,OAAO,OAAK;AAC9B,oBAAM,WAAW;AAAA,gBACf,EAAE;AAAA,gBACF,EAAE;AAAA,gBACF,GAAI,EAAE,QAAQ,CAAC;AAAA,gBACf,GAAG,EAAE;AAAA,gBACL,EAAE;AAAA,cACJ,EAAE,KAAK,GAAG,EAAE,YAAY;AACxB,qBAAO,SAAS,SAAS,MAAM;AAAA,YACjC,CAAC;AAAA,UACH;AAGA,cAAI,WAAW;AACb,uBAAW,SAAS;AAAA,cAAO,OACzB,EAAE,WAAW,KAAK,OAAK,EAAE,YAAY,MAAM,SAAS;AAAA,YACtD;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,SAAS,CAAC;AAAA,cACR,MAAM;AAAA,cACN,MAAM,KAAK,UAAU;AAAA,gBACnB,OAAO,SAAS;AAAA,gBAChB,SAAS;AAAA,cACX,GAAG,MAAM,CAAC;AAAA,YACZ,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QAEA,KAAK,WAAW,QAAQ;AACtB,gBAAM,EAAE,OAAO,eAAe,IAAI,mBAAmB,SAAS,IAAI,MAAM,WAAW;AACnF,gBAAM,QAAQ,IAAI,MAAM;AACxB,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,cAAc,MAAM;AAC1B,gBAAM,QAAS,MAAM,SAAmB,OAAO,SAAS,SAAS;AACjE,gBAAM,YAAa,MAAM,aAAwB,OAAO,aAAa,SAAS;AAE9E,cAAI,CAAC,iBAAiB,CAAC,aAAa;AAClC,kBAAM,IAAI,MAAM,oCAAoC;AAAA,UACtD;AAEA,gBAAM,UAAU,MAAM,kBAAkB;AACxC,gBAAM,OAAO,MAAM,eAAe;AAClC,gBAAM,OAAO,MAAM,cAAc;AAGjC,gBAAM,WAAW,MAAM,QAAQ,aAAa,eAAe,aAAa,KAAK;AAE7E,cAAI,CAAC,UAAU;AACb,mBAAO;AAAA,cACL,SAAS;AAAA,gBACP;AAAA,kBACE,MAAM;AAAA,kBACN,MAAM,KAAK;AAAA,oBACT;AAAA,sBACE,SAAS;AAAA,sBACT,SAAS;AAAA,sBACT,gBAAgB;AAAA,sBAChB,YAAY;AAAA,sBACZ,UAAU;AAAA,sBACV,OAAO,CAAC;AAAA,sBACR,OAAO,yBAAyB,aAAa,IAAI,WAAW,WAAW,MAAM,UAAU;AAAA,sBACvF,QAAQ,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,MAAM,QAAQ,EAAE;AAAA,oBAC3E;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,YAAY,OAAO,aAAa,oBAAoB,SAAS,IAAI;AACvE,gBAAM,gBAAgB,IAAI,GAAG,MAAM,SAAS;AAE5C,gBAAM,UAAU,MAAM,cAAc,eAAe,eAAe,aAAa;AAAA,YAC7E;AAAA,YACA,OAAO,SAAS;AAAA,UAClB,CAAC;AAGD,cAAI;AACJ,cAAI,UAAU;AAEd,cAAI,KAAK,aAAa,SAAS,QAAQ,GAAG;AACxC,sBAAU;AACV,yBAAa;AAAA,cACX,SAAS;AAAA,cACT,gBAAgB;AAAA,cAChB,gBAAgB;AAAA,cAChB,aAAa,QAAQ,SAAS,QAAQ,QAAQ,SAAS;AAAA,cACvD,gBAAgB,CAAC;AAAA,cACjB,YAAY;AAAA,YACd;AAAA,UACF,OAAO;AACL,yBAAa,KAAK,QAAQ,SAAS,UAAU,EAAE,UAAU,CAAC;AAC1D,sBAAU,WAAW;AAAA,UACvB;AAEA,gBAAM,SAAuB;AAAA,YAC3B,SAAS,UAAU,SAAS;AAAA,YAC5B;AAAA,YACA,gBAAgB,WAAW;AAAA,YAC3B,YAAY,SAAS,QAAQ,IAAI;AAAA,YACjC,UAAU,SAAS,SAAS,IAAI;AAAA,YAChC,WAAW,WAAW,YAClB,SAAS,WAAW,SAAS,IAC7B;AAAA,YACJ,OAAO,UACH,CAAC,8CAA8C,IAC/C;AAAA,cACE,oBAAoB,WAAW,cAAc,yBAAyB,SAAS;AAAA,cAC/E,GAAG,WAAW,eAAe,MAAM;AAAA,YACrC;AAAA,YACJ,QAAQ;AAAA,cACN,UAAU,QAAQ,SAAS;AAAA,cAC3B,WAAW,QAAQ,SAAS;AAAA,cAC5B,QAAQ,WAAW;AAAA,cACnB,SAAS,MAAM,QAAQ;AAAA,YACzB;AAAA,UACF;AAEA,iBAAO;AAAA,YACL,SAAS;AAAA,cACP;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM,KAAK,UAAU,QAAQ,MAAM,CAAC;AAAA,cACtC;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA;AACE,gBAAM,IAAI,MAAM,iBAAiB,IAAI,EAAE;AAAA,MAC3C;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS;AAAA,UACP;AAAA,YACE,MAAM;AAAA,YACN,MAAM,KAAK,UAAU;AAAA,cACnB,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,YAC9D,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AAGD,SAAO,UAAU,YAAY;AAC3B,QAAI,aAAa;AACf,YAAM,YAAY,SAAS;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAsB,eAAe,QAAwC;AAC3E,QAAM,SAAS,gBAAgB,MAAM;AACrC,QAAM,YAAY,IAAI,qBAAqB;AAE3C,QAAM,OAAO,QAAQ,SAAS;AAChC;","names":["name"]}