@better-fullstack/types 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["CATEGORY_ORDER: CompatibilityCategory[]","rustCategoryNames: Record<string, string>","pythonCategoryNames: Record<string, string>","goCategoryNames: Record<string, string>","notes: CompatibilityAnalysisResult[\"notes\"]","changes: CompatibilityAdjustment[]","WEB_FRAMEWORKS: readonly Frontend[]","UI_LIBRARY_COMPATIBILITY: Record<\n UILibrary,\n {\n frontends: readonly Frontend[];\n cssFrameworks: readonly CSSFramework[];\n }\n>","ADDON_COMPATIBILITY: Record<Addons, readonly Frontend[]>","base: API[]","all: Forms[]","issues: CompatibilityIssue[]","scalarChecks: Array<[CompatibilityCategory, string]>"],"sources":["../src/compatibility.ts"],"sourcesContent":["import type {\n Addons,\n API,\n AstroIntegration,\n Auth,\n Backend,\n CSSFramework,\n Forms,\n Frontend,\n Runtime,\n UILibrary,\n} from \"./types\";\n\nexport type CompatibilityCategory =\n | \"api\"\n | \"webFrontend\"\n | \"nativeFrontend\"\n | \"astroIntegration\"\n | \"runtime\"\n | \"backend\"\n | \"database\"\n | \"orm\"\n | \"dbSetup\"\n | \"webDeploy\"\n | \"serverDeploy\"\n | \"auth\"\n | \"payments\"\n | \"email\"\n | \"fileUpload\"\n | \"logging\"\n | \"observability\"\n | \"backendLibraries\"\n | \"stateManagement\"\n | \"forms\"\n | \"validation\"\n | \"testing\"\n | \"realtime\"\n | \"jobQueue\"\n | \"caching\"\n | \"search\"\n | \"fileStorage\"\n | \"animation\"\n | \"cssFramework\"\n | \"uiLibrary\"\n | \"cms\"\n | \"featureFlags\"\n | \"analytics\"\n | \"codeQuality\"\n | \"documentation\"\n | \"appPlatforms\"\n | \"packageManager\"\n | \"examples\"\n | \"ai\"\n | \"aiDocs\"\n | \"git\"\n | \"install\"\n | \"effect\"\n | \"rustWebFramework\"\n | \"rustFrontend\"\n | \"rustOrm\"\n | \"rustApi\"\n | \"rustCli\"\n | \"rustLibraries\"\n | \"pythonWebFramework\"\n | \"pythonOrm\"\n | \"pythonValidation\"\n | \"pythonAi\"\n | \"pythonTaskQueue\"\n | \"pythonQuality\"\n | \"goWebFramework\"\n | \"goOrm\"\n | \"goApi\"\n | \"goCli\"\n | \"goLogging\";\n\nexport type CompatibilityIssue = {\n code: string;\n message: string;\n category?: CompatibilityCategory;\n optionId?: string;\n};\n\nexport type CompatibilityEvaluation = {\n issues: CompatibilityIssue[];\n};\n\nexport type CompatibilityAdjustment = {\n category: string;\n message: string;\n};\n\nexport type CompatibilityInput = {\n ecosystem: \"typescript\" | \"rust\" | \"python\" | \"go\";\n projectName: string | null;\n webFrontend: string[];\n nativeFrontend: string[];\n astroIntegration: string;\n runtime: string;\n backend: string;\n database: string;\n orm: string;\n dbSetup: string;\n auth: string;\n payments: string;\n email: string;\n fileUpload: string;\n logging: string;\n observability: string;\n featureFlags: string;\n analytics: string;\n backendLibraries: string;\n stateManagement: string;\n forms: string;\n validation: string;\n testing: string;\n realtime: string;\n jobQueue: string;\n caching: string;\n animation: string;\n cssFramework: string;\n uiLibrary: string;\n cms: string;\n search: string;\n fileStorage: string;\n codeQuality: string[];\n documentation: string[];\n appPlatforms: string[];\n packageManager: string;\n examples: string[];\n aiSdk: string;\n aiDocs: string[];\n git: string;\n install: string;\n api: string;\n webDeploy: string;\n serverDeploy: string;\n yolo: string;\n rustWebFramework: string;\n rustFrontend: string;\n rustOrm: string;\n rustApi: string;\n rustCli: string;\n rustLibraries: string;\n pythonWebFramework: string;\n pythonOrm: string;\n pythonValidation: string;\n pythonAi: string;\n pythonTaskQueue: string;\n pythonQuality: string;\n goWebFramework: string;\n goOrm: string;\n goApi: string;\n goCli: string;\n goLogging: string;\n};\n\nconst TYPESCRIPT_CATEGORY_ORDER: CompatibilityCategory[] = [\n \"webFrontend\",\n \"nativeFrontend\",\n \"astroIntegration\",\n \"cssFramework\",\n \"uiLibrary\",\n \"backend\",\n \"backendLibraries\",\n \"runtime\",\n \"api\",\n \"database\",\n \"orm\",\n \"dbSetup\",\n \"webDeploy\",\n \"serverDeploy\",\n \"auth\",\n \"payments\",\n \"email\",\n \"fileUpload\",\n \"logging\",\n \"observability\",\n \"featureFlags\",\n \"analytics\",\n \"ai\",\n \"stateManagement\",\n \"forms\",\n \"validation\",\n \"testing\",\n \"realtime\",\n \"jobQueue\",\n \"caching\",\n \"search\",\n \"fileStorage\",\n \"animation\",\n \"cms\",\n \"codeQuality\",\n \"documentation\",\n \"appPlatforms\",\n \"packageManager\",\n \"examples\",\n \"aiDocs\",\n \"git\",\n \"install\",\n];\n\nconst CATEGORY_ORDER: CompatibilityCategory[] = [\n ...TYPESCRIPT_CATEGORY_ORDER,\n \"rustWebFramework\",\n \"rustFrontend\",\n \"rustOrm\",\n \"rustApi\",\n \"rustCli\",\n \"rustLibraries\",\n \"pythonWebFramework\",\n \"pythonOrm\",\n \"pythonValidation\",\n \"pythonAi\",\n \"pythonTaskQueue\",\n \"pythonQuality\",\n \"goWebFramework\",\n \"goOrm\",\n \"goApi\",\n \"goCli\",\n \"goLogging\",\n];\n\nconst DEFAULT_RUNTIME = \"bun\";\n\nexport function validateProjectName(name: string): string | undefined {\n const INVALID_CHARS = [\"<\", \">\", \":\", '\"', \"|\", \"?\", \"*\"];\n const MAX_LENGTH = 255;\n\n if (name === \".\") return undefined;\n\n if (!name) return \"Project name cannot be empty\";\n if (name.length > MAX_LENGTH) {\n return `Project name must be less than ${MAX_LENGTH} characters`;\n }\n if (INVALID_CHARS.some((char) => name.includes(char))) {\n return \"Project name contains invalid characters\";\n }\n if (name.startsWith(\".\") || name.startsWith(\"-\")) {\n return \"Project name cannot start with a dot or dash\";\n }\n if (name.toLowerCase() === \"node_modules\" || name.toLowerCase() === \"favicon.ico\") {\n return \"Project name is reserved\";\n }\n return undefined;\n}\n\nexport const hasPWACompatibleFrontend = (webFrontend: string[]) =>\n webFrontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"solid\", \"next\", \"astro\"].includes(f),\n );\n\nexport const hasTauriCompatibleFrontend = (webFrontend: string[]) =>\n webFrontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"nuxt\", \"svelte\", \"solid\", \"next\", \"astro\"].includes(f),\n );\n\nconst isChatSdkExampleSupported = (stack: CompatibilityInput): boolean => {\n if (stack.ecosystem !== \"typescript\") return false;\n\n if (stack.backend === \"self-next\" || stack.backend === \"self-tanstack-start\") {\n return true;\n }\n\n if (stack.backend === \"self-nuxt\") {\n return true;\n }\n\n if (stack.backend === \"hono\") {\n return stack.runtime === \"node\";\n }\n\n return false;\n};\n\nexport const requiresChatSdkVercelAI = (stack: CompatibilityInput): boolean => {\n return (\n stack.examples.includes(\"chat-sdk\") &&\n (stack.backend === \"self-nuxt\" || (stack.backend === \"hono\" && stack.runtime === \"node\"))\n );\n};\n\nexport const getCategoryDisplayName = (categoryKey: string): string => {\n // Custom display names for Rust categories\n const rustCategoryNames: Record<string, string> = {\n rustWebFramework: \"Rust Web Framework\",\n rustFrontend: \"Rust Frontend (WASM)\",\n rustOrm: \"Rust ORM / Database\",\n rustApi: \"Rust API Layer\",\n rustCli: \"Rust CLI Tools\",\n rustLibraries: \"Rust Core Libraries\",\n };\n\n // Custom display names for Python categories\n const pythonCategoryNames: Record<string, string> = {\n pythonWebFramework: \"Python Web Framework\",\n pythonOrm: \"Python ORM / Database\",\n pythonValidation: \"Python Validation\",\n pythonAi: \"Python AI / ML\",\n pythonTaskQueue: \"Python Task Queue\",\n pythonQuality: \"Python Code Quality\",\n };\n\n // Custom display names for Go categories\n const goCategoryNames: Record<string, string> = {\n goWebFramework: \"Go Web Framework\",\n goOrm: \"Go ORM / Database\",\n goApi: \"Go API Layer\",\n goCli: \"Go CLI Tools\",\n goLogging: \"Go Logging\",\n };\n\n if (rustCategoryNames[categoryKey]) {\n return rustCategoryNames[categoryKey];\n }\n\n if (pythonCategoryNames[categoryKey]) {\n return pythonCategoryNames[categoryKey];\n }\n\n if (goCategoryNames[categoryKey]) {\n return goCategoryNames[categoryKey];\n }\n\n const result = categoryKey.replace(/([A-Z])/g, \" $1\");\n return result.charAt(0).toUpperCase() + result.slice(1);\n};\n\nexport type CompatibilityAnalysisResult = {\n adjustedStack: CompatibilityInput | null;\n notes: Record<string, { notes: string[]; hasIssue: boolean }>;\n changes: CompatibilityAdjustment[];\n};\n\n/**\n * Analyzes the stack and auto-adjusts incompatible selections.\n * This follows the CLI approach: when you make a selection, dependent items adjust automatically.\n * The flow is: frontend -> backend -> runtime -> database -> orm -> api -> auth -> etc.\n */\nexport const analyzeStackCompatibility = (\n stack: CompatibilityInput,\n): CompatibilityAnalysisResult => {\n // Skip all validation if YOLO mode is enabled\n if (stack.yolo === \"true\") {\n return {\n adjustedStack: null,\n notes: {},\n changes: [],\n };\n }\n\n const nextStack = { ...stack };\n let changed = false;\n const notes: CompatibilityAnalysisResult[\"notes\"] = {};\n const changes: CompatibilityAdjustment[] = [];\n\n for (const cat of CATEGORY_ORDER) {\n notes[cat] = { notes: [], hasIssue: false };\n }\n\n // ============================================\n // BACKEND CONSTRAINTS\n // ============================================\n\n if (nextStack.backend === \"convex\") {\n // Convex handles its own runtime, database, orm, api, dbSetup\n const convexOverrides: Partial<CompatibilityInput> = {\n runtime: \"none\",\n database: \"none\",\n orm: \"none\",\n api: \"none\",\n dbSetup: \"none\",\n serverDeploy: \"none\",\n search: \"none\",\n fileStorage: \"none\",\n };\n\n for (const [key, value] of Object.entries(convexOverrides)) {\n const catKey = key as keyof CompatibilityInput;\n if (nextStack[catKey] !== value) {\n nextStack[catKey] = value as never;\n changed = true;\n changes.push({\n category: \"backend\",\n message: `${getCategoryDisplayName(catKey)} set to '${value}' (Convex provides this)`,\n });\n }\n }\n\n // Remove incompatible frontends\n if (nextStack.webFrontend.includes(\"solid\")) {\n nextStack.webFrontend = nextStack.webFrontend.filter((f) => f !== \"solid\");\n if (nextStack.webFrontend.length === 0) nextStack.webFrontend = [\"none\"];\n changed = true;\n changes.push({ category: \"backend\", message: \"Removed Solid (incompatible with Convex)\" });\n }\n if (nextStack.webFrontend.includes(\"solid-start\")) {\n nextStack.webFrontend = nextStack.webFrontend.filter((f) => f !== \"solid-start\");\n if (nextStack.webFrontend.length === 0) nextStack.webFrontend = [\"none\"];\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Removed SolidStart (incompatible with Convex)\",\n });\n }\n if (nextStack.webFrontend.includes(\"astro\")) {\n nextStack.webFrontend = nextStack.webFrontend.filter((f) => f !== \"astro\");\n if (nextStack.webFrontend.length === 0) nextStack.webFrontend = [\"none\"];\n nextStack.astroIntegration = \"none\";\n changed = true;\n changes.push({ category: \"backend\", message: \"Removed Astro (incompatible with Convex)\" });\n }\n\n // Remove AI example if incompatible frontends are selected (Convex AI only supports React-based frontends)\n if (nextStack.examples.includes(\"ai\")) {\n const hasIncompatibleFrontend = nextStack.webFrontend.some((f) =>\n [\"solid\", \"svelte\", \"nuxt\"].includes(f),\n );\n if (hasIncompatibleFrontend) {\n nextStack.examples = nextStack.examples.filter((e) => e !== \"ai\");\n if (nextStack.examples.length === 0) nextStack.examples = [\"none\"];\n changed = true;\n changes.push({\n category: \"examples\",\n message: \"AI example removed (Convex AI only supports React-based frontends)\",\n });\n }\n }\n\n // Auth constraints for Convex\n if (nextStack.auth === \"clerk\") {\n const hasClerkCompatible =\n nextStack.webFrontend.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"].includes(f),\n ) ||\n nextStack.nativeFrontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n if (!hasClerkCompatible) {\n nextStack.auth = \"none\";\n changed = true;\n changes.push({\n category: \"auth\",\n message: \"Auth set to 'None' (Clerk requires compatible frontend)\",\n });\n }\n }\n\n if (nextStack.auth === \"better-auth\") {\n const hasBetterAuthCompatible =\n nextStack.webFrontend.some((f) =>\n [\"tanstack-router\", \"tanstack-start\", \"next\"].includes(f),\n ) ||\n nextStack.nativeFrontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n if (!hasBetterAuthCompatible) {\n nextStack.auth = \"none\";\n changed = true;\n changes.push({\n category: \"auth\",\n message: \"Auth set to 'None' (Better-Auth with Convex requires compatible frontend)\",\n });\n }\n }\n }\n\n if (nextStack.backend === \"none\") {\n // No backend means no runtime, database, orm, api, auth, dbSetup, serverDeploy\n const noneOverrides: Partial<CompatibilityInput> = {\n runtime: \"none\",\n database: \"none\",\n orm: \"none\",\n api: \"none\",\n auth: \"none\",\n dbSetup: \"none\",\n serverDeploy: \"none\",\n payments: \"none\",\n search: \"none\",\n fileStorage: \"none\",\n };\n\n for (const [key, value] of Object.entries(noneOverrides)) {\n const catKey = key as keyof CompatibilityInput;\n if (nextStack[catKey] !== value) {\n nextStack[catKey] = value as never;\n changed = true;\n changes.push({\n category: \"backend\",\n message: `${getCategoryDisplayName(catKey)} set to '${value}' (no backend)`,\n });\n }\n }\n\n // Clear examples\n if (\n nextStack.examples.length > 0 &&\n !(nextStack.examples.length === 1 && nextStack.examples[0] === \"none\")\n ) {\n nextStack.examples = [\"none\"];\n changed = true;\n changes.push({ category: \"backend\", message: \"Examples cleared (no backend)\" });\n }\n }\n\n // Self (fullstack) backend constraints\n if (\n nextStack.backend === \"self-next\" ||\n nextStack.backend === \"self-tanstack-start\" ||\n nextStack.backend === \"self-astro\" ||\n nextStack.backend === \"self-nuxt\" ||\n nextStack.backend === \"self-svelte\" ||\n nextStack.backend === \"self-solid-start\"\n ) {\n // Fullstack uses frontend's API routes, no separate runtime needed\n if (nextStack.runtime !== \"none\") {\n nextStack.runtime = \"none\";\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Runtime set to 'None' (fullstack uses frontend's API routes)\",\n });\n }\n if (nextStack.serverDeploy !== \"none\") {\n nextStack.serverDeploy = \"none\";\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Server deploy set to 'None' (fullstack uses frontend deployment)\",\n });\n }\n\n // Ensure correct frontend is selected\n if (nextStack.backend === \"self-next\" && !nextStack.webFrontend.includes(\"next\")) {\n nextStack.webFrontend = [\"next\"];\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Frontend set to 'Next.js' (required for Next.js fullstack)\",\n });\n }\n if (\n nextStack.backend === \"self-tanstack-start\" &&\n !nextStack.webFrontend.includes(\"tanstack-start\")\n ) {\n nextStack.webFrontend = [\"tanstack-start\"];\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Frontend set to 'TanStack Start' (required for TanStack Start fullstack)\",\n });\n }\n if (nextStack.backend === \"self-astro\" && !nextStack.webFrontend.includes(\"astro\")) {\n nextStack.webFrontend = [\"astro\"];\n if (nextStack.astroIntegration === \"none\") {\n nextStack.astroIntegration = \"react\";\n }\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Frontend set to 'Astro' (required for Astro fullstack)\",\n });\n }\n if (nextStack.backend === \"self-nuxt\" && !nextStack.webFrontend.includes(\"nuxt\")) {\n nextStack.webFrontend = [\"nuxt\"];\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Frontend set to 'Nuxt' (required for Nuxt fullstack)\",\n });\n }\n if (nextStack.backend === \"self-svelte\" && !nextStack.webFrontend.includes(\"svelte\")) {\n nextStack.webFrontend = [\"svelte\"];\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Frontend set to 'SvelteKit' (required for SvelteKit fullstack)\",\n });\n }\n if (\n nextStack.backend === \"self-solid-start\" &&\n !nextStack.webFrontend.includes(\"solid-start\")\n ) {\n nextStack.webFrontend = [\"solid-start\"];\n changed = true;\n changes.push({\n category: \"backend\",\n message: \"Frontend set to 'SolidStart' (required for SolidStart fullstack)\",\n });\n }\n }\n\n // ============================================\n // RUNTIME CONSTRAINTS\n // ============================================\n\n // Workers runtime requires Hono backend\n if (nextStack.runtime === \"workers\" && nextStack.backend !== \"hono\") {\n nextStack.backend = \"hono\";\n changed = true;\n changes.push({ category: \"runtime\", message: \"Backend set to 'Hono' (required for Workers)\" });\n }\n\n // Workers runtime requires server deployment\n if (nextStack.runtime === \"workers\" && nextStack.serverDeploy === \"none\") {\n nextStack.serverDeploy = \"cloudflare\";\n changed = true;\n changes.push({\n category: \"runtime\",\n message: \"Server deploy set to 'Cloudflare' (required for Workers)\",\n });\n }\n\n // Workers runtime is incompatible with MongoDB\n if (nextStack.runtime === \"workers\" && nextStack.database === \"mongodb\") {\n nextStack.database = \"sqlite\";\n nextStack.orm = \"drizzle\";\n nextStack.dbSetup = \"d1\";\n changed = true;\n changes.push({\n category: \"runtime\",\n message:\n \"Database changed to SQLite with D1 (Better-Fullstack doesn't support MongoDB with Workers)\",\n });\n }\n\n // Runtime \"none\" only for convex and fullstack backends\n if (\n nextStack.runtime === \"none\" &&\n nextStack.backend !== \"convex\" &&\n nextStack.backend !== \"none\" &&\n nextStack.backend !== \"self-next\" &&\n nextStack.backend !== \"self-tanstack-start\" &&\n nextStack.backend !== \"self-astro\" &&\n nextStack.backend !== \"self-nuxt\" &&\n nextStack.backend !== \"self-svelte\" &&\n nextStack.backend !== \"self-solid-start\"\n ) {\n nextStack.runtime = DEFAULT_RUNTIME;\n changed = true;\n changes.push({\n category: \"runtime\",\n message: `Runtime set to '${DEFAULT_RUNTIME}' (required for this backend)`,\n });\n }\n\n // ============================================\n // DATABASE & ORM CONSTRAINTS (CLI-like flow)\n // ============================================\n\n // Skip if backend doesn't use database\n if (nextStack.backend !== \"convex\" && nextStack.backend !== \"none\") {\n // If database is none, ORM and dbSetup must be none\n if (nextStack.database === \"none\") {\n if (nextStack.orm !== \"none\") {\n nextStack.orm = \"none\";\n changed = true;\n changes.push({ category: \"database\", message: \"ORM set to 'None' (no database selected)\" });\n }\n if (nextStack.dbSetup !== \"none\") {\n nextStack.dbSetup = \"none\";\n changed = true;\n changes.push({\n category: \"database\",\n message: \"DB Setup set to 'None' (no database selected)\",\n });\n }\n }\n\n // MongoDB requires Prisma or Mongoose\n if (nextStack.database === \"mongodb\") {\n if (nextStack.orm !== \"prisma\" && nextStack.orm !== \"mongoose\") {\n nextStack.orm = \"prisma\";\n changed = true;\n changes.push({\n category: \"database\",\n message: \"ORM set to 'Prisma' (required for MongoDB)\",\n });\n }\n // MongoDB only works with mongodb-atlas or none for dbSetup\n if (\n nextStack.dbSetup !== \"mongodb-atlas\" &&\n nextStack.dbSetup !== \"none\" &&\n nextStack.dbSetup !== \"docker\"\n ) {\n nextStack.dbSetup = \"none\";\n changed = true;\n changes.push({\n category: \"database\",\n message: \"DB Setup set to 'None' (incompatible with MongoDB)\",\n });\n }\n }\n\n // Relational databases (sqlite, postgres, mysql) need Drizzle or Prisma\n if ([\"sqlite\", \"postgres\", \"mysql\"].includes(nextStack.database)) {\n if (nextStack.orm === \"none\") {\n nextStack.orm = \"drizzle\";\n changed = true;\n changes.push({\n category: \"database\",\n message: \"ORM set to 'Drizzle' (required for database)\",\n });\n }\n if (nextStack.orm === \"mongoose\") {\n nextStack.orm = \"drizzle\";\n changed = true;\n changes.push({\n category: \"database\",\n message: \"ORM set to 'Drizzle' (Mongoose only works with MongoDB)\",\n });\n }\n }\n\n // ORM selected but no database - select appropriate database\n if (nextStack.orm !== \"none\" && nextStack.database === \"none\") {\n if (nextStack.orm === \"mongoose\") {\n nextStack.database = \"mongodb\";\n changed = true;\n changes.push({\n category: \"orm\",\n message: \"Database set to 'MongoDB' (required for Mongoose)\",\n });\n } else {\n nextStack.database = \"sqlite\";\n changed = true;\n changes.push({ category: \"orm\", message: \"Database set to 'SQLite' (required for ORM)\" });\n }\n }\n\n // DB Setup constraints\n if (nextStack.dbSetup === \"turso\" && nextStack.database !== \"sqlite\") {\n nextStack.database = \"sqlite\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Database set to 'SQLite' (required for Turso)\",\n });\n }\n if (nextStack.dbSetup === \"d1\") {\n if (nextStack.database !== \"sqlite\") {\n nextStack.database = \"sqlite\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Database set to 'SQLite' (required for D1)\",\n });\n }\n if (nextStack.runtime !== \"workers\") {\n nextStack.runtime = \"workers\";\n nextStack.backend = \"hono\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Runtime set to 'Workers' with 'Hono' (required for D1)\",\n });\n }\n }\n if (nextStack.dbSetup === \"neon\" && nextStack.database !== \"postgres\") {\n nextStack.database = \"postgres\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Database set to 'PostgreSQL' (required for Neon)\",\n });\n }\n if (nextStack.dbSetup === \"supabase\" && nextStack.database !== \"postgres\") {\n nextStack.database = \"postgres\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Database set to 'PostgreSQL' (required for Supabase)\",\n });\n }\n if (nextStack.dbSetup === \"prisma-postgres\" && nextStack.database !== \"postgres\") {\n nextStack.database = \"postgres\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Database set to 'PostgreSQL' (required for Prisma Postgres)\",\n });\n }\n if (nextStack.dbSetup === \"mongodb-atlas\" && nextStack.database !== \"mongodb\") {\n nextStack.database = \"mongodb\";\n if (nextStack.orm !== \"prisma\" && nextStack.orm !== \"mongoose\") {\n nextStack.orm = \"prisma\";\n }\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Database set to 'MongoDB' (required for MongoDB Atlas)\",\n });\n }\n if (\n nextStack.dbSetup === \"planetscale\" &&\n nextStack.database !== \"postgres\" &&\n nextStack.database !== \"mysql\"\n ) {\n nextStack.database = \"postgres\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"Database set to 'PostgreSQL' (required for PlanetScale)\",\n });\n }\n if (nextStack.dbSetup === \"docker\") {\n if (nextStack.database === \"sqlite\") {\n nextStack.dbSetup = \"none\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message: \"DB Setup set to 'None' (SQLite doesn't need Docker)\",\n });\n }\n if (nextStack.runtime === \"workers\") {\n nextStack.dbSetup = \"d1\";\n changed = true;\n changes.push({\n category: \"dbSetup\",\n message:\n \"DB Setup set to 'D1' (Better-Fullstack doesn't support Docker setup with Workers)\",\n });\n }\n }\n }\n\n // ============================================\n // API CONSTRAINTS\n // ============================================\n\n if (nextStack.backend !== \"convex\" && nextStack.backend !== \"none\") {\n // Nuxt, Svelte, Solid, SolidStart require oRPC (not tRPC)\n const needsOrpc = nextStack.webFrontend.some((f) =>\n [\"nuxt\", \"svelte\", \"solid\", \"solid-start\"].includes(f),\n );\n if (needsOrpc && nextStack.api === \"trpc\") {\n nextStack.api = \"orpc\";\n changed = true;\n changes.push({ category: \"api\", message: \"API set to 'oRPC' (required for this frontend)\" });\n }\n\n // Astro with non-React integration requires oRPC\n if (\n nextStack.webFrontend.includes(\"astro\") &&\n nextStack.astroIntegration !== \"react\" &&\n nextStack.api === \"trpc\"\n ) {\n nextStack.api = \"orpc\";\n changed = true;\n changes.push({\n category: \"api\",\n message: \"API set to 'oRPC' (tRPC requires React integration with Astro)\",\n });\n }\n }\n\n // ============================================\n // ASTRO INTEGRATION CONSTRAINTS\n // ============================================\n\n // If Astro is not selected, reset astroIntegration\n if (!nextStack.webFrontend.includes(\"astro\") && nextStack.astroIntegration !== \"none\") {\n nextStack.astroIntegration = \"none\";\n changed = true;\n changes.push({\n category: \"astroIntegration\",\n message: \"Astro integration reset (Astro not selected)\",\n });\n }\n\n // If Astro is selected but no integration is set, default to react\n if (nextStack.webFrontend.includes(\"astro\") && nextStack.astroIntegration === \"none\") {\n // Only set default if api is trpc (which requires react)\n if (nextStack.api === \"trpc\") {\n nextStack.astroIntegration = \"react\";\n changed = true;\n changes.push({\n category: \"astroIntegration\",\n message: \"Astro integration set to 'React' (required for tRPC)\",\n });\n }\n }\n\n // ============================================\n // AUTH CONSTRAINTS\n // ============================================\n\n if (nextStack.auth === \"clerk\") {\n const supportsClerkBackend =\n nextStack.backend === \"convex\" ||\n nextStack.backend === \"self-next\" ||\n nextStack.backend === \"self-tanstack-start\";\n\n if (!supportsClerkBackend) {\n nextStack.auth = \"none\";\n changed = true;\n changes.push({\n category: \"auth\",\n message:\n \"Auth set to 'None' (Better-Fullstack currently supports Clerk with Convex, Next.js fullstack, or TanStack Start fullstack)\",\n });\n } else if (\n (nextStack.backend === \"self-next\" || nextStack.backend === \"self-tanstack-start\") &&\n nextStack.nativeFrontend.some((f) => f !== \"none\")\n ) {\n nextStack.auth = \"none\";\n changed = true;\n changes.push({\n category: \"auth\",\n message:\n \"Auth set to 'None' (Better-Fullstack currently supports Clerk with self backend only for web-only Next.js/TanStack Start projects)\",\n });\n }\n }\n\n // ============================================\n // PAYMENTS CONSTRAINTS\n // ============================================\n\n if (nextStack.payments === \"polar\") {\n if (nextStack.auth !== \"better-auth\") {\n nextStack.payments = \"none\";\n changed = true;\n changes.push({\n category: \"payments\",\n message: \"Payments set to 'None' (Polar requires Better Auth)\",\n });\n }\n if (nextStack.backend === \"convex\") {\n nextStack.payments = \"none\";\n changed = true;\n changes.push({\n category: \"payments\",\n message: \"Payments set to 'None' (Polar incompatible with Convex)\",\n });\n }\n const hasWebFrontend = nextStack.webFrontend.some((f) => f !== \"none\");\n if (!hasWebFrontend) {\n nextStack.payments = \"none\";\n changed = true;\n changes.push({\n category: \"payments\",\n message: \"Payments set to 'None' (Polar requires web frontend)\",\n });\n }\n }\n\n // ============================================\n // EMAIL CONSTRAINTS\n // ============================================\n\n if (nextStack.email !== \"none\") {\n if (nextStack.backend === \"convex\") {\n nextStack.email = \"none\";\n changed = true;\n changes.push({\n category: \"email\",\n message: \"Email set to 'None' (incompatible with Convex)\",\n });\n }\n if (nextStack.backend === \"none\") {\n nextStack.email = \"none\";\n changed = true;\n changes.push({\n category: \"email\",\n message: \"Email set to 'None' (requires backend)\",\n });\n }\n }\n\n // ============================================\n // CSS FRAMEWORK & UI LIBRARY CONSTRAINTS\n // ============================================\n\n // If no web frontend, reset CSS framework and UI library to none\n if (!nextStack.webFrontend.some((f) => f !== \"none\")) {\n if (nextStack.cssFramework !== \"none\") {\n nextStack.cssFramework = \"none\";\n changed = true;\n changes.push({\n category: \"cssFramework\",\n message: \"CSS framework set to 'None' (no web frontend)\",\n });\n }\n if (nextStack.uiLibrary !== \"none\") {\n nextStack.uiLibrary = \"none\";\n changed = true;\n changes.push({\n category: \"uiLibrary\",\n message: \"UI library set to 'None' (no web frontend)\",\n });\n }\n }\n\n // UI libraries requiring Tailwind - auto-adjust CSS framework or clear UI library\n const requiresTailwind = [\"shadcn-ui\", \"daisyui\", \"nextui\"].includes(nextStack.uiLibrary);\n if (requiresTailwind && nextStack.cssFramework !== \"tailwind\") {\n // Auto-set Tailwind when selecting a Tailwind-dependent UI library\n nextStack.cssFramework = \"tailwind\";\n changed = true;\n changes.push({\n category: \"cssFramework\",\n message: `CSS framework set to 'Tailwind' (required by ${nextStack.uiLibrary})`,\n });\n }\n\n // React-only UI libraries - check frontend compatibility\n const reactOnlyLibraries = [\"shadcn-ui\", \"radix-ui\", \"chakra-ui\", \"nextui\"];\n const reactFrontends = [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"];\n if (reactOnlyLibraries.includes(nextStack.uiLibrary)) {\n const hasReactFrontend = nextStack.webFrontend.some((f) => reactFrontends.includes(f));\n const hasAstroReact =\n nextStack.webFrontend.includes(\"astro\") && nextStack.astroIntegration === \"react\";\n if (!hasReactFrontend && !hasAstroReact && nextStack.webFrontend.some((f) => f !== \"none\")) {\n // Reset to a compatible UI library (daisyui works with all frontends)\n nextStack.uiLibrary = \"daisyui\";\n changed = true;\n changes.push({\n category: \"uiLibrary\",\n message:\n \"UI library changed to 'daisyUI' (React-only library incompatible with this frontend)\",\n });\n }\n }\n\n // Headless UI requires React or Vue\n if (nextStack.uiLibrary === \"headless-ui\") {\n const hasReactFrontend = nextStack.webFrontend.some((f) => reactFrontends.includes(f));\n const hasVueFrontend = nextStack.webFrontend.includes(\"nuxt\");\n const hasAstroReactOrVue =\n nextStack.webFrontend.includes(\"astro\") &&\n [\"react\", \"vue\"].includes(nextStack.astroIntegration);\n if (!hasReactFrontend && !hasVueFrontend && !hasAstroReactOrVue) {\n nextStack.uiLibrary = \"daisyui\";\n changed = true;\n changes.push({\n category: \"uiLibrary\",\n message: \"UI library changed to 'daisyUI' (Headless UI requires React or Vue)\",\n });\n }\n }\n\n // Park UI requires React, Vue, or Solid\n if (nextStack.uiLibrary === \"park-ui\") {\n const hasReactFrontend = nextStack.webFrontend.some((f) => reactFrontends.includes(f));\n const hasVueFrontend = nextStack.webFrontend.includes(\"nuxt\");\n const hasSolidFrontend = nextStack.webFrontend.includes(\"solid\");\n const hasAstroCompatible =\n nextStack.webFrontend.includes(\"astro\") &&\n [\"react\", \"vue\", \"solid\"].includes(nextStack.astroIntegration);\n if (\n !hasReactFrontend &&\n !hasVueFrontend &&\n !hasSolidFrontend &&\n !hasAstroCompatible &&\n nextStack.webFrontend.some((f) => f !== \"none\")\n ) {\n nextStack.uiLibrary = \"daisyui\";\n changed = true;\n changes.push({\n category: \"uiLibrary\",\n message: \"UI library changed to 'daisyUI' (Park UI requires React, Vue, or Solid)\",\n });\n }\n }\n\n // ============================================\n // APP PLATFORMS CONSTRAINTS\n // ============================================\n\n const pwaCompat = hasPWACompatibleFrontend(nextStack.webFrontend);\n const tauriCompat = hasTauriCompatibleFrontend(nextStack.webFrontend);\n\n if (!pwaCompat && nextStack.appPlatforms.includes(\"pwa\")) {\n nextStack.appPlatforms = nextStack.appPlatforms.filter((a) => a !== \"pwa\");\n changed = true;\n changes.push({\n category: \"appPlatforms\",\n message: \"PWA removed (requires compatible frontend)\",\n });\n }\n if (!tauriCompat && nextStack.appPlatforms.includes(\"tauri\")) {\n nextStack.appPlatforms = nextStack.appPlatforms.filter((a) => a !== \"tauri\");\n changed = true;\n changes.push({\n category: \"appPlatforms\",\n message: \"Tauri removed (requires compatible frontend)\",\n });\n }\n\n // ============================================\n // EXAMPLES CONSTRAINTS\n // ============================================\n\n // AI example constraints\n if (nextStack.examples.includes(\"ai\")) {\n // Solid/SolidStart frontend is incompatible with AI example\n if (nextStack.webFrontend.includes(\"solid\") || nextStack.webFrontend.includes(\"solid-start\")) {\n nextStack.examples = nextStack.examples.filter((e) => e !== \"ai\");\n if (nextStack.examples.length === 0) nextStack.examples = [\"none\"];\n changed = true;\n changes.push({\n category: \"examples\",\n message: \"AI removed (not compatible with Solid frontend)\",\n });\n }\n // Convex AI only supports React-based frontends (not Svelte/Nuxt)\n if (nextStack.backend === \"convex\") {\n const hasIncompatibleFrontend = nextStack.webFrontend.some((f) =>\n [\"svelte\", \"nuxt\"].includes(f),\n );\n if (hasIncompatibleFrontend) {\n nextStack.examples = nextStack.examples.filter((e) => e !== \"ai\");\n if (nextStack.examples.length === 0) nextStack.examples = [\"none\"];\n changed = true;\n changes.push({\n category: \"examples\",\n message: \"AI removed (Convex AI only supports React-based frontends)\",\n });\n }\n }\n }\n\n // Chat SDK example constraints (framework-specific profiles in v1)\n if (nextStack.examples.includes(\"chat-sdk\")) {\n if (!isChatSdkExampleSupported(nextStack)) {\n nextStack.examples = nextStack.examples.filter((e) => e !== \"chat-sdk\");\n if (nextStack.examples.length === 0) nextStack.examples = [\"none\"];\n changed = true;\n\n let reason = \"unsupported stack\";\n if (nextStack.ecosystem !== \"typescript\") {\n reason = \"TypeScript ecosystem only\";\n } else if (nextStack.backend === \"convex\") {\n reason = \"Convex backend not supported in v1\";\n } else if (nextStack.backend === \"none\") {\n reason = \"requires a backend\";\n } else if (nextStack.backend === \"hono\" && nextStack.runtime !== \"node\") {\n reason = \"Hono profile requires Node runtime\";\n } else if (nextStack.backend.startsWith(\"self-\")) {\n reason = \"self backend only supports Next.js, TanStack Start, or Nuxt in v1\";\n }\n\n changes.push({\n category: \"examples\",\n message: `Chat SDK removed (${reason})`,\n });\n } else if (requiresChatSdkVercelAI(nextStack) && nextStack.aiSdk !== \"vercel-ai\") {\n nextStack.aiSdk = \"vercel-ai\";\n changed = true;\n changes.push({\n category: \"ai\",\n message: \"AI SDK set to 'Vercel AI SDK' (required by Chat SDK Nuxt/Hono profile in v1)\",\n });\n }\n }\n\n // ============================================\n // FRESH FRONTEND CONSTRAINTS\n // Fresh is Preact-based and incompatible with React-specific packages\n // ============================================\n\n const isFresh = nextStack.webFrontend.includes(\"fresh\");\n\n if (isFresh) {\n // TanStack Form has no Preact adapter\n if (nextStack.forms === \"tanstack-form\") {\n nextStack.forms = \"none\";\n changed = true;\n changes.push({\n category: \"forms\",\n message: \"Forms set to 'None' (TanStack Form has no Preact adapter)\",\n });\n }\n\n // State management libraries that require React bindings\n const reactOnlyStateManagement = [\"nanostores\", \"xstate\", \"tanstack-store\"];\n if (reactOnlyStateManagement.includes(nextStack.stateManagement)) {\n const oldValue = nextStack.stateManagement;\n nextStack.stateManagement = \"none\";\n changed = true;\n changes.push({\n category: \"stateManagement\",\n message: `State management set to 'None' (${oldValue} requires React bindings)`,\n });\n }\n\n // Lottie uses lottie-react which requires React\n if (nextStack.animation === \"lottie\") {\n nextStack.animation = \"none\";\n changed = true;\n changes.push({\n category: \"animation\",\n message: \"Animation set to 'None' (Lottie requires lottie-react)\",\n });\n }\n }\n\n // ============================================\n // DEPLOYMENT CONSTRAINTS\n // ============================================\n\n // Web deploy requires web frontend\n if (nextStack.webDeploy !== \"none\" && !nextStack.webFrontend.some((f) => f !== \"none\")) {\n nextStack.webDeploy = \"none\";\n changed = true;\n changes.push({ category: \"webDeploy\", message: \"Web deploy set to 'None' (no web frontend)\" });\n }\n\n // Server deploy constraints\n if (nextStack.serverDeploy === \"cloudflare\") {\n if (nextStack.runtime !== \"workers\" || nextStack.backend !== \"hono\") {\n nextStack.serverDeploy = \"none\";\n changed = true;\n changes.push({\n category: \"serverDeploy\",\n message: \"Server deploy set to 'None' (Cloudflare requires Workers + Hono)\",\n });\n }\n }\n\n if (\n nextStack.serverDeploy !== \"none\" &&\n [\n \"none\",\n \"convex\",\n \"self-next\",\n \"self-tanstack-start\",\n \"self-astro\",\n \"self-nuxt\",\n \"self-svelte\",\n \"self-solid-start\",\n ].includes(nextStack.backend)\n ) {\n nextStack.serverDeploy = \"none\";\n changed = true;\n changes.push({\n category: \"serverDeploy\",\n message: \"Server deploy set to 'None' (not needed for this backend)\",\n });\n }\n\n return {\n adjustedStack: changed ? nextStack : null,\n notes,\n changes,\n };\n};\n\n/**\n * Returns a reason why an option is disabled, or null if it's enabled.\n *\n * PHILOSOPHY: Only disable options that are TRULY incompatible.\n * - Don't create circular dependencies\n * - Allow users to select options that will trigger auto-adjustments\n * - Follow CLI behavior: filter options based on UPSTREAM selections only\n */\nexport const getDisabledReason = (\n currentStack: CompatibilityInput,\n category: CompatibilityCategory,\n optionId: string,\n): string | null => {\n // ============================================\n // CONVEX BACKEND - locks down many options\n // ============================================\n if (currentStack.backend === \"convex\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"Convex provides its own runtime\";\n }\n if (category === \"database\" && optionId !== \"none\") {\n return \"Convex provides its own database\";\n }\n if (category === \"orm\" && optionId !== \"none\") {\n return \"Convex has built-in data access\";\n }\n if (category === \"api\" && optionId !== \"none\") {\n return \"Convex provides its own API layer\";\n }\n if (category === \"dbSetup\" && optionId !== \"none\") {\n return \"Convex handles database setup\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"Convex has its own deployment\";\n }\n if (category === \"search\" && optionId !== \"none\") {\n return \"Search requires a standalone backend\";\n }\n if (category === \"fileStorage\" && optionId !== \"none\") {\n return \"File storage requires a standalone backend\";\n }\n if (category === \"auth\" && optionId === \"better-auth\") {\n const compatible =\n currentStack.webFrontend.some((f) =>\n [\"tanstack-router\", \"tanstack-start\", \"next\"].includes(f),\n ) ||\n currentStack.nativeFrontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n if (!compatible) {\n return \"Better-Auth with Convex requires TanStack Router, TanStack Start, Next.js, or React Native\";\n }\n }\n if (category === \"webFrontend\" && optionId === \"solid\") {\n return \"In Better-Fullstack, the Convex backend is currently not available with Solid\";\n }\n if (category === \"webFrontend\" && optionId === \"astro\") {\n return \"In Better-Fullstack, the Convex backend is currently not available with Astro\";\n }\n if (category === \"examples\" && optionId === \"ai\") {\n const hasIncompatibleFrontend = currentStack.webFrontend.some((f) =>\n [\"solid\", \"svelte\", \"nuxt\"].includes(f),\n );\n if (hasIncompatibleFrontend) {\n const frontendName = currentStack.webFrontend.find((f) =>\n [\"solid\", \"svelte\", \"nuxt\"].includes(f),\n );\n return `Convex AI example only supports React-based frontends (not ${frontendName})`;\n }\n }\n if (category === \"payments\" && optionId === \"polar\") {\n return \"In Better-Fullstack, Polar is currently not available with the Convex backend\";\n }\n }\n\n // ============================================\n // NO BACKEND - locks down backend-dependent options\n // ============================================\n if (currentStack.backend === \"none\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"database\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"orm\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"api\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"auth\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"dbSetup\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"payments\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"search\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"fileStorage\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n if (category === \"examples\" && optionId !== \"none\") {\n return \"No backend selected\";\n }\n }\n\n // ============================================\n // FULLSTACK BACKEND CONSTRAINTS\n // ============================================\n if (currentStack.backend === \"self-next\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"Next.js fullstack uses built-in API routes\";\n }\n if (category === \"webFrontend\" && optionId !== \"next\" && optionId !== \"none\") {\n return \"Next.js fullstack requires Next.js frontend\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"Fullstack uses frontend deployment\";\n }\n }\n\n if (currentStack.backend === \"self-tanstack-start\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"TanStack Start fullstack uses built-in API routes\";\n }\n if (category === \"webFrontend\" && optionId !== \"tanstack-start\" && optionId !== \"none\") {\n return \"TanStack Start fullstack requires TanStack Start frontend\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"Fullstack uses frontend deployment\";\n }\n }\n\n if (currentStack.backend === \"self-astro\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"Astro fullstack uses built-in API routes\";\n }\n if (category === \"webFrontend\" && optionId !== \"astro\" && optionId !== \"none\") {\n return \"Astro fullstack requires Astro frontend\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"Fullstack uses frontend deployment\";\n }\n }\n\n if (currentStack.backend === \"self-nuxt\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"Nuxt fullstack uses built-in API routes\";\n }\n if (category === \"webFrontend\" && optionId !== \"nuxt\" && optionId !== \"none\") {\n return \"Nuxt fullstack requires Nuxt frontend\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"Fullstack uses frontend deployment\";\n }\n }\n\n if (currentStack.backend === \"self-svelte\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"SvelteKit fullstack uses built-in API routes\";\n }\n if (category === \"webFrontend\" && optionId !== \"svelte\" && optionId !== \"none\") {\n return \"SvelteKit fullstack requires SvelteKit frontend\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"Fullstack uses frontend deployment\";\n }\n }\n\n if (currentStack.backend === \"self-solid-start\") {\n if (category === \"runtime\" && optionId !== \"none\") {\n return \"SolidStart fullstack uses built-in API routes\";\n }\n if (category === \"webFrontend\" && optionId !== \"solid-start\" && optionId !== \"none\") {\n return \"SolidStart fullstack requires SolidStart frontend\";\n }\n if (category === \"serverDeploy\" && optionId !== \"none\") {\n return \"Fullstack uses frontend deployment\";\n }\n }\n\n // ============================================\n // BACKEND SELECTION CONSTRAINTS\n // ============================================\n if (category === \"backend\") {\n if (optionId === \"self-next\" && !currentStack.webFrontend.includes(\"next\")) {\n return \"Requires Next.js frontend\";\n }\n if (\n optionId === \"self-tanstack-start\" &&\n !currentStack.webFrontend.includes(\"tanstack-start\")\n ) {\n return \"Requires TanStack Start frontend\";\n }\n if (optionId === \"self-astro\" && !currentStack.webFrontend.includes(\"astro\")) {\n return \"Requires Astro frontend\";\n }\n if (optionId === \"self-nuxt\" && !currentStack.webFrontend.includes(\"nuxt\")) {\n return \"Requires Nuxt frontend\";\n }\n if (optionId === \"self-svelte\" && !currentStack.webFrontend.includes(\"svelte\")) {\n return \"Requires SvelteKit frontend\";\n }\n if (optionId === \"self-solid-start\" && !currentStack.webFrontend.includes(\"solid-start\")) {\n return \"Requires SolidStart frontend\";\n }\n if (optionId === \"convex\" && currentStack.webFrontend.includes(\"solid\")) {\n return \"In Better-Fullstack, Convex is currently not available with Solid\";\n }\n if (optionId === \"convex\" && currentStack.webFrontend.includes(\"solid-start\")) {\n return \"In Better-Fullstack, Convex is currently not available with SolidStart\";\n }\n if (optionId === \"convex\" && currentStack.webFrontend.includes(\"astro\")) {\n return \"In Better-Fullstack, Convex is currently not available with Astro\";\n }\n // Workers runtime only works with Hono backend\n if (currentStack.runtime === \"workers\" && optionId !== \"hono\" && optionId !== \"none\") {\n return \"In Better-Fullstack, Workers runtime is currently supported only with Hono\";\n }\n }\n\n // ============================================\n // RUNTIME CONSTRAINTS\n // ============================================\n if (category === \"runtime\") {\n if (optionId === \"workers\" && currentStack.backend !== \"hono\") {\n return \"In Better-Fullstack, Workers runtime currently requires the Hono backend\";\n }\n if (optionId === \"none\") {\n const allowedBackends = [\n \"convex\",\n \"none\",\n \"self-next\",\n \"self-tanstack-start\",\n \"self-astro\",\n \"self-nuxt\",\n \"self-svelte\",\n \"self-solid-start\",\n ];\n if (!allowedBackends.includes(currentStack.backend)) {\n return \"Runtime 'None' only for Convex or fullstack backends\";\n }\n }\n }\n\n // ============================================\n // DATABASE CONSTRAINTS\n // ============================================\n if (category === \"database\") {\n if (optionId === \"mongodb\" && currentStack.runtime === \"workers\") {\n return \"In Better-Fullstack, MongoDB is currently not available with Workers runtime\";\n }\n // Allow all databases when ORM is none - system will auto-select ORM\n }\n\n // ============================================\n // ORM CONSTRAINTS\n // ============================================\n if (category === \"orm\") {\n if (optionId === \"mongoose\") {\n if (currentStack.runtime === \"workers\") {\n return \"Mongoose requires MongoDB, and Better-Fullstack currently doesn't support MongoDB with Workers runtime\";\n }\n // Only block if a non-MongoDB database is EXPLICITLY selected\n if (currentStack.database !== \"none\" && currentStack.database !== \"mongodb\") {\n return \"Mongoose only works with MongoDB\";\n }\n // Allow when database is \"none\" - system will auto-select MongoDB\n }\n if (optionId === \"drizzle\" && currentStack.database === \"mongodb\") {\n return \"Drizzle does not support MongoDB\";\n }\n if (optionId === \"none\" && currentStack.database !== \"none\") {\n return \"Database requires an ORM\";\n }\n }\n\n // ============================================\n // DB SETUP CONSTRAINTS\n // ============================================\n if (category === \"dbSetup\" && optionId !== \"none\") {\n if (currentStack.database === \"none\") {\n return \"Select a database first\";\n }\n\n // Database-specific setups\n if (optionId === \"turso\" && currentStack.database !== \"sqlite\") {\n return \"Turso requires SQLite\";\n }\n if (optionId === \"d1\") {\n if (currentStack.database !== \"sqlite\") return \"D1 requires SQLite\";\n if (currentStack.runtime !== \"workers\") return \"D1 requires Workers runtime\";\n }\n if (optionId === \"neon\" && currentStack.database !== \"postgres\") {\n return \"Neon requires PostgreSQL\";\n }\n if (optionId === \"supabase\" && currentStack.database !== \"postgres\") {\n return \"Supabase requires PostgreSQL\";\n }\n if (optionId === \"prisma-postgres\" && currentStack.database !== \"postgres\") {\n return \"Prisma Postgres requires PostgreSQL\";\n }\n if (optionId === \"mongodb-atlas\" && currentStack.database !== \"mongodb\") {\n return \"MongoDB Atlas requires MongoDB\";\n }\n if (\n optionId === \"planetscale\" &&\n currentStack.database !== \"postgres\" &&\n currentStack.database !== \"mysql\"\n ) {\n return \"PlanetScale requires PostgreSQL or MySQL\";\n }\n if (optionId === \"docker\") {\n if (currentStack.database === \"sqlite\") return \"SQLite doesn't need Docker\";\n if (currentStack.runtime === \"workers\") return \"Docker is incompatible with Workers\";\n }\n }\n\n // ============================================\n // API CONSTRAINTS\n // ============================================\n if (category === \"api\" && optionId === \"trpc\") {\n const needsOrpc = currentStack.webFrontend.some((f) =>\n [\"nuxt\", \"svelte\", \"solid\", \"solid-start\"].includes(f),\n );\n if (needsOrpc) {\n const frontendName = currentStack.webFrontend.find((f) =>\n [\"nuxt\", \"svelte\", \"solid\", \"solid-start\"].includes(f),\n );\n return `${frontendName} requires oRPC, not tRPC`;\n }\n // Astro with non-React integration requires oRPC\n if (\n currentStack.webFrontend.includes(\"astro\") &&\n currentStack.astroIntegration !== \"react\" &&\n currentStack.astroIntegration !== \"none\"\n ) {\n return `Astro with ${currentStack.astroIntegration} integration requires oRPC, not tRPC`;\n }\n }\n\n // ============================================\n // ASTRO INTEGRATION CONSTRAINTS\n // ============================================\n if (category === \"astroIntegration\") {\n if (!currentStack.webFrontend.includes(\"astro\") && optionId !== \"none\") {\n return \"Astro integration requires Astro frontend\";\n }\n // tRPC requires React integration\n if (currentStack.api === \"trpc\" && optionId !== \"react\" && optionId !== \"none\") {\n return \"tRPC requires React integration with Astro\";\n }\n }\n\n // ============================================\n // AUTH CONSTRAINTS\n // ============================================\n if (category === \"auth\") {\n if (optionId === \"clerk\") {\n if (currentStack.backend === \"convex\") {\n const hasClerkCompatibleFrontend =\n currentStack.webFrontend.some((f) =>\n [\"react-router\", \"tanstack-router\", \"tanstack-start\", \"next\"].includes(f),\n ) ||\n currentStack.nativeFrontend.some((f) =>\n [\"native-bare\", \"native-uniwind\", \"native-unistyles\"].includes(f),\n );\n if (!hasClerkCompatibleFrontend) {\n return \"Clerk with Convex requires React Router, TanStack Router, TanStack Start, Next.js, or React Native\";\n }\n } else if (\n currentStack.backend === \"self-next\" ||\n currentStack.backend === \"self-tanstack-start\"\n ) {\n if (currentStack.nativeFrontend.some((f) => f !== \"none\")) {\n return \"In Better-Fullstack, Clerk with self backend is currently supported only for web-only Next.js or TanStack Start projects (no native companion app)\";\n }\n } else if (currentStack.backend === \"self-astro\") {\n return \"In Better-Fullstack, Clerk is not yet supported for Astro fullstack projects\";\n } else if (currentStack.backend === \"self-nuxt\") {\n return \"In Better-Fullstack, Clerk is not yet supported for Nuxt fullstack projects\";\n } else if (currentStack.backend === \"self-svelte\") {\n return \"In Better-Fullstack, Clerk is not yet supported for SvelteKit fullstack projects\";\n } else if (currentStack.backend === \"self-solid-start\") {\n return \"In Better-Fullstack, Clerk is not yet supported for SolidStart fullstack projects\";\n } else if (currentStack.backend === \"none\") {\n return \"Clerk requires a backend\";\n } else {\n return \"In Better-Fullstack, Clerk is currently supported with Convex, Next.js fullstack, or TanStack Start fullstack\";\n }\n }\n }\n\n // ============================================\n // PAYMENTS CONSTRAINTS\n // ============================================\n if (category === \"payments\" && optionId === \"polar\") {\n if (currentStack.auth !== \"better-auth\") {\n return \"Polar requires Better Auth\";\n }\n if (!currentStack.webFrontend.some((f) => f !== \"none\")) {\n return \"Polar requires a web frontend\";\n }\n }\n\n // ============================================\n // EMAIL CONSTRAINTS\n // ============================================\n if (category === \"email\" && optionId !== \"none\") {\n if (currentStack.backend === \"convex\") {\n return \"Email integration is not available with Convex backend\";\n }\n if (currentStack.backend === \"none\") {\n return \"Email integration requires a backend\";\n }\n }\n\n // ============================================\n // AI CONSTRAINTS\n // ============================================\n if (category === \"ai\" && requiresChatSdkVercelAI(currentStack) && optionId !== \"vercel-ai\") {\n return \"Chat SDK example (Nuxt/Hono profile) requires Vercel AI SDK in v1\";\n }\n\n // ============================================\n // APP PLATFORMS CONSTRAINTS\n // ============================================\n if (category === \"appPlatforms\") {\n if (optionId === \"pwa\" && !hasPWACompatibleFrontend(currentStack.webFrontend)) {\n return \"PWA requires TanStack Router, React Router, Solid, Next.js, or Astro\";\n }\n if (optionId === \"tauri\" && !hasTauriCompatibleFrontend(currentStack.webFrontend)) {\n return \"Tauri requires TanStack Router, React Router, Nuxt, Svelte, Solid, Next.js, or Astro\";\n }\n }\n\n // ============================================\n // EXAMPLES CONSTRAINTS\n // ============================================\n if (category === \"examples\") {\n if (optionId === \"ai\") {\n if (\n currentStack.webFrontend.includes(\"solid\") ||\n currentStack.webFrontend.includes(\"solid-start\")\n ) {\n return \"AI example not compatible with Solid frontend\";\n }\n if (currentStack.backend === \"convex\") {\n const hasIncompatibleFrontend = currentStack.webFrontend.some((f) =>\n [\"svelte\", \"nuxt\"].includes(f),\n );\n if (hasIncompatibleFrontend) {\n const frontendName = currentStack.webFrontend.find((f) => [\"svelte\", \"nuxt\"].includes(f));\n return `Convex AI example only supports React-based frontends (not ${frontendName})`;\n }\n }\n }\n\n if (optionId === \"chat-sdk\") {\n if (currentStack.ecosystem !== \"typescript\") {\n return \"Chat SDK example is currently available only for TypeScript stacks\";\n }\n if (currentStack.backend === \"convex\") {\n return \"Chat SDK example is not supported with Convex backend in v1\";\n }\n if (\n currentStack.backend === \"self-astro\" ||\n currentStack.backend === \"self-svelte\" ||\n currentStack.backend === \"self-solid-start\"\n ) {\n return \"Chat SDK self backend profile supports Next.js, TanStack Start, or Nuxt in v1\";\n }\n if (currentStack.backend === \"self-next\" || currentStack.backend === \"self-tanstack-start\") {\n return null;\n }\n if (currentStack.backend === \"self-nuxt\") {\n return null;\n }\n if (currentStack.backend === \"hono\") {\n if (currentStack.runtime !== \"node\") {\n return \"Chat SDK Hono profile requires Node runtime in v1\";\n }\n return null;\n }\n if (currentStack.backend.startsWith(\"self-\")) {\n return \"Chat SDK self backend profile supports Next.js, TanStack Start, or Nuxt in v1\";\n }\n if (currentStack.backend !== \"none\") {\n return \"Chat SDK example is only supported for self (Next/TanStack Start/Nuxt) or Hono+Node in v1\";\n }\n }\n }\n\n // ============================================\n // FRESH FRONTEND CONSTRAINTS\n // Fresh is Preact-based and incompatible with React-specific packages\n // ============================================\n const isFresh = currentStack.webFrontend.includes(\"fresh\");\n\n // Forms: TanStack Form has no Preact adapter\n if (category === \"forms\" && optionId === \"tanstack-form\" && isFresh) {\n return \"TanStack Form has no Preact adapter (Fresh uses Preact)\";\n }\n\n // State Management: These all require React bindings\n if (category === \"stateManagement\" && isFresh) {\n if (optionId === \"nanostores\") {\n return \"Nanostores requires @nanostores/react (no Preact support)\";\n }\n if (optionId === \"xstate\") {\n return \"XState requires @xstate/react (no Preact support)\";\n }\n if (optionId === \"tanstack-store\") {\n return \"TanStack Store requires @tanstack/react-store (no Preact support)\";\n }\n }\n\n // Animation: Lottie uses lottie-react which requires React\n if (category === \"animation\" && optionId === \"lottie\" && isFresh) {\n return \"Lottie uses lottie-react which requires React (not Preact)\";\n }\n\n // ============================================\n // CSS FRAMEWORK CONSTRAINTS\n // ============================================\n if (category === \"cssFramework\") {\n // CSS frameworks only apply to web frontends\n if (!currentStack.webFrontend.some((f) => f !== \"none\")) {\n if (optionId !== \"none\") {\n return \"CSS framework requires a web frontend\";\n }\n }\n // Some UI libraries require Tailwind\n const requiresTailwind = [\"shadcn-ui\", \"daisyui\", \"nextui\"].includes(currentStack.uiLibrary);\n if (requiresTailwind && optionId !== \"tailwind\") {\n return `${currentStack.uiLibrary === \"shadcn-ui\" ? \"shadcn/ui\" : currentStack.uiLibrary === \"daisyui\" ? \"daisyUI\" : \"NextUI\"} requires Tailwind CSS`;\n }\n }\n\n // ============================================\n // UI LIBRARY CONSTRAINTS\n // ============================================\n if (category === \"uiLibrary\") {\n // UI libraries only apply to web frontends\n if (!currentStack.webFrontend.some((f) => f !== \"none\")) {\n if (optionId !== \"none\") {\n return \"UI library requires a web frontend\";\n }\n }\n\n // React-only UI libraries\n const reactOnlyLibraries = [\"shadcn-ui\", \"radix-ui\", \"chakra-ui\", \"nextui\"];\n const reactFrontends = [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\"];\n\n if (reactOnlyLibraries.includes(optionId)) {\n const hasReactFrontend = currentStack.webFrontend.some((f) => reactFrontends.includes(f));\n // Astro with React integration also works\n const hasAstroReact =\n currentStack.webFrontend.includes(\"astro\") && currentStack.astroIntegration === \"react\";\n if (!hasReactFrontend && !hasAstroReact) {\n const libraryName =\n optionId === \"shadcn-ui\"\n ? \"shadcn/ui\"\n : optionId === \"radix-ui\"\n ? \"Radix UI\"\n : optionId === \"chakra-ui\"\n ? \"Chakra UI\"\n : \"NextUI\";\n return `${libraryName} requires a React-based frontend`;\n }\n }\n\n // Headless UI works with React and Vue\n if (optionId === \"headless-ui\") {\n const hasReactFrontend = currentStack.webFrontend.some((f) => reactFrontends.includes(f));\n const hasVueFrontend = currentStack.webFrontend.includes(\"nuxt\");\n const hasAstroReactOrVue =\n currentStack.webFrontend.includes(\"astro\") &&\n [\"react\", \"vue\"].includes(currentStack.astroIntegration);\n if (!hasReactFrontend && !hasVueFrontend && !hasAstroReactOrVue) {\n return \"Headless UI requires React or Vue frontend\";\n }\n }\n\n // Park UI works with React, Vue, and Solid\n if (optionId === \"park-ui\") {\n const hasReactFrontend = currentStack.webFrontend.some((f) => reactFrontends.includes(f));\n const hasVueFrontend = currentStack.webFrontend.includes(\"nuxt\");\n const hasSolidFrontend =\n currentStack.webFrontend.includes(\"solid\") ||\n currentStack.webFrontend.includes(\"solid-start\");\n const hasAstroCompatible =\n currentStack.webFrontend.includes(\"astro\") &&\n [\"react\", \"vue\", \"solid\"].includes(currentStack.astroIntegration);\n if (!hasReactFrontend && !hasVueFrontend && !hasSolidFrontend && !hasAstroCompatible) {\n return \"Park UI requires React, Vue, or Solid frontend\";\n }\n // Park UI requires a CSS framework (not \"none\")\n if (currentStack.cssFramework === \"none\") {\n return \"Park UI requires a CSS framework\";\n }\n }\n\n // UI libraries requiring Tailwind\n if ([\"shadcn-ui\", \"daisyui\", \"nextui\"].includes(optionId)) {\n if (currentStack.cssFramework !== \"tailwind\") {\n const libraryName =\n optionId === \"shadcn-ui\" ? \"shadcn/ui\" : optionId === \"daisyui\" ? \"daisyUI\" : \"NextUI\";\n return `${libraryName} requires Tailwind CSS`;\n }\n }\n }\n\n // ============================================\n // DEPLOYMENT CONSTRAINTS\n // ============================================\n if (category === \"webDeploy\" && optionId !== \"none\") {\n if (!currentStack.webFrontend.some((f) => f !== \"none\")) {\n return \"Web deployment requires a web frontend\";\n }\n }\n\n if (category === \"serverDeploy\") {\n if (optionId === \"cloudflare\") {\n if (currentStack.runtime !== \"workers\") {\n return \"In Better-Fullstack, Cloudflare server deploy currently requires Workers runtime\";\n }\n if (currentStack.backend !== \"hono\") {\n return \"In Better-Fullstack, Cloudflare server deploy is currently supported only with Hono\";\n }\n }\n if (optionId !== \"none\") {\n const noServerDeploy = [\n \"none\",\n \"convex\",\n \"self-next\",\n \"self-tanstack-start\",\n \"self-astro\",\n \"self-nuxt\",\n \"self-svelte\",\n \"self-solid-start\",\n ];\n if (noServerDeploy.includes(currentStack.backend)) {\n return \"Server deployment not needed for this backend\";\n }\n }\n if (optionId === \"none\" && currentStack.runtime === \"workers\") {\n return \"Workers requires server deployment\";\n }\n }\n\n return null;\n};\n\nexport const isOptionCompatible = (\n currentStack: CompatibilityInput,\n category: CompatibilityCategory,\n optionId: string,\n): boolean => {\n if (currentStack.yolo === \"true\") {\n return true;\n }\n return getDisabledReason(currentStack, category, optionId) === null;\n};\n\nconst WEB_FRAMEWORKS: readonly Frontend[] = [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n \"solid-start\",\n \"astro\",\n \"qwik\",\n \"angular\",\n \"redwood\",\n \"fresh\",\n \"none\",\n] as const;\n\nconst UI_LIBRARY_COMPATIBILITY: Record<\n UILibrary,\n {\n frontends: readonly Frontend[];\n cssFrameworks: readonly CSSFramework[];\n }\n> = {\n \"shadcn-ui\": {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"],\n cssFrameworks: [\"tailwind\"],\n },\n daisyui: {\n frontends: [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n \"solid-start\",\n \"astro\",\n \"qwik\",\n \"angular\",\n \"redwood\",\n \"fresh\",\n ],\n cssFrameworks: [\"tailwind\"],\n },\n \"radix-ui\": {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n \"headless-ui\": {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"nuxt\", \"astro\"],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n \"park-ui\": {\n frontends: [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"solid\",\n \"solid-start\",\n \"astro\",\n ],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\"],\n },\n \"chakra-ui\": {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n nextui: {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"],\n cssFrameworks: [\"tailwind\"],\n },\n mantine: {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n \"base-ui\": {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n \"ark-ui\": {\n frontends: [\n \"tanstack-router\",\n \"react-router\",\n \"tanstack-start\",\n \"next\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n \"solid-start\",\n \"astro\",\n ],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n \"react-aria\": {\n frontends: [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"],\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n none: {\n frontends: WEB_FRAMEWORKS,\n cssFrameworks: [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"],\n },\n};\n\nconst ADDON_COMPATIBILITY: Record<Addons, readonly Frontend[]> = {\n pwa: [\n \"tanstack-router\",\n \"react-router\",\n \"solid\",\n \"next\",\n \"astro\",\n \"qwik\",\n \"angular\",\n \"redwood\",\n \"fresh\",\n ],\n tauri: [\n \"tanstack-router\",\n \"react-router\",\n \"nuxt\",\n \"svelte\",\n \"solid\",\n \"next\",\n \"astro\",\n \"qwik\",\n \"angular\",\n \"redwood\",\n \"fresh\",\n ],\n biome: [],\n husky: [],\n lefthook: [],\n turborepo: [],\n starlight: [],\n ultracite: [],\n ruler: [],\n mcp: [],\n skills: [],\n oxlint: [],\n fumadocs: [],\n opentui: [],\n wxt: [],\n msw: [],\n storybook: [\"tanstack-router\", \"react-router\", \"next\", \"nuxt\", \"svelte\", \"solid\"],\n none: [],\n};\n\nexport function isWebFrontend(value: Frontend) {\n return WEB_FRAMEWORKS.includes(value);\n}\n\nexport function splitFrontends(values: Frontend[] = []): {\n web: Frontend[];\n native: Frontend[];\n} {\n const web = values.filter((f) => isWebFrontend(f));\n const native = values.filter(\n (f) => f === \"native-bare\" || f === \"native-uniwind\" || f === \"native-unistyles\",\n );\n return { web, native };\n}\n\nexport function allowedApisForFrontends(\n frontends: Frontend[] = [],\n astroIntegration?: AstroIntegration,\n) {\n const includesNuxt = frontends.includes(\"nuxt\");\n const includesSvelte = frontends.includes(\"svelte\");\n const includesSolid = frontends.includes(\"solid\");\n const includesAstro = frontends.includes(\"astro\");\n const includesQwik = frontends.includes(\"qwik\");\n const includesAngular = frontends.includes(\"angular\");\n const includesRedwood = frontends.includes(\"redwood\");\n const includesFresh = frontends.includes(\"fresh\");\n const base: API[] = [\"trpc\", \"orpc\", \"ts-rest\", \"garph\", \"none\"];\n\n if (includesQwik || includesAngular || includesRedwood || includesFresh) {\n return [\"none\"] as API[];\n }\n\n const includesSolidStartApi = frontends.includes(\"solid-start\");\n if (includesNuxt || includesSvelte || includesSolid || includesSolidStartApi) {\n return [\"orpc\", \"none\"] as API[];\n }\n\n if (includesAstro && astroIntegration && astroIntegration !== \"react\") {\n return [\"orpc\", \"none\"] as API[];\n }\n\n return base;\n}\n\nexport function isFrontendAllowedWithBackend(frontend: Frontend, backend?: Backend, auth?: string) {\n if (backend === \"convex\" && frontend === \"solid\") return false;\n if (backend === \"convex\" && frontend === \"solid-start\") return false;\n if (backend === \"convex\" && frontend === \"astro\") return false;\n if (backend === \"convex\" && frontend === \"qwik\") return false;\n if (backend === \"convex\" && frontend === \"angular\") return false;\n if (backend === \"convex\" && frontend === \"redwood\") return false;\n if (backend === \"convex\" && frontend === \"fresh\") return false;\n\n if (frontend === \"qwik\" && backend && backend !== \"none\") return false;\n if (frontend === \"angular\" && backend && backend !== \"none\") return false;\n if (frontend === \"redwood\" && backend && backend !== \"none\") return false;\n if (frontend === \"fresh\" && backend && backend !== \"none\") return false;\n\n if (auth === \"clerk\" && backend === \"convex\") {\n const incompatibleFrontends = [\"nuxt\", \"svelte\", \"solid\", \"solid-start\"];\n if (incompatibleFrontends.includes(frontend)) return false;\n }\n\n if (auth === \"clerk\" && backend === \"self\") {\n if (![\"next\", \"tanstack-start\"].includes(frontend)) return false;\n }\n\n if (auth === \"nextauth\") {\n if (frontend !== \"next\") return false;\n if (backend !== \"self\") return false;\n }\n\n if (auth === \"supabase-auth\") {\n if (frontend !== \"next\") return false;\n if (backend !== \"self\") return false;\n }\n\n return true;\n}\n\nexport function isExampleAIAllowed(backend?: Backend, frontends: Frontend[] = []) {\n const includesSolid = frontends.includes(\"solid\");\n const includesSolidStart = frontends.includes(\"solid-start\");\n if (includesSolid || includesSolidStart) return false;\n\n if (backend === \"convex\") {\n const includesNuxt = frontends.includes(\"nuxt\");\n const includesSvelte = frontends.includes(\"svelte\");\n if (includesNuxt || includesSvelte) return false;\n }\n\n return true;\n}\n\nfunction hasExampleChatSdkSelfFrontend(frontends: Frontend[] = []) {\n return frontends.some((f) => [\"next\", \"tanstack-start\", \"nuxt\"].includes(f));\n}\n\nexport function isExampleChatSdkAllowed(\n backend?: Backend | string,\n frontends: Frontend[] = [],\n runtime?: Runtime | string,\n) {\n if (!backend || backend === \"none\" || backend === \"convex\") return false;\n\n if (backend === \"self\") {\n return hasExampleChatSdkSelfFrontend(frontends);\n }\n\n if (backend === \"self-next\" || backend === \"self-tanstack-start\" || backend === \"self-nuxt\") {\n return true;\n }\n\n if (backend === \"self-astro\" || backend === \"self-svelte\" || backend === \"self-solid-start\") {\n return false;\n }\n\n if (backend === \"hono\") {\n return runtime === \"node\";\n }\n\n return false;\n}\n\nexport function requiresChatSdkVercelAIForSelection(\n backend?: Backend | string,\n frontends: Frontend[] = [],\n runtime?: Runtime | string,\n) {\n if (backend === \"self\" && frontends.includes(\"nuxt\")) return true;\n if (backend === \"self-nuxt\") return true;\n if (backend === \"hono\" && runtime === \"node\") return true;\n return false;\n}\n\nexport function validateAddonCompatibility(\n addon: Addons,\n frontend: Frontend[],\n _auth?: Auth,\n): { isCompatible: boolean; reason?: string } {\n const compatibleFrontends = ADDON_COMPATIBILITY[addon];\n\n if (compatibleFrontends.length > 0) {\n const hasCompatibleFrontend = frontend.some((f) =>\n (compatibleFrontends as readonly string[]).includes(f),\n );\n\n if (!hasCompatibleFrontend) {\n const frontendList = compatibleFrontends.join(\", \");\n return {\n isCompatible: false,\n reason: `${addon} addon requires one of these frontends: ${frontendList}`,\n };\n }\n }\n\n return { isCompatible: true };\n}\n\nexport function getCompatibleAddons(\n allAddons: Addons[],\n frontend: Frontend[],\n existingAddons: Addons[] = [],\n auth?: Auth,\n) {\n return allAddons.filter((addon) => {\n if (existingAddons.includes(addon)) return false;\n if (addon === \"none\") return false;\n const { isCompatible } = validateAddonCompatibility(addon, frontend, auth);\n return isCompatible;\n });\n}\n\nexport function getCompatibleUILibraries(\n frontends: Frontend[] = [],\n astroIntegration?: AstroIntegration,\n): UILibrary[] {\n const { web } = splitFrontends(frontends);\n if (web.length === 0) return [\"none\"];\n\n const webFrontend = web[0];\n const allUILibraries = Object.keys(UI_LIBRARY_COMPATIBILITY) as UILibrary[];\n\n return allUILibraries.filter((lib) => {\n if (lib === \"none\") return true;\n\n const compatibility = UI_LIBRARY_COMPATIBILITY[lib];\n if (webFrontend === \"astro\") {\n if (astroIntegration === \"react\") {\n return compatibility.frontends.some((f) =>\n [\"tanstack-router\", \"react-router\", \"tanstack-start\", \"next\", \"astro\"].includes(f),\n );\n }\n return compatibility.frontends.some((f) =>\n [\"nuxt\", \"svelte\", \"solid\", \"qwik\", \"angular\"].includes(f),\n );\n }\n\n return compatibility.frontends.includes(webFrontend);\n });\n}\n\nexport function getCompatibleCSSFrameworks(uiLibrary: UILibrary | undefined): CSSFramework[] {\n if (!uiLibrary || uiLibrary === \"none\") {\n return [\"tailwind\", \"scss\", \"less\", \"postcss-only\", \"none\"];\n }\n\n const compatibility = UI_LIBRARY_COMPATIBILITY[uiLibrary];\n return compatibility.cssFrameworks as CSSFramework[];\n}\n\nexport function hasWebStyling(frontends: Frontend[] = []): boolean {\n const { web } = splitFrontends(frontends);\n return web.length > 0;\n}\n\nexport function getCompatibleFormLibraries(frontends: Frontend[] = []): Forms[] {\n const hasSolid = frontends.includes(\"solid\");\n const hasSolidStart = frontends.includes(\"solid-start\");\n const hasQwik = frontends.includes(\"qwik\");\n const hasFresh = frontends.includes(\"fresh\");\n\n const all: Forms[] = [\n \"tanstack-form\",\n \"react-hook-form\",\n \"formik\",\n \"final-form\",\n \"conform\",\n \"modular-forms\",\n \"none\",\n ];\n\n if (hasFresh) {\n return all.filter((f) => f !== \"tanstack-form\" && f !== \"react-hook-form\" && f !== \"formik\");\n }\n\n if (hasSolid || hasSolidStart || hasQwik) {\n return all.filter((f) => f !== \"react-hook-form\" && f !== \"formik\" && f !== \"final-form\");\n }\n\n return all;\n}\n\nexport function evaluateCompatibility(input: CompatibilityInput): CompatibilityEvaluation {\n const issues: CompatibilityIssue[] = [];\n\n const scalarChecks: Array<[CompatibilityCategory, string]> = [\n [\"runtime\", input.runtime],\n [\"backend\", input.backend],\n [\"database\", input.database],\n [\"orm\", input.orm],\n [\"dbSetup\", input.dbSetup],\n [\"api\", input.api],\n [\"auth\", input.auth],\n [\"payments\", input.payments],\n [\"email\", input.email],\n [\"cssFramework\", input.cssFramework],\n [\"uiLibrary\", input.uiLibrary],\n [\"webDeploy\", input.webDeploy],\n [\"serverDeploy\", input.serverDeploy],\n [\"forms\", input.forms],\n [\"stateManagement\", input.stateManagement],\n [\"animation\", input.animation],\n [\"ai\", input.aiSdk],\n ];\n\n for (const [category, optionId] of scalarChecks) {\n const reason = getDisabledReason(input, category, optionId);\n if (reason) {\n issues.push({\n code: `INCOMPATIBLE_${category.toUpperCase()}`,\n message: reason,\n category,\n optionId,\n });\n }\n }\n\n for (const frontend of input.webFrontend) {\n const reason = getDisabledReason(input, \"webFrontend\", frontend);\n if (reason) {\n issues.push({\n code: \"INCOMPATIBLE_FRONTEND\",\n message: reason,\n category: \"webFrontend\",\n optionId: frontend,\n });\n }\n }\n\n for (const addon of [...input.codeQuality, ...input.documentation, ...input.appPlatforms]) {\n const reason = getDisabledReason(input, \"appPlatforms\", addon);\n if (reason) {\n issues.push({\n code: \"INCOMPATIBLE_ADDON\",\n message: reason,\n category: \"appPlatforms\",\n optionId: addon,\n });\n }\n }\n\n return { issues };\n}\n"],"mappings":";;;AAyMA,MAAMA,iBAA0C;CAC9C,GA9CyD;EACzD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CAIC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAM,kBAAkB;AAExB,SAAgB,oBAAoB,MAAkC;CACpE,MAAM,gBAAgB;EAAC;EAAK;EAAK;EAAK;EAAK;EAAK;EAAK;EAAI;CACzD,MAAM,aAAa;AAEnB,KAAI,SAAS,IAAK,QAAO;AAEzB,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,KAAK,SAAS,WAChB,QAAO,kCAAkC,WAAW;AAEtD,KAAI,cAAc,MAAM,SAAS,KAAK,SAAS,KAAK,CAAC,CACnD,QAAO;AAET,KAAI,KAAK,WAAW,IAAI,IAAI,KAAK,WAAW,IAAI,CAC9C,QAAO;AAET,KAAI,KAAK,aAAa,KAAK,kBAAkB,KAAK,aAAa,KAAK,cAClE,QAAO;;AAKX,MAAa,4BAA4B,gBACvC,YAAY,MAAM,MAChB;CAAC;CAAmB;CAAgB;CAAS;CAAQ;CAAQ,CAAC,SAAS,EAAE,CAC1E;AAEH,MAAa,8BAA8B,gBACzC,YAAY,MAAM,MAChB;CAAC;CAAmB;CAAgB;CAAQ;CAAU;CAAS;CAAQ;CAAQ,CAAC,SAAS,EAAE,CAC5F;AAEH,MAAM,6BAA6B,UAAuC;AACxE,KAAI,MAAM,cAAc,aAAc,QAAO;AAE7C,KAAI,MAAM,YAAY,eAAe,MAAM,YAAY,sBACrD,QAAO;AAGT,KAAI,MAAM,YAAY,YACpB,QAAO;AAGT,KAAI,MAAM,YAAY,OACpB,QAAO,MAAM,YAAY;AAG3B,QAAO;;AAGT,MAAa,2BAA2B,UAAuC;AAC7E,QACE,MAAM,SAAS,SAAS,WAAW,KAClC,MAAM,YAAY,eAAgB,MAAM,YAAY,UAAU,MAAM,YAAY;;AAIrF,MAAa,0BAA0B,gBAAgC;CAErE,MAAMC,oBAA4C;EAChD,kBAAkB;EAClB,cAAc;EACd,SAAS;EACT,SAAS;EACT,SAAS;EACT,eAAe;EAChB;CAGD,MAAMC,sBAA8C;EAClD,oBAAoB;EACpB,WAAW;EACX,kBAAkB;EAClB,UAAU;EACV,iBAAiB;EACjB,eAAe;EAChB;CAGD,MAAMC,kBAA0C;EAC9C,gBAAgB;EAChB,OAAO;EACP,OAAO;EACP,OAAO;EACP,WAAW;EACZ;AAED,KAAI,kBAAkB,aACpB,QAAO,kBAAkB;AAG3B,KAAI,oBAAoB,aACtB,QAAO,oBAAoB;AAG7B,KAAI,gBAAgB,aAClB,QAAO,gBAAgB;CAGzB,MAAM,SAAS,YAAY,QAAQ,YAAY,MAAM;AACrD,QAAO,OAAO,OAAO,EAAE,CAAC,aAAa,GAAG,OAAO,MAAM,EAAE;;;;;;;AAczD,MAAa,6BACX,UACgC;AAEhC,KAAI,MAAM,SAAS,OACjB,QAAO;EACL,eAAe;EACf,OAAO,EAAE;EACT,SAAS,EAAE;EACZ;CAGH,MAAM,YAAY,EAAE,GAAG,OAAO;CAC9B,IAAI,UAAU;CACd,MAAMC,QAA8C,EAAE;CACtD,MAAMC,UAAqC,EAAE;AAE7C,MAAK,MAAM,OAAO,eAChB,OAAM,OAAO;EAAE,OAAO,EAAE;EAAE,UAAU;EAAO;AAO7C,KAAI,UAAU,YAAY,UAAU;AAalC,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAXmB;GACnD,SAAS;GACT,UAAU;GACV,KAAK;GACL,KAAK;GACL,SAAS;GACT,cAAc;GACd,QAAQ;GACR,aAAa;GACd,CAEyD,EAAE;GAC1D,MAAM,SAAS;AACf,OAAI,UAAU,YAAY,OAAO;AAC/B,cAAU,UAAU;AACpB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS,GAAG,uBAAuB,OAAO,CAAC,WAAW,MAAM;KAC7D,CAAC;;;AAKN,MAAI,UAAU,YAAY,SAAS,QAAQ,EAAE;AAC3C,aAAU,cAAc,UAAU,YAAY,QAAQ,MAAM,MAAM,QAAQ;AAC1E,OAAI,UAAU,YAAY,WAAW,EAAG,WAAU,cAAc,CAAC,OAAO;AACxE,aAAU;AACV,WAAQ,KAAK;IAAE,UAAU;IAAW,SAAS;IAA4C,CAAC;;AAE5F,MAAI,UAAU,YAAY,SAAS,cAAc,EAAE;AACjD,aAAU,cAAc,UAAU,YAAY,QAAQ,MAAM,MAAM,cAAc;AAChF,OAAI,UAAU,YAAY,WAAW,EAAG,WAAU,cAAc,CAAC,OAAO;AACxE,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,SAAS,QAAQ,EAAE;AAC3C,aAAU,cAAc,UAAU,YAAY,QAAQ,MAAM,MAAM,QAAQ;AAC1E,OAAI,UAAU,YAAY,WAAW,EAAG,WAAU,cAAc,CAAC,OAAO;AACxE,aAAU,mBAAmB;AAC7B,aAAU;AACV,WAAQ,KAAK;IAAE,UAAU;IAAW,SAAS;IAA4C,CAAC;;AAI5F,MAAI,UAAU,SAAS,SAAS,KAAK,EAInC;OAHgC,UAAU,YAAY,MAAM,MAC1D;IAAC;IAAS;IAAU;IAAO,CAAC,SAAS,EAAE,CACxC,EAC4B;AAC3B,cAAU,WAAW,UAAU,SAAS,QAAQ,MAAM,MAAM,KAAK;AACjE,QAAI,UAAU,SAAS,WAAW,EAAG,WAAU,WAAW,CAAC,OAAO;AAClE,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;AAKN,MAAI,UAAU,SAAS,SAQrB;OAAI,EANF,UAAU,YAAY,MAAM,MAC1B;IAAC;IAAmB;IAAgB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1E,IACD,UAAU,eAAe,MAAM,MAC7B;IAAC;IAAe;IAAkB;IAAmB,CAAC,SAAS,EAAE,CAClE,GACsB;AACvB,cAAU,OAAO;AACjB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;AAIN,MAAI,UAAU,SAAS,eAQrB;OAAI,EANF,UAAU,YAAY,MAAM,MAC1B;IAAC;IAAmB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1D,IACD,UAAU,eAAe,MAAM,MAC7B;IAAC;IAAe;IAAkB;IAAmB,CAAC,SAAS,EAAE,CAClE,GAC2B;AAC5B,cAAU,OAAO;AACjB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;;AAKR,KAAI,UAAU,YAAY,QAAQ;AAehC,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAbiB;GACjD,SAAS;GACT,UAAU;GACV,KAAK;GACL,KAAK;GACL,MAAM;GACN,SAAS;GACT,cAAc;GACd,UAAU;GACV,QAAQ;GACR,aAAa;GACd,CAEuD,EAAE;GACxD,MAAM,SAAS;AACf,OAAI,UAAU,YAAY,OAAO;AAC/B,cAAU,UAAU;AACpB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS,GAAG,uBAAuB,OAAO,CAAC,WAAW,MAAM;KAC7D,CAAC;;;AAKN,MACE,UAAU,SAAS,SAAS,KAC5B,EAAE,UAAU,SAAS,WAAW,KAAK,UAAU,SAAS,OAAO,SAC/D;AACA,aAAU,WAAW,CAAC,OAAO;AAC7B,aAAU;AACV,WAAQ,KAAK;IAAE,UAAU;IAAW,SAAS;IAAiC,CAAC;;;AAKnF,KACE,UAAU,YAAY,eACtB,UAAU,YAAY,yBACtB,UAAU,YAAY,gBACtB,UAAU,YAAY,eACtB,UAAU,YAAY,iBACtB,UAAU,YAAY,oBACtB;AAEA,MAAI,UAAU,YAAY,QAAQ;AAChC,aAAU,UAAU;AACpB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,iBAAiB,QAAQ;AACrC,aAAU,eAAe;AACzB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAIJ,MAAI,UAAU,YAAY,eAAe,CAAC,UAAU,YAAY,SAAS,OAAO,EAAE;AAChF,aAAU,cAAc,CAAC,OAAO;AAChC,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MACE,UAAU,YAAY,yBACtB,CAAC,UAAU,YAAY,SAAS,iBAAiB,EACjD;AACA,aAAU,cAAc,CAAC,iBAAiB;AAC1C,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,gBAAgB,CAAC,UAAU,YAAY,SAAS,QAAQ,EAAE;AAClF,aAAU,cAAc,CAAC,QAAQ;AACjC,OAAI,UAAU,qBAAqB,OACjC,WAAU,mBAAmB;AAE/B,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,eAAe,CAAC,UAAU,YAAY,SAAS,OAAO,EAAE;AAChF,aAAU,cAAc,CAAC,OAAO;AAChC,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,iBAAiB,CAAC,UAAU,YAAY,SAAS,SAAS,EAAE;AACpF,aAAU,cAAc,CAAC,SAAS;AAClC,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MACE,UAAU,YAAY,sBACtB,CAAC,UAAU,YAAY,SAAS,cAAc,EAC9C;AACA,aAAU,cAAc,CAAC,cAAc;AACvC,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AASN,KAAI,UAAU,YAAY,aAAa,UAAU,YAAY,QAAQ;AACnE,YAAU,UAAU;AACpB,YAAU;AACV,UAAQ,KAAK;GAAE,UAAU;GAAW,SAAS;GAAgD,CAAC;;AAIhG,KAAI,UAAU,YAAY,aAAa,UAAU,iBAAiB,QAAQ;AACxE,YAAU,eAAe;AACzB,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SAAS;GACV,CAAC;;AAIJ,KAAI,UAAU,YAAY,aAAa,UAAU,aAAa,WAAW;AACvE,YAAU,WAAW;AACrB,YAAU,MAAM;AAChB,YAAU,UAAU;AACpB,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SACE;GACH,CAAC;;AAIJ,KACE,UAAU,YAAY,UACtB,UAAU,YAAY,YACtB,UAAU,YAAY,UACtB,UAAU,YAAY,eACtB,UAAU,YAAY,yBACtB,UAAU,YAAY,gBACtB,UAAU,YAAY,eACtB,UAAU,YAAY,iBACtB,UAAU,YAAY,oBACtB;AACA,YAAU,UAAU;AACpB,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SAAS,mBAAmB,gBAAgB;GAC7C,CAAC;;AAQJ,KAAI,UAAU,YAAY,YAAY,UAAU,YAAY,QAAQ;AAElE,MAAI,UAAU,aAAa,QAAQ;AACjC,OAAI,UAAU,QAAQ,QAAQ;AAC5B,cAAU,MAAM;AAChB,cAAU;AACV,YAAQ,KAAK;KAAE,UAAU;KAAY,SAAS;KAA4C,CAAC;;AAE7F,OAAI,UAAU,YAAY,QAAQ;AAChC,cAAU,UAAU;AACpB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;AAKN,MAAI,UAAU,aAAa,WAAW;AACpC,OAAI,UAAU,QAAQ,YAAY,UAAU,QAAQ,YAAY;AAC9D,cAAU,MAAM;AAChB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;AAGJ,OACE,UAAU,YAAY,mBACtB,UAAU,YAAY,UACtB,UAAU,YAAY,UACtB;AACA,cAAU,UAAU;AACpB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;AAKN,MAAI;GAAC;GAAU;GAAY;GAAQ,CAAC,SAAS,UAAU,SAAS,EAAE;AAChE,OAAI,UAAU,QAAQ,QAAQ;AAC5B,cAAU,MAAM;AAChB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;AAEJ,OAAI,UAAU,QAAQ,YAAY;AAChC,cAAU,MAAM;AAChB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;AAKN,MAAI,UAAU,QAAQ,UAAU,UAAU,aAAa,OACrD,KAAI,UAAU,QAAQ,YAAY;AAChC,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;SACG;AACL,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IAAE,UAAU;IAAO,SAAS;IAA+C,CAAC;;AAK7F,MAAI,UAAU,YAAY,WAAW,UAAU,aAAa,UAAU;AACpE,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,MAAM;AAC9B,OAAI,UAAU,aAAa,UAAU;AACnC,cAAU,WAAW;AACrB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;AAEJ,OAAI,UAAU,YAAY,WAAW;AACnC,cAAU,UAAU;AACpB,cAAU,UAAU;AACpB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;AAGN,MAAI,UAAU,YAAY,UAAU,UAAU,aAAa,YAAY;AACrE,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,cAAc,UAAU,aAAa,YAAY;AACzE,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,qBAAqB,UAAU,aAAa,YAAY;AAChF,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,mBAAmB,UAAU,aAAa,WAAW;AAC7E,aAAU,WAAW;AACrB,OAAI,UAAU,QAAQ,YAAY,UAAU,QAAQ,WAClD,WAAU,MAAM;AAElB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MACE,UAAU,YAAY,iBACtB,UAAU,aAAa,cACvB,UAAU,aAAa,SACvB;AACA,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,UAAU;AAClC,OAAI,UAAU,aAAa,UAAU;AACnC,cAAU,UAAU;AACpB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;AAEJ,OAAI,UAAU,YAAY,WAAW;AACnC,cAAU,UAAU;AACpB,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SACE;KACH,CAAC;;;;AASR,KAAI,UAAU,YAAY,YAAY,UAAU,YAAY,QAAQ;AAKlE,MAHkB,UAAU,YAAY,MAAM,MAC5C;GAAC;GAAQ;GAAU;GAAS;GAAc,CAAC,SAAS,EAAE,CACvD,IACgB,UAAU,QAAQ,QAAQ;AACzC,aAAU,MAAM;AAChB,aAAU;AACV,WAAQ,KAAK;IAAE,UAAU;IAAO,SAAS;IAAkD,CAAC;;AAI9F,MACE,UAAU,YAAY,SAAS,QAAQ,IACvC,UAAU,qBAAqB,WAC/B,UAAU,QAAQ,QAClB;AACA,aAAU,MAAM;AAChB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AASN,KAAI,CAAC,UAAU,YAAY,SAAS,QAAQ,IAAI,UAAU,qBAAqB,QAAQ;AACrF,YAAU,mBAAmB;AAC7B,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SAAS;GACV,CAAC;;AAIJ,KAAI,UAAU,YAAY,SAAS,QAAQ,IAAI,UAAU,qBAAqB,QAE5E;MAAI,UAAU,QAAQ,QAAQ;AAC5B,aAAU,mBAAmB;AAC7B,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AAQN,KAAI,UAAU,SAAS,SAMrB;MAAI,EAJF,UAAU,YAAY,YACtB,UAAU,YAAY,eACtB,UAAU,YAAY,wBAEG;AACzB,aAAU,OAAO;AACjB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SACE;IACH,CAAC;cAED,UAAU,YAAY,eAAe,UAAU,YAAY,0BAC5D,UAAU,eAAe,MAAM,MAAM,MAAM,OAAO,EAClD;AACA,aAAU,OAAO;AACjB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SACE;IACH,CAAC;;;AAQN,KAAI,UAAU,aAAa,SAAS;AAClC,MAAI,UAAU,SAAS,eAAe;AACpC,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,UAAU;AAClC,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAGJ,MAAI,CADmB,UAAU,YAAY,MAAM,MAAM,MAAM,OAAO,EACjD;AACnB,aAAU,WAAW;AACrB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AAQN,KAAI,UAAU,UAAU,QAAQ;AAC9B,MAAI,UAAU,YAAY,UAAU;AAClC,aAAU,QAAQ;AAClB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,YAAY,QAAQ;AAChC,aAAU,QAAQ;AAClB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AASN,KAAI,CAAC,UAAU,YAAY,MAAM,MAAM,MAAM,OAAO,EAAE;AACpD,MAAI,UAAU,iBAAiB,QAAQ;AACrC,aAAU,eAAe;AACzB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAEJ,MAAI,UAAU,cAAc,QAAQ;AAClC,aAAU,YAAY;AACtB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AAMN,KADyB;EAAC;EAAa;EAAW;EAAS,CAAC,SAAS,UAAU,UAAU,IACjE,UAAU,iBAAiB,YAAY;AAE7D,YAAU,eAAe;AACzB,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SAAS,gDAAgD,UAAU,UAAU;GAC9E,CAAC;;CAIJ,MAAM,qBAAqB;EAAC;EAAa;EAAY;EAAa;EAAS;CAC3E,MAAM,iBAAiB;EAAC;EAAmB;EAAgB;EAAkB;EAAO;AACpF,KAAI,mBAAmB,SAAS,UAAU,UAAU,EAAE;EACpD,MAAM,mBAAmB,UAAU,YAAY,MAAM,MAAM,eAAe,SAAS,EAAE,CAAC;EACtF,MAAM,gBACJ,UAAU,YAAY,SAAS,QAAQ,IAAI,UAAU,qBAAqB;AAC5E,MAAI,CAAC,oBAAoB,CAAC,iBAAiB,UAAU,YAAY,MAAM,MAAM,MAAM,OAAO,EAAE;AAE1F,aAAU,YAAY;AACtB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SACE;IACH,CAAC;;;AAKN,KAAI,UAAU,cAAc,eAAe;EACzC,MAAM,mBAAmB,UAAU,YAAY,MAAM,MAAM,eAAe,SAAS,EAAE,CAAC;EACtF,MAAM,iBAAiB,UAAU,YAAY,SAAS,OAAO;EAC7D,MAAM,qBACJ,UAAU,YAAY,SAAS,QAAQ,IACvC,CAAC,SAAS,MAAM,CAAC,SAAS,UAAU,iBAAiB;AACvD,MAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,oBAAoB;AAC/D,aAAU,YAAY;AACtB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AAKN,KAAI,UAAU,cAAc,WAAW;EACrC,MAAM,mBAAmB,UAAU,YAAY,MAAM,MAAM,eAAe,SAAS,EAAE,CAAC;EACtF,MAAM,iBAAiB,UAAU,YAAY,SAAS,OAAO;EAC7D,MAAM,mBAAmB,UAAU,YAAY,SAAS,QAAQ;EAChE,MAAM,qBACJ,UAAU,YAAY,SAAS,QAAQ,IACvC;GAAC;GAAS;GAAO;GAAQ,CAAC,SAAS,UAAU,iBAAiB;AAChE,MACE,CAAC,oBACD,CAAC,kBACD,CAAC,oBACD,CAAC,sBACD,UAAU,YAAY,MAAM,MAAM,MAAM,OAAO,EAC/C;AACA,aAAU,YAAY;AACtB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;CAQN,MAAM,YAAY,yBAAyB,UAAU,YAAY;CACjE,MAAM,cAAc,2BAA2B,UAAU,YAAY;AAErE,KAAI,CAAC,aAAa,UAAU,aAAa,SAAS,MAAM,EAAE;AACxD,YAAU,eAAe,UAAU,aAAa,QAAQ,MAAM,MAAM,MAAM;AAC1E,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SAAS;GACV,CAAC;;AAEJ,KAAI,CAAC,eAAe,UAAU,aAAa,SAAS,QAAQ,EAAE;AAC5D,YAAU,eAAe,UAAU,aAAa,QAAQ,MAAM,MAAM,QAAQ;AAC5E,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SAAS;GACV,CAAC;;AAQJ,KAAI,UAAU,SAAS,SAAS,KAAK,EAAE;AAErC,MAAI,UAAU,YAAY,SAAS,QAAQ,IAAI,UAAU,YAAY,SAAS,cAAc,EAAE;AAC5F,aAAU,WAAW,UAAU,SAAS,QAAQ,MAAM,MAAM,KAAK;AACjE,OAAI,UAAU,SAAS,WAAW,EAAG,WAAU,WAAW,CAAC,OAAO;AAClE,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAGJ,MAAI,UAAU,YAAY,UAIxB;OAHgC,UAAU,YAAY,MAAM,MAC1D,CAAC,UAAU,OAAO,CAAC,SAAS,EAAE,CAC/B,EAC4B;AAC3B,cAAU,WAAW,UAAU,SAAS,QAAQ,MAAM,MAAM,KAAK;AACjE,QAAI,UAAU,SAAS,WAAW,EAAG,WAAU,WAAW,CAAC,OAAO;AAClE,cAAU;AACV,YAAQ,KAAK;KACX,UAAU;KACV,SAAS;KACV,CAAC;;;;AAMR,KAAI,UAAU,SAAS,SAAS,WAAW,EACzC;MAAI,CAAC,0BAA0B,UAAU,EAAE;AACzC,aAAU,WAAW,UAAU,SAAS,QAAQ,MAAM,MAAM,WAAW;AACvE,OAAI,UAAU,SAAS,WAAW,EAAG,WAAU,WAAW,CAAC,OAAO;AAClE,aAAU;GAEV,IAAI,SAAS;AACb,OAAI,UAAU,cAAc,aAC1B,UAAS;YACA,UAAU,YAAY,SAC/B,UAAS;YACA,UAAU,YAAY,OAC/B,UAAS;YACA,UAAU,YAAY,UAAU,UAAU,YAAY,OAC/D,UAAS;YACA,UAAU,QAAQ,WAAW,QAAQ,CAC9C,UAAS;AAGX,WAAQ,KAAK;IACX,UAAU;IACV,SAAS,qBAAqB,OAAO;IACtC,CAAC;aACO,wBAAwB,UAAU,IAAI,UAAU,UAAU,aAAa;AAChF,aAAU,QAAQ;AAClB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AAWN,KAFgB,UAAU,YAAY,SAAS,QAAQ,EAE1C;AAEX,MAAI,UAAU,UAAU,iBAAiB;AACvC,aAAU,QAAQ;AAClB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;AAKJ,MADiC;GAAC;GAAc;GAAU;GAAiB,CAC9C,SAAS,UAAU,gBAAgB,EAAE;GAChE,MAAM,WAAW,UAAU;AAC3B,aAAU,kBAAkB;AAC5B,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS,mCAAmC,SAAS;IACtD,CAAC;;AAIJ,MAAI,UAAU,cAAc,UAAU;AACpC,aAAU,YAAY;AACtB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AASN,KAAI,UAAU,cAAc,UAAU,CAAC,UAAU,YAAY,MAAM,MAAM,MAAM,OAAO,EAAE;AACtF,YAAU,YAAY;AACtB,YAAU;AACV,UAAQ,KAAK;GAAE,UAAU;GAAa,SAAS;GAA8C,CAAC;;AAIhG,KAAI,UAAU,iBAAiB,cAC7B;MAAI,UAAU,YAAY,aAAa,UAAU,YAAY,QAAQ;AACnE,aAAU,eAAe;AACzB,aAAU;AACV,WAAQ,KAAK;IACX,UAAU;IACV,SAAS;IACV,CAAC;;;AAIN,KACE,UAAU,iBAAiB,UAC3B;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,SAAS,UAAU,QAAQ,EAC7B;AACA,YAAU,eAAe;AACzB,YAAU;AACV,UAAQ,KAAK;GACX,UAAU;GACV,SAAS;GACV,CAAC;;AAGJ,QAAO;EACL,eAAe,UAAU,YAAY;EACrC;EACA;EACD;;;;;;;;;;AAWH,MAAa,qBACX,cACA,UACA,aACkB;AAIlB,KAAI,aAAa,YAAY,UAAU;AACrC,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,cAAc,aAAa,OAC1C,QAAO;AAET,MAAI,aAAa,SAAS,aAAa,OACrC,QAAO;AAET,MAAI,aAAa,SAAS,aAAa,OACrC,QAAO;AAET,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;AAET,MAAI,aAAa,YAAY,aAAa,OACxC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,OAC7C,QAAO;AAET,MAAI,aAAa,UAAU,aAAa,eAQtC;OAAI,EANF,aAAa,YAAY,MAAM,MAC7B;IAAC;IAAmB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1D,IACD,aAAa,eAAe,MAAM,MAChC;IAAC;IAAe;IAAkB;IAAmB,CAAC,SAAS,EAAE,CAClE,EAED,QAAO;;AAGX,MAAI,aAAa,iBAAiB,aAAa,QAC7C,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,QAC7C,QAAO;AAET,MAAI,aAAa,cAAc,aAAa,MAI1C;OAHgC,aAAa,YAAY,MAAM,MAC7D;IAAC;IAAS;IAAU;IAAO,CAAC,SAAS,EAAE,CACxC,CAKC,QAAO,8DAHc,aAAa,YAAY,MAAM,MAClD;IAAC;IAAS;IAAU;IAAO,CAAC,SAAS,EAAE,CACxC,CACiF;;AAGtF,MAAI,aAAa,cAAc,aAAa,QAC1C,QAAO;;AAOX,KAAI,aAAa,YAAY,QAAQ;AACnC,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,cAAc,aAAa,OAC1C,QAAO;AAET,MAAI,aAAa,SAAS,aAAa,OACrC,QAAO;AAET,MAAI,aAAa,SAAS,aAAa,OACrC,QAAO;AAET,MAAI,aAAa,UAAU,aAAa,OACtC,QAAO;AAET,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;AAET,MAAI,aAAa,cAAc,aAAa,OAC1C,QAAO;AAET,MAAI,aAAa,YAAY,aAAa,OACxC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,OAC7C,QAAO;AAET,MAAI,aAAa,cAAc,aAAa,OAC1C,QAAO;;AAOX,KAAI,aAAa,YAAY,aAAa;AACxC,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,UAAU,aAAa,OACpE,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;;AAIX,KAAI,aAAa,YAAY,uBAAuB;AAClD,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,oBAAoB,aAAa,OAC9E,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;;AAIX,KAAI,aAAa,YAAY,cAAc;AACzC,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,WAAW,aAAa,OACrE,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;;AAIX,KAAI,aAAa,YAAY,aAAa;AACxC,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,UAAU,aAAa,OACpE,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;;AAIX,KAAI,aAAa,YAAY,eAAe;AAC1C,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,YAAY,aAAa,OACtE,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;;AAIX,KAAI,aAAa,YAAY,oBAAoB;AAC/C,MAAI,aAAa,aAAa,aAAa,OACzC,QAAO;AAET,MAAI,aAAa,iBAAiB,aAAa,iBAAiB,aAAa,OAC3E,QAAO;AAET,MAAI,aAAa,kBAAkB,aAAa,OAC9C,QAAO;;AAOX,KAAI,aAAa,WAAW;AAC1B,MAAI,aAAa,eAAe,CAAC,aAAa,YAAY,SAAS,OAAO,CACxE,QAAO;AAET,MACE,aAAa,yBACb,CAAC,aAAa,YAAY,SAAS,iBAAiB,CAEpD,QAAO;AAET,MAAI,aAAa,gBAAgB,CAAC,aAAa,YAAY,SAAS,QAAQ,CAC1E,QAAO;AAET,MAAI,aAAa,eAAe,CAAC,aAAa,YAAY,SAAS,OAAO,CACxE,QAAO;AAET,MAAI,aAAa,iBAAiB,CAAC,aAAa,YAAY,SAAS,SAAS,CAC5E,QAAO;AAET,MAAI,aAAa,sBAAsB,CAAC,aAAa,YAAY,SAAS,cAAc,CACtF,QAAO;AAET,MAAI,aAAa,YAAY,aAAa,YAAY,SAAS,QAAQ,CACrE,QAAO;AAET,MAAI,aAAa,YAAY,aAAa,YAAY,SAAS,cAAc,CAC3E,QAAO;AAET,MAAI,aAAa,YAAY,aAAa,YAAY,SAAS,QAAQ,CACrE,QAAO;AAGT,MAAI,aAAa,YAAY,aAAa,aAAa,UAAU,aAAa,OAC5E,QAAO;;AAOX,KAAI,aAAa,WAAW;AAC1B,MAAI,aAAa,aAAa,aAAa,YAAY,OACrD,QAAO;AAET,MAAI,aAAa,QAWf;OAAI,CAVoB;IACtB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CACoB,SAAS,aAAa,QAAQ,CACjD,QAAO;;;AAQb,KAAI,aAAa,YACf;MAAI,aAAa,aAAa,aAAa,YAAY,UACrD,QAAO;;AAQX,KAAI,aAAa,OAAO;AACtB,MAAI,aAAa,YAAY;AAC3B,OAAI,aAAa,YAAY,UAC3B,QAAO;AAGT,OAAI,aAAa,aAAa,UAAU,aAAa,aAAa,UAChE,QAAO;;AAIX,MAAI,aAAa,aAAa,aAAa,aAAa,UACtD,QAAO;AAET,MAAI,aAAa,UAAU,aAAa,aAAa,OACnD,QAAO;;AAOX,KAAI,aAAa,aAAa,aAAa,QAAQ;AACjD,MAAI,aAAa,aAAa,OAC5B,QAAO;AAIT,MAAI,aAAa,WAAW,aAAa,aAAa,SACpD,QAAO;AAET,MAAI,aAAa,MAAM;AACrB,OAAI,aAAa,aAAa,SAAU,QAAO;AAC/C,OAAI,aAAa,YAAY,UAAW,QAAO;;AAEjD,MAAI,aAAa,UAAU,aAAa,aAAa,WACnD,QAAO;AAET,MAAI,aAAa,cAAc,aAAa,aAAa,WACvD,QAAO;AAET,MAAI,aAAa,qBAAqB,aAAa,aAAa,WAC9D,QAAO;AAET,MAAI,aAAa,mBAAmB,aAAa,aAAa,UAC5D,QAAO;AAET,MACE,aAAa,iBACb,aAAa,aAAa,cAC1B,aAAa,aAAa,QAE1B,QAAO;AAET,MAAI,aAAa,UAAU;AACzB,OAAI,aAAa,aAAa,SAAU,QAAO;AAC/C,OAAI,aAAa,YAAY,UAAW,QAAO;;;AAOnD,KAAI,aAAa,SAAS,aAAa,QAAQ;AAI7C,MAHkB,aAAa,YAAY,MAAM,MAC/C;GAAC;GAAQ;GAAU;GAAS;GAAc,CAAC,SAAS,EAAE,CACvD,CAKC,QAAO,GAHc,aAAa,YAAY,MAAM,MAClD;GAAC;GAAQ;GAAU;GAAS;GAAc,CAAC,SAAS,EAAE,CACvD,CACsB;AAGzB,MACE,aAAa,YAAY,SAAS,QAAQ,IAC1C,aAAa,qBAAqB,WAClC,aAAa,qBAAqB,OAElC,QAAO,cAAc,aAAa,iBAAiB;;AAOvD,KAAI,aAAa,oBAAoB;AACnC,MAAI,CAAC,aAAa,YAAY,SAAS,QAAQ,IAAI,aAAa,OAC9D,QAAO;AAGT,MAAI,aAAa,QAAQ,UAAU,aAAa,WAAW,aAAa,OACtE,QAAO;;AAOX,KAAI,aAAa,QACf;MAAI,aAAa,QACf,KAAI,aAAa,YAAY,UAQ3B;OAAI,EANF,aAAa,YAAY,MAAM,MAC7B;IAAC;IAAgB;IAAmB;IAAkB;IAAO,CAAC,SAAS,EAAE,CAC1E,IACD,aAAa,eAAe,MAAM,MAChC;IAAC;IAAe;IAAkB;IAAmB,CAAC,SAAS,EAAE,CAClE,EAED,QAAO;aAGT,aAAa,YAAY,eACzB,aAAa,YAAY,uBAEzB;OAAI,aAAa,eAAe,MAAM,MAAM,MAAM,OAAO,CACvD,QAAO;aAEA,aAAa,YAAY,aAClC,QAAO;WACE,aAAa,YAAY,YAClC,QAAO;WACE,aAAa,YAAY,cAClC,QAAO;WACE,aAAa,YAAY,mBAClC,QAAO;WACE,aAAa,YAAY,OAClC,QAAO;MAEP,QAAO;;AAQb,KAAI,aAAa,cAAc,aAAa,SAAS;AACnD,MAAI,aAAa,SAAS,cACxB,QAAO;AAET,MAAI,CAAC,aAAa,YAAY,MAAM,MAAM,MAAM,OAAO,CACrD,QAAO;;AAOX,KAAI,aAAa,WAAW,aAAa,QAAQ;AAC/C,MAAI,aAAa,YAAY,SAC3B,QAAO;AAET,MAAI,aAAa,YAAY,OAC3B,QAAO;;AAOX,KAAI,aAAa,QAAQ,wBAAwB,aAAa,IAAI,aAAa,YAC7E,QAAO;AAMT,KAAI,aAAa,gBAAgB;AAC/B,MAAI,aAAa,SAAS,CAAC,yBAAyB,aAAa,YAAY,CAC3E,QAAO;AAET,MAAI,aAAa,WAAW,CAAC,2BAA2B,aAAa,YAAY,CAC/E,QAAO;;AAOX,KAAI,aAAa,YAAY;AAC3B,MAAI,aAAa,MAAM;AACrB,OACE,aAAa,YAAY,SAAS,QAAQ,IAC1C,aAAa,YAAY,SAAS,cAAc,CAEhD,QAAO;AAET,OAAI,aAAa,YAAY,UAI3B;QAHgC,aAAa,YAAY,MAAM,MAC7D,CAAC,UAAU,OAAO,CAAC,SAAS,EAAE,CAC/B,CAGC,QAAO,8DADc,aAAa,YAAY,MAAM,MAAM,CAAC,UAAU,OAAO,CAAC,SAAS,EAAE,CAAC,CACP;;;AAKxF,MAAI,aAAa,YAAY;AAC3B,OAAI,aAAa,cAAc,aAC7B,QAAO;AAET,OAAI,aAAa,YAAY,SAC3B,QAAO;AAET,OACE,aAAa,YAAY,gBACzB,aAAa,YAAY,iBACzB,aAAa,YAAY,mBAEzB,QAAO;AAET,OAAI,aAAa,YAAY,eAAe,aAAa,YAAY,sBACnE,QAAO;AAET,OAAI,aAAa,YAAY,YAC3B,QAAO;AAET,OAAI,aAAa,YAAY,QAAQ;AACnC,QAAI,aAAa,YAAY,OAC3B,QAAO;AAET,WAAO;;AAET,OAAI,aAAa,QAAQ,WAAW,QAAQ,CAC1C,QAAO;AAET,OAAI,aAAa,YAAY,OAC3B,QAAO;;;CASb,MAAM,UAAU,aAAa,YAAY,SAAS,QAAQ;AAG1D,KAAI,aAAa,WAAW,aAAa,mBAAmB,QAC1D,QAAO;AAIT,KAAI,aAAa,qBAAqB,SAAS;AAC7C,MAAI,aAAa,aACf,QAAO;AAET,MAAI,aAAa,SACf,QAAO;AAET,MAAI,aAAa,iBACf,QAAO;;AAKX,KAAI,aAAa,eAAe,aAAa,YAAY,QACvD,QAAO;AAMT,KAAI,aAAa,gBAAgB;AAE/B,MAAI,CAAC,aAAa,YAAY,MAAM,MAAM,MAAM,OAAO,EACrD;OAAI,aAAa,OACf,QAAO;;AAKX,MADyB;GAAC;GAAa;GAAW;GAAS,CAAC,SAAS,aAAa,UAAU,IACpE,aAAa,WACnC,QAAO,GAAG,aAAa,cAAc,cAAc,cAAc,aAAa,cAAc,YAAY,YAAY,SAAS;;AAOjI,KAAI,aAAa,aAAa;AAE5B,MAAI,CAAC,aAAa,YAAY,MAAM,MAAM,MAAM,OAAO,EACrD;OAAI,aAAa,OACf,QAAO;;EAKX,MAAM,qBAAqB;GAAC;GAAa;GAAY;GAAa;GAAS;EAC3E,MAAM,iBAAiB;GAAC;GAAmB;GAAgB;GAAkB;GAAO;AAEpF,MAAI,mBAAmB,SAAS,SAAS,EAAE;GACzC,MAAM,mBAAmB,aAAa,YAAY,MAAM,MAAM,eAAe,SAAS,EAAE,CAAC;GAEzF,MAAM,gBACJ,aAAa,YAAY,SAAS,QAAQ,IAAI,aAAa,qBAAqB;AAClF,OAAI,CAAC,oBAAoB,CAAC,cASxB,QAAO,GAPL,aAAa,cACT,cACA,aAAa,aACX,aACA,aAAa,cACX,cACA,SACY;;AAK1B,MAAI,aAAa,eAAe;GAC9B,MAAM,mBAAmB,aAAa,YAAY,MAAM,MAAM,eAAe,SAAS,EAAE,CAAC;GACzF,MAAM,iBAAiB,aAAa,YAAY,SAAS,OAAO;GAChE,MAAM,qBACJ,aAAa,YAAY,SAAS,QAAQ,IAC1C,CAAC,SAAS,MAAM,CAAC,SAAS,aAAa,iBAAiB;AAC1D,OAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,mBAC3C,QAAO;;AAKX,MAAI,aAAa,WAAW;GAC1B,MAAM,mBAAmB,aAAa,YAAY,MAAM,MAAM,eAAe,SAAS,EAAE,CAAC;GACzF,MAAM,iBAAiB,aAAa,YAAY,SAAS,OAAO;GAChE,MAAM,mBACJ,aAAa,YAAY,SAAS,QAAQ,IAC1C,aAAa,YAAY,SAAS,cAAc;GAClD,MAAM,qBACJ,aAAa,YAAY,SAAS,QAAQ,IAC1C;IAAC;IAAS;IAAO;IAAQ,CAAC,SAAS,aAAa,iBAAiB;AACnE,OAAI,CAAC,oBAAoB,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,mBAChE,QAAO;AAGT,OAAI,aAAa,iBAAiB,OAChC,QAAO;;AAKX,MAAI;GAAC;GAAa;GAAW;GAAS,CAAC,SAAS,SAAS,EACvD;OAAI,aAAa,iBAAiB,WAGhC,QAAO,GADL,aAAa,cAAc,cAAc,aAAa,YAAY,YAAY,SAC1D;;;AAQ5B,KAAI,aAAa,eAAe,aAAa,QAC3C;MAAI,CAAC,aAAa,YAAY,MAAM,MAAM,MAAM,OAAO,CACrD,QAAO;;AAIX,KAAI,aAAa,gBAAgB;AAC/B,MAAI,aAAa,cAAc;AAC7B,OAAI,aAAa,YAAY,UAC3B,QAAO;AAET,OAAI,aAAa,YAAY,OAC3B,QAAO;;AAGX,MAAI,aAAa,QAWf;OAVuB;IACrB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACD,CACkB,SAAS,aAAa,QAAQ,CAC/C,QAAO;;AAGX,MAAI,aAAa,UAAU,aAAa,YAAY,UAClD,QAAO;;AAIX,QAAO;;AAGT,MAAa,sBACX,cACA,UACA,aACY;AACZ,KAAI,aAAa,SAAS,OACxB,QAAO;AAET,QAAO,kBAAkB,cAAc,UAAU,SAAS,KAAK;;AAGjE,MAAMC,iBAAsC;CAC1C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAMC,2BAMF;CACF,aAAa;EACX,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;EACjF,eAAe,CAAC,WAAW;EAC5B;CACD,SAAS;EACP,WAAW;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACD,eAAe,CAAC,WAAW;EAC5B;CACD,YAAY;EACV,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;EACjF,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACD,eAAe;EACb,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;GAAQ;EACzF,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACD,WAAW;EACT,WAAW;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACD,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAe;EAC5D;CACD,aAAa;EACX,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;EACjF,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACD,QAAQ;EACN,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;EACjF,eAAe,CAAC,WAAW;EAC5B;CACD,SAAS;EACP,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;EACjF,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACD,WAAW;EACT,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;EACjF,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACD,UAAU;EACR,WAAW;GACT;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EACD,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACD,cAAc;EACZ,WAAW;GAAC;GAAmB;GAAgB;GAAkB;GAAQ;GAAQ;EACjF,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACD,MAAM;EACJ,WAAW;EACX,eAAe;GAAC;GAAY;GAAQ;GAAQ;GAAgB;GAAO;EACpE;CACF;AAED,MAAMC,sBAA2D;CAC/D,KAAK;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD;CACD,OAAO,EAAE;CACT,OAAO,EAAE;CACT,UAAU,EAAE;CACZ,WAAW,EAAE;CACb,WAAW,EAAE;CACb,WAAW,EAAE;CACb,OAAO,EAAE;CACT,KAAK,EAAE;CACP,QAAQ,EAAE;CACV,QAAQ,EAAE;CACV,UAAU,EAAE;CACZ,SAAS,EAAE;CACX,KAAK,EAAE;CACP,KAAK,EAAE;CACP,WAAW;EAAC;EAAmB;EAAgB;EAAQ;EAAQ;EAAU;EAAQ;CACjF,MAAM,EAAE;CACT;AAED,SAAgB,cAAc,OAAiB;AAC7C,QAAO,eAAe,SAAS,MAAM;;AAGvC,SAAgB,eAAe,SAAqB,EAAE,EAGpD;AAKA,QAAO;EAAE,KAJG,OAAO,QAAQ,MAAM,cAAc,EAAE,CAAC;EAIpC,QAHC,OAAO,QACnB,MAAM,MAAM,iBAAiB,MAAM,oBAAoB,MAAM,mBAC/D;EACqB;;AAGxB,SAAgB,wBACd,YAAwB,EAAE,EAC1B,kBACA;CACA,MAAM,eAAe,UAAU,SAAS,OAAO;CAC/C,MAAM,iBAAiB,UAAU,SAAS,SAAS;CACnD,MAAM,gBAAgB,UAAU,SAAS,QAAQ;CACjD,MAAM,gBAAgB,UAAU,SAAS,QAAQ;CACjD,MAAM,eAAe,UAAU,SAAS,OAAO;CAC/C,MAAM,kBAAkB,UAAU,SAAS,UAAU;CACrD,MAAM,kBAAkB,UAAU,SAAS,UAAU;CACrD,MAAM,gBAAgB,UAAU,SAAS,QAAQ;CACjD,MAAMC,OAAc;EAAC;EAAQ;EAAQ;EAAW;EAAS;EAAO;AAEhE,KAAI,gBAAgB,mBAAmB,mBAAmB,cACxD,QAAO,CAAC,OAAO;CAGjB,MAAM,wBAAwB,UAAU,SAAS,cAAc;AAC/D,KAAI,gBAAgB,kBAAkB,iBAAiB,sBACrD,QAAO,CAAC,QAAQ,OAAO;AAGzB,KAAI,iBAAiB,oBAAoB,qBAAqB,QAC5D,QAAO,CAAC,QAAQ,OAAO;AAGzB,QAAO;;AAGT,SAAgB,6BAA6B,UAAoB,SAAmB,MAAe;AACjG,KAAI,YAAY,YAAY,aAAa,QAAS,QAAO;AACzD,KAAI,YAAY,YAAY,aAAa,cAAe,QAAO;AAC/D,KAAI,YAAY,YAAY,aAAa,QAAS,QAAO;AACzD,KAAI,YAAY,YAAY,aAAa,OAAQ,QAAO;AACxD,KAAI,YAAY,YAAY,aAAa,UAAW,QAAO;AAC3D,KAAI,YAAY,YAAY,aAAa,UAAW,QAAO;AAC3D,KAAI,YAAY,YAAY,aAAa,QAAS,QAAO;AAEzD,KAAI,aAAa,UAAU,WAAW,YAAY,OAAQ,QAAO;AACjE,KAAI,aAAa,aAAa,WAAW,YAAY,OAAQ,QAAO;AACpE,KAAI,aAAa,aAAa,WAAW,YAAY,OAAQ,QAAO;AACpE,KAAI,aAAa,WAAW,WAAW,YAAY,OAAQ,QAAO;AAElE,KAAI,SAAS,WAAW,YAAY,UAElC;MAD8B;GAAC;GAAQ;GAAU;GAAS;GAAc,CAC9C,SAAS,SAAS,CAAE,QAAO;;AAGvD,KAAI,SAAS,WAAW,YAAY,QAClC;MAAI,CAAC,CAAC,QAAQ,iBAAiB,CAAC,SAAS,SAAS,CAAE,QAAO;;AAG7D,KAAI,SAAS,YAAY;AACvB,MAAI,aAAa,OAAQ,QAAO;AAChC,MAAI,YAAY,OAAQ,QAAO;;AAGjC,KAAI,SAAS,iBAAiB;AAC5B,MAAI,aAAa,OAAQ,QAAO;AAChC,MAAI,YAAY,OAAQ,QAAO;;AAGjC,QAAO;;AAGT,SAAgB,mBAAmB,SAAmB,YAAwB,EAAE,EAAE;CAChF,MAAM,gBAAgB,UAAU,SAAS,QAAQ;CACjD,MAAM,qBAAqB,UAAU,SAAS,cAAc;AAC5D,KAAI,iBAAiB,mBAAoB,QAAO;AAEhD,KAAI,YAAY,UAAU;EACxB,MAAM,eAAe,UAAU,SAAS,OAAO;EAC/C,MAAM,iBAAiB,UAAU,SAAS,SAAS;AACnD,MAAI,gBAAgB,eAAgB,QAAO;;AAG7C,QAAO;;AAGT,SAAS,8BAA8B,YAAwB,EAAE,EAAE;AACjE,QAAO,UAAU,MAAM,MAAM;EAAC;EAAQ;EAAkB;EAAO,CAAC,SAAS,EAAE,CAAC;;AAG9E,SAAgB,wBACd,SACA,YAAwB,EAAE,EAC1B,SACA;AACA,KAAI,CAAC,WAAW,YAAY,UAAU,YAAY,SAAU,QAAO;AAEnE,KAAI,YAAY,OACd,QAAO,8BAA8B,UAAU;AAGjD,KAAI,YAAY,eAAe,YAAY,yBAAyB,YAAY,YAC9E,QAAO;AAGT,KAAI,YAAY,gBAAgB,YAAY,iBAAiB,YAAY,mBACvE,QAAO;AAGT,KAAI,YAAY,OACd,QAAO,YAAY;AAGrB,QAAO;;AAGT,SAAgB,oCACd,SACA,YAAwB,EAAE,EAC1B,SACA;AACA,KAAI,YAAY,UAAU,UAAU,SAAS,OAAO,CAAE,QAAO;AAC7D,KAAI,YAAY,YAAa,QAAO;AACpC,KAAI,YAAY,UAAU,YAAY,OAAQ,QAAO;AACrD,QAAO;;AAGT,SAAgB,2BACd,OACA,UACA,OAC4C;CAC5C,MAAM,sBAAsB,oBAAoB;AAEhD,KAAI,oBAAoB,SAAS,GAK/B;MAAI,CAJ0B,SAAS,MAAM,MAC1C,oBAA0C,SAAS,EAAE,CACvD,CAIC,QAAO;GACL,cAAc;GACd,QAAQ,GAAG,MAAM,0CAHE,oBAAoB,KAAK,KAAK;GAIlD;;AAIL,QAAO,EAAE,cAAc,MAAM;;AAG/B,SAAgB,oBACd,WACA,UACA,iBAA2B,EAAE,EAC7B,MACA;AACA,QAAO,UAAU,QAAQ,UAAU;AACjC,MAAI,eAAe,SAAS,MAAM,CAAE,QAAO;AAC3C,MAAI,UAAU,OAAQ,QAAO;EAC7B,MAAM,EAAE,iBAAiB,2BAA2B,OAAO,UAAU,KAAK;AAC1E,SAAO;GACP;;AAGJ,SAAgB,yBACd,YAAwB,EAAE,EAC1B,kBACa;CACb,MAAM,EAAE,QAAQ,eAAe,UAAU;AACzC,KAAI,IAAI,WAAW,EAAG,QAAO,CAAC,OAAO;CAErC,MAAM,cAAc,IAAI;AAGxB,QAFuB,OAAO,KAAK,yBAAyB,CAEtC,QAAQ,QAAQ;AACpC,MAAI,QAAQ,OAAQ,QAAO;EAE3B,MAAM,gBAAgB,yBAAyB;AAC/C,MAAI,gBAAgB,SAAS;AAC3B,OAAI,qBAAqB,QACvB,QAAO,cAAc,UAAU,MAAM,MACnC;IAAC;IAAmB;IAAgB;IAAkB;IAAQ;IAAQ,CAAC,SAAS,EAAE,CACnF;AAEH,UAAO,cAAc,UAAU,MAAM,MACnC;IAAC;IAAQ;IAAU;IAAS;IAAQ;IAAU,CAAC,SAAS,EAAE,CAC3D;;AAGH,SAAO,cAAc,UAAU,SAAS,YAAY;GACpD;;AAGJ,SAAgB,2BAA2B,WAAkD;AAC3F,KAAI,CAAC,aAAa,cAAc,OAC9B,QAAO;EAAC;EAAY;EAAQ;EAAQ;EAAgB;EAAO;AAI7D,QADsB,yBAAyB,WAC1B;;AAGvB,SAAgB,cAAc,YAAwB,EAAE,EAAW;CACjE,MAAM,EAAE,QAAQ,eAAe,UAAU;AACzC,QAAO,IAAI,SAAS;;AAGtB,SAAgB,2BAA2B,YAAwB,EAAE,EAAW;CAC9E,MAAM,WAAW,UAAU,SAAS,QAAQ;CAC5C,MAAM,gBAAgB,UAAU,SAAS,cAAc;CACvD,MAAM,UAAU,UAAU,SAAS,OAAO;CAC1C,MAAM,WAAW,UAAU,SAAS,QAAQ;CAE5C,MAAMC,MAAe;EACnB;EACA;EACA;EACA;EACA;EACA;EACA;EACD;AAED,KAAI,SACF,QAAO,IAAI,QAAQ,MAAM,MAAM,mBAAmB,MAAM,qBAAqB,MAAM,SAAS;AAG9F,KAAI,YAAY,iBAAiB,QAC/B,QAAO,IAAI,QAAQ,MAAM,MAAM,qBAAqB,MAAM,YAAY,MAAM,aAAa;AAG3F,QAAO;;AAGT,SAAgB,sBAAsB,OAAoD;CACxF,MAAMC,SAA+B,EAAE;CAEvC,MAAMC,eAAuD;EAC3D,CAAC,WAAW,MAAM,QAAQ;EAC1B,CAAC,WAAW,MAAM,QAAQ;EAC1B,CAAC,YAAY,MAAM,SAAS;EAC5B,CAAC,OAAO,MAAM,IAAI;EAClB,CAAC,WAAW,MAAM,QAAQ;EAC1B,CAAC,OAAO,MAAM,IAAI;EAClB,CAAC,QAAQ,MAAM,KAAK;EACpB,CAAC,YAAY,MAAM,SAAS;EAC5B,CAAC,SAAS,MAAM,MAAM;EACtB,CAAC,gBAAgB,MAAM,aAAa;EACpC,CAAC,aAAa,MAAM,UAAU;EAC9B,CAAC,aAAa,MAAM,UAAU;EAC9B,CAAC,gBAAgB,MAAM,aAAa;EACpC,CAAC,SAAS,MAAM,MAAM;EACtB,CAAC,mBAAmB,MAAM,gBAAgB;EAC1C,CAAC,aAAa,MAAM,UAAU;EAC9B,CAAC,MAAM,MAAM,MAAM;EACpB;AAED,MAAK,MAAM,CAAC,UAAU,aAAa,cAAc;EAC/C,MAAM,SAAS,kBAAkB,OAAO,UAAU,SAAS;AAC3D,MAAI,OACF,QAAO,KAAK;GACV,MAAM,gBAAgB,SAAS,aAAa;GAC5C,SAAS;GACT;GACA;GACD,CAAC;;AAIN,MAAK,MAAM,YAAY,MAAM,aAAa;EACxC,MAAM,SAAS,kBAAkB,OAAO,eAAe,SAAS;AAChE,MAAI,OACF,QAAO,KAAK;GACV,MAAM;GACN,SAAS;GACT,UAAU;GACV,UAAU;GACX,CAAC;;AAIN,MAAK,MAAM,SAAS;EAAC,GAAG,MAAM;EAAa,GAAG,MAAM;EAAe,GAAG,MAAM;EAAa,EAAE;EACzF,MAAM,SAAS,kBAAkB,OAAO,gBAAgB,MAAM;AAC9D,MAAI,OACF,QAAO,KAAK;GACV,MAAM;GACN,SAAS;GACT,UAAU;GACV,UAAU;GACX,CAAC;;AAIN,QAAO,EAAE,QAAQ"}