@ufira/vibma 0.3.1 → 0.3.2-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/mcp.cjs +61 -10
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.js +61 -10
- package/dist/mcp.js.map +1 -1
- package/package.json +3 -4
package/dist/mcp.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp.ts","../src/tools/types.ts","../src/tools/registry.ts","../src/tools/defs/connection.ts","../src/tools/defs/document.ts","../src/tools/defs/selection.ts","../src/utils/coercion.ts","../src/tools/defs/node-info.ts","../src/tools/defs/create-shape.ts","../src/tools/schemas.ts","../src/tools/defs/create-frame.ts","../src/tools/defs/create-text.ts","../src/tools/defs/modify-node.ts","../src/tools/defs/patch-nodes.ts","../src/tools/defs/text.ts","../src/tools/defs/fonts.ts","../src/tools/defs/lint.ts","../src/tools/defs/styles.ts","../src/tools/endpoint.ts","../src/tools/defs/variables.ts","../src/tools/defs/components.ts","../src/tools/prompts.ts","../src/tools/mcp-registry.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport WebSocket from \"ws\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { readFileSync } from \"fs\";\nimport { join, basename } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { registerAllTools } from \"./tools/mcp-registry\";\n\n// Read version — works with both tsx (source) and node (compiled dist/)\nlet VIBMA_VERSION = \"0.0.0\";\ntry {\n // Walk up from current file's dir to find package.json\n // Use import.meta.url (works in ESM), __dirname (works in CJS), process.cwd() as last resort\n const start = typeof import.meta?.url !== \"undefined\"\n ? join(fileURLToPath(import.meta.url), \"..\")\n : typeof __dirname !== \"undefined\" ? __dirname : process.cwd();\n for (let dir = start; dir !== \"/\"; dir = join(dir, \"..\")) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, \"package.json\"), \"utf8\"));\n if (pkg.name === \"@ufira/vibma\") { VIBMA_VERSION = pkg.version; break; }\n } catch { continue; }\n }\n} catch { /* fallback */ }\n\n// ─── Logger (stderr so it doesn't pollute MCP stdio) ────────────\nconst logger = {\n info: (msg: string) => process.stderr.write(`[INFO] ${msg}\\n`),\n debug: (msg: string) => process.stderr.write(`[DEBUG] ${msg}\\n`),\n warn: (msg: string) => process.stderr.write(`[WARN] ${msg}\\n`),\n error: (msg: string) => process.stderr.write(`[ERROR] ${msg}\\n`),\n log: (msg: string) => process.stderr.write(`[LOG] ${msg}\\n`),\n};\n\n// ─── Types ───────────────────────────────────────────────────────\n\ninterface FigmaResponse {\n id: string;\n result?: any;\n error?: string;\n}\n\ninterface CommandProgressUpdate {\n type: \"command_progress\";\n commandId: string;\n commandType: string;\n status: \"started\" | \"in_progress\" | \"completed\" | \"error\";\n progress: number;\n totalItems: number;\n processedItems: number;\n currentChunk?: number;\n totalChunks?: number;\n chunkSize?: number;\n message: string;\n payload?: any;\n timestamp: number;\n}\n\n// ─── WebSocket state ─────────────────────────────────────────────\n\nlet ws: WebSocket | null = null;\nconst pendingRequests = new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n timeout: ReturnType<typeof setTimeout>;\n lastActivity: number;\n }\n>();\nlet currentChannel: string | null = null;\nlet activePort: number = parseInt(process.env.VIBMA_PORT || \"3055\");\nlet rejected = false; // Suppress auto-reconnect after ROLE_OCCUPIED rejection\nlet versionWarning: string | null = null;\n\n// CLI args\nconst args = process.argv.slice(2);\nconst serverArg = args.find((a) => a.startsWith(\"--server=\"));\nconst portArg = args.find((a) => a.startsWith(\"--port=\"));\nconst serverUrl = serverArg ? serverArg.split(\"=\")[1] : \"localhost\";\nif (portArg) activePort = parseInt(portArg.split(\"=\")[1]);\nconst WS_URL = serverUrl === \"localhost\" ? `ws://${serverUrl}` : `wss://${serverUrl}`;\n\n// Access-tier flags: read is always on, --create / --edit opt-in\nconst caps = {\n create: args.includes(\"--create\") || args.includes(\"--edit\"),\n edit: args.includes(\"--edit\"),\n};\n\n// ─── WebSocket connection ────────────────────────────────────────\n\nfunction connectToFigma(port: number = activePort) {\n activePort = port;\n if (ws && ws.readyState === WebSocket.OPEN) {\n logger.info(\"Already connected to Figma\");\n return;\n }\n\n const wsUrl = serverUrl === \"localhost\" ? `${WS_URL}:${port}` : WS_URL;\n logger.info(`Connecting to Figma socket server at ${wsUrl}...`);\n ws = new WebSocket(wsUrl);\n\n ws.on(\"open\", () => {\n logger.info(\"Connected to Figma socket server\");\n currentChannel = null;\n });\n\n ws.on(\"message\", (data: any) => {\n try {\n const json = JSON.parse(data) as any;\n\n // Handle same-client rejoin (already in channel)\n if (json.type === \"join-success\") {\n logger.info(json.message);\n if (json.id && pendingRequests.has(json.id)) {\n const req = pendingRequests.get(json.id)!;\n clearTimeout(req.timeout);\n req.resolve({ status: \"already_joined\", channel: json.channel });\n pendingRequests.delete(json.id);\n }\n return;\n }\n\n // Handle system messages with a code (version mismatch, peer join/leave)\n // Note: join-success also uses type=system but carries message.id + message.result — let those fall through\n if (json.type === \"system\" && json.code) {\n if (json.code === \"VERSION_MISMATCH\") {\n versionWarning = json.message;\n logger.warn(`Version mismatch: ${json.message}`);\n }\n return;\n }\n\n // Handle relay errors (e.g., ROLE_OCCUPIED rejection)\n if (json.type === \"error\") {\n logger.error(`Relay error: ${json.message}`);\n if (json.code === \"ROLE_OCCUPIED\") rejected = true;\n if (json.id && pendingRequests.has(json.id)) {\n const req = pendingRequests.get(json.id)!;\n clearTimeout(req.timeout);\n req.reject(new Error(json.message));\n pendingRequests.delete(json.id);\n }\n return;\n }\n\n // Handle progress updates\n if (json.type === \"progress_update\") {\n const progressData = json.message.data as CommandProgressUpdate;\n const requestId = json.id || \"\";\n\n if (requestId && pendingRequests.has(requestId)) {\n const request = pendingRequests.get(requestId)!;\n request.lastActivity = Date.now();\n clearTimeout(request.timeout);\n request.timeout = setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n logger.error(`Request ${requestId} timed out after extended period of inactivity`);\n pendingRequests.delete(requestId);\n request.reject(new Error(\"Request to Figma timed out\"));\n }\n }, 60000);\n logger.info(`Progress update for ${progressData.commandType}: ${progressData.progress}% - ${progressData.message}`);\n if (progressData.status === \"completed\" && progressData.progress === 100) {\n logger.info(`Operation ${progressData.commandType} completed, waiting for final result`);\n }\n }\n return;\n }\n\n // Handle regular responses\n const myResponse = json.message;\n logger.debug(`Received message: ${JSON.stringify(myResponse)}`);\n\n if (myResponse.id && pendingRequests.has(myResponse.id) && myResponse.result) {\n const request = pendingRequests.get(myResponse.id)!;\n clearTimeout(request.timeout);\n if (myResponse.error) {\n logger.error(`Error from Figma: ${myResponse.error}`);\n request.reject(new Error(myResponse.error));\n } else {\n request.resolve(myResponse.result);\n }\n pendingRequests.delete(myResponse.id);\n } else {\n logger.info(`Received broadcast message: ${JSON.stringify(myResponse)}`);\n }\n } catch (error) {\n logger.error(`Error parsing message: ${error instanceof Error ? error.message : String(error)}`);\n }\n });\n\n ws.on(\"error\", (error) => {\n logger.error(`Socket error: ${error}`);\n });\n\n ws.on(\"close\", () => {\n logger.info(\"Disconnected from Figma socket server\");\n ws = null;\n for (const [id, request] of pendingRequests.entries()) {\n clearTimeout(request.timeout);\n request.reject(new Error(\"Connection closed\"));\n pendingRequests.delete(id);\n }\n if (rejected) {\n logger.info(\"Not reconnecting — channel role was rejected. Call join_channel to retry.\");\n } else {\n logger.info(\"Attempting to reconnect in 2 seconds...\");\n setTimeout(() => connectToFigma(port), 2000);\n }\n });\n}\n\n// ─── Channel management ──────────────────────────────────────────\n\nasync function joinChannel(channelName: string): Promise<void> {\n rejected = false; // Reset rejection state on explicit join attempt\n versionWarning = null;\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n connectToFigma();\n // Wait briefly for connection\n await new Promise((resolve) => setTimeout(resolve, 1000));\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"Not connected to relay. Check that the relay server is running.\");\n }\n }\n try {\n await sendCommandToFigma(\"join\", { channel: channelName });\n currentChannel = channelName;\n logger.info(`Joined channel: ${channelName}`);\n } catch (error) {\n logger.error(`Failed to join channel: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n}\n\n// ─── Send command to Figma ───────────────────────────────────────\n\nfunction sendCommandToFigma(\n command: string,\n params: unknown = {},\n timeoutMs: number = 30000\n): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n connectToFigma();\n reject(new Error(\"Not connected to Figma. Attempting to connect...\"));\n return;\n }\n\n const requiresChannel = command !== \"join\";\n if (requiresChannel && !currentChannel) {\n reject(new Error(\"No channel joined. Call join_channel first with the channel name shown in the Figma plugin panel.\"));\n return;\n }\n\n const id = uuidv4();\n const request = {\n id,\n type: command === \"join\" ? \"join\" : \"message\",\n ...(command === \"join\"\n ? { channel: (params as any).channel, role: \"mcp\", version: VIBMA_VERSION, name: basename(process.cwd()) }\n : { channel: currentChannel }),\n message: {\n id,\n command,\n params: {\n ...(params as any),\n commandId: id,\n },\n },\n };\n\n const timeout = setTimeout(() => {\n if (pendingRequests.has(id)) {\n pendingRequests.delete(id);\n logger.error(`Request ${id} to Figma timed out after ${timeoutMs / 1000} seconds`);\n reject(new Error(\n `Request to Figma timed out. This usually means the Figma plugin is not connected to the relay. ` +\n `MCP is using port ${activePort}, channel \"${currentChannel}\". ` +\n `Check the Figma plugin window: the port and channel name must match.`\n ));\n }\n }, timeoutMs);\n\n pendingRequests.set(id, { resolve, reject, timeout, lastActivity: Date.now() });\n logger.info(`Sending command to Figma: ${command}`);\n logger.debug(`Request details: ${JSON.stringify(request)}`);\n ws.send(JSON.stringify(request));\n });\n}\n\n// ─── MCP Server bootstrap ────────────────────────────────────────\n\nconst server = new McpServer({\n name: \"VibmaMCP\",\n version: \"1.0.0\",\n});\n\n// Register the join_channel tool directly (it uses local state)\nserver.registerTool(\n \"join_channel\",\n {\n description: \"REQUIRED FIRST STEP: Join a channel before using any other tool. The channel name is shown in the Figma plugin UI (defaults to 'vibma' if not customised). After joining, call `ping` to verify the Figma plugin is connected. All subsequent commands are sent through this channel.\",\n inputSchema: { channel: z.string().describe(\"The channel name displayed in the Figma plugin panel. Defaults to 'vibma' if omitted.\").default(\"vibma\") },\n },\n async ({ channel }: any) => {\n try {\n await joinChannel(channel);\n // Brief wait for VERSION_MISMATCH system message from relay\n await new Promise((r) => setTimeout(r, 200));\n let msg = `Joined channel \"${channel}\" on port ${activePort}. Call \\`ping\\` now to verify the Figma plugin is connected.`;\n if (versionWarning) msg += `\\n\\n⚠️ ${versionWarning}\\nSee \"Version mismatch\" in CARRYME.md or DRAGME.md for update steps.`;\n return {\n content: [{ type: \"text\", text: msg }],\n };\n } catch (error) {\n return {\n content: [{\n type: \"text\",\n text: `Error joining channel: ${error instanceof Error ? error.message : String(error)}. MCP is using port ${activePort} — confirm the relay is running on the same port.`,\n }],\n };\n }\n }\n);\n\n// Debug tool: inspect relay channel occupancy\nserver.registerTool(\n \"channel_info\",\n {\n description: \"Debug: inspect which clients (MCP, plugin) are connected to each relay channel. Useful for diagnosing connection issues. Does not require an active channel.\",\n },\n async () => {\n try {\n const url = serverUrl === \"localhost\"\n ? `http://localhost:${activePort}/channels`\n : `https://${serverUrl}/channels`;\n const response = await fetch(url);\n if (!response.ok) {\n return { content: [{ type: \"text\", text: `Relay returned ${response.status}: ${await response.text()}` }] };\n }\n const data = await response.json();\n return { content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }] };\n } catch (error) {\n return {\n content: [{\n type: \"text\",\n text: `Could not reach relay at port ${activePort}: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n }\n }\n);\n\n// Factory-reset the tunnel — clears channel on relay via HTTP, then reconnects\nserver.registerTool(\n \"reset_tunnel\",\n {\n description: \"DESTRUCTIVE: Factory-reset a channel on the relay via HTTP, disconnecting ALL occupants (MCP + Figma plugin). Only use this when the channel is stuck or occupied by another MCP — do NOT use it just to reconnect yourself (use `join_channel` instead). After reset, ask the user to reopen the Vibma plugin in Figma, then call `join_channel` and `ping`.\",\n inputSchema: {\n channel: z.string().describe(\"Channel to reset. Defaults to 'vibma'.\").default(\"vibma\"),\n },\n },\n async ({ channel }: { channel: string }) => {\n const targetChannel = channel || currentChannel || \"vibma\";\n try {\n // Factory reset the channel via HTTP — works regardless of socket state\n const url = serverUrl === \"localhost\"\n ? `http://localhost:${activePort}/channels/${encodeURIComponent(targetChannel)}`\n : `https://${serverUrl}/channels/${encodeURIComponent(targetChannel)}`;\n const res = await fetch(url, { method: \"DELETE\" });\n const body = await res.json() as { ok: boolean; message: string };\n\n // Reject all pending requests\n for (const [reqId, request] of pendingRequests.entries()) {\n clearTimeout(request.timeout);\n request.reject(new Error(\"Tunnel reset by user\"));\n pendingRequests.delete(reqId);\n }\n\n // Close the local WebSocket\n if (ws) {\n const old = ws;\n ws = null;\n old.removeAllListeners();\n old.close(1000, \"Tunnel reset\");\n }\n currentChannel = null;\n rejected = false;\n\n // Reconnect to relay\n connectToFigma();\n await new Promise((resolve) => setTimeout(resolve, 1000));\n const connected = ws && ws.readyState === WebSocket.OPEN;\n\n return {\n content: [{\n type: \"text\",\n text: connected\n ? `Tunnel reset: ${body.message}. Reconnected on port ${activePort}.\\n\\nIMPORTANT: The Figma plugin was also disconnected. Ask the user to reopen the Vibma plugin in Figma (or click \"Reset tunnel\" in the plugin panel). Then call \\`join_channel\\` followed by \\`ping\\`.`\n : `Tunnel reset: ${body.message}. Reconnection in progress.\\n\\nIMPORTANT: The Figma plugin was also disconnected. Ask the user to reopen the Vibma plugin in Figma (or click \"Reset tunnel\" in the plugin panel). Then call \\`join_channel\\` to retry.`,\n }],\n };\n } catch (error) {\n return {\n content: [{\n type: \"text\",\n text: `Error resetting tunnel: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n }\n }\n);\n\n// Register all per-tool-file tools and prompts\nregisterAllTools(server, sendCommandToFigma, caps);\n\n// ─── Start ───────────────────────────────────────────────────────\n\nfunction cleanup() {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.close(1000, \"MCP server shutting down\");\n }\n}\n\nprocess.on(\"SIGINT\", () => { cleanup(); process.exit(0); });\nprocess.on(\"SIGTERM\", () => { cleanup(); process.exit(0); });\nprocess.on(\"exit\", cleanup);\n\nasync function main() {\n try {\n connectToFigma();\n } catch (error) {\n logger.warn(`Could not connect to Figma initially: ${error instanceof Error ? error.message : String(error)}`);\n logger.warn(\"Will try to connect when the first command is sent\");\n }\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info(\"FigmaMCP server running on stdio\");\n}\n\nmain().catch((error) => {\n logger.error(`Error starting FigmaMCP server: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { z } from \"zod\";\n\n/** Function signature for sending commands to Figma via WebSocket */\nexport type SendCommandFn = (command: string, params?: unknown, timeoutMs?: number) => Promise<unknown>;\n\n/** Re-export McpServer type for tool files */\nexport type { McpServer };\n\n// ─── Tool Registry Types ────────────────────────────────────────\n\n/** Access tier for a tool */\nexport type ToolTier = \"read\" | \"create\" | \"edit\";\n\n/** Which tiers are enabled for this MCP session */\nexport interface Capabilities { create: boolean; edit: boolean }\n\n/** Declarative tool definition — replaces imperative registerMcpTools() */\nexport interface ToolDef {\n name: string;\n description: string;\n schema: Record<string, z.ZodTypeAny>\n | ((caps: Capabilities) => Record<string, z.ZodTypeAny>);\n tier: ToolTier;\n /** Figma command name. Defaults to name. */\n command?: string;\n /** sendCommand timeout in ms (default: 30 000) */\n timeout?: number;\n /** Pre-send validation (e.g. per-method item parsing for endpoints) */\n validate?: (params: any) => void;\n /** Custom response formatter. Default: mcpJson */\n formatResponse?: (result: unknown) => any;\n}\n\n/** Standard batch result from Figma handlers */\nexport interface BatchResult<T = unknown> {\n results: Array<T | \"ok\" | { error: string }>;\n warnings?: string[];\n /** Set when some items were deferred (e.g. font loading cap exceeded) */\n deferred?: string;\n}\n\n/** Max response size in characters (~12K tokens). Prevents LLM client-side truncation that corrupts JSON. */\nconst MAX_RESPONSE_CHARS = 50_000;\n\n/** Format a successful MCP response (JSON). Returns a clean error if response exceeds safe size. */\nexport function mcpJson(data: unknown) {\n const text = JSON.stringify(data);\n if (text.length <= MAX_RESPONSE_CHARS) {\n return { content: [{ type: \"text\" as const, text }] };\n }\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({\n _error: \"response_too_large\",\n _sizeKB: Math.round(text.length / 1024),\n warning: \"Response exceeds safe size. Use 'depth', 'fields', 'limit', or 'summaryOnly' parameters to reduce response size.\",\n }),\n }],\n };\n}\n\n/** Format an error MCP response */\nexport function mcpError(prefix: string, error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: [{ type: \"text\" as const, text: `${prefix}: ${msg}` }] };\n}\n","import type { McpServer, SendCommandFn, Capabilities, ToolDef } from \"./types\";\nimport { mcpJson, mcpError } from \"./types\";\n\n/**\n * Batch-register declarative ToolDefs on the MCP server.\n *\n * 1. Filters by tier: read → always, create → caps.create, edit → caps.edit\n * 2. Resolves dynamic schemas (endpoint tools pass caps-dependent functions)\n * 3. Generates a uniform handler: validate? → sendCommand → formatResponse ?? mcpJson\n */\nexport function registerTools(\n server: McpServer,\n sendCommand: SendCommandFn,\n caps: Capabilities,\n tools: ToolDef[],\n): void {\n for (const tool of tools) {\n // Tier gate\n if (tool.tier === \"create\" && !caps.create) continue;\n if (tool.tier === \"edit\" && !caps.edit) continue;\n\n const schema = typeof tool.schema === \"function\" ? tool.schema(caps) : tool.schema;\n const command = tool.command ?? tool.name;\n const timeout = tool.timeout;\n const format = tool.formatResponse ?? mcpJson;\n\n server.registerTool(tool.name, { description: tool.description, inputSchema: schema }, async (params: any) => {\n try {\n if (tool.validate) tool.validate(params);\n const result = await sendCommand(command, params, timeout);\n return format(result);\n } catch (e) {\n return mcpError(`${tool.name} error`, e);\n }\n });\n }\n}\n","import type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"ping\",\n description: \"Verify end-to-end connection to Figma. Call this right after join_channel. Returns { status: 'pong', documentName, currentPage } if the full chain (MCP → relay → plugin → Figma) is working. If this times out, the Figma plugin is not connected — ask the user to check the plugin window for the correct port and channel name.\",\n schema: {},\n tier: \"read\",\n timeout: 5000,\n },\n];\n","import { z } from \"zod\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_document_info\",\n description: \"Get the document name, current page, and list of all pages.\",\n schema: {},\n tier: \"read\",\n },\n {\n name: \"get_current_page\",\n description: \"Get the current page info and its top-level children.\",\n schema: {},\n tier: \"read\",\n },\n {\n name: \"set_current_page\",\n description: \"Switch to a different page. Provide either pageId or pageName.\",\n schema: {\n pageId: z.string().optional().describe(\"The page ID to switch to\"),\n pageName: z.string().optional().describe(\"The page name (case-insensitive, partial match)\"),\n },\n tier: \"read\",\n },\n {\n name: \"create_page\",\n description: \"Create a new page in the document\",\n schema: { name: z.string().optional().describe(\"Name for the new page (default: 'New Page')\") },\n tier: \"create\",\n },\n {\n name: \"rename_page\",\n description: \"Rename a page. Defaults to current page if no pageId given.\",\n schema: {\n newName: z.string().describe(\"New name for the page\"),\n pageId: z.string().optional().describe(\"Page ID (default: current page)\"),\n },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_selection\",\n description: \"Get the current selection. Without depth, returns stubs (id/name/type). With depth, returns full serialized node trees.\",\n schema: { depth: z.coerce.number().optional().describe(\"Child recursion depth. Omit for stubs only, 0=selected nodes' properties, -1=unlimited.\") },\n tier: \"read\",\n },\n {\n name: \"set_selection\",\n description: \"Set selection to nodes and scroll viewport to show them. Also works as focus (single node).\",\n schema: {\n nodeIds: flexJson(z.array(z.string())).describe('Array of node IDs to select. Example: [\"1:2\",\"1:3\"]'),\n },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\n\n// AI agents (Claude, GPT, etc.) frequently pass numbers as strings\n// (\"10\" instead of 10), booleans as strings (\"true\" instead of true),\n// and objects/arrays as JSON strings. These helpers add resilient\n// coercion so tools don't fail on valid-but-mistyped input.\n\n/** Coerce \"true\"/\"false\"/\"1\"/\"0\" strings to boolean */\nexport const flexBool = <T extends z.ZodTypeAny>(inner: T) =>\n z.preprocess((v) => {\n if (v === \"true\" || v === \"1\") return true;\n if (v === \"false\" || v === \"0\") return false;\n return v;\n }, inner);\n\n/** Coerce JSON strings to parsed values (for objects/arrays that agents may stringify) */\nexport const flexJson = <T extends z.ZodTypeAny>(inner: T) =>\n z.preprocess((v) => {\n if (typeof v === \"string\") {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n }\n return v;\n }, inner);\n\n/** Coerce numeric strings only when they're valid numbers (safe for use inside unions) */\nexport const flexNum = <T extends z.ZodTypeAny>(inner: T) =>\n z.preprocess((v) => {\n if (typeof v === \"string\") {\n const n = Number(v);\n if (!isNaN(n) && v.trim() !== \"\") return n;\n }\n return v;\n }, inner);\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_node_info\",\n description: \"Get detailed information about one or more nodes. Always pass an array of IDs. Use `fields` to select only the properties you need (reduces context size).\",\n schema: {\n nodeIds: flexJson(z.array(z.string())).describe('Array of node IDs. Example: [\"1:2\",\"1:3\"]'),\n depth: z.coerce.number().optional().describe(\"Child recursion depth (default: unlimited). 0=stubs only.\"),\n fields: flexJson(z.array(z.string())).optional().describe('Whitelist of property names to include. Example: [\"absoluteBoundingBox\",\"layoutMode\",\"fills\"]. Omit to return all properties.'),\n },\n tier: \"read\",\n },\n {\n name: \"search_nodes\",\n description: \"Search nodes on the current page by name and/or type. Use set_current_page first to search other pages. Paginated (default 50).\",\n schema: {\n query: z.string().optional().describe(\"Name search (case-insensitive substring). Omit to match all names.\"),\n types: flexJson(z.array(z.string())).optional().describe('Filter by types. Example: [\"FRAME\",\"TEXT\"]. Omit to match all types.'),\n scopeNodeId: z.string().optional().describe(\"Node ID to search within (defaults to current page)\"),\n caseSensitive: flexBool(z.boolean()).optional().describe(\"Case-sensitive name match (default false)\"),\n limit: z.coerce.number().optional().describe(\"Max results (default 50)\"),\n offset: z.coerce.number().optional().describe(\"Skip N results for pagination (default 0)\"),\n },\n tier: \"read\",\n },\n {\n name: \"export_node_as_image\",\n description: \"Export a node as an image from Figma\",\n schema: {\n nodeId: z.string().describe(\"The node ID to export\"),\n format: z.enum([\"PNG\", \"JPG\", \"SVG\", \"PDF\"]).optional().describe(\"Export format (default: PNG)\"),\n scale: z.coerce.number().positive().optional().describe(\"Export scale (default: 1)\"),\n },\n tier: \"read\",\n formatResponse: (result: unknown) => {\n const r = result as any;\n return {\n content: [{ type: \"image\" as const, data: r.imageData, mimeType: r.mimeType || \"image/png\" }],\n };\n },\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst sectionItem = z.object({\n name: z.string().optional().describe(\"Name (default: 'Section')\"),\n x: S.xPos,\n y: S.yPos,\n width: z.coerce.number().optional().describe(\"Width (default: 500)\"),\n height: z.coerce.number().optional().describe(\"Height (default: 500)\"),\n parentId: S.parentId,\n});\n\nconst svgItem = z.object({\n svg: z.string().describe(\"SVG markup string\"),\n name: z.string().optional().describe(\"Layer name (default: 'SVG')\"),\n x: S.xPos,\n y: S.yPos,\n parentId: S.parentId,\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"create_section\",\n description: \"Create section nodes to organize content on the canvas.\",\n schema: { items: flexJson(z.array(sectionItem)).describe(\"Array of sections to create\"), depth: S.depth },\n tier: \"create\",\n },\n {\n name: \"create_node_from_svg\",\n description: \"Create nodes from SVG strings.\",\n schema: { items: flexJson(z.array(svgItem)).describe(\"Array of SVG items to create\"), depth: S.depth },\n tier: \"create\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../utils/coercion\";\n\n// ─── Shared Zod Schema Fragments ────────────────────────────────\n// Import as: import * as S from \"./schemas\";\n\n/** Single node ID */\nexport const nodeId = z.string().describe(\"Node ID\");\n\n/** Array of node IDs */\nexport const nodeIds = flexJson(z.array(z.string())).describe(\"Array of node IDs\");\n\n/** Optional parent reference for creation tools */\nexport const parentId = z.string().optional()\n .describe(\"Parent node ID. Omit to place on current page.\");\n\n/**\n * Response depth — controls how much node detail is returned after an operation.\n * Omit for minimal response (id + name only).\n * 0 = node with full properties, children as stubs.\n * N = recurse N levels of children with full properties.\n * -1 = unlimited recursion.\n */\nexport const depth = z.coerce.number().optional()\n .describe(\"Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.\");\n\n/** X position for creation tools */\nexport const xPos = z.coerce.number().optional().describe(\"X position (default: 0)\");\n\n/** Y position for creation tools */\nexport const yPos = z.coerce.number().optional().describe(\"Y position (default: 0)\");\n\n/** Parse hex color string (#RGB, #RRGGBB, #RRGGBBAA) to {r,g,b,a} 0-1 */\nfunction parseHex(hex: string): { r: number; g: number; b: number; a?: number } | null {\n const m = hex.match(/^#?([0-9a-f]{3,8})$/i);\n if (!m) return null;\n let h = m[1];\n if (h.length === 3) h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2];\n if (h.length === 4) h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2]+h[3]+h[3];\n if (h.length !== 6 && h.length !== 8) return null;\n const r = parseInt(h.slice(0, 2), 16) / 255;\n const g = parseInt(h.slice(2, 4), 16) / 255;\n const b = parseInt(h.slice(4, 6), 16) / 255;\n if (h.length === 8) return { r, g, b, a: parseInt(h.slice(6, 8), 16) / 255 };\n return { r, g, b };\n}\n\n/** RGBA color — accepts {r,g,b,a?} object (0-1) or hex string (#RGB, #RRGGBB, #RRGGBBAA) */\nexport const colorRgba = z.preprocess((v) => {\n if (typeof v === \"string\") return parseHex(v) ?? v;\n return v;\n}, z.object({\n r: z.coerce.number().min(0).max(1),\n g: z.coerce.number().min(0).max(1),\n b: z.coerce.number().min(0).max(1),\n a: z.coerce.number().min(0).max(1).optional(),\n})).describe('Hex \"#FF0000\" or {r,g,b,a?} with values 0-1.');\n\n/** Single effect entry — shared by set_effects and styles create */\nexport const effectEntry = z.object({\n type: z.enum([\"DROP_SHADOW\", \"INNER_SHADOW\", \"LAYER_BLUR\", \"BACKGROUND_BLUR\"]),\n color: flexJson(colorRgba).optional(),\n offset: flexJson(z.object({ x: z.coerce.number(), y: z.coerce.number() })).optional(),\n radius: z.coerce.number(),\n spread: z.coerce.number().optional(),\n visible: flexBool(z.boolean()).optional(),\n blendMode: z.string().optional(),\n});\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst frameItem = z.object({\n name: z.string().optional().describe(\"Frame name (default: 'Frame')\"),\n x: S.xPos,\n y: S.yPos,\n width: z.coerce.number().optional().describe(\"Width (default: 100)\"),\n height: z.coerce.number().optional().describe(\"Height (default: 100)\"),\n parentId: S.parentId,\n fillColor: flexJson(S.colorRgba).optional().describe('Fill color. Default: no fill.'),\n strokeColor: flexJson(S.colorRgba).optional().describe('Stroke color. Default: none.'),\n strokeWeight: z.coerce.number().positive().optional().describe(\"Stroke weight (default: 1)\"),\n cornerRadius: z.coerce.number().min(0).optional().describe(\"Corner radius (default: 0)\"),\n layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Auto-layout direction (default: NONE)\"),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional().describe(\"Wrap (default: NO_WRAP)\"),\n paddingTop: z.coerce.number().optional().describe(\"Top padding (default: 0)\"),\n paddingRight: z.coerce.number().optional().describe(\"Right padding (default: 0)\"),\n paddingBottom: z.coerce.number().optional().describe(\"Bottom padding (default: 0)\"),\n paddingLeft: z.coerce.number().optional().describe(\"Left padding (default: 0)\"),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional(),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n fillStyleName: z.string().optional().describe(\"Apply a fill paint style by name (case-insensitive). Omit to skip.\"),\n strokeStyleName: z.string().optional().describe(\"Apply a stroke paint style by name. Omit to skip.\"),\n fillVariableId: z.string().optional().describe(\"Bind a color variable to the fill. Creates a solid fill and binds the variable to fills/0/color.\"),\n strokeVariableId: z.string().optional().describe(\"Bind a color variable to the stroke. Creates a solid stroke and binds the variable to strokes/0/color.\"),\n});\n\nconst autoLayoutItem = z.object({\n nodeIds: flexJson(z.array(z.string())).describe(\"Array of node IDs to wrap\"),\n name: z.string().optional().describe(\"Frame name (default: 'Auto Layout')\"),\n layoutMode: z.enum([\"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Direction (default: VERTICAL)\"),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n paddingTop: z.coerce.number().optional().describe(\"Top padding (default: 0)\"),\n paddingRight: z.coerce.number().optional().describe(\"Right padding (default: 0)\"),\n paddingBottom: z.coerce.number().optional().describe(\"Bottom padding (default: 0)\"),\n paddingLeft: z.coerce.number().optional().describe(\"Left padding (default: 0)\"),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional(),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional(),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"create_frame\",\n description: \"Create frames in Figma. Batch supported. Use fillStyleName/fillVariableId and strokeStyleName/strokeVariableId instead of hardcoded colors — hardcoded values skip design tokens and will trigger lint warnings.\",\n schema: { items: flexJson(z.array(frameItem)).describe(\"Array of frames to create\"), depth: S.depth },\n tier: \"create\",\n },\n {\n name: \"create_auto_layout\",\n description: \"Wrap existing nodes in an auto-layout frame. One call replaces create_frame + update_frame + insert_child × N.\",\n schema: { items: flexJson(z.array(autoLayoutItem)).describe(\"Array of auto-layout wraps to perform\"), depth: S.depth },\n tier: \"create\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst textItem = z.object({\n text: z.string().describe(\"Text content\"),\n name: z.string().optional().describe(\"Layer name (default: text content)\"),\n x: S.xPos,\n y: S.yPos,\n fontFamily: z.string().optional().describe(\"Font family (default: Inter). Use get_available_fonts to list installed fonts.\"),\n fontStyle: z.string().optional().describe(\"Font style, e.g. 'Regular', 'Bold', 'Italic' (default: derived from fontWeight). Overrides fontWeight when set.\"),\n fontSize: z.coerce.number().optional().describe(\"Font size (default: 14)\"),\n fontWeight: z.coerce.number().optional().describe(\"Font weight: 100-900 (default: 400). Ignored when fontStyle is set.\"),\n fontColor: flexJson(S.colorRgba).optional().describe('Font color. Default: black.'),\n fontColorVariableId: z.string().optional().describe(\"Bind a color variable to the text fill instead of hardcoded fontColor.\"),\n fontColorStyleName: z.string().optional().describe(\"Apply a paint style to the text fill by name (case-insensitive). Overrides fontColor.\"),\n parentId: S.parentId,\n textStyleId: z.string().optional().describe(\"Text style ID to apply (overrides fontSize/fontWeight). Omit to skip.\"),\n textStyleName: z.string().optional().describe(\"Text style name (case-insensitive match). Omit to skip.\"),\n textAlignHorizontal: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\", \"JUSTIFIED\"]).optional().describe(\"Horizontal text alignment (default: LEFT)\"),\n textAlignVertical: z.enum([\"TOP\", \"CENTER\", \"BOTTOM\"]).optional().describe(\"Vertical text alignment (default: TOP)\"),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Horizontal sizing. FILL auto-sets textAutoResize to HEIGHT.\"),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Vertical sizing (default: HUG)\"),\n textAutoResize: z.enum([\"NONE\", \"WIDTH_AND_HEIGHT\", \"HEIGHT\", \"TRUNCATE\"]).optional().describe(\"Text auto-resize behavior (default: WIDTH_AND_HEIGHT when FILL)\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"create_text\",\n description: \"Create text nodes. Max 10 per batch. Prefer textStyleName for typography and fontColorStyleName or fontColorVariableId for color — hardcoded values skip design tokens. Supports custom fonts via fontFamily.\",\n schema: { items: flexJson(z.array(textItem).max(10)).describe(\"Array of text nodes to create (max 10)\"), depth: S.depth },\n tier: \"create\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst deleteItem = z.object({\n nodeId: z.string().describe(\"Node ID to delete\"),\n});\nconst cloneItem = z.object({\n nodeId: z.string().describe(\"Node ID to clone\"),\n parentId: z.string().optional().describe(\"Parent for the clone (e.g. a page ID). Defaults to same parent as original.\"),\n x: z.coerce.number().optional().describe(\"New X for clone. Omit to keep original position.\"),\n y: z.coerce.number().optional().describe(\"New Y for clone. Omit to keep original position.\"),\n});\nconst insertItem = z.object({\n parentId: z.string().describe(\"Parent node ID\"),\n childId: z.string().describe(\"Child node ID to move\"),\n index: z.coerce.number().optional().describe(\"Index to insert at (0=first). Omit to append.\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"delete_node\",\n description: \"Delete nodes. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(deleteItem)).describe(\"Array of {nodeId}\") },\n tier: \"edit\",\n },\n {\n name: \"clone_node\",\n description: \"Clone nodes. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(cloneItem)).describe(\"Array of {nodeId, x?, y?}\"), depth: S.depth },\n tier: \"create\",\n },\n {\n name: \"insert_child\",\n description: \"Move nodes into a parent at a specific index (reorder/reparent). Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(insertItem)).describe(\"Array of {parentId, childId, index?}\"), depth: S.depth },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst exportSettingEntry = z.object({\n format: z.enum([\"PNG\", \"JPG\", \"SVG\", \"PDF\"]),\n suffix: z.string().optional(),\n contentsOnly: flexBool(z.boolean()).optional(),\n constraint: flexJson(z.object({\n type: z.enum([\"SCALE\", \"WIDTH\", \"HEIGHT\"]),\n value: z.coerce.number(),\n })).optional(),\n});\n\nconst patchNodeItem = z.object({\n nodeId: S.nodeId,\n\n // Geometry (flat)\n x: z.coerce.number().optional().describe(\"X position\"),\n y: z.coerce.number().optional().describe(\"Y position\"),\n width: z.coerce.number().positive().optional().describe(\"Width (must provide height too)\"),\n height: z.coerce.number().positive().optional().describe(\"Height (must provide width too)\"),\n\n // Appearance (nested)\n fill: flexJson(z.object({\n color: flexJson(S.colorRgba).optional(),\n styleName: z.string().optional().describe(\"Paint style name (preferred over color)\"),\n })).optional().describe(\"Fill color or style\"),\n\n stroke: flexJson(z.object({\n color: flexJson(S.colorRgba).optional(),\n weight: z.coerce.number().positive().optional().describe(\"Stroke weight\"),\n styleName: z.string().optional().describe(\"Paint style name (preferred over color)\"),\n })).optional().describe(\"Stroke color/weight or style\"),\n\n cornerRadius: flexJson(z.object({\n radius: z.coerce.number().min(0).describe(\"Corner radius\"),\n corners: flexJson(z.array(flexBool(z.boolean())).length(4)).optional()\n .describe(\"Which corners [topLeft, topRight, bottomRight, bottomLeft]. Default: all.\"),\n })).optional().describe(\"Corner radius\"),\n\n opacity: z.coerce.number().min(0).max(1).optional().describe(\"Opacity (0-1)\"),\n\n effects: flexJson(z.object({\n effects: flexJson(z.array(S.effectEntry)).optional().describe(\"Effect objects\"),\n styleName: z.string().optional().describe(\"Effect style name (preferred over raw effects)\"),\n })).optional().describe(\"Effects or effect style\"),\n\n constraints: flexJson(z.object({\n horizontal: z.enum([\"MIN\", \"CENTER\", \"MAX\", \"STRETCH\", \"SCALE\"]),\n vertical: z.enum([\"MIN\", \"CENTER\", \"MAX\", \"STRETCH\", \"SCALE\"]),\n })).optional().describe(\"Layout constraints\"),\n\n exportSettings: flexJson(z.array(exportSettingEntry)).optional().describe(\"Export settings\"),\n\n // Layout (nested)\n layout: flexJson(z.object({\n layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).optional(),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional(),\n paddingTop: z.coerce.number().optional(),\n paddingRight: z.coerce.number().optional(),\n paddingBottom: z.coerce.number().optional(),\n paddingLeft: z.coerce.number().optional(),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional(),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n itemSpacing: z.coerce.number().optional(),\n counterAxisSpacing: z.coerce.number().optional(),\n })).optional().describe(\"Auto-layout properties\"),\n\n // Text (nested)\n text: flexJson(z.object({\n fontSize: z.coerce.number().optional(),\n fontWeight: z.coerce.number().optional(),\n fontColor: flexJson(S.colorRgba).optional(),\n textStyleId: z.string().optional(),\n textStyleName: z.string().optional(),\n textAlignHorizontal: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\", \"JUSTIFIED\"]).optional(),\n textAlignVertical: z.enum([\"TOP\", \"CENTER\", \"BOTTOM\"]).optional(),\n textAutoResize: z.enum([\"NONE\", \"WIDTH_AND_HEIGHT\", \"HEIGHT\", \"TRUNCATE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n })).optional().describe(\"Text properties (font, alignment, sizing)\"),\n\n // Escape hatch\n properties: flexJson(z.record(z.string(), z.unknown())).optional()\n .describe(\"Arbitrary key-value properties to set directly on the node\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"patch_nodes\",\n description: \"Patch properties on nodes. Combines geometry (x/y/width/height), appearance (fill, stroke, cornerRadius, opacity, effects, constraints, exportSettings), layout (auto-layout), text (font props), and arbitrary properties in one call. Prefer styleName over hardcoded colors. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(patchNodeItem)).describe(\"Array of nodes to patch\"), depth: S.depth },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst textContentItem = z.object({\n nodeId: z.string().describe(\"Text node ID\"),\n text: z.string().describe(\"New text content\"),\n});\n\nconst scanTextItem = z.object({\n nodeId: S.nodeId,\n limit: z.coerce.number().optional().describe(\"Max text nodes to return (default: 50)\"),\n includePath: flexBool(z.boolean()).optional().describe(\"Include ancestor path strings (default: true). Set false to reduce payload.\"),\n includeGeometry: flexBool(z.boolean()).optional().describe(\"Include absoluteX/absoluteY/width/height (default: true). Set false to reduce payload.\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"set_text_content\",\n description: \"Set text content on text nodes. Batch: pass multiple items to replace text in multiple nodes at once.\",\n schema: { items: flexJson(z.array(textContentItem)).describe(\"Array of {nodeId, text}\"), depth: S.depth },\n tier: \"edit\",\n },\n {\n name: \"scan_text_nodes\",\n description: \"Scan all text nodes within a node tree. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(scanTextItem)).describe(\"Array of {nodeId}\") },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_available_fonts\",\n description: \"Get available fonts in Figma. Optionally filter by query string.\",\n schema: { query: z.string().optional().describe(\"Filter fonts by name (case-insensitive). Omit to list all fonts.\") },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst lintRules = z.enum([\n \"no-autolayout\",\n \"shape-instead-of-frame\",\n \"hardcoded-color\",\n \"no-text-style\",\n \"fixed-in-autolayout\",\n \"default-name\",\n \"empty-container\",\n \"stale-text-name\",\n \"no-text-property\",\n \"wcag-contrast\",\n \"wcag-contrast-enhanced\",\n \"wcag-non-text-contrast\",\n \"wcag-target-size\",\n \"wcag-text-size\",\n \"wcag-line-height\",\n \"wcag\",\n \"all\",\n]);\n\nexport const tools: ToolDef[] = [\n {\n name: \"lint_node\",\n description: \"Run design linter on a node tree. Returns issues grouped by category with affected node IDs and fix instructions. Lint child nodes individually for large trees.\",\n schema: {\n nodeId: z.string().optional().describe(\"Node ID to lint. Omit to lint current selection.\"),\n rules: flexJson(z.array(lintRules)).optional().describe('Rules to run. Default: [\"all\"]. Options: no-autolayout, shape-instead-of-frame, hardcoded-color, no-text-style, fixed-in-autolayout, default-name, empty-container, stale-text-name, no-text-property, all, wcag-contrast, wcag-contrast-enhanced, wcag-non-text-contrast, wcag-target-size, wcag-text-size, wcag-line-height, wcag'),\n maxDepth: z.coerce.number().optional().describe(\"Max depth to recurse (default: 10)\"),\n maxFindings: z.coerce.number().optional().describe(\"Stop after N findings (default: 50)\"),\n },\n tier: \"read\",\n },\n {\n name: \"lint_fix_autolayout\",\n description: \"Auto-fix: convert frames with multiple children to auto-layout. Takes node IDs from lint_node 'no-autolayout' results.\",\n schema: {\n items: flexJson(z.array(z.object({\n nodeId: S.nodeId,\n layoutMode: z.enum([\"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Layout direction (default: auto-detect based on child positions)\"),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n }))).describe(\"Array of frames to convert to auto-layout\"),\n depth: S.depth,\n },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexNum } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\nimport { endpointSchema } from \"../endpoint\";\n\nconst paintStyleItem = z.object({\n name: z.string().describe(\"Style name\"),\n color: flexJson(S.colorRgba).describe('Color.'),\n});\n\nconst textStyleItem = z.object({\n name: z.string().describe(\"Style name\"),\n fontFamily: z.string().describe(\"Font family\"),\n fontStyle: z.string().optional().describe(\"Font style (default: Regular)\"),\n fontSize: z.coerce.number().describe(\"Font size\"),\n lineHeight: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\", \"AUTO\"]) }),\n ])).optional().describe(\"Line height — number (px) or {value, unit}. Default: auto.\"),\n letterSpacing: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\"]) }),\n ])).optional().describe(\"Letter spacing — number (px) or {value, unit}. Default: 0.\"),\n textCase: z.enum([\"ORIGINAL\", \"UPPER\", \"LOWER\", \"TITLE\"]).optional(),\n textDecoration: z.enum([\"NONE\", \"UNDERLINE\", \"STRIKETHROUGH\"]).optional(),\n});\n\nconst effectStyleItem = z.object({\n name: z.string().describe(\"Style name\"),\n effects: flexJson(z.array(S.effectEntry)).describe(\"Array of effects\"),\n});\n\nconst patchBase = {\n id: z.string().describe(\"Style ID or name (case-insensitive match)\"),\n name: z.string().optional().describe(\"Rename the style\"),\n};\n\nconst patchPaintItem = z.object({\n ...patchBase,\n color: flexJson(S.colorRgba).optional().describe('New color.'),\n});\n\nconst patchTextItem = z.object({\n ...patchBase,\n fontFamily: z.string().optional().describe(\"Font family\"),\n fontStyle: z.string().optional().describe(\"Font style, e.g. Regular, Bold\"),\n fontSize: z.coerce.number().optional().describe(\"Font size\"),\n lineHeight: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\", \"AUTO\"]) }),\n ])).optional().describe(\"Line height — number (px) or {value, unit}\"),\n letterSpacing: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\"]) }),\n ])).optional().describe(\"Letter spacing — number (px) or {value, unit}\"),\n textCase: z.enum([\"ORIGINAL\", \"UPPER\", \"LOWER\", \"TITLE\"]).optional(),\n textDecoration: z.enum([\"NONE\", \"UNDERLINE\", \"STRIKETHROUGH\"]).optional(),\n});\n\nconst patchEffectItem = z.object({\n ...patchBase,\n effects: flexJson(z.array(S.effectEntry)).optional().describe(\"Array of effects\"),\n});\n\nconst patchAnyItem = z.object({\n ...patchBase,\n color: flexJson(S.colorRgba).optional(),\n fontFamily: z.string().optional(),\n fontStyle: z.string().optional(),\n fontSize: z.coerce.number().optional(),\n lineHeight: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\", \"AUTO\"]) }),\n ])).optional(),\n letterSpacing: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\"]) }),\n ])).optional(),\n textCase: z.enum([\"ORIGINAL\", \"UPPER\", \"LOWER\", \"TITLE\"]).optional(),\n textDecoration: z.enum([\"NONE\", \"UNDERLINE\", \"STRIKETHROUGH\"]).optional(),\n effects: flexJson(z.array(S.effectEntry)).optional(),\n});\n\nconst createSchemas: Record<string, z.ZodTypeAny> = {\n paint: paintStyleItem, text: textStyleItem, effect: effectStyleItem,\n};\nconst updateSchemas: Record<string, z.ZodTypeAny> = {\n paint: patchPaintItem, text: patchTextItem, effect: patchEffectItem,\n};\n\nexport const tools: ToolDef[] = [\n {\n name: \"styles\",\n description:\n \"CRUD endpoint for local styles (paint, text, effect).\\n\" +\n \" list → {type?, fields?, offset?, limit?} → {totalCount, items: [{id, name, type, ...}]}\\n\" +\n \" get → {id, fields?} → style object (full detail; fields to filter)\\n\" +\n \" create → {type, items: [...]} → {results: [{id}, ...]}\\n\" +\n \" update → {type?, items: [{id, ...}]} → {results: ['ok'|{warning}, ...]}\\n\" +\n \" delete → {id} or {items: [{id}, ...]} → 'ok' or {results: ['ok', ...]}\",\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"update\", \"delete\"],\n caps,\n {\n type: z.enum([\"paint\", \"text\", \"effect\"]).optional()\n .describe(\"Style type. Required for create. Filters list by type. Optional for update (strict per-type validation; omit to auto-detect).\"),\n items: flexJson(z.array(z.any())).optional()\n .describe(\"Create: [{name, color}] (paint), [{name, fontFamily, fontSize, ...}] (text), [{name, effects}] (effect). Update: [{id, ...fields}]. Delete (batch): [{id}, ...].\"),\n depth: S.depth,\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n const map = params.method === \"update\" ? updateSchemas : createSchemas;\n const itemSchema = (params.type && map[params.type]) || patchAnyItem;\n params.items = z.array(itemSchema).parse(params.items);\n }\n },\n },\n];\n","/**\n * Shared endpoint infrastructure.\n *\n * Every resource endpoint follows the same contract:\n * create → items[{...}] → { results: [{id}, ...] }\n * get → { id, fields? } → resource object (field-filtered)\n * list → { filters?, fields?, offset, limit } → { totalCount, returned, offset, limit, items: [...] }\n * update → items[{...}] → { results: [\"ok\", ...] }\n * delete → { id } or items[{id}] → \"ok\" or { results: [\"ok\", ...] }\n *\n * MCP side: endpointSchema()\n * Figma side: createDispatcher() + paginate()\n */\n\nimport { z } from \"zod\";\nimport { flexJson } from \"../utils/coercion\";\nimport type { Capabilities } from \"./types\";\n\n// ─── Method Types ────────────────────────────────────────────────\n\nexport type EndpointMethod = \"create\" | \"get\" | \"list\" | \"update\" | \"delete\";\n\n// ─── Response Types ──────────────────────────────────────────────\n\n/** Batch response envelope (create, update, delete). Produced by batchHandler. */\nexport interface BatchResponse<T = { id: string }> {\n results: Array<T | \"ok\" | { error: string }>;\n warnings?: string[];\n deferred?: string;\n}\n\n/** Paginated list response envelope. */\nexport interface ListResponse<T = Record<string, any>> {\n totalCount: number;\n returned: number;\n offset: number;\n limit: number;\n items: T[];\n}\n\n// ─── Discriminated Param Types ───────────────────────────────────\n//\n// Each endpoint specializes these with its own create/update item\n// types and list filters. Example:\n//\n// type StyleParams = EndpointParams<StyleCreateItem, StyleUpdateItem, { type?: string }>;\n//\n\nexport type EndpointParams<\n TCreate = Record<string, any>,\n TUpdate = Record<string, any>,\n TListFilters = Record<string, never>,\n> =\n | { method: \"create\"; items: TCreate[] }\n | { method: \"get\"; id: string; fields?: string[] }\n | ({ method: \"list\"; fields?: string[]; offset?: number; limit?: number } & TListFilters)\n | { method: \"update\"; items: TUpdate[] }\n | { method: \"delete\"; id?: string; items?: Array<{ id: string }> };\n\n// ─── Helpers ────────────────────────────────────────────────────\n\n/**\n * Top-level field filter for get/list responses.\n * Always preserves identity fields (id, name, type).\n * Pass [\"*\"] to return all fields.\n */\nexport function pickFields(obj: Record<string, any>, fields: string[]): Record<string, any> {\n if (fields.includes(\"*\")) return obj;\n const keep = new Set([...fields, \"id\", \"name\", \"type\"]);\n const out: Record<string, any> = {};\n for (const key of Object.keys(obj)) {\n if (keep.has(key)) out[key] = obj[key];\n }\n return out;\n}\n\n/**\n * Paginate an array of items. Default limit: 100.\n * Call from list handlers after assembling the full result set.\n */\nexport function paginate<T>(items: T[], offset = 0, limit = 100): ListResponse<T> {\n const sliced = items.slice(offset, offset + limit);\n return { totalCount: items.length, returned: sliced.length, offset, limit, items: sliced };\n}\n\n// ─── Schema Builder ──────────────────────────────────────────────\n\n/** Maps each endpoint method to the minimum tier required to use it. */\nexport type MethodTier = \"read\" | \"create\" | \"edit\";\n\nconst DEFAULT_TIERS: Record<string, MethodTier> = {\n get: \"read\", list: \"read\", create: \"create\", update: \"edit\", delete: \"edit\",\n};\n\n/**\n * Build standard endpoint Zod schema fields.\n *\n * Always includes `method`. Auto-adds:\n * - `id` when get/delete are in the method list\n * - `fields` when get or list are in the method list\n * - `offset`/`limit` when list is in the method list\n * Merge endpoint-specific fields (items, list filters) via `extra`.\n *\n * When `caps` is provided, methods are filtered by tier — only methods\n * whose tier is enabled appear in the enum.\n */\nexport function endpointSchema(\n methods: string[],\n capsOrExtra?: Capabilities | Record<string, z.ZodTypeAny>,\n extraOrTiers?: Record<string, z.ZodTypeAny>,\n methodTiers?: Record<string, MethodTier>,\n): Record<string, z.ZodTypeAny> {\n // Overload resolution: (methods, extra?) or (methods, caps, extra?, tiers?)\n let caps: Capabilities | undefined;\n let extra: Record<string, z.ZodTypeAny> | undefined;\n\n if (capsOrExtra && (\"create\" in capsOrExtra) && (\"edit\" in capsOrExtra)\n && typeof (capsOrExtra as any).create === \"boolean\") {\n caps = capsOrExtra as Capabilities;\n extra = extraOrTiers;\n } else {\n extra = capsOrExtra as Record<string, z.ZodTypeAny> | undefined;\n // methodTiers and extraOrTiers are unused in the legacy call signature\n }\n\n // Filter methods by capabilities\n let filtered = methods;\n if (caps) {\n const tiers = { ...DEFAULT_TIERS, ...methodTiers };\n filtered = methods.filter(m => {\n const tier = tiers[m] ?? \"edit\"; // unknown methods default to edit\n if (tier === \"read\") return true;\n if (tier === \"create\") return caps!.create;\n if (tier === \"edit\") return caps!.edit;\n return false;\n });\n }\n\n const schema: Record<string, z.ZodTypeAny> = {\n method: z.enum(filtered as [string, ...string[]]),\n };\n if (filtered.includes(\"get\") || filtered.includes(\"delete\")) {\n schema.id = z.string().optional().describe(\"Resource ID (get, delete)\");\n }\n if (filtered.includes(\"get\") || filtered.includes(\"list\")) {\n schema.fields = flexJson(z.array(z.string())).optional()\n .describe('Property whitelist (get/list). Identity fields (id, name, type) always included. Omit for stubs on list, full detail on get. Pass [\"*\"] for all fields.');\n }\n if (filtered.includes(\"list\")) {\n schema.offset = z.coerce.number().optional().describe(\"Skip N items for pagination (default 0)\");\n schema.limit = z.coerce.number().optional().describe(\"Max items per page (default 100)\");\n }\n return { ...schema, ...extra };\n}\n\n// ─── Figma Dispatcher ────────────────────────────────────────────\n\ntype MethodHandlers = Record<string, (params: any) => Promise<any>>;\n\n/**\n * Create a Figma handler that dispatches on `params.method`.\n * Only methods with registered handlers are allowed.\n * Automatically applies `fields` filtering on get responses.\n */\nexport function createDispatcher(handlers: MethodHandlers) {\n const supported = Object.keys(handlers).join(\", \");\n return async (params: any): Promise<any> => {\n const method = params.method as EndpointMethod;\n const handler = handlers[method];\n if (!handler) throw new Error(`Method '${method}' not supported. Available: ${supported}`);\n let result = await handler(params);\n // Auto-apply fields filtering on get responses (full detail by default)\n if (method === \"get\" && params.fields?.length && result && typeof result === \"object\") {\n result = pickFields(result, params.fields);\n }\n return result;\n };\n}\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\nimport { endpointSchema } from \"../endpoint\";\nimport type { MethodTier } from \"../endpoint\";\n\nconst collectionCreateItem = z.object({\n name: z.string().describe(\"Collection name\"),\n});\n\nconst addModeItem = z.object({\n collectionId: z.string().describe(\"Collection ID\"),\n name: z.string().describe(\"Mode name\"),\n});\n\nconst renameModeItem = z.object({\n collectionId: z.string().describe(\"Collection ID\"),\n modeId: z.string().describe(\"Mode ID\"),\n name: z.string().describe(\"New name\"),\n});\n\nconst removeModeItem = z.object({\n collectionId: z.string().describe(\"Collection ID\"),\n modeId: z.string().describe(\"Mode ID\"),\n});\n\nconst deleteCollectionItem = z.object({\n id: z.string().describe(\"Collection ID\"),\n});\n\nconst collectionMethodSchemas: Record<string, z.ZodTypeAny> = {\n create: collectionCreateItem,\n delete: deleteCollectionItem,\n add_mode: addModeItem,\n rename_mode: renameModeItem,\n remove_mode: removeModeItem,\n};\n\nconst variableCreateItem = z.object({\n collectionId: z.string().describe(\"Variable collection ID\"),\n name: z.string().describe(\"Variable name\"),\n resolvedType: z.enum([\"COLOR\", \"FLOAT\", \"STRING\", \"BOOLEAN\"]).describe(\"Variable type\"),\n});\n\nconst variableUpdateItem = z.object({\n id: z.string().describe(\"Variable ID (full ID, e.g. VariableID:1:6)\"),\n modeId: z.string().describe(\"Mode ID\"),\n value: flexJson(z.union([\n z.number(), z.boolean(), S.colorRgba,\n ])).describe('Value: number, boolean, or color (hex \"#RRGGBB\" or {r,g,b,a?} 0-1)'),\n});\n\nconst variableMethodSchemas: Record<string, z.ZodTypeAny> = {\n create: variableCreateItem,\n update: variableUpdateItem,\n};\n\nconst bindingItem = z.object({\n nodeId: z.string().describe(\"Node ID\"),\n field: z.string().describe(\"Property field (e.g., 'opacity', 'fills/0/color')\"),\n variableId: z.string().describe(\"Variable ID (use full ID from create_variable response, e.g. VariableID:1:6)\"),\n});\n\nconst setExplicitModeItem = z.object({\n nodeId: S.nodeId,\n collectionId: z.string().describe(\"Variable collection ID\"),\n modeId: z.string().describe(\"Mode ID to pin (e.g. Dark mode)\"),\n});\n\nconst vcMethodTiers: Record<string, MethodTier> = {\n add_mode: \"create\",\n rename_mode: \"edit\",\n remove_mode: \"edit\",\n};\n\nexport const tools: ToolDef[] = [\n {\n name: \"variable_collections\",\n description:\n `CRUD endpoint for variable collections + mode management.\n create → {items: [{name}]} → {results: [{id, modes, defaultModeId}]}\n get → {id, fields?} → collection object\n list → {fields?, offset?, limit?} → paginated stubs\n delete → {id} or {items: [{id}]} → 'ok' or {results: ['ok', ...]}\n add_mode → {items: [{collectionId, name}]} → {results: [{modeId, modes}]}\n rename_mode → {items: [{collectionId, modeId, name}]} → {results: [{modes}]}\n remove_mode → {items: [{collectionId, modeId}]} → {results: [{modes}]}`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"delete\", \"add_mode\", \"rename_mode\", \"remove_mode\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create: [{name}]. delete (batch): [{id}]. add_mode: [{collectionId, name}]. rename_mode: [{collectionId, modeId, name}]. remove_mode: [{collectionId, modeId}].\"),\n },\n vcMethodTiers,\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n const schema = collectionMethodSchemas[params.method];\n if (schema) params.items = z.array(schema).parse(params.items);\n }\n },\n },\n {\n name: \"variables\",\n description:\n `CRUD endpoint for design variables.\n create → {items: [{collectionId, name, resolvedType}]} → {results: [{id}]}\n get → {id, fields?} → variable object (full detail)\n list → {type?, collectionId?, fields?, offset?, limit?} → paginated stubs (fields for detail)\n update → {items: [{id, modeId, value}]} → {results: ['ok', ...]}`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"update\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create: [{collectionId, name, resolvedType}]. update: [{id, modeId, value}].\"),\n type: z.enum([\"COLOR\", \"FLOAT\", \"STRING\", \"BOOLEAN\"]).optional()\n .describe(\"Filter list by variable type.\"),\n collectionId: z.string().optional()\n .describe(\"Filter list by collection ID.\"),\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n const schema = variableMethodSchemas[params.method];\n if (schema) params.items = z.array(schema).parse(params.items);\n }\n },\n },\n {\n name: \"set_variable_binding\",\n description: \"Bind variables to node properties. Common fields: 'fills/0/color', 'strokes/0/color', 'opacity', 'topLeftRadius', 'itemSpacing'. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(bindingItem)).describe(\"Array of {nodeId, field, variableId}\") },\n tier: \"edit\",\n },\n {\n name: \"set_explicit_variable_mode\",\n description: \"Pin a variable collection mode on a frame (e.g. show Dark mode). Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(setExplicitModeItem)).describe(\"Array of {nodeId, collectionId, modeId}\") },\n tier: \"edit\",\n },\n {\n name: \"get_node_variables\",\n description: \"Get variable bindings on a node. Returns which variables are bound to fills, strokes, opacity, corner radius, etc.\",\n schema: { nodeId: S.nodeId },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\nimport { endpointSchema } from \"../endpoint\";\n\nconst componentItem = z.object({\n name: z.string().describe(\"Component name\"),\n x: S.xPos,\n y: S.yPos,\n width: z.coerce.number().optional().describe(\"Width (default: 100)\"),\n height: z.coerce.number().optional().describe(\"Height (default: 100)\"),\n parentId: S.parentId,\n fillColor: flexJson(S.colorRgba).optional().describe('Fill color. Omit for no fill.'),\n fillStyleName: z.string().optional().describe(\"Apply a fill paint style by name (case-insensitive).\"),\n fillVariableId: z.string().optional().describe(\"Bind a color variable to the fill.\"),\n strokeColor: flexJson(S.colorRgba).optional().describe('Stroke color. Omit for no stroke.'),\n strokeStyleName: z.string().optional().describe(\"Apply a stroke paint style by name.\"),\n strokeVariableId: z.string().optional().describe(\"Bind a color variable to the stroke.\"),\n strokeWeight: z.coerce.number().positive().optional().describe(\"Stroke weight (default: 1)\"),\n cornerRadius: z.coerce.number().optional().describe(\"Corner radius (default: 0)\"),\n layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Layout direction (default: NONE)\"),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional().describe(\"Wrap behavior (default: NO_WRAP)\"),\n paddingTop: z.coerce.number().optional().describe(\"Top padding (default: 0)\"),\n paddingRight: z.coerce.number().optional().describe(\"Right padding (default: 0)\"),\n paddingBottom: z.coerce.number().optional().describe(\"Bottom padding (default: 0)\"),\n paddingLeft: z.coerce.number().optional().describe(\"Left padding (default: 0)\"),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional().describe(\"Primary axis alignment (default: MIN)\"),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional().describe(\"Counter axis alignment (default: MIN)\"),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Horizontal sizing (default: FIXED)\"),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Vertical sizing (default: FIXED)\"),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n});\n\nconst fromNodeItem = z.object({\n nodeId: S.nodeId,\n});\n\nconst combineItem = z.object({\n componentIds: flexJson(z.array(z.string())).describe(\"Component IDs to combine (min 2)\"),\n name: z.string().optional().describe(\"Name for the component set. Omit to auto-generate.\"),\n});\n\nconst updateComponentItem = z.object({\n id: z.string().describe(\"Component node ID\"),\n propertyName: z.string().describe(\"Property name\"),\n type: z.enum([\"BOOLEAN\", \"TEXT\", \"INSTANCE_SWAP\", \"VARIANT\"]).describe(\"Property type\"),\n defaultValue: flexBool(z.union([z.string(), z.boolean()])).describe(\"Default value (string for TEXT/VARIANT, boolean for BOOLEAN)\"),\n preferredValues: flexJson(z.array(z.object({\n type: z.enum([\"COMPONENT\", \"COMPONENT_SET\"]),\n key: z.string(),\n })).optional()).describe(\"Preferred values for INSTANCE_SWAP type. Omit for none.\"),\n});\n\nconst componentCreateSchemas: Record<string, z.ZodTypeAny> = {\n component: componentItem,\n from_node: fromNodeItem,\n variant_set: combineItem,\n};\n\nconst instanceCreateItem = z.object({\n componentId: z.string().describe(\"Component or component set ID\"),\n variantProperties: flexJson(z.record(z.string(), z.string())).optional().describe('Pick variant by properties, e.g. {\"Style\":\"Secondary\",\"Size\":\"Large\"}. Ignored for plain COMPONENT IDs.'),\n x: z.coerce.number().optional().describe(\"X position. Omit to keep default.\"),\n y: z.coerce.number().optional().describe(\"Y position. Omit to keep default.\"),\n parentId: S.parentId,\n});\n\nconst instanceUpdateItem = z.object({\n id: S.nodeId,\n properties: flexJson(z.record(z.string(), z.union([z.string(), z.boolean()]))).describe('Property key→value map, e.g. {\"Label#1:0\":\"Click Me\"}'),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"components\",\n description:\n `CRUD endpoint for components.\n create → {type, items, depth?} → {results: [{id}, ...]}\n type 'component': create from scratch with layout/style params\n type 'from_node': convert existing nodes to components\n type 'variant_set': combine components into variant sets\n get → {id, fields?} → component object (full detail, field-filterable)\n list → {name?, setsOnly?, fields?, offset?, limit?} → paginated stubs\n update → {items: [{id, propertyName, type, defaultValue}]} → {results: ['ok', ...]}`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"update\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create (component): [{name, parentId?, ...layout}]. create (from_node): [{nodeId}]. create (variant_set): [{componentIds, name?}]. update: [{id, propertyName, type, defaultValue}].\"),\n type: z.enum([\"component\", \"from_node\", \"variant_set\"]).optional()\n .describe(\"Create type. Required for create: 'component' (from scratch), 'from_node' (convert existing), 'variant_set' (combine as variants).\"),\n depth: S.depth,\n name: z.string().optional().describe(\"Filter list by name (case-insensitive substring).\"),\n setsOnly: flexBool(z.boolean()).optional().describe(\"If true, list returns only COMPONENT_SET nodes.\"),\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n if (params.method === \"create\") {\n const schema = params.type && componentCreateSchemas[params.type];\n if (!schema) throw new Error(`create requires type: component, from_node, or variant_set`);\n params.items = z.array(schema).parse(params.items);\n } else if (params.method === \"update\") {\n params.items = z.array(updateComponentItem).parse(params.items);\n }\n }\n },\n },\n {\n name: \"instances\",\n description:\n `CRUD endpoint for component instances.\n create → {items: [{componentId, variantProperties?, x?, y?, parentId?}], depth?} → {results: [{id}]}\n get → {id} → {mainComponentId, overrides: [{id, fields}]}\n update → {items: [{id, properties}]} → {results: ['ok', ...]}`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"update\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create: [{componentId, variantProperties?, x?, y?, parentId?}]. update: [{id, properties}].\"),\n depth: S.depth,\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n if (params.method === \"create\") {\n params.items = z.array(instanceCreateItem).parse(params.items);\n } else if (params.method === \"update\") {\n params.items = z.array(instanceUpdateItem).parse(params.items);\n }\n }\n },\n },\n];\n","import type { McpServer } from \"./types\";\n\nexport function registerPrompts(server: McpServer) {\n server.registerPrompt(\n \"design_strategy\",\n { description: \"Best practices for working with Figma designs\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `When working with Figma designs, follow these best practices:\n\n1. Understand Before Creating:\n - Use get_document_info() to see pages and current page\n - Use styles(method: \"list\") and get_local_variables() to discover existing design tokens\n - Plan layout hierarchy before creating elements\n\n2. Use Design Tokens — Never Hardcode:\n - Colors: use fillStyleName/strokeStyleName (paint styles) or fillVariableId/strokeVariableId (variables)\n - Text: use textStyleName to apply text styles that control font size, weight, and line height together\n - Effects: use effectStyleName to apply shadow/blur styles\n - Only use raw fillColor/fontColor for one-off values not in the design system\n\n3. Auto-Layout First:\n - Use create_frame() with layoutMode: \"VERTICAL\" or \"HORIZONTAL\" for every container\n - Set itemSpacing, padding, and alignment at creation time\n - Use layoutSizingHorizontal/Vertical: \"FILL\" for responsive children\n - Avoid absolute positioning — let auto-layout handle spacing\n\n4. Naming Conventions:\n - Use descriptive, semantic names for all elements\n - Name components with Property=Value pattern (e.g. \"Size=Small\") before components(method: \"create\", type: \"variant_set\")\n\n5. Variable Modes:\n - Use set_explicit_variable_mode() to pin a frame to a specific mode (e.g. Dark)\n - Use get_node_variables() to verify which variables are bound to a node\n\n6. Quality Check — Run Lint:\n - After building a section, run lint_node() to catch common issues:\n * hardcoded-color: fills/strokes not using styles or variables\n * no-text-style: text without a text style applied\n * no-autolayout: frames with children but no auto-layout\n * default-name: nodes still named \"Frame\", \"Rectangle\", etc.\n - Use lint_fix_autolayout() to auto-fix layout issues\n - Lint early and often — it is cheaper to fix issues during creation than after`,\n },\n }],\n description: \"Best practices for working with Figma designs\",\n })\n );\n\n server.registerPrompt(\n \"read_design_strategy\",\n { description: \"Best practices for reading Figma designs\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `When reading Figma designs, follow these best practices:\n\n1. Start with selection:\n - First use get_selection() to understand the current selection\n - If no selection ask user to select single or multiple nodes\n`,\n },\n }],\n description: \"Best practices for reading Figma designs\",\n })\n );\n\n server.registerPrompt(\n \"text_replacement_strategy\",\n { description: \"Systematic approach for replacing text in Figma designs\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `# Intelligent Text Replacement Strategy\n\n## 1. Analyze Design & Identify Structure\n- Scan text nodes to understand the overall structure of the design\n- Use AI pattern recognition to identify logical groupings:\n * Tables (rows, columns, headers, cells)\n * Lists (items, headers, nested lists)\n * Card groups (similar cards with recurring text fields)\n * Forms (labels, input fields, validation text)\n * Navigation (menu items, breadcrumbs)\n\\`\\`\\`\nscan_text_nodes(nodeId: \"node-id\")\nget_node_info(nodeId: \"node-id\") // optional\n\\`\\`\\`\n\n## 2. Strategic Chunking for Complex Designs\n- Divide replacement tasks into logical content chunks based on design structure\n- Use one of these chunking strategies that best fits the design:\n * **Structural Chunking**: Table rows/columns, list sections, card groups\n * **Spatial Chunking**: Top-to-bottom, left-to-right in screen areas\n * **Semantic Chunking**: Content related to the same topic or functionality\n * **Component-Based Chunking**: Process similar component instances together\n\n## 3. Progressive Replacement with Verification\n- Create a safe copy of the node for text replacement\n- Replace text chunk by chunk with continuous progress updates\n- After each chunk is processed:\n * Export that section as a small, manageable image\n * Verify text fits properly and maintain design integrity\n * Fix issues before proceeding to the next chunk\n\n\\`\\`\\`\n// Clone the node to create a safe copy\nclone_node(nodeId: \"selected-node-id\", x: [new-x], y: [new-y])\n\n// Replace text chunk by chunk\nset_text_content(\n items: [\n { nodeId: \"node-id-1\", text: \"New text 1\" },\n // More nodes in this chunk...\n ]\n)\n\n// Verify chunk with small, targeted image exports\nexport_node_as_image(nodeId: \"chunk-node-id\", format: \"PNG\", scale: 0.5)\n\\`\\`\\`\n\n## 4. Intelligent Handling for Table Data\n- For tabular content:\n * Process one row or column at a time\n * Maintain alignment and spacing between cells\n * Consider conditional formatting based on cell content\n * Preserve header/data relationships\n\n## 5. Smart Text Adaptation\n- Adaptively handle text based on container constraints:\n * Auto-detect space constraints and adjust text length\n * Apply line breaks at appropriate linguistic points\n * Maintain text hierarchy and emphasis\n * Consider font scaling for critical content that must fit\n\n## 6. Progressive Feedback Loop\n- Establish a continuous feedback loop during replacement:\n * Real-time progress updates (0-100%)\n * Small image exports after each chunk for verification\n * Issues identified early and resolved incrementally\n * Quick adjustments applied to subsequent chunks\n\n## 7. Final Verification & Context-Aware QA\n- After all chunks are processed:\n * Export the entire design at reduced scale for final verification\n * Check for cross-chunk consistency issues\n * Verify proper text flow between different sections\n * Ensure design harmony across the full composition\n\n## 8. Chunk-Specific Export Scale Guidelines\n- Scale exports appropriately based on chunk size:\n * Small chunks (1-5 elements): scale 1.0\n * Medium chunks (6-20 elements): scale 0.7\n * Large chunks (21-50 elements): scale 0.5\n * Very large chunks (50+ elements): scale 0.3\n * Full design verification: scale 0.2\n\n## Sample Chunking Strategy for Common Design Types\n\n### Tables\n- Process by logical rows (5-10 rows per chunk)\n- Alternative: Process by column for columnar analysis\n- Tip: Always include header row in first chunk for reference\n\n### Card Lists\n- Group 3-5 similar cards per chunk\n- Process entire cards to maintain internal consistency\n- Verify text-to-image ratio within cards after each chunk\n\n### Forms\n- Group related fields (e.g., \"Personal Information\", \"Payment Details\")\n- Process labels and input fields together\n- Ensure validation messages and hints are updated with their fields\n\n### Navigation & Menus\n- Process hierarchical levels together (main menu, submenu)\n- Respect information architecture relationships\n- Verify menu fit and alignment after replacement\n\n## Best Practices\n- **Preserve Design Intent**: Always prioritize design integrity\n- **Structural Consistency**: Maintain alignment, spacing, and hierarchy\n- **Visual Feedback**: Verify each chunk visually before proceeding\n- **Incremental Improvement**: Learn from each chunk to improve subsequent ones\n- **Balance Automation & Control**: Let AI handle repetitive replacements but maintain oversight\n- **Respect Content Relationships**: Keep related content consistent across chunks\n\nRemember that text is never just text—it's a core design element that must work harmoniously with the overall composition. This chunk-based strategy allows you to methodically transform text while maintaining design integrity.`,\n },\n }],\n description: \"Systematic approach for replacing text in Figma designs\",\n })\n );\n\n server.registerPrompt(\n \"swap_overrides_instances\",\n { description: \"Guide to swap instance overrides between instances\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `# Swap Component Instance Overrides\n\n## Overview\nTransfer content overrides from a source instance to target instances.\n\n## Process\n\n### 1. Identify Instances\n- Use \\`get_selection()\\` to identify selected instances\n- Use \\`search_nodes(types: [\"INSTANCE\"])\\` to find instances on the page\n\n### 2. Extract Source Overrides\n- \\`instances(method: \"get\", id: \"source-instance-id\")\\`\n- Returns mainComponentId and per-child override fields (characters, fills, fontSize, etc.)\n\n### 3. Apply to Targets\n- For text overrides: use \\`set_text_content\\` on matching child node IDs\n- For style overrides: use \\`patch_nodes\\` with fill/stroke/text/effects styleName fields\n- Match children by name path — source and target instances share the same internal structure\n\n### 4. Verify\n- \\`get_node_info(nodeId, depth: 1)\\` on target instances\n- \\`export_node_as_image\\` for visual verification`,\n },\n }],\n description: \"Strategy for transferring overrides between component instances in Figma\",\n })\n );\n}\n","import type { McpServer, SendCommandFn, Capabilities } from \"./types\";\nimport { registerTools } from \"./registry\";\n\n// Import tool definitions from all modules\nimport { tools as connectionTools } from \"./defs/connection\";\nimport { tools as documentTools } from \"./defs/document\";\nimport { tools as selectionTools } from \"./defs/selection\";\nimport { tools as nodeInfoTools } from \"./defs/node-info\";\nimport { tools as createShapeTools } from \"./defs/create-shape\";\nimport { tools as createFrameTools } from \"./defs/create-frame\";\nimport { tools as createTextTools } from \"./defs/create-text\";\nimport { tools as modifyNodeTools } from \"./defs/modify-node\";\nimport { tools as patchNodesTools } from \"./defs/patch-nodes\";\nimport { tools as textTools } from \"./defs/text\";\nimport { tools as fontTools } from \"./defs/fonts\";\nimport { tools as lintTools } from \"./defs/lint\";\nimport { tools as styleTools } from \"./defs/styles\";\nimport { tools as variableTools } from \"./defs/variables\";\nimport { tools as componentTools } from \"./defs/components\";\nimport { registerPrompts } from \"./prompts\";\n\nexport const allTools = [\n ...connectionTools,\n ...documentTools,\n ...selectionTools,\n ...nodeInfoTools,\n ...createShapeTools,\n ...createFrameTools,\n ...createTextTools,\n ...modifyNodeTools,\n ...patchNodesTools,\n ...textTools,\n ...fontTools,\n ...lintTools,\n ...styleTools,\n ...variableTools,\n ...componentTools,\n];\n\n/** Register all MCP tools and prompts on the server */\nexport function registerAllTools(server: McpServer, sendCommand: SendCommandFn, caps: Capabilities) {\n registerTools(server, sendCommand, caps, allTools);\n registerPrompts(server);\n}\n"],"mappings":"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","names":["import_zod","server","caps","tools","tools","import_zod","import_zod","tools","import_zod","tools","import_zod","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","import_zod","caps","tools","caps","import_zod","tools","caps","import_zod","tools","caps","server","tools","server","caps","WebSocket","uuidv4"]}
|
|
1
|
+
{"version":3,"sources":["../src/mcp.ts","../src/tools/types.ts","../src/tools/registry.ts","../src/tools/defs/connection.ts","../src/tools/defs/document.ts","../src/tools/defs/selection.ts","../src/utils/coercion.ts","../src/tools/defs/node-info.ts","../src/tools/defs/create-shape.ts","../src/tools/schemas.ts","../src/tools/defs/create-frame.ts","../src/tools/defs/create-text.ts","../src/tools/defs/modify-node.ts","../src/tools/defs/patch-nodes.ts","../src/tools/defs/text.ts","../src/tools/defs/fonts.ts","../src/tools/defs/lint.ts","../src/tools/defs/styles.ts","../src/tools/endpoint.ts","../src/tools/defs/variables.ts","../src/tools/defs/components.ts","../src/tools/prompts.ts","../src/tools/mcp-registry.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { z } from \"zod\";\nimport WebSocket from \"ws\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { readFileSync } from \"fs\";\nimport { join, basename } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { registerAllTools } from \"./tools/mcp-registry\";\n\n// Read version — works with both tsx (source) and node (compiled dist/)\nlet VIBMA_VERSION = \"0.0.0\";\ntry {\n // Walk up from current file's dir to find package.json\n // Use import.meta.url (works in ESM), __dirname (works in CJS), process.cwd() as last resort\n const start = typeof import.meta?.url !== \"undefined\"\n ? join(fileURLToPath(import.meta.url), \"..\")\n : typeof __dirname !== \"undefined\" ? __dirname : process.cwd();\n for (let dir = start; dir !== \"/\"; dir = join(dir, \"..\")) {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, \"package.json\"), \"utf8\"));\n if (pkg.name === \"@ufira/vibma\") { VIBMA_VERSION = pkg.version; break; }\n // Workspace root — dist/ is at root level, read core package version\n if (pkg.workspaces) {\n try { VIBMA_VERSION = JSON.parse(readFileSync(join(dir, \"packages/core/package.json\"), \"utf8\")).version; } catch {}\n break;\n }\n } catch { continue; }\n }\n} catch { /* fallback */ }\n\n// ─── Logger (stderr so it doesn't pollute MCP stdio) ────────────\nconst logger = {\n info: (msg: string) => process.stderr.write(`[INFO] ${msg}\\n`),\n debug: (msg: string) => process.stderr.write(`[DEBUG] ${msg}\\n`),\n warn: (msg: string) => process.stderr.write(`[WARN] ${msg}\\n`),\n error: (msg: string) => process.stderr.write(`[ERROR] ${msg}\\n`),\n log: (msg: string) => process.stderr.write(`[LOG] ${msg}\\n`),\n};\n\n// ─── Types ───────────────────────────────────────────────────────\n\ninterface FigmaResponse {\n id: string;\n result?: any;\n error?: string;\n}\n\ninterface CommandProgressUpdate {\n type: \"command_progress\";\n commandId: string;\n commandType: string;\n status: \"started\" | \"in_progress\" | \"completed\" | \"error\";\n progress: number;\n totalItems: number;\n processedItems: number;\n currentChunk?: number;\n totalChunks?: number;\n chunkSize?: number;\n message: string;\n payload?: any;\n timestamp: number;\n}\n\n// ─── WebSocket state ─────────────────────────────────────────────\n\nlet ws: WebSocket | null = null;\nconst pendingRequests = new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n timeout: ReturnType<typeof setTimeout>;\n lastActivity: number;\n }\n>();\nlet currentChannel: string | null = null;\nlet activePort: number = parseInt(process.env.VIBMA_PORT || \"3055\");\nlet rejected = false; // Suppress auto-reconnect after ROLE_OCCUPIED rejection\nlet versionWarning: string | null = null;\n\n// CLI args\nconst args = process.argv.slice(2);\nconst serverArg = args.find((a) => a.startsWith(\"--server=\"));\nconst portArg = args.find((a) => a.startsWith(\"--port=\"));\nconst serverUrl = serverArg ? serverArg.split(\"=\")[1] : \"localhost\";\nif (portArg) activePort = parseInt(portArg.split(\"=\")[1]);\nconst WS_URL = serverUrl === \"localhost\" ? `ws://${serverUrl}` : `wss://${serverUrl}`;\n\n// Access-tier flags: read is always on, --create / --edit opt-in\nconst caps = {\n create: args.includes(\"--create\") || args.includes(\"--edit\"),\n edit: args.includes(\"--edit\"),\n};\n\n// ─── WebSocket connection ────────────────────────────────────────\n\nfunction connectToFigma(port: number = activePort) {\n activePort = port;\n if (ws && ws.readyState === WebSocket.OPEN) {\n logger.info(\"Already connected to Figma\");\n return;\n }\n\n const wsUrl = serverUrl === \"localhost\" ? `${WS_URL}:${port}` : WS_URL;\n logger.info(`Connecting to Figma socket server at ${wsUrl}...`);\n ws = new WebSocket(wsUrl);\n\n ws.on(\"open\", () => {\n logger.info(\"Connected to Figma socket server\");\n currentChannel = null;\n });\n\n ws.on(\"message\", (data: any) => {\n try {\n const json = JSON.parse(data) as any;\n\n // Handle same-client rejoin (already in channel)\n if (json.type === \"join-success\") {\n logger.info(json.message);\n if (json.id && pendingRequests.has(json.id)) {\n const req = pendingRequests.get(json.id)!;\n clearTimeout(req.timeout);\n req.resolve({ status: \"already_joined\", channel: json.channel });\n pendingRequests.delete(json.id);\n }\n return;\n }\n\n // Handle system messages with a code (version mismatch, peer join/leave)\n // Note: join-success also uses type=system but carries message.id + message.result — let those fall through\n if (json.type === \"system\" && json.code) {\n if (json.code === \"VERSION_MISMATCH\") {\n versionWarning = json.message;\n logger.warn(`Version mismatch: ${json.message}`);\n }\n return;\n }\n\n // Handle relay errors (e.g., ROLE_OCCUPIED rejection)\n if (json.type === \"error\") {\n logger.error(`Relay error: ${json.message}`);\n if (json.code === \"ROLE_OCCUPIED\") rejected = true;\n if (json.id && pendingRequests.has(json.id)) {\n const req = pendingRequests.get(json.id)!;\n clearTimeout(req.timeout);\n req.reject(new Error(json.message));\n pendingRequests.delete(json.id);\n }\n return;\n }\n\n // Handle progress updates\n if (json.type === \"progress_update\") {\n const progressData = json.message.data as CommandProgressUpdate;\n const requestId = json.id || \"\";\n\n if (requestId && pendingRequests.has(requestId)) {\n const request = pendingRequests.get(requestId)!;\n request.lastActivity = Date.now();\n clearTimeout(request.timeout);\n request.timeout = setTimeout(() => {\n if (pendingRequests.has(requestId)) {\n logger.error(`Request ${requestId} timed out after extended period of inactivity`);\n pendingRequests.delete(requestId);\n request.reject(new Error(\"Request to Figma timed out\"));\n }\n }, 60000);\n logger.info(`Progress update for ${progressData.commandType}: ${progressData.progress}% - ${progressData.message}`);\n if (progressData.status === \"completed\" && progressData.progress === 100) {\n logger.info(`Operation ${progressData.commandType} completed, waiting for final result`);\n }\n }\n return;\n }\n\n // Handle regular responses\n const myResponse = json.message;\n logger.debug(`Received message: ${JSON.stringify(myResponse)}`);\n\n if (myResponse.id && pendingRequests.has(myResponse.id) && myResponse.result) {\n const request = pendingRequests.get(myResponse.id)!;\n clearTimeout(request.timeout);\n if (myResponse.error) {\n logger.error(`Error from Figma: ${myResponse.error}`);\n request.reject(new Error(myResponse.error));\n } else {\n request.resolve(myResponse.result);\n }\n pendingRequests.delete(myResponse.id);\n } else {\n logger.info(`Received broadcast message: ${JSON.stringify(myResponse)}`);\n }\n } catch (error) {\n logger.error(`Error parsing message: ${error instanceof Error ? error.message : String(error)}`);\n }\n });\n\n ws.on(\"error\", (error) => {\n logger.error(`Socket error: ${error}`);\n });\n\n ws.on(\"close\", () => {\n logger.info(\"Disconnected from Figma socket server\");\n ws = null;\n for (const [id, request] of pendingRequests.entries()) {\n clearTimeout(request.timeout);\n request.reject(new Error(\"Connection closed\"));\n pendingRequests.delete(id);\n }\n if (rejected) {\n logger.info(\"Not reconnecting — channel role was rejected. Call join_channel to retry.\");\n } else {\n logger.info(\"Attempting to reconnect in 2 seconds...\");\n setTimeout(() => connectToFigma(port), 2000);\n }\n });\n}\n\n// ─── Channel management ──────────────────────────────────────────\n\nasync function joinChannel(channelName: string): Promise<void> {\n rejected = false; // Reset rejection state on explicit join attempt\n versionWarning = null;\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n connectToFigma();\n // Wait briefly for connection\n await new Promise((resolve) => setTimeout(resolve, 1000));\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"Not connected to relay. Check that the relay server is running.\");\n }\n }\n try {\n await sendCommandToFigma(\"join\", { channel: channelName });\n currentChannel = channelName;\n logger.info(`Joined channel: ${channelName}`);\n } catch (error) {\n logger.error(`Failed to join channel: ${error instanceof Error ? error.message : String(error)}`);\n throw error;\n }\n}\n\n// ─── Send command to Figma ───────────────────────────────────────\n\nfunction sendCommandToFigma(\n command: string,\n params: unknown = {},\n timeoutMs: number = 30000\n): Promise<unknown> {\n return new Promise((resolve, reject) => {\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n connectToFigma();\n reject(new Error(\"Not connected to Figma. Attempting to connect...\"));\n return;\n }\n\n const requiresChannel = command !== \"join\";\n if (requiresChannel && !currentChannel) {\n reject(new Error(\"No channel joined. Call join_channel first with the channel name shown in the Figma plugin panel.\"));\n return;\n }\n\n const id = uuidv4();\n const request = {\n id,\n type: command === \"join\" ? \"join\" : \"message\",\n ...(command === \"join\"\n ? { channel: (params as any).channel, role: \"mcp\", version: VIBMA_VERSION, name: basename(process.cwd()) }\n : { channel: currentChannel }),\n message: {\n id,\n command,\n params: {\n ...(params as any),\n commandId: id,\n },\n },\n };\n\n const timeout = setTimeout(() => {\n if (pendingRequests.has(id)) {\n pendingRequests.delete(id);\n logger.error(`Request ${id} to Figma timed out after ${timeoutMs / 1000} seconds`);\n reject(new Error(\n `Request to Figma timed out. This usually means the Figma plugin is not connected to the relay. ` +\n `MCP is using port ${activePort}, channel \"${currentChannel}\". ` +\n `Check the Figma plugin window: the port and channel name must match.`\n ));\n }\n }, timeoutMs);\n\n pendingRequests.set(id, { resolve, reject, timeout, lastActivity: Date.now() });\n logger.info(`Sending command to Figma: ${command}`);\n logger.debug(`Request details: ${JSON.stringify(request)}`);\n ws.send(JSON.stringify(request));\n });\n}\n\n// ─── MCP Server bootstrap ────────────────────────────────────────\n\nconst server = new McpServer({\n name: \"VibmaMCP\",\n version: \"1.0.0\",\n});\n\n// Register the join_channel tool directly (it uses local state)\nserver.registerTool(\n \"join_channel\",\n {\n description: \"REQUIRED FIRST STEP: Join a channel before using any other tool. The channel name is shown in the Figma plugin UI (defaults to 'vibma' if not customised). After joining, call `ping` to verify the Figma plugin is connected. All subsequent commands are sent through this channel.\",\n inputSchema: { channel: z.string().describe(\"The channel name displayed in the Figma plugin panel. Defaults to 'vibma' if omitted.\").default(\"vibma\") },\n },\n async ({ channel }: any) => {\n try {\n await joinChannel(channel);\n // Brief wait for VERSION_MISMATCH system message from relay\n await new Promise((r) => setTimeout(r, 200));\n let msg = `Joined channel \"${channel}\" on port ${activePort}. Call \\`ping\\` now to verify the Figma plugin is connected.`;\n if (versionWarning) msg += `\\n\\n⚠️ ${versionWarning}\\nSee \"Version mismatch\" in CARRYME.md or DRAGME.md for update steps.`;\n return {\n content: [{ type: \"text\", text: msg }],\n };\n } catch (error) {\n return {\n content: [{\n type: \"text\",\n text: `Error joining channel: ${error instanceof Error ? error.message : String(error)}. MCP is using port ${activePort} — confirm the relay is running on the same port.`,\n }],\n };\n }\n }\n);\n\n// Debug tool: inspect relay channel occupancy\nserver.registerTool(\n \"channel_info\",\n {\n description: \"Debug: inspect which clients (MCP, plugin) are connected to each relay channel. Useful for diagnosing connection issues. Does not require an active channel.\",\n },\n async () => {\n try {\n const url = serverUrl === \"localhost\"\n ? `http://localhost:${activePort}/channels`\n : `https://${serverUrl}/channels`;\n const response = await fetch(url);\n if (!response.ok) {\n return { content: [{ type: \"text\", text: `Relay returned ${response.status}: ${await response.text()}` }] };\n }\n const data = await response.json();\n return { content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }] };\n } catch (error) {\n return {\n content: [{\n type: \"text\",\n text: `Could not reach relay at port ${activePort}: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n }\n }\n);\n\n// Factory-reset the tunnel — clears channel on relay via HTTP, then reconnects\nserver.registerTool(\n \"reset_tunnel\",\n {\n description: \"DESTRUCTIVE: Factory-reset a channel on the relay via HTTP, disconnecting ALL occupants (MCP + Figma plugin). Only use this when the channel is stuck or occupied by another MCP — do NOT use it just to reconnect yourself (use `join_channel` instead). After reset, ask the user to reopen the Vibma plugin in Figma, then call `join_channel` and `ping`.\",\n inputSchema: {\n channel: z.string().describe(\"Channel to reset. Defaults to 'vibma'.\").default(\"vibma\"),\n },\n },\n async ({ channel }: { channel: string }) => {\n const targetChannel = channel || currentChannel || \"vibma\";\n try {\n // Factory reset the channel via HTTP — works regardless of socket state\n const url = serverUrl === \"localhost\"\n ? `http://localhost:${activePort}/channels/${encodeURIComponent(targetChannel)}`\n : `https://${serverUrl}/channels/${encodeURIComponent(targetChannel)}`;\n const res = await fetch(url, { method: \"DELETE\" });\n const body = await res.json() as { ok: boolean; message: string };\n\n // Reject all pending requests\n for (const [reqId, request] of pendingRequests.entries()) {\n clearTimeout(request.timeout);\n request.reject(new Error(\"Tunnel reset by user\"));\n pendingRequests.delete(reqId);\n }\n\n // Close the local WebSocket\n if (ws) {\n const old = ws;\n ws = null;\n old.removeAllListeners();\n old.close(1000, \"Tunnel reset\");\n }\n currentChannel = null;\n rejected = false;\n\n // Reconnect to relay\n connectToFigma();\n await new Promise((resolve) => setTimeout(resolve, 1000));\n const connected = ws && ws.readyState === WebSocket.OPEN;\n\n return {\n content: [{\n type: \"text\",\n text: connected\n ? `Tunnel reset: ${body.message}. Reconnected on port ${activePort}.\\n\\nIMPORTANT: The Figma plugin was also disconnected. Ask the user to reopen the Vibma plugin in Figma (or click \"Reset tunnel\" in the plugin panel). Then call \\`join_channel\\` followed by \\`ping\\`.`\n : `Tunnel reset: ${body.message}. Reconnection in progress.\\n\\nIMPORTANT: The Figma plugin was also disconnected. Ask the user to reopen the Vibma plugin in Figma (or click \"Reset tunnel\" in the plugin panel). Then call \\`join_channel\\` to retry.`,\n }],\n };\n } catch (error) {\n return {\n content: [{\n type: \"text\",\n text: `Error resetting tunnel: ${error instanceof Error ? error.message : String(error)}`,\n }],\n };\n }\n }\n);\n\n// Register all per-tool-file tools and prompts\nregisterAllTools(server, sendCommandToFigma, caps);\n\n// ─── Start ───────────────────────────────────────────────────────\n\nfunction cleanup() {\n if (ws && ws.readyState === WebSocket.OPEN) {\n ws.close(1000, \"MCP server shutting down\");\n }\n}\n\nprocess.on(\"SIGINT\", () => { cleanup(); process.exit(0); });\nprocess.on(\"SIGTERM\", () => { cleanup(); process.exit(0); });\nprocess.on(\"exit\", cleanup);\n\nasync function main() {\n try {\n connectToFigma();\n } catch (error) {\n logger.warn(`Could not connect to Figma initially: ${error instanceof Error ? error.message : String(error)}`);\n logger.warn(\"Will try to connect when the first command is sent\");\n }\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n logger.info(\"FigmaMCP server running on stdio\");\n}\n\nmain().catch((error) => {\n logger.error(`Error starting FigmaMCP server: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n});\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { z } from \"zod\";\n\n/** Function signature for sending commands to Figma via WebSocket */\nexport type SendCommandFn = (command: string, params?: unknown, timeoutMs?: number) => Promise<unknown>;\n\n/** Re-export McpServer type for tool files */\nexport type { McpServer };\n\n// ─── Tool Registry Types ────────────────────────────────────────\n\n/** Access tier for a tool */\nexport type ToolTier = \"read\" | \"create\" | \"edit\";\n\n/** Which tiers are enabled for this MCP session */\nexport interface Capabilities { create: boolean; edit: boolean }\n\n/** Declarative tool definition — replaces imperative registerMcpTools() */\nexport interface ToolDef {\n name: string;\n description: string;\n schema: Record<string, z.ZodTypeAny>\n | ((caps: Capabilities) => Record<string, z.ZodTypeAny>);\n tier: ToolTier;\n /** Figma command name. Defaults to name. */\n command?: string;\n /** sendCommand timeout in ms (default: 30 000) */\n timeout?: number;\n /** Pre-send validation (e.g. per-method item parsing for endpoints) */\n validate?: (params: any) => void;\n /** Custom response formatter. Default: mcpJson */\n formatResponse?: (result: unknown) => any;\n}\n\n/** Standard batch result from Figma handlers */\nexport interface BatchResult<T = unknown> {\n results: Array<T | \"ok\" | { error: string }>;\n warnings?: string[];\n /** Set when some items were deferred (e.g. font loading cap exceeded) */\n deferred?: string;\n}\n\n/** Max response size in characters (~12K tokens). Prevents LLM client-side truncation that corrupts JSON. */\nconst MAX_RESPONSE_CHARS = 50_000;\n\n/** Format a successful MCP response (JSON). Returns a clean error if response exceeds safe size. */\nexport function mcpJson(data: unknown) {\n const text = JSON.stringify(data);\n if (text.length <= MAX_RESPONSE_CHARS) {\n return { content: [{ type: \"text\" as const, text }] };\n }\n return {\n content: [{\n type: \"text\" as const,\n text: JSON.stringify({\n _error: \"response_too_large\",\n _sizeKB: Math.round(text.length / 1024),\n warning: \"Response exceeds safe size. Use 'depth', 'fields', 'limit', or 'summaryOnly' parameters to reduce response size.\",\n }),\n }],\n };\n}\n\n/** Format an error MCP response */\nexport function mcpError(prefix: string, error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n return { content: [{ type: \"text\" as const, text: `${prefix}: ${msg}` }] };\n}\n","import type { McpServer, SendCommandFn, Capabilities, ToolDef } from \"./types\";\nimport { mcpJson, mcpError } from \"./types\";\n\n/**\n * Batch-register declarative ToolDefs on the MCP server.\n *\n * 1. Filters by tier: read → always, create → caps.create, edit → caps.edit\n * 2. Resolves dynamic schemas (endpoint tools pass caps-dependent functions)\n * 3. Generates a uniform handler: validate? → sendCommand → formatResponse ?? mcpJson\n */\nexport function registerTools(\n server: McpServer,\n sendCommand: SendCommandFn,\n caps: Capabilities,\n tools: ToolDef[],\n): void {\n for (const tool of tools) {\n // Tier gate\n if (tool.tier === \"create\" && !caps.create) continue;\n if (tool.tier === \"edit\" && !caps.edit) continue;\n\n const schema = typeof tool.schema === \"function\" ? tool.schema(caps) : tool.schema;\n const command = tool.command ?? tool.name;\n const timeout = tool.timeout;\n const format = tool.formatResponse ?? mcpJson;\n\n server.registerTool(tool.name, { description: tool.description, inputSchema: schema }, async (params: any) => {\n try {\n if (tool.validate) tool.validate(params);\n const result = await sendCommand(command, params, timeout);\n return format(result);\n } catch (e) {\n return mcpError(`${tool.name} error`, e);\n }\n });\n }\n}\n","import type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"ping\",\n description: \"Verify end-to-end connection to Figma. Call this right after join_channel. Returns { status: 'pong', documentName, currentPage } if the full chain (MCP → relay → plugin → Figma) is working. If this times out, the Figma plugin is not connected — ask the user to check the plugin window for the correct port and channel name.\",\n schema: {},\n tier: \"read\",\n timeout: 5000,\n },\n];\n","import { z } from \"zod\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_document_info\",\n description: \"Get the document name, current page, and list of all pages.\",\n schema: {},\n tier: \"read\",\n },\n {\n name: \"get_current_page\",\n description: \"Get the current page info and its top-level children.\",\n schema: {},\n tier: \"read\",\n },\n {\n name: \"set_current_page\",\n description: \"Switch to a different page. Provide either pageId or pageName.\",\n schema: {\n pageId: z.string().optional().describe(\"The page ID to switch to\"),\n pageName: z.string().optional().describe(\"The page name (case-insensitive, partial match)\"),\n },\n tier: \"read\",\n },\n {\n name: \"create_page\",\n description: \"Create a new page in the document\",\n schema: { name: z.string().optional().describe(\"Name for the new page (default: 'New Page')\") },\n tier: \"create\",\n },\n {\n name: \"rename_page\",\n description: \"Rename a page. Defaults to current page if no pageId given.\",\n schema: {\n newName: z.string().describe(\"New name for the page\"),\n pageId: z.string().optional().describe(\"Page ID (default: current page)\"),\n },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_selection\",\n description: \"Get the current selection. Without depth, returns stubs (id/name/type). With depth, returns full serialized node trees.\",\n schema: { depth: z.coerce.number().optional().describe(\"Child recursion depth. Omit for stubs only, 0=selected nodes' properties, -1=unlimited.\") },\n tier: \"read\",\n },\n {\n name: \"set_selection\",\n description: \"Set selection to nodes and scroll viewport to show them. Also works as focus (single node).\",\n schema: {\n nodeIds: flexJson(z.array(z.string())).describe('Array of node IDs to select. Example: [\"1:2\",\"1:3\"]'),\n },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\n\n// AI agents (Claude, GPT, etc.) frequently pass numbers as strings\n// (\"10\" instead of 10), booleans as strings (\"true\" instead of true),\n// and objects/arrays as JSON strings. These helpers add resilient\n// coercion so tools don't fail on valid-but-mistyped input.\n\n/** Coerce \"true\"/\"false\"/\"1\"/\"0\" strings to boolean */\nexport const flexBool = <T extends z.ZodTypeAny>(inner: T) =>\n z.preprocess((v) => {\n if (v === \"true\" || v === \"1\") return true;\n if (v === \"false\" || v === \"0\") return false;\n return v;\n }, inner);\n\n/** Coerce JSON strings to parsed values (for objects/arrays that agents may stringify) */\nexport const flexJson = <T extends z.ZodTypeAny>(inner: T) =>\n z.preprocess((v) => {\n if (typeof v === \"string\") {\n try {\n return JSON.parse(v);\n } catch {\n return v;\n }\n }\n return v;\n }, inner);\n\n/** Coerce numeric strings only when they're valid numbers (safe for use inside unions) */\nexport const flexNum = <T extends z.ZodTypeAny>(inner: T) =>\n z.preprocess((v) => {\n if (typeof v === \"string\") {\n const n = Number(v);\n if (!isNaN(n) && v.trim() !== \"\") return n;\n }\n return v;\n }, inner);\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_node_info\",\n description: \"Get detailed information about one or more nodes. Always pass an array of IDs. Use `fields` to select only the properties you need (reduces context size).\",\n schema: {\n nodeIds: flexJson(z.array(z.string())).describe('Array of node IDs. Example: [\"1:2\",\"1:3\"]'),\n depth: z.coerce.number().optional().describe(\"Child recursion depth (default: unlimited). 0=stubs only.\"),\n fields: flexJson(z.array(z.string())).optional().describe('Whitelist of property names to include. Example: [\"absoluteBoundingBox\",\"layoutMode\",\"fills\"]. Omit to return all properties.'),\n },\n tier: \"read\",\n },\n {\n name: \"search_nodes\",\n description: \"Search nodes on the current page by name and/or type. Use set_current_page first to search other pages. Paginated (default 50).\",\n schema: {\n query: z.string().optional().describe(\"Name search (case-insensitive substring). Omit to match all names.\"),\n types: flexJson(z.array(z.string())).optional().describe('Filter by types. Example: [\"FRAME\",\"TEXT\"]. Omit to match all types.'),\n scopeNodeId: z.string().optional().describe(\"Node ID to search within (defaults to current page)\"),\n caseSensitive: flexBool(z.boolean()).optional().describe(\"Case-sensitive name match (default false)\"),\n limit: z.coerce.number().optional().describe(\"Max results (default 50)\"),\n offset: z.coerce.number().optional().describe(\"Skip N results for pagination (default 0)\"),\n },\n tier: \"read\",\n },\n {\n name: \"export_node_as_image\",\n description: \"Export a node as an image from Figma\",\n schema: {\n nodeId: z.string().describe(\"The node ID to export\"),\n format: z.enum([\"PNG\", \"JPG\", \"SVG\", \"PDF\"]).optional().describe(\"Export format (default: PNG)\"),\n scale: z.coerce.number().positive().optional().describe(\"Export scale (default: 1)\"),\n },\n tier: \"read\",\n formatResponse: (result: unknown) => {\n const r = result as any;\n return {\n content: [{ type: \"image\" as const, data: r.imageData, mimeType: r.mimeType || \"image/png\" }],\n };\n },\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst sectionItem = z.object({\n name: z.string().optional().describe(\"Name (default: 'Section')\"),\n x: S.xPos,\n y: S.yPos,\n width: z.coerce.number().optional().describe(\"Width (default: 500)\"),\n height: z.coerce.number().optional().describe(\"Height (default: 500)\"),\n parentId: S.parentId,\n fillColor: flexJson(S.colorRgba).optional().describe(\"Fill color. Default: no fill (transparent).\"),\n fillStyleName: z.string().optional().describe(\"Apply a fill paint style by name (case-insensitive).\"),\n fillVariableId: z.string().optional().describe(\"Bind a color variable to the fill.\"),\n});\n\nconst svgItem = z.object({\n svg: z.string().describe(\"SVG markup string\"),\n name: z.string().optional().describe(\"Layer name (default: 'SVG')\"),\n x: S.xPos,\n y: S.yPos,\n parentId: S.parentId,\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"create_section\",\n description: \"Create section nodes to organize content on the canvas. Default: no fill (transparent).\",\n schema: { items: flexJson(z.array(sectionItem)).describe(\"Array of sections to create\"), depth: S.depth },\n tier: \"create\",\n },\n {\n name: \"create_node_from_svg\",\n description: \"Create nodes from SVG strings.\",\n schema: { items: flexJson(z.array(svgItem)).describe(\"Array of SVG items to create\"), depth: S.depth },\n tier: \"create\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../utils/coercion\";\n\n// ─── Shared Zod Schema Fragments ────────────────────────────────\n// Import as: import * as S from \"./schemas\";\n\n/** Single node ID */\nexport const nodeId = z.string().describe(\"Node ID\");\n\n/** Array of node IDs */\nexport const nodeIds = flexJson(z.array(z.string())).describe(\"Array of node IDs\");\n\n/** Optional parent reference for creation tools */\nexport const parentId = z.string().optional()\n .describe(\"Parent node ID. Omit to place on current page.\");\n\n/**\n * Response depth — controls how much node detail is returned after an operation.\n * Omit for minimal response (id + name only).\n * 0 = node with full properties, children as stubs.\n * N = recurse N levels of children with full properties.\n * -1 = unlimited recursion.\n */\nexport const depth = z.coerce.number().optional()\n .describe(\"Response detail: omit for id+name only. 0=properties + child stubs. N=recurse N levels. -1=unlimited.\");\n\n/** X position for creation tools */\nexport const xPos = z.coerce.number().optional().describe(\"X position (default: 0)\");\n\n/** Y position for creation tools */\nexport const yPos = z.coerce.number().optional().describe(\"Y position (default: 0)\");\n\n/** Parse hex color string (#RGB, #RRGGBB, #RRGGBBAA) to {r,g,b,a} 0-1 */\nfunction parseHex(hex: string): { r: number; g: number; b: number; a?: number } | null {\n const m = hex.match(/^#?([0-9a-f]{3,8})$/i);\n if (!m) return null;\n let h = m[1];\n if (h.length === 3) h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2];\n if (h.length === 4) h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2]+h[3]+h[3];\n if (h.length !== 6 && h.length !== 8) return null;\n const r = parseInt(h.slice(0, 2), 16) / 255;\n const g = parseInt(h.slice(2, 4), 16) / 255;\n const b = parseInt(h.slice(4, 6), 16) / 255;\n if (h.length === 8) return { r, g, b, a: parseInt(h.slice(6, 8), 16) / 255 };\n return { r, g, b };\n}\n\n/** RGBA color — accepts {r,g,b,a?} object (0-1) or hex string (#RGB, #RRGGBB, #RRGGBBAA) */\nexport const colorRgba = z.preprocess((v) => {\n if (typeof v === \"string\") return parseHex(v) ?? v;\n return v;\n}, z.object({\n r: z.coerce.number().min(0).max(1),\n g: z.coerce.number().min(0).max(1),\n b: z.coerce.number().min(0).max(1),\n a: z.coerce.number().min(0).max(1).optional(),\n})).describe('Hex \"#FF0000\" or {r,g,b,a?} with values 0-1.');\n\n/** Single effect entry — shared by set_effects and styles create */\nexport const effectEntry = z.object({\n type: z.enum([\"DROP_SHADOW\", \"INNER_SHADOW\", \"LAYER_BLUR\", \"BACKGROUND_BLUR\"]),\n color: flexJson(colorRgba).optional(),\n offset: flexJson(z.object({ x: z.coerce.number(), y: z.coerce.number() })).optional(),\n radius: z.coerce.number(),\n spread: z.coerce.number().optional(),\n visible: flexBool(z.boolean()).optional(),\n blendMode: z.string().optional(),\n});\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst frameItem = z.object({\n name: z.string().optional().describe(\"Frame name (default: 'Frame')\"),\n x: S.xPos,\n y: S.yPos,\n width: z.coerce.number().optional().describe(\"Width (default: 100)\"),\n height: z.coerce.number().optional().describe(\"Height (default: 100)\"),\n parentId: S.parentId,\n fillColor: flexJson(S.colorRgba).optional().describe('Fill color. Default: no fill.'),\n strokeColor: flexJson(S.colorRgba).optional().describe('Stroke color. Default: none.'),\n strokeWeight: z.coerce.number().positive().optional().describe(\"Stroke weight (default: 1)\"),\n cornerRadius: z.coerce.number().min(0).optional().describe(\"Corner radius (default: 0)\"),\n layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Auto-layout direction (default: NONE)\"),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional().describe(\"Wrap (default: NO_WRAP)\"),\n paddingTop: z.coerce.number().optional().describe(\"Top padding (default: 0)\"),\n paddingRight: z.coerce.number().optional().describe(\"Right padding (default: 0)\"),\n paddingBottom: z.coerce.number().optional().describe(\"Bottom padding (default: 0)\"),\n paddingLeft: z.coerce.number().optional().describe(\"Left padding (default: 0)\"),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional(),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n fillStyleName: z.string().optional().describe(\"Apply a fill paint style by name (case-insensitive). Omit to skip.\"),\n strokeStyleName: z.string().optional().describe(\"Apply a stroke paint style by name. Omit to skip.\"),\n fillVariableId: z.string().optional().describe(\"Bind a color variable to the fill. Creates a solid fill and binds the variable to fills/0/color.\"),\n strokeVariableId: z.string().optional().describe(\"Bind a color variable to the stroke. Creates a solid stroke and binds the variable to strokes/0/color.\"),\n});\n\nconst autoLayoutItem = z.object({\n nodeIds: flexJson(z.array(z.string())).describe(\"Array of node IDs to wrap\"),\n name: z.string().optional().describe(\"Frame name (default: 'Auto Layout')\"),\n layoutMode: z.enum([\"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Direction (default: VERTICAL)\"),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n paddingTop: z.coerce.number().optional().describe(\"Top padding (default: 0)\"),\n paddingRight: z.coerce.number().optional().describe(\"Right padding (default: 0)\"),\n paddingBottom: z.coerce.number().optional().describe(\"Bottom padding (default: 0)\"),\n paddingLeft: z.coerce.number().optional().describe(\"Left padding (default: 0)\"),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional(),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional(),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"create_frame\",\n description: \"Create frames in Figma. Batch supported. Use fillStyleName/fillVariableId and strokeStyleName/strokeVariableId instead of hardcoded colors — hardcoded values skip design tokens and will trigger lint warnings.\",\n schema: { items: flexJson(z.array(frameItem)).describe(\"Array of frames to create\"), depth: S.depth },\n tier: \"create\",\n },\n {\n name: \"create_auto_layout\",\n description: \"Wrap existing nodes in an auto-layout frame. One call replaces create_frame + update_frame + insert_child × N.\",\n schema: { items: flexJson(z.array(autoLayoutItem)).describe(\"Array of auto-layout wraps to perform\"), depth: S.depth },\n tier: \"create\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst textItem = z.object({\n text: z.string().describe(\"Text content\"),\n name: z.string().optional().describe(\"Layer name (default: text content)\"),\n x: S.xPos,\n y: S.yPos,\n fontFamily: z.string().optional().describe(\"Font family (default: Inter). Use get_available_fonts to list installed fonts.\"),\n fontStyle: z.string().optional().describe(\"Font style, e.g. 'Regular', 'Bold', 'Italic' (default: derived from fontWeight). Overrides fontWeight when set.\"),\n fontSize: z.coerce.number().optional().describe(\"Font size (default: 14)\"),\n fontWeight: z.coerce.number().optional().describe(\"Font weight: 100-900 (default: 400). Ignored when fontStyle is set.\"),\n fontColor: flexJson(S.colorRgba).optional().describe('Font color. Default: black.'),\n fontColorVariableId: z.string().optional().describe(\"Bind a color variable to the text fill instead of hardcoded fontColor.\"),\n fontColorStyleName: z.string().optional().describe(\"Apply a paint style to the text fill by name (case-insensitive). Overrides fontColor.\"),\n parentId: S.parentId,\n textStyleId: z.string().optional().describe(\"Text style ID to apply (overrides fontSize/fontWeight). Omit to skip.\"),\n textStyleName: z.string().optional().describe(\"Text style name (case-insensitive match). Omit to skip.\"),\n textAlignHorizontal: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\", \"JUSTIFIED\"]).optional().describe(\"Horizontal text alignment (default: LEFT)\"),\n textAlignVertical: z.enum([\"TOP\", \"CENTER\", \"BOTTOM\"]).optional().describe(\"Vertical text alignment (default: TOP)\"),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Horizontal sizing. FILL auto-sets textAutoResize to HEIGHT.\"),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Vertical sizing (default: HUG)\"),\n textAutoResize: z.enum([\"NONE\", \"WIDTH_AND_HEIGHT\", \"HEIGHT\", \"TRUNCATE\"]).optional().describe(\"Text auto-resize behavior (default: WIDTH_AND_HEIGHT when FILL)\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"create_text\",\n description: \"Create text nodes. Prefer textStyleName for typography and fontColorStyleName or fontColorVariableId for color — hardcoded values skip design tokens. Supports custom fonts via fontFamily.\",\n schema: { items: flexJson(z.array(textItem)).describe(\"Array of text nodes to create\"), depth: S.depth },\n tier: \"create\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst deleteItem = z.object({\n nodeId: z.string().describe(\"Node ID to delete\"),\n});\nconst cloneItem = z.object({\n nodeId: z.string().describe(\"Node ID to clone\"),\n parentId: z.string().optional().describe(\"Parent for the clone (e.g. a page ID). Defaults to same parent as original.\"),\n x: z.coerce.number().optional().describe(\"New X for clone. Omit to keep original position.\"),\n y: z.coerce.number().optional().describe(\"New Y for clone. Omit to keep original position.\"),\n});\nconst insertItem = z.object({\n parentId: z.string().describe(\"Parent node ID\"),\n childId: z.string().describe(\"Child node ID to move\"),\n index: z.coerce.number().optional().describe(\"Index to insert at (0=first). Omit to append.\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"delete_node\",\n description: \"Delete nodes. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(deleteItem)).describe(\"Array of {nodeId}\") },\n tier: \"edit\",\n },\n {\n name: \"clone_node\",\n description: \"Clone nodes. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(cloneItem)).describe(\"Array of {nodeId, x?, y?}\"), depth: S.depth },\n tier: \"create\",\n },\n {\n name: \"insert_child\",\n description: \"Move nodes into a parent at a specific index (reorder/reparent). Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(insertItem)).describe(\"Array of {parentId, childId, index?}\"), depth: S.depth },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst exportSettingEntry = z.object({\n format: z.enum([\"PNG\", \"JPG\", \"SVG\", \"PDF\"]),\n suffix: z.string().optional(),\n contentsOnly: flexBool(z.boolean()).optional(),\n constraint: flexJson(z.object({\n type: z.enum([\"SCALE\", \"WIDTH\", \"HEIGHT\"]),\n value: z.coerce.number(),\n })).optional(),\n});\n\nconst patchNodeItem = z.object({\n nodeId: S.nodeId,\n\n // Geometry (flat)\n x: z.coerce.number().optional().describe(\"X position\"),\n y: z.coerce.number().optional().describe(\"Y position\"),\n width: z.coerce.number().positive().optional().describe(\"Width (must provide height too)\"),\n height: z.coerce.number().positive().optional().describe(\"Height (must provide width too)\"),\n\n // Appearance (nested)\n fill: flexJson(z.object({\n color: flexJson(S.colorRgba).optional(),\n styleName: z.string().optional().describe(\"Paint style name (preferred over color)\"),\n clear: flexBool(z.boolean()).optional().describe(\"Set true to remove all fills\"),\n })).optional().describe(\"Fill color, style, or clear\"),\n\n stroke: flexJson(z.object({\n color: flexJson(S.colorRgba).optional(),\n weight: z.coerce.number().positive().optional().describe(\"Stroke weight\"),\n styleName: z.string().optional().describe(\"Paint style name (preferred over color)\"),\n })).optional().describe(\"Stroke color/weight or style\"),\n\n cornerRadius: flexJson(z.object({\n radius: z.coerce.number().min(0).describe(\"Corner radius\"),\n corners: flexJson(z.array(flexBool(z.boolean())).length(4)).optional()\n .describe(\"Which corners [topLeft, topRight, bottomRight, bottomLeft]. Default: all.\"),\n })).optional().describe(\"Corner radius\"),\n\n opacity: z.coerce.number().min(0).max(1).optional().describe(\"Opacity (0-1)\"),\n\n effects: flexJson(z.object({\n effects: flexJson(z.array(S.effectEntry)).optional().describe(\"Effect objects\"),\n styleName: z.string().optional().describe(\"Effect style name (preferred over raw effects)\"),\n })).optional().describe(\"Effects or effect style\"),\n\n constraints: flexJson(z.object({\n horizontal: z.enum([\"MIN\", \"CENTER\", \"MAX\", \"STRETCH\", \"SCALE\"]),\n vertical: z.enum([\"MIN\", \"CENTER\", \"MAX\", \"STRETCH\", \"SCALE\"]),\n })).optional().describe(\"Layout constraints\"),\n\n exportSettings: flexJson(z.array(exportSettingEntry)).optional().describe(\"Export settings\"),\n\n // Layout (nested)\n layout: flexJson(z.object({\n layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).optional(),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional(),\n paddingTop: z.coerce.number().optional(),\n paddingRight: z.coerce.number().optional(),\n paddingBottom: z.coerce.number().optional(),\n paddingLeft: z.coerce.number().optional(),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional(),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n itemSpacing: z.coerce.number().optional(),\n counterAxisSpacing: z.coerce.number().optional(),\n })).optional().describe(\"Auto-layout properties\"),\n\n // Text (nested)\n text: flexJson(z.object({\n fontSize: z.coerce.number().optional(),\n fontWeight: z.coerce.number().optional(),\n fontColor: flexJson(S.colorRgba).optional(),\n textStyleId: z.string().optional(),\n textStyleName: z.string().optional(),\n textAlignHorizontal: z.enum([\"LEFT\", \"CENTER\", \"RIGHT\", \"JUSTIFIED\"]).optional(),\n textAlignVertical: z.enum([\"TOP\", \"CENTER\", \"BOTTOM\"]).optional(),\n textAutoResize: z.enum([\"NONE\", \"WIDTH_AND_HEIGHT\", \"HEIGHT\", \"TRUNCATE\"]).optional(),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional(),\n })).optional().describe(\"Text properties (font, alignment, sizing)\"),\n\n // Escape hatch\n properties: flexJson(z.record(z.string(), z.unknown())).optional()\n .describe(\"Arbitrary key-value properties to set directly on the node\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"patch_nodes\",\n description: \"Patch properties on nodes. Combines geometry (x/y/width/height), appearance (fill, stroke, cornerRadius, opacity, effects, constraints, exportSettings), layout (auto-layout), text (font props), and arbitrary properties in one call. Prefer styleName over hardcoded colors. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(patchNodeItem)).describe(\"Array of nodes to patch\"), depth: S.depth },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst textContentItem = z.object({\n nodeId: z.string().describe(\"Text node ID\"),\n text: z.string().describe(\"New text content\"),\n});\n\nconst scanTextItem = z.object({\n nodeId: S.nodeId,\n limit: z.coerce.number().optional().describe(\"Max text nodes to return (default: 50)\"),\n includePath: flexBool(z.boolean()).optional().describe(\"Include ancestor path strings (default: true). Set false to reduce payload.\"),\n includeGeometry: flexBool(z.boolean()).optional().describe(\"Include absoluteX/absoluteY/width/height (default: true). Set false to reduce payload.\"),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"set_text_content\",\n description: \"Set text content on text nodes. Batch: pass multiple items to replace text in multiple nodes at once.\",\n schema: { items: flexJson(z.array(textContentItem)).describe(\"Array of {nodeId, text}\"), depth: S.depth },\n tier: \"edit\",\n },\n {\n name: \"scan_text_nodes\",\n description: \"Scan all text nodes within a node tree. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(scanTextItem)).describe(\"Array of {nodeId}\") },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\nimport type { ToolDef } from \"../types\";\n\nexport const tools: ToolDef[] = [\n {\n name: \"get_available_fonts\",\n description: \"Get available fonts in Figma. Optionally filter by query string.\",\n schema: { query: z.string().optional().describe(\"Filter fonts by name (case-insensitive). Omit to list all fonts.\") },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\n\nconst lintRules = z.enum([\n \"no-autolayout\",\n \"shape-instead-of-frame\",\n \"hardcoded-color\",\n \"no-text-style\",\n \"fixed-in-autolayout\",\n \"default-name\",\n \"empty-container\",\n \"stale-text-name\",\n \"no-text-property\",\n \"wcag-contrast\",\n \"wcag-contrast-enhanced\",\n \"wcag-non-text-contrast\",\n \"wcag-target-size\",\n \"wcag-text-size\",\n \"wcag-line-height\",\n \"wcag\",\n \"all\",\n]);\n\nexport const tools: ToolDef[] = [\n {\n name: \"lint_node\",\n description: \"Run design linter on a node tree. Returns issues grouped by category with affected node IDs and fix instructions. Lint child nodes individually for large trees.\",\n schema: {\n nodeId: z.string().optional().describe(\"Node ID to lint. Omit to lint current selection.\"),\n rules: flexJson(z.array(lintRules)).optional().describe('Rules to run. Default: [\"all\"]. Options: no-autolayout, shape-instead-of-frame, hardcoded-color, no-text-style, fixed-in-autolayout, default-name, empty-container, stale-text-name, no-text-property, all, wcag-contrast, wcag-contrast-enhanced, wcag-non-text-contrast, wcag-target-size, wcag-text-size, wcag-line-height, wcag'),\n maxDepth: z.coerce.number().optional().describe(\"Max depth to recurse (default: 10)\"),\n maxFindings: z.coerce.number().optional().describe(\"Stop after N findings (default: 50)\"),\n },\n tier: \"read\",\n },\n {\n name: \"lint_fix_autolayout\",\n description: \"Auto-fix: convert frames with multiple children to auto-layout. Takes node IDs from lint_node 'no-autolayout' results.\",\n schema: {\n items: flexJson(z.array(z.object({\n nodeId: S.nodeId,\n layoutMode: z.enum([\"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Layout direction (default: auto-detect based on child positions)\"),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n }))).describe(\"Array of frames to convert to auto-layout\"),\n depth: S.depth,\n },\n tier: \"edit\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexNum } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\nimport { endpointSchema } from \"../endpoint\";\n\nconst paintStyleItem = z.object({\n name: z.string().describe(\"Style name\"),\n color: flexJson(S.colorRgba).describe('Color.'),\n});\n\nconst textStyleItem = z.object({\n name: z.string().describe(\"Style name\"),\n fontFamily: z.string().describe(\"Font family\"),\n fontStyle: z.string().optional().describe(\"Font style (default: Regular)\"),\n fontSize: z.coerce.number().describe(\"Font size\"),\n lineHeight: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\", \"AUTO\"]) }),\n ])).optional().describe(\"Line height — number (px) or {value, unit}. Default: auto.\"),\n letterSpacing: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\"]) }),\n ])).optional().describe(\"Letter spacing — number (px) or {value, unit}. Default: 0.\"),\n textCase: z.enum([\"ORIGINAL\", \"UPPER\", \"LOWER\", \"TITLE\"]).optional(),\n textDecoration: z.enum([\"NONE\", \"UNDERLINE\", \"STRIKETHROUGH\"]).optional(),\n});\n\nconst effectStyleItem = z.object({\n name: z.string().describe(\"Style name\"),\n effects: flexJson(z.array(S.effectEntry)).describe(\"Array of effects\"),\n});\n\nconst patchBase = {\n id: z.string().describe(\"Style ID or name (case-insensitive match)\"),\n name: z.string().optional().describe(\"Rename the style\"),\n};\n\nconst patchPaintItem = z.object({\n ...patchBase,\n color: flexJson(S.colorRgba).optional().describe('New color.'),\n});\n\nconst patchTextItem = z.object({\n ...patchBase,\n fontFamily: z.string().optional().describe(\"Font family\"),\n fontStyle: z.string().optional().describe(\"Font style, e.g. Regular, Bold\"),\n fontSize: z.coerce.number().optional().describe(\"Font size\"),\n lineHeight: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\", \"AUTO\"]) }),\n ])).optional().describe(\"Line height — number (px) or {value, unit}\"),\n letterSpacing: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\"]) }),\n ])).optional().describe(\"Letter spacing — number (px) or {value, unit}\"),\n textCase: z.enum([\"ORIGINAL\", \"UPPER\", \"LOWER\", \"TITLE\"]).optional(),\n textDecoration: z.enum([\"NONE\", \"UNDERLINE\", \"STRIKETHROUGH\"]).optional(),\n});\n\nconst patchEffectItem = z.object({\n ...patchBase,\n effects: flexJson(z.array(S.effectEntry)).optional().describe(\"Array of effects\"),\n});\n\nconst patchAnyItem = z.object({\n ...patchBase,\n color: flexJson(S.colorRgba).optional(),\n fontFamily: z.string().optional(),\n fontStyle: z.string().optional(),\n fontSize: z.coerce.number().optional(),\n lineHeight: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\", \"AUTO\"]) }),\n ])).optional(),\n letterSpacing: flexNum(z.union([\n z.number(),\n z.object({ value: z.coerce.number(), unit: z.enum([\"PIXELS\", \"PERCENT\"]) }),\n ])).optional(),\n textCase: z.enum([\"ORIGINAL\", \"UPPER\", \"LOWER\", \"TITLE\"]).optional(),\n textDecoration: z.enum([\"NONE\", \"UNDERLINE\", \"STRIKETHROUGH\"]).optional(),\n effects: flexJson(z.array(S.effectEntry)).optional(),\n});\n\nconst createSchemas: Record<string, z.ZodTypeAny> = {\n paint: paintStyleItem, text: textStyleItem, effect: effectStyleItem,\n};\nconst updateSchemas: Record<string, z.ZodTypeAny> = {\n paint: patchPaintItem, text: patchTextItem, effect: patchEffectItem,\n};\n\nexport const tools: ToolDef[] = [\n {\n name: \"styles\",\n description:\n \"CRUD endpoint for local styles (paint, text, effect).\\n\" +\n \" list → {type?, fields?, offset?, limit?} → {totalCount, items: [{id, name, type, ...}]}\\n\" +\n \" get → {id, fields?} → style object (full detail; fields to filter)\\n\" +\n \" create → {type, items: [...]} → {results: [{id}, ...]}\\n\" +\n \" update → {type?, items: [{id, ...}]} → {results: ['ok'|{warning}, ...]}\\n\" +\n \" delete → {id} or {items: [{id}, ...]} → 'ok' or {results: ['ok', ...]}\",\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"update\", \"delete\"],\n caps,\n {\n type: z.enum([\"paint\", \"text\", \"effect\"]).optional()\n .describe(\"Style type. Required for create. Filters list by type. Optional for update (strict per-type validation; omit to auto-detect).\"),\n items: flexJson(z.array(z.any())).optional()\n .describe(\"Create: [{name, color}] (paint), [{name, fontFamily, fontSize, ...}] (text), [{name, effects}] (effect). Update: [{id, ...fields}]. Delete (batch): [{id}, ...].\"),\n depth: S.depth,\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n const map = params.method === \"update\" ? updateSchemas : createSchemas;\n const itemSchema = (params.type && map[params.type]) || patchAnyItem;\n params.items = z.array(itemSchema).parse(params.items);\n }\n },\n },\n];\n","/**\n * Shared endpoint infrastructure.\n *\n * Every resource endpoint follows the same contract:\n * create → items[{...}] → { results: [{id}, ...] }\n * get → { id, fields? } → resource object (field-filtered)\n * list → { filters?, fields?, offset, limit } → { totalCount, returned, offset, limit, items: [...] }\n * update → items[{...}] → { results: [\"ok\", ...] }\n * delete → { id } or items[{id}] → \"ok\" or { results: [\"ok\", ...] }\n *\n * MCP side: endpointSchema()\n * Figma side: createDispatcher() + paginate()\n */\n\nimport { z } from \"zod\";\nimport { flexJson } from \"../utils/coercion\";\nimport type { Capabilities } from \"./types\";\n\n// ─── Method Types ────────────────────────────────────────────────\n\nexport type EndpointMethod = \"create\" | \"get\" | \"list\" | \"update\" | \"delete\";\n\n// ─── Response Types ──────────────────────────────────────────────\n\n/** Batch response envelope (create, update, delete). Produced by batchHandler. */\nexport interface BatchResponse<T = { id: string }> {\n results: Array<T | \"ok\" | { error: string }>;\n warnings?: string[];\n deferred?: string;\n}\n\n/** Paginated list response envelope. */\nexport interface ListResponse<T = Record<string, any>> {\n totalCount: number;\n returned: number;\n offset: number;\n limit: number;\n items: T[];\n}\n\n// ─── Discriminated Param Types ───────────────────────────────────\n//\n// Each endpoint specializes these with its own create/update item\n// types and list filters. Example:\n//\n// type StyleParams = EndpointParams<StyleCreateItem, StyleUpdateItem, { type?: string }>;\n//\n\nexport type EndpointParams<\n TCreate = Record<string, any>,\n TUpdate = Record<string, any>,\n TListFilters = Record<string, never>,\n> =\n | { method: \"create\"; items: TCreate[] }\n | { method: \"get\"; id: string; fields?: string[] }\n | ({ method: \"list\"; fields?: string[]; offset?: number; limit?: number } & TListFilters)\n | { method: \"update\"; items: TUpdate[] }\n | { method: \"delete\"; id?: string; items?: Array<{ id: string }> };\n\n// ─── Helpers ────────────────────────────────────────────────────\n\n/**\n * Top-level field filter for get/list responses.\n * Always preserves identity fields (id, name, type).\n * Pass [\"*\"] to return all fields.\n */\nexport function pickFields(obj: Record<string, any>, fields: string[]): Record<string, any> {\n if (fields.includes(\"*\")) return obj;\n const keep = new Set([...fields, \"id\", \"name\", \"type\"]);\n const out: Record<string, any> = {};\n for (const key of Object.keys(obj)) {\n if (keep.has(key)) out[key] = obj[key];\n }\n return out;\n}\n\n/**\n * Paginate an array of items. Default limit: 100.\n * Call from list handlers after assembling the full result set.\n */\nexport function paginate<T>(items: T[], offset = 0, limit = 100): ListResponse<T> {\n const sliced = items.slice(offset, offset + limit);\n return { totalCount: items.length, returned: sliced.length, offset, limit, items: sliced };\n}\n\n// ─── Schema Builder ──────────────────────────────────────────────\n\n/** Maps each endpoint method to the minimum tier required to use it. */\nexport type MethodTier = \"read\" | \"create\" | \"edit\";\n\nconst DEFAULT_TIERS: Record<string, MethodTier> = {\n get: \"read\", list: \"read\", create: \"create\", update: \"edit\", delete: \"edit\",\n};\n\n/**\n * Build standard endpoint Zod schema fields.\n *\n * Always includes `method`. Auto-adds:\n * - `id` when get/delete are in the method list\n * - `fields` when get or list are in the method list\n * - `offset`/`limit` when list is in the method list\n * Merge endpoint-specific fields (items, list filters) via `extra`.\n *\n * When `caps` is provided, methods are filtered by tier — only methods\n * whose tier is enabled appear in the enum.\n */\nexport function endpointSchema(\n methods: string[],\n capsOrExtra?: Capabilities | Record<string, z.ZodTypeAny>,\n extraOrTiers?: Record<string, z.ZodTypeAny>,\n methodTiers?: Record<string, MethodTier>,\n): Record<string, z.ZodTypeAny> {\n // Overload resolution: (methods, extra?) or (methods, caps, extra?, tiers?)\n let caps: Capabilities | undefined;\n let extra: Record<string, z.ZodTypeAny> | undefined;\n\n if (capsOrExtra && (\"create\" in capsOrExtra) && (\"edit\" in capsOrExtra)\n && typeof (capsOrExtra as any).create === \"boolean\") {\n caps = capsOrExtra as Capabilities;\n extra = extraOrTiers;\n } else {\n extra = capsOrExtra as Record<string, z.ZodTypeAny> | undefined;\n // methodTiers and extraOrTiers are unused in the legacy call signature\n }\n\n // Filter methods by capabilities\n let filtered = methods;\n if (caps) {\n const tiers = { ...DEFAULT_TIERS, ...methodTiers };\n filtered = methods.filter(m => {\n const tier = tiers[m] ?? \"edit\"; // unknown methods default to edit\n if (tier === \"read\") return true;\n if (tier === \"create\") return caps!.create;\n if (tier === \"edit\") return caps!.edit;\n return false;\n });\n }\n\n const schema: Record<string, z.ZodTypeAny> = {\n method: z.enum(filtered as [string, ...string[]]),\n };\n if (filtered.includes(\"get\") || filtered.includes(\"delete\")) {\n schema.id = z.string().optional().describe(\"Resource ID (get, delete)\");\n }\n if (filtered.includes(\"get\") || filtered.includes(\"list\")) {\n schema.fields = flexJson(z.array(z.string())).optional()\n .describe('Property whitelist (get/list). Identity fields (id, name, type) always included. Omit for stubs on list, full detail on get. Pass [\"*\"] for all fields.');\n }\n if (filtered.includes(\"list\")) {\n schema.offset = z.coerce.number().optional().describe(\"Skip N items for pagination (default 0)\");\n schema.limit = z.coerce.number().optional().describe(\"Max items per page (default 100)\");\n }\n return { ...schema, ...extra };\n}\n\n// ─── Figma Dispatcher ────────────────────────────────────────────\n\ntype MethodHandlers = Record<string, (params: any) => Promise<any>>;\n\n/**\n * Create a Figma handler that dispatches on `params.method`.\n * Only methods with registered handlers are allowed.\n * Automatically applies `fields` filtering on get responses.\n */\nexport function createDispatcher(handlers: MethodHandlers) {\n const supported = Object.keys(handlers).join(\", \");\n return async (params: any): Promise<any> => {\n const method = params.method as EndpointMethod;\n const handler = handlers[method];\n if (!handler) throw new Error(`Method '${method}' not supported. Available: ${supported}`);\n let result = await handler(params);\n // Auto-apply fields filtering on get responses (full detail by default)\n if (method === \"get\" && params.fields?.length && result && typeof result === \"object\") {\n result = pickFields(result, params.fields);\n }\n return result;\n };\n}\n","import { z } from \"zod\";\nimport { flexJson } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\nimport { endpointSchema } from \"../endpoint\";\nimport type { MethodTier } from \"../endpoint\";\n\nconst collectionCreateItem = z.object({\n name: z.string().describe(\"Collection name\"),\n});\n\nconst addModeItem = z.object({\n collectionId: z.string().describe(\"Collection ID\"),\n name: z.string().describe(\"Mode name\"),\n});\n\nconst renameModeItem = z.object({\n collectionId: z.string().describe(\"Collection ID\"),\n modeId: z.string().describe(\"Mode ID\"),\n name: z.string().describe(\"New name\"),\n});\n\nconst removeModeItem = z.object({\n collectionId: z.string().describe(\"Collection ID\"),\n modeId: z.string().describe(\"Mode ID\"),\n});\n\nconst deleteCollectionItem = z.object({\n id: z.string().describe(\"Collection ID\"),\n});\n\nconst collectionMethodSchemas: Record<string, z.ZodTypeAny> = {\n create: collectionCreateItem,\n delete: deleteCollectionItem,\n add_mode: addModeItem,\n rename_mode: renameModeItem,\n remove_mode: removeModeItem,\n};\n\nconst variableCreateItem = z.object({\n collectionId: z.string().describe(\"Variable collection ID\"),\n name: z.string().describe(\"Variable name\"),\n resolvedType: z.enum([\"COLOR\", \"FLOAT\", \"STRING\", \"BOOLEAN\"]).describe(\"Variable type\"),\n});\n\nconst variableUpdateItem = z.object({\n id: z.string().describe(\"Variable ID (full ID, e.g. VariableID:1:6)\"),\n modeId: z.string().describe(\"Mode ID\"),\n value: flexJson(z.union([\n z.number(), z.boolean(), S.colorRgba,\n ])).describe('Value: number, boolean, or color (hex \"#RRGGBB\" or {r,g,b,a?} 0-1)'),\n});\n\nconst variableMethodSchemas: Record<string, z.ZodTypeAny> = {\n create: variableCreateItem,\n update: variableUpdateItem,\n};\n\nconst bindingItem = z.object({\n nodeId: z.string().describe(\"Node ID\"),\n field: z.string().describe(\"Property field (e.g., 'opacity', 'fills/0/color')\"),\n variableId: z.string().describe(\"Variable ID (use full ID from create_variable response, e.g. VariableID:1:6)\"),\n});\n\nconst setExplicitModeItem = z.object({\n nodeId: S.nodeId,\n collectionId: z.string().describe(\"Variable collection ID\"),\n modeId: z.string().describe(\"Mode ID to pin (e.g. Dark mode)\"),\n});\n\nconst vcMethodTiers: Record<string, MethodTier> = {\n add_mode: \"create\",\n rename_mode: \"edit\",\n remove_mode: \"edit\",\n};\n\nexport const tools: ToolDef[] = [\n {\n name: \"variable_collections\",\n description:\n `CRUD endpoint for variable collections + mode management.\n create → {items: [{name}]} → {results: [{id, modes, defaultModeId}]}\n get → {id, fields?} → collection object\n list → {fields?, offset?, limit?} → paginated stubs\n delete → {id} or {items: [{id}]} → 'ok' or {results: ['ok', ...]}\n add_mode → {items: [{collectionId, name}]} → {results: [{modeId, modes}]}\n rename_mode → {items: [{collectionId, modeId, name}]} → {results: [{modes}]}\n remove_mode → {items: [{collectionId, modeId}]} → {results: [{modes}]}`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"delete\", \"add_mode\", \"rename_mode\", \"remove_mode\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create: [{name}]. delete (batch): [{id}]. add_mode: [{collectionId, name}]. rename_mode: [{collectionId, modeId, name}]. remove_mode: [{collectionId, modeId}].\"),\n },\n vcMethodTiers,\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n const schema = collectionMethodSchemas[params.method];\n if (schema) params.items = z.array(schema).parse(params.items);\n }\n },\n },\n {\n name: \"variables\",\n description:\n `CRUD endpoint for design variables.\n create → {items: [{collectionId, name, resolvedType}]} → {results: [{id}]}\n get → {id, fields?} → variable object (full detail)\n list → {type?, collectionId?, fields?, offset?, limit?} → paginated stubs (fields for detail)\n update → {items: [{id, modeId, value}]} → {results: ['ok', ...]}`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"update\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create: [{collectionId, name, resolvedType}]. update: [{id, modeId, value}].\"),\n type: z.enum([\"COLOR\", \"FLOAT\", \"STRING\", \"BOOLEAN\"]).optional()\n .describe(\"Filter list by variable type.\"),\n collectionId: z.string().optional()\n .describe(\"Filter list by collection ID.\"),\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n const schema = variableMethodSchemas[params.method];\n if (schema) params.items = z.array(schema).parse(params.items);\n }\n },\n },\n {\n name: \"set_variable_binding\",\n description: \"Bind variables to node properties. Common fields: 'fills/0/color', 'strokes/0/color', 'opacity', 'topLeftRadius', 'itemSpacing'. Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(bindingItem)).describe(\"Array of {nodeId, field, variableId}\") },\n tier: \"edit\",\n },\n {\n name: \"set_explicit_variable_mode\",\n description: \"Pin a variable collection mode on a frame (e.g. show Dark mode). Batch: pass multiple items.\",\n schema: { items: flexJson(z.array(setExplicitModeItem)).describe(\"Array of {nodeId, collectionId, modeId}\") },\n tier: \"edit\",\n },\n {\n name: \"get_node_variables\",\n description: \"Get variable bindings on a node. Returns which variables are bound to fills, strokes, opacity, corner radius, etc.\",\n schema: { nodeId: S.nodeId },\n tier: \"read\",\n },\n];\n","import { z } from \"zod\";\nimport { flexJson, flexBool } from \"../../utils/coercion\";\nimport * as S from \"../schemas\";\nimport type { ToolDef } from \"../types\";\nimport { endpointSchema } from \"../endpoint\";\n\nconst componentItem = z.object({\n name: z.string().describe(\"Component name\"),\n x: S.xPos,\n y: S.yPos,\n width: z.coerce.number().optional().describe(\"Width (default: 100)\"),\n height: z.coerce.number().optional().describe(\"Height (default: 100)\"),\n parentId: S.parentId,\n fillColor: flexJson(S.colorRgba).optional().describe('Fill color. Omit for no fill.'),\n fillStyleName: z.string().optional().describe(\"Apply a fill paint style by name (case-insensitive).\"),\n fillVariableId: z.string().optional().describe(\"Bind a color variable to the fill.\"),\n strokeColor: flexJson(S.colorRgba).optional().describe('Stroke color. Omit for no stroke.'),\n strokeStyleName: z.string().optional().describe(\"Apply a stroke paint style by name.\"),\n strokeVariableId: z.string().optional().describe(\"Bind a color variable to the stroke.\"),\n strokeWeight: z.coerce.number().positive().optional().describe(\"Stroke weight (default: 1)\"),\n cornerRadius: z.coerce.number().optional().describe(\"Corner radius (default: 0)\"),\n layoutMode: z.enum([\"NONE\", \"HORIZONTAL\", \"VERTICAL\"]).optional().describe(\"Layout direction (default: NONE)\"),\n layoutWrap: z.enum([\"NO_WRAP\", \"WRAP\"]).optional().describe(\"Wrap behavior (default: NO_WRAP)\"),\n paddingTop: z.coerce.number().optional().describe(\"Top padding (default: 0)\"),\n paddingRight: z.coerce.number().optional().describe(\"Right padding (default: 0)\"),\n paddingBottom: z.coerce.number().optional().describe(\"Bottom padding (default: 0)\"),\n paddingLeft: z.coerce.number().optional().describe(\"Left padding (default: 0)\"),\n primaryAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"SPACE_BETWEEN\"]).optional().describe(\"Primary axis alignment (default: MIN)\"),\n counterAxisAlignItems: z.enum([\"MIN\", \"MAX\", \"CENTER\", \"BASELINE\"]).optional().describe(\"Counter axis alignment (default: MIN)\"),\n layoutSizingHorizontal: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Horizontal sizing (default: FIXED)\"),\n layoutSizingVertical: z.enum([\"FIXED\", \"HUG\", \"FILL\"]).optional().describe(\"Vertical sizing (default: FIXED)\"),\n itemSpacing: z.coerce.number().optional().describe(\"Spacing between children (default: 0)\"),\n});\n\nconst fromNodeItem = z.object({\n nodeId: S.nodeId,\n exposeText: flexBool(z.boolean()).default(true).describe(\"Auto-expose text children as editable TEXT properties and bind them (default: true). Set false to skip.\"),\n});\n\nconst combineItem = z.object({\n componentIds: flexJson(z.array(z.string())).describe(\"Component IDs to combine (min 2)\"),\n name: z.string().optional().describe(\"Name for the component set. Omit to auto-generate.\"),\n});\n\nconst updateComponentItem = z.object({\n id: z.string().describe(\"Component node ID\"),\n propertyName: z.string().describe(\"Property name\"),\n type: z.enum([\"BOOLEAN\", \"TEXT\", \"INSTANCE_SWAP\", \"VARIANT\"]).describe(\"Property type\"),\n defaultValue: flexBool(z.union([z.string(), z.boolean()])).describe(\"Default value (string for TEXT/VARIANT, boolean for BOOLEAN)\"),\n preferredValues: flexJson(z.array(z.object({\n type: z.enum([\"COMPONENT\", \"COMPONENT_SET\"]),\n key: z.string(),\n })).optional()).describe(\"Preferred values for INSTANCE_SWAP type. Omit for none.\"),\n});\n\nconst componentCreateSchemas: Record<string, z.ZodTypeAny> = {\n component: componentItem,\n from_node: fromNodeItem,\n variant_set: combineItem,\n};\n\nconst instanceCreateItem = z.object({\n componentId: z.string().describe(\"Component or component set ID\"),\n variantProperties: flexJson(z.record(z.string(), z.string())).optional().describe('Pick variant by properties, e.g. {\"Style\":\"Secondary\",\"Size\":\"Large\"}. Ignored for plain COMPONENT IDs.'),\n x: z.coerce.number().optional().describe(\"X position. Omit to keep default.\"),\n y: z.coerce.number().optional().describe(\"Y position. Omit to keep default.\"),\n parentId: S.parentId,\n});\n\nconst instanceUpdateItem = z.object({\n id: S.nodeId,\n properties: flexJson(z.record(z.string(), z.union([z.string(), z.boolean()]))).describe('Property key→value map, e.g. {\"Label#1:0\":\"Click Me\"}'),\n});\n\nexport const tools: ToolDef[] = [\n {\n name: \"components\",\n description:\n `CRUD endpoint for components.\n create → {type, items, depth?} → {results: [{id}, ...]}\n type 'component': create from scratch with layout/style params\n type 'from_node': convert existing nodes to components. Text children are auto-exposed as editable properties by default (exposeText: true) — instances can set text directly via properties.\n type 'variant_set': combine components into variant sets\n get → {id, fields?} → component object (full detail, field-filterable)\n list → {name?, setsOnly?, fields?, offset?, limit?} → paginated stubs\n update → {items: [{id, propertyName, type, defaultValue}]} → creates property AND binds matching text node automatically`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"list\", \"update\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create (component): [{name, parentId?, ...layout}]. create (from_node): [{nodeId, exposeText?}]. create (variant_set): [{componentIds, name?}]. update: [{id, propertyName, type, defaultValue}].\"),\n type: z.enum([\"component\", \"from_node\", \"variant_set\"]).optional()\n .describe(\"Create type. Required for create: 'component' (from scratch), 'from_node' (convert existing), 'variant_set' (combine as variants).\"),\n depth: S.depth,\n name: z.string().optional().describe(\"Filter list by name (case-insensitive substring).\"),\n setsOnly: flexBool(z.boolean()).optional().describe(\"If true, list returns only COMPONENT_SET nodes.\"),\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n if (params.method === \"create\") {\n const schema = params.type && componentCreateSchemas[params.type];\n if (!schema) throw new Error(`create requires type: component, from_node, or variant_set`);\n params.items = z.array(schema).parse(params.items);\n } else if (params.method === \"update\") {\n params.items = z.array(updateComponentItem).parse(params.items);\n }\n }\n },\n },\n {\n name: \"instances\",\n description:\n `CRUD endpoint for component instances.\n create → {items: [{componentId, variantProperties?, x?, y?, parentId?}], depth?} → {results: [{id}]}\n get → {id} → {mainComponentId, overrides: [{id, fields}]}\n update → {items: [{id, properties}]} → {results: ['ok', ...]}`,\n schema: (caps) => endpointSchema(\n [\"create\", \"get\", \"update\"],\n caps,\n {\n items: flexJson(z.array(z.any())).optional()\n .describe(\"create: [{componentId, variantProperties?, x?, y?, parentId?}]. update: [{id, properties}].\"),\n depth: S.depth,\n },\n ),\n tier: \"read\",\n validate: (params: any) => {\n if (params.items) {\n if (params.method === \"create\") {\n params.items = z.array(instanceCreateItem).parse(params.items);\n } else if (params.method === \"update\") {\n params.items = z.array(instanceUpdateItem).parse(params.items);\n }\n }\n },\n },\n];\n","import type { McpServer } from \"./types\";\n\nexport function registerPrompts(server: McpServer) {\n server.registerPrompt(\n \"design_strategy\",\n { description: \"Best practices for working with Figma designs\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `When working with Figma designs, follow these best practices:\n\n1. Understand Before Creating:\n - Use get_document_info() to see pages and current page\n - Use styles(method: \"list\") and get_local_variables() to discover existing design tokens\n - Plan layout hierarchy before creating elements\n\n2. Use Design Tokens — Never Hardcode:\n - Colors: use fillStyleName/strokeStyleName (paint styles) or fillVariableId/strokeVariableId (variables)\n - Text: use textStyleName to apply text styles that control font size, weight, and line height together\n - Effects: use effectStyleName to apply shadow/blur styles\n - Only use raw fillColor/fontColor for one-off values not in the design system\n\n3. Auto-Layout First:\n - Use create_frame() with layoutMode: \"VERTICAL\" or \"HORIZONTAL\" for every container\n - Set itemSpacing, padding, and alignment at creation time\n - Use layoutSizingHorizontal/Vertical: \"FILL\" for responsive children\n - Avoid absolute positioning — let auto-layout handle spacing\n\n4. Naming Conventions:\n - Use descriptive, semantic names for all elements\n - Name components with Property=Value pattern (e.g. \"Size=Small\") before components(method: \"create\", type: \"variant_set\")\n\n5. Variable Modes:\n - Use set_explicit_variable_mode() to pin a frame to a specific mode (e.g. Dark)\n - Use get_node_variables() to verify which variables are bound to a node\n\n6. Quality Check — Run Lint:\n - After building a section, run lint_node() to catch common issues:\n * hardcoded-color: fills/strokes not using styles or variables\n * no-text-style: text without a text style applied\n * no-autolayout: frames with children but no auto-layout\n * default-name: nodes still named \"Frame\", \"Rectangle\", etc.\n - Use lint_fix_autolayout() to auto-fix layout issues\n - Lint early and often — it is cheaper to fix issues during creation than after`,\n },\n }],\n description: \"Best practices for working with Figma designs\",\n })\n );\n\n server.registerPrompt(\n \"read_design_strategy\",\n { description: \"Best practices for reading Figma designs\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `When reading Figma designs, follow these best practices:\n\n1. Start with selection:\n - First use get_selection() to understand the current selection\n - If no selection ask user to select single or multiple nodes\n`,\n },\n }],\n description: \"Best practices for reading Figma designs\",\n })\n );\n\n server.registerPrompt(\n \"text_replacement_strategy\",\n { description: \"Systematic approach for replacing text in Figma designs\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `# Intelligent Text Replacement Strategy\n\n## 1. Analyze Design & Identify Structure\n- Scan text nodes to understand the overall structure of the design\n- Use AI pattern recognition to identify logical groupings:\n * Tables (rows, columns, headers, cells)\n * Lists (items, headers, nested lists)\n * Card groups (similar cards with recurring text fields)\n * Forms (labels, input fields, validation text)\n * Navigation (menu items, breadcrumbs)\n\\`\\`\\`\nscan_text_nodes(nodeId: \"node-id\")\nget_node_info(nodeId: \"node-id\") // optional\n\\`\\`\\`\n\n## 2. Strategic Chunking for Complex Designs\n- Divide replacement tasks into logical content chunks based on design structure\n- Use one of these chunking strategies that best fits the design:\n * **Structural Chunking**: Table rows/columns, list sections, card groups\n * **Spatial Chunking**: Top-to-bottom, left-to-right in screen areas\n * **Semantic Chunking**: Content related to the same topic or functionality\n * **Component-Based Chunking**: Process similar component instances together\n\n## 3. Progressive Replacement with Verification\n- Create a safe copy of the node for text replacement\n- Replace text chunk by chunk with continuous progress updates\n- After each chunk is processed:\n * Export that section as a small, manageable image\n * Verify text fits properly and maintain design integrity\n * Fix issues before proceeding to the next chunk\n\n\\`\\`\\`\n// Clone the node to create a safe copy\nclone_node(nodeId: \"selected-node-id\", x: [new-x], y: [new-y])\n\n// Replace text chunk by chunk\nset_text_content(\n items: [\n { nodeId: \"node-id-1\", text: \"New text 1\" },\n // More nodes in this chunk...\n ]\n)\n\n// Verify chunk with small, targeted image exports\nexport_node_as_image(nodeId: \"chunk-node-id\", format: \"PNG\", scale: 0.5)\n\\`\\`\\`\n\n## 4. Intelligent Handling for Table Data\n- For tabular content:\n * Process one row or column at a time\n * Maintain alignment and spacing between cells\n * Consider conditional formatting based on cell content\n * Preserve header/data relationships\n\n## 5. Smart Text Adaptation\n- Adaptively handle text based on container constraints:\n * Auto-detect space constraints and adjust text length\n * Apply line breaks at appropriate linguistic points\n * Maintain text hierarchy and emphasis\n * Consider font scaling for critical content that must fit\n\n## 6. Progressive Feedback Loop\n- Establish a continuous feedback loop during replacement:\n * Real-time progress updates (0-100%)\n * Small image exports after each chunk for verification\n * Issues identified early and resolved incrementally\n * Quick adjustments applied to subsequent chunks\n\n## 7. Final Verification & Context-Aware QA\n- After all chunks are processed:\n * Export the entire design at reduced scale for final verification\n * Check for cross-chunk consistency issues\n * Verify proper text flow between different sections\n * Ensure design harmony across the full composition\n\n## 8. Chunk-Specific Export Scale Guidelines\n- Scale exports appropriately based on chunk size:\n * Small chunks (1-5 elements): scale 1.0\n * Medium chunks (6-20 elements): scale 0.7\n * Large chunks (21-50 elements): scale 0.5\n * Very large chunks (50+ elements): scale 0.3\n * Full design verification: scale 0.2\n\n## Sample Chunking Strategy for Common Design Types\n\n### Tables\n- Process by logical rows (5-10 rows per chunk)\n- Alternative: Process by column for columnar analysis\n- Tip: Always include header row in first chunk for reference\n\n### Card Lists\n- Group 3-5 similar cards per chunk\n- Process entire cards to maintain internal consistency\n- Verify text-to-image ratio within cards after each chunk\n\n### Forms\n- Group related fields (e.g., \"Personal Information\", \"Payment Details\")\n- Process labels and input fields together\n- Ensure validation messages and hints are updated with their fields\n\n### Navigation & Menus\n- Process hierarchical levels together (main menu, submenu)\n- Respect information architecture relationships\n- Verify menu fit and alignment after replacement\n\n## Best Practices\n- **Preserve Design Intent**: Always prioritize design integrity\n- **Structural Consistency**: Maintain alignment, spacing, and hierarchy\n- **Visual Feedback**: Verify each chunk visually before proceeding\n- **Incremental Improvement**: Learn from each chunk to improve subsequent ones\n- **Balance Automation & Control**: Let AI handle repetitive replacements but maintain oversight\n- **Respect Content Relationships**: Keep related content consistent across chunks\n\nRemember that text is never just text—it's a core design element that must work harmoniously with the overall composition. This chunk-based strategy allows you to methodically transform text while maintaining design integrity.`,\n },\n }],\n description: \"Systematic approach for replacing text in Figma designs\",\n })\n );\n\n server.registerPrompt(\n \"swap_overrides_instances\",\n { description: \"Guide to swap instance overrides between instances\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `# Swap Component Instance Overrides\n\n## Overview\nTransfer content overrides from a source instance to target instances.\n\n## Process\n\n### 1. Identify Instances\n- Use \\`get_selection()\\` to identify selected instances\n- Use \\`search_nodes(types: [\"INSTANCE\"])\\` to find instances on the page\n\n### 2. Extract Source Overrides\n- \\`instances(method: \"get\", id: \"source-instance-id\")\\`\n- Returns mainComponentId and per-child override fields (characters, fills, fontSize, etc.)\n\n### 3. Apply to Targets\n- For text overrides: use \\`set_text_content\\` on matching child node IDs\n- For style overrides: use \\`patch_nodes\\` with fill/stroke/text/effects styleName fields\n- Match children by name path — source and target instances share the same internal structure\n\n### 4. Verify\n- \\`get_node_info(nodeId, depth: 1)\\` on target instances\n- \\`export_node_as_image\\` for visual verification`,\n },\n }],\n description: \"Strategy for transferring overrides between component instances in Figma\",\n })\n );\n\n server.registerPrompt(\n \"missing_tools\",\n { description: \"Why create or edit tools are missing and how to fix it\" },\n () => ({\n messages: [{\n role: \"assistant\" as const,\n content: {\n type: \"text\" as const,\n text: `# Missing Create / Edit Tools\n\nIf the user asks you to create or modify something in Figma but you cannot find tools like \\`create_frame\\`, \\`create_text\\`, \\`patch_nodes\\`, \\`delete_node\\`, or \\`set_text_content\\`, the MCP server was started without the correct access tier flag.\n\nVibma filters tools at startup based on CLI flags passed in the MCP config \\`args\\` array:\n\n| Flag | Tools available |\n|------|----------------|\n| _(none)_ | Read-only (inspect, search, export) |\n| \\`--create\\` | Read + creation tools |\n| \\`--edit\\` | All tools (read + create + edit + delete) |\n\nAsk the user to add \\`--edit\\` (or \\`--create\\`) to their MCP config args:\n\n\\`\\`\\`json\n{\n \"mcpServers\": {\n \"Vibma\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"@ufira/vibma\", \"--edit\"]\n }\n }\n}\n\\`\\`\\`\n\nAfter updating, the user must restart their AI tool or reload MCP servers — stdio-based servers cannot hot-reload.`,\n },\n }],\n description: \"Why create or edit tools are missing and how to fix it\",\n })\n );\n}\n","import type { McpServer, SendCommandFn, Capabilities } from \"./types\";\nimport { registerTools } from \"./registry\";\n\n// Import tool definitions from all modules\nimport { tools as connectionTools } from \"./defs/connection\";\nimport { tools as documentTools } from \"./defs/document\";\nimport { tools as selectionTools } from \"./defs/selection\";\nimport { tools as nodeInfoTools } from \"./defs/node-info\";\nimport { tools as createShapeTools } from \"./defs/create-shape\";\nimport { tools as createFrameTools } from \"./defs/create-frame\";\nimport { tools as createTextTools } from \"./defs/create-text\";\nimport { tools as modifyNodeTools } from \"./defs/modify-node\";\nimport { tools as patchNodesTools } from \"./defs/patch-nodes\";\nimport { tools as textTools } from \"./defs/text\";\nimport { tools as fontTools } from \"./defs/fonts\";\nimport { tools as lintTools } from \"./defs/lint\";\nimport { tools as styleTools } from \"./defs/styles\";\nimport { tools as variableTools } from \"./defs/variables\";\nimport { tools as componentTools } from \"./defs/components\";\nimport { registerPrompts } from \"./prompts\";\n\nexport const allTools = [\n ...connectionTools,\n ...documentTools,\n ...selectionTools,\n ...nodeInfoTools,\n ...createShapeTools,\n ...createFrameTools,\n ...createTextTools,\n ...modifyNodeTools,\n ...patchNodesTools,\n ...textTools,\n ...fontTools,\n ...lintTools,\n ...styleTools,\n ...variableTools,\n ...componentTools,\n];\n\n/** Register all MCP tools and prompts on the server */\nexport function registerAllTools(server: McpServer, sendCommand: SendCommandFn, caps: Capabilities) {\n registerTools(server, sendCommand, caps, allTools);\n registerPrompts(server);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAEA,iBAA0B;AAC1B,mBAAqC;AACrC,IAAAA,eAAkB;AAClB,gBAAsB;AACtB,kBAA6B;AAC7B,gBAA6B;AAC7B,kBAA+B;AAC/B,iBAA8B;;;ACkC9B,IAAM,qBAAqB;AAGpB,SAAS,QAAQ,MAAe;AACrC,QAAM,OAAO,KAAK,UAAU,IAAI;AAChC,MAAI,KAAK,UAAU,oBAAoB;AACrC,WAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,KAAK,CAAC,EAAE;AAAA,EACtD;AACA,SAAO;AAAA,IACL,SAAS,CAAC;AAAA,MACR,MAAM;AAAA,MACN,MAAM,KAAK,UAAU;AAAA,QACnB,QAAQ;AAAA,QACR,SAAS,KAAK,MAAM,KAAK,SAAS,IAAI;AAAA,QACtC,SAAS;AAAA,MACX,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;AAGO,SAAS,SAAS,QAAgB,OAAgB;AACvD,QAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAiB,MAAM,GAAG,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE;AAC3E;;;ACzDO,SAAS,cACdC,SACA,aACAC,OACAC,SACM;AACN,aAAW,QAAQA,SAAO;AAExB,QAAI,KAAK,SAAS,YAAY,CAACD,MAAK,OAAQ;AAC5C,QAAI,KAAK,SAAS,UAAU,CAACA,MAAK,KAAM;AAExC,UAAM,SAAS,OAAO,KAAK,WAAW,aAAa,KAAK,OAAOA,KAAI,IAAI,KAAK;AAC5E,UAAM,UAAU,KAAK,WAAW,KAAK;AACrC,UAAM,UAAU,KAAK;AACrB,UAAM,SAAS,KAAK,kBAAkB;AAEtC,IAAAD,QAAO,aAAa,KAAK,MAAM,EAAE,aAAa,KAAK,aAAa,aAAa,OAAO,GAAG,OAAO,WAAgB;AAC5G,UAAI;AACF,YAAI,KAAK,SAAU,MAAK,SAAS,MAAM;AACvC,cAAM,SAAS,MAAM,YAAY,SAAS,QAAQ,OAAO;AACzD,eAAO,OAAO,MAAM;AAAA,MACtB,SAAS,GAAG;AACV,eAAO,SAAS,GAAG,KAAK,IAAI,UAAU,CAAC;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AClCO,IAAM,QAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;;;ACVA,iBAAkB;AAGX,IAAMG,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,CAAC;AAAA,IACT,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,QAAQ,aAAE,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,MACjE,UAAU,aAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,IAC5F;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,MAAM,aAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6CAA6C,EAAE;AAAA,IAC9F,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,SAAS,aAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,MACpD,QAAQ,aAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,IAC1E;AAAA,IACA,MAAM;AAAA,EACR;AACF;;;ACxCA,IAAAC,cAAkB;;;ACAlB,IAAAC,cAAkB;AAQX,IAAM,WAAW,CAAyB,UAC/C,cAAE,WAAW,CAAC,MAAM;AAClB,MAAI,MAAM,UAAU,MAAM,IAAK,QAAO;AACtC,MAAI,MAAM,WAAW,MAAM,IAAK,QAAO;AACvC,SAAO;AACT,GAAG,KAAK;AAGH,IAAM,WAAW,CAAyB,UAC/C,cAAE,WAAW,CAAC,MAAM;AAClB,MAAI,OAAO,MAAM,UAAU;AACzB,QAAI;AACF,aAAO,KAAK,MAAM,CAAC;AAAA,IACrB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT,GAAG,KAAK;AAGH,IAAM,UAAU,CAAyB,UAC9C,cAAE,WAAW,CAAC,MAAM;AAClB,MAAI,OAAO,MAAM,UAAU;AACzB,UAAM,IAAI,OAAO,CAAC;AAClB,QAAI,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,MAAM,GAAI,QAAO;AAAA,EAC3C;AACA,SAAO;AACT,GAAG,KAAK;;;ADhCH,IAAMC,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,yFAAyF,EAAE;AAAA,IAClJ,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,SAAS,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,EAAE,SAAS,qDAAqD;AAAA,IACvG;AAAA,IACA,MAAM;AAAA,EACR;AACF;;;AEnBA,IAAAC,cAAkB;AAIX,IAAMC,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,SAAS,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,EAAE,SAAS,2CAA2C;AAAA,MAC3F,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,2DAA2D;AAAA,MACxG,QAAQ,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,+HAA+H;AAAA,IAC3L;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,OAAO,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,MAC1G,OAAO,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,sEAAsE;AAAA,MAC/H,aAAa,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qDAAqD;AAAA,MACjG,eAAe,SAAS,cAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,MACpG,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,MACvE,QAAQ,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,IAC3F;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,QAAQ,cAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,MACnD,QAAQ,cAAE,KAAK,CAAC,OAAO,OAAO,OAAO,KAAK,CAAC,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,MAC/F,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,IACrF;AAAA,IACA,MAAM;AAAA,IACN,gBAAgB,CAAC,WAAoB;AACnC,YAAM,IAAI;AACV,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,SAAkB,MAAM,EAAE,WAAW,UAAU,EAAE,YAAY,YAAY,CAAC;AAAA,MAC9F;AAAA,IACF;AAAA,EACF;AACF;;;AC5CA,IAAAC,cAAkB;;;ACAlB,IAAAC,cAAkB;AAOX,IAAM,SAAS,cAAE,OAAO,EAAE,SAAS,SAAS;AAG5C,IAAM,UAAU,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,EAAE,SAAS,mBAAmB;AAG1E,IAAM,WAAW,cAAE,OAAO,EAAE,SAAS,EACzC,SAAS,gDAAgD;AASrD,IAAM,QAAQ,cAAE,OAAO,OAAO,EAAE,SAAS,EAC7C,SAAS,uGAAuG;AAG5G,IAAM,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAG5E,IAAM,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAGnF,SAAS,SAAS,KAAqE;AACrF,QAAM,IAAI,IAAI,MAAM,sBAAsB;AAC1C,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,IAAI,EAAE,CAAC;AACX,MAAI,EAAE,WAAW,EAAG,KAAI,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC;AACpD,MAAI,EAAE,WAAW,EAAG,KAAI,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC,IAAE,EAAE,CAAC;AAC9D,MAAI,EAAE,WAAW,KAAK,EAAE,WAAW,EAAG,QAAO;AAC7C,QAAM,IAAI,SAAS,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AACxC,QAAM,IAAI,SAAS,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AACxC,QAAM,IAAI,SAAS,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI;AACxC,MAAI,EAAE,WAAW,EAAG,QAAO,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI,IAAI;AAC3E,SAAO,EAAE,GAAG,GAAG,EAAE;AACnB;AAGO,IAAM,YAAY,cAAE,WAAW,CAAC,MAAM;AAC3C,MAAI,OAAO,MAAM,SAAU,QAAO,SAAS,CAAC,KAAK;AACjD,SAAO;AACT,GAAG,cAAE,OAAO;AAAA,EACV,GAAG,cAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACjC,GAAG,cAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACjC,GAAG,cAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EACjC,GAAG,cAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAC9C,CAAC,CAAC,EAAE,SAAS,8CAA8C;AAGpD,IAAM,cAAc,cAAE,OAAO;AAAA,EAClC,MAAM,cAAE,KAAK,CAAC,eAAe,gBAAgB,cAAc,iBAAiB,CAAC;AAAA,EAC7E,OAAO,SAAS,SAAS,EAAE,SAAS;AAAA,EACpC,QAAQ,SAAS,cAAE,OAAO,EAAE,GAAG,cAAE,OAAO,OAAO,GAAG,GAAG,cAAE,OAAO,OAAO,EAAE,CAAC,CAAC,EAAE,SAAS;AAAA,EACpF,QAAQ,cAAE,OAAO,OAAO;AAAA,EACxB,QAAQ,cAAE,OAAO,OAAO,EAAE,SAAS;AAAA,EACnC,SAAS,SAAS,cAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EACxC,WAAW,cAAE,OAAO,EAAE,SAAS;AACjC,CAAC;;;AD9DD,IAAM,cAAc,cAAE,OAAO;AAAA,EAC3B,MAAM,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,EAChE,GAAK;AAAA,EACL,GAAK;AAAA,EACL,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,EACnE,QAAQ,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,EACrE;AAAA,EACA,WAAW,SAAW,SAAS,EAAE,SAAS,EAAE,SAAS,6CAA6C;AAAA,EAClG,eAAe,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,EACpG,gBAAgB,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AACrF,CAAC;AAED,IAAM,UAAU,cAAE,OAAO;AAAA,EACvB,KAAK,cAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,EAC5C,MAAM,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EAClE,GAAK;AAAA,EACL,GAAK;AAAA,EACL;AACF,CAAC;AAEM,IAAMC,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,WAAW,CAAC,EAAE,SAAS,6BAA6B,GAAG,MAAe;AAAA,IACxG,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,OAAO,CAAC,EAAE,SAAS,8BAA8B,GAAG,MAAe;AAAA,IACrG,MAAM;AAAA,EACR;AACF;;;AEtCA,IAAAC,cAAkB;AAKlB,IAAM,YAAY,cAAE,OAAO;AAAA,EACzB,MAAM,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EACpE,GAAK;AAAA,EACL,GAAK;AAAA,EACL,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,EACnE,QAAQ,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,EACrE;AAAA,EACA,WAAW,SAAW,SAAS,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EACpF,aAAa,SAAW,SAAS,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,EACrF,cAAc,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EAC3F,cAAc,cAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EACvF,YAAY,cAAE,KAAK,CAAC,QAAQ,cAAc,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,EAClH,YAAY,cAAE,KAAK,CAAC,WAAW,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,EACrF,YAAY,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EAC5E,cAAc,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EAChF,eAAe,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EAClF,aAAa,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,EAC9E,uBAAuB,cAAE,KAAK,CAAC,OAAO,OAAO,UAAU,eAAe,CAAC,EAAE,SAAS;AAAA,EAClF,uBAAuB,cAAE,KAAK,CAAC,OAAO,OAAO,UAAU,UAAU,CAAC,EAAE,SAAS;AAAA,EAC7E,wBAAwB,cAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,EAClE,sBAAsB,cAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,EAChE,aAAa,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,EAC1F,eAAe,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oEAAoE;AAAA,EAClH,iBAAiB,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,EACnG,gBAAgB,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kGAAkG;AAAA,EACjJ,kBAAkB,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wGAAwG;AAC3J,CAAC;AAED,IAAM,iBAAiB,cAAE,OAAO;AAAA,EAC9B,SAAS,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,CAAC,EAAE,SAAS,2BAA2B;AAAA,EAC3E,MAAM,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EAC1E,YAAY,cAAE,KAAK,CAAC,cAAc,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EAClG,aAAa,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,EAC1F,YAAY,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EAC5E,cAAc,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EAChF,eAAe,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EAClF,aAAa,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,EAC9E,uBAAuB,cAAE,KAAK,CAAC,OAAO,OAAO,UAAU,eAAe,CAAC,EAAE,SAAS;AAAA,EAClF,uBAAuB,cAAE,KAAK,CAAC,OAAO,OAAO,UAAU,UAAU,CAAC,EAAE,SAAS;AAAA,EAC7E,wBAAwB,cAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,EAClE,sBAAsB,cAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,EAChE,YAAY,cAAE,KAAK,CAAC,WAAW,MAAM,CAAC,EAAE,SAAS;AACnD,CAAC;AAEM,IAAMC,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,SAAS,CAAC,EAAE,SAAS,2BAA2B,GAAG,MAAe;AAAA,IACpG,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,cAAc,CAAC,EAAE,SAAS,uCAAuC,GAAG,MAAe;AAAA,IACrH,MAAM;AAAA,EACR;AACF;;;AC9DA,IAAAC,cAAkB;AAKlB,IAAM,WAAW,cAAE,OAAO;AAAA,EACxB,MAAM,cAAE,OAAO,EAAE,SAAS,cAAc;AAAA,EACxC,MAAM,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,EACzE,GAAK;AAAA,EACL,GAAK;AAAA,EACL,YAAY,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gFAAgF;AAAA,EAC3H,WAAW,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,iHAAiH;AAAA,EAC3J,UAAU,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,EACzE,YAAY,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,qEAAqE;AAAA,EACvH,WAAW,SAAW,SAAS,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EAClF,qBAAqB,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,wEAAwE;AAAA,EAC5H,oBAAoB,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uFAAuF;AAAA,EAC1I;AAAA,EACA,aAAa,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uEAAuE;AAAA,EACnH,eAAe,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yDAAyD;AAAA,EACvG,qBAAqB,cAAE,KAAK,CAAC,QAAQ,UAAU,SAAS,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA,EACrI,mBAAmB,cAAE,KAAK,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,EACnH,wBAAwB,cAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,6DAA6D;AAAA,EAC1I,sBAAsB,cAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC3G,gBAAgB,cAAE,KAAK,CAAC,QAAQ,oBAAoB,UAAU,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,iEAAiE;AAClK,CAAC;AAEM,IAAMC,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,QAAQ,CAAC,EAAE,SAAS,+BAA+B,GAAG,MAAe;AAAA,IACvG,MAAM;AAAA,EACR;AACF;;;AClCA,IAAAC,cAAkB;AAKlB,IAAM,aAAa,cAAE,OAAO;AAAA,EAC1B,QAAQ,cAAE,OAAO,EAAE,SAAS,mBAAmB;AACjD,CAAC;AACD,IAAM,YAAY,cAAE,OAAO;AAAA,EACzB,QAAQ,cAAE,OAAO,EAAE,SAAS,kBAAkB;AAAA,EAC9C,UAAU,cAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6EAA6E;AAAA,EACtH,GAAG,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA,EAC3F,GAAG,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAC7F,CAAC;AACD,IAAM,aAAa,cAAE,OAAO;AAAA,EAC1B,UAAU,cAAE,OAAO,EAAE,SAAS,gBAAgB;AAAA,EAC9C,SAAS,cAAE,OAAO,EAAE,SAAS,uBAAuB;AAAA,EACpD,OAAO,cAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,+CAA+C;AAC9F,CAAC;AAEM,IAAMC,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE;AAAA,IAC7E,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,SAAS,CAAC,EAAE,SAAS,2BAA2B,GAAG,MAAe;AAAA,IACpG,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,cAAE,MAAM,UAAU,CAAC,EAAE,SAAS,sCAAsC,GAAG,MAAe;AAAA,IAChH,MAAM;AAAA,EACR;AACF;;;ACvCA,IAAAC,eAAkB;AAKlB,IAAM,qBAAqB,eAAE,OAAO;AAAA,EAClC,QAAQ,eAAE,KAAK,CAAC,OAAO,OAAO,OAAO,KAAK,CAAC;AAAA,EAC3C,QAAQ,eAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,cAAc,SAAS,eAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,EAC7C,YAAY,SAAS,eAAE,OAAO;AAAA,IAC5B,MAAM,eAAE,KAAK,CAAC,SAAS,SAAS,QAAQ,CAAC;AAAA,IACzC,OAAO,eAAE,OAAO,OAAO;AAAA,EACzB,CAAC,CAAC,EAAE,SAAS;AACf,CAAC;AAED,IAAM,gBAAgB,eAAE,OAAO;AAAA,EAC7B;AAAA;AAAA,EAGA,GAAG,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,YAAY;AAAA,EACrD,GAAG,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,YAAY;AAAA,EACrD,OAAO,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA,EACzF,QAAQ,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,iCAAiC;AAAA;AAAA,EAG1F,MAAM,SAAS,eAAE,OAAO;AAAA,IACtB,OAAO,SAAW,SAAS,EAAE,SAAS;AAAA,IACtC,WAAW,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,IACnF,OAAO,SAAS,eAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,EACjF,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EAErD,QAAQ,SAAS,eAAE,OAAO;AAAA,IACxB,OAAO,SAAW,SAAS,EAAE,SAAS;AAAA,IACtC,QAAQ,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,eAAe;AAAA,IACxE,WAAW,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAAA,EACrF,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,8BAA8B;AAAA,EAEtD,cAAc,SAAS,eAAE,OAAO;AAAA,IAC9B,QAAQ,eAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS,eAAe;AAAA,IACzD,SAAS,SAAS,eAAE,MAAM,SAAS,eAAE,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS,EAClE,SAAS,2EAA2E;AAAA,EACzF,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,eAAe;AAAA,EAEvC,SAAS,eAAE,OAAO,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,eAAe;AAAA,EAE5E,SAAS,SAAS,eAAE,OAAO;AAAA,IACzB,SAAS,SAAS,eAAE,MAAQ,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,gBAAgB;AAAA,IAC9E,WAAW,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gDAAgD;AAAA,EAC5F,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,yBAAyB;AAAA,EAEjD,aAAa,SAAS,eAAE,OAAO;AAAA,IAC7B,YAAY,eAAE,KAAK,CAAC,OAAO,UAAU,OAAO,WAAW,OAAO,CAAC;AAAA,IAC/D,UAAU,eAAE,KAAK,CAAC,OAAO,UAAU,OAAO,WAAW,OAAO,CAAC;AAAA,EAC/D,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,oBAAoB;AAAA,EAE5C,gBAAgB,SAAS,eAAE,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,SAAS,iBAAiB;AAAA;AAAA,EAG3F,QAAQ,SAAS,eAAE,OAAO;AAAA,IACxB,YAAY,eAAE,KAAK,CAAC,QAAQ,cAAc,UAAU,CAAC,EAAE,SAAS;AAAA,IAChE,YAAY,eAAE,KAAK,CAAC,WAAW,MAAM,CAAC,EAAE,SAAS;AAAA,IACjD,YAAY,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,IACvC,cAAc,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,IACzC,eAAe,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,IAC1C,aAAa,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,IACxC,uBAAuB,eAAE,KAAK,CAAC,OAAO,OAAO,UAAU,eAAe,CAAC,EAAE,SAAS;AAAA,IAClF,uBAAuB,eAAE,KAAK,CAAC,OAAO,OAAO,UAAU,UAAU,CAAC,EAAE,SAAS;AAAA,IAC7E,wBAAwB,eAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,IAClE,sBAAsB,eAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,IAChE,aAAa,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,IACxC,oBAAoB,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,EACjD,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,wBAAwB;AAAA;AAAA,EAGhD,MAAM,SAAS,eAAE,OAAO;AAAA,IACtB,UAAU,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,IACrC,YAAY,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,IACvC,WAAW,SAAW,SAAS,EAAE,SAAS;AAAA,IAC1C,aAAa,eAAE,OAAO,EAAE,SAAS;AAAA,IACjC,eAAe,eAAE,OAAO,EAAE,SAAS;AAAA,IACnC,qBAAqB,eAAE,KAAK,CAAC,QAAQ,UAAU,SAAS,WAAW,CAAC,EAAE,SAAS;AAAA,IAC/E,mBAAmB,eAAE,KAAK,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,SAAS;AAAA,IAChE,gBAAgB,eAAE,KAAK,CAAC,QAAQ,oBAAoB,UAAU,UAAU,CAAC,EAAE,SAAS;AAAA,IACpF,wBAAwB,eAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,IAClE,sBAAsB,eAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS;AAAA,EAClE,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,2CAA2C;AAAA;AAAA,EAGnE,YAAY,SAAS,eAAE,OAAO,eAAE,OAAO,GAAG,eAAE,QAAQ,CAAC,CAAC,EAAE,SAAS,EAC9D,SAAS,4DAA4D;AAC1E,CAAC;AAEM,IAAMC,SAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,eAAE,MAAM,aAAa,CAAC,EAAE,SAAS,yBAAyB,GAAG,MAAe;AAAA,IACtG,MAAM;AAAA,EACR;AACF;;;ACnGA,IAAAC,eAAkB;AAKlB,IAAM,kBAAkB,eAAE,OAAO;AAAA,EAC/B,QAAQ,eAAE,OAAO,EAAE,SAAS,cAAc;AAAA,EAC1C,MAAM,eAAE,OAAO,EAAE,SAAS,kBAAkB;AAC9C,CAAC;AAED,IAAM,eAAe,eAAE,OAAO;AAAA,EAC5B;AAAA,EACA,OAAO,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,wCAAwC;AAAA,EACrF,aAAa,SAAS,eAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,6EAA6E;AAAA,EACpI,iBAAiB,SAAS,eAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,wFAAwF;AACrJ,CAAC;AAEM,IAAMC,UAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,eAAE,MAAM,eAAe,CAAC,EAAE,SAAS,yBAAyB,GAAG,MAAe;AAAA,IACxG,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,eAAE,MAAM,YAAY,CAAC,EAAE,SAAS,mBAAmB,EAAE;AAAA,IAC/E,MAAM;AAAA,EACR;AACF;;;AC9BA,IAAAC,eAAkB;AAGX,IAAMC,UAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kEAAkE,EAAE;AAAA,IACpH,MAAM;AAAA,EACR;AACF;;;ACVA,IAAAC,eAAkB;AAKlB,IAAM,YAAY,eAAE,KAAK;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,IAAMC,UAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,QAAQ,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kDAAkD;AAAA,MACzF,OAAO,SAAS,eAAE,MAAM,SAAS,CAAC,EAAE,SAAS,EAAE,SAAS,qUAAqU;AAAA,MAC7X,UAAU,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,MACpF,aAAa,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,IAC1F;AAAA,IACA,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ;AAAA,MACN,OAAO,SAAS,eAAE,MAAM,eAAE,OAAO;AAAA,QAC/B;AAAA,QACA,YAAY,eAAE,KAAK,CAAC,cAAc,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,kEAAkE;AAAA,QACrI,aAAa,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,MAC5F,CAAC,CAAC,CAAC,EAAE,SAAS,2CAA2C;AAAA,MACzD;AAAA,IACF;AAAA,IACA,MAAM;AAAA,EACR;AACF;;;AClDA,IAAAC,eAAkB;;;ACclB,IAAAC,eAAkB;AA4ElB,IAAM,gBAA4C;AAAA,EAChD,KAAK;AAAA,EAAQ,MAAM;AAAA,EAAQ,QAAQ;AAAA,EAAU,QAAQ;AAAA,EAAQ,QAAQ;AACvE;AAcO,SAAS,eACd,SACA,aACA,cACA,aAC8B;AAE9B,MAAIC;AACJ,MAAI;AAEJ,MAAI,eAAgB,YAAY,eAAiB,UAAU,eACpD,OAAQ,YAAoB,WAAW,WAAW;AACvD,IAAAA,QAAO;AACP,YAAQ;AAAA,EACV,OAAO;AACL,YAAQ;AAAA,EAEV;AAGA,MAAI,WAAW;AACf,MAAIA,OAAM;AACR,UAAM,QAAQ,EAAE,GAAG,eAAe,GAAG,YAAY;AACjD,eAAW,QAAQ,OAAO,OAAK;AAC7B,YAAM,OAAO,MAAM,CAAC,KAAK;AACzB,UAAI,SAAS,OAAQ,QAAO;AAC5B,UAAI,SAAS,SAAU,QAAOA,MAAM;AACpC,UAAI,SAAS,OAAQ,QAAOA,MAAM;AAClC,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,QAAM,SAAuC;AAAA,IAC3C,QAAQ,eAAE,KAAK,QAAiC;AAAA,EAClD;AACA,MAAI,SAAS,SAAS,KAAK,KAAK,SAAS,SAAS,QAAQ,GAAG;AAC3D,WAAO,KAAK,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,EACxE;AACA,MAAI,SAAS,SAAS,KAAK,KAAK,SAAS,SAAS,MAAM,GAAG;AACzD,WAAO,SAAS,SAAS,eAAE,MAAM,eAAE,OAAO,CAAC,CAAC,EAAE,SAAS,EACpD,SAAS,yJAAyJ;AAAA,EACvK;AACA,MAAI,SAAS,SAAS,MAAM,GAAG;AAC7B,WAAO,SAAS,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,yCAAyC;AAC/F,WAAO,QAAQ,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EACzF;AACA,SAAO,EAAE,GAAG,QAAQ,GAAG,MAAM;AAC/B;;;ADnJA,IAAM,iBAAiB,eAAE,OAAO;AAAA,EAC9B,MAAM,eAAE,OAAO,EAAE,SAAS,YAAY;AAAA,EACtC,OAAO,SAAW,SAAS,EAAE,SAAS,QAAQ;AAChD,CAAC;AAED,IAAM,gBAAgB,eAAE,OAAO;AAAA,EAC7B,MAAM,eAAE,OAAO,EAAE,SAAS,YAAY;AAAA,EACtC,YAAY,eAAE,OAAO,EAAE,SAAS,aAAa;AAAA,EAC7C,WAAW,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EACzE,UAAU,eAAE,OAAO,OAAO,EAAE,SAAS,WAAW;AAAA,EAChD,YAAY,QAAQ,eAAE,MAAM;AAAA,IAC1B,eAAE,OAAO;AAAA,IACT,eAAE,OAAO,EAAE,OAAO,eAAE,OAAO,OAAO,GAAG,MAAM,eAAE,KAAK,CAAC,UAAU,WAAW,MAAM,CAAC,EAAE,CAAC;AAAA,EACpF,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,iEAA4D;AAAA,EACpF,eAAe,QAAQ,eAAE,MAAM;AAAA,IAC7B,eAAE,OAAO;AAAA,IACT,eAAE,OAAO,EAAE,OAAO,eAAE,OAAO,OAAO,GAAG,MAAM,eAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,CAAC;AAAA,EAC5E,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,iEAA4D;AAAA,EACpF,UAAU,eAAE,KAAK,CAAC,YAAY,SAAS,SAAS,OAAO,CAAC,EAAE,SAAS;AAAA,EACnE,gBAAgB,eAAE,KAAK,CAAC,QAAQ,aAAa,eAAe,CAAC,EAAE,SAAS;AAC1E,CAAC;AAED,IAAM,kBAAkB,eAAE,OAAO;AAAA,EAC/B,MAAM,eAAE,OAAO,EAAE,SAAS,YAAY;AAAA,EACtC,SAAS,SAAS,eAAE,MAAQ,WAAW,CAAC,EAAE,SAAS,kBAAkB;AACvE,CAAC;AAED,IAAM,YAAY;AAAA,EAChB,IAAI,eAAE,OAAO,EAAE,SAAS,2CAA2C;AAAA,EACnE,MAAM,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,kBAAkB;AACzD;AAEA,IAAM,iBAAiB,eAAE,OAAO;AAAA,EAC9B,GAAG;AAAA,EACH,OAAO,SAAW,SAAS,EAAE,SAAS,EAAE,SAAS,YAAY;AAC/D,CAAC;AAED,IAAM,gBAAgB,eAAE,OAAO;AAAA,EAC7B,GAAG;AAAA,EACH,YAAY,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,aAAa;AAAA,EACxD,WAAW,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,gCAAgC;AAAA,EAC1E,UAAU,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,WAAW;AAAA,EAC3D,YAAY,QAAQ,eAAE,MAAM;AAAA,IAC1B,eAAE,OAAO;AAAA,IACT,eAAE,OAAO,EAAE,OAAO,eAAE,OAAO,OAAO,GAAG,MAAM,eAAE,KAAK,CAAC,UAAU,WAAW,MAAM,CAAC,EAAE,CAAC;AAAA,EACpF,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,iDAA4C;AAAA,EACpE,eAAe,QAAQ,eAAE,MAAM;AAAA,IAC7B,eAAE,OAAO;AAAA,IACT,eAAE,OAAO,EAAE,OAAO,eAAE,OAAO,OAAO,GAAG,MAAM,eAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,CAAC;AAAA,EAC5E,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,oDAA+C;AAAA,EACvE,UAAU,eAAE,KAAK,CAAC,YAAY,SAAS,SAAS,OAAO,CAAC,EAAE,SAAS;AAAA,EACnE,gBAAgB,eAAE,KAAK,CAAC,QAAQ,aAAa,eAAe,CAAC,EAAE,SAAS;AAC1E,CAAC;AAED,IAAM,kBAAkB,eAAE,OAAO;AAAA,EAC/B,GAAG;AAAA,EACH,SAAS,SAAS,eAAE,MAAQ,WAAW,CAAC,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAClF,CAAC;AAED,IAAM,eAAe,eAAE,OAAO;AAAA,EAC5B,GAAG;AAAA,EACH,OAAO,SAAW,SAAS,EAAE,SAAS;AAAA,EACtC,YAAY,eAAE,OAAO,EAAE,SAAS;AAAA,EAChC,WAAW,eAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,UAAU,eAAE,OAAO,OAAO,EAAE,SAAS;AAAA,EACrC,YAAY,QAAQ,eAAE,MAAM;AAAA,IAC1B,eAAE,OAAO;AAAA,IACT,eAAE,OAAO,EAAE,OAAO,eAAE,OAAO,OAAO,GAAG,MAAM,eAAE,KAAK,CAAC,UAAU,WAAW,MAAM,CAAC,EAAE,CAAC;AAAA,EACpF,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,eAAe,QAAQ,eAAE,MAAM;AAAA,IAC7B,eAAE,OAAO;AAAA,IACT,eAAE,OAAO,EAAE,OAAO,eAAE,OAAO,OAAO,GAAG,MAAM,eAAE,KAAK,CAAC,UAAU,SAAS,CAAC,EAAE,CAAC;AAAA,EAC5E,CAAC,CAAC,EAAE,SAAS;AAAA,EACb,UAAU,eAAE,KAAK,CAAC,YAAY,SAAS,SAAS,OAAO,CAAC,EAAE,SAAS;AAAA,EACnE,gBAAgB,eAAE,KAAK,CAAC,QAAQ,aAAa,eAAe,CAAC,EAAE,SAAS;AAAA,EACxE,SAAS,SAAS,eAAE,MAAQ,WAAW,CAAC,EAAE,SAAS;AACrD,CAAC;AAED,IAAM,gBAA8C;AAAA,EAClD,OAAO;AAAA,EAAgB,MAAM;AAAA,EAAe,QAAQ;AACtD;AACA,IAAM,gBAA8C;AAAA,EAClD,OAAO;AAAA,EAAgB,MAAM;AAAA,EAAe,QAAQ;AACtD;AAEO,IAAMC,UAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IAMF,QAAQ,CAACC,UAAS;AAAA,MAChB,CAAC,UAAU,OAAO,QAAQ,UAAU,QAAQ;AAAA,MAC5CA;AAAA,MACA;AAAA,QACE,MAAM,eAAE,KAAK,CAAC,SAAS,QAAQ,QAAQ,CAAC,EAAE,SAAS,EAChD,SAAS,+HAA+H;AAAA,QAC3I,OAAO,SAAS,eAAE,MAAM,eAAE,IAAI,CAAC,CAAC,EAAE,SAAS,EACxC,SAAS,kKAAkK;AAAA,QAC9K;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU,CAAC,WAAgB;AACzB,UAAI,OAAO,OAAO;AAChB,cAAM,MAAM,OAAO,WAAW,WAAW,gBAAgB;AACzD,cAAM,aAAc,OAAO,QAAQ,IAAI,OAAO,IAAI,KAAM;AACxD,eAAO,QAAQ,eAAE,MAAM,UAAU,EAAE,MAAM,OAAO,KAAK;AAAA,MACvD;AAAA,IACF;AAAA,EACF;AACF;;;AEzHA,IAAAC,eAAkB;AAOlB,IAAM,uBAAuB,eAAE,OAAO;AAAA,EACpC,MAAM,eAAE,OAAO,EAAE,SAAS,iBAAiB;AAC7C,CAAC;AAED,IAAM,cAAc,eAAE,OAAO;AAAA,EAC3B,cAAc,eAAE,OAAO,EAAE,SAAS,eAAe;AAAA,EACjD,MAAM,eAAE,OAAO,EAAE,SAAS,WAAW;AACvC,CAAC;AAED,IAAM,iBAAiB,eAAE,OAAO;AAAA,EAC9B,cAAc,eAAE,OAAO,EAAE,SAAS,eAAe;AAAA,EACjD,QAAQ,eAAE,OAAO,EAAE,SAAS,SAAS;AAAA,EACrC,MAAM,eAAE,OAAO,EAAE,SAAS,UAAU;AACtC,CAAC;AAED,IAAM,iBAAiB,eAAE,OAAO;AAAA,EAC9B,cAAc,eAAE,OAAO,EAAE,SAAS,eAAe;AAAA,EACjD,QAAQ,eAAE,OAAO,EAAE,SAAS,SAAS;AACvC,CAAC;AAED,IAAM,uBAAuB,eAAE,OAAO;AAAA,EACpC,IAAI,eAAE,OAAO,EAAE,SAAS,eAAe;AACzC,CAAC;AAED,IAAM,0BAAwD;AAAA,EAC5D,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,aAAa;AAAA,EACb,aAAa;AACf;AAEA,IAAM,qBAAqB,eAAE,OAAO;AAAA,EAClC,cAAc,eAAE,OAAO,EAAE,SAAS,wBAAwB;AAAA,EAC1D,MAAM,eAAE,OAAO,EAAE,SAAS,eAAe;AAAA,EACzC,cAAc,eAAE,KAAK,CAAC,SAAS,SAAS,UAAU,SAAS,CAAC,EAAE,SAAS,eAAe;AACxF,CAAC;AAED,IAAM,qBAAqB,eAAE,OAAO;AAAA,EAClC,IAAI,eAAE,OAAO,EAAE,SAAS,4CAA4C;AAAA,EACpE,QAAQ,eAAE,OAAO,EAAE,SAAS,SAAS;AAAA,EACrC,OAAO,SAAS,eAAE,MAAM;AAAA,IACtB,eAAE,OAAO;AAAA,IAAG,eAAE,QAAQ;AAAA,IAAK;AAAA,EAC7B,CAAC,CAAC,EAAE,SAAS,oEAAoE;AACnF,CAAC;AAED,IAAM,wBAAsD;AAAA,EAC1D,QAAQ;AAAA,EACR,QAAQ;AACV;AAEA,IAAM,cAAc,eAAE,OAAO;AAAA,EAC3B,QAAQ,eAAE,OAAO,EAAE,SAAS,SAAS;AAAA,EACrC,OAAO,eAAE,OAAO,EAAE,SAAS,mDAAmD;AAAA,EAC9E,YAAY,eAAE,OAAO,EAAE,SAAS,8EAA8E;AAChH,CAAC;AAED,IAAM,sBAAsB,eAAE,OAAO;AAAA,EACnC;AAAA,EACA,cAAc,eAAE,OAAO,EAAE,SAAS,wBAAwB;AAAA,EAC1D,QAAQ,eAAE,OAAO,EAAE,SAAS,iCAAiC;AAC/D,CAAC;AAED,IAAM,gBAA4C;AAAA,EAChD,UAAU;AAAA,EACV,aAAa;AAAA,EACb,aAAa;AACf;AAEO,IAAMC,UAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQF,QAAQ,CAACC,UAAS;AAAA,MAChB,CAAC,UAAU,OAAO,QAAQ,UAAU,YAAY,eAAe,aAAa;AAAA,MAC5EA;AAAA,MACA;AAAA,QACE,OAAO,SAAS,eAAE,MAAM,eAAE,IAAI,CAAC,CAAC,EAAE,SAAS,EACxC,SAAS,iKAAiK;AAAA,MAC/K;AAAA,MACA;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU,CAAC,WAAgB;AACzB,UAAI,OAAO,OAAO;AAChB,cAAM,SAAS,wBAAwB,OAAO,MAAM;AACpD,YAAI,OAAQ,QAAO,QAAQ,eAAE,MAAM,MAAM,EAAE,MAAM,OAAO,KAAK;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA;AAAA;AAAA;AAAA;AAAA,IAKF,QAAQ,CAACA,UAAS;AAAA,MAChB,CAAC,UAAU,OAAO,QAAQ,QAAQ;AAAA,MAClCA;AAAA,MACA;AAAA,QACE,OAAO,SAAS,eAAE,MAAM,eAAE,IAAI,CAAC,CAAC,EAAE,SAAS,EACxC,SAAS,8EAA8E;AAAA,QAC1F,MAAM,eAAE,KAAK,CAAC,SAAS,SAAS,UAAU,SAAS,CAAC,EAAE,SAAS,EAC5D,SAAS,+BAA+B;AAAA,QAC3C,cAAc,eAAE,OAAO,EAAE,SAAS,EAC/B,SAAS,+BAA+B;AAAA,MAC7C;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU,CAAC,WAAgB;AACzB,UAAI,OAAO,OAAO;AAChB,cAAM,SAAS,sBAAsB,OAAO,MAAM;AAClD,YAAI,OAAQ,QAAO,QAAQ,eAAE,MAAM,MAAM,EAAE,MAAM,OAAO,KAAK;AAAA,MAC/D;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,eAAE,MAAM,WAAW,CAAC,EAAE,SAAS,sCAAsC,EAAE;AAAA,IACjG,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO,SAAS,eAAE,MAAM,mBAAmB,CAAC,EAAE,SAAS,yCAAyC,EAAE;AAAA,IAC5G,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAiB;AAAA,IAC3B,MAAM;AAAA,EACR;AACF;;;ACvJA,IAAAC,eAAkB;AAMlB,IAAM,gBAAgB,eAAE,OAAO;AAAA,EAC7B,MAAM,eAAE,OAAO,EAAE,SAAS,gBAAgB;AAAA,EAC1C,GAAK;AAAA,EACL,GAAK;AAAA,EACL,OAAO,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,sBAAsB;AAAA,EACnE,QAAQ,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;AAAA,EACrE;AAAA,EACA,WAAW,SAAW,SAAS,EAAE,SAAS,EAAE,SAAS,+BAA+B;AAAA,EACpF,eAAe,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sDAAsD;AAAA,EACpG,gBAAgB,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,EACnF,aAAa,SAAW,SAAS,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,EAC1F,iBAAiB,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,qCAAqC;AAAA,EACrF,kBAAkB,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,sCAAsC;AAAA,EACvF,cAAc,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EAC3F,cAAc,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EAChF,YAAY,eAAE,KAAK,CAAC,QAAQ,cAAc,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAC7G,YAAY,eAAE,KAAK,CAAC,WAAW,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAC9F,YAAY,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,0BAA0B;AAAA,EAC5E,cAAc,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,4BAA4B;AAAA,EAChF,eAAe,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;AAAA,EAClF,aAAa,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,2BAA2B;AAAA,EAC9E,uBAAuB,eAAE,KAAK,CAAC,OAAO,OAAO,UAAU,eAAe,CAAC,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,EACpI,uBAAuB,eAAE,KAAK,CAAC,OAAO,OAAO,UAAU,UAAU,CAAC,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAAA,EAC/H,wBAAwB,eAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,oCAAoC;AAAA,EACjH,sBAAsB,eAAE,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,EAAE,SAAS,EAAE,SAAS,kCAAkC;AAAA,EAC7G,aAAa,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,uCAAuC;AAC5F,CAAC;AAED,IAAM,eAAe,eAAE,OAAO;AAAA,EAC5B;AAAA,EACA,YAAY,SAAS,eAAE,QAAQ,CAAC,EAAE,QAAQ,IAAI,EAAE,SAAS,yGAAyG;AACpK,CAAC;AAED,IAAM,cAAc,eAAE,OAAO;AAAA,EAC3B,cAAc,SAAS,eAAE,MAAM,eAAE,OAAO,CAAC,CAAC,EAAE,SAAS,kCAAkC;AAAA,EACvF,MAAM,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAC3F,CAAC;AAED,IAAM,sBAAsB,eAAE,OAAO;AAAA,EACnC,IAAI,eAAE,OAAO,EAAE,SAAS,mBAAmB;AAAA,EAC3C,cAAc,eAAE,OAAO,EAAE,SAAS,eAAe;AAAA,EACjD,MAAM,eAAE,KAAK,CAAC,WAAW,QAAQ,iBAAiB,SAAS,CAAC,EAAE,SAAS,eAAe;AAAA,EACtF,cAAc,SAAS,eAAE,MAAM,CAAC,eAAE,OAAO,GAAG,eAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,8DAA8D;AAAA,EAClI,iBAAiB,SAAS,eAAE,MAAM,eAAE,OAAO;AAAA,IACzC,MAAM,eAAE,KAAK,CAAC,aAAa,eAAe,CAAC;AAAA,IAC3C,KAAK,eAAE,OAAO;AAAA,EAChB,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,SAAS,yDAAyD;AACpF,CAAC;AAED,IAAM,yBAAuD;AAAA,EAC3D,WAAW;AAAA,EACX,WAAW;AAAA,EACX,aAAa;AACf;AAEA,IAAM,qBAAqB,eAAE,OAAO;AAAA,EAClC,aAAa,eAAE,OAAO,EAAE,SAAS,+BAA+B;AAAA,EAChE,mBAAmB,SAAS,eAAE,OAAO,eAAE,OAAO,GAAG,eAAE,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,yGAAyG;AAAA,EAC3L,GAAG,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,EAC5E,GAAG,eAAE,OAAO,OAAO,EAAE,SAAS,EAAE,SAAS,mCAAmC;AAAA,EAC5E;AACF,CAAC;AAED,IAAM,qBAAqB,eAAE,OAAO;AAAA,EAClC,IAAM;AAAA,EACN,YAAY,SAAS,eAAE,OAAO,eAAE,OAAO,GAAG,eAAE,MAAM,CAAC,eAAE,OAAO,GAAG,eAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,4DAAuD;AACjJ,CAAC;AAEM,IAAMC,UAAmB;AAAA,EAC9B;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQF,QAAQ,CAACC,UAAS;AAAA,MAChB,CAAC,UAAU,OAAO,QAAQ,QAAQ;AAAA,MAClCA;AAAA,MACA;AAAA,QACE,OAAO,SAAS,eAAE,MAAM,eAAE,IAAI,CAAC,CAAC,EAAE,SAAS,EACxC,SAAS,mMAAmM;AAAA,QAC/M,MAAM,eAAE,KAAK,CAAC,aAAa,aAAa,aAAa,CAAC,EAAE,SAAS,EAC9D,SAAS,oIAAoI;AAAA,QAChJ;AAAA,QACA,MAAM,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS,mDAAmD;AAAA,QACxF,UAAU,SAAS,eAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,iDAAiD;AAAA,MACvG;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU,CAAC,WAAgB;AACzB,UAAI,OAAO,OAAO;AAChB,YAAI,OAAO,WAAW,UAAU;AAC9B,gBAAM,SAAS,OAAO,QAAQ,uBAAuB,OAAO,IAAI;AAChE,cAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,4DAA4D;AACzF,iBAAO,QAAQ,eAAE,MAAM,MAAM,EAAE,MAAM,OAAO,KAAK;AAAA,QACnD,WAAW,OAAO,WAAW,UAAU;AACrC,iBAAO,QAAQ,eAAE,MAAM,mBAAmB,EAAE,MAAM,OAAO,KAAK;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA;AAAA;AAAA;AAAA,IAIF,QAAQ,CAACA,UAAS;AAAA,MAChB,CAAC,UAAU,OAAO,QAAQ;AAAA,MAC1BA;AAAA,MACA;AAAA,QACE,OAAO,SAAS,eAAE,MAAM,eAAE,IAAI,CAAC,CAAC,EAAE,SAAS,EACxC,SAAS,6FAA6F;AAAA,QACzG;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM;AAAA,IACN,UAAU,CAAC,WAAgB;AACzB,UAAI,OAAO,OAAO;AAChB,YAAI,OAAO,WAAW,UAAU;AAC9B,iBAAO,QAAQ,eAAE,MAAM,kBAAkB,EAAE,MAAM,OAAO,KAAK;AAAA,QAC/D,WAAW,OAAO,WAAW,UAAU;AACrC,iBAAO,QAAQ,eAAE,MAAM,kBAAkB,EAAE,MAAM,OAAO,KAAK;AAAA,QAC/D;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACzIO,SAAS,gBAAgBC,SAAmB;AACjD,EAAAA,QAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,gDAAgD;AAAA,IAC/D,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAmCR;AAAA,MACF,CAAC;AAAA,MACD,aAAa;AAAA,IACf;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,2CAA2C;AAAA,IAC1D,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMR;AAAA,MACF,CAAC;AAAA,MACD,aAAa;AAAA,IACf;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,0DAA0D;AAAA,IACzE,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAkHR;AAAA,MACF,CAAC;AAAA,MACD,aAAa;AAAA,IACf;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,qDAAqD;AAAA,IACpE,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAuBR;AAAA,MACF,CAAC;AAAA,MACD,aAAa;AAAA,IACf;AAAA,EACF;AAEA,EAAAA,QAAO;AAAA,IACL;AAAA,IACA,EAAE,aAAa,yDAAyD;AAAA,IACxE,OAAO;AAAA,MACL,UAAU,CAAC;AAAA,QACT,MAAM;AAAA,QACN,SAAS;AAAA,UACP,MAAM;AAAA,UACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QA0BR;AAAA,MACF,CAAC;AAAA,MACD,aAAa;AAAA,IACf;AAAA,EACF;AACF;;;AC/PO,IAAM,WAAW;AAAA,EACtB,GAAG;AAAA,EACH,GAAGC;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AAAA,EACH,GAAGA;AACL;AAGO,SAAS,iBAAiBC,SAAmB,aAA4BC,OAAoB;AAClG,gBAAcD,SAAQ,aAAaC,OAAM,QAAQ;AACjD,kBAAgBD,OAAM;AACxB;;;AtB3CA;AAaA,IAAI,gBAAgB;AACpB,IAAI;AAGF,QAAM,QAAQ,OAAO,aAAa,QAAQ,kBACtC,sBAAK,0BAAc,YAAY,GAAG,GAAG,IAAI,IACzC,OAAO,cAAc,cAAc,YAAY,QAAQ,IAAI;AAC/D,WAAS,MAAM,OAAO,QAAQ,KAAK,UAAM,kBAAK,KAAK,IAAI,GAAG;AACxD,QAAI;AACF,YAAM,MAAM,KAAK,UAAM,4BAAa,kBAAK,KAAK,cAAc,GAAG,MAAM,CAAC;AACtE,UAAI,IAAI,SAAS,gBAAgB;AAAE,wBAAgB,IAAI;AAAS;AAAA,MAAO;AAEvE,UAAI,IAAI,YAAY;AAClB,YAAI;AAAE,0BAAgB,KAAK,UAAM,4BAAa,kBAAK,KAAK,4BAA4B,GAAG,MAAM,CAAC,EAAE;AAAA,QAAS,QAAQ;AAAA,QAAC;AAClH;AAAA,MACF;AAAA,IACF,QAAQ;AAAE;AAAA,IAAU;AAAA,EACtB;AACF,QAAQ;AAAiB;AAGzB,IAAM,SAAS;AAAA,EACb,MAAM,CAAC,QAAgB,QAAQ,OAAO,MAAM,UAAU,GAAG;AAAA,CAAI;AAAA,EAC7D,OAAO,CAAC,QAAgB,QAAQ,OAAO,MAAM,WAAW,GAAG;AAAA,CAAI;AAAA,EAC/D,MAAM,CAAC,QAAgB,QAAQ,OAAO,MAAM,UAAU,GAAG;AAAA,CAAI;AAAA,EAC7D,OAAO,CAAC,QAAgB,QAAQ,OAAO,MAAM,WAAW,GAAG;AAAA,CAAI;AAAA,EAC/D,KAAK,CAAC,QAAgB,QAAQ,OAAO,MAAM,SAAS,GAAG;AAAA,CAAI;AAC7D;AA4BA,IAAI,KAAuB;AAC3B,IAAM,kBAAkB,oBAAI,IAQ1B;AACF,IAAI,iBAAgC;AACpC,IAAI,aAAqB,SAAS,QAAQ,IAAI,cAAc,MAAM;AAClE,IAAI,WAAW;AACf,IAAI,iBAAgC;AAGpC,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,YAAY,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AAC5D,IAAM,UAAU,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,CAAC;AACxD,IAAM,YAAY,YAAY,UAAU,MAAM,GAAG,EAAE,CAAC,IAAI;AACxD,IAAI,QAAS,cAAa,SAAS,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC;AACxD,IAAM,SAAS,cAAc,cAAc,QAAQ,SAAS,KAAK,SAAS,SAAS;AAGnF,IAAM,OAAO;AAAA,EACX,QAAQ,KAAK,SAAS,UAAU,KAAK,KAAK,SAAS,QAAQ;AAAA,EAC3D,MAAM,KAAK,SAAS,QAAQ;AAC9B;AAIA,SAAS,eAAe,OAAe,YAAY;AACjD,eAAa;AACb,MAAI,MAAM,GAAG,eAAe,UAAAE,QAAU,MAAM;AAC1C,WAAO,KAAK,4BAA4B;AACxC;AAAA,EACF;AAEA,QAAM,QAAQ,cAAc,cAAc,GAAG,MAAM,IAAI,IAAI,KAAK;AAChE,SAAO,KAAK,wCAAwC,KAAK,KAAK;AAC9D,OAAK,IAAI,UAAAA,QAAU,KAAK;AAExB,KAAG,GAAG,QAAQ,MAAM;AAClB,WAAO,KAAK,kCAAkC;AAC9C,qBAAiB;AAAA,EACnB,CAAC;AAED,KAAG,GAAG,WAAW,CAAC,SAAc;AAC9B,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,IAAI;AAG5B,UAAI,KAAK,SAAS,gBAAgB;AAChC,eAAO,KAAK,KAAK,OAAO;AACxB,YAAI,KAAK,MAAM,gBAAgB,IAAI,KAAK,EAAE,GAAG;AAC3C,gBAAM,MAAM,gBAAgB,IAAI,KAAK,EAAE;AACvC,uBAAa,IAAI,OAAO;AACxB,cAAI,QAAQ,EAAE,QAAQ,kBAAkB,SAAS,KAAK,QAAQ,CAAC;AAC/D,0BAAgB,OAAO,KAAK,EAAE;AAAA,QAChC;AACA;AAAA,MACF;AAIA,UAAI,KAAK,SAAS,YAAY,KAAK,MAAM;AACvC,YAAI,KAAK,SAAS,oBAAoB;AACpC,2BAAiB,KAAK;AACtB,iBAAO,KAAK,qBAAqB,KAAK,OAAO,EAAE;AAAA,QACjD;AACA;AAAA,MACF;AAGA,UAAI,KAAK,SAAS,SAAS;AACzB,eAAO,MAAM,gBAAgB,KAAK,OAAO,EAAE;AAC3C,YAAI,KAAK,SAAS,gBAAiB,YAAW;AAC9C,YAAI,KAAK,MAAM,gBAAgB,IAAI,KAAK,EAAE,GAAG;AAC3C,gBAAM,MAAM,gBAAgB,IAAI,KAAK,EAAE;AACvC,uBAAa,IAAI,OAAO;AACxB,cAAI,OAAO,IAAI,MAAM,KAAK,OAAO,CAAC;AAClC,0BAAgB,OAAO,KAAK,EAAE;AAAA,QAChC;AACA;AAAA,MACF;AAGA,UAAI,KAAK,SAAS,mBAAmB;AACnC,cAAM,eAAe,KAAK,QAAQ;AAClC,cAAM,YAAY,KAAK,MAAM;AAE7B,YAAI,aAAa,gBAAgB,IAAI,SAAS,GAAG;AAC/C,gBAAM,UAAU,gBAAgB,IAAI,SAAS;AAC7C,kBAAQ,eAAe,KAAK,IAAI;AAChC,uBAAa,QAAQ,OAAO;AAC5B,kBAAQ,UAAU,WAAW,MAAM;AACjC,gBAAI,gBAAgB,IAAI,SAAS,GAAG;AAClC,qBAAO,MAAM,WAAW,SAAS,gDAAgD;AACjF,8BAAgB,OAAO,SAAS;AAChC,sBAAQ,OAAO,IAAI,MAAM,4BAA4B,CAAC;AAAA,YACxD;AAAA,UACF,GAAG,GAAK;AACR,iBAAO,KAAK,uBAAuB,aAAa,WAAW,KAAK,aAAa,QAAQ,OAAO,aAAa,OAAO,EAAE;AAClH,cAAI,aAAa,WAAW,eAAe,aAAa,aAAa,KAAK;AACxE,mBAAO,KAAK,aAAa,aAAa,WAAW,sCAAsC;AAAA,UACzF;AAAA,QACF;AACA;AAAA,MACF;AAGA,YAAM,aAAa,KAAK;AACxB,aAAO,MAAM,qBAAqB,KAAK,UAAU,UAAU,CAAC,EAAE;AAE9D,UAAI,WAAW,MAAM,gBAAgB,IAAI,WAAW,EAAE,KAAK,WAAW,QAAQ;AAC5E,cAAM,UAAU,gBAAgB,IAAI,WAAW,EAAE;AACjD,qBAAa,QAAQ,OAAO;AAC5B,YAAI,WAAW,OAAO;AACpB,iBAAO,MAAM,qBAAqB,WAAW,KAAK,EAAE;AACpD,kBAAQ,OAAO,IAAI,MAAM,WAAW,KAAK,CAAC;AAAA,QAC5C,OAAO;AACL,kBAAQ,QAAQ,WAAW,MAAM;AAAA,QACnC;AACA,wBAAgB,OAAO,WAAW,EAAE;AAAA,MACtC,OAAO;AACL,eAAO,KAAK,+BAA+B,KAAK,UAAU,UAAU,CAAC,EAAE;AAAA,MACzE;AAAA,IACF,SAAS,OAAO;AACd,aAAO,MAAM,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,IACjG;AAAA,EACF,CAAC;AAED,KAAG,GAAG,SAAS,CAAC,UAAU;AACxB,WAAO,MAAM,iBAAiB,KAAK,EAAE;AAAA,EACvC,CAAC;AAED,KAAG,GAAG,SAAS,MAAM;AACnB,WAAO,KAAK,uCAAuC;AACnD,SAAK;AACL,eAAW,CAAC,IAAI,OAAO,KAAK,gBAAgB,QAAQ,GAAG;AACrD,mBAAa,QAAQ,OAAO;AAC5B,cAAQ,OAAO,IAAI,MAAM,mBAAmB,CAAC;AAC7C,sBAAgB,OAAO,EAAE;AAAA,IAC3B;AACA,QAAI,UAAU;AACZ,aAAO,KAAK,gFAA2E;AAAA,IACzF,OAAO;AACL,aAAO,KAAK,yCAAyC;AACrD,iBAAW,MAAM,eAAe,IAAI,GAAG,GAAI;AAAA,IAC7C;AAAA,EACF,CAAC;AACH;AAIA,eAAe,YAAY,aAAoC;AAC7D,aAAW;AACX,mBAAiB;AACjB,MAAI,CAAC,MAAM,GAAG,eAAe,UAAAA,QAAU,MAAM;AAC3C,mBAAe;AAEf,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AACxD,QAAI,CAAC,MAAM,GAAG,eAAe,UAAAA,QAAU,MAAM;AAC3C,YAAM,IAAI,MAAM,iEAAiE;AAAA,IACnF;AAAA,EACF;AACA,MAAI;AACF,UAAM,mBAAmB,QAAQ,EAAE,SAAS,YAAY,CAAC;AACzD,qBAAiB;AACjB,WAAO,KAAK,mBAAmB,WAAW,EAAE;AAAA,EAC9C,SAAS,OAAO;AACd,WAAO,MAAM,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAChG,UAAM;AAAA,EACR;AACF;AAIA,SAAS,mBACP,SACA,SAAkB,CAAC,GACnB,YAAoB,KACF;AAClB,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,QAAI,CAAC,MAAM,GAAG,eAAe,UAAAA,QAAU,MAAM;AAC3C,qBAAe;AACf,aAAO,IAAI,MAAM,kDAAkD,CAAC;AACpE;AAAA,IACF;AAEA,UAAM,kBAAkB,YAAY;AACpC,QAAI,mBAAmB,CAAC,gBAAgB;AACtC,aAAO,IAAI,MAAM,mGAAmG,CAAC;AACrH;AAAA,IACF;AAEA,UAAM,SAAK,YAAAC,IAAO;AAClB,UAAM,UAAU;AAAA,MACd;AAAA,MACA,MAAM,YAAY,SAAS,SAAS;AAAA,MACpC,GAAI,YAAY,SACZ,EAAE,SAAU,OAAe,SAAS,MAAM,OAAO,SAAS,eAAe,UAAM,sBAAS,QAAQ,IAAI,CAAC,EAAE,IACvG,EAAE,SAAS,eAAe;AAAA,MAC9B,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,UACN,GAAI;AAAA,UACJ,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAEA,UAAM,UAAU,WAAW,MAAM;AAC/B,UAAI,gBAAgB,IAAI,EAAE,GAAG;AAC3B,wBAAgB,OAAO,EAAE;AACzB,eAAO,MAAM,WAAW,EAAE,6BAA6B,YAAY,GAAI,UAAU;AACjF,eAAO,IAAI;AAAA,UACT,oHACqB,UAAU,cAAc,cAAc;AAAA,QAE7D,CAAC;AAAA,MACH;AAAA,IACF,GAAG,SAAS;AAEZ,oBAAgB,IAAI,IAAI,EAAE,SAAS,QAAQ,SAAS,cAAc,KAAK,IAAI,EAAE,CAAC;AAC9E,WAAO,KAAK,6BAA6B,OAAO,EAAE;AAClD,WAAO,MAAM,oBAAoB,KAAK,UAAU,OAAO,CAAC,EAAE;AAC1D,OAAG,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,EACjC,CAAC;AACH;AAIA,IAAM,SAAS,IAAI,qBAAU;AAAA,EAC3B,MAAM;AAAA,EACN,SAAS;AACX,CAAC;AAGD,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa,EAAE,SAAS,eAAE,OAAO,EAAE,SAAS,uFAAuF,EAAE,QAAQ,OAAO,EAAE;AAAA,EACxJ;AAAA,EACA,OAAO,EAAE,QAAQ,MAAW;AAC1B,QAAI;AACF,YAAM,YAAY,OAAO;AAEzB,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC3C,UAAI,MAAM,mBAAmB,OAAO,aAAa,UAAU;AAC3D,UAAI,eAAgB,QAAO;AAAA;AAAA,eAAU,cAAc;AAAA;AACnD,aAAO;AAAA,QACL,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,IAAI,CAAC;AAAA,MACvC;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,0BAA0B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,uBAAuB,UAAU;AAAA,QACzH,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,EACf;AAAA,EACA,YAAY;AACV,QAAI;AACF,YAAM,MAAM,cAAc,cACtB,oBAAoB,UAAU,cAC9B,WAAW,SAAS;AACxB,YAAM,WAAW,MAAM,MAAM,GAAG;AAChC,UAAI,CAAC,SAAS,IAAI;AAChB,eAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,kBAAkB,SAAS,MAAM,KAAK,MAAM,SAAS,KAAK,CAAC,GAAG,CAAC,EAAE;AAAA,MAC5G;AACA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM,MAAM,CAAC,EAAE,CAAC,EAAE;AAAA,IAC5E,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,iCAAiC,UAAU,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QAC9G,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAGA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,IACE,aAAa;AAAA,IACb,aAAa;AAAA,MACX,SAAS,eAAE,OAAO,EAAE,SAAS,wCAAwC,EAAE,QAAQ,OAAO;AAAA,IACxF;AAAA,EACF;AAAA,EACA,OAAO,EAAE,QAAQ,MAA2B;AAC1C,UAAM,gBAAgB,WAAW,kBAAkB;AACnD,QAAI;AAEF,YAAM,MAAM,cAAc,cACtB,oBAAoB,UAAU,aAAa,mBAAmB,aAAa,CAAC,KAC5E,WAAW,SAAS,aAAa,mBAAmB,aAAa,CAAC;AACtE,YAAM,MAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,SAAS,CAAC;AACjD,YAAM,OAAO,MAAM,IAAI,KAAK;AAG5B,iBAAW,CAAC,OAAO,OAAO,KAAK,gBAAgB,QAAQ,GAAG;AACxD,qBAAa,QAAQ,OAAO;AAC5B,gBAAQ,OAAO,IAAI,MAAM,sBAAsB,CAAC;AAChD,wBAAgB,OAAO,KAAK;AAAA,MAC9B;AAGA,UAAI,IAAI;AACN,cAAM,MAAM;AACZ,aAAK;AACL,YAAI,mBAAmB;AACvB,YAAI,MAAM,KAAM,cAAc;AAAA,MAChC;AACA,uBAAiB;AACjB,iBAAW;AAGX,qBAAe;AACf,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AACxD,YAAM,YAAY,MAAM,GAAG,eAAe,UAAAD,QAAU;AAEpD,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,YACF,iBAAiB,KAAK,OAAO,yBAAyB,UAAU;AAAA;AAAA,uMAChE,iBAAiB,KAAK,OAAO;AAAA;AAAA;AAAA,QACnC,CAAC;AAAA,MACH;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,SAAS,CAAC;AAAA,UACR,MAAM;AAAA,UACN,MAAM,2BAA2B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,QACzF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAGA,iBAAiB,QAAQ,oBAAoB,IAAI;AAIjD,SAAS,UAAU;AACjB,MAAI,MAAM,GAAG,eAAe,UAAAA,QAAU,MAAM;AAC1C,OAAG,MAAM,KAAM,0BAA0B;AAAA,EAC3C;AACF;AAEA,QAAQ,GAAG,UAAU,MAAM;AAAE,UAAQ;AAAG,UAAQ,KAAK,CAAC;AAAG,CAAC;AAC1D,QAAQ,GAAG,WAAW,MAAM;AAAE,UAAQ;AAAG,UAAQ,KAAK,CAAC;AAAG,CAAC;AAC3D,QAAQ,GAAG,QAAQ,OAAO;AAE1B,eAAe,OAAO;AACpB,MAAI;AACF,mBAAe;AAAA,EACjB,SAAS,OAAO;AACd,WAAO,KAAK,yCAAyC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAC7G,WAAO,KAAK,oDAAoD;AAAA,EAClE;AAEA,QAAM,YAAY,IAAI,kCAAqB;AAC3C,QAAM,OAAO,QAAQ,SAAS;AAC9B,SAAO,KAAK,kCAAkC;AAChD;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,SAAO,MAAM,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AACxG,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["import_zod","server","caps","tools","tools","import_zod","import_zod","tools","import_zod","tools","import_zod","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","tools","import_zod","import_zod","caps","tools","caps","import_zod","tools","caps","import_zod","tools","caps","server","tools","server","caps","WebSocket","uuidv4"]}
|