@wairon/cli 5.0.1-dev.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/models/agent.ts","../src/models/domain.ts","../src/models/project.ts","../src/models/registry.ts","../src/models/template.ts","../src/models/specs.ts","../src/models/index.ts","../src/utils/fs.ts","../src/utils/yaml.ts","../src/utils/errors.ts","../src/core/narrative-labels.ts","../src/core/rules/type-analysis.ts","../src/core/canvas-layout.ts","../src/core/diagram-export.ts","../src/core/canvas.ts","../src/core/extensions.ts","../src/core/rules/types.ts","../src/core/rules/hierarchy.ts","../src/core/rules/type-references.ts","../src/core/statehash.ts","../src/core/openapi.ts","../src/core/surfaces.ts","../src/core/rules/namespace.ts","../src/core/rules/contracts.ts","../src/core/rules/narrative-flow.ts","../src/core/source-analysis.ts","../src/core/rules/conformance.ts","../src/core/rules/complexity.ts","../src/core/rules/narrative-detail.ts","../src/core/rules/portals.ts","../src/core/rules/stereotype-deps.ts","../src/core/rules/patterns.ts","../src/core/rules/facade-forwarding.ts","../src/core/rules/pattern-references.ts","../src/core/rules/variant-references.ts","../src/core/rules/declarative-assertions.ts","../src/core/rules/profiles.ts","../src/core/rules/public-surface.ts","../src/core/rules/graph.ts","../src/core/rules/semantic-edges.ts","../src/core/rules/invariants.ts","../src/core/rules/guarantee-tokens.ts","../src/core/rules/event-topology.ts","../src/core/rules/narrative-antipatterns.ts","../src/core/rules/call-conformance.ts","../src/core/rules/coupling.ts","../src/core/rules/language.ts","../src/core/rules/technology.ts","../src/core/rules/naming.ts","../src/core/rules/integration-conformance.ts","../src/core/rules/hidden-state.ts","../src/core/rules/dependency-conformance.ts","../src/core/rules/lint-allows.ts","../src/core/rules/index.ts","../src/core/rules/repository.ts","../src/core/variants.ts","../src/core/validation.ts","../src/core/diagram.ts","../src/core/specs.ts","../src/core/agent_resolver.ts","../src/config/loader.ts","../src/core/domains.ts","../src/index.ts","../src/config/defaults.ts","../src/config/index.ts","../src/core/detection.ts","../src/core/index.ts","../src/core/templates.ts","../src/core/provision.ts","../src/core/lockfile.ts","../src/core/skills.ts","../src/core/context.ts","../src/core/stamp.ts","../src/utils/ai-guide.ts","../src/exporters/base.ts","../src/exporters/claude.ts","../src/exporters/custom.ts","../src/exporters/gemini.ts","../src/exporters/generate.ts","../src/exporters/registry.ts","../src/utils/index.ts","../src/utils/logger.ts"],"sourcesContent":["import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Output target definitions\n// ---------------------------------------------------------------------------\n\nexport const BuiltinTargetSchema = z.enum(['claude', 'gemini', 'agy', 'cursor', 'copilot', 'codex']);\nexport type BuiltinTarget = z.infer<typeof BuiltinTargetSchema>;\n\nexport const CustomTargetSchema = z.object({\n type: z.literal('custom'),\n /** Human-readable label for this target, e.g. \"Cursor\" */\n label: z.string(),\n /** Root output directory relative to the project root, e.g. \".cursor/agents\" */\n outputDir: z.string(),\n});\nexport type CustomTarget = z.infer<typeof CustomTargetSchema>;\n\nexport const OutputTargetSchema = z.union([BuiltinTargetSchema, CustomTargetSchema]);\nexport type OutputTarget = z.infer<typeof OutputTargetSchema>;\n\n// ---------------------------------------------------------------------------\n// Agent status\n// ---------------------------------------------------------------------------\n\nexport const AgentStatusSchema = z.enum(['active', 'draft', 'deprecated']);\nexport type AgentStatus = z.infer<typeof AgentStatusSchema>;\n\n// ---------------------------------------------------------------------------\n// Core agent record — the internal source-of-truth representation\n// ---------------------------------------------------------------------------\n\nexport const AgentRecordSchema = z.object({\n /** Unique identifier within this project, e.g. \"core-service-owner\" */\n id: z.string().regex(/^[a-z0-9-_]+$/, 'Agent id must be lowercase alphanumeric with dashes or underscores'),\n\n /** Human-readable display name */\n name: z.string(),\n\n /** Short description of what this agent is responsible for */\n description: z.string(),\n\n /** Template id this agent was created from, e.g. \"domain-owner\" */\n template: z.string(),\n\n /** Bundle id this agent was created as part of, if applicable */\n bundleOrigin: z.string().optional(),\n\n /**\n * The domain id this agent is responsible for (a subsystem id or a\n * free-standing domain id). Undefined = root-level agent.\n */\n domainRoot: z.string().optional(),\n\n /**\n * Paths this agent owns, expressed relative to the project root.\n * e.g. [\"services/core/**\"]\n */\n ownedPaths: z.array(z.string()).default([]),\n\n /** Paths this agent may read but does not own */\n readPaths: z.array(z.string()).default([]),\n\n /** Paths this agent may write to but does not own */\n writePaths: z.array(z.string()).default([]),\n\n /** Classification tags, e.g. [\"service\", \"backend\", \"critical\"] */\n tags: z.array(z.string()).default([]),\n\n /** Ids of related agents this agent should be aware of */\n dependencies: z.array(z.string()).default([]),\n\n /** Rendered implementation guidance for this agent's variant-tagged components (deep variant integration); empty when none. */\n variantGuidance: z.string().optional(),\n\n /** Why this agent was created — the architectural reason for its existence */\n creationReason: z.string(),\n\n status: AgentStatusSchema.default('active'),\n\n /** Which output targets should receive this agent's generated file */\n targets: z.array(OutputTargetSchema).default(['claude']),\n\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\nexport type AgentRecord = z.infer<typeof AgentRecordSchema>;\n\n// ---------------------------------------------------------------------------\n// Helper: create a minimal valid agent record (useful in tests / stubs)\n// ---------------------------------------------------------------------------\n\nexport function createAgentRecord(\n partial: Pick<AgentRecord, 'id' | 'name' | 'template' | 'creationReason'> &\n Partial<AgentRecord>,\n): AgentRecord {\n const now = new Date().toISOString();\n return AgentRecordSchema.parse({\n description: '',\n ownedPaths: [],\n readPaths: [],\n writePaths: [],\n tags: [],\n dependencies: [],\n status: 'active',\n targets: ['claude'],\n createdAt: now,\n updatedAt: now,\n ...partial,\n });\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Domain — a unit of agent ownership / responsibility in the topology.\n//\n// A *subsystem* (L1 spec) is a software unit; a *domain* is who owns a scope.\n// Every subsystem yields a domain; not every domain comes from a subsystem.\n//\n// Two flavours:\n// - Spec-backed: derived from an L1 subsystem (boundTo = subsystem id).\n// Not hand-maintained — produced by resolveDomains() from the spec tree.\n// - Free-standing: declared in .wai/topology.yaml for cross-cutting scopes\n// (docs, infra, packages) that are not a software subsystem.\n// ---------------------------------------------------------------------------\n\nexport const DomainSchema = z.object({\n /** Unique identifier within the project, e.g. \"billing\" or \"docs\". */\n id: z.string().regex(/^[a-z0-9-_]+$/, 'Domain id must be lowercase alphanumeric with dashes or underscores'),\n\n /** Optional display name. */\n name: z.string().optional(),\n\n /** Optional description of the domain's responsibility. */\n description: z.string().optional(),\n\n /**\n * The spec node this domain binds to: a subsystem id (the common case) or a\n * component id. Omitted means the domain is free-standing.\n */\n boundTo: z.string().optional(),\n\n /** Glob patterns this domain owns. Derived for spec-backed, authored for free-standing. */\n ownedPaths: z.array(z.string()).default([]),\n\n /** Optional physical directory (e.g. a monorepo package or submodule root). */\n path: z.string().optional(),\n});\n\nexport type Domain = z.infer<typeof DomainSchema>;\n\n// ---------------------------------------------------------------------------\n// Topology config — lives at .wai/topology.yaml\n//\n// Holds only FREE-STANDING domains. Spec-backed domains are derived from the\n// spec tree at read time (resolveDomains) and are never stored here.\n// ---------------------------------------------------------------------------\n\nexport const TopologyConfigSchema = z.object({\n schemaVersion: z.string().default('1.0.0'),\n domains: z.array(DomainSchema).default([]),\n});\nexport type TopologyConfig = z.infer<typeof TopologyConfigSchema>;\n\nexport function createEmptyTopologyConfig(): TopologyConfig {\n return { schemaVersion: '1.0.0', domains: [] };\n}\n\n// ---------------------------------------------------------------------------\n// Detection — physical directory candidates (the `domains scan` helper).\n// These describe *candidates* before the user adds them as free-standing\n// domains; they are not the stored domain shape.\n// ---------------------------------------------------------------------------\n\nexport const DomainTypeSchema = z.enum([\n 'git-submodule', // declared in .gitmodules\n 'git-repo', // directory containing a .git folder\n 'package-root', // directory with package.json / pyproject.toml / Cargo.toml / go.mod\n 'manual', // explicitly added by the user\n]);\nexport type DomainType = z.infer<typeof DomainTypeSchema>;\n\nexport interface DetectedDomainCandidate {\n /** Suggested id derived from path */\n suggestedId: string;\n /** Suggested display name */\n suggestedName: string;\n /** Path relative to project root */\n path: string;\n type: DomainType;\n /** Whether this path is already covered by an existing domain */\n alreadyTracked: boolean;\n}\n","import { z } from 'zod';\nimport { CustomTargetSchema } from './agent.js';\n\n// ---------------------------------------------------------------------------\n// Project configuration — lives at .wai/project.yaml\n//\n// This is the primary project-level config. It is human-edited and defines\n// which output targets are active, project metadata, and high-level rules.\n// ---------------------------------------------------------------------------\n\nexport const BuiltinTargetConfigSchema = z.object({\n type: z.enum(['claude', 'gemini', 'agy', 'cursor', 'copilot', 'codex']),\n /** Output directory for generated agent files, relative to project root */\n outputDir: z.string(),\n /** Whether this target is active */\n enabled: z.boolean().default(true),\n});\nexport type BuiltinTargetConfig = z.infer<typeof BuiltinTargetConfigSchema>;\n\nexport const CustomTargetConfigSchema = CustomTargetSchema.extend({\n enabled: z.boolean().default(true),\n});\nexport type CustomTargetConfig = z.infer<typeof CustomTargetConfigSchema>;\n\nexport const TargetConfigSchema = z.union([BuiltinTargetConfigSchema, CustomTargetConfigSchema]);\nexport type TargetConfig = z.infer<typeof TargetConfigSchema>;\n\nexport const NamingRuleConfigSchema = z.object({\n /** Casing style or regular expression for subsystem names/IDs */\n subsystems: z.string().optional(),\n /** Casing style or regular expression for component names/IDs */\n components: z.string().optional(),\n /** Casing style or regular expression for interface names/IDs */\n interfaces: z.string().optional(),\n /** Casing style or regular expression for general type names/IDs */\n types: z.string().optional(),\n /** Casing style or regular expression for entity type names/IDs */\n entities: z.string().optional(),\n /** Casing style or regular expression for value-object type names/IDs */\n valueObjects: z.string().optional(),\n /** Casing style or regular expression for interface/implementation/type method names */\n methods: z.string().optional(),\n /** Casing style or regular expression for general type fields */\n fields: z.string().optional(),\n /** Casing style or regular expression for constants/enum variants */\n constants: z.string().optional(),\n /** Casing style or regular expression for parameters/variables */\n variables: z.string().optional(),\n /** Stereotype-specific naming rules (prefixes, suffixes, regexes) */\n stereotypes: z.record(z.object({\n match: z.enum(['id', 'name', 'both']).default('both'),\n prefix: z.string().optional(),\n suffix: z.string().optional(),\n regex: z.string().optional(),\n })).optional(),\n});\nexport type NamingRuleConfig = z.infer<typeof NamingRuleConfigSchema>;\n\nexport const DocumentationRuleConfigSchema = z.object({\n /** Minimum character length for description fields */\n minDescriptionLength: z.number().int().nonnegative().optional(),\n /** Force subsystem, component, interface, and type specs to have non-empty descriptions */\n requireDescriptions: z.boolean().optional(),\n /** Force interface and type methods to have non-empty descriptions */\n requireMethodDescriptions: z.boolean().optional(),\n /** Force type fields to have non-empty descriptions */\n requireFieldDescriptions: z.boolean().optional(),\n});\nexport type DocumentationRuleConfig = z.infer<typeof DocumentationRuleConfigSchema>;\n\nexport const ComplexityRuleConfigSchema = z.object({\n /** Maximum number of parameters allowed on a single interface method */\n maxMethodParams: z.number().int().nonnegative().optional(),\n /** Maximum number of methods allowed on a single interface contract */\n maxInterfaceMethods: z.number().int().nonnegative().optional(),\n /** Maximum number of dependencies allowed on a single component */\n maxComponentDependencies: z.number().int().nonnegative().optional(),\n /** Maximum number of narrative steps allowed in a single method implementation */\n maxNarrativeSteps: z.number().int().nonnegative().optional(),\n /** Maximum number of direct components allowed in a single subsystem */\n maxSubsystemComponents: z.number().int().nonnegative().optional(),\n /**\n * Maximum cyclomatic complexity a realized function may measure (exact AST\n * grade) while its method's narrative detail sits below `full` with no\n * narrative — above it the detail-sufficiency lint fires\n * (UNNARRATED_COMPLEXITY). Default 8 when unset.\n */\n maxUnnarratedComplexity: z.number().int().nonnegative().optional(),\n});\nexport type ComplexityRuleConfig = z.infer<typeof ComplexityRuleConfigSchema>;\n\n/**\n * How deep this project (or subsystem, or pack profile) commits to DESIGNING.\n * The validator gates EXPECTATION checks by depth — nothing below the declared\n * depth is demanded to exist (no missing-narrative/-implementation/-endpoint\n * findings, no reachability walk that would need narrative edges) — while\n * SOUNDNESS checks always apply to whatever IS authored (a malformed narrative\n * errors even at designDepth: interfaces). Default is `narratives` (full\n * depth): shallower depth is a per-team choice, never the tool's default.\n * Resolution: subsystem.designDepth → project rules.designDepth → the\n * subsystem's pack-profile designDepth → narratives.\n */\nexport const DesignDepthSchema = z.enum(['components', 'interfaces', 'implementations', 'narratives']);\nexport type DesignDepth = z.infer<typeof DesignDepthSchema>;\n\nexport const RulesConfigSchema = z.object({\n /**\n * Prevent two agents from declaring overlapping ownedPaths.\n * Strongly recommended: true.\n */\n noOverlappingOwnership: z.boolean().default(true),\n\n /**\n * Require every non-meta agent to have at least one ownedPath.\n */\n requireOwnedPaths: z.boolean().default(true),\n\n /**\n * Tags that mark an agent as a meta/guardian agent — exempt from\n * requireOwnedPaths.\n */\n metaAgentTags: z.array(z.string()).default(['meta', 'guardian', 'architect']),\n\n /**\n * Generated outputs should exactly reproduce from the registry.\n * Warn if generated files differ from what the registry would produce.\n */\n enforceReproducibility: z.boolean().default(true),\n\n /**\n * Whether to generate an individual implementer agent PER COMPONENT. Off by\n * default: one subsystem-owner agent per subsystem owns its components'\n * implementations, which keeps the generated topology (and the per-session\n * agent context every session loads) proportional to the number of\n * subsystems, not components. A large project or subproject with `true` can\n * emit thousands of agents — reserve it for small trees that genuinely want\n * per-component isolation.\n */\n generateComponentImplementers: z.boolean().default(false),\n\n /**\n * Severity overrides for SDD validation rules.\n * Key: rule code (e.g. CIRCULAR_DEPENDENCY), Value: error | warning | off\n */\n sddRuleSeverity: z.record(z.enum(['error', 'warning', 'off'])).default({}),\n\n /** Dynamic naming conventions and stereotype suffix rules */\n naming: NamingRuleConfigSchema.optional(),\n\n /** Dynamic metadata documentation constraints */\n documentation: DocumentationRuleConfigSchema.optional(),\n\n /** Dynamic structural complexity caps (method limit, step limit, dependency limit) */\n complexity: ComplexityRuleConfigSchema.optional(),\n\n /** Project-default design depth (see DesignDepthSchema); subsystems may override. */\n designDepth: DesignDepthSchema.optional(),\n});\n\nexport type RulesConfig = z.infer<typeof RulesConfigSchema>;\n\nexport const PathsConfigSchema = z.object({\n /** Base directory containing SDD specification files, relative to project root */\n specsDir: z.string().default('.wai/specs'),\n});\nexport type PathsConfig = z.infer<typeof PathsConfigSchema>;\n\nexport const ProjectConfigSchema = z.object({\n /**\n * Schema version — used to detect incompatible config formats in future\n * CLI versions.\n */\n schemaVersion: z.string().default('1.0.0'),\n\n /** Human-readable project name */\n name: z.string(),\n\n /**\n * The type/profile of the project, which configures targeted guidelines, rules,\n * templates, and validation constraints. Open string: built-ins are backend,\n * frontend-reactive, frontend-controller, lowlevel-os, game-ecs,\n * realtime-embedded, plc-cyclic, fullstack, system-of-systems, monorepo;\n * extension packs may register more (unknown names get UNKNOWN_PROFILE).\n */\n projectType: z.string().default('backend'),\n\n /** Optional short description of this project */\n description: z.string().optional(),\n\n /**\n * Active output targets. At least one must be enabled.\n * Configured during `wairon init` and editable afterward.\n */\n targets: z.array(TargetConfigSchema).default([]),\n\n rules: RulesConfigSchema.default({}),\n\n /**\n * Extension packs — wairon's plugin surface. Each entry is a relative path\n * to a declarative YAML pack (custom profiles + language/platform tables)\n * or a requireable JS module id (which may also inject SddRule[] `rules`).\n * Loaded identically by CLI and MCP at validation time.\n */\n extensions: z.object({\n packs: z.array(z.string()).default([]),\n /**\n * Whether to also load machine-wide packs from the global folder\n * (WAIRON_PACKS_DIR or ~/.wairon/packs). Default true; set false for\n * strict reproducibility (only committed project packs apply).\n */\n useGlobalPacks: z.boolean().default(true),\n }).optional(),\n\n paths: PathsConfigSchema.default({}),\n\n /**\n * Path to a directory containing org/user-level default templates.\n * Resolved before built-in templates but after project-local templates.\n *\n * Default: ~/.wairon/templates\n * Can also be set via WAIRON_TEMPLATES_DIR environment variable.\n */\n globalTemplatesDir: z.string().optional(),\n\n /**\n * Tracks whether the wairon usage guide has been injected into each target's\n * AI tool configuration files so the tool knows how to use wairon.\n */\n aiGuide: z.object({\n claudeGlobal: z.boolean().default(false),\n claudeLocal: z.boolean().default(false),\n geminiGlobal: z.boolean().default(false),\n geminiLocal: z.boolean().default(false),\n }).optional(),\n\n /** Created by wairon at init time */\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\nexport type ProjectConfig = z.infer<typeof ProjectConfigSchema>;\n","import { z } from 'zod';\nimport { AgentRecordSchema } from './agent.js';\n\n// ---------------------------------------------------------------------------\n// Registry — the in-memory agent set\n//\n// Agents are derived from the SDD spec tree (resolveAgentTopology); this is the\n// in-memory shape returned by loadRegistry(). There is no hand-maintained\n// agents.json — generated agent files are outputs, not a source of truth.\n//\n// JSON is used (not YAML) because:\n// - The registry is primarily written by the CLI, not by humans\n// - JSON is universally parseable with no ambiguity\n// - Diffs are clear and predictable in version control\n// ---------------------------------------------------------------------------\n\nexport const RegistrySchema = z.object({\n schemaVersion: z.string().default('1.0.0'),\n agents: z.array(AgentRecordSchema).default([]),\n updatedAt: z.string().datetime(),\n});\n\nexport type Registry = z.infer<typeof RegistrySchema>;\n\nexport function createEmptyRegistry(): Registry {\n return {\n schemaVersion: '1.0.0',\n agents: [],\n updatedAt: new Date().toISOString(),\n };\n}\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Template definition — a reusable agent shape\n//\n// Templates live both as built-in files shipped with the CLI (src/templates/)\n// and as project-local overrides (.wai/templates/).\n//\n// Project-local templates take precedence over built-ins.\n// ---------------------------------------------------------------------------\n\nexport const TemplateSchema = z.object({\n /** Unique template identifier, e.g. \"domain-owner\" */\n id: z.string(),\n\n /** Display name */\n name: z.string(),\n\n /** Short description of this template's purpose */\n description: z.string(),\n\n /**\n * Markdown instruction body for the agent.\n * Supports simple variable interpolation: {{agentName}}, {{ownedPaths}}, etc.\n */\n instructions: z.string(),\n\n /** Default tags applied to agents created from this template */\n defaultTags: z.array(z.string()).default([]),\n\n /** Whether agents from this template must have ownedPaths defined */\n requiresOwnedPaths: z.boolean().default(true),\n\n /**\n * Optional YAML front-matter fields to include in generated output.\n * These are passed through to the exporter as-is.\n */\n frontmatter: z.record(z.unknown()).optional(),\n\n /** Version of this template definition */\n version: z.string().default('1.0.0'),\n});\n\nexport type Template = z.infer<typeof TemplateSchema>;\n","import { z } from 'zod';\n\n// ---------------------------------------------------------------------------\n// Common Identifier Schema\n// ---------------------------------------------------------------------------\nexport const SpecIdSchema = z.string().regex(/^[a-z0-9-_]+$/, 'Identifier must be lowercase alphanumeric with dashes or underscores');\n\nexport const SpecStatusSchema = z.enum(['draft', 'design', 'complete']).default('complete');\nexport type SpecStatus = z.infer<typeof SpecStatusSchema>;\n\n\nexport const BoundaryItemSchema = z.union([\n z.string(),\n z.object({\n name: z.string(),\n description: z.string().optional(),\n }),\n]);\nexport type BoundaryItem = z.infer<typeof BoundaryItemSchema>;\n\nexport const RequirementItemSchema = z.union([\n z.string(),\n z.object({\n description: z.string(),\n }),\n]);\nexport type RequirementItem = z.infer<typeof RequirementItemSchema>;\n\nexport const DatabaseSpecSchema = z.object({\n id: SpecIdSchema,\n name: z.string(),\n engine: z.string(), // e.g. \"postgresql\", \"mysql\", \"sqlite\", \"redis\"\n description: z.string().optional(),\n tables: z.array(SpecIdSchema).optional(),\n});\nexport type DatabaseSpec = z.infer<typeof DatabaseSpecSchema>;\n\nexport const DiagramConfigSchema = z.object({\n lineStyle: z.enum(['bezier', 'straight', 'taxi']).optional(),\n defaultView: z.enum(['architecture', 'types', 'databases']).optional(),\n showDatabases: z.boolean().optional(),\n});\nexport type DiagramConfig = z.infer<typeof DiagramConfigSchema>;\n\n/**\n * Ascending audience reach for L0 gateway entries. An entry travels only as\n * far as its audience allows: project (family-internal — exported only into\n * own chained children), department (owning org-unit subtree), instance\n * (whole hosted instance), partner (grant-gated cross-tenant), external\n * (publicly consumable / 3rd-party-facing).\n */\nexport const SURFACE_AUDIENCES = ['project', 'department', 'instance', 'partner', 'external'] as const;\nexport const SurfaceAudienceSchema = z.enum(SURFACE_AUDIENCES);\nexport type SurfaceAudience = z.infer<typeof SurfaceAudienceSchema>;\n\n/**\n * One entry of the project's L0 gateway surface — the ONLY thing another\n * project may consume. Fields are lenient (existing trees authored this\n * un-schema'd); the surface projector applies defaults where sensible.\n */\nexport const SystemPublicInterfaceSchema = z.object({\n /** Stable public interface id within the system. */\n id: z.string().optional(),\n name: z.string().optional(),\n /** Subsystem publishing the backing L1 public interface. */\n subsystem: z.string().optional(),\n /** Portal (or compatible published component) backing this entry. */\n component: z.string().optional(),\n /** Optional L3 interface id backing the surface. */\n interface: z.string().optional(),\n /** Surface kind: REST, GraphQL, MessageBus, RPC, or Custom. */\n type: z.string().optional(),\n details: z.string().optional(),\n /** Exposure ceiling (see SurfaceAudienceSchema). Defaults to 'instance' at projection time. */\n audience: z.string().optional(),\n authPolicy: z.string().optional(),\n version: z.string().optional(),\n stability: z.string().optional(),\n});\nexport type SystemPublicInterface = z.infer<typeof SystemPublicInterfaceSchema>;\n\nexport const SystemSpecSchema = z.object({\n schemaVersion: z.string().default('1.0.0'),\n name: z.string(),\n vision: z.string(),\n boundaries: z.array(BoundaryItemSchema).default([]),\n globalRequirements: z.array(RequirementItemSchema).default([]),\n /**\n * The project's gateway surface: entries intentionally exported beyond the\n * project, each backed by a subsystem-published Portal and carrying an\n * audience ceiling. Cross-PROJECT consumption may only target these.\n */\n publicInterfaces: z.array(SystemPublicInterfaceSchema).optional(),\n /**\n * System-level databases. Enables database table mapping, PK/FK views,\n * and isolated ERD schemas.\n */\n databases: z.array(DatabaseSpecSchema).default([]),\n /** Optional defaults for the interactive diagram canvas. */\n diagram: DiagramConfigSchema.optional(),\n /**\n * Default implementation language for the whole system (e.g. \"typescript\",\n * \"rust\", \"python\"). Subsystems may override. Drives language-aware\n * validation (builtin-type vocabulary, language rule packs); free-form but\n * normalized to lowercase by the validator.\n */\n targetLanguage: z.string().optional(),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\nexport type SystemSpec = z.infer<typeof SystemSpecSchema>;\n\n// ---------------------------------------------------------------------------\n// Level 1: Subsystem / Service Spec (subsystems/*.yaml)\n// ---------------------------------------------------------------------------\nexport const PublicInterfaceTypeSchema = z.enum(['REST', 'GraphQL', 'MessageBus', 'RPC', 'Custom']);\nexport type PublicInterfaceType = z.infer<typeof PublicInterfaceTypeSchema>;\n\nexport const PublicInterfaceSchema = z.object({\n type: PublicInterfaceTypeSchema,\n details: z.string(),\n /** The L2 component that realizes this public interface (the subsystem's published surface). */\n component: SpecIdSchema.optional(),\n /** Optional L3 interface on that component backing this entry. */\n interface: SpecIdSchema.optional(),\n});\n\nexport type PublicInterface = z.infer<typeof PublicInterfaceSchema>;\n\n/**\n * An explicitly sanctioned tight coupling with a peer subsystem — e.g. a\n * latency \"fast lane\" where a trusted sibling calls directly instead of going\n * over the message bus. Mutual subsystem dependencies are flagged unless one\n * side declares the link, turning the exception into reviewable spec instead\n * of tribal knowledge. Declared on the SOURCE subsystem, the link licenses\n * direct in-process edges into the peer WITHOUT the client-Adapter shim; the\n * target must still be published (the peer's Portal in publicInterfaces) — a\n * trusted link never licenses reaching internals, and a target-side\n * declaration waives nothing for callers.\n */\nexport const TrustedLinkSchema = z.object({\n /** The peer subsystem id this link sanctions tight coupling with. */\n subsystem: SpecIdSchema,\n /** Why this coupling is sanctioned (e.g. \"runtime dispatch latency — bus round-trip too slow\"). */\n reason: z.string(),\n});\nexport type TrustedLink = z.infer<typeof TrustedLinkSchema>;\n\n/**\n * Per-spec lint suppression — wairon's #[allow(...)]. An allow silences\n * WARNING-severity findings of the named code on THIS spec only; error\n * findings are architecture violations and are never locally suppressible\n * (a human can still re-tune codes globally via rules.sddRuleSeverity in\n * project.yaml). Same philosophy as trustedLinks: the exception becomes\n * reviewable spec — reason required, stale allows are flagged.\n */\nexport const LintAllowSchema = z.object({\n /** The issue code being allowed (see `wairon rules list`). */\n code: z.string(),\n /** Why this finding is acceptable here (e.g. \"dispatcher — fan-out is the point\"). */\n reason: z.string().min(1),\n});\nexport type LintAllow = z.infer<typeof LintAllowSchema>;\n\nexport const LintConfigSchema = z.object({\n allow: z.array(LintAllowSchema).default([]),\n});\nexport type LintConfig = z.infer<typeof LintConfigSchema>;\n\n/**\n * Open, namespaced extension-data channel: an opaque map packs and tools may\n * attach structured domain data to (ISR priorities, topic names, memory\n * budgets, …). Never validated, relativized, or interpreted by the core —\n * preserved verbatim through load/save so pack rules have something to read.\n * Key discipline (e.g. \"mypack:priority\") is the pack's concern.\n */\nexport const ExtDataSchema = z.record(z.unknown());\nexport type ExtData = z.infer<typeof ExtDataSchema>;\n\n/**\n * A declared lifecycle flow root: a component.method the runtime invokes at a\n * lifecycle phase. Reachability analysis (unused-detection, durability\n * round-trip) treats these as entrypoints alongside Portals, Observers, and\n * published components — boot-time wiring like hydration and environment\n * provisioning becomes statically checkable instead of a blanket lint-allow\n * (\"called at startup, invisible to the walker\"). Beyond init/shutdown, the\n * execution-model roots open the walker to non-request/response systems:\n * `cyclic` (invoked every scan/tick — the PLC/game-loop model), `interrupt`\n * (invoked by a hardware/OS interrupt), `scheduled` (invoked by a\n * timer/cron). Only `init` flows feed the durable-Store hydration check.\n */\nexport const LifecycleEntrypointSchema = z.object({\n /** Which lifecycle/execution flow this roots. */\n phase: z.enum(['init', 'shutdown', 'cyclic', 'interrupt', 'scheduled']),\n /** Component id whose method the runtime invokes at this phase. */\n component: z.string(),\n /** Method name on that component's interface. */\n method: z.string(),\n /** What this lifecycle flow establishes or tears down. */\n description: z.string().optional(),\n});\nexport type LifecycleEntrypoint = z.infer<typeof LifecycleEntrypointSchema>;\n\nexport const SubsystemSpecSchema = z.object({\n id: SpecIdSchema,\n name: z.string(),\n description: z.string(),\n parentSystem: z.string(), // References L0 System Name or file\n publicInterfaces: z.array(PublicInterfaceSchema).default([]),\n /** Declared init/shutdown flow roots (see LifecycleEntrypointSchema). */\n lifecycle: z.array(LifecycleEntrypointSchema).optional(),\n /**\n * Optional subsystem profile override (e.g. for fullstack systems). Open\n * string: built-ins are backend, frontend-reactive, frontend-controller,\n * lowlevel-os, game-ecs, realtime-embedded, plc-cyclic; extension packs\n * may register more. Unknown names get UNKNOWN_PROFILE.\n */\n profile: z.string().optional(),\n projectPath: z.string().optional(), // Relative path to external project root for subsystem chaining\n /** Optional override of the system-level targetLanguage for this subsystem. */\n targetLanguage: z.string().optional(),\n /** Explicitly sanctioned tight couplings with peer subsystems (see TrustedLinkSchema). */\n trustedLinks: z.array(TrustedLinkSchema).default([]),\n /**\n * Per-subsystem design-depth override (components | interfaces |\n * implementations | narratives): how deep THIS subsystem commits to\n * designing. Overrides the project rules.designDepth — a black-box or\n * externally-owned subsystem can stop at interfaces while siblings go to\n * L5, or one flagship subsystem can go deeper than the project default.\n * Expectation checks below the depth are gated; soundness of authored\n * content never is.\n */\n designDepth: z.enum(['components', 'interfaces', 'implementations', 'narratives']).optional(),\n /** Per-spec lint suppressions (see LintConfigSchema). */\n lint: LintConfigSchema.optional(),\n /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */\n ext: ExtDataSchema.optional(),\n status: SpecStatusSchema.optional().default('complete'),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\nexport type SubsystemSpec = z.infer<typeof SubsystemSpecSchema>;\n\n// ---------------------------------------------------------------------------\n// Level 2: Component Spec (components/*.yaml)\n// ---------------------------------------------------------------------------\nexport const ComponentTypeSchema = z.enum([\n // Building blocks\n 'Portal',\n 'Orchestrator',\n 'Supervisor',\n 'Actor',\n 'Store',\n 'Index',\n 'Registry',\n 'Adapter',\n 'Observer',\n 'Specialist',\n 'View', // Pure presenter/UI component\n // Patterns (compositions of blocks)\n 'Repository',\n 'Gateway',\n 'FeatureComponent', // Logic Hook + View Presenter pattern\n 'RouterComponent', // Switch/routing component pattern\n]);\nexport type ComponentType = z.infer<typeof ComponentTypeSchema>;\n\n/** Component types that are patterns (own member blocks) rather than building blocks. */\nexport const PATTERN_TYPES: ReadonlySet<ComponentType> = new Set(['Repository', 'Gateway', 'FeatureComponent', 'RouterComponent']);\n\nexport const PortalTypeSchema = z.enum(['HTTP_API', 'gRPC', 'GraphQL', 'MessageBus', 'CLI', 'NamedPipe', 'IPC', 'Custom']);\nexport type PortalType = z.infer<typeof PortalTypeSchema>;\n\n/**\n * One entry of a generic-dispatch Portal's machine-readable dispatch table:\n * maps a runtime capability name to the component.method serving it. Makes\n * dynamic dispatch visible to the static walker — each binding is validated\n * against the serving component's interface (UNSERVED_CAPABILITY) and\n * traversed by unused-detection, so a portal with a table no longer needs\n * \"invisible to the static walker\" lint-allows (which then go stale and are\n * flagged by the stale-allow audit).\n */\nexport const DispatchBindingSchema = z.object({\n /** Capability name exactly as dispatched at runtime (e.g. \"shadow_module.get\"). */\n capability: z.string().min(1),\n /** Component id serving this capability (local, super::-relative, or ::-absolute). */\n component: z.string(),\n /** Method name on the serving component's interface. */\n method: z.string(),\n /** What this capability does. */\n description: z.string().optional(),\n});\nexport type DispatchBinding = z.infer<typeof DispatchBindingSchema>;\n\n/**\n * Store durability declaration — the orthogonal axis to the access shape\n * (bare Store vs Repository). Every Store should declare one\n * (MISSING_DURABILITY otherwise):\n * - `durable` — persisted RAM projection: survives restart AND holds a\n * RAM copy, so the round-trip rule requires a hydration\n * read-back reachable from a lifecycle init entrypoint\n * (MISSING_HYDRATION otherwise).\n * - `read-through` — persisted with NO RAM copy: every read hits the\n * backing medium, so every read IS the read-back —\n * hydration exempt by definition (the file-backed\n * config/record store).\n * - `ram-projection` — rebuilt, not restored; exempt from the round-trip.\n * - `cache` — evictable memo state whose loss is behavior-preserving;\n * hydration exempt (the honest home for TTL caches that\n * would otherwise hide inside a Specialist).\n */\nexport const DurabilitySchema = z.enum(['ram-projection', 'durable', 'read-through', 'cache']);\nexport type Durability = z.infer<typeof DurabilitySchema>;\n\n/** A reference from a component to a pack-declared reusable pattern (resolved against loaded packs' PatternDefs; UNKNOWN_PATTERN_REF when unresolved). */\nexport const PatternRefSchema = z.object({\n id: z.string(),\n version: z.string().optional(),\n});\nexport type PatternRef = z.infer<typeof PatternRefSchema>;\n\n/**\n * One event edge of the pub/sub topology: a topic this component emits to or\n * consumes from. First-class so the event graph is STATABLE, not prose — the\n * event-topology rule pairs every emitted topic with a subscriber and vice\n * versa (UNCONSUMED_TOPIC / UNSOURCED_SUBSCRIPTION). MessageBus endpoints on\n * Portal methods (direction publish|subscribe) count into the same pairing.\n */\nexport const EventBindingSchema = z.object({\n /** Topic/channel name exactly as used on the bus. */\n topic: z.string().min(1),\n /** Optional event name within the topic (informational in v1 — pairing is by topic). */\n event: z.string().optional(),\n description: z.string().optional(),\n});\nexport type EventBinding = z.infer<typeof EventBindingSchema>;\n\nexport const ComponentSpecSchema = z.object({\n id: SpecIdSchema,\n name: z.string(),\n description: z.string(),\n subsystem: z.string(), // References L1 Subsystem id\n componentType: ComponentTypeSchema,\n /** Member block ids privately owned by this component (patterns only; one hop). */\n owns: z.array(z.string()).default([]),\n /** Other L2 component ids this component collaborates with (facades / standalone blocks). */\n dependsOn: z.array(z.string()).default([]),\n portalType: PortalTypeSchema.optional(),\n basePath: z.string().optional(),\n /** Portal-only: capability → component.method dispatch table (see DispatchBindingSchema). */\n dispatch: z.array(DispatchBindingSchema).optional(),\n /** Store-only: whether held state survives restart (see DurabilitySchema). */\n durability: DurabilitySchema.optional(),\n /** Topics this component publishes to (see EventBindingSchema). */\n emits: z.array(EventBindingSchema).optional(),\n /** Topics this component consumes (see EventBindingSchema) — typical on Observers. */\n subscribesTo: z.array(EventBindingSchema).optional(),\n /** Pack-declared reusable patterns this component realizes (resolved against loaded packs; UNKNOWN_PATTERN_REF). */\n patterns: z.array(PatternRefSchema).optional(),\n /** Optional component variant — a declared, base-anchored specialization of this component's stereotype (resolved against the variant registry; UNKNOWN_VARIANT / VARIANT_BASE_MISMATCH). */\n variant: z.string().optional(),\n /** Per-spec lint suppressions (see LintConfigSchema). */\n lint: LintConfigSchema.optional(),\n /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */\n ext: ExtDataSchema.optional(),\n status: SpecStatusSchema.optional().default('complete'),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\nexport type ComponentSpec = z.infer<typeof ComponentSpecSchema>;\n\n// ---------------------------------------------------------------------------\n// Level 3: Interface / Contract Spec (interfaces/*.yaml)\n// ---------------------------------------------------------------------------\nexport const HttpMethodSchema = z.enum(['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD']);\nexport type HttpMethod = z.infer<typeof HttpMethodSchema>;\n\n/** The wire protocols a Portal can expose. Mirrors PortalType (sans the *_API suffix). */\nexport const TransportSchema = z.enum(['HTTP', 'gRPC', 'GraphQL', 'MessageBus', 'NamedPipe', 'IPC', 'CLI', 'Custom']);\nexport type Transport = z.infer<typeof TransportSchema>;\n\n// A method's concrete wire endpoint — ONE generic field, discriminated by `transport`,\n// so HTTP / gRPC / GraphQL / MessageBus / NamedPipe / IPC / CLI / Custom all bind\n// through the same slot (set via the `sdd_set_endpoints` MCP tool). Each transport keeps\n// its own precise address fields, so the gate validates exact shape, not just presence.\nexport const EndpointSchema = z.discriminatedUnion('transport', [\n z.object({ transport: z.literal('HTTP'), method: HttpMethodSchema, path: z.string() }),\n z.object({ transport: z.literal('gRPC'), service: z.string(), method: z.string() }),\n z.object({ transport: z.literal('GraphQL'), operation: z.enum(['query', 'mutation', 'subscription']), field: z.string() }),\n z.object({ transport: z.literal('MessageBus'), topic: z.string(), event: z.string(), queue: z.string().optional(), direction: z.enum(['subscribe', 'publish']).default('subscribe') }),\n z.object({ transport: z.literal('NamedPipe'), pipe: z.string() }),\n z.object({ transport: z.literal('IPC'), channel: z.string() }),\n z.object({ transport: z.literal('CLI'), command: z.string() }),\n z.object({ transport: z.literal('Custom'), address: z.string() }),\n]);\nexport type Endpoint = z.infer<typeof EndpointSchema>;\n\n/**\n * Method-level semantic guarantee tokens. SEMANTIC_GUARANTEES is wairon's BUILTIN\n * vocabulary — the cross-level consistency check (narrative claim ↔ contract guarantee)\n * and the prose-claim linter are data-driven over it (add a builtin here + its narrative\n * keyword in validation.ts). The schema itself is OPEN so extension packs can declare\n * platform vocabularies (`guarantees:` in a pack manifest); a token that is neither\n * builtin nor pack-declared is flagged by the guarantee-token rule (UNKNOWN_GUARANTEE),\n * not rejected at parse time. Still NOT a place for free-form prose — every token must\n * be declared somewhere.\n */\nexport const SEMANTIC_GUARANTEES = ['idempotent', 'atomic', 'transactional', 'exactly-once'] as const;\nexport const GuaranteeSchema = z.string().min(1);\nexport type Guarantee = z.infer<typeof GuaranteeSchema>;\n\n/**\n * A structured method parameter. When a method declares `params`, they are the\n * AUTHORITATIVE source for type-reference validation — the free-form\n * `signature` string becomes display-only and is never tokenized. Strongly\n * preferred over prose signatures: it removes the whole heuristic-parsing\n * class of false positives/negatives.\n */\nexport const MethodParamSchema = z.object({\n name: z.string(),\n /** A primitive/builtin or a defined type id (qualified across subsystems, e.g. \"billing.Invoice\"). */\n type: z.string(),\n description: z.string().optional(),\n optional: z.boolean().optional(),\n});\nexport type MethodParam = z.infer<typeof MethodParamSchema>;\n\nexport const MethodSignatureSchema = z.object({\n name: z.string().regex(/^[a-zA-Z0-9_]+$/, 'Method name must be alphanumeric'),\n description: z.string(),\n signature: z.string(), // e.g. \"save(key: string, data: Buffer): Promise<void>\"\n returns: z.string(), // e.g. \"Promise<void>\"\n /** Structured parameters (authoritative for type checking when present). */\n params: z.array(MethodParamSchema).optional(),\n /** Concrete wire binding for this method when its component is a Portal (set via sdd_set_endpoints). */\n endpoint: EndpointSchema.optional(),\n /**\n * First-class semantic guarantees this method's contract promises (combinable). The\n * implementer MUST honour them, and the gate checks *consistency*: a narrative step that\n * asserts a guarantee must call a method that declares it here. Whether the guarantee is\n * actually delivered is implementation correctness (implementer tests), not a static check.\n */\n guarantees: z.array(GuaranteeSchema).optional(),\n /**\n * State-effect direction of this method on its component's held state. Required on a\n * durable Store's contract methods so the durability round-trip rule can pair external\n * writes with hydration read-backs (MISSING_HYDRATION); optional elsewhere.\n */\n effect: z.enum(['read', 'write']).optional(),\n /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */\n ext: ExtDataSchema.optional(),\n});\n\nexport type MethodSignature = z.infer<typeof MethodSignatureSchema>;\n\nexport const InterfaceSpecSchema = z.object({\n id: SpecIdSchema.regex(/^i[a-z0-9-_]+$/, 'Interface id must be prefixed with a lowercase \"i\"'),\n name: z.string(),\n description: z.string(),\n component: z.string(), // References L2 Component id\n methods: z.array(MethodSignatureSchema).default([]),\n /** Per-spec lint suppressions (see LintConfigSchema). */\n lint: LintConfigSchema.optional(),\n /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */\n ext: ExtDataSchema.optional(),\n status: SpecStatusSchema.optional().default('complete'),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\nexport type InterfaceSpec = z.infer<typeof InterfaceSpecSchema>;\n\n// ---------------------------------------------------------------------------\n// Level 5: Method / Narrative Step (embedded in L4)\n//\n// Narratives are a FLAT ordered list whose order mimics the code lines. Flow\n// structure is expressed by special step types whose config jumps by step\n// number (\"when false, jump to step 6\") — blocks are just skipped regions.\n// Syntax variants are config on one type (all four loop forms are `loop` +\n// `loopKind`), so renderers/validators handle one shape per concept.\n// Structural soundness (jump targets exist, regions well-formed) is enforced\n// by the narrative-flow validation rule, not the schema.\n// ---------------------------------------------------------------------------\nexport const NarrativeStepTypeSchema = z.enum([\n 'local', // in-component work\n 'call', // cross-component call (targetComponent/targetMethod)\n 'dispatch', // capability routed through a generic Portal's dispatch table (targetComponent + capability)\n 'branch', // if/else: condition + onTrueStep (default next) / onFalseStep\n 'switch', // multiway dispatch: on + cases[{value, step}] + defaultStep\n 'loop', // header step; body = next..endStep; loopKind picks the form\n 'try', // guarded region: body = next..endStep; catches[{error, step}] + finallyStep\n 'parallel', // concurrent fan-out/join: body = next..endStep; branches[{step}] name the arm entries; flow continues after endStep once ALL arms complete\n 'jump', // unconditional goto (break / continue / rejoin-after-catch)\n 'return', // terminator (happy or handled-failure exit)\n 'throw', // error terminator: this path raises/propagates\n]);\nexport type NarrativeStepType = z.infer<typeof NarrativeStepTypeSchema>;\n\nexport const LoopKindSchema = z.enum(['forEach', 'for', 'while', 'doWhile']);\nexport type LoopKind = z.infer<typeof LoopKindSchema>;\n\nexport const SwitchCaseSchema = z.object({\n value: z.string(), // the matched value/case label\n step: z.number().int().positive(), // first step of this case's region\n});\nexport type SwitchCase = z.infer<typeof SwitchCaseSchema>;\n\nexport const CatchClauseSchema = z.object({\n error: z.string(), // error/condition caught (free text; 'any' for catch-all)\n step: z.number().int().positive(), // first step of the handler region\n});\nexport type CatchClause = z.infer<typeof CatchClauseSchema>;\n\n/**\n * One arm of a parallel fan-out. Arms are contiguous, ordered sub-regions of\n * the parallel body: arm i spans its entry step through the step before arm\n * i+1's entry (the last arm ends at the parallel's endStep). The join is\n * implicit — flow continues after endStep once ALL arms complete; an arm\n * never falls through into its neighbor.\n */\nexport const ParallelBranchSchema = z.object({\n step: z.number().int().positive(), // first step of this arm's region\n name: z.string().optional(), // optional arm label for renderers/readers\n});\nexport type ParallelBranch = z.infer<typeof ParallelBranchSchema>;\n\nexport const NarrativeStepSchema = z.object({\n stepNumber: z.number().int().positive(),\n /**\n * Optional symbolic anchor for this step. Authoring surfaces accept *Label\n * twins of every jump-by-number field (toLabel, onTrueLabel, …) resolved\n * against these anchors at WRITE time (updateSpec / sdd_write_narrative) —\n * the stored numeric fields stay the single flow representation. Labels\n * persist so later deltas can reference existing steps symbolically.\n */\n label: z.string().min(1).optional(),\n description: z.string(),\n type: NarrativeStepTypeSchema,\n targetComponent: z.string().optional(), // Required if type is 'call' or 'dispatch', references L2 Component id\n targetMethod: z.string().optional(), // Required if type is 'call', references Method name on target interface\n capability: z.string().optional(), // Required if type is 'dispatch': the capability routed through the target Portal's dispatch table\n assertsGuarantees: z.array(GuaranteeSchema).optional(),\n /**\n * Declared entity invariants this step upholds, as \"<type-id>.<invariant-id>\"\n * references (type id optionally subsystem-qualified). The invariant-backing\n * rule resolves each against the entity's declared invariants\n * (UNKNOWN_INVARIANT_REF) and counts the step as the write-path assertion the\n * entity's write methods must carry (UNASSERTED_INVARIANT otherwise).\n */\n assertsInvariants: z.array(z.string()).optional(),\n\n // --- flow config (per type; validated by the narrative-flow rule) ---------\n condition: z.string().optional(), // branch; loop (while/doWhile)\n onTrueStep: z.number().int().positive().optional(), // branch (default: next step)\n onFalseStep: z.number().int().positive().optional(), // branch (required)\n on: z.string().optional(), // switch: the dispatched value\n cases: z.array(SwitchCaseSchema).optional(), // switch (required)\n defaultStep: z.number().int().positive().optional(), // switch (default: next step)\n loopKind: LoopKindSchema.optional(), // loop (default: forEach when `over`, else while)\n over: z.string().optional(), // loop (forEach/for): iteration source\n endStep: z.number().int().positive().optional(), // loop/try/parallel: last step of the body region\n catches: z.array(CatchClauseSchema).optional(), // try\n finallyStep: z.number().int().positive().optional(), // try: first step of the always-runs region\n branches: z.array(ParallelBranchSchema).optional(), // parallel (required, >= 2 arms)\n toStep: z.number().int().positive().optional(), // jump (required)\n /**\n * call/dispatch only: fire-and-forget — the call is issued and this\n * narrative CONTINUES without awaiting the result (no result is consumed\n * by later steps). Language/platform packs may gate it via unsupportedFlow.\n */\n detach: z.boolean().optional(),\n outcome: z.string().optional(), // return: 'success' / 'not found' / …\n error: z.string().optional(), // throw: the raised error\n});\n\nexport type NarrativeStep = z.infer<typeof NarrativeStepSchema>;\n\n// ---------------------------------------------------------------------------\n// Level 4: Implementation Spec (implementations/*.yaml)\n// ---------------------------------------------------------------------------\n\n/**\n * The narrative detail dial — declared per method (or per spec as a default),\n * IN the implementation spec. Absent = the component stereotype's default\n * (Portal/Observer/Adapter → calls-only, Store/Index/Registry → intent,\n * everything else → full). Levels are floors, not ceilings.\n */\nexport const NarrativeDetailSchema = z.enum(['full', 'calls-only', 'intent']);\nexport type NarrativeDetail = z.infer<typeof NarrativeDetailSchema>;\n\n/**\n * The structural-conformance dial — declared per method (or per spec as a\n * default), mirroring the narrative detail dial. Absent = the component\n * stereotype's default (Portal → anchored, everything else → declared).\n * `declared` requires a declaration-tier anchor for each contract method in\n * the sourcePath file; `anchored` also accepts exact string-literal\n * occurrences (tool/route registrations); `off` skips method checks for\n * generated/vendored code (the sourcePath existence check always applies).\n */\nexport const ConformanceTierSchema = z.enum(['declared', 'anchored', 'off']);\nexport type ConformanceTier = z.infer<typeof ConformanceTierSchema>;\n\nexport const MethodImplementationSchema = z.object({\n name: z.string(), // Must match a method name in the L3 interface contract\n narrative: z.array(NarrativeStepSchema).default([]), // Level 5 Narrative\n /** Detail level for THIS method (overrides the spec-level default). */\n detail: NarrativeDetailSchema.optional(),\n /**\n * Behavioral specification as prose — the narrative substitute at\n * detail: intent. Subject to the INTENT_FLOOR check: non-trivial, and\n * failure behavior stated here or in the contract's guarantees.\n */\n intent: z.string().optional(),\n /** Conformance tier for THIS method (overrides the spec-level default). */\n conformance: ConformanceTierSchema.optional(),\n /**\n * The code-level name realizing this contract method in the sourcePath\n * file, when it legitimately differs from the intent-language contract\n * name — e.g. a store's `put` realized by `saveSnapshot`.\n */\n symbol: z.string().optional(),\n /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */\n ext: ExtDataSchema.optional(),\n});\n\nexport type MethodImplementation = z.infer<typeof MethodImplementationSchema>;\n\nexport const ImplementationSpecSchema = z.object({\n id: SpecIdSchema,\n name: z.string(),\n description: z.string(),\n contract: z.string(), // References L3 Interface id\n sourcePath: z.string().optional(), // Path to the concrete source code file (e.g. \"src/storage/vfs.ts\")\n /**\n * The committed integration-sim harness for this implementation (N:1\n * sharing allowed, like sourcePath — one subsystem sim may cover several\n * components). The integration-conformance rule proves the harness EXISTS\n * and its import graph WIRES the real modules (this component's and each\n * direct dependency's); whether it passes is CI's job. Declaring the first\n * simPath in a subsystem activates MISSING_INTEGRATION_SIM for that\n * subsystem's other complete non-leaf implementations.\n */\n simPath: z.string().optional(),\n /**\n * External technologies (vendor, engine, SDK, service) this implementation\n * binds to — e.g. [\"mysql\"], [\"sendgrid\"]. Declaring one makes this\n * component's ownership tree the technology's home: references anywhere\n * outside it are flagged (TECH_LEAKAGE), contract identifiers must stay\n * intent-language (VENDOR_NAME_IN_CONTRACT), and only data-layer\n * stereotypes should bind tech directly (TECH_ON_LOGIC_COMPONENT).\n */\n technologies: z.array(z.string()).optional(),\n methods: z.array(MethodImplementationSchema).default([]),\n /** Spec-level narrative detail default for all methods (each may override). */\n detail: NarrativeDetailSchema.optional(),\n /** Spec-level structural-conformance tier default (each method may override). */\n conformance: ConformanceTierSchema.optional(),\n /** Per-spec lint suppressions (see LintConfigSchema). */\n lint: LintConfigSchema.optional(),\n /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */\n ext: ExtDataSchema.optional(),\n status: SpecStatusSchema.optional().default('complete'),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\n\nexport type ImplementationSpec = z.infer<typeof ImplementationSpecSchema>;\n\n// ---------------------------------------------------------------------------\n// Types: entities and value objects (the data the components operate on).\n// Defined once by their owner; referenced — never redefined — elsewhere.\n// ---------------------------------------------------------------------------\nexport const TypeKindSchema = z.enum(['entity', 'value-object']);\nexport type TypeKind = z.infer<typeof TypeKindSchema>;\n\nexport const TypeFieldSchema = z.object({\n name: z.string(),\n type: z.string(), // a primitive, or another type id (qualified across subsystems, e.g. \"billing.Invoice\")\n description: z.string().optional(),\n optional: z.boolean().default(false),\n /**\n * Identity marker for ERD / database schema derivation:\n * - 'primary' (PK)\n * - 'unique' (UK)\n * - 'foreign' (FK)\n */\n key: z.enum(['primary', 'unique', 'foreign']).optional(),\n /**\n * For foreign keys, the referenced type/table ID (e.g. \"billing.Invoice\")\n * and optionally field (e.g. \"billing.Invoice.id\").\n */\n references: z.string().optional(),\n});\nexport type TypeField = z.infer<typeof TypeFieldSchema>;\n\n/** A pure, self-contained method on an entity (no external collaborators). */\nexport const TypeMethodSchema = z.object({\n name: z.string(),\n signature: z.string(),\n returns: z.string(),\n description: z.string().optional(),\n});\nexport type TypeMethod = z.infer<typeof TypeMethodSchema>;\n\n/**\n * A declared domain invariant on an entity — a property every write path must\n * uphold (e.g. \"slug unique among siblings\"). A DECLARATION, not a proof: the\n * invariant-backing rule checks that each write-effect method of the entity's\n * componentClass carries a narrative step asserting it (assertsInvariants) —\n * it never verifies the narrative actually enforces the property. It catches\n * \"nobody considered this here\", not incorrectness.\n */\nexport const InvariantSchema = z.object({\n /** Stable invariant id, unique within the entity (referenced as \"<type-id>.<invariant-id>\"). */\n id: SpecIdSchema,\n /** The property that must hold, stated precisely enough to test against. */\n description: z.string().min(1),\n});\nexport type Invariant = z.infer<typeof InvariantSchema>;\n\nexport const TypeSpecSchema = z.object({\n kind: TypeKindSchema, // discriminator — entity | value-object\n id: SpecIdSchema,\n name: z.string(),\n description: z.string().optional(),\n /** Owning subsystem id (entities). Omit for system-level shared value objects. */\n subsystem: z.string().optional(),\n /** Optional logical group ID to organize this type in subfolders. */\n group: z.string().optional(),\n fields: z.array(TypeFieldSchema).default([]),\n /** Pure intrinsic behaviour only — anything needing a collaborator belongs on a component. */\n methods: z.array(TypeMethodSchema).default([]),\n /**\n * Linked Component ID if this system entity is implemented as a class Component\n * (e.g., a Store or Registry that owns this entity's lifecycle and methods).\n */\n componentClass: z.string().optional(),\n /**\n * Declared domain invariants on this entity (see InvariantSchema). Anchored\n * through componentClass: its write-effect contract methods must each carry\n * a narrative step asserting every declared invariant.\n */\n invariants: z.array(InvariantSchema).optional(),\n /**\n * The database ID this schema belongs to (marks it as a database table schema).\n */\n database: z.string().optional(),\n /**\n * The database table name for this schema (e.g., \"users\").\n */\n table: z.string().optional(),\n /**\n * If this type is a database table schema, the ID of the corresponding\n * logical system entity type it maps to.\n */\n linkedEntity: z.string().optional(),\n /** Per-spec lint suppressions (see LintConfigSchema). */\n lint: LintConfigSchema.optional(),\n /** Opaque pack/tool extension data (see ExtDataSchema) — preserved verbatim. */\n ext: ExtDataSchema.optional(),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\nexport type TypeSpec = z.infer<typeof TypeSpecSchema>;\n\n// ---------------------------------------------------------------------------\n// Surface snapshots — the portable, contract-grade public-surface artifact\n// (Public Surface Exchange). One format, three origins: generated (own\n// parent/child family), exchanged (another wairon project), authored (an\n// external 3rd-party system, hand-declared or imported from OpenAPI).\n// ---------------------------------------------------------------------------\n\nexport const SurfaceOriginSchema = z.enum(['generated', 'exchanged', 'authored']);\nexport type SurfaceOrigin = z.infer<typeof SurfaceOriginSchema>;\n\n/** A self-contained type definition embedded in a snapshot (closure member). */\nexport const SurfaceTypeDefSchema = z.object({\n id: z.string(),\n name: z.string(),\n kind: z.string().default('value-object'),\n fields: z.array(z.object({\n name: z.string(),\n type: z.string(),\n description: z.string().optional(),\n optional: z.boolean().optional(),\n })).default([]),\n});\nexport type SurfaceTypeDef = z.infer<typeof SurfaceTypeDefSchema>;\n\n/** One exported interface at CONTRACT grade — full methods + dispatch table. */\nexport const SurfaceContractEntrySchema = z.object({\n id: z.string(),\n name: z.string(),\n /** Exposure level of the L0 entry (see SurfaceAudienceSchema). */\n audience: z.string().default('instance'),\n /** Transport kind: REST, GraphQL, MessageBus, RPC, or Custom. */\n type: z.string().default('Custom'),\n /** Local name of the backing Portal in the producing project. */\n component: z.string(),\n /** Full contract methods (params, returns, guarantees, effect, endpoint). */\n methods: z.array(MethodSignatureSchema).default([]),\n /** The backing portal's capability dispatch table, when generic-dispatch. */\n dispatch: z.array(DispatchBindingSchema).optional(),\n details: z.string().default(''),\n version: z.string().optional(),\n stability: z.string().optional(),\n});\nexport type SurfaceContractEntry = z.infer<typeof SurfaceContractEntrySchema>;\n\nexport const SurfaceSnapshotSchema = z.object({\n /** Producing project/system name — the snapshot's resolution identity. */\n projectName: z.string(),\n origin: SurfaceOriginSchema,\n /** Producing spec tree's StateId at generation time (wairon-produced snapshots). */\n stateId: z.string().optional(),\n /** Contract version for authored/3rd-party surfaces without a StateId. */\n version: z.string().optional(),\n generatedAt: z.string(),\n interfaces: z.array(SurfaceContractEntrySchema).default([]),\n /** Transitive type closure of every exported signature — self-contained. */\n types: z.array(SurfaceTypeDefSchema).default([]),\n});\nexport type SurfaceSnapshot = z.infer<typeof SurfaceSnapshotSchema>;\n\nexport const GroupSpecSchema = z.object({\n kind: z.literal('group'),\n id: SpecIdSchema,\n name: z.string(),\n description: z.string().optional(),\n createdAt: z.string().datetime(),\n updatedAt: z.string().datetime(),\n});\nexport type GroupSpec = z.infer<typeof GroupSpecSchema>;\n","export * from './agent.js';\nexport * from './domain.js';\nexport * from './project.js';\nexport * from './registry.js';\nexport * from './template.js';\nexport * from './specs.js';\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\n// ---------------------------------------------------------------------------\n// File system helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Ensure a directory exists, creating it (and parents) if needed.\n */\nexport function ensureDir(dirPath: string): void {\n fs.mkdirSync(dirPath, { recursive: true });\n}\n\n/**\n * Write a file, ensuring the parent directory exists first.\n */\nexport function writeFile(filePath: string, content: string): void {\n ensureDir(path.dirname(filePath));\n fs.writeFileSync(filePath, content, 'utf-8');\n}\n\n/**\n * Write a file only if the content differs from what is already on disk.\n * Returns true if the file was written (new or changed), false if unchanged.\n */\nexport function writeFileIfChanged(filePath: string, content: string): boolean {\n if (fs.existsSync(filePath)) {\n const existing = fs.readFileSync(filePath, 'utf-8');\n if (existing === content) return false;\n }\n ensureDir(path.dirname(filePath));\n fs.writeFileSync(filePath, content, 'utf-8');\n return true;\n}\n\n/**\n * Read a file as a string, or return null if it doesn't exist.\n */\nexport function readFileOrNull(filePath: string): string | null {\n try {\n return fs.readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\n/**\n * Check whether a path exists.\n */\nexport function pathExists(targetPath: string): boolean {\n return fs.existsSync(targetPath);\n}\n\n/**\n * List all files (non-recursively) in a directory with a given extension.\n * Returns an empty array if the directory does not exist.\n */\nexport function listFiles(dirPath: string, ext: string): string[] {\n if (!fs.existsSync(dirPath)) return [];\n return fs\n .readdirSync(dirPath)\n .filter((f) => f.endsWith(ext))\n .map((f) => path.join(dirPath, f));\n}\n\n/**\n * List all files recursively in a directory with a given extension.\n * Returns an empty array if the directory does not exist.\n */\nexport function listFilesRecursive(dirPath: string, ext: string): string[] {\n if (!fs.existsSync(dirPath)) return [];\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n if (entry.isDirectory()) {\n files.push(...listFilesRecursive(fullPath, ext));\n } else if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(fullPath);\n }\n }\n return files;\n}\n\n// The project root defaults to the cwd, but can be overridden — notably by the\n// MCP server, which a host (e.g. Antigravity) may launch with an unrelated cwd.\nlet projectRootOverride: string | null = null;\n\n// Request-scoped project root for the hosting server (sdd_host). A single\n// process serves many fully-isolated projects concurrently, so the active root\n// must live per async context, not in the process-global override above (which\n// concurrent requests would race). getProjectRoot() consults this FIRST, so the\n// entire existing flat spec/config API becomes request-scoped with no changes to\n// its call sites. Stdio/CLI paths set no scope and fall through to the override.\nconst requestRootStore = new AsyncLocalStorage<string>();\n\n/** Run `fn` with `dir` as the active project root for the current async context\n * (and everything it awaits). The hosting server wraps each request in this so\n * its sdd_* handlers resolve to the authenticated project's .wai/ tree without a\n * mutable global. */\nexport function runWithProjectRoot<T>(dir: string, fn: () => T): T {\n return requestRootStore.run(path.resolve(dir), fn);\n}\n\n/** The request-scoped root if one is bound, else null. */\nexport function getRequestProjectRoot(): string | null {\n return requestRootStore.getStore() ?? null;\n}\n\n/** Override the project root. Pass an absolute path to the dir containing .wai/,\n * or null to clear the override and fall back to process.cwd(). */\nexport function setProjectRoot(dir: string | null): void {\n projectRootOverride = dir === null ? null : path.resolve(dir);\n}\n\n/** Get the raw project root override value (or null if none set) */\nexport function getProjectRootOverride(): string | null {\n return projectRootOverride;\n}\n\n/**\n * Walk up from startDir to the nearest ancestor containing a wairon project\n * with system.yaml in its specs folder. Returns null if none is found.\n */\nexport function findSystemRoot(startDir: string): string | null {\n let dir = path.resolve(startDir);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const isWai = fs.existsSync(path.join(dir, '.wai'));\n const isWairon = !isWai && fs.existsSync(path.join(dir, '.wairon'));\n const base = isWai ? '.wai' : (isWairon ? '.wairon' : null);\n if (base) {\n if (fs.existsSync(path.join(dir, base, 'specs', '.index.yaml')) || fs.existsSync(path.join(dir, base, 'specs', 'system.yaml'))) {\n return dir;\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/** The resolved project root: the request-scoped root if bound (hosting server),\n * else the explicit override if set, else the resolved system root, else cwd. */\nexport function getProjectRoot(): string {\n const scoped = requestRootStore.getStore();\n if (scoped) return scoped;\n if (projectRootOverride) return projectRootOverride;\n const systemRoot = findSystemRoot(process.cwd());\n return systemRoot ?? process.cwd();\n}\n\n/**\n * Resolve a path relative to the project root (override if set, else cwd).\n */\nexport function fromProjectRoot(...segments: string[]): string {\n return path.resolve(getProjectRoot(), ...segments);\n}\n\n/**\n * Walk up from startDir to the nearest ancestor containing a wairon project\n * marker (.wai/ or legacy .wairon/). Returns null if none is found.\n */\nexport function findProjectRoot(startDir: string): string | null {\n let dir = path.resolve(startDir);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (fs.existsSync(path.join(dir, '.wai')) || fs.existsSync(path.join(dir, '.wairon'))) {\n return dir;\n }\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * Return the path to the wairon project directory (.wai/).\n *\n * Resolution order:\n * 1. .wai/ — primary (new projects)\n * 2. .wairon/ — legacy fallback (older installs)\n *\n * If neither exists (e.g. during `wairon init`), defaults to .wai/.\n */\nexport function aiDir(...segments: string[]): string {\n const waiPath = fromProjectRoot('.wai');\n const waiironPath = fromProjectRoot('.wairon');\n\n const base =\n !fs.existsSync(waiPath) && fs.existsSync(waiironPath) ? '.wairon' : '.wai';\n\n return fromProjectRoot(base, ...segments);\n}\n","import * as yaml from 'js-yaml';\nimport { readFileOrNull, writeFile } from './fs.js';\n\n// ---------------------------------------------------------------------------\n// YAML read/write helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Parse a YAML string into an unknown value.\n * Throws a descriptive error on parse failure.\n */\nexport function parseYaml(content: string, sourcePath?: string): unknown {\n try {\n return yaml.load(content);\n } catch (err) {\n const loc = sourcePath ? ` (${sourcePath})` : '';\n throw new Error(`Failed to parse YAML${loc}: ${String(err)}`);\n }\n}\n\n/**\n * Serialize a value to a YAML string.\n */\nexport function serializeYaml(value: unknown): string {\n return yaml.dump(value, {\n indent: 2,\n lineWidth: 100,\n noRefs: true,\n sortKeys: false,\n });\n}\n\n/**\n * Read and parse a YAML file.\n * Returns null if the file does not exist.\n */\nexport function readYamlFile(filePath: string): unknown {\n const content = readFileOrNull(filePath);\n if (content === null) return null;\n return parseYaml(content, filePath);\n}\n\n/**\n * Serialize and write a value to a YAML file.\n */\nexport function writeYamlFile(filePath: string, value: unknown): void {\n writeFile(filePath, serializeYaml(value));\n}\n\n/**\n * Read and parse a JSON file.\n * Returns null if the file does not exist.\n */\nexport function readJsonFile(filePath: string): unknown {\n const content = readFileOrNull(filePath);\n if (content === null) return null;\n try {\n return JSON.parse(content);\n } catch (err) {\n throw new Error(`Failed to parse JSON (${filePath}): ${String(err)}`);\n }\n}\n\n/**\n * Serialize and write a value to a JSON file (pretty-printed).\n */\nexport function writeJsonFile(filePath: string, value: unknown): void {\n writeFile(filePath, JSON.stringify(value, null, 2) + '\\n');\n}\n","// ---------------------------------------------------------------------------\n// Typed error classes for waffle-airon\n// ---------------------------------------------------------------------------\n\nexport class WaironError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'WaironError';\n }\n}\n\n/**\n * Thrown when the project has not been initialized (.wai/ directory missing).\n */\nexport class ProjectNotInitializedError extends WaironError {\n constructor() {\n super(\n 'No wairon project found in this directory.\\n' +\n 'Run `wairon init` to initialize the project.',\n );\n this.name = 'ProjectNotInitializedError';\n }\n}\n\n/**\n * Thrown when configuration is invalid or missing required fields.\n */\nexport class ConfigValidationError extends WaironError {\n constructor(detail: string) {\n super(`Configuration validation failed: ${detail}`);\n this.name = 'ConfigValidationError';\n }\n}\n\n/**\n * Thrown when a template referenced by an agent or bundle does not exist.\n */\nexport class TemplateNotFoundError extends WaironError {\n constructor(id: string) {\n super(`Template not found: \"${id}\"`);\n this.name = 'TemplateNotFoundError';\n }\n}\n\n/**\n * Thrown when a bundle definition does not exist.\n */\nexport class BundleNotFoundError extends WaironError {\n constructor(id: string) {\n super(`Bundle not found: \"${id}\"`);\n this.name = 'BundleNotFoundError';\n }\n}\n","// ---------------------------------------------------------------------------\n// Symbolic step labels. LLM authors miscount steps; a `label` is an anchor\n// fixed to a step, and every jump-by-number flow field has a *Label twin\n// resolved against the anchors AT WRITE TIME. The stored spec keeps plain\n// step numbers (renderers and the flow validator handle one shape); only the\n// authoring surface gets the renumber-proof references. Resolution runs in\n// updateSpec (post-merge, so a delta can reference labels on existing steps)\n// and in sdd_write_narrative; an unresolvable reference ABORTS the write —\n// silently dropping it would turn a typo into a dangling numeric jump.\n// ---------------------------------------------------------------------------\n\n/** Transient *Label reference field → the persisted numeric field it resolves into. */\nconst SCALAR_REFS: [string, string][] = [\n ['onTrueLabel', 'onTrueStep'],\n ['onFalseLabel', 'onFalseStep'],\n ['defaultLabel', 'defaultStep'],\n ['endLabel', 'endStep'],\n ['finallyLabel', 'finallyStep'],\n ['toLabel', 'toStep'],\n];\n\n/**\n * Resolve every symbolic label reference in a method's narrative to its step\n * number, deleting the reference fields. Mutates the steps in place. Returns\n * the list of resolution errors (empty = fully resolved); the caller must\n * abort the write when any are returned.\n */\nexport function resolveNarrativeLabels(methodName: string, steps: Record<string, any>[]): string[] {\n const errors: string[] = [];\n const labels = new Map<string, number>();\n for (const s of steps) {\n if (typeof s.label === 'string' && s.label.length) {\n const prior = labels.get(s.label);\n if (prior !== undefined) errors.push(`duplicate label \"${s.label}\" (steps ${prior} and ${s.stepNumber})`);\n else labels.set(s.label, s.stepNumber);\n }\n }\n\n const lookup = (ref: unknown, where: string): number | undefined => {\n if (typeof ref !== 'string' || !ref.length) {\n errors.push(`${where} is not a label string`);\n return undefined;\n }\n const n = labels.get(ref);\n if (n === undefined) {\n errors.push(`${where} references unknown label \"${ref}\"${labels.size ? ` (declared: ${[...labels.keys()].join(', ')})` : ' (no step declares a label)'}`);\n }\n return n;\n };\n\n for (const s of steps) {\n for (const [labelField, stepField] of SCALAR_REFS) {\n if (s[labelField] === undefined) continue;\n const n = lookup(s[labelField], `step ${s.stepNumber} ${labelField}`);\n if (n !== undefined) {\n if (typeof s[stepField] === 'number' && s[stepField] !== n) {\n errors.push(`step ${s.stepNumber} sets both ${stepField}=${s[stepField]} and ${labelField}=\"${s[labelField]}\" (= step ${n}) — they disagree`);\n } else {\n s[stepField] = n;\n }\n }\n delete s[labelField];\n }\n for (const key of ['cases', 'catches', 'branches']) {\n const arr = s[key];\n if (!Array.isArray(arr)) continue;\n for (const entry of arr) {\n if (!entry || typeof entry !== 'object' || (entry as Record<string, unknown>).label === undefined) continue;\n const e = entry as Record<string, any>;\n const n = lookup(e.label, `step ${s.stepNumber} ${key} entry`);\n if (n !== undefined) {\n if (typeof e.step === 'number' && e.step !== n) {\n errors.push(`step ${s.stepNumber} ${key} entry sets both step=${e.step} and label=\"${e.label}\" (= step ${n}) — they disagree`);\n } else {\n e.step = n;\n }\n }\n delete e.label;\n }\n }\n }\n return errors.map(e => `narrative of \"${methodName}\": ${e}`);\n}\n","// ---------------------------------------------------------------------------\n// Type-reference analysis over free-form signature strings.\n//\n// Signatures are prose-ish (\"save(key: string, data: Buffer): Promise<void>\"),\n// so extraction is heuristic. This module is the single home for that\n// heuristic; structured `params` on method signatures will eventually replace\n// most of it (see roadmap).\n// ---------------------------------------------------------------------------\n\n/** Language-agnostic builtin/primitive vocabulary accepted everywhere. */\nexport const BUILTIN_TYPES = new Set([\n 'string', 'str', 'number', 'boolean', 'bool', 'float', 'double', 'int', 'integer',\n 'u8', 'u16', 'u32', 'u64', 'u128', 'usize',\n 'i8', 'i16', 'i32', 'i64', 'i128', 'isize',\n 'f32', 'f64', 'char', 'byte', 'bytes',\n 'any', 'void', 'null', 'undefined', 'object',\n 'date', 'datetime', 'time', 'timestamp', 'duration',\n 'uuid', 'decimal', 'json', 'true', 'false',\n 'list', 'vector', 'vec', 'array', 'map', 'set', 'dict', 'dictionary', 'hashmap', 'tuple',\n 'result', 'option', 'box', 'arc', 'rc', 'ref', 'cell', 'refcell', 'mutex', 'rwlock', 'std',\n 'promise', 'record', 'json', 'unknown', 'never', 'error', 'mcpserver',\n]);\n\n/**\n * Builtins that clearly belong to ONE language family. When a subsystem\n * declares a targetLanguage, using another family's marker in a contract is\n * flagged (LANGUAGE_FOREIGN_BUILTIN) — e.g. `usize` in a TypeScript system.\n * Conservative on purpose: only unambiguous markers, no shared vocabulary.\n */\nexport const LANGUAGE_MARKERS: Record<string, ReadonlySet<string>> = {\n rust: new Set([\n 'u8', 'u16', 'u32', 'u64', 'u128', 'usize',\n 'i8', 'i16', 'i32', 'i64', 'i128', 'isize',\n 'f32', 'f64', 'vec', 'box', 'arc', 'rc', 'refcell', 'cell', 'mutex', 'rwlock', 'str',\n ]),\n typescript: new Set(['any', 'unknown', 'never', 'undefined', 'promise', 'record']),\n javascript: new Set(['promise', 'undefined']),\n python: new Set(['dict', 'tuple']),\n csharp: new Set(['task']),\n go: new Set(['chan', 'rune']),\n};\n\n/** Normalize user-supplied language names onto LANGUAGE_MARKERS keys. */\nexport function normalizeLanguage(lang: string): string {\n const l = lang.toLowerCase().trim();\n if (l === 'ts' || l === 'typescript') return 'typescript';\n if (l === 'js' || l === 'javascript' || l === 'node' || l === 'nodejs') return 'javascript';\n if (l === 'rs' || l === 'rust') return 'rust';\n if (l === 'py' || l === 'python') return 'python';\n if (l === 'c#' || l === 'cs' || l === 'csharp' || l === 'dotnet') return 'csharp';\n if (l === 'golang' || l === 'go') return 'go';\n return l;\n}\n\nexport function extractTypeIdentifiers(typeStr: string): string[] {\n // 1. Strip comments\n let cleaned = typeStr\n .replace(/\\/\\/.*$/gm, '')\n .replace(/#.*$/gm, '')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n\n // 2. Strip trailing parenthesized descriptions: e.g. \"Result<T> (or eof)\" -> \"Result<T>\"\n // We only strip it if it is preceded by non-whitespace, to avoid stripping a top-level tuple like \"(string, number)\"\n cleaned = cleaned.replace(/(?<=\\S)\\s*\\([^)]*\\)\\s*$/, '');\n\n // 3. Strip trailing prose after a dash, em-dash, or colon: e.g. \"Result<T> - returns eof\" -> \"Result<T>\"\n cleaned = cleaned.replace(/(?<=\\S)\\s+[-—:]\\s+[a-z\\s_-]+$/, '');\n\n // 4. Strip string literals (both single quotes, double quotes, and backticks)\n cleaned = cleaned.replace(/([\"'`])(?:\\\\.|[^\\\\])*?\\1/g, ' ');\n\n // 5. Extract identifiers (allowing dashes, underscores, and qualified namespace resolution)\n const matches = cleaned.match(/[a-zA-Z0-9_-]+(?:::[a-zA-Z0-9_-]+|\\.[a-zA-Z0-9_-]+)*/g) || [];\n\n // 6. Filter out pure numbers, standalone punctuation/dashes, and ensure the token represents a valid type reference\n return matches.filter(t => {\n if (!/[a-zA-Z0-9]/.test(t)) return false;\n if (/^\\d+$/.test(t)) return false;\n return true;\n });\n}\n\nexport function extractGenericTypeVariables(signature: string): Set<string> {\n const vars = new Set<string>();\n const openParen = signature.indexOf('(');\n const beforeParen = openParen !== -1 ? signature.slice(0, openParen) : signature;\n\n const openBracket = beforeParen.indexOf('<');\n const closeBracket = beforeParen.lastIndexOf('>');\n if (openBracket !== -1 && closeBracket !== -1 && closeBracket > openBracket) {\n const varsStr = beforeParen.slice(openBracket + 1, closeBracket);\n const parsedVars = varsStr.split(',').map(v => v.trim().split(/\\s+extends\\s+/i)[0].split('=')[0].trim());\n for (const v of parsedVars) {\n if (v) vars.add(v);\n }\n }\n return vars;\n}\n\nexport function extractTypeGenerics(name: string): Set<string> {\n const vars = new Set<string>();\n const openBracket = name.indexOf('<');\n const closeBracket = name.lastIndexOf('>');\n if (openBracket !== -1 && closeBracket !== -1 && closeBracket > openBracket) {\n const varsStr = name.slice(openBracket + 1, closeBracket);\n const parsedVars = varsStr.split(',').map(v => v.trim().split(/\\s+extends\\s+/i)[0].split('=')[0].trim());\n for (const v of parsedVars) {\n if (v) vars.add(v);\n }\n }\n return vars;\n}\n\nexport function extractTypesFromSignature(signature: string, returns: string): string[] {\n const types: string[] = [];\n\n // Clean comments and trailing prose/parentheses first\n let sigCleaned = signature.replace(/\\/\\/.*$/gm, '').replace(/#.*$/gm, '').replace(/\\/\\*[\\s\\S]*?\\*\\//g, '');\n sigCleaned = sigCleaned.replace(/(?<=\\S)\\s*\\([^)]*\\)\\s*$/, '');\n sigCleaned = sigCleaned.replace(/(?<=\\S)\\s+[-—:]\\s+[a-z\\s_-]+$/, '');\n\n const returnsCleaned = returns.replace(/\\/\\/.*$/gm, '').replace(/#.*$/gm, '').replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/[a-zA-Z0-9_-]+\\s*\\??\\s*:/g, '');\n\n types.push(...extractTypeIdentifiers(returnsCleaned));\n\n const openParen = sigCleaned.indexOf('(');\n const closeParen = sigCleaned.lastIndexOf(')');\n if (openParen !== -1 && closeParen !== -1 && closeParen > openParen) {\n const paramsStr = sigCleaned.slice(openParen + 1, closeParen);\n\n let bracketDepth = 0;\n let braceDepth = 0;\n let parenDepth = 0;\n let paramStart = 0;\n const params: string[] = [];\n\n for (let i = 0; i < paramsStr.length; i++) {\n const char = paramsStr[i];\n if (char === '<') bracketDepth++;\n else if (char === '>') bracketDepth--;\n else if (char === '{') braceDepth++;\n else if (char === '}') braceDepth--;\n else if (char === '(') parenDepth++;\n else if (char === ')') parenDepth--;\n else if (char === ',' && bracketDepth === 0 && braceDepth === 0 && parenDepth === 0) {\n params.push(paramsStr.slice(paramStart, i).trim());\n paramStart = i + 1;\n }\n }\n if (paramStart < paramsStr.length) {\n params.push(paramsStr.slice(paramStart).trim());\n }\n\n for (const param of params) {\n const colonIndex = param.indexOf(':');\n if (colonIndex !== -1) {\n const paramType = param.slice(colonIndex + 1).trim();\n const paramTypeCleaned = paramType.replace(/[a-zA-Z0-9_-]+\\s*\\??\\s*:/g, '');\n types.push(...extractTypeIdentifiers(paramTypeCleaned));\n }\n }\n }\n\n return Array.from(new Set(types));\n}\n\n/**\n * The type references of a method. Structured `params` are authoritative when\n * present (no prose parsing); otherwise falls back to tokenizing the free-form\n * signature string.\n */\nexport interface MethodLike {\n signature: string;\n returns: string;\n params?: { name: string; type: string }[];\n}\n\nexport function methodTypeRefs(m: MethodLike): string[] {\n if (m.params && m.params.length > 0) {\n const refs: string[] = [];\n for (const p of m.params) {\n refs.push(...extractTypeIdentifiers(p.type));\n }\n refs.push(...extractTypeIdentifiers(m.returns));\n return Array.from(new Set(refs));\n }\n return extractTypesFromSignature(m.signature, m.returns);\n}\n\nfunction normalizePart(part: string): string {\n return part.toLowerCase().replace(/[^a-z0-9]/g, '');\n}\n\nexport function matchTypeRef(ref: string, typeId: string): boolean {\n const refParts = ref.split(/::|\\./).map(normalizePart).filter(Boolean);\n const typeParts = typeId.split(/::|\\./).map(normalizePart).filter(Boolean);\n\n if (refParts.length === 0 || typeParts.length === 0) return false;\n if (refParts.length > typeParts.length) return false;\n\n for (let i = 1; i <= refParts.length; i++) {\n if (refParts[refParts.length - i] !== typeParts[typeParts.length - i]) {\n return false;\n }\n }\n return true;\n}\n","// ---------------------------------------------------------------------------\n// Deterministic blueprint layout for the architecture graph.\n//\n// SINGLE SOURCE OF TRUTH for placement: the TypeScript exporters (draw.io,\n// Excalidraw) call computeLayout directly, and the interactive canvas embeds\n// computeLayout.toString() into its HTML so the browser runs the exact same\n// algorithm on collapse/expand. For that to work the function MUST stay fully\n// self-contained: no imports, no references to module scope — everything it\n// needs is defined inside its own body.\n//\n// The algorithm: subsystems in topological order (callers left of providers),\n// components in dependency layers within each subsystem (entrypoints left →\n// data right), barycenter sweeps to minimize edge crossings, pattern members\n// nested inside their owning pattern's box.\n// ---------------------------------------------------------------------------\n\nexport interface LayoutBox { x: number; y: number; w: number; h: number; }\n\nexport interface LayoutModel {\n subsystems: { id: string }[];\n components: {\n id: string;\n subsystem: string;\n componentType: string;\n owner?: string;\n owns: string[];\n dependsOn: string[];\n }[];\n edges: { from: string; to: string; cross: boolean }[];\n}\n\nexport interface LayoutResult {\n /** Absolute boxes for every VISIBLE component (members inside patterns). */\n boxes: Record<string, LayoutBox>;\n /** Absolute boxes for every subsystem container. */\n subs: Record<string, LayoutBox & { collapsed: boolean }>;\n}\n\nexport function computeLayout(model: LayoutModel, collapsed: Record<string, boolean>): LayoutResult {\n const BOX_W = 190, BOX_H = 52, GAP_X = 90, GAP_Y = 26, SUB_PAD = 30, SUB_HEAD = 44;\n const MEMBER_W = 168, MEMBER_H = 44, PAT_PAD = 16, PAT_HEAD = 34;\n const MAX_ROW = 2100;\n const PATTERN_TYPES: Record<string, number> = { Repository: 1, Gateway: 1, FeatureComponent: 1, RouterComponent: 1 };\n\n const compById: Record<string, LayoutModel['components'][number]> = {};\n model.components.forEach(function (c) { compById[c.id] = c; });\n const subIds: Record<string, number> = {};\n model.subsystems.forEach(function (s) { subIds[s.id] = 1; });\n\n // Subsystems ordered so callers sit left of the subsystems they depend on —\n // cross-boundary edges then flow consistently rightward. DFS post-order over\n // the subsystem dep graph, reversed; alphabetical tiebreak; cycle-guarded.\n function subsystemOrder(): string[] {\n const deps: Record<string, Record<string, number>> = {};\n model.edges.forEach(function (e) {\n if (!e.cross) return;\n const from = compById[e.from], to = compById[e.to];\n if (!from || !to) return;\n (deps[from.subsystem] = deps[from.subsystem] || {})[to.subsystem] = 1;\n });\n const ids = model.subsystems.map(function (s) { return s.id; }).sort();\n const order: string[] = [];\n const mark: Record<string, number> = {};\n function visit(id: string, stack: Record<string, number>): void {\n if (mark[id] || stack[id]) return;\n stack[id] = 1;\n Object.keys(deps[id] || {}).sort().forEach(function (d) { if (subIds[d]) visit(d, stack); });\n delete stack[id];\n mark[id] = 1;\n order.push(id);\n }\n ids.forEach(function (id) { visit(id, {}); });\n order.reverse();\n return order;\n }\n\n // Dependency layer of a top-level component within its subsystem: entrypoints\n // (Portal/Observer) at 0, everything else 1 + max layer of its callers.\n function layerOf(\n comp: LayoutModel['components'][number],\n topIds: Record<string, boolean>,\n memo: Record<string, number>,\n stack: Record<string, boolean>,\n ): number {\n if (memo[comp.id] !== undefined) return memo[comp.id];\n if (stack[comp.id]) return 0; // cycle guard\n stack[comp.id] = true;\n let l: number;\n if (comp.componentType === 'Portal' || comp.componentType === 'Observer') {\n l = 0;\n } else {\n l = 0;\n model.components.forEach(function (other) {\n if (other.subsystem !== comp.subsystem) return;\n if (!topIds[other.id]) return;\n if (other.dependsOn.indexOf(comp.id) >= 0) {\n l = Math.max(l, layerOf(other, topIds, memo, stack) + 1);\n }\n });\n if (l === 0) l = 1;\n }\n delete stack[comp.id];\n memo[comp.id] = l;\n return l;\n }\n\n function boxSizeFor(comp: LayoutModel['components'][number]): { w: number; h: number } {\n if (PATTERN_TYPES[comp.componentType] && comp.owns.length && !collapsed[comp.id]) {\n return { w: MEMBER_W + PAT_PAD * 2 + 24, h: PAT_HEAD + comp.owns.length * (MEMBER_H + 12) + PAT_PAD };\n }\n return { w: BOX_W, h: BOX_H };\n }\n\n // Barycenter crossing-reduction: order each column's components by the mean\n // row of their neighbors in the adjacent column (alternating sweeps).\n function refineColumns(colInfo: { comps: LayoutModel['components'][number][]; w: number; h: number }[]): void {\n function neighborsMean(c: LayoutModel['components'][number], refIds: Record<string, number>, fallback: number): number {\n const vals: number[] = [];\n c.dependsOn.forEach(function (d) { if (refIds[d] !== undefined) vals.push(refIds[d]); });\n model.components.forEach(function (o) {\n if (refIds[o.id] !== undefined && o.dependsOn.indexOf(c.id) >= 0) vals.push(refIds[o.id]);\n });\n if (!vals.length) return fallback;\n return vals.reduce(function (s, v) { return s + v; }, 0) / vals.length;\n }\n for (let iter = 0; iter < 4; iter++) {\n const forward = iter % 2 === 0;\n colInfo.forEach(function (col, k) {\n const refK = forward ? k - 1 : k + 1;\n if (refK < 0 || refK >= colInfo.length) return;\n const refIds: Record<string, number> = {};\n colInfo[refK].comps.forEach(function (c, i) { refIds[c.id] = i; });\n const keyed = col.comps.map(function (c, i) { return { c: c, key: neighborsMean(c, refIds, i) }; });\n keyed.sort(function (a, b) { return a.key - b.key || (a.c.id < b.c.id ? -1 : 1); });\n col.comps = keyed.map(function (x) { return x.c; });\n });\n }\n }\n\n const boxes: Record<string, LayoutBox> = {};\n const subs: Record<string, LayoutBox & { collapsed: boolean }> = {};\n const order = subsystemOrder();\n const sizes: Record<string, { w: number; h: number; cols: { comps: LayoutModel['components'][number][]; w: number; h: number }[] }> = {};\n\n order.forEach(function (subId) {\n if (collapsed[subId]) { sizes[subId] = { w: 240, h: 76, cols: [] }; return; }\n const comps = model.components.filter(function (c) { return c.subsystem === subId && !c.owner; });\n const topIds: Record<string, boolean> = {};\n comps.forEach(function (c) { topIds[c.id] = true; });\n const memo: Record<string, number> = {};\n comps.forEach(function (c) { layerOf(c, topIds, memo, {}); });\n const cols: Record<number, LayoutModel['components'][number][]> = {};\n comps.forEach(function (c) { (cols[memo[c.id]] = cols[memo[c.id]] || []).push(c); });\n const colKeys = Object.keys(cols).map(Number).sort(function (a, b) { return a - b; });\n const colInfo: { comps: LayoutModel['components'][number][]; w: number; h: number }[] = [];\n colKeys.forEach(function (k) {\n colInfo.push({ comps: cols[k].sort(function (a, b) { return a.id < b.id ? -1 : 1; }), w: 0, h: 0 });\n });\n refineColumns(colInfo);\n let width = SUB_PAD * 2, height = 0;\n colInfo.forEach(function (col) {\n let colW = 0, colH = 0;\n col.comps.forEach(function (c) { const s = boxSizeFor(c); colW = Math.max(colW, s.w); colH += s.h + GAP_Y; });\n col.w = colW; col.h = colH;\n width += colW + GAP_X;\n height = Math.max(height, colH);\n });\n if (colInfo.length) width -= GAP_X;\n sizes[subId] = { w: Math.max(width, 240), h: SUB_HEAD + height + SUB_PAD, cols: colInfo };\n });\n\n let x = 40, y = 40, rowH = 0;\n order.forEach(function (subId) {\n const s = sizes[subId];\n if (x + s.w > MAX_ROW && x > 40) { x = 40; y += rowH + 70; rowH = 0; }\n subs[subId] = { x: x, y: y, w: s.w, h: s.h, collapsed: !!collapsed[subId] };\n if (!collapsed[subId]) {\n let cx = x + SUB_PAD;\n s.cols.forEach(function (col) {\n let cy0 = y + SUB_HEAD + Math.max(0, (s.h - SUB_HEAD - SUB_PAD - col.h + GAP_Y) / 2);\n col.comps.forEach(function (c) {\n const bs = boxSizeFor(c);\n boxes[c.id] = { x: cx, y: cy0, w: bs.w, h: bs.h };\n if (PATTERN_TYPES[c.componentType] && c.owns.length && !collapsed[c.id]) {\n let my = cy0 + PAT_HEAD;\n c.owns.forEach(function (mid) {\n boxes[mid] = { x: cx + PAT_PAD + 12, y: my, w: MEMBER_W, h: MEMBER_H };\n my += MEMBER_H + 12;\n });\n }\n cy0 += bs.h + GAP_Y;\n });\n cx += col.w + GAP_X;\n });\n }\n x += s.w + 70;\n rowH = Math.max(rowH, s.h);\n });\n\n return { boxes: boxes, subs: subs };\n}\n","import { CanvasModel } from './canvas.js';\nimport { computeLayout, LayoutResult } from './canvas-layout.js';\n\n// ---------------------------------------------------------------------------\n// Editable diagram exports: draw.io (mxGraph XML) and Excalidraw (scene JSON).\n//\n// Both builders are SELF-CONTAINED BY DESIGN (no references to module scope):\n// the interactive canvas serializes them via Function.prototype.toString into\n// its HTML, so in-browser exports use the user's CURRENT (possibly rearranged)\n// node positions — while the CLI exporters below call them with the computed\n// blueprint layout. One implementation, both worlds.\n// ---------------------------------------------------------------------------\n\n/** Minimal model surface the builders need (structural subset of CanvasModel). */\nexport interface ExportModel {\n system: { name: string };\n generatedAt: string;\n subsystems: { id: string; name: string }[];\n components: {\n id: string;\n name: string;\n subsystem: string;\n componentType: string;\n portalType?: string;\n public: boolean;\n owner?: string;\n owns: string[];\n }[];\n edges: { from: string; to: string; cross: boolean }[];\n}\n\nexport function buildDrawioXml(model: ExportModel, L: LayoutResult): string {\n const PATTERN_TYPES: Record<string, number> = { Repository: 1, Gateway: 1, FeatureComponent: 1, RouterComponent: 1 };\n const COLORS: Record<string, { fill: string; stroke: string }> = {\n entry: { fill: '#eef4ff', stroke: '#4a7dcf' },\n logic: { fill: '#f4effd', stroke: '#8a5cf6' },\n data: { fill: '#fdf6e3', stroke: '#c9963f' },\n adapter: { fill: '#eef8f1', stroke: '#4f9e6b' },\n pattern: { fill: '#f6f8fa', stroke: '#6a737d' },\n };\n function stereo(t: string): string {\n if (t === 'Portal' || t === 'Observer') return 'entry';\n if (t === 'Store' || t === 'Index' || t === 'Registry') return 'data';\n if (t === 'Adapter') return 'adapter';\n if (PATTERN_TYPES[t]) return 'pattern';\n return 'logic';\n }\n function esc(s: string): string {\n return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;');\n }\n\n const cells: string[] = [];\n const compById: Record<string, ExportModel['components'][number]> = {};\n model.components.forEach(function (c) { compById[c.id] = c; });\n\n function vertex(id: string, parent: string, value: string, style: string, box: { x: number; y: number; w: number; h: number }, parentBox?: { x: number; y: number }): void {\n const x = parentBox ? box.x - parentBox.x : box.x;\n const y = parentBox ? box.y - parentBox.y : box.y;\n cells.push(\n ' <mxCell id=\"' + esc(id) + '\" value=\"' + esc(value) + '\" style=\"' + esc(style) + '\" vertex=\"1\" parent=\"' + esc(parent) + '\">' +\n '<mxGeometry x=\"' + x + '\" y=\"' + y + '\" width=\"' + box.w + '\" height=\"' + box.h + '\" as=\"geometry\"/></mxCell>',\n );\n }\n\n model.subsystems.forEach(function (sub) {\n const box = L.subs[sub.id];\n if (!box) return;\n vertex('sub_' + sub.id, '1', sub.name,\n 'rounded=1;arcSize=4;fillColor=#ffffff;strokeColor=#b6c0cc;verticalAlign=top;fontStyle=1;fontSize=13;container=1;collapsible=1;whiteSpace=wrap;',\n box);\n });\n\n model.components.forEach(function (comp) {\n const box = L.boxes[comp.id];\n if (!box) return;\n const isPattern = !!PATTERN_TYPES[comp.componentType] && comp.owns.length > 0;\n const owner = comp.owner ? compById[comp.owner] : undefined;\n const nestInPattern = !!(owner && L.boxes[owner.id]);\n const parentId = nestInPattern ? 'comp_' + owner!.id : 'sub_' + comp.subsystem;\n const parentBox = nestInPattern ? L.boxes[owner!.id] : L.subs[comp.subsystem];\n const colors = COLORS[stereo(comp.componentType)];\n const label = comp.name + '\\n«' + comp.componentType + (comp.portalType ? '/' + comp.portalType : '') + '»';\n const style = isPattern\n ? 'rounded=1;fillColor=' + colors.fill + ';strokeColor=' + colors.stroke + ';dashed=1;verticalAlign=top;fontStyle=1;container=1;collapsible=1;whiteSpace=wrap;'\n : 'rounded=1;fillColor=' + colors.fill + ';strokeColor=' + colors.stroke + ';whiteSpace=wrap;fontSize=11;' + (comp.public ? 'strokeWidth=3;' : '');\n vertex('comp_' + comp.id, parentId, label, style, box, parentBox);\n });\n\n let edgeN = 0;\n model.edges.forEach(function (edge) {\n if (!L.boxes[edge.from] || !L.boxes[edge.to]) return;\n const style = edge.cross\n ? 'edgeStyle=orthogonalEdgeStyle;rounded=1;strokeColor=#c26767;strokeWidth=2;endArrow=block;endFill=1;'\n : 'edgeStyle=orthogonalEdgeStyle;rounded=1;strokeColor=#8d97a5;endArrow=block;endFill=1;';\n cells.push(\n ' <mxCell id=\"edge_' + (edgeN++) + '\" style=\"' + esc(style) + '\" edge=\"1\" parent=\"1\" ' +\n 'source=\"' + esc('comp_' + edge.from) + '\" target=\"' + esc('comp_' + edge.to) + '\">' +\n '<mxGeometry relative=\"1\" as=\"geometry\"/></mxCell>',\n );\n });\n\n return [\n '<mxfile host=\"wairon\" agent=\"wairon\" modified=\"' + esc(model.generatedAt) + '\">',\n ' <diagram id=\"architecture\" name=\"' + esc(model.system.name) + ' architecture\">',\n ' <mxGraphModel dx=\"1000\" dy=\"700\" grid=\"0\" gridSize=\"10\" guides=\"1\" tooltips=\"1\" connect=\"1\" arrows=\"1\" fold=\"1\" page=\"0\" pageScale=\"1\" math=\"0\" shadow=\"0\">',\n ' <root>',\n ' <mxCell id=\"0\"/>',\n ' <mxCell id=\"1\" parent=\"0\"/>',\n ].concat(cells, [\n ' </root>',\n ' </mxGraphModel>',\n ' </diagram>',\n '</mxfile>',\n '',\n ]).join('\\n');\n}\n\nexport function buildExcalidrawScene(model: ExportModel, L: LayoutResult): string {\n const PATTERN_TYPES: Record<string, number> = { Repository: 1, Gateway: 1, FeatureComponent: 1, RouterComponent: 1 };\n const COLORS: Record<string, { fill: string; stroke: string }> = {\n entry: { fill: '#eef4ff', stroke: '#4a7dcf' },\n logic: { fill: '#f4effd', stroke: '#8a5cf6' },\n data: { fill: '#fdf6e3', stroke: '#c9963f' },\n adapter: { fill: '#eef8f1', stroke: '#4f9e6b' },\n pattern: { fill: '#f6f8fa', stroke: '#6a737d' },\n };\n function stereo(t: string): string {\n if (t === 'Portal' || t === 'Observer') return 'entry';\n if (t === 'Store' || t === 'Index' || t === 'Registry') return 'data';\n if (t === 'Adapter') return 'adapter';\n if (PATTERN_TYPES[t]) return 'pattern';\n return 'logic';\n }\n function seedFor(id: string): number {\n let h = 2166136261;\n for (let i = 0; i < id.length; i++) {\n h ^= id.charCodeAt(i);\n h = Math.imul(h, 16777619);\n }\n return Math.abs(h) || 1;\n }\n function base(id: string, type: string, box: { x: number; y: number; w: number; h: number }): any {\n return {\n id: id, type: type, x: box.x, y: box.y, width: box.w, height: box.h,\n angle: 0, strokeColor: '#1f2328', backgroundColor: 'transparent',\n fillStyle: 'solid', strokeWidth: 1, strokeStyle: 'solid', roughness: 0,\n opacity: 100, groupIds: [], frameId: null, roundness: { type: 3 },\n seed: seedFor(id), version: 1, versionNonce: seedFor(id + '#n'),\n isDeleted: false, boundElements: [], updated: 1, link: null, locked: false,\n };\n }\n function boundLabel(rect: any, text: string, fontSize: number, verticalAlign: string): any {\n const id = rect.id + '-label';\n const label = base(id, 'text', { x: rect.x + 8, y: rect.y + 6, w: rect.width - 16, h: 20 });\n label.roundness = null;\n label.text = text;\n label.originalText = text;\n label.fontSize = fontSize;\n label.fontFamily = 1;\n label.textAlign = 'center';\n label.verticalAlign = verticalAlign;\n label.containerId = rect.id;\n label.autoResize = true;\n label.lineHeight = 1.25;\n rect.boundElements.push({ id: id, type: 'text' });\n return label;\n }\n\n const elements: any[] = [];\n const rectById: Record<string, any> = {};\n\n model.subsystems.forEach(function (sub) {\n const box = L.subs[sub.id];\n if (!box) return;\n const rect = base('sub-' + sub.id, 'rectangle', box);\n rect.backgroundColor = '#ffffff';\n rect.strokeColor = '#b6c0cc';\n elements.push(rect);\n elements.push(boundLabel(rect, sub.name, 14, 'top'));\n });\n\n model.components.forEach(function (comp) {\n const box = L.boxes[comp.id];\n if (!box) return;\n const isPattern = !!PATTERN_TYPES[comp.componentType] && comp.owns.length > 0;\n const colors = COLORS[stereo(comp.componentType)];\n const rect = base('comp-' + comp.id, 'rectangle', box);\n rect.backgroundColor = colors.fill;\n rect.strokeColor = colors.stroke;\n rect.strokeWidth = comp.public ? 3 : 1;\n rect.strokeStyle = (isPattern || stereo(comp.componentType) === 'pattern') ? 'dashed' : 'solid';\n elements.push(rect);\n rectById[comp.id] = rect;\n const label = comp.name + '\\n«' + comp.componentType + (comp.portalType ? '/' + comp.portalType : '') + '»';\n elements.push(boundLabel(rect, label, 11, isPattern ? 'top' : 'middle'));\n });\n\n let edgeN = 0;\n model.edges.forEach(function (edge) {\n const a = L.boxes[edge.from], b = L.boxes[edge.to];\n const src = rectById[edge.from], tgt = rectById[edge.to];\n if (!a || !b || !src || !tgt) return;\n const leftToRight = b.x >= a.x + a.w;\n const start = leftToRight ? { x: a.x + a.w, y: a.y + a.h / 2 } : { x: a.x, y: a.y + a.h / 2 };\n const end = leftToRight ? { x: b.x, y: b.y + b.h / 2 } : { x: b.x + b.w, y: b.y + b.h / 2 };\n const id = 'edge-' + (edgeN++);\n const arrow = base(id, 'arrow', { x: start.x, y: start.y, w: Math.abs(end.x - start.x), h: Math.abs(end.y - start.y) });\n arrow.roundness = { type: 2 };\n arrow.strokeColor = edge.cross ? '#c26767' : '#8d97a5';\n arrow.strokeWidth = edge.cross ? 2 : 1;\n arrow.points = [[0, 0], [end.x - start.x, end.y - start.y]];\n arrow.lastCommittedPoint = null;\n arrow.startBinding = { elementId: src.id, focus: 0, gap: 4 };\n arrow.endBinding = { elementId: tgt.id, focus: 0, gap: 4 };\n arrow.startArrowhead = null;\n arrow.endArrowhead = 'arrow';\n src.boundElements.push({ id: id, type: 'arrow' });\n tgt.boundElements.push({ id: id, type: 'arrow' });\n elements.push(arrow);\n });\n\n return JSON.stringify({\n type: 'excalidraw',\n version: 2,\n source: 'wairon',\n elements: elements,\n appState: { viewBackgroundColor: '#fafbfc', gridSize: null },\n files: {},\n }, null, 2);\n}\n\n// ---------------------------------------------------------------------------\n// CLI-facing wrappers (blueprint layout)\n// ---------------------------------------------------------------------------\n\nexport function generateDrawioXml(model: CanvasModel): string {\n return buildDrawioXml(model, computeLayout(model, {}));\n}\n\nexport function generateExcalidrawScene(model: CanvasModel): string {\n return buildExcalidrawScene(model, computeLayout(model, {}));\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n loadSystemSpec,\n loadSubsystemSpecs,\n loadComponentSpecs,\n loadInterfaceSpecs,\n loadImplementationSpecs,\n loadTypeSpecs,\n} from './specs.js';\nimport type { ValidationIssue } from './validation.js';\nimport { extractTypeIdentifiers, matchTypeRef, methodTypeRefs } from './rules/type-analysis.js';\nimport { buildDrawioXml, buildExcalidrawScene } from './diagram-export.js';\n\n// ---------------------------------------------------------------------------\n// Interactive architecture canvas — a self-contained single-page app with\n// C4-style scoped navigation.\n//\n// One HTML file, zero network: Cytoscape.js is vendored inline, and the\n// export builders (buildDrawioXml / buildExcalidrawScene) are serialized\n// verbatim from their TypeScript modules — in-browser exports use the\n// CURRENT view and positions (main canvas AND narrative flowcharts).\n//\n// Navigation model: a VIEW renders exactly one scope's direct children —\n// System → top-level subsystems → a subsystem's children (nested subsystems\n// + components) → a pattern's members, infinitely deep by ownership.\n// Double-click drills in; the breadcrumb navigates back out. \"Internals\"\n// previews each child's own children inside its box WITH their relations\n// (micro-layered). \"Externals\" shows ghost references to out-of-scope\n// dependencies. Per-view layout rearrangements persist in localStorage.\n//\n// SCOPE NOTE (deliberate, revisit in the canvas-engine epic): the model\n// projects structure + contracts + flow. Newer component-level semantics —\n// durability, emits/subscribesTo event topology, ext maps, method effect\n// tags, type invariants, narrative step labels — are NOT projected yet;\n// omitting a field here means \"not visualized\", never \"not persisted\".\n//\n// ---------------------------------------------------------------------------\n\nexport interface CanvasModel {\n system: {\n name: string;\n vision?: string;\n targetLanguage?: string;\n databases?: { id: string; name: string; engine: string; description?: string; tables?: string[] }[];\n diagram?: { lineStyle?: 'bezier' | 'straight' | 'taxi'; defaultView?: 'architecture' | 'types' | 'databases'; showDatabases?: boolean };\n };\n generatedAt: string;\n subsystems: {\n id: string;\n name: string;\n description: string;\n targetLanguage?: string;\n status?: string;\n trustedLinks: { subsystem: string; reason: string }[];\n }[];\n components: {\n id: string;\n name: string;\n description: string;\n subsystem: string;\n componentType: string;\n portalType?: string;\n status?: string;\n public: boolean;\n /** The L0 gateway entry id this component backs (the OpenAPI operation tag),\n * present only for a component published in the system's public surface. */\n apiTag?: string;\n owner?: string;\n owns: string[];\n dependsOn: string[];\n interfaces: {\n id: string;\n name: string;\n description: string;\n methods: {\n name: string;\n description: string;\n signature: string;\n returns: string;\n params?: { name: string; type: string; optional?: boolean }[];\n endpoint?: unknown;\n guarantees?: string[];\n }[];\n }[];\n narratives: {\n method: string;\n steps: {\n n: number;\n text: string;\n kind: string;\n call?: { component: string; method: string };\n // flow config (present per kind; names kept short — this JSON ships inline in the HTML)\n cond?: string;\n onTrue?: number;\n onFalse?: number;\n on?: string;\n cases?: { value: string; step: number }[];\n defaultStep?: number;\n loopKind?: string;\n over?: string;\n end?: number;\n catches?: { error: string; step: number }[];\n fin?: number;\n to?: number;\n /** parallel: arm entry steps (contiguous ordered sub-regions of the body). */\n branches?: { step: number; name?: string }[];\n /** call/dispatch: fire-and-forget — failure does not propagate to this flow. */\n detach?: boolean;\n outcome?: string;\n err?: string;\n }[];\n }[];\n /** Methods specified as intent prose instead of a narrative (the detail dial). */\n intents: { method: string; text: string }[];\n }[];\n edges: { from: string; to: string; cross: boolean }[];\n types: {\n id: string;\n name: string;\n kind: string;\n subsystem?: string;\n fields: { name: string; type: string; optional?: boolean; key?: string; references?: string }[];\n methods: { name: string; signature: string; returns: string; description?: string }[];\n /** Interface methods whose params/returns reference this type (usage trace). */\n usedBy: { component: string; method: string }[];\n componentClass?: string;\n database?: string;\n table?: string;\n linkedEntity?: string;\n }[];\n /** Type → type references derived from field type strings (ERD edges). */\n typeEdges: { from: string; to: string; field: string; card: '1' | '0..1' | '*' }[];\n /** Data-coupling edges: a component depends on another subsystem's data\n * (uses a type it owns), pointed at that subsystem's published portal. */\n dataEdges: { from: string; to: string }[];\n issues: { severity: string; code: string; message: string; specId?: string }[];\n}\n\nexport function buildCanvasModel(issues: ValidationIssue[] = []): CanvasModel {\n const system = loadSystemSpec();\n const subsystems = loadSubsystemSpecs();\n const components = loadComponentSpecs();\n const interfaces = loadInterfaceSpecs();\n const implementations = loadImplementationSpecs();\n\n const componentIds = new Set(components.map(c => c.id));\n const publicComponents = new Set<string>();\n for (const sub of subsystems) {\n for (const pi of sub.publicInterfaces) {\n if (pi.component) publicComponents.add(pi.component);\n }\n }\n // The combined project OpenAPI tags each operation with its L0 gateway entry id.\n // Map the backing component → that tag so a portal's \"View OpenAPI\" can deep-link\n // straight to its section of the combined spec.\n const apiTagOf = new Map<string, string>();\n for (const pi of system?.publicInterfaces ?? []) {\n if (pi.component && pi.id) apiTagOf.set(pi.component, pi.id);\n }\n\n const ownerOf = new Map<string, string>();\n for (const comp of components) {\n for (const memberId of comp.owns) {\n if (componentIds.has(memberId)) ownerOf.set(memberId, comp.id);\n }\n }\n\n const modelComponents: CanvasModel['components'] = components.map(comp => {\n const compInterfaces = interfaces.filter(i => i.component === comp.id);\n const contractIds = new Set(compInterfaces.map(i => i.id));\n const impls = implementations.filter(im => contractIds.has(im.contract));\n const narratives: CanvasModel['components'][number]['narratives'] = [];\n const intents: CanvasModel['components'][number]['intents'] = [];\n for (const impl of impls) {\n for (const m of impl.methods) {\n if (!m.narrative.length) {\n if (m.intent) intents.push({ method: m.name, text: m.intent });\n continue;\n }\n narratives.push({\n method: m.name,\n steps: m.narrative.map(s => ({\n n: s.stepNumber,\n text: s.description,\n kind: s.type,\n ...(s.type === 'call' && s.targetComponent && s.targetMethod\n ? { call: { component: s.targetComponent, method: s.targetMethod } }\n : {}),\n ...(s.type === 'dispatch' && s.targetComponent && s.capability\n ? { call: { component: s.targetComponent, method: `⟨${s.capability}⟩` } }\n : {}),\n ...(s.condition ? { cond: s.condition } : {}),\n ...(s.onTrueStep !== undefined ? { onTrue: s.onTrueStep } : {}),\n ...(s.onFalseStep !== undefined ? { onFalse: s.onFalseStep } : {}),\n ...(s.on ? { on: s.on } : {}),\n ...(s.cases && s.cases.length ? { cases: s.cases } : {}),\n ...(s.defaultStep !== undefined ? { defaultStep: s.defaultStep } : {}),\n ...(s.loopKind ? { loopKind: s.loopKind } : {}),\n ...(s.over ? { over: s.over } : {}),\n ...(s.endStep !== undefined ? { end: s.endStep } : {}),\n ...(s.catches && s.catches.length ? { catches: s.catches } : {}),\n ...(s.finallyStep !== undefined ? { fin: s.finallyStep } : {}),\n ...(s.toStep !== undefined ? { to: s.toStep } : {}),\n ...(s.branches && s.branches.length\n ? { branches: s.branches.map(b => ({ step: b.step, ...(b.name ? { name: b.name } : {}) })) }\n : {}),\n ...(s.detach ? { detach: true } : {}),\n ...(s.outcome ? { outcome: s.outcome } : {}),\n ...(s.error ? { err: s.error } : {}),\n })),\n });\n }\n }\n return {\n id: comp.id,\n name: comp.name,\n description: comp.description,\n subsystem: comp.subsystem,\n componentType: comp.componentType,\n ...(comp.portalType ? { portalType: comp.portalType } : {}),\n ...(comp.status ? { status: comp.status } : {}),\n public: publicComponents.has(comp.id),\n ...(apiTagOf.has(comp.id) ? { apiTag: apiTagOf.get(comp.id) } : {}),\n ...(ownerOf.has(comp.id) ? { owner: ownerOf.get(comp.id) } : {}),\n owns: comp.owns.filter(o => componentIds.has(o)),\n dependsOn: comp.dependsOn,\n interfaces: compInterfaces.map(i => ({\n id: i.id,\n name: i.name,\n description: i.description,\n methods: i.methods.map(m => ({\n name: m.name,\n description: m.description,\n signature: m.signature,\n returns: m.returns,\n ...(m.params && m.params.length ? { params: m.params } : {}),\n ...(m.endpoint ? { endpoint: m.endpoint } : {}),\n ...(m.guarantees && m.guarantees.length ? { guarantees: m.guarantees } : {}),\n })),\n })),\n narratives,\n intents,\n };\n });\n\n const componentSub = new Map(components.map(c => [c.id, c.subsystem]));\n const edges: CanvasModel['edges'] = [];\n for (const comp of components) {\n for (const depId of comp.dependsOn) {\n if (!componentIds.has(depId)) continue;\n edges.push({\n from: comp.id,\n to: depId,\n cross: componentSub.get(depId) !== comp.subsystem,\n });\n }\n }\n\n // Types + ERD reference edges (field type strings → defined types)\n const typeSpecs = loadTypeSpecs();\n // Usage trace: every interface method whose params/returns reference a type.\n const usedByFor = (t: (typeof typeSpecs)[number]): { component: string; method: string }[] => {\n const qualified = t.subsystem && !t.id.startsWith(`${t.subsystem}::`) ? `${t.subsystem}::${t.id}` : t.id;\n const seen = new Set<string>();\n const out: { component: string; method: string }[] = [];\n for (const intf of interfaces) {\n for (const m of intf.methods) {\n for (const ref of methodTypeRefs(m)) {\n if (!matchTypeRef(ref, qualified)) continue;\n const k = `${intf.component}#${m.name}`;\n if (!seen.has(k)) { seen.add(k); out.push({ component: intf.component, method: m.name }); }\n break;\n }\n }\n }\n return out;\n };\n\n const modelTypes: CanvasModel['types'] = typeSpecs.map(t => ({\n id: t.id,\n name: t.name,\n kind: t.kind,\n ...(t.subsystem ? { subsystem: t.subsystem } : {}),\n fields: t.fields.map(f => ({\n name: f.name,\n type: f.type,\n ...(f.optional ? { optional: true } : {}),\n ...(f.key ? { key: f.key } : {}),\n ...(f.references ? { references: f.references } : {}),\n })),\n methods: t.methods.map(m => ({ name: m.name, signature: m.signature, returns: m.returns, ...(m.description ? { description: m.description } : {}) })),\n usedBy: usedByFor(t),\n ...(t.componentClass ? { componentClass: t.componentClass } : {}),\n ...(t.database ? { database: t.database } : {}),\n ...(t.table ? { table: t.table } : {}),\n ...(t.linkedEntity ? { linkedEntity: t.linkedEntity } : {}),\n }));\n // Cardinality is derivable from the field's type string: collection shapes\n // mean \"many\", the optional flag means 0..1 — real ERD multiplicity for free.\n const MANY_SHAPE = /\\[\\s*\\]|Array<|Vec<|Set<|List<|Map<|Record<|HashMap</i;\n const typeEdges: CanvasModel['typeEdges'] = [];\n for (const t of typeSpecs) {\n for (const field of t.fields) {\n const refs = new Set<string>(extractTypeIdentifiers(field.type));\n if (field.references) {\n const refStr = field.references;\n refs.add(refStr);\n if (refStr.includes('.')) {\n const parts = refStr.split('.');\n parts.pop(); // remove field/column name if present\n refs.add(parts.join('.'));\n }\n }\n\n for (const ref of refs) {\n const target = typeSpecs.find(other => {\n const qualified = other.subsystem && !other.id.startsWith(`${other.subsystem}::`)\n ? `${other.subsystem}::${other.id}`\n : other.id;\n return matchTypeRef(ref, qualified);\n });\n if (target && target.id !== t.id) {\n const card = MANY_SHAPE.test(field.type) ? '*' : field.optional ? '0..1' : '1';\n if (!typeEdges.some(e => e.from === t.id && e.to === target.id && e.field === field.name)) {\n typeEdges.push({ from: t.id, to: target.id, field: field.name, card });\n }\n }\n }\n }\n }\n\n // Data-coupling edges: a component that USES a type owned by another subsystem\n // depends on that subsystem's data — represented as a dependency on the owner\n // subsystem's published portal (its front door). Shared (system-level) types\n // have no owner, so imply no directional coupling. Rendered only under the toggle.\n const portalOf = new Map<string, string>();\n for (const sub of subsystems) {\n for (const pi of sub.publicInterfaces) {\n if (pi.component && !portalOf.has(sub.id)) portalOf.set(sub.id, pi.component);\n }\n }\n const dataEdges: { from: string; to: string }[] = [];\n const dataSeen = new Set<string>();\n const addData = (from: string, ownerSub?: string): void => {\n if (!from || !ownerSub) return;\n const fromSub = componentSub.get(from);\n if (!fromSub || fromSub === ownerSub) return; // same subsystem — not coupling\n const target = portalOf.get(ownerSub);\n if (!target || target === from) return;\n const key = `${from}=>${target}`;\n if (dataSeen.has(key)) return;\n dataSeen.add(key);\n dataEdges.push({ from, to: target });\n };\n const typeSubOf = new Map<string, string | undefined>(typeSpecs.map(t => [t.id, t.subsystem]));\n for (const mt of modelTypes) {\n if (!mt.subsystem) continue;\n for (const u of mt.usedBy) addData(u.component, mt.subsystem);\n }\n for (const te of typeEdges) {\n const fromSub = typeSubOf.get(te.from), toSub = typeSubOf.get(te.to);\n if (fromSub && toSub && fromSub !== toSub) {\n const src = portalOf.get(fromSub);\n if (src) addData(src, toSub);\n }\n }\n\n return {\n system: {\n name: system?.name ?? 'System',\n ...(system?.vision ? { vision: system.vision } : {}),\n ...(system?.targetLanguage ? { targetLanguage: system.targetLanguage } : {}),\n ...(system?.databases ? { databases: system.databases } : {}),\n ...(system?.diagram ? { diagram: system.diagram } : {}),\n },\n generatedAt: new Date().toISOString(),\n subsystems: subsystems.map(s => ({\n id: s.id,\n name: s.name,\n description: s.description,\n ...(s.targetLanguage ? { targetLanguage: s.targetLanguage } : {}),\n ...(s.status ? { status: s.status } : {}),\n trustedLinks: s.trustedLinks ?? [],\n })),\n components: modelComponents,\n edges,\n types: modelTypes,\n typeEdges,\n dataEdges,\n issues: issues.map(i => ({\n severity: i.severity,\n code: i.code,\n message: i.message,\n ...(i.specId ? { specId: i.specId } : {}),\n })),\n };\n}\n\n/** Embed arbitrary JSON safely inside a <script> block. */\nfunction embedJson(value: unknown): string {\n return JSON.stringify(value).replace(/</g, '\\\\u003c');\n}\n\n/** The vendored cytoscape bundle, shipped with wairon's templates. */\nfunction loadCytoscapeLib(): string {\n const candidates = [\n path.resolve(__dirname, '..', 'templates', 'canvas', 'cytoscape.min.js'), // src/core & dist/cli\n path.resolve(__dirname, 'templates', 'canvas', 'cytoscape.min.js'), // dist (library entry)\n ];\n for (const p of candidates) {\n if (fs.existsSync(p)) {\n return fs.readFileSync(p, 'utf-8').replace(/<\\/script/gi, '<\\\\/script');\n }\n }\n throw new Error('Vendored cytoscape bundle not found (templates/canvas/cytoscape.min.js) — the wairon installation is incomplete.');\n}\n\nexport function renderCanvasHtml(model: CanvasModel): string {\n const title = `${model.system.name} — architecture canvas`;\n return CANVAS_TEMPLATE\n .replace('__TITLE__', () => escapeHtml(title))\n .replace('__SYSTEM_NAME__', () => escapeHtml(model.system.name))\n .replace('__SYSTEM_NAME__', () => escapeHtml(model.system.name))\n .replace('__GENERATED_AT__', () => escapeHtml(model.generatedAt))\n .replace('__CYTOSCAPE_LIB__', () => loadCytoscapeLib())\n .replace('__DRAWIO_FN__', () => buildDrawioXml.toString())\n .replace('__EXCALIDRAW_FN__', () => buildExcalidrawScene.toString())\n .replace('__MODEL_JSON__', () => embedJson(model));\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;');\n}\n\n// The inline script avoids template literals so this outer file stays simple.\nconst CANVAS_TEMPLATE = `<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>__TITLE__</title>\n<style>\n/* SYW Apps Standardized Global CSS (inlined for offline use) */\n:root {\n --syw-cyan: #22ddff;\n --syw-purple: #8b5cf6;\n --syw-yellow: #ddff22;\n --syw-amber: #f59e0b;\n --syw-bg: #0a0a0f;\n --syw-deep-space: linear-gradient(135deg, #0f172a 0%, #1e1b4b 50%, #312e81 100%);\n --syw-surface: rgba(13, 27, 42, 0.95);\n --syw-primary-gradient: linear-gradient(135deg, #22ddff 0%, #8b5cf6 100%);\n --syw-secondary-gradient: linear-gradient(135deg, #fbbf24 0%, #f59e0b 100%);\n --syw-surface-gradient: linear-gradient(135deg, rgba(13, 27, 42, 0.95) 0%, rgba(27, 38, 59, 0.98) 100%);\n --syw-glow: 0 0 20px rgba(34, 221, 255, 0.3);\n --syw-deep-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);\n}\n.syw-gradient-text { background: var(--syw-primary-gradient); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; display: inline-block; }\n* { box-sizing: border-box; }\n\nbody[data-theme=\"syw\"] {\n --bg: var(--syw-bg);\n --chrome: #0e1a2b;\n --chrome-border: rgba(34, 221, 255, 0.22);\n --ink: #e8ecf3;\n --dim: #9db0c7;\n --line: rgba(255,255,255,0.12);\n --input-bg: rgba(255,255,255,0.07);\n --hover-bg: rgba(34, 221, 255, 0.12);\n --accent: var(--syw-cyan);\n --card: rgba(255,255,255,0.05);\n --danger: #ff6b81; --warn: #f59e0b;\n}\nbody[data-theme=\"light\"] {\n --bg: #f2f5f8;\n --chrome: #ffffff;\n --chrome-border: #cfd8e1;\n --ink: #1f2328;\n --dim: #4d5761;\n --line: #dde4ea;\n --input-bg: #f1f4f7;\n --hover-bg: rgba(74, 125, 207, 0.10);\n --accent: #3465b4;\n --card: #f7fafc;\n --danger: #c22f3e; --warn: #9a6a00;\n}\nbody { margin:0; position:relative; background:var(--bg); color:var(--ink); font:13px/1.45 \"Inter\", system-ui, \"Segoe UI\", sans-serif; overflow:hidden; }\nbody[data-theme=\"syw\"] { background-image: var(--syw-deep-space); background-attachment: fixed; }\n\n/* Floating header: the toolbar hovers over a FULL-BLEED canvas (blueprint-\n designer style) instead of reserving a solid top bar. It anchors to the body\n (position:relative there) and yields to the details panel when that is open. */\nheader { display:flex; align-items:center; gap:10px; padding:0 14px; height:52px; background:var(--chrome); border:1px solid var(--chrome-border); border-radius:12px; box-shadow:var(--syw-deep-shadow); position:absolute; top:10px; left:12px; right:12px; z-index:20; overflow-x:auto; scrollbar-width:thin; }\nbody:not(.panel-closed) header { right:calc(var(--panel-width, 380px) + 19px); }\n/* Responsive overflow: on a narrow header the toolbar buttons must stay\n REACHABLE (scroll) rather than wrapping off the right edge. Groups keep their\n own shape; nothing shrinks below its content width. */\nheader > * { flex:0 0 auto; }\nheader .toolbar, header .tabs, header .grp { display:flex; align-items:center; gap:6px; flex:0 0 auto; }\nheader .brand { font-weight:800; font-size:17px; letter-spacing:.02em; }\n#crumbs { display:flex; align-items:center; gap:4px; max-width:34vw; overflow-x:auto; white-space:nowrap; scrollbar-width:thin; }\n#crumbs .crumb { border:none; background:transparent; color:var(--dim); cursor:pointer; font:inherit; font-size:12.5px; padding:4px 7px; border-radius:7px; }\n#crumbs .crumb:hover { background:var(--hover-bg); color:var(--ink); }\n#crumbs .crumb.cur { color:var(--ink); font-weight:700; cursor:default; }\n#crumbs .sep { color:var(--dim); font-size:11px; }\nheader .divider { width:1px; height:24px; background:var(--line); margin:0 2px; }\nheader input[type=\"search\"] { padding:6px 10px; border:1px solid var(--chrome-border); border-radius:8px; width:170px; font:inherit; background:var(--input-bg); color:var(--ink); }\nheader input[type=\"search\"]::placeholder { color:var(--dim); }\n.switch { display:inline-flex; align-items:center; gap:6px; cursor:pointer; color:var(--dim); font-size:12px; white-space:nowrap; user-select:none; padding:5px 8px; border-radius:8px; }\n.switch:hover { background:var(--hover-bg); color:var(--ink); }\n.switch input { accent-color:var(--accent); margin:0; }\n.tbtn { border:1px solid var(--chrome-border); background:var(--input-bg); color:var(--ink); padding:6px 11px; border-radius:8px; cursor:pointer; font:inherit; font-size:12px; white-space:nowrap; }\n.tbtn:hover { background:var(--hover-bg); border-color:var(--accent); }\n.spacer { flex:1; }\n.seg { display:flex; border:1px solid var(--chrome-border); border-radius:8px; overflow:hidden; }\n.seg button { border:none; background:transparent; color:var(--dim); padding:5px 11px; cursor:pointer; font:inherit; font-size:12px; }\n.seg button.active { background:var(--accent); color:#fff; font-weight:700; }\n\n.dropdown { position:relative; }\n/* Fixed (viewport-anchored) + JS-positioned on open, so the menu overlays the\n whole page and is NEVER clipped by the header's overflow-x:auto (or, in the\n embedded canvas, the app's scroll container) — which would otherwise trap it\n inside the canvas and force a scrollbar. Position is set in wireDropdown. */\n.dropdown .menu { display:none; position:fixed; max-height:calc(100vh - 80px); overflow-y:auto; background:var(--chrome); border:1px solid var(--chrome-border); border-radius:10px; box-shadow:var(--syw-deep-shadow); min-width:200px; padding:6px; z-index:120; }\n/* Child combinator, deliberately: a dropdown moved INTO the \"⋯\" overflow menu\n must not auto-open when the More dropdown opens (a descendant selector would\n match every nested menu under .dropdown.open). */\n.dropdown.open > .menu { display:block; }\n.dropdown .menu button { display:block; width:100%; text-align:left; border:none; background:transparent; color:var(--ink); padding:8px 10px; border-radius:7px; cursor:pointer; font:inherit; font-size:12.5px; }\n.dropdown .menu button:hover { background:var(--hover-bg); }\n.dropdown .menu .hint { display:block; color:var(--dim); font-size:10.5px; }\n/* Header controls collapsed into the \"⋯\" overflow menu: whole items (buttons\n or nested dropdowns) stack vertically; a nested dropdown's own menu still\n opens fixed-positioned over the page. */\n#moreMenu .dropdown { display:block; width:100%; }\n#moreMenu .dropdown > .tbtn, #moreMenu > .tbtn { display:block; width:100%; text-align:left; border:none; background:transparent; margin:2px 0; }\n#moreMenu .dropdown > .tbtn:hover, #moreMenu > .tbtn:hover { background:var(--hover-bg); }\n\n/* Settings panel — toggle switches */\n.settings-menu { min-width:266px; }\n.swrow { display:flex; align-items:center; justify-content:space-between; gap:16px; padding:7px 9px; border-radius:8px; cursor:pointer; user-select:none; }\n.swrow:hover { background:var(--hover-bg); }\n.swrow .lbl { font-size:12.5px; color:var(--ink); line-height:1.3; }\n.swrow .lbl .sub { display:block; color:var(--dim); font-size:10.5px; font-weight:400; }\n.selectWrap { position:relative; width:100%; }\n.selectWrap::after { content:'\\\\25BE'; position:absolute; right:10px; top:50%; transform:translateY(-50%); color:var(--dim); pointer-events:none; font-size:10px; }\n.selectControl { width:100%; appearance:none; -webkit-appearance:none; background:var(--input-bg); color:var(--ink); border:1px solid var(--chrome-border); border-radius:7px; padding:6px 30px 6px 9px; font-size:11.5px; font-family:inherit; outline:none; color-scheme:dark; }\n.selectControl:hover { border-color:var(--accent); background:var(--hover-bg); }\n.selectControl:focus { border-color:var(--accent); box-shadow:0 0 0 2px color-mix(in srgb, var(--accent) 28%, transparent); }\n.selectControl option { background:var(--chrome); color:var(--ink); }\nbody[data-theme=\"light\"] .selectControl { color-scheme:light; }\n.toggle { position:relative; display:inline-block; width:36px; height:20px; flex:0 0 auto; }\n.toggle input { position:absolute; opacity:0; width:0; height:0; margin:0; }\n.toggle .track { position:absolute; inset:0; background:var(--input-bg); border:1px solid var(--chrome-border); border-radius:20px; transition:background .15s, border-color .15s; }\n.toggle .track::after { content:''; position:absolute; top:2px; left:2px; width:14px; height:14px; background:var(--dim); border-radius:50%; transition:transform .15s, background .15s; }\n.toggle input:checked + .track { background:var(--accent); border-color:var(--accent); }\n.toggle input:checked + .track::after { transform:translateX(16px); background:#fff; }\n\n#wrap { display:flex; height:100vh; }\n#stage { flex:1; min-width:0; position:relative; }\n#cy { position:absolute; inset:0; }\n.legend { position:absolute; left:12px; bottom:12px; background:var(--chrome); border:1px solid var(--chrome-border); border-radius:10px; padding:8px 12px; font-size:11px; color:var(--dim); z-index:5; pointer-events:none; }\n.legend .sw { display:inline-block; width:10px; height:10px; border-radius:3px; margin-right:4px; vertical-align:-1px; border:1.5px solid; }\n/* Stage overlays clear the floating header (52px + 10px top + 10px gap). The\n header hides in presentation mode, where they return to the top edge. */\n.viewhint { position:absolute; top:72px; left:12px; color:var(--dim); font-size:11px; background:var(--chrome); border:1px solid var(--chrome-border); border-radius:9px; padding:5px 10px; z-index:5; pointer-events:none; }\nbody.presentation .viewhint { top:10px; }\n#typesWarn { position:absolute; top:72px; left:50%; transform:translateX(-50%); color:var(--ink); font-size:12px; background:var(--chrome); border:1px solid var(--warn); border-radius:9px; padding:6px 12px; z-index:6; max-width:72vw; box-shadow:var(--syw-deep-shadow); display:none; }\n#typesWarn button { margin-left:8px; }\n\n#panelResizer { flex:0 0 7px; cursor:col-resize; background:var(--chrome); border-left:1px solid var(--chrome-border); border-right:1px solid var(--line); z-index:11; position:relative; }\n#panelResizer::after { content:''; position:absolute; top:50%; left:50%; width:2px; height:48px; transform:translate(-50%, -50%); border-radius:2px; background:var(--dim); opacity:.45; }\n#panelResizer:hover::after, body.resizing-panel #panelResizer::after { background:var(--accent); opacity:1; }\n#panel { width:var(--panel-width, 380px); flex:0 0 var(--panel-width, 380px); border-left:1px solid var(--chrome-border); background:var(--chrome); overflow-y:auto; z-index:10; }\nbody.panel-closed #panel, body.panel-closed #panelResizer { display:none; }\nbody.resizing-panel { cursor:col-resize; user-select:none; }\nbody.resizing-panel #cy { pointer-events:none; }\nbody:not(.panel-closed) #panelToggle { background:var(--accent); color:#fff; border-color:var(--accent); font-weight:700; }\n#panel .head { padding:16px 18px 10px; border-bottom:1px solid var(--line); }\n#panel .head h2 { font-size:16px; margin:0 0 6px; }\n#panel .body { padding:12px 18px 30px; }\n#panel .chip { display:inline-block; padding:2px 9px; border-radius:11px; font-size:11px; border:1px solid var(--chrome-border); margin:0 4px 5px 0; background:var(--input-bg); color:var(--ink); }\n#panel .chip[data-kind] { cursor:pointer; }\n#panel .chip[data-kind]:hover { border-color:var(--accent); background:var(--hover-bg); }\n#panel .desc { color:var(--dim); margin:8px 0 2px; }\n#panel .openbtn { margin:6px 0 0; }\n#panel details { border:1px solid var(--line); border-radius:10px; margin:10px 0; background:var(--card); overflow:hidden; }\n#panel summary { cursor:pointer; padding:9px 12px; font-size:11.5px; font-weight:700; text-transform:uppercase; letter-spacing:.05em; color:var(--dim); user-select:none; display:flex; align-items:center; gap:8px; }\n#panel summary:hover { color:var(--ink); background:var(--hover-bg); }\n#panel summary .count { margin-left:auto; font-weight:600; background:var(--input-bg); border:1px solid var(--line); border-radius:9px; padding:0 7px; font-size:10.5px; }\n#panel details > .inner { padding:4px 12px 12px; }\n#panel .method { border:1px solid var(--line); border-radius:8px; padding:8px 10px; margin:8px 0; background:var(--chrome); }\n#panel .method .mname { font-weight:700; display:flex; align-items:center; gap:6px; flex-wrap:wrap; }\n#panel .method .mname .grow { flex:1; }\n#panel .method code { font-size:11px; word-break:break-all; color:var(--dim); display:block; margin-top:3px; }\n#panel .method .mdesc { color:var(--dim); font-size:12px; margin-top:3px; }\n#panel .flowbtn { border:1px solid var(--chrome-border); background:var(--input-bg); color:var(--accent); font-size:10.5px; padding:2px 8px; border-radius:7px; cursor:pointer; }\n#panel .flowbtn:hover { background:var(--hover-bg); }\n#panel .issue { border-left:3px solid var(--danger); padding:6px 9px; margin:6px 0; background:var(--card); font-size:12px; border-radius:0 7px 7px 0; }\n#panel .issue.warning { border-left-color:var(--warn); }\n#panel .issue code { font-size:10.5px; color:var(--dim); }\n\n/* Presentation mode = the canvas page, focused: the header chrome and legend\n are hidden, but the details panel stays TOGGLE-ABLE (the current settings are\n still applied). It does NOT force browser fullscreen (F11) — exiting is one\n step, not two. */\nbody.presentation header, body.presentation .legend { display:none; }\n/* Embed mode (?_embed=true): the canvas is rendered inside the wairon web app's\n own chrome, so its redundant brand mark is hidden — the interactive toolbar\n (views, search, settings) stays. Keeps the iframe from showing a second logo. */\nbody.embed header .brand { display:none; }\n/* Embedded in the web UI: the app owns the brand + theme, so hide the canvas's\n own brand mark and Theme toggle (the host drives the canvas theme). */\nbody.embed #themeBtn { display:none; }\n/* The details panel hides by default in presentation, but the floating details\n toggle brings it back without leaving presentation mode. */\nbody.presentation #panel, body.presentation #panelResizer { display:none; }\nbody.presentation.show-details #panel { display:block; }\nbody.presentation.show-details #panelResizer { display:block; }\nbody.presentation #wrap { height:100vh; }\n#exitPresent, #presentDetails { display:none; position:fixed; top:10px; z-index:100; border:1px solid var(--chrome-border); background:var(--chrome); color:var(--ink); border-radius:9px; padding:7px 13px; cursor:pointer; opacity:0.06; transition:opacity .15s ease; font:inherit; }\n#exitPresent { right:10px; }\n#presentDetails { right:190px; }\n#exitPresent:hover, #presentDetails:hover { opacity:1; box-shadow:var(--syw-glow); }\nbody.presentation #exitPresent, body.presentation #presentDetails { display:block; }\n\n@media (max-width: 860px) {\n #wrap { position:relative; }\n #panel { position:absolute; top:0; right:0; bottom:0; width:min(var(--panel-width, 360px), calc(100vw - 44px)); flex-basis:auto; box-shadow:var(--syw-deep-shadow); }\n #panelResizer { position:absolute; top:0; bottom:0; right:min(var(--panel-width, 360px), calc(100vw - 44px)); width:7px; flex-basis:auto; box-shadow:-3px 0 10px rgba(0,0,0,.18); }\n /* The panel overlays the stage here, so the floating header keeps full width. */\n body:not(.panel-closed) header { right:12px; }\n}\n\n#flowModal { display:none; position:fixed; inset:0; background:rgba(4,6,12,0.6); backdrop-filter:blur(3px); z-index:80; align-items:center; justify-content:center; }\n#flowModal.open { display:flex; }\n#flowModal .box { width:min(880px, 92vw); height:min(660px, 88vh); background:var(--chrome); border:1px solid var(--chrome-border); border-radius:14px; box-shadow:var(--syw-deep-shadow); display:flex; flex-direction:column; overflow:hidden; }\n#flowModal .bar { display:flex; align-items:center; gap:10px; padding:10px 14px; border-bottom:1px solid var(--line); }\n#flowModal .bar .crumbf { font-weight:700; font-size:13px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n#flowModal .bar .crumbf .dimc { color:var(--dim); font-weight:400; }\n#flowCy { flex:1; }\n#flowSteps { flex:1; display:none; overflow-y:auto; padding:16px 22px; }\n#flowModal.steps #flowCy { display:none; }\n#flowModal.steps #flowSteps { display:block; }\n#flowSteps .fstep { border:1px solid var(--line); border-radius:9px; background:var(--card); padding:9px 12px; margin:8px 0; font-size:12.5px; }\n#flowSteps .fstep .num { display:inline-block; min-width:22px; font-weight:700; color:var(--accent); }\n#flowSteps .fstep .call { color:var(--dim); }\n#flowSteps .fstep .call.drillstep { color:var(--accent); cursor:pointer; text-decoration:underline; }\n#flowSteps .fstep .call.drillstep:hover { opacity:.82; }\n#flowModal .hintbar { padding:6px 14px; color:var(--dim); font-size:11px; border-top:1px solid var(--line); }\n</style>\n</head>\n<body data-theme=\"syw\">\n<header id=\"hdr\">\n <span class=\"brand syw-gradient-text\">wairon</span>\n <div class=\"seg\" id=\"modeSeg\" title=\"Switch between the component architecture, the type ERD, or the database schemas\">\n <button data-vm=\"components\" class=\"active\">Components</button>\n <button data-vm=\"types\">Types</button>\n <button data-vm=\"databases\">Databases</button>\n </div>\n <nav id=\"crumbs\"></nav>\n <span class=\"divider\"></span>\n <input id=\"search\" type=\"search\" placeholder=\"Search this view…\">\n <div class=\"seg\" id=\"typesDetailSeg\" style=\"display:none\" title=\"ERD detail level\">\n <button data-td=\"full\">Full</button>\n <button data-td=\"fields\">Fields</button>\n <button data-td=\"keys\">Keys</button>\n <button data-td=\"names\">Names</button>\n </div>\n <span class=\"spacer\"></span>\n <div class=\"dropdown\" id=\"settingsDd\">\n <button class=\"tbtn\" id=\"settingsBtn\" title=\"View options\">⚙ View ▾</button>\n <div class=\"menu settings-menu\" id=\"settingsMenu\">\n <label class=\"swrow\">\n <span class=\"lbl\">Internals<span class=\"sub\">preview each box's children + relations</span></span>\n <span class=\"toggle\"><input type=\"checkbox\" id=\"internalsToggle\"><span class=\"track\"></span></span>\n </label>\n <label class=\"swrow\">\n <span class=\"lbl\">Externals<span class=\"sub\">out-of-scope dependencies as ghosts</span></span>\n <span class=\"toggle\"><input type=\"checkbox\" id=\"externalsToggle\" checked><span class=\"track\"></span></span>\n </label>\n <label class=\"swrow\">\n <span class=\"lbl\">Data coupling<span class=\"sub\">who uses another subsystem's types (dashed)</span></span>\n <span class=\"toggle\"><input type=\"checkbox\" id=\"dataCouplingToggle\"><span class=\"track\"></span></span>\n </label>\n <label class=\"swrow\">\n <span class=\"lbl\">Issues (<span id=\"issueCount\"></span>)<span class=\"sub\">overlay validation findings</span></span>\n <span class=\"toggle\"><input type=\"checkbox\" id=\"issuesToggle\"><span class=\"track\"></span></span>\n </label>\n <label class=\"swrow\">\n <span class=\"lbl\">Rearrange<span class=\"sub\">drag boxes to fine-tune the layout</span></span>\n <span class=\"toggle\"><input type=\"checkbox\" id=\"dragToggle\"><span class=\"track\"></span></span>\n </label>\n <div class=\"swrow\" style=\"flex-direction:column;align-items:flex-start;gap:6px;padding:8px 12px 10px;border-top:1px solid var(--line);\">\n <span class=\"lbl\" style=\"padding:0\">Line Style<span class=\"sub\" style=\"margin-top:2px\">Choose how relationship lines are routed</span></span>\n <span class=\"selectWrap\">\n <select id=\"lineStyleSelect\" class=\"selectControl\">\n <option value=\"bezier\">Curved Bezier</option>\n <option value=\"straight\">Straight Lines</option>\n <option value=\"taxi\">Orthogonal Corners</option>\n </select>\n </span>\n </div>\n </div>\n </div>\n <button class=\"tbtn\" id=\"fitBtn\" title=\"Fit graph to view\">Fit</button>\n <button class=\"tbtn\" id=\"resetBtn\" title=\"Discard this view's saved rearrangement\">Reset layout</button>\n <button class=\"tbtn\" id=\"panelToggle\" title=\"Show or hide the details sidebar\">Details</button>\n <div class=\"dropdown\" id=\"layoutDd\">\n <button class=\"tbtn\" id=\"layoutBtn\" title=\"Choose the auto-layout algorithm\">Layout: Layered ▾</button>\n <div class=\"menu\">\n <button id=\"layoutLayered\">Layered <span class=\"hint\">dependency columns (default)</span></button>\n <button id=\"layoutForce\">Force <span class=\"hint\">physics relaxation — untangles crossings</span></button>\n <button id=\"layoutConcentric\">Concentric <span class=\"hint\">most-referenced in the centre, rings outward</span></button>\n <button id=\"layoutGrid\">Grid <span class=\"hint\">compact wrapped rows</span></button>\n </div>\n </div>\n <div class=\"dropdown\" id=\"exportDd\">\n <button class=\"tbtn\" id=\"exportBtn\">Export ▾</button>\n <div class=\"menu\">\n <button id=\"expPng\">PNG image <span class=\"hint\">this view, high-res</span></button>\n <button id=\"expDrawio\">draw.io file <span class=\"hint\">this view, editable, current layout</span></button>\n <button id=\"expExcalidraw\">Excalidraw file <span class=\"hint\">this view, editable, current layout</span></button>\n </div>\n </div>\n <button class=\"tbtn\" id=\"themeBtn\" title=\"Toggle theme\">◐ Theme</button>\n <button class=\"tbtn\" id=\"presentBtn\" title=\"Presentation mode (hides menus)\">⛶ Present</button>\n <div class=\"dropdown\" id=\"moreDd\" style=\"display:none\">\n <button class=\"tbtn\" id=\"moreBtn\" title=\"More options\">⋯</button>\n <div class=\"menu\" id=\"moreMenu\"></div>\n </div>\n</header>\n<div id=\"wrap\">\n <div id=\"stage\">\n <div id=\"cy\"></div>\n <div class=\"viewhint\" id=\"viewHint\"></div>\n <div id=\"typesWarn\"></div>\n <div class=\"legend\" id=\"legend\"></div>\n </div>\n <div id=\"panelResizer\" title=\"Drag to resize details sidebar\"></div>\n <div id=\"panel\"></div>\n</div>\n<button id=\"presentDetails\">Details</button>\n<button id=\"exitPresent\">✕ Exit presentation</button>\n<div id=\"flowModal\">\n <div class=\"box\">\n <div class=\"bar\">\n <button class=\"tbtn\" id=\"flowBack\" title=\"Back to the calling narrative\">← Back</button>\n <span class=\"crumbf\" id=\"flowCrumb\"></span>\n <span class=\"spacer\"></span>\n <div class=\"seg\" id=\"flowModeSeg\">\n <button data-fm=\"flow\" class=\"active\">Flow</button>\n <button data-fm=\"steps\">Steps</button>\n </div>\n <button class=\"tbtn\" id=\"flowErrToggle\" title=\"Hide the paths only reachable through error handling (catch regions, propagated throws)\">Hide error paths</button>\n <div class=\"dropdown\" id=\"flowExportDd\">\n <button class=\"tbtn\" id=\"flowExportBtn\">Export ▾</button>\n <div class=\"menu\">\n <button id=\"flowExpPng\">PNG image</button>\n <button id=\"flowExpDrawio\">draw.io file</button>\n <button id=\"flowExpExcalidraw\">Excalidraw file</button>\n </div>\n </div>\n <button class=\"tbtn\" id=\"flowClose\">✕</button>\n </div>\n <div id=\"flowCy\"></div>\n <div id=\"flowSteps\"></div>\n <div class=\"hintbar\">Narrative (L5) — double-click a call step to drill into the target method; Back returns to the caller.</div>\n </div>\n</div>\n<script>__CYTOSCAPE_LIB__</script>\n<script>\nvar MODEL = __MODEL_JSON__;\n</script>\n<script>\n(function () {\n 'use strict';\n var buildDrawioXml = __DRAWIO_FN__;\n var buildExcalidrawScene = __EXCALIDRAW_FN__;\n\n var store = (typeof localStorage !== 'undefined') ? localStorage : null;\n var inBrowser = (typeof window !== 'undefined');\n var STORE_KEY = 'wairon:canvas2:' + MODEL.system.name;\n\n // Embed mode: when the canvas is iframed inside the wairon web app\n // (?_embed=true), hide its own brand mark so the app's chrome isn't doubled.\n if (inBrowser && document.body && new URLSearchParams(window.location.search).get('_embed') === 'true') {\n document.body.classList.add('embed');\n }\n\n // ---- indexes -------------------------------------------------------------\n var compById = {};\n MODEL.components.forEach(function (c) { compById[c.id] = c; });\n var subById = {};\n MODEL.subsystems.forEach(function (s) { subById[s.id] = s; });\n var issuesBySpec = {};\n MODEL.issues.forEach(function (i) {\n if (!i.specId) return;\n (issuesBySpec[i.specId] = issuesBySpec[i.specId] || []).push(i);\n });\n document.getElementById('issueCount').textContent =\n MODEL.issues.filter(function (i) { return i.severity === 'error'; }).length + 'e/' +\n MODEL.issues.filter(function (i) { return i.severity === 'warning'; }).length + 'w';\n\n var PATTERN_TYPES = { Repository:1, Gateway:1, FeatureComponent:1, RouterComponent:1 };\n function stereoClass(t) {\n if (t === 'Portal' || t === 'Observer') return 'entry';\n if (t === 'Store' || t === 'Index' || t === 'Registry') return 'data';\n if (t === 'Adapter') return 'adapter';\n if (PATTERN_TYPES[t]) return 'patternLeaf';\n return 'logic';\n }\n var CN = function (id) { return 'c~' + id; };\n var SN = function (id) { return 's~' + id; };\n var IN = function (kind, id) { return 'i~' + kind + '~' + id; };\n\n // ---- ownership hierarchy ----------------------------------------------------\n function topSubsystems() {\n return MODEL.subsystems.filter(function (s) { return s.id.indexOf('::') < 0; });\n }\n function childSubsOf(subId) {\n var prefix = subId + '::';\n return MODEL.subsystems.filter(function (s) {\n return s.id.indexOf(prefix) === 0 && s.id.slice(prefix.length).indexOf('::') < 0;\n });\n }\n function childCompsOf(subId) {\n return MODEL.components.filter(function (c) { return c.subsystem === subId && !c.owner; });\n }\n function memberCompsOf(compId) {\n var c = compById[compId];\n return c ? c.owns.map(function (id) { return compById[id]; }).filter(Boolean) : [];\n }\n function childrenOf(scope) {\n var out = [];\n if (scope.kind === 'system') {\n topSubsystems().forEach(function (s) { out.push({ kind: 'subsystem', id: s.id }); });\n } else if (scope.kind === 'subsystem') {\n childSubsOf(scope.id).forEach(function (s) { out.push({ kind: 'subsystem', id: s.id }); });\n childCompsOf(scope.id).forEach(function (c) { out.push({ kind: 'component', id: c.id }); });\n } else if (scope.kind === 'component') {\n memberCompsOf(scope.id).forEach(function (c) { out.push({ kind: 'component', id: c.id }); });\n }\n out.forEach(function (e) {\n e.hasKids = e.kind === 'subsystem'\n ? (childSubsOf(e.id).length + childCompsOf(e.id).length) > 0\n : memberCompsOf(e.id).length > 0;\n });\n return out;\n }\n function subsystemChainOf(comp) {\n var segs = comp.subsystem.split('::');\n var out = [];\n for (var i = 1; i <= segs.length; i++) out.push(segs.slice(0, i).join('::'));\n return out;\n }\n function ownerChainOf(comp) {\n var out = [];\n var cur = comp;\n while (cur && cur.owner) { out.unshift(cur.owner); cur = compById[cur.owner]; }\n return out;\n }\n function childOfScopeContaining(compId, scope) {\n var c = compById[compId];\n if (!c) return null;\n var subs = subsystemChainOf(c);\n var owners = ownerChainOf(c);\n if (scope.kind === 'system') {\n return { kind: 'subsystem', id: subs[0] };\n }\n if (scope.kind === 'subsystem') {\n var idx = subs.indexOf(scope.id);\n if (idx < 0) return null;\n if (idx < subs.length - 1) return { kind: 'subsystem', id: subs[idx + 1] };\n return { kind: 'component', id: owners.length ? owners[0] : c.id };\n }\n var chain = owners.concat([c.id]);\n var pos = chain.indexOf(scope.id);\n if (pos < 0 || pos === chain.length - 1) return null;\n return { kind: 'component', id: chain[pos + 1] };\n }\n function anchorNodeId(entry) { return entry.kind === 'subsystem' ? SN(entry.id) : CN(entry.id); }\n function nameOf(entry) {\n if (entry.kind === 'subsystem') { var s = subById[entry.id]; return s ? s.name : entry.id; }\n var c = compById[entry.id]; return c ? c.name : entry.id;\n }\n\n // ---- persisted state -------------------------------------------------------\n var saved = { positionsByView: {}, theme: 'syw' };\n try { if (store && store.getItem(STORE_KEY)) saved = JSON.parse(store.getItem(STORE_KEY)) || saved; } catch (e) { /* ignore */ }\n\n var diagramConfig = MODEL.system.diagram || {};\n var showDatabaseTab = diagramConfig.showDatabases !== false;\n var configuredLineStyle = ['bezier', 'straight', 'taxi'].indexOf(diagramConfig.lineStyle) >= 0 ? diagramConfig.lineStyle : 'bezier';\n var defaultViewKind = diagramConfig.defaultView === 'types' ? 'types' : (diagramConfig.defaultView === 'databases' && showDatabaseTab ? 'databases' : 'system');\n\n var state = {\n view: { kind: defaultViewKind, id: null },\n internals: false,\n externals: true,\n dataCoupling: false,\n showIssues: false,\n query: '',\n selected: null,\n selectedKind: null,\n theme: (typeof opts !== 'undefined' && opts && opts.theme) ? (opts.theme === 'light' ? 'light' : 'syw') : (saved.theme === 'light' ? 'light' : 'syw'),\n typesDetail: ['full', 'fields', 'keys', 'names'].indexOf(saved.typesDetail) >= 0 ? saved.typesDetail : 'full',\n typesRenderAll: false,\n layout: ['layered', 'force', 'concentric', 'grid'].indexOf(saved.layout) >= 0 ? saved.layout : 'layered',\n lineStyle: ['bezier', 'straight', 'taxi'].indexOf(saved.lineStyle) >= 0 ? saved.lineStyle : configuredLineStyle,\n panelOpen: typeof saved.panelOpen === 'boolean' ? saved.panelOpen : !(inBrowser && window.innerWidth < 900),\n panelWidth: typeof saved.panelWidth === 'number' ? saved.panelWidth : 380,\n };\n // Set by buildTypeElements when the ERD is degraded for performance (huge\n // scopes); consumed by renderTypesNotice to explain the level-of-detail.\n var typesNotice = '';\n\n function viewKey() {\n // 'types2' + detail level: table sizes differ per detail, and the prefix\n // bump invalidates layouts saved for the old compact type boxes. The layout\n // strategy is part of the key so a manual rearrange is remembered per layout.\n if (state.view.kind === 'types' || state.view.kind === 'databases') return 'types2:' + (state.view.id || 'root') + ':' + state.typesDetail + ':' + state.layout;\n return state.view.kind + ':' + (state.view.id || 'root') + (state.internals ? '+i' : '') + ':' + state.layout;\n }\n function persist() {\n if (!store) return;\n try {\n store.setItem(STORE_KEY, JSON.stringify({\n positionsByView: saved.positionsByView || {},\n theme: state.theme,\n typesDetail: state.typesDetail,\n layout: state.layout,\n lineStyle: state.lineStyle,\n panelOpen: state.panelOpen,\n panelWidth: state.panelWidth,\n }));\n } catch (e) { /* non-fatal */ }\n }\n\n // ---- details panel sizing -------------------------------------------------\n var PANEL_MIN = 260;\n var PANEL_MAX = 620;\n var panelToggle = document.getElementById('panelToggle');\n var panelResizer = document.getElementById('panelResizer');\n\n function panelMaxWidth() {\n if (!inBrowser) return PANEL_MAX;\n var room = window.innerWidth <= 860 ? window.innerWidth - 44 : window.innerWidth - 320;\n return Math.max(PANEL_MIN, Math.min(PANEL_MAX, room));\n }\n function clampPanelWidth(width) {\n return Math.max(PANEL_MIN, Math.min(panelMaxWidth(), Math.round(width || 380)));\n }\n function resizeCanvasSoon() {\n setTimeout(function () {\n if (typeof cy !== 'undefined' && cy && cy.resize) cy.resize();\n }, 60);\n }\n function applyPanelState(skipPersist) {\n state.panelWidth = clampPanelWidth(state.panelWidth);\n if (document.documentElement && document.documentElement.style) {\n document.documentElement.style.setProperty('--panel-width', state.panelWidth + 'px');\n }\n if (document.body.classList) document.body.classList[state.panelOpen ? 'remove' : 'add']('panel-closed');\n if (panelToggle) {\n if (panelToggle.setAttribute) panelToggle.setAttribute('aria-expanded', state.panelOpen ? 'true' : 'false');\n panelToggle.title = state.panelOpen ? 'Hide the details sidebar' : 'Show the details sidebar';\n }\n if (!skipPersist) persist();\n resizeCanvasSoon();\n }\n applyPanelState(true);\n if (panelToggle && panelToggle.addEventListener) {\n panelToggle.addEventListener('click', function () {\n state.panelOpen = !state.panelOpen;\n applyPanelState(false);\n });\n }\n if (panelResizer && panelResizer.addEventListener) {\n panelResizer.addEventListener('mousedown', function (ev) {\n if (ev && ev.preventDefault) ev.preventDefault();\n state.panelOpen = true;\n applyPanelState(false);\n if (document.body.classList) document.body.classList.add('resizing-panel');\n function move(mev) {\n var next = inBrowser ? window.innerWidth - mev.clientX : state.panelWidth;\n state.panelWidth = clampPanelWidth(next);\n if (document.documentElement && document.documentElement.style) {\n document.documentElement.style.setProperty('--panel-width', state.panelWidth + 'px');\n }\n resizeCanvasSoon();\n }\n function done() {\n if (document.body.classList) document.body.classList.remove('resizing-panel');\n document.removeEventListener('mousemove', move);\n document.removeEventListener('mouseup', done);\n persist();\n }\n document.addEventListener('mousemove', move);\n document.addEventListener('mouseup', done);\n });\n }\n if (inBrowser && window.addEventListener) {\n window.addEventListener('resize', function () { applyPanelState(false); });\n }\n\n function matches(entry) {\n if (!state.query) return true;\n var q = state.query.toLowerCase();\n return entry.id.toLowerCase().indexOf(q) >= 0 || nameOf(entry).toLowerCase().indexOf(q) >= 0;\n }\n\n // ---- themes (solid fills, WCAG AA text contrast) ------------------------------\n var THEMES = {\n light: {\n pageEdge: '#5f6b78', edgeText: '#3d4650', cross: '#b3261e', ink: '#1a1f24',\n subFill: '#e9eef4', subStroke: '#8195aa', subText: '#122a44',\n patFill: '#eef1f5', patStroke: '#5f6b78',\n innerFill: '#dbe3ec', innerStroke: '#8195aa', innerText: '#1a1f24',\n ghostFill: '#eceff2', ghostStroke: '#7d8a97', ghostText: '#414b55',\n typeE: { fill: '#e6efd8', stroke: '#4e6b23', text: '#22300d' },\n typeV: { fill: '#ecdff3', stroke: '#6e4288', text: '#2d1740' },\n proxyIn: { fill: '#d5eef8', stroke: '#14708f' },\n proxyOut: { fill: '#f7e8cd', stroke: '#8a6116' },\n stereo: {\n entry: { fill: '#dcebff', stroke: '#2f5fa8', text: '#0f2a4d' },\n logic: { fill: '#ece2fb', stroke: '#6d3fbf', text: '#2a1650' },\n data: { fill: '#f7ecd0', stroke: '#8a6116', text: '#3d2c05' },\n adapter: { fill: '#dcf2e4', stroke: '#2e7d4f', text: '#0e3320' },\n patternLeaf: { fill: '#eef1f5', stroke: '#5f6b78', text: '#1a1f24' },\n },\n issue: '#b3261e', selGlow: '#3465b4', bgLabel: '#f2f5f8', png: '#f2f5f8',\n },\n syw: {\n pageEdge: '#7c8ca3', edgeText: '#aebdd2', cross: '#ff6b81', ink: '#eef2f8',\n subFill: '#101f33', subStroke: '#3ec5e8', subText: '#7fe7ff',\n patFill: '#1b2740', patStroke: '#93a1b8',\n innerFill: '#243a5c', innerStroke: '#6b7c96', innerText: '#eef2f8',\n ghostFill: '#16202f', ghostStroke: '#5d6b80', ghostText: '#aab8cc',\n typeE: { fill: '#1e3317', stroke: '#8fd14f', text: '#e2f5cf' },\n typeV: { fill: '#321a3d', stroke: '#c084fc', text: '#f0dcff' },\n proxyIn: { fill: '#0d3b4a', stroke: '#22ddff' },\n proxyOut: { fill: '#3b2a10', stroke: '#f59e0b' },\n stereo: {\n entry: { fill: '#0d2b4d', stroke: '#22ddff', text: '#d8f6ff' },\n logic: { fill: '#2a2052', stroke: '#a78bfa', text: '#eae2ff' },\n data: { fill: '#3a2c10', stroke: '#f59e0b', text: '#ffe9c2' },\n adapter: { fill: '#0f3323', stroke: '#34d399', text: '#d3f8e6' },\n patternLeaf: { fill: '#1b2740', stroke: '#93a1b8', text: '#eef2f8' },\n },\n issue: '#ff6b81', selGlow: '#22ddff', bgLabel: '#0a0a0f', png: '#0a0a0f',\n },\n };\n\n function buildStyle(t) {\n var routingStyle = state.lineStyle === 'taxi'\n ? { 'curve-style': 'taxi', 'taxi-direction': 'horizontal', 'taxi-turn': 54, 'taxi-turn-min-distance': 34 }\n : state.lineStyle === 'straight'\n ? { 'curve-style': 'straight' }\n : { 'curve-style': 'unbundled-bezier', 'control-point-distances': [78], 'control-point-weights': [0.48] };\n var routedStyle = state.lineStyle === 'bezier'\n ? { 'control-point-distances': 'data(cpDist)', 'control-point-weights': 'data(cpWeight)' }\n : state.lineStyle === 'taxi'\n ? { 'taxi-turn': 'data(taxiTurn)' }\n : {};\n return [\n { selector: 'node', style: {\n shape: 'round-rectangle', width: 'data(w)', height: 'data(h)',\n label: 'data(label)', 'text-wrap': 'wrap', 'text-max-width': 'data(tw)',\n 'font-family': 'Inter, system-ui, sans-serif', 'font-size': 11, color: t.ink,\n 'text-valign': 'center', 'text-halign': 'center', 'border-width': 1.5,\n }},\n { selector: '.entry', style: { 'background-color': t.stereo.entry.fill, 'border-color': t.stereo.entry.stroke, color: t.stereo.entry.text } },\n { selector: '.logic', style: { 'background-color': t.stereo.logic.fill, 'border-color': t.stereo.logic.stroke, color: t.stereo.logic.text } },\n { selector: '.data', style: { 'background-color': t.stereo.data.fill, 'border-color': t.stereo.data.stroke, color: t.stereo.data.text } },\n { selector: '.adapter', style: { 'background-color': t.stereo.adapter.fill, 'border-color': t.stereo.adapter.stroke, color: t.stereo.adapter.text } },\n { selector: '.patternLeaf', style: { 'background-color': t.stereo.patternLeaf.fill, 'border-color': t.stereo.patternLeaf.stroke, color: t.stereo.patternLeaf.text, 'border-style': 'dashed' } },\n { selector: '.subsysBox', style: { 'background-color': t.subFill, 'border-color': t.subStroke, color: t.subText, 'font-weight': 'bold', 'font-size': 12.5 } },\n { selector: 'node.public', style: { 'border-width': 3.5 } },\n { selector: ':parent', style: { 'text-valign': 'top', 'text-halign': 'center', 'font-size': 12, 'font-weight': 'bold', 'text-margin-y': -5, padding: '10px', 'background-opacity': 1 } },\n { selector: '.inner', style: { 'background-color': t.innerFill, 'border-color': t.innerStroke, 'border-width': 1.2, 'font-size': 9.5, color: t.innerText } },\n { selector: '.ghost', style: { 'background-color': t.ghostFill, 'border-color': t.ghostStroke, 'border-style': 'dotted', color: t.ghostText, 'font-size': 10 } },\n { selector: '.typeEntity', style: { 'background-color': t.typeE.fill, 'border-color': t.typeE.stroke, color: t.typeE.text, 'text-halign': 'center', 'font-size': 10.5 } },\n { selector: '.typeValue', style: { 'background-color': t.typeV.fill, 'border-color': t.typeV.stroke, color: t.typeV.text, 'border-style': 'dashed', 'font-size': 10.5 } },\n { selector: '.typeBox', style: { 'background-opacity': 0.18, padding: '0px', 'border-width': 1.8 } },\n { selector: '.typeHead', style: { 'font-weight': 'bold', 'font-size': 11 } },\n { selector: '.typeRow', style: { 'background-color': t.innerFill, 'border-color': t.innerStroke, 'border-width': 0.5, color: t.innerText, 'font-size': 10, 'text-justification': 'left', shape: 'rectangle' } },\n { selector: '.typePlain', style: { 'font-weight': 'bold' } },\n { selector: 'edge.typeref', style: { width: 1.4, 'line-style': 'solid' } },\n { selector: 'edge.erd', style: { 'source-label': '1', 'target-label': 'data(tcard)', 'source-text-offset': 16, 'target-text-offset': 22, 'font-size': 9.5, color: t.edgeText } },\n { selector: 'edge.fieldhl', style: { 'line-color': t.selGlow, 'target-arrow-color': t.selGlow, width: 2.6 } },\n { selector: '.proxyExt', style: { 'font-size': 12, 'border-width': 1.6 } },\n { selector: '.proxyIn', style: { 'background-color': t.proxyIn.fill, 'border-color': t.proxyIn.stroke, color: t.proxyIn.stroke } },\n { selector: '.proxyOut', style: { 'background-color': t.proxyOut.fill, 'border-color': t.proxyOut.stroke, color: t.proxyOut.stroke } },\n { selector: 'edge.revealEdge', style: { 'line-color': t.selGlow, 'target-arrow-color': t.selGlow, 'line-style': 'dashed', width: 2.4, opacity: 0.95 } },\n { selector: 'edge', style: Object.assign({}, routingStyle, {\n width: 1.8, 'line-color': t.pageEdge,\n 'target-arrow-shape': 'triangle', 'target-arrow-color': t.pageEdge, 'arrow-scale': 0.9,\n label: 'data(lbl)', 'font-size': 10, color: t.edgeText,\n 'text-background-color': t.bgLabel, 'text-background-opacity': 0.85, 'text-rotation': 'autorotate',\n })},\n { selector: 'edge.routed', style: routedStyle },\n { selector: 'edge.cross', style: { 'line-color': t.cross, 'target-arrow-color': t.cross, width: 2.6 } },\n { selector: 'edge.datacoupling', style: {\n 'line-color': t.typeV.stroke, 'target-arrow-color': t.typeV.stroke, 'line-style': 'dashed',\n width: 1.8, 'arrow-scale': 0.85, label: 'data(lbl)', 'font-size': 9, color: t.typeV.stroke,\n 'text-background-color': t.bgLabel, 'text-background-opacity': 0.85, 'text-rotation': 'autorotate',\n }},\n { selector: 'edge.bundle', style: { width: 4.5, opacity: 0.7 } },\n { selector: 'edge.toghost', style: { 'line-style': 'dashed', opacity: 0.75 } },\n { selector: 'edge.inneredge', style: { width: 1.1, 'arrow-scale': 0.6, opacity: 0.8 } },\n { selector: 'edge.stubHover', style: { 'line-color': t.selGlow, 'target-arrow-color': t.selGlow, width: 2.6, opacity: 1, 'z-compound-depth': 'top' } },\n { selector: '.dimmed', style: { opacity: 0.13 } },\n { selector: '.hasIssue', style: { 'border-color': t.issue, 'border-style': 'dashed', 'border-width': 3 } },\n // Overlay only (no border) — a border changes node geometry, which nudges\n // the compound parent and makes hover flicker; overlay never affects layout.\n { selector: '.sel', style: { 'overlay-color': t.selGlow, 'overlay-opacity': 0.34, 'overlay-padding': 6 } },\n { selector: '.hoverhl', style: { 'overlay-color': t.selGlow, 'overlay-opacity': 0.2, 'overlay-padding': 6 } },\n // Focus mode: on selection, the picked element's edges are lifted above\n // every box and recoloured, while unrelated elements recede — so a single\n // block's relations read clearly even in a dense graph.\n { selector: '.defocus', style: { opacity: 0.08 } },\n { selector: 'edge.edgeFocus', style: {\n 'line-color': t.selGlow, 'target-arrow-color': t.selGlow, 'source-arrow-color': t.selGlow,\n width: 3.6, opacity: 1, 'z-compound-depth': 'top', 'z-index': 9999,\n 'text-background-opacity': 1,\n }},\n // Directional focus: outgoing (this element depends on →) vs incoming\n // (← something depends on this element) get distinct colours.\n { selector: 'edge.edgeOut', style: {\n 'line-color': t.selGlow, 'target-arrow-color': t.selGlow, 'source-arrow-color': t.selGlow,\n width: 3.6, opacity: 1, 'z-compound-depth': 'top', 'z-index': 9999, 'text-background-opacity': 1,\n }},\n { selector: 'edge.edgeIn', style: {\n 'line-color': t.warn, 'target-arrow-color': t.warn, 'source-arrow-color': t.warn,\n width: 3.6, opacity: 1, 'z-compound-depth': 'top', 'z-index': 9998, 'text-background-opacity': 1,\n }},\n { selector: 'node.typeCluster', style: {\n 'background-color': t.subFill, 'border-color': t.subStroke, color: t.subText,\n 'font-weight': 'bold', 'font-size': 12, 'border-width': 2, 'text-wrap': 'wrap',\n }},\n ];\n }\n\n function renderLegend() {\n var t = THEMES[state.theme];\n var sw = function (c) { return '<span class=\"sw\" style=\"background:' + c.fill + ';border-color:' + c.stroke + '\"></span>'; };\n document.getElementById('legend').innerHTML =\n sw({ fill: t.subFill, stroke: t.subStroke }) + 'Subsystem&nbsp; ' +\n sw(t.stereo.entry) + 'Portal/Observer&nbsp; ' + sw(t.stereo.logic) + 'Logic&nbsp; ' +\n sw(t.stereo.data) + 'Data&nbsp; ' + sw(t.stereo.adapter) + 'Adapter&nbsp; ' +\n sw(t.stereo.patternLeaf) + 'Pattern&nbsp; ' +\n sw({ fill: t.ghostFill, stroke: t.ghostStroke }) + 'External&nbsp; ' +\n sw(t.proxyIn) + '\\\\u21E0 in-port&nbsp; ' + sw(t.proxyOut) + '\\\\u21E2 out-port&nbsp; — bold border = published · ' +\n '<span style=\"color:' + t.cross + '\">red</span> = boundary hop · double-click = open<br>' +\n 'on select: <span style=\"color:' + t.selGlow + '\">\\\\u2192 depends on</span>&nbsp; <span style=\"color:' + t.warn + '\">\\\\u2190 used by</span>' +\n (state.dataCoupling ? '&nbsp; · &nbsp;<span style=\"color:' + t.typeV.stroke + '\">- - \\\\u25B8 uses models</span>' : '');\n }\n\n // ---- view layout ---------------------------------------------------------------\n var BOX_W = 200, BOX_H = 56, SUBBOX_W = 230, SUBBOX_H = 84, GAP_X = 110, GAP_Y = 34;\n var INNER_W = 130, INNER_H = 36, INNER_GAPX = 26, INNER_GAPY = 12, HEAD_H = 34, PADI = 14;\n\n // Micro-layout for a container's direct children when Internals is on:\n // layered mini columns + intra-container edges. Each external relation gets\n // its own small PORT node INSIDE the container (one per external\n // counterpart; incoming left, outgoing right). Children connect to ports\n // with short edges that never leave the box — the real cross-boundary line\n // is only revealed on hover, or pinned while the port is selected.\n function innerLayout(entry) {\n var kids = state.internals && entry.hasKids ? childrenOf({ kind: entry.kind, id: entry.id }) : [];\n if (!kids.length) return null;\n var scope = { kind: entry.kind, id: entry.id };\n var kidAnchor = {};\n kids.forEach(function (k) { kidAnchor[k.kind + ':' + k.id] = k; });\n var parentId = anchorNodeId(entry);\n var pBaseIn = 'p~in~' + parentId + '~', pBaseOut = 'p~out~' + parentId + '~';\n var edges = {};\n var extIn = {}, extOut = {};\n MODEL.edges.forEach(function (edge) {\n var a = childOfScopeContaining(edge.from, scope);\n var b = childOfScopeContaining(edge.to, scope);\n var aKid = a && kidAnchor[a.kind + ':' + a.id];\n var bKid = b && kidAnchor[b.kind + ':' + b.id];\n if (aKid && bKid) {\n if (a.kind === b.kind && a.id === b.id) return;\n edges[IN(a.kind, a.id) + '=>' + IN(b.kind, b.id)] = { src: IN(a.kind, a.id), tgt: IN(b.kind, b.id) };\n } else if (aKid && !bKid) {\n // raws = raw ids on OUR side of the relation — they key the matching\n // port inside the counterpart's container (port-to-port reveal).\n var ro = extOut[edge.to] = extOut[edge.to] || { kids: {}, raws: {} };\n ro.kids[a.kind + ':' + a.id] = a;\n ro.raws[edge.from] = 1;\n edges[IN(a.kind, a.id) + '=>' + pBaseOut + edge.to] = { src: IN(a.kind, a.id), tgt: pBaseOut + edge.to, stub: true };\n } else if (!aKid && bKid) {\n var ri = extIn[edge.from] = extIn[edge.from] || { kids: {}, raws: {} };\n ri.kids[b.kind + ':' + b.id] = b;\n ri.raws[edge.to] = 1;\n edges[pBaseIn + edge.from + '=>' + IN(b.kind, b.id)] = { src: pBaseIn + edge.from, tgt: IN(b.kind, b.id), stub: true };\n }\n });\n // layering\n var layer = {};\n function calc(k, stack) {\n var key = IN(k.kind, k.id);\n if (layer[key] !== undefined) return layer[key];\n if (stack[key]) return 0;\n stack[key] = 1;\n var l = 0;\n if (k.kind === 'component') {\n var c = compById[k.id];\n if (c && (c.componentType === 'Portal' || c.componentType === 'Observer')) { layer[key] = 0; delete stack[key]; return 0; }\n }\n Object.keys(edges).forEach(function (ek) {\n var e = edges[ek];\n if (e.tgt !== key) return;\n var srcKid = kids.filter(function (x) { return IN(x.kind, x.id) === e.src; })[0];\n if (srcKid) l = Math.max(l, calc(srcKid, stack) + 1);\n });\n delete stack[key];\n layer[key] = l;\n return l;\n }\n kids.forEach(function (k) { calc(k, {}); });\n var cols = {};\n kids.forEach(function (k) { var l = layer[IN(k.kind, k.id)] || 0; (cols[l] = cols[l] || []).push(k); });\n var colKeys = Object.keys(cols).map(Number).sort(function (a, b) { return a - b; });\n var inIds = Object.keys(extIn).sort(), outIds = Object.keys(extOut).sort();\n var hasIn = inIds.length > 0, hasOut = outIds.length > 0;\n var PROXY_W = 22, PROXY_H = 22, PROXY_GAP = 8;\n // Inner tile placement mirrors the diagram's chosen layout (ports still flank\n // the box on the left/right). Layered keeps the dependency columns; Grid and\n // Concentric re-place the children; Force approximates with Concentric (a\n // physics sim can't run inside a build-time sub-layout).\n var leftPad = PADI + (hasIn ? PROXY_W + INNER_GAPX : 0);\n var tiles = [], x, maxH;\n var kidKey = function (k) { return IN(k.kind, k.id); };\n if (state.layout === 'grid' || state.layout === 'concentric' || state.layout === 'force') {\n var ids = kids.map(kidKey), byKey = {};\n kids.forEach(function (k) { byKey[kidKey(k)] = k; });\n var rel;\n if (state.layout === 'grid') {\n rel = {};\n var per = Math.max(1, Math.ceil(Math.sqrt(ids.length)));\n ids.slice().sort().forEach(function (id, idx) { rel[id] = { x: (idx % per) * (INNER_W + INNER_GAPX), y: Math.floor(idx / per) * (INNER_H + INNER_GAPY) }; });\n } else {\n var ideg = {};\n ids.forEach(function (id) { ideg[id] = 0; });\n Object.keys(edges).forEach(function (ek) { var e = edges[ek]; if (ideg[e.src] !== undefined) ideg[e.src]++; if (ideg[e.tgt] !== undefined) ideg[e.tgt]++; });\n rel = concentricPositions(ids, function (id) { return ideg[id] || 0; }, function () { return { w: INNER_W, h: INNER_H }; });\n }\n var minX = Infinity, minY = Infinity;\n ids.forEach(function (id) { var p = rel[id] || { x: 0, y: 0 }; if (p.x < minX) minX = p.x; if (p.y < minY) minY = p.y; });\n if (minX === Infinity) { minX = 0; minY = 0; }\n tiles = ids.map(function (id) { var p = rel[id] || { x: 0, y: 0 }; return { kid: byKey[id], x: leftPad + (p.x - minX) + INNER_W / 2, y: HEAD_H + (p.y - minY) + INNER_H / 2 }; });\n var maxRight = leftPad + INNER_W, maxBottom = HEAD_H + INNER_H;\n tiles.forEach(function (t) { maxRight = Math.max(maxRight, t.x + INNER_W / 2); maxBottom = Math.max(maxBottom, t.y + INNER_H / 2); });\n x = maxRight + INNER_GAPX;\n maxH = maxBottom + INNER_GAPY;\n } else {\n x = leftPad; maxH = 0;\n colKeys.forEach(function (ck) {\n var col = cols[ck].sort(function (a, b) { return a.id < b.id ? -1 : 1; });\n var y = HEAD_H;\n col.forEach(function (k) {\n tiles.push({ kid: k, x: x + INNER_W / 2, y: y + INNER_H / 2 });\n y += INNER_H + INNER_GAPY;\n });\n maxH = Math.max(maxH, y);\n x += INNER_W + INNER_GAPX;\n });\n }\n var stackMax = Math.max(inIds.length, outIds.length);\n maxH = Math.max(maxH, HEAD_H + stackMax * PROXY_H + Math.max(0, stackMax - 1) * PROXY_GAP + INNER_GAPY);\n var midY = HEAD_H + Math.max(0, (maxH - HEAD_H - INNER_GAPY) / 2);\n var outX = x;\n if (hasOut) x += PROXY_W + INNER_GAPX;\n function stackPorts(ids, recs, base, cx, dir) {\n var total = ids.length * PROXY_H + Math.max(0, ids.length - 1) * PROXY_GAP;\n var y0 = Math.max(HEAD_H + PROXY_H / 2, midY - total / 2 + PROXY_H / 2);\n return ids.map(function (eid, i) {\n var km = recs[eid].kids, klist = [];\n Object.keys(km).forEach(function (key) { klist.push(km[key]); });\n return { id: base + eid, extId: eid, dir: dir, kids: klist, raws: Object.keys(recs[eid].raws), x: cx, y: y0 + i * (PROXY_H + PROXY_GAP), w: PROXY_W, h: PROXY_H };\n });\n }\n return {\n tiles: tiles,\n edges: Object.keys(edges).map(function (k) { return edges[k]; }),\n proxies: stackPorts(inIds, extIn, pBaseIn, PADI + PROXY_W / 2, 'in')\n .concat(stackPorts(outIds, extOut, pBaseOut, outX + PROXY_W / 2, 'out')),\n w: Math.max(x - INNER_GAPX + PADI, entry.kind === 'subsystem' ? SUBBOX_W : BOX_W),\n h: maxH - INNER_GAPY + PADI,\n };\n }\n\n function sizeOf(entry, inner) {\n if (inner) return { w: inner.w, h: inner.h };\n return entry.kind === 'subsystem' ? { w: SUBBOX_W, h: SUBBOX_H } : { w: BOX_W, h: BOX_H };\n }\n\n function viewEdges(scope, entries, edgeList) {\n edgeList = edgeList || MODEL.edges;\n var entryByAnchor = {};\n entries.forEach(function (e) { entryByAnchor[e.kind + ':' + e.id] = e; });\n var agg = {}, ghosts = {};\n edgeList.forEach(function (edge) {\n var a = childOfScopeContaining(edge.from, scope);\n var b = childOfScopeContaining(edge.to, scope);\n var aIn = a && entryByAnchor[a.kind + ':' + a.id];\n var bIn = b && entryByAnchor[b.kind + ':' + b.id];\n if (!aIn && !bIn) return;\n var src, tgt, ghost = false;\n if (aIn && bIn) {\n if (a.kind === b.kind && a.id === b.id) return;\n src = anchorNodeId(a); tgt = anchorNodeId(b);\n } else if (state.externals) {\n ghost = true;\n if (aIn) {\n var ext = externalAnchorFor(edge.to, scope);\n if (!ext) return;\n ghosts[ext.gid] = ext;\n src = anchorNodeId(a); tgt = ext.gid;\n } else {\n var ext2 = externalAnchorFor(edge.from, scope);\n if (!ext2) return;\n ghosts[ext2.gid] = ext2;\n src = ext2.gid; tgt = anchorNodeId(b);\n }\n } else {\n return;\n }\n var key = src + '=>' + tgt;\n if (!agg[key]) agg[key] = { src: src, tgt: tgt, n: 0, cross: false, ghost: ghost };\n agg[key].n++;\n if (edge.cross) agg[key].cross = true;\n });\n return { agg: agg, ghosts: ghosts };\n }\n\n function externalAnchorFor(compId, scope) {\n var c = compById[compId];\n if (!c) return null;\n var contexts = [];\n if (scope.kind === 'component') {\n var oc = compById[scope.id];\n var chain = oc ? ownerChainOf(oc) : [];\n for (var i = chain.length - 1; i >= 0; i--) contexts.push({ kind: 'component', id: chain[i] });\n if (oc) subsystemChainOf(oc).reverse().forEach(function (sid) { contexts.push({ kind: 'subsystem', id: sid }); });\n } else if (scope.kind === 'subsystem') {\n var segs = scope.id.split('::');\n for (var j = segs.length - 1; j >= 1; j--) contexts.push({ kind: 'subsystem', id: segs.slice(0, j).join('::') });\n }\n contexts.push({ kind: 'system', id: null });\n for (var k = 0; k < contexts.length; k++) {\n var child = childOfScopeContaining(compId, contexts[k]);\n if (child) {\n return { gid: 'x~' + child.kind + '~' + child.id, kind: child.kind, id: child.id, label: nameOf(child) };\n }\n }\n return null;\n }\n\n // ---- Types (ERD) view ------------------------------------------------------\n function typeMatches(t) {\n if (!state.query) return true;\n var q = state.query.toLowerCase();\n return t.id.toLowerCase().indexOf(q) >= 0 || t.name.toLowerCase().indexOf(q) >= 0;\n }\n // Types visible in the current ERD scope: the focused subsystem's own (and\n // nested) types, plus only the system-level SHARED types those own types\n // actually reference — NOT the entire shared library. (Including all shared\n // types flooded a small subsystem's scope so it re-clustered and its single\n // own type was unreachable.) Unscoped = all.\n var SHARED_KEY = '\\\\u2014 shared \\\\u2014';\n function databaseAllowsType(t) {\n if (!t.database) return false;\n if (!MODEL.system.databases || !MODEL.system.databases.length) return true;\n var db = MODEL.system.databases.find(function (d) { return d.id === t.database; });\n if (!db || !db.tables || !db.tables.length) return true;\n return db.tables.indexOf(t.id) >= 0 || db.tables.indexOf(t.table || t.id) >= 0;\n }\n function typesInScope() {\n var sid = state.view.id;\n if (state.view.kind === 'databases') {\n return MODEL.types.filter(function (t) {\n if (!databaseAllowsType(t)) return false;\n if (sid) {\n return t.database === sid || t.subsystem === sid || (t.subsystem && t.subsystem.indexOf(sid + '::') === 0);\n }\n return true;\n });\n }\n if (!sid) return MODEL.types;\n // The shared-library cluster scopes to the system-level (unowned) types.\n if (sid === SHARED_KEY) return MODEL.types.filter(function (t) { return !t.subsystem; });\n var own = {};\n MODEL.types.forEach(function (t) {\n if (t.subsystem === sid || (t.subsystem && t.subsystem.indexOf(sid + '::') === 0)) own[t.id] = 1;\n });\n var sharedRef = {};\n MODEL.typeEdges.forEach(function (e) {\n if (own[e.from] && !own[e.to]) sharedRef[e.to] = 1;\n if (own[e.to] && !own[e.from]) sharedRef[e.from] = 1;\n });\n return MODEL.types.filter(function (t) {\n return own[t.id] || (!t.subsystem && sharedRef[t.id]);\n });\n }\n\n // ERD proper: each type is a compound TABLE — header row + one child node\n // per field (marker | name | type), so relation edges anchor at the exact\n // field they originate from. Detail levels: full (+methods), fields, keys\n // (PK/U/FK rows only), names (headers + aggregated dependency lines).\n // Level-of-detail thresholds: a system can have 1000+ types, and a full\n // compound table per type (header + a node per field) melts the renderer.\n // Above CLUSTER_AT we draw a subsystem-cluster overview (a handful of nodes,\n // drill in for detail); above NAMES_AT we force header-only boxes. The user\n // can override to force full detail (accepting the cost) via the banner.\n var TYPES_CLUSTER_AT = 400, TYPES_NAMES_AT = 120;\n\n // Size-aware concentric placement shared by the component view and the ERD.\n // Rank by degree (references); the most-connected sit toward the centre. A\n // ring's radius is derived from the ACTUAL node sizes it must hold (so it is\n // only as spacious as needed, and dense rings grow), and a tied innermost tier\n // becomes a proper ring rather than a pile at the centre — only a lone top\n // node truly sits at (0,0). Returns { id: {x, y} } (centres).\n function concentricPositions(ids, degFn, sizeFn, aspectX, rankFn) {\n aspectX = aspectX || 1; // >1 widens the rings into landscape ellipses\n if (!ids.length) return {};\n var sorted = ids.slice().sort(function (a, b) { return (degFn(b) - degFn(a)) || (a < b ? -1 : 1); });\n var rings = [], idx = 0;\n if (sorted.length === 1 || degFn(sorted[0]) > degFn(sorted[1])) { rings.push([sorted[0]]); idx = 1; }\n var rn = rings.length;\n while (idx < sorted.length) {\n var cap = Math.max(6, rn * 8);\n rings.push(sorted.slice(idx, idx + cap));\n idx += cap; rn++;\n }\n var pos = {}, prevRadius = 0, prevMaxDim = 0;\n var RING_GAP = 80, ARC_GAP = 70;\n rings.forEach(function (members, ri) {\n var maxDim = 0, maxW = 0;\n members.forEach(function (id) { var s = sizeFn(id); if (Math.max(s.w, s.h) > maxDim) maxDim = Math.max(s.w, s.h); if (s.w > maxW) maxW = s.w; });\n var n = members.length;\n var radius;\n if (ri === 0 && n === 1) {\n radius = 0;\n } else {\n // Chord constraint: adjacent nodes on the ring must clear each other's\n // width, so the radius is derived from the actual node width — not an\n // arc-length estimate (which under-sizes small rings and overlaps).\n var chordR = n >= 2 ? (maxW + ARC_GAP) / (2 * Math.sin(Math.PI / n)) : 0;\n radius = Math.max(chordR, prevRadius + prevMaxDim / 2 + maxDim / 2 + RING_GAP);\n }\n if (radius === 0) {\n members.forEach(function (id) { pos[id] = { x: 0, y: 0 }; });\n } else if (rankFn) {\n // Flow order: sort the ring by rank (entrypoints first) and lay it out\n // from TOP to BOTTOM on both sides — so entrypoints sit at the top and\n // leaves at the bottom, at the same density (no new overlap).\n var ordered = members.slice().sort(function (a, b) { return (rankFn(a) - rankFn(b)) || (a < b ? -1 : 1); });\n var mL = Math.ceil(n / 2), mR = n - mL;\n ordered.forEach(function (id, i) {\n var ang = (i % 2 === 0)\n ? -Math.PI / 2 - ((i / 2) + 0.5) / mL * Math.PI // left column, top → bottom\n : -Math.PI / 2 + (((i - 1) / 2) + 0.5) / Math.max(1, mR) * Math.PI; // right column\n pos[id] = { x: Math.cos(ang) * radius * aspectX, y: Math.sin(ang) * radius };\n });\n } else {\n members.forEach(function (id, i) {\n var ang = n === 1 ? -Math.PI / 2 : (i / n) * 2 * Math.PI - Math.PI / 2;\n pos[id] = { x: Math.cos(ang) * radius * aspectX, y: Math.sin(ang) * radius };\n });\n }\n prevRadius = radius; prevMaxDim = maxDim;\n });\n return pos;\n }\n\n // Collapse the in-scope types into one node per child subsystem, with\n // aggregated cross-cluster reference edges — the whole system as a small,\n // fast, navigable map. Returns null if it wouldn't reduce to >1 cluster.\n function buildTypeClusters(list) {\n var scopeId = state.view.id;\n function keyOf(t) {\n var sub = t.subsystem || '';\n if (!sub) return '\\\\u2014 shared \\\\u2014';\n if (!scopeId) return sub.split('::')[0];\n if (sub === scopeId) return scopeId;\n if (sub.indexOf(scopeId + '::') === 0) return scopeId + '::' + sub.slice(scopeId.length + 2).split('::')[0];\n return sub.split('::')[0];\n }\n var groups = {}, order = [], clusterOf = {};\n list.forEach(function (t) {\n var k = keyOf(t); clusterOf[t.id] = k;\n if (!groups[k]) { groups[k] = 0; order.push(k); }\n groups[k]++;\n });\n if (order.length < 2) return null;\n var agg = {};\n MODEL.typeEdges.forEach(function (e) {\n var a = clusterOf[e.from], b = clusterOf[e.to];\n if (a === undefined || b === undefined || a === b) return;\n var key = a + '=>' + b; agg[key] = (agg[key] || 0) + 1;\n });\n var out = [], keys = order.slice().sort();\n var per = Math.max(1, Math.ceil(Math.sqrt(keys.length)));\n keys.forEach(function (k, i) {\n var nm = subById[k] ? subById[k].name : k;\n out.push({\n data: { id: 'TC~' + k, label: nm + '\\\\n' + groups[k] + ' types', w: 210, h: 66, tw: 192, clusterKey: k },\n position: { x: (i % per) * 300, y: Math.floor(i / per) * 150 }, classes: 'typeCluster',\n });\n });\n var ei = 0;\n Object.keys(agg).forEach(function (key) {\n var pr = key.split('=>');\n out.push({ data: { id: 'tc' + (ei++), source: 'TC~' + pr[0], target: 'TC~' + pr[1], lbl: agg[key] > 1 ? String(agg[key]) : '' }, classes: 'typeref' });\n });\n return out;\n }\n\n function buildTypeElements() {\n var eles = [];\n var det = state.typesDetail;\n var list = typesInScope();\n typesNotice = '';\n if (!state.typesRenderAll) {\n if (list.length > TYPES_CLUSTER_AT) {\n var clustered = buildTypeClusters(list);\n if (clustered) { typesNotice = 'cluster:' + list.length; return clustered; }\n }\n if (list.length > TYPES_NAMES_AT && det !== 'names') { det = 'names'; typesNotice = 'names:' + list.length; }\n }\n var inList = {};\n list.forEach(function (t) { inList[t.id] = 1; });\n\n var CARD_RANK = { '1': 0, '0..1': 1, '*': 2 };\n var fkBy = {}, aggRefs = {};\n MODEL.typeEdges.forEach(function (e) {\n if (!inList[e.from] || !inList[e.to]) return;\n (fkBy[e.from] = fkBy[e.from] || {})[e.field] = e;\n var key = e.from + '=>' + e.to;\n if (!aggRefs[key]) aggRefs[key] = { from: e.from, to: e.to, card: e.card || '1' };\n else if (CARD_RANK[e.card] > CARD_RANK[aggRefs[key].card]) aggRefs[key].card = e.card;\n });\n\n function markerOf(t, f) {\n if (f.key === 'primary') return 'PK';\n if (f.key === 'unique') return 'U';\n if (fkBy[t.id] && fkBy[t.id][f.name]) return 'FK';\n return '';\n }\n function visibleFields(t) {\n if (det === 'names') return [];\n if (det === 'keys') return t.fields.filter(function (f) { return markerOf(t, f) !== ''; });\n return t.fields;\n }\n function rowText(t, f) {\n var m = markerOf(t, f);\n return (m ? '[' + m + '] ' : '') + f.name + (f.optional ? '?' : '') + ': ' + f.type;\n }\n\n var groups = {}, groupIds = [];\n list.forEach(function (t) {\n var g = t.subsystem || '\\\\u2014 shared \\\\u2014';\n if (!groups[g]) { groups[g] = []; groupIds.push(g); }\n groups[g].push(t);\n });\n groupIds.sort();\n var multi = groupIds.length > 1;\n\n var layer = {};\n function calc(id, stack) {\n if (layer[id] !== undefined) return layer[id];\n if (stack[id]) return 0;\n stack[id] = 1;\n var l = 0;\n Object.keys(aggRefs).forEach(function (k) {\n var r = aggRefs[k];\n if (r.to !== id) return;\n l = Math.max(l, calc(r.from, stack) + 1);\n });\n delete stack[id];\n layer[id] = l;\n return l;\n }\n list.forEach(function (t) { calc(t.id, {}); });\n\n var ROW_H = 20, TH_H = 26, X_GAP = 170, Y_GAP = 60, GROUP_GAP = 130;\n var rowIds = {};\n\n // Table geometry, independent of placement — so a layout strategy can size\n // tables before choosing anchors.\n function tableShape(t) {\n var fields = visibleFields(t);\n var meths = det === 'full' ? t.methods : [];\n var head = t.name + ' \\\\u00AB' + t.kind + '\\\\u00BB';\n var rows = fields.map(function (f) { return rowText(t, f); })\n .concat(meths.map(function (m) { return '\\\\u0192 ' + m.name + '(): ' + m.returns; }));\n var longest = head.length + 4;\n rows.forEach(function (r) { if (r.length > longest) longest = r.length; });\n var plain = rows.length === 0;\n var pw = Math.max(170, head.length * 6.8 + 26);\n var W = Math.max(210, Math.min(400, longest * 6.6 + 30));\n return { fields: fields, meths: meths, head: head, plain: plain, w: plain ? pw : W, h: plain ? 40 : TH_H + fields.length * ROW_H + meths.length * ROW_H };\n }\n\n // Emit one type table with its top-left at (ax, ay); returns its size.\n function emitTable(t, ax, ay, parentId) {\n var sh = tableShape(t);\n var kindCls = t.kind === 'entity' ? 'typeEntity' : 'typeValue';\n var dim = !typeMatches(t);\n var extra = (dim ? ' dimmed' : '')\n + (state.showIssues && issuesBySpec[t.id] ? ' hasIssue' : '')\n + (state.selectedKind === 'type' && state.selected === t.id ? ' sel' : '');\n if (sh.plain) {\n eles.push({\n data: { id: 'T~' + t.id, parent: parentId, label: sh.head, w: sh.w, h: 40, tw: sh.w - 12 },\n position: { x: ax + sh.w / 2, y: ay + 20 }, classes: 'typePlain ' + kindCls + extra,\n });\n return sh;\n }\n eles.push({ data: { id: 'T~' + t.id, parent: parentId, label: '' }, classes: 'typeBox ' + kindCls + extra });\n eles.push({\n data: { id: 'TH~' + t.id, parent: 'T~' + t.id, label: sh.head, w: sh.w, h: TH_H, tw: sh.w - 12 },\n position: { x: ax + sh.w / 2, y: ay + TH_H / 2 }, classes: 'typeHead ' + kindCls + (dim ? ' dimmed' : ''), grabbable: false,\n });\n var ry = ay + TH_H;\n sh.fields.forEach(function (f) {\n var rid = 'TF~' + t.id + '~' + f.name;\n rowIds[rid] = 1;\n eles.push({\n data: { id: rid, parent: 'T~' + t.id, label: rowText(t, f), w: sh.w, h: ROW_H, tw: sh.w - 14 },\n position: { x: ax + sh.w / 2, y: ry + ROW_H / 2 }, classes: 'typeRow' + (fkBy[t.id] && fkBy[t.id][f.name] ? ' fkRow' : '') + (dim ? ' dimmed' : ''), grabbable: false,\n });\n ry += ROW_H;\n });\n sh.meths.forEach(function (m, mi) {\n eles.push({\n data: { id: 'TM~' + t.id + '~' + mi, parent: 'T~' + t.id, label: '\\\\u0192 ' + m.name + '(): ' + m.returns, w: sh.w, h: ROW_H, tw: sh.w - 14 },\n position: { x: ax + sh.w / 2, y: ry + ROW_H / 2 }, classes: 'typeRow methRow' + (dim ? ' dimmed' : ''), grabbable: false,\n });\n ry += ROW_H;\n });\n return sh;\n }\n\n // ERD placement follows the layout picker: Layered keeps the grouped\n // dependency columns; Grid wraps tables into rows (no single giant column);\n // Concentric rings the most-referenced types toward the centre.\n var deg = {};\n list.forEach(function (t) { deg[t.id] = 0; });\n Object.keys(aggRefs).forEach(function (k) { var r = aggRefs[k]; if (deg[r.from] !== undefined) deg[r.from]++; if (deg[r.to] !== undefined) deg[r.to]++; });\n var byDegree = function (a, b) { return (deg[b.id] - deg[a.id]) || (a.id < b.id ? -1 : 1); };\n var erdLayout = state.layout === 'grid' ? 'grid' : (state.layout === 'concentric' || state.layout === 'force') ? 'concentric' : 'layered';\n\n if (erdLayout === 'grid') {\n var target = Math.max(1000, Math.ceil(Math.sqrt(list.length)) * 300);\n var gx = 0, gy = 0, rowH = 0;\n list.slice().sort(byDegree).forEach(function (t) {\n var s = tableShape(t);\n if (gx > 0 && gx + s.w > target) { gx = 0; gy += rowH + Y_GAP; rowH = 0; }\n emitTable(t, gx, gy, undefined);\n gx += s.w + X_GAP;\n if (s.h > rowH) rowH = s.h;\n });\n } else if (erdLayout === 'concentric') {\n var sizeById = {};\n list.forEach(function (t) { sizeById[t.id] = tableShape(t); });\n var cpos = concentricPositions(\n list.map(function (t) { return t.id; }),\n function (id) { return deg[id] || 0; },\n function (id) { return sizeById[id]; },\n 1.7, // widen into a landscape ellipse — screens are horizontal\n function (id) { return layer[id] || 0; } // upstream types toward the top\n );\n list.forEach(function (t) {\n var s = sizeById[t.id], p = cpos[t.id] || { x: 0, y: 0 };\n emitTable(t, p.x - s.w / 2, p.y - s.h / 2, undefined);\n });\n } else {\n var groupY = 0;\n groupIds.forEach(function (g) {\n var gid = 'TG~' + g;\n if (multi) eles.push({ data: { id: gid, label: g }, classes: 'subsysBox' });\n var cols = {};\n groups[g].forEach(function (t) { var l = layer[t.id] || 0; (cols[l] = cols[l] || []).push(t); });\n var colKeys = Object.keys(cols).map(Number).sort(function (a, b) { return a - b; });\n var x = 0, groupH = 0;\n colKeys.forEach(function (ck) {\n var col = cols[ck].sort(function (a, b) { return a.id < b.id ? -1 : 1; });\n var y = groupY, colW = 230;\n col.forEach(function (t) {\n var s = emitTable(t, x, y, multi ? gid : undefined);\n y += s.h + Y_GAP;\n if (s.w > colW) colW = s.w;\n });\n groupH = Math.max(groupH, y - groupY);\n x += colW + X_GAP;\n });\n groupY += groupH + GROUP_GAP;\n });\n }\n\n var i = 0;\n var typeById = {};\n MODEL.types.forEach(function (t) { typeById[t.id] = t; });\n var dimEdge = function (from, to) {\n return state.query && (!typeMatches(typeById[from] || { id: from, name: '' }) || !typeMatches(typeById[to] || { id: to, name: '' }));\n };\n if (det === 'names') {\n // Header-only mode: plain aggregated dependency lines, no ERD labels.\n Object.keys(aggRefs).forEach(function (k) {\n var r = aggRefs[k];\n eles.push({ data: { id: 'te' + (i++), source: 'T~' + r.from, target: 'T~' + r.to, lbl: '' }, classes: 'typeref plain' + (dimEdge(r.from, r.to) ? ' dimmed' : '') });\n });\n } else {\n // One relation line per field, anchored AT that field's row, with\n // UML multiplicity on the ends (1 at the owner, card at the target).\n MODEL.typeEdges.forEach(function (e) {\n if (!inList[e.from] || !inList[e.to]) return;\n var rowId = 'TF~' + e.from + '~' + e.field;\n eles.push({\n data: {\n id: 'te' + (i++), source: rowIds[rowId] ? rowId : 'T~' + e.from, target: 'T~' + e.to,\n lbl: '', tcard: e.card || '1', ffrom: e.from, ffield: e.field,\n },\n classes: 'typeref erd' + (dimEdge(e.from, e.to) ? ' dimmed' : ''),\n });\n });\n }\n return eles;\n }\n\n function buildElements() {\n var scope = state.view;\n if (scope.kind === 'types' || scope.kind === 'databases') return buildTypeElements();\n var entries = childrenOf(scope);\n var eles = [];\n var ve = viewEdges(scope, entries);\n // Data-coupling overlay: same scoping pipeline, a different edge source.\n var vd = state.dataCoupling ? viewEdges(scope, entries, MODEL.dataEdges) : { agg: {}, ghosts: {} };\n Object.keys(vd.ghosts).forEach(function (g) { if (!ve.ghosts[g]) ve.ghosts[g] = vd.ghosts[g]; });\n var inners = {};\n entries.forEach(function (e) { inners[anchorNodeId(e)] = innerLayout(e); });\n\n // Resolve a port's reveal target(s) in THIS view. Preference order: the\n // MATCHING PORT inside the counterpart's container (a port-to-port line\n // both endpoints share), then the counterpart's container box, then a\n // ghost node when externals are shown.\n var entryAnchors = {};\n entries.forEach(function (e2) { entryAnchors[anchorNodeId(e2)] = 1; });\n function resolvePortTargets(px) {\n var child = childOfScopeContaining(px.extId, scope);\n if (child && entryAnchors[anchorNodeId(child)]) {\n var cAid = anchorNodeId(child);\n var cInner = inners[cAid];\n if (cInner && cInner.proxies) {\n var base = (px.dir === 'out' ? 'p~in~' : 'p~out~') + cAid + '~';\n var have = {};\n cInner.proxies.forEach(function (q) { have[q.id] = 1; });\n var hits = [];\n (px.raws || []).forEach(function (r) { if (have[base + r]) hits.push(base + r); });\n if (hits.length) return hits;\n }\n return [cAid];\n }\n if (state.externals) {\n var ext = externalAnchorFor(px.extId, scope);\n if (ext && ve.ghosts[ext.gid]) return [ext.gid];\n }\n return [];\n }\n\n var layerOf = {};\n function calcLayer(e, stack) {\n var key = anchorNodeId(e);\n if (layerOf[key] !== undefined) return layerOf[key];\n if (stack[key]) return 0;\n stack[key] = 1;\n var l = 0;\n if (e.kind === 'component') {\n var c = compById[e.id];\n if (c && (c.componentType === 'Portal' || c.componentType === 'Observer')) { layerOf[key] = 0; delete stack[key]; return 0; }\n }\n Object.keys(ve.agg).forEach(function (k) {\n var edge = ve.agg[k];\n if (edge.tgt !== key) return;\n var srcEntry = entries.filter(function (x) { return anchorNodeId(x) === edge.src; })[0];\n if (srcEntry) l = Math.max(l, calcLayer(srcEntry, stack) + 1);\n });\n delete stack[key];\n layerOf[key] = l;\n return l;\n }\n // Anchor sizes + reference degree, for the layout strategies.\n var sizeByAnchor = {}, degByAnchor = {};\n entries.forEach(function (e) { var aid = anchorNodeId(e); sizeByAnchor[aid] = sizeOf(e, inners[aid]); degByAnchor[aid] = 0; });\n Object.keys(ve.agg).forEach(function (k) {\n var edge = ve.agg[k];\n if (degByAnchor[edge.src] !== undefined) degByAnchor[edge.src]++;\n if (degByAnchor[edge.tgt] !== undefined) degByAnchor[edge.tgt]++;\n });\n\n // Top-level anchor placement follows the layout picker. Concentric and Grid\n // are computed here (as presets); Force seeds from Layered and is relaxed by\n // cytoscape's physics layout afterwards in positionView().\n var posByAnchor = {}, x = 0;\n if (state.layout === 'concentric') {\n entries.forEach(function (e) { calcLayer(e, {}); }); // dependency depth → flow rank\n var cpos = concentricPositions(\n entries.map(function (e) { return anchorNodeId(e); }),\n function (id) { return degByAnchor[id] || 0; },\n function (id) { return sizeByAnchor[id]; },\n 1.7, // widen into a landscape ellipse — screens are horizontal\n function (id) { return layerOf[id] || 0; } // entrypoints (layer 0) toward the top\n );\n entries.forEach(function (e) {\n var aid = anchorNodeId(e), s = sizeByAnchor[aid], p = cpos[aid] || { x: 0, y: 0 };\n posByAnchor[aid] = { x: p.x, y: p.y, w: s.w, h: s.h };\n if (p.x + s.w / 2 > x) x = p.x + s.w / 2;\n });\n } else if (state.layout === 'grid') {\n var gsorted = entries.slice().sort(function (a, b) { return (degByAnchor[anchorNodeId(b)] - degByAnchor[anchorNodeId(a)]) || (a.id < b.id ? -1 : 1); });\n var target = Math.max(900, Math.ceil(Math.sqrt(entries.length)) * 320);\n var gx = 0, gy = 0, rowH = 0;\n gsorted.forEach(function (e) {\n var aid = anchorNodeId(e), s = sizeByAnchor[aid];\n if (gx > 0 && gx + s.w > target) { gx = 0; gy += rowH + GAP_Y; rowH = 0; }\n posByAnchor[aid] = { x: gx + s.w / 2, y: gy + s.h / 2, w: s.w, h: s.h };\n gx += s.w + GAP_X; if (s.h > rowH) rowH = s.h;\n if (gx > x) x = gx;\n });\n } else {\n entries.forEach(function (e) { calcLayer(e, {}); });\n var cols = {};\n entries.forEach(function (e) { var l = layerOf[anchorNodeId(e)] || 0; (cols[l] = cols[l] || []).push(e); });\n var colKeys = Object.keys(cols).map(Number).sort(function (a, b) { return a - b; });\n // Force seeds from a DIAGONAL cascade — each dependency layer starts lower,\n // so cose relaxes from an entrypoints-top-left → leaves-bottom-right flow.\n // Layered stays a pure left-to-right grid (cascade 0), unchanged.\n var cascade = state.layout === 'force' ? 130 : 0, colIdx = 0;\n colKeys.forEach(function (ck) {\n var col = cols[ck].sort(function (a, b) { return a.id < b.id ? -1 : 1; });\n var colW = 0, y = colIdx * cascade;\n col.forEach(function (e) { colW = Math.max(colW, sizeByAnchor[anchorNodeId(e)].w); });\n col.forEach(function (e) {\n var aid = anchorNodeId(e), s = sizeByAnchor[aid];\n posByAnchor[aid] = { x: x + colW / 2, y: y + s.h / 2, w: s.w, h: s.h };\n y += s.h + GAP_Y;\n });\n x += colW + GAP_X;\n colIdx++;\n });\n }\n\n entries.forEach(function (e) {\n var aid = anchorNodeId(e);\n var p = posByAnchor[aid];\n var inner = inners[aid];\n var dim = state.query && !matches(e);\n var classes, label;\n var isPub = e.kind === 'component' && compById[e.id] && compById[e.id].public;\n if (e.kind === 'subsystem') {\n classes = 'subsysBox';\n label = nameOf(e) + (e.hasKids && !inner ? '\\\\n\\\\u25B8 open' : '');\n } else {\n var c = compById[e.id];\n classes = stereoClass(c.componentType);\n label = c.name + '\\\\n\\\\u00AB' + c.componentType + (c.portalType ? '/' + c.portalType : '') + '\\\\u00BB' + (e.hasKids && !inner ? ' \\\\u25B8' : '');\n }\n classes += (e.hasKids ? ' drillable' : '') + (isPub ? ' public' : '')\n + (dim ? ' dimmed' : '')\n + (state.showIssues && issuesBySpec[e.id] ? ' hasIssue' : '')\n + (state.selectedKind === e.kind && state.selected === e.id ? ' sel' : '');\n if (inner) {\n eles.push({ data: { id: aid, label: e.kind === 'subsystem' ? nameOf(e) : nameOf(e), w: p.w, h: p.h, tw: p.w - 16 }, classes: classes });\n inner.tiles.forEach(function (tile) {\n eles.push({\n data: {\n id: IN(tile.kid.kind, tile.kid.id), parent: aid,\n label: nameOf(tile.kid), w: INNER_W, h: INNER_H, tw: INNER_W - 10,\n },\n position: { x: p.x - p.w / 2 + tile.x, y: p.y - p.h / 2 + tile.y },\n classes: 'inner' + (dim ? ' dimmed' : ''),\n });\n });\n (inner.proxies || []).forEach(function (px) {\n eles.push({\n data: {\n id: px.id, parent: aid, label: px.dir === 'in' ? '\\\\u21E0' : '\\\\u21E2',\n w: px.w, h: px.h, tw: px.w,\n extId: px.extId, dir: px.dir,\n rvTargets: resolvePortTargets(px), rvDir: px.dir,\n viaKids: px.kids.map(function (k2) { return { kind: k2.kind, id: k2.id, label: nameOf(k2) }; }),\n },\n position: { x: p.x - p.w / 2 + px.x, y: p.y - p.h / 2 + px.y },\n classes: 'proxyExt ' + (px.dir === 'in' ? 'proxyIn' : 'proxyOut')\n + (dim ? ' dimmed' : '')\n + (state.selectedKind === 'external' && state.selected === px.id ? ' sel' : ''),\n });\n });\n inner.edges.forEach(function (ie, k) {\n eles.push({ data: { id: aid + '-ie' + k, source: ie.src, target: ie.tgt, lbl: '' }, classes: 'inneredge' + (ie.stub ? ' toghost' : '') + (dim ? ' dimmed' : '') });\n });\n } else {\n eles.push({ data: { id: aid, label: label, w: p.w, h: p.h, tw: p.w - 14 }, position: { x: p.x, y: p.y }, classes: classes });\n }\n });\n\n // Externals are placed TOWARD the in-scope node(s) they connect to — on the\n // perimeter of the graph bounds in that direction — so the connecting line is\n // short and doesn't cut across the diagram. Falls back to left(incoming) /\n // right(outgoing) when the connection is dead-centre or unknown.\n var ghostDir = {}, ghostConn = {};\n var conn = function (gid, other) {\n var p = posByAnchor[other];\n if (!p) return;\n var gc = ghostConn[gid] = ghostConn[gid] || { sx: 0, sy: 0, n: 0 };\n gc.sx += p.x; gc.sy += p.y; gc.n++;\n };\n [ve.agg, vd.agg].forEach(function (aggMap) {\n Object.keys(aggMap).forEach(function (k) {\n var e = aggMap[k];\n if (ve.ghosts[e.src]) { ghostDir[e.src] = (ghostDir[e.src] || 0) | 1; conn(e.src, e.tgt); }\n if (ve.ghosts[e.tgt]) { ghostDir[e.tgt] = (ghostDir[e.tgt] || 0) | 2; conn(e.tgt, e.src); }\n });\n });\n var bMinX = Infinity, bMaxX = -Infinity, bMinY = Infinity, bMaxY = -Infinity;\n Object.keys(posByAnchor).forEach(function (aid) {\n var p = posByAnchor[aid];\n if (p.x - p.w / 2 < bMinX) bMinX = p.x - p.w / 2;\n if (p.x + p.w / 2 > bMaxX) bMaxX = p.x + p.w / 2;\n if (p.y - p.h / 2 < bMinY) bMinY = p.y - p.h / 2;\n if (p.y + p.h / 2 > bMaxY) bMaxY = p.y + p.h / 2;\n });\n if (bMinX === Infinity) { bMinX = 0; bMaxX = 0; bMinY = 0; bMaxY = 0; }\n var GHW = 170, GHH = 46, GH_GAP = 90;\n var ccx = (bMinX + bMaxX) / 2, ccy = (bMinY + bMaxY) / 2;\n var halfW = (bMaxX - bMinX) / 2 + GHW / 2 + GH_GAP, halfH = (bMaxY - bMinY) / 2 + GHH / 2 + GH_GAP;\n var placedGhosts = [];\n Object.keys(ve.ghosts).sort().forEach(function (gid) {\n var g = ve.ghosts[gid], incoming = (ghostDir[gid] || 2) & 1, gc = ghostConn[gid];\n var dx = gc && gc.n ? gc.sx / gc.n - ccx : 0, dy = gc && gc.n ? gc.sy / gc.n - ccy : 0;\n if (dx === 0 && dy === 0) { dx = incoming ? -1 : 1; dy = 0; } // fallback: in=left, out=right\n var len = Math.sqrt(dx * dx + dy * dy) || 1, ux = dx / len, uy = dy / len;\n var t = Math.min(ux !== 0 ? halfW / Math.abs(ux) : Infinity, uy !== 0 ? halfH / Math.abs(uy) : Infinity);\n placedGhosts.push({ gid: gid, g: g, x: ccx + ux * t, y: ccy + uy * t });\n });\n // Separate any externals that landed on top of each other.\n for (var gIter = 0; gIter < 40; gIter++) {\n var gMoved = false;\n for (var ga = 0; ga < placedGhosts.length; ga++) {\n for (var gb = ga + 1; gb < placedGhosts.length; gb++) {\n var pa = placedGhosts[ga], pb = placedGhosts[gb];\n var ddx = pb.x - pa.x, ddy = pb.y - pa.y;\n var ox = (GHW + 24) - Math.abs(ddx), oy = (GHH + 14) - Math.abs(ddy);\n if (ox > 0 && oy > 0) {\n if (ox <= oy) { var sx = (ddx === 0 ? (ga < gb ? -1 : 1) : (ddx > 0 ? 1 : -1)) * ox / 2; pa.x -= sx; pb.x += sx; }\n else { var sy = (ddy === 0 ? -1 : (ddy > 0 ? 1 : -1)) * oy / 2; pa.y -= sy; pb.y += sy; }\n gMoved = true;\n }\n }\n }\n if (!gMoved) break;\n }\n placedGhosts.forEach(function (pp) {\n posByAnchor[pp.gid] = { x: pp.x, y: pp.y, w: GHW, h: GHH };\n eles.push({\n data: { id: pp.gid, label: pp.g.label + '\\\\n(external)', w: GHW, h: GHH, tw: GHW - 14, extKind: pp.g.kind, extId: pp.g.id },\n position: { x: pp.x, y: pp.y },\n classes: 'ghost',\n });\n });\n\n function pointInRect(p, r) {\n return p.x >= r.l && p.x <= r.r && p.y >= r.t && p.y <= r.b;\n }\n function orient(a, b, c) {\n var v = (b.y - a.y) * (c.x - b.x) - (b.x - a.x) * (c.y - b.y);\n return Math.abs(v) < 0.0001 ? 0 : (v > 0 ? 1 : 2);\n }\n function onSeg(a, b, c) {\n return b.x <= Math.max(a.x, c.x) && b.x >= Math.min(a.x, c.x)\n && b.y <= Math.max(a.y, c.y) && b.y >= Math.min(a.y, c.y);\n }\n function segsCross(a, b, c, d) {\n var o1 = orient(a, b, c), o2 = orient(a, b, d), o3 = orient(c, d, a), o4 = orient(c, d, b);\n if (o1 !== o2 && o3 !== o4) return true;\n return (o1 === 0 && onSeg(a, c, b)) || (o2 === 0 && onSeg(a, d, b))\n || (o3 === 0 && onSeg(c, a, d)) || (o4 === 0 && onSeg(c, b, d));\n }\n function segmentHitsRect(a, b, rect) {\n if (pointInRect(a, rect) || pointInRect(b, rect)) return true;\n var tl = { x: rect.l, y: rect.t }, tr = { x: rect.r, y: rect.t };\n var br = { x: rect.r, y: rect.b }, bl = { x: rect.l, y: rect.b };\n return segsCross(a, b, tl, tr) || segsCross(a, b, tr, br)\n || segsCross(a, b, br, bl) || segsCross(a, b, bl, tl);\n }\n function routeHash(s) {\n var h = 0;\n for (var hi = 0; hi < s.length; hi++) h = ((h << 5) - h + s.charCodeAt(hi)) | 0;\n return Math.abs(h);\n }\n function routeData(src, tgt, routeKey) {\n var a = posByAnchor[src], b = posByAnchor[tgt];\n var hash = routeHash(routeKey || (src + '>' + tgt));\n var laneStep = hash % 4;\n var laneSign = (hash % 8) < 4 ? 1 : -1;\n if (!a || !b) {\n return { cpDist: laneSign * (78 + laneStep * 8), cpWeight: 0.48, taxiTurn: laneSign * (54 + laneStep * 20) };\n }\n var dx = b.x - a.x, dy = b.y - a.y;\n var len = Math.sqrt(dx * dx + dy * dy) || 1;\n var nx = -dy / len, ny = dx / len;\n var mid = { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 };\n var hits = 0, side = 0, margin = 54;\n Object.keys(posByAnchor).forEach(function (id) {\n if (id === src || id === tgt) return;\n var p = posByAnchor[id];\n var rect = { l: p.x - p.w / 2 - margin, r: p.x + p.w / 2 + margin, t: p.y - p.h / 2 - margin, b: p.y + p.h / 2 + margin };\n if (!segmentHitsRect({ x: a.x, y: a.y }, { x: b.x, y: b.y }, rect)) return;\n hits++;\n var obstacleSide = ((p.x - mid.x) * nx + (p.y - mid.y) * ny) >= 0 ? -1 : 1;\n side += obstacleSide;\n });\n if (!hits) {\n return { cpDist: laneSign * (78 + laneStep * 8), cpWeight: 0.48, taxiTurn: laneSign * (54 + laneStep * 20) };\n }\n var sign = side === 0 ? laneSign : (side > 0 ? 1 : -1);\n return {\n cpDist: sign * Math.min(280, 132 + hits * 44 + laneStep * 10),\n cpWeight: 0.5,\n taxiTurn: sign * Math.min(170, 74 + hits * 22 + laneStep * 20),\n };\n }\n\n var dimmedAnchors = {};\n entries.forEach(function (e) { if (state.query && !matches(e)) dimmedAnchors[anchorNodeId(e)] = true; });\n var i = 0;\n Object.keys(ve.agg).forEach(function (key) {\n var e = ve.agg[key];\n var bundle = e.n > 1;\n var dim = state.query && (dimmedAnchors[e.src] || dimmedAnchors[e.tgt]);\n var route = routeData(e.src, e.tgt, key);\n eles.push({\n data: { id: 'e' + (i++), source: e.src, target: e.tgt, lbl: bundle ? e.n + ' links' : '', cpDist: route.cpDist, cpWeight: route.cpWeight, taxiTurn: route.taxiTurn },\n classes: 'routed ' + (e.cross ? 'cross ' : '') + (bundle ? 'bundle ' : '') + (e.ghost ? 'toghost ' : '') + (dim ? 'dimmed' : ''),\n });\n });\n\n // Data-coupling overlay edges (dashed, distinct) — only where there is NO\n // logical dependency already, so it reveals the otherwise-hidden coupling.\n if (state.dataCoupling) {\n var di = 0;\n Object.keys(vd.agg).forEach(function (key) {\n if (ve.agg[key]) return;\n var e = vd.agg[key];\n var dim = state.query && (dimmedAnchors[e.src] || dimmedAnchors[e.tgt]);\n var route = routeData(e.src, e.tgt, key);\n eles.push({\n data: { id: 'de' + (di++), source: e.src, target: e.tgt, lbl: e.n > 1 ? e.n + ' \\\\u00d7 models' : 'models', cpDist: route.cpDist, cpWeight: route.cpWeight, taxiTurn: route.taxiTurn },\n classes: 'routed datacoupling' + (e.ghost ? ' toghost' : '') + (dim ? ' dimmed' : ''),\n });\n });\n }\n\n return eles;\n }\n\n // ---- cytoscape init ----------------------------------------------------------\n document.body.setAttribute('data-theme', state.theme);\n renderLegend();\n\n var cy = cytoscape({\n container: document.getElementById('cy'),\n elements: buildElements(),\n style: buildStyle(THEMES[state.theme]),\n layout: { name: 'preset' },\n minZoom: 0.05,\n maxZoom: 4,\n boxSelectionEnabled: false,\n autounselectify: true,\n });\n cy.autolock(true);\n var pinnedProxy = null;\n positionView(true);\n renderCrumbs();\n renderViewHint();\n\n // NOTE: lift autolock globally instead of lock-juggling per node — with\n // autolock on, n.locked() is true for EVERY node, so restoring it would\n // set individual locks that survive rearrange mode (frozen tiles that no\n // longer follow their dragged parent).\n function applySavedPositions() {\n var pos = (saved.positionsByView || {})[viewKey()] || {};\n var wasAuto = cy.autolock();\n if (wasAuto) cy.autolock(false);\n cy.nodes().forEach(function (n) {\n if (!n.isParent() && pos[n.id()]) n.position(pos[n.id()]);\n });\n if (wasAuto) cy.autolock(true);\n }\n function harvestPositions() {\n var all = saved.positionsByView || {};\n var pos = all[viewKey()] || {};\n cy.nodes().forEach(function (n) { if (!n.isParent()) pos[n.id()] = { x: n.position('x'), y: n.position('y') }; });\n all[viewKey()] = pos;\n saved.positionsByView = all;\n persist();\n }\n // Cytoscape's built-in layouts for the component view (self-contained — no\n // layout extension). Force is seeded from the layered positions so it\n // untangles crossings deterministically instead of reshuffling each rebuild.\n // Only Force (cose) is a native cytoscape layout now — Concentric and Grid are\n // computed as size-aware presets in buildElements. Cose is tuned to account for\n // the large box sizes (nodeDimensionsIncludeLabels + high repulsion/overlap and\n // long ideal edges) so nodes spread out instead of clumping and overlapping.\n function nativeLayoutOptions() {\n return {\n name: 'cose', animate: false, randomize: false, padding: 60,\n nodeDimensionsIncludeLabels: true,\n nodeRepulsion: function () { return 400000; },\n nodeOverlap: 80,\n idealEdgeLength: function () { return 200; },\n edgeElasticity: function () { return 120; },\n gravity: 0.15, componentSpacing: 200, nestingFactor: 1.2,\n numIter: 1500, coolingFactor: 0.96, initialTemp: 240,\n };\n }\n // Post-layout overlap removal: cose is isotropic, so wide-but-short boxes still\n // overlap horizontally even when vertically clear. Separate every overlapping\n // pair along its axis of LEAST overlap (horizontal overlaps resolve\n // horizontally), honouring per-axis gaps — so wide nodes get real horizontal\n // clearance without inflating the (already fine) vertical spacing.\n function resolveOverlaps(gapX, gapY) {\n var arr = cy.nodes().orphans().toArray();\n for (var iter = 0; iter < 80; iter++) {\n var moved = false;\n for (var i = 0; i < arr.length; i++) {\n for (var j = i + 1; j < arr.length; j++) {\n var a = arr[i], b = arr[j];\n var ba = a.boundingBox(), bb = b.boundingBox();\n var dx = (bb.x1 + bb.x2) / 2 - (ba.x1 + ba.x2) / 2;\n var dy = (bb.y1 + bb.y2) / 2 - (ba.y1 + ba.y2) / 2;\n var ox = (ba.w + bb.w) / 2 + gapX - Math.abs(dx);\n var oy = (ba.h + bb.h) / 2 + gapY - Math.abs(dy);\n if (ox > 0 && oy > 0) {\n if (ox <= oy) {\n var sx = (dx === 0 ? (i < j ? -1 : 1) : (dx > 0 ? 1 : -1)) * ox / 2;\n a.position('x', a.position('x') - sx); b.position('x', b.position('x') + sx);\n } else {\n var sy = (dy === 0 ? -1 : (dy > 0 ? 1 : -1)) * oy / 2;\n a.position('y', a.position('y') - sy); b.position('y', b.position('y') + sy);\n }\n moved = true;\n }\n }\n }\n if (!moved) break;\n }\n }\n function runNativeLayout() {\n if (state.layout !== 'force') return; // concentric/grid are presets from buildElements\n var wasAuto = cy.autolock();\n if (wasAuto) cy.autolock(false);\n try {\n cy.layout(nativeLayoutOptions()).run();\n resolveOverlaps(56, 20);\n // Widen the result into landscape (screens are horizontal). Stretching only\n // x, around the centre, after overlap removal never re-introduces overlaps.\n var ns = cy.nodes().orphans();\n if (ns.length > 1) {\n var bb = ns.boundingBox(), cx = (bb.x1 + bb.x2) / 2;\n ns.forEach(function (n) { n.position('x', cx + (n.position('x') - cx) * 1.6); });\n }\n } catch (e) { /* layout unavailable */ }\n if (wasAuto) cy.autolock(true);\n }\n // Position the current view: run the chosen algorithm for a fresh component\n // view (the ERD is pre-anchored by buildElements per strategy), then let any\n // saved manual rearrangement win on top.\n function positionView(fit) {\n var sv = (saved.positionsByView || {})[viewKey()];\n var hasSaved = sv && Object.keys(sv).length > 0;\n if (state.view.kind !== 'types' && state.layout !== 'layered' && !hasSaved) runNativeLayout();\n applySavedPositions();\n if (fit) cy.fit(undefined, 60);\n }\n function rebuild(fit) {\n pinnedProxy = null;\n cy.batch(function () {\n cy.elements().remove();\n cy.add(buildElements());\n });\n positionView(fit);\n // A selected port survives a rebuild (e.g. issue toggle) if it still\n // exists; otherwise (Internals off) drop the selection cleanly.\n if (state.selectedKind === 'external') {\n if (cy.getElementById(state.selected).length) { pinnedProxy = state.selected; showPinned(); }\n else { state.selectedKind = null; state.selected = null; renderPanel(); }\n }\n renderCrumbs();\n renderViewHint();\n renderTypesNotice();\n updateHeaderSegs();\n if (state.selectedKind && state.selectedKind !== 'external') {\n var rfn = nodeForRef(state.selectedKind, state.selected);\n if (rfn.length) applyFocus(rfn);\n }\n }\n\n function harvestLayout() {\n var boxes = {}, subs = {};\n cy.nodes().forEach(function (n) {\n var id = n.id();\n var bb = n.boundingBox({ includeLabels: false, includeOverlays: false });\n var box = { x: bb.x1, y: bb.y1, w: bb.w, h: bb.h };\n if (id.indexOf('s~') === 0) subs[id.slice(2)] = { x: box.x, y: box.y, w: box.w, h: box.h, collapsed: true };\n else if (id.indexOf('c~') === 0) boxes[id.slice(2)] = box;\n });\n return { boxes: boxes, subs: subs };\n }\n\n // Resolve a spec reference to whatever node represents it in the CURRENT view:\n // the exact node, its inner tile, or the visible child-of-scope containing it.\n function nodeForRef(kind, id) {\n if (kind === 'type') return cy.getElementById('T~' + id);\n if (kind === 'external') return cy.getElementById(id);\n var direct = cy.getElementById(kind === 'subsystem' ? SN(id) : CN(id));\n if (direct.length) return direct;\n var tile = cy.getElementById(IN(kind, id));\n if (tile.length) return tile;\n if (kind === 'component') {\n var child = childOfScopeContaining(id, state.view);\n if (child) {\n var anchor = cy.getElementById(anchorNodeId(child));\n if (anchor.length) return anchor;\n }\n var ghost = cy.getElementById('x~component~' + id);\n if (ghost.length) return ghost;\n } else {\n var g2 = cy.getElementById('x~subsystem~' + id);\n if (g2.length) return g2;\n }\n return cy.collection();\n }\n\n // ---- navigation -----------------------------------------------------------\n function crumbPath() {\n var path = [{ kind: 'system', id: null, label: MODEL.system.name }];\n var v = state.view;\n if (v.kind === 'databases') {\n var dpath = [{ kind: 'databases', id: null, label: MODEL.system.name }];\n if (v.id) {\n var dsegs = v.id.split('::');\n for (var di = 1; di <= dsegs.length; di++) {\n var dsid = dsegs.slice(0, di).join('::');\n dpath.push({ kind: 'databases', id: dsid, label: nameOf({ kind: 'subsystem', id: dsid }) });\n }\n }\n dpath[dpath.length - 1].label += ' \\\\u00B7 Databases';\n return dpath;\n }\n if (v.kind === 'types') {\n // Breadcrumbs stay in TYPES mode when walking up — a subsystem's types\n // lead to the PARENT'S types, not the parent's components. The header\n // Components/Types toggle remains the explicit way to change mode.\n var tpath = [{ kind: 'types', id: null, label: MODEL.system.name }];\n if (v.id) {\n var tsegs = v.id.split('::');\n for (var ti = 1; ti <= tsegs.length; ti++) {\n var tsid = tsegs.slice(0, ti).join('::');\n tpath.push({ kind: 'types', id: tsid, label: nameOf({ kind: 'subsystem', id: tsid }) });\n }\n }\n // Keep the ERD legible in the trail by tagging the current scope.\n tpath[tpath.length - 1].label += ' \\\\u00B7 Types (ERD)';\n return tpath;\n }\n if (v.kind === 'subsystem') {\n var segs = v.id.split('::');\n for (var i = 1; i <= segs.length; i++) {\n var sid = segs.slice(0, i).join('::');\n path.push({ kind: 'subsystem', id: sid, label: nameOf({ kind: 'subsystem', id: sid }) });\n }\n } else if (v.kind === 'component') {\n var c = compById[v.id];\n if (c) {\n subsystemChainOf(c).forEach(function (sid) {\n path.push({ kind: 'subsystem', id: sid, label: nameOf({ kind: 'subsystem', id: sid }) });\n });\n ownerChainOf(c).forEach(function (oid) {\n path.push({ kind: 'component', id: oid, label: nameOf({ kind: 'component', id: oid }) });\n });\n path.push({ kind: 'component', id: c.id, label: c.name });\n }\n }\n return path;\n }\n function renderCrumbs() {\n var el = document.getElementById('crumbs');\n var path = crumbPath();\n el.innerHTML = path.map(function (p, i) {\n var cur = i === path.length - 1;\n return '<button class=\"crumb' + (cur ? ' cur' : '') + '\" data-ck=\"' + p.kind + '\" data-ci=\"' + (p.id || '') + '\">' + p.label + '</button>'\n + (cur ? '' : '<span class=\"sep\">\\\\u203A</span>');\n }).join('');\n var btns = el.querySelectorAll('button');\n for (var i = 0; i < btns.length; i++) {\n (function (b) {\n b.addEventListener('click', function () {\n navigateTo(b.getAttribute('data-ck'), b.getAttribute('data-ci') || null);\n });\n })(btns[i]);\n }\n }\n function renderViewHint() {\n if (state.view.kind === 'types' || state.view.kind === 'databases') {\n var scoped = typesInScope().length;\n var label = state.view.kind === 'databases' ? 'database tables' : 'types (ERD';\n document.getElementById('viewHint').textContent = 'View: ' + scoped + ' ' + label\n + (state.view.id ? ', ' + state.view.id + ' + shared' : '') + (state.view.kind === 'databases' ? '' : ')') + ' \\\\u00B7 '\n + (state.typesDetail === 'names' ? 'dependency lines' : 'relation lines anchor at their field \\\\u00B7 double-click an FK row to jump to its type');\n return;\n }\n var n = childrenOf(state.view).length;\n var what = state.view.kind === 'system' ? 'top-level subsystems'\n : state.view.kind === 'subsystem' ? 'children of this subsystem' : 'members of this pattern';\n document.getElementById('viewHint').textContent = 'View: ' + n + ' ' + what + ' \\\\u00B7 double-click a box to open it';\n }\n function navigateTo(kind, id) {\n if (state.view.kind === kind && state.view.id === id) return;\n state.view = { kind: kind, id: id };\n state.selected = null;\n state.selectedKind = null;\n state.typesRenderAll = false; // a fresh scope re-evaluates the LOD budget\n rebuild(true);\n renderPanel();\n }\n // Explain (and offer to override) a performance-degraded ERD.\n function renderTypesNotice() {\n var el = document.getElementById('typesWarn');\n if (!el) return;\n if ((state.view.kind !== 'types' && state.view.kind !== 'databases') || !typesNotice) { el.style.display = 'none'; el.innerHTML = ''; return; }\n var cut = typesNotice.indexOf(':');\n var mode = typesNotice.slice(0, cut), count = typesNotice.slice(cut + 1);\n var msg = mode === 'cluster'\n ? '\\\\u26A0 ' + count + ' types \\\\u2014 showing a subsystem overview so it stays fast. Double-click a group to open its types.'\n : '\\\\u26A0 ' + count + ' types \\\\u2014 showing names only so it stays fast. Drill into a subsystem for fields, or';\n el.innerHTML = msg + '<button class=\"tbtn\" id=\"typesAllBtn\">Render full detail anyway</button>';\n el.style.display = 'block';\n var b = document.getElementById('typesAllBtn');\n if (b) b.addEventListener('click', function () { state.typesRenderAll = true; rebuild(true); });\n }\n\n // ---- interactions -----------------------------------------------------------\n function idOf(node) {\n var raw = node.id();\n if (raw.indexOf('p~') === 0) return { proxy: true, id: raw };\n if (raw.indexOf('x~') === 0) return { ghost: true, kind: node.data('extKind'), id: node.data('extId') };\n if (raw.indexOf('TC~') === 0) return { cluster: true, id: raw.slice(3) };\n if (raw.indexOf('TG~') === 0) return { group: true, id: raw };\n if (raw.indexOf('TH~') === 0) return { kind: 'type', id: raw.slice(3) };\n if (raw.indexOf('TM~') === 0) return { kind: 'type', id: raw.slice(3, raw.lastIndexOf('~')) };\n if (raw.indexOf('TF~') === 0) {\n var trest = raw.slice(3);\n var tcut = trest.lastIndexOf('~');\n return { kind: 'type', id: trest.slice(0, tcut), field: trest.slice(tcut + 1) };\n }\n if (raw.indexOf('T~') === 0) return { kind: 'type', id: raw.slice(2) };\n if (raw.indexOf('i~') === 0) {\n var rest = raw.slice(2);\n var sep = rest.indexOf('~');\n return { inner: true, kind: rest.slice(0, sep), id: rest.slice(sep + 1) };\n }\n return { kind: raw.charAt(0) === 's' ? 'subsystem' : 'component', id: raw.slice(2) };\n }\n\n // Port reveal: the selected (pinned) port and a hovered port each draw\n // their own cross-boundary lines in independent namespaces, so both can be\n // visible at the same time.\n // Reveal edge ids are canonical by ENDPOINTS (not by which port initiated),\n // so the two ports of one relation share a single line — hovering one end\n // of an already-pinned relation adds nothing instead of stacking a twin.\n function revealEdgesFor(node, cls) {\n var targets = node.data('rvTargets') || [];\n var dir = node.data('rvDir');\n var adds = [];\n targets.forEach(function (tid) {\n if (!cy.getElementById(tid).length) return;\n var src = dir === 'out' ? node.id() : tid;\n var tgt = dir === 'out' ? tid : node.id();\n var eid = 'rv~' + cls + '~' + src + '~' + tgt;\n if (cy.getElementById(eid).length) return;\n if (cls === 'revealHover' && cy.getElementById('rv~revealPin~' + src + '~' + tgt).length) return;\n adds.push({ group: 'edges', data: { id: eid, source: src, target: tgt }, classes: 'revealEdge ' + cls });\n });\n if (adds.length) cy.add(adds);\n }\n function showPinned() {\n cy.remove('.revealPin');\n if (!pinnedProxy) return;\n var pn = cy.getElementById(pinnedProxy);\n if (pn.length) revealEdgesFor(pn, 'revealPin');\n }\n function clearReveal() {\n cy.remove('.revealEdge');\n }\n // Port hover reveals the cross-boundary line; the general node-hover below\n // handles the per-node highlight and stub edges.\n cy.on('mouseover', 'node.proxyExt', function (ev) {\n cy.remove('.revealHover');\n if (ev.target.id() !== pinnedProxy) revealEdgesFor(ev.target, 'revealHover');\n });\n cy.on('mouseout', 'node.proxyExt', function () { cy.remove('.revealHover'); });\n\n // Hover-highlight the SPECIFIC node under the cursor (inner tiles/ports\n // included), GUARDED so a stationary/oscillating pointer over the same node\n // doesn't re-thrash classes (which flickered). Container boxes are skipped —\n // you hover their children, not the box — and it never touches the selection.\n var hoveredNode = null;\n function setHover(n) {\n var nid = n && n.length ? n.id() : null;\n if ((hoveredNode ? hoveredNode.id() : null) === nid) return; // unchanged — no churn\n if (hoveredNode && hoveredNode.length) { hoveredNode.removeClass('hoverhl'); hoveredNode.connectedEdges('.inneredge').removeClass('stubHover'); }\n hoveredNode = null;\n if (n && n.length && !n.isParent()) {\n var t = idOf(n);\n if (!(t.group || t.cluster)) {\n n.addClass('hoverhl');\n n.connectedEdges('.inneredge').addClass('stubHover');\n hoveredNode = n;\n }\n }\n }\n cy.on('mouseover', 'node', function (ev) { setHover(ev.target); });\n cy.on('mouseout', 'node', function (ev) { if (hoveredNode && hoveredNode.id() === ev.target.id()) setHover(null); });\n\n cy.on('tap', 'node', function (ev) {\n var t = idOf(ev.target);\n if (t.group) return;\n if (t.cluster) { select(null, null, false); return; }\n if (t.proxy) {\n // Ports are real nodes: selecting one pins its cross-boundary line and\n // shows the external counterpart's details in the sidebar.\n cy.remove('.revealHover');\n if (pinnedProxy === t.id) { pinnedProxy = null; showPinned(); select(null, null, false); }\n else { pinnedProxy = t.id; showPinned(); select('external', t.id, false); }\n return;\n }\n if (pinnedProxy) { pinnedProxy = null; clearReveal(); }\n select(t.kind, t.id, false);\n // Tapping a field row also spotlights the relation line leaving it.\n if (t.kind === 'type' && t.field) {\n cy.edges().removeClass('fieldhl');\n cy.edges().filter(function (e) { return e.data('ffrom') === t.id && e.data('ffield') === t.field; }).addClass('fieldhl');\n }\n });\n cy.on('tap', function (ev) {\n if (ev.target === cy) {\n if (pinnedProxy) { pinnedProxy = null; clearReveal(); }\n select(null, null, false);\n }\n });\n cy.on('dbltap', 'node', function (ev) {\n var t = idOf(ev.target);\n if (t.proxy || t.group) return;\n // Optional host hook (web UI): double-clicking a leaf component node hands the\n // id back to the embedder (e.g. the environment view opens that project's\n // canvas). The opts object only exists when the engine is mounted as a module;\n // in the standalone export it is undefined, so this is inert there.\n if (typeof opts !== 'undefined' && opts && opts.onNodeOpen && t.kind === 'component') {\n opts.onNodeOpen('component', t.id);\n return;\n }\n if (t.cluster) { navigateTo('types', t.id); return; }\n if (t.kind === 'type') {\n // Double-clicking an FK field row jumps to the referenced type.\n if (t.field) {\n var fe = null;\n MODEL.typeEdges.forEach(function (e) { if (!fe && e.from === t.id && e.field === t.field) fe = e; });\n if (fe) select('type', fe.to, true);\n }\n return;\n }\n if (t.ghost) {\n state.view = parentViewOf(t.kind, t.id);\n rebuild(true);\n select(t.kind, t.id, true);\n return;\n }\n var hasKids = t.kind === 'subsystem'\n ? (childSubsOf(t.id).length + childCompsOf(t.id).length) > 0\n : memberCompsOf(t.id).length > 0;\n if (hasKids) navigateTo(t.kind, t.id);\n });\n cy.on('dragfree', 'node', function () { harvestPositions(); });\n\n function parentViewOf(kind, id) {\n if (kind === 'subsystem') {\n var segs = id.split('::');\n return segs.length > 1 ? { kind: 'subsystem', id: segs.slice(0, -1).join('::') } : { kind: 'system', id: null };\n }\n var c = compById[id];\n if (c && c.owner) return { kind: 'component', id: c.owner };\n return c ? { kind: 'subsystem', id: c.subsystem } : { kind: 'system', id: null };\n }\n\n document.getElementById('search').addEventListener('input', function (ev) { state.query = ev.target.value.trim(); rebuild(false); });\n document.getElementById('internalsToggle').addEventListener('change', function (ev) { state.internals = ev.target.checked; rebuild(true); });\n document.getElementById('externalsToggle').addEventListener('change', function (ev) { state.externals = ev.target.checked; rebuild(true); });\n document.getElementById('dataCouplingToggle').addEventListener('change', function (ev) { state.dataCoupling = ev.target.checked; renderLegend(); rebuild(true); });\n document.getElementById('issuesToggle').addEventListener('change', function (ev) { state.showIssues = ev.target.checked; rebuild(false); renderPanel(); });\n document.getElementById('dragToggle').addEventListener('change', function (ev) { cy.autolock(!ev.target.checked); });\n // Mode seg: Components ⇄ Types. Entering Types keeps the current subsystem\n // scope, so a subsystem's own types (plus shared ones) show scoped.\n function typesScopeFromView() {\n if (state.view.kind === 'subsystem') return state.view.id;\n if (state.view.kind === 'component') {\n var c = compById[state.view.id];\n return c ? c.subsystem : null;\n }\n if (state.view.kind === 'types' || state.view.kind === 'databases') return state.view.id;\n return null;\n }\n (function () {\n var seg = document.getElementById('modeSeg');\n var btns = seg.querySelectorAll('button');\n for (var i = 0; i < btns.length; i++) {\n (function (b) {\n if (b.getAttribute('data-vm') === 'databases' && !showDatabaseTab) {\n b.style.display = 'none';\n }\n b.addEventListener('click', function () {\n var vm = b.getAttribute('data-vm');\n if (vm === 'databases' && showDatabaseTab) navigateTo('databases', typesScopeFromView());\n else if (vm === 'types') navigateTo('types', typesScopeFromView());\n else if (vm === 'components') navigateTo(state.view.id ? 'subsystem' : 'system', state.view.id || null);\n });\n })(btns[i]);\n }\n })();\n (function () {\n var seg = document.getElementById('typesDetailSeg');\n var btns = seg.querySelectorAll('button');\n for (var i = 0; i < btns.length; i++) {\n (function (b) {\n b.addEventListener('click', function () {\n state.typesDetail = b.getAttribute('data-td');\n persist();\n if (state.view.kind === 'types' || state.view.kind === 'databases') rebuild(true);\n else updateHeaderSegs();\n });\n })(btns[i]);\n }\n })();\n function updateHeaderSegs() {\n var seg = document.getElementById('modeSeg');\n var btns = seg.querySelectorAll('button');\n for (var i = 0; i < btns.length; i++) {\n var vm = btns[i].getAttribute('data-vm');\n var active = vm === 'components'\n ? (state.view.kind !== 'types' && state.view.kind !== 'databases')\n : vm === state.view.kind;\n if (btns[i].classList) btns[i].classList[active ? 'add' : 'remove']('active');\n }\n var td = document.getElementById('typesDetailSeg');\n td.style.display = (state.view.kind === 'types' || state.view.kind === 'databases') ? '' : 'none';\n var tbs = td.querySelectorAll('button');\n for (var j = 0; j < tbs.length; j++) {\n if (tbs[j].classList) tbs[j].classList[tbs[j].getAttribute('data-td') === state.typesDetail ? 'add' : 'remove']('active');\n }\n }\n (function () {\n var lSelect = document.getElementById('lineStyleSelect');\n if (lSelect) {\n lSelect.value = state.lineStyle;\n lSelect.addEventListener('change', function (ev) {\n state.lineStyle = ev.target.value;\n persist();\n cy.style(buildStyle(THEMES[state.theme]));\n });\n }\n })();\n document.getElementById('fitBtn').addEventListener('click', function () { cy.fit(undefined, 60); });\n document.getElementById('resetBtn').addEventListener('click', function () {\n var all = saved.positionsByView || {};\n delete all[viewKey()];\n saved.positionsByView = all;\n persist();\n rebuild(true);\n });\n\n document.getElementById('themeBtn').addEventListener('click', function () {\n state.theme = state.theme === 'syw' ? 'light' : 'syw';\n document.body.setAttribute('data-theme', state.theme);\n cy.style(buildStyle(THEMES[state.theme]));\n renderLegend();\n persist();\n });\n\n // Presentation mode is CSS-only — it does NOT trigger browser F11 fullscreen,\n // so exiting is a single step (the ✕ button), not \"exit F11 then exit\n // presentation\". The details panel stays reachable via a floating toggle, so\n // presentation is \"the canvas focused with the current settings\", not a\n // stripped view.\n function setPresentation(on) {\n if (document.body.classList) {\n document.body.classList[on ? 'add' : 'remove']('presentation');\n if (!on) document.body.classList.remove('show-details');\n }\n setTimeout(function () { cy.resize(); cy.fit(undefined, 40); }, 60);\n }\n document.getElementById('presentBtn').addEventListener('click', function () { setPresentation(true); });\n document.getElementById('exitPresent').addEventListener('click', function () { setPresentation(false); });\n document.getElementById('presentDetails').addEventListener('click', function () {\n if (document.body.classList) document.body.classList.toggle('show-details');\n setTimeout(function () { cy.resize(); cy.fit(undefined, 40); }, 60);\n });\n\n // Anchor a fixed dropdown menu just under its button, right-aligned, clamped to\n // the viewport. Fixed positioning means it floats over the whole page and is\n // never clipped by the header's overflow (or the embedded canvas's scroll box).\n function positionDropdownMenu(dd, btn) {\n var menu = dd.querySelector ? dd.querySelector('.menu') : null;\n if (!menu || !btn.getBoundingClientRect || typeof window === 'undefined') return;\n var r = btn.getBoundingClientRect();\n menu.style.top = (r.bottom + 6) + 'px';\n menu.style.left = 'auto';\n menu.style.right = Math.max(6, window.innerWidth - r.right) + 'px';\n }\n function wireDropdown(ddId, btnId) {\n var dd = document.getElementById(ddId);\n var btn = document.getElementById(btnId);\n btn.addEventListener('click', function (ev) {\n if (ev && ev.stopPropagation) ev.stopPropagation();\n if (!dd.classList) return;\n var opening = !dd.classList.contains('open');\n dd.classList.toggle('open');\n if (opening) positionDropdownMenu(dd, btn);\n });\n return dd;\n }\n var dd = wireDropdown('exportDd', 'exportBtn');\n var fdd = wireDropdown('flowExportDd', 'flowExportBtn');\n var ldd = wireDropdown('layoutDd', 'layoutBtn');\n var sdd = wireDropdown('settingsDd', 'settingsBtn');\n var mdd = wireDropdown('moreDd', 'moreBtn');\n // Keep the settings panel open while flipping switches (clicks inside it don't\n // bubble to the document-level close handler).\n (function () {\n var m = document.getElementById('settingsMenu');\n if (m && m.addEventListener) m.addEventListener('click', function (ev) { if (ev && ev.stopPropagation) ev.stopPropagation(); });\n })();\n\n // Layout picker: choose the auto-layout algorithm. Components use cytoscape's\n // native layouts; the ERD maps them onto its table-anchor strategies.\n var LAYOUT_LABEL = { layered: 'Layered', force: 'Force', concentric: 'Concentric', grid: 'Grid' };\n function updateLayoutBtn() {\n var b = document.getElementById('layoutBtn');\n if (b) b.textContent = 'Layout: ' + (LAYOUT_LABEL[state.layout] || 'Layered') + ' \\\\u25BE';\n }\n function setLayout(name) {\n if (!LAYOUT_LABEL[name] || state.layout === name) { if (ldd.classList) ldd.classList.remove('open'); return; }\n state.layout = name;\n persist();\n updateLayoutBtn();\n if (ldd.classList) ldd.classList.remove('open');\n rebuild(true);\n }\n Object.keys(LAYOUT_LABEL).forEach(function (name) {\n var b = document.getElementById('layout' + name.charAt(0).toUpperCase() + name.slice(1));\n if (b && b.addEventListener) b.addEventListener('click', function () { setLayout(name); });\n });\n updateLayoutBtn();\n\n if (document.addEventListener) {\n document.addEventListener('click', function () {\n if (dd.classList) dd.classList.remove('open');\n if (fdd.classList) fdd.classList.remove('open');\n if (ldd.classList) ldd.classList.remove('open');\n if (sdd.classList) sdd.classList.remove('open');\n if (mdd && mdd.classList) mdd.classList.remove('open');\n });\n document.addEventListener('keydown', function (ev) {\n if (ev.key === 'Escape') {\n var modal = document.getElementById('flowModal');\n if (modal.classList && String(modal.className).indexOf('open') >= 0) { closeFlow(); return; }\n setPresentation(false);\n if (dd.classList) dd.classList.remove('open');\n }\n });\n }\n\n // ── Responsive header overflow → \"⋯\" dropdown ─────────────────────────────\n // When the floating header no longer fits its controls, trailing items\n // COLLAPSE into the More menu instead of relying on horizontal scroll —\n // every control stays one click away. Whole items move (listeners survive\n // reparenting); a hidden placeholder pins each item's original position so\n // restoring keeps the exact order. Collapse order = least-used first.\n (function () {\n if (typeof window === 'undefined') return;\n var hdr = document.getElementById('hdr');\n var moreDd = document.getElementById('moreDd');\n var moreMenu = document.getElementById('moreMenu');\n if (!hdr || !moreDd || !moreMenu || !hdr.getBoundingClientRect) return;\n // Collapse order = least-used first. A dropdown trigger moves with its\n // WRAPPER (the .dropdown div) so its own menu keeps working from the More\n // menu (menus are fixed-positioned at the trigger's rect).\n var COLLAPSE = ['themeBtn', 'resetBtn', 'exportBtn', 'layoutBtn', 'presentBtn', 'fitBtn', 'panelToggle'];\n var markers = {};\n function movableFor(id) {\n var el = document.getElementById(id);\n if (!el) return null;\n var p = el.parentNode;\n if (p && p.className && String(p.className).indexOf('dropdown') >= 0 && p !== moreMenu) return p;\n return el;\n }\n function markerFor(id, el) {\n if (!markers[id]) {\n var m = document.createElement('span');\n m.style.display = 'none';\n el.parentNode.insertBefore(m, el);\n markers[id] = m;\n }\n return markers[id];\n }\n var collapsed = [];\n // True content overflow in px, measured with FRACTIONAL rect precision:\n // scrollWidth/clientWidth are rounded integers and scrollWidth never reads\n // below clientWidth, so a sub-pixel overflow that still paints a scrollbar\n // is invisible to them. Positive = overflowing; negative = headroom.\n function overflowPx() {\n var box = hdr.getBoundingClientRect();\n var edge = box.left;\n for (var c = hdr.firstElementChild; c; c = c.nextElementSibling) {\n var cr = c.getBoundingClientRect();\n if (cr.width > 0 && cr.right > edge) edge = cr.right;\n }\n return edge - (box.right - 14); // 14 = the header's right padding\n }\n function reflow() {\n // Not laid out (hidden tab, non-browser DOM) — measuring would misfire.\n var box = hdr.getBoundingClientRect();\n if (!box || box.width <= 0) return;\n // Restore everything, then collapse until the row fits (idempotent).\n for (var i = collapsed.length - 1; i >= 0; i--) {\n var it = collapsed[i];\n if (it.el && it.marker && it.marker.parentNode) it.marker.parentNode.insertBefore(it.el, it.marker);\n }\n collapsed = [];\n moreDd.style.display = 'none';\n hdr.scrollLeft = 0;\n var guard = 0;\n // Demand a few px of headroom, not a bare fit — the marginal-fit widths\n // are exactly where the phantom scrollbar appeared.\n while (overflowPx() > -8 && guard < COLLAPSE.length) {\n var id = COLLAPSE[guard++];\n var el = movableFor(id);\n if (!el || el === moreDd || el.parentNode === moreMenu) continue;\n var m = markerFor(id, el);\n // A dropdown moved while open would strand its fixed-positioned menu.\n if (el.classList) el.classList.remove('open');\n moreDd.style.display = '';\n moreMenu.appendChild(el);\n collapsed.push({ el: el, marker: m });\n }\n if (collapsed.length === 0) moreDd.style.display = 'none';\n }\n var raf = null;\n var defer = window.requestAnimationFrame\n ? window.requestAnimationFrame.bind(window)\n : window.setTimeout.bind(window);\n function schedule() {\n if (raf !== null) return;\n raf = defer(function () { raf = null; reflow(); });\n }\n if (typeof ResizeObserver !== 'undefined') {\n new ResizeObserver(schedule).observe(hdr);\n } else if (window.addEventListener) {\n window.addEventListener('resize', schedule);\n }\n schedule();\n })();\n function fileBase() {\n var scope = state.view.kind === 'types' ? 'types'\n : state.view.id ? state.view.id.replace(/::/g, '-') : 'system';\n return (String(MODEL.system.name) + '-' + scope).replace(/\\\\s+/g, '-').toLowerCase();\n }\n function downloadText(name, text, mime) {\n if (!inBrowser) return;\n var blob = new Blob([text], { type: mime });\n var a = document.createElement('a');\n a.href = URL.createObjectURL(blob);\n a.download = name;\n document.body.appendChild(a);\n a.click();\n a.remove();\n setTimeout(function () { URL.revokeObjectURL(a.href); }, 5000);\n }\n function downloadPng(cyInst, name) {\n if (!inBrowser) return;\n var uri = cyInst.png({ full: true, scale: 2, bg: THEMES[state.theme].png });\n var a = document.createElement('a');\n a.href = uri; a.download = name;\n document.body.appendChild(a); a.click(); a.remove();\n }\n // Types (ERD) view exports through the same builders via a synthetic model.\n function typesExportModel() {\n var list = typesInScope();\n var inScope = {};\n list.forEach(function (t) { inScope[t.id] = 1; });\n var comps = list.map(function (t) {\n return { id: t.id, name: t.name, subsystem: 'types', componentType: t.kind === 'entity' ? 'Entity' : 'ValueObject', public: false, owns: [] };\n });\n var seen = {};\n var edges = [];\n MODEL.typeEdges.forEach(function (e) {\n if (!inScope[e.from] || !inScope[e.to]) return;\n var k = e.from + '=>' + e.to;\n if (seen[k]) return;\n seen[k] = 1;\n edges.push({ from: e.from, to: e.to, cross: false });\n });\n return {\n system: { name: MODEL.system.name },\n generatedAt: MODEL.generatedAt,\n subsystems: [{ id: 'types', name: MODEL.system.name + ' — types' }],\n components: comps,\n edges: edges,\n };\n }\n function typesHarvestLayout() {\n var boxes = {};\n var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n cy.nodes().forEach(function (n) {\n if (n.id().indexOf('T~') !== 0) return;\n var bb = n.boundingBox({ includeLabels: false, includeOverlays: false });\n boxes[n.id().slice(2)] = { x: bb.x1, y: bb.y1, w: bb.w, h: bb.h };\n minX = Math.min(minX, bb.x1); minY = Math.min(minY, bb.y1);\n maxX = Math.max(maxX, bb.x2); maxY = Math.max(maxY, bb.y2);\n });\n return { boxes: boxes, subs: { types: { x: minX - 24, y: minY - 42, w: (maxX - minX) + 48, h: (maxY - minY) + 66, collapsed: false } } };\n }\n function currentExport() {\n if (state.view.kind === 'types') return { model: typesExportModel(), layout: typesHarvestLayout() };\n return { model: MODEL, layout: harvestLayout() };\n }\n document.getElementById('expPng').addEventListener('click', function () { downloadPng(cy, fileBase() + '.png'); });\n document.getElementById('expDrawio').addEventListener('click', function () {\n var ex = currentExport();\n downloadText(fileBase() + '.drawio', buildDrawioXml(ex.model, ex.layout), 'application/xml');\n });\n document.getElementById('expExcalidraw').addEventListener('click', function () {\n var ex = currentExport();\n downloadText(fileBase() + '.excalidraw', buildExcalidrawScene(ex.model, ex.layout), 'application/json');\n });\n\n // ---- narrative modal (Flow + Steps modes) --------------------------------------\n var flowCy = null;\n var flowStack = [];\n var flowMode = 'flow';\n var flowHideErr = false;\n function narrativeFor(compId, method) {\n var c = compById[compId];\n if (!c) return null;\n for (var i = 0; i < c.narratives.length; i++) {\n if (c.narratives[i].method === method) return c.narratives[i];\n }\n return null;\n }\n // Intent prose (the detail dial's alternative to a step narrative).\n function intentFor(compId, method) {\n var c = compById[compId];\n if (!c || !c.intents) return null;\n for (var i = 0; i < c.intents.length; i++) {\n if (c.intents[i].method === method) return c.intents[i].text;\n }\n return null;\n }\n // The method's L3 contract (signature/description/returns) if declared.\n function methodInfo(compId, method) {\n var c = compById[compId];\n if (!c) return null;\n for (var i = 0; i < c.interfaces.length; i++) {\n var ms = c.interfaces[i].methods;\n for (var j = 0; j < ms.length; j++) {\n if (ms[j].name === method) return { intf: c.interfaces[i], m: ms[j] };\n }\n }\n return null;\n }\n // A call target is \"openable\" when we can show SOMETHING for it: a step\n // narrative, an intent paragraph, or at least its contract. This lets the user\n // drill into intent-only / contract-only methods (see the explanation there),\n // not just fully-narrated ones.\n function openable(compId, method) {\n return !!(narrativeFor(compId, method) || intentFor(compId, method) || methodInfo(compId, method));\n }\n function flowTitle() {\n var top = flowStack[flowStack.length - 1];\n return top.comp + '.' + top.method;\n }\n function renderFlowCrumb() {\n document.getElementById('flowCrumb').innerHTML = flowStack.map(function (f, i) {\n var s = f.comp + '.' + f.method + '()';\n return i === flowStack.length - 1 ? s : '<span class=\"dimc\">' + s + ' → </span>';\n }).join('');\n document.getElementById('flowBack').style.display = flowStack.length > 1 ? '' : 'none';\n }\n function drillFlow(comp, method) {\n flowStack.push({ comp: comp, method: method });\n renderFlowModal();\n }\n // Shared flow-graph derivation: one node per step plus semantic edges\n // (seq | true | false | case | default | enter | exit | back | error |\n // finally | jump). Both the modal renderer and the exports consume it.\n function buildFlowGraph(narrative) {\n var steps = (narrative ? narrative.steps.slice() : []).sort(function (a, b) { return a.n - b.n; });\n var byN = {}, nums = [];\n steps.forEach(function (s) { byN[s.n] = s; nums.push(s.n); });\n var idx = {};\n nums.forEach(function (n, i) { idx[n] = i; });\n function nextOf(n) { var i = idx[n]; return i !== undefined && i + 1 < nums.length ? nums[i + 1] : null; }\n\n // Region depth (loop/try/parallel bodies) → indentation; loop body ends\n // flow back to their header instead of falling through.\n var depth = {}, open = [], loopEnd = {};\n steps.forEach(function (s) {\n while (open.length && open[open.length - 1] < s.n) open.pop();\n depth[s.n] = open.length;\n if ((s.kind === 'loop' || s.kind === 'try' || s.kind === 'parallel') && s.end !== undefined) open.push(s.end);\n if (s.kind === 'loop' && s.end !== undefined) loopEnd[s.end] = s.n;\n });\n\n // Parallel fan-out/join: arms are contiguous ordered sub-regions of the\n // body; an arm's LAST step continues at the region's JOIN bar (a virtual\n // node, id 'j'+header), never into its neighbor arm. Built outermost-first\n // (ascending header) so a nested parallel whose endStep is an outer arm\n // end resolves its continuation through the outer mapping — mirrors the\n // validator's stepGraph() fallNext generalization.\n var joins = []; // [{id, header, end, arms}] — virtual join-bar nodes\n var virtualNode = {}; // non-step node ids (join bars, detached ghosts)\n var armEndJoin = {}; // arm-end step → the join id it flows into\n var joinCont = {}; // join id → what runs after the region (step or outer join)\n function fallNext(n) { return armEndJoin[n] !== undefined ? armEndJoin[n] : nextOf(n); }\n steps.forEach(function (p) {\n if (p.kind !== 'parallel' || p.end === undefined || !(p.branches && p.branches.length >= 2)) return;\n var jid = 'j' + p.n;\n var pEntries = p.branches.map(function (b) { return b.step; }).sort(function (a, b) { return a - b; });\n joinCont[jid] = fallNext(p.end);\n joins.push({ id: jid, header: p.n, end: p.end, arms: pEntries.length });\n virtualNode[jid] = 1;\n for (var ai = 0; ai < pEntries.length; ai++) {\n var armEnd = ai + 1 < pEntries.length ? prevOf(pEntries[ai + 1]) : p.end;\n if (armEnd !== null && armEnd >= pEntries[ai]) armEndJoin[armEnd] = jid;\n }\n });\n\n // Detached (fire-and-forget) calls: the callee hangs OFF the flow as a\n // ghost node reached by a dashed open arrow, while the caller's own lane\n // continues immediately — failure does not propagate back.\n var detached = [];\n steps.forEach(function (s) {\n if (!s.detach || !(s.kind === 'call' || s.kind === 'dispatch') || !s.call) return;\n var did = 'd' + s.n;\n detached.push({ id: did, from: s.n, comp: s.call.component, method: s.call.method });\n virtualNode[did] = 1;\n });\n\n // Lanes: structured-flowchart X assignment. Loop/try bodies, branch\n // then-blocks, and switch case blocks shift into their own lane, so the\n // alternate path (false / default / loop-exit) continues straight down\n // an EMPTY main lane instead of cutting through the block's nodes.\n // Nested structures shift additively.\n var laneAdd = nums.map(function () { return 0; });\n function prevOf(n) { var i = idx[n]; return i !== undefined && i > 0 ? nums[i - 1] : null; }\n function shiftSpan(a, b, amt) {\n if (a === null || a === undefined || b === null || b === undefined) return;\n var i = idx[a], j = idx[b];\n if (i === undefined || j === undefined || j < i) return;\n for (var k = i; k <= j; k++) laneAdd[k] += amt;\n }\n steps.forEach(function (s) {\n if ((s.kind === 'loop' || s.kind === 'try') && s.end !== undefined) {\n shiftSpan(nextOf(s.n), s.end, 1);\n }\n if (s.kind === 'branch' && s.onFalse !== undefined && s.onFalse > s.n) {\n var thenStart = s.onTrue !== undefined ? s.onTrue : nextOf(s.n);\n if (thenStart !== null && thenStart > s.n && thenStart < s.onFalse) {\n shiftSpan(thenStart, prevOf(s.onFalse), 1);\n }\n }\n if (s.kind === 'switch') {\n var starts = (s.cases || []).map(function (cse) { return cse.step; })\n .filter(function (n2) { return n2 > s.n && byN[n2]; })\n .sort(function (a, b) { return a - b; });\n // Each case block gets its own lane (a staircase); a block ends\n // where the next case (or the default target) starts. The default\n // path stays in the main lane — the straight-down continuation.\n var bound = s.defaultStep !== undefined && s.defaultStep > s.n ? s.defaultStep : null;\n starts.forEach(function (cs, ci) {\n var endN = ci + 1 < starts.length ? prevOf(starts[ci + 1])\n : (bound !== null && bound > cs ? prevOf(bound) : null);\n if (endN !== null && endN >= cs) shiftSpan(cs, endN, ci + 1);\n });\n }\n if (s.kind === 'parallel' && s.end !== undefined && s.branches && s.branches.length >= 2) {\n // One lane per arm: arm 0 stays under the fan-out bar; each further\n // arm shifts into its own lane, side by side (like case blocks).\n var armStarts = s.branches.map(function (b) { return b.step; })\n .filter(function (n2) { return byN[n2]; })\n .sort(function (a, b) { return a - b; });\n armStarts.forEach(function (as2, ai) {\n if (ai === 0) return;\n var aEnd = ai + 1 < armStarts.length ? prevOf(armStarts[ai + 1]) : s.end;\n if (aEnd !== null && aEnd >= as2) shiftSpan(as2, aEnd, ai);\n });\n }\n });\n var lane = {};\n nums.forEach(function (n, i) { lane[n] = laneAdd[i]; });\n\n var edges = [];\n function E(a, b, kind, label) { if (b !== null && b !== undefined && (byN[b] || virtualNode[b])) edges.push({ from: a, to: b, kind: kind, label: label || '' }); }\n steps.forEach(function (s) {\n var n = s.n;\n switch (s.kind) {\n case 'branch':\n E(n, s.onTrue !== undefined ? s.onTrue : fallNext(n), 'true', 'true');\n E(n, s.onFalse, 'false', 'false');\n break;\n case 'switch':\n (s.cases || []).forEach(function (cse) { E(n, cse.step, 'case', cse.value); });\n E(n, s.defaultStep !== undefined ? s.defaultStep : fallNext(n), 'default', 'default');\n break;\n case 'loop':\n E(n, nextOf(n), 'enter', s.loopKind === 'doWhile' ? 'do' : '');\n if (s.end !== undefined) {\n E(s.end, n, 'back', s.loopKind === 'doWhile' ? 'while ' + (s.cond || '') : '\\\\u27F3');\n E(n, fallNext(s.end), 'exit', 'done');\n }\n break;\n case 'try':\n E(n, nextOf(n), 'seq');\n (s.catches || []).forEach(function (cc) { E(n, cc.step, 'error', cc.error); });\n if (s.fin !== undefined) E(n, s.fin, 'finally', 'finally');\n break;\n case 'parallel':\n // Fan-out: the header bar forks to EVERY arm entry; the implicit\n // join (all arms complete) is the virtual bar wired up below.\n (s.branches || []).forEach(function (br) { E(n, br.step, 'fork', br.name || ''); });\n break;\n case 'jump':\n E(n, s.to, 'jump');\n break;\n case 'return':\n case 'throw':\n break;\n default:\n // Fall-through — except a loop body end (flows back to its header)\n // and an arm end (flows into the join bar, never the neighbor arm).\n if (loopEnd[n] === undefined) E(n, fallNext(n), armEndJoin[n] !== undefined ? 'join' : 'seq');\n }\n });\n // Join bars continue at the step after the region (or the outer join);\n // detached ghosts hang off their firing step with an annotated open arrow.\n joins.forEach(function (j) { E(j.id, joinCont[j.id], 'seq'); });\n detached.forEach(function (d) { E(d.from, d.id, 'detached', 'detached'); });\n return { steps: steps, edges: edges, depth: depth, lane: lane, first: nums.length ? nums[0] : null, joins: joins, detached: detached };\n }\n\n // \"Hide error paths\": drop everything only reachable through error edges —\n // catch regions, their throws — leaving the pure happy-path flow.\n function pruneErrorPaths(graph) {\n if (graph.first === null) return graph;\n var adj = {};\n graph.edges.forEach(function (e) {\n if (e.kind === 'error') return;\n (adj[e.from] = adj[e.from] || []).push(e.to);\n });\n var keep = {}, stack = [graph.first];\n while (stack.length) {\n var n = stack.pop();\n if (keep[n]) continue;\n keep[n] = 1;\n (adj[n] || []).forEach(function (m) { if (!keep[m]) stack.push(m); });\n }\n return {\n steps: graph.steps.filter(function (s) { return keep[s.n]; }),\n edges: graph.edges.filter(function (e) { return e.kind !== 'error' && keep[e.from] && keep[e.to]; }),\n depth: graph.depth,\n lane: graph.lane,\n first: graph.first,\n // Join bars and detached ghosts are NOT error paths — they survive the\n // toggle whenever their region/firing step does.\n joins: (graph.joins || []).filter(function (j) { return keep[j.id]; }),\n detached: (graph.detached || []).filter(function (d) { return keep[d.id]; }),\n };\n }\n\n function flowStepLabel(s) {\n switch (s.kind) {\n case 'branch': return s.n + '. \\\\u25C7 ' + (s.cond || s.text);\n case 'switch': return s.n + '. \\\\u25C7 switch ' + (s.on || s.text);\n case 'loop': return s.n + '. \\\\u27F3 ' + (s.loopKind === 'doWhile' ? 'do' : (s.loopKind || 'forEach')) + (s.over ? ' ' + s.over : s.cond ? ' while ' + s.cond : '');\n case 'try': return s.n + '. \\\\u26E8 try \\\\u2014 ' + s.text;\n case 'parallel': return s.n + '. \\\\u2225 ' + s.text;\n case 'jump': return s.n + '. \\\\u21B7 ' + s.text;\n case 'return': return s.n + '. \\\\u23CE return' + (s.outcome ? ' \\\\u2014 ' + s.outcome : '');\n case 'throw': return s.n + '. \\\\u26A1 throw' + (s.err ? ' ' + s.err : '');\n default: return s.n + '. ' + s.text;\n }\n }\n\n function renderFlowGraph() {\n var top = flowStack[flowStack.length - 1];\n var c = compById[top.comp];\n var narrative = narrativeFor(top.comp, top.method);\n var t = THEMES[state.theme];\n\n var graph = buildFlowGraph(narrative);\n if (flowHideErr) graph = pruneErrorPaths(graph);\n\n var eles = [];\n eles.push({ data: { id: 'start', label: (c ? c.name : top.comp) + '.' + top.method + '()', w: 280, h: 44, tw: 260 }, position: { x: 0, y: 0 }, classes: 'flowstart' });\n var rowOf = {};\n graph.steps.forEach(function (s2, i2) { rowOf[s2.n] = i2 + 1; });\n var joinByHeader = {};\n (graph.joins || []).forEach(function (j2) { joinByHeader[j2.header] = j2; });\n graph.steps.forEach(function (s, i) {\n var id = 'n' + s.n;\n var isCall = (s.kind === 'call' || s.kind === 'dispatch') && !!s.call;\n // A detached call's target renders as a separate ghost node (below), so\n // the step node itself stays plain and undrillable.\n var isDetached = isCall && !!s.detach;\n var callable = isCall && !isDetached && openable(s.call.component, s.call.method);\n var isCond = s.kind === 'branch' || s.kind === 'switch' || s.kind === 'loop';\n var label = flowStepLabel(s) + (isCall && !isDetached ? '\\\\n\\\\u2192 ' + s.call.component + '.' + s.call.method + '()' + (callable ? ' \\\\u21B4' : '') : '');\n var cls = s.kind === 'branch' || s.kind === 'switch' ? 'flowcond'\n : s.kind === 'loop' ? 'flowloop'\n : s.kind === 'try' ? 'flowtry'\n : s.kind === 'parallel' ? 'flowfork'\n : s.kind === 'return' ? 'flowend'\n : s.kind === 'throw' ? 'flowthrow'\n : s.kind === 'jump' ? 'flowjumpn'\n : isCall ? 'flowcall' : 'flowlocal';\n // A parallel header renders as a fan-out BAR spanning its arm lanes\n // (label above); its implicit join bar is added after the loop.\n var jinfo = s.kind === 'parallel' ? joinByHeader[s.n] : undefined;\n var laneN = graph.lane[s.n] || 0;\n eles.push({\n data: {\n id: id, label: label,\n w: jinfo ? 344 * (jinfo.arms - 1) + 320 : isCond ? 320 : 300,\n h: jinfo ? 16 : isCall ? 58 : isCond ? 64 : 46,\n tw: jinfo ? 344 * (jinfo.arms - 1) + 280 : isCond ? 210 : 280,\n callComp: isCall ? s.call.component : '', callMethod: isCall ? s.call.method : '',\n },\n // Rows keep code order (Y); lanes give branches/cases/arms their own\n // column (X), wide enough that side-by-side nodes never overlap.\n position: { x: jinfo ? (laneN + (jinfo.arms - 1) / 2) * 344 : laneN * 344, y: (i + 1) * 92 },\n classes: cls + (callable ? ' drill' : ''),\n });\n });\n // Implicit join bars: one per parallel region, spanning the arm lanes just\n // below the body's last row — all arms complete before flow continues.\n (graph.joins || []).forEach(function (j) {\n // A pruned/dangling endStep must not orphan the bar's edges — park it\n // after the last kept row instead of dropping it.\n var rEnd = rowOf[j.end] !== undefined ? rowOf[j.end] : graph.steps.length;\n var laneJ = graph.lane[j.header] || 0;\n var barW = 344 * (j.arms - 1) + 320;\n eles.push({\n data: { id: 'n' + j.id, label: 'join \\\\u2014 all ' + j.arms + ' arms', w: barW, h: 16, tw: barW - 40 },\n position: { x: (laneJ + (j.arms - 1) / 2) * 344, y: rEnd * 92 + 46 },\n classes: 'flowjoin',\n });\n });\n // Detached-call ghosts: the callee sits OFF the flow lane, reached by a\n // dashed open arrow labeled \"detached\" — failure does not propagate back.\n (graph.detached || []).forEach(function (d) {\n if (rowOf[d.from] === undefined) return;\n var dCallable = openable(d.comp, d.method);\n eles.push({\n data: {\n id: 'n' + d.id,\n label: d.comp + '.' + d.method + '()' + (dCallable ? ' \\\\u21B4' : '') + '\\\\ndetached \\\\u2014 fire & forget',\n w: 260, h: 52, tw: 240, callComp: d.comp, callMethod: d.method,\n },\n position: { x: ((graph.lane[d.from] || 0)) * 344 + 330, y: rowOf[d.from] * 92 },\n classes: 'flowdetach' + (dCallable ? ' drill' : ''),\n });\n });\n // No L5 narrative for the opened method: instead of an empty chart, show\n // its intent paragraph (or contract description) as a single note node, so a\n // drilled-in intent-only / contract-only method still explains itself.\n if (!narrative) {\n var noteText = intentFor(top.comp, top.method);\n var miN = methodInfo(top.comp, top.method);\n if (!noteText && miN) noteText = miN.m.description + (miN.m.returns ? ' \\\\u2192 returns ' + miN.m.returns : '');\n eles.push({ data: { id: 'intentNote', label: noteText || 'No narrative or intent recorded for this method.', w: 380, h: 120, tw: 340 }, position: { x: 0, y: 120 }, classes: 'flowintent' });\n eles.push({ data: { id: 'fe-intent', source: 'start', target: 'intentNote', lbl: '' } });\n }\n if (graph.first !== null) eles.push({ data: { id: 'fe-start', source: 'start', target: 'n' + graph.first, lbl: '' } });\n graph.edges.forEach(function (e, i) {\n var cls = e.kind === 'error' ? 'fErr'\n : e.kind === 'back' ? 'fBack'\n : e.kind === 'false' ? 'fAlt'\n : e.kind === 'jump' || e.kind === 'finally' ? 'fJump'\n : e.kind === 'case' || e.kind === 'default' ? 'fAlt'\n : e.kind === 'fork' ? 'fFork'\n : e.kind === 'join' ? 'fJoin'\n : e.kind === 'detached' ? 'fDetach'\n : e.kind === 'exit' ? 'fAlt' : '';\n eles.push({ data: { id: 'fe' + i, source: 'n' + e.from, target: 'n' + e.to, lbl: e.label }, classes: cls });\n });\n\n var style = [\n { selector: 'node', style: { shape: 'round-rectangle', width: 'data(w)', height: 'data(h)', label: 'data(label)', 'text-wrap': 'wrap', 'text-max-width': 'data(tw)', 'font-size': 11, 'font-family': 'Inter, system-ui, sans-serif', color: t.ink, 'text-valign': 'center', 'border-width': 1.5 } },\n { selector: '.flowstart', style: { 'background-color': t.stereo.entry.fill, 'border-color': t.stereo.entry.stroke, color: t.stereo.entry.text, 'font-weight': 'bold' } },\n { selector: '.flowlocal', style: { 'background-color': t.innerFill, 'border-color': t.innerStroke, color: t.innerText } },\n { selector: '.flowcall', style: { 'background-color': t.stereo.logic.fill, 'border-color': t.stereo.logic.stroke, color: t.stereo.logic.text } },\n { selector: '.flowcond', style: { shape: 'round-diamond', 'background-color': t.stereo.data.fill, 'border-color': t.stereo.data.stroke, color: t.stereo.data.text } },\n { selector: '.flowloop', style: { shape: 'round-diamond', 'background-color': t.stereo.adapter.fill, 'border-color': t.stereo.adapter.stroke, color: t.stereo.adapter.text } },\n { selector: '.flowtry', style: { 'background-color': t.innerFill, 'border-color': t.issue, 'border-style': 'dashed', color: t.innerText } },\n { selector: '.flowend', style: { shape: 'round-rectangle', 'background-color': t.stereo.entry.fill, 'border-color': t.stereo.entry.stroke, color: t.stereo.entry.text, 'border-width': 2.5 } },\n { selector: '.flowthrow', style: { shape: 'round-rectangle', 'background-color': t.ghostFill, 'border-color': t.issue, color: t.issue, 'border-width': 2.5 } },\n { selector: '.flowjumpn', style: { 'background-color': t.ghostFill, 'border-color': t.ghostStroke, 'border-style': 'dotted', color: t.ghostText } },\n // Parallel fan-out/join bars (UML activity style): solid slim bars; the\n // fork carries the step label above it, the join a small caption below.\n { selector: '.flowfork', style: { 'background-color': t.ink, 'border-color': t.ink, color: t.ink, 'text-valign': 'top', 'text-margin-y': -6, 'font-weight': 'bold' } },\n { selector: '.flowjoin', style: { 'background-color': t.ink, 'border-color': t.ink, color: t.edgeText, 'text-valign': 'bottom', 'text-margin-y': 6, 'font-size': 9.5 } },\n // Detached-call ghost: visibly off the flow, no failure propagation.\n { selector: '.flowdetach', style: { 'background-color': t.ghostFill, 'border-color': t.ghostStroke, 'border-style': 'dashed', color: t.ghostText, 'font-style': 'italic' } },\n { selector: '.flowintent', style: { shape: 'round-rectangle', width: 'label', height: 'label', padding: '16px', 'background-color': t.ghostFill, 'border-color': t.ghostStroke, 'border-style': 'dashed', color: t.innerText, 'text-max-width': 340, 'text-wrap': 'wrap', 'font-size': 11.5, 'text-valign': 'center', 'text-halign': 'center', 'font-style': 'italic' } },\n { selector: '.drill', style: { 'border-width': 2.5 } },\n { selector: 'edge', style: { 'curve-style': 'bezier', width: 1.6, 'line-color': t.pageEdge, 'target-arrow-shape': 'triangle', 'target-arrow-color': t.pageEdge, label: 'data(lbl)', 'font-size': 9.5, color: t.edgeText, 'text-background-color': t.bgLabel, 'text-background-opacity': 0.85, 'text-rotation': 'autorotate' } },\n // Long edges (false/case/exit, jumps, error paths) route orthogonally:\n // down the source's lane, one horizontal turn just above the target\n // row (where the corridor between rows is guaranteed free), then into\n // the target — instead of a straight line cutting through the nodes\n // stacked in between.\n { selector: 'edge.fAlt', style: { 'line-style': 'dashed', 'curve-style': 'taxi', 'taxi-direction': 'downward', 'taxi-turn': -34, 'taxi-turn-min-distance': 10 } },\n { selector: 'edge.fBack', style: { 'line-style': 'dashed', 'curve-style': 'unbundled-bezier', 'control-point-distances': [-70], 'control-point-weights': [0.5] } },\n { selector: 'edge.fErr', style: { 'line-style': 'dashed', 'curve-style': 'taxi', 'taxi-direction': 'downward', 'taxi-turn': -34, 'taxi-turn-min-distance': 10, 'line-color': t.issue, 'target-arrow-color': t.issue, color: t.issue } },\n { selector: 'edge.fJump', style: { 'line-style': 'dotted', 'curve-style': 'taxi', 'taxi-direction': 'downward', 'taxi-turn': -34, 'taxi-turn-min-distance': 10 } },\n // Fork fan-out is a first-class flow edge (slightly heavier); the join\n // collectors route orthogonally down their own (empty) lane corridor.\n { selector: 'edge.fFork', style: { width: 2.2 } },\n { selector: 'edge.fJoin', style: { width: 2.2, 'curve-style': 'taxi', 'taxi-direction': 'downward', 'taxi-turn': -34, 'taxi-turn-min-distance': 10 } },\n // Detached: dashed OPEN arrow — fire-and-forget, no failure propagation.\n { selector: 'edge.fDetach', style: { 'line-style': 'dashed', 'target-arrow-shape': 'vee' } },\n ];\n\n if (!flowCy) {\n flowCy = cytoscape({ container: document.getElementById('flowCy'), elements: eles, style: style, layout: { name: 'preset' }, boxSelectionEnabled: false, autounselectify: true });\n // Flowcharts are fixed documentation — never rearrangeable.\n flowCy.autolock(true);\n // Drill on DOUBLE-click only — single taps in a dense flowchart are\n // too easy to land accidentally.\n flowCy.on('dbltap', 'node.drill', function (ev) {\n var d = ev.target.data();\n drillFlow(d.callComp, d.callMethod);\n });\n } else {\n flowCy.batch(function () { flowCy.elements().remove(); flowCy.add(eles); });\n flowCy.style(style);\n }\n flowCy.fit(undefined, 30);\n }\n function flowStepText(s) {\n switch (s.kind) {\n case 'branch': return '\\\\u25C7 if ' + (s.cond || s.text) + (s.onFalse !== undefined ? ' \\\\u2014 else \\\\u2192 ' + s.onFalse : '');\n case 'switch': return '\\\\u25C7 switch on ' + (s.on || s.text) + ' \\\\u2014 ' + (s.cases || []).map(function (c) { return c.value + ' \\\\u2192 ' + c.step; }).join(', ') + (s.defaultStep !== undefined ? ', default \\\\u2192 ' + s.defaultStep : '');\n case 'loop': return '\\\\u27F3 ' + (s.loopKind || 'forEach') + (s.over ? ' ' + s.over : '') + (s.cond ? ' while ' + s.cond : '') + (s.end !== undefined ? ' (body \\\\u2192 ' + s.end + ')' : '');\n case 'try': return '\\\\u26E8 try (body \\\\u2192 ' + s.end + ')' + (s.catches || []).map(function (c) { return ' \\\\u2014 on ' + c.error + ' \\\\u2192 ' + c.step; }).join('') + (s.fin !== undefined ? ' \\\\u2014 finally \\\\u2192 ' + s.fin : '');\n case 'parallel': return '\\\\u2225 parallel \\\\u2014 arms ' + (s.branches || []).map(function (b) { return (b.name ? b.name + ' ' : '') + '\\\\u2192 ' + b.step; }).join(', ') + (s.end !== undefined ? ' (join after ' + s.end + ')' : '');\n case 'jump': return '\\\\u21B7 \\\\u2192 step ' + s.to + (s.text ? ' \\\\u2014 ' + s.text : '');\n case 'return': return '\\\\u23CE return' + (s.outcome ? ' \\\\u2014 ' + s.outcome : '') + (s.text ? ' (' + s.text + ')' : '');\n case 'throw': return '\\\\u26A1 throw' + (s.err ? ' ' + s.err : '') + (s.text ? ' \\\\u2014 ' + s.text : '');\n default: return s.text;\n }\n }\n function renderFlowSteps() {\n var top = flowStack[flowStack.length - 1];\n var narrative = narrativeFor(top.comp, top.method);\n var el = document.getElementById('flowSteps');\n if (!narrative) {\n // No step-by-step narrative — show the method's contract + intent prose so\n // a drilled-in intent-only / contract-only method still explains itself.\n var intent = intentFor(top.comp, top.method);\n var mi = methodInfo(top.comp, top.method);\n var parts = ['<div class=\"fstep\" style=\"opacity:.7\">No step-by-step narrative \\\\u2014 showing intent / contract:</div>'];\n if (mi) {\n parts.push('<div class=\"fstep\"><code>' + escText(mi.m.signature) + '</code></div>');\n parts.push('<div class=\"fstep\">' + escText(mi.m.description) + (mi.m.returns ? ' \\\\u2014 returns ' + escText(mi.m.returns) : '') + '</div>');\n }\n if (intent) parts.push('<div class=\"fstep\" style=\"font-style:italic\">' + escText(intent) + '</div>');\n if (!mi && !intent) parts.push('<div class=\"fstep\">No intent or contract recorded for this method.</div>');\n el.innerHTML = parts.join('');\n return;\n }\n var html = narrative.steps.map(function (s) {\n var callHtml = '';\n if (s.call) {\n var callable = openable(s.call.component, s.call.method);\n callHtml = ' \\\\u2192 <span class=\"call' + (callable ? ' drillstep' : '') + '\" data-dc=\"' + s.call.component + '\" data-dm=\"' + s.call.method + '\">'\n + s.call.component + '.' + s.call.method + '()' + (callable ? ' \\\\u21B4' : '') + '</span>'\n + (s.detach ? ' <span style=\"opacity:.72\">\\\\u21E2 detached \\\\u2014 fire &amp; forget</span>' : '');\n }\n return '<div class=\"fstep\"><span class=\"num\">' + s.n + '.</span> ' + escText(flowStepText(s)) + callHtml + '</div>';\n }).join('');\n el.innerHTML = html;\n // Single click on the styled step link drills in (it looks like a hyperlink,\n // so it behaves like one). The flowchart graph keeps double-click, since a\n // single tap in a dense chart is too easy to land accidentally.\n var drills = el.querySelectorAll('.drillstep');\n for (var i = 0; i < drills.length; i++) {\n (function (d) {\n d.addEventListener('click', function () { drillFlow(d.getAttribute('data-dc'), d.getAttribute('data-dm')); });\n })(drills[i]);\n }\n }\n function escText(s) { var d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; }\n function renderFlowModal() {\n renderFlowCrumb();\n renderFlowGraph();\n renderFlowSteps();\n var modal = document.getElementById('flowModal');\n if (modal.classList) modal.classList[flowMode === 'steps' ? 'add' : 'remove']('steps');\n }\n function openFlow(compId, method, mode) {\n flowStack = [{ comp: compId, method: method }];\n flowMode = mode || 'flow';\n var seg = document.getElementById('flowModeSeg');\n var btns = seg.querySelectorAll('button');\n for (var i = 0; i < btns.length; i++) {\n if (btns[i].classList) btns[i].classList[btns[i].getAttribute('data-fm') === flowMode ? 'add' : 'remove']('active');\n }\n var modal = document.getElementById('flowModal');\n if (modal.classList) modal.classList.add('open');\n renderFlowModal();\n setTimeout(function () { if (flowCy) { flowCy.resize(); flowCy.fit(undefined, 30); } }, 60);\n }\n function closeFlow() {\n var modal = document.getElementById('flowModal');\n if (modal.classList) { modal.classList.remove('open'); modal.classList.remove('steps'); }\n }\n document.getElementById('flowClose').addEventListener('click', closeFlow);\n document.getElementById('flowBack').addEventListener('click', function () { if (flowStack.length > 1) { flowStack.pop(); renderFlowModal(); } });\n document.getElementById('flowErrToggle').addEventListener('click', function () {\n flowHideErr = !flowHideErr;\n var b = document.getElementById('flowErrToggle');\n b.textContent = flowHideErr ? 'Show error paths' : 'Hide error paths';\n if (!flowStack.length) return;\n renderFlowGraph();\n if (flowCy) flowCy.fit(undefined, 30);\n });\n (function () {\n var seg = document.getElementById('flowModeSeg');\n var btns = seg.querySelectorAll('button');\n for (var i = 0; i < btns.length; i++) {\n (function (b) {\n b.addEventListener('click', function () {\n flowMode = b.getAttribute('data-fm');\n for (var j = 0; j < btns.length; j++) {\n if (btns[j].classList) btns[j].classList[btns[j] === b ? 'add' : 'remove']('active');\n }\n renderFlowModal();\n setTimeout(function () { if (flowCy && flowMode === 'flow') { flowCy.resize(); flowCy.fit(undefined, 30); } }, 60);\n });\n })(btns[i]);\n }\n })();\n\n // Flow exports: build a small synthetic model so the same draw.io/Excalidraw\n // builders produce editable flowcharts (using the flow's current positions).\n function flowExportModel() {\n var top = flowStack[flowStack.length - 1];\n var narrative = narrativeFor(top.comp, top.method) || { steps: [] };\n var graph = buildFlowGraph(narrative);\n if (flowHideErr) graph = pruneErrorPaths(graph);\n var comps = [], edges = [];\n comps.push({ id: 'start', name: flowTitle() + '()', subsystem: 'flow', componentType: 'Start', public: false, owns: [] });\n graph.steps.forEach(function (s) {\n var name = flowStepLabel(s) + (s.call && !s.detach ? ' \\\\u2192 ' + s.call.component + '.' + s.call.method + '()' : '');\n comps.push({ id: 'n' + s.n, name: name, subsystem: 'flow', componentType: (s.kind === 'call' || s.kind === 'dispatch') ? 'Call' : 'Step', public: false, owns: [] });\n });\n // Virtual flow nodes (join bars, detached-call ghosts) export as plain\n // steps so the editable diagrams keep the fan-out/join and detachment.\n (graph.joins || []).forEach(function (j) {\n comps.push({ id: 'n' + j.id, name: '\\\\u2225 join \\\\u2014 all ' + j.arms + ' arms', subsystem: 'flow', componentType: 'Step', public: false, owns: [] });\n });\n (graph.detached || []).forEach(function (d) {\n comps.push({ id: 'n' + d.id, name: d.comp + '.' + d.method + '() \\\\u2014 detached', subsystem: 'flow', componentType: 'Call', public: false, owns: [] });\n });\n if (graph.first !== null) edges.push({ from: 'start', to: 'n' + graph.first, cross: false });\n graph.edges.forEach(function (e) {\n edges.push({ from: 'n' + e.from, to: 'n' + e.to, cross: e.kind === 'error' });\n });\n return {\n system: { name: MODEL.system.name },\n generatedAt: MODEL.generatedAt,\n subsystems: [{ id: 'flow', name: flowTitle() + '()' }],\n components: comps,\n edges: edges,\n };\n }\n function flowHarvestLayout() {\n var boxes = {};\n var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n flowCy.nodes().forEach(function (n) {\n var bb = n.boundingBox({ includeLabels: false, includeOverlays: false });\n boxes[n.id()] = { x: bb.x1, y: bb.y1, w: bb.w, h: bb.h };\n minX = Math.min(minX, bb.x1); minY = Math.min(minY, bb.y1);\n maxX = Math.max(maxX, bb.x2); maxY = Math.max(maxY, bb.y2);\n });\n var subs = { flow: { x: minX - 24, y: minY - 42, w: (maxX - minX) + 48, h: (maxY - minY) + 66, collapsed: false } };\n return { boxes: boxes, subs: subs };\n }\n function flowFileBase() { return flowTitle().replace(/[^a-zA-Z0-9_.-]/g, '-') + '-flow'; }\n document.getElementById('flowExpPng').addEventListener('click', function () { if (flowCy) downloadPng(flowCy, flowFileBase() + '.png'); });\n document.getElementById('flowExpDrawio').addEventListener('click', function () {\n if (flowCy) downloadText(flowFileBase() + '.drawio', buildDrawioXml(flowExportModel(), flowHarvestLayout()), 'application/xml');\n });\n document.getElementById('flowExpExcalidraw').addEventListener('click', function () {\n if (flowCy) downloadText(flowFileBase() + '.excalidraw', buildExcalidrawScene(flowExportModel(), flowHarvestLayout()), 'application/json');\n });\n\n // ---- detail sidebar -------------------------------------------------------------\n var panel = document.getElementById('panel');\n function esc(s) { var d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; }\n function chip(label, kind, target) {\n return '<span class=\"chip\" data-kind=\"' + kind + '\" data-id=\"' + esc(target) + '\">' + esc(label) + '</span>';\n }\n function staticChip(label) { return '<span class=\"chip\">' + esc(label) + '</span>'; }\n // Resolve a signature type reference (possibly wrapped: Foo[], Array<Foo>)\n // to a defined type id, for click-through from method cards into the ERD.\n function typeIdFor(ref) {\n if (!ref) return null;\n var r = String(ref).toLowerCase();\n for (var i = 0; i < MODEL.types.length; i++) {\n var t2 = MODEL.types[i];\n if (r === t2.id.toLowerCase() || r === t2.name.toLowerCase()) return t2.id;\n }\n for (var j = 0; j < MODEL.types.length; j++) {\n var t3 = MODEL.types[j];\n if (t3.name.length > 2 && r.indexOf(t3.name.toLowerCase()) >= 0) return t3.id;\n }\n return null;\n }\n function typeRefHtml(ref) {\n var tid = typeIdFor(ref);\n return tid ? chip(ref, 'type', tid) : esc(ref);\n }\n function section(title, count, inner, open) {\n return '<details' + (open ? ' open' : '') + '><summary>' + esc(title)\n + (count !== null ? '<span class=\"count\">' + count + '</span>' : '') + '</summary><div class=\"inner\">' + inner + '</div></details>';\n }\n function issueHtml(list) {\n return list.map(function (i) {\n return '<div class=\"issue ' + esc(i.severity) + '\"><code>' + esc(i.code) + '</code><br>' + esc(i.message) + '</div>';\n }).join('');\n }\n\n // Focus mode: lift the selected element's own edges above everything and let\n // the rest recede, so its relations read clearly in a busy graph.\n function clearFocus() { cy.elements().removeClass('defocus edgeFocus edgeOut edgeIn'); }\n function applyFocus(node) {\n clearFocus();\n if (!node || !node.length) return;\n var core = node;\n if (node.isParent && node.isParent()) core = core.union(node.descendants());\n var edges = core.connectedEdges();\n // A top-level box focuses its EXTERNAL relations (not its own internal\n // wiring); an inner tile or a port focuses the edges WITHIN its boundary too.\n if (!(node.isChild && node.isChild())) edges = edges.not('.inneredge');\n if (!edges.length) return; // isolated node — nothing to spotlight\n var reveal = edges.filter('.revealEdge'); // keep visible, keep its own style\n var colorable = edges.not('.revealEdge');\n var keep = core.union(edges).union(edges.connectedNodes());\n keep = keep.union(keep.ancestors());\n cy.elements().addClass('defocus');\n keep.removeClass('defocus');\n // Colour by direction: outgoing (this → dependency) vs incoming (← dependent).\n var outE = colorable.filter(function (e) { return core.contains(e.source()) && !core.contains(e.target()); });\n var inE = colorable.filter(function (e) { return core.contains(e.target()) && !core.contains(e.source()); });\n outE.addClass('edgeOut').removeClass('defocus');\n inE.addClass('edgeIn').removeClass('defocus');\n colorable.not(outE).not(inE).addClass('edgeFocus').removeClass('defocus');\n reveal.removeClass('defocus');\n }\n\n function select(kind, id, focus) {\n // Selecting a type from a component view (param chip, \"Used by\" chip…)\n // switches into the ERD first, keeping the current subsystem scope.\n if (kind === 'type' && state.view.kind !== 'types' && state.view.kind !== 'databases') {\n state.view = { kind: 'types', id: typesScopeFromView() };\n rebuild(true);\n } else if (kind === 'component' && (state.view.kind === 'types' || state.view.kind === 'databases')) {\n var c = compById[id];\n state.view = { kind: 'subsystem', id: c ? c.subsystem : null };\n rebuild(true);\n }\n state.selectedKind = kind;\n state.selected = id;\n cy.nodes().removeClass('sel');\n cy.edges().removeClass('fieldhl');\n if (id) {\n var node = nodeForRef(kind, id);\n if (node.length) {\n node.addClass('sel');\n applyFocus(node);\n if (focus) cy.animate({ center: { eles: node }, duration: 250 });\n } else { clearFocus(); }\n } else { clearFocus(); }\n renderPanel();\n }\n\n function openViewButton(kind, id, hasKids) {\n if (!hasKids) return '';\n return '<div class=\"openbtn\"><button class=\"tbtn\" data-open-kind=\"' + kind + '\" data-open-id=\"' + esc(id) + '\">\\\\u25B8 Open as view</button></div>';\n }\n\n // ---- OpenAPI affordance ---------------------------------------------------\n // A component \"exposes an API\" when any of its contract methods carries an HTTP\n // endpoint. The details panel offers a \"View OpenAPI\" button that opens the\n // project's rendered surface: in the web app via the host hook (opts.onOpenApi),\n // on a served shared page as a sibling path (/share/<token>/openapi). In a\n // downloaded standalone file (file://) there is no server, so it is hidden.\n function componentExposesApi(c) {\n return (c.interfaces || []).some(function (i) {\n return (i.methods || []).some(function (m) { return m.endpoint && m.endpoint.transport === 'HTTP'; });\n });\n }\n function openApiSiblingHref() {\n if (typeof window === 'undefined' || !/^https?:$/.test(window.location.protocol)) return null;\n return window.location.pathname.replace(/\\\\/$/, '') + '/openapi';\n }\n function openApiAllowed() {\n return (typeof opts !== 'undefined' && opts && opts.onOpenApi) || openApiSiblingHref() !== null;\n }\n // The OpenAPI document is a PROJECT-level artifact (the whole project's external\n // gateway surface), so the affordance is offered up the whole hierarchy where\n // it is contextually relevant: a portal that exposes HTTP, its subsystem, and\n // the project root — each opens the same project surface.\n function subsystemExposesApi(sid) {\n return MODEL.components.some(function (x) {\n return (x.subsystem === sid || (x.subsystem || '').indexOf(sid + '::') === 0) && componentExposesApi(x);\n });\n }\n function projectExposesApi() {\n return MODEL.components.some(componentExposesApi);\n }\n // tag = the component's L0 gateway entry id (its section in the combined spec),\n // so a portal deep-links straight to its own operations; a subsystem/project\n // passes '' and opens the whole combined document.\n function openApiButton(exposes, tag) {\n if (!exposes || !openApiAllowed()) return '';\n return '<div class=\"openbtn\"><button class=\"tbtn\" data-openapi-tag=\"' + esc(tag || '') + '\">\\\\u25A4 View OpenAPI \\\\u2197</button></div>';\n }\n\n function renderPanel() {\n var head = '', body = '';\n // With nothing selected, describe the CURRENT VIEW SCOPE rather than the\n // root system — so drilling into a subsystem/component shows that scope's\n // details, and the breadcrumb still walks back up to the parent.\n var focusKind = state.selectedKind, focusId = state.selected, scopeFocus = false;\n if (!focusKind) {\n scopeFocus = true;\n if (state.view.kind === 'subsystem') { focusKind = 'subsystem'; focusId = state.view.id; }\n else if (state.view.kind === 'component') { focusKind = 'component'; focusId = state.view.id; }\n else if (state.view.kind === 'types' && state.view.id) { focusKind = 'subsystem'; focusId = state.view.id; }\n }\n if (focusKind === 'component' && compById[focusId]) {\n var c = compById[focusId];\n head = '<h2>' + esc(c.name) + '</h2>'\n + staticChip('\\\\u00AB' + c.componentType + (c.portalType ? '/' + c.portalType : '') + '\\\\u00BB')\n + (c.public ? staticChip('published') : '')\n + (c.status ? staticChip(c.status) : '')\n + (scopeFocus ? staticChip('current view') : '')\n + chip(c.subsystem, 'subsystem', c.subsystem)\n + (scopeFocus ? '' : openViewButton('component', c.id, c.owns.length > 0))\n + openApiButton(componentExposesApi(c), c.apiTag);\n \n var linkedTypes = MODEL.types.filter(function (t) { return t.componentClass === c.id; });\n if (linkedTypes.length) {\n head += '<div style=\"margin-top:6px\"><b style=\"font-size:11px\">Linked System Entity:</b> '\n + linkedTypes.map(function (t) { return chip(t.id, 'type', t.id); }).join(' ')\n + '</div>';\n }\n body += '<p class=\"desc\">' + esc(c.description) + '</p>';\n\n var depInner = (c.dependsOn.length ? c.dependsOn.map(function (d) { return chip(d, 'component', d); }).join('') : '<span class=\"desc\">none</span>')\n + (c.owns.length ? '<div style=\"margin-top:8px\"><b style=\"font-size:11px\">Owns:</b><br>' + c.owns.map(function (d) { return chip(d, 'component', d); }).join('') + '</div>' : '');\n body += section('Dependencies', c.dependsOn.length + c.owns.length, depInner, true);\n\n // Methods: contracts + narratives unified — each method card links to its\n // narrative (flowchart or numbered steps) instead of dumping steps inline.\n var methodCount = 0;\n var intfInner = c.interfaces.map(function (intf) {\n methodCount += intf.methods.length;\n return '<div style=\"margin:6px 0 2px\"><b>' + esc(intf.name) + '</b> <code style=\"font-size:10.5px;display:inline\">' + esc(intf.id) + '</code></div>'\n + intf.methods.map(function (m) {\n var hasNarr = !!narrativeFor(c.id, m.name);\n var mIntent = null;\n (c.intents || []).forEach(function (x) { if (x.method === m.name) mIntent = x.text; });\n return '<div class=\"method\"><div class=\"mname\">' + esc(m.name) + '<span class=\"grow\"></span>'\n + (hasNarr\n ? '<button class=\"flowbtn\" data-flow-comp=\"' + esc(c.id) + '\" data-flow-method=\"' + esc(m.name) + '\" data-flow-mode=\"flow\">flow \\\\u25F7</button>'\n + '<button class=\"flowbtn\" data-flow-comp=\"' + esc(c.id) + '\" data-flow-method=\"' + esc(m.name) + '\" data-flow-mode=\"steps\">steps</button>'\n : mIntent\n ? '<span class=\"chip\">intent</span>'\n : '<span class=\"chip\" style=\"opacity:.6\">no narrative</span>')\n + '</div>'\n + '<code>' + esc(m.signature) + '</code>'\n + '<div class=\"mdesc\">' + esc(m.description) + ' \\\\u2014 returns ' + typeRefHtml(m.returns) + '</div>'\n + (mIntent && !hasNarr ? '<div class=\"mdesc\" style=\"font-style:italic\">' + esc(mIntent) + '</div>' : '')\n + (m.params ? '<div class=\"mdesc\">params: ' + m.params.map(function (p) { return esc(p.name) + ': ' + typeRefHtml(p.type); }).join(', ') + '</div>' : '')\n + (m.endpoint ? '<code>' + esc(JSON.stringify(m.endpoint)) + '</code>' : '')\n + (m.guarantees ? '<div style=\"margin-top:4px\">' + m.guarantees.map(staticChip).join('') + '</div>' : '')\n + '</div>';\n }).join('');\n }).join('');\n // narratives without a matching contract method (edge case) still reachable\n var orphanNarrs = c.narratives.filter(function (n) {\n return !c.interfaces.some(function (intf) { return intf.methods.some(function (m) { return m.name === n.method; }); });\n });\n if (orphanNarrs.length) {\n intfInner += orphanNarrs.map(function (n) {\n return '<div class=\"method\"><div class=\"mname\">' + esc(n.method) + '() <span class=\"grow\"></span>'\n + '<button class=\"flowbtn\" data-flow-comp=\"' + esc(c.id) + '\" data-flow-method=\"' + esc(n.method) + '\" data-flow-mode=\"flow\">flow \\\\u25F7</button>'\n + '<button class=\"flowbtn\" data-flow-comp=\"' + esc(c.id) + '\" data-flow-method=\"' + esc(n.method) + '\" data-flow-mode=\"steps\">steps</button>'\n + '</div><div class=\"mdesc\">narrative without a contract method</div></div>';\n }).join('');\n }\n if (c.interfaces.length || orphanNarrs.length) body += section('Methods', methodCount + orphanNarrs.length, intfInner, true);\n\n var iss = issuesBySpec[c.id];\n if (iss) body += section('Validation issues', iss.length, issueHtml(iss), true);\n } else if (focusKind === 'external') {\n var pn2 = cy.getElementById(state.selected);\n var pd = pn2.length ? pn2.data() : null;\n if (pd) {\n var xt = compById[pd.extId];\n head = '<h2>' + esc(xt ? xt.name : pd.extId) + '</h2>'\n + staticChip(pd.dir === 'in' ? '\\\\u21E0 external caller' : 'external dependency \\\\u21E2')\n + (xt ? staticChip('\\\\u00AB' + xt.componentType + (xt.portalType ? '/' + xt.portalType : '') + '\\\\u00BB') : '')\n + (xt ? chip(xt.subsystem, 'subsystem', xt.subsystem) : '');\n body += '<p class=\"desc\">' + (pd.dir === 'in'\n ? 'Lives outside this box and depends on something inside it. The dashed line shows the actual cross-boundary link while this port is selected.'\n : 'A dependency of this box\\\\u2019s internals that lives outside it. The dashed line shows the actual cross-boundary link while this port is selected.') + '</p>';\n if (xt) {\n body += section('External component', null,\n chip(xt.id, 'component', xt.id) + '<div class=\"mdesc\">' + esc(xt.description) + '</div>', true);\n }\n var via = pd.viaKids || [];\n if (via.length) {\n body += section(pd.dir === 'in' ? 'Enters through' : 'Used by (inside this box)', via.length,\n via.map(function (v) { return chip(v.label, v.kind, v.id); }).join(''), true);\n }\n }\n } else if (focusKind === 'type') {\n var ty = null;\n MODEL.types.forEach(function (t2) { if (t2.id === focusId) ty = t2; });\n if (ty) {\n head = '<h2>' + esc(ty.name) + '</h2>' + staticChip('\\\\u00AB' + ty.kind + '\\\\u00BB')\n + (ty.subsystem ? chip(ty.subsystem, 'subsystem', ty.subsystem) : staticChip('system-level shared'));\n \n if (ty.componentClass) {\n head += '<div style=\"margin-top:6px\"><b style=\"font-size:11px\">Class Component:</b> ' + chip(ty.componentClass, 'component', ty.componentClass) + '</div>';\n }\n if (ty.database) {\n var dbName = ty.database;\n if (MODEL.system.databases) {\n var dbSpec = MODEL.system.databases.find(function(d) { return d.id === ty.database; });\n if (dbSpec) dbName = dbSpec.name;\n }\n head += '<div style=\"margin-top:6px\"><b style=\"font-size:11px\">Database Table:</b> ' + staticChip(dbName + '.' + (ty.table || ty.id)) + '</div>';\n }\n if (ty.linkedEntity) {\n head += '<div style=\"margin-top:6px\"><b style=\"font-size:11px\">Linked System Entity:</b> ' + chip(ty.linkedEntity, 'type', ty.linkedEntity) + '</div>';\n }\n var mappingTables = MODEL.types.filter(function (t) { return t.linkedEntity === ty.id; });\n if (mappingTables.length) {\n head += '<div style=\"margin-top:6px\"><b style=\"font-size:11px\">Database Table Mapping:</b> '\n + mappingTables.map(function (t) { return chip(t.id, 'type', t.id); }).join(' ')\n + '</div>';\n }\n\n var fieldsInner = ty.fields.length\n ? ty.fields.map(function (f) {\n var fk = null;\n MODEL.typeEdges.forEach(function (e2) { if (!fk && e2.from === ty.id && e2.field === f.name) fk = e2; });\n var keyLabel = f.key === 'primary' ? 'PK' : f.key === 'unique' ? 'unique' : f.key === 'foreign' ? 'FK' : '';\n if (!keyLabel && f.references) keyLabel = 'FK';\n \n var refHtml = '';\n if (f.references) {\n var targetTypeId = f.references.split('.')[0];\n var targetExists = MODEL.types.some(function(t) { return t.id === targetTypeId; });\n refHtml = '<div class=\"mdesc\">References: ' + (targetExists ? chip(f.references, 'type', targetTypeId) : esc(f.references)) + '</div>';\n } else if (fk) {\n refHtml = '<div class=\"mdesc\">FK \\\\u2192 ' + chip(fk.to + ' [' + (fk.card || '1') + ']', 'type', fk.to) + '</div>';\n }\n\n return '<div class=\"method\"><div class=\"mname\">' + esc(f.name)\n + (keyLabel ? ' <span class=\"chip\">' + keyLabel + '</span>' : '')\n + (f.optional ? ' <span class=\"chip\" style=\"opacity:.7\">optional</span>' : '')\n + '</div><code>' + esc(f.type) + '</code>'\n + refHtml\n + '</div>';\n }).join('')\n : '<span class=\"desc\">no fields</span>';\n body += section('Fields', ty.fields.length, fieldsInner, true);\n if (ty.usedBy && ty.usedBy.length) {\n body += section('Used by methods', ty.usedBy.length, ty.usedBy.map(function (u) {\n return chip(u.component + '.' + u.method + '()', 'component', u.component);\n }).join(''), true);\n }\n if (ty.methods.length) {\n body += section('Methods (pure intrinsic)', ty.methods.length, ty.methods.map(function (m2) {\n return '<div class=\"method\"><div class=\"mname\">' + esc(m2.name) + '</div><code>' + esc(m2.signature) + '</code><div class=\"mdesc\">' + esc(m2.description || '') + ' \\\\u2014 returns <code style=\"display:inline\">' + esc(m2.returns) + '</code></div></div>';\n }).join(''), true);\n }\n var refsOut = MODEL.typeEdges.filter(function (e2) { return e2.from === ty.id; });\n var refsIn = MODEL.typeEdges.filter(function (e2) { return e2.to === ty.id; });\n if (refsOut.length || refsIn.length) {\n var refInner = (refsOut.length ? '<div class=\"mdesc\"><b>References:</b></div>' + refsOut.map(function (e2) { return chip(e2.to + ' \\\\u00B7 ' + e2.field + ' [' + (e2.card || '1') + ']', 'type', e2.to); }).join('') : '')\n + (refsIn.length ? '<div class=\"mdesc\" style=\"margin-top:6px\"><b>Referenced by:</b></div>' + refsIn.map(function (e2) { return chip(e2.from + ' \\\\u00B7 ' + e2.field + ' [' + (e2.card || '1') + ']', 'type', e2.from); }).join('') : '');\n body += section('Relations', refsOut.length + refsIn.length, refInner, true);\n }\n var issT = issuesBySpec[ty.id];\n if (issT) body += section('Validation issues', issT.length, issueHtml(issT), true);\n }\n } else if (focusKind === 'subsystem' && subById[focusId]) {\n var s = subById[focusId];\n var subKids = childSubsOf(s.id).length + childCompsOf(s.id).length;\n head = '<h2>' + esc(s.name) + '</h2>' + staticChip('subsystem')\n + (s.targetLanguage ? staticChip(s.targetLanguage) : '')\n + (s.status ? staticChip(s.status) : '')\n + (scopeFocus ? staticChip('current view') : '')\n + (scopeFocus ? '' : openViewButton('subsystem', s.id, subKids > 0))\n + openApiButton(subsystemExposesApi(s.id), '');\n body += '<p class=\"desc\">' + esc(s.description) + '</p>';\n if (s.trustedLinks.length) {\n body += section('Trusted links (fast lanes)', s.trustedLinks.length, s.trustedLinks.map(function (t2) {\n return '<div class=\"method\">' + chip(t2.subsystem, 'subsystem', t2.subsystem) + '<div class=\"mdesc\">' + esc(t2.reason) + '</div></div>';\n }).join(''), true);\n }\n var subs2 = childSubsOf(s.id);\n if (subs2.length) body += section('Nested subsystems', subs2.length, subs2.map(function (s2) { return chip(s2.id, 'subsystem', s2.id); }).join(''), true);\n var comps = childCompsOf(s.id);\n body += section('Components', comps.length, comps.map(function (c2) { return chip(c2.id, 'component', c2.id); }).join(''), true);\n var iss2 = issuesBySpec[s.id];\n if (iss2) body += section('Validation issues', iss2.length, issueHtml(iss2), true);\n } else {\n head = '<h2>' + esc(MODEL.system.name) + '</h2>'\n + (MODEL.system.targetLanguage ? staticChip(MODEL.system.targetLanguage) : '')\n + staticChip(MODEL.subsystems.length + ' subsystems')\n + staticChip(MODEL.components.length + ' components')\n + (MODEL.types.length ? '<div class=\"openbtn\"><button class=\"tbtn\" id=\"openTypesBtn\">\\\\u25B8 Types (ERD) \\\\u2014 ' + MODEL.types.length + '</button></div>' : '')\n + openApiButton(projectExposesApi(), '');\n if (MODEL.system.vision) body += '<p class=\"desc\">' + esc(MODEL.system.vision) + '</p>';\n body += '<p class=\"desc\">Each view shows one scope\\\\u2019s direct children \\\\u2014 double-click a box (or use \\\\u201COpen as view\\\\u201D) to drill in, and the breadcrumb to come back. Derived from <code style=\"display:inline\">.wai/specs/</code>.</p>';\n if (state.showIssues && MODEL.issues.length) body += section('All validation issues', MODEL.issues.length, issueHtml(MODEL.issues), true);\n }\n panel.innerHTML = '<div class=\"head\">' + head + '</div><div class=\"body\">' + body + '</div>';\n\n var navs = panel.querySelectorAll('[data-kind]');\n for (var i = 0; i < navs.length; i++) {\n (function (n) {\n n.addEventListener('click', function () { select(n.getAttribute('data-kind'), n.getAttribute('data-id'), true); });\n n.addEventListener('mouseenter', function () {\n var node = nodeForRef(n.getAttribute('data-kind'), n.getAttribute('data-id'));\n if (node.length) node.addClass('hoverhl');\n });\n n.addEventListener('mouseleave', function () { cy.nodes().removeClass('hoverhl'); });\n })(navs[i]);\n }\n var opens = panel.querySelectorAll('[data-open-kind]');\n for (var k = 0; k < opens.length; k++) {\n (function (b) {\n b.addEventListener('click', function () { navigateTo(b.getAttribute('data-open-kind'), b.getAttribute('data-open-id')); });\n })(opens[k]);\n }\n var typesOpen = document.getElementById('openTypesBtn');\n if (typesOpen && typesOpen.addEventListener && panel.innerHTML.indexOf('openTypesBtn') >= 0) {\n typesOpen.addEventListener('click', function () { navigateTo('types', null); });\n }\n var oapis = panel.querySelectorAll('[data-openapi-tag]');\n for (var oi = 0; oi < oapis.length; oi++) {\n (function (b) {\n b.addEventListener('click', function () {\n var tag = b.getAttribute('data-openapi-tag') || '';\n if (typeof opts !== 'undefined' && opts && opts.onOpenApi) { opts.onOpenApi(tag); return; }\n var href = openApiSiblingHref();\n if (href) window.open(href + (tag ? '#/' + tag : ''), '_blank', 'noopener');\n });\n })(oapis[oi]);\n }\n var flows = panel.querySelectorAll('[data-flow-comp]');\n for (var j = 0; j < flows.length; j++) {\n (function (b) {\n b.addEventListener('click', function (ev) {\n if (ev && ev.stopPropagation) ev.stopPropagation();\n openFlow(b.getAttribute('data-flow-comp'), b.getAttribute('data-flow-method'), b.getAttribute('data-flow-mode') || 'flow');\n });\n })(flows[j]);\n }\n }\n\n renderPanel();\n})();\n</script>\n</body>\n</html>\n`;\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { createRequire } from 'module';\nimport { z } from 'zod';\nimport { readYamlFile } from '../utils/yaml.js';\nimport { getProjectRoot } from '../utils/fs.js';\nimport { loadProjectConfig } from '../config/loader.js';\nimport type { SddRule } from './rules/types.js';\nimport { RulesConfigSchema } from '../models/project.js';\n\n// ---------------------------------------------------------------------------\n// Extension packs — wairon's plugin surface.\n//\n// Wairon core defines the rule contract and the enforcement engine; platform-\n// specific profiles and rules are injected from outside so wrappers (e.g. an\n// automation-platform SDD tool) never fork core and core never learns about\n// their platform. Two pack forms, both listed in `.wai/project.yaml` under\n// `extensions.packs`:\n//\n// - Declarative YAML (path ending in .yaml/.yml, relative to project root):\n// custom profile definitions and language/platform tables. Data only.\n// - Programmatic JS (anything else — a requireable module id or relative\n// path): the same data plus `rules: SddRule[]` written against wairon's\n// exported rule API. Loaded via createRequire from the project root\n// (Node resolution semantics for module ids).\n//\n// Packs load identically in the CLI and the MCP server: validateSddTree\n// auto-loads them from project config unless the caller passes its own\n// LoadedExtensions (the programmatic-wrapper path). A pack that fails to\n// load becomes an EXTENSION_LOAD_ERROR issue — never a silent skip.\n// ---------------------------------------------------------------------------\n\n/**\n * A pack-defined architectural profile. `family` opts into the built-in\n * stereotype fencing (backend-like ⇒ frontend stereotypes are violations,\n * frontend-like ⇒ backend runtime stereotypes are warned); the explicit\n * stereotype lists carry the profile's own doctrine with a stated reason.\n */\nexport const ProfileDefSchema = z.object({\n family: z.enum(['backend-like', 'frontend-like', 'neutral']).default('neutral'),\n forbiddenStereotypes: z.array(z.object({ types: z.array(z.string()).min(1), reason: z.string().min(1) })).default([]),\n discouragedStereotypes: z.array(z.object({ types: z.array(z.string()).min(1), reason: z.string().min(1) })).default([]),\n /**\n * Edge deltas — the ALLOW half of the profile-scoped dependency matrix. An\n * entry LICENSES intra-subsystem dependsOn edges the builtin stereotype\n * matrix refuses, for components governed by this profile (the platform's\n * own idiom, e.g. an ECS system reading component Stores directly), with\n * the stated reason. Scoped to the stereotype matrix only: cross-subsystem\n * boundary rules and pattern containment are never relaxable. The DENY\n * half is a `forbid-edge` declarative assertion.\n */\n allowedEdges: z.array(z.object({\n from: z.array(z.string().min(1)).min(1),\n to: z.array(z.string().min(1)).min(1),\n reason: z.string().min(1),\n })).default([]),\n rules: RulesConfigSchema.partial().optional(),\n});\nexport type ProfileDef = z.infer<typeof ProfileDefSchema>;\n\n/**\n * A pack-defined target language/platform. `unsupportedFlow` maps a narrative\n * flow construct (branch | switch | forEach | for | while | doWhile | try |\n * throw | jump | parallel | detach) to remodeling guidance — merged over the\n * built-in table, so a\n * pack can gate constructs for its platform (warning severity: \"possible but\n * not clean\" is guidance, not prohibition). `foreignBuiltins` are builtin-type\n * markers unambiguous to THIS language, enabling the foreign-builtin check\n * both ways.\n */\nexport const LanguagePackDefSchema = z.object({\n unsupportedFlow: z.record(z.string()).default({}),\n foreignBuiltins: z.array(z.string()).default([]),\n});\nexport type LanguagePackDef = z.infer<typeof LanguagePackDefSchema>;\n\n/**\n * A declarative AI-agent skill shipped by a pack: a SKILL.md discovered relative\n * to the pack directory and installed (namespaced `<pack-id>-<skill-id>`) into\n * supported client targets and the MCP resource mirror. Not an MCP tool.\n */\nexport const PackSkillSchema = z.object({\n id: z.string().min(1),\n source: z.string().min(1),\n targets: z.array(z.string()).default([]),\n});\nexport type PackSkill = z.infer<typeof PackSkillSchema>;\n\n/**\n * A named, versioned reusable architecture pattern declared by a pack. Core\n * resolves references to it and surfaces it in tooling; the actual pattern\n * constraints are enforced by the pack's own programmatic rules.\n */\nexport const PatternDefSchema = z.object({\n id: z.string().min(1),\n version: z.string().min(1),\n description: z.string().optional(),\n metadata: z.record(z.unknown()).optional(),\n});\nexport type PatternDef = z.infer<typeof PatternDefSchema>;\n\n/**\n * Selector for declarative assertions (closed, v1): absent keys match all,\n * present keys AND together. `profile` matches the component's governing\n * profile — how a platform pack scopes doctrine to its own subsystems.\n * `id` is a simple glob (`*` wildcard only).\n */\nexport const AssertionSelectorSchema = z.object({\n componentType: z.array(z.string().min(1)).optional(),\n profile: z.array(z.string().min(1)).optional(),\n id: z.string().min(1).optional(),\n});\nexport type AssertionSelector = z.infer<typeof AssertionSelectorSchema>;\n\nconst assertionBase = {\n /** Pack-local code; surfaced namespaced as <PACK_NAME>_<CODE>. */\n code: z.string().min(1),\n severity: z.enum(['warning', 'error']).default('warning'),\n /** The doctrine, stated for the finding message. */\n reason: z.string().min(1),\n};\n\n/**\n * Declarative rule assertions (docs/design/declarative-rule-dsl.md): packs\n * add INSTANCES of closed assertion kinds, never rule logic — the hosted-safe\n * doctrine channel. An unknown `kind` fails the pack load loudly (an old\n * wairon must never silently not-enforce a newer pack's doctrine).\n */\nexport const PackAssertionSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('forbid-edge'),\n ...assertionBase,\n from: AssertionSelectorSchema,\n to: AssertionSelectorSchema,\n relation: z.array(z.enum(['dependsOn', 'owns'])).default(['dependsOn', 'owns']),\n }),\n z.object({\n kind: z.literal('require-field'),\n ...assertionBase,\n on: AssertionSelectorSchema,\n level: z.enum(['component', 'interface', 'implementation']).default('component'),\n /** A top-level spec field name, or one `ext.*` path — nothing else is addressable. */\n field: z.string().min(1),\n /** Optional closed value set (string equality). */\n values: z.array(z.string()).optional(),\n }),\n z.object({\n kind: z.literal('endpoint-shape'),\n ...assertionBase,\n on: AssertionSelectorSchema,\n /** Optional transport allowlist. */\n transport: z.array(z.string().min(1)).optional(),\n /** Optional anchored regex over the transport's address field (path/topic/command/…). */\n pathPattern: z.string().min(1).optional(),\n }),\n]);\nexport type PackAssertion = z.infer<typeof PackAssertionSchema>;\n\n/** A pack assertion tagged with provenance and its namespaced finding code. */\nexport type LoadedAssertion = PackAssertion & { pack: string; fullCode: string };\n\n/** <PACK_NAME>_<CODE>, upper-snake, non-alphanumerics collapsed — collision-free across packs, provenance legible in every finding. */\nexport function assertionFullCode(packName: string, code: string): string {\n const norm = (s: string): string => s.toUpperCase().replace(/[^A-Z0-9]+/g, '_').replace(/^_+|_+$/g, '');\n return `${norm(packName)}_${norm(code)}`;\n}\n\nexport const DeclarativePackSchema = z.object({\n name: z.string().min(1),\n version: z.string().optional(),\n profiles: z.record(ProfileDefSchema).default({}),\n languages: z.record(LanguagePackDefSchema).default({}),\n skills: z.array(PackSkillSchema).default([]),\n patterns: z.array(PatternDefSchema).default([]),\n /** Declarative rule assertions — instances of closed kinds, hosted-safe. */\n assertions: z.array(PackAssertionSchema).default([]),\n /**\n * Semantic guarantee tokens this pack adds to the builtin vocabulary\n * (SEMANTIC_GUARANTEES). Declaring a token makes it legal on L3 method\n * `guarantees` and narrative `assertsGuarantees`; referenced tokens outside\n * builtin + declared are flagged UNKNOWN_GUARANTEE by the validator.\n */\n guarantees: z.array(z.string().min(1)).default([]),\n});\nexport type DeclarativePack = z.infer<typeof DeclarativePackSchema>;\n\n/** A pack skill tagged with the pack that ships it (provenance for install + `skills list`) and the absolute path to its SKILL.md. */\nexport type LoadedPackSkill = PackSkill & { pack: string; packVersion?: string; sourcePath: string };\n/** A pack pattern definition tagged with the pack that declares it. */\nexport type LoadedPattern = PatternDef & { pack: string };\n\n/** Where a pack came from — global installs load before (and lose to) project packs. */\nexport type PackScope = 'global' | 'project';\n\nexport interface PackRef {\n ref: string;\n scope: PackScope;\n}\n\nexport interface LoadedExtensions {\n packNames: string[];\n /** Per-pack provenance (name, resolved ref, scope). */\n packs: { name: string; ref: string; scope: PackScope; version?: string }[];\n /** Programmatic rules, run after the built-in registry. */\n rules: SddRule[];\n /** Pack-registered profiles, keyed by profile id. */\n profiles: Record<string, ProfileDef>;\n /** Pack-registered language/platform tables, keyed by normalized language. */\n languages: Record<string, LanguagePackDef>;\n /** Pack-provided AI-agent skills across all loaded packs (with provenance). */\n skills: LoadedPackSkill[];\n /** Pack-registered reusable pattern definitions (with provenance). */\n patterns: LoadedPattern[];\n /** Pack-declared semantic guarantee tokens (merged, deduped) — the extension half of the guarantee vocabulary. */\n guarantees: string[];\n /** Declarative rule assertions across all loaded packs (with provenance + namespaced codes). */\n assertions: LoadedAssertion[];\n /** Pack loading failures — surfaced as EXTENSION_LOAD_ERROR (error). */\n errors: string[];\n}\n\nexport function emptyExtensions(): LoadedExtensions {\n return { packNames: [], packs: [], rules: [], profiles: {}, languages: {}, skills: [], patterns: [], guarantees: [], assertions: [], errors: [] };\n}\n\n// ---------------------------------------------------------------------------\n// Global packs — machine-wide installs, auto-loaded for every project.\n// ---------------------------------------------------------------------------\n\n/**\n * The global packs directory: WAIRON_PACKS_DIR or ~/.wairon/packs (same\n * convention as global templates). Every pack found here is loaded for every\n * project on this machine, BEFORE the project's own packs (so project packs\n * win on collision). A project can opt out via\n * `extensions.useGlobalPacks: false`. Note: repo-defining doctrine belongs\n * in project packs (committed, so CI and every clone enforce it); the global\n * folder is for personal/org-wide additions on this machine.\n */\nexport function globalPacksDir(): string {\n return process.env.WAIRON_PACKS_DIR ?? path.join(os.homedir(), '.wairon', 'packs');\n}\n\n/** Entry-file names that make a directory a pack. */\nexport const PACK_DIR_ENTRIES = ['pack.yaml', 'pack.yml', 'pack.cjs', 'pack.js', 'index.cjs', 'index.js'];\n\n/** The entry file of a directory pack, or null if the directory isn't one. */\nexport function packDirEntry(dir: string): string | null {\n for (const name of PACK_DIR_ENTRIES) {\n const p = path.join(dir, name);\n if (fs.existsSync(p)) return p;\n }\n return null;\n}\n\n/**\n * Pack refs discovered in a directory (used for the global packs folder):\n * *.yaml/*.yml/*.cjs/*.js files, and subdirectories containing a pack entry\n * file. Sorted for deterministic load order.\n */\nexport function discoverPacks(dir: string): string[] {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n const refs: string[] = [];\n for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n const full = path.join(dir, e.name);\n if (e.isDirectory()) {\n if (packDirEntry(full)) refs.push(full);\n } else if (/\\.(ya?ml|cjs|js)$/i.test(e.name)) {\n refs.push(full);\n }\n }\n return refs;\n}\n\nfunction isRuleShaped(r: unknown): r is SddRule {\n if (!r || typeof r !== 'object') return false;\n const c = r as Record<string, unknown>;\n return typeof c.name === 'string' && Array.isArray(c.codes) && typeof c.check === 'function';\n}\n\nfunction mergePack(out: LoadedExtensions, pack: DeclarativePack, ref: string, scope: PackScope, packDir: string): void {\n out.packNames.push(pack.name);\n out.packs.push({ name: pack.name, ref, scope, version: pack.version });\n // Later packs win on collision — pack order in project.yaml is precedence.\n Object.assign(out.profiles, pack.profiles);\n for (const [lang, def] of Object.entries(pack.languages)) {\n const key = lang.toLowerCase();\n const existing = out.languages[key];\n out.languages[key] = existing\n ? {\n unsupportedFlow: { ...existing.unsupportedFlow, ...def.unsupportedFlow },\n foreignBuiltins: [...new Set([...existing.foreignBuiltins, ...def.foreignBuiltins])],\n }\n : def;\n }\n // Skills and patterns are namespaced by pack id (skills at install time, pattern\n // ids by convention), so they accumulate across packs with their provenance.\n for (const s of pack.skills) out.skills.push({ ...s, pack: pack.name, packVersion: pack.version, sourcePath: path.resolve(packDir, s.source) });\n for (const p of pack.patterns) out.patterns.push({ ...p, pack: pack.name });\n // Guarantee tokens are a flat vocabulary — same token from two packs is one token.\n out.guarantees = [...new Set([...out.guarantees, ...pack.guarantees])];\n // Assertions accumulate with provenance; the namespaced code keeps packs collision-free.\n for (const a of pack.assertions) out.assertions.push({ ...a, pack: pack.name, fullCode: assertionFullCode(pack.name, a.code) });\n}\n\n/**\n * Load extension packs from scoped refs. Path-like refs (relative, absolute,\n * or *.yaml) resolve against the project root; a directory ref loads its\n * pack entry file; anything else resolves as a module id from the project\n * root (Node semantics).\n */\nconst isYamlPath = (p: string): boolean => /\\.ya?ml$/i.test(p);\n\n/**\n * Resolve a ref to a concrete load target: a path-like ref (relative, absolute,\n * or *.yaml) against the project root — a directory resolving to its pack entry\n * file (throwing when it has none) — otherwise a Node module id returned as-is\n * for resolution from the project root.\n */\nexport function resolvePackRef(ref: string, projectRoot: string): string {\n const pathLike = ref.startsWith('.') || path.isAbsolute(ref) || isYamlPath(ref);\n if (!pathLike) return ref;\n const resolved = path.resolve(projectRoot, ref);\n if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {\n const entry = packDirEntry(resolved);\n if (!entry) throw new Error(`directory pack has no entry file (${PACK_DIR_ENTRIES.join(' | ')})`);\n return entry;\n }\n return resolved;\n}\n\n/**\n * Read a resolved target's pack manifest, deserializing it into a DeclarativePack\n * (with any programmatic rules attached): a *.yaml/*.yml target is parsed as YAML\n * (throwing on a missing/empty file); any other target is required as a CommonJS\n * module from the project root and its default/module export used. A read/require/\n * parse failure propagates to the caller, which records an EXTENSION_LOAD_ERROR.\n */\nexport function readManifest(target: string, projectRoot: string): DeclarativePack & { rules: SddRule[] } {\n if (isYamlPath(target)) {\n const raw = readYamlFile(target);\n if (raw == null) throw new Error('file not found or empty');\n return { ...DeclarativePackSchema.parse(raw), rules: [] };\n }\n const req = createRequire(path.join(projectRoot, 'package.json'));\n const modRaw: unknown = req(target);\n const mod = ((modRaw as { default?: unknown })?.default ?? modRaw) as Record<string, unknown>;\n const parsed = DeclarativePackSchema.parse({\n name: mod.name ?? target,\n version: mod.version,\n profiles: mod.profiles ?? {},\n languages: mod.languages ?? {},\n skills: mod.skills ?? [],\n patterns: mod.patterns ?? [],\n guarantees: mod.guarantees ?? [],\n assertions: mod.assertions ?? [],\n });\n const rules: SddRule[] = [];\n for (const r of (mod.rules as unknown[] | undefined) ?? []) {\n if (!isRuleShaped(r)) throw new Error('each entry of `rules` must be an SddRule ({ name, description, codes, check })');\n rules.push(r);\n }\n return { ...parsed, rules };\n}\n\nexport function loadExtensionPacks(refs: PackRef[], projectRoot: string): LoadedExtensions {\n const out = emptyExtensions();\n for (const { ref, scope } of refs) {\n try {\n const target = resolvePackRef(ref, projectRoot);\n const manifest = readManifest(target, projectRoot);\n mergePack(out, manifest, ref, scope, path.dirname(target));\n for (const r of manifest.rules) out.rules.push(r);\n } catch (e) {\n out.errors.push(`Extension pack \"${ref}\" failed to load: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n return out;\n}\n\n/**\n * Load extension packs from plain refs (all project-scoped). The simple\n * programmatic API — see loadExtensionPacks for scoped loading.\n */\nexport function loadExtensions(packRefs: string[], projectRoot: string): LoadedExtensions {\n return loadExtensionPacks(packRefs.map(ref => ({ ref, scope: 'project' as const })), projectRoot);\n}\n\n/**\n * Load everything governing the current project: globally installed packs\n * (unless `extensions.useGlobalPacks: false`), then the packs declared in\n * the project's config — project packs win on collision. Used by\n * validateSddTree when the caller doesn't inject extensions explicitly;\n * an uninitialized project simply has none.\n */\nexport function loadProjectExtensions(): LoadedExtensions {\n try {\n const config = loadProjectConfig();\n const refs: PackRef[] = [];\n if (config.extensions?.useGlobalPacks ?? true) {\n for (const ref of discoverPacks(globalPacksDir())) refs.push({ ref, scope: 'global' });\n }\n for (const ref of config.extensions?.packs ?? []) refs.push({ ref, scope: 'project' });\n if (refs.length === 0) return emptyExtensions();\n return loadExtensionPacks(refs, getProjectRoot());\n } catch {\n return emptyExtensions();\n }\n}\n","import {\n SystemSpec,\n SubsystemSpec,\n ComponentSpec,\n InterfaceSpec,\n ImplementationSpec,\n TypeSpec,\n RulesConfig,\n SurfaceSnapshot,\n} from '../../models/index.js';\nimport type { ProfileDef, LanguagePackDef, LoadedPattern, LoadedAssertion } from '../extensions.js';\nimport type { VariantDef } from '../variants.js';\nimport type { CodeModel } from '../source-analysis.js';\n\n// ---------------------------------------------------------------------------\n// Rule registry contracts\n//\n// Every SDD conformance check is an SddRule: a named, documented unit with the\n// issue codes it can emit and a check(ctx) over the shared RuleContext. The\n// registry (rules/index.ts) runs them in order; severity resolution (user\n// overrides + draft-context downgrades) is centralized in ctx.addIssue.\n//\n// This is the \"custom linter\" foundation: adding a rule is a new module in\n// this directory plus a registry entry — no surgery on a monolith.\n// ---------------------------------------------------------------------------\n\nexport type Severity = 'error' | 'warning';\n\nexport interface RuleCode {\n code: string;\n defaultSeverity: Severity;\n summary: string;\n}\n\n/** The built-in architectural profiles; extension packs may register more. */\nexport const BUILTIN_PROFILES = [\n 'backend',\n 'frontend-reactive',\n 'frontend-controller',\n 'lowlevel-os',\n 'game-ecs',\n 'realtime-embedded',\n 'plc-cyclic',\n] as const;\n\n/**\n * A profile id — one of BUILTIN_PROFILES or a pack-registered name (open\n * string; UNKNOWN_PROFILE flags anything unregistered).\n */\nexport type ArchProfile = string;\n\nexport interface RuleContext {\n system: SystemSpec;\n subsystems: SubsystemSpec[];\n components: ComponentSpec[];\n interfaces: InterfaceSpec[];\n implementations: ImplementationSpec[];\n types: TypeSpec[];\n\n rules?: RulesConfig;\n projectType: string;\n scopeSubsystem?: string;\n\n componentMap: Map<string, ComponentSpec>;\n interfaceMap: Map<string, InterfaceSpec>;\n subsystemIds: Set<string>;\n componentIds: Set<string>;\n interfaceIds: Set<string>;\n /** Per-subsystem published component ids (its public surface). */\n publicSet: Map<string, Set<string>>;\n /** Interfaces grouped by owning component id — the shared read path for a component's contract methods (rules and the reachability walker must agree on this enumeration). */\n interfacesByComponent: Map<string, InterfaceSpec[]>;\n /** Stored surface snapshots (.wai/surfaces/) — declared contracts that unresolved cross-tree/remote references validate against. */\n surfaceSnapshots: SurfaceSnapshot[];\n /**\n * The pure source-code model (per-sourcePath declaration/export/import/\n * anchor facts) built by the source analysis adapter — what the\n * structural-conformance family checks realization against. Empty when the\n * context was built without one (the family then only reports missing\n * sourcePaths, never file-level findings).\n */\n codeModel: CodeModel;\n /** Implementations grouped by their contract interface id. */\n implementationsByContract: Map<string, ImplementationSpec[]>;\n\n /** True when the spec (or its ancestors) is in draft/design status. */\n isComponentDraft(compId: string): boolean;\n /** True when the implementation, its contract, or the contract's component is in draft/design status — the shared draft recipe for implementation-scoped findings. */\n isImplementationDraft(impl: ImplementationSpec): boolean;\n /** The architectural profile governing a component (subsystem override, else project type). */\n getComponentProfile(compId: string): ArchProfile;\n /** Whether a type reference resolves against builtins, generics, or defined types. */\n isTypeResolved(ref: string, generics: Set<string>): boolean;\n /** Effective target language for a subsystem (subsystem override, else system), lowercase, or undefined. */\n targetLanguageFor(subsystemId: string | undefined): string | undefined;\n /** Scope filter for granular (per-subsystem) validation. */\n isSpecInScope(specId: string): boolean;\n\n /**\n * Extension-pack data (empty when no packs are loaded): pack-registered\n * profiles, language/platform tables, and reusable pattern definitions.\n * Rules merge these over their built-in tables and resolve spec references\n * (component.patterns) against ext.patterns.\n */\n ext: {\n profiles: Record<string, ProfileDef>;\n languages: Record<string, LanguagePackDef>;\n patterns: LoadedPattern[];\n /** Pack-declared semantic guarantee tokens — unioned with SEMANTIC_GUARANTEES by the guarantee-token rule. */\n guarantees: string[];\n /** Declarative rule assertions (closed kinds, pack-instantiated) evaluated by the declarative-assertions rule. */\n assertions: LoadedAssertion[];\n };\n\n /**\n * Component-variant registry (the dynamic layer on top of packs; empty when\n * none): the resolution set for component.variant references — each a\n * base-anchored specialization carrying implementation guidance.\n */\n variants: VariantDef[];\n\n /**\n * Bookkeeping for per-spec lint suppressions (lint.allow). Suppression\n * itself happens inside addIssue (warnings only — errors always surface);\n * the lint-allows rule audits these entries at the end of the run.\n */\n lintAllows: { specId: string; code: string; reason: string; used: boolean }[];\n /** Every issue code any registered rule can emit (for allow validation). */\n knownIssueCodes: Set<string>;\n\n /**\n * Report an issue. Applies scope filtering, user severity overrides\n * (rules.sddRuleSeverity), and draft-context downgrades for completeness\n * rules. 'off' suppresses the issue entirely.\n */\n addIssue(\n defaultSeverity: Severity,\n code: string,\n message: string,\n specId?: string,\n isDraftContext?: boolean,\n ): void;\n}\n\nexport interface SddRule {\n /** Stable rule id (kebab-case), e.g. \"stereotype-dependencies\". */\n name: string;\n /** One-paragraph description of what the rule enforces and why. */\n description: string;\n /** Every issue code this rule can emit, with default severity and summary. */\n codes: RuleCode[];\n check(ctx: RuleContext): void;\n}\n","import { SddRule } from './types.js';\n\n/**\n * Tree integrity: every spec points at an existing parent, and draft/design\n * specs are surfaced as informational warnings.\n */\nexport const hierarchyRule: SddRule = {\n name: 'hierarchy-integrity',\n description:\n 'Every subsystem references the system, every component an existing subsystem, every interface an existing component, and every implementation an existing interface contract. Draft/design specs are reported informationally.',\n codes: [\n { code: 'DRAFT_SUBSYSTEM_WARNING', defaultSeverity: 'warning', summary: 'Subsystem is in draft/design status' },\n { code: 'DRAFT_COMPONENT_WARNING', defaultSeverity: 'warning', summary: 'Component is in draft/design status' },\n { code: 'ORPHANED_SUBSYSTEM', defaultSeverity: 'warning', summary: 'Subsystem does not reference the L0 system' },\n { code: 'INVALID_SUBSYSTEM_REFERENCE', defaultSeverity: 'error', summary: 'Reference to a non-existent subsystem' },\n { code: 'INVALID_COMPONENT_REFERENCE', defaultSeverity: 'error', summary: 'Interface references a non-existent component' },\n { code: 'INVALID_INTERFACE_REFERENCE', defaultSeverity: 'error', summary: 'Implementation references a non-existent interface contract' },\n ],\n check(ctx) {\n // Informational draft warnings\n for (const sub of ctx.subsystems) {\n if (sub.status === 'draft' || sub.status === 'design') {\n ctx.addIssue('warning', 'DRAFT_SUBSYSTEM_WARNING', `Subsystem \"${sub.id}\" is in draft/design status.`, sub.id, true);\n }\n }\n for (const comp of ctx.components) {\n if (ctx.isComponentDraft(comp.id)) {\n ctx.addIssue('warning', 'DRAFT_COMPONENT_WARNING', `Component \"${comp.id}\" is in draft/design status.`, comp.id, true);\n }\n }\n\n // Check subsystems reference parent system\n for (const sub of ctx.subsystems) {\n const isDraftCtx = sub.status === 'draft' || sub.status === 'design';\n if (!sub.parentSystem || (sub.parentSystem !== ctx.system.name && !sub.id.includes('::'))) {\n ctx.addIssue(\n 'warning',\n 'ORPHANED_SUBSYSTEM',\n `Subsystem \"${sub.id}\" does not reference system \"${ctx.system.name}\".`,\n sub.id,\n isDraftCtx,\n );\n }\n }\n\n // Check components reference existing subsystem\n for (const comp of ctx.components) {\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n if (!ctx.subsystemIds.has(comp.subsystem)) {\n ctx.addIssue(\n 'error',\n 'INVALID_SUBSYSTEM_REFERENCE',\n `Component \"${comp.id}\" references non-existent subsystem \"${comp.subsystem}\".`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n\n // Check interfaces reference existing component\n for (const intf of ctx.interfaces) {\n const isDraftCtx = ctx.isComponentDraft(intf.component) || intf.status === 'draft' || intf.status === 'design';\n if (!ctx.componentIds.has(intf.component)) {\n ctx.addIssue(\n 'error',\n 'INVALID_COMPONENT_REFERENCE',\n `Interface \"${intf.id}\" references non-existent component \"${intf.component}\".`,\n intf.id,\n isDraftCtx,\n );\n }\n }\n\n // Check implementations reference existing interface\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaces.find(i => i.id === impl.contract);\n const isDraftCtx = impl.status === 'draft' || impl.status === 'design' || (contract && (ctx.isComponentDraft(contract.component) || contract.status === 'draft' || contract.status === 'design'));\n if (!ctx.interfaceIds.has(impl.contract)) {\n ctx.addIssue(\n 'error',\n 'INVALID_INTERFACE_REFERENCE',\n `Implementation \"${impl.id}\" references non-existent interface contract \"${impl.contract}\".`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n },\n};\n","import { SddRule } from './types.js';\nimport {\n BUILTIN_TYPES,\n extractTypeIdentifiers,\n extractGenericTypeVariables,\n extractTypeGenerics,\n methodTypeRefs,\n matchTypeRef,\n} from './type-analysis.js';\n\n/**\n * Types are defined once and referenced everywhere: every type mentioned in a\n * type field or an interface method signature must resolve to a builtin, a\n * generic parameter in scope, or a defined TypeSpec.\n */\nexport const typeReferencesRule: SddRule = {\n name: 'type-references',\n description:\n 'Type fields and interface method signatures may only reference builtins, in-scope generic parameters, or defined entity/value-object types. Types owned by a subsystem must reference an existing subsystem.',\n codes: [\n { code: 'INVALID_SUBSYSTEM_REFERENCE', defaultSeverity: 'error', summary: 'Type references a non-existent owning subsystem' },\n { code: 'UNDEFINED_TYPE_REFERENCE', defaultSeverity: 'error', summary: 'Reference to a type that is not defined anywhere' },\n { code: 'HOLLOW_TYPE', defaultSeverity: 'warning', summary: 'Type declares no fields and no methods — a placeholder that informs neither implementers nor the ERD' },\n ],\n check(ctx) {\n // Check types reference existing subsystem and resolve fields\n for (const t of ctx.types) {\n const sub = ctx.subsystems.find(s => s.id === t.subsystem);\n const isDraftCtx = sub ? (sub.status === 'draft' || sub.status === 'design') : false;\n if (t.subsystem && !ctx.subsystemIds.has(t.subsystem)) {\n ctx.addIssue(\n 'error',\n 'INVALID_SUBSYSTEM_REFERENCE',\n `Type \"${t.id}\" references non-existent subsystem \"${t.subsystem}\".`,\n t.id,\n isDraftCtx,\n );\n }\n\n // A type with neither fields nor methods carries a name and nothing\n // else — it can't inform implementers, can't participate in the ERD,\n // and usually marks a post-hoc \"make validation pass\" placeholder.\n if ((!t.fields || t.fields.length === 0) && (!t.methods || t.methods.length === 0)) {\n ctx.addIssue(\n 'warning',\n 'HOLLOW_TYPE',\n `Type \"${t.id}\" (${t.kind}) declares no fields and no methods. Fill in the shape it actually models, or delete it.`,\n t.id,\n isDraftCtx,\n );\n }\n\n if (t.fields) {\n const typeGenerics = new Set(\n Array.from(extractTypeGenerics(t.name)).map(g => g.toLowerCase()),\n );\n for (const field of t.fields) {\n const refs = extractTypeIdentifiers(field.type);\n for (const ref of refs) {\n const refLower = ref.toLowerCase();\n if (BUILTIN_TYPES.has(refLower)) {\n continue;\n }\n if (typeGenerics.has(refLower)) {\n continue;\n }\n const resolved = ctx.types.find(spec => {\n const typeQualifiedId = spec.subsystem && !spec.id.startsWith(`${spec.subsystem}::`)\n ? `${spec.subsystem}::${spec.id}`\n : spec.id;\n return matchTypeRef(ref, typeQualifiedId);\n });\n if (!resolved) {\n ctx.addIssue(\n 'error',\n 'UNDEFINED_TYPE_REFERENCE',\n `Type \"${t.id}\" field \"${field.name}\" references undefined type \"${ref}\" in \"${field.type}\".`,\n t.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n }\n\n // Interface method signature type references\n for (const intf of ctx.interfaces) {\n const isDraftCtx = ctx.isComponentDraft(intf.component) || intf.status === 'draft' || intf.status === 'design';\n const interfaceGenerics = new Set(\n Array.from(extractTypeGenerics(intf.name)).map(g => g.toLowerCase()),\n );\n for (const m of intf.methods) {\n const methodGenerics = new Set(\n Array.from(extractGenericTypeVariables(m.signature)).map(g => g.toLowerCase()),\n );\n const allGenerics = new Set([...interfaceGenerics, ...methodGenerics]);\n const refs = methodTypeRefs(m);\n for (const ref of refs) {\n if (!ctx.isTypeResolved(ref, allGenerics)) {\n ctx.addIssue(\n 'error',\n 'UNDEFINED_TYPE_REFERENCE',\n `Method \"${m.name}\" on interface \"${intf.id}\" references undefined type \"${ref}\" in signature.`,\n intf.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n },\n};\n","import * as crypto from 'crypto';\nimport {\n loadSystemSpec,\n loadSubsystemSpecs,\n loadComponentSpecs,\n loadInterfaceSpecs,\n loadImplementationSpecs,\n loadTypeSpecs,\n} from './specs.js';\n\n// ---------------------------------------------------------------------------\n// State Hash Specialist (sdd_host / sdd_core)\n//\n// Computes the deterministic content identity (StateId) of the current\n// project's spec tree. Two trees with identical spec CONTENT produce the same\n// StateId; any edit changes it. This backs the commit-scoped lock record and\n// the promote-time re-check: a lock is scoped to the StateId it validated, and\n// promotion recomputes it, so any change after locking auto-invalidates the\n// lock. Volatile metadata (createdAt/updatedAt) is excluded so a no-op re-save\n// that only bumps a timestamp does not shift the identity.\n// ---------------------------------------------------------------------------\n\nexport interface StateId {\n algorithm: string;\n digest: string;\n}\n\n/** Deterministic StateId over the current (request-scoped) project's spec tree. */\nexport function computeStateId(): StateId {\n const tree = {\n system: loadSystemSpec(),\n subsystems: loadSubsystemSpecs(),\n components: loadComponentSpecs(),\n interfaces: loadInterfaceSpecs(),\n implementations: loadImplementationSpecs(),\n types: loadTypeSpecs(),\n };\n const digest = crypto.createHash('sha256').update(canonicalize(tree)).digest('hex');\n return { algorithm: 'sha256', digest };\n}\n\n/** True when two StateIds identify the same spec-tree content. */\nexport function stateIdEquals(a: StateId | null | undefined, b: StateId | null | undefined): boolean {\n return !!a && !!b && a.algorithm === b.algorithm && a.digest === b.digest;\n}\n\n/** Stable serialization: object keys sorted recursively (so key/formatting\n * order never changes the digest), with volatile timestamps stripped. */\nfunction canonicalize(value: unknown): string {\n return JSON.stringify(sortKeys(value));\n}\n\nfunction sortKeys(v: unknown): unknown {\n if (Array.isArray(v)) return v.map(sortKeys);\n if (v && typeof v === 'object') {\n const src = v as Record<string, unknown>;\n const out: Record<string, unknown> = {};\n for (const k of Object.keys(src).sort()) {\n if (k === 'createdAt' || k === 'updatedAt') continue; // volatile metadata\n out[k] = sortKeys(src[k]);\n }\n return out;\n }\n return v;\n}\n","import * as yaml from 'js-yaml';\nimport {\n MethodSignature,\n SurfaceContractEntry,\n SurfaceSnapshot,\n SurfaceSnapshotSchema,\n SurfaceTypeDef,\n} from '../models/index.js';\n\n// ---------------------------------------------------------------------------\n// OpenAPI 3.1 codec (openapi_codec) — the first surface-exchange format.\n// Export: a snapshot's HTTP-transport entries become an OpenAPI document,\n// the embedded type closure becomes JSON-Schema components. Import: a\n// 3rd-party OpenAPI document becomes an authored-origin snapshot, so a\n// bespoke external API is validated like any declared surface instead of\n// being trusted as prose.\n// ---------------------------------------------------------------------------\n\nconst PRIMITIVES: Record<string, { type: string; format?: string }> = {\n string: { type: 'string' },\n number: { type: 'number' },\n float: { type: 'number' },\n decimal: { type: 'number' },\n int: { type: 'integer' },\n integer: { type: 'integer' },\n boolean: { type: 'boolean' },\n bool: { type: 'boolean' },\n date: { type: 'string', format: 'date-time' },\n datetime: { type: 'string', format: 'date-time' },\n uuid: { type: 'string', format: 'uuid' },\n json: { type: 'object' },\n object: { type: 'object' },\n any: {} as { type: string },\n unknown: {} as { type: string },\n void: {} as { type: string },\n};\n\n/** Map a wairon type ref to a JSON-Schema fragment ($ref into components for closure types). */\nfunction schemaFor(typeRef: string, closureIds: Set<string>): Record<string, unknown> {\n const trimmed = typeRef.trim().replace(/^promise\\s*<(.+)>$/i, '$1').trim();\n const arrayMatch = /^(.+)\\[\\]$/.exec(trimmed);\n if (arrayMatch) {\n return { type: 'array', items: schemaFor(arrayMatch[1], closureIds) };\n }\n const lower = trimmed.toLowerCase();\n if (lower in PRIMITIVES) {\n const p = PRIMITIVES[lower];\n return p.type ? { ...p } : {};\n }\n // Closure types match by local segment (billing.Invoice / billing::invoice → invoice).\n const local = trimmed.split(/::|\\./).pop()!.toLowerCase().replace(/[^a-z0-9_-]/g, '');\n const hit = [...closureIds].find(id => id.toLowerCase() === local);\n if (hit) return { $ref: `#/components/schemas/${hit}` };\n return { type: 'object', description: `Unresolved type: ${trimmed}` };\n}\n\nfunction operationFor(method: MethodSignature, closureIds: Set<string>): Record<string, unknown> {\n const endpoint = method.endpoint;\n const httpVerb = endpoint && endpoint.transport === 'HTTP' ? endpoint.method.toLowerCase() : 'post';\n const bodyVerbs = new Set(['post', 'put', 'patch']);\n const params = method.params ?? [];\n\n const op: Record<string, unknown> = {\n operationId: method.name,\n summary: method.description,\n responses: {\n '200': {\n description: method.returns || 'Success',\n ...(method.returns && method.returns.toLowerCase() !== 'void'\n ? { content: { 'application/json': { schema: schemaFor(method.returns, closureIds) } } }\n : {}),\n },\n },\n };\n if (method.guarantees?.length) op['x-wairon-guarantees'] = method.guarantees;\n if (method.effect) op['x-wairon-effect'] = method.effect;\n // Opaque pack/tool extension data — emitted verbatim so the OpenAPI form\n // round-trips everything the native YAML snapshot preserves.\n if (method.ext && Object.keys(method.ext).length) op['x-wairon-ext'] = method.ext;\n\n if (params.length) {\n if (bodyVerbs.has(httpVerb)) {\n op.requestBody = {\n required: true,\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: Object.fromEntries(params.map(p => [p.name, schemaFor(p.type, closureIds)])),\n required: params.filter(p => !p.optional).map(p => p.name),\n },\n },\n },\n };\n } else {\n op.parameters = params.map(p => ({\n name: p.name,\n in: 'query',\n required: !p.optional,\n ...(p.description ? { description: p.description } : {}),\n schema: schemaFor(p.type, closureIds),\n }));\n }\n }\n return op;\n}\n\nexport function toOpenApi(snapshot: SurfaceSnapshot): string {\n const closureIds = new Set(snapshot.types.map(t => t.id));\n const httpEntries = snapshot.interfaces.filter(e =>\n e.type === 'REST' || e.methods.some(m => m.endpoint?.transport === 'HTTP'));\n\n const paths: Record<string, Record<string, unknown>> = {};\n for (const entry of httpEntries) {\n for (const method of entry.methods) {\n const endpoint = method.endpoint;\n if (!endpoint || endpoint.transport !== 'HTTP') continue;\n const p = endpoint.path.startsWith('/') ? endpoint.path : `/${endpoint.path}`;\n paths[p] = paths[p] ?? {};\n paths[p][endpoint.method.toLowerCase()] = {\n tags: [entry.id],\n ...operationFor(method, closureIds),\n };\n }\n }\n\n const schemas: Record<string, unknown> = {};\n for (const t of snapshot.types) {\n schemas[t.id] = {\n type: 'object',\n title: t.name,\n properties: Object.fromEntries(t.fields.map(f => [f.name, schemaFor(f.type, closureIds)])),\n required: t.fields.filter(f => !f.optional).map(f => f.name),\n };\n }\n\n const doc = {\n openapi: '3.1.0',\n info: {\n title: snapshot.projectName,\n version: snapshot.version ?? '0.0.0',\n ...(snapshot.stateId ? { 'x-wairon-state-id': snapshot.stateId } : {}),\n 'x-wairon-origin': snapshot.origin,\n 'x-wairon-generated-at': snapshot.generatedAt,\n },\n paths,\n ...(Object.keys(schemas).length ? { components: { schemas } } : {}),\n };\n return JSON.stringify(doc, null, 2);\n}\n\n// ---------------------------------------------------------------------------\n// Import\n// ---------------------------------------------------------------------------\n\nexport function isOpenApiDocument(body: string): boolean {\n try {\n const parsed = yaml.load(body) as Record<string, unknown> | null;\n return !!parsed && typeof parsed === 'object' && typeof (parsed as { openapi?: unknown }).openapi === 'string';\n } catch {\n return false;\n }\n}\n\nfunction typeRefFromSchema(schema: Record<string, unknown> | undefined): string {\n if (!schema) return 'json';\n const ref = schema.$ref;\n if (typeof ref === 'string') return ref.split('/').pop() ?? 'json';\n if (schema.type === 'array') {\n return `${typeRefFromSchema(schema.items as Record<string, unknown>)}[]`;\n }\n const t = schema.type;\n if (t === 'integer') return 'int';\n if (typeof t === 'string' && t !== 'object') return t;\n return 'json';\n}\n\nexport function fromOpenApi(document: string, projectName: string): SurfaceSnapshot {\n let parsed: Record<string, unknown>;\n try {\n parsed = yaml.load(document) as Record<string, unknown>;\n } catch (e) {\n throw new Error(`Invalid surface document: not parseable as JSON/YAML (${e instanceof Error ? e.message : String(e)})`);\n }\n if (!parsed || typeof parsed !== 'object' || typeof parsed.openapi !== 'string' || typeof parsed.paths !== 'object') {\n throw new Error('Invalid surface document: missing OpenAPI \"openapi\"/\"paths\" structure.');\n }\n\n const info = (parsed.info ?? {}) as Record<string, unknown>;\n const methods: MethodSignature[] = [];\n for (const [rawPath, ops] of Object.entries(parsed.paths as Record<string, Record<string, unknown>>)) {\n for (const [verb, opRaw] of Object.entries(ops ?? {})) {\n if (!['get', 'post', 'put', 'delete', 'patch', 'options', 'head'].includes(verb)) continue;\n const op = (opRaw ?? {}) as Record<string, unknown>;\n const name = typeof op.operationId === 'string' && /^[a-zA-Z0-9_]+$/.test(op.operationId)\n ? op.operationId\n : `${verb}_${rawPath.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '')}`;\n\n const params: { name: string; type: string; optional?: boolean; description?: string }[] = [];\n for (const p of (op.parameters as Record<string, unknown>[] | undefined) ?? []) {\n if (typeof p.name !== 'string') continue;\n params.push({\n name: p.name,\n type: typeRefFromSchema(p.schema as Record<string, unknown>),\n ...(p.required === true ? {} : { optional: true }),\n ...(typeof p.description === 'string' ? { description: p.description } : {}),\n });\n }\n const bodySchema = ((op.requestBody as Record<string, unknown>)?.content as Record<string, Record<string, unknown>>)?.['application/json']?.schema as Record<string, unknown> | undefined;\n if (bodySchema) {\n const props = (bodySchema.properties ?? {}) as Record<string, Record<string, unknown>>;\n const required = new Set((bodySchema.required as string[] | undefined) ?? []);\n if (Object.keys(props).length) {\n for (const [pname, pschema] of Object.entries(props)) {\n params.push({ name: pname, type: typeRefFromSchema(pschema), ...(required.has(pname) ? {} : { optional: true }) });\n }\n } else {\n params.push({ name: 'body', type: typeRefFromSchema(bodySchema) });\n }\n }\n\n const okResponse = ((op.responses as Record<string, Record<string, unknown>>)?.['200']\n ?? (op.responses as Record<string, Record<string, unknown>>)?.['201']) as Record<string, unknown> | undefined;\n const responseSchema = ((okResponse?.content as Record<string, Record<string, unknown>>)?.['application/json']?.schema) as Record<string, unknown> | undefined;\n const returns = responseSchema ? typeRefFromSchema(responseSchema) : 'void';\n\n // Read back the x-wairon-* keys toOpenApi emits, so an OpenAPI-format\n // exchange preserves the same contract the native YAML snapshot does.\n // All three are optional: documents from other producers simply lack\n // them, and a malformed value is ignored rather than failing the import.\n const rawGuarantees = op['x-wairon-guarantees'];\n const guarantees = Array.isArray(rawGuarantees)\n ? rawGuarantees.filter((g): g is string => typeof g === 'string' && g.length > 0)\n : [];\n const rawEffect = op['x-wairon-effect'];\n const effect = rawEffect === 'read' || rawEffect === 'write' ? rawEffect : undefined;\n // Opaque by doctrine — preserved verbatim, never validated beyond \"is a map\".\n const rawExt = op['x-wairon-ext'];\n const ext = rawExt && typeof rawExt === 'object' && !Array.isArray(rawExt)\n ? (rawExt as Record<string, unknown>)\n : undefined;\n\n methods.push({\n name,\n description: typeof op.summary === 'string' ? op.summary : (typeof op.description === 'string' ? op.description : name),\n signature: `${name}(${params.map(p => `${p.name}: ${p.type}`).join(', ')}): ${returns}`,\n returns,\n params,\n endpoint: { transport: 'HTTP', method: verb.toUpperCase() as 'GET', path: rawPath },\n ...(guarantees.length ? { guarantees } : {}),\n ...(effect ? { effect } : {}),\n ...(ext ? { ext } : {}),\n });\n }\n }\n\n const types: SurfaceTypeDef[] = [];\n const schemas = ((parsed.components as Record<string, unknown>)?.schemas ?? {}) as Record<string, Record<string, unknown>>;\n for (const [id, schema] of Object.entries(schemas)) {\n const props = (schema.properties ?? {}) as Record<string, Record<string, unknown>>;\n const required = new Set((schema.required as string[] | undefined) ?? []);\n types.push({\n id,\n name: typeof schema.title === 'string' ? schema.title : id,\n kind: 'value-object',\n fields: Object.entries(props).map(([fname, fschema]) => ({\n name: fname,\n type: typeRefFromSchema(fschema),\n ...(required.has(fname) ? {} : { optional: true }),\n })),\n });\n }\n\n const entry: SurfaceContractEntry = {\n id: `${projectName}-api`,\n name: typeof info.title === 'string' ? info.title : projectName,\n audience: 'external',\n type: 'REST',\n component: `${projectName}-api`,\n methods,\n details: typeof info.description === 'string' ? info.description : `Imported OpenAPI surface of ${projectName}.`,\n ...(typeof info.version === 'string' ? { version: info.version } : {}),\n };\n\n return SurfaceSnapshotSchema.parse({\n projectName,\n origin: 'authored',\n ...(typeof info.version === 'string' ? { version: info.version } : {}),\n generatedAt: new Date().toISOString(),\n interfaces: [entry],\n types,\n });\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { getProjectRoot } from '../utils/fs.js';\nimport { readYamlFile, writeYamlFile } from '../utils/yaml.js';\nimport {\n SurfaceSnapshot,\n SurfaceSnapshotSchema,\n SurfaceContractEntry,\n SurfaceTypeDef,\n SurfaceOrigin,\n SURFACE_AUDIENCES,\n SystemPublicInterface,\n TypeSpec,\n} from '../models/index.js';\nimport {\n loadSystemSpec,\n loadSubsystemSpecs,\n loadComponentSpecs,\n loadInterfaceSpecs,\n loadTypeSpecs,\n} from './specs.js';\nimport { computeStateId } from './statehash.js';\nimport { extractTypeIdentifiers, matchTypeRef, methodTypeRefs, BUILTIN_TYPES } from './rules/type-analysis.js';\nimport { fromOpenApi, isOpenApiDocument, toOpenApi } from './openapi.js';\nimport type { ValidationIssue } from './validation.js';\n\n// ---------------------------------------------------------------------------\n// Public Surface Exchange (sdd_surfaces)\n//\n// Contract-grade, portable public-surface snapshots. One artifact, three\n// origins: generated (own family — written into chained children), exchanged\n// (another wairon project), authored (an external 3rd-party system, declared\n// by hand or imported from OpenAPI). The core semantic of the whole feature:\n// an Adapter consumes a DECLARED surface — org governance layers on top.\n// ---------------------------------------------------------------------------\n\nconst SURFACES_DIRNAME = 'surfaces';\n\nfunction surfacesDir(rootDir: string): string {\n return path.join(rootDir, '.wai', SURFACES_DIRNAME);\n}\n\n/** Ascending reach rank of an audience level; unknown levels rank as 'instance'. */\nexport function audienceRank(audience: string | undefined): number {\n const idx = (SURFACE_AUDIENCES as readonly string[]).indexOf(audience ?? 'instance');\n return idx === -1 ? (SURFACE_AUDIENCES as readonly string[]).indexOf('instance') : idx;\n}\n\nexport function stateIdString(): string {\n const s = computeStateId();\n return `${s.algorithm}:${s.digest}`;\n}\n\n// ---------------------------------------------------------------------------\n// Projection (surface_projector)\n// ---------------------------------------------------------------------------\n\n/**\n * Transitive type closure: every type reachable from the exported method\n * signatures (params + returns), following field type references. The\n * snapshot must be self-contained — types are the one sanctioned\n * cross-boundary \"internal\", so a consumer's type resolution has to work\n * without the producing tree.\n */\nfunction computeTypeClosure(entries: SurfaceContractEntry[], types: TypeSpec[]): SurfaceTypeDef[] {\n const included = new Map<string, TypeSpec>();\n const queue: string[] = [];\n\n const enqueueRef = (ref: string): void => {\n if (BUILTIN_TYPES.has(ref.toLowerCase())) return;\n for (const spec of types) {\n const qualifiedId = spec.subsystem && !spec.id.startsWith(`${spec.subsystem}::`)\n ? `${spec.subsystem}::${spec.id}`\n : spec.id;\n if (matchTypeRef(ref, qualifiedId) && !included.has(spec.id)) {\n included.set(spec.id, spec);\n queue.push(spec.id);\n }\n }\n };\n\n for (const entry of entries) {\n for (const m of entry.methods) {\n for (const ref of methodTypeRefs(m)) enqueueRef(ref);\n }\n }\n while (queue.length) {\n const spec = included.get(queue.shift()!)!;\n for (const field of spec.fields) {\n for (const ref of extractTypeIdentifiers(field.type)) enqueueRef(ref);\n }\n }\n\n return [...included.values()].map(t => ({\n id: t.id,\n name: t.name,\n kind: t.kind,\n fields: t.fields.map(f => ({\n name: f.name,\n type: f.type,\n ...(f.description ? { description: f.description } : {}),\n ...(f.optional ? { optional: true } : {}),\n })),\n }));\n}\n\n/**\n * Project the own tree's L0 gateway surface into a contract-grade snapshot.\n * `maxAudience` is the consumer's distance class: an entry is included when\n * its declared reach covers that distance (rank(entry) >= rank(maxAudience)).\n * The family ceiling 'project' therefore includes everything.\n */\nexport function projectOwnSurface(maxAudience: string): SurfaceSnapshot {\n const system = loadSystemSpec();\n if (!system) {\n throw new Error('Cannot project a surface: the L0 system spec is missing.');\n }\n const subsystems = loadSubsystemSpecs();\n const components = loadComponentSpecs();\n const interfaces = loadInterfaceSpecs();\n const types = loadTypeSpecs();\n\n const floor = audienceRank(maxAudience);\n const rawEntries: SystemPublicInterface[] = system.publicInterfaces ?? [];\n\n const entries: SurfaceContractEntry[] = [];\n for (const raw of rawEntries) {\n const audience = raw.audience ?? 'instance';\n if (audienceRank(audience) < floor) continue;\n if (!raw.component) continue; // unbound gateway entries cannot be exported\n\n const comp = components.find(c => c.id === raw.component);\n if (!comp) continue;\n const compInterfaces = interfaces.filter(i =>\n i.component === comp.id && (!raw.interface || i.id === raw.interface));\n const methods = compInterfaces.flatMap(i => i.methods);\n\n const subsystemType = subsystems\n .find(s => s.id === comp.subsystem)?.publicInterfaces\n .find(pi => pi.component === comp.id)?.type;\n\n entries.push({\n id: raw.id ?? raw.interface ?? comp.id,\n name: raw.name ?? comp.name,\n audience,\n type: raw.type ?? subsystemType ?? 'Custom',\n component: comp.id,\n methods,\n ...(comp.dispatch && comp.dispatch.length ? { dispatch: comp.dispatch } : {}),\n details: raw.details ?? '',\n ...(raw.version ? { version: raw.version } : {}),\n ...(raw.stability ? { stability: raw.stability } : {}),\n });\n }\n\n return SurfaceSnapshotSchema.parse({\n projectName: system.name,\n origin: 'generated',\n stateId: stateIdString(),\n generatedAt: new Date().toISOString(),\n interfaces: entries,\n types: computeTypeClosure(entries, types),\n });\n}\n\n/** The parent surface a chained child may see — the family ceiling includes project-audience entries. */\nexport function projectChildSurface(): SurfaceSnapshot {\n return projectOwnSurface('project');\n}\n\n// ---------------------------------------------------------------------------\n// Stored snapshots (surface_repository over .wai/surfaces/)\n// ---------------------------------------------------------------------------\n\nexport function listSnapshots(rootDir: string = getProjectRoot()): SurfaceSnapshot[] {\n const dir = surfacesDir(rootDir);\n if (!fs.existsSync(dir)) return [];\n const out: SurfaceSnapshot[] = [];\n for (const file of fs.readdirSync(dir)) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;\n try {\n out.push(SurfaceSnapshotSchema.parse(readYamlFile(path.join(dir, file))));\n } catch {\n // A malformed snapshot never aborts the read — it is simply not available.\n }\n }\n return out;\n}\n\nexport function getSnapshot(projectName: string, rootDir: string = getProjectRoot()): SurfaceSnapshot | null {\n return listSnapshots(rootDir).find(s => s.projectName === projectName) ?? null;\n}\n\nexport function saveSnapshot(snapshot: SurfaceSnapshot, rootDir: string = getProjectRoot()): string {\n const dir = surfacesDir(rootDir);\n fs.mkdirSync(dir, { recursive: true });\n const p = path.join(dir, `${snapshot.projectName}.yaml`);\n writeYamlFile(p, SurfaceSnapshotSchema.parse(snapshot));\n return p;\n}\n\nexport function removeSnapshot(projectName: string, rootDir: string = getProjectRoot()): boolean {\n const p = path.join(surfacesDir(rootDir), `${projectName}.yaml`);\n if (!fs.existsSync(p)) return false;\n fs.unlinkSync(p);\n return true;\n}\n\n/** Validator-facing load (validator_surfaces_adapter realization). */\nexport function loadSurfaceSnapshots(): SurfaceSnapshot[] {\n return listSnapshots();\n}\n\n// ---------------------------------------------------------------------------\n// Exchange workflows (surface_orchestrator)\n// ---------------------------------------------------------------------------\n\nexport interface SurfaceExportResult {\n snapshot: SurfaceSnapshot;\n /** Rendered document body when format was openapi. */\n rendered?: string;\n /** Written output path when one was requested. */\n writtenTo?: string;\n}\n\nexport function exportSurface(maxAudience: string, format: string, outPath?: string): SurfaceExportResult {\n const snapshot = projectOwnSurface(maxAudience);\n const rendered = format === 'openapi' ? toOpenApi(snapshot) : undefined;\n let writtenTo: string | undefined;\n if (outPath) {\n fs.mkdirSync(path.dirname(path.resolve(outPath)), { recursive: true });\n if (rendered !== undefined) {\n fs.writeFileSync(path.resolve(outPath), rendered);\n } else {\n writeYamlFile(path.resolve(outPath), snapshot);\n }\n writtenTo = path.resolve(outPath);\n }\n return { snapshot, ...(rendered !== undefined ? { rendered } : {}), ...(writtenTo ? { writtenTo } : {}) };\n}\n\nexport function importSurface(sourcePath: string, origin: SurfaceOrigin): SurfaceSnapshot {\n const resolved = path.resolve(sourcePath);\n if (!fs.existsSync(resolved)) {\n throw new Error(`Surface document not found: ${resolved}`);\n }\n const body = fs.readFileSync(resolved, 'utf8');\n\n let snapshot: SurfaceSnapshot;\n if (isOpenApiDocument(body)) {\n const projectName = path.basename(resolved).replace(/\\.(json|ya?ml)$/i, '');\n snapshot = fromOpenApi(body, projectName);\n snapshot = { ...snapshot, origin };\n } else {\n snapshot = SurfaceSnapshotSchema.parse(readYamlFile(resolved));\n snapshot = { ...snapshot, origin };\n }\n saveSnapshot(snapshot);\n return snapshot;\n}\n\n/**\n * Write the family-scoped parent surface into every chained child project's\n * .wai/surfaces/, so children can validate cross-tree references standalone.\n */\nexport function generateChildSnapshots(rootDir: string = getProjectRoot()): string[] {\n const children = loadSubsystemSpecs().filter(s => s.projectPath && !s.id.includes('::'));\n if (!children.length) return [];\n const snapshot = projectChildSurface();\n const written: string[] = [];\n for (const child of children) {\n const childDir = path.resolve(rootDir, child.projectPath!);\n if (!fs.existsSync(childDir)) continue;\n written.push(saveSnapshot(snapshot, childDir));\n }\n return written;\n}\n\n// ---------------------------------------------------------------------------\n// Freshness (SURFACE_STALE) — computable exactly where both sides are visible:\n// validating from the parent, each chained child's stored parent-snapshot can\n// be compared against the parent's CURRENT StateId.\n// ---------------------------------------------------------------------------\n\n/** Snapshot content minus provenance — what staleness is actually about. */\nfunction surfaceContentKey(snapshot: SurfaceSnapshot): string {\n const { stateId, generatedAt, origin, ...content } = snapshot;\n return JSON.stringify(content);\n}\n\nexport function checkChildSurfaceFreshness(rootDir: string = getProjectRoot()): ValidationIssue[] {\n const system = loadSystemSpec();\n if (!system) return [];\n const children = loadSubsystemSpecs().filter(s => s.projectPath && !s.id.includes('::'));\n if (!children.length) return [];\n\n // Compare CONTENT, not tree StateIds: a child editing its own specs shifts\n // the recursive StateId without changing the parent's exported contracts,\n // and that must not read as staleness.\n const current = surfaceContentKey(projectChildSurface());\n const issues: ValidationIssue[] = [];\n for (const child of children) {\n const childDir = path.resolve(rootDir, child.projectPath!);\n const held = getSnapshot(system.name, childDir);\n if (!held || held.origin !== 'generated') continue;\n if (surfaceContentKey(held) !== current) {\n issues.push({\n severity: 'warning',\n code: 'SURFACE_STALE',\n message: `Chained child \"${child.id}\" holds a parent surface snapshot whose contracts no longer match the current tree — rerun \\`wairon surface generate-children\\` so the child validates against the current surface.`,\n specId: child.id,\n });\n }\n }\n return issues;\n}\n","import { SurfaceContractEntry, SurfaceSnapshot } from '../../models/index.js';\nimport { RuleContext, SddRule } from './types.js';\nimport { dryRunSerializeSpecs } from '../specs.js';\nimport { checkChildSurfaceFreshness } from '../surfaces.js';\n\n/**\n * True when an unresolved reference points OUTSIDE the current loading root,\n * rather than being a genuine local typo — so it warrants the softer\n * CROSS_TREE_REF_UNRESOLVED warning (\"validate from the parent project\")\n * instead of a hard \"does not exist\" error. Two shapes qualify:\n * - an explicit relative form (`::x` / `super::x`), and\n * - a qualified id whose leading namespace segment is not a subsystem in THIS\n * tree — e.g. `waffler_core::blueprints-portal` authored from a parent root,\n * where `waffler_core` is absent when the same specs are validated from the\n * child subproject's own directory. This is exactly the \"different root,\n * different verdict\" case: from the child root such a ref is unresolvable but\n * honest, not broken, so it must not flood the report with hard errors.\n */\nexport function isExternalNamespaceRef(ctx: RuleContext, ref: string): boolean {\n if (ref.startsWith('::') || ref.startsWith('super::')) return true;\n const sep = ref.indexOf('::');\n if (sep === -1) return false; // a bare unresolved id is a local typo, not cross-tree\n return !ctx.subsystemIds.has(ref.slice(0, sep));\n}\n\n/**\n * Resolve an unresolved cross-tree reference (a `super::`/`::` form whose\n * target is outside this loading root) against the stored surface snapshots:\n * the ref's final segment is matched against each snapshot's exported entry\n * ids and backing component names. A hit means the edge is validated against\n * the DECLARED contract instead of falling back to the unresolvable warning.\n */\nexport function resolveSurfaceRef(\n ctx: RuleContext,\n ref: string,\n): { snapshot: SurfaceSnapshot; entry: SurfaceContractEntry } | null {\n const local = ref.split('::').filter(seg => seg && seg !== 'super').pop();\n if (!local) return null;\n for (const snapshot of ctx.surfaceSnapshots) {\n const entry = snapshot.interfaces.find(e => e.component === local || e.id === local);\n if (entry) return { snapshot, entry };\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Namespace integrity: the :: grammar must stay round-trippable. Two rules:\n// the writer dry-run (validate predicts every save/lock refusal) and the id\n// hygiene checks that keep the qualify/relativize grammar unambiguous.\n// ---------------------------------------------------------------------------\n\n/**\n * Registered as a real rule (not an ad-hoc loader injection) so the code is\n * visible in `wairon rules list`, tunable via rules.sddRuleSeverity, scoped by\n * ctx.addIssue like every other finding, and recognized by the lint-allow\n * audit (errors are still never locally suppressible).\n */\nexport const roundtripRule: SddRule = {\n name: 'roundtrip-serialization',\n description:\n 'Every loaded spec must re-serialize through the exact writer pipeline (same relativization, same schema, no I/O) — validate must predict every refusal that lock\\'s status promotion or any later save would otherwise raise mid-write.',\n codes: [\n { code: 'ROUNDTRIP_SERIALIZATION', defaultSeverity: 'error', summary: 'Spec cannot be re-serialized through the writer schema (any save or lock would refuse it)' },\n ],\n check(ctx) {\n for (const issue of dryRunSerializeSpecs(ctx.isSpecInScope)) {\n ctx.addIssue('error', 'ROUNDTRIP_SERIALIZATION', issue.message, issue.specId);\n }\n },\n};\n\n/**\n * Parent-side surface freshness: a chained child holds the parent-surface\n * snapshot it validates against standalone; when the parent's exported\n * contracts change without regenerating, the child is verifying against a\n * stale truth. Computable exactly here — the only context where both sides\n * (the live parent tree and the child's held snapshot) are visible.\n */\nexport const surfaceFreshnessRule: SddRule = {\n name: 'surface-freshness',\n description:\n 'Every chained child\\'s stored parent-surface snapshot must match the parent\\'s CURRENT exported contracts — a drifted snapshot means the child validates standalone against a stale truth. Regenerate with `wairon surface generate-children`.',\n codes: [\n { code: 'SURFACE_STALE', defaultSeverity: 'warning', summary: 'A chained child holds a parent surface snapshot whose contracts no longer match the current tree' },\n ],\n check(ctx) {\n for (const issue of checkChildSurfaceFreshness()) {\n ctx.addIssue('warning', 'SURFACE_STALE', issue.message, issue.specId);\n }\n },\n};\n\nexport const namespaceHygieneRule: SddRule = {\n name: 'namespace-hygiene',\n description:\n 'Ids must stay resolvable in the :: namespace grammar: no id segment may be the reserved keyword \"super\", and a subproject-local name must not shadow a root-level subsystem id — a bare reference to a shadowed name silently anchors to the ROOT subsystem, so the local spec becomes unaddressable.',\n codes: [\n { code: 'RESERVED_ID_SEGMENT', defaultSeverity: 'error', summary: 'Id uses the reserved namespace keyword \"super\"' },\n { code: 'NAMESPACE_SHADOWING', defaultSeverity: 'error', summary: 'Subproject-local id shadows a root subsystem id (bare references anchor to the root)' },\n ],\n check(ctx) {\n const rootSubs = new Set(ctx.subsystems.filter(s => !s.id.includes('::')).map(s => s.id));\n\n const checkId = (id: string, kindLabel: string): void => {\n if (!ctx.isSpecInScope(id)) return;\n const segments = id.split('::');\n if (segments.includes('super')) {\n ctx.addIssue(\n 'error',\n 'RESERVED_ID_SEGMENT',\n `${kindLabel} id \"${id}\" uses the reserved namespace keyword \"super\" — stored references to it would be consumed as a namespace hop and resolve to a different spec.`,\n id,\n );\n }\n if (segments.length > 1) {\n const local = segments[segments.length - 1];\n if (rootSubs.has(local)) {\n ctx.addIssue(\n 'error',\n 'NAMESPACE_SHADOWING',\n `${kindLabel} \"${id}\" shadows root subsystem \"${local}\" — inside its subproject a bare reference to \"${local}\" anchors to the ROOT subsystem, so this spec cannot be addressed reliably. Rename one of them.`,\n id,\n );\n }\n }\n };\n\n for (const s of ctx.subsystems) checkId(s.id, 'Subsystem');\n for (const c of ctx.components) checkId(c.id, 'Component');\n for (const i of ctx.interfaces) checkId(i.id, 'Interface');\n for (const im of ctx.implementations) checkId(im.id, 'Implementation');\n for (const t of ctx.types) checkId(t.id, 'Type');\n },\n};\n","import { SddRule } from './types.js';\nimport { resolveSurfaceRef, isExternalNamespaceRef } from './namespace.js';\n\n/**\n * Contract ↔ implementation symmetry, and narrative-step resolution: every\n * `call` step targets a real dependency's real method, and any guarantee a\n * step asserts must be declared on the contract it calls.\n */\nexport const contractsRule: SddRule = {\n name: 'contract-symmetry-and-narratives',\n description:\n 'Implementations mirror their contract method-for-method. Narrative call steps must name an existing component and method, the caller must declare the dependency, and asserted semantic guarantees must be backed by the target contract.',\n codes: [\n { code: 'UNEXPECTED_IMPLEMENTATION_METHOD', defaultSeverity: 'error', summary: 'Implementation method not present on the contract' },\n { code: 'MISSING_IMPLEMENTATION_METHOD', defaultSeverity: 'error', summary: 'Contract method missing from the implementation' },\n { code: 'MISSING_TARGET_COMPONENT', defaultSeverity: 'error', summary: 'Call step missing targetComponent' },\n { code: 'MISSING_TARGET_METHOD', defaultSeverity: 'error', summary: 'Call step missing targetMethod' },\n { code: 'INVALID_TARGET_COMPONENT_REFERENCE', defaultSeverity: 'error', summary: 'Call step targets a non-existent component' },\n { code: 'CROSS_TREE_REF_UNRESOLVED', defaultSeverity: 'warning', summary: 'Cross-tree reference (super::/:: form) with no surface snapshot covering it — only the parent project can verify it' },\n { code: 'SURFACE_REF_NOT_EXPOSED', defaultSeverity: 'error', summary: 'Cross-tree reference resolves to a surface snapshot that does not expose the called method/capability' },\n { code: 'UNDECLARED_DEPENDENCY_CALL', defaultSeverity: 'error', summary: 'Call step targets a component the caller does not depend on or own' },\n { code: 'INVALID_TARGET_METHOD_REFERENCE', defaultSeverity: 'error', summary: 'Call step targets a method not on any target interface' },\n { code: 'NARRATIVE_SEMANTIC_UNBACKED', defaultSeverity: 'warning', summary: 'Narrative asserts a guarantee the called contract does not declare' },\n ],\n check(ctx) {\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n if (!contract) continue;\n\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n const contractMethodNames = new Set(contract.methods.map(m => m.name));\n const implMethodNames = new Set(impl.methods.map(m => m.name));\n\n // Check implementation has extra methods not defined in interface\n for (const implMethod of impl.methods) {\n if (!contractMethodNames.has(implMethod.name)) {\n ctx.addIssue(\n 'error',\n 'UNEXPECTED_IMPLEMENTATION_METHOD',\n `Implementation \"${impl.id}\" implements method \"${implMethod.name}\" which is not defined on contract \"${contract.id}\".`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n\n // Check implementation is missing methods defined in interface\n for (const contractMethod of contract.methods) {\n if (!implMethodNames.has(contractMethod.name)) {\n ctx.addIssue(\n 'error',\n 'MISSING_IMPLEMENTATION_METHOD',\n `Implementation \"${impl.id}\" is missing implementation for contract method \"${contractMethod.name}\" from interface \"${contract.id}\".`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n\n // Level 5 narrative step validation. Dispatch steps share the component-\n // existence and declared-dependency checks with call steps; capability\n // resolution against the target Portal's table is the dispatch rule's.\n for (const implMethod of impl.methods) {\n for (const step of implMethod.narrative) {\n if (step.type !== 'call' && step.type !== 'dispatch') continue;\n\n if (!step.targetComponent) {\n ctx.addIssue(\n 'error',\n 'MISSING_TARGET_COMPONENT',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" has a ${step.type} step (${step.stepNumber}) missing \"targetComponent\".`,\n impl.id,\n isDraftCtx,\n );\n continue;\n }\n\n // An unresolved reference that points OUTSIDE this loading root — a\n // chained subproject opened standalone physically does not contain its\n // parent's specs, so the edge is only verifiable from the parent. That\n // is a known-honest state, not a spec defect: warn with its own code\n // instead of raising the same error a genuine typo gets. This covers\n // the explicit relative forms (super::/::) AND a qualified reference\n // whose leading namespace segment is not a subsystem in THIS tree —\n // e.g. `waffler_core::x` authored from a parent root, where\n // `waffler_core` is not present when validating from the child dir.\n const isCrossTreeForm = isExternalNamespaceRef(ctx, step.targetComponent);\n\n if (step.type === 'dispatch') {\n const dispatchTarget = ctx.componentMap.get(step.targetComponent);\n if (!dispatchTarget) {\n if (isCrossTreeForm) {\n const resolved = resolveSurfaceRef(ctx, step.targetComponent);\n if (resolved) {\n // Validate the capability against the DECLARED surface.\n if (step.capability && !(resolved.entry.dispatch ?? []).some(b => b.capability === step.capability)) {\n ctx.addIssue(\n 'error',\n 'SURFACE_REF_NOT_EXPOSED',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" dispatches capability \"${step.capability}\" through cross-tree portal \"${step.targetComponent}\" (step ${step.stepNumber}), but the surface snapshot of \"${resolved.snapshot.projectName}\" does not serve that capability on \"${resolved.entry.id}\".`,\n impl.id,\n isDraftCtx,\n );\n }\n continue;\n }\n ctx.addIssue(\n 'warning',\n 'CROSS_TREE_REF_UNRESOLVED',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" dispatches through cross-tree component \"${step.targetComponent}\" (step ${step.stepNumber}), and no surface snapshot covers it — validate from the parent project, or import/generate the producing project's surface.`,\n impl.id,\n isDraftCtx,\n );\n } else {\n ctx.addIssue(\n 'error',\n 'INVALID_TARGET_COMPONENT_REFERENCE',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" dispatches through component \"${step.targetComponent}\" which does not exist (step ${step.stepNumber}).`,\n impl.id,\n isDraftCtx,\n );\n }\n continue;\n }\n const dispatchCaller = ctx.componentMap.get(contract.component);\n if (dispatchCaller && step.targetComponent !== dispatchCaller.id\n && !dispatchCaller.dependsOn.includes(step.targetComponent)\n && !dispatchCaller.owns.includes(step.targetComponent)) {\n ctx.addIssue(\n 'error',\n 'UNDECLARED_DEPENDENCY_CALL',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" (component \"${dispatchCaller.id}\") dispatches through component \"${step.targetComponent}\" (step ${step.stepNumber}) but component \"${dispatchCaller.id}\" does not list \"${step.targetComponent}\" as a dependency.`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(dispatchCaller.id),\n );\n }\n continue;\n }\n\n if (!step.targetMethod) {\n ctx.addIssue(\n 'error',\n 'MISSING_TARGET_METHOD',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" has a call step (${step.stepNumber}) missing \"targetMethod\".`,\n impl.id,\n isDraftCtx,\n );\n continue;\n }\n\n const targetComp = ctx.componentMap.get(step.targetComponent);\n if (!targetComp) {\n if (isCrossTreeForm) {\n const resolved = resolveSurfaceRef(ctx, step.targetComponent);\n if (resolved) {\n // Validate method + asserted guarantees against the DECLARED surface.\n const surfaceMethod = resolved.entry.methods.find(m => m.name === step.targetMethod);\n if (!surfaceMethod) {\n ctx.addIssue(\n 'error',\n 'SURFACE_REF_NOT_EXPOSED',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" calls \"${step.targetMethod}\" on cross-tree component \"${step.targetComponent}\" (step ${step.stepNumber}), but the surface snapshot of \"${resolved.snapshot.projectName}\" does not expose that method on \"${resolved.entry.id}\".`,\n impl.id,\n isDraftCtx,\n );\n } else if (step.assertsGuarantees) {\n const declared = new Set(surfaceMethod.guarantees ?? []);\n for (const g of step.assertsGuarantees) {\n if (!declared.has(g)) {\n ctx.addIssue(\n 'warning',\n 'NARRATIVE_SEMANTIC_UNBACKED',\n `Step ${step.stepNumber} of \"${implMethod.name}\" in implementation \"${impl.id}\" asserts guarantee \"${g}\", but the surface snapshot of \"${resolved.snapshot.projectName}\" does not declare it on \"${resolved.entry.id}.${step.targetMethod}\".`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n continue;\n }\n ctx.addIssue(\n 'warning',\n 'CROSS_TREE_REF_UNRESOLVED',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" calls cross-tree component \"${step.targetComponent}\" (step ${step.stepNumber}), and no surface snapshot covers it — validate from the parent project, or import/generate the producing project's surface.`,\n impl.id,\n isDraftCtx,\n );\n } else {\n ctx.addIssue(\n 'error',\n 'INVALID_TARGET_COMPONENT_REFERENCE',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" calls component \"${step.targetComponent}\" which does not exist (step ${step.stepNumber}).`,\n impl.id,\n isDraftCtx,\n );\n }\n continue;\n }\n\n // Check if calling component declares targetComponent as dependency\n const callingComponent = ctx.componentMap.get(contract.component);\n if (callingComponent && step.targetComponent !== callingComponent.id) {\n if (!callingComponent.dependsOn.includes(step.targetComponent) &&\n !callingComponent.owns.includes(step.targetComponent)) {\n ctx.addIssue(\n 'error',\n 'UNDECLARED_DEPENDENCY_CALL',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" (component \"${callingComponent.id}\") calls component \"${step.targetComponent}\" (step ${step.stepNumber}) but component \"${callingComponent.id}\" does not list \"${step.targetComponent}\" as a dependency.`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(callingComponent.id),\n );\n }\n }\n\n // Check if target component has an interface containing targetMethod\n const targetInterfaces = ctx.interfacesByComponent.get(step.targetComponent) ?? [];\n let targetMethodSpec: (typeof targetInterfaces)[number]['methods'][number] | undefined;\n for (const targetIntf of targetInterfaces) {\n const found = targetIntf.methods.find(m => m.name === step.targetMethod);\n if (found) { targetMethodSpec = found; break; }\n }\n\n if (!targetMethodSpec) {\n ctx.addIssue(\n 'error',\n 'INVALID_TARGET_METHOD_REFERENCE',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" calls method \"${step.targetMethod}\" on component \"${step.targetComponent}\" which is not defined on any of its interfaces (step ${step.stepNumber}).`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(step.targetComponent),\n );\n } else {\n // Semantic cross-check (consistency, not truth): the gate can't read prose, but\n // it CAN catch a narrative step that asserts a guarantee the contract it calls\n // doesn't declare. Data-driven over the recognized guarantee set — a step whose\n // description claims a guarantee must call a method that lists it in `guarantees`.\n // Whether the method truly delivers it is implementation correctness, not here.\n const declared = new Set(targetMethodSpec.guarantees ?? []);\n if (step.assertsGuarantees) {\n for (const g of step.assertsGuarantees) {\n if (!declared.has(g)) {\n ctx.addIssue(\n 'warning',\n 'NARRATIVE_SEMANTIC_UNBACKED',\n `Step ${step.stepNumber} of \"${implMethod.name}\" in implementation \"${impl.id}\" explicitly asserts guarantee \"${g}\", but the method it calls — \"${step.targetMethod}\" on \"${step.targetComponent}\" — does not list \"${g}\" among its L3 contract guarantees. Declare it on that method (and ensure its shape can deliver it), or revise the narrative.`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(step.targetComponent),\n );\n }\n }\n }\n }\n }\n }\n }\n },\n};\n","import { NarrativeStep } from '../../models/index.js';\nimport { SddRule } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Structural soundness of narrative control flow. Narratives are flat ordered\n// step lists; flow steps (branch/switch/loop/try/jump) jump by step number.\n// The schema keeps all flow fields optional — THIS rule enforces that each\n// step type carries its required config, that every jump lands on a real\n// step, and that no step is dead code.\n// ---------------------------------------------------------------------------\n\nconst FLOW_FIELDS = [\n 'condition', 'onTrueStep', 'onFalseStep', 'on', 'cases', 'defaultStep',\n 'loopKind', 'over', 'endStep', 'catches', 'finallyStep', 'branches', 'toStep',\n] as const;\n\nfunction flowConfigOn(step: NarrativeStep): string[] {\n return FLOW_FIELDS.filter(f => {\n const v = step[f];\n if (v === undefined) return false;\n if (Array.isArray(v) && v.length === 0) return false;\n return true;\n });\n}\n\n/**\n * The step graph of one narrative: the SINGLE source of truth for successor\n * semantics (fall-through + jumps; loop and try headers carry both their body\n * edge and their after-region exit edge; return/throw terminate). Shared by\n * the reachability walk here and the antipattern analysis — the two must\n * never disagree about what \"next\" means.\n */\nexport function stepGraph(steps: NarrativeStep[]): {\n byNum: Map<number, NarrativeStep>;\n nums: number[];\n nextOf: (n: number) => number | undefined;\n successorsOf: (n: number) => number[];\n} {\n const byNum = new Map<number, NarrativeStep>();\n for (const s of steps) byNum.set(s.stepNumber, s);\n const nums = [...byNum.keys()].sort((a, b) => a - b);\n const indexOf = new Map(nums.map((n, i) => [n, i]));\n const nextOf = (n: number): number | undefined => {\n const i = indexOf.get(n);\n return i !== undefined && i + 1 < nums.length ? nums[i + 1] : undefined;\n };\n const prevOf = (n: number): number | undefined => {\n const i = indexOf.get(n);\n return i !== undefined && i > 0 ? nums[i - 1] : undefined;\n };\n\n // Parallel arm boundaries: the last step of an arm continues at the JOIN\n // (after the parallel's endStep), never into its neighbor arm. Built\n // outermost-first (ascending header) so a nested parallel whose endStep is\n // an outer arm end resolves its join through the outer mapping.\n const armEndJoin = new Map<number, number | undefined>();\n const fallNext = (n: number): number | undefined =>\n (armEndJoin.has(n) ? armEndJoin.get(n) : nextOf(n));\n for (const n of nums) {\n const s = byNum.get(n)!;\n if (s.type !== 'parallel' || s.endStep === undefined || !s.branches?.length) continue;\n const entries = s.branches.map(b => b.step).sort((a, b) => a - b);\n const join = fallNext(s.endStep);\n for (let i = 0; i < entries.length; i++) {\n const armEnd = i + 1 < entries.length ? prevOf(entries[i + 1]) : s.endStep;\n if (armEnd !== undefined && armEnd >= entries[i]) armEndJoin.set(armEnd, join);\n }\n }\n\n const successorsOf = (n: number): number[] => {\n const s = byNum.get(n);\n if (!s) return [];\n const succ: (number | undefined)[] = [];\n switch (s.type) {\n case 'local':\n case 'call':\n case 'dispatch':\n succ.push(fallNext(n));\n break;\n case 'branch':\n succ.push(s.onTrueStep ?? fallNext(n), s.onFalseStep);\n break;\n case 'switch':\n succ.push(...(s.cases ?? []).map(c => c.step), s.defaultStep ?? fallNext(n));\n break;\n case 'loop':\n succ.push(nextOf(n), s.endStep !== undefined ? fallNext(s.endStep) : undefined);\n break;\n case 'try':\n succ.push(\n nextOf(n),\n ...(s.catches ?? []).map(c => c.step),\n s.finallyStep,\n s.endStep !== undefined ? fallNext(s.endStep) : undefined,\n );\n break;\n case 'parallel':\n // Fan-out to every arm entry; the join continuation is the step after\n // the region (all arms complete before flow proceeds).\n succ.push(\n ...(s.branches ?? []).map(b => b.step),\n s.endStep !== undefined ? fallNext(s.endStep) : undefined,\n );\n break;\n case 'jump':\n succ.push(s.toStep);\n break;\n // return / throw terminate the path\n }\n return [...new Set(succ.filter((t): t is number => t !== undefined && byNum.has(t)))];\n };\n return { byNum, nums, nextOf, successorsOf };\n}\n\nexport const narrativeFlowRule: SddRule = {\n name: 'narrative-flow',\n description:\n 'Control-flow soundness of L5 narratives: flow steps (branch, switch, loop, try, parallel, jump) must carry their required config, every jump field must target an existing step number in the same narrative, and every step must be reachable from the first step following fall-through and jumps. A parallel body is covered by contiguous, ordered arms (>= 2) whose last steps continue at the join after endStep; \"detach\" (fire-and-forget) is legal on call/dispatch steps only.',\n codes: [\n { code: 'MALFORMED_FLOW_STEP', defaultSeverity: 'error', summary: 'Flow step missing required config (or flow config on a local/call step)' },\n { code: 'INVALID_STEP_JUMP', defaultSeverity: 'error', summary: 'Jump field targets a step number that does not exist in the narrative' },\n { code: 'UNREACHABLE_STEP', defaultSeverity: 'warning', summary: 'Step not reachable from the first step following fall-through and jumps' },\n { code: 'REGION_OVERLAP', defaultSeverity: 'error', summary: 'loop/try regions interleave — regions must nest or be disjoint to map onto structured code' },\n { code: 'JUMP_INTO_REGION', defaultSeverity: 'warning', summary: 'Jump lands in the middle of a loop/try body from outside — regions are entered through their header' },\n { code: 'FALLTHROUGH_INTO_HANDLER', defaultSeverity: 'warning', summary: 'try body falls through into its own catch/finally region on the success path' },\n { code: 'BACKWARD_JUMP', defaultSeverity: 'warning', summary: 'Backward jump that is not a continue to an enclosing loop header — model repetition with a loop step' },\n ],\n check(ctx) {\n for (const impl of ctx.implementations) {\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n for (const implMethod of impl.methods) {\n const steps = implMethod.narrative;\n if (!steps.length) continue;\n const where = `Method \"${implMethod.name}\" in implementation \"${impl.id}\": `;\n\n let sound = true;\n const malformed = (msg: string): void => {\n sound = false;\n ctx.addIssue('error', 'MALFORMED_FLOW_STEP', where + msg, impl.id, isDraftCtx);\n };\n\n const byNum = new Map<number, NarrativeStep>();\n for (const s of steps) {\n if (byNum.has(s.stepNumber)) malformed(`duplicate stepNumber ${s.stepNumber} — jump targets would be ambiguous.`);\n byNum.set(s.stepNumber, s);\n }\n const nums = [...byNum.keys()].sort((a, b) => a - b);\n const indexOf = new Map(nums.map((n, i) => [n, i]));\n const nextOf = (n: number): number | undefined => {\n const i = indexOf.get(n);\n return i !== undefined && i + 1 < nums.length ? nums[i + 1] : undefined;\n };\n\n for (const s of steps) {\n if (s.detach && s.type !== 'call' && s.type !== 'dispatch') {\n malformed(`step ${s.stepNumber} (${s.type}) carries \"detach\" — fire-and-forget applies to call/dispatch steps only.`);\n }\n switch (s.type) {\n case 'local':\n case 'call':\n case 'dispatch': {\n const extra = flowConfigOn(s);\n if (extra.length) malformed(`step ${s.stepNumber} (${s.type}) carries flow config (${extra.join(', ')}) — use a flow step type instead.`);\n break;\n }\n case 'branch':\n if (!s.condition) malformed(`branch step ${s.stepNumber} requires \"condition\".`);\n if (s.onFalseStep === undefined) malformed(`branch step ${s.stepNumber} requires \"onFalseStep\" (true continues at onTrueStep or the next step).`);\n break;\n case 'switch':\n if (!s.cases || !s.cases.length) malformed(`switch step ${s.stepNumber} requires non-empty \"cases\".`);\n break;\n case 'loop': {\n if (s.endStep === undefined) malformed(`loop step ${s.stepNumber} requires \"endStep\" (last step of the body).`);\n else if (s.endStep <= s.stepNumber) malformed(`loop step ${s.stepNumber} \"endStep\" (${s.endStep}) must lie beyond the header.`);\n const kind = s.loopKind ?? (s.over ? 'forEach' : 'while');\n if ((kind === 'while' || kind === 'doWhile') && !s.condition) malformed(`${kind} loop step ${s.stepNumber} requires \"condition\".`);\n if ((kind === 'forEach' || kind === 'for') && !s.over) malformed(`${kind} loop step ${s.stepNumber} requires \"over\" (the iteration source).`);\n break;\n }\n case 'try':\n if (s.endStep === undefined) malformed(`try step ${s.stepNumber} requires \"endStep\" (last step of the guarded body).`);\n else if (s.endStep <= s.stepNumber) malformed(`try step ${s.stepNumber} \"endStep\" (${s.endStep}) must lie beyond the header.`);\n if ((!s.catches || !s.catches.length) && s.finallyStep === undefined) malformed(`try step ${s.stepNumber} requires \"catches\" and/or \"finallyStep\" — a guard that handles nothing guards nothing.`);\n break;\n case 'parallel': {\n if (s.endStep === undefined) malformed(`parallel step ${s.stepNumber} requires \"endStep\" (last step of the fan-out body).`);\n else if (s.endStep <= s.stepNumber) malformed(`parallel step ${s.stepNumber} \"endStep\" (${s.endStep}) must lie beyond the header.`);\n const entries = (s.branches ?? []).map(b => b.step);\n if (entries.length < 2) {\n malformed(`parallel step ${s.stepNumber} requires \"branches\" with at least two arms — a single arm is sequential flow.`);\n } else {\n const sorted = [...entries].sort((a, b) => a - b);\n if (entries.some((e, i) => e !== sorted[i])) malformed(`parallel step ${s.stepNumber} \"branches\" must list arm entries in ascending order — arms are contiguous sub-regions of the body.`);\n if (new Set(entries).size !== entries.length) malformed(`parallel step ${s.stepNumber} \"branches\" lists the same entry step twice.`);\n const bodyStart = nextOf(s.stepNumber);\n if (bodyStart !== undefined && sorted[0] !== bodyStart) malformed(`parallel step ${s.stepNumber}: the first arm must start at the body's first step (${bodyStart}), got ${sorted[0]} — steps before the first arm would belong to no arm.`);\n if (s.endStep !== undefined && sorted.some(e => e > s.endStep!)) malformed(`parallel step ${s.stepNumber}: every arm entry must lie within the body (..${s.endStep}).`);\n }\n break;\n }\n case 'jump':\n if (s.toStep === undefined) malformed(`jump step ${s.stepNumber} requires \"toStep\".`);\n break;\n // return / throw need no config\n }\n\n const jumpFields: [string, number][] = [];\n if (s.onTrueStep !== undefined) jumpFields.push(['onTrueStep', s.onTrueStep]);\n if (s.onFalseStep !== undefined) jumpFields.push(['onFalseStep', s.onFalseStep]);\n if (s.defaultStep !== undefined) jumpFields.push(['defaultStep', s.defaultStep]);\n if (s.endStep !== undefined) jumpFields.push(['endStep', s.endStep]);\n if (s.finallyStep !== undefined) jumpFields.push(['finallyStep', s.finallyStep]);\n if (s.toStep !== undefined) jumpFields.push(['toStep', s.toStep]);\n (s.cases ?? []).forEach((c, i) => jumpFields.push([`cases[${i}].step`, c.step]));\n (s.catches ?? []).forEach((c, i) => jumpFields.push([`catches[${i}].step`, c.step]));\n (s.branches ?? []).forEach((b, i) => jumpFields.push([`branches[${i}].step`, b.step]));\n for (const [field, target] of jumpFields) {\n if (!byNum.has(target)) {\n sound = false;\n ctx.addIssue(\n 'error',\n 'INVALID_STEP_JUMP',\n `${where}step ${s.stepNumber} \"${field}\" targets step ${target}, which does not exist in this narrative.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n\n // Reachability only makes sense over a structurally sound narrative.\n if (!sound) continue;\n const graph = stepGraph(steps);\n const visited = new Set<number>();\n const stack = [nums[0]];\n while (stack.length) {\n const n = stack.pop()!;\n if (visited.has(n)) continue;\n visited.add(n);\n for (const t of graph.successorsOf(n)) {\n if (!visited.has(t)) stack.push(t);\n }\n }\n const dead = nums.filter(n => !visited.has(n));\n if (dead.length) {\n ctx.addIssue(\n 'warning',\n 'UNREACHABLE_STEP',\n `${where}step(s) ${dead.join(', ')} cannot be reached from step ${nums[0]} following fall-through and jumps.`,\n impl.id,\n isDraftCtx,\n );\n }\n\n // ---- structural soundness of regions and jumps ----------------------\n // Regions (loop/try bodies) are numeric spans; structured code can only\n // express them nested or disjoint, entered through their header.\n const regions: { h: number; end: number; kind: string }[] = [];\n for (const s of steps) {\n if ((s.type === 'loop' || s.type === 'try' || s.type === 'parallel') && s.endStep !== undefined) {\n regions.push({ h: s.stepNumber, end: s.endStep, kind: s.type });\n }\n }\n const inBody = (n: number, r: { h: number; end: number }): boolean => n > r.h && n <= r.end;\n\n for (const a of regions) {\n for (const b of regions) {\n if (b.h > a.h && b.h <= a.end && b.end > a.end) {\n ctx.addIssue(\n 'error',\n 'REGION_OVERLAP',\n `${where}${b.kind} region ${b.h}..${b.end} interleaves with ${a.kind} region ${a.h}..${a.end} — regions must be nested or disjoint.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n\n const jumpEdges: { from: number; to: number; field: string; kind: string }[] = [];\n for (const s of steps) {\n const push = (field: string, to: number | undefined): void => {\n if (to !== undefined) jumpEdges.push({ from: s.stepNumber, to, field, kind: s.type });\n };\n push('onTrueStep', s.onTrueStep);\n push('onFalseStep', s.onFalseStep);\n push('defaultStep', s.defaultStep);\n push('toStep', s.toStep);\n push('finallyStep', s.finallyStep);\n (s.cases ?? []).forEach((c, i) => push(`cases[${i}].step`, c.step));\n (s.catches ?? []).forEach((c, i) => push(`catches[${i}].step`, c.step));\n }\n\n for (const e of jumpEdges) {\n for (const r of regions) {\n if (inBody(e.to, r) && e.from !== r.h && !inBody(e.from, r)) {\n ctx.addIssue(\n 'warning',\n 'JUMP_INTO_REGION',\n `${where}step ${e.from} \"${e.field}\" jumps into the middle of the ${r.kind} region ${r.h}..${r.end} (step ${e.to}) — regions are entered through their header.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n // Backward jumps are only idiomatic as a continue to an enclosing\n // loop header; anything else is an unstructured loop in disguise.\n if ((e.kind === 'branch' || e.kind === 'switch' || e.kind === 'jump') && e.to < e.from) {\n const continueToLoop = regions.some(r => r.kind === 'loop' && r.h === e.to && inBody(e.from, r));\n if (!continueToLoop) {\n ctx.addIssue(\n 'warning',\n 'BACKWARD_JUMP',\n `${where}step ${e.from} \"${e.field}\" jumps backwards to step ${e.to} — model repetition with a loop step (backward jumps are only idiomatic as a continue to an enclosing loop header).`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n\n // A try body whose last step simply falls through runs its handlers on\n // the SUCCESS path — almost always a missing jump/return at the body end.\n for (const s of steps) {\n if (s.type !== 'try' || s.endStep === undefined) continue;\n const handlerStarts = new Set<number>((s.catches ?? []).map(c => c.step));\n if (s.finallyStep !== undefined) handlerStarts.add(s.finallyStep);\n const last = byNum.get(s.endStep);\n const nxt = nextOf(s.endStep);\n if (last && (last.type === 'local' || last.type === 'call' || last.type === 'dispatch') && nxt !== undefined && handlerStarts.has(nxt)) {\n ctx.addIssue(\n 'warning',\n 'FALLTHROUGH_INTO_HANDLER',\n `${where}the try body ending at step ${s.endStep} falls through into its handler region (step ${nxt}) — end the body with a jump, return, or throw so handlers only run on error.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n },\n};\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { createRequire } from 'module';\nimport type { ImplementationSpec } from '../models/index.js';\n\n// ---------------------------------------------------------------------------\n// Source Analysis Adapter — the validator subsystem's only source-code I/O.\n//\n// Resolves every distinct L4 sourcePath inside the project root, reads the\n// files, and produces the pure CodeModel the structural-conformance rule\n// family consumes. Analysis is tiered so wairon carries ZERO mandatory parser\n// dependencies:\n// exact — full AST via the TypeScript compiler, resolved dynamically from\n// the analyzed project's node_modules first and wairon's own\n// installation second (never bundled),\n// pattern — declarative per-language declaration/import pattern tables,\n// generic — word-boundary identifier scan, the universal floor.\n// The grade is recorded per file and carried onto finding messages, so a\n// weaker analysis is visible rather than silently over-trusted. A single\n// file's failure degrades that file, never the run.\n// ---------------------------------------------------------------------------\n\nexport type AnalysisGrade = 'exact' | 'pattern' | 'generic';\nexport type SourceFileStatus = 'analyzed' | 'missing' | 'escaped' | 'unreadable';\n\nexport interface SourceFileFacts {\n /** Project-relative resolved source path (many implementations may share it, N:1). */\n path: string;\n status: SourceFileStatus;\n /** Effective language the file was analyzed as. */\n language?: string;\n analysisGrade?: AnalysisGrade;\n /**\n * Declaration-tier anchors: named declarations at any nesting depth,\n * destructuring bindings, object-literal keys, import bindings, and export\n * specifiers (export-* barrels chased through relative specifiers).\n */\n declaredNames: string[];\n /** Weaker anchors: exact string-literal occurrences (tool/route registrations). */\n anchoredNames: string[];\n /** Exported bindings (Level 2 dependency-conformance and UNDECLARED_EXPORT fuel). */\n exportedNames: string[];\n /**\n * Runtime import/require module specifiers (dependency-conformance fuel).\n * Type-only imports and export-from specifiers are excluded — type coupling\n * is allowed by default, and re-exporting is surface republication, not\n * collaboration.\n */\n imports: string[];\n /** Module specifiers of export-from declarations (surface republication). */\n reexports: string[];\n /**\n * Cyclomatic complexity per named function-like (function/method/accessor\n * declarations, and function/arrow initializers of named slots). EXACT grade\n * only — lower grades omit the map rather than guess. Same-named functions\n * in one file record their maximum. Fuel for the detail-sufficiency lint.\n */\n functionComplexity?: Record<string, number>;\n /**\n * Direct callee names per named function-like: identifiers and property\n * names invoked as calls inside the function body (nested NAMED functions\n * excluded — they carry their own entries; anonymous callbacks included).\n * EXACT grade only. Same-named functions union their sets. Fuel for the\n * call-step realization check (Level 3).\n */\n functionCalls?: Record<string, string[]>;\n /**\n * Module-scope mutable bindings (`let`/`var` at the top level of the file).\n * EXACT grade only. The static approximation of held state a logic\n * component may be hiding — fuel for the HIDDEN_STATE lint. (Mutation of\n * const-bound containers is invisible to this collection; the lint says so.)\n */\n topLevelMutableBindings?: string[];\n}\n\nexport interface CodeModel {\n /** One facts entry per distinct resolved sourcePath (missing/escaped/unreadable included). */\n files: SourceFileFacts[];\n /** The root every sourcePath was resolved and containment-checked against. */\n projectRoot: string;\n}\n\nexport function emptyCodeModel(): CodeModel {\n return { files: [], projectRoot: '' };\n}\n\n/** Canonical project-relative form all sourcePath keys are stored/looked up in. */\nexport function normalizeSourcePath(p: string): string {\n return p.replace(/\\\\/g, '/').replace(/^\\.\\//, '');\n}\n\n// ---------------------------------------------------------------------------\n// Language detection + declarative pattern tables\n// ---------------------------------------------------------------------------\n\nconst EXTENSION_LANGUAGE: Record<string, string> = {\n '.ts': 'typescript', '.tsx': 'typescript', '.mts': 'typescript', '.cts': 'typescript',\n '.js': 'javascript', '.jsx': 'javascript', '.mjs': 'javascript', '.cjs': 'javascript',\n '.py': 'python', '.rs': 'rust', '.go': 'go', '.cs': 'csharp', '.java': 'java',\n '.c': 'c', '.h': 'c', '.cpp': 'cpp', '.cc': 'cpp', '.hpp': 'cpp',\n '.rb': 'ruby', '.php': 'php', '.kt': 'kotlin', '.swift': 'swift',\n};\n\ninterface LanguagePatterns {\n lineComments: string[];\n blockComments: [string, string][];\n /** Regexes whose FIRST capture group is a declared name (run with /g). */\n declarations: RegExp[];\n /** Regexes whose first non-empty capture group is an import module specifier. */\n imports: RegExp[];\n /** Line prefix that marks a declaration as exported (coarse). */\n exportMarkers: RegExp[];\n}\n\nconst C_FAMILY_COMMENTS = { lineComments: ['//'], blockComments: [['/*', '*/']] as [string, string][] };\n\nconst JS_PATTERNS: LanguagePatterns = {\n ...C_FAMILY_COMMENTS,\n declarations: [\n /\\b(?:function|class|interface|enum|namespace)\\s+([A-Za-z_$][\\w$]*)/g,\n /\\b(?:const|let|var|type)\\s+([A-Za-z_$][\\w$]*)/g,\n // property/arrow style: `name: (…) =>`, `name = function`, `name(…) {` members\n /([A-Za-z_$][\\w$]*)\\s*[:=]\\s*(?:async\\s+)?(?:function\\b|\\()/g,\n /(?:^|\\s)(?:public|private|protected|static|async|get|set)\\s+([A-Za-z_$][\\w$]*)\\s*\\(/g,\n // named import bindings realize forwarding adapters\n /\\bimport\\s*\\{([^}]*)\\}/g,\n ],\n imports: [\n /\\b(?:import|export)\\b[^'\"\\n]*['\"]([^'\"]+)['\"]/g,\n /\\brequire\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n /\\bimport\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/g,\n ],\n exportMarkers: [/^\\s*export\\b/],\n};\n\nconst LANGUAGE_PATTERNS: Record<string, LanguagePatterns> = {\n typescript: JS_PATTERNS,\n javascript: JS_PATTERNS,\n python: {\n lineComments: ['#'], blockComments: [['\"\"\"', '\"\"\"'], [\"'''\", \"'''\"]],\n declarations: [/\\b(?:def|class)\\s+([A-Za-z_]\\w*)/g, /^([A-Za-z_]\\w*)\\s*=/gm],\n imports: [/^\\s*from\\s+([\\w.]+)\\s+import\\b/gm, /^\\s*import\\s+([\\w.]+)/gm],\n exportMarkers: [],\n },\n rust: {\n ...C_FAMILY_COMMENTS,\n declarations: [/\\b(?:fn|struct|enum|trait|mod|const|static|type)\\s+([A-Za-z_]\\w*)/g],\n imports: [/\\buse\\s+([\\w:]+)/g],\n exportMarkers: [/^\\s*pub\\b/],\n },\n go: {\n ...C_FAMILY_COMMENTS,\n declarations: [/\\bfunc\\s+(?:\\([^)]*\\)\\s*)?([A-Za-z_]\\w*)/g, /\\b(?:type|var|const)\\s+([A-Za-z_]\\w*)/g],\n imports: [/\\bimport\\s+(?:\\w+\\s+)?\"([^\"]+)\"/g, /^\\s*(?:\\w+\\s+)?\"([^\"]+)\"\\s*$/gm],\n exportMarkers: [],\n },\n csharp: {\n ...C_FAMILY_COMMENTS,\n declarations: [\n /\\b(?:class|interface|struct|enum|record)\\s+([A-Za-z_]\\w*)/g,\n // separators are same-line only ([ \\t], never \\n) — an unbounded lazy\n // class containing \\s here is verified quadratic on large generated files\n /\\b(?:public|private|protected|internal|static|async|override|virtual)(?:[ \\t]+[\\w<>,[\\]?]+)*[ \\t]+([A-Za-z_]\\w*)[ \\t]*\\(/g,\n ],\n imports: [/\\busing\\s+([\\w.]+)\\s*;/g],\n exportMarkers: [/^\\s*public\\b/],\n },\n java: {\n ...C_FAMILY_COMMENTS,\n declarations: [\n /\\b(?:class|interface|enum|record)\\s+([A-Za-z_]\\w*)/g,\n /\\b(?:public|private|protected|static|final|synchronized)(?:[ \\t]+[\\w<>,[\\]?]+)*[ \\t]+([A-Za-z_]\\w*)[ \\t]*\\(/g,\n ],\n imports: [/\\bimport\\s+([\\w.]+)\\s*;/g],\n exportMarkers: [/^\\s*public\\b/],\n },\n c: {\n ...C_FAMILY_COMMENTS,\n declarations: [/\\b([A-Za-z_]\\w*)\\s*\\([^;]*\\)\\s*\\{/g, /\\b(?:struct|enum|union|typedef)\\s+([A-Za-z_]\\w*)/g],\n imports: [/#include\\s*[<\"]([^>\"]+)[>\"]/g],\n exportMarkers: [],\n },\n ruby: {\n lineComments: ['#'], blockComments: [['=begin', '=end']],\n declarations: [/\\b(?:def|class|module)\\s+([A-Za-z_]\\w*[?!]?)/g],\n imports: [/\\brequire(?:_relative)?\\s+['\"]([^'\"]+)['\"]/g],\n exportMarkers: [],\n },\n php: {\n lineComments: ['//', '#'], blockComments: [['/*', '*/']],\n declarations: [/\\b(?:function|class|interface|trait)\\s+([A-Za-z_]\\w*)/g],\n imports: [/\\b(?:require|include)(?:_once)?\\s*\\(?\\s*['\"]([^'\"]+)['\"]/g, /\\buse\\s+([\\w\\\\]+)/g],\n exportMarkers: [],\n },\n kotlin: {\n ...C_FAMILY_COMMENTS,\n declarations: [/\\b(?:fun|class|interface|object|val|var)\\s+([A-Za-z_]\\w*)/g],\n imports: [/\\bimport\\s+([\\w.]+)/g],\n exportMarkers: [],\n },\n swift: {\n ...C_FAMILY_COMMENTS,\n declarations: [/\\b(?:func|class|struct|enum|protocol|let|var)\\s+([A-Za-z_]\\w*)/g],\n imports: [/\\bimport\\s+([\\w.]+)/g],\n exportMarkers: [/^\\s*public\\b/],\n },\n};\n\n// C-family patterns cover the same declaration shapes (`cpp` mirrors `c`).\nLANGUAGE_PATTERNS.cpp = LANGUAGE_PATTERNS.c;\n\n/** Pattern tables are for human-authored sources; above this size (generated/\n * minified) the linear generic scan takes over — regex worst cases stay bounded. */\nconst PATTERN_ANALYSIS_MAX_BYTES = 1_000_000;\n\nconst IDENTIFIER_RE = /[A-Za-z_$][\\w$]*/g;\nconst STRING_RE = /'([^'\\\\\\n]*(?:\\\\.[^'\\\\\\n]*)*)'|\"([^\"\\\\\\n]*(?:\\\\.[^\"\\\\\\n]*)*)\"|`([^`\\\\]*(?:\\\\.[^`\\\\]*)*)`/g;\n\nfunction stripComments(text: string, patterns: LanguagePatterns): string {\n let out = text;\n for (const [open, close] of patterns.blockComments) {\n const re = new RegExp(`${escapeRe(open)}[\\\\s\\\\S]*?${escapeRe(close)}`, 'g');\n out = out.replace(re, ' ');\n }\n if (patterns.lineComments.length > 0) {\n const re = new RegExp(`(?:${patterns.lineComments.map(escapeRe).join('|')})[^\\n]*`, 'g');\n out = out.replace(re, '');\n }\n return out;\n}\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nfunction collectStrings(text: string): Set<string> {\n const anchors = new Set<string>();\n for (const m of text.matchAll(STRING_RE)) {\n const value = m[1] ?? m[2] ?? m[3];\n if (value) anchors.add(value);\n }\n return anchors;\n}\n\n// ---------------------------------------------------------------------------\n// Pattern + generic analyzers\n// ---------------------------------------------------------------------------\n\nfunction analyzeWithPatterns(text: string, patterns: LanguagePatterns): Omit<SourceFileFacts, 'path' | 'status' | 'language'> {\n const stripped = stripComments(text, patterns);\n const declared = new Set<string>();\n const exported = new Set<string>();\n const imports = new Set<string>();\n\n for (const re of patterns.declarations) {\n for (const m of stripped.matchAll(re)) {\n const captured = m[1];\n if (!captured) continue;\n // A named-import capture (\"a, b as c\") carries multiple bindings.\n for (const piece of captured.split(',')) {\n const name = (piece.includes(' as ') ? piece.split(' as ')[1] : piece).trim();\n if (name && /^[A-Za-z_$][\\w$]*$/.test(name)) declared.add(name);\n }\n }\n }\n for (const re of patterns.imports) {\n for (const m of stripped.matchAll(re)) {\n const spec = m.slice(1).find(g => g);\n if (spec) imports.add(spec);\n }\n }\n if (patterns.exportMarkers.length > 0) {\n for (const line of stripped.split('\\n')) {\n if (!patterns.exportMarkers.some(re => re.test(line))) continue;\n for (const re of patterns.declarations) {\n re.lastIndex = 0;\n const m = re.exec(line);\n if (m?.[1]) exported.add(m[1]);\n }\n }\n }\n\n // Weak anchors: string literals plus bare identifier occurrences — the\n // pattern grade cannot prove a declaration, so mentions count at the\n // anchored tier (grade honesty covers the leniency).\n const anchors = collectStrings(text);\n for (const m of stripped.matchAll(IDENTIFIER_RE)) anchors.add(m[0]);\n\n return {\n analysisGrade: 'pattern',\n declaredNames: [...declared],\n anchoredNames: [...anchors],\n exportedNames: [...exported],\n imports: [...imports],\n reexports: [],\n };\n}\n\nfunction analyzeGeneric(text: string): Omit<SourceFileFacts, 'path' | 'status' | 'language'> {\n // The universal floor: any word-boundary identifier counts at BOTH tiers —\n // with no grammar at all, \"the name still appears in the file\" is the only\n // honest check, and the generic grade on the finding says exactly that.\n const words = new Set<string>();\n for (const m of text.matchAll(IDENTIFIER_RE)) words.add(m[0]);\n const anchors = new Set(words);\n for (const s of collectStrings(text)) anchors.add(s);\n return {\n analysisGrade: 'generic',\n declaredNames: [...words],\n anchoredNames: [...anchors],\n exportedNames: [],\n imports: [],\n reexports: [],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Exact analyzer — TypeScript compiler API, resolved dynamically (never bundled)\n// ---------------------------------------------------------------------------\n\ntype TsModule = typeof import('typescript');\n\n/**\n * Per-projectRoot resolution cache. Successful resolutions are kept for the\n * process lifetime (the module is loaded either way); FAILED resolutions are\n * retried after a short TTL so a long-running MCP/hosted process picks up an\n * `npm install typescript` in the analyzed project without a restart.\n */\nconst tsResolutionCache = new Map<string, { ts: TsModule | null; at: number }>();\nconst TS_RESOLUTION_RETRY_MS = 30_000;\n\nfunction resolveTypeScript(projectRoot: string): TsModule | null {\n const cached = tsResolutionCache.get(projectRoot);\n if (cached && (cached.ts !== null || Date.now() - cached.at < TS_RESOLUTION_RETRY_MS)) {\n return cached.ts;\n }\n let ts: TsModule | null = null;\n // The analyzed project's own compiler first, wairon's installation second.\n const bases = [path.join(projectRoot, 'package.json'), __filename];\n for (const base of bases) {\n try {\n const req = createRequire(base);\n ts = req('typescript') as TsModule;\n break;\n } catch {\n // keep trying — absence is a supported state, not an error\n }\n }\n tsResolutionCache.set(projectRoot, { ts, at: Date.now() });\n return ts;\n}\n\ninterface ExactFacts {\n declared: Set<string>;\n anchors: Set<string>;\n exported: Set<string>;\n imports: Set<string>;\n /** All export-from specifiers (named and star). */\n reexports: Set<string>;\n /** Relative export-* specifiers to chase for barrel re-exports. */\n starExports: string[];\n /** Cyclomatic complexity per named function-like (max across same-named). */\n complexity: Map<string, number>;\n /** Direct callee names per named function-like (union across same-named). */\n calls: Map<string, Set<string>>;\n /** Module-scope mutable (`let`/`var`) binding names. */\n mutableBindings: Set<string>;\n}\n\nfunction walkExact(ts: TsModule, sourceText: string, fileName: string): ExactFacts {\n const sf = ts.createSourceFile(fileName, sourceText, ts.ScriptTarget.Latest, /*setParentNodes*/ true);\n const declared = new Set<string>();\n const anchors = new Set<string>();\n const exported = new Set<string>();\n const imports = new Set<string>();\n const reexports = new Set<string>();\n const starExports: string[] = [];\n const complexity = new Map<string, number>();\n const calls = new Map<string, Set<string>>();\n const mutableBindings = new Set<string>();\n\n const addBindingNames = (name: import('typescript').BindingName): void => {\n if (ts.isIdentifier(name)) declared.add(name.text);\n else if (ts.isObjectBindingPattern(name) || ts.isArrayBindingPattern(name)) {\n for (const el of name.elements) {\n if (ts.isBindingElement(el)) addBindingNames(el.name);\n }\n }\n };\n\n const propertyNameText = (name: import('typescript').PropertyName): string | undefined => {\n if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) return name.text;\n if (ts.isPrivateIdentifier(name)) return name.text;\n return undefined;\n };\n\n const hasExportModifier = (node: import('typescript').Node): boolean => {\n const mods = (node as { modifiers?: readonly import('typescript').ModifierLike[] }).modifiers;\n return !!mods?.some(m => m.kind === ts.SyntaxKind.ExportKeyword);\n };\n\n // The name under which a function-like gets its own complexity entry: a\n // declaration's own name, or the named slot (variable / property) a\n // function/arrow initializer is bound to. Anonymous inline callbacks return\n // undefined — their branching belongs to the enclosing named function.\n const namedFunctionName = (node: import('typescript').Node): string | undefined => {\n if (ts.isFunctionDeclaration(node)) {\n return node.name && ts.isIdentifier(node.name) ? node.name.text : undefined;\n }\n if (ts.isMethodDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node)) {\n return propertyNameText(node.name);\n }\n if (ts.isFunctionExpression(node) || ts.isArrowFunction(node)) {\n const p = node.parent;\n if (p && ts.isVariableDeclaration(p) && p.initializer === node && ts.isIdentifier(p.name)) return p.name.text;\n if (p && (ts.isPropertyAssignment(p) || ts.isPropertyDeclaration(p)) && p.initializer === node) {\n return propertyNameText(p.name);\n }\n }\n return undefined;\n };\n\n // One pass per named function's body collecting classic cyclomatic\n // complexity (decision points + 1) AND direct callee names. Nested NAMED\n // function-likes are excluded — they get their own entries — while\n // anonymous callbacks count into the enclosing function.\n const collectFunctionFacts = (fn: import('typescript').Node & { body?: import('typescript').Node }): { score: number; callees: Set<string> } => {\n let score = 1;\n const callees = new Set<string>();\n const count = (node: import('typescript').Node): void => {\n if (namedFunctionName(node) !== undefined) return;\n if (ts.isIfStatement(node) || ts.isConditionalExpression(node)\n || ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)\n || ts.isWhileStatement(node) || ts.isDoStatement(node)\n || ts.isCaseClause(node) || ts.isCatchClause(node)) {\n score++;\n } else if (ts.isBinaryExpression(node)) {\n const k = node.operatorToken.kind;\n if (k === ts.SyntaxKind.AmpersandAmpersandToken || k === ts.SyntaxKind.BarBarToken\n || k === ts.SyntaxKind.QuestionQuestionToken) {\n score++;\n }\n } else if (ts.isCallExpression(node)) {\n const callee = node.expression;\n if (ts.isIdentifier(callee)) callees.add(callee.text);\n else if (ts.isPropertyAccessExpression(callee)) callees.add(callee.name.text);\n }\n ts.forEachChild(node, count);\n };\n // count() on the body node itself (not just children): an arrow's\n // expression body may BE the decision point (`x => x ? a : b`). A body is\n // never itself a named function, so the skip guard cannot short-circuit it.\n if (fn.body) count(fn.body);\n return { score, callees };\n };\n\n const visit = (node: import('typescript').Node): void => {\n const fnName = namedFunctionName(node);\n if (fnName && (node as { body?: import('typescript').Node }).body) {\n const facts = collectFunctionFacts(node as { body?: import('typescript').Node } & import('typescript').Node);\n complexity.set(fnName, Math.max(complexity.get(fnName) ?? 0, facts.score));\n const set = calls.get(fnName) ?? new Set<string>();\n for (const c of facts.callees) set.add(c);\n calls.set(fnName, set);\n }\n if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node)\n || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node) || ts.isModuleDeclaration(node)) {\n const name = node.name && ts.isIdentifier(node.name) ? node.name.text : undefined;\n if (name) {\n declared.add(name);\n if (hasExportModifier(node)) exported.add(name);\n }\n } else if (ts.isVariableStatement(node)) {\n const isExported = hasExportModifier(node);\n const isMutable = (node.declarationList.flags & ts.NodeFlags.Const) === 0;\n const atModuleScope = node.parent === sf;\n for (const decl of node.declarationList.declarations) {\n addBindingNames(decl.name);\n if (isExported && ts.isIdentifier(decl.name)) exported.add(decl.name.text);\n if (isMutable && atModuleScope && ts.isIdentifier(decl.name)) mutableBindings.add(decl.name.text);\n }\n } else if (ts.isVariableDeclaration(node)) {\n // nested declarations (inside functions) — parameters are deliberately excluded\n addBindingNames(node.name);\n } else if (ts.isMethodDeclaration(node) || ts.isMethodSignature(node) || ts.isPropertyDeclaration(node)\n || ts.isPropertySignature(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node)\n || ts.isPropertyAssignment(node)) {\n const name = propertyNameText(node.name);\n if (name) declared.add(name);\n } else if (ts.isShorthandPropertyAssignment(node)) {\n declared.add(node.name.text);\n } else if (ts.isImportDeclaration(node)) {\n const clause = node.importClause;\n // Type-only imports never form a dependency edge (type coupling is\n // allowed by default) — but their bindings still anchor declarations.\n const typeOnly = clause?.isTypeOnly ?? false;\n if (!typeOnly && ts.isStringLiteral(node.moduleSpecifier)) imports.add(node.moduleSpecifier.text);\n if (clause?.name) declared.add(clause.name.text);\n if (clause?.namedBindings) {\n if (ts.isNamespaceImport(clause.namedBindings)) declared.add(clause.namedBindings.name.text);\n else for (const el of clause.namedBindings.elements) declared.add(el.name.text);\n }\n } else if (ts.isExportDeclaration(node)) {\n const spec = node.moduleSpecifier && ts.isStringLiteral(node.moduleSpecifier) ? node.moduleSpecifier.text : undefined;\n if (spec) reexports.add(spec);\n if (node.exportClause && ts.isNamedExports(node.exportClause)) {\n for (const el of node.exportClause.elements) {\n declared.add(el.name.text);\n exported.add(el.name.text);\n }\n } else if (!node.exportClause && spec) {\n starExports.push(spec);\n }\n } else if (ts.isExportAssignment(node)) {\n exported.add('default');\n } else if (ts.isCallExpression(node)) {\n const expr = node.expression;\n const isRequire = ts.isIdentifier(expr) && expr.text === 'require';\n const isDynamicImport = expr.kind === ts.SyntaxKind.ImportKeyword;\n if ((isRequire || isDynamicImport) && node.arguments.length > 0 && ts.isStringLiteral(node.arguments[0])) {\n imports.add((node.arguments[0] as import('typescript').StringLiteral).text);\n }\n } else if (ts.isStringLiteral(node) || ts.isNoSubstitutionTemplateLiteral(node)) {\n anchors.add(node.text);\n } else if (ts.isPropertyAccessExpression(node)) {\n // `specs.loadComponentSpecs()` — a property-access reference is a weak\n // anchor: real usage of the name (forwarding adapters, namespace\n // dispatch) without a local declaration.\n anchors.add(node.name.text);\n }\n ts.forEachChild(node, visit);\n };\n visit(sf);\n\n return { declared, anchors, exported, imports, reexports, starExports, complexity, calls, mutableBindings };\n}\n\n/** Resolve a relative export-* specifier to a real file (.js → .ts mapping, index files). */\nfunction resolveRelativeModule(fromFile: string, specifier: string): string | null {\n if (!specifier.startsWith('.')) return null;\n const base = path.resolve(path.dirname(fromFile), specifier);\n const candidates = [\n base,\n base.replace(/\\.js$/, '.ts'), base.replace(/\\.js$/, '.tsx'),\n `${base}.ts`, `${base}.tsx`, `${base}.js`,\n path.join(base, 'index.ts'), path.join(base, 'index.js'),\n ];\n for (const c of candidates) {\n try {\n if (fs.statSync(c).isFile()) return c;\n } catch { /* not this candidate */ }\n }\n return null;\n}\n\n/**\n * Chase `export *` barrels: merge the (transitive) exported names of every\n * relative star-export target into the facts, so a pure re-export barrel like\n * core_portal's index.ts realizes the names it publishes.\n */\nfunction chaseStarExports(\n ts: TsModule,\n facts: ExactFacts,\n filePath: string,\n projectRoot: string,\n visited: Set<string>,\n exactCache: Map<string, ExactFacts | null>,\n): void {\n for (const spec of facts.starExports) {\n const target = resolveRelativeModule(filePath, spec);\n if (!target || visited.has(target)) continue;\n // containment: never chase outside the analyzed project\n if (path.relative(projectRoot, target).startsWith('..')) continue;\n visited.add(target);\n\n let targetFacts = exactCache.get(target);\n if (targetFacts === undefined) {\n try {\n targetFacts = walkExact(ts, fs.readFileSync(target, 'utf8'), target);\n } catch {\n targetFacts = null;\n }\n exactCache.set(target, targetFacts);\n }\n if (!targetFacts) continue;\n chaseStarExports(ts, targetFacts, target, projectRoot, visited, exactCache);\n for (const name of targetFacts.exported) {\n facts.exported.add(name);\n facts.declared.add(name);\n // A pure re-export barrel realizes the function it publishes — carry the\n // real function's complexity and callees onto the barrel so the\n // detail-sufficiency and call-realization checks see through the hop.\n const c = targetFacts.complexity.get(name);\n if (c !== undefined) facts.complexity.set(name, Math.max(facts.complexity.get(name) ?? 0, c));\n const targetCalls = targetFacts.calls.get(name);\n if (targetCalls) {\n const set = facts.calls.get(name) ?? new Set<string>();\n for (const callee of targetCalls) set.add(callee);\n facts.calls.set(name, set);\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// The adapter entry point\n// ---------------------------------------------------------------------------\n\nfunction looksBinary(buffer: Buffer): boolean {\n const probe = buffer.subarray(0, Math.min(buffer.length, 4096));\n return probe.includes(0);\n}\n\n/**\n * Build the pure source-code model for a validation run: one SourceFileFacts\n * per distinct sourcePath across the given implementations, resolved and\n * containment-checked within projectRoot, analyzed at the best available\n * grade. Deterministic over file contents; a single file's analysis failure\n * degrades that file to the generic scan, never aborts the run.\n */\nexport function buildCodeModel(implementations: ImplementationSpec[], projectRoot: string): CodeModel {\n const files: SourceFileFacts[] = [];\n const seen = new Set<string>();\n const exactCache = new Map<string, ExactFacts | null>();\n\n // simPath files are analyzed alongside sourcePaths: the integration-\n // conformance rule needs their import graphs to prove the harness wires\n // the real modules. Same containment, same tiers, same dedup (N:1).\n const declaredPaths: string[] = [];\n for (const impl of implementations) {\n if (impl.sourcePath) declaredPaths.push(impl.sourcePath);\n if (impl.simPath) declaredPaths.push(impl.simPath);\n }\n for (const declared of declaredPaths) {\n const sourcePath = normalizeSourcePath(declared);\n if (seen.has(sourcePath)) continue;\n seen.add(sourcePath);\n\n const empty = { declaredNames: [], anchoredNames: [], exportedNames: [], imports: [], reexports: [] };\n\n // Containment: sourcePaths are project-relative — absolute paths and\n // parent-directory escapes never touch the filesystem (mirrors the\n // projectPath chaining containment rule).\n if (path.isAbsolute(sourcePath) || path.normalize(sourcePath).split(path.sep)[0] === '..') {\n files.push({ path: sourcePath, status: 'escaped', ...empty });\n continue;\n }\n\n const absolute = path.resolve(projectRoot, sourcePath);\n if (path.relative(projectRoot, absolute).startsWith('..')) {\n files.push({ path: sourcePath, status: 'escaped', ...empty });\n continue;\n }\n\n let buffer: Buffer;\n try {\n const stat = fs.statSync(absolute);\n if (!stat.isFile()) {\n files.push({ path: sourcePath, status: 'missing', ...empty });\n continue;\n }\n buffer = fs.readFileSync(absolute);\n } catch {\n files.push({ path: sourcePath, status: 'missing', ...empty });\n continue;\n }\n\n if (looksBinary(buffer)) {\n files.push({ path: sourcePath, status: 'unreadable', ...empty });\n continue;\n }\n\n const text = buffer.toString('utf8');\n const language = EXTENSION_LANGUAGE[path.extname(sourcePath).toLowerCase()];\n\n let analyzed: Omit<SourceFileFacts, 'path' | 'status' | 'language'>;\n if (language === 'typescript' || language === 'javascript') {\n const ts = resolveTypeScript(projectRoot);\n if (ts) {\n try {\n const facts = walkExact(ts, text, absolute);\n chaseStarExports(ts, facts, absolute, projectRoot, new Set([absolute]), exactCache);\n analyzed = {\n analysisGrade: 'exact',\n declaredNames: [...facts.declared],\n anchoredNames: [...facts.anchors],\n exportedNames: [...facts.exported],\n imports: [...facts.imports],\n reexports: [...facts.reexports],\n functionComplexity: Object.fromEntries(facts.complexity),\n functionCalls: Object.fromEntries([...facts.calls].map(([k, v]) => [k, [...v]])),\n topLevelMutableBindings: [...facts.mutableBindings],\n };\n } catch {\n analyzed = analyzeGeneric(text);\n }\n } else {\n analyzed = analyzeWithPatterns(text, LANGUAGE_PATTERNS[language]);\n }\n } else if (language && LANGUAGE_PATTERNS[language] && text.length <= PATTERN_ANALYSIS_MAX_BYTES) {\n analyzed = analyzeWithPatterns(text, LANGUAGE_PATTERNS[language]);\n } else {\n // unknown language, or a file too large for regex tables (generated/\n // minified) — the linear word scan is the safe floor either way\n analyzed = analyzeGeneric(text);\n }\n\n files.push({ path: sourcePath, status: 'analyzed', language, ...analyzed });\n }\n\n return { files, projectRoot };\n}\n","import type { SourceFileFacts } from '../source-analysis.js';\nimport { normalizeSourcePath } from '../source-analysis.js';\nimport { RuleContext, SddRule } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Structural conformance (code↔spec Level 1)\n//\n// The spec tree names real files (L4 sourcePath) and real contract methods\n// (L3); this family checks the code actually honors both. It consumes the\n// pure CodeModel the source analysis adapter builds once per run (injected\n// into the context beside surfaceSnapshots) — the rule itself does no I/O.\n//\n// Realization is tiered per implementation (the conformance dial, mirroring\n// the narrative detail dial):\n// declared — the method name (or its per-method `symbol` override) must be\n// a declaration-tier anchor: a named declaration at any nesting\n// depth, destructuring binding, object-literal key, import\n// binding, or export specifier (barrels resolved).\n// anchored — declared, or an exact string-literal occurrence (tool/route\n// registrations). The stereotype default for Portals.\n// off — method checks skipped (generated/vendored code); the\n// sourcePath existence check always applies.\n//\n// N:1 is native: many implementations may share one file, and one anchor\n// satisfies every component that declares that method name — telling WHICH\n// component a symbol serves is Level 3's job.\n//\n// Implementations owned by a chained subsystem (any projectPath along its\n// namespace chain) are skipped: their sourcePaths are relative to the child\n// project's root, and the child validates them standalone in its own run.\n// ---------------------------------------------------------------------------\n\nexport type ConformanceTier = 'declared' | 'anchored' | 'off';\n\nexport function stereotypeDefaultTier(componentType: string): ConformanceTier {\n return componentType === 'Portal' ? 'anchored' : 'declared';\n}\n\nexport function isInChainedSubproject(subsystemId: string, ctx: RuleContext): boolean {\n const segments = subsystemId.split('::');\n let prefix = '';\n for (const segment of segments) {\n prefix = prefix ? `${prefix}::${segment}` : segment;\n const sub = ctx.subsystems.find(s => s.id === prefix);\n if (sub?.projectPath) return true;\n }\n return false;\n}\n\ninterface FactsLookup {\n declared: Set<string>;\n anchored: Set<string>;\n facts: SourceFileFacts;\n}\n\nexport const structuralConformanceRule: SddRule = {\n name: 'structural-conformance',\n description:\n 'Code↔spec Level 1: every L4 sourcePath must resolve to a real file inside the project root, and every L3 contract method must be realized in that file at the implementation\\'s conformance tier (declared | anchored | off; Portals default to anchored, everything else to declared; per-method `symbol` maps intent-language names to code names). Findings carry the analysis grade (exact AST | pattern table | generic scan) so weaker analysis is visible. Implementations under chained subsystems (projectPath) validate standalone in their own project run and are skipped here.',\n codes: [\n { code: 'MISSING_SOURCE_PATH', defaultSeverity: 'warning', summary: 'An implementation spec declares no sourcePath — structural conformance cannot link it to code' },\n { code: 'MISSING_SOURCE_FILE', defaultSeverity: 'error', summary: 'An L4 sourcePath does not resolve to a file on disk' },\n { code: 'SOURCE_PATH_ESCAPES_ROOT', defaultSeverity: 'error', summary: 'An L4 sourcePath is absolute or escapes the project root (containment refusal)' },\n { code: 'UNREALIZED_METHOD', defaultSeverity: 'warning', summary: 'An L3 contract method has no anchor in its implementation\\'s source file at the required conformance tier' },\n { code: 'CONFORMANCE_ANALYSIS_SKIPPED', defaultSeverity: 'warning', summary: 'A source file could not be analyzed (binary/unreadable) — method realization was not checked' },\n { code: 'CONFORMANCE_DEGRADED', defaultSeverity: 'warning', summary: 'TypeScript/JavaScript files were analyzed below exact grade (compiler not resolvable) — dependency conformance skips them' },\n ],\n\n check(ctx: RuleContext): void {\n const lookups = new Map<string, FactsLookup>();\n for (const facts of ctx.codeModel.files) {\n lookups.set(normalizeSourcePath(facts.path), {\n declared: new Set([...facts.declaredNames, ...facts.exportedNames]),\n anchored: new Set([...facts.declaredNames, ...facts.exportedNames, ...facts.anchoredNames]),\n facts,\n });\n }\n\n // A silently degraded gate is worse than a degraded gate: when ts/js files\n // could not be analyzed at exact grade the compiler was not resolvable —\n // structural anchors stay honest (grade is on each finding), but dependency\n // conformance SKIPS those files entirely. Surface that once per run.\n const degradedTsFiles = ctx.codeModel.files.filter(\n f => f.status === 'analyzed'\n && (f.language === 'typescript' || f.language === 'javascript')\n && f.analysisGrade !== 'exact',\n );\n if (degradedTsFiles.length > 0) {\n ctx.addIssue(\n 'warning',\n 'CONFORMANCE_DEGRADED',\n `${degradedTsFiles.length} TypeScript/JavaScript source file(s) were analyzed below exact grade — the TypeScript compiler could not be resolved from the analyzed project or the wairon installation. Structural findings carry their grade, but dependency conformance skips these files. Install \"typescript\" in the analyzed project to restore exact analysis.`,\n );\n }\n\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n if (!contract) continue;\n const component = ctx.componentMap.get(contract.component);\n if (!component) continue;\n if (isInChainedSubproject(component.subsystem, ctx)) continue;\n\n const draft = ctx.isImplementationDraft(impl);\n\n if (!impl.sourcePath) {\n ctx.addIssue(\n 'warning',\n 'MISSING_SOURCE_PATH',\n `Implementation \"${impl.id}\" declares no sourcePath — its contract \"${impl.contract}\" cannot be structurally checked against code.`,\n impl.id,\n draft,\n );\n continue;\n }\n\n const lookup = lookups.get(normalizeSourcePath(impl.sourcePath));\n if (!lookup) continue; // no code model for this path (context built without one)\n\n const { facts } = lookup;\n if (facts.status === 'escaped') {\n ctx.addIssue(\n 'error',\n 'SOURCE_PATH_ESCAPES_ROOT',\n `Implementation \"${impl.id}\" sourcePath \"${impl.sourcePath}\" is absolute or escapes the project root — sourcePaths must stay inside the project.`,\n impl.id,\n draft,\n );\n continue;\n }\n if (facts.status === 'missing') {\n ctx.addIssue(\n 'error',\n 'MISSING_SOURCE_FILE',\n `Implementation \"${impl.id}\" sourcePath \"${impl.sourcePath}\" does not resolve to a file — the spec names code that does not exist.`,\n impl.id,\n draft,\n );\n continue;\n }\n if (facts.status === 'unreadable') {\n ctx.addIssue(\n 'warning',\n 'CONFORMANCE_ANALYSIS_SKIPPED',\n `Implementation \"${impl.id}\" sourcePath \"${impl.sourcePath}\" could not be analyzed (binary or unreadable) — method realization was not checked.`,\n impl.id,\n draft,\n );\n continue;\n }\n\n const specTier = (impl.conformance as ConformanceTier | undefined)\n ?? stereotypeDefaultTier(component.componentType);\n\n for (const method of contract.methods) {\n const methodImpl = impl.methods.find(m => m.name === method.name);\n const tier = (methodImpl?.conformance as ConformanceTier | undefined) ?? specTier;\n if (tier === 'off') continue;\n\n const symbol = methodImpl?.symbol ?? method.name;\n const inDeclared = lookup.declared.has(symbol);\n const inAnchored = inDeclared || lookup.anchored.has(symbol);\n const realized = tier === 'declared' ? inDeclared : inAnchored;\n if (realized) continue;\n\n const label = methodImpl?.symbol ? `\"${method.name}\" (symbol \"${symbol}\")` : `\"${method.name}\"`;\n const weakHint = tier === 'declared' && inAnchored\n ? ' Only a weak string/word anchor exists — declare the symbol, map it via a per-method `symbol`, or dial this method to `anchored`.'\n : '';\n ctx.addIssue(\n 'warning',\n 'UNREALIZED_METHOD',\n `Method ${label} of contract \"${impl.contract}\" is not realized in \"${impl.sourcePath}\" at the \"${tier}\" tier (analysis grade: ${facts.analysisGrade}).${weakHint}`,\n impl.id,\n draft,\n );\n }\n }\n },\n};\n","import { DocumentationRuleConfig, ComplexityRuleConfig } from '../../models/index.js';\nimport { RuleContext, SddRule } from './types.js';\n\nfunction extensionProfileFor(ctx: RuleContext, subsystemId?: string) {\n const sub = subsystemId ? ctx.subsystems.find(s => s.id === subsystemId) : undefined;\n const profile = sub?.profile || ctx.projectType;\n return ctx.ext.profiles[profile];\n}\n\nfunction getEffectiveDocConfig(ctx: RuleContext, subsystemId?: string): DocumentationRuleConfig | undefined {\n const projectDoc = ctx.rules?.documentation;\n const packDef = extensionProfileFor(ctx, subsystemId);\n \n if (packDef?.rules?.documentation) {\n return { ...projectDoc, ...packDef.rules.documentation };\n }\n return projectDoc;\n}\n\nexport function getEffectiveComplexityConfig(ctx: RuleContext, subsystemId?: string): ComplexityRuleConfig | undefined {\n const projectComp = ctx.rules?.complexity;\n const packDef = extensionProfileFor(ctx, subsystemId);\n \n if (packDef?.rules?.complexity) {\n return { ...projectComp, ...packDef.rules.complexity };\n }\n return projectComp;\n}\n\nfunction checkDescription(\n ctx: RuleContext,\n desc: string | undefined,\n required: boolean,\n minLength: number | undefined,\n specId: string,\n typeName: string,\n isDraft: boolean\n) {\n if (required && (!desc || desc.trim().length === 0)) {\n ctx.addIssue(\n 'warning',\n 'MISSING_DESCRIPTION',\n `${typeName} \"${specId}\" is missing a required description.`,\n specId,\n isDraft\n );\n return;\n }\n if (desc && minLength && desc.trim().length < minLength) {\n ctx.addIssue(\n 'warning',\n 'DESCRIPTION_TOO_SHORT',\n `${typeName} \"${specId}\" description is too short (${desc.trim().length} chars, min ${minLength}).`,\n specId,\n isDraft\n );\n }\n}\n\nexport const complexityRule: SddRule = {\n name: 'complexity-and-metadata',\n description:\n 'Enforces metadata documentation completeness (checking if descriptions are missing or too short) and structural complexity caps (limits on methods per interface, dependencies per component, and narrative steps per method) configured globally or in architectural profiles.',\n codes: [\n { code: 'MISSING_DESCRIPTION', defaultSeverity: 'warning', summary: 'Required description field is missing or empty' },\n { code: 'DESCRIPTION_TOO_SHORT', defaultSeverity: 'warning', summary: 'Description is shorter than the configured minimum length' },\n { code: 'EXCESSIVE_METHODS', defaultSeverity: 'warning', summary: 'Interface declares more methods than the configured limit' },\n { code: 'EXCESSIVE_METHOD_PARAMS', defaultSeverity: 'warning', summary: 'Interface method declares more parameters than the configured limit' },\n { code: 'EXCESSIVE_DEPENDENCIES', defaultSeverity: 'warning', summary: 'Component has more dependencies than the configured limit' },\n { code: 'EXCESSIVE_NARRATIVE_STEPS', defaultSeverity: 'warning', summary: 'Method implementation contains more narrative steps than the configured limit' },\n { code: 'EXCESSIVE_SUBSYSTEM_COMPONENTS', defaultSeverity: 'warning', summary: 'Subsystem has more direct components than the configured limit' },\n ],\n check(ctx) {\n // 1. Subsystems (Doc checks)\n for (const sub of ctx.subsystems) {\n const docConfig = getEffectiveDocConfig(ctx, sub.id);\n checkDescription(ctx, sub.description, docConfig?.requireDescriptions ?? false, docConfig?.minDescriptionLength, sub.id, 'Subsystem', false);\n\n const complexityConfig = getEffectiveComplexityConfig(ctx, sub.id);\n const directComponents = ctx.components.filter(c => c.subsystem === sub.id).length;\n if (complexityConfig?.maxSubsystemComponents !== undefined && directComponents > complexityConfig.maxSubsystemComponents) {\n ctx.addIssue(\n 'warning',\n 'EXCESSIVE_SUBSYSTEM_COMPONENTS',\n `Subsystem \"${sub.id}\" has ${directComponents} direct components, exceeding the configured limit of ${complexityConfig.maxSubsystemComponents}.`,\n sub.id,\n );\n }\n }\n\n // 2. Components (Doc & Complexity checks)\n for (const comp of ctx.components) {\n const docConfig = getEffectiveDocConfig(ctx, comp.subsystem);\n const complexityConfig = getEffectiveComplexityConfig(ctx, comp.subsystem);\n const isDraft = ctx.isComponentDraft(comp.id);\n\n checkDescription(\n ctx,\n comp.description,\n docConfig?.requireDescriptions ?? false,\n docConfig?.minDescriptionLength,\n comp.id,\n 'Component',\n isDraft\n );\n\n if (complexityConfig?.maxComponentDependencies !== undefined && comp.dependsOn.length > complexityConfig.maxComponentDependencies) {\n ctx.addIssue(\n 'warning',\n 'EXCESSIVE_DEPENDENCIES',\n `Component \"${comp.id}\" has ${comp.dependsOn.length} dependencies, exceeding the configured limit of ${complexityConfig.maxComponentDependencies}.`,\n comp.id,\n isDraft\n );\n }\n }\n\n // 3. Interfaces & Methods (Doc & Complexity checks)\n for (const intf of ctx.interfaces) {\n const comp = ctx.componentMap.get(intf.component);\n const docConfig = getEffectiveDocConfig(ctx, comp?.subsystem);\n const complexityConfig = getEffectiveComplexityConfig(ctx, comp?.subsystem);\n const isDraft = ctx.isComponentDraft(intf.component) || intf.status === 'draft' || intf.status === 'design';\n\n checkDescription(\n ctx,\n intf.description,\n docConfig?.requireDescriptions ?? false,\n docConfig?.minDescriptionLength,\n intf.id,\n 'Interface',\n isDraft\n );\n\n if (complexityConfig?.maxInterfaceMethods !== undefined && intf.methods.length > complexityConfig.maxInterfaceMethods) {\n ctx.addIssue(\n 'warning',\n 'EXCESSIVE_METHODS',\n `Interface \"${intf.id}\" declares ${intf.methods.length} methods, exceeding the configured limit of ${complexityConfig.maxInterfaceMethods}.`,\n intf.id,\n isDraft\n );\n }\n\n for (const m of intf.methods) {\n checkDescription(\n ctx,\n m.description,\n docConfig?.requireMethodDescriptions ?? false,\n docConfig?.minDescriptionLength,\n `${intf.id}.${m.name}`,\n 'Interface method',\n isDraft\n );\n\n const paramCount = (m.params ?? []).length;\n if (complexityConfig?.maxMethodParams !== undefined && paramCount > complexityConfig.maxMethodParams) {\n ctx.addIssue(\n 'warning',\n 'EXCESSIVE_METHOD_PARAMS',\n `Method \"${m.name}\" on interface \"${intf.id}\" declares ${paramCount} parameters, exceeding the configured limit of ${complexityConfig.maxMethodParams}.`,\n intf.id,\n isDraft\n );\n }\n }\n }\n\n // 4. Implementations (Complexity checks)\n for (const impl of ctx.implementations) {\n const intf = ctx.interfaceMap.get(impl.contract);\n const comp = intf ? ctx.componentMap.get(intf.component) : undefined;\n const complexityConfig = getEffectiveComplexityConfig(ctx, comp?.subsystem);\n const isDraft = impl.status === 'draft' || impl.status === 'design';\n\n if (complexityConfig?.maxNarrativeSteps !== undefined) {\n for (const m of impl.methods) {\n if (m.narrative.length > complexityConfig.maxNarrativeSteps) {\n ctx.addIssue(\n 'warning',\n 'EXCESSIVE_NARRATIVE_STEPS',\n `Method \"${m.name}\" in implementation \"${impl.id}\" contains ${m.narrative.length} narrative steps, exceeding the configured limit of ${complexityConfig.maxNarrativeSteps}.`,\n impl.id,\n isDraft\n );\n }\n }\n }\n }\n\n // 5. Types (Doc checks)\n for (const t of ctx.types) {\n const docConfig = getEffectiveDocConfig(ctx, t.subsystem);\n\n checkDescription(\n ctx,\n t.description,\n docConfig?.requireDescriptions ?? false,\n docConfig?.minDescriptionLength,\n t.id,\n 'Type',\n false\n );\n\n for (const f of t.fields) {\n checkDescription(\n ctx,\n f.description,\n docConfig?.requireFieldDescriptions ?? false,\n docConfig?.minDescriptionLength,\n `${t.id}.${f.name}`,\n 'Type field',\n false\n );\n }\n\n for (const m of t.methods) {\n checkDescription(\n ctx,\n m.description,\n docConfig?.requireMethodDescriptions ?? false,\n docConfig?.minDescriptionLength,\n `${t.id}.${m.name}`,\n 'Type method',\n false\n );\n }\n }\n },\n};\n","import {\n ComponentSpec,\n ImplementationSpec,\n MethodImplementation,\n NarrativeDetail,\n} from '../../models/index.js';\nimport { normalizeSourcePath, type SourceFileFacts } from '../source-analysis.js';\nimport { isInChainedSubproject, stereotypeDefaultTier } from './conformance.js';\nimport { getEffectiveComplexityConfig } from './complexity.js';\nimport { SddRule } from './types.js';\n\n// ---------------------------------------------------------------------------\n// The narrative detail dial. Levels are FLOORS, not ceilings — extra detail is\n// never penalized. Resolution: method.detail → spec.detail → stereotype\n// default. Stereotype defaults exist so the common case needs zero extra\n// fields: Portals/Adapters are boundary pass-throughs (real logic belongs in\n// the Orchestrator they forward to), and a Store's semantics are a contract\n// paragraph, not choreography.\n// ---------------------------------------------------------------------------\n\n/**\n * The unambiguous LOGIC blocks — where behavior genuinely lives. Deliberately\n * narrower than \"everything defaulting to detail: full\": pattern facades\n * (Repository, Gateway) and presenter/pattern components inherit the full\n * floor but forward to members, so an explicit dial-down there is a normal\n * choice, not a smell worth DETAIL_BELOW_STEREOTYPE.\n */\nconst LOGIC_STEREOTYPES = new Set(['Orchestrator', 'Supervisor', 'Actor', 'Specialist']);\n\nexport function stereotypeDetailDefault(componentType: string | undefined): NarrativeDetail {\n if (componentType === 'Portal' || componentType === 'Observer' || componentType === 'Adapter') {\n return 'calls-only';\n }\n if (componentType === 'Store' || componentType === 'Index' || componentType === 'Registry') {\n return 'intent';\n }\n return 'full';\n}\n\nexport interface ResolvedDetail {\n level: NarrativeDetail;\n /** True when declared on the method or spec (as opposed to a stereotype default). */\n explicit: boolean;\n}\n\nexport function effectiveNarrativeDetail(\n method: MethodImplementation,\n impl: ImplementationSpec,\n component: ComponentSpec | undefined,\n): ResolvedDetail {\n if (method.detail) return { level: method.detail, explicit: true };\n if (impl.detail) return { level: impl.detail, explicit: true };\n return { level: stereotypeDetailDefault(component?.componentType), explicit: false };\n}\n\n// The detail-sufficiency floor: above this cyclomatic complexity a realized\n// function has enough real branching that leaving its method below detail:\n// full (with no narrative) hides logic from every deeper conformance check.\n// Overridable via rules.complexity.maxUnnarratedComplexity.\nexport const DEFAULT_MAX_UNNARRATED_COMPLEXITY = 8;\n\n// The intent floor: prose short enough to be a placeholder cannot specify\n// behavior an implementer could be held to.\nconst INTENT_FLOOR_MIN_CHARS = 40;\n\nexport function passesIntentFloor(text: string | undefined, methodName: string): boolean {\n if (!text) return false;\n const t = text.trim();\n if (t.length < INTENT_FLOOR_MIN_CHARS) return false;\n const norm = (s: string) => s.toLowerCase().replace(/[^a-z0-9]/g, '');\n if (norm(t) === norm(methodName)) return false;\n return true;\n}\n\n/**\n * Enforces that every method carries the detail its declared (or defaulted)\n * level promises: `full` requires a narrative; `intent` (and `calls-only`\n * without any calls to choreograph) requires prose passing the intent floor —\n * the method's L4 `intent`, or failing that its L3 contract description.\n */\nexport const narrativeDetailRule: SddRule = {\n name: 'narrative-detail',\n description:\n 'The narrative detail dial: each method resolves to full | calls-only | intent (method override → spec default → stereotype default). full requires a narrative; intent-level methods without a narrative must specify behavior as non-trivial prose (L4 intent or L3 description) — dialing detail down never means leaving behavior unspecified. Explicit declarations are held to their promise as errors; stereotype-defaulted gaps surface as warnings. Detail sufficiency rides along: a method whose realized function measures real branching (cyclomatic complexity above rules.complexity.maxUnnarratedComplexity, exact AST grade only) may not hide below detail: full without a narrative (UNNARRATED_COMPLEXITY), and an explicit dial below a full-floor logic stereotype without a narrative is a visible, lint.allow-justifiable choice (DETAIL_BELOW_STEREOTYPE). Both are honest lints over declarations — they never claim the narrative or prose is CORRECT.',\n codes: [\n { code: 'MISSING_NARRATIVE', defaultSeverity: 'warning', summary: 'Method resolved to detail: full but has no narrative (error when the level was declared explicitly)' },\n { code: 'INTENT_FLOOR', defaultSeverity: 'warning', summary: 'Intent-level method whose intent/description prose is missing or placeholder-thin (error when declared explicitly)' },\n { code: 'UNNARRATED_COMPLEXITY', defaultSeverity: 'warning', summary: 'Method below detail: full with no narrative whose realized function has real branching (cyclomatic complexity over the configured threshold, exact-grade analysis only)' },\n { code: 'DETAIL_BELOW_STEREOTYPE', defaultSeverity: 'warning', summary: 'Method explicitly dialed below the full narrative floor of its logic stereotype, with no narrative' },\n ],\n check(ctx) {\n const factsByPath = new Map<string, SourceFileFacts>();\n for (const f of ctx.codeModel.files) factsByPath.set(normalizeSourcePath(f.path), f);\n\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n if (!contract) continue;\n const component = ctx.componentMap.get(contract.component);\n\n const isDraftCtx =\n impl.status === 'draft' || impl.status === 'design'\n || contract.status === 'draft' || contract.status === 'design'\n || ctx.isComponentDraft(contract.component);\n\n for (const implMethod of impl.methods) {\n const contractMethod = contract.methods.find(m => m.name === implMethod.name);\n if (!contractMethod) continue; // UNEXPECTED_IMPLEMENTATION_METHOD covers this\n\n const eff = effectiveNarrativeDetail(implMethod, impl, component);\n const hasNarrative = implMethod.narrative.length > 0;\n if (hasNarrative) continue; // floors, not ceilings\n\n if (eff.level === 'full') {\n ctx.addIssue(\n eff.explicit ? 'error' : 'warning',\n 'MISSING_NARRATIVE',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" resolves to detail: full`\n + (eff.explicit ? ' (declared explicitly)' : ` (stereotype default for ${component?.componentType ?? 'component'})`)\n + ' but has no narrative. Write the narrative, or dial the method down (detail: calls-only / intent).',\n impl.id,\n isDraftCtx,\n );\n continue;\n }\n\n // Detail sufficiency (code side): the realized function's measured\n // branching may not hide below detail: full. Exact-grade analysis\n // only — a weaker grade skips rather than guesses. `off` conformance\n // means the name↔symbol mapping is untrusted, so skip that too.\n let complexityFired = false;\n const tier = implMethod.conformance ?? impl.conformance\n ?? stereotypeDefaultTier(component?.componentType ?? '');\n if (impl.sourcePath && tier !== 'off'\n && !(component && isInChainedSubproject(component.subsystem, ctx))) {\n const facts = factsByPath.get(normalizeSourcePath(impl.sourcePath));\n const symbol = implMethod.symbol ?? implMethod.name;\n // Own-property lookup: a method named e.g. \"constructor\" must not\n // resolve to Object.prototype members.\n const complexity = facts?.status === 'analyzed' && facts.analysisGrade === 'exact'\n && facts.functionComplexity\n && Object.prototype.hasOwnProperty.call(facts.functionComplexity, symbol)\n ? facts.functionComplexity[symbol]\n : undefined;\n const limit = getEffectiveComplexityConfig(ctx, component?.subsystem)?.maxUnnarratedComplexity\n ?? DEFAULT_MAX_UNNARRATED_COMPLEXITY;\n if (complexity !== undefined && complexity > limit) {\n complexityFired = true;\n ctx.addIssue(\n 'warning',\n 'UNNARRATED_COMPLEXITY',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" sits at detail: ${eff.level} with no narrative, but its realized function \"${symbol}\" in \"${impl.sourcePath}\" measures cyclomatic complexity ${complexity} (limit ${limit}) — real branching is hiding behind ${eff.level}. Write the narrative, or keep the dial with a lint.allow stating why the branching needs no choreography.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n\n // Detail sufficiency (spec side): explicitly dialing a logic\n // stereotype's method below its full floor is a visible design choice.\n // Skipped when the code-backed finding already fired for this method.\n if (!complexityFired && eff.explicit\n && component && LOGIC_STEREOTYPES.has(component.componentType)) {\n ctx.addIssue(\n 'warning',\n 'DETAIL_BELOW_STEREOTYPE',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" is explicitly dialed to detail: ${eff.level}, below the full narrative floor of its ${component?.componentType ?? 'logic'} stereotype, and has no narrative. Logic behavior belongs in a narrative — write one, or keep the dial with a lint.allow stating why.`,\n impl.id,\n isDraftCtx,\n );\n }\n\n // intent — and calls-only with nothing to choreograph — must clear the\n // intent floor: behavior specified as prose an implementer can follow.\n const prose = implMethod.intent ?? contractMethod.description;\n if (!passesIntentFloor(prose, implMethod.name)) {\n ctx.addIssue(\n eff.explicit ? 'error' : 'warning',\n 'INTENT_FLOOR',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\" has no narrative (detail: ${eff.level}`\n + (eff.explicit ? ', declared explicitly)' : `, stereotype default for ${component?.componentType ?? 'component'})`)\n + ' and its behavioral prose is missing or placeholder-thin. Provide an \"intent\" on the L4 method (or a substantive L3 description) stating what it does and how it fails — or write a narrative.',\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n },\n};\n","import { SddRule } from './types.js';\n\n// Maps a Portal's portalType to the wire `transport` its interface methods must\n// declare on each `endpoint`. Custom is free-form (carries no endpoint obligation).\nexport const PORTAL_TRANSPORT: Record<string, string | undefined> = {\n HTTP_API: 'HTTP', gRPC: 'gRPC', GraphQL: 'GraphQL', MessageBus: 'MessageBus',\n NamedPipe: 'NamedPipe', IPC: 'IPC', CLI: 'CLI', Custom: undefined,\n};\n\n/**\n * Portals are the only components carrying wire concerns: portalType is\n * required, every method needs a matching-transport endpoint, and non-Portal\n * components may not declare endpoints or portal fields at all.\n */\nexport const portalsRule: SddRule = {\n name: 'portal-endpoints',\n description:\n 'A Portal declares its portalType and binds every interface method to a concrete endpoint of the matching transport. Non-Portal components carry no portalType, basePath, or endpoints.',\n codes: [\n { code: 'MISSING_PORTAL_TYPE', defaultSeverity: 'error', summary: 'Portal without a portalType' },\n { code: 'MISSING_ENDPOINT', defaultSeverity: 'error', summary: 'Portal method without a wire endpoint binding' },\n { code: 'ENDPOINT_TRANSPORT_MISMATCH', defaultSeverity: 'error', summary: 'Endpoint transport does not match the Portal portalType' },\n { code: 'UNEXPECTED_PORTAL_FIELD', defaultSeverity: 'error', summary: 'Non-Portal component with portalType/basePath' },\n { code: 'ARCHITECTURE_VIOLATION_NON_PORTAL_ENDPOINT', defaultSeverity: 'error', summary: 'Non-Portal component method declaring an endpoint' },\n ],\n check(ctx) {\n for (const comp of ctx.components) {\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n\n if (comp.componentType === 'Portal') {\n if (!comp.portalType) {\n ctx.addIssue(\n 'error',\n 'MISSING_PORTAL_TYPE',\n `Component \"${comp.id}\" has type \"Portal\" but is missing \"portalType\" field.`,\n comp.id,\n isDraftCtx,\n );\n } else {\n // Generic endpoint check: every Portal whose portalType maps to a\n // transport requires each interface method to declare a concrete\n // `endpoint` of the MATCHING transport. One mechanism for HTTP /\n // gRPC / GraphQL / MessageBus / NamedPipe / IPC / CLI — bound via\n // the generic sdd_set_endpoints tool. Custom carries no obligation.\n const expected = PORTAL_TRANSPORT[comp.portalType];\n if (expected) {\n const compInterfaces = ctx.interfaces.filter(i => i.component === comp.id);\n for (const intf of compInterfaces) {\n const isIntfDraft = intf.status === 'draft' || intf.status === 'design';\n for (const m of intf.methods) {\n if (!m.endpoint) {\n ctx.addIssue(\n 'error',\n 'MISSING_ENDPOINT',\n `Method \"${m.name}\" on interface \"${intf.id}\" (Portal ${comp.portalType}) is missing an \"endpoint\" mapping. Bind it with sdd_set_endpoints (transport \"${expected}\").`,\n intf.id,\n isDraftCtx || isIntfDraft,\n );\n } else if (m.endpoint.transport !== expected) {\n ctx.addIssue(\n 'error',\n 'ENDPOINT_TRANSPORT_MISMATCH',\n `Method \"${m.name}\" on interface \"${intf.id}\" declares a \"${m.endpoint.transport}\" endpoint, but its Portal \"${comp.id}\" is portalType \"${comp.portalType}\" (expects transport \"${expected}\").`,\n intf.id,\n isDraftCtx || isIntfDraft,\n );\n }\n }\n }\n }\n }\n } else {\n if (comp.portalType !== undefined || comp.basePath !== undefined) {\n ctx.addIssue(\n 'error',\n 'UNEXPECTED_PORTAL_FIELD',\n `Component \"${comp.id}\" does not have type \"Portal\" but has \"portalType\" or \"basePath\" configured.`,\n comp.id,\n isDraftCtx,\n );\n }\n\n // Ensure non-portal components do not carry endpoints on their interface methods\n const compInterfaces = ctx.interfaces.filter(i => i.component === comp.id);\n for (const intf of compInterfaces) {\n for (const m of intf.methods) {\n if (m.endpoint) {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_NON_PORTAL_ENDPOINT',\n `Architectural violation: Component \"${comp.id}\" is a ${comp.componentType}, but method \"${m.name}\" on its interface \"${intf.id}\" declares an endpoint. Only Portal components may carry endpoints.`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n }\n },\n};\n","import { SddRule } from './types.js';\nimport { resolveSurfaceRef, isExternalNamespaceRef } from './namespace.js';\n\n// The one shortcut agents reach for when a Store link is refused is the one\n// that must never happen: folding the store's state into the consumer. Say so\n// on every Store-target violation, next to the CORRECT resolution.\nconst NEVER_INLINE_STATE =\n ' Never resolve this by merging the store\\'s state into the consuming component — state hidden inside a logic block is invisible to the spec and unrecoverable.';\n\nconst storeResolutionHint = (consumerType: string, storeId: string): string => {\n if (consumerType === 'Specialist') {\n return ` Resolution: wrap \"${storeId}\" in a Repository pattern (owns: Store + Registry + Index) and depend on that Repository facade instead.${NEVER_INLINE_STATE}`;\n }\n // Portal / Observer / View: even the Repository facade is out of reach —\n // the hop goes through the logic side.\n return ` Resolution: wrap \"${storeId}\" in a Repository pattern and reach it through an Orchestrator that uses the Repository facade.${NEVER_INLINE_STATE}`;\n};\n\n/**\n * The stereotype dependency matrix (intra-subsystem) and the bounded-context\n * boundary rules (cross-subsystem): only a local client Adapter may cross a\n * subsystem boundary, and only into the remote subsystem's published Portal.\n */\nexport const stereotypeDepsRule: SddRule = {\n name: 'stereotype-dependencies',\n description:\n 'Enforces the component-stereotype interaction matrix (Portal reaches the data layer only through Repository/Index READ faces — writes route through Orchestrators (PORTAL_WRITE_SHORTCUT); Stores are depended upon; Registries write their Store; Adapters are sinks; Views stay passive; …) and the cross-subsystem shape: client Adapter → published remote Portal, OR a direct in-process edge licensed by a trustedLink declared on the SOURCE subsystem (the published-Portal target requirement applies either way). A governing pack profile may license intra-subsystem edges the matrix refuses via allowedEdges (its platform idiom, with the stated reason); boundary rules stay unrelaxable.',\n codes: [\n { code: 'INVALID_DEPENDENCY_REFERENCE', defaultSeverity: 'error', summary: 'dependsOn names a non-existent component' },\n { code: 'CROSS_TREE_REF_UNRESOLVED', defaultSeverity: 'warning', summary: 'Cross-tree dependsOn (super::/:: form) with no surface snapshot covering it' },\n { code: 'CROSS_SUBSYSTEM_NON_ADAPTER', defaultSeverity: 'error', summary: 'Non-Adapter component crossing a subsystem boundary' },\n { code: 'CROSS_SUBSYSTEM_PRIVATE_ACCESS', defaultSeverity: 'error', summary: 'Cross-subsystem dependency on an unpublished component' },\n { code: 'CROSS_SUBSYSTEM_TARGET_NON_PORTAL', defaultSeverity: 'error', summary: 'Cross-subsystem hop entering through a non-Portal' },\n { code: 'ARCHITECTURE_VIOLATION_PORTAL_DEP', defaultSeverity: 'error', summary: 'Component depending on a Portal/Observer' },\n { code: 'ARCHITECTURE_VIOLATION_PORTAL_FORBIDDEN_DEP', defaultSeverity: 'error', summary: 'Portal/Observer reaching the data layer directly' },\n { code: 'ARCHITECTURE_VIOLATION_SPECIALIST_DEP', defaultSeverity: 'error', summary: 'Specialist depending on workflow/runtime/state blocks' },\n { code: 'ARCHITECTURE_VIOLATION_STORE_DEP', defaultSeverity: 'error', summary: 'Store depending on anything but another Store or a backend Adapter' },\n { code: 'ARCHITECTURE_VIOLATION_REGISTRY_DEP', defaultSeverity: 'warning', summary: 'Registry depending on anything but its Store, a backend Adapter, or a validation Specialist (warning while new; aligned to the standard §7 validate→write path)' },\n { code: 'ARCHITECTURE_VIOLATION_ADAPTER_DEP', defaultSeverity: 'error', summary: 'Adapter depending on Orchestrators or Stores' },\n { code: 'ARCHITECTURE_VIOLATION_INDEX_DEP', defaultSeverity: 'error', summary: 'Index depending on anything but its Store or an Adapter' },\n { code: 'ARCHITECTURE_VIOLATION_VIEW_DEP', defaultSeverity: 'error', summary: 'View depending on logic/persistence layers' },\n { code: 'PORTAL_WRITE_SHORTCUT', defaultSeverity: 'error', summary: 'Portal narrative calls a write-effect method on a Repository/Index directly — reads may shortcut, writes route through an Orchestrator (judged on effect-tagged facade methods; untagged methods are not yet judged)' },\n ],\n check(ctx) {\n for (const comp of ctx.components) {\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n\n const dependencies = comp.dependsOn;\n for (const depId of dependencies) {\n const depComp = ctx.componentMap.get(depId);\n if (!depComp) {\n // A cross-tree form (super::/::) in a standalone context: resolve\n // against the stored surface snapshots — a hit is a DECLARED remote\n // portal, and the cross-boundary shape rule (source must be an\n // Adapter) applies exactly as it does for cross-subsystem deps.\n if (isExternalNamespaceRef(ctx, depId)) {\n const resolved = resolveSurfaceRef(ctx, depId);\n if (resolved) {\n if (comp.componentType !== 'Adapter') {\n ctx.addIssue(\n 'error',\n 'CROSS_SUBSYSTEM_NON_ADAPTER',\n `Boundary violation: ${comp.componentType} \"${comp.id}\" depends directly on \"${depId}\", a surface of project \"${resolved.snapshot.projectName}\". Only a local client Adapter may cross a project boundary — route this hop through an Adapter.`,\n comp.id,\n isDraftCtx,\n );\n }\n continue;\n }\n ctx.addIssue(\n 'warning',\n 'CROSS_TREE_REF_UNRESOLVED',\n `Component \"${comp.id}\" depends on cross-tree component \"${depId}\", and no surface snapshot covers it — validate from the parent project, or import/generate the producing project's surface.`,\n comp.id,\n isDraftCtx,\n );\n continue;\n }\n ctx.addIssue(\n 'error',\n 'INVALID_DEPENDENCY_REFERENCE',\n `Component \"${comp.id}\" lists dependency \"${depId}\" which does not exist.`,\n comp.id,\n isDraftCtx,\n );\n continue;\n }\n\n // Cross-subsystem boundary: a dependency crossing into another subsystem is\n // governed ONLY by the boundary rules below — the intra-subsystem type matrix\n // does not apply across a bounded-context boundary, where the sanctioned\n // crosser is an Adapter and the target is an explicitly published component.\n if (depComp.subsystem !== comp.subsystem) {\n const crossDraft = isDraftCtx || ctx.isComponentDraft(depComp.id);\n\n // \"Always an Adapter\": only a (local) client Adapter may reach another\n // subsystem; an Orchestrator/etc. must depend on a local Adapter that\n // abstracts the hop (in-process forwarding, REST, gRPC, IPC).\n // EXCEPTION: the SOURCE subsystem may license a direct in-process\n // edge by declaring a trustedLink to the target — the reviewable-\n // exception mechanism instead of a forwarding shim per hop. The\n // published-Portal target requirements below apply regardless, so\n // the distribution seam stays intact at the receiving end.\n const sourceSub = ctx.subsystems.find(s => s.id === comp.subsystem);\n const licensed = sourceSub?.trustedLinks?.some(t => t.subsystem === depComp.subsystem) ?? false;\n if (comp.componentType !== 'Adapter' && !licensed) {\n ctx.addIssue(\n 'error',\n 'CROSS_SUBSYSTEM_NON_ADAPTER',\n `Boundary violation: ${comp.componentType} \"${comp.id}\" (subsystem \"${comp.subsystem}\") depends directly on \"${depComp.id}\" in subsystem \"${depComp.subsystem}\". Only a local client Adapter may cross a subsystem boundary — route this hop through an Adapter that calls \"${depComp.subsystem}\"'s public interface, or declare a trustedLink on \"${comp.subsystem}\" (with the reason) to license a direct in-process edge to that peer's published Portal.`,\n comp.id,\n crossDraft,\n );\n }\n\n // The target must be part of the other subsystem's published public surface,\n // AND that surface must be the subsystem's inbound Portal (its front door) — not\n // a published internal Specialist/Orchestrator/Store. The hop is always:\n // client Adapter → remote Portal → Portal dispatches inward. Allowing a non-Portal\n // target leaks the boundary and breaks the adapter→network→remote-Portal seam.\n const targetIsPublic = ctx.publicSet.get(depComp.subsystem)?.has(depComp.id) ?? false;\n if (!targetIsPublic) {\n ctx.addIssue(\n 'error',\n 'CROSS_SUBSYSTEM_PRIVATE_ACCESS',\n `Boundary violation: \"${comp.id}\" depends on \"${depComp.id}\", which is not part of subsystem \"${depComp.subsystem}\"'s published public surface. Depend on one of its publicInterfaces components instead.`,\n comp.id,\n crossDraft,\n );\n } else if (depComp.componentType !== 'Portal' && depComp.componentType !== 'Gateway') {\n ctx.addIssue(\n 'error',\n 'CROSS_SUBSYSTEM_TARGET_NON_PORTAL',\n `Boundary violation: client Adapter \"${comp.id}\" enters subsystem \"${depComp.subsystem}\" through \"${depComp.id}\" (${depComp.componentType}), not its inbound Portal. A cross-subsystem hop must target the remote subsystem's Portal (its front door), which dispatches inward — publishing/depending on an internal ${depComp.componentType} leaks the boundary and breaks the distribution seam. Expose a Portal for \"${depComp.subsystem}\" and point this Adapter at it.`,\n comp.id,\n crossDraft,\n );\n }\n\n continue;\n }\n\n // Profile edge-deltas: the governing pack profile may LICENSE an\n // intra-subsystem edge the builtin matrix refuses — the platform's\n // own idiom (e.g. an ECS system reading component Stores directly),\n // declared with a reason on the profile. Scoped to the stereotype\n // matrix only: the cross-subsystem boundary rules above and pattern\n // containment/visibility are never relaxable this way.\n const governingProfile = ctx.ext.profiles[ctx.getComponentProfile(comp.id)];\n if (governingProfile?.allowedEdges?.some(e => e.from.includes(comp.componentType) && e.to.includes(depComp.componentType))) {\n continue;\n }\n\n // Check Portal/Observer dependency boundary: components cannot depend on Portals or Observers\n if (depComp.componentType === 'Portal' || depComp.componentType === 'Observer') {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_PORTAL_DEP',\n `Architectural violation: Component \"${comp.id}\" cannot depend on ${depComp.componentType} component \"${depComp.id}\". ${depComp.componentType}s are top-level entry points/subscribers and cannot be dependencies.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n\n // Portal dispatches to Orchestrators, and may READ through Indexes and\n // Repository facades (the per-entity empty-Orchestrator ceremony is\n // not required for passthrough reads) — but its WRITES always route\n // through the workflow layer (PORTAL_WRITE_SHORTCUT below), and the\n // raw data blocks (Store/Registry) plus Adapters stay out of reach.\n // Observer forwards to one Orchestrator/Supervisor and may use a\n // message-bus Adapter to subscribe.\n if (comp.componentType === 'Portal' || comp.componentType === 'Observer') {\n const forbiddenTypes = comp.componentType === 'Portal'\n ? ['Store', 'Registry', 'Adapter']\n : ['Store', 'Registry', 'Repository', 'Index'];\n if (forbiddenTypes.includes(depComp.componentType)) {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_PORTAL_FORBIDDEN_DEP',\n `Architectural violation: ${comp.componentType} component \"${comp.id}\" cannot depend directly on \"${depComp.componentType}\" component \"${depComp.id}\". ${comp.componentType}s coordinate through Orchestrators (and Supervisors); they do not reach the data layer directly.`\n + (depComp.componentType === 'Store' ? storeResolutionHint(comp.componentType, depComp.id) : ''),\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n }\n\n // Specialist rule: narrow capability. It MAY use Repositories, Indexes, and\n // Adapters, but must not own/drive bus, persistence, or runtime concerns.\n if (comp.componentType === 'Specialist') {\n const forbiddenTypes = ['Portal', 'Observer', 'Orchestrator', 'Store', 'Supervisor'];\n if (forbiddenTypes.includes(depComp.componentType)) {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_SPECIALIST_DEP',\n `Architectural violation: Specialist component \"${comp.id}\" cannot depend on \"${depComp.componentType}\" component \"${depComp.id}\". Specialists are narrow capabilities — they may use Repositories, Indexes, and Adapters, but not Orchestrators, Supervisors, Stores, Portals, or Observers.`\n + (depComp.componentType === 'Store' ? storeResolutionHint(comp.componentType, depComp.id) : ''),\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n }\n\n // Store rule: a Store may depend only on another Store or its backend\n // Adapter. It is depended upon by Registries/Indexes — never the\n // reverse (the Registry allowance the code used to carry contradicted\n // both this comment and the standard, and existed only to serve the\n // since-retyped file-backed \"Registries\").\n if (comp.componentType === 'Store') {\n if (depComp.componentType !== 'Store' && depComp.componentType !== 'Adapter') {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_STORE_DEP',\n `Architectural violation: Store component \"${comp.id}\" cannot depend on \"${depComp.componentType}\" component \"${depComp.id}\". Stores may only depend on other Stores or a backend Adapter — Registries and Indexes depend on the Store, never the reverse.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n }\n\n // Registry rule: the write path to its Store — validate → store.write.\n // It may depend on that Store, a backend Adapter, or a validation\n // Specialist (the standard's §7 write path names Specialists\n // explicitly); reaching workflow, read projections, or boundaries\n // inverts the layering. Warning while the check is new.\n if (comp.componentType === 'Registry') {\n if (\n depComp.componentType !== 'Store' &&\n depComp.componentType !== 'Adapter' &&\n depComp.componentType !== 'Specialist'\n ) {\n ctx.addIssue(\n 'warning',\n 'ARCHITECTURE_VIOLATION_REGISTRY_DEP',\n `Architectural violation: Registry component \"${comp.id}\" should not depend on \"${depComp.componentType}\" component \"${depComp.id}\". A Registry is the write path to its Store and may depend only on that Store, a backend Adapter, or a validation Specialist — the Registry never updates Indexes and never drives workflow.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n }\n\n // Adapter rule: Adapter is a sink toward the system; it cannot call Orchestrators or Stores\n if (comp.componentType === 'Adapter') {\n if (depComp.componentType === 'Orchestrator' || depComp.componentType === 'Store') {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_ADAPTER_DEP',\n `Architectural violation: Adapter component \"${comp.id}\" cannot depend on \"${depComp.componentType}\" component \"${depComp.id}\". Adapters cannot depend on Orchestrators or Stores.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n }\n\n // Index rule: a read projection — may depend only on its Store or a backend Adapter.\n if (comp.componentType === 'Index') {\n if (depComp.componentType !== 'Store' && depComp.componentType !== 'Adapter') {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_INDEX_DEP',\n `Architectural violation: Index component \"${comp.id}\" cannot depend on \"${depComp.componentType}\" component \"${depComp.id}\". An Index is a read projection and may depend only on its Store or a backend Adapter.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n }\n\n // View rule: pure presenter block. Decoupled from logical execution and persistence layers.\n if (comp.componentType === 'View') {\n const forbiddenTypes = ['Store', 'Registry', 'Index', 'Adapter', 'Portal', 'Observer', 'Repository', 'Gateway', 'Orchestrator'];\n if (forbiddenTypes.includes(depComp.componentType)) {\n ctx.addIssue(\n 'error',\n 'ARCHITECTURE_VIOLATION_VIEW_DEP',\n `Architectural violation: View component \"${comp.id}\" cannot depend on \"${depComp.componentType}\" component \"${depComp.id}\". Views must remain passive UI blocks and be decoupled from logical layers.`\n + (depComp.componentType === 'Store' ? storeResolutionHint(comp.componentType, depComp.id) : ''),\n comp.id,\n isDraftCtx || ctx.isComponentDraft(depComp.id),\n );\n }\n }\n }\n }\n\n // Portal read-face guard: the Repository/Index shortcut above is licensed\n // for READS only. A Portal narrative call step that hits a write-effect\n // method on a data facade is the persistence shortcut in disguise —\n // writes go through the workflow layer. Untagged methods are not judged\n // (effect tags are the mechanism; MISSING_EFFECT_TAG drives their\n // adoption on durable stores).\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n const component = contract ? ctx.componentMap.get(contract.component) : undefined;\n if (!component || component.componentType !== 'Portal') continue;\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n for (const implMethod of impl.methods) {\n for (const step of implMethod.narrative) {\n if (step.type !== 'call' || !step.targetComponent || !step.targetMethod) continue;\n const target = ctx.componentMap.get(step.targetComponent);\n if (!target || (target.componentType !== 'Repository' && target.componentType !== 'Index')) continue;\n const targetMethod = (ctx.interfacesByComponent.get(target.id) ?? [])\n .flatMap(i => i.methods)\n .find(m => m.name === step.targetMethod);\n if (targetMethod?.effect !== 'write') continue;\n ctx.addIssue(\n 'error',\n 'PORTAL_WRITE_SHORTCUT',\n `Portal \"${component.id}\": step ${step.stepNumber} of \"${implMethod.name}\" calls write-effect method ${target.id}.${step.targetMethod} directly. The Portal→${target.componentType} shortcut is licensed for READS only — route the write through an Orchestrator that owns the workflow.`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(target.id),\n );\n }\n }\n }\n },\n};\n","import { SddRule } from './types.js';\nimport { PATTERN_TYPES } from '../../models/index.js';\n\n/**\n * Pattern ownership: only patterns own member blocks (exactly one hop, one\n * owner), containment matches the pattern's definition, and nobody reaches a\n * block privately owned by another pattern.\n */\nexport const patternsRule: SddRule = {\n name: 'pattern-ownership',\n description:\n 'Patterns (Repository/Gateway/FeatureComponent/RouterComponent) own member blocks with the containment their definition prescribes; blocks own nothing; a member has exactly one owner; and private members are reachable only via their facade or siblings.',\n codes: [\n { code: 'EMPTY_PATTERN', defaultSeverity: 'error', summary: 'Pattern with no owned member blocks' },\n { code: 'BLOCK_OWNS_MEMBERS', defaultSeverity: 'error', summary: 'Building block using owns' },\n { code: 'INVALID_OWNED_MEMBER', defaultSeverity: 'error', summary: 'owns names a non-existent component' },\n { code: 'PATTERN_OWNS_PATTERN', defaultSeverity: 'error', summary: 'Pattern owning another pattern' },\n { code: 'SHARED_OWNED_MEMBER', defaultSeverity: 'error', summary: 'Block owned by two patterns' },\n { code: 'REPOSITORY_CONTAINMENT', defaultSeverity: 'error', summary: 'Repository owning a non Store/Registry/Index/Adapter member' },\n { code: 'GATEWAY_CONTAINMENT', defaultSeverity: 'error', summary: 'Gateway owning a non Portal/Orchestrator/Specialist member' },\n { code: 'FEATURE_COMPONENT_CONTAINMENT', defaultSeverity: 'error', summary: 'FeatureComponent not owning exactly one Orchestrator + one or more Views' },\n { code: 'ROUTER_COMPONENT_CONTAINMENT', defaultSeverity: 'error', summary: 'RouterComponent missing its Portal facade or children' },\n { code: 'VISIBILITY_VIOLATION', defaultSeverity: 'error', summary: 'Dependency on a block privately owned by another pattern' },\n { code: 'UNOWNED_STORE', defaultSeverity: 'warning', summary: 'Store not owned by any pattern — recommended shape is a Repository; a deliberate standalone Store needs a lint.allow' },\n { code: 'REGISTRY_WITHOUT_STORE', defaultSeverity: 'warning', summary: 'Standalone Registry with no Store to write to — either mistyped (a fused file-backed store belongs typed Store) or orphaned' },\n ],\n check(ctx) {\n const ownedBy = new Map<string, string>(); // member block id -> owning pattern id\n for (const comp of ctx.components) {\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n const isPattern = PATTERN_TYPES.has(comp.componentType);\n\n if (isPattern && comp.owns.length === 0) {\n ctx.addIssue('error', 'EMPTY_PATTERN', `Pattern \"${comp.id}\" (${comp.componentType}) must own member blocks via \"owns\".`, comp.id, isDraftCtx);\n }\n if (!isPattern && comp.owns.length > 0) {\n ctx.addIssue('error', 'BLOCK_OWNS_MEMBERS', `Building block \"${comp.id}\" (${comp.componentType}) cannot own members; only patterns (${Array.from(PATTERN_TYPES).join('/')}) use \"owns\".`, comp.id, isDraftCtx);\n }\n\n for (const memberId of comp.owns) {\n const member = ctx.componentMap.get(memberId);\n if (!member) {\n ctx.addIssue('error', 'INVALID_OWNED_MEMBER', `Component \"${comp.id}\" owns \"${memberId}\" which does not exist.`, comp.id, isDraftCtx);\n continue;\n }\n if (PATTERN_TYPES.has(member.componentType)) {\n ctx.addIssue('error', 'PATTERN_OWNS_PATTERN', `Pattern \"${comp.id}\" owns \"${memberId}\", which is itself a pattern. Patterns own only building blocks — compose patterns at the subsystem (L1) level.`, comp.id, isDraftCtx);\n }\n const prev = ownedBy.get(memberId);\n if (prev && prev !== comp.id) {\n ctx.addIssue('error', 'SHARED_OWNED_MEMBER', `Block \"${memberId}\" is owned by both \"${prev}\" and \"${comp.id}\"; a block has exactly one owner.`, comp.id, isDraftCtx);\n }\n ownedBy.set(memberId, comp.id);\n }\n\n // Repository containment: only Store / Registry / Index / Adapter\n if (comp.componentType === 'Repository') {\n const allowed = new Set(['Store', 'Registry', 'Index', 'Adapter']);\n for (const memberId of comp.owns) {\n const t = ctx.componentMap.get(memberId)?.componentType;\n if (t && !allowed.has(t)) {\n ctx.addIssue('error', 'REPOSITORY_CONTAINMENT', `Repository \"${comp.id}\" owns \"${memberId}\" of type ${t}; a Repository may own only Store, Registry, Index, and (optionally) Adapter.`, comp.id, isDraftCtx);\n }\n }\n }\n\n // Gateway containment: only Portal / Orchestrator / Specialist\n if (comp.componentType === 'Gateway') {\n const allowed = new Set(['Portal', 'Orchestrator', 'Specialist']);\n for (const memberId of comp.owns) {\n const t = ctx.componentMap.get(memberId)?.componentType;\n if (t && !allowed.has(t)) {\n ctx.addIssue('error', 'GATEWAY_CONTAINMENT', `Gateway \"${comp.id}\" owns \"${memberId}\" of type ${t}; a Gateway may own only a Portal, Orchestrators, and Specialists.`, comp.id, isDraftCtx);\n }\n }\n }\n\n // FeatureComponent containment: exactly one Orchestrator and one or\n // more Views — a feature slice often has several faces (list, detail,\n // form) sharing the one logic component. A second Orchestrator is a\n // second feature; anything else does not belong inside the slice.\n if (comp.componentType === 'FeatureComponent') {\n let orchestrators = 0;\n let views = 0;\n let others = 0;\n for (const memberId of comp.owns) {\n const t = ctx.componentMap.get(memberId)?.componentType;\n if (t === 'Orchestrator') orchestrators++;\n else if (t === 'View') views++;\n else if (t) others++;\n }\n if (orchestrators !== 1 || views < 1 || others > 0) {\n ctx.addIssue('error', 'FEATURE_COMPONENT_CONTAINMENT', `FeatureComponent \"${comp.id}\" must own exactly one Orchestrator (logic side) and one or more Views (UI faces) — no other member types.`, comp.id, isDraftCtx);\n }\n }\n\n // RouterComponent containment: exactly one Portal facade and at least one other child component/View\n if (comp.componentType === 'RouterComponent') {\n let hasPortal = false;\n let hasChildren = false;\n for (const memberId of comp.owns) {\n const t = ctx.componentMap.get(memberId)?.componentType;\n if (t === 'Portal') hasPortal = true;\n else if (t) hasChildren = true;\n }\n if (!hasPortal) {\n ctx.addIssue('error', 'ROUTER_COMPONENT_CONTAINMENT', `RouterComponent \"${comp.id}\" must own exactly one Portal component to act as its facade.`, comp.id, isDraftCtx);\n }\n if (!hasChildren) {\n ctx.addIssue('error', 'ROUTER_COMPONENT_CONTAINMENT', `RouterComponent \"${comp.id}\" must own at least one child component/View to route to.`, comp.id, isDraftCtx);\n }\n }\n }\n\n // A Store is held state. The RECOMMENDED shape is a Repository (Store +\n // Registry + Index behind one facade); a deliberately standalone Store is\n // the sanctioned LIGHTWEIGHT form for genuinely simple state — visible to\n // the spec, reachable from the workflow layer, acknowledged via\n // lint.allow. What must never happen is the third path: an implementer\n // \"solving\" a refused link by folding the state into the consumer, where\n // no spec, diagram, or conformance check can ever see it again.\n for (const comp of ctx.components) {\n if (comp.componentType !== 'Store' || ownedBy.has(comp.id)) continue;\n ctx.addIssue(\n 'warning',\n 'UNOWNED_STORE',\n `Store \"${comp.id}\" is not owned by any pattern. The recommended shape for held state is a Repository (owns: [\"${comp.id}\", its Registry, its Index]) with consumers on the facade. For genuinely simple state a deliberately standalone Store is the sanctioned lightweight form — keep it visible as this Store, reachable from the workflow layer (Orchestrator/Supervisor/Actor), and acknowledge it with a lint.allow reason. Never take the third path of merging the state into a consuming component: state hidden inside a logic block disappears from the architecture permanently.`,\n comp.id,\n ctx.isComponentDraft(comp.id),\n );\n }\n\n // The symmetric tripwire: a Registry is by definition the WRITE PATH to a\n // Store. Standalone with no Store dependency it is either mistyped (the\n // \"file-backed Registry\" idiom — a fused persistent store that belongs\n // typed Store, where the durability machinery can see it) or orphaned.\n // Repository-owned Registries reach their Store as a sibling member and\n // are exempt from the dependency requirement.\n for (const comp of ctx.components) {\n if (comp.componentType !== 'Registry' || ownedBy.has(comp.id)) continue;\n const hasStoreDep = comp.dependsOn.some(depId => ctx.componentMap.get(depId)?.componentType === 'Store');\n if (hasStoreDep) continue;\n ctx.addIssue(\n 'warning',\n 'REGISTRY_WITHOUT_STORE',\n `Registry \"${comp.id}\" stands alone with no Store to write to. A Registry is the write path to a Store — if this component itself holds the persisted state (a file-backed record/config store), retype it as a Store with the honest durability (read-through for no-RAM-copy file I/O) so the durability machinery can see it; otherwise wire its Store, or lint.allow with a reason.`,\n comp.id,\n ctx.isComponentDraft(comp.id),\n );\n }\n\n // Visibility rule: a component may depend on (a) blocks within its OWN group\n // (it is the owning pattern, or a sibling member of the same pattern), (b) any\n // pattern facade, or (c) a standalone block — never on a block privately owned by\n // ANOTHER pattern.\n for (const comp of ctx.components) {\n for (const depId of comp.dependsOn) {\n const owner = ownedBy.get(depId);\n if (!owner) continue; // dep is a facade or standalone block — fine\n if (owner === comp.id) continue; // the owning pattern depending on its own member — fine\n if (ownedBy.get(comp.id) === owner) continue; // a sibling member of the same group — fine\n ctx.addIssue('error', 'VISIBILITY_VIOLATION', `Component \"${comp.id}\" depends on \"${depId}\", which is privately owned by pattern \"${owner}\". Depend on the facade \"${owner}\" instead.`, comp.id, ctx.isComponentDraft(comp.id) || ctx.isComponentDraft(depId));\n }\n }\n },\n};\n","import type { SddRule } from './types.js';\n\n// ---------------------------------------------------------------------------\n// The facade rule (docs/standards/architecture.md §7): a pattern's facade does\n// PURE 1:1 forwarding — every facade method's authored narrative is exactly\n// one `call` step targeting an owned member block. More than one step, a\n// non-call step, or a call that leaves the pattern means the facade contains\n// logic, and logic belongs inside a member (Registry/Index/Store for a\n// Repository; ingress Orchestrator/Specialists for a Gateway). Scoped to the\n// backend patterns (Repository/Gateway) whose facade semantics §7 defines;\n// methods without an authored narrative are the detail dial's business, not\n// this rule's.\n// ---------------------------------------------------------------------------\n\nconst FACADE_TYPES = new Set(['Repository', 'Gateway']);\n\nexport const facadeForwardingRule: SddRule = {\n name: 'facade-forwarding',\n description:\n 'A Repository/Gateway facade method with an authored narrative must be pure 1:1 forwarding: exactly one call step, targeting one of the pattern\\'s owned members. Anything else is logic living on the facade — move it into a member block, or acknowledge a deliberate exception via lint.allow.',\n codes: [\n { code: 'FACADE_FORWARDING', defaultSeverity: 'warning', summary: 'Pattern facade narrative is not a single call to an owned member' },\n ],\n check(ctx) {\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n if (!contract) continue;\n const comp = ctx.componentMap.get(contract.component);\n if (!comp || !FACADE_TYPES.has(comp.componentType)) continue;\n const owned = new Set(comp.owns);\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n for (const method of impl.methods) {\n const steps = method.narrative ?? [];\n if (steps.length === 0) continue;\n\n let problem: string | undefined;\n if (steps.length !== 1) {\n problem = `has ${steps.length} steps (${steps.map(s => s.type).join(', ')})`;\n } else if (steps[0].type !== 'call') {\n problem = `is a single \"${steps[0].type}\" step, not a call`;\n } else if (steps[0].targetComponent && !owned.has(steps[0].targetComponent)) {\n problem = `forwards outside the pattern — its call targets \"${steps[0].targetComponent}\", which \"${comp.id}\" does not own`;\n }\n if (problem) {\n ctx.addIssue(\n 'warning',\n 'FACADE_FORWARDING',\n `Facade method \"${method.name}\" of ${comp.componentType} \"${comp.id}\" (implementation \"${impl.id}\") must be pure 1:1 forwarding — exactly one call step to an owned member (${comp.owns.join(', ') || 'none declared'}) — but its narrative ${problem}. Move the logic into a member block, or lint.allow a deliberate exception.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n },\n};\n","import { SddRule } from './types.js';\n\n/**\n * Resolves component references to pack-declared reusable patterns. A\n * component's `patterns` entry must name a pattern id that a loaded extension\n * pack declares (UNKNOWN_PATTERN_REF), and a pinned version must match one the\n * pack provides (PATTERN_VERSION_MISMATCH). Core only checks identity and\n * version visibility — the pattern's actual architectural constraints are\n * enforced by the pack's own programmatic rules against this same reference.\n */\nexport const patternReferencesRule: SddRule = {\n name: 'pattern-references',\n description:\n \"Every component pattern reference resolves to a reusable pattern declared by a loaded extension pack (UNKNOWN_PATTERN_REF); a pinned version with no matching pack pattern is warned (PATTERN_VERSION_MISMATCH). Pattern constraint enforcement itself is delegated to the declaring pack's rules.\",\n codes: [\n { code: 'UNKNOWN_PATTERN_REF', defaultSeverity: 'warning', summary: 'Component references a pattern no loaded pack declares' },\n { code: 'PATTERN_VERSION_MISMATCH', defaultSeverity: 'warning', summary: 'Referenced pattern version matches no loaded pack pattern' },\n ],\n check(ctx) {\n // Nothing references a pattern — skip building the index entirely.\n if (!ctx.components.some(c => c.patterns && c.patterns.length > 0)) return;\n\n const versionsById = new Map<string, Set<string>>();\n for (const p of ctx.ext.patterns) {\n const set = versionsById.get(p.id) ?? new Set<string>();\n set.add(p.version);\n versionsById.set(p.id, set);\n }\n\n for (const comp of ctx.components) {\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n for (const ref of comp.patterns ?? []) {\n const versions = versionsById.get(ref.id);\n if (!versions) {\n ctx.addIssue(\n 'warning',\n 'UNKNOWN_PATTERN_REF',\n `Component \"${comp.id}\" references pattern \"${ref.id}\", which no loaded extension pack declares. Install the pack that provides it (or remove the reference).`,\n comp.id,\n isDraftCtx,\n );\n continue;\n }\n if (ref.version && !versions.has(ref.version)) {\n ctx.addIssue(\n 'warning',\n 'PATTERN_VERSION_MISMATCH',\n `Component \"${comp.id}\" pins pattern \"${ref.id}\" version \"${ref.version}\", but the loaded pack provides version(s) ${[...versions].join(', ')}.`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n }\n },\n};\n","import { SddRule } from './types.js';\n\n/**\n * Resolves a component's `variant` against the loaded variant registry. The\n * variant must be declared (UNKNOWN_VARIANT), and the component's stereotype must\n * equal the variant's declared base (VARIANT_BASE_MISMATCH) — a variant is always\n * \"a kind of <base stereotype>\", never a cross-cutting attribute. The base stays\n * authoritative for generic semantics; the variant adds domain vocabulary + a\n * stable rule target + the implementation guidance the implementer reuses across\n * same-variant components.\n */\nexport const variantReferencesRule: SddRule = {\n name: 'component-variants',\n description:\n \"A component's variant resolves to a declared registry variant (UNKNOWN_VARIANT), and the component's stereotype equals the variant's declared base (VARIANT_BASE_MISMATCH). A variant is a base-anchored specialization (a kind of the base stereotype), not a cross-cutting attribute — those stay method guarantees.\",\n codes: [\n { code: 'UNKNOWN_VARIANT', defaultSeverity: 'warning', summary: 'Component references a variant no registry declares' },\n { code: 'VARIANT_BASE_MISMATCH', defaultSeverity: 'error', summary: \"Component's stereotype does not match the variant's declared base\" },\n ],\n check(ctx) {\n if (!ctx.components.some(c => c.variant)) return;\n\n const byId = new Map(ctx.variants.map(v => [v.id, v]));\n\n for (const comp of ctx.components) {\n if (!comp.variant) continue;\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n const def = byId.get(comp.variant);\n if (!def) {\n ctx.addIssue(\n 'warning',\n 'UNKNOWN_VARIANT',\n `Component \"${comp.id}\" declares variant \"${comp.variant}\", which no loaded variant registry declares. Define it under .wai/variants/ or the global variants directory (or remove the reference).`,\n comp.id,\n isDraftCtx,\n );\n continue;\n }\n if (def.base !== comp.componentType) {\n ctx.addIssue(\n 'error',\n 'VARIANT_BASE_MISMATCH',\n `Component \"${comp.id}\" is a ${comp.componentType}, but variant \"${comp.variant}\" specializes base \"${def.base}\". A variant may only be worn by a component of its base stereotype.`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n },\n};\n","import type { ComponentSpec, Endpoint } from '../../models/index.js';\nimport type { AssertionSelector, LoadedAssertion } from '../extensions.js';\nimport type { RuleContext, SddRule, Severity } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Declarative rule assertions (docs/design/declarative-rule-dsl.md): packs\n// contribute INSTANCES of closed assertion kinds — parameters, never logic —\n// so hosted (declarative-only) packs can carry real doctrine. This one rule\n// evaluates every loaded assertion; the finding codes are the packs'\n// namespaced codes, which join knownIssueCodes at context build so\n// lint.allow and sddRuleSeverity treat them exactly like builtins.\n// ---------------------------------------------------------------------------\n\nfunction globToRegExp(glob: string): RegExp {\n const escaped = glob.replace(/[.*+?^${}()|[\\]\\\\]/g, ch => (ch === '*' ? '.*' : `\\\\${ch}`));\n return new RegExp(`^${escaped}$`);\n}\n\nfunction matches(sel: AssertionSelector, comp: ComponentSpec, ctx: RuleContext): boolean {\n if (sel.componentType?.length && !sel.componentType.includes(comp.componentType)) return false;\n if (sel.profile?.length && !sel.profile.includes(ctx.getComponentProfile(comp.id))) return false;\n if (sel.id && !globToRegExp(sel.id).test(comp.id)) return false;\n return true;\n}\n\n/** The one address field each transport carries (validated by EndpointSchema). */\nfunction endpointAddress(ep: Endpoint): string {\n switch (ep.transport) {\n case 'HTTP': return ep.path;\n case 'gRPC': return `${ep.service}/${ep.method}`;\n case 'GraphQL': return ep.field;\n case 'MessageBus': return ep.topic;\n case 'NamedPipe': return ep.pipe;\n case 'IPC': return ep.channel;\n case 'CLI': return ep.command;\n case 'Custom': return ep.address;\n }\n}\n\n/** Resolve `field` on a spec: one top-level name, or an `ext.*` path. */\nfunction fieldValue(spec: Record<string, unknown>, field: string): unknown {\n const segments = field.split('.');\n if (segments[0] !== 'ext') {\n return segments.length === 1 ? spec[field] : undefined;\n }\n let cur: unknown = spec.ext;\n for (const seg of segments.slice(1)) {\n if (cur === null || typeof cur !== 'object') return undefined;\n if (!Object.prototype.hasOwnProperty.call(cur, seg)) return undefined;\n cur = (cur as Record<string, unknown>)[seg];\n }\n return cur;\n}\n\nexport const declarativeAssertionsRule: SddRule = {\n name: 'declarative-assertions',\n description:\n 'Evaluates the declarative rule assertions loaded packs declare (forbid-edge / require-field / endpoint-shape) — closed kinds instantiated with pack data, the hosted-safe doctrine channel. Findings carry the pack\\'s namespaced code (<PACK>_<CODE>) and its stated reason; severity is the pack\\'s declaration (project sddRuleSeverity still wins, and error downgrades to warning in draft context).',\n // Static codes are unknown here — packs bring their own. buildRuleContext\n // adds every loaded assertion's fullCode to knownIssueCodes.\n codes: [],\n check(ctx) {\n const assertions: LoadedAssertion[] = ctx.ext.assertions;\n if (!assertions.length) return;\n\n const emit = (a: LoadedAssertion, message: string, specId: string, isDraftCtx: boolean): void => {\n // Pack severity is the default; drafts soften errors (doctrine is\n // completeness-class, and pack codes cannot join the static\n // COMPLETENESS_RULES set, so the downgrade lives here).\n const severity: Severity = isDraftCtx && a.severity === 'error' ? 'warning' : a.severity;\n ctx.addIssue(severity, a.fullCode, `${message} [pack \"${a.pack}\"]: ${a.reason}`, specId, isDraftCtx);\n };\n\n for (const a of assertions) {\n if (a.kind === 'forbid-edge') {\n for (const comp of ctx.components) {\n if (!matches(a.from, comp, ctx)) continue;\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n for (const relation of a.relation) {\n for (const targetId of comp[relation]) {\n const target = ctx.componentMap.get(targetId);\n if (!target || !matches(a.to, target, ctx)) continue;\n emit(a, `Component \"${comp.id}\" (${comp.componentType}) ${relation === 'owns' ? 'owns' : 'depends on'} \"${target.id}\" (${target.componentType}), forbidden by assertion ${a.code}`, comp.id, isDraftCtx);\n }\n }\n }\n } else if (a.kind === 'require-field') {\n type Holder = { spec: Record<string, unknown>; specId: string; comp: ComponentSpec; draft: boolean };\n const holders: Holder[] = [];\n if (a.level === 'component') {\n for (const c of ctx.components) holders.push({ spec: c as unknown as Record<string, unknown>, specId: c.id, comp: c, draft: ctx.isComponentDraft(c.id) });\n } else if (a.level === 'interface') {\n for (const i of ctx.interfaces) {\n const comp = ctx.componentMap.get(i.component);\n if (comp) holders.push({ spec: i as unknown as Record<string, unknown>, specId: i.id, comp, draft: ctx.isComponentDraft(comp.id) || i.status === 'draft' || i.status === 'design' });\n }\n } else {\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n const comp = contract ? ctx.componentMap.get(contract.component) : undefined;\n if (comp) holders.push({ spec: impl as unknown as Record<string, unknown>, specId: impl.id, comp, draft: ctx.isImplementationDraft(impl) });\n }\n }\n for (const h of holders) {\n if (!matches(a.on, h.comp, ctx)) continue;\n const v = fieldValue(h.spec, a.field);\n if (v === undefined || v === null) {\n emit(a, `${a.level} spec \"${h.specId}\" does not declare \"${a.field}\", required by assertion ${a.code}`, h.specId, h.draft);\n } else if (a.values && !a.values.includes(String(v))) {\n emit(a, `${a.level} spec \"${h.specId}\" declares \"${a.field}\" = \"${String(v)}\", outside the allowed set (${a.values.join(', ')}) of assertion ${a.code}`, h.specId, h.draft);\n }\n }\n } else if (a.kind === 'endpoint-shape') {\n const pattern = a.pathPattern ? new RegExp(a.pathPattern) : undefined;\n for (const intf of ctx.interfaces) {\n const comp = ctx.componentMap.get(intf.component);\n if (!comp || !matches(a.on, comp, ctx)) continue;\n const isDraftCtx = ctx.isComponentDraft(comp.id) || intf.status === 'draft' || intf.status === 'design';\n for (const method of intf.methods) {\n if (!method.endpoint) continue;\n const ep = method.endpoint;\n if (a.transport?.length && !a.transport.includes(ep.transport)) {\n emit(a, `Endpoint of \"${intf.id}.${method.name}\" uses transport ${ep.transport}, outside the allowlist (${a.transport.join(', ')}) of assertion ${a.code}`, intf.id, isDraftCtx);\n continue;\n }\n const address = endpointAddress(ep);\n if (pattern && !pattern.test(address)) {\n emit(a, `Endpoint of \"${intf.id}.${method.name}\" binds \"${address}\", which does not match ${a.pathPattern} required by assertion ${a.code}`, intf.id, isDraftCtx);\n }\n }\n }\n }\n }\n },\n};\n","import { BUILTIN_PROFILES, SddRule } from './types.js';\n\n/**\n * Architectural profile constraints. Built-in profiles carry built-in\n * doctrine (frontend stereotypes stay out of backend-oriented subsystems,\n * PLC-cyclic forbids concurrent stereotypes, backend runtime stereotypes in\n * frontend subsystems get a sanity warning). Extension packs register their\n * own profiles: `family` opts into the built-in fencing, and explicit\n * forbidden/discouraged stereotype lists carry the pack's doctrine with a\n * stated reason. Unregistered profile names are flagged, not guessed at.\n */\nconst BACKEND_LIKE = new Set(['backend', 'lowlevel-os', 'game-ecs', 'realtime-embedded', 'plc-cyclic']);\nconst FRONTEND_LIKE = new Set(['frontend-reactive', 'frontend-controller']);\n/** projectType additionally allows the composite project kinds. */\nconst PROJECT_KINDS = new Set(['fullstack', 'system-of-systems', 'monorepo']);\n\nexport const profilesRule: SddRule = {\n name: 'architectural-profiles',\n description:\n 'Per-profile stereotype constraints: View/FeatureComponent/RouterComponent only in frontend profiles; Actor/Supervisor forbidden in plc-cyclic (single scan cycle); Actor/Supervisor in frontend profiles warned. Extension packs may register custom profiles (family + forbidden/discouraged stereotype lists); unknown profile names are flagged.',\n codes: [\n { code: 'FRONTEND_STEREOTYPE_IN_BACKEND', defaultSeverity: 'error', summary: 'Frontend stereotype in a backend-oriented subsystem' },\n { code: 'PLC_CYCLIC_CONCURRENCY_VIOLATION', defaultSeverity: 'error', summary: 'Concurrent stereotype in a PLC-cyclic profile' },\n { code: 'BACKEND_STEREOTYPE_IN_FRONTEND', defaultSeverity: 'warning', summary: 'Backend runtime stereotype in a frontend subsystem' },\n { code: 'PROFILE_FORBIDDEN_STEREOTYPE', defaultSeverity: 'error', summary: 'Stereotype forbidden by the governing pack-defined profile' },\n { code: 'PROFILE_DISCOURAGED_STEREOTYPE', defaultSeverity: 'warning', summary: 'Stereotype discouraged by the governing pack-defined profile' },\n { code: 'UNKNOWN_PROFILE', defaultSeverity: 'warning', summary: 'Profile name is neither built-in nor registered by an extension pack' },\n ],\n check(ctx) {\n const registered = new Set<string>([...BUILTIN_PROFILES, ...Object.keys(ctx.ext.profiles)]);\n\n for (const sub of ctx.subsystems) {\n if (sub.profile && !registered.has(sub.profile)) {\n ctx.addIssue(\n 'warning',\n 'UNKNOWN_PROFILE',\n `Subsystem \"${sub.id}\" declares profile \"${sub.profile}\", which is neither a built-in profile (${BUILTIN_PROFILES.join(', ')}) nor registered by a loaded extension pack. No profile doctrine is being enforced for it.`,\n sub.id,\n );\n }\n }\n if (!registered.has(ctx.projectType) && !PROJECT_KINDS.has(ctx.projectType)) {\n ctx.addIssue(\n 'warning',\n 'UNKNOWN_PROFILE',\n `projectType \"${ctx.projectType}\" (project.yaml) is neither a built-in profile/kind nor registered by a loaded extension pack. Components default to backend doctrine.`,\n );\n }\n\n for (const comp of ctx.components) {\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n const profile = ctx.getComponentProfile(comp.id);\n const packDef = ctx.ext.profiles[profile];\n const family = packDef\n ? packDef.family\n : FRONTEND_LIKE.has(profile) ? 'frontend-like'\n : BACKEND_LIKE.has(profile) ? 'backend-like'\n : 'neutral'; // unknown profile — already flagged above, no doctrine to guess\n\n if (family === 'backend-like') {\n const frontendTypes = ['View', 'FeatureComponent', 'RouterComponent'];\n if (frontendTypes.includes(comp.componentType)) {\n ctx.addIssue(\n 'error',\n 'FRONTEND_STEREOTYPE_IN_BACKEND',\n `Architectural violation: Component \"${comp.id}\" is a frontend stereotype (${comp.componentType}) but subsystem \"${comp.subsystem}\" is configured as a backend-oriented subsystem.`,\n comp.id,\n isDraftCtx,\n );\n }\n\n // PLC Cyclic specific constraints\n if (profile === 'plc-cyclic') {\n if (comp.componentType === 'Actor' || comp.componentType === 'Supervisor') {\n ctx.addIssue(\n 'error',\n 'PLC_CYCLIC_CONCURRENCY_VIOLATION',\n `Architectural violation: Component \"${comp.id}\" is a concurrent stereotype (${comp.componentType}) which is forbidden in PLC Cyclic profile. PLC logic runs strictly single-threaded within the main execution scan cycle.`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n } else if (family === 'frontend-like') {\n const backendOnlyTypes = ['Supervisor', 'Actor'];\n if (backendOnlyTypes.includes(comp.componentType)) {\n ctx.addIssue(\n 'warning',\n 'BACKEND_STEREOTYPE_IN_FRONTEND',\n `Subsystem \"${comp.subsystem}\" is a frontend subsystem, but component \"${comp.id}\" is a backend stereotype (${comp.componentType}). Ensure this runtime concern is genuinely client-side.`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n\n // Pack-declared doctrine, applied on top of the family fencing.\n if (packDef) {\n for (const rule of packDef.forbiddenStereotypes) {\n if (rule.types.includes(comp.componentType)) {\n ctx.addIssue(\n 'error',\n 'PROFILE_FORBIDDEN_STEREOTYPE',\n `Component \"${comp.id}\" is a ${comp.componentType}, forbidden by profile \"${profile}\": ${rule.reason}`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n for (const rule of packDef.discouragedStereotypes) {\n if (rule.types.includes(comp.componentType)) {\n ctx.addIssue(\n 'warning',\n 'PROFILE_DISCOURAGED_STEREOTYPE',\n `Component \"${comp.id}\" is a ${comp.componentType}, discouraged by profile \"${profile}\": ${rule.reason}`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n },\n};\n","import { SddRule } from './types.js';\n\nconst pubTypeMatches = (piType: string, ct: string, portalType?: string): boolean => {\n switch (piType) {\n case 'REST': return ct === 'Portal' && portalType === 'HTTP_API';\n case 'GraphQL': return ct === 'Portal' && portalType === 'GraphQL';\n case 'RPC': return ct === 'Portal' && portalType === 'gRPC';\n case 'MessageBus': return (ct === 'Portal' && portalType === 'MessageBus') || ct === 'Observer';\n case 'Custom': return true;\n default: return true;\n }\n};\n\n// Strong event/async signal words. Used only to flag a Custom-typed public\n// interface whose prose describes eventing but whose backing component can't\n// realize it (see PUBLIC_INTERFACE_EVENT_MISTYPED below).\n// Verb-form \"subscribe\" signals eventing; the noun \"subscription\" is deliberately\n// omitted — it collides with domain nouns (e.g. billing \"subscription plans\").\nconst EVENT_VOCAB = /\\b(async|asynchronous|queue|queued|queues|event|events|event-driven|listen|listens|listening|listener|subscribe|subscribes|pub\\/sub|stream|streams|streaming|emit|emits|emitted|message[\\s-]?bus)\\b/i;\n\nconst expectedFor = (t: string): string => {\n switch (t) {\n case 'REST': return 'a Portal with portalType HTTP_API';\n case 'GraphQL': return 'a Portal with portalType GraphQL';\n case 'RPC': return 'a Portal with portalType gRPC';\n case 'MessageBus': return 'a Portal with portalType MessageBus, or an Observer';\n default: return 'a compatible component';\n }\n};\n\n/**\n * Public interface binding: each declared publicInterface must be backed by a\n * real component in the SAME subsystem whose type can realize the declared\n * interface. This is what makes \"which components are public\"\n * machine-checkable (and catches a declared interface no component implements).\n */\nexport const publicSurfaceRule: SddRule = {\n name: 'public-surface',\n description:\n 'Every declared publicInterface is bound to an existing component of this subsystem whose stereotype can realize the declared interface type; Custom entries whose prose implies eventing must be backed by an event-capable component.',\n codes: [\n { code: 'PUBLIC_INTERFACE_UNBOUND', defaultSeverity: 'error', summary: 'Public interface with no backing component' },\n { code: 'PUBLIC_INTERFACE_INVALID_COMPONENT', defaultSeverity: 'error', summary: 'Public interface references a non-existent component' },\n { code: 'PUBLIC_INTERFACE_FOREIGN_COMPONENT', defaultSeverity: 'error', summary: 'Subsystem publishing a component it does not own' },\n { code: 'PUBLIC_INTERFACE_TYPE_MISMATCH', defaultSeverity: 'error', summary: 'Backing component cannot realize the declared interface type' },\n { code: 'PUBLIC_INTERFACE_INVALID_INTERFACE', defaultSeverity: 'error', summary: 'Bound L3 interface missing or belonging to another component' },\n { code: 'PUBLIC_INTERFACE_EVENT_MISTYPED', defaultSeverity: 'warning', summary: 'Custom interface describing eventing backed by a non-event component' },\n ],\n check(ctx) {\n for (const sub of ctx.subsystems) {\n const isDraftCtx = sub.status === 'draft' || sub.status === 'design';\n for (const pi of sub.publicInterfaces) {\n if (!pi.component) {\n ctx.addIssue('error', 'PUBLIC_INTERFACE_UNBOUND', `Subsystem \"${sub.id}\" declares a ${pi.type} public interface with no backing component. Bind it to the component that realizes it (publicInterfaces[].component).`, sub.id, isDraftCtx);\n continue;\n }\n const backing = ctx.componentMap.get(pi.component);\n if (!backing) {\n ctx.addIssue('error', 'PUBLIC_INTERFACE_INVALID_COMPONENT', `Subsystem \"${sub.id}\" public interface references component \"${pi.component}\" which does not exist.`, sub.id, isDraftCtx);\n continue;\n }\n const isSubsystemOwner = backing.subsystem === sub.id || backing.subsystem.startsWith(sub.id + '::');\n if (!isSubsystemOwner) {\n ctx.addIssue('error', 'PUBLIC_INTERFACE_FOREIGN_COMPONENT', `Subsystem \"${sub.id}\" publishes component \"${pi.component}\", but it belongs to subsystem \"${backing.subsystem}\". A subsystem may only publish its own components.`, sub.id, isDraftCtx);\n }\n if (!pubTypeMatches(pi.type, backing.componentType, backing.portalType)) {\n ctx.addIssue('error', 'PUBLIC_INTERFACE_TYPE_MISMATCH', `Subsystem \"${sub.id}\" declares a ${pi.type} public interface backed by \"${pi.component}\" (${backing.componentType}${backing.portalType ? `/${backing.portalType}` : ''}), which cannot realize ${pi.type}. Expected ${expectedFor(pi.type)}.`, sub.id, isDraftCtx);\n }\n if (pi.interface) {\n const intf = ctx.interfaceMap.get(pi.interface);\n if (!intf) {\n ctx.addIssue('error', 'PUBLIC_INTERFACE_INVALID_INTERFACE', `Subsystem \"${sub.id}\" public interface references interface \"${pi.interface}\" which does not exist.`, sub.id, isDraftCtx);\n } else if (intf.component !== pi.component) {\n ctx.addIssue('error', 'PUBLIC_INTERFACE_INVALID_INTERFACE', `Subsystem \"${sub.id}\" binds interface \"${pi.interface}\" to component \"${pi.component}\", but that interface belongs to component \"${intf.component}\".`, sub.id, isDraftCtx);\n }\n }\n // Heuristic — closes the \"escape to Custom\" hole. `Custom` is the only public\n // interface type that carries no backing obligation, so an unrealized event\n // boundary can hide there: declare an async queue/event contract as Custom and\n // back it with an ordinary Orchestrator (a synchronous push). The type matrix\n // can't catch that, but the contradiction is legible in the prose — event/async\n // vocabulary in `details` while the backing component cannot actually realize\n // eventing. Warn so the mislabel surfaces; override via rules.sddRuleSeverity.\n if (pi.type === 'Custom' && EVENT_VOCAB.test(pi.details)) {\n const eventCapable = backing.componentType === 'Observer'\n || (backing.componentType === 'Portal' && backing.portalType === 'MessageBus');\n if (!eventCapable) {\n ctx.addIssue('warning', 'PUBLIC_INTERFACE_EVENT_MISTYPED', `Subsystem \"${sub.id}\" declares a Custom public interface whose description implies an event/async boundary (\"${pi.details}\"), but it is backed by \"${pi.component}\" (${backing.componentType}${backing.portalType ? `/${backing.portalType}` : ''}), which cannot realize eventing. If this is genuinely event-driven, type it MessageBus and back it with an Observer or a Portal(MessageBus); otherwise reword the description to match the synchronous contract.`, sub.id, isDraftCtx);\n }\n }\n }\n }\n },\n};\n","import { RuleContext, SddRule } from './types.js';\nimport { BUILTIN_TYPES, extractTypeIdentifiers, extractTypeGenerics, methodTypeRefs, matchTypeRef } from './type-analysis.js';\nimport { effectiveNarrativeDetail } from './narrative-detail.js';\n\n/** Dependency-cycle detection over the component dependsOn graph. */\nexport const cyclesRule: SddRule = {\n name: 'dependency-cycles',\n description: 'The component dependsOn graph must be a DAG; the first detected cycle is reported with its full path.',\n codes: [\n { code: 'CIRCULAR_DEPENDENCY', defaultSeverity: 'error', summary: 'Circular dependency between components' },\n ],\n check(ctx) {\n const visited = new Set<string>();\n const recStack = new Set<string>();\n\n const dfs = (compId: string, pathTrace: string[]): boolean => {\n visited.add(compId);\n recStack.add(compId);\n pathTrace.push(compId);\n\n const comp = ctx.componentMap.get(compId);\n if (comp) {\n for (const depId of comp.dependsOn) {\n if (!visited.has(depId)) {\n if (dfs(depId, pathTrace)) {\n recStack.delete(compId);\n pathTrace.pop();\n return true;\n }\n } else if (recStack.has(depId)) {\n pathTrace.push(depId);\n const cyclePath = pathTrace.slice(pathTrace.indexOf(depId)).join(' -> ');\n const isDraftCtx = ctx.isComponentDraft(compId) || ctx.isComponentDraft(depId);\n ctx.addIssue(\n 'error',\n 'CIRCULAR_DEPENDENCY',\n `Circular dependency detected: ${cyclePath}`,\n compId,\n isDraftCtx,\n );\n pathTrace.pop();\n recStack.delete(compId);\n pathTrace.pop();\n return true;\n }\n }\n }\n\n recStack.delete(compId);\n pathTrace.pop();\n return false;\n };\n\n for (const comp of ctx.components) {\n if (!visited.has(comp.id)) {\n if (dfs(comp.id, [])) {\n break;\n }\n }\n }\n },\n};\n\n// Key with '#': component ids may themselves contain '::' (namespaced subprojects),\n// so '::' cannot separate component from method.\nexport const methodKey = (compId: string, methodName: string): string => `${compId}#${methodName}`;\n\n/** A reachability seed: a specific method, or (methodName omitted) every contract method of the component. */\nexport interface WalkSeed {\n compId: string;\n methodName?: string;\n}\n\n/**\n * The shared narrative-graph walker: BFS over L5 execution edges from a seed\n * set. Edges are `call` steps, `dispatch` steps (routed through the target\n * Portal's dispatch table to the bound capability server), and every dispatch\n * binding of a reached Portal (its declared served surface — the runtime\n * dispatches into those bindings even though no static call names them).\n * Used by unused-detection (roots: Portals/Observers/published components/\n * lifecycle entrypoints) and by the durability round-trip rule (roots:\n * lifecycle init flows only).\n */\nexport interface WalkOptions {\n /**\n * Whether reaching a Portal floods every binding of its dispatch table into\n * the reachable set. TRUE for unused-detection (the table IS the portal's\n * served surface). FALSE for the durability boot-graph: at boot only edges\n * the init narratives actually take count — a capability merely *offered*\n * by a reached portal is not a boot-time read. Explicit `dispatch` steps\n * are followed either way.\n */\n followDispatchTables?: boolean;\n}\n\nexport function walkNarrativeGraph(\n ctx: RuleContext,\n seeds: WalkSeed[],\n opts: WalkOptions = {},\n): { reachedComponents: Set<string>; reachedMethods: Set<string> } {\n const followDispatchTables = opts.followDispatchTables ?? true;\n const reachedComponents = new Set<string>();\n const reachedMethods = new Set<string>();\n const queue: { compId: string; methodName: string }[] = [];\n\n const enqueueMethod = (compId: string, methodName: string): void => {\n const key = methodKey(compId, methodName);\n if (!reachedMethods.has(key)) {\n reachedMethods.add(key);\n queue.push({ compId, methodName });\n }\n };\n\n const reachComponent = (compId: string): void => {\n if (reachedComponents.has(compId)) return;\n reachedComponents.add(compId);\n if (!followDispatchTables) return;\n // A Portal's dispatch table IS its served surface: reaching the portal\n // reaches every capability binding.\n const comp = ctx.componentMap.get(compId);\n for (const b of comp?.dispatch ?? []) {\n if (ctx.componentMap.has(b.component)) {\n reachComponent(b.component);\n enqueueMethod(b.component, b.method);\n }\n }\n };\n\n const enqueueAllMethods = (compId: string): void => {\n for (const intf of ctx.interfacesByComponent.get(compId) ?? []) {\n for (const m of intf.methods) {\n enqueueMethod(compId, m.name);\n }\n }\n };\n\n for (const seed of seeds) {\n reachComponent(seed.compId);\n if (seed.methodName) {\n enqueueMethod(seed.compId, seed.methodName);\n } else {\n enqueueAllMethods(seed.compId);\n }\n }\n\n while (queue.length > 0) {\n const { compId, methodName } = queue.shift()!;\n\n // The method may be implemented against any of the component's interfaces.\n let methodImpl: (typeof ctx.implementations)[number]['methods'][number] | undefined;\n let impl: (typeof ctx.implementations)[number] | undefined;\n for (const intf of ctx.interfacesByComponent.get(compId) ?? []) {\n for (const candidate of ctx.implementationsByContract.get(intf.id) ?? []) {\n const m = candidate.methods.find(mm => mm.name === methodName);\n if (m) { impl = candidate; methodImpl = m; break; }\n }\n if (impl) break;\n }\n if (!impl || !methodImpl) continue;\n\n for (const step of methodImpl.narrative) {\n if (step.type === 'call' && step.targetComponent && step.targetMethod) {\n reachComponent(step.targetComponent);\n enqueueMethod(step.targetComponent, step.targetMethod);\n }\n if (step.type === 'dispatch' && step.targetComponent) {\n reachComponent(step.targetComponent);\n const portal = ctx.componentMap.get(step.targetComponent);\n const binding = portal?.dispatch?.find(b => b.capability === step.capability);\n if (binding && ctx.componentMap.has(binding.component)) {\n reachComponent(binding.component);\n enqueueMethod(binding.component, binding.method);\n }\n }\n }\n\n // Detail-dial fallback: an intent/calls-only method with no narrative\n // contributes no call edges, so walk its component's L2 dependsOn/owns\n // at component granularity (all contract methods) instead — the lower\n // declared fidelity must not false-positive its collaborators as\n // unused. Full-detail methods get NO fallback: their missing narrative\n // is a reported gap (MISSING_NARRATIVE) and unused-detection stays strong.\n if (methodImpl.narrative.length === 0) {\n const comp = ctx.componentMap.get(compId);\n if (comp && effectiveNarrativeDetail(methodImpl, impl, comp).level !== 'full') {\n for (const depId of [...comp.dependsOn, ...comp.owns]) {\n if (!ctx.componentMap.has(depId)) continue;\n reachComponent(depId);\n enqueueAllMethods(depId);\n }\n }\n }\n }\n\n return { reachedComponents, reachedMethods };\n}\n\n/**\n * Reachability analysis from entrypoints (Portals, Observers, published\n * components, declared lifecycle flows): unwired components/methods and\n * unreferenced types are flagged.\n */\nexport const reachabilityRule: SddRule = {\n name: 'unused-detection',\n description:\n 'Walks the narrative execution graph (call steps, dispatch-table routing, lifecycle flows) from every entrypoint (Portal/Observer/published component/lifecycle entrypoint) and flags components and methods no execution chain reaches, plus types no field or signature references.',\n codes: [\n { code: 'UNUSED_COMPONENT', defaultSeverity: 'warning', summary: 'Component never reached by any narrative call chain' },\n { code: 'UNUSED_METHOD', defaultSeverity: 'warning', summary: 'Method never called by any narrative step' },\n { code: 'UNUSED_TYPE', defaultSeverity: 'warning', summary: 'Type never referenced by fields or signatures' },\n ],\n check(ctx) {\n // Collect root entry points: Portals, Observers, components backing public\n // subsystem interfaces (all their methods), and declared lifecycle\n // entrypoints (the specific init/shutdown method the runtime invokes).\n const seeds: WalkSeed[] = [];\n for (const comp of ctx.components) {\n if (comp.componentType === 'Portal' || comp.componentType === 'Observer') {\n seeds.push({ compId: comp.id });\n }\n }\n for (const sub of ctx.subsystems) {\n for (const pi of sub.publicInterfaces) {\n if (pi.component) {\n seeds.push({ compId: pi.component });\n }\n }\n for (const le of sub.lifecycle ?? []) {\n seeds.push({ compId: le.component, methodName: le.method });\n }\n }\n\n const { reachedComponents, reachedMethods } = walkNarrativeGraph(ctx, seeds);\n\n // Generate warnings for unused components\n for (const comp of ctx.components) {\n if (!ctx.isSpecInScope(comp.id)) continue;\n if (!reachedComponents.has(comp.id)) {\n const isDraftCtx = comp.status === 'draft' || comp.status === 'design';\n ctx.addIssue(\n 'warning',\n 'UNUSED_COMPONENT',\n `Component \"${comp.id}\" is defined but never reached by any execution call chain starting from portals or entry points.`,\n comp.id,\n isDraftCtx,\n );\n } else {\n // Warn about unused methods on this reached component (across ALL its interfaces)\n for (const intf of ctx.interfacesByComponent.get(comp.id) ?? []) {\n for (const m of intf.methods) {\n if (!reachedMethods.has(methodKey(comp.id, m.name))) {\n const isDraftCtx = comp.status === 'draft' || comp.status === 'design' || intf.status === 'draft' || intf.status === 'design';\n ctx.addIssue(\n 'warning',\n 'UNUSED_METHOD',\n `Method \"${m.name}\" on component \"${comp.id}\" is defined but never called by any narrative step.`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n }\n\n // Generate warnings for unused types\n const referencedTypes = new Set<string>();\n const markTypeReferenced = (ref: string) => {\n const refLower = ref.toLowerCase();\n if (BUILTIN_TYPES.has(refLower)) return;\n for (const spec of ctx.types) {\n const typeQualifiedId = spec.subsystem && !spec.id.startsWith(`${spec.subsystem}::`)\n ? `${spec.subsystem}::${spec.id}`\n : spec.id;\n if (matchTypeRef(ref, typeQualifiedId)) {\n referencedTypes.add(spec.id);\n }\n }\n };\n\n // 1. Scan type fields\n for (const t of ctx.types) {\n for (const field of t.fields) {\n const refs = extractTypeIdentifiers(field.type);\n for (const ref of refs) {\n const typeGenerics = new Set(\n Array.from(extractTypeGenerics(t.name)).map(g => g.toLowerCase()),\n );\n if (typeGenerics.has(ref.toLowerCase())) {\n continue;\n }\n markTypeReferenced(ref);\n }\n }\n }\n\n // 2. Scan interface method signatures & returns (structured params preferred)\n for (const intf of ctx.interfaces) {\n for (const m of intf.methods) {\n const refs = methodTypeRefs(m);\n for (const ref of refs) {\n markTypeReferenced(ref);\n }\n }\n }\n\n for (const t of ctx.types) {\n if (!ctx.isSpecInScope(t.id)) continue;\n if (!referencedTypes.has(t.id)) {\n const sub = ctx.subsystems.find(s => s.id === t.subsystem);\n const isDraftCtx = sub ? (sub.status === 'draft' || sub.status === 'design') : false;\n ctx.addIssue(\n 'warning',\n 'UNUSED_TYPE',\n `Type \"${t.id}\" is defined but never referenced by any type fields or interface methods.`,\n t.id,\n isDraftCtx,\n );\n }\n }\n },\n};\n","import { ComponentSpec, MethodSignature } from '../../models/index.js';\nimport { RuleContext, SddRule } from './types.js';\nimport { methodKey, walkNarrativeGraph, WalkSeed } from './graph.js';\n\n// ---------------------------------------------------------------------------\n// Semantic-edge rules: the validator checks not just that referenced things\n// exist, but that semantically-required EDGES exist. Four historic blind\n// spots close here:\n// 1. generic-portal dispatch was invisible to the static walker,\n// 2. persistence had no round-trip (write with no boot read-back),\n// 3. lifecycle/boot wiring was inexpressible (blanket lint-allows),\n// 4. bare-Json seams crossed subsystem boundaries untyped.\n// Plus the prose-claim tripwire: durability claims that live only in prose.\n// ---------------------------------------------------------------------------\n\n/** Data-layer stereotypes — where persistence/registration claims are structurally realized. */\nconst DATA_STEREOTYPES = new Set(['Store', 'Registry', 'Index', 'Adapter', 'Repository']);\n\nfunction interfaceMethodsOf(ctx: RuleContext, compId: string): MethodSignature[] {\n const out: MethodSignature[] = [];\n for (const intf of ctx.interfacesByComponent.get(compId) ?? []) {\n out.push(...intf.methods);\n }\n return out;\n}\n\nfunction componentOfImpl(ctx: RuleContext, implContract: string): ComponentSpec | undefined {\n const contract = ctx.interfaceMap.get(implContract);\n return contract ? ctx.componentMap.get(contract.component) : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Dispatch tables — machine-readable capability → component.method maps on\n// generic-dispatch Portals, and the dispatch narrative step routed through\n// them. Both sides are contract-checked so a capability can no longer exist\n// only in prose while its server silently doesn't.\n// ---------------------------------------------------------------------------\n\nexport const dispatchRule: SddRule = {\n name: 'dispatch-tables',\n description:\n 'Portal dispatch tables must bind every capability to an existing component.method inside the portal\\'s own subsystem (the portal dispatches inward), with no duplicate capabilities; dispatch narrative steps must route a declared capability through a Portal that actually serves it.',\n codes: [\n { code: 'DISPATCH_ON_NON_PORTAL', defaultSeverity: 'error', summary: 'Dispatch table declared on a component that is not a Portal' },\n { code: 'DUPLICATE_CAPABILITY', defaultSeverity: 'error', summary: 'Capability bound more than once in one dispatch table' },\n { code: 'UNSERVED_CAPABILITY', defaultSeverity: 'error', summary: 'Capability has no existing server (bad table binding, or dispatch step routing a capability the target Portal does not serve)' },\n { code: 'DISPATCH_CROSS_SUBSYSTEM', defaultSeverity: 'error', summary: 'Dispatch binding targets a component outside the portal\\'s subsystem' },\n { code: 'UNDECLARED_DISPATCH_TARGET', defaultSeverity: 'error', summary: 'Dispatch binding targets a component the portal does not depend on or own' },\n { code: 'MALFORMED_DISPATCH_STEP', defaultSeverity: 'error', summary: 'Dispatch step missing its capability (targetComponent presence is the contracts rule\\'s finding)' },\n { code: 'NARRATIVE_SEMANTIC_UNBACKED', defaultSeverity: 'warning', summary: 'Dispatch step asserts a guarantee the bound capability method does not declare' },\n ],\n check(ctx) {\n // --- table side ---------------------------------------------------------\n for (const comp of ctx.components) {\n if (!comp.dispatch || comp.dispatch.length === 0) continue;\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n\n if (comp.componentType !== 'Portal') {\n ctx.addIssue(\n 'error',\n 'DISPATCH_ON_NON_PORTAL',\n `Component \"${comp.id}\" (${comp.componentType}) declares a dispatch table — capability dispatch is a Portal responsibility (the subsystem's front door routing inward).`,\n comp.id,\n isDraftCtx,\n );\n }\n\n const seen = new Set<string>();\n for (const b of comp.dispatch) {\n if (seen.has(b.capability)) {\n ctx.addIssue(\n 'error',\n 'DUPLICATE_CAPABILITY',\n `Dispatch table of \"${comp.id}\" binds capability \"${b.capability}\" more than once — runtime routing would be ambiguous.`,\n comp.id,\n isDraftCtx,\n );\n }\n seen.add(b.capability);\n\n const target = ctx.componentMap.get(b.component);\n if (!target) {\n ctx.addIssue(\n 'error',\n 'UNSERVED_CAPABILITY',\n `Dispatch table of \"${comp.id}\" binds capability \"${b.capability}\" to component \"${b.component}\", which does not exist — the capability has no server.`,\n comp.id,\n isDraftCtx,\n );\n continue;\n }\n if (!interfaceMethodsOf(ctx, target.id).some(method => method.name === b.method)) {\n ctx.addIssue(\n 'error',\n 'UNSERVED_CAPABILITY',\n `Dispatch table of \"${comp.id}\" binds capability \"${b.capability}\" to \"${b.component}.${b.method}\", but \"${target.id}\" declares no such method on any of its interfaces.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(target.id),\n );\n }\n if (target.subsystem !== comp.subsystem) {\n ctx.addIssue(\n 'error',\n 'DISPATCH_CROSS_SUBSYSTEM',\n `Dispatch table of \"${comp.id}\" (subsystem \"${comp.subsystem}\") binds capability \"${b.capability}\" to \"${b.component}\" in subsystem \"${target.subsystem}\" — a portal dispatches inward; cross-subsystem hops go local Adapter → remote Portal.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(target.id),\n );\n }\n // The table IS a runtime invocation path: declare it, so stereotype\n // and coupling rules see the portal's true fan-out.\n if (target.id !== comp.id && !comp.dependsOn.includes(target.id) && !comp.owns.includes(target.id)) {\n ctx.addIssue(\n 'error',\n 'UNDECLARED_DISPATCH_TARGET',\n `Dispatch table of \"${comp.id}\" binds capability \"${b.capability}\" to \"${b.component}\", but \"${comp.id}\" does not list it under dependsOn/owns — the dispatch edge is a real runtime dependency.`,\n comp.id,\n isDraftCtx || ctx.isComponentDraft(target.id),\n );\n }\n }\n }\n\n // --- step side ----------------------------------------------------------\n for (const impl of ctx.implementations) {\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n for (const implMethod of impl.methods) {\n for (const step of implMethod.narrative) {\n if (step.type !== 'dispatch') continue;\n const where = `Method \"${implMethod.name}\" in implementation \"${impl.id}\": dispatch step ${step.stepNumber}`;\n\n if (!step.capability) {\n ctx.addIssue(\n 'error',\n 'MALFORMED_DISPATCH_STEP',\n `${where} requires \"capability\" (the routed capability name).`,\n impl.id,\n isDraftCtx,\n );\n continue;\n }\n // Missing/dangling targetComponent is the contracts rule's finding.\n if (!step.targetComponent) continue;\n const portal = ctx.componentMap.get(step.targetComponent);\n if (!portal) continue;\n\n if (portal.componentType !== 'Portal' || !portal.dispatch || portal.dispatch.length === 0) {\n ctx.addIssue(\n 'error',\n 'UNSERVED_CAPABILITY',\n `${where} routes capability \"${step.capability}\" through \"${portal.id}\", which ${portal.componentType !== 'Portal' ? `is a ${portal.componentType}, not a Portal` : 'declares no dispatch table'} — the capability cannot be resolved to a server.`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(portal.id),\n );\n continue;\n }\n\n const binding = portal.dispatch.find(b => b.capability === step.capability);\n if (!binding) {\n ctx.addIssue(\n 'error',\n 'UNSERVED_CAPABILITY',\n `${where} routes capability \"${step.capability}\" through \"${portal.id}\", but that portal's dispatch table does not serve it (declared: ${portal.dispatch.map(b => `\"${b.capability}\"`).join(', ')}).`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(portal.id),\n );\n continue;\n }\n\n // Same consistency check call steps get: a guarantee this step\n // asserts must be declared by the method the capability resolves to.\n if (step.assertsGuarantees?.length) {\n const boundMethod = interfaceMethodsOf(ctx, binding.component).find(m => m.name === binding.method);\n const declared = new Set(boundMethod?.guarantees ?? []);\n for (const g of step.assertsGuarantees) {\n if (!declared.has(g)) {\n ctx.addIssue(\n 'warning',\n 'NARRATIVE_SEMANTIC_UNBACKED',\n `${where} asserts guarantee \"${g}\", but capability \"${step.capability}\" resolves to \"${binding.component}.${binding.method}\", which does not list \"${g}\" among its L3 contract guarantees. Declare it there (and ensure its shape can deliver it), or revise the narrative.`,\n impl.id,\n isDraftCtx || ctx.isComponentDraft(binding.component),\n );\n }\n }\n }\n }\n }\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Lifecycle entrypoints — declared init/shutdown flow roots. Existence is\n// checked here; the reachability and durability rules consume them as roots.\n// ---------------------------------------------------------------------------\n\nexport const lifecycleRule: SddRule = {\n name: 'lifecycle-entrypoints',\n description:\n 'Declared subsystem lifecycle entrypoints (init/shutdown flows) must name an existing component and a method on one of its interfaces — they are reachability roots, so a dangling entrypoint would silently detach every flow rooted in it.',\n codes: [\n { code: 'INVALID_LIFECYCLE_ENTRYPOINT', defaultSeverity: 'error', summary: 'Lifecycle entrypoint names a missing component or method' },\n { code: 'LIFECYCLE_CROSS_SUBSYSTEM', defaultSeverity: 'error', summary: 'Lifecycle entrypoint roots a flow in another subsystem\\'s component' },\n ],\n check(ctx) {\n for (const sub of ctx.subsystems) {\n const isDraftCtx = sub.status === 'draft' || sub.status === 'design';\n for (const le of sub.lifecycle ?? []) {\n const comp = ctx.componentMap.get(le.component);\n if (!comp) {\n ctx.addIssue(\n 'error',\n 'INVALID_LIFECYCLE_ENTRYPOINT',\n `Subsystem \"${sub.id}\" declares ${le.phase} lifecycle entrypoint \"${le.component}.${le.method}\", but component \"${le.component}\" does not exist.`,\n sub.id,\n isDraftCtx,\n );\n continue;\n }\n // A lifecycle flow is the subsystem's own boot/shutdown wiring —\n // rooting it in a sibling's internals crosses the boundary (and would\n // silently dangle when that sibling is externalized/renamed).\n if (comp.subsystem !== sub.id) {\n ctx.addIssue(\n 'error',\n 'LIFECYCLE_CROSS_SUBSYSTEM',\n `Subsystem \"${sub.id}\" declares ${le.phase} lifecycle entrypoint \"${le.component}.${le.method}\", but \"${comp.id}\" belongs to subsystem \"${comp.subsystem}\" — declare the entrypoint on the owning subsystem instead.`,\n sub.id,\n isDraftCtx || ctx.isComponentDraft(comp.id),\n );\n }\n if (!interfaceMethodsOf(ctx, comp.id).some(method => method.name === le.method)) {\n ctx.addIssue(\n 'error',\n 'INVALID_LIFECYCLE_ENTRYPOINT',\n `Subsystem \"${sub.id}\" declares ${le.phase} lifecycle entrypoint \"${le.component}.${le.method}\", but \"${comp.id}\" declares no method \"${le.method}\" on any of its interfaces.`,\n sub.id,\n isDraftCtx || ctx.isComponentDraft(comp.id),\n );\n }\n }\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Durability round-trip — a durable Store's externally-persisted writes must\n// have a hydration read-back reachable from a declared lifecycle init flow.\n// Every method was individually valid in the historic bug; the missing thing\n// was this EDGE (no boot read-back into the RAM projection).\n// ---------------------------------------------------------------------------\n\nexport const durabilityRule: SddRule = {\n name: 'durability-round-trip',\n description:\n 'Every Store must declare its durability (MISSING_DURABILITY): durable = persisted RAM projection (effect-tagged methods; writes require a hydration read-back reachable from a lifecycle init entrypoint), read-through = persisted with no RAM copy (every read IS the read-back — hydration exempt), ram-projection = rebuilt not restored, cache = evictable loss-safe memo state. The round-trip requirement applies to durable Stores only — the flagship semantic check is opt-out by declaration, never silently absent.',\n codes: [\n { code: 'DURABILITY_ON_NON_STORE', defaultSeverity: 'error', summary: 'durability declared on a component that is not a Store' },\n { code: 'MISSING_DURABILITY', defaultSeverity: 'warning', summary: 'Store with no durability declaration — the round-trip machinery cannot know whether restart-survival is promised' },\n { code: 'MISSING_EFFECT_TAG', defaultSeverity: 'warning', summary: 'Durable Store contract method lacks an effect: read | write tag' },\n { code: 'MISSING_HYDRATION', defaultSeverity: 'error', summary: 'Durable Store is written but no read-back is reachable from any lifecycle init entrypoint' },\n ],\n check(ctx) {\n // Reachability from lifecycle INIT flows only — the boot graph.\n const initSeeds: WalkSeed[] = [];\n for (const sub of ctx.subsystems) {\n for (const le of sub.lifecycle ?? []) {\n if (le.phase === 'init' && ctx.componentMap.has(le.component)) {\n initSeeds.push({ compId: le.component, methodName: le.method });\n }\n }\n }\n // followDispatchTables: false — at boot only edges the init narratives\n // actually TAKE count; a hydrating read merely offered in a reached\n // portal's table is not a boot-time read (explicit dispatch steps in the\n // init flow are still followed).\n const initReach = initSeeds.length ? walkNarrativeGraph(ctx, initSeeds, { followDispatchTables: false }) : null;\n\n for (const comp of ctx.components) {\n const isDraftCtx = ctx.isComponentDraft(comp.id);\n\n if (!comp.durability) {\n // Undeclared durability hollows out the round-trip machinery: on a\n // 12-store tree with 2 declarations the flagship check protects\n // almost nothing. Exemption is by declaration, never by omission.\n if (comp.componentType === 'Store') {\n ctx.addIssue(\n 'warning',\n 'MISSING_DURABILITY',\n `Store \"${comp.id}\" declares no durability. Declare one: durable (persisted RAM projection — hydration round-trip enforced), read-through (persisted, no RAM copy — every read is the read-back), ram-projection (rebuilt, not restored), or cache (evictable, loss-safe).`,\n comp.id,\n isDraftCtx,\n );\n }\n continue;\n }\n\n if (comp.componentType !== 'Store') {\n ctx.addIssue(\n 'error',\n 'DURABILITY_ON_NON_STORE',\n `Component \"${comp.id}\" (${comp.componentType}) declares durability \"${comp.durability}\" — durability is a Store property (state lives in Stores; see the no-persistence-shortcuts rule).`,\n comp.id,\n isDraftCtx,\n );\n continue;\n }\n // Only `durable` (persisted RAM projection) needs the boot read-back:\n // read-through reads the medium on every call, ram-projection rebuilds,\n // cache loss is behavior-preserving.\n if (comp.durability !== 'durable') continue;\n\n const methods = interfaceMethodsOf(ctx, comp.id);\n const untagged = methods.filter(method => !method.effect);\n if (untagged.length) {\n ctx.addIssue(\n 'warning',\n 'MISSING_EFFECT_TAG',\n `Durable Store \"${comp.id}\" has contract methods without an effect tag (${untagged.map(u => `\"${u.name}\"`).join(', ')}) — the round-trip rule can only pair writes with read-backs over tagged methods.`,\n comp.id,\n isDraftCtx,\n );\n }\n\n const writes = methods.filter(method => method.effect === 'write');\n const reads = methods.filter(method => method.effect === 'read');\n if (writes.length === 0) continue; // nothing persisted, nothing to hydrate\n\n const hydrated = initReach !== null\n && reads.some(method => initReach.reachedMethods.has(methodKey(comp.id, method.name)));\n if (!hydrated) {\n const because = initReach === null\n ? 'no subsystem declares a lifecycle init entrypoint at all'\n : reads.length === 0\n ? 'the store declares no read-effect method to hydrate from'\n : `none of its read-effect methods (${reads.map(r => `\"${r.name}\"`).join(', ')}) are reachable from any declared lifecycle init flow`;\n ctx.addIssue(\n 'error',\n 'MISSING_HYDRATION',\n `Durable Store \"${comp.id}\" is written (${writes.map(w => `\"${w.name}\"`).join(', ')}) but ${because} — persisted state would never be read back after a restart. Wire a hydrate/read-back into a lifecycle init flow.`,\n comp.id,\n isDraftCtx,\n );\n }\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Untyped seams — bare Json/any/unknown crossing a subsystem's public surface.\n// The seam is exactly where role-envelope mismatches hide; inside a component\n// a loose bag is a style choice, across a boundary it is an unchecked contract.\n// ---------------------------------------------------------------------------\n\nconst BARE_SEAM_TYPES = new Set(['json', 'any', 'unknown', 'object']);\n\nfunction unwrapPromise(typeRef: string): string {\n const m = /^promise\\s*<(.+)>$/i.exec(typeRef.trim());\n return (m ? m[1] : typeRef).trim();\n}\n\nexport const untypedSeamRule: SddRule = {\n name: 'untyped-seams',\n description:\n 'Methods on a subsystem\\'s published components (its public surface) should not take or return bare Json/any/unknown — cross-subsystem contracts are the swap seam and must be typed. Generic-dispatch portals carry per-capability types via their dispatch table instead.',\n codes: [\n { code: 'UNTYPED_SEAM', defaultSeverity: 'warning', summary: 'Bare Json/any/unknown parameter or return crossing a subsystem public surface' },\n ],\n check(ctx) {\n for (const sub of ctx.subsystems) {\n const published = ctx.publicSet.get(sub.id);\n if (!published || published.size === 0) continue;\n\n for (const compId of published) {\n const comp = ctx.componentMap.get(compId);\n if (!comp) continue;\n // A generic-dispatch portal's untyped envelope is the sanctioned\n // pattern ONCE it carries a dispatch table — the table is where the\n // per-capability typing lives.\n if (comp.componentType === 'Portal' && comp.dispatch && comp.dispatch.length > 0) continue;\n\n for (const intf of ctx.interfacesByComponent.get(compId) ?? []) {\n const isDraftCtx = ctx.isComponentDraft(compId) || intf.status === 'draft' || intf.status === 'design';\n for (const m of intf.methods) {\n const offenders: string[] = [];\n for (const p of m.params ?? []) {\n if (BARE_SEAM_TYPES.has(unwrapPromise(p.type).toLowerCase())) {\n offenders.push(`param \"${p.name}: ${p.type}\"`);\n }\n }\n const ret = unwrapPromise(m.returns ?? '');\n if (BARE_SEAM_TYPES.has(ret.toLowerCase())) {\n offenders.push(`return \"${m.returns}\"`);\n }\n if (offenders.length) {\n ctx.addIssue(\n 'warning',\n 'UNTYPED_SEAM',\n `Method \"${m.name}\" on published component \"${compId}\" (public surface of subsystem \"${sub.id}\") crosses the boundary untyped: ${offenders.join(', ')}. Type the seam — or, for a generic-dispatch portal, carry per-capability types in the dispatch table.`,\n intf.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Prose-claim linter — durability/side-effect phrases whose step graph has no\n// matching edge. A heuristic tripwire, deliberately conservative: the durable\n// fix is dispatch tables + durability tags making the claims structural.\n// ---------------------------------------------------------------------------\n\nconst CLAIM_PHRASES = /\\b(persist(s|ed|ent)?|survives?\\s+(a\\s+)?restart|writ(es?|ten)\\s+to\\s+disk|registered\\s+into|durabl[ey])\\b/i;\n\nexport const proseClaimRule: SddRule = {\n name: 'prose-claims',\n description:\n 'Flags durability/side-effect claims that exist only in prose: a local step description or an intent paragraph claiming persistence (\"persisted\", \"survives restart\", \"registered into\") on a logic component whose narrative has no call/dispatch edge to any data-layer component (Store/Registry/Index/Adapter/Repository). Data-layer components are exempt — they ARE the persistence.',\n codes: [\n { code: 'UNREALIZED_CLAIM', defaultSeverity: 'warning', summary: 'Durability/side-effect claim in prose with no matching structural edge' },\n ],\n check(ctx) {\n for (const impl of ctx.implementations) {\n const comp = componentOfImpl(ctx, impl.contract);\n if (!comp) continue;\n // The persistence layer legitimately talks about persisting.\n if (DATA_STEREOTYPES.has(comp.componentType)) continue;\n\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n for (const implMethod of impl.methods) {\n // Cheap regex gate first: almost no methods carry claims, so the\n // graph probing below only runs on actual hits.\n const stepClaims = implMethod.narrative\n .filter(step => step.type === 'local')\n .map(step => ({ step, claim: CLAIM_PHRASES.exec(step.description) }))\n .filter((c): c is { step: (typeof implMethod.narrative)[number]; claim: RegExpExecArray } => c.claim !== null);\n const intentClaim = implMethod.intent ? CLAIM_PHRASES.exec(implMethod.intent) : null;\n if (!stepClaims.length && !intentClaim) continue;\n\n const hasDataEdge = implMethod.narrative.some(step => {\n if (step.type !== 'call' && step.type !== 'dispatch') return false;\n if (!step.targetComponent) return false;\n const target = ctx.componentMap.get(step.targetComponent);\n if (target && DATA_STEREOTYPES.has(target.componentType)) return true;\n // A dispatch resolves to its bound server.\n const binding = target?.dispatch?.find(b => b.capability === step.capability);\n const server = binding ? ctx.componentMap.get(binding.component) : undefined;\n return server ? DATA_STEREOTYPES.has(server.componentType) : false;\n });\n\n // Steps: a LOCAL step claiming persistence in a narrative with no\n // data-layer edge realizes nothing. (call/dispatch steps carry their\n // own edge and are exempt.)\n for (const { step, claim } of stepClaims) {\n if (!hasDataEdge) {\n ctx.addIssue(\n 'warning',\n 'UNREALIZED_CLAIM',\n `Step ${step.stepNumber} of \"${implMethod.name}\" in implementation \"${impl.id}\" claims \"${claim[0]}\" but no call/dispatch edge in this narrative reaches a Store/Registry/Index/Adapter — realize the claim as a structural edge (and durability tags), or reword the prose.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n\n // Intent prose: no steps to inspect, so fall back to the component's\n // declared collaborators — a persistence claim with no data-layer\n // dependency anywhere cannot be realized.\n if (intentClaim && !hasDataEdge) {\n const dependsOnDataLayer = [...comp.dependsOn, ...comp.owns].some(depId => {\n const dep = ctx.componentMap.get(depId);\n return dep ? DATA_STEREOTYPES.has(dep.componentType) : false;\n });\n if (!dependsOnDataLayer) {\n ctx.addIssue(\n 'warning',\n 'UNREALIZED_CLAIM',\n `The intent of \"${implMethod.name}\" in implementation \"${impl.id}\" claims \"${intentClaim[0]}\" but component \"${comp.id}\" neither depends on nor owns any Store/Registry/Index/Adapter — the claim has no structural realization.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n },\n};\n","import { ComponentSpec, ImplementationSpec, InterfaceSpec, TypeSpec } from '../../models/index.js';\nimport { RuleContext, SddRule } from './types.js';\nimport { matchTypeRef } from './type-analysis.js';\n\n// ---------------------------------------------------------------------------\n// The invariant registry — an HONEST linter, deliberately not a prover.\n//\n// An entity declares domain invariants (e.g. \"slug unique among siblings\" —\n// the class of bug where a property held nowhere because nobody owned it).\n// Anchoring piggybacks the existing entity→component link (componentClass)\n// and the existing effect dial: every write-effect contract method of the\n// owning component must carry a narrative step ASSERTING each invariant\n// (step.assertsInvariants: [\"<type-id>.<invariant-id>\"]), mirroring how\n// claimed guarantees must be backed by narrative steps.\n//\n// What a green run proves: someone declared the property AND every write path\n// visibly claims to uphold it. What it never proves: that the narrative (or\n// the code) actually enforces it — that is implementer correctness, checked\n// by tests, not by prose analysis. Findings default to warnings and are\n// lint.allow-suppressible; only dangling references are errors.\n// ---------------------------------------------------------------------------\n\n/** Split \"<type-ref>.<invariant-id>\" at the LAST dot (invariant ids cannot contain dots). */\nfunction splitInvariantRef(ref: string): { typeRef: string; invariantId: string } | null {\n const at = ref.lastIndexOf('.');\n if (at <= 0 || at === ref.length - 1) return null;\n return { typeRef: ref.slice(0, at), invariantId: ref.slice(at + 1) };\n}\n\nfunction qualifiedTypeId(spec: TypeSpec): string {\n return spec.subsystem && !spec.id.startsWith(`${spec.subsystem}::`)\n ? `${spec.subsystem}::${spec.id}`\n : spec.id;\n}\n\n/** Resolve an assertsInvariants reference against the declared entity invariants. */\nexport function resolveInvariantRef(ref: string, types: TypeSpec[]): { type: TypeSpec; invariantId: string } | null {\n const parts = splitInvariantRef(ref);\n if (!parts) return null;\n for (const t of types) {\n if (!t.invariants?.length) continue;\n if (!matchTypeRef(parts.typeRef, qualifiedTypeId(t))) continue;\n if (t.invariants.some(inv => inv.id === parts.invariantId)) {\n return { type: t, invariantId: parts.invariantId };\n }\n }\n return null;\n}\n\n/**\n * Does this reference denote THIS type's invariant? Matched directly against\n * the type under check (suffix-style over its qualified id) instead of through\n * a global first-in-scan-order resolution: when two subsystems (or a parent\n * and a chained subproject) declare same-named entities with same-named\n * invariants, first-match attributed a bare ref to whichever type the scan\n * happened to list first — crediting the wrong type's write path and flagging\n * the right one. A qualified ref still only matches its own namespace.\n */\nfunction refMatchesInvariant(ref: string, type: TypeSpec, invariantId: string): boolean {\n const parts = splitInvariantRef(ref);\n if (!parts || parts.invariantId !== invariantId) return false;\n if (!(type.invariants ?? []).some(inv => inv.id === invariantId)) return false;\n return matchTypeRef(parts.typeRef, qualifiedTypeId(type));\n}\n\nfunction stepAsserts(impl: ImplementationSpec, methodName: string, type: TypeSpec, invariantId: string): boolean {\n const method = impl.methods.find(m => m.name === methodName);\n if (!method) return false;\n return method.narrative.some(step =>\n (step.assertsInvariants ?? []).some(ref => refMatchesInvariant(ref, type, invariantId)),\n );\n}\n\n/**\n * The entity's owning component. componentClass survives namespacing\n * UNQUALIFIED (the loader qualifies type ids but not this link), so a chained\n * subproject's entity names its owner in the child's own id space — resolve\n * exact first, then inside the entity's mount namespace.\n */\nfunction resolveComponentClass(t: TypeSpec, ctx: RuleContext): ComponentSpec | undefined {\n if (!t.componentClass) return undefined;\n const direct = ctx.componentMap.get(t.componentClass);\n if (direct) return direct;\n const at = t.id.lastIndexOf('::');\n if (at === -1) return undefined;\n return ctx.componentMap.get(`${t.id.slice(0, at)}::${t.componentClass}`);\n}\n\nexport const invariantBackingRule: SddRule = {\n name: 'invariant-backing',\n description:\n 'The invariant registry: entities may declare domain invariants (type.invariants), anchored through their componentClass. Every write-effect contract method of the owning component must carry a narrative step asserting each invariant (step.assertsInvariants: \"<type-id>.<invariant-id>\") — the same declared-and-backed shape as semantic guarantees. This is an HONEST lint over declarations: a green run means every write path visibly claims the invariant, never that the narrative or code actually enforces it. An invariant with no resolvable owner or no declared write path is unanchored; dangling assertion references are errors.',\n codes: [\n { code: 'DUPLICATE_INVARIANT_ID', defaultSeverity: 'error', summary: 'An entity declares two invariants with the same id' },\n { code: 'INVARIANT_UNANCHORED', defaultSeverity: 'warning', summary: 'An entity declares invariants but has no componentClass, its componentClass does not resolve, or the owning component declares no write-effect contract methods' },\n { code: 'UNASSERTED_INVARIANT', defaultSeverity: 'warning', summary: 'A write-effect method of the invariant\\'s owning component has no narrative step asserting it' },\n { code: 'UNKNOWN_INVARIANT_REF', defaultSeverity: 'error', summary: 'A narrative step asserts an invariant that no entity declares' },\n ],\n check(ctx) {\n // --- entity side: duplicates, anchoring, and write-path coverage --------\n for (const t of ctx.types) {\n const invariants = t.invariants ?? [];\n if (invariants.length === 0) continue;\n\n const seen = new Set<string>();\n for (const inv of invariants) {\n if (seen.has(inv.id)) {\n ctx.addIssue(\n 'error',\n 'DUPLICATE_INVARIANT_ID',\n `Entity \"${t.id}\" declares invariant id \"${inv.id}\" more than once — invariant ids must be unique within the entity.`,\n t.id,\n );\n }\n seen.add(inv.id);\n }\n\n const comp = resolveComponentClass(t, ctx);\n if (!comp) {\n ctx.addIssue(\n 'warning',\n 'INVARIANT_UNANCHORED',\n `Entity \"${t.id}\" declares ${invariants.length} invariant(s) but ${t.componentClass ? `its componentClass \"${t.componentClass}\" does not resolve to a component` : 'has no componentClass'} — without an owning component there is no write path to hold the invariant against. Link the lifecycle owner via componentClass.`,\n t.id,\n );\n continue;\n }\n\n const contracts: InterfaceSpec[] = ctx.interfacesByComponent.get(comp.id) ?? [];\n const writeMethods = contracts.flatMap(intf =>\n intf.methods.filter(m => m.effect === 'write').map(m => ({ intf, method: m })),\n );\n if (writeMethods.length === 0) {\n ctx.addIssue(\n 'warning',\n 'INVARIANT_UNANCHORED',\n `Entity \"${t.id}\" declares ${invariants.length} invariant(s) anchored to \"${comp.id}\", but none of that component's contract methods declare effect: write — the validator cannot identify the write paths that must assert them. Tag the mutating methods with effect: write.`,\n t.id,\n ctx.isComponentDraft(comp.id),\n );\n continue;\n }\n\n for (const { intf, method } of writeMethods) {\n for (const impl of ctx.implementationsByContract.get(intf.id) ?? []) {\n const isDraftCtx = ctx.isImplementationDraft(impl);\n for (const inv of invariants) {\n if (stepAsserts(impl, method.name, t, inv.id)) continue;\n ctx.addIssue(\n 'warning',\n 'UNASSERTED_INVARIANT',\n `Write method \"${method.name}\" of \"${comp.id}\" (implementation \"${impl.id}\") has no narrative step asserting invariant \"${t.id}.${inv.id}\" (${inv.description}). Add the step that upholds it and mark it with assertsInvariants — or lint.allow with a reason. Note: an assertion only declares the intent; it does not prove enforcement.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n\n // --- step side: every assertion reference must resolve ------------------\n for (const impl of ctx.implementations) {\n const isDraftCtx = ctx.isImplementationDraft(impl);\n for (const method of impl.methods) {\n for (const step of method.narrative) {\n for (const ref of step.assertsInvariants ?? []) {\n if (resolveInvariantRef(ref, ctx.types)) continue;\n ctx.addIssue(\n 'error',\n 'UNKNOWN_INVARIANT_REF',\n `Step ${step.stepNumber} of \"${method.name}\" in implementation \"${impl.id}\" asserts invariant \"${ref}\", but no entity declares it (expected \"<type-id>.<invariant-id>\" naming a declared entry in that entity's invariants).`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n },\n};\n","import { SEMANTIC_GUARANTEES } from '../../models/index.js';\nimport type { SddRule } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Guarantee-token vocabulary. The guarantee field is an OPEN string so packs\n// can extend the vocabulary beyond the builtin set — which makes typo\n// detection the validator's job instead of the schema's: a token that is\n// neither builtin nor declared by any loaded pack cannot be matched by the\n// consistency machinery (NARRATIVE_SEMANTIC_UNBACKED compares tokens\n// literally), so it silently opts the contract out of every guarantee check.\n// ---------------------------------------------------------------------------\n\nexport const guaranteeTokensRule: SddRule = {\n name: 'guarantee-tokens',\n description:\n 'Every semantic-guarantee token an L3 method declares or a narrative step asserts must be a builtin guarantee or one a loaded extension pack declares in its `guarantees` list. The vocabulary is open for packs, not for typos — an undeclared token is matched by nothing and silently escapes the narrative↔contract consistency checks.',\n codes: [\n { code: 'UNKNOWN_GUARANTEE', defaultSeverity: 'warning', summary: 'Guarantee token is neither builtin nor pack-declared' },\n ],\n check(ctx) {\n const known = new Set<string>([...SEMANTIC_GUARANTEES, ...ctx.ext.guarantees]);\n const fixHint = `Known tokens: builtin ${SEMANTIC_GUARANTEES.join(', ')}${ctx.ext.guarantees.length ? `; pack-declared ${ctx.ext.guarantees.join(', ')}` : ''}. Fix the spelling or declare the token in an extension pack's \\`guarantees\\` list.`;\n\n for (const intf of ctx.interfaces) {\n const isDraftCtx = intf.status === 'draft' || intf.status === 'design' || ctx.isComponentDraft(intf.component);\n for (const method of intf.methods) {\n for (const g of method.guarantees ?? []) {\n if (!known.has(g)) {\n ctx.addIssue(\n 'warning',\n 'UNKNOWN_GUARANTEE',\n `Method \"${method.name}\" on interface \"${intf.id}\" declares guarantee \"${g}\", which is neither a builtin guarantee nor declared by any loaded extension pack — no narrative assertion can ever match it. ${fixHint}`,\n intf.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n\n for (const impl of ctx.implementations) {\n const isDraftCtx = ctx.isImplementationDraft(impl);\n for (const method of impl.methods) {\n for (const step of method.narrative ?? []) {\n for (const g of step.assertsGuarantees ?? []) {\n if (!known.has(g)) {\n ctx.addIssue(\n 'warning',\n 'UNKNOWN_GUARANTEE',\n `Step ${step.stepNumber} of \"${method.name}\" in implementation \"${impl.id}\" asserts guarantee \"${g}\", which is neither a builtin guarantee nor declared by any loaded extension pack — no L3 contract can ever back it. ${fixHint}`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n }\n },\n};\n","import { RuleContext, SddRule } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Event topology — the bipartite completeness of the pub/sub graph.\n//\n// Emit side: component `emits` declarations + MessageBus endpoints with\n// direction: publish. Subscribe side: component `subscribesTo` declarations +\n// MessageBus endpoints with direction: subscribe. Every emitted topic needs a\n// consumer and every subscription a source — the observer-never-subscribed\n// and announce-topic-mismatch class of bug, caught at spec level.\n//\n// Pairing is by exact topic string (v1; `event` is informational). A tree\n// that declares no event edges at all sees nothing — request/response\n// systems pay zero noise. Warnings + lint.allow (a topic consumed by an\n// EXTERNAL system is a legitimate, declarable exception).\n// ---------------------------------------------------------------------------\n\ninterface TopicEnd {\n topic: string;\n compId: string;\n via: string;\n}\n\nfunction collectEnds(ctx: RuleContext): { emitters: TopicEnd[]; subscribers: TopicEnd[] } {\n const emitters: TopicEnd[] = [];\n const subscribers: TopicEnd[] = [];\n\n for (const comp of ctx.components) {\n for (const e of comp.emits ?? []) {\n emitters.push({ topic: e.topic, compId: comp.id, via: 'emits declaration' });\n }\n for (const s of comp.subscribesTo ?? []) {\n subscribers.push({ topic: s.topic, compId: comp.id, via: 'subscribesTo declaration' });\n }\n }\n\n for (const intf of ctx.interfaces) {\n for (const method of intf.methods) {\n const ep = method.endpoint;\n if (!ep || ep.transport !== 'MessageBus') continue;\n const end: TopicEnd = {\n topic: ep.topic,\n compId: intf.component,\n via: `MessageBus endpoint on ${intf.id}.${method.name}`,\n };\n if (ep.direction === 'publish') emitters.push(end);\n else subscribers.push(end);\n }\n }\n\n return { emitters, subscribers };\n}\n\nexport const eventTopologyRule: SddRule = {\n name: 'event-topology',\n description:\n 'Bipartite completeness of the declared pub/sub graph: every topic a component emits (emits declarations, MessageBus publish endpoints) must have at least one subscriber (subscribesTo declarations, MessageBus subscribe endpoints), and every subscription must have at least one source. Pairing is by exact topic name. Trees that declare no event edges see nothing — the rule costs request/response systems zero noise. Warnings + lint.allow: a topic produced for (or consumed from) an EXTERNAL system is a legitimate, declarable exception.',\n codes: [\n { code: 'UNCONSUMED_TOPIC', defaultSeverity: 'warning', summary: 'Topic is emitted but nothing in the tree subscribes to it' },\n { code: 'UNSOURCED_SUBSCRIPTION', defaultSeverity: 'warning', summary: 'Topic is subscribed to but nothing in the tree emits it' },\n ],\n check(ctx) {\n const { emitters, subscribers } = collectEnds(ctx);\n if (emitters.length === 0 && subscribers.length === 0) return;\n\n const emittedTopics = new Set(emitters.map(e => e.topic));\n const subscribedTopics = new Set(subscribers.map(s => s.topic));\n\n for (const e of emitters) {\n if (subscribedTopics.has(e.topic)) continue;\n ctx.addIssue(\n 'warning',\n 'UNCONSUMED_TOPIC',\n `Component \"${e.compId}\" emits topic \"${e.topic}\" (${e.via}), but nothing in this tree subscribes to it — the event goes nowhere. Wire a subscriber (subscribesTo, or a MessageBus subscribe endpoint), fix the topic name, or lint.allow with the external consumer named.`,\n e.compId,\n ctx.isComponentDraft(e.compId),\n );\n }\n for (const s of subscribers) {\n if (emittedTopics.has(s.topic)) continue;\n ctx.addIssue(\n 'warning',\n 'UNSOURCED_SUBSCRIPTION',\n `Component \"${s.compId}\" subscribes to topic \"${s.topic}\" (${s.via}), but nothing in this tree emits it — the handler can never fire from inside this system. Wire the emitter (emits, or a MessageBus publish endpoint), fix the topic name, or lint.allow with the external source named.`,\n s.compId,\n ctx.isComponentDraft(s.compId),\n );\n }\n },\n};\n","import { ImplementationSpec, NarrativeStep } from '../../models/index.js';\nimport { RuleContext, SddRule } from './types.js';\nimport { stepGraph } from './narrative-flow.js';\n\n// ---------------------------------------------------------------------------\n// Narrative antipatterns — spec-level bug detection over the L5 step graphs\n// and the method-level call graph they wire up. Deliberately restricted to\n// what is PROVABLE from structure alone:\n// INESCAPABLE_CYCLE — a step cycle with no exit edge and no return/\n// throw member never terminates, by construction.\n// MEANINGLESS_BRANCH — a branch/switch whose arms all land on the same\n// step decides nothing (a classic authoring slip).\n// UNCONDITIONAL_CALL_CYCLE— a cross-component call cycle in which every\n// call edge is unavoidable on all entry-to-exit\n// paths of its narrative: unbounded recursion.\n// Prose conditions are never judged — a `while` loop's termination is the\n// implementer's problem (halting problem); only structural inescapability is\n// claimed. All findings are warnings + lint.allow (new-check policy).\n// ---------------------------------------------------------------------------\n\n/**\n * Terminators: return/throw steps, plus every place execution can complete by\n * falling off the end of the narrative — mirroring each `?? nextOf` fallback\n * in stepGraph's successor semantics (a branch whose true arm falls off the\n * end completes there just as surely as a return).\n */\nfunction isTerminal(step: NarrativeStep, nextOf: (n: number) => number | undefined): boolean {\n if (step.type === 'return' || step.type === 'throw') return true;\n const n = step.stepNumber;\n switch (step.type) {\n case 'local': case 'call': case 'dispatch':\n return nextOf(n) === undefined;\n case 'branch':\n return step.onTrueStep === undefined && nextOf(n) === undefined;\n case 'switch':\n return step.defaultStep === undefined && nextOf(n) === undefined;\n case 'loop': case 'try':\n return step.endStep !== undefined && nextOf(step.endStep) === undefined;\n default:\n return false;\n }\n}\n\n/**\n * True when step `target` lies on EVERY path from the entry to any terminator\n * — i.e. execution cannot complete without passing it. Computed as: with\n * `target` removed from the graph, no terminator is reachable from the entry.\n */\nexport function isUnavoidable(steps: NarrativeStep[], target: number): boolean {\n const { nums, byNum, nextOf, successorsOf } = stepGraph(steps);\n if (nums.length === 0) return false;\n if (nums[0] === target) return true;\n\n const visited = new Set<number>();\n const stack = [nums[0]];\n while (stack.length) {\n const n = stack.pop()!;\n if (n === target || visited.has(n)) continue;\n visited.add(n);\n const s = byNum.get(n)!;\n if (isTerminal(s, nextOf)) return false; // a completion path avoids the target\n for (const t of successorsOf(n)) {\n if (t !== target && !visited.has(t)) stack.push(t);\n }\n }\n return true;\n}\n\n/** Strongly connected components (Tarjan, iterative) over the step graph. */\nfunction stronglyConnected(nums: number[], successorsOf: (n: number) => number[]): number[][] {\n const index = new Map<number, number>();\n const low = new Map<number, number>();\n const onStack = new Set<number>();\n const stack: number[] = [];\n const sccs: number[][] = [];\n let counter = 0;\n\n for (const root of nums) {\n if (index.has(root)) continue;\n const work: { n: number; succ: number[]; i: number }[] = [{ n: root, succ: successorsOf(root), i: 0 }];\n index.set(root, counter); low.set(root, counter); counter++;\n stack.push(root); onStack.add(root);\n\n while (work.length) {\n const frame = work[work.length - 1];\n if (frame.i < frame.succ.length) {\n const t = frame.succ[frame.i++];\n if (!index.has(t)) {\n index.set(t, counter); low.set(t, counter); counter++;\n stack.push(t); onStack.add(t);\n work.push({ n: t, succ: successorsOf(t), i: 0 });\n } else if (onStack.has(t)) {\n low.set(frame.n, Math.min(low.get(frame.n)!, index.get(t)!));\n }\n } else {\n work.pop();\n if (work.length) {\n const parent = work[work.length - 1];\n low.set(parent.n, Math.min(low.get(parent.n)!, low.get(frame.n)!));\n }\n if (low.get(frame.n) === index.get(frame.n)) {\n const scc: number[] = [];\n let m: number;\n do { m = stack.pop()!; onStack.delete(m); scc.push(m); } while (m !== frame.n);\n sccs.push(scc);\n }\n }\n }\n }\n return sccs;\n}\n\ninterface CallEdge {\n fromKey: string;\n toKey: string;\n unconditional: boolean;\n impl: ImplementationSpec;\n methodName: string;\n stepNumber: number;\n toLabel: string;\n}\n\nexport const narrativeAntipatternsRule: SddRule = {\n name: 'narrative-antipatterns',\n description:\n 'Provable narrative bugs, caught at spec level before implementation: a step-graph cycle with no exit edge and no return/throw member never terminates by construction (INESCAPABLE_CYCLE); a branch or switch whose arms all target the same step decides nothing (MEANINGLESS_BRANCH); a method-level call cycle across components in which every call edge is unavoidable on every entry-to-exit path is unbounded recursion (UNCONDITIONAL_CALL_CYCLE — dispatch steps resolved through their portal tables; a cycle with even one guarded edge is NOT flagged, since prose conditions are never judged). Structure-only claims — warnings, lint.allow-suppressible.',\n codes: [\n { code: 'INESCAPABLE_CYCLE', defaultSeverity: 'warning', summary: 'Step cycle with no exit edge and no return/throw member — never terminates by construction' },\n { code: 'MEANINGLESS_BRANCH', defaultSeverity: 'warning', summary: 'Branch/switch whose arms all target the same step — the decision changes nothing' },\n { code: 'UNCONDITIONAL_CALL_CYCLE', defaultSeverity: 'warning', summary: 'Cross-component call cycle in which every call edge is unavoidable — unbounded recursion by construction' },\n ],\n check(ctx: RuleContext) {\n const callEdges: CallEdge[] = [];\n\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n const component = contract ? ctx.componentMap.get(contract.component) : undefined;\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n for (const implMethod of impl.methods) {\n const steps = implMethod.narrative;\n if (!steps.length) continue;\n const where = `Method \"${implMethod.name}\" in implementation \"${impl.id}\": `;\n const graph = stepGraph(steps);\n\n // -- MEANINGLESS_BRANCH ---------------------------------------------\n for (const s of steps) {\n if (s.type === 'branch' && s.onFalseStep !== undefined) {\n const onTrue = s.onTrueStep ?? graph.nextOf(s.stepNumber);\n if (onTrue !== undefined && onTrue === s.onFalseStep) {\n ctx.addIssue(\n 'warning',\n 'MEANINGLESS_BRANCH',\n `${where}branch step ${s.stepNumber} sends both arms to step ${onTrue} — the condition decides nothing. Point the arms at different steps, or replace the branch with a local step.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n if (s.type === 'switch' && s.cases?.length) {\n const targets = new Set<number>(s.cases.map(c => c.step));\n const def = s.defaultStep ?? graph.nextOf(s.stepNumber);\n if (def !== undefined) targets.add(def);\n if (targets.size === 1) {\n ctx.addIssue(\n 'warning',\n 'MEANINGLESS_BRANCH',\n `${where}switch step ${s.stepNumber} sends every case (and the default) to step ${[...targets][0]} — the dispatch decides nothing.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n\n // -- INESCAPABLE_CYCLE ----------------------------------------------\n for (const scc of stronglyConnected(graph.nums, graph.successorsOf)) {\n const inScc = new Set(scc);\n const isCycle = scc.length > 1\n || graph.successorsOf(scc[0]).includes(scc[0]);\n if (!isCycle) continue;\n const hasExit = scc.some(n => graph.successorsOf(n).some(t => !inScc.has(t)));\n const hasTerminator = scc.some(n => {\n const s = graph.byNum.get(n)!;\n return s.type === 'return' || s.type === 'throw';\n });\n if (!hasExit && !hasTerminator) {\n const sorted = [...scc].sort((a, b) => a - b);\n ctx.addIssue(\n 'warning',\n 'INESCAPABLE_CYCLE',\n `${where}steps ${sorted.join(' → ')} form a cycle with no exit edge and no return/throw — once entered, this flow never terminates, by construction. Add an exit branch or a terminator inside the cycle.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n\n // -- collect method-level call edges for the cycle pass -------------\n if (!component) continue;\n const fromKey = `${component.id}::${implMethod.name}`;\n for (const s of steps) {\n let toComponent: string | undefined;\n let toMethod: string | undefined;\n if (s.type === 'call' && s.targetComponent && s.targetMethod) {\n toComponent = s.targetComponent;\n toMethod = s.targetMethod;\n } else if (s.type === 'dispatch' && s.targetComponent && s.capability) {\n const portal = ctx.componentMap.get(s.targetComponent);\n const binding = portal?.dispatch?.find(b => b.capability === s.capability);\n if (binding) { toComponent = binding.component; toMethod = binding.method; }\n }\n if (!toComponent || !toMethod || !ctx.componentMap.has(toComponent)) continue;\n callEdges.push({\n fromKey,\n toKey: `${toComponent}::${toMethod}`,\n unconditional: isUnavoidable(steps, s.stepNumber),\n impl,\n methodName: implMethod.name,\n stepNumber: s.stepNumber,\n toLabel: `${toComponent}.${toMethod}`,\n });\n }\n }\n }\n\n // -- UNCONDITIONAL_CALL_CYCLE over the unconditional-edge subgraph -------\n const adjacency = new Map<string, CallEdge[]>();\n for (const e of callEdges) {\n if (!e.unconditional) continue;\n const list = adjacency.get(e.fromKey);\n if (list) list.push(e);\n else adjacency.set(e.fromKey, [e]);\n }\n const nodes = [...new Set([...adjacency.keys(), ...[...adjacency.values()].flat().map(e => e.toKey)])];\n const nodeIndex = new Map(nodes.map((k, i) => [k, i]));\n const succOf = (i: number): number[] =>\n (adjacency.get(nodes[i]) ?? []).map(e => nodeIndex.get(e.toKey)!).filter(t => t !== undefined);\n\n for (const scc of stronglyConnected([...nodes.keys()], succOf)) {\n const keys = scc.map(i => nodes[i]);\n const inScc = new Set(keys);\n const isCycle = keys.length > 1\n || (adjacency.get(keys[0]) ?? []).some(e => e.toKey === keys[0]);\n if (!isCycle) continue;\n const memberEdges = keys.flatMap(k => (adjacency.get(k) ?? []).filter(e => inScc.has(e.toKey)));\n if (memberEdges.length === 0) continue;\n // Anchor the finding on the lexicographically first member's impl, so a\n // single lint.allow covers the cycle finding deterministically.\n const anchor = [...memberEdges].sort((a, b) => a.fromKey.localeCompare(b.fromKey))[0];\n const path = [...keys].sort().join(' → ');\n ctx.addIssue(\n 'warning',\n 'UNCONDITIONAL_CALL_CYCLE',\n `Call cycle with no guard: ${path} — every call edge in this cycle is unavoidable on all paths of its narrative (e.g. step ${anchor.stepNumber} of \"${anchor.methodName}\" in \"${anchor.impl.id}\" always calls ${anchor.toLabel}). This recurses without a base case, by construction. Guard at least one edge with a branch/return before the call, or lint.allow with the termination argument.`,\n anchor.impl.id,\n memberEdges.some(e => ctx.isImplementationDraft(e.impl)),\n );\n }\n },\n};\n","import type { SourceFileFacts } from '../source-analysis.js';\nimport { normalizeSourcePath } from '../source-analysis.js';\nimport { RuleContext, SddRule } from './types.js';\nimport { isInChainedSubproject, stereotypeDefaultTier } from './conformance.js';\n\n// ---------------------------------------------------------------------------\n// Call-step realization (code↔spec Level 3, the opener).\n//\n// Levels 1–2 prove the code matches the spec's SHAPE (files, symbols, import\n// graph). This rule takes the first honest step toward INTENT: every `call`\n// step of a narrative must appear as a callee of the realized function.\n//\n// What it proves — and all it proves: the realized function (exact AST grade\n// only) contains a call to the target method's name (or its per-method\n// `symbol` override), where \"contains\" closes transitively over same-file\n// named helpers the function calls (extract-helper refactors stay clean).\n// Order, arguments, and conditions are deliberately unverified — this is set\n// membership, not behavioral equivalence, and the finding text says so.\n// `dispatch` steps are skipped: they route through runtime tables, so the\n// bound method's name legitimately never appears at the call site.\n// ---------------------------------------------------------------------------\n\n/**\n * Own-property record lookup: callee/function names include things like\n * \"toString\" and \"constructor\", which a bare index would resolve to\n * Object.prototype members (functions — not iterable, not numbers).\n */\nfunction ownEntry<T>(record: Record<string, T> | undefined, key: string): T | undefined {\n return record && Object.prototype.hasOwnProperty.call(record, key) ? record[key] : undefined;\n}\n\n/** Callee set of `fn`, closed transitively over same-file named functions. */\nexport function closedCallees(facts: SourceFileFacts, fn: string): Set<string> | undefined {\n const direct = ownEntry(facts.functionCalls, fn);\n if (!direct) return undefined;\n const closed = new Set<string>(direct);\n const queue = [...direct];\n while (queue.length) {\n const name = queue.pop()!;\n for (const next of ownEntry(facts.functionCalls, name) ?? []) {\n if (!closed.has(next)) {\n closed.add(next);\n queue.push(next);\n }\n }\n }\n return closed;\n}\n\nexport const callConformanceRule: SddRule = {\n name: 'call-conformance',\n description:\n 'Code↔spec Level 3 (opener): every narrative `call` step of an exactly-analyzed method must be realized as a call in the realized function — the target method\\'s contract name or its per-method symbol override must appear among the function\\'s callees, closed transitively over same-file named helpers. Set membership only: order, arguments, and conditions are deliberately unverified, and dispatch steps (runtime-table routed) are skipped. Respects the conformance dial (off skips) and fires only at exact analysis grade — weaker grades never guess.',\n codes: [\n { code: 'CALL_STEP_UNREALIZED', defaultSeverity: 'warning', summary: 'Narrative call step whose target method name (or symbol) never appears among the realized function\\'s callees (exact grade, set membership)' },\n ],\n check(ctx: RuleContext) {\n const factsByPath = new Map<string, SourceFileFacts>();\n for (const f of ctx.codeModel.files) factsByPath.set(normalizeSourcePath(f.path), f);\n\n for (const impl of ctx.implementations) {\n if (!impl.sourcePath) continue;\n const contract = ctx.interfaceMap.get(impl.contract);\n if (!contract) continue;\n const component = ctx.componentMap.get(contract.component);\n if (!component) continue;\n if (isInChainedSubproject(component.subsystem, ctx)) continue;\n\n const facts = factsByPath.get(normalizeSourcePath(impl.sourcePath));\n if (!facts || facts.status !== 'analyzed' || facts.analysisGrade !== 'exact') continue;\n\n const specTier = impl.conformance ?? stereotypeDefaultTier(component.componentType);\n const isDraftCtx = ctx.isImplementationDraft(impl);\n\n for (const implMethod of impl.methods) {\n const tier = implMethod.conformance ?? specTier;\n if (tier === 'off') continue;\n if (!implMethod.narrative.length) continue;\n\n const fnSymbol = implMethod.symbol ?? implMethod.name;\n const callees = closedCallees(facts, fnSymbol);\n // The realized function itself is missing — UNREALIZED_METHOD's find,\n // not ours; a duplicate finding here would just be noise.\n if (!callees) continue;\n\n // Aggregate per method: one finding listing every unrealized call\n // step, so a method with systematic naming drift reads as one review\n // item instead of a finding per step.\n const missing: { step: number; target: string; accepted: string[] }[] = [];\n for (const step of implMethod.narrative) {\n if (step.type !== 'call' || !step.targetComponent || !step.targetMethod) continue;\n // Dangling targets are the contracts rule's findings.\n if (!ctx.componentMap.has(step.targetComponent)) continue;\n\n // Accept the contract name or any symbol override a target-side\n // implementation declares for that method.\n const accepted = new Set<string>([step.targetMethod]);\n for (const targetIntf of ctx.interfacesByComponent.get(step.targetComponent) ?? []) {\n for (const targetImpl of ctx.implementationsByContract.get(targetIntf.id) ?? []) {\n const targetMethod = targetImpl.methods.find(m => m.name === step.targetMethod);\n if (targetMethod?.symbol) accepted.add(targetMethod.symbol);\n }\n }\n\n // N:1 identity forwarding: when the caller's own realized symbol IS\n // the target name, facade and target collapse onto one function\n // (pure 1:1 forwarding, barrel republication) — the call step is\n // realized by identity, exactly as Level 1's N:1 sharing blesses.\n if (accepted.has(fnSymbol)) continue;\n if ([...accepted].some(name => callees.has(name))) continue;\n missing.push({\n step: step.stepNumber,\n target: `${step.targetComponent}.${step.targetMethod}`,\n accepted: [...accepted],\n });\n }\n if (missing.length === 0) continue;\n const detail = missing\n .map(m => `step ${m.step} → ${m.target} (looked for ${m.accepted.map(a => `\"${a}\"`).join(' / ')})`)\n .join('; ');\n ctx.addIssue(\n 'warning',\n 'CALL_STEP_UNREALIZED',\n `Method \"${implMethod.name}\" in implementation \"${impl.id}\": ${missing.length} narrative call step(s) are not realized as calls of the function \"${fnSymbol}\" in \"${impl.sourcePath}\" — ${detail}. Callees are matched by name, closed over same-file helpers (exact grade, set membership — order and arguments are not checked). Realize the calls, fix the narrative, or map code names via per-method symbols on the targets.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n },\n};\n","import { SddRule } from './types.js';\nimport { splitNamespace } from '../specs.js';\n\n/** Default dependsOn count above which a component is flagged as doing too much.\n * Overridable per project via rules.complexity.maxComponentDependencies — the\n * same knob the EXCESSIVE_DEPENDENCIES rule reads, so both agree on the cap. */\nconst DEFAULT_GOD_COMPONENT_THRESHOLD = 8;\n\n/**\n * Coupling health: mutual subsystem dependencies must be explicitly sanctioned\n * via trustedLinks (turning \"fast lanes\" into reviewable spec), trustedLinks\n * must reference real peers, and components with an excessive dependency\n * fan-out are flagged as god components.\n */\nexport const couplingRule: SddRule = {\n name: 'coupling-health',\n description:\n 'Two subsystems depending on each other is a real architectural commitment (deployment affinity, backpressure, scaling coupling). It is allowed but must be acknowledged with a trustedLinks declaration on either side, stating the reason (e.g. a latency fast lane that bypasses the bus). A trustedLink on the SOURCE subsystem additionally licenses its direct edges into the peer without the client-Adapter shim; the published-Portal target requirement stays either way. Also flags components whose dependsOn fan-out suggests a god component.',\n codes: [\n { code: 'MUTUAL_SUBSYSTEM_DEPENDENCY', defaultSeverity: 'warning', summary: 'Subsystems depend on each other without a declared trusted link' },\n { code: 'INVALID_TRUSTED_LINK', defaultSeverity: 'error', summary: 'trustedLinks references a non-existent subsystem' },\n { code: 'UNUSED_TRUSTED_LINK', defaultSeverity: 'warning', summary: 'trustedLinks declares a peer no dependency actually reaches' },\n { code: 'GOD_COMPONENT', defaultSeverity: 'warning', summary: 'Component with excessive dependency fan-out' },\n ],\n check(ctx) {\n // --- Build the subsystem-level dependency graph from cross-subsystem component deps\n const subsystemDeps = new Map<string, Set<string>>(); // from -> to\n const exampleEdge = new Map<string, string>(); // \"from->to\" -> example component edge\n for (const comp of ctx.components) {\n for (const depId of comp.dependsOn) {\n const dep = ctx.componentMap.get(depId);\n if (!dep || dep.subsystem === comp.subsystem) continue;\n const set = subsystemDeps.get(comp.subsystem) ?? new Set<string>();\n set.add(dep.subsystem);\n subsystemDeps.set(comp.subsystem, set);\n const key = `${comp.subsystem}->${dep.subsystem}`;\n if (!exampleEdge.has(key)) exampleEdge.set(key, `${comp.id} → ${dep.id}`);\n }\n }\n\n // trustedLinks index: subsystem -> set of peers it sanctions.\n // A declared link on EITHER side acknowledges the pair.\n const sanctionedPairs = new Set<string>();\n const pairKey = (a: string, b: string) => [a, b].sort().join('<->');\n const declaredPeers = new Map<string, Set<string>>();\n for (const sub of ctx.subsystems) {\n const isDraftCtx = sub.status === 'draft' || sub.status === 'design';\n for (const link of sub.trustedLinks ?? []) {\n // Resolve the peer: exact id, or a local id within the same namespace.\n const { prefix } = splitNamespace(sub.id);\n const candidates = [link.subsystem, prefix ? `${prefix}::${link.subsystem}` : link.subsystem];\n const peer = ctx.subsystems.find(s => candidates.includes(s.id));\n if (!peer) {\n ctx.addIssue(\n 'error',\n 'INVALID_TRUSTED_LINK',\n `Subsystem \"${sub.id}\" declares a trusted link to \"${link.subsystem}\", which does not exist.`,\n sub.id,\n isDraftCtx,\n );\n continue;\n }\n sanctionedPairs.add(pairKey(sub.id, peer.id));\n const peers = declaredPeers.get(sub.id) ?? new Set<string>();\n peers.add(peer.id);\n declaredPeers.set(sub.id, peers);\n\n // A trusted link that no actual dependency uses is stale spec — flag it.\n const outbound = subsystemDeps.get(sub.id)?.has(peer.id) ?? false;\n const inbound = subsystemDeps.get(peer.id)?.has(sub.id) ?? false;\n if (!outbound && !inbound) {\n ctx.addIssue(\n 'warning',\n 'UNUSED_TRUSTED_LINK',\n `Subsystem \"${sub.id}\" declares a trusted link to \"${peer.id}\" (reason: \"${link.reason}\"), but no component dependency crosses between them. Remove the stale link or wire the dependency.`,\n sub.id,\n isDraftCtx,\n );\n }\n }\n }\n\n // --- Mutual dependency detection\n const reported = new Set<string>();\n for (const [from, tos] of subsystemDeps) {\n for (const to of tos) {\n if (!(subsystemDeps.get(to)?.has(from))) continue; // not mutual\n const key = pairKey(from, to);\n if (reported.has(key)) continue;\n reported.add(key);\n if (sanctionedPairs.has(key)) continue; // acknowledged via trustedLinks\n\n const subA = ctx.subsystems.find(s => s.id === from);\n const subB = ctx.subsystems.find(s => s.id === to);\n const isDraftCtx = (subA?.status === 'draft' || subA?.status === 'design')\n && (subB?.status === 'draft' || subB?.status === 'design');\n ctx.addIssue(\n 'warning',\n 'MUTUAL_SUBSYSTEM_DEPENDENCY',\n `Subsystems \"${from}\" and \"${to}\" depend on each other (${exampleEdge.get(`${from}->${to}`)}; ${exampleEdge.get(`${to}->${from}`)}). Mutual coupling is a real commitment — if intentional (e.g. a latency fast lane bypassing the bus between trusted services), declare it with trustedLinks on either subsystem, stating the reason; otherwise break one direction (usually via events over the bus).`,\n from,\n isDraftCtx,\n );\n }\n }\n\n // --- God component detection\n const threshold = ctx.rules?.complexity?.maxComponentDependencies ?? DEFAULT_GOD_COMPONENT_THRESHOLD;\n for (const comp of ctx.components) {\n if (comp.dependsOn.length > threshold) {\n ctx.addIssue(\n 'warning',\n 'GOD_COMPONENT',\n `Component \"${comp.id}\" depends on ${comp.dependsOn.length} components (> ${threshold}). That fan-out suggests it owns more than one responsibility — split the workflow, or group cohesive collaborators behind a pattern facade (Repository/Gateway).`,\n comp.id,\n ctx.isComponentDraft(comp.id),\n );\n }\n }\n },\n};\n","import { SddRule } from './types.js';\nimport { LANGUAGE_MARKERS, normalizeLanguage, methodTypeRefs } from './type-analysis.js';\n\n/**\n * Flow constructs that do not exist in a given target language. Conservative\n * by design (same philosophy as LANGUAGE_MARKERS): only unambiguous\n * per-language gaps are listed — the narrative stays semantic, so a construct\n * is flagged only when the language genuinely has no direct equivalent and\n * the implementer would be forced to emulate or re-model it.\n */\nconst UNSUPPORTED_FLOW: Record<string, Record<string, string>> = {\n rust: {\n try: 'Rust models errors as values (Result + ?) — specify the guarded logic as explicit error branches, or note the Result mapping in the step description',\n throw: 'Rust has no exceptions — model the failure as a return step whose outcome names the Err variant',\n doWhile: 'Rust has no do-while — prefer loopKind: while, or state the emulation (loop + break) in the description',\n },\n go: {\n try: 'Go models errors as return values — specify explicit error-check branches instead of a try region (panic is not control flow)',\n throw: 'Go has no exceptions — model the failure as a return step with an error outcome',\n doWhile: 'Go has no do-while — prefer loopKind: while (the `for cond` form), or state the emulation',\n },\n c: {\n try: 'C has no exceptions — specify explicit error-code checks instead of a try region',\n throw: 'C has no exceptions — model the failure as a return step with an error-code outcome',\n },\n python: {\n doWhile: 'Python has no do-while — prefer loopKind: while, or state the emulation (while True + break)',\n },\n};\n\n/**\n * Language-aware contract hygiene: when a system/subsystem declares a\n * targetLanguage, builtins that unambiguously belong to a DIFFERENT language\n * family are flagged in interface signatures — e.g. `usize`/`Vec` in a\n * TypeScript system, or `Promise`/`any` in a Rust one. Conservative by design:\n * only unambiguous per-language markers trigger, shared vocabulary never does.\n * The same opt-in gates narrative flow steps: constructs the language lacks\n * (try/throw in Rust or Go, do-while in Python) are flagged so the narrative\n * describes flows an implementer can write idiomatically.\n */\nexport const languageRule: SddRule = {\n name: 'target-language',\n description:\n 'Contracts must speak the declared target language: builtin types that unambiguously belong to another language family are flagged in method signatures, and narrative flow steps using constructs the language lacks (e.g. exceptions in Rust/Go, do-while in Python) are flagged too. Set targetLanguage on the system (L0) or override per subsystem (L1).',\n codes: [\n { code: 'LANGUAGE_FOREIGN_BUILTIN', defaultSeverity: 'warning', summary: 'Signature uses a builtin from a different language family' },\n { code: 'LANGUAGE_FOREIGN_FLOW', defaultSeverity: 'warning', summary: 'Narrative flow step uses a construct the target language does not have' },\n ],\n check(ctx) {\n // Effective per-language tables: built-ins merged with extension-pack\n // languages (packs may add whole platforms, e.g. \"make\", or extend a\n // built-in language's tables).\n const markersFor = (family: string): ReadonlySet<string> | undefined => {\n const base = LANGUAGE_MARKERS[family];\n const extra = ctx.ext.languages[family]?.foreignBuiltins;\n if (!extra?.length) return base;\n return new Set([...(base ?? []), ...extra.map(s => s.toLowerCase())]);\n };\n const families = new Set([...Object.keys(LANGUAGE_MARKERS), ...Object.keys(ctx.ext.languages)]);\n const gapsFor = (lang: string): Record<string, string> => ({\n ...(UNSUPPORTED_FLOW[lang] ?? {}),\n ...(ctx.ext.languages[lang]?.unsupportedFlow ?? {}),\n });\n\n for (const intf of ctx.interfaces) {\n const comp = ctx.componentMap.get(intf.component);\n const lang = ctx.targetLanguageFor(comp?.subsystem);\n if (!lang) continue;\n const normalized = normalizeLanguage(lang);\n const ownMarkers = markersFor(normalized);\n // A language with no builtin vocabulary of its own (unknown, or a pack\n // platform that declared none) could legitimately share any builtin —\n // nothing reliable to check against.\n if (!ownMarkers || ownMarkers.size === 0) continue;\n\n const isDraftCtx = ctx.isComponentDraft(intf.component) || intf.status === 'draft' || intf.status === 'design';\n for (const m of intf.methods) {\n const refs = methodTypeRefs(m);\n for (const ref of refs) {\n const refLower = ref.toLowerCase();\n if (ownMarkers.has(refLower)) continue;\n for (const family of families) {\n if (family === normalized) continue;\n if (markersFor(family)?.has(refLower)) {\n ctx.addIssue(\n 'warning',\n 'LANGUAGE_FOREIGN_BUILTIN',\n `Method \"${m.name}\" on interface \"${intf.id}\" uses \"${ref}\", a ${family} builtin, but the target language here is ${normalized}. Use the ${normalized} equivalent so implementers generate idiomatic code.`,\n intf.id,\n isDraftCtx,\n );\n break;\n }\n }\n }\n }\n }\n\n // Narrative flow steps against the language's actual control constructs.\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n if (!contract) continue;\n const comp = ctx.componentMap.get(contract.component);\n const lang = ctx.targetLanguageFor(comp?.subsystem);\n if (!lang) continue;\n const gaps = gapsFor(normalizeLanguage(lang));\n if (Object.keys(gaps).length === 0) continue;\n\n const isDraftCtx = impl.status === 'draft' || impl.status === 'design'\n || contract.status === 'draft' || contract.status === 'design'\n || ctx.isComponentDraft(contract.component);\n\n for (const implMethod of impl.methods) {\n for (const step of implMethod.narrative) {\n // The full construct keyspace: branch | switch | forEach | for |\n // while | doWhile | try | throw | jump | parallel | detach\n // (local/call/return are universal and never gated; detach is a\n // call-step flag gated as its own construct).\n const constructs: string[] = [\n step.type === 'loop'\n ? (step.loopKind ?? (step.over ? 'forEach' : 'while'))\n : step.type,\n ];\n if (step.detach) constructs.push('detach');\n for (const construct of constructs) {\n const guidance = gaps[construct];\n if (!guidance) continue;\n const label = construct === 'doWhile' ? 'a do-while loop'\n : (construct === 'forEach' || construct === 'for' || construct === 'while') ? `a ${construct} loop`\n : construct === 'detach' ? 'a detached (fire-and-forget) call'\n : `a ${construct} step`;\n ctx.addIssue(\n 'warning',\n 'LANGUAGE_FOREIGN_FLOW',\n `Step ${step.stepNumber} of \"${implMethod.name}\" in implementation \"${impl.id}\" uses ${label}, but the target language is ${normalizeLanguage(lang)}: ${guidance}.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n }\n }\n },\n};\n","import { SddRule } from './types.js';\nimport type { MethodSignature } from '../../models/index.js';\n\n/**\n * Technology-boundary rules: an L4 that declares `technologies` (e.g.\n * [\"mysql\"]) makes its component's ownership tree the technology's home.\n * The rest of the system may only know the boundary's intent interface —\n * that is what makes the implementation swappable (mysql → postgresql)\n * without contract change. No hardcoded vendor lists: only declared tokens\n * are policed, so the rule never fires on a tree that doesn't opt in.\n */\n\n/** Stereotypes that may legitimately bind a technology directly. */\nconst DATA_LAYER = new Set(['Adapter', 'Store', 'Registry', 'Index']);\n\n/**\n * Identifier-aware matcher for one technology token. The token normalizes to\n * its fused alphanumeric form (\"js-yaml\" → \"jsyaml\"); text splits into\n * alphanumeric words. Single-part tokens hit when a word contains them\n * (\"MySqlCustomerStore\" hits \"mysql\"; \"my sql notes\" does not). Multi-part\n * tokens additionally hit when that many CONSECUTIVE words fuse to contain\n * them, so prose \"Google Sheets\" / \"google-sheets\" hits token\n * \"google-sheets\". Returns null for tokens under 3 chars — too noisy to\n * police.\n */\nfunction makeMatcher(tech: string): ((text: string | undefined | null) => boolean) | null {\n const parts = tech.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);\n const joined = parts.join('');\n if (joined.length < 3) return null;\n const n = parts.length;\n return (text) => {\n if (!text) return false;\n const words = text.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean);\n if (words.some(w => w.includes(joined))) return true;\n if (n < 2) return false;\n for (let i = 0; i + n <= words.length; i++) {\n if (words.slice(i, i + n).join('').includes(joined)) return true;\n }\n return false;\n };\n}\n\n/** The identifier surfaces of a contract method (prose descriptions excluded). */\nfunction contractIdentifiers(m: MethodSignature): string {\n const parts: string[] = [m.name, m.signature, m.returns];\n for (const p of m.params ?? []) parts.push(p.name, p.type);\n if (m.endpoint) parts.push(Object.values(m.endpoint).map(String).join(' '));\n return parts.join(' ');\n}\n\nexport const technologyRule: SddRule = {\n name: 'technology-boundaries',\n description:\n 'Technology stays behind its owning boundary: an L4 that declares `technologies` (e.g. [mysql]) makes its component\\'s ownership tree the technology\\'s home. References outside that tree are leakage, L3 contract identifiers must stay intent-language (the contract is the swap seam), and only data-layer stereotypes (Adapter/Store/Registry/Index) should bind a technology directly.',\n codes: [\n { code: 'TECH_LEAKAGE', defaultSeverity: 'warning', summary: 'Technology referenced outside its owning boundary' },\n { code: 'VENDOR_NAME_IN_CONTRACT', defaultSeverity: 'warning', summary: 'Technology name in L3 contract identifiers' },\n { code: 'TECH_ON_LOGIC_COMPONENT', defaultSeverity: 'warning', summary: 'Technology bound by a non-data-layer stereotype' },\n ],\n check(ctx) {\n // -- ownership helpers ----------------------------------------------------\n const ownerOf = new Map<string, string>();\n for (const c of ctx.components) for (const m of c.owns) ownerOf.set(m, c.id);\n\n const ownershipRoot = (id: string): string => {\n const seen = new Set<string>();\n let cur = id;\n while (ownerOf.has(cur) && !seen.has(cur)) {\n seen.add(cur);\n cur = ownerOf.get(cur)!;\n }\n return cur;\n };\n\n const ownsClosure = (rootId: string): Set<string> => {\n const out = new Set<string>([rootId]);\n const queue = [rootId];\n while (queue.length) {\n const c = ctx.componentMap.get(queue.shift()!);\n for (const m of c?.owns ?? []) {\n if (!out.has(m)) { out.add(m); queue.push(m); }\n }\n }\n return out;\n };\n\n // -- collect declarations → per-token owning scopes ------------------------\n interface TechHome {\n label: string;\n match: (text: string | undefined | null) => boolean;\n ownerComponents: Set<string>;\n scope: Set<string>;\n }\n const homes = new Map<string, TechHome>();\n\n for (const impl of ctx.implementations) {\n if (!impl.technologies?.length) continue;\n const intf = ctx.interfaceMap.get(impl.contract);\n const comp = intf ? ctx.componentMap.get(intf.component) : undefined;\n if (!comp) continue; // dangling contract — the hierarchy rule reports it\n\n if (!DATA_LAYER.has(comp.componentType)) {\n ctx.addIssue(\n 'warning',\n 'TECH_ON_LOGIC_COMPONENT',\n `Implementation \"${impl.id}\" binds technology (${impl.technologies.join(', ')}) on component \"${comp.id}\" (${comp.componentType}). Technology belongs behind a data-layer seam — extract an Adapter (or Store/Registry/Index) behind an intent interface and let this component depend on that.`,\n impl.id,\n ctx.isComponentDraft(comp.id),\n );\n }\n\n // The owning scope: the whole ownership tree containing the declaring\n // component (pattern root + members), those components' contracts and\n // implementations, and the ancestor subsystem chain.\n const compSet = ownsClosure(ownershipRoot(comp.id));\n const scope = new Set<string>(compSet);\n for (const i of ctx.interfaces) if (compSet.has(i.component)) scope.add(i.id);\n for (const im of ctx.implementations) {\n const owner = ctx.interfaceMap.get(im.contract)?.component;\n if (owner && compSet.has(owner)) scope.add(im.id);\n }\n for (const cid of compSet) {\n const subId = ctx.componentMap.get(cid)?.subsystem;\n if (!subId) continue;\n for (const s of ctx.subsystems) {\n if (subId === s.id || subId.startsWith(`${s.id}::`)) scope.add(s.id);\n }\n }\n\n for (const tech of impl.technologies) {\n const match = makeMatcher(tech);\n if (!match) continue; // unpoliceable without drowning in noise\n const key = tech.toLowerCase().split(/[^a-z0-9]+/).filter(Boolean).join('');\n const home = homes.get(key) ?? { label: tech, match, ownerComponents: new Set<string>(), scope: new Set<string>() };\n home.ownerComponents.add(comp.id);\n for (const id of scope) home.scope.add(id);\n homes.set(key, home);\n }\n }\n if (homes.size === 0) return;\n\n const ownersDesc = (h: TechHome): string => [...h.ownerComponents].map(c => `\"${c}\"`).join(', ');\n\n for (const home of homes.values()) {\n // L3 identifier surfaces — ALL interfaces, including the owning\n // component's own: the contract is the swap seam, so the vendor name\n // is wrong even there. (Prose descriptions inside the owning scope may\n // name the tech — that is honest documentation, not coupling.)\n for (const intf of ctx.interfaces) {\n const offending = intf.methods.filter(m => home.match(contractIdentifiers(m))).map(m => m.name);\n if (offending.length) {\n ctx.addIssue(\n 'warning',\n 'VENDOR_NAME_IN_CONTRACT',\n `Interface \"${intf.id}\" exposes technology \"${home.label}\" in contract identifiers (method${offending.length > 1 ? 's' : ''}: ${offending.join(', ')}). Name the intent, not the vendor — the technology is owned by component ${ownersDesc(home)} and must stay swappable behind this contract.`,\n intf.id,\n ctx.isComponentDraft(intf.component),\n );\n }\n }\n\n // Leakage — every spec outside the owning scope, all text surfaces.\n for (const comp of ctx.components) {\n if (home.scope.has(comp.id)) continue;\n const surfaces: [string, string | undefined][] = [\n ['id/name', `${comp.id} ${comp.name}`],\n ['description', comp.description],\n ['dependsOn', comp.dependsOn.join(' ')],\n ['owns', comp.owns.join(' ')],\n ['basePath', comp.basePath],\n ];\n const found = surfaces.filter(([, t]) => home.match(t)).map(([s]) => s);\n if (found.length) {\n ctx.addIssue(\n 'warning',\n 'TECH_LEAKAGE',\n `Component \"${comp.id}\" references \"${home.label}\" (${found.join(', ')}) outside its owning boundary — the technology lives behind component ${ownersDesc(home)}. Route through that boundary's intent interface.`,\n comp.id,\n ctx.isComponentDraft(comp.id),\n );\n }\n }\n\n for (const sub of ctx.subsystems) {\n if (home.scope.has(sub.id)) continue;\n if (home.match(`${sub.id} ${sub.name} ${sub.description}`)) {\n ctx.addIssue(\n 'warning',\n 'TECH_LEAKAGE',\n `Subsystem \"${sub.id}\" references \"${home.label}\" outside the technology's owning boundary (component ${ownersDesc(home)}).`,\n sub.id,\n );\n }\n }\n\n for (const intf of ctx.interfaces) {\n if (home.scope.has(intf.id)) continue;\n const prose = [intf.description, ...intf.methods.map(m => m.description)].join(' ');\n if (home.match(prose)) {\n ctx.addIssue(\n 'warning',\n 'TECH_LEAKAGE',\n `Interface \"${intf.id}\" describes \"${home.label}\" outside its owning boundary (component ${ownersDesc(home)}) — consumers must not know backend specifics.`,\n intf.id,\n ctx.isComponentDraft(intf.component),\n );\n }\n }\n\n for (const impl of ctx.implementations) {\n if (home.scope.has(impl.id)) continue;\n const parts: (string | undefined)[] = [impl.description, impl.sourcePath];\n for (const m of impl.methods) {\n parts.push(m.intent);\n for (const s of m.narrative ?? []) {\n parts.push(s.description, s.targetComponent, s.targetMethod, s.condition, s.over, s.on, s.outcome, s.error);\n for (const c of s.cases ?? []) parts.push(c.value);\n for (const c of s.catches ?? []) parts.push(c.error);\n }\n }\n if (home.match(parts.filter(Boolean).join(' '))) {\n ctx.addIssue(\n 'warning',\n 'TECH_LEAKAGE',\n `Implementation \"${impl.id}\" references \"${home.label}\" outside its owning boundary — call the intent interface of component ${ownersDesc(home)} instead of naming its technology.`,\n impl.id,\n );\n }\n }\n\n // Types are shared data space — vendor-specific shapes don't belong in\n // it at all, so every type is scanned (there is no owning exemption).\n for (const t of ctx.types) {\n const parts: string[] = [t.id, t.name, t.description ?? ''];\n for (const f of t.fields ?? []) parts.push(f.name, f.type);\n for (const m of t.methods ?? []) parts.push(m.name, m.signature, m.returns);\n if (home.match(parts.join(' '))) {\n ctx.addIssue(\n 'warning',\n 'TECH_LEAKAGE',\n `Type \"${t.id}\" carries technology \"${home.label}\" in the shared type space — vendor-specific shapes belong inside the owning boundary (component ${ownersDesc(home)}), or the type should be renamed to its intent.`,\n t.id,\n );\n }\n }\n }\n },\n};\n","import { NamingRuleConfig } from '../../models/index.js';\nimport { RuleContext, SddRule } from './types.js';\n\nconst casingPatterns: Record<string, RegExp> = {\n camelCase: /^[a-z][a-zA-Z0-9]*$/,\n PascalCase: /^[A-Z][a-zA-Z0-9]*$/,\n snake_case: /^[a-z0-9]+(_[a-z0-9]+)*$/,\n 'kebab-case': /^[a-z0-9]+(-[a-z0-9]+)*$/,\n UPPER_CASE: /^[A-Z0-9]+(_[A-Z0-9]+)*$/,\n};\n\nfunction extensionProfileFor(ctx: RuleContext, subsystemId?: string) {\n const sub = subsystemId ? ctx.subsystems.find(s => s.id === subsystemId) : undefined;\n const profile = sub?.profile || ctx.projectType;\n return ctx.ext.profiles[profile];\n}\n\nfunction getEffectiveNamingConfig(ctx: RuleContext, subsystemId?: string): NamingRuleConfig | undefined {\n const projectNaming = ctx.rules?.naming;\n const packDef = extensionProfileFor(ctx, subsystemId);\n \n if (packDef?.rules?.naming) {\n return {\n ...projectNaming,\n ...packDef.rules.naming,\n stereotypes: {\n ...(projectNaming?.stereotypes ?? {}),\n ...(packDef.rules.naming.stereotypes ?? {}),\n },\n };\n }\n return projectNaming;\n}\n\nfunction compilePattern(patternOrCasing: string): RegExp | null {\n if (casingPatterns[patternOrCasing]) return casingPatterns[patternOrCasing];\n try {\n return new RegExp(patternOrCasing);\n } catch {\n return null;\n }\n}\n\nfunction checkCasingOrRegex(value: string, patternOrCasing: string): boolean | null {\n if (!patternOrCasing) return true;\n \n // Strip generics for type testing (e.g. \"IdentifiedEntity<T>\" -> \"IdentifiedEntity\")\n const valueToTest = value.split('<')[0].trim();\n const regex = compilePattern(patternOrCasing);\n if (!regex) return null;\n return regex.test(valueToTest);\n}\n\nfunction checkNamedValue(\n ctx: RuleContext,\n value: string,\n pattern: string,\n message: string,\n specId?: string,\n isDraft?: boolean,\n): void {\n const result = checkCasingOrRegex(value, pattern);\n if (result === null) {\n ctx.addIssue(\n 'error',\n 'INVALID_NAMING_PATTERN',\n `Naming pattern \"${pattern}\" is neither a known casing style nor a valid regular expression.`,\n specId,\n isDraft,\n );\n return;\n }\n if (!result) {\n ctx.addIssue('warning', 'NAMING_CONVENTION_VIOLATION', message, specId, isDraft);\n }\n}\n\nfunction getBaseId(id: string): string {\n const parts = id.split('::');\n return parts[parts.length - 1];\n}\n\nconst isAllUppercase = (s: string) => /^[A-Z0-9_]+$/.test(s);\n\nexport const namingRule: SddRule = {\n name: 'naming-conventions',\n description:\n 'Enforces naming conventions (casing styles or regular expressions) for subsystem, component, interface, type (differentiating entities and value-objects), method, variables/parameters, fields, and constants names/IDs, plus stereotype-specific naming patterns.',\n codes: [\n { code: 'NAMING_CONVENTION_VIOLATION', defaultSeverity: 'warning', summary: 'Item name or ID does not match the configured casing pattern or regex' },\n { code: 'STEREOTYPE_NAMING_VIOLATION', defaultSeverity: 'warning', summary: 'Component name or ID does not match stereotype suffix/prefix/regex rules' },\n { code: 'INVALID_NAMING_PATTERN', defaultSeverity: 'error', summary: 'Configured naming pattern is not a known casing style or valid regular expression' },\n ],\n check(ctx) {\n // 1. Subsystems\n for (const sub of ctx.subsystems) {\n const namingConfig = getEffectiveNamingConfig(ctx, sub.id);\n if (!namingConfig?.subsystems) continue;\n\n const baseId = getBaseId(sub.id);\n checkNamedValue(ctx, baseId, namingConfig.subsystems, `Subsystem ID \"${sub.id}\" does not match naming convention \"${namingConfig.subsystems}\".`, sub.id);\n checkNamedValue(ctx, sub.name, namingConfig.subsystems, `Subsystem Name \"${sub.name}\" does not match naming convention \"${namingConfig.subsystems}\".`, sub.id);\n }\n\n // 2. Components & Stereotypes\n for (const comp of ctx.components) {\n const namingConfig = getEffectiveNamingConfig(ctx, comp.subsystem);\n const isDraft = ctx.isComponentDraft(comp.id);\n\n if (namingConfig?.components) {\n const baseId = getBaseId(comp.id);\n checkNamedValue(ctx, baseId, namingConfig.components, `Component ID \"${comp.id}\" does not match naming convention \"${namingConfig.components}\".`, comp.id, isDraft);\n checkNamedValue(ctx, comp.name, namingConfig.components, `Component Name \"${comp.name}\" does not match naming convention \"${namingConfig.components}\".`, comp.id, isDraft);\n }\n\n // Stereotype suffix/prefix/regex checks\n const stereotypesConfig = namingConfig?.stereotypes?.[comp.componentType];\n if (stereotypesConfig) {\n const matchMode = stereotypesConfig.match ?? 'both';\n const prefix = stereotypesConfig.prefix;\n const suffix = stereotypesConfig.suffix;\n const regexStr = stereotypesConfig.regex;\n\n const baseId = getBaseId(comp.id);\n const idsToTest = matchMode === 'id' || matchMode === 'both' ? [baseId] : [];\n const namesToTest = matchMode === 'name' || matchMode === 'both' ? [comp.name] : [];\n const allToTest = [...idsToTest, ...namesToTest];\n\n for (const val of allToTest) {\n if (prefix && !val.startsWith(prefix)) {\n ctx.addIssue(\n 'warning',\n 'STEREOTYPE_NAMING_VIOLATION',\n `Component \"${comp.id}\" (${comp.componentType}) naming check failed: \"${val}\" must start with prefix \"${prefix}\".`,\n comp.id,\n isDraft\n );\n }\n if (suffix && !val.endsWith(suffix)) {\n ctx.addIssue(\n 'warning',\n 'STEREOTYPE_NAMING_VIOLATION',\n `Component \"${comp.id}\" (${comp.componentType}) naming check failed: \"${val}\" must end with suffix \"${suffix}\".`,\n comp.id,\n isDraft\n );\n }\n const regex = regexStr ? compilePattern(regexStr) : null;\n if (regexStr && !regex) {\n ctx.addIssue(\n 'error',\n 'INVALID_NAMING_PATTERN',\n `Stereotype naming regex \"${regexStr}\" for component type \"${comp.componentType}\" is invalid.`,\n comp.id,\n isDraft\n );\n } else if (regex && !regex.test(val)) {\n ctx.addIssue(\n 'warning',\n 'STEREOTYPE_NAMING_VIOLATION',\n `Component \"${comp.id}\" (${comp.componentType}) naming check failed: \"${val}\" does not match regex \"${regexStr}\".`,\n comp.id,\n isDraft\n );\n }\n }\n }\n }\n\n // 3. Interfaces & Methods & Variables\n for (const intf of ctx.interfaces) {\n const comp = ctx.componentMap.get(intf.component);\n const namingConfig = getEffectiveNamingConfig(ctx, comp?.subsystem);\n const isDraft = ctx.isComponentDraft(intf.component) || intf.status === 'draft' || intf.status === 'design';\n\n if (namingConfig?.interfaces) {\n const baseId = getBaseId(intf.id);\n // Strip the leading 'i' prefix if it is required by the SpecIdSchema itself.\n const cleanId = baseId.startsWith('i') ? baseId.slice(1) : baseId;\n checkNamedValue(ctx, cleanId, namingConfig.interfaces, `Interface ID \"${intf.id}\" does not match naming convention \"${namingConfig.interfaces}\".`, intf.id, isDraft);\n checkNamedValue(ctx, intf.name, namingConfig.interfaces, `Interface Name \"${intf.name}\" does not match naming convention \"${namingConfig.interfaces}\".`, intf.id, isDraft);\n }\n\n for (const m of intf.methods) {\n if (namingConfig?.methods) {\n checkNamedValue(ctx, m.name, namingConfig.methods, `Interface method \"${m.name}\" on \"${intf.id}\" does not match naming convention \"${namingConfig.methods}\".`, intf.id, isDraft);\n }\n\n // Method parameter variable naming\n if (namingConfig?.variables) {\n for (const param of m.params ?? []) {\n checkNamedValue(ctx, param.name, namingConfig.variables, `Method parameter \"${param.name}\" in method \"${m.name}\" on \"${intf.id}\" does not match naming convention \"${namingConfig.variables}\".`, intf.id, isDraft);\n }\n }\n }\n }\n\n // 4. Implementations (check their methods match naming.methods casing)\n for (const impl of ctx.implementations) {\n const intf = ctx.interfaceMap.get(impl.contract);\n const comp = intf ? ctx.componentMap.get(intf.component) : undefined;\n const namingConfig = getEffectiveNamingConfig(ctx, comp?.subsystem);\n const isDraft = impl.status === 'draft' || impl.status === 'design';\n\n if (namingConfig?.methods) {\n for (const m of impl.methods) {\n checkNamedValue(ctx, m.name, namingConfig.methods, `Implementation method \"${m.name}\" on \"${impl.id}\" does not match naming convention \"${namingConfig.methods}\".`, impl.id, isDraft);\n }\n }\n }\n\n // 5. Types & Fields & Methods & Constants\n for (const t of ctx.types) {\n const namingConfig = getEffectiveNamingConfig(ctx, t.subsystem);\n \n // Determine type naming rule pattern based on kind (entity vs value-object)\n let typePattern = namingConfig?.types;\n if (t.kind === 'entity' && namingConfig?.entities) {\n typePattern = namingConfig.entities;\n } else if (t.kind === 'value-object' && namingConfig?.valueObjects) {\n typePattern = namingConfig.valueObjects;\n }\n\n if (typePattern) {\n const baseId = getBaseId(t.id);\n checkNamedValue(ctx, baseId, typePattern, `Type ID \"${t.id}\" (${t.kind}) does not match naming convention \"${typePattern}\".`, t.id);\n checkNamedValue(ctx, t.name, typePattern, `Type Name \"${t.name}\" (${t.kind}) does not match naming convention \"${typePattern}\".`, t.id);\n }\n\n // Fields & Constants checks\n for (const f of t.fields) {\n // If field name is all uppercase, consider it a constant\n const isConst = isAllUppercase(f.name);\n const fieldPattern = (isConst && namingConfig?.constants) ? namingConfig.constants : namingConfig?.fields;\n \n if (fieldPattern) {\n checkNamedValue(ctx, f.name, fieldPattern, `${isConst ? 'Constant' : 'Field'} \"${f.name}\" on type \"${t.id}\" does not match naming convention \"${fieldPattern}\".`, t.id);\n }\n }\n\n if (namingConfig?.methods) {\n for (const m of t.methods) {\n checkNamedValue(ctx, m.name, namingConfig.methods, `Method \"${m.name}\" on type \"${t.id}\" does not match naming convention \"${namingConfig.methods}\".`, t.id);\n }\n }\n }\n },\n};\n","import * as path from 'path';\nimport type { ImplementationSpec } from '../../models/index.js';\nimport { normalizeSourcePath } from '../source-analysis.js';\nimport type { RuleContext, SddRule } from './types.js';\nimport { isInChainedSubproject } from './conformance.js';\n\n// ---------------------------------------------------------------------------\n// Integration conformance (docs/design/integration-conformance.md §4).\n//\n// Unit suites with mocked collaborators prove contract SHAPE; cross-component\n// bugs live in the wiring the mocks encode away. The static gate proves — and\n// only proves — that a committed integration harness (L4 `simPath`) EXISTS\n// and its import graph WIRES the real modules: the component's own sourcePath\n// and at least one sourcePath of each direct dependency. Whether the harness\n// PASSES is CI's job (it is an ordinary test file); the validator never runs\n// anything.\n//\n// Adoption is subsystem-by-subsystem and mechanical: declaring the FIRST\n// simPath in a subsystem activates MISSING_INTEGRATION_SIM for that\n// subsystem's other complete, non-leaf implementations — no global flood on\n// trees that have not adopted sims yet.\n// ---------------------------------------------------------------------------\n\nconst normalizePath = normalizeSourcePath;\n\n/** Pure candidate resolution of a relative specifier against the analyzed-file set (mirrors dependency-conformance). */\nfunction resolveAgainst(mapped: Set<string>, fromFile: string, specifier: string): string | null {\n if (!specifier.startsWith('.')) return null;\n const joined = normalizePath(path.posix.normalize(path.posix.join(path.posix.dirname(fromFile), specifier)));\n const candidates = [\n joined,\n joined.replace(/\\.js$/, '.ts'), joined.replace(/\\.js$/, '.tsx'),\n `${joined}.ts`, `${joined}.tsx`, `${joined}.js`,\n `${joined}/index.ts`, `${joined}/index.js`,\n ];\n for (const c of candidates) {\n if (mapped.has(c)) return c;\n }\n return null;\n}\n\nexport const integrationConformanceRule: SddRule = {\n name: 'integration-conformance',\n description:\n 'A component cannot honestly claim completeness until a committed integration harness wires it to its REAL dependencies (L4 simPath). Statically checked: the harness file exists inside the project root, and its import graph — closed transitively over the analyzed module set, exact grade only — reaches the component\\'s own sourcePath module and at least one sourcePath module of each direct dependsOn/owns component (technology-boundary dependencies exempt: their fakes are sanctioned). Execution is CI\\'s job — these findings prove wiring, never that the sim passes. MISSING_INTEGRATION_SIM activates per subsystem once its first simPath is declared.',\n codes: [\n { code: 'MISSING_INTEGRATION_SIM', defaultSeverity: 'warning', summary: 'Complete non-leaf implementation in a sim-adopting subsystem declares no simPath' },\n { code: 'SIM_FILE_MISSING', defaultSeverity: 'warning', summary: 'Declared simPath resolves to no file inside the project root' },\n { code: 'UNWIRED_INTEGRATION_SIM', defaultSeverity: 'warning', summary: 'Sim file does not import the real modules it claims to wire' },\n { code: 'SIM_PATH_UNCOVERED', defaultSeverity: 'warning', summary: 'A narrative path has no sim:<component>.<method>[:<label>] anchor in the component\\'s coverage-opted harness' },\n ],\n check(ctx: RuleContext): void {\n const factsByPath = new Map(ctx.codeModel.files.map(f => [normalizePath(f.path), f]));\n const allPaths = new Set(factsByPath.keys());\n\n // Files realizing each component / each subsystem (reach targets). The\n // subsystem set exists for cross-subsystem dependencies: the published\n // portal's barrel is cosmetic at runtime (same doctrine as\n // dependency-conformance), so wiring is proven by reaching ANY module of\n // the target subsystem.\n const filesByComponent = new Map<string, Set<string>>();\n const filesBySubsystem = new Map<string, Set<string>>();\n const implsByComponent = new Map<string, ImplementationSpec[]>();\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n const comp = contract ? ctx.componentMap.get(contract.component) : undefined;\n if (!comp) continue;\n if (!implsByComponent.has(comp.id)) implsByComponent.set(comp.id, []);\n implsByComponent.get(comp.id)!.push(impl);\n if (impl.sourcePath) {\n const p = normalizePath(impl.sourcePath);\n if (!filesByComponent.has(comp.id)) filesByComponent.set(comp.id, new Set());\n filesByComponent.get(comp.id)!.add(p);\n if (!filesBySubsystem.has(comp.subsystem)) filesBySubsystem.set(comp.subsystem, new Set());\n filesBySubsystem.get(comp.subsystem)!.add(p);\n }\n }\n\n // A dependency whose implementations declare technologies is a technology\n // boundary — its contract-faithful fake is sanctioned, so the sim need\n // not import its real module.\n const isTechBoundary = (compId: string): boolean =>\n (implsByComponent.get(compId) ?? []).some(i => (i.technologies ?? []).length > 0);\n\n // Subsystems that have adopted sims: any implementation declaring one.\n const adopted = new Set<string>();\n for (const impl of ctx.implementations) {\n if (!impl.simPath) continue;\n const contract = ctx.interfaceMap.get(impl.contract);\n const comp = contract ? ctx.componentMap.get(contract.component) : undefined;\n if (comp) adopted.add(comp.subsystem);\n }\n\n // Transitive import closure from one file over the analyzed set (imports\n // realize wiring; export-from barrels republish it — both count).\n const reachFrom = (start: string): Set<string> => {\n const seen = new Set<string>([start]);\n const stack = [start];\n while (stack.length) {\n const from = stack.pop()!;\n const facts = factsByPath.get(from);\n if (!facts || facts.status !== 'analyzed') continue;\n for (const spec of [...facts.imports, ...facts.reexports]) {\n const to = resolveAgainst(allPaths, from, spec);\n if (to && !seen.has(to)) { seen.add(to); stack.push(to); }\n }\n }\n return seen;\n };\n\n for (const impl of ctx.implementations) {\n const contract = ctx.interfaceMap.get(impl.contract);\n const comp = contract ? ctx.componentMap.get(contract.component) : undefined;\n if (!comp) continue;\n if (isInChainedSubproject(comp.subsystem, ctx)) continue;\n\n const deps = [...new Set([...comp.dependsOn, ...comp.owns])].filter(d => ctx.componentMap.has(d));\n\n if (!impl.simPath) {\n // Expectation half: only for complete implementations, only once the\n // subsystem has adopted sims, and only for non-leaf components (a\n // leaf's unit suite IS its sim).\n if (!adopted.has(comp.subsystem)) continue;\n if (ctx.isImplementationDraft(impl)) continue;\n if (deps.length === 0) continue;\n ctx.addIssue(\n 'warning',\n 'MISSING_INTEGRATION_SIM',\n `Implementation \"${impl.id}\" (component \"${comp.id}\") is complete with ${deps.length} declared dependenc${deps.length === 1 ? 'y' : 'ies'}, its subsystem \"${comp.subsystem}\" has adopted integration sims, but it declares no simPath — its unit suite proves contract shape against mocks, not that the wired components run together. Declare the committed harness that constructs it with its REAL dependencies (N:1 sharing allowed), or lint.allow with the reason.`,\n impl.id,\n );\n continue;\n }\n\n // Soundness half: the declared harness must exist and wire the real modules.\n const simPath = normalizePath(impl.simPath);\n const facts = factsByPath.get(simPath);\n const isDraftCtx = ctx.isImplementationDraft(impl);\n if (!facts || facts.status === 'missing' || facts.status === 'escaped' || facts.status === 'unreadable') {\n const why = !facts || facts.status === 'missing'\n ? 'resolves to no file'\n : facts.status === 'escaped' ? 'escapes the project root — sims are project-relative, committed files'\n : 'is not readable as source text';\n ctx.addIssue(\n 'warning',\n 'SIM_FILE_MISSING',\n `Implementation \"${impl.id}\" declares simPath \"${impl.simPath}\", which ${why}. The integration harness must be a committed, re-runnable file inside the project.`,\n impl.id,\n isDraftCtx,\n );\n continue;\n }\n // Only exact-grade import graphs can prove wiring — weaker grades stay\n // silent rather than guess (the honest-lint stance).\n if (facts.analysisGrade !== 'exact') continue;\n\n const reach = reachFrom(simPath);\n const ownFiles = filesByComponent.get(comp.id) ?? new Set<string>();\n const missing: string[] = [];\n if (ownFiles.size > 0 && ![...ownFiles].some(f => reach.has(f))) {\n missing.push(`the component's own module (${[...ownFiles].join(' | ')})`);\n }\n for (const dep of deps) {\n if (isTechBoundary(dep)) continue;\n const depComp = ctx.componentMap.get(dep)!;\n // Cross-subsystem: the sanctioned hop is the published surface whose\n // barrel is cosmetic — any reached module of the target subsystem\n // proves the real wiring.\n const depFiles = depComp.subsystem !== comp.subsystem\n ? filesBySubsystem.get(depComp.subsystem)\n : filesByComponent.get(dep);\n if (!depFiles || depFiles.size === 0) continue; // unrealized dependency — its own findings cover that\n if (![...depFiles].some(f => reach.has(f))) {\n const label = depComp.subsystem !== comp.subsystem ? `\"${dep}\" (any module of subsystem \"${depComp.subsystem}\")` : `\"${dep}\" (${[...depFiles].join(' | ')})`;\n missing.push(label);\n }\n }\n if (missing.length) {\n ctx.addIssue(\n 'warning',\n 'UNWIRED_INTEGRATION_SIM',\n `Sim \"${impl.simPath}\" of implementation \"${impl.id}\" does not reach ${missing.join(', nor ')} through its import graph (closed over the analyzed modules, exact grade) — the harness is not wiring the real implementations it claims to exercise. Import the real modules (technology-boundary adapters may stay contract-faithfully faked), or fix the simPath.`,\n impl.id,\n isDraftCtx,\n );\n }\n\n // Path coverage (§4.5) — opt-in PER COMPONENT: only once the harness\n // carries at least one \"sim:<component-id>.\" anchor does this component\n // claim path coverage, and only then are its narrated methods held to\n // it. An anchor proves the harness NAMES the path; whether the driven\n // scenario asserts anything useful stays the test author's craft.\n const simAnchors = new Set(facts.anchoredNames.filter(a => a.startsWith('sim:')));\n if (simAnchors.size === 0) continue;\n const compPrefix = `sim:${comp.id}.`;\n if (![...simAnchors].some(a => a.startsWith(compPrefix))) continue;\n\n const uncovered: string[] = [];\n for (const method of impl.methods) {\n const steps = method.narrative ?? [];\n if (!steps.length) continue;\n const happy = `sim:${comp.id}.${method.name}`;\n if (!simAnchors.has(happy)) {\n uncovered.push(`the happy path of \"${method.name}\" (anchor \"${happy}\")`);\n }\n for (const step of steps) {\n if (step.type !== 'throw' || !step.label) continue;\n const pathAnchor = `sim:${comp.id}.${method.name}:${step.label}`;\n if (!simAnchors.has(pathAnchor)) {\n uncovered.push(`error path \"${step.label}\" of \"${method.name}\" (anchor \"${pathAnchor}\")`);\n }\n }\n }\n if (uncovered.length) {\n ctx.addIssue(\n 'warning',\n 'SIM_PATH_UNCOVERED',\n `Sim \"${impl.simPath}\" declares path coverage for component \"${comp.id}\" (it carries sim: anchors) but does not name ${uncovered.join(', nor ')}. Drive the path and anchor it with the exact string literal, or drop the component's sim: anchors to withdraw the coverage claim. Unlabeled throw steps are not expected — a step's label is the path's identity. Anchors prove the path is NAMED; assertion quality and execution stay CI's job.`,\n impl.id,\n isDraftCtx,\n );\n }\n }\n },\n};\n","import type { ImplementationSpec } from '../../models/index.js';\nimport { normalizeSourcePath } from '../source-analysis.js';\nimport { RuleContext, SddRule } from './types.js';\nimport { isInChainedSubproject } from './conformance.js';\n\n// ---------------------------------------------------------------------------\n// HIDDEN_STATE — the enforcement half of the fields-vs-Store criterion.\n//\n// The doctrine: a component's own fields hold only wiring/config/ephemeral\n// state; anything written after construction AND read across separate\n// entrypoint activations is domain state and belongs in a Store (or a Store\n// with durability: cache, for memo state). This lint is the honest STATIC\n// approximation: module-scope mutable bindings (`let`/`var`) in a file whose\n// mapped components are exclusively LOGIC stereotypes.\n//\n// Deliberately conservative:\n// - exact analysis grade only (lower grades never guess);\n// - files mapped to ANY data/boundary component are exempt (a shared file\n// hosting a Store's state is the Store's business — N:1 collapse);\n// - conformance: off implementations don't count as mapping evidence;\n// - mutation of const-bound containers (a `const map = new Map()` that is\n// written per-request) is invisible to this check — the finding text says\n// what was measured, never more.\n// ---------------------------------------------------------------------------\n\n/** The stereotypes where behavior lives and held state must not. */\nconst LOGIC_STEREOTYPES = new Set(['Orchestrator', 'Supervisor', 'Actor', 'Specialist']);\n\nexport const hiddenStateRule: SddRule = {\n name: 'hidden-state',\n description:\n 'The fields-vs-Store criterion, statically approximated: module-scope mutable bindings (let/var) in a source file mapped EXCLUSIVELY to logic-stereotype components (Orchestrator/Supervisor/Actor/Specialist) are flagged as hidden held state — state a logic component keeps for itself is invisible to the spec, the canvas, and every persistence rule. Promote it to a Store (durability: cache for loss-safe memo state), or lint.allow with the reason it is genuinely wiring/ephemeral. Exact analysis grade only; files also mapped to data or boundary components are exempt (N:1 collapse); const-bound container mutation is beyond this check and the finding says so.',\n codes: [\n { code: 'HIDDEN_STATE', defaultSeverity: 'warning', summary: 'Module-scope mutable binding in a file mapped only to logic-stereotype components — held state hiding outside a Store' },\n ],\n check(ctx: RuleContext) {\n // sourcePath → the implementations mapping it (with their components).\n const byPath = new Map<string, { impl: ImplementationSpec; componentType: string; compId: string }[]>();\n for (const impl of ctx.implementations) {\n if (!impl.sourcePath) continue;\n if (impl.conformance === 'off') continue; // untrusted mapping\n const contract = ctx.interfaceMap.get(impl.contract);\n const component = contract ? ctx.componentMap.get(contract.component) : undefined;\n if (!component) continue;\n if (isInChainedSubproject(component.subsystem, ctx)) continue;\n const key = normalizeSourcePath(impl.sourcePath);\n const list = byPath.get(key) ?? [];\n list.push({ impl, componentType: component.componentType, compId: component.id });\n byPath.set(key, list);\n }\n\n for (const facts of ctx.codeModel.files) {\n if (facts.status !== 'analyzed' || facts.analysisGrade !== 'exact') continue;\n const bindings = facts.topLevelMutableBindings ?? [];\n if (bindings.length === 0) continue;\n\n const mapped = byPath.get(normalizeSourcePath(facts.path)) ?? [];\n if (mapped.length === 0) continue;\n if (!mapped.every(m => LOGIC_STEREOTYPES.has(m.componentType))) continue;\n\n const anchor = [...mapped].sort((a, b) => a.impl.id.localeCompare(b.impl.id))[0];\n const compList = [...new Set(mapped.map(m => `${m.compId} (${m.componentType})`))].join(', ');\n ctx.addIssue(\n 'warning',\n 'HIDDEN_STATE',\n `\"${facts.path}\" holds module-scope mutable binding(s) ${bindings.map(b => `\"${b}\"`).join(', ')} while realizing only logic components (${compList}). State written after construction and read across invocations belongs in a Store — visible to the spec — not inside a logic component (a loss-safe memo belongs in a Store with durability: cache). Promote the state, or lint.allow with the reason it is genuinely wiring/ephemeral. (Measured: let/var at module scope, exact grade; const-bound container mutation is beyond this check.)`,\n anchor.impl.id,\n mapped.some(m => ctx.isImplementationDraft(m.impl)),\n );\n }\n },\n};\n","import * as path from 'path';\nimport type { ComponentSpec, ImplementationSpec } from '../../models/index.js';\nimport { normalizeSourcePath } from '../source-analysis.js';\nimport { RuleContext, SddRule } from './types.js';\nimport { isInChainedSubproject } from './conformance.js';\n\n// ---------------------------------------------------------------------------\n// Dependency conformance (code↔spec Level 2)\n//\n// The spec declares who collaborates (dependsOn/owns); the code's runtime\n// import graph is the physical record of who ACTUALLY collaborates. This rule\n// lifts file→file import edges (between component-mapped files only) to\n// component sets via the sourcePath map and checks both directions:\n//\n// UNDECLARED_DEPENDENCY — an import edge no declared relation justifies.\n// Justified when the two files share a component, any component pair has\n// a direct dependsOn/owns edge, the target is a member of a pattern the\n// importer depends on, or — across subsystems — the importer declares an\n// edge to the target subsystem's PUBLISHED surface (in-process imports\n// may land in the subsystem's concrete modules; the published-portal\n// declaration is the sanctioned hop, its barrel is cosmetic at runtime).\n//\n// UNREALIZED_DEPENDENCY — a declared dependsOn/owns edge between components\n// realized in different files with NO import edge realizing it (for a\n// cross-subsystem portal edge: no import landing anywhere in the target\n// subsystem). Skipped when either side shares a file (N:1 collapse) —\n// dependency-injection indirection can also produce false positives,\n// which is why this stays a warning.\n//\n// Resolution is PURE: import specifiers are resolved string-wise against the\n// closed set of component-mapped paths (.js→.ts swaps, index files) — no I/O.\n// Only exact-grade (AST) analyzed files participate; pattern/generic imports\n// are too coarse to accuse anyone with. Type-only imports never reach the\n// model (excluded at collection). Chained-subproject implementations validate\n// standalone in their own run and are skipped here, as in Level 1.\n// ---------------------------------------------------------------------------\n\ninterface FileNode {\n /** Normalized project-relative path (forward slashes). */\n path: string;\n components: ComponentSpec[];\n /** First impl id mapped to this file (deterministic finding anchor). */\n anchorImplId: string;\n imports: string[];\n reexports: string[];\n draft: boolean;\n}\n\nconst normalizePath = normalizeSourcePath;\n\n/** Pure candidate resolution of a relative specifier against the mapped-file set. */\nfunction resolveAgainst(mapped: Set<string>, fromFile: string, specifier: string): string | null {\n if (!specifier.startsWith('.')) return null;\n const joined = normalizePath(path.posix.normalize(path.posix.join(path.posix.dirname(fromFile), specifier)));\n const candidates = [\n joined,\n joined.replace(/\\.js$/, '.ts'), joined.replace(/\\.js$/, '.tsx'),\n `${joined}.ts`, `${joined}.tsx`, `${joined}.js`,\n `${joined}/index.ts`, `${joined}/index.js`,\n ];\n for (const c of candidates) {\n if (mapped.has(c)) return c;\n }\n return null;\n}\n\nexport const dependencyConformanceRule: SddRule = {\n name: 'dependency-conformance',\n description:\n 'Code↔spec Level 2: runtime import edges between component-mapped source files must be justified by declared relations — a direct dependsOn/owns pair, a shared component, membership in a depended-on pattern, or (across subsystems) a declared edge to the target subsystem\\'s published surface (UNDECLARED_DEPENDENCY). Conversely, a declared dependsOn/owns edge between components realized in different files should be visible as an import (UNREALIZED_DEPENDENCY — DI indirection can defeat this, hence warning). Only exact-grade analyzed files participate; type-only imports are exempt; chained subprojects validate standalone.',\n codes: [\n { code: 'UNDECLARED_DEPENDENCY', defaultSeverity: 'warning', summary: 'A runtime import between component-mapped files has no declared dependsOn/owns (or published-surface) justification' },\n { code: 'UNREALIZED_DEPENDENCY', defaultSeverity: 'warning', summary: 'A declared dependsOn/owns edge between components in different files is realized by no import' },\n ],\n\n check(ctx: RuleContext): void {\n // ---- build the file→components map (exact-grade, non-chained only) ----\n const factsByPath = new Map(ctx.codeModel.files.map(f => [normalizePath(f.path), f]));\n const nodes = new Map<string, FileNode>();\n const filesByComponent = new Map<string, Set<string>>();\n const implsByComponent = new Map<string, ImplementationSpec[]>();\n\n for (const impl of ctx.implementations) {\n if (!impl.sourcePath) continue;\n const contract = ctx.interfaceMap.get(impl.contract);\n if (!contract) continue;\n const component = ctx.componentMap.get(contract.component);\n if (!component) continue;\n if (isInChainedSubproject(component.subsystem, ctx)) continue;\n\n const p = normalizePath(impl.sourcePath);\n const facts = factsByPath.get(p);\n if (!facts || facts.status !== 'analyzed' || facts.analysisGrade !== 'exact') continue;\n\n let node = nodes.get(p);\n if (!node) {\n node = { path: p, components: [], anchorImplId: impl.id, imports: facts.imports, reexports: facts.reexports, draft: false };\n nodes.set(p, node);\n }\n if (!node.components.some(c => c.id === component.id)) node.components.push(component);\n node.draft = node.draft || ctx.isImplementationDraft(impl);\n\n if (!filesByComponent.has(component.id)) filesByComponent.set(component.id, new Set());\n filesByComponent.get(component.id)!.add(p);\n if (!implsByComponent.has(component.id)) implsByComponent.set(component.id, []);\n implsByComponent.get(component.id)!.push(impl);\n }\n\n const mappedPaths = new Set(nodes.keys());\n\n // ---- resolve import edges between mapped files ----\n // Runtime imports are collaboration (checked); export-from re-exports are\n // surface republication (never accused, but they DO realize a declared\n // forwarding edge — a portal barrel republishing its orchestrator).\n const edges = new Map<string, Set<string>>(); // from path -> to paths\n const realizationEdges = new Map<string, Set<string>>(); // imports ∪ reexports\n for (const node of nodes.values()) {\n const targets = new Set<string>();\n for (const spec of node.imports) {\n const resolved = resolveAgainst(mappedPaths, node.path, spec);\n if (resolved && resolved !== node.path) targets.add(resolved);\n }\n edges.set(node.path, targets);\n const realized = new Set(targets);\n for (const spec of node.reexports) {\n const resolved = resolveAgainst(mappedPaths, node.path, spec);\n if (resolved && resolved !== node.path) realized.add(resolved);\n }\n realizationEdges.set(node.path, realized);\n }\n\n // ---- justification helpers ----\n const dependsOrOwns = (from: ComponentSpec, toId: string): boolean =>\n from.dependsOn.includes(toId) || (from.owns ?? []).includes(toId);\n\n // pattern facade ownership, one hop (owner computed once, both directions)\n const ownerOf = new Map<string, ComponentSpec>();\n for (const c of ctx.components) {\n for (const member of c.owns ?? []) ownerOf.set(member, c);\n }\n\n // Does `from` declare an edge to the published surface of `subsystemId`?\n const declaresSurfaceEdge = (from: ComponentSpec, subsystemId: string): boolean => {\n const published = ctx.publicSet.get(subsystemId);\n if (!published || published.size === 0) return false;\n return from.dependsOn.some(d => published.has(d));\n };\n\n const edgeJustified = (fromNode: FileNode, toNode: FileNode): boolean => {\n for (const cf of fromNode.components) {\n for (const cg of toNode.components) {\n if (cf.id === cg.id) return true;\n if (dependsOrOwns(cf, cg.id)) return true;\n // mutual wiring collapsed to one file direction: a portal declares\n // it mounts ONTO the server (portal → supervisor), while the server\n // file physically imports the portal's file to dispatch inward —\n // the declared relation exists, code chose the other direction.\n // ONLY the mounting shape (the reverse-declarer is an inbound\n // Portal/Observer) is forgiven; a Store importing the orchestrator\n // that depends on it stays a violation.\n if (\n cf.subsystem === cg.subsystem\n && dependsOrOwns(cg, cf.id)\n && (cg.componentType === 'Portal' || cg.componentType === 'Observer')\n ) return true;\n // facade hops, both directions: the target is a member of a pattern\n // the importer depends on/is; OR the importer is itself an owned\n // member whose FACADE declares the collaborator (a Repository's\n // Store does the physical I/O the Repository declared) — and two\n // members of the same pattern collaborate by construction.\n const ownerG = ownerOf.get(cg.id);\n if (ownerG && (dependsOrOwns(cf, ownerG.id) || cf.id === ownerG.id)) return true;\n const ownerF = ownerOf.get(cf.id);\n if (ownerF && (dependsOrOwns(ownerF, cg.id) || ownerF.id === cg.id)) return true;\n if (ownerF && ownerG && ownerF.id === ownerG.id) return true;\n // cross-subsystem: declared edge to the target subsystem's surface\n if (cf.subsystem !== cg.subsystem && declaresSurfaceEdge(cf, cg.subsystem)) return true;\n }\n }\n return false;\n };\n\n // ---- UNDECLARED_DEPENDENCY: every import edge needs a justification ----\n for (const [fromPath, targets] of edges) {\n const fromNode = nodes.get(fromPath)!;\n for (const toPath of targets) {\n const toNode = nodes.get(toPath)!;\n if (edgeJustified(fromNode, toNode)) continue;\n ctx.addIssue(\n 'warning',\n 'UNDECLARED_DEPENDENCY',\n `\"${fromPath}\" (realizing ${fromNode.components.map(c => c.id).join(', ')}) imports \"${toPath}\" (realizing ${toNode.components.map(c => c.id).join(', ')}) but no declared dependsOn/owns edge justifies it — declare the collaboration on the component that actually uses it, or route the cross-subsystem hop through the target's published surface.`,\n fromNode.anchorImplId,\n fromNode.draft || toNode.draft,\n );\n }\n }\n\n // ---- UNREALIZED_DEPENDENCY: every declared edge should leave a trace ----\n // A trace is a runtime import, a re-export (barrel forwarding), or — for a\n // mounting declarer (Portal/Observer) — the REVERSE import (the server\n // file imports the portal's file; mutual wiring, one file direction).\n const hasImportBetween = (fromFiles: Set<string>, toFiles: Set<string>, allowReverse: boolean): boolean => {\n for (const f of fromFiles) {\n const targets = realizationEdges.get(f);\n if (!targets) continue;\n for (const t of toFiles) if (targets.has(t)) return true;\n }\n if (allowReverse) {\n for (const t of toFiles) {\n const reverse = realizationEdges.get(t);\n if (!reverse) continue;\n for (const f of fromFiles) if (reverse.has(f)) return true;\n }\n }\n return false;\n };\n\n for (const component of ctx.components) {\n const fromFiles = filesByComponent.get(component.id);\n if (!fromFiles) continue;\n\n const isMountingDeclarer = component.componentType === 'Portal' || component.componentType === 'Observer';\n const declaredTargets = [...component.dependsOn, ...(component.owns ?? [])];\n for (const targetId of declaredTargets) {\n const target = ctx.componentMap.get(targetId);\n if (!target) continue;\n\n if (component.subsystem !== target.subsystem) {\n // Cross-subsystem portal edge: realized when ANY import lands in the\n // target subsystem's mapped files.\n const subsystemFiles = new Set<string>();\n for (const node of nodes.values()) {\n if (node.components.some(c => c.subsystem === target.subsystem)) subsystemFiles.add(node.path);\n }\n if (subsystemFiles.size === 0) continue;\n for (const f of fromFiles) subsystemFiles.delete(f); // shared files satisfy trivially\n if (subsystemFiles.size === 0) continue;\n if (hasImportBetween(fromFiles, subsystemFiles, isMountingDeclarer)) continue;\n } else {\n const toFiles = filesByComponent.get(targetId);\n if (!toFiles) continue; // target unmapped (no sourcePath / non-exact) — Level 1 territory\n if ([...fromFiles].some(f => toFiles.has(f))) continue; // N:1 same-file collapse\n if (hasImportBetween(fromFiles, toFiles, isMountingDeclarer)) continue;\n }\n\n const impls = implsByComponent.get(component.id) ?? [];\n const anchor = impls[0];\n const draft = ctx.isComponentDraft(component.id) || ctx.isComponentDraft(targetId)\n || impls.some(i => ctx.isImplementationDraft(i));\n ctx.addIssue(\n 'warning',\n 'UNREALIZED_DEPENDENCY',\n `Component \"${component.id}\" declares ${component.dependsOn.includes(targetId) ? 'dependsOn' : 'owns'} \"${targetId}\", but no runtime import connects their source files (${[...fromFiles].join(', ')} ↛ ${target.subsystem !== component.subsystem ? `subsystem ${target.subsystem}` : [...(filesByComponent.get(targetId) ?? [])].join(', ')}) — either the collaboration is wired indirectly (DI) or the declared edge is stale.`,\n anchor?.id ?? component.id,\n draft,\n );\n }\n }\n },\n};\n","import { SddRule } from './types.js';\n\n/**\n * Audits per-spec lint suppressions (lint.allow — wairon's #[allow(...)]).\n * The suppression itself happens centrally in ctx.addIssue; this rule runs\n * LAST in the registry so every other rule has already had the chance to\n * match (and mark) each allow. Two failure modes are flagged:\n *\n * - an allow naming a code no registered rule can emit (typo / removed rule),\n * - an allow that matched nothing this run — stale suppressions rot into\n * invisible risk exactly like commented-out tests.\n *\n * By design, allows silence WARNING-severity findings only. Error findings\n * are architecture violations and always surface; a human can still re-tune\n * a code globally via rules.sddRuleSeverity in project.yaml.\n */\nexport const lintAllowsRule: SddRule = {\n name: 'lint-allows',\n description:\n 'Per-spec lint suppressions (lint.allow) must name real issue codes and actually suppress a finding — unknown codes and stale allows are flagged. Allows silence warnings only; errors always surface.',\n codes: [\n { code: 'UNKNOWN_LINT_ALLOW_CODE', defaultSeverity: 'warning', summary: 'lint.allow names an issue code no registered rule emits' },\n { code: 'UNUSED_LINT_ALLOW', defaultSeverity: 'warning', summary: 'lint.allow entry matched no finding this run — remove the stale allow' },\n ],\n check(ctx) {\n for (const a of ctx.lintAllows) {\n if (!ctx.knownIssueCodes.has(a.code)) {\n ctx.addIssue(\n 'warning',\n 'UNKNOWN_LINT_ALLOW_CODE',\n `Spec \"${a.specId}\" allows unknown issue code \"${a.code}\" — no registered rule emits it (see \\`wairon rules list\\`).`,\n a.specId,\n );\n continue;\n }\n if (!a.used) {\n ctx.addIssue(\n 'warning',\n 'UNUSED_LINT_ALLOW',\n `Spec \"${a.specId}\" allows \"${a.code}\" (reason: ${a.reason}) but no such finding fired this run — remove the stale allow.`,\n a.specId,\n );\n }\n }\n },\n};\n","import {\n SystemSpec,\n SubsystemSpec,\n ComponentSpec,\n InterfaceSpec,\n ImplementationSpec,\n TypeSpec,\n RulesConfig,\n} from '../../models/index.js';\nimport type { ValidationIssue } from '../validation.js';\nimport { emptyExtensions, LoadedExtensions } from '../extensions.js';\nimport type { VariantDef } from '../variants.js';\nimport { ArchProfile, BUILTIN_PROFILES, RuleContext, SddRule, Severity } from './types.js';\nimport { BUILTIN_TYPES, matchTypeRef, normalizeLanguage } from './type-analysis.js';\n\nimport { hierarchyRule } from './hierarchy.js';\nimport { typeReferencesRule } from './type-references.js';\nimport { contractsRule } from './contracts.js';\nimport { narrativeFlowRule } from './narrative-flow.js';\nimport { narrativeDetailRule } from './narrative-detail.js';\nimport { portalsRule } from './portals.js';\nimport { stereotypeDepsRule } from './stereotype-deps.js';\nimport { patternsRule } from './patterns.js';\nimport { facadeForwardingRule } from './facade-forwarding.js';\nimport { patternReferencesRule } from './pattern-references.js';\nimport { variantReferencesRule } from './variant-references.js';\nimport { declarativeAssertionsRule } from './declarative-assertions.js';\nimport { profilesRule } from './profiles.js';\nimport { publicSurfaceRule } from './public-surface.js';\nimport { cyclesRule, reachabilityRule } from './graph.js';\nimport { dispatchRule, lifecycleRule, durabilityRule, untypedSeamRule, proseClaimRule } from './semantic-edges.js';\nimport { invariantBackingRule } from './invariants.js';\nimport { guaranteeTokensRule } from './guarantee-tokens.js';\nimport { eventTopologyRule } from './event-topology.js';\nimport { narrativeAntipatternsRule } from './narrative-antipatterns.js';\nimport { callConformanceRule } from './call-conformance.js';\nimport { roundtripRule, namespaceHygieneRule, surfaceFreshnessRule } from './namespace.js';\nimport { couplingRule } from './coupling.js';\nimport { languageRule } from './language.js';\nimport { technologyRule } from './technology.js';\nimport { namingRule } from './naming.js';\nimport { complexityRule } from './complexity.js';\nimport { structuralConformanceRule } from './conformance.js';\nimport { integrationConformanceRule } from './integration-conformance.js';\nimport { hiddenStateRule } from './hidden-state.js';\nimport { dependencyConformanceRule } from './dependency-conformance.js';\nimport { lintAllowsRule } from './lint-allows.js';\nimport { emptyCodeModel, CodeModel } from '../source-analysis.js';\n\nexport * from './types.js';\nexport * from './type-analysis.js';\n\n// ---------------------------------------------------------------------------\n// The registry. Order matters only for issue-list readability (hierarchy first,\n// heuristics last) — rules are independent.\n// ---------------------------------------------------------------------------\n\nexport const SDD_RULES: SddRule[] = [\n hierarchyRule,\n // Namespace integrity right after hierarchy: unresolvable/unwritable ids\n // explain many downstream findings, so surface them early in the list.\n namespaceHygieneRule,\n roundtripRule,\n surfaceFreshnessRule,\n typeReferencesRule,\n contractsRule,\n // Vocabulary check right after contracts: an unknown token explains why the\n // consistency findings around it are absent, so surface them together.\n guaranteeTokensRule,\n narrativeFlowRule,\n // Antipatterns right after flow soundness: they analyze the same step\n // graphs and only make sense once the graphs are structurally valid.\n narrativeAntipatternsRule,\n narrativeDetailRule,\n portalsRule,\n stereotypeDepsRule,\n patternsRule,\n // Facade shape rides with pattern ownership: same §7 doctrine, narrative side.\n facadeForwardingRule,\n profilesRule,\n patternReferencesRule,\n variantReferencesRule,\n // Pack-instantiated declarative doctrine rides with the pack-reference\n // family: same data source, same provenance-bearing findings.\n declarativeAssertionsRule,\n publicSurfaceRule,\n cyclesRule,\n // Semantic-edge family: dispatch/lifecycle validity BEFORE reachability so a\n // reader sees the broken edge finding next to the unused-detection fallout\n // it explains.\n dispatchRule,\n lifecycleRule,\n reachabilityRule,\n durabilityRule,\n untypedSeamRule,\n proseClaimRule,\n // Invariant registry rides with the semantic-edge family: declared entity\n // invariants must be asserted on every write path (declarations, not proofs).\n invariantBackingRule,\n // Pub/sub completeness: emitted topics need subscribers and vice versa.\n eventTopologyRule,\n // Code↔spec: structural conformance consumes the injected CodeModel (built\n // by the source analysis adapter next to the surface snapshots); dependency\n // conformance lifts its import edges onto the declared dependsOn/owns graph.\n structuralConformanceRule,\n // Level 3 opener: narrative call steps must be realized as callees of the\n // realized function (set membership, exact grade).\n callConformanceRule,\n // The fields-vs-Store criterion: mutable module state in logic-only files.\n hiddenStateRule,\n dependencyConformanceRule,\n // Integration wiring proof rides after the code↔spec family: it consumes\n // the same code model and speaks about the same sourcePath modules.\n integrationConformanceRule,\n couplingRule,\n languageRule,\n technologyRule,\n namingRule,\n complexityRule,\n // MUST run last: it audits which lint.allow entries the earlier rules\n // actually consumed (stale/unknown allows).\n lintAllowsRule,\n];\n\n/**\n * The full rule sequence for a validation run: built-ins, then extension-pack\n * rules, with the lint-allows audit LAST so it also sees every allow the pack\n * rules consumed (otherwise a suppressed pack warning reads as a stale allow).\n */\nexport function composeRuleSequence(extraRules: SddRule[] = []): SddRule[] {\n const base = SDD_RULES.filter(r => r !== lintAllowsRule);\n return [...base, ...extraRules, lintAllowsRule];\n}\n\n// ---------------------------------------------------------------------------\n// Design depth — which layers a project/subsystem COMMITS to designing.\n// EXPECTATION codes (something deeper must exist / be complete) are gated by\n// the effective depth; SOUNDNESS codes (what is authored must be coherent)\n// are deliberately absent from this map and always apply. The gate runs\n// BEFORE severity overrides: a gated code is skipped, period — raising the\n// depth is the way to get it back.\n// ---------------------------------------------------------------------------\n\ntype DesignDepth = import('../../models/index.js').DesignDepth;\n\nconst DEPTH_RANK: Record<DesignDepth, number> = {\n components: 2,\n interfaces: 3,\n implementations: 4,\n narratives: 5,\n};\n\n/** Expectation code → the minimum design depth at which it applies. */\nconst DEPTH_GATED_CODES: Record<string, DesignDepth> = {\n // L3 expectations: contract content the design promises at interface depth.\n MISSING_ENDPOINT: 'interfaces',\n MISSING_EFFECT_TAG: 'interfaces',\n UNUSED_TYPE: 'interfaces',\n // L4 expectations: implementations and their code linkage.\n MISSING_IMPLEMENTATION_METHOD: 'implementations',\n MISSING_SOURCE_PATH: 'implementations',\n MISSING_SOURCE_FILE: 'implementations',\n SOURCE_PATH_ESCAPES_ROOT: 'implementations',\n UNREALIZED_METHOD: 'implementations',\n CONFORMANCE_ANALYSIS_SKIPPED: 'implementations',\n CONFORMANCE_DEGRADED: 'implementations',\n UNDECLARED_DEPENDENCY: 'implementations',\n UNREALIZED_DEPENDENCY: 'implementations',\n MISSING_INTEGRATION_SIM: 'implementations',\n // L5 expectations: narratives and everything whose fuel is narrative edges\n // (the reachability walk and the hydration round-trip would drown a\n // narrative-less tree in findings about flows nobody designed).\n MISSING_NARRATIVE: 'narratives',\n INTENT_FLOOR: 'narratives',\n UNNARRATED_COMPLEXITY: 'narratives',\n DETAIL_BELOW_STEREOTYPE: 'narratives',\n UNASSERTED_INVARIANT: 'narratives',\n MISSING_HYDRATION: 'narratives',\n UNUSED_COMPONENT: 'narratives',\n UNUSED_METHOD: 'narratives',\n};\n\n// Completeness rules downgrade to warnings while the surrounding specs are\n// still draft/design — the tree is allowed to be unfinished, not inconsistent.\nconst COMPLETENESS_RULES = new Set([\n 'MISSING_IMPLEMENTATION_METHOD',\n 'MISSING_NARRATIVE',\n 'INTENT_FLOOR',\n 'MISSING_ENDPOINT',\n 'ENDPOINT_TRANSPORT_MISMATCH',\n 'MISSING_PORTAL_TYPE',\n 'UNEXPECTED_IMPLEMENTATION_METHOD',\n 'ORPHANED_SUBSYSTEM',\n 'PUBLIC_INTERFACE_UNBOUND',\n 'PUBLIC_INTERFACE_TYPE_MISMATCH',\n // Structural conformance: a draft tree is allowed to name code that does\n // not exist yet — the findings gate only once the specs claim completeness.\n 'MISSING_SOURCE_PATH',\n 'MISSING_SOURCE_FILE',\n 'SOURCE_PATH_ESCAPES_ROOT',\n 'UNREALIZED_METHOD',\n 'CONFORMANCE_ANALYSIS_SKIPPED',\n 'UNDECLARED_DEPENDENCY',\n 'UNREALIZED_DEPENDENCY',\n // Detail sufficiency reads the realized code like the conformance family\n // does — a draft tree is allowed to disagree with its code.\n 'UNNARRATED_COMPLEXITY',\n // Invariant assertions are narrative completeness — a draft tree may not\n // have written its write-path narratives yet.\n 'UNASSERTED_INVARIANT',\n // Call-step realization reads the realized code — a draft tree is allowed\n // to disagree with its code.\n 'CALL_STEP_UNREALIZED',\n // Integration-sim gate: a draft tree may not have written its harness yet.\n 'MISSING_INTEGRATION_SIM',\n 'SIM_FILE_MISSING',\n 'UNWIRED_INTEGRATION_SIM',\n]);\n\nexport interface ScopeFilterOptions {\n components: ComponentSpec[];\n interfaces: InterfaceSpec[];\n implementations: ImplementationSpec[];\n types: TypeSpec[];\n scopeSubsystem?: string;\n}\n\n/**\n * Scope filter for granular (per-subsystem) validation — shared by the rule\n * context and the loader-issue filtering that runs before rules.\n */\nexport function makeScopeFilter(opts: ScopeFilterOptions): (specId: string) => boolean {\n const { components, interfaces, implementations, types, scopeSubsystem } = opts;\n return (specId: string): boolean => {\n if (!scopeSubsystem) return true;\n if (specId === scopeSubsystem) return true;\n\n const comp = components.find(c => c.id === specId);\n if (comp) return comp.subsystem === scopeSubsystem || comp.subsystem.startsWith(`${scopeSubsystem}::`);\n\n const intf = interfaces.find(i => i.id === specId);\n if (intf) {\n const parentComp = components.find(c => c.id === intf.component);\n return parentComp ? (parentComp.subsystem === scopeSubsystem || parentComp.subsystem.startsWith(`${scopeSubsystem}::`)) : false;\n }\n\n const impl = implementations.find(i => i.id === specId);\n if (impl) {\n const contractIntf = interfaces.find(i => i.id === impl.contract);\n if (contractIntf) {\n const parentComp = components.find(c => c.id === contractIntf.component);\n return parentComp ? (parentComp.subsystem === scopeSubsystem || parentComp.subsystem.startsWith(`${scopeSubsystem}::`)) : false;\n }\n return false;\n }\n\n const t = types.find(type => type.id === specId);\n if (t) return t.subsystem === scopeSubsystem || (t.subsystem ? t.subsystem.startsWith(`${scopeSubsystem}::`) : false);\n\n if (specId.startsWith(`${scopeSubsystem}::`)) return true;\n\n return false;\n };\n}\n\nexport interface BuildContextOptions {\n system: SystemSpec;\n subsystems: SubsystemSpec[];\n components: ComponentSpec[];\n interfaces: InterfaceSpec[];\n implementations: ImplementationSpec[];\n types: TypeSpec[];\n rules?: RulesConfig;\n projectType: string;\n scopeSubsystem?: string;\n /** Loaded extension packs (pack profiles/languages/rules); empty when absent. */\n extensions?: LoadedExtensions;\n /** Loaded component-variant registry (dynamic layer on top of packs); empty when absent. */\n variants?: VariantDef[];\n /** Stored surface snapshots for cross-tree/remote reference resolution. */\n surfaceSnapshots?: import('../../models/index.js').SurfaceSnapshot[];\n /** Source-code model for structural conformance; empty when not built. */\n codeModel?: CodeModel;\n /** Collector the context's addIssue pushes into. */\n issues: ValidationIssue[];\n}\n\nexport function buildRuleContext(opts: BuildContextOptions): RuleContext {\n const { system, subsystems, components, interfaces, implementations, types, rules, projectType, scopeSubsystem, issues } = opts;\n const extensions = opts.extensions ?? emptyExtensions();\n\n const componentMap = new Map(components.map(c => [c.id, c]));\n const interfaceMap = new Map(interfaces.map(i => [i.id, i]));\n const subsystemIds = new Set(subsystems.map(s => s.id));\n const componentIds = new Set(components.map(c => c.id));\n const interfaceIds = new Set(interfaces.map(i => i.id));\n\n const interfacesByComponent = new Map<string, InterfaceSpec[]>();\n for (const intf of interfaces) {\n const list = interfacesByComponent.get(intf.component);\n if (list) list.push(intf);\n else interfacesByComponent.set(intf.component, [intf]);\n }\n const implementationsByContract = new Map<string, ImplementationSpec[]>();\n for (const impl of implementations) {\n const list = implementationsByContract.get(impl.contract);\n if (list) list.push(impl);\n else implementationsByContract.set(impl.contract, [impl]);\n }\n\n // A subsystem's published public surface: the component ids bound via its\n // publicInterfaces. Cross-subsystem dependencies may only target these.\n const publicSet = new Map<string, Set<string>>();\n for (const sub of subsystems) {\n publicSet.set(\n sub.id,\n new Set(sub.publicInterfaces.map(pi => pi.component).filter((c): c is string => !!c)),\n );\n }\n\n const isSpecInScope = makeScopeFilter({ components, interfaces, implementations, types, scopeSubsystem });\n\n // ---- design depth resolution --------------------------------------------\n // specId → owning subsystem, so a finding can be judged under the depth of\n // the subsystem it belongs to (project default otherwise).\n const subsystemOfSpec = new Map<string, string>();\n for (const s of subsystems) subsystemOfSpec.set(s.id, s.id);\n for (const c of components) subsystemOfSpec.set(c.id, c.subsystem);\n for (const i of interfaces) {\n const comp = componentMap.get(i.component);\n if (comp) subsystemOfSpec.set(i.id, comp.subsystem);\n }\n for (const im of implementations) {\n const contract = interfaceMap.get(im.contract);\n const comp = contract ? componentMap.get(contract.component) : undefined;\n if (comp) subsystemOfSpec.set(im.id, comp.subsystem);\n }\n for (const t of types) {\n if (t.subsystem) subsystemOfSpec.set(t.id, t.subsystem);\n }\n\n const profileDepth = (profileName: string | undefined): import('../../models/index.js').DesignDepth | undefined =>\n profileName ? extensions.profiles[profileName]?.rules?.designDepth : undefined;\n\n const effectiveDesignDepth = (subsystemId: string | undefined): import('../../models/index.js').DesignDepth => {\n const sub = subsystemId ? subsystems.find(s => s.id === subsystemId) : undefined;\n return sub?.designDepth\n ?? rules?.designDepth\n ?? profileDepth(sub?.profile)\n ?? profileDepth(projectType)\n ?? 'narratives';\n };\n\n const isComponentDraft = (compId: string): boolean => {\n const comp = componentMap.get(compId);\n if (!compId || !comp) return false;\n if (comp.status === 'draft' || comp.status === 'design') return true;\n\n const sub = subsystems.find(s => s.id === comp.subsystem);\n if (sub && (sub.status === 'draft' || sub.status === 'design')) return true;\n\n return false;\n };\n\n const isImplementationDraft = (impl: ImplementationSpec): boolean => {\n if (impl.status === 'draft' || impl.status === 'design') return true;\n const contract = interfaceMap.get(impl.contract);\n if (!contract) return false;\n return contract.status === 'draft' || contract.status === 'design' || isComponentDraft(contract.component);\n };\n\n const getComponentProfile = (compId: string): ArchProfile => {\n const comp = componentMap.get(compId);\n if (!comp) return 'backend';\n const sub = subsystems.find(s => s.id === comp.subsystem);\n if (sub && sub.profile) {\n return sub.profile;\n }\n if ((BUILTIN_PROFILES as readonly string[]).includes(projectType) || projectType in extensions.profiles) {\n return projectType;\n }\n return 'backend';\n };\n\n const isTypeResolved = (ref: string, generics: Set<string>): boolean => {\n const refLower = ref.toLowerCase();\n if (BUILTIN_TYPES.has(refLower)) return true;\n if (generics.has(refLower)) return true;\n\n return types.some(spec => {\n const typeQualifiedId = spec.subsystem && !spec.id.startsWith(`${spec.subsystem}::`)\n ? `${spec.subsystem}::${spec.id}`\n : spec.id;\n return matchTypeRef(ref, typeQualifiedId);\n });\n };\n\n const targetLanguageFor = (subsystemId: string | undefined): string | undefined => {\n if (subsystemId) {\n const sub = subsystems.find(s => s.id === subsystemId);\n if (sub?.targetLanguage) return normalizeLanguage(sub.targetLanguage);\n }\n return system.targetLanguage ? normalizeLanguage(system.targetLanguage) : undefined;\n };\n\n const getRuleSeverity = (\n ruleCode: string,\n defaultSeverity: Severity,\n isDraftContext?: boolean,\n subsystemId?: string,\n ): Severity | 'off' => {\n // Explicit project config wins over everything.\n if (rules?.sddRuleSeverity?.[ruleCode]) {\n return rules.sddRuleSeverity[ruleCode];\n }\n // Then the governing pack profile's severity overrides — the mechanism a\n // platform pack (e.g. a low-code profile) uses to auto-apply its doctrine\n // to every subsystem running under it, scoped to those subsystems only.\n const sub = subsystemId ? subsystems.find(s => s.id === subsystemId) : undefined;\n const profileSeverity = extensions.profiles[sub?.profile ?? projectType]?.rules?.sddRuleSeverity?.[ruleCode];\n if (profileSeverity) {\n return profileSeverity;\n }\n if (isDraftContext && COMPLETENESS_RULES.has(ruleCode)) {\n return 'warning';\n }\n return defaultSeverity;\n };\n\n // Per-spec lint suppressions — wairon's #[allow(...)]. Collected from every\n // spec kind that carries a `lint` block; addIssue consults them AFTER\n // severity resolution: a matching allow silences a WARNING, while an error\n // still surfaces (architecture violations are never locally suppressible —\n // the allow is only marked used so it isn't flagged as stale).\n const lintAllows: RuleContext['lintAllows'] = [];\n const allowLookup = new Map<string, Map<string, RuleContext['lintAllows'][number]>>();\n const collectAllows = (specId: string, lint?: { allow: { code: string; reason: string }[] }): void => {\n for (const a of lint?.allow ?? []) {\n const entry = { specId, code: a.code, reason: a.reason, used: false };\n lintAllows.push(entry);\n if (!allowLookup.has(specId)) allowLookup.set(specId, new Map());\n allowLookup.get(specId)!.set(a.code, entry);\n }\n };\n for (const s of subsystems) collectAllows(s.id, s.lint);\n for (const c of components) collectAllows(c.id, c.lint);\n for (const i of interfaces) collectAllows(i.id, i.lint);\n for (const im of implementations) collectAllows(im.id, im.lint);\n for (const t of types) collectAllows(t.id, t.lint);\n\n const knownIssueCodes = new Set([\n ...[...SDD_RULES, ...extensions.rules].flatMap(r => r.codes.map(c => c.code)),\n // Declarative assertions bring their own namespaced codes — lint.allow\n // and severity overrides treat them exactly like builtins.\n ...extensions.assertions.map(a => a.fullCode),\n ]);\n\n const addIssue = (\n defaultSeverity: Severity,\n code: string,\n message: string,\n specId?: string,\n isDraftContext?: boolean,\n ): void => {\n if (scopeSubsystem && specId && !isSpecInScope(specId)) {\n return;\n }\n const owner = specId ? subsystemOfSpec.get(specId) : undefined;\n // Design-depth gate (before severity resolution): expectation codes below\n // the effective depth are skipped entirely — the team declared it does\n // not design that layer, so nothing at that layer can be \"missing\".\n const requiredDepth = DEPTH_GATED_CODES[code];\n if (requiredDepth) {\n if (DEPTH_RANK[effectiveDesignDepth(owner)] < DEPTH_RANK[requiredDepth]) return;\n }\n const severity = getRuleSeverity(code, defaultSeverity, isDraftContext, owner);\n if (severity === 'off') return;\n if (specId) {\n const allow = allowLookup.get(specId)?.get(code);\n if (allow) {\n allow.used = true;\n if (severity === 'warning') return;\n }\n }\n // Carry the draft/design provenance onto the issue (only when true, to keep\n // issues clean) so command-level policy can classify draft-related warnings\n // without re-deriving spec status. The rule stays fully emitted/visible.\n issues.push({ severity, code, message, specId, ...(isDraftContext ? { draftContext: true } : {}) });\n };\n\n return {\n system,\n subsystems,\n components,\n interfaces,\n implementations,\n types,\n rules,\n projectType,\n scopeSubsystem,\n componentMap,\n interfaceMap,\n subsystemIds,\n componentIds,\n interfaceIds,\n publicSet,\n interfacesByComponent,\n implementationsByContract,\n isComponentDraft,\n isImplementationDraft,\n getComponentProfile,\n isTypeResolved,\n targetLanguageFor,\n isSpecInScope,\n ext: { profiles: extensions.profiles, languages: extensions.languages, patterns: extensions.patterns, guarantees: extensions.guarantees, assertions: extensions.assertions },\n variants: opts.variants ?? [],\n surfaceSnapshots: opts.surfaceSnapshots ?? [],\n codeModel: opts.codeModel ?? emptyCodeModel(),\n lintAllows,\n knownIssueCodes,\n addIssue,\n };\n}\n","import { SddRule, RuleCode } from './types.js';\nimport { SDD_RULES } from './index.js';\nimport { lintAllowsRule } from './lint-allows.js';\n\n// ---------------------------------------------------------------------------\n// Rule repository (rule_store + rule_registry + rule_index + rule_repository).\n// The in-memory rule set for one validation run: the built-in rules plus any\n// programmatic pack rules, in registration order. A ram-projection — reseeded\n// each run, never persisted. `wairon rules list` and the validator read the\n// composed run sequence and the aggregate known-code set from here.\n// ---------------------------------------------------------------------------\n\nlet ruleSet: SddRule[] = [];\n\n/** rule_store: append a rule to the held set (registration order preserved). Repository-internal. */\nfunction addRule(rule: SddRule): void {\n ruleSet.push(rule);\n}\n\n/** rule_store: return the held rules in registration order. Repository-internal. */\nfunction listRules(): SddRule[] {\n return ruleSet;\n}\n\n/** rule_registry: seed the built-in SDD rule set, resetting the set for a fresh run. */\nexport function registerBuiltinRules(): void {\n ruleSet = [];\n for (const rule of SDD_RULES) addRule(rule);\n}\n\n/** rule_registry: register programmatic pack rules after the built-ins (project pack order is precedence). */\nexport function registerPackRules(packRules: SddRule[]): void {\n for (const rule of packRules) addRule(rule);\n}\n\n/** rule_index: the ordered run sequence — registration order with the lint-allows audit forced last. */\nexport function ruleSequence(): SddRule[] {\n const base = ruleSet.filter(r => r !== lintAllowsRule);\n return ruleSet.includes(lintAllowsRule) ? [...base, lintAllowsRule] : base;\n}\n\n/** rule_index: every issue code any registered rule can emit — the lint.allow validation set. */\nexport function knownIssueCodes(): RuleCode[] {\n return listRules().flatMap(r => r.codes);\n}\n","import * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { z } from 'zod';\nimport { readYamlFile } from '../utils/yaml.js';\nimport { getProjectRoot } from '../utils/fs.js';\n\n// ---------------------------------------------------------------------------\n// Component variant registry — a DYNAMIC layer that lives ON TOP OF packs.\n//\n// A variant is a named, base-anchored specialization of a core stereotype (a\n// \"kind of Adapter/Specialist/…\"), carrying implementation guidance so the\n// implementer treats every component of the same variant alike — reusing one\n// shared approach instead of reimplementing it per instance. The base stereotype\n// stays authoritative for all of wairon's generic semantics; the variant adds\n// domain vocabulary + a stable rule target + that guidance.\n//\n// Variants deliberately live OUTSIDE packs: a user can define one on demand — no\n// pack edit or release — and share it anywhere (a variant is a tiny, portable\n// YAML). Loaded from a machine/org-wide directory and the project, so a decent\n// variant can be reused across projects, orgs, and tenants.\n// ---------------------------------------------------------------------------\n\nexport const VariantDefSchema = z.object({\n /** Variant id referenced by a component's `variant` (e.g. \"publisher\", \"org/external-config-adapter\"). */\n id: z.string().min(1),\n /** The core stereotype this variant specializes — authoritative for generic semantics (Adapter, Specialist, …). */\n base: z.string().min(1),\n /** How to implement a component of this variant — the recipe the implementer follows and reuses across same-variant components. */\n guidance: z.string().min(1),\n /** Optional: this variant only applies for the given target language (else it applies everywhere). */\n target: z.string().optional(),\n /** Optional: this variant only applies under the given architectural profile. */\n profile: z.string().optional(),\n});\nexport type VariantDef = z.infer<typeof VariantDefSchema>;\n\n/**\n * The global variants directory: WAIRON_VARIANTS_DIR, else ~/.wairon/variants.\n * Machine/org-wide, auto-loaded for every project on this machine (the shared,\n * cross-project home; project variants win on collision).\n */\nexport function globalVariantsDir(): string {\n return process.env.WAIRON_VARIANTS_DIR ?? path.join(os.homedir(), '.wairon', 'variants');\n}\n\n/**\n * Read every VariantDef from a directory of *.yaml files (each file holds one\n * variant or a list of them). A missing/unreadable directory is an empty set,\n * never an error; a single malformed file is skipped (a diagnostic is logged)\n * so one bad variant never suppresses the rest.\n */\nfunction readVariantsDir(dir: string): VariantDef[] {\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n } catch {\n return [];\n }\n const out: VariantDef[] = [];\n for (const e of entries.sort((a, b) => a.name.localeCompare(b.name))) {\n if (!e.isFile() || !/\\.ya?ml$/i.test(e.name)) continue;\n const full = path.join(dir, e.name);\n try {\n const raw = readYamlFile(full);\n if (raw == null) continue;\n const items = Array.isArray(raw) ? raw : [raw];\n for (const item of items) out.push(VariantDefSchema.parse(item));\n } catch (err) {\n console.error(`[variants] skipped \"${full}\": ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n return out;\n}\n\n/**\n * Load the component-variant registry governing the current project: the global\n * variants (machine/org-wide) then the project's own (.wai/variants/), with the\n * project winning on an id collision. An uninitialized project simply has none.\n */\nexport function loadProjectVariants(): VariantDef[] {\n try {\n const byId = new Map<string, VariantDef>();\n for (const v of readVariantsDir(globalVariantsDir())) byId.set(v.id, v);\n for (const v of readVariantsDir(path.join(getProjectRoot(), '.wai', 'variants'))) byId.set(v.id, v);\n return [...byId.values()];\n } catch {\n return [];\n }\n}\n","import { AgentRecord } from '../models/agent.js';\nimport { ProjectConfig, RulesConfig } from '../models/project.js';\nimport { Registry } from '../models/registry.js';\n\nimport {\n loadSystemSpec,\n loadSubsystemSpecs,\n loadComponentSpecs,\n loadInterfaceSpecs,\n loadImplementationSpecs,\n loadTypeSpecs,\n clearLoaderIssues,\n getLoaderIssues,\n scanAllSpecs,\n} from './specs.js';\nimport { buildRuleContext, makeScopeFilter, SddRule } from './rules/index.js';\nimport { registerBuiltinRules, registerPackRules, ruleSequence } from './rules/repository.js';\nimport { LoadedExtensions, loadProjectExtensions } from './extensions.js';\nimport { loadProjectVariants } from './variants.js';\nimport { loadSurfaceSnapshots } from './surfaces.js';\nimport { buildCodeModel } from './source-analysis.js';\nimport { findChainingParent } from './specs.js';\nimport { getProjectRoot } from '../utils/fs.js';\n\n/**\n * Codes whose verdict is ROOT-DEPENDENT: they fail because a referenced spec, a\n * source file, or a dependency edge cannot be resolved in THIS tree, but resolve\n * fine from the parent. When the tree is a chained subproject validated\n * standalone, the target legitimately lives in the absent parent (or is reached\n * by a parent-root-relative sourcePath), so these downgrade to warnings and the\n * parent root remains the authoritative gate. Two families:\n * - cross-tree spec references (type/component/subsystem/dependency), and\n * - code↔spec conformance (sourcePaths + realization + dependency graph),\n * whose sourcePaths are stored relative to the authoring (parent) root.\n */\nconst SUBPROJECT_LENIENT_CODES = new Set([\n // reference resolution\n 'UNDEFINED_TYPE_REFERENCE',\n 'INVALID_DEPENDENCY_REFERENCE',\n 'INVALID_TARGET_COMPONENT_REFERENCE',\n 'INVALID_SUBSYSTEM_REFERENCE',\n 'UNDECLARED_DEPENDENCY_CALL',\n 'INVALID_TRUSTED_LINK',\n 'CROSS_SUBSYSTEM_NON_ADAPTER',\n 'CROSS_TREE_REF_UNRESOLVED',\n // code↔spec conformance (root-relative sourcePaths / import graph)\n 'MISSING_SOURCE_FILE',\n 'SOURCE_PATH_ESCAPES_ROOT',\n 'MISSING_SOURCE_PATH',\n 'UNREALIZED_METHOD',\n 'CONFORMANCE_ANALYSIS_SKIPPED',\n 'CONFORMANCE_DEGRADED',\n 'UNDECLARED_DEPENDENCY',\n 'UNREALIZED_DEPENDENCY',\n]);\n\n// ---------------------------------------------------------------------------\n// Validation\n//\n// The SDD conformance checks themselves live in ./rules/ as a registry of\n// documented SddRule modules (the \"custom linter\"). This module is the public\n// entry point: it loads the spec tree, surfaces loader issues, builds the rule\n// context, and runs the registry. Registry/topology and project-config\n// validation (non-SDD) also live here.\n// ---------------------------------------------------------------------------\n\nexport interface ValidationIssue {\n severity: 'error' | 'warning';\n code: string;\n message: string;\n /** Optional: agent id related to the issue */\n agentId?: string;\n specId?: string;\n /**\n * True when this issue was raised in a draft/design context — i.e. the spec\n * it concerns (or an ancestor) is not yet complete. Rules that already know\n * this (e.g. DRAFT_COMPONENT_WARNING, UNUSED_COMPONENT on a draft component)\n * surface it so downstream policy — like the --ci gate — can waive warnings\n * that merely reflect declared, unfinished work without silencing the rule.\n */\n draftContext?: boolean;\n /**\n * True when this issue reflects a reference that cannot be resolved because the\n * tree is being validated STANDALONE as a chained subproject — the referenced\n * spec lives in the (absent) parent tree. Downgraded from error to warning and\n * marked so the --ci gate can waive it: a subproject is fully verified from the\n * parent root, not standalone.\n */\n crossTreeContext?: boolean;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n issues: ValidationIssue[];\n}\n\nfunction issue(\n severity: ValidationIssue['severity'],\n code: string,\n message: string,\n agentId?: string,\n specId?: string,\n): ValidationIssue {\n return { severity, code, message, agentId, specId };\n}\n\n// ---------------------------------------------------------------------------\n// Registry validation\n// ---------------------------------------------------------------------------\n\nexport function validateRegistry(registry: Registry, rules: RulesConfig): ValidationResult {\n const issues: ValidationIssue[] = [];\n\n // Duplicate agent ids\n const idCounts = new Map<string, number>();\n for (const agent of registry.agents) {\n idCounts.set(agent.id, (idCounts.get(agent.id) ?? 0) + 1);\n }\n for (const [id, count] of idCounts) {\n if (count > 1) {\n issues.push(issue('error', 'DUPLICATE_AGENT_ID', `Duplicate agent id: \"${id}\"`, id));\n }\n }\n\n // Per-agent checks\n for (const agent of registry.agents) {\n validateAgent(agent, rules, issues);\n }\n\n // Overlapping ownership\n if (rules.noOverlappingOwnership) {\n checkOverlappingOwnership(registry.agents, issues);\n }\n\n return {\n valid: issues.every((i) => i.severity !== 'error'),\n issues,\n };\n}\n\nfunction validateAgent(\n agent: AgentRecord,\n rules: RulesConfig,\n issues: ValidationIssue[],\n): void {\n const isMeta = agent.tags.some((t) => rules.metaAgentTags.includes(t));\n\n if (rules.requireOwnedPaths && !isMeta && agent.ownedPaths.length === 0) {\n issues.push(\n issue(\n 'warning',\n 'NO_OWNED_PATHS',\n `Agent \"${agent.id}\" has no ownedPaths. Add paths or tag as meta/guardian.`,\n agent.id,\n ),\n );\n }\n\n if (agent.targets.length === 0) {\n issues.push(\n issue('warning', 'NO_TARGETS', `Agent \"${agent.id}\" has no output targets configured.`, agent.id),\n );\n }\n}\n\nfunction checkOverlappingOwnership(agents: AgentRecord[], issues: ValidationIssue[]): void {\n // Simple exact-match check — a full glob overlap check is a future improvement\n const pathToAgents = new Map<string, string[]>();\n\n for (const agent of agents) {\n for (const p of agent.ownedPaths) {\n const owners = pathToAgents.get(p) ?? [];\n owners.push(agent.id);\n pathToAgents.set(p, owners);\n }\n }\n\n for (const [p, owners] of pathToAgents) {\n if (owners.length > 1) {\n issues.push(\n issue(\n 'error',\n 'OVERLAPPING_OWNERSHIP',\n `Path \"${p}\" is claimed by multiple agents: ${owners.join(', ')}`,\n ),\n );\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Project config validation\n// ---------------------------------------------------------------------------\n\nexport function validateProjectConfig(config: ProjectConfig): ValidationResult {\n const issues: ValidationIssue[] = [];\n\n if (config.targets.length === 0) {\n issues.push(issue('error', 'NO_TARGETS', 'No output targets configured in project.yaml'));\n }\n\n const enabled = config.targets.filter((t) => {\n if (typeof t === 'string') return true;\n return t.enabled !== false;\n });\n\n if (enabled.length === 0) {\n issues.push(issue('error', 'NO_ENABLED_TARGETS', 'All configured targets are disabled'));\n }\n\n return {\n valid: issues.every((i) => i.severity !== 'error'),\n issues,\n };\n}\n\n// ---------------------------------------------------------------------------\n// SDD Spec Tree Validation (rule registry entry point)\n// ---------------------------------------------------------------------------\n\nexport interface ValidationOptions {\n rules?: RulesConfig;\n projectType?: string;\n scopeSubsystem?: string;\n recursive?: boolean | number;\n /**\n * Pre-loaded extension packs (the programmatic-wrapper path). When omitted,\n * the packs declared in the project's own config are loaded — so CLI and\n * MCP callers get pack rules/profiles/languages without passing anything.\n */\n extensions?: LoadedExtensions;\n /**\n * Validate at FULL strictness: treat every spec as `complete`, so the\n * completeness rules that relax to warnings while draft/design apply as\n * errors. This is the as-complete gate behind `wairon lock`. The flip must\n * happen INSIDE the validation run — clearLoaderIssues() invalidates the\n * spec cache, so any status mutation done before calling in is lost to the\n * rescan (statuses are restored before returning, so the flip is never\n * observable to later callers).\n */\n treatAllAsComplete?: boolean;\n}\n\n/**\n * The active conformance rule set — the built-in rules plus the loaded\n * programmatic pack rules, in run order — for `wairon rules list`. Loads and\n * registers the governing packs, then reads the composed sequence.\n */\nexport function listRules(): SddRule[] {\n const extensions = loadProjectExtensions();\n registerBuiltinRules();\n registerPackRules(extensions.rules);\n return ruleSequence();\n}\n\nexport function validateSddTree(\n rulesOrOptions?: RulesConfig | ValidationOptions,\n projectType: string = 'backend'\n): ValidationResult {\n let rules = rulesOrOptions as RulesConfig | undefined;\n let scopeSubsystem: string | undefined;\n let recursive: boolean | number = true;\n let extensions: LoadedExtensions | undefined;\n let treatAllAsComplete = false;\n\n if (rulesOrOptions && ('scopeSubsystem' in rulesOrOptions || 'recursive' in rulesOrOptions || 'rules' in rulesOrOptions || 'projectType' in rulesOrOptions || 'extensions' in rulesOrOptions || 'treatAllAsComplete' in rulesOrOptions)) {\n const opts = rulesOrOptions as ValidationOptions;\n rules = opts.rules;\n projectType = opts.projectType ?? 'backend';\n scopeSubsystem = opts.scopeSubsystem;\n recursive = opts.recursive ?? true;\n extensions = opts.extensions;\n treatAllAsComplete = opts.treatAllAsComplete ?? false;\n }\n extensions ??= loadProjectExtensions();\n\n // Configure spec loader recursion\n scanAllSpecs({ recursive });\n\n const issues: ValidationIssue[] = [];\n\n // Load specs\n clearLoaderIssues();\n const system = loadSystemSpec();\n const subsystems = loadSubsystemSpecs();\n const components = loadComponentSpecs();\n const interfaces = loadInterfaceSpecs();\n const implementations = loadImplementationSpecs();\n const types = loadTypeSpecs();\n // Stored surface snapshots (.wai/surfaces/): declared contracts that\n // unresolved cross-tree/remote references validate against.\n const surfaceSnapshots = loadSurfaceSnapshots();\n // Source-code model (per-sourcePath declaration/export/import/anchor facts)\n // — what structural conformance checks realization against.\n const codeModel = buildCodeModel(implementations, getProjectRoot());\n\n // As-complete mode: flip statuses on the freshly loaded instances — these\n // are the workspace cache's own objects, loaded after the cache clear above,\n // so the rules genuinely see them as complete. Restore in `finally` so the\n // flip never leaks to later callers sharing this process (e.g. the MCP\n // server or hosted request scope).\n const statusBearing: { status?: 'draft' | 'design' | 'complete' }[] = treatAllAsComplete\n ? [...subsystems, ...components, ...interfaces, ...implementations]\n : [];\n const statusSnapshot = statusBearing.map((s) => s.status);\n for (const s of statusBearing) s.status = 'complete';\n\n try {\n // Retrieve any loader schema validation issues\n const isSpecInScope = makeScopeFilter({ components, interfaces, implementations, types, scopeSubsystem });\n const loaderErrors = getLoaderIssues();\n if (scopeSubsystem) {\n issues.push(...loaderErrors.filter(e => e.specId && isSpecInScope(e.specId)));\n } else {\n issues.push(...loaderErrors);\n }\n // Round-trip serializability runs as a registered rule (roundtripRule in\n // rules/namespace.ts) — visible in `rules list`, severity-tunable, scoped\n // like every other finding.\n\n if (!system) {\n issues.push(issue('error', 'MISSING_SYSTEM_SPEC', 'L0 System specification (.system.yaml) is missing.'));\n return { valid: false, issues };\n }\n\n // A --subsystem scope that names no loaded subsystem is almost always a typo\n // or a wrong namespace prefix; validating \"clean\" would silently hide the real\n // tree. Fail with a clear error instead. A scope is valid when a subsystem's id\n // matches it exactly, or a namespaced (subproject) subsystem lives under it.\n if (scopeSubsystem) {\n const scopeMatches = subsystems.some(\n s => s.id === scopeSubsystem || s.id.startsWith(`${scopeSubsystem}::`),\n );\n if (!scopeMatches) {\n const known = subsystems.map(s => s.id).sort();\n const hint = known.length\n ? ` Known subsystems: ${known.join(', ')}.`\n : ' This project declares no subsystems.';\n issues.push(\n issue(\n 'error',\n 'SUBSYSTEM_NOT_FOUND',\n `--subsystem \"${scopeSubsystem}\" matches no subsystem in this project.${hint}`,\n undefined,\n scopeSubsystem,\n ),\n );\n return { valid: false, issues };\n }\n }\n\n // A pack that fails to load is an error, never a silent skip — otherwise\n // the gate would quietly run without the doctrine the project declared.\n for (const err of extensions.errors) {\n issues.push(issue('error', 'EXTENSION_LOAD_ERROR', err));\n }\n\n const ctx = buildRuleContext({\n system,\n subsystems,\n components,\n interfaces,\n implementations,\n types,\n rules,\n projectType,\n scopeSubsystem,\n extensions,\n variants: loadProjectVariants(),\n surfaceSnapshots,\n codeModel,\n issues,\n });\n\n // Register the built-in rules and the loaded pack rules into the rule\n // repository, then run the composed sequence against the context.\n registerBuiltinRules();\n registerPackRules(extensions.rules);\n for (const rule of ruleSequence()) {\n rule.check(ctx);\n }\n\n // Chained-subproject leniency: when this tree is being validated STANDALONE\n // but is actually a chained subproject of a discoverable parent, references\n // INTO the parent (shared types, sibling subsystems, cross-tree components)\n // point at specs that physically live ABOVE this root and cannot be resolved\n // here. That is the \"different root, different verdict\" surprise: from the\n // parent these resolve and the tree is clean; from the subproject's own dir\n // they explode into hundreds of hard errors. Downgrade those resolution\n // errors to warnings, mark them cross-tree (so --ci can waive them), and add\n // ONE clear notice — so an agent running `wairon validate`/`mcp serve` inside\n // a subproject dir gets an honest, non-exploding result. Full cross-tree\n // verification still happens from the parent root.\n //\n // Gated on actually HAVING such issues, so a clean tree (or a hosted per-\n // request validate) never pays the walk-up-the-filesystem cost.\n const hasCrossTreeSuspects = issues.some(i => SUBPROJECT_LENIENT_CODES.has(i.code));\n const chainingParent = hasCrossTreeSuspects ? findChainingParent(getProjectRoot()) : null;\n if (chainingParent) {\n let downgraded = 0;\n for (const iss of issues) {\n if (!SUBPROJECT_LENIENT_CODES.has(iss.code)) continue;\n if (iss.severity === 'error') {\n iss.severity = 'warning';\n downgraded++;\n }\n iss.crossTreeContext = true; // mark so --ci waives it (parent root is authoritative)\n }\n if (downgraded > 0) {\n issues.unshift({\n severity: 'warning',\n code: 'CHAINED_SUBPROJECT_CONTEXT',\n crossTreeContext: true,\n message:\n `This project is a chained subproject (\"${chainingParent.subsystemId}\") of the parent project at ` +\n `\"${chainingParent.parentRoot}\". ${downgraded} reference(s) resolve only in the parent tree (shared ` +\n `types, sibling subsystems, or cross-tree components that live above this root) and were downgraded ` +\n `to warnings — validating a subproject standalone cannot verify them. Run validation from the parent ` +\n `root for full cross-tree verification.`,\n });\n }\n }\n\n return {\n valid: issues.every((i) => i.severity !== 'error'),\n issues,\n };\n } finally {\n statusBearing.forEach((s, i) => { s.status = statusSnapshot[i]; });\n }\n}\n\n/**\n * Validate the tree at FULL strictness — treating every spec as `complete`, so\n * the completeness rules that relax to warnings while draft/design apply as\n * errors — WITHOUT mutating anything on disk. This is the as-complete gate that\n * `wairon lock` and the hosting lock require: a draft tree can \"pass\" a normal\n * validate yet break the moment it is frozen, so lock must gate on this.\n *\n * The status flip lives inside validateSddTree (treatAllAsComplete) because\n * validation begins by invalidating the spec cache (clearLoaderIssues), which\n * would discard any objects mutated out here before the rules ever saw them —\n * exactly the silent degradation this wrapper previously suffered from.\n */\nexport function validateAsComplete(options?: ValidationOptions): ValidationResult {\n return validateSddTree({ ...(options ?? {}), treatAllAsComplete: true });\n}\n","import {\n loadSystemSpec,\n loadSubsystemSpecs,\n loadComponentSpecs,\n loadInterfaceSpecs,\n loadImplementationSpecs,\n} from './specs.js';\nimport {\n ComponentSpec,\n SubsystemSpec,\n InterfaceSpec,\n ImplementationSpec,\n PATTERN_TYPES,\n} from '../models/index.js';\nimport { buildCanvasModel, renderCanvasHtml, type CanvasModel } from './canvas.js';\nimport { generateDrawioXml, generateExcalidrawScene } from './diagram-export.js';\nimport { validateSddTree, type ValidationIssue } from './validation.js';\nimport { loadProjectConfig } from '../config/loader.js';\n// Pure interface types for the web UI graph payload. Type-only import: erased at\n// compile time, so this adds no runtime core→server coupling.\nimport type { WebGraphModel, WebGraphNode, LandscapeEdge } from '../server/types.js';\n\n// ---------------------------------------------------------------------------\n// Diagram Specialist entrypoint (sdd_core diagram_specialist)\n//\n// Render the current (request-scoped) project's spec tree into a diagram\n// artifact STRING — the engine behind `wairon diagram`, reused by the hosting\n// server's diagram endpoints. The canvas embeds the validation-issue overlay;\n// all formats are self-contained.\n// ---------------------------------------------------------------------------\n\nexport function renderDiagram(format: string): string {\n switch (format) {\n case 'canvas': return renderCanvasHtml(buildCanvasModel(diagramIssues()));\n case 'mermaid': return generateComponentDiagram();\n case 'drawio': return generateDrawioXml(buildCanvasModel());\n case 'excalidraw': return generateExcalidrawScene(buildCanvasModel());\n default:\n throw new Error(`Unsupported diagram format \"${format}\" (canvas | mermaid | drawio | excalidraw).`);\n }\n}\n\n/**\n * The full CanvasModel for the current (request-scoped) project — the same model\n * `renderDiagram('canvas')` renders to the standalone HTML, but returned as data\n * so the React web app can mount the shared renderer directly (no iframe) and,\n * later, receive it in on-demand scope slices. Pure derivation, no side effects.\n */\nexport function buildCanvasDataModel(): CanvasModel {\n return buildCanvasModel(diagramIssues());\n}\n\nfunction diagramIssues(): ValidationIssue[] {\n try {\n const config = loadProjectConfig();\n return validateSddTree({ rules: config.rules, projectType: config.projectType }).issues;\n } catch {\n return [];\n }\n}\n\n// ---------------------------------------------------------------------------\n// Live level-of-detail graph model (project tier)\n//\n// A PURE projection of the current (request-scoped) project's spec tree into a\n// WebGraphModel for the web UI — the live JSON sibling of renderDiagram's static\n// HTML/diagram export. It reuses buildCanvasModel's spec traversal, then tags\n// each node with its level-of-detail depth (subsystems 1, components 2,\n// interfaces/types 3), keeps only nodes at or below the requested level, and\n// wires containment/ownership/dependency edges between the surviving nodes\n// (dropping any edge whose endpoint was filtered out). No side effects.\n// ---------------------------------------------------------------------------\n\nexport function buildGraphModel(level: number): WebGraphModel {\n const model = buildCanvasModel();\n\n // The project/system root is the apex of the graph (level 0): the whole\n // project collapsed to a single node, off which every top-level subsystem\n // hangs. Level 0 yields just this node.\n const rootId = model.system.name;\n const nodes: WebGraphNode[] = [\n { id: rootId, label: model.system.name, kind: 'project', level: 0 },\n ];\n const candidates: LandscapeEdge[] = [];\n\n // L1 — subsystems. A nested subsystem's parent is its owning subsystem (the\n // id up to the last '::'); a top-level subsystem hangs off the project root.\n // Each carries a containment edge from that parent (project → subsystem, or\n // subsystem → nested subsystem).\n for (const s of model.subsystems) {\n const cut = s.id.lastIndexOf('::');\n const parentId = cut >= 0 ? s.id.slice(0, cut) : rootId;\n nodes.push({\n id: s.id,\n label: s.name,\n kind: 'subsystem',\n level: 1,\n parentId,\n ...(s.status ? { status: s.status } : {}),\n });\n candidates.push({ from: parentId, to: s.id, edgeKind: 'contains' });\n }\n\n // L2 — components (parent = their subsystem, with a containment edge).\n for (const c of model.components) {\n nodes.push({\n id: c.id,\n label: c.name,\n kind: 'component',\n level: 2,\n parentId: c.subsystem,\n ...(c.status ? { status: c.status } : {}),\n });\n candidates.push({ from: c.subsystem, to: c.id, edgeKind: 'contains' });\n }\n\n // L3 — interfaces (parent = their component, with an ownership edge) and types.\n for (const c of model.components) {\n for (const intf of c.interfaces) {\n nodes.push({ id: intf.id, label: intf.name, kind: 'interface', level: 3, parentId: c.id });\n candidates.push({ from: c.id, to: intf.id, edgeKind: 'owns' });\n }\n }\n for (const t of model.types) {\n nodes.push({\n id: t.id,\n label: t.name,\n kind: 'type',\n level: 3,\n ...(t.subsystem ? { parentId: t.subsystem } : {}),\n });\n }\n\n // Component → collaborator dependency edges.\n for (const e of model.edges) {\n candidates.push({ from: e.from, to: e.to, edgeKind: 'depends_on' });\n }\n\n // Keep only nodes at or below the requested detail level, then drop any edge\n // whose endpoint was filtered out above that level.\n const kept = nodes.filter(n => n.level <= level);\n const keptIds = new Set(kept.map(n => n.id));\n const edges = candidates.filter(e => keptIds.has(e.from) && keptIds.has(e.to));\n\n return {\n tier: 'project',\n nodes: kept,\n edges,\n level,\n generatedAt: new Date().toISOString(),\n scope: model.system.name,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Diagram generation (Mermaid)\n//\n// The spec tree is a typed, hierarchical graph, so diagrams are pure\n// derivation — no extra modeling:\n// - component diagrams: subsystems → subgraphs, components → nodes,\n// dependsOn → edges (thick when crossing a subsystem boundary),\n// owns → dashed containment edges, public surface → bold border.\n// - sequence diagrams: L5 narratives → lifelines and arrows, with `call`\n// steps expanded recursively (cycle-guarded, depth-limited).\n//\n// This is stage 1 of the visualization plan (renders on GitHub / IDEs); the\n// interactive compound-graph canvas consumes the same graph extraction later.\n// ---------------------------------------------------------------------------\n\nexport interface DiagramFile {\n /** Path relative to the diagrams output directory, using forward slashes. */\n relPath: string;\n title: string;\n /** Raw mermaid source (no markdown fence). */\n mermaid: string;\n}\n\ninterface SpecGraph {\n systemName: string;\n subsystems: SubsystemSpec[];\n components: ComponentSpec[];\n interfaces: InterfaceSpec[];\n implementations: ImplementationSpec[];\n /** Component ids published via some subsystem's publicInterfaces. */\n publicComponents: Set<string>;\n}\n\nexport function loadSpecGraph(): SpecGraph {\n const system = loadSystemSpec();\n const subsystems = loadSubsystemSpecs();\n const components = loadComponentSpecs();\n const interfaces = loadInterfaceSpecs();\n const implementations = loadImplementationSpecs();\n const publicComponents = new Set<string>();\n for (const sub of subsystems) {\n for (const pi of sub.publicInterfaces) {\n if (pi.component) publicComponents.add(pi.component);\n }\n }\n return {\n systemName: system?.name ?? 'System',\n subsystems,\n components,\n interfaces,\n implementations,\n publicComponents,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Mermaid encoding helpers\n// ---------------------------------------------------------------------------\n\n/** Deterministic mermaid-safe node ids ('::' and '-' are not id-safe). */\nclass IdPool {\n private byOriginal = new Map<string, string>();\n private taken = new Set<string>();\n\n idFor(original: string): string {\n const existing = this.byOriginal.get(original);\n if (existing) return existing;\n const base = original.replace(/[^A-Za-z0-9_]/g, '_');\n let candidate = base;\n let n = 2;\n while (this.taken.has(candidate)) {\n candidate = `${base}_${n++}`;\n }\n this.byOriginal.set(original, candidate);\n this.taken.add(candidate);\n return candidate;\n }\n}\n\nfunction escapeLabel(text: string): string {\n return text.replace(/\"/g, '#quot;');\n}\n\nfunction truncate(text: string, max: number): string {\n const clean = text.replace(/\\s+/g, ' ').trim();\n return clean.length <= max ? clean : `${clean.slice(0, max - 1)}…`;\n}\n\n/** Shape a node by stereotype: entrypoints stadium, state cylinder, patterns subroutine. */\nfunction nodeDecl(id: string, label: string, comp: ComponentSpec): string {\n const l = escapeLabel(label);\n if (comp.componentType === 'Portal' || comp.componentType === 'Observer') return `${id}([\"${l}\"])`;\n if (comp.componentType === 'Store' || comp.componentType === 'Index') return `${id}[(\"${l}\")]`;\n if (PATTERN_TYPES.has(comp.componentType)) return `${id}[[\"${l}\"]]`;\n return `${id}[\"${l}\"]`;\n}\n\nfunction stereotypeClass(comp: ComponentSpec): string {\n switch (comp.componentType) {\n case 'Portal':\n case 'Observer':\n return 'entry';\n case 'Store':\n case 'Index':\n case 'Registry':\n return 'data';\n case 'Adapter':\n return 'adapter';\n case 'Repository':\n case 'Gateway':\n case 'FeatureComponent':\n case 'RouterComponent':\n return 'pattern';\n default:\n return 'logic';\n }\n}\n\nconst CLASS_DEFS = [\n 'classDef entry fill:#eef4ff,stroke:#4a7dcf,color:#1a2b4a;',\n 'classDef logic fill:#f4effd,stroke:#8a63c9,color:#2d1f45;',\n 'classDef data fill:#fdf6e3,stroke:#c9963f,color:#4a3517;',\n 'classDef adapter fill:#eef8f1,stroke:#4f9e6b,color:#173322;',\n 'classDef pattern fill:#f6f8fa,stroke:#6a737d,color:#24292e;',\n 'classDef publicSurface stroke-width:3px;',\n];\n\n// ---------------------------------------------------------------------------\n// Component diagrams\n// ---------------------------------------------------------------------------\n\nexport interface ComponentDiagramOptions {\n /** Scope to one subsystem (its components plus directly-connected externals). */\n subsystem?: string;\n}\n\nexport function generateComponentDiagram(options?: ComponentDiagramOptions): string {\n const graph = loadSpecGraph();\n const scope = options?.subsystem;\n\n let components = graph.components;\n if (scope) {\n const inScope = graph.components.filter(\n c => c.subsystem === scope || c.subsystem.startsWith(`${scope}::`),\n );\n if (inScope.length === 0) {\n throw new Error(`No components found for subsystem \"${scope}\".`);\n }\n const scopeIds = new Set(inScope.map(c => c.id));\n // Include direct external neighbors (either direction) for boundary context.\n const neighbors = graph.components.filter(c => {\n if (scopeIds.has(c.id)) return false;\n const referencesScope = [...c.dependsOn, ...c.owns].some(d => scopeIds.has(d));\n const referencedByScope = inScope.some(s => s.dependsOn.includes(c.id) || s.owns.includes(c.id));\n return referencesScope || referencedByScope;\n });\n components = [...inScope, ...neighbors];\n }\n\n const componentIds = new Set(components.map(c => c.id));\n const ids = new IdPool();\n const lines: string[] = [];\n const title = scope\n ? `${graph.systemName} — ${scope} (components)`\n : `${graph.systemName} — component architecture`;\n lines.push('---');\n lines.push(`title: \"${escapeLabel(title)}\"`);\n lines.push('---');\n lines.push('flowchart LR');\n\n // Group nodes into subsystem subgraphs\n const bySubsystem = new Map<string, ComponentSpec[]>();\n for (const comp of components) {\n const list = bySubsystem.get(comp.subsystem) ?? [];\n list.push(comp);\n bySubsystem.set(comp.subsystem, list);\n }\n\n const classAssignments = new Map<string, string[]>(); // class -> node ids\n const assignClass = (cls: string, nodeId: string) => {\n const list = classAssignments.get(cls) ?? [];\n list.push(nodeId);\n classAssignments.set(cls, list);\n };\n\n for (const [subId, comps] of bySubsystem) {\n const sub = graph.subsystems.find(s => s.id === subId);\n const subLabel = escapeLabel(sub?.name ?? subId);\n lines.push(` subgraph ${ids.idFor(`sub:${subId}`)}[\"${subLabel}\"]`);\n for (const comp of comps) {\n const nodeId = ids.idFor(comp.id);\n const label = `${comp.name}<br/>«${comp.componentType}»`;\n lines.push(` ${nodeDecl(nodeId, label, comp)}`);\n assignClass(stereotypeClass(comp), nodeId);\n if (graph.publicComponents.has(comp.id)) assignClass('publicSurface', nodeId);\n }\n lines.push(' end');\n }\n\n // Edges\n for (const comp of components) {\n const fromId = ids.idFor(comp.id);\n for (const memberId of comp.owns) {\n if (!componentIds.has(memberId)) continue;\n lines.push(` ${fromId} -. owns .-> ${ids.idFor(memberId)}`);\n }\n for (const depId of comp.dependsOn) {\n if (!componentIds.has(depId)) continue;\n const dep = components.find(c => c.id === depId)!;\n const crossesBoundary = dep.subsystem !== comp.subsystem;\n lines.push(crossesBoundary\n ? ` ${fromId} ==> ${ids.idFor(depId)}`\n : ` ${fromId} --> ${ids.idFor(depId)}`);\n }\n }\n\n lines.push('');\n lines.push(...CLASS_DEFS.map(d => ` ${d}`));\n for (const [cls, nodeIds] of classAssignments) {\n lines.push(` class ${nodeIds.join(',')} ${cls}`);\n }\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Sequence diagrams (from L5 narratives)\n// ---------------------------------------------------------------------------\n\nexport interface SequenceDiagramOptions {\n /** Max call-expansion depth (default 3). Depth 1 = only the method's own steps. */\n depth?: number;\n}\n\nexport function generateSequenceDiagram(\n componentId: string,\n methodName: string,\n options?: SequenceDiagramOptions,\n): string {\n const graph = loadSpecGraph();\n const maxDepth = options?.depth ?? 3;\n\n const componentById = new Map(graph.components.map(c => [c.id, c]));\n const resolveComponent = (id: string): ComponentSpec | undefined => {\n if (componentById.has(id)) return componentById.get(id);\n // Accept a bare id that suffix-matches exactly one qualified component.\n const matches = graph.components.filter(c => c.id.endsWith(`::${id}`));\n return matches.length === 1 ? matches[0] : undefined;\n };\n\n const entry = resolveComponent(componentId);\n if (!entry) {\n throw new Error(`Component \"${componentId}\" not found in the spec tree.`);\n }\n\n const findMethodImpl = (compId: string, method: string) => {\n const contractIds = new Set(\n graph.interfaces.filter(i => i.component === compId).map(i => i.id),\n );\n const impl = graph.implementations.find(\n im => contractIds.has(im.contract) && im.methods.some(m => m.name === method),\n );\n return impl?.methods.find(m => m.name === method) ?? null;\n };\n\n if (!findMethodImpl(entry.id, methodName)) {\n throw new Error(\n `No L4 narrative found for \"${methodName}\" on component \"${entry.id}\". ` +\n 'Write it with sdd_write_narrative first.',\n );\n }\n\n const ids = new IdPool();\n const lines: string[] = [];\n lines.push('---');\n lines.push(`title: \"${escapeLabel(`${entry.name}.${methodName} — narrative sequence`)}\"`);\n lines.push('---');\n lines.push('sequenceDiagram');\n lines.push(' autonumber');\n\n const declared = new Set<string>();\n const declare = (comp: ComponentSpec): string => {\n const pid = ids.idFor(comp.id);\n if (!declared.has(pid)) {\n declared.add(pid);\n lines.push(` participant ${pid} as ${escapeLabel(comp.name)} «${comp.componentType}»`);\n }\n return pid;\n };\n\n const caller = declare(entry);\n // Pre-pass declared participants lazily; mermaid allows late declaration but\n // early declarations keep lifeline order stable (callers before callees).\n\n const walk = (comp: ComponentSpec, method: string, depth: number, stack: Set<string>): void => {\n const key = `${comp.id}#${method}`;\n if (stack.has(key)) {\n lines.push(` Note over ${ids.idFor(comp.id)}: ${escapeLabel(`${method}() recurses — cycle cut`)}`);\n return;\n }\n const methodImpl = findMethodImpl(comp.id, method);\n if (!methodImpl) return;\n\n const nextStack = new Set(stack);\n nextStack.add(key);\n const selfId = ids.idFor(comp.id);\n\n // Region blocks (loop / try / parallel) have an explicit endStep, so they\n // map cleanly onto Mermaid `loop` / `critical` / `par` fragments; free-form\n // jumps (branch / switch / jump / return / throw) become annotated markers —\n // the canvas flowchart is where arbitrary branching renders faithfully.\n const pendingEnds: number[] = [];\n // Open parallel regions: arms are contiguous, so each later arm entry\n // emits its `and` separator when the walk reaches that step. Block\n // reconstruction beyond endStep-bounded regions is deliberately not\n // attempted (mirrors the loop/critical approach).\n const parallelArms: { end: number; sepByStep: Map<number, string> }[] = [];\n const closeRegionsAfter = (stepNumber: number): void => {\n while (pendingEnds.length && pendingEnds[pendingEnds.length - 1] <= stepNumber) {\n pendingEnds.pop();\n lines.push(' end');\n }\n while (parallelArms.length && parallelArms[parallelArms.length - 1].end <= stepNumber) {\n parallelArms.pop();\n }\n };\n\n const steps = [...methodImpl.narrative].sort((a, b) => a.stepNumber - b.stepNumber);\n for (const step of steps) {\n // Reaching a later arm's entry inside an open `par` fragment starts its\n // `and` block (arm entries never collide across nesting levels).\n for (const par of parallelArms) {\n const sep = par.sepByStep.get(step.stepNumber);\n if (sep !== undefined) lines.push(` and ${escapeLabel(sep)}`);\n }\n switch (step.type) {\n case 'local':\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(step.description, 70))}`);\n break;\n case 'branch':\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(`◇ if ${step.condition ?? step.description}${step.onFalseStep !== undefined ? ` — else → step ${step.onFalseStep}` : ''}`, 80))}`);\n break;\n case 'switch':\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(`◇ switch on ${step.on ?? step.description} (${step.cases?.length ?? 0} cases)`, 80))}`);\n break;\n case 'loop':\n if (step.endStep !== undefined) {\n lines.push(` loop ${escapeLabel(truncate(step.over ?? step.condition ?? step.description, 60))}`);\n pendingEnds.push(step.endStep);\n } else {\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(`⟳ ${step.description}`, 70))}`);\n }\n break;\n case 'try':\n if (step.endStep !== undefined) {\n lines.push(` critical ${escapeLabel(truncate(step.description, 60))}`);\n pendingEnds.push(step.endStep);\n }\n for (const c of step.catches ?? []) {\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(`⚠ on ${c.error} → step ${c.step}`, 70))}`);\n }\n break;\n case 'parallel': {\n const arms = step.branches ?? [];\n if (step.endStep !== undefined && arms.length >= 2) {\n const head = truncate(step.description, 60) + (arms[0].name ? ` — ${arms[0].name}` : '');\n lines.push(` par ${escapeLabel(head)}`);\n const sepByStep = new Map<number, string>();\n arms.slice(1).forEach((b, i) => sepByStep.set(b.step, b.name ?? `arm ${i + 2}`));\n parallelArms.push({ end: step.endStep, sepByStep });\n pendingEnds.push(step.endStep);\n } else {\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(`∥ ${step.description}`, 70))}`);\n }\n break;\n }\n case 'jump':\n lines.push(` Note over ${selfId}: ${escapeLabel(`↷ → step ${step.toStep}`)}`);\n break;\n case 'return':\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(`⏎ return${step.outcome ? ` — ${step.outcome}` : ''}`, 70))}`);\n break;\n case 'throw':\n lines.push(` Note over ${selfId}: ${escapeLabel(truncate(`⚡ throw${step.error ? ` ${step.error}` : ''}`, 70))}`);\n break;\n case 'dispatch': {\n if (!step.targetComponent) break;\n const portal = componentById.get(step.targetComponent);\n if (!portal) {\n lines.push(` Note over ${selfId}: ${escapeLabel(`dispatches via unknown \"${step.targetComponent}\"`)}`);\n break;\n }\n const portalId = declare(portal);\n // A detached dispatch fires asynchronously (open arrow, no wait);\n // the portal's own routing to the bound server stays synchronous.\n lines.push(step.detach\n ? ` ${selfId}-)${portalId}: ${escapeLabel(`⟨${step.capability ?? '?'}⟩`)} — detached`\n : ` ${selfId}->>${portalId}: ${escapeLabel(`⟨${step.capability ?? '?'}⟩`)}`);\n // Follow the table binding so the diagram shows the real server —\n // and keep walking its narrative, exactly like a call step, so the\n // downstream flow doesn't silently truncate at the dispatch hop.\n const binding = portal.dispatch?.find(b => b.capability === step.capability);\n const server = binding ? componentById.get(binding.component) : undefined;\n if (binding && server) {\n const serverId = declare(server);\n const expandable = depth < maxDepth\n && !!findMethodImpl(server.id, binding.method)\n && server.id !== comp.id;\n if (expandable) {\n lines.push(` ${portalId}->>+${serverId}: ${escapeLabel(binding.method)}()`);\n walk(server, binding.method, depth + 1, nextStack);\n lines.push(` ${serverId}-->>-${portalId}: return`);\n } else {\n lines.push(` ${portalId}->>${serverId}: ${escapeLabel(binding.method)}()`);\n }\n }\n break;\n }\n case 'call': {\n if (!step.targetComponent || !step.targetMethod) break;\n const target = componentById.get(step.targetComponent);\n if (!target) {\n lines.push(` Note over ${selfId}: ${escapeLabel(`calls unknown \"${step.targetComponent}\"`)}`);\n break;\n }\n const targetId = declare(target);\n const expandable = depth < maxDepth\n && !!findMethodImpl(target.id, step.targetMethod)\n && target.id !== comp.id;\n if (step.detach) {\n // Fire-and-forget: async open arrow, no activation, NO return —\n // the caller continues immediately and the callee's failure does\n // not propagate back into this flow.\n lines.push(` ${selfId}-)${targetId}: ${escapeLabel(step.targetMethod)}() — detached`);\n if (expandable) walk(target, step.targetMethod, depth + 1, nextStack);\n } else if (expandable) {\n lines.push(` ${selfId}->>+${targetId}: ${escapeLabel(step.targetMethod)}()`);\n walk(target, step.targetMethod, depth + 1, nextStack);\n lines.push(` ${targetId}-->>-${selfId}: return`);\n } else {\n lines.push(` ${selfId}->>${targetId}: ${escapeLabel(step.targetMethod)}()`);\n }\n break;\n }\n }\n closeRegionsAfter(step.stepNumber);\n }\n // Force-close any region whose endStep pointed past the last step.\n while (pendingEnds.length) { pendingEnds.pop(); lines.push(' end'); }\n };\n\n lines.push(` Note over ${caller}: ${escapeLabel(`${methodName}()`)}`);\n walk(entry, methodName, 1, new Set());\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Full diagram set (for `wairon diagram --all`)\n// ---------------------------------------------------------------------------\n\nexport function generateDiagramSet(): DiagramFile[] {\n const graph = loadSpecGraph();\n const files: DiagramFile[] = [];\n\n files.push({\n relPath: 'system.md',\n title: `${graph.systemName} — component architecture`,\n mermaid: generateComponentDiagram(),\n });\n\n for (const sub of graph.subsystems) {\n const hasComponents = graph.components.some(\n c => c.subsystem === sub.id || c.subsystem.startsWith(`${sub.id}::`),\n );\n if (!hasComponents) continue;\n files.push({\n relPath: `subsystems/${sub.id.replace(/::/g, '--')}.md`,\n title: `${sub.name} — components`,\n mermaid: generateComponentDiagram({ subsystem: sub.id }),\n });\n }\n\n // Sequences for every entrypoint (Portal/Observer/public) method with a narrative.\n const roots = graph.components.filter(\n c => c.componentType === 'Portal' || c.componentType === 'Observer' || graph.publicComponents.has(c.id),\n );\n const seen = new Set<string>();\n for (const root of roots) {\n if (seen.has(root.id)) continue;\n seen.add(root.id);\n const contractIds = new Set(graph.interfaces.filter(i => i.component === root.id).map(i => i.id));\n const impls = graph.implementations.filter(im => contractIds.has(im.contract));\n for (const impl of impls) {\n for (const m of impl.methods) {\n if (!m.narrative.length) continue;\n files.push({\n relPath: `sequences/${root.id.replace(/::/g, '--')}.${m.name}.md`,\n title: `${root.name}.${m.name} — narrative sequence`,\n mermaid: generateSequenceDiagram(root.id, m.name),\n });\n }\n }\n }\n\n return files;\n}\n\n/** Wrap raw mermaid in a titled markdown document (renders on GitHub / IDEs). */\nexport function toMarkdown(file: DiagramFile): string {\n return `# ${file.title}\\n\\n> Generated by \\`wairon diagram\\` from \\`.wai/specs/\\` — do not edit; regenerate instead.\\n\\n\\`\\`\\`mermaid\\n${file.mermaid}\\n\\`\\`\\`\\n`;\n}\n\n/** Index README linking every generated diagram. */\nexport function diagramSetIndex(files: DiagramFile[], systemName: string): string {\n const lines: string[] = [];\n lines.push(`# ${systemName} — architecture diagrams`);\n lines.push('');\n lines.push('> Generated by `wairon diagram --all` from `.wai/specs/` — living documentation derived');\n lines.push('> from the same source of truth as the conformance gate. Regenerate after spec changes.');\n lines.push('');\n for (const f of files) {\n lines.push(`- [${f.title}](${f.relPath.replace(/\\\\/g, '/')})`);\n }\n lines.push('');\n return lines.join('\\n');\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { z } from 'zod';\nimport { aiPathsAt, WaiPaths } from '../config/loader.js';\nimport { ensureDir, listFiles, listFilesRecursive, pathExists, getProjectRoot } from '../utils/fs.js';\nimport { readYamlFile, writeYamlFile } from '../utils/yaml.js';\nimport {\n SystemSpec,\n SystemSpecSchema,\n SubsystemSpec,\n SubsystemSpecSchema,\n ComponentSpec,\n ComponentSpecSchema,\n InterfaceSpec,\n InterfaceSpecSchema,\n ImplementationSpec,\n ImplementationSpecSchema,\n TypeSpec,\n TypeSpecSchema,\n GroupSpec,\n GroupSpecSchema,\n SpecStatus,\n} from '../models/index.js';\nimport type { ValidationIssue } from './validation.js';\nimport { resolveNarrativeLabels } from './narrative-labels.js';\nimport { buildGraphModel } from './diagram.js';\nimport type { WebGraphModel } from '../server/types.js';\n\n// ---------------------------------------------------------------------------\n// Spec workspace\n//\n// All spec-tree state (index cache, loader issues, freshness signature, root\n// subsystem set) lives on a SpecWorkspace instance keyed by project root.\n// Nested subproject resolution asks for the CHILD's workspace instead of\n// temporarily overriding a global project root — the override juggling that\n// used to live here was the main source of namespacing regressions.\n//\n// The module-level functions at the bottom keep the historical flat API and\n// delegate to the workspace of the current project root.\n// ---------------------------------------------------------------------------\n\ninterface SpecIndex {\n subsystems: SubsystemSpec[];\n components: ComponentSpec[];\n interfaces: InterfaceSpec[];\n implementations: ImplementationSpec[];\n types: TypeSpec[];\n groups: GroupSpec[];\n paths: {\n subsystem: Record<string, string>;\n component: Record<string, string>;\n interface: Record<string, string>;\n implementation: Record<string, string>;\n type: Record<string, string>;\n group: Record<string, string>;\n };\n}\n\nfunction emptyIndex(): SpecIndex {\n return {\n subsystems: [],\n components: [],\n interfaces: [],\n implementations: [],\n types: [],\n groups: [],\n paths: {\n subsystem: {},\n component: {},\n interface: {},\n implementation: {},\n type: {},\n group: {},\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Pure namespace helpers\n// ---------------------------------------------------------------------------\n\nfunction qualifyId(id: string, prefix: string, rootSubsystems: ReadonlySet<string>): string;\nfunction qualifyId(id: string | undefined, prefix: string, rootSubsystems: ReadonlySet<string>): string | undefined;\nfunction qualifyId(id: string | undefined, prefix: string, rootSubsystems: ReadonlySet<string>): string | undefined {\n if (!id) return id;\n if (id.startsWith('::')) {\n return id.slice(2);\n }\n if (id.startsWith('super::')) {\n const prefixParts = prefix.split('::');\n const idParts = id.split('::');\n while (idParts[0] === 'super') {\n idParts.shift();\n prefixParts.pop();\n }\n return [...prefixParts, ...idParts].join('::');\n }\n const firstSegment = id.split('::')[0];\n if (rootSubsystems.has(firstSegment)) {\n return id;\n }\n return prefix ? `${prefix}::${id}` : id;\n}\n\nexport function splitNamespace(qualifiedId: string): { prefix: string; localId: string } {\n if (!qualifiedId.includes('::')) {\n return { prefix: '', localId: qualifiedId };\n }\n const parts = qualifiedId.split('::');\n const localId = parts.pop()!;\n return { prefix: parts.join('::'), localId };\n}\n\n/**\n * The exact inverse of `qualifyId`: turn an in-memory qualified id back into\n * the relative form that re-qualifies to the same id when the file is loaded\n * again from `prefix`'s namespace context.\n *\n * - `::`/`super::` forms are already relative — passed through.\n * - Ids under `prefix` lose it (the local case).\n * - Ids in a DIFFERENT namespace climb to the common ancestor with `super::`\n * hops, or anchor `::`-absolute when there is none. Never truncate to the\n * last segment: that re-qualifies into the LOCAL namespace on the next load\n * and silently corrupts the reference (the cross-tree targetComponent bug).\n * - At the root context (empty prefix) qualified ids are already absolute in\n * the loading namespace and round-trip as-is.\n */\nfunction relativizeId(id: string, prefix: string): string {\n if (id.startsWith('::') || id.startsWith('super::')) {\n return id;\n }\n // Root context: in-memory ids are already absolute in the loading namespace\n // and round-trip as-is.\n if (!prefix) {\n return id;\n }\n if (id.startsWith(`${prefix}::`)) {\n return id.slice(prefix.length + 2);\n }\n // The mount namespace itself (a flat external subsystem's own id, e.g. a\n // child component's `subsystem` field): stored bare, it resolves in BOTH\n // load contexts — as the child's root subsystem standalone, and via the\n // root-subsystem anchor when loaded through the parent.\n if (id === prefix) {\n return id.split('::').pop()!;\n }\n // NOT under the save prefix — including a BARE id, which in a prefixed\n // context is a root-level reference (what qualifyId('super::x'/'::x')\n // resolves to), never a local one: locals carry the prefix in memory.\n // Emit super:: hops to the deepest common ancestor — a RELATIVE path whose hop\n // count is the physical nesting between source and target, which is invariant\n // across WHICH ancestor is the loading root. This is the key to a chained\n // subproject validating identically from the top project and from its own dir\n // as a standalone root: an absolute ::-anchor instead encodes the depth from\n // the current root and silently breaks the moment the root changes (the\n // \"different root, different verdict\" bug).\n const prefixParts = prefix.split('::');\n const idParts = id.split('::');\n let common = 0;\n while (common < prefixParts.length && common < idParts.length && prefixParts[common] === idParts[common]) {\n common++;\n }\n // The id IS an ancestor namespace: step out one more hop so it can be named.\n if (common === idParts.length) common--;\n return `${'super::'.repeat(prefixParts.length - common)}${idParts.slice(common).join('::')}`;\n}\n\n/** True when `file` is the same as, or nested under, directory `dir`. */\nfunction isWithin(dir: string, file: string): boolean {\n const d = path.resolve(dir);\n const f = path.resolve(file);\n return f === d || f.startsWith(d + path.sep);\n}\n\n// ---------------------------------------------------------------------------\n// projectPath chaining containment (Fix B2)\n//\n// A subsystem's `projectPath` is resolved with path.resolve, which honors\n// absolute paths and ../ traversal. Left unchecked, a chained subproject could\n// escape the bound project root and federate — and, via a code pack living\n// there, execute — another tenant's spec tree. The single invariant enforced\n// everywhere a projectPath is written or resolved: the child directory must\n// stay strictly within its owning project root. Empty/undefined projectPath is\n// not chaining and is never checked here (callers skip it).\n// ---------------------------------------------------------------------------\n\n/**\n * Whether a subproject's already-resolved child directory escapes `projectRoot`.\n * `resolvedChildDir` is resolved by the caller because for multi-hop chains the\n * resolution base is an intermediate parent, while the containment boundary is\n * always the bound top root. An absolute `projectPath` or a `../`-escape fails.\n */\nfunction projectPathEscapesRoot(\n projectRoot: string,\n projectPath: string,\n resolvedChildDir: string,\n): boolean {\n return path.isAbsolute(projectPath) || !isWithin(projectRoot, resolvedChildDir);\n}\n\n/**\n * Assert a subsystem `projectPath` resolves strictly within `projectRoot`, and\n * return the resolved absolute child directory. Throws a clear Error naming the\n * offending path when `projectPath` is absolute or `../`-escapes the root.\n * Applied on every write/setter path that persists a projectPath; the load-time\n * loader uses projectPathEscapesRoot directly (it collects issues, not throws).\n */\nexport function assertContainedProjectPath(projectRoot: string, projectPath: string): string {\n const root = path.resolve(projectRoot);\n const resolved = path.resolve(root, projectPath);\n if (projectPathEscapesRoot(root, projectPath, resolved)) {\n throw new Error(\n `projectPath \"${projectPath}\" must resolve within the project root \"${root}\", but resolves ` +\n `to \"${resolved}\"; absolute paths and ../-escaping paths are rejected so a chained ` +\n `subproject is always contained by its parent.`,\n );\n }\n return resolved;\n}\n\n/**\n * Walk UP from a project root to find a PARENT wairon project that chains to it\n * — a subsystem (anywhere in the parent's spec tree) whose `projectPath` resolves\n * to this exact root. Returns the parent root + the subsystem id it mounts as, or\n * null when this is a top-level root.\n *\n * This is how a STANDALONE validation of a subproject knows it is a subproject:\n * references INTO the parent tree (shared types, sibling subsystems, cross-tree\n * components — all of which live ABOVE this root and are physically absent here)\n * cannot be resolved standalone, so they are honest cross-tree edges to warn on,\n * not spec defects to error on. Pure filesystem read; no cache mutation.\n */\nexport function findChainingParent(childRoot: string): { parentRoot: string; subsystemId: string } | null {\n let childResolved: string;\n try {\n childResolved = path.resolve(childRoot);\n } catch {\n return null;\n }\n let dir = path.dirname(childResolved);\n for (let hops = 0; hops < 32; hops++) {\n const specsDir = aiPathsAt(dir).specsDir();\n if (pathExists(specsDir)) {\n for (const file of listFilesRecursive(specsDir, '.yaml')) {\n let raw: unknown;\n try {\n raw = readYamlFile(file);\n } catch {\n continue;\n }\n // A subsystem spec (has parentSystem) that mounts a child via projectPath.\n if (raw && typeof raw === 'object' && 'parentSystem' in raw) {\n const projectPath = (raw as { projectPath?: unknown }).projectPath;\n if (typeof projectPath === 'string' && projectPath.trim() !== '') {\n try {\n if (path.resolve(dir, projectPath) === childResolved) {\n const id = (raw as { id?: unknown }).id;\n return { parentRoot: dir, subsystemId: typeof id === 'string' ? id : '?' };\n }\n } catch {\n /* malformed projectPath — not our mount */\n }\n }\n }\n }\n }\n const up = path.dirname(dir);\n if (up === dir) break;\n dir = up;\n }\n return null;\n}\n\n/**\n * Collapse a mount subsystem (has projectPath) and its same-id child realization\n * into a single flat external subsystem: the child provides the content, the\n * mount contributes projectPath. Genuine duplicates (both internal or both\n * external) are left intact for the validator to flag.\n */\nfunction mergeMountRealizations(subs: SubsystemSpec[]): SubsystemSpec[] {\n const result: SubsystemSpec[] = [];\n const indexById = new Map<string, number>();\n for (const sub of subs) {\n const at = indexById.get(sub.id);\n if (at === undefined) {\n indexById.set(sub.id, result.length);\n result.push(sub);\n continue;\n }\n const prev = result[at];\n const prevExternal = !!prev.projectPath;\n const subExternal = !!sub.projectPath;\n if (prevExternal !== subExternal) {\n const mount = prevExternal ? prev : sub;\n const child = prevExternal ? sub : prev;\n result[at] = { ...child, projectPath: mount.projectPath };\n } else {\n result.push(sub);\n }\n }\n return result;\n}\n\nfunction stripNamespaceFromSubsystem(spec: SubsystemSpec, prefix: string): SubsystemSpec {\n // MUST mirror the loader (scanSpecsForProject step 2): an external\n // (projectPath) subsystem's members are qualified with the subsystem's own\n // qualified id, not with its surrounding namespace — so they relativize\n // against that same prefix. Deriving both from the subsystem id's namespace\n // left a root-mounted external subsystem's members fully qualified on save,\n // which the writer schema then refused (the lock-blocking asymmetry).\n // A BARE member is already in load form (a freshly constructed spec that\n // never went through scan qualification) and passes through untouched —\n // subsystem members bind the subsystem's OWN components, never cross-tree.\n const memberPrefix = spec.projectPath ? spec.id : prefix;\n const relMember = (id: string): string => (id.includes('::') ? relativizeId(id, memberPrefix) : id);\n return {\n ...spec,\n id: relativizeId(spec.id, prefix),\n publicInterfaces: spec.publicInterfaces.map(pi => ({\n ...pi,\n component: pi.component ? relMember(pi.component) : undefined,\n interface: pi.interface ? relMember(pi.interface) : undefined,\n })),\n lifecycle: spec.lifecycle?.map(le => ({\n ...le,\n component: relMember(le.component),\n })),\n };\n}\n\nfunction stripNamespaceFromComponent(spec: ComponentSpec, prefix: string): ComponentSpec {\n return {\n ...spec,\n id: relativizeId(spec.id, prefix),\n subsystem: relativizeId(spec.subsystem, prefix),\n owns: spec.owns.map(o => relativizeId(o, prefix)),\n dependsOn: spec.dependsOn.map(d => relativizeId(d, prefix)),\n dispatch: spec.dispatch?.map(b => ({\n ...b,\n component: relativizeId(b.component, prefix),\n })),\n };\n}\n\nfunction stripNamespaceFromInterface(spec: InterfaceSpec, prefix: string): InterfaceSpec {\n return {\n ...spec,\n id: relativizeId(spec.id, prefix),\n component: relativizeId(spec.component, prefix),\n };\n}\n\nfunction stripNamespaceFromImplementation(spec: ImplementationSpec, prefix: string): ImplementationSpec {\n return {\n ...spec,\n id: relativizeId(spec.id, prefix),\n contract: relativizeId(spec.contract, prefix),\n methods: spec.methods.map(m => ({\n ...m,\n narrative: m.narrative.map(step => ({\n ...step,\n targetComponent: step.targetComponent ? relativizeId(step.targetComponent, prefix) : undefined,\n })),\n })),\n };\n}\n\nfunction stripNamespaceFromType(spec: TypeSpec, prefix: string): TypeSpec {\n return {\n ...spec,\n id: relativizeId(spec.id, prefix),\n subsystem: spec.subsystem ? relativizeId(spec.subsystem, prefix) : undefined,\n };\n}\n\nfunction stripNamespaceFromGroup(spec: GroupSpec, prefix: string): GroupSpec {\n return {\n ...spec,\n id: relativizeId(spec.id, prefix),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Pure structural helpers\n// ---------------------------------------------------------------------------\n\n/**\n * The pattern component that owns `id` via its `owns` list (at most one — the\n * SHARED_OWNED_MEMBER rule forbids two owners), or null. An owned member nests\n * physically under its owner because the owner owns its *implementation*; an\n * interface/port reference uses `dependsOn` and stays a flat sibling instead.\n */\nfunction findOwner(id: string, components: ComponentSpec[]): ComponentSpec | null {\n const { localId } = splitNamespace(id);\n return components.find((c) => {\n const { localId: cLocalId } = splitNamespace(c.id);\n if (cLocalId === localId) return false;\n return (c.owns ?? []).some(ownedId => {\n const { localId: ownedLocalId } = splitNamespace(ownedId);\n return ownedLocalId === localId;\n });\n }) ?? null;\n}\n\nfunction moveComponentFolder(fromDir: string, toDir: string): boolean {\n if (path.normalize(fromDir) === path.normalize(toDir)) return false;\n if (!fs.existsSync(fromDir) || fs.existsSync(toDir)) return false; // don't clobber\n ensureDir(path.dirname(toDir));\n fs.renameSync(fromDir, toDir);\n return true;\n}\n\n/** Helper to clean up empty parent directories up to the given specs root. */\nfunction cleanEmptyDirs(filePath: string, specsRoot: string): void {\n let dir = path.dirname(filePath);\n while (dir !== specsRoot && dir.startsWith(specsRoot)) {\n if (fs.existsSync(dir) && fs.readdirSync(dir).length === 0) {\n fs.rmdirSync(dir);\n dir = path.dirname(dir);\n } else {\n break;\n }\n }\n}\n\n/**\n * Validate a spec object against its schema before it is written to disk, so a\n * malformed delta (e.g. via sdd_update_spec) fails loudly instead of writing a\n * corrupt file that only surfaces on the next scan. Returns the parsed value\n * (with schema defaults applied).\n */\n/** One rendering for writer-schema refusals — shared by parseOrThrow and the dry-run so validate-time output is byte-comparable with the mid-write error it predicts. */\nfunction formatZodIssues(error: z.ZodError): string {\n return error.issues.map(i => `${i.path.join('.') || '(root)'}: ${i.message}`).join('; ');\n}\n\nfunction parseOrThrow<S extends z.ZodTypeAny>(schema: S, value: unknown, kind: string, id: string): z.infer<S> {\n const res = schema.safeParse(value);\n if (!res.success) {\n throw new Error(`Refusing to write invalid ${kind} spec \"${id}\": ${formatZodIssues(res.error)}`);\n }\n return res.data;\n}\n\n// Freshness signature over file paths + mtimes + sizes, so a long-running\n// process (the MCP server) notices external YAML edits.\nconst SIGNATURE_TTL_MS = 2000;\n\nfunction computeSpecTreeSignature(dirs: string[]): string {\n const parts: string[] = [];\n for (const dir of dirs) {\n if (!fs.existsSync(dir)) {\n parts.push(`${dir}:missing`);\n continue;\n }\n for (const f of listFilesRecursive(dir, '.yaml')) {\n try {\n const st = fs.statSync(f);\n parts.push(`${f}:${st.mtimeMs}:${st.size}`);\n } catch {\n parts.push(`${f}:gone`);\n }\n }\n }\n return parts.join('|');\n}\n\n// ---------------------------------------------------------------------------\n// Status promotion types (see collectPromotableSpecs)\n// ---------------------------------------------------------------------------\n\nexport type SpecKind = 'subsystem' | 'component' | 'interface' | 'implementation';\n\nexport interface PromotableSpec {\n kind: SpecKind;\n id: string;\n /** The current (pre-promotion) status — captured so callers can revert. */\n status: SpecStatus;\n}\n\n/**\n * Options for the spec save functions.\n * `allowStatusDemotion`: by default a re-save carrying status 'draft' does NOT\n * demote an existing 'design'/'complete' spec (the add tools always pass\n * 'draft', and re-adding must not silently reopen a locked spec). An explicit\n * status change via sdd_update_spec sets this to make deliberate demotion work.\n */\nexport interface SaveSpecOptions {\n allowStatusDemotion?: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// SpecWorkspace\n// ---------------------------------------------------------------------------\n\nexport class SpecWorkspace {\n readonly rootDir: string;\n readonly paths: WaiPaths;\n\n private cachedIndex: SpecIndex | null = null;\n private cachedRecursive: boolean | number | null = null;\n private cachedSpecDirs: string[] = [];\n private cachedSignature: string | null = null;\n private lastSignatureCheckMs = 0;\n private rootSubsystems = new Set<string>();\n private scanVisitedSpecDirs: string[] = [];\n loaderIssues: ValidationIssue[] = [];\n\n constructor(rootDir: string) {\n this.rootDir = path.resolve(rootDir);\n this.paths = aiPathsAt(this.rootDir);\n }\n\n invalidate(): void {\n this.cachedIndex = null;\n this.cachedRecursive = null;\n this.cachedSpecDirs = [];\n this.cachedSignature = null;\n this.lastSignatureCheckMs = 0;\n this.rootSubsystems.clear();\n }\n\n // -------------------------------------------------------------------------\n // Scanning\n // -------------------------------------------------------------------------\n\n scanAll(options?: { recursive?: boolean | number }): SpecIndex {\n const recursive = options?.recursive ?? true;\n if (this.cachedIndex && this.cachedRecursive === recursive) {\n // Cache hit — but the files may have been edited externally (hand edits,\n // another process) since we scanned. Re-verify via mtime signature at\n // most once per TTL.\n const now = Date.now();\n if (now - this.lastSignatureCheckMs <= SIGNATURE_TTL_MS) return this.cachedIndex;\n this.lastSignatureCheckMs = now;\n if (computeSpecTreeSignature(this.cachedSpecDirs) === this.cachedSignature) return this.cachedIndex;\n this.invalidate();\n }\n\n this.loaderIssues = [];\n this.rootSubsystems.clear();\n this.cachedRecursive = recursive;\n this.scanVisitedSpecDirs = [];\n const visited = new Set<string>([path.resolve(this.rootDir)]);\n\n const maxDepth = typeof recursive === 'number' ? recursive : (recursive ? Infinity : 0);\n this.cachedIndex = this.scanSpecsForProject(this.rootDir, '', visited, maxDepth, 0);\n this.cachedSpecDirs = this.scanVisitedSpecDirs;\n this.cachedSignature = computeSpecTreeSignature(this.cachedSpecDirs);\n this.lastSignatureCheckMs = Date.now();\n return this.cachedIndex;\n }\n\n private scanSpecsForProject(\n projectDir: string,\n namespacePrefix: string,\n visitedDirs: Set<string>,\n maxDepth: number,\n currentDepth: number,\n ): SpecIndex {\n const index = emptyIndex();\n const projectPaths = aiPathsAt(projectDir);\n\n const specsDir = projectPaths.specsDir();\n // Track every visited specs dir (even absent ones, so their later creation\n // is picked up) for the freshness signature.\n this.scanVisitedSpecDirs.push(specsDir);\n if (!pathExists(specsDir)) return index;\n\n const files = listFilesRecursive(specsDir, '.yaml');\n const systemYaml = path.normalize(projectPaths.specsSystem());\n\n const localSubprojects: { subsystemId: string; projectPath: string }[] = [];\n\n for (const file of files) {\n const normFile = path.normalize(file);\n if (normFile === systemYaml) continue;\n\n let detectedType = 'spec';\n try {\n const raw = readYamlFile(file);\n if (raw === null || typeof raw !== 'object') {\n this.loaderIssues.push({\n severity: 'error',\n code: 'INVALID_YAML',\n message: `Spec file \"${file}\" is not a valid YAML object or is empty.`,\n specId: path.basename(file, '.yaml'),\n });\n continue;\n }\n\n if ('parentSystem' in raw) {\n detectedType = 'subsystem';\n const parsed = SubsystemSpecSchema.parse(raw);\n if (currentDepth === 0) {\n this.rootSubsystems.add(parsed.id);\n }\n if (parsed.projectPath) {\n localSubprojects.push({\n subsystemId: parsed.id,\n projectPath: parsed.projectPath,\n });\n }\n index.subsystems.push(parsed);\n index.paths.subsystem[parsed.id] = file;\n } else if ('componentType' in raw) {\n detectedType = 'component';\n const parsed = ComponentSpecSchema.parse(raw);\n index.components.push(parsed);\n index.paths.component[parsed.id] = file;\n } else if ('component' in raw) {\n detectedType = 'interface';\n const parsed = InterfaceSpecSchema.parse(raw);\n index.interfaces.push(parsed);\n index.paths.interface[parsed.id] = file;\n } else if ('contract' in raw) {\n detectedType = 'implementation';\n const parsed = ImplementationSpecSchema.parse(raw);\n if (parsed.sourcePath) {\n const absSourcePath = path.resolve(projectDir, parsed.sourcePath);\n parsed.sourcePath = path.relative(projectDir, absSourcePath).replace(/\\\\/g, '/');\n }\n index.implementations.push(parsed);\n index.paths.implementation[parsed.id] = file;\n } else if ('kind' in raw) {\n if (raw.kind === 'group') {\n detectedType = 'group';\n const parsed = GroupSpecSchema.parse(raw);\n index.groups.push(parsed);\n index.paths.group[parsed.id] = file;\n } else {\n detectedType = 'type';\n const parsed = TypeSpecSchema.parse(raw);\n index.types.push(parsed);\n index.paths.type[parsed.id] = file;\n }\n }\n\n if (detectedType === 'spec') {\n this.loaderIssues.push({\n severity: 'error',\n code: 'UNKNOWN_SPEC_TYPE',\n message: `Spec file \"${file}\" does not match any recognized L1-L4 schema structure.`,\n specId: path.basename(file, '.yaml'),\n });\n }\n } catch (e: any) {\n const filename = path.basename(file, '.yaml');\n this.loaderIssues.push({\n severity: 'error',\n code: 'SCHEMA_VALIDATION_ERROR',\n message: `Failed to parse ${detectedType} spec \"${file}\": ${e.message || String(e)}`,\n specId: filename,\n });\n }\n }\n\n // 2. Namespace local subsystems (runs always to handle projectPath delegation)\n index.subsystems = index.subsystems.map(sub => {\n const qualifiedSubId = namespacePrefix ? qualifyId(sub.id, namespacePrefix, this.rootSubsystems) : sub.id;\n const componentPrefix = sub.projectPath ? qualifiedSubId : namespacePrefix;\n return {\n ...sub,\n id: qualifiedSubId,\n publicInterfaces: sub.publicInterfaces.map(p => ({\n ...p,\n component: p.component ? qualifyId(p.component, componentPrefix, this.rootSubsystems) : undefined,\n interface: p.interface ? qualifyId(p.interface, componentPrefix, this.rootSubsystems) : undefined,\n })),\n lifecycle: sub.lifecycle?.map(le => ({\n ...le,\n component: qualifyId(le.component, componentPrefix, this.rootSubsystems),\n })),\n };\n });\n\n const originalSubsystemPaths = index.paths.subsystem;\n index.paths.subsystem = {};\n for (const [k, v] of Object.entries(originalSubsystemPaths)) {\n const qualifiedK = namespacePrefix ? qualifyId(k, namespacePrefix, this.rootSubsystems) : k;\n index.paths.subsystem[qualifiedK] = v;\n }\n\n if (namespacePrefix) {\n index.components = index.components.map(comp => ({\n ...comp,\n id: qualifyId(comp.id, namespacePrefix, this.rootSubsystems),\n subsystem: qualifyId(comp.subsystem, namespacePrefix, this.rootSubsystems),\n owns: comp.owns.map(o => qualifyId(o, namespacePrefix, this.rootSubsystems)),\n dependsOn: comp.dependsOn.map(d => qualifyId(d, namespacePrefix, this.rootSubsystems)),\n dispatch: comp.dispatch?.map(b => ({\n ...b,\n component: qualifyId(b.component, namespacePrefix, this.rootSubsystems),\n })),\n }));\n\n index.interfaces = index.interfaces.map(intf => ({\n ...intf,\n id: qualifyId(intf.id, namespacePrefix, this.rootSubsystems),\n component: qualifyId(intf.component, namespacePrefix, this.rootSubsystems),\n }));\n\n index.implementations = index.implementations.map(impl => ({\n ...impl,\n id: qualifyId(impl.id, namespacePrefix, this.rootSubsystems),\n contract: qualifyId(impl.contract, namespacePrefix, this.rootSubsystems),\n methods: impl.methods.map(m => ({\n ...m,\n narrative: m.narrative.map(step => ({\n ...step,\n targetComponent: step.targetComponent ? qualifyId(step.targetComponent, namespacePrefix, this.rootSubsystems) : undefined,\n })),\n })),\n }));\n\n index.types = index.types.map(t => ({\n ...t,\n id: qualifyId(t.id, namespacePrefix, this.rootSubsystems),\n subsystem: t.subsystem ? qualifyId(t.subsystem, namespacePrefix, this.rootSubsystems) : undefined,\n group: t.group ? qualifyId(t.group, namespacePrefix, this.rootSubsystems) : undefined,\n }));\n\n index.groups = index.groups.map(g => ({\n ...g,\n id: qualifyId(g.id, namespacePrefix, this.rootSubsystems),\n }));\n\n const originalPaths = index.paths;\n index.paths = {\n subsystem: index.paths.subsystem,\n component: {},\n interface: {},\n implementation: {},\n type: {},\n group: {},\n };\n\n for (const [k, v] of Object.entries(originalPaths.component)) {\n index.paths.component[qualifyId(k, namespacePrefix, this.rootSubsystems)] = v;\n }\n for (const [k, v] of Object.entries(originalPaths.interface)) {\n index.paths.interface[qualifyId(k, namespacePrefix, this.rootSubsystems)] = v;\n }\n for (const [k, v] of Object.entries(originalPaths.implementation)) {\n index.paths.implementation[qualifyId(k, namespacePrefix, this.rootSubsystems)] = v;\n }\n for (const [k, v] of Object.entries(originalPaths.type)) {\n index.paths.type[qualifyId(k, namespacePrefix, this.rootSubsystems)] = v;\n }\n for (const [k, v] of Object.entries(originalPaths.group)) {\n index.paths.group[qualifyId(k, namespacePrefix, this.rootSubsystems)] = v;\n }\n }\n\n if (currentDepth < maxDepth) {\n for (const subproj of localSubprojects) {\n const childDir = path.resolve(projectDir, subproj.projectPath);\n\n // Containment guard (Fix B2) — THE critical read-time defense. The\n // resolution base is the immediate parent (projectDir) so nested chains\n // compose, but containment is always checked against this.rootDir, the\n // workspace's bound root (the tenant project root when hosted). No hop,\n // however deep, may escape it via an absolute or ../ projectPath. On a\n // violation, surface a loader error and SKIP the child (do not recurse).\n if (projectPathEscapesRoot(this.rootDir, subproj.projectPath, childDir)) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'PROJECTPATH_ESCAPE',\n message: `Subproject path \"${subproj.projectPath}\" declared by subsystem \"${subproj.subsystemId}\" escapes the project root \"${this.rootDir}\" (resolves to \"${childDir}\"); absolute and ../-escaping projectPaths are rejected. Skipping this subproject.`,\n specId: subproj.subsystemId,\n });\n continue;\n }\n\n if (visitedDirs.has(childDir)) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'CIRCULAR_SUBPROJECT_REFERENCE',\n message: `Circular reference detected: Subsystem \"${subproj.subsystemId}\" refers to subproject \"${childDir}\" which is already loaded.`,\n specId: subproj.subsystemId,\n });\n continue;\n }\n\n if (!fs.existsSync(childDir)) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'SUBPROJECT_NOT_FOUND',\n message: `Subproject directory \"${childDir}\" declared by subsystem \"${subproj.subsystemId}\" does not exist.`,\n specId: subproj.subsystemId,\n });\n continue;\n }\n\n const childNamespace = namespacePrefix\n ? `${namespacePrefix}::${subproj.subsystemId}`\n : subproj.subsystemId;\n\n const newVisited = new Set(visitedDirs);\n newVisited.add(childDir);\n\n const childIndex = this.scanSpecsForProject(childDir, childNamespace, newVisited, maxDepth, currentDepth + 1);\n\n index.subsystems.push(...childIndex.subsystems);\n index.components.push(...childIndex.components);\n index.interfaces.push(...childIndex.interfaces);\n index.implementations.push(...childIndex.implementations);\n index.types.push(...childIndex.types);\n index.groups.push(...childIndex.groups);\n\n Object.assign(index.paths.subsystem, childIndex.paths.subsystem);\n Object.assign(index.paths.component, childIndex.paths.component);\n Object.assign(index.paths.interface, childIndex.paths.interface);\n Object.assign(index.paths.implementation, childIndex.paths.implementation);\n Object.assign(index.paths.type, childIndex.paths.type);\n Object.assign(index.paths.group, childIndex.paths.group);\n }\n }\n\n // Collapse a mount and its same-id child realization into one flat external\n // subsystem (child content + mount projectPath). index.paths.subsystem already\n // resolves the id to the child file (child scan Object.assign wins), so content\n // saves route to the child; saveSubsystemSpec strips projectPath there.\n index.subsystems = mergeMountRealizations(index.subsystems);\n\n return index;\n }\n\n // -------------------------------------------------------------------------\n // Namespace / subproject resolution\n // -------------------------------------------------------------------------\n\n resolveSubprojectForNamespace(namespace: string): string | null {\n const parts = namespace.split('::');\n let currentDir = this.rootDir;\n let resolvedAny = false;\n let currentPrefix = '';\n for (const part of parts) {\n currentPrefix = currentPrefix ? `${currentPrefix}::${part}` : part;\n const index = this.scanAll();\n const sub = index.subsystems.find((s) => s.id === currentPrefix);\n if (sub && sub.projectPath) {\n const nextDir = path.resolve(currentDir, sub.projectPath);\n // Containment guard (Fix B2): never resolve a namespace into a directory\n // that escapes the bound top root (this.rootDir). Surface a loader error\n // and SKIP the escaping hop, leaving currentDir contained, rather than\n // handing back an out-of-root directory for a save/lookup.\n if (projectPathEscapesRoot(this.rootDir, sub.projectPath, nextDir)) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'PROJECTPATH_ESCAPE',\n message: `Subproject path \"${sub.projectPath}\" declared by subsystem \"${currentPrefix}\" escapes the project root \"${this.rootDir}\" (resolves to \"${nextDir}\"); absolute and ../-escaping projectPaths are rejected. Skipping this subproject.`,\n specId: currentPrefix,\n });\n continue;\n }\n currentDir = nextDir;\n resolvedAny = true;\n }\n }\n return resolvedAny ? currentDir : null;\n }\n\n getSubprojectPrefix(qualifiedId: string): string | null {\n const parts = qualifiedId.split('::');\n if (parts.length <= 1) return null;\n const index = this.scanAll();\n // The DEEPEST mount wins: for a nested chain a::b::x (both a and a::b are\n // mounts), the file lives in b's tree, so ids relativize against a::b.\n // Returning the first (shallowest) hit left one namespace level in the\n // written ids, which the strict id schema then refused — every depth-2+\n // spec became un-savable through the parent root.\n let deepest: string | null = null;\n let currentPrefix = '';\n for (let i = 0; i < parts.length - 1; i++) {\n currentPrefix = currentPrefix ? `${currentPrefix}::${parts[i]}` : parts[i];\n const sub = index.subsystems.find(s => s.id === currentPrefix);\n if (sub && sub.projectPath) {\n deepest = currentPrefix;\n }\n }\n return deepest;\n }\n\n // -------------------------------------------------------------------------\n // Path builders\n // -------------------------------------------------------------------------\n\n getSubsystemPath(id: string): string {\n const index = this.scanAll();\n if (index.paths.subsystem[id]) {\n return index.paths.subsystem[id];\n }\n if (id.includes('::')) {\n const parts = id.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n return workspaceFor(childProj).getSubsystemPath(parts[parts.length - 1]);\n }\n }\n\n // Suffix match for bare IDs matching a unique qualified subsystem\n const suffix = `::${id}`;\n const matches = Object.keys(index.paths.subsystem).filter(key => key.endsWith(suffix));\n if (matches.length === 1) {\n return index.paths.subsystem[matches[0]];\n }\n\n if (pathExists(this.paths.specsSubsystemsDir()) && listFiles(this.paths.specsSubsystemsDir(), '.yaml').length > 0) {\n return path.join(this.paths.specsSubsystemsDir(), `${id}.yaml`);\n }\n return path.join(this.paths.specsDir(), id, '.index.yaml');\n }\n\n getComponentPath(id: string, subsystemId?: string): string {\n const index = this.scanAll();\n if (index.paths.component[id]) {\n return index.paths.component[id];\n }\n\n if (id.includes('::')) {\n const parts = id.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingId = parts[parts.length - 1];\n const remainingSubsystem = subsystemId ? subsystemId.split('::').pop() : undefined;\n return workspaceFor(childProj).getComponentPath(remainingId, remainingSubsystem);\n }\n }\n\n // Owned members nest one level deep inside their owning pattern's folder\n // (patterns never own patterns, so it is exactly one level).\n const owner = findOwner(id, index.components);\n if (owner) {\n const ownerPath = index.paths.component[owner.id];\n if (ownerPath && ownerPath.endsWith('.index.yaml')) {\n return path.join(path.dirname(ownerPath), id, '.index.yaml');\n }\n }\n\n if (subsystemId) {\n const subPath = this.getSubsystemPath(subsystemId);\n const subDir = path.dirname(subPath);\n if (subPath.endsWith('.index.yaml')) {\n return path.join(subDir, id, '.index.yaml');\n }\n }\n\n if (pathExists(this.paths.specsComponentsDir()) && listFiles(this.paths.specsComponentsDir(), '.yaml').length > 0) {\n return path.join(this.paths.specsComponentsDir(), `${id}.yaml`);\n }\n\n const targetSubsystem = subsystemId || 'default';\n return path.join(this.paths.specsDir(), targetSubsystem, id, '.index.yaml');\n }\n\n getInterfacePath(id: string, componentId?: string): string {\n const index = this.scanAll();\n if (index.paths.interface[id]) {\n return index.paths.interface[id];\n }\n\n if (id.includes('::')) {\n const parts = id.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingId = parts[parts.length - 1];\n const remainingComponent = componentId ? componentId.split('::').pop() : undefined;\n return workspaceFor(childProj).getInterfacePath(remainingId, remainingComponent);\n }\n }\n\n if (componentId && componentId.includes('::')) {\n const parts = componentId.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingComponent = parts[parts.length - 1];\n return workspaceFor(childProj).getInterfacePath(id, remainingComponent);\n }\n }\n\n if (componentId) {\n const compPath = this.getComponentPath(componentId);\n const compDir = path.dirname(compPath);\n if (compPath.endsWith('.index.yaml')) {\n return path.join(compDir, '.interface.yaml');\n }\n }\n\n if (pathExists(this.paths.specsInterfacesDir()) && listFiles(this.paths.specsInterfacesDir(), '.yaml').length > 0) {\n return path.join(this.paths.specsInterfacesDir(), `${id}.yaml`);\n }\n\n const targetComponent = componentId || 'default';\n return path.join(this.paths.specsDir(), 'default', targetComponent, '.interface.yaml');\n }\n\n getImplementationPath(id: string, contractId?: string): string {\n const index = this.scanAll();\n if (index.paths.implementation[id]) {\n return index.paths.implementation[id];\n }\n\n if (id.includes('::')) {\n const parts = id.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingId = parts[parts.length - 1];\n const remainingContract = contractId ? contractId.split('::').pop() : undefined;\n return workspaceFor(childProj).getImplementationPath(remainingId, remainingContract);\n }\n }\n\n if (contractId && contractId.includes('::')) {\n const parts = contractId.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingContract = parts[parts.length - 1];\n return workspaceFor(childProj).getImplementationPath(id, remainingContract);\n }\n }\n\n if (contractId) {\n const intfPath = this.getInterfacePath(contractId);\n const intfDir = path.dirname(intfPath);\n if (intfPath.endsWith('.interface.yaml')) {\n return path.join(intfDir, '.implementation.yaml');\n }\n }\n\n if (pathExists(this.paths.specsImplementationsDir()) && listFiles(this.paths.specsImplementationsDir(), '.yaml').length > 0) {\n return path.join(this.paths.specsImplementationsDir(), `${id}.yaml`);\n }\n\n const targetContract = contractId ? contractId.replace(/^i/, '') : 'default';\n return path.join(this.paths.specsDir(), 'default', targetContract, '.implementation.yaml');\n }\n\n getTypePath(id: string, subsystemId?: string, group?: string): string {\n const index = this.scanAll();\n if (index.paths.type[id]) return index.paths.type[id];\n\n if (id.includes('::')) {\n const parts = id.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingId = parts[parts.length - 1];\n const remainingSubsystem = subsystemId ? subsystemId.split('::').pop() : undefined;\n const remainingGroup = group ? group.split('::').pop() : undefined;\n return workspaceFor(childProj).getTypePath(remainingId, remainingSubsystem, remainingGroup);\n }\n }\n\n if (subsystemId && subsystemId.includes('::')) {\n const parts = subsystemId.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingSubsystem = parts[parts.length - 1];\n const remainingGroup = group ? group.split('::').pop() : undefined;\n return workspaceFor(childProj).getTypePath(id, remainingSubsystem, remainingGroup);\n }\n }\n\n const { localId: plainId } = splitNamespace(id);\n const targetGroup = group || index.types.find((t) => t.id === id || t.id === plainId)?.group;\n if (targetGroup) {\n const { localId: plainGroup } = splitNamespace(targetGroup);\n const groupPath = index.paths.group[targetGroup] || index.paths.group[plainGroup];\n if (groupPath) {\n const localId = id.split('::').pop()!;\n return path.join(path.dirname(groupPath), `${localId}.yaml`);\n }\n }\n\n let localId = id;\n if (id.includes('::')) {\n const parts = id.split('::');\n localId = parts[parts.length - 1];\n if (!subsystemId) {\n subsystemId = parts.slice(0, -1).join('::');\n }\n }\n\n if (subsystemId) {\n const subPath = this.getSubsystemPath(subsystemId);\n const subDir = path.dirname(subPath);\n if (subPath.endsWith('.index.yaml')) {\n return path.join(subDir, 'types', `${localId}.yaml`);\n }\n }\n return path.join(this.paths.specsTypesDir(), `${localId}.yaml`);\n }\n\n getGroupPath(id: string, subsystemId?: string): string {\n const index = this.scanAll();\n const { localId: plainId } = splitNamespace(id);\n if (index.paths.group[id]) return index.paths.group[id];\n if (index.paths.group[plainId]) return index.paths.group[plainId];\n\n if (id.includes('::')) {\n const parts = id.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingId = parts[parts.length - 1];\n const remainingSubsystem = subsystemId ? subsystemId.split('::').pop() : undefined;\n return workspaceFor(childProj).getGroupPath(remainingId, remainingSubsystem);\n }\n }\n\n if (subsystemId && subsystemId.includes('::')) {\n const parts = subsystemId.split('::');\n const childProj = this.resolveSubprojectForNamespace(parts.slice(0, -1).join('::'));\n if (childProj) {\n const remainingSubsystem = parts[parts.length - 1];\n return workspaceFor(childProj).getGroupPath(id, remainingSubsystem);\n }\n }\n\n let localId = id;\n if (id.includes('::')) {\n const parts = id.split('::');\n localId = parts[parts.length - 1];\n if (!subsystemId) {\n subsystemId = parts.slice(0, -1).join('::');\n }\n }\n\n if (subsystemId) {\n const subPath = this.getSubsystemPath(subsystemId);\n const subDir = path.dirname(subPath);\n if (subPath.endsWith('.index.yaml')) {\n return path.join(subDir, 'types', localId, '.index.yaml');\n }\n }\n return path.join(this.paths.specsTypesDir(), localId, '.index.yaml');\n }\n\n // -------------------------------------------------------------------------\n // Level 0: System\n // -------------------------------------------------------------------------\n\n loadSystemSpec(): SystemSpec | null {\n const p = this.paths.specsSystem();\n if (!pathExists(p)) return null;\n try {\n const raw = readYamlFile(p);\n return SystemSpecSchema.parse(raw);\n } catch (e: any) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'SCHEMA_VALIDATION_ERROR',\n message: `Failed to parse system spec: ${e.message || String(e)}`,\n specId: 'system',\n });\n return null;\n }\n }\n\n saveSystemSpec(spec: SystemSpec): void {\n const p = this.paths.specsSystem();\n ensureDir(path.dirname(p));\n writeYamlFile(p, parseOrThrow(SystemSpecSchema, spec, 'system', spec.name));\n invalidateSpecCache();\n }\n\n // -------------------------------------------------------------------------\n // Level 1: Subsystems\n // -------------------------------------------------------------------------\n\n loadSubsystemSpecs(): SubsystemSpec[] {\n return this.scanAll().subsystems;\n }\n\n loadSubsystemSpec(id: string): SubsystemSpec | null {\n const index = this.scanAll();\n const cached = index.subsystems.find((s) => s.id === id);\n if (cached) return cached;\n\n const p = this.getSubsystemPath(id);\n if (!pathExists(p)) return null;\n try {\n const raw = readYamlFile(p);\n return SubsystemSpecSchema.parse(raw);\n } catch (e: any) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'SCHEMA_VALIDATION_ERROR',\n message: `Failed to parse subsystem spec \"${id}\": ${e.message || String(e)}`,\n specId: id,\n });\n return null;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Write-pipeline preparation — the single serialization path shared by the\n // real saves and dryRunSerializeSpecs, so the round-trip check can never\n // drift from what a write would actually do.\n // ---------------------------------------------------------------------------\n\n /**\n * The namespace context a spec's file is written in: the deepest subproject\n * mount containing the id, else the id's own namespace. THE single prefix\n * derivation for the whole write pipeline — every prepare*ForWrite and every\n * ancillary relativization must use this, never re-derive it inline, or the\n * dry-run check and the real saves could drift apart.\n */\n writePrefixFor(qualifiedId: string): string {\n return this.getSubprojectPrefix(qualifiedId) || splitNamespace(qualifiedId).prefix;\n }\n\n prepareSubsystemForWrite(spec: SubsystemSpec): SubsystemSpec {\n const { prefix } = splitNamespace(spec.id);\n return stripNamespaceFromSubsystem(spec, prefix);\n }\n\n prepareComponentForWrite(spec: ComponentSpec): ComponentSpec {\n const prefix = this.writePrefixFor(spec.id);\n return prefix ? stripNamespaceFromComponent(spec, prefix) : spec;\n }\n\n prepareInterfaceForWrite(spec: InterfaceSpec): InterfaceSpec {\n const prefix = this.writePrefixFor(spec.id);\n return prefix ? stripNamespaceFromInterface(spec, prefix) : spec;\n }\n\n prepareImplementationForWrite(spec: ImplementationSpec): ImplementationSpec {\n const prefix = this.writePrefixFor(spec.id);\n return prefix ? stripNamespaceFromImplementation(spec, prefix) : spec;\n }\n\n prepareTypeForWrite(spec: TypeSpec): TypeSpec {\n const prefix = this.writePrefixFor(spec.id);\n return prefix ? stripNamespaceFromType(spec, prefix) : spec;\n }\n\n prepareGroupForWrite(spec: GroupSpec): GroupSpec {\n const prefix = this.writePrefixFor(spec.id);\n return prefix ? stripNamespaceFromGroup(spec, prefix) : spec;\n }\n\n /**\n * Re-serialize every loaded spec through the exact write pipeline the save\n * paths use — same relativization, same schema — without touching disk.\n * Returns one ROUNDTRIP_SERIALIZATION issue per spec the writer would\n * refuse, so validate reports at validate time every refusal that lock's\n * status promotion or any later save would otherwise raise mid-write.\n * `include` (when given) skips out-of-scope specs BEFORE the expensive\n * clone+parse, so scoped validation pays scoped cost.\n */\n dryRunSerializeSpecs(include?: (specId: string) => boolean): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n const index = this.scanAll();\n const inScope = include ?? ((): boolean => true);\n\n const check = (kind: string, id: string, result: z.SafeParseReturnType<unknown, unknown>): void => {\n if (result.success) return;\n issues.push({\n severity: 'error',\n code: 'ROUNDTRIP_SERIALIZATION',\n message: `${kind} spec \"${id}\" cannot be re-serialized through the writer schema (any save or lock would refuse it): ${formatZodIssues(result.error)}`,\n specId: id,\n });\n };\n\n for (const sub of index.subsystems) {\n if (!inScope(sub.id)) continue;\n check('subsystem', sub.id, SubsystemSpecSchema.safeParse(this.prepareSubsystemForWrite(sub)));\n }\n for (const comp of index.components) {\n if (!inScope(comp.id)) continue;\n check('component', comp.id, ComponentSpecSchema.safeParse(this.prepareComponentForWrite(comp)));\n }\n for (const intf of index.interfaces) {\n if (!inScope(intf.id)) continue;\n check('interface', intf.id, InterfaceSpecSchema.safeParse(this.prepareInterfaceForWrite(intf)));\n }\n for (const impl of index.implementations) {\n if (!inScope(impl.id)) continue;\n check('implementation', impl.id, ImplementationSpecSchema.safeParse(this.prepareImplementationForWrite(impl)));\n }\n for (const t of index.types) {\n if (!inScope(t.id)) continue;\n check('type', t.id, TypeSpecSchema.safeParse(this.prepareTypeForWrite(t)));\n }\n for (const g of index.groups) {\n if (!inScope(g.id)) continue;\n check('group', g.id, GroupSpecSchema.safeParse(this.prepareGroupForWrite(g)));\n }\n return issues;\n }\n\n saveSubsystemSpec(spec: SubsystemSpec): void {\n const p = this.getSubsystemPath(spec.id);\n ensureDir(path.dirname(p));\n\n const { prefix } = splitNamespace(spec.id);\n // Fix B2 (defense in depth): never persist an escaping projectPath, so no\n // later code path can resolve+act on it. Only for a top-level (non-prefixed)\n // subsystem, whose projectPath is relative to this.rootDir; a namespaced\n // subsystem's projectPath is child-relative and is contained by the\n // load-time guards (resolveSubprojectForNamespace + the recursive loader).\n if (!prefix && spec.projectPath && spec.projectPath.trim() !== '') {\n assertContainedProjectPath(this.rootDir, spec.projectPath);\n }\n // ALWAYS strip: an external subsystem's members carry the subsystem's own\n // id prefix even when the subsystem itself is mounted at the root (empty\n // prefix) — skipping the strip there wrote qualified member ids the\n // schema refuses, blocking lock.\n let specToWrite = this.prepareSubsystemForWrite(spec);\n\n if (prefix) {\n const childProj = this.resolveSubprojectForNamespace(prefix);\n if (childProj) {\n const childSystem = workspaceFor(childProj).loadSystemSpec();\n if (childSystem) {\n specToWrite = {\n ...specToWrite,\n parentSystem: childSystem.name,\n };\n }\n }\n }\n\n // A flat external subsystem carries projectPath ONLY in its parent mount.\n // getSubsystemPath routes a bare id whose realization lives in a subproject to\n // the child file; never write projectPath there or the child becomes a mount\n // that recurses into itself (e.g. lock's promote re-saving every subsystem).\n if (!spec.id.includes('::') && specToWrite.projectPath && !isWithin(this.paths.specsDir(), p)) {\n specToWrite = { ...specToWrite, projectPath: undefined };\n }\n\n const existing = this.loadSubsystemSpec(spec.id);\n if (existing) {\n specToWrite.createdAt = existing.createdAt;\n }\n specToWrite.updatedAt = new Date().toISOString();\n writeYamlFile(p, parseOrThrow(SubsystemSpecSchema, specToWrite, 'subsystem', spec.id));\n invalidateSpecCache();\n }\n\n deleteSubsystemSpec(id: string): boolean {\n const p = this.getSubsystemPath(id);\n if (!fs.existsSync(p)) return false;\n fs.unlinkSync(p);\n cleanEmptyDirs(p, path.resolve(this.paths.specsDir()));\n invalidateSpecCache();\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Level 2: Components\n // -------------------------------------------------------------------------\n\n loadComponentSpecs(): ComponentSpec[] {\n return this.scanAll().components;\n }\n\n loadComponentSpec(id: string): ComponentSpec | null {\n const index = this.scanAll();\n const spec = index.components.find((c) => c.id === id);\n if (spec) return spec;\n\n const p = this.getComponentPath(id);\n if (!pathExists(p)) return null;\n try {\n const raw = readYamlFile(p);\n return ComponentSpecSchema.parse(raw);\n } catch (e: any) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'SCHEMA_VALIDATION_ERROR',\n message: `Failed to parse component spec \"${id}\": ${e.message || String(e)}`,\n specId: id,\n });\n return null;\n }\n }\n\n /** Returns non-fatal placement notices (see saveTypeSpec) — empty when there is nothing to clarify. */\n saveComponentSpec(spec: ComponentSpec, opts?: SaveSpecOptions): string[] {\n const notices: string[] = [];\n const p = this.getComponentPath(spec.id, spec.subsystem);\n ensureDir(path.dirname(p));\n\n const specToWrite = this.prepareComponentForWrite(spec);\n\n const existing = this.loadComponentSpec(spec.id);\n if (existing) {\n specToWrite.createdAt = existing.createdAt;\n if (!opts?.allowStatusDemotion && existing.status && (!spec.status || spec.status === 'draft')) {\n specToWrite.status = existing.status;\n }\n }\n // Doctrine guidance at the moment it helps: fire once, at creation,\n // BEFORE the usual member-first authoring order creates the owner — it\n // tells the agent the two sanctioned paths and pre-empts the forbidden\n // third one (folding the state into a consumer).\n if (!existing && spec.componentType === 'Store'\n && !findOwner(spec.id, this.scanAll().components)) {\n notices.push(\n `Store \"${spec.id}\" has no owning pattern yet. Recommended: create the Repository that owns it `\n + `(plus its Registry and Index) and point consumers at the facade. For genuinely simple held state, `\n + `a standalone Store is the sanctioned lightweight form — keep the state visible here (workflow-layer `\n + `consumers only) and acknowledge the UNOWNED_STORE warning with a lint.allow reason. `\n + `Never fold the state into a consuming component instead.`,\n );\n }\n // The nested layout normalizes folders after the write; the flat legacy\n // layout keeps the file where it is — say so when the subsystem changed,\n // or a re-add reads as \"the parameter was ignored\".\n const subsystemChanged = existing\n && existing.subsystem !== spec.subsystem\n && splitNamespace(existing.subsystem).localId !== splitNamespace(spec.subsystem).localId;\n if (subsystemChanged && !p.endsWith('.index.yaml')) {\n notices.push(\n `component \"${spec.id}\" already exists at ${path.relative(this.rootDir, p)} — the flat layout re-saves in place and never relocates the file. `\n + `The subsystem field is now \"${spec.subsystem}\" (was \"${existing.subsystem}\").`,\n );\n }\n specToWrite.updatedAt = new Date().toISOString();\n writeYamlFile(p, parseOrThrow(ComponentSpecSchema, specToWrite, 'component', spec.id));\n invalidateSpecCache();\n // Keep the physical layout in sync with ownership: nest owned members under\n // their pattern, and move anything an `owns` change has displaced.\n this.normalizeComponentLayout();\n return notices;\n }\n\n deleteComponentSpec(id: string): boolean {\n const p = this.getComponentPath(id);\n if (!fs.existsSync(p)) return false;\n fs.unlinkSync(p);\n cleanEmptyDirs(p, path.resolve(this.paths.specsDir()));\n invalidateSpecCache();\n return true;\n }\n\n /** The directory a component's folder should live in, given current ownership. */\n private desiredComponentDir(comp: ComponentSpec, index: SpecIndex): string | null {\n const currentPath = index.paths.component[comp.id];\n // Only the nested-tree layout is normalized (skip the legacy flat components/ dir).\n if (!currentPath || !currentPath.endsWith('.index.yaml')) return null;\n if (comp.id.includes('::')) return null;\n\n const owner = findOwner(comp.id, index.components);\n if (owner) {\n const ownerPath = index.paths.component[owner.id];\n if (ownerPath && ownerPath.endsWith('.index.yaml')) {\n // The owner (a pattern) lives flat under its subsystem; the member nests inside it.\n const ownerSubDir = path.dirname(this.getSubsystemPath(owner.subsystem));\n return path.join(ownerSubDir, owner.id, comp.id);\n }\n }\n // Patterns, standalone blocks, and shared (interface-referenced) blocks stay flat.\n const subDir = path.dirname(this.getSubsystemPath(comp.subsystem));\n return path.join(subDir, comp.id);\n }\n\n /**\n * Move component folders so the physical tree mirrors ownership: each owned\n * member sits inside its pattern's folder, everything else flat under its\n * subsystem. Idempotent — only misplaced folders move. Returns the ids moved.\n * The interface.yaml / implementation.yaml travel with the folder.\n */\n normalizeComponentLayout(): string[] {\n const index = this.scanAll();\n const moved: string[] = [];\n for (const comp of index.components) {\n const currentPath = index.paths.component[comp.id];\n if (!currentPath) continue;\n const desiredDir = this.desiredComponentDir(comp, index);\n if (!desiredDir) continue;\n if (moveComponentFolder(path.dirname(currentPath), desiredDir)) moved.push(comp.id);\n }\n if (moved.length) invalidateSpecCache();\n return moved;\n }\n\n // -------------------------------------------------------------------------\n // Level 3: Interfaces\n // -------------------------------------------------------------------------\n\n loadInterfaceSpecs(): InterfaceSpec[] {\n return this.scanAll().interfaces;\n }\n\n loadInterfaceSpec(id: string): InterfaceSpec | null {\n const index = this.scanAll();\n const spec = index.interfaces.find((i) => i.id === id);\n if (spec) return spec;\n\n const p = this.getInterfacePath(id);\n if (!pathExists(p)) return null;\n try {\n const raw = readYamlFile(p);\n return InterfaceSpecSchema.parse(raw);\n } catch (e: any) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'SCHEMA_VALIDATION_ERROR',\n message: `Failed to parse interface spec \"${id}\": ${e.message || String(e)}`,\n specId: id,\n });\n return null;\n }\n }\n\n /** Returns non-fatal placement notices (see saveTypeSpec) — empty when there is nothing to clarify. */\n saveInterfaceSpec(spec: InterfaceSpec, opts?: SaveSpecOptions): string[] {\n const notices: string[] = [];\n const p = this.getInterfacePath(spec.id, spec.component);\n ensureDir(path.dirname(p));\n\n const specToWrite = this.prepareInterfaceForWrite(spec);\n\n const existing = this.loadInterfaceSpec(spec.id);\n if (existing && existing.component !== spec.component\n && splitNamespace(existing.component).localId !== splitNamespace(spec.component).localId) {\n notices.push(\n `interface \"${spec.id}\" already exists at ${path.relative(this.rootDir, p)} — re-saving updates the component binding field in place `\n + `(now \"${spec.component}\", was \"${existing.component}\") and never moves the file.`,\n );\n }\n if (existing) {\n specToWrite.createdAt = existing.createdAt;\n if (!opts?.allowStatusDemotion && existing.status && (!spec.status || spec.status === 'draft')) {\n specToWrite.status = existing.status;\n }\n // Preserve endpoint bindings for matching methods that don't carry their own\n for (const m of specToWrite.methods) {\n if (m.endpoint) continue;\n const existingMethod = existing.methods.find(x => x.name === m.name);\n if (existingMethod && existingMethod.endpoint) {\n m.endpoint = existingMethod.endpoint;\n }\n }\n }\n specToWrite.updatedAt = new Date().toISOString();\n writeYamlFile(p, parseOrThrow(InterfaceSpecSchema, specToWrite, 'interface', spec.id));\n invalidateSpecCache();\n return notices;\n }\n\n deleteInterfaceSpec(id: string): boolean {\n const p = this.getInterfacePath(id);\n if (!fs.existsSync(p)) return false;\n fs.unlinkSync(p);\n cleanEmptyDirs(p, path.resolve(this.paths.specsDir()));\n invalidateSpecCache();\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Level 4: Implementations\n // -------------------------------------------------------------------------\n\n loadImplementationSpecs(): ImplementationSpec[] {\n return this.scanAll().implementations;\n }\n\n loadImplementationSpec(id: string): ImplementationSpec | null {\n const index = this.scanAll();\n const spec = index.implementations.find((impl) => impl.id === id);\n if (spec) return spec;\n\n const p = this.getImplementationPath(id);\n if (!pathExists(p)) return null;\n try {\n const raw = readYamlFile(p);\n return ImplementationSpecSchema.parse(raw);\n } catch (e: any) {\n this.loaderIssues.push({\n severity: 'error',\n code: 'SCHEMA_VALIDATION_ERROR',\n message: `Failed to parse implementation spec \"${id}\": ${e.message || String(e)}`,\n specId: id,\n });\n return null;\n }\n }\n\n /** Returns non-fatal placement notices (see saveTypeSpec) — empty when there is nothing to clarify. */\n saveImplementationSpec(spec: ImplementationSpec, opts?: SaveSpecOptions): string[] {\n const notices: string[] = [];\n const p = this.getImplementationPath(spec.id, spec.contract);\n ensureDir(path.dirname(p));\n\n const specToWrite = this.prepareImplementationForWrite(spec);\n\n const existing = this.loadImplementationSpec(spec.id);\n if (existing && existing.contract !== spec.contract\n && splitNamespace(existing.contract).localId !== splitNamespace(spec.contract).localId) {\n notices.push(\n `implementation \"${spec.id}\" already exists at ${path.relative(this.rootDir, p)} — re-saving updates the contract binding field in place `\n + `(now \"${spec.contract}\", was \"${existing.contract}\") and never moves the file.`,\n );\n }\n if (existing) {\n specToWrite.createdAt = existing.createdAt;\n if (!opts?.allowStatusDemotion && existing.status && (!spec.status || spec.status === 'draft')) {\n specToWrite.status = existing.status;\n }\n }\n specToWrite.updatedAt = new Date().toISOString();\n writeYamlFile(p, parseOrThrow(ImplementationSpecSchema, specToWrite, 'implementation', spec.id));\n invalidateSpecCache();\n return notices;\n }\n\n deleteImplementationSpec(id: string): boolean {\n const p = this.getImplementationPath(id);\n if (!fs.existsSync(p)) return false;\n fs.unlinkSync(p);\n cleanEmptyDirs(p, path.resolve(this.paths.specsDir()));\n invalidateSpecCache();\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Types (entities / value objects)\n // -------------------------------------------------------------------------\n\n loadTypeSpecs(): TypeSpec[] {\n return this.scanAll().types;\n }\n\n loadTypeSpec(id: string): TypeSpec | null {\n return this.scanAll().types.find((t) => t.id === id) ?? null;\n }\n\n /**\n * Returns non-fatal placement notices (empty when there is nothing to\n * clarify): the flat legacy layout records subsystem ownership as a FIELD\n * while the file stays in the shared types/ directory, and a re-save never\n * relocates an existing file — both are by design, but silent they read as\n * \"the subsystem parameter was ignored\".\n */\n saveTypeSpec(spec: TypeSpec): string[] {\n const notices: string[] = [];\n const existing = this.loadTypeSpec(spec.id);\n const group = spec.group || (existing ? existing.group : undefined);\n const p = this.getTypePath(spec.id, spec.subsystem, group);\n ensureDir(path.dirname(p));\n\n const subsystemChanged = existing\n && (existing.subsystem ?? '') !== (spec.subsystem ?? '')\n && splitNamespace(existing.subsystem ?? '').localId !== splitNamespace(spec.subsystem ?? '').localId;\n if (subsystemChanged) {\n notices.push(\n `type \"${spec.id}\" already exists at ${path.relative(this.rootDir, p)} — re-saving updates fields in place and never relocates the file. `\n + `The subsystem field is now \"${spec.subsystem ?? '(none)'}\" (was \"${existing.subsystem ?? '(none)'}\").`,\n );\n }\n if (spec.subsystem && (!existing || subsystemChanged)\n && !this.getSubsystemPath(spec.subsystem).endsWith('.index.yaml')) {\n notices.push(\n `flat layout: type \"${spec.id}\" is recorded under subsystem \"${spec.subsystem}\" via its subsystem field, `\n + `and the file lives in the shared types/ directory — per-subsystem type folders exist only in the nested layout `\n + `(subsystem indexes as .index.yaml). The subsystem parameter took effect: ownership is the field, not the folder.`,\n );\n }\n\n const specToWrite = this.prepareTypeForWrite(spec);\n\n if (existing) {\n specToWrite.createdAt = existing.createdAt;\n if (!specToWrite.group && existing.group) {\n specToWrite.group = relativizeId(existing.group, this.writePrefixFor(spec.id));\n }\n }\n specToWrite.updatedAt = new Date().toISOString();\n writeYamlFile(p, parseOrThrow(TypeSpecSchema, specToWrite, 'type', spec.id));\n invalidateSpecCache();\n return notices;\n }\n\n deleteTypeSpec(id: string): boolean {\n const spec = this.loadTypeSpec(id);\n const p = this.getTypePath(id, spec?.subsystem, spec?.group);\n if (!fs.existsSync(p)) return false;\n fs.unlinkSync(p);\n cleanEmptyDirs(p, path.resolve(this.paths.specsDir()));\n invalidateSpecCache();\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Groups (folders/categories for types)\n // -------------------------------------------------------------------------\n\n loadGroupSpecs(): GroupSpec[] {\n return this.scanAll().groups;\n }\n\n loadGroupSpec(id: string): GroupSpec | null {\n return this.scanAll().groups.find((g) => g.id === id) ?? null;\n }\n\n saveGroupSpec(spec: GroupSpec): void {\n const p = this.getGroupPath(spec.id);\n ensureDir(path.dirname(p));\n\n const specToWrite = this.prepareGroupForWrite(spec);\n\n const existing = this.loadGroupSpec(spec.id);\n if (existing) {\n specToWrite.createdAt = existing.createdAt;\n }\n specToWrite.updatedAt = new Date().toISOString();\n writeYamlFile(p, parseOrThrow(GroupSpecSchema, specToWrite, 'group', spec.id));\n invalidateSpecCache();\n }\n\n deleteGroupSpec(id: string): boolean {\n const p = this.getGroupPath(id);\n if (!fs.existsSync(p)) return false;\n fs.unlinkSync(p);\n cleanEmptyDirs(p, path.resolve(this.paths.specsDir()));\n invalidateSpecCache();\n return true;\n }\n\n // -------------------------------------------------------------------------\n // Spec status promotion (draft/design → complete)\n // -------------------------------------------------------------------------\n\n /** Every spec whose status is not yet 'complete', with its current status captured. */\n collectPromotableSpecs(scopeSubsystem?: string): PromotableSpec[] {\n const out: PromotableSpec[] = [];\n const subsystems = this.loadSubsystemSpecs();\n const components = this.loadComponentSpecs();\n const interfaces = this.loadInterfaceSpecs();\n const implementations = this.loadImplementationSpecs();\n\n const isSpecInSubsystemScope = (specSubsystem: string | undefined): boolean => {\n if (!scopeSubsystem) return true;\n if (!specSubsystem) return false;\n return specSubsystem === scopeSubsystem || specSubsystem.startsWith(`${scopeSubsystem}::`);\n };\n\n for (const s of subsystems) {\n if (s.status !== 'complete' && (!scopeSubsystem || s.id === scopeSubsystem || s.id.startsWith(scopeSubsystem + '::'))) {\n out.push({ kind: 'subsystem', id: s.id, status: (s.status ?? 'complete') as SpecStatus });\n }\n }\n for (const c of components) {\n if (c.status !== 'complete' && isSpecInSubsystemScope(c.subsystem)) {\n out.push({ kind: 'component', id: c.id, status: (c.status ?? 'complete') as SpecStatus });\n }\n }\n for (const i of interfaces) {\n if (i.status !== 'complete') {\n const comp = components.find(c => c.id === i.component);\n if (comp && isSpecInSubsystemScope(comp.subsystem)) {\n out.push({ kind: 'interface', id: i.id, status: (i.status ?? 'complete') as SpecStatus });\n }\n }\n }\n for (const m of implementations) {\n if (m.status !== 'complete') {\n const intf = interfaces.find(i => i.id === m.contract);\n const comp = intf ? components.find(c => c.id === intf.component) : null;\n if (comp && isSpecInSubsystemScope(comp.subsystem)) {\n out.push({ kind: 'implementation', id: m.id, status: (m.status ?? 'complete') as SpecStatus });\n }\n }\n }\n return out;\n }\n\n /** Set a single spec's status (bumps updatedAt). Caller invalidates the cache. */\n applySpecStatus(kind: SpecKind, id: string, status: SpecStatus): void {\n switch (kind) {\n case 'subsystem': { const s = this.loadSubsystemSpec(id); if (s) this.saveSubsystemSpec({ ...s, status }); break; }\n case 'component': { const s = this.loadComponentSpec(id); if (s) this.saveComponentSpec({ ...s, status }); break; }\n case 'interface': { const s = this.loadInterfaceSpec(id); if (s) this.saveInterfaceSpec({ ...s, status }); break; }\n case 'implementation': { const s = this.loadImplementationSpec(id); if (s) this.saveImplementationSpec({ ...s, status }); break; }\n }\n }\n\n /**\n * Snapshot the raw bytes of every spec file under .wai/specs. Paired with\n * restoreSpecFiles() to give a byte-exact revert — used by `wairon lock` to\n * dry-run a promotion (write 'complete' → validate → restore) without leaving\n * any change behind if validation fails or the user cancels.\n */\n snapshotSpecFiles(): Map<string, string> {\n const index = this.scanAll();\n const snapshot = new Map<string, string>();\n const files = new Set<string>();\n\n const sysPath = this.paths.specsSystem();\n if (pathExists(sysPath)) {\n files.add(path.resolve(sysPath));\n }\n\n for (const group of Object.values(index.paths)) {\n for (const file of Object.values(group)) {\n files.add(path.resolve(file));\n }\n }\n\n for (const file of files) {\n if (fs.existsSync(file)) {\n snapshot.set(file, fs.readFileSync(file, 'utf8'));\n }\n }\n\n return snapshot;\n }\n\n // -------------------------------------------------------------------------\n // Legacy layout detection\n // -------------------------------------------------------------------------\n\n findLegacySpecFiles(): { path: string; expected: string }[] {\n const specsDir = this.paths.specsDir();\n if (!pathExists(specsDir)) return [];\n const files = listFilesRecursive(specsDir, '.yaml');\n const legacy: { path: string; expected: string }[] = [];\n for (const f of files) {\n const base = path.basename(f);\n const dir = path.dirname(f);\n if (base === 'system.yaml') {\n legacy.push({ path: f, expected: path.join(dir, '.index.yaml') });\n } else if (base === 'subsystem.yaml') {\n legacy.push({ path: f, expected: path.join(dir, '.index.yaml') });\n } else if (base === 'component.yaml') {\n legacy.push({ path: f, expected: path.join(dir, '.index.yaml') });\n } else if (base === 'group.yaml') {\n legacy.push({ path: f, expected: path.join(dir, '.index.yaml') });\n } else if (base === 'interface.yaml') {\n legacy.push({ path: f, expected: path.join(dir, '.interface.yaml') });\n } else if (base === 'implementation.yaml') {\n legacy.push({ path: f, expected: path.join(dir, '.implementation.yaml') });\n }\n }\n return legacy;\n }\n\n // -------------------------------------------------------------------------\n // Granular delta updates (sdd_update_spec)\n // -------------------------------------------------------------------------\n\n /**\n * Returns non-fatal notices about the merge (e.g. an insert whose position\n * was a jump target, so the relocated jumps now bypass the inserted step) —\n * empty when the merge had nothing to warn about.\n */\n updateSpec(\n kind: 'system' | 'subsystem' | 'component' | 'interface' | 'implementation' | 'type',\n id: string,\n delta: Record<string, any>\n ): string[] {\n const notices: string[] = [];\n const result = (() => {\n switch (kind) {\n case 'system': return this.loadSystemSpec(); // singleton — id is informational\n case 'subsystem': return this.loadSubsystemSpec(id);\n case 'component': return this.loadComponentSpec(id);\n case 'interface': return this.loadInterfaceSpec(id);\n case 'implementation': return this.loadImplementationSpec(id);\n case 'type': return this.loadTypeSpec(id);\n }\n })();\n\n if (!result) {\n throw new Error(`Spec of kind \"${kind}\" with ID \"${id}\" does not exist. Define it first.`);\n }\n\n // The L0 is a singleton and its load ignores the id — reject a mismatched\n // id loudly so a mis-selected kind can't silently rewrite the system spec.\n if (kind === 'system' && id && id !== 'system' && id !== (result as SystemSpec).name) {\n throw new Error(\n `kind \"system\" targets the singleton L0 spec (system name \"${(result as SystemSpec).name}\") — pass id \"system\" or the system name, got \"${id}\". For a subsystem, use kind \"subsystem\".`,\n );\n }\n\n // Flow-step jump fields relocate with renumbering, exactly like an\n // assembler relocating addresses: inserts/deletes shift every jump field\n // in the SAME narrative that points at or beyond the mutation point.\n const JUMP_FIELDS = ['onTrueStep', 'onFalseStep', 'defaultStep', 'endStep', 'finallyStep', 'toStep'] as const;\n const JUMP_LIST_FIELDS = ['cases', 'catches', 'branches'] as const;\n\n // captureInsertTarget: ENTRY jumps pointing exactly at the insertion point\n // stay put, so they land on the inserted step instead of following the\n // shifted original (\"execute this first\" insert semantics). endStep is a\n // region TAIL (last step of a loop/try body), not an entry: capturing it\n // would shrink the region and evict its original last step, so it always\n // relocates with the body.\n const relocateJumps = (step: any, shiftFrom: number, deltaN: number, captureInsertTarget = false): any => {\n const hit = (v: number, isRegionTail = false) =>\n (deltaN > 0 ? ((captureInsertTarget && !isRegionTail) ? v > shiftFrom : v >= shiftFrom) : v > shiftFrom);\n const out = { ...step };\n for (const f of JUMP_FIELDS) {\n if (typeof out[f] === 'number' && hit(out[f], f === 'endStep')) out[f] = out[f] + deltaN;\n }\n for (const lf of JUMP_LIST_FIELDS) {\n if (Array.isArray(out[lf])) {\n out[lf] = out[lf].map((c: any) =>\n typeof c?.step === 'number' && hit(c.step) ? { ...c, step: c.step + deltaN } : c,\n );\n }\n }\n return out;\n };\n\n const jumpRefsTo = (step: any, target: number): string[] => {\n const refs: string[] = [];\n for (const f of JUMP_FIELDS) if (step[f] === target) refs.push(f);\n for (const lf of JUMP_LIST_FIELDS) {\n (Array.isArray(step[lf]) ? step[lf] : []).forEach((c: any, i: number) => {\n if (c?.step === target) refs.push(`${lf}[${i}].step`);\n });\n }\n return refs;\n };\n\n const mergeNarrative = (existingSteps: any[], deltaSteps: any[]): any[] => {\n let steps = [...existingSteps];\n const sortedDeltas = [...deltaSteps].sort((a, b) => a.stepNumber - b.stepNumber);\n for (const deltaStep of sortedDeltas) {\n const stepNum = deltaStep.stepNumber;\n if (deltaStep.action === 'delete' || deltaStep.remove === true) {\n const idx = steps.findIndex(s => s.stepNumber === stepNum);\n if (idx !== -1) {\n const referrers = steps\n .filter(s => s.stepNumber !== stepNum)\n .map(s => ({ n: s.stepNumber, refs: jumpRefsTo(s, stepNum) }))\n .filter(r => r.refs.length > 0);\n if (referrers.length) {\n throw new Error(\n `Cannot delete narrative step ${stepNum}: it is a jump target of step(s) `\n + referrers.map(r => `${r.n} (${r.refs.join(', ')})`).join(', ')\n + '. Retarget or delete the referring steps first.',\n );\n }\n steps.splice(idx, 1);\n steps = steps.map(s => relocateJumps(\n s.stepNumber > stepNum ? { ...s, stepNumber: s.stepNumber - 1 } : s,\n stepNum,\n -1,\n ));\n }\n } else if (deltaStep.action === 'insert') {\n // The inserted step's own jump fields are taken as-is: they refer\n // to the POST-insert numbering the author is creating. Existing\n // jumps AT the insertion point follow their old referent to N+1 by\n // default (assembler-style relocation) — captureJumps: true keeps\n // them on N so they hit the inserted step first.\n const capture = deltaStep.captureJumps === true;\n if (!capture) {\n const incoming = steps\n .map(s => ({ n: s.stepNumber, refs: jumpRefsTo(s, stepNum) }))\n .filter(r => r.refs.length > 0);\n if (incoming.length) {\n notices.push(\n `Inserted step ${stepNum} was a jump target: `\n + incoming.map(r => `step ${r.n} (${r.refs.join(', ')})`).join(', ')\n + ` now target the shifted original step ${stepNum + 1} and BYPASS the inserted step — it is only reached by fall-through.`\n + ` If those jumps should hit the new step first, insert with \"captureJumps\": true or retarget them.`,\n );\n }\n }\n steps = steps.map(s => relocateJumps(\n s.stepNumber >= stepNum ? { ...s, stepNumber: s.stepNumber + 1 } : s,\n stepNum,\n 1,\n capture,\n ));\n const { action, remove, captureJumps, ...cleanStep } = deltaStep;\n steps.push(cleanStep);\n } else {\n const idx = steps.findIndex(s => s.stepNumber === stepNum);\n if (idx !== -1) {\n const { action, remove, ...cleanStep } = deltaStep;\n steps[idx] = {\n ...steps[idx],\n ...cleanStep,\n };\n } else {\n const { action, remove, ...cleanStep } = deltaStep;\n steps.push(cleanStep);\n }\n }\n }\n return steps.sort((a, b) => a.stepNumber - b.stepNumber);\n };\n\n /**\n * Opaque `ext` maps key-merge at EVERY level. Spec-level ext already does\n * (mergeDelta's object recursion); a METHOD-level ext delta went through\n * the shallow method spread instead, clobbering the whole map. This mirrors\n * mergeDelta's semantics for a plain data map — delta keys win, absent keys\n * survive, nested objects merge, arrays replace, null/undefined skipped —\n * without mergeDelta's named-key special cases (ext content is opaque; a\n * pack key spelled \"methods\" must never trigger the methods merge).\n */\n const isPlainObject = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' && v !== null && !Array.isArray(v);\n const mergeExt = (existing: any, delta: any): any => {\n if (!isPlainObject(existing) || !isPlainObject(delta)) return delta ?? existing;\n const res: Record<string, unknown> = { ...existing };\n for (const [key, value] of Object.entries(delta)) {\n if (value === undefined || value === null) continue;\n res[key] = isPlainObject(value) && isPlainObject(res[key]) ? mergeExt(res[key], value) : value;\n }\n return res;\n };\n\n const mergeMethods = (existingMethods: any[], deltaMethods: any[]): any[] => {\n const merged = [...existingMethods];\n for (const deltaMethod of deltaMethods) {\n const idx = merged.findIndex(m => m.name === deltaMethod.name);\n if (idx !== -1) {\n if (deltaMethod.remove === true || deltaMethod.action === 'delete') {\n merged.splice(idx, 1);\n } else {\n const existingMethod = merged[idx];\n let narrative = existingMethod.narrative ? [...existingMethod.narrative] : [];\n if (deltaMethod.narrative && Array.isArray(deltaMethod.narrative)) {\n narrative = mergeNarrative(narrative, deltaMethod.narrative);\n }\n const { narrative: _, ...cleanMethod } = deltaMethod;\n merged[idx] = {\n ...existingMethod,\n ...cleanMethod,\n ...(deltaMethod.ext !== undefined ? { ext: mergeExt(existingMethod.ext, deltaMethod.ext) } : {}),\n narrative,\n };\n }\n } else {\n if (deltaMethod.remove !== true && deltaMethod.action !== 'delete') {\n merged.push(deltaMethod);\n }\n }\n }\n return merged;\n };\n\n const mergeNamedArray = (existing: any[], delta: any[]): any[] => {\n const merged = [...existing];\n for (const deltaItem of delta) {\n const idx = merged.findIndex(item => item.name === deltaItem.name);\n if (idx !== -1) {\n if (deltaItem.remove === true || deltaItem.action === 'delete') {\n merged.splice(idx, 1);\n } else {\n merged[idx] = {\n ...merged[idx],\n ...deltaItem,\n ...(deltaItem.ext !== undefined ? { ext: mergeExt(merged[idx].ext, deltaItem.ext) } : {}),\n };\n }\n } else {\n if (deltaItem.remove !== true && deltaItem.action !== 'delete') {\n merged.push(deltaItem);\n }\n }\n }\n return merged;\n };\n\n // Upsert-by-key for arrays whose elements have no `name`/`id`: dispatch\n // bindings key on capability, lifecycle entrypoints on phase+component+\n // method. Without this they fell to the wholesale-replace branch and a\n // one-entry delta silently erased the rest of the table.\n const mergeKeyedArray = (existing: any[], delta: any[], keyOf: (item: any) => string): any[] => {\n const merged = [...existing];\n for (const deltaItem of delta) {\n const idx = merged.findIndex(item => keyOf(item) === keyOf(deltaItem));\n if (idx !== -1) {\n if (deltaItem.remove === true || deltaItem.action === 'delete') {\n merged.splice(idx, 1);\n } else {\n merged[idx] = { ...merged[idx], ...deltaItem };\n }\n } else if (deltaItem.remove !== true && deltaItem.action !== 'delete') {\n merged.push(deltaItem);\n }\n }\n return merged.map(({ action, remove, ...item }) => item);\n };\n\n const mergePublicInterfaces = (existing: any[], delta: any[]): any[] => {\n const merged = [...existing];\n for (const deltaItem of delta) {\n const idx = merged.findIndex(item => item.component === deltaItem.component && item.interface === deltaItem.interface);\n if (idx !== -1) {\n if (deltaItem.remove === true || deltaItem.action === 'delete') {\n merged.splice(idx, 1);\n } else {\n merged[idx] = {\n ...merged[idx],\n ...deltaItem,\n };\n }\n } else {\n if (deltaItem.remove !== true && deltaItem.action !== 'delete') {\n merged.push(deltaItem);\n }\n }\n }\n return merged;\n };\n\n const mergeDelta = (existing: any, delta2: any): any => {\n const res = { ...existing };\n for (const [key, value] of Object.entries(delta2)) {\n if (value === undefined || value === null) {\n continue;\n }\n if (key === 'methods' && Array.isArray(value) && Array.isArray(existing.methods)) {\n if (kind === 'implementation') {\n res.methods = mergeMethods(existing.methods, value);\n } else {\n res.methods = mergeNamedArray(existing.methods, value);\n }\n } else if (key === 'fields' && Array.isArray(value) && Array.isArray(existing.fields)) {\n res.fields = mergeNamedArray(existing.fields, value);\n } else if (key === 'publicInterfaces' && Array.isArray(value) && Array.isArray(existing.publicInterfaces)) {\n res.publicInterfaces = mergePublicInterfaces(existing.publicInterfaces, value);\n } else if (key === 'dispatch' && Array.isArray(value) && Array.isArray(existing.dispatch)) {\n res.dispatch = mergeKeyedArray(existing.dispatch, value, b => String(b?.capability));\n } else if (key === 'lifecycle' && Array.isArray(value) && Array.isArray(existing.lifecycle)) {\n res.lifecycle = mergeKeyedArray(existing.lifecycle, value, le => `${le?.phase} ${le?.component} ${le?.method}`);\n } else if ((key === 'emits' || key === 'subscribesTo') && Array.isArray(value) && Array.isArray(existing[key])) {\n res[key] = mergeKeyedArray(existing[key], value, (b: { topic?: string; event?: string }) => `${b?.topic} ${b?.event ?? ''}`);\n } else if (Array.isArray(value)) {\n res[key] = value;\n } else if (typeof value === 'object' && typeof existing[key] === 'object' && existing[key] !== null) {\n res[key] = mergeDelta(existing[key], value);\n } else {\n res[key] = value;\n }\n }\n return res;\n };\n\n // Callers write DELTAS with LOCAL names (the natural form inside a\n // namespace) while the loaded spec is fully qualified. Qualify the\n // delta's id-bearing references BEFORE the merge, exactly as the loader\n // would have — never after, because post-merge a bare id is ambiguous\n // (a loaded root-level ref and a delta-local ref read identically).\n // Only fields PRESENT in the delta are touched, so nothing new is merged.\n const qualifyDeltaRefs = (d: Record<string, any>): Record<string, any> => {\n if (kind === 'system') return d;\n const prefix = this.writePrefixFor(id);\n if (!prefix) return d;\n const q = (ref: unknown): unknown =>\n typeof ref === 'string' ? qualifyId(ref, prefix, this.rootSubsystems) : ref;\n const out: Record<string, any> = { ...d };\n switch (kind) {\n case 'subsystem': {\n const isExternal = !!(out.projectPath ?? (result as SubsystemSpec).projectPath);\n const memberPrefix = isExternal ? id : prefix;\n const qm = (ref: unknown): unknown =>\n typeof ref === 'string' ? qualifyId(ref, memberPrefix, this.rootSubsystems) : ref;\n if (Array.isArray(out.publicInterfaces)) {\n out.publicInterfaces = out.publicInterfaces.map((pi: any) => ({\n ...pi,\n ...(typeof pi?.component === 'string' ? { component: qm(pi.component) } : {}),\n ...(typeof pi?.interface === 'string' ? { interface: qm(pi.interface) } : {}),\n }));\n }\n if (Array.isArray(out.lifecycle)) {\n out.lifecycle = out.lifecycle.map((le: any) =>\n (typeof le?.component === 'string' ? { ...le, component: qm(le.component) } : le));\n }\n break;\n }\n case 'component':\n if (typeof out.subsystem === 'string') out.subsystem = q(out.subsystem);\n if (Array.isArray(out.owns)) out.owns = out.owns.map(q);\n if (Array.isArray(out.dependsOn)) out.dependsOn = out.dependsOn.map(q);\n if (Array.isArray(out.dispatch)) {\n out.dispatch = out.dispatch.map((b: any) =>\n (typeof b?.component === 'string' ? { ...b, component: q(b.component) } : b));\n }\n break;\n case 'interface':\n if (typeof out.component === 'string') out.component = q(out.component);\n break;\n case 'implementation':\n if (typeof out.contract === 'string') out.contract = q(out.contract);\n if (Array.isArray(out.methods)) {\n out.methods = out.methods.map((m: any) =>\n (Array.isArray(m?.narrative)\n ? {\n ...m,\n narrative: m.narrative.map((s: any) =>\n (typeof s?.targetComponent === 'string' ? { ...s, targetComponent: q(s.targetComponent) } : s)),\n }\n : m));\n }\n break;\n case 'type':\n if (typeof out.subsystem === 'string') out.subsystem = q(out.subsystem);\n if (typeof out.group === 'string') out.group = q(out.group);\n break;\n }\n return out;\n };\n\n const mergedResult = mergeDelta(result, qualifyDeltaRefs(delta));\n mergedResult.updatedAt = new Date().toISOString();\n\n // Symbolic step-label references resolve AFTER the merge, so a delta can\n // reference labels anchored on pre-existing steps. Unresolved references\n // abort the whole update — a dropped reference would silently become a\n // dangling numeric jump.\n if (kind === 'implementation' && Array.isArray(mergedResult.methods)) {\n const labelErrors: string[] = [];\n for (const m of mergedResult.methods) {\n if (m && Array.isArray(m.narrative)) labelErrors.push(...resolveNarrativeLabels(String(m.name), m.narrative));\n }\n if (labelErrors.length) {\n throw new Error(`Unresolved narrative label references — nothing was saved:\\n- ${labelErrors.join('\\n- ')}`);\n }\n }\n\n // An explicit status in the delta is a deliberate change — allow demotion\n // (e.g. reopening a completed spec to 'draft' for revision).\n const opts: SaveSpecOptions = {\n allowStatusDemotion: Object.prototype.hasOwnProperty.call(delta, 'status'),\n };\n\n switch (kind) {\n case 'system': this.saveSystemSpec(mergedResult); break;\n case 'subsystem': this.saveSubsystemSpec(mergedResult); break;\n case 'component': notices.push(...this.saveComponentSpec(mergedResult, opts)); break;\n case 'interface': notices.push(...this.saveInterfaceSpec(mergedResult, opts)); break;\n case 'implementation': notices.push(...this.saveImplementationSpec(mergedResult, opts)); break;\n case 'type': notices.push(...this.saveTypeSpec(mergedResult)); break;\n }\n\n return notices;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Workspace registry + flat module API (delegates to the current root)\n// ---------------------------------------------------------------------------\n\nconst workspaces = new Map<string, SpecWorkspace>();\n\n/** The workspace for an explicit project root (created on first use). */\nexport function workspaceFor(rootDir: string): SpecWorkspace {\n const key = path.resolve(rootDir);\n let ws = workspaces.get(key);\n if (!ws) {\n ws = new SpecWorkspace(key);\n workspaces.set(key, ws);\n }\n return ws;\n}\n\n/** The workspace for the current project root (override, else resolved cwd). */\nfunction current(): SpecWorkspace {\n return workspaceFor(getProjectRoot());\n}\n\n/**\n * Invalidate every workspace's cache and drop the instances. Invalidation must\n * hit the instances themselves (not just the map) because a workspace method\n * may still be mid-flight holding `this` — e.g. saveComponentSpec invalidates\n * globally and then runs normalizeComponentLayout on the same instance, which\n * must rescan rather than serve its stale index.\n */\nexport function invalidateSpecCache(): void {\n // Invalidate IN PLACE — never clear the registry. A caller holding a\n // workspaceFor() reference (tests, the hosted server's per-project scopes)\n // must keep receiving invalidations; evicting the instance orphaned such\n // references on a permanently-stale index whose path lookups then\n // mis-routed writes into specs/default fallbacks.\n for (const ws of workspaces.values()) ws.invalidate();\n}\n\nexport function getLoaderIssues(): ValidationIssue[] {\n return current().loaderIssues;\n}\n\nexport function clearLoaderIssues(): void {\n current().loaderIssues = [];\n invalidateSpecCache();\n}\n\nexport function scanAllSpecs(options?: { recursive?: boolean | number }): SpecIndex {\n return current().scanAll(options);\n}\n\nexport function resolveSubprojectForNamespace(namespace: string): string | null {\n return current().resolveSubprojectForNamespace(namespace);\n}\n\nexport function getSubprojectPrefix(qualifiedId: string): string | null {\n return current().getSubprojectPrefix(qualifiedId);\n}\n\nexport function getSubsystemPath(id: string): string {\n return current().getSubsystemPath(id);\n}\n\nexport function getComponentPath(id: string, subsystemId?: string): string {\n return current().getComponentPath(id, subsystemId);\n}\n\nexport function getInterfacePath(id: string, componentId?: string): string {\n return current().getInterfacePath(id, componentId);\n}\n\nexport function getImplementationPath(id: string, contractId?: string): string {\n return current().getImplementationPath(id, contractId);\n}\n\nexport function getTypePath(id: string, subsystemId?: string, group?: string): string {\n return current().getTypePath(id, subsystemId, group);\n}\n\nexport function getGroupPath(id: string, subsystemId?: string): string {\n return current().getGroupPath(id, subsystemId);\n}\n\nexport function loadSystemSpec(): SystemSpec | null {\n return current().loadSystemSpec();\n}\n\nexport function saveSystemSpec(spec: SystemSpec): void {\n current().saveSystemSpec(spec);\n}\n\nexport function loadSubsystemSpecs(): SubsystemSpec[] {\n return current().loadSubsystemSpecs();\n}\n\nexport function loadSubsystemSpec(id: string): SubsystemSpec | null {\n return current().loadSubsystemSpec(id);\n}\n\nexport function saveSubsystemSpec(spec: SubsystemSpec): void {\n current().saveSubsystemSpec(spec);\n}\n\nexport function deleteSubsystemSpec(id: string): boolean {\n return current().deleteSubsystemSpec(id);\n}\n\nexport function loadComponentSpecs(): ComponentSpec[] {\n return current().loadComponentSpecs();\n}\n\nexport function loadComponentSpec(id: string): ComponentSpec | null {\n return current().loadComponentSpec(id);\n}\n\nexport function saveComponentSpec(spec: ComponentSpec, opts?: SaveSpecOptions): string[] {\n return current().saveComponentSpec(spec, opts);\n}\n\nexport function deleteComponentSpec(id: string): boolean {\n return current().deleteComponentSpec(id);\n}\n\nexport function normalizeComponentLayout(): string[] {\n return current().normalizeComponentLayout();\n}\n\nexport function loadInterfaceSpecs(): InterfaceSpec[] {\n return current().loadInterfaceSpecs();\n}\n\nexport function loadInterfaceSpec(id: string): InterfaceSpec | null {\n return current().loadInterfaceSpec(id);\n}\n\nexport function saveInterfaceSpec(spec: InterfaceSpec, opts?: SaveSpecOptions): string[] {\n return current().saveInterfaceSpec(spec, opts);\n}\n\nexport function deleteInterfaceSpec(id: string): boolean {\n return current().deleteInterfaceSpec(id);\n}\n\nexport function loadImplementationSpecs(): ImplementationSpec[] {\n return current().loadImplementationSpecs();\n}\n\nexport function loadImplementationSpec(id: string): ImplementationSpec | null {\n return current().loadImplementationSpec(id);\n}\n\nexport function saveImplementationSpec(spec: ImplementationSpec, opts?: SaveSpecOptions): string[] {\n return current().saveImplementationSpec(spec, opts);\n}\n\nexport function deleteImplementationSpec(id: string): boolean {\n return current().deleteImplementationSpec(id);\n}\n\nexport function loadTypeSpecs(): TypeSpec[] {\n return current().loadTypeSpecs();\n}\n\nexport function loadTypeSpec(id: string): TypeSpec | null {\n return current().loadTypeSpec(id);\n}\n\nexport function saveTypeSpec(spec: TypeSpec): string[] {\n return current().saveTypeSpec(spec);\n}\n\nexport function dryRunSerializeSpecs(include?: (specId: string) => boolean): ValidationIssue[] {\n return current().dryRunSerializeSpecs(include);\n}\n\n/** Project the current project's spec tree into a level-filtered WebGraphModel,\n * forwarded to the diagram specialist's pure graph projection (core_orchestrator\n * → diagram_specialist). */\nexport function buildProjectGraph(level: number): WebGraphModel {\n return buildGraphModel(level);\n}\n\nexport function deleteTypeSpec(id: string): boolean {\n return current().deleteTypeSpec(id);\n}\n\nexport function loadGroupSpecs(): GroupSpec[] {\n return current().loadGroupSpecs();\n}\n\nexport function loadGroupSpec(id: string): GroupSpec | null {\n return current().loadGroupSpec(id);\n}\n\nexport function saveGroupSpec(spec: GroupSpec): void {\n current().saveGroupSpec(spec);\n}\n\nexport function deleteGroupSpec(id: string): boolean {\n return current().deleteGroupSpec(id);\n}\n\nexport function collectPromotableSpecs(scopeSubsystem?: string): PromotableSpec[] {\n return current().collectPromotableSpecs(scopeSubsystem);\n}\n\nexport function applySpecStatus(kind: SpecKind, id: string, status: SpecStatus): void {\n current().applySpecStatus(kind, id, status);\n}\n\nexport function snapshotSpecFiles(): Map<string, string> {\n return current().snapshotSpecFiles();\n}\n\n/** Restore files captured by snapshotSpecFiles(). Caller invalidates the cache. */\nexport function restoreSpecFiles(snapshot: Map<string, string>): void {\n for (const [file, content] of snapshot) {\n fs.writeFileSync(file, content);\n }\n}\n\nexport function findLegacySpecFiles(): { path: string; expected: string }[] {\n return current().findLegacySpecFiles();\n}\n\nexport function updateSpec(\n kind: 'system' | 'subsystem' | 'component' | 'interface' | 'implementation' | 'type',\n id: string,\n delta: Record<string, any>\n): string[] {\n return current().updateSpec(kind, id, delta);\n}\n","import * as path from 'path';\nimport * as fs from 'fs';\nimport { AgentRecord } from '../models/agent.js';\nimport { loadProjectConfig, AI_PATHS, loadTopologyConfig } from '../config/loader.js';\nimport { getProjectRoot, pathExists } from '../utils/fs.js';\nimport {\n loadSystemSpec,\n loadSubsystemSpecs,\n loadComponentSpecs,\n loadInterfaceSpecs,\n loadImplementationSpecs,\n getSubsystemPath,\n getComponentPath,\n getInterfacePath,\n getImplementationPath,\n resolveSubprojectForNamespace,\n} from './specs.js';\nimport { ComponentSpec } from '../models/specs.js';\nimport { loadProjectVariants, type VariantDef } from './variants.js';\n\n// Cache for project files relative to the system root\nconst projectFilesCache = new Map<string, string[]>();\n\nfunction listFilesRecursiveSafe(dirPath: string, ext: string): string[] {\n if (!fs.existsSync(dirPath)) return [];\n const nameLower = path.basename(dirPath).toLowerCase();\n const IGNORED_DIRS = new Set([\n 'node_modules',\n 'target',\n 'dist',\n 'build',\n '.git',\n '.wai',\n '.claude',\n '.gemini',\n '.codex',\n '.agents',\n '.vscode',\n ]);\n if (IGNORED_DIRS.has(nameLower)) return [];\n\n const entries = fs.readdirSync(dirPath, { withFileTypes: true });\n const files: string[] = [];\n for (const entry of entries) {\n const fullPath = path.join(dirPath, entry.name);\n if (entry.isDirectory()) {\n files.push(...listFilesRecursiveSafe(fullPath, ext));\n } else if (entry.isFile() && entry.name.endsWith(ext)) {\n files.push(fullPath);\n }\n }\n return files;\n}\n\nfunction getProjectFiles(projectDir: string): string[] {\n let files = projectFilesCache.get(projectDir);\n if (!files) {\n files = [];\n const srcDir = path.join(projectDir, 'src');\n const legacySrcDir = path.join(projectDir, 'legacy-src');\n \n let searchDir = projectDir;\n if (pathExists(srcDir)) {\n searchDir = srcDir;\n } else if (pathExists(legacySrcDir)) {\n searchDir = legacySrcDir;\n } else if (projectDir === getProjectRoot()) {\n // Avoid scanning the entire monorepo root recursively\n projectFilesCache.set(projectDir, []);\n return [];\n }\n \n const extensions = ['.rs', '.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.c', '.cpp', '.cs', '.java', '.kt', '.swift', '.rb', '.php', '.lua'];\n for (const ext of extensions) {\n files.push(...listFilesRecursiveSafe(searchDir, ext));\n }\n const rootDir = getProjectRoot();\n files = files.map(f => path.relative(rootDir, f).replace(/\\\\/g, '/'));\n projectFilesCache.set(projectDir, files);\n }\n return files;\n}\n\nfunction inferSourcePathForComponent(comp: ComponentSpec, subsystems: any[]): string | null {\n try {\n const projectDir = resolveSubprojectForNamespace(comp.subsystem) || getProjectRoot();\n const files = getProjectFiles(projectDir);\n if (files.length === 0) return null;\n\n const compRelativeId = comp.id.split('::').pop() || comp.id;\n const subRelativeId = comp.subsystem.split('::').pop() || comp.subsystem;\n\n let cleanName = compRelativeId;\n if (cleanName.startsWith(`${subRelativeId}-`)) {\n cleanName = cleanName.slice(subRelativeId.length + 1);\n }\n\n const candidates = new Set<string>();\n candidates.add(cleanName.toLowerCase());\n candidates.add(cleanName.replace(/-/g, '_').toLowerCase());\n candidates.add(compRelativeId.toLowerCase());\n candidates.add(compRelativeId.replace(/-/g, '_').toLowerCase());\n candidates.add(comp.componentType.toLowerCase());\n\n let bestFile: string | null = null;\n let bestScore = -1;\n\n for (const f of files) {\n const ext = path.extname(f);\n const base = path.basename(f, ext).toLowerCase();\n if (candidates.has(base)) {\n let score = 0;\n const normalizedPath = f.toLowerCase();\n \n // Match directory to subsystem name or its segments\n const subPattern1 = `/${subRelativeId.toLowerCase()}/`;\n const subPattern2 = `/${subRelativeId.replace(/-/g, '_').toLowerCase()}/`;\n const hasSubsystemSegmentMatch = subRelativeId\n .split(/[-_]/)\n .some((seg: string) => seg.length >= 3 && normalizedPath.includes(`/${seg.toLowerCase()}/`));\n\n const hasSubsystemMatch = normalizedPath.includes(subPattern1) || \n normalizedPath.includes(subPattern2) || \n hasSubsystemSegmentMatch;\n\n if (hasSubsystemMatch) {\n score += 10;\n }\n\n // Deduct points or skip if file belongs to another subsystem folder\n let belongsToOtherSubsystem = false;\n for (const otherSub of subsystems) {\n if (otherSub.id === comp.subsystem) continue;\n const otherSubRelativeId = otherSub.id.split('::').pop() || otherSub.id;\n const otherPattern1 = `/${otherSubRelativeId.toLowerCase()}/`;\n const otherPattern2 = `/${otherSubRelativeId.replace(/-/g, '_').toLowerCase()}/`;\n const otherSegmentMatch = otherSubRelativeId\n .split(/[-_]/)\n .some((seg: string) => seg.length >= 3 && normalizedPath.includes(`/${seg.toLowerCase()}/`));\n\n if (normalizedPath.includes(otherPattern1) || \n normalizedPath.includes(otherPattern2) || \n otherSegmentMatch) {\n belongsToOtherSubsystem = true;\n break;\n }\n }\n if (belongsToOtherSubsystem) {\n continue; // Skip this file because it belongs to another subsystem\n }\n\n // Exact match of clean name\n const isCleanNameMatch = base === cleanName.toLowerCase() || base === cleanName.replace(/-/g, '_').toLowerCase();\n if (isCleanNameMatch) {\n score += 5;\n }\n\n // Exact match of component ID\n const isIdMatch = base === compRelativeId.toLowerCase() || base === compRelativeId.replace(/-/g, '_').toLowerCase();\n if (isIdMatch) {\n score += 3;\n }\n\n // A specific name match means it matches the clean name and that clean name is not just the generic component type\n const isSpecificNameMatch = isCleanNameMatch && cleanName.toLowerCase() !== comp.componentType.toLowerCase();\n\n // Reject matches that don't have any specific relation to the component or subsystem\n if (!hasSubsystemMatch && !isSpecificNameMatch && !isIdMatch) {\n continue;\n }\n\n // Under src or legacy-src folder\n if (normalizedPath.startsWith('src/') || normalizedPath.includes('/src/') ||\n normalizedPath.startsWith('legacy-src/') || normalizedPath.includes('/legacy-src/')) {\n score += 2;\n }\n\n // Match component type suffix\n if (base === comp.componentType.toLowerCase()) {\n score += 1;\n }\n\n if (score > bestScore) {\n bestScore = score;\n bestFile = f;\n }\n }\n }\n\n return bestFile;\n } catch {\n return null;\n }\n}\n\n/**\n * Compact one-line summary for agent descriptions. Descriptions are loaded\n * into EVERY session's agent list by the host tool — at scale (a hundred-plus\n * agents) an uncapped multi-sentence description per agent is a permanent\n * token tax. First sentence, hard-capped, single line.\n */\nfunction summarize(text: string, max = 140): string {\n const clean = text.replace(/\\s+/g, ' ').trim();\n const period = clean.indexOf('. ');\n const firstSentence = period > 0 ? clean.slice(0, period + 1) : clean;\n if (firstSentence.length <= max) return firstSentence;\n return `${firstSentence.slice(0, max - 1).trimEnd()}…`;\n}\n\n/**\n * Build the \"Component variants\" guidance block injected into an owner/implementer\n * agent for its variant-tagged components: each component's variant guidance plus\n * the same-variant siblings elsewhere in the project, so the implementer reuses one\n * shared approach. Empty when none of the given components declare a known variant.\n */\nfunction buildVariantGuidance(\n comps: ComponentSpec[],\n allComponents: ComponentSpec[],\n variantsById: Map<string, VariantDef>,\n): string {\n const tagged = comps.filter((c) => c.variant && variantsById.has(c.variant));\n if (tagged.length === 0) return '';\n const lines = [\n '## Component variants — reuse the shared approach',\n '',\n 'One or more of your components declare a variant — a base-anchored kind with implementation guidance. Implement every component of the same variant alike, reusing one shared approach instead of reinventing it per instance:',\n '',\n ];\n for (const c of tagged) {\n const v = variantsById.get(c.variant!)!;\n const siblings = allComponents.filter((o) => o.variant === c.variant && o.id !== c.id).map((o) => o.id);\n let line = `- **${c.id}** — variant \\`${c.variant}\\` (a kind of ${v.base}): ${v.guidance}`;\n if (siblings.length > 0) {\n line += ` Same-variant components elsewhere: ${siblings.join(', ')} — implement them consistently, reusing the same logic/concept.`;\n }\n lines.push(line);\n }\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Topology Resolver: Translates SDD Spec Tree into Agent Topology\n// ---------------------------------------------------------------------------\nexport function resolveAgentTopology(): AgentRecord[] {\n projectFilesCache.clear();\n\n const system = loadSystemSpec();\n if (!system) return [];\n\n // LAYERED topology: generate agents ONLY for THIS project's own layer. The\n // loader federates every chained subproject recursively (their specs carry a\n // `::` namespace prefix); those belong to the SUBPROJECT's layer, generated in\n // the subproject's own .wai. Here a chained subproject collapses to a single\n // delegating owner. A LOCAL spec id carries no `::` prefix. This keeps each\n // .claude/agents/ (and the context every session loads) proportional to one\n // layer, not the whole deep tree.\n const isLocal = (id: string): boolean => !id.includes('::');\n const subsystems = loadSubsystemSpecs().filter((s) => isLocal(s.id));\n const components = loadComponentSpecs().filter((c) => isLocal(c.id) && isLocal(c.subsystem));\n const interfaces = loadInterfaceSpecs();\n const implementations = loadImplementationSpecs();\n // Component-variant registry (dynamic layer on top of packs) — resolved here so\n // each owner/implementer carries its variant-tagged components' guidance + siblings.\n const variantsById = new Map(loadProjectVariants().map((v) => [v.id, v]));\n\n const config = loadProjectConfig();\n const activeTargets = config.targets\n .filter((t) => !('enabled' in t) || t.enabled)\n .map((t) => typeof t === 'string' ? t : t.type) as AgentRecord['targets'];\n\n const agents: AgentRecord[] = [];\n\n // 1. Global System Architect\n agents.push({\n id: 'system-architect',\n name: `${system.name} Architect`,\n description: `Global architect for ${system.name} — owns the spec tree and topology. ${summarize(system.vision)}`,\n template: 'architect',\n creationReason: 'Automatically inferred from L0 system spec',\n ownedPaths: ['.wai/specs/**'],\n readPaths: ['**'],\n writePaths: ['.wai/specs/**'],\n tags: ['architect', 'global', 'sdd'],\n dependencies: subsystems.map((s) => `${s.id}-owner`),\n status: 'active',\n targets: activeTargets,\n createdAt: system.createdAt,\n updatedAt: system.updatedAt,\n });\n\n // 2. Subsystem Owners (Domain Owners)\n for (const sub of subsystems) {\n // A chained subproject collapses to ONE delegating owner: it owns only the\n // parent-side mount spec and points work DOWN into the subproject, whose own\n // detailed agents are generated in that subproject's .wai (one layer deeper).\n // It never enumerates the child's internals here — that is the whole point of\n // stacking agents per layer instead of flattening the tree at the top.\n if (sub.projectPath) {\n const mountSpecPath = path.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\\\/g, '/');\n agents.push({\n id: `${sub.id}-owner`,\n name: `${sub.name} (chained subproject)`,\n description: `Delegates into the \"${sub.id}\" chained subproject at ${sub.projectPath}. Its own agents live in that subproject's .wai — run \\`wairon generate\\` there (or spawn from ${sub.projectPath}/.claude/agents). Do not implement its internals from this layer.`,\n template: 'domain-owner',\n creationReason: `Automatically inferred from a chained subproject subsystem: ${sub.id}`,\n domainRoot: sub.id,\n ownedPaths: [mountSpecPath],\n readPaths: ['**'],\n writePaths: [mountSpecPath],\n tags: ['owner', 'subproject', 'delegate', 'sdd'],\n dependencies: [],\n status: 'active',\n targets: activeTargets,\n createdAt: sub.createdAt,\n updatedAt: sub.updatedAt,\n });\n continue;\n }\n\n const subComponents = components.filter((c) => c.subsystem === sub.id);\n\n const ownedPaths: string[] = [];\n // Subsystem Owners own subsystem specification and component specifications under their domain\n ownedPaths.push(path.relative(getProjectRoot(), getSubsystemPath(sub.id)).replace(/\\\\/g, '/'));\n for (const c of subComponents) {\n ownedPaths.push(path.relative(getProjectRoot(), getComponentPath(c.id, sub.id)).replace(/\\\\/g, '/'));\n }\n\n if (!config.rules.generateComponentImplementers) {\n // Aggregate all component implementation source paths under the subsystem owner.\n // Several spec-level roles may be realized in one shared module, so dedupe —\n // an owner claiming the same path twice would trip OVERLAPPING_OWNERSHIP.\n for (const comp of subComponents) {\n // Find contract interfaces for this component\n const compInterfaces = interfaces.filter((i) => i.component === comp.id);\n const compInterfaceIds = compInterfaces.map((i) => i.id);\n\n // Find implementations of those contracts\n const compImpls = implementations.filter((impl) => compInterfaceIds.includes(impl.contract));\n\n let hasExplicitSource = false;\n for (const impl of compImpls) {\n if (impl.sourcePath) {\n hasExplicitSource = true;\n if (!ownedPaths.includes(impl.sourcePath)) ownedPaths.push(impl.sourcePath);\n }\n }\n\n // Inference is a FALLBACK for components whose implementations declare\n // no sourcePath. Running it on implemented components lets a filename\n // that matches the component TYPE claim a foreign file — e.g. a\n // Repository facade realized in specs.ts inferring rules/repository.ts\n // owned by another subsystem — tripping OVERLAPPING_OWNERSHIP.\n if (!hasExplicitSource) {\n const inferred = inferSourcePathForComponent(comp, subsystems);\n if (inferred && !ownedPaths.includes(inferred)) {\n ownedPaths.push(inferred);\n }\n }\n }\n }\n\n let dependencies: string[] = [];\n if (config.rules.generateComponentImplementers) {\n dependencies = subComponents.map((c) => `${c.id}-implementer`);\n } else {\n // Subsystem depends on other subsystem owners that its components depend on\n const depSubsystems = new Set<string>();\n for (const c of subComponents) {\n for (const depId of c.dependsOn) {\n const depComp = components.find((other) => other.id === depId);\n if (depComp && depComp.subsystem !== sub.id) {\n depSubsystems.add(`${depComp.subsystem}-owner`);\n }\n }\n }\n dependencies = Array.from(depSubsystems);\n }\n\n agents.push({\n id: `${sub.id}-owner`,\n name: `${sub.name} Owner`,\n description: `Owns the ${sub.id} subsystem. ${summarize(sub.description)}`,\n template: 'domain-owner',\n creationReason: `Automatically inferred from L1 subsystem spec: ${sub.id}`,\n domainRoot: sub.id,\n ownedPaths,\n readPaths: ['**'],\n writePaths: ownedPaths,\n tags: ['owner', 'domain', 'sdd'],\n dependencies,\n variantGuidance: buildVariantGuidance(subComponents, components, variantsById),\n status: 'active',\n targets: activeTargets,\n createdAt: sub.createdAt,\n updatedAt: sub.updatedAt,\n });\n }\n\n // 3. Component Implementers\n if (config.rules.generateComponentImplementers) {\n for (const comp of components) {\n // Find contract interfaces for this component\n const compInterfaces = interfaces.filter((i) => i.component === comp.id);\n const compInterfaceIds = compInterfaces.map((i) => i.id);\n\n // Find implementations of those contracts\n const compImpls = implementations.filter((impl) => compInterfaceIds.includes(impl.contract));\n\n const ownedPaths: string[] = [];\n for (const impl of compImpls) {\n if (impl.sourcePath) ownedPaths.push(impl.sourcePath);\n }\n\n if (ownedPaths.length === 0) {\n const inferred = inferSourcePathForComponent(comp, subsystems);\n if (inferred) {\n ownedPaths.push(inferred);\n }\n }\n\n const dependencies = comp.dependsOn.map((depId) => `${depId}-implementer`);\n\n // An implementer needs to read specs, interfaces, and direct dependency component files\n const readPaths = [\n path.relative(getProjectRoot(), AI_PATHS.specsSystem()).replace(/\\\\/g, '/'),\n path.relative(getProjectRoot(), getComponentPath(comp.id, comp.subsystem)).replace(/\\\\/g, '/'),\n ...compInterfaces.map((i) => path.relative(getProjectRoot(), getInterfacePath(i.id, comp.id)).replace(/\\\\/g, '/')),\n ...compImpls.map((impl) => path.relative(getProjectRoot(), getImplementationPath(impl.id, impl.contract)).replace(/\\\\/g, '/')),\n ];\n\n agents.push({\n id: `${comp.id}-implementer`,\n name: `${comp.name} Implementer`,\n description: `Developer agent implementing ${comp.name} (${comp.componentType})`,\n template: 'implementer',\n creationReason: `Automatically inferred from L2 component spec: ${comp.id}`,\n domainRoot: comp.subsystem,\n ownedPaths,\n readPaths,\n writePaths: ownedPaths,\n tags: ['implementer', 'component', 'sdd', comp.componentType.toLowerCase()],\n dependencies,\n variantGuidance: buildVariantGuidance([comp], components, variantsById),\n status: 'active',\n targets: activeTargets,\n createdAt: comp.createdAt,\n updatedAt: comp.updatedAt,\n });\n }\n }\n\n\n // 4. Free-standing domain owners (declared in .wai/topology.yaml)\n const now = new Date().toISOString();\n for (const dom of loadTopologyConfig().domains) {\n agents.push({\n id: `${dom.id}-owner`,\n name: `${dom.name ?? dom.id} Owner`,\n description: dom.description ? summarize(dom.description) : `Owner agent for the free-standing \"${dom.id}\" domain.`,\n template: 'domain-owner',\n creationReason: 'Inferred from a free-standing domain in .wai/topology.yaml',\n domainRoot: dom.id,\n ownedPaths: dom.ownedPaths,\n readPaths: ['**'],\n writePaths: dom.ownedPaths,\n tags: ['owner', 'domain'],\n dependencies: [],\n status: 'active',\n targets: activeTargets,\n createdAt: now,\n updatedAt: now,\n });\n }\n\n return agents;\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { pathExists, getProjectRoot } from '../utils/fs.js';\nimport { readYamlFile, writeYamlFile } from '../utils/yaml.js';\nimport { ProjectNotInitializedError, WaironError } from '../utils/errors.js';\nimport {\n ProjectConfig,\n ProjectConfigSchema,\n Registry,\n createEmptyRegistry,\n TopologyConfig,\n TopologyConfigSchema,\n createEmptyTopologyConfig,\n} from '../models/index.js';\n\n// ---------------------------------------------------------------------------\n// Paths within the .wai/ directory\n// ---------------------------------------------------------------------------\n\nexport interface WaiPaths {\n root: () => string;\n projectConfig: () => string;\n topologyConfig: () => string;\n templatesDir: () => string;\n rulesDir: () => string;\n docsDir: () => string;\n generatedDir: () => string;\n contextDir: () => string;\n contextProjectMd: () => string;\n contextArchitectureMd: () => string;\n contextDomainsMd: () => string;\n contextWaironGuideMd: () => string;\n specsDir: () => string;\n specsSystem: () => string;\n specsSubsystemsDir: () => string;\n specsComponentsDir: () => string;\n specsInterfacesDir: () => string;\n specsImplementationsDir: () => string;\n specsTypesDir: () => string;\n}\n\n/**\n * Build the .wai path accessors for an EXPLICIT project root. This is what the\n * spec workspace uses so nested subproject resolution never has to override the\n * global project root. AI_PATHS below stays the implicit-root convenience view.\n */\nexport function aiPathsAt(rootDir: string): WaiPaths {\n const resolvedRoot = path.resolve(rootDir);\n // .wai/ is primary; .wairon/ is the legacy fallback for older installs.\n const aiDirAt = (...segments: string[]): string => {\n const waiPath = path.join(resolvedRoot, '.wai');\n const waironPath = path.join(resolvedRoot, '.wairon');\n const base = !fs.existsSync(waiPath) && fs.existsSync(waironPath) ? waironPath : waiPath;\n return path.join(base, ...segments);\n };\n const specsDir = (): string => {\n try {\n const projConfig = aiDirAt('project.yaml');\n if (pathExists(projConfig)) {\n const raw = readYamlFile(projConfig) as any;\n if (raw && raw.paths && raw.paths.specsDir) {\n return path.resolve(resolvedRoot, raw.paths.specsDir);\n }\n }\n } catch {\n // ignore and fallback\n }\n return aiDirAt('specs');\n };\n return {\n root: () => aiDirAt(),\n projectConfig: () => aiDirAt('project.yaml'),\n topologyConfig: () => aiDirAt('topology.yaml'),\n templatesDir: () => aiDirAt('templates'),\n rulesDir: () => aiDirAt('rules'),\n docsDir: () => aiDirAt('docs'),\n generatedDir: () => aiDirAt('generated'),\n contextDir: () => aiDirAt('context'),\n contextProjectMd: () => aiDirAt('context', 'project.md'),\n contextArchitectureMd: () => aiDirAt('context', 'architecture.md'),\n contextDomainsMd: () => aiDirAt('context', 'domains.md'),\n contextWaironGuideMd: () => aiDirAt('context', 'wairon-guide.md'),\n specsDir,\n specsSystem: () => path.join(specsDir(), '.index.yaml'),\n specsSubsystemsDir: () => path.join(specsDir(), 'subsystems'),\n specsComponentsDir: () => path.join(specsDir(), 'components'),\n specsInterfacesDir: () => path.join(specsDir(), 'interfaces'),\n specsImplementationsDir: () => path.join(specsDir(), 'implementations'),\n specsTypesDir: () => path.join(specsDir(), 'types'),\n };\n}\n\n/** Path accessors for the CURRENT project root (override, else resolved cwd). */\nexport const AI_PATHS: WaiPaths = {\n root: () => aiPathsAt(getProjectRoot()).root(),\n projectConfig: () => aiPathsAt(getProjectRoot()).projectConfig(),\n topologyConfig: () => aiPathsAt(getProjectRoot()).topologyConfig(),\n templatesDir: () => aiPathsAt(getProjectRoot()).templatesDir(),\n rulesDir: () => aiPathsAt(getProjectRoot()).rulesDir(),\n docsDir: () => aiPathsAt(getProjectRoot()).docsDir(),\n generatedDir: () => aiPathsAt(getProjectRoot()).generatedDir(),\n contextDir: () => aiPathsAt(getProjectRoot()).contextDir(),\n contextProjectMd: () => aiPathsAt(getProjectRoot()).contextProjectMd(),\n contextArchitectureMd: () => aiPathsAt(getProjectRoot()).contextArchitectureMd(),\n contextDomainsMd: () => aiPathsAt(getProjectRoot()).contextDomainsMd(),\n contextWaironGuideMd: () => aiPathsAt(getProjectRoot()).contextWaironGuideMd(),\n specsDir: () => aiPathsAt(getProjectRoot()).specsDir(),\n specsSystem: () => aiPathsAt(getProjectRoot()).specsSystem(),\n specsSubsystemsDir: () => aiPathsAt(getProjectRoot()).specsSubsystemsDir(),\n specsComponentsDir: () => aiPathsAt(getProjectRoot()).specsComponentsDir(),\n specsInterfacesDir: () => aiPathsAt(getProjectRoot()).specsInterfacesDir(),\n specsImplementationsDir: () => aiPathsAt(getProjectRoot()).specsImplementationsDir(),\n specsTypesDir: () => aiPathsAt(getProjectRoot()).specsTypesDir(),\n};\n\n// ---------------------------------------------------------------------------\n// Project config\n// ---------------------------------------------------------------------------\n\n/**\n * Check whether the current directory has been initialized as a wairon project.\n */\nexport function isProjectInitialized(): boolean {\n return pathExists(AI_PATHS.root()) && pathExists(AI_PATHS.projectConfig());\n}\n\n/**\n * Assert the project has been initialized, throwing a clear error if not.\n */\nexport function assertProjectInitialized(): void {\n if (!isProjectInitialized()) {\n throw new ProjectNotInitializedError();\n }\n}\n\n/**\n * Load and validate the project config from .wai/project.yaml.\n */\nexport function loadProjectConfig(): ProjectConfig {\n assertProjectInitialized();\n const raw = readYamlFile(AI_PATHS.projectConfig());\n try {\n return ProjectConfigSchema.parse(raw);\n } catch (e: unknown) {\n throw new WaironError(`Invalid .wai/project.yaml: ${e instanceof Error ? e.message : String(e)}`);\n }\n}\n\n/**\n * Write the project config to .wai/project.yaml.\n */\nexport function saveProjectConfig(config: ProjectConfig): void {\n writeYamlFile(AI_PATHS.projectConfig(), config);\n}\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the agent registry. The SDD spec tree (.wai/specs/) is the single\n * source of truth for agents — the topology is always derived from it via\n * resolveAgentTopology(), never read from a hand-maintained agents.json.\n * Returns an empty registry when no system spec exists yet.\n */\nexport function loadRegistry(): Registry {\n assertProjectInitialized();\n if (!pathExists(AI_PATHS.specsSystem())) return createEmptyRegistry();\n const { resolveAgentTopology } = require('../core/agent_resolver.js') as typeof import('../core/agent_resolver.js');\n return {\n schemaVersion: '1.0.0',\n agents: resolveAgentTopology(),\n updatedAt: new Date().toISOString(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// Topology config (free-standing domains) — .wai/topology.yaml\n//\n// Spec-backed domains are derived from the spec tree at read time and are NOT\n// stored here. This file holds only free-standing (cross-cutting) domains.\n// ---------------------------------------------------------------------------\n\nexport function loadTopologyConfig(): TopologyConfig {\n assertProjectInitialized();\n if (!pathExists(AI_PATHS.topologyConfig())) return createEmptyTopologyConfig();\n const raw = readYamlFile(AI_PATHS.topologyConfig());\n if (!raw) return createEmptyTopologyConfig();\n return TopologyConfigSchema.parse(raw);\n}\n\nexport function saveTopologyConfig(config: TopologyConfig): void {\n writeYamlFile(AI_PATHS.topologyConfig(), config);\n}\n","import * as path from 'path';\nimport { Domain } from '../models/domain.js';\nimport { loadTopologyConfig, saveTopologyConfig } from '../config/loader.js';\nimport {\n loadSubsystemSpecs,\n loadComponentSpecs,\n getSubsystemPath,\n getComponentPath,\n} from './specs.js';\nimport { WaironError } from '../utils/errors.js';\n\n// ---------------------------------------------------------------------------\n// Domain resolution\n//\n// A domain is a unit of agent ownership. Domains come from two sources:\n// - Spec-backed: derived 1:1 from L1 subsystems (boundTo = subsystem id).\n// - Free-standing: declared in .wai/topology.yaml for cross-cutting scopes.\n//\n// resolveDomains() returns both. Only free-standing domains are mutable.\n// ---------------------------------------------------------------------------\n\nfunction rel(p: string): string {\n return path.relative(process.cwd(), p).replace(/\\\\/g, '/');\n}\n\n/** Domains derived from L1 subsystems (spec-backed). */\nexport function deriveSubsystemDomains(): Domain[] {\n const subsystems = loadSubsystemSpecs();\n const components = loadComponentSpecs();\n\n return subsystems.map((sub) => {\n const ownedPaths = [\n rel(getSubsystemPath(sub.id)),\n ...components\n .filter((c) => c.subsystem === sub.id)\n .map((c) => rel(getComponentPath(c.id, sub.id))),\n ];\n return {\n id: sub.id,\n name: sub.name,\n description: sub.description,\n boundTo: sub.id,\n ownedPaths,\n };\n });\n}\n\n/** Free-standing domains declared in .wai/topology.yaml. */\nexport function listFreeStandingDomains(): Domain[] {\n return loadTopologyConfig().domains;\n}\n\n/** All domains: spec-backed (derived) + free-standing. */\nexport function resolveDomains(): Domain[] {\n return [...deriveSubsystemDomains(), ...listFreeStandingDomains()];\n}\n\nexport function findDomain(id: string): Domain | undefined {\n return resolveDomains().find((d) => d.id === id);\n}\n\n// ---------------------------------------------------------------------------\n// Free-standing domain mutation (the only authored part of the topology)\n// ---------------------------------------------------------------------------\n\nexport function addFreeStandingDomain(domain: Domain): void {\n const config = loadTopologyConfig();\n if (config.domains.some((d) => d.id === domain.id)) {\n throw new WaironError(`A free-standing domain \"${domain.id}\" already exists in .wai/topology.yaml.`);\n }\n if (deriveSubsystemDomains().some((d) => d.id === domain.id)) {\n throw new WaironError(`Domain id \"${domain.id}\" collides with a subsystem-derived domain.`);\n }\n config.domains.push(domain);\n saveTopologyConfig(config);\n}\n\nexport function removeFreeStandingDomain(id: string): void {\n const config = loadTopologyConfig();\n const idx = config.domains.findIndex((d) => d.id === id);\n if (idx === -1) {\n throw new WaironError(\n `\"${id}\" is not a free-standing domain. Subsystem-backed domains are derived from the spec tree and cannot be removed here.`,\n );\n }\n config.domains.splice(idx, 1);\n saveTopologyConfig(config);\n}\n","// ---------------------------------------------------------------------------\n// wairon public library API\n//\n// This module exports the core primitives so wairon can be used\n// programmatically by other tools or scripts — without going through the CLI.\n// This is the foundation for a future MCP server wrapper.\n// ---------------------------------------------------------------------------\n\nexport * from './models/index.js';\nexport * from './config/index.js';\nexport * from './core/index.js';\nexport * from './exporters/index.js';\nexport * from './utils/index.js';\n","import * as os from 'os';\nimport * as path from 'path';\nimport { BuiltinTargetConfig } from '../models/project.js';\n\n// ---------------------------------------------------------------------------\n// Default output directory locations for each supported target\n//\n// These match the conventional directories used by each tool.\n// Users can override these in project.yaml.\n// ---------------------------------------------------------------------------\n\nexport const DEFAULT_TARGET_DIRS: Record<string, string> = {\n claude: '.claude/agents',\n gemini: '.gemini/agents',\n agy: '.gemini/agents',\n cursor: '.cursor/rules',\n copilot: '.github/prompts',\n codex: '.codex/agents',\n};\n\nexport function defaultTargetConfig(type: 'claude' | 'gemini' | 'agy' | 'cursor' | 'copilot' | 'codex'): BuiltinTargetConfig {\n return {\n type,\n outputDir: DEFAULT_TARGET_DIRS[type],\n enabled: true,\n };\n}\n\n// ---------------------------------------------------------------------------\n// waffle-airon CLI version embedded at build time\n// ---------------------------------------------------------------------------\n\nexport const WAIRON_VERSION = '5.0.1-dev.4';\n\n// ---------------------------------------------------------------------------\n// GitHub repository (owner/repo) — used by the update command\n// ---------------------------------------------------------------------------\n\nexport const GITHUB_REPO = 'SYW-Apps/Waffle-AIron';\n\n// ---------------------------------------------------------------------------\n// The name of the architect agent created during init\n// ---------------------------------------------------------------------------\n\nexport const ARCHITECT_AGENT_ID = 'agent-architect';\nexport const ARCHITECT_TEMPLATE_ID = 'architect';\n\n// ---------------------------------------------------------------------------\n// Global templates directory\n//\n// Resolution order for templates:\n// 1. Project-local: .wai/templates/<id>.yaml\n// 2. Global user/org: WAIRON_TEMPLATES_DIR or globalTemplatesDir in project.yaml\n// or ~/.wairon/templates/<id>.yaml\n// 3. Built-in: <package>/dist/templates/<id>.yaml\n// ---------------------------------------------------------------------------\n\nexport function globalTemplatesDir(projectOverride?: string): string {\n // 1. Environment variable\n if (process.env.WAIRON_TEMPLATES_DIR) {\n return process.env.WAIRON_TEMPLATES_DIR;\n }\n // 2. Project config override\n if (projectOverride) {\n return projectOverride;\n }\n // 3. Default ~/.wairon/templates\n return path.join(os.homedir(), '.wairon', 'templates');\n}\n\n// ---------------------------------------------------------------------------\n// Backend CLI commands\n// Maps backend names to the shell command used to spawn them.\n// ---------------------------------------------------------------------------\n\nexport const BACKEND_COMMANDS: Record<string, string> = {\n claude: 'claude',\n gemini: 'gemini',\n};\n\nexport function backendCommand(backend: string): string {\n return BACKEND_COMMANDS[backend] ?? backend;\n}\n\n// ---------------------------------------------------------------------------\n// Command aliases\n//\n// SUPPORTED_ALIASES — every short name wairon can be reached under.\n// These are registered in package.json `bin` for npm installs, and created\n// as symlinks / .cmd wrappers for binary installs.\n// Users can disable any alias via `wairon aliases disable <name>`.\n// ---------------------------------------------------------------------------\n\nexport const SUPPORTED_ALIASES = ['wai'] as const;\nexport type SupportedAlias = (typeof SUPPORTED_ALIASES)[number];\n\n// ---------------------------------------------------------------------------\n// Directories to exclude from domain detection scanning\n// ---------------------------------------------------------------------------\n\nexport const SCAN_EXCLUDE_DIRS = new Set([\n 'node_modules',\n 'dist',\n 'build',\n 'out',\n '.git',\n '.cache',\n 'coverage',\n '__pycache__',\n '.venv',\n 'venv',\n 'target', // Rust\n 'vendor',\n]);\n","export * from './defaults.js';\nexport * from './loader.js';\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { DetectedDomainCandidate, DomainType } from '../models/domain.js';\nimport { SCAN_EXCLUDE_DIRS } from '../config/defaults.js';\n\n// ---------------------------------------------------------------------------\n// Domain detection\n//\n// Scans the project for directories that are good candidates for agent\n// domains. Three detection strategies:\n//\n// 1. Git submodules — parsed from .gitmodules (most reliable signal)\n// 2. Nested .git repos — directories containing their own .git folder\n// 3. Package roots — directories with package.json / pyproject.toml / etc.\n//\n// All results are candidates only. The user confirms which to include.\n// ---------------------------------------------------------------------------\n\nconst PACKAGE_MARKERS = [\n 'package.json',\n 'pyproject.toml',\n 'Cargo.toml',\n 'go.mod',\n 'build.gradle',\n 'build.gradle.kts',\n 'pom.xml',\n];\n\nconst MAX_SCAN_DEPTH = 5;\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Scan a project root and return all domain candidates.\n * Already-tracked domain paths are marked with alreadyTracked: true.\n *\n * De-duplication rules applied after detection:\n * - package-root entries whose path is inside a git-submodule or git-repo\n * are suppressed (the submodule already represents that boundary)\n * - candidates with conflicting suggestedIds get their parent path segment\n * prepended to produce a unique id (e.g. shared → packages-shared)\n */\nexport function detectDomainCandidates(\n projectRoot: string,\n alreadyTrackedPaths: Set<string> = new Set(),\n alreadyTrackedIds: Set<string> = new Set(),\n): DetectedDomainCandidate[] {\n const candidates = new Map<string, DetectedDomainCandidate>();\n\n // 1. Git submodules (highest confidence)\n for (const c of detectGitSubmodules(projectRoot)) {\n candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });\n }\n\n // 2. Nested git repos (catches non-declared submodules)\n for (const c of detectNestedGitRepos(projectRoot)) {\n if (!candidates.has(c.path)) {\n candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });\n }\n }\n\n // 3. Package roots — but skip any that live inside a git-submodule / git-repo\n const gitPaths = new Set(\n Array.from(candidates.values())\n .filter((c) => c.type === 'git-submodule' || c.type === 'git-repo')\n .map((c) => c.path),\n );\n\n for (const c of detectPackageRoots(projectRoot)) {\n if (candidates.has(c.path)) continue;\n // Suppress if the package root is inside any git boundary\n const insideGit = Array.from(gitPaths).some(\n (gp) => c.path === gp || c.path.startsWith(gp + '/'),\n );\n if (insideGit) continue;\n candidates.set(c.path, { ...c, alreadyTracked: alreadyTrackedPaths.has(c.path) });\n }\n\n const sorted = Array.from(candidates.values()).sort((a, b) => a.path.localeCompare(b.path));\n\n // Resolve duplicate suggestedIds — also counting ids already claimed in the registry\n return deduplicateIds(sorted, alreadyTrackedIds);\n}\n\n/**\n * If two candidates share the same suggestedId, qualify each with its parent\n * directory segment (e.g. \"shared\" in packages/ vs services/ → \"packages-shared\"\n * and \"services-shared\").\n */\nfunction deduplicateIds(\n candidates: DetectedDomainCandidate[],\n existingIds: Set<string> = new Set(),\n): DetectedDomainCandidate[] {\n const idCount = new Map<string, number>();\n // Pre-seed counts with ids already claimed in the registry so that a single\n // new candidate whose basename matches an existing domain still gets qualified.\n for (const id of existingIds) {\n idCount.set(id, (idCount.get(id) ?? 0) + 1);\n }\n for (const c of candidates) {\n idCount.set(c.suggestedId, (idCount.get(c.suggestedId) ?? 0) + 1);\n }\n\n return candidates.map((c) => {\n if ((idCount.get(c.suggestedId) ?? 0) <= 1) return c;\n // Qualify with parent segment\n const parts = c.path.split('/');\n const qualifiedId = parts.length >= 2\n ? pathToId(`${parts[parts.length - 2]}-${parts[parts.length - 1]}`)\n : c.suggestedId;\n return { ...c, suggestedId: qualifiedId };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Strategy 1: Git submodules\n// ---------------------------------------------------------------------------\n\ninterface GitSubmoduleEntry {\n name: string;\n path: string;\n url: string;\n}\n\nfunction parseGitmodules(filePath: string): GitSubmoduleEntry[] {\n const content = fs.readFileSync(filePath, 'utf-8');\n const entries: GitSubmoduleEntry[] = [];\n let current: Partial<GitSubmoduleEntry> = {};\n\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n\n const headerMatch = trimmed.match(/^\\[submodule \"(.+)\"\\]$/);\n if (headerMatch) {\n if (current.path) entries.push(current as GitSubmoduleEntry);\n current = { name: headerMatch[1] };\n continue;\n }\n\n const keyVal = trimmed.match(/^(\\w+)\\s*=\\s*(.+)$/);\n if (keyVal) {\n const [, key, value] = keyVal;\n if (key === 'path') current.path = value.trim();\n if (key === 'url') current.url = value.trim();\n }\n }\n\n if (current.path) entries.push(current as GitSubmoduleEntry);\n return entries;\n}\n\nfunction detectGitSubmodules(projectRoot: string): DetectedDomainCandidate[] {\n const gitmodulesPath = path.join(projectRoot, '.gitmodules');\n if (!fs.existsSync(gitmodulesPath)) return [];\n\n return parseGitmodules(gitmodulesPath).map((entry) => ({\n suggestedId: pathToId(entry.path),\n suggestedName: pathToName(entry.path),\n path: normalizePath(entry.path),\n type: 'git-submodule' as DomainType,\n alreadyTracked: false,\n }));\n}\n\n// ---------------------------------------------------------------------------\n// Strategy 2: Nested .git repos\n// ---------------------------------------------------------------------------\n\nfunction detectNestedGitRepos(projectRoot: string): DetectedDomainCandidate[] {\n const results: DetectedDomainCandidate[] = [];\n walkForGit(projectRoot, projectRoot, 0, results);\n return results;\n}\n\nfunction walkForGit(\n projectRoot: string,\n currentDir: string,\n depth: number,\n results: DetectedDomainCandidate[],\n): void {\n if (depth > MAX_SCAN_DEPTH) return;\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(currentDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;\n\n const fullPath = path.join(currentDir, entry.name);\n const relPath = normalizePath(path.relative(projectRoot, fullPath));\n\n // Skip the project root itself\n if (relPath === '' || relPath === '.') continue;\n\n const gitPath = path.join(fullPath, '.git');\n if (fs.existsSync(gitPath)) {\n results.push({\n suggestedId: pathToId(relPath),\n suggestedName: pathToName(relPath),\n path: relPath,\n type: 'git-repo',\n alreadyTracked: false,\n });\n // Don't recurse into detected git repos — their internals are their own\n continue;\n }\n\n walkForGit(projectRoot, fullPath, depth + 1, results);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Strategy 3: Package roots\n// ---------------------------------------------------------------------------\n\nfunction detectPackageRoots(projectRoot: string): DetectedDomainCandidate[] {\n const results: DetectedDomainCandidate[] = [];\n walkForPackages(projectRoot, projectRoot, 0, results);\n return results;\n}\n\nfunction walkForPackages(\n projectRoot: string,\n currentDir: string,\n depth: number,\n results: DetectedDomainCandidate[],\n): void {\n if (depth > MAX_SCAN_DEPTH) return;\n\n let entries: fs.Dirent[];\n try {\n entries = fs.readdirSync(currentDir, { withFileTypes: true });\n } catch {\n return;\n }\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (SCAN_EXCLUDE_DIRS.has(entry.name)) continue;\n\n const fullPath = path.join(currentDir, entry.name);\n const relPath = normalizePath(path.relative(projectRoot, fullPath));\n if (relPath === '' || relPath === '.') continue;\n\n const hasMarker = PACKAGE_MARKERS.some((m) => fs.existsSync(path.join(fullPath, m)));\n if (hasMarker) {\n results.push({\n suggestedId: pathToId(relPath),\n suggestedName: pathToName(relPath),\n path: relPath,\n type: 'package-root',\n alreadyTracked: false,\n });\n }\n\n walkForPackages(projectRoot, fullPath, depth + 1, results);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/** Convert a relative path to a domain id: \"services/core-service\" → \"core-service\" */\nfunction pathToId(relPath: string): string {\n const basename = path.basename(relPath);\n return basename\n .toLowerCase()\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\n/** Convert a relative path to a display name: \"services/core-service\" → \"Core Service\" */\nfunction pathToName(relPath: string): string {\n const id = pathToId(relPath);\n return id\n .split('-')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\n/** Normalize path separators to forward slashes */\nfunction normalizePath(p: string): string {\n return p.replace(/\\\\/g, '/');\n}\n","export * from './detection.js';\nexport * from './domains.js';\nexport * from './templates.js';\nexport * from './validation.js';\nexport * from './extensions.js';\nexport * from './variants.js';\nexport * from './rules/index.js';\nexport * from './specs.js';\nexport * from './provision.js';\nexport * from './diagram.js';\nexport * from './lockfile.js';\nexport * from './statehash.js';\nexport * from './agent_resolver.js';\nexport * from './skills.js';\nexport * from './context.js';\nexport * from './surfaces.js';\nexport * from './openapi.js';\n","import * as path from 'path';\nimport { listFiles, pathExists } from '../utils/fs.js';\nimport { parseYaml, readYamlFile } from '../utils/yaml.js';\nimport { TemplateNotFoundError } from '../utils/errors.js';\nimport { Template, TemplateSchema } from '../models/template.js';\nimport { AI_PATHS } from '../config/loader.js';\nimport { globalTemplatesDir as resolveGlobalDir } from '../config/defaults.js';\n\n// ---------------------------------------------------------------------------\n// Template loader\n//\n// Three-tier resolution order (first match wins):\n// 1. Project-local: .wai/templates/<id>.yaml\n// 2. Global user/org: WAIRON_TEMPLATES_DIR | ~/.wairon/templates/<id>.yaml\n// 3. Built-in: <package>/dist/templates/<id>.yaml\n//\n// This lets organizations ship their own default templates (tier 2) while\n// still allowing per-project overrides (tier 1).\n// ---------------------------------------------------------------------------\n\nfunction builtinTemplatesDir(): string {\n return path.resolve(__dirname, '..', 'templates');\n}\n\n/**\n * Load a single template by id.\n * Throws TemplateNotFoundError if not found in any tier.\n *\n * @param globalOverride - optional path from project config (globalTemplatesDir field)\n */\nexport function loadTemplate(id: string, globalOverride?: string): Template {\n const dirs = templateSearchDirs(globalOverride);\n for (const dir of dirs) {\n const filePath = path.join(dir, `${id}.yaml`);\n if (pathExists(filePath)) {\n const raw = readYamlFile(filePath);\n return TemplateSchema.parse(raw);\n }\n }\n throw new TemplateNotFoundError(id);\n}\n\n/**\n * List all available template ids across all tiers, deduplicated.\n * Earlier tiers shadow later ones.\n */\nexport function listTemplateIds(globalOverride?: string): string[] {\n const seen = new Set<string>();\n for (const dir of templateSearchDirs(globalOverride)) {\n for (const file of listFiles(dir, '.yaml')) {\n seen.add(path.basename(file, '.yaml'));\n }\n }\n return Array.from(seen).sort();\n}\n\n/**\n * Return the ordered list of directories to search for templates.\n */\nfunction templateSearchDirs(globalOverride?: string): string[] {\n return [\n AI_PATHS.templatesDir(), // 1. project-local\n resolveGlobalDir(globalOverride), // 2. global user/org\n builtinTemplatesDir(), // 3. built-in fallback\n ];\n}\n\n/**\n * Render a template's instruction body by substituting {{variable}} placeholders.\n */\nexport function renderTemplateInstructions(\n template: Template,\n vars: Record<string, string>,\n): string {\n return template.instructions.replace(/\\{\\{(\\w+)\\}\\}/g, (_match, key: string) => {\n return key in vars ? vars[key] : `{{${key}}}`;\n });\n}\n\n/**\n * Parse a template from a raw YAML string (used for testing / one-off loading).\n */\nexport function parseTemplate(yamlContent: string): Template {\n return TemplateSchema.parse(parseYaml(yamlContent));\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport {\n saveSystemSpec,\n saveSubsystemSpec,\n loadSubsystemSpec,\n loadSubsystemSpecs,\n loadSystemSpec,\n loadComponentSpecs,\n loadInterfaceSpecs,\n loadTypeSpecs,\n collectPromotableSpecs,\n applySpecStatus,\n invalidateSpecCache,\n assertContainedProjectPath,\n} from './specs.js';\nimport { saveProjectConfig, aiPathsAt } from '../config/loader.js';\nimport { getProjectRoot, runWithProjectRoot, ensureDir, listFilesRecursive } from '../utils/fs.js';\nimport { readYamlFile, writeYamlFile } from '../utils/yaml.js';\nimport { WaironError } from '../utils/errors.js';\nimport type { ProjectConfig } from '../models/project.js';\nimport type { SubsystemSpec } from '../models/index.js';\n\n// ---------------------------------------------------------------------------\n// Project provisioning + bulk status promotion (sdd_core, used by sdd_host)\n//\n// provisionProject bootstraps a fresh isolated project at the currently-bound\n// root: a default project.yaml plus an L0 system spec. promoteAllComplete is the\n// lock status write — every promotable spec → complete. Both operate on the\n// active (request-scoped) project root, so the hosting server binds the target\n// root first and these Just Work against it.\n// ---------------------------------------------------------------------------\n\nfunction defaultProjectConfig(name: string, now: string): ProjectConfig {\n return {\n schemaVersion: '1.0.0',\n name,\n projectType: 'backend',\n targets: [{ type: 'claude', outputDir: '.claude/agents', enabled: true }],\n rules: {\n noOverlappingOwnership: true,\n requireOwnedPaths: true,\n metaAgentTags: ['meta', 'guardian', 'architect'],\n enforceReproducibility: true,\n // Lean by default: one owner agent per subsystem, not one per component —\n // a large tree/subproject with per-component implementers emits thousands\n // of agents that every session then loads. Opt in with `true` on small trees.\n generateComponentImplementers: false,\n sddRuleSeverity: {},\n },\n paths: { specsDir: '.wai/specs' },\n createdAt: now,\n updatedAt: now,\n };\n}\n\n/** Bootstrap a fresh isolated project (project.yaml + L0 system spec) at the bound root. */\nexport function provisionProject(name: string): void {\n const now = new Date().toISOString();\n saveProjectConfig(defaultProjectConfig(name, now));\n saveSystemSpec({\n schemaVersion: '1.0.0',\n name,\n vision: `Core vision for ${name}`,\n boundaries: [],\n globalRequirements: [],\n databases: [],\n createdAt: now,\n updatedAt: now,\n });\n}\n\n/**\n * NON-DESTRUCTIVELY complete a project's bootstrap at the bound root: write the\n * default project.yaml and/or the L0 system spec ONLY when each is absent. Unlike\n * provisionProject (which always writes both, overwriting an existing system\n * spec), this preserves any spec tree already present — used to fully initialize\n * a chained subproject on creation and to backfill a partially-scaffolded one\n * (specs present but project.yaml missing, the state that makes a subproject\n * un-runnable standalone) without clobbering it. Prefers the existing system\n * spec's name so a backfilled project.yaml stays consistent with its tree.\n * Returns which files it created.\n */\nexport function ensureProjectInitialized(fallbackName: string): { wroteConfig: boolean; wroteSystem: boolean } {\n const now = new Date().toISOString();\n const paths = aiPathsAt(getProjectRoot());\n const hasSystem = fs.existsSync(paths.specsSystem());\n let name = fallbackName;\n if (hasSystem) {\n const existing = loadSystemSpec();\n if (existing?.name) name = existing.name;\n }\n let wroteConfig = false;\n let wroteSystem = false;\n if (!fs.existsSync(paths.projectConfig())) {\n saveProjectConfig(defaultProjectConfig(name, now));\n wroteConfig = true;\n }\n if (!hasSystem) {\n saveSystemSpec({\n schemaVersion: '1.0.0',\n name,\n vision: `Core vision for ${name}`,\n boundaries: [],\n globalRequirements: [],\n databases: [],\n createdAt: now,\n updatedAt: now,\n });\n wroteSystem = true;\n }\n if (wroteConfig || wroteSystem) invalidateSpecCache();\n return { wroteConfig, wroteSystem };\n}\n\n/** Promote every promotable spec in the bound project to status complete. */\nexport function promoteAllComplete(): void {\n for (const p of collectPromotableSpecs()) {\n applySpecStatus(p.kind, p.id, 'complete');\n }\n invalidateSpecCache();\n}\n\n// ---------------------------------------------------------------------------\n// Chained (external) subsystem lifecycle\n//\n// An external subsystem is an L1 whose `projectPath` points at a sibling wairon\n// project; the loader recursively federates that child tree under the parent's\n// namespace. These helpers keep the two halves — the parent link and the child\n// project — in sync, so authoring one never leaves the other dangling.\n// ---------------------------------------------------------------------------\n\n/**\n * Walk a project and every chained subproject it links (recursively), invoking\n * `onChild` for each child dir together with the subsystem id that mounts it.\n * Shared scan behind the detection + backfill helpers below.\n */\nfunction walkChainedSubprojects(\n projectRoot: string,\n onChild: (childDir: string, subsystemId: string) => void,\n): void {\n const visited = new Set<string>();\n const walk = (dir: string): void => {\n const resolved = path.resolve(dir);\n if (visited.has(resolved)) return;\n visited.add(resolved);\n const specsDir = aiPathsAt(dir).specsDir();\n if (!fs.existsSync(specsDir)) return;\n for (const file of listFilesRecursive(specsDir, '.yaml')) {\n let raw: unknown;\n try {\n raw = readYamlFile(file);\n } catch {\n continue;\n }\n if (!(raw && typeof raw === 'object' && 'parentSystem' in raw)) continue;\n const pp = (raw as { projectPath?: unknown }).projectPath;\n if (typeof pp !== 'string' || pp.trim() === '') continue;\n let childDir: string;\n try {\n childDir = assertContainedProjectPath(dir, pp);\n } catch {\n continue; // absolute / escaping projectPath — never touch it\n }\n const id = (raw as { id?: unknown }).id;\n onChild(childDir, typeof id === 'string' ? id : path.basename(childDir));\n walk(childDir); // recurse into the chain (handles multi-level subprojects)\n }\n };\n walk(projectRoot);\n}\n\n/**\n * The DIRECT chained subprojects of a project (one level — the projectPath\n * subsystems declared in THIS project's own spec tree, not those nested deeper\n * inside a child). Each entry is the resolved child dir + the mounting subsystem\n * id. Used by layered `wairon generate` to cascade one level at a time (each\n * child then lists its own direct subprojects), so every layer is generated in\n * its own .wai without the parent enumerating the whole deep tree.\n */\nexport function listDirectChainedSubprojects(projectRoot: string): { dir: string; subsystemId: string }[] {\n const out: { dir: string; subsystemId: string }[] = [];\n const specsDir = aiPathsAt(projectRoot).specsDir();\n if (!fs.existsSync(specsDir)) return out;\n for (const file of listFilesRecursive(specsDir, '.yaml')) {\n let raw: unknown;\n try {\n raw = readYamlFile(file);\n } catch {\n continue;\n }\n if (!(raw && typeof raw === 'object' && 'parentSystem' in raw)) continue;\n const pp = (raw as { projectPath?: unknown }).projectPath;\n if (typeof pp !== 'string' || pp.trim() === '') continue;\n let dir: string;\n try {\n dir = assertContainedProjectPath(projectRoot, pp);\n } catch {\n continue;\n }\n const id = (raw as { id?: unknown }).id;\n out.push({ dir, subsystemId: typeof id === 'string' ? id : path.basename(dir) });\n }\n return out;\n}\n\n/** True when a child dir has a spec tree but no project.yaml (un-runnable standalone). */\nfunction childHasSpecsButNoConfig(childDir: string): boolean {\n return fs.existsSync(aiPathsAt(childDir).specsDir()) && !fs.existsSync(aiPathsAt(childDir).projectConfig());\n}\n\n/**\n * Detect chained subprojects (recursively) that have specs but no project.yaml —\n * the state that makes a subproject un-runnable standalone (`wairon` reports \"No\n * wairon project found\"). Pure read; returns the child dirs. Used by the doctor\n * report to point the user at `--fix`.\n */\nexport function findChainingSubprojectsMissingConfig(projectRoot: string): string[] {\n const missing: string[] = [];\n walkChainedSubprojects(projectRoot, (childDir) => {\n if (childHasSpecsButNoConfig(childDir)) missing.push(childDir);\n });\n return missing;\n}\n\n/**\n * Backfill a missing project.yaml on any chained subproject that has a spec tree\n * but no project config. Existing specs are never touched. Returns the child dirs\n * repaired. Used by `wairon doctor --fix`.\n */\nexport function backfillChainedSubprojectConfigs(projectRoot: string): string[] {\n const backfilled: string[] = [];\n walkChainedSubprojects(projectRoot, (childDir, subsystemId) => {\n if (childHasSpecsButNoConfig(childDir)) {\n runWithProjectRoot(childDir, () => {\n ensureProjectInitialized(subsystemId);\n });\n backfilled.push(childDir);\n }\n });\n return backfilled;\n}\n\n/**\n * Create a chained subproject subsystem: persist the parent L1 subsystem spec\n * (with `projectPath`) at the bound root, then scaffold an isolated child wairon\n * project at that path when one does not already exist. Idempotent — re-running\n * against an already-initialized child wires the parent only.\n */\nexport function createChainedSubsystem(subsystem: SubsystemSpec, projectName: string): void {\n if (!subsystem.projectPath || subsystem.projectPath.trim() === '') {\n throw new WaironError('projectPath is required to create a chained subsystem.');\n }\n\n // Store projectPath with forward slashes so the spec tree stays portable\n // across platforms (path.resolve accepts them everywhere).\n const projectPath = toPosixPath(subsystem.projectPath);\n\n // 1. Persist the parent L1 subsystem spec (with projectPath) at the parent root.\n saveSubsystemSpec({ ...subsystem, projectPath });\n\n // 2. Resolve + contain the child project directory relative to the bound\n // (parent) root. Fix B2: reject an absolute or ../-escaping projectPath so\n // a chained subproject can never scaffold, load, or execute code outside\n // its parent. Throws before any child scaffolding below.\n const childDir = assertContainedProjectPath(getProjectRoot(), projectPath);\n\n // 3. Fully initialize the child project in the SAME action — but\n // NON-DESTRUCTIVELY: create the specs dir, project.yaml, and L0 system\n // spec only when each is absent. A fresh child gets a complete, runnable\n // project (so an agent never has to hand-author project.yaml); an\n // already-scaffolded or partially-scaffolded child (specs but no\n // project.yaml) is completed without clobbering its existing spec tree.\n runWithProjectRoot(childDir, () => {\n ensureDir(aiPathsAt(childDir).specsDir());\n ensureProjectInitialized(projectName);\n });\n\n invalidateSpecCache();\n}\n\n/**\n * Relocate an external subsystem's subproject: move its directory on disk from\n * the current `projectPath` to `newProjectPath` and persist the updated link.\n * Throws if the subsystem has no `projectPath` (i.e. it is not external).\n */\nexport function moveSubsystemProject(subsystemId: string, newProjectPath: string): void {\n const sub = loadSubsystemSpec(subsystemId);\n if (!sub) {\n throw new WaironError(`Subsystem \"${subsystemId}\" does not exist.`);\n }\n if (!sub.projectPath || sub.projectPath.trim() === '') {\n throw new WaironError(\n `Subsystem \"${subsystemId}\" has no projectPath to move (not an external subproject).`,\n );\n }\n\n const nextPath = toPosixPath(newProjectPath);\n const root = getProjectRoot();\n // Fix B2: contain BOTH the persisted source and the new target within the\n // bound root before any on-disk relocation or spec write; absolute/../-escaping\n // paths are rejected (the source is attacker-influenced via set-project-path).\n const oldDir = assertContainedProjectPath(root, sub.projectPath);\n const newDir = assertContainedProjectPath(root, nextPath);\n\n if (oldDir !== newDir) {\n if (!fs.existsSync(oldDir)) {\n throw new WaironError(`Subproject directory not found at its current path: ${oldDir}`);\n }\n if (fs.existsSync(newDir)) {\n throw new WaironError(`Target directory already exists: ${newDir}`);\n }\n ensureDir(path.dirname(newDir));\n fs.renameSync(oldDir, newDir);\n }\n\n saveSubsystemSpec({ ...sub, projectPath: nextPath, updatedAt: new Date().toISOString() });\n invalidateSpecCache();\n}\n\n/** Normalize a filesystem path to forward-slash form for portable storage. */\nfunction toPosixPath(p: string): string {\n return p.replace(/\\\\/g, '/');\n}\n\n/** True when `file` is the same as, or nested under, directory `dir`. */\nfunction isWithinDir(dir: string, file: string): boolean {\n const d = path.resolve(dir);\n const f = path.resolve(file);\n return f === d || f.startsWith(d + path.sep);\n}\n\n// ---------------------------------------------------------------------------\n// Subsystem migration: externalize (internal -> subproject) and internalize\n// (subproject -> internal). Only the .wai specs move; the source code is the\n// user's responsibility. Both directions keep the tree valid by rewriting the\n// cross-subsystem references that change when component ids gain/lose the\n// `<subsystem>::` namespace prefix.\n// ---------------------------------------------------------------------------\n\n/**\n * Externalize an internal subsystem into a standalone subproject: provision a\n * child wairon project at projectPath, move the subsystem's spec subtree there,\n * reduce the parent entry to a projectPath mount, and rewrite cross-subsystem\n * references to the new namespaced ids. Source code is not moved.\n */\nexport function externalizeSubsystem(subsystemId: string, projectPath: string): void {\n if (subsystemId.includes('::')) {\n throw new WaironError('cannot externalize a nested/namespaced subsystem; run from its owning project.');\n }\n const foo = loadSubsystemSpec(subsystemId);\n if (!foo || foo.projectPath) {\n throw new WaironError(`cannot externalize: subsystem \"${subsystemId}\" is missing or already external.`);\n }\n\n const parentRoot = getProjectRoot();\n const parentSpecsDir = aiPathsAt(parentRoot).specsDir();\n const fooDir = path.join(parentSpecsDir, subsystemId);\n if (!fs.existsSync(fooDir)) {\n throw new WaironError(`subsystem specs directory not found: ${fooDir}`);\n }\n\n const relPath = toPosixPath(projectPath);\n // Fix B2: contain the child project within the parent root before provisioning\n // or moving any specs; absolute/../-escaping projectPaths are rejected.\n const childDir = assertContainedProjectPath(parentRoot, relPath);\n const childFooDir = path.join(childDir, '.wai', 'specs', subsystemId);\n if (fs.existsSync(childFooDir)) {\n throw new WaironError(`target already contains a \"${subsystemId}\" subsystem: ${childFooDir}`);\n }\n\n // Build the rename map (bare id -> namespaced) from foo's public surface BEFORE moving.\n const renameMap = buildRenameMap(subsystemId, /* externalize */ true);\n\n // Provision the child project (project.yaml + L0), then move foo's subtree in.\n const childSystemName = foo.name || subsystemId;\n runWithProjectRoot(childDir, () => {\n ensureDir(path.join(childDir, '.wai', 'specs'));\n provisionProject(childSystemName);\n });\n ensureDir(path.dirname(childFooDir));\n fs.renameSync(fooDir, childFooDir);\n\n // Re-home the moved subsystem under the child system; it must not carry projectPath.\n patchSubsystemIndex(path.join(childFooDir, '.index.yaml'), (s) => {\n s.parentSystem = childSystemName;\n delete s.projectPath;\n });\n\n // Write the minimal parent mount (id + projectPath, empty public surface).\n ensureDir(fooDir);\n writeYamlFile(path.join(fooDir, '.index.yaml'), {\n id: subsystemId,\n name: foo.name,\n description: foo.description,\n parentSystem: foo.parentSystem,\n publicInterfaces: [],\n projectPath: relPath,\n trustedLinks: [],\n status: foo.status ?? 'draft',\n createdAt: foo.createdAt ?? new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n });\n\n // Rewrite cross-subsystem references in the remaining parent specs.\n rewriteRefsInDir(parentSpecsDir, renameMap, fooDir);\n invalidateSpecCache();\n}\n\n/**\n * Internalize an external subsystem back into the parent tree: move the\n * subproject's spec subtree back under the parent subsystem, drop projectPath,\n * delete the child .wai project, and rewrite references back to bare ids. Only\n * a flat subproject (whose sole subsystem is the mount id) can be internalized.\n */\nexport function internalizeSubsystem(subsystemId: string): void {\n if (subsystemId.includes('::')) {\n throw new WaironError('cannot internalize a nested/namespaced subsystem; run from its owning project.');\n }\n const foo = loadSubsystemSpec(subsystemId);\n if (!foo || !foo.projectPath) {\n throw new WaironError(`cannot internalize: subsystem \"${subsystemId}\" is missing or not external.`);\n }\n\n const parentRoot = getProjectRoot();\n const parentSpecsDir = aiPathsAt(parentRoot).specsDir();\n // Fix B2: the PERSISTED projectPath is attacker-influenced (a prior\n // set-project-path). Contain it before resolving — otherwise the fs.rmSync of\n // childWai below could delete a directory outside the bound project root.\n const childDir = assertContainedProjectPath(parentRoot, foo.projectPath);\n const childWai = path.join(childDir, '.wai');\n const childFooDir = path.join(childDir, '.wai', 'specs', subsystemId);\n if (!fs.existsSync(childFooDir)) {\n throw new WaironError(`external subproject missing subsystem \"${subsystemId}\": ${childFooDir}`);\n }\n\n // Guard: the subproject must be a single flat subsystem matching the mount id.\n const childOwnSubs = runWithProjectRoot(childDir, () => loadSubsystemSpecs()).filter((s) => !s.id.includes('::'));\n if (childOwnSubs.length !== 1 || childOwnSubs[0].id !== subsystemId) {\n throw new WaironError(`cannot internalize: subproject is a multi-subsystem system, not a flat \"${subsystemId}\".`);\n }\n\n // Reverse rename map (namespaced -> bare), from the federated parent view, BEFORE moving.\n const renameMap = buildRenameMap(subsystemId, /* externalize */ false);\n const parentSystemName = loadSystemSpec()?.name ?? foo.parentSystem;\n\n // Replace the parent mount stub with the child's subtree.\n const fooDir = path.join(parentSpecsDir, subsystemId);\n fs.rmSync(fooDir, { recursive: true, force: true });\n ensureDir(path.dirname(fooDir));\n fs.renameSync(childFooDir, fooDir);\n\n // Re-home the internalized subsystem under the parent system; drop projectPath.\n patchSubsystemIndex(path.join(fooDir, '.index.yaml'), (s) => {\n s.parentSystem = parentSystemName;\n delete s.projectPath;\n });\n\n // Delete the child .wai project entirely (project.yaml + specs).\n fs.rmSync(childWai, { recursive: true, force: true });\n\n // Rewrite references back to bare ids.\n rewriteRefsInDir(parentSpecsDir, renameMap, fooDir);\n invalidateSpecCache();\n}\n\n/**\n * Map foo's public ids to/from their namespaced form. externalize=true yields\n * bare -> `foo::bare`; externalize=false yields `foo::x` -> `x`. Built from the\n * federated view, so it reflects foo's components, interfaces, and types.\n */\nfunction buildRenameMap(subsystemId: string, externalize: boolean): Map<string, string> {\n const map = new Map<string, string>();\n const prefix = `${subsystemId}::`;\n const add = (bare: string, namespaced: string) =>\n externalize ? map.set(bare, namespaced) : map.set(namespaced, bare);\n\n const comps = loadComponentSpecs().filter((c) => c.subsystem === subsystemId);\n const compIds = new Set(comps.map((c) => c.id));\n for (const c of comps) {\n const bare = c.id.startsWith(prefix) ? c.id.slice(prefix.length) : c.id;\n add(bare, `${prefix}${bare}`);\n }\n for (const i of loadInterfaceSpecs()) {\n if (!compIds.has(i.component)) continue;\n const bare = i.id.startsWith(prefix) ? i.id.slice(prefix.length) : i.id;\n add(bare, `${prefix}${bare}`);\n }\n for (const t of loadTypeSpecs()) {\n if (t.subsystem !== subsystemId) continue;\n const bare = t.id.startsWith(prefix) ? t.id.slice(prefix.length) : t.id;\n add(bare, `${prefix}${bare}`);\n }\n return map;\n}\n\n/** Rewrite cross-subsystem reference fields in every spec under `specsDir`, skipping `excludeDir`. */\nfunction rewriteRefsInDir(specsDir: string, renameMap: Map<string, string>, excludeDir?: string): void {\n if (renameMap.size === 0) return;\n const remap = (id: string | undefined): string | undefined =>\n id !== undefined && renameMap.has(id) ? renameMap.get(id)! : id;\n\n for (const file of listFilesRecursive(specsDir, '.yaml')) {\n if (excludeDir && isWithinDir(excludeDir, file)) continue;\n let raw: any;\n try {\n raw = readYamlFile(file);\n } catch {\n continue;\n }\n if (!raw || typeof raw !== 'object') continue;\n let changed = false;\n\n if ('componentType' in raw && Array.isArray(raw.dependsOn)) {\n const next = raw.dependsOn.map((d: string) => remap(d));\n if (next.some((v: string, i: number) => v !== raw.dependsOn[i])) {\n raw.dependsOn = next;\n changed = true;\n }\n // A Portal's dispatch table carries component refs of its own.\n if (Array.isArray(raw.dispatch)) {\n for (const b of raw.dispatch) {\n const nc = remap(b.component);\n if (nc !== b.component) {\n b.component = nc;\n changed = true;\n }\n }\n }\n } else if ('parentSystem' in raw && Array.isArray(raw.lifecycle)) {\n // Subsystem index: lifecycle entrypoints name components (same-subsystem\n // by rule, but rewrite defensively so a legacy/misdeclared tree can't\n // silently dangle across a migration).\n for (const le of raw.lifecycle) {\n const nc = remap(le.component);\n if (nc !== le.component) {\n le.component = nc;\n changed = true;\n }\n }\n } else if ('component' in raw && Array.isArray(raw.methods)) {\n for (const m of raw.methods) {\n if (!Array.isArray(m.params)) continue;\n for (const p of m.params) {\n const nt = remap(p.type);\n if (nt !== p.type) {\n p.type = nt;\n changed = true;\n }\n }\n }\n } else if ('contract' in raw && Array.isArray(raw.methods)) {\n for (const m of raw.methods) {\n if (!Array.isArray(m.narrative)) continue;\n for (const step of m.narrative) {\n const nt = remap(step.targetComponent);\n if (nt !== step.targetComponent) {\n step.targetComponent = nt;\n changed = true;\n }\n }\n }\n } else if ('kind' in raw && Array.isArray(raw.fields)) {\n for (const f of raw.fields) {\n const nt = remap(f.type);\n if (nt !== f.type) {\n f.type = nt;\n changed = true;\n }\n }\n }\n\n if (changed) writeYamlFile(file, raw);\n }\n}\n\n/** Load, mutate, and re-persist a subsystem `.index.yaml` in place. */\nfunction patchSubsystemIndex(indexPath: string, mutate: (spec: any) => void): void {\n if (!fs.existsSync(indexPath)) return;\n const raw = readYamlFile(indexPath) as any;\n mutate(raw);\n raw.updatedAt = new Date().toISOString();\n writeYamlFile(indexPath, raw);\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { aiDir } from '../utils/fs.js';\nimport type { StateId } from './statehash.js';\n\n// ---------------------------------------------------------------------------\n// Lock Registry (sdd_host / sdd_core)\n//\n// File-backed I/O for a project's commit-scoped lock record (.wai/lock.json).\n// The record is proof that the spec tree validated as-complete at one exact\n// StateId; promotion re-checks the current StateId against it and refuses on\n// drift. This module never validates or promotes — it only reads/writes the\n// record. Resolves the path through aiDir(), so it targets whichever project is\n// bound in the current (request-scoped) context.\n// ---------------------------------------------------------------------------\n\nexport interface LockRecord {\n /** The exact spec-tree state this lock validated. */\n stateId: StateId;\n /** ISO-8601 lock timestamp. */\n lockedAt: string;\n /** Audit id of the principal that locked (never a raw credential). */\n lockedBy: string;\n /** wairon version that produced the validation. */\n validatorVersion: string;\n /** The as-complete validation outcome captured at lock time. */\n validationResult: { valid: boolean; errors: number; warnings: number };\n /** \"ready\" (locked, awaiting promotion) or \"promoted\". */\n status: 'ready' | 'promoted';\n /** For git-backed projects: the pushed commit the PR is at. */\n commitSha?: string;\n /** For git-backed projects: the compare/PR URL a human opens to merge. */\n compareUrl?: string;\n}\n\nfunction lockPath(): string {\n return aiDir('lock.json');\n}\n\n/** Read the current project's lock record, or null when absent/unreadable. */\nexport function readLockRecord(): LockRecord | null {\n try {\n return JSON.parse(fs.readFileSync(lockPath(), 'utf8')) as LockRecord;\n } catch {\n return null;\n }\n}\n\n/** Persist the lock record atomically to .wai/lock.json (overwrites any prior). */\nexport function writeLockRecord(record: LockRecord): void {\n const p = lockPath();\n fs.mkdirSync(path.dirname(p), { recursive: true });\n const tmp = `${p}.tmp`;\n fs.writeFileSync(tmp, JSON.stringify(record, null, 2) + '\\n');\n fs.renameSync(tmp, p);\n}\n","import * as path from 'path';\nimport * as fs from 'fs';\nimport { ensureDir, fromProjectRoot } from '../utils/fs.js';\nimport { WAIRON_VERSION } from '../config/defaults.js';\nimport { loadProjectExtensions as loadCoreExtensions, LoadedPackSkill } from './extensions.js';\n\n// ---------------------------------------------------------------------------\n// SDD skills export\n//\n// The built-in SDD skills (architect / narrative / auditor / implement) are\n// copied into each active target tool's skills directory so the host AI tool\n// can run them in-session. Skills are how wairon \"equips\" a session — it does\n// not orchestrate sessions itself.\n// ---------------------------------------------------------------------------\n\nconst SKILL_NAMES = ['sdd-architect', 'sdd-narrative', 'sdd-auditor', 'sdd-implement'];\n\n/** skills_core_adapter: forward to the core surface to load the governing extension packs (for their pack-provided skills). */\nfunction loadProjectExtensions() {\n return loadCoreExtensions();\n}\n\n/**\n * The install/resource id for a pack skill: namespaced by pack id so it never\n * collides with the reserved built-in sdd-* skills or another pack's skills.\n */\nfunction packSkillId(skill: LoadedPackSkill): string {\n const ns = skill.pack.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');\n return `${ns}-${skill.id}`;\n}\n\n/** Parse a SKILL.md's YAML frontmatter (name + description) from its raw content. */\nfunction readFrontmatter(raw: string, fallbackName: string): { name: string; description: string } {\n const match = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/.exec(raw);\n const block = match ? match[1] : '';\n const field = (key: string): string => {\n const m = new RegExp(`^${key}:\\\\s*(.*)$`, 'm').exec(block);\n return m ? m[1].trim() : '';\n };\n return { name: field('name') || fallbackName, description: field('description') };\n}\n\nfunction builtinSkillsDir(): string {\n return path.resolve(__dirname, '..', 'templates', 'skills');\n}\n\n/** Built-in template source for a skill (always flat <name>.md). */\nfunction skillTemplatePath(name: string): string {\n return path.join(builtinSkillsDir(), `${name}.md`);\n}\n\n/**\n * Destination path for a skill inside a target's skills dir.\n *\n * Claude, Codex, and Antigravity have all converged on the same packaging:\n * a `<name>/SKILL.md` directory with YAML frontmatter (name + description).\n * Flat `<name>.md` files are silently ignored by these tools (so `Skill(<name>)`\n * reports \"Unknown skill\"). Only unverified targets fall back to a flat layout.\n */\nfunction skillDestPath(type: string, destDir: string, name: string): string {\n if (type === 'claude' || type === 'codex' || type === 'gemini' || type === 'agy') {\n return path.join(destDir, name, 'SKILL.md');\n }\n return path.join(destDir, `${name}.md`);\n}\n\n/**\n * The skills directory for a given target tool, or null if the tool has none.\n *\n * Codex and Antigravity both discover project-scoped skills from `.agents/skills/`\n * (Codex scans it from cwd up to the repo root; Antigravity reads it as project\n * scope), so they share one directory. Claude uses its own `.claude/skills/`.\n */\nexport function skillsDirForTarget(type: string): string | null {\n switch (type) {\n case 'claude': return fromProjectRoot('.claude', 'skills');\n case 'gemini': // Gemini-based Antigravity\n case 'agy':\n case 'codex': return fromProjectRoot('.agents', 'skills');\n case 'cursor': return fromProjectRoot('.cursor', 'skills');\n default: return null;\n }\n}\n\n/** Names (without extension) of the built-in SDD skills. */\nexport function listSkillNames(): string[] {\n return [...SKILL_NAMES];\n}\n\nexport interface SkillsExportResult {\n /** Skills directories written to. */\n destinations: string[];\n /** Total skill files written. */\n fileCount: number;\n /** Target types that have no skills directory (skipped). */\n skipped: string[];\n}\n\n/**\n * Copy the built-in SDD skill templates into each active target's skills dir.\n * If targetTypes is omitted, the active targets are read from project config.\n */\nexport function exportSddSkills(targetTypes?: string[]): SkillsExportResult {\n const types = targetTypes ?? activeTargetTypes();\n\n const destinations: string[] = [];\n const skipped: string[] = [];\n let fileCount = 0;\n\n // Pack-provided skills discovered from the loaded extension packs (empty when\n // no packs declare any — so projects without pack skills see no change).\n const packSkills = loadProjectExtensions().skills;\n\n for (const type of types) {\n const destDir = skillsDirForTarget(type);\n if (!destDir) {\n skipped.push(type);\n continue;\n }\n ensureDir(destDir);\n destinations.push(destDir);\n\n for (const name of SKILL_NAMES) {\n const srcPath = skillTemplatePath(name);\n if (!fs.existsSync(srcPath)) continue;\n // Copy verbatim — skills are agent-facing and reference MCP tools, not the\n // `wairon` CLI, so there is no dev-path command to substitute.\n const content = fs.readFileSync(srcPath, 'utf-8');\n const destPath = skillDestPath(type, destDir, name);\n ensureDir(path.dirname(destPath));\n fs.writeFileSync(destPath, content, 'utf-8');\n fileCount++;\n }\n\n // Pack skills targeting this client: installed namespaced <pack-id>-<skill-id>.\n for (const skill of packSkills) {\n if (!skill.targets.includes(type)) continue;\n if (!fs.existsSync(skill.sourcePath)) continue;\n const id = packSkillId(skill);\n const content = fs.readFileSync(skill.sourcePath, 'utf-8');\n const destPath = skillDestPath(type, destDir, id);\n ensureDir(path.dirname(destPath));\n fs.writeFileSync(destPath, content, 'utf-8');\n fileCount++;\n }\n }\n\n return { destinations, fileCount, skipped };\n}\n\nexport interface SkillFreshness {\n /** The skills directory for this target, or null if the target has none. */\n dir: string | null;\n /** Skill files that are missing on disk. */\n missing: string[];\n /** Skill files present on disk but differing from the current built-in template. */\n stale: string[];\n /** Skill files present and byte-identical to the built-in template. */\n ok: string[];\n}\n\n/**\n * Compare a target's installed SDD skills against the built-in templates, so\n * `wairon doctor` can report missing or stale (out-of-date) skill files.\n */\nexport function checkSkillFreshness(type: string): SkillFreshness {\n const dir = skillsDirForTarget(type);\n const result: SkillFreshness = { dir, missing: [], stale: [], ok: [] };\n if (!dir) return result;\n\n for (const name of SKILL_NAMES) {\n const destPath = skillDestPath(type, dir, name);\n if (!fs.existsSync(destPath)) { result.missing.push(name); continue; }\n const srcPath = skillTemplatePath(name);\n const want = fs.existsSync(srcPath) ? fs.readFileSync(srcPath, 'utf-8') : '';\n const have = fs.readFileSync(destPath, 'utf-8');\n if (have === want) result.ok.push(name);\n else result.stale.push(name);\n }\n return result;\n}\n\nexport function activeTargetTypes(): string[] {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { loadProjectConfig } = require('../config/loader.js') as typeof import('../config/loader.js');\n const config = loadProjectConfig();\n return config.targets\n .filter((t: { enabled?: boolean }) => !('enabled' in t) || t.enabled)\n .map((t: string | { type: string }) => (typeof t === 'string' ? t : t.type));\n}\n\n// ---------------------------------------------------------------------------\n// SDD skills as MCP resources\n//\n// Cloud-only agents cannot receive the filesystem-exported skills above, so the\n// MCP server also publishes the four built-in SDD skills as read-only MCP\n// resources. The functions below resolve the SAME packaged templates that\n// exportSddSkills copies to disk (src/templates/skills/*.md) into MCP-safe\n// descriptors and markdown content.\n//\n// Layering (folded into this module, mirroring exportSddSkills):\n// skills_resource_specialist → listSkillResources / readSkillResource (pure)\n// skills_resource_orchestrator→ validation + dispatch (inside readResource)\n// skills_portal → listResources / readResource (adapter entry)\n// ---------------------------------------------------------------------------\n\n/** MCP resource URI scheme for a built-in SDD skill (e.g. wairon-skill://sdd-architect). */\nconst SKILL_RESOURCE_SCHEME = 'wairon-skill';\n\n/**\n * The four packaged SDD skills published as MCP resources, in a stable\n * (alphabetical) order. Derived from SKILL_NAMES so the resource set can never\n * drift from the export source of truth.\n */\nconst RESOURCE_SKILL_IDS: string[] = [...SKILL_NAMES].sort();\n\n/** MCP-safe descriptor for a Wairon-provided built-in skill resource. */\nexport interface SkillResourceDescriptor {\n /** Stable skill resource id, such as \"sdd-architect\". */\n id: string;\n /** Human-readable skill name. */\n name: string;\n /** Short description of when an agent should use the skill. */\n description: string;\n /** Skill content version / Wairon version that provides it. */\n version?: string;\n /** MCP resource URI used to fetch the skill content. */\n resourceUri: string;\n /** Whether hosted MCP advertises this skill by default. */\n defaultForHostedMcp: boolean;\n}\n\n/** Thrown when a skill resource id is not one of the built-in SDD skills. */\nexport class SkillResourceNotFoundError extends Error {\n constructor(resourceId: string) {\n super(`Unknown SDD skill resource id: \"${resourceId}\".`);\n this.name = 'SkillResourceNotFoundError';\n }\n}\n\n/** Parse a skill template's YAML frontmatter for its name and description. */\nfunction readSkillFrontmatter(name: string): { name: string; description: string } {\n return readFrontmatter(fs.readFileSync(skillTemplatePath(name), 'utf-8'), name);\n}\n\n// ── skills_resource_specialist ─────────────────────────────────────────────\n\n/** List the four built-in SDD skills as MCP-safe resource descriptors. */\nexport function listSkillResources(): SkillResourceDescriptor[] {\n const builtin: SkillResourceDescriptor[] = RESOURCE_SKILL_IDS.map((id) => {\n const fm = readSkillFrontmatter(id);\n return {\n id,\n name: fm.name,\n description: fm.description,\n version: WAIRON_VERSION,\n resourceUri: `${SKILL_RESOURCE_SCHEME}://${id}`,\n defaultForHostedMcp: true,\n };\n });\n // Pack-provided skills (namespaced by pack id), published alongside the built-ins.\n const pack: SkillResourceDescriptor[] = loadProjectExtensions().skills\n .filter((s) => fs.existsSync(s.sourcePath))\n .map((skill) => {\n const id = packSkillId(skill);\n const fm = readFrontmatter(fs.readFileSync(skill.sourcePath, 'utf-8'), id);\n return {\n id,\n name: fm.name,\n description: fm.description,\n version: skill.packVersion ?? WAIRON_VERSION,\n resourceUri: `${SKILL_RESOURCE_SCHEME}://${id}`,\n defaultForHostedMcp: true,\n };\n });\n return [...builtin, ...pack];\n}\n\n/** Read one built-in skill's markdown content from the packaged templates. */\nexport function readSkillResource(resourceId: string): string {\n const packSkill = loadProjectExtensions().skills.find((s) => packSkillId(s) === resourceId);\n if (packSkill) return fs.readFileSync(packSkill.sourcePath, 'utf-8');\n return fs.readFileSync(skillTemplatePath(resourceId), 'utf-8');\n}\n\n// ── skills_resource_orchestrator → skills_portal ───────────────────────────\n\n/** Portal: list the built-in SDD skills as MCP resource descriptors. */\nexport function listResources(): SkillResourceDescriptor[] {\n return listSkillResources();\n}\n\n/**\n * Portal: read one built-in SDD skill's content by MCP resource id. Rejects an\n * unknown id — validated against the listed descriptors — before reading.\n */\nexport function readResource(resourceId: string): string {\n const known = listSkillResources().some((d) => d.id === resourceId);\n if (!known) throw new SkillResourceNotFoundError(resourceId);\n return readSkillResource(resourceId);\n}\n","import { aiDir, writeFile, writeFileIfChanged, readFileOrNull, pathExists } from '../utils/fs.js';\nimport { GLOBAL_GUIDE_BODY } from '../utils/ai-guide.js';\nimport { versionStamp } from './stamp.js';\n\n// ---------------------------------------------------------------------------\n// Context — shared project context under .wai/context/\n//\n// .wai/context/\n// project.md ← human-edited: project description, stack, conventions\n// architecture.md ← human-edited: system design notes (optional)\n// domains.md ← auto-generated: domain list from registry\n// wairon-guide.md ← auto-generated: importable reference for AI tools\n//\n// The generated files are rebuilt by syncContextFiles() which is called by\n// `wairon generate` and `wairon init`.\n// ---------------------------------------------------------------------------\n\nexport function contextDir(...segments: string[]): string {\n return aiDir('context', ...segments);\n}\n\nexport const CONTEXT_PATHS = {\n dir: () => contextDir(),\n projectMd: () => contextDir('project.md'),\n architectureMd:() => contextDir('architecture.md'),\n domainsMd: () => contextDir('domains.md'),\n waironGuideMd: () => contextDir('wairon-guide.md'),\n} as const;\n\n// ---------------------------------------------------------------------------\n// Presence checks\n// ---------------------------------------------------------------------------\n\nexport function hasContext(): boolean {\n return pathExists(CONTEXT_PATHS.projectMd());\n}\n\nexport function hasArchitectureContext(): boolean {\n return pathExists(CONTEXT_PATHS.architectureMd());\n}\n\n// ---------------------------------------------------------------------------\n// Raw reads / writes (human-edited files)\n// ---------------------------------------------------------------------------\n\nexport function readProjectContext(): string | null {\n return readFileOrNull(CONTEXT_PATHS.projectMd());\n}\n\nexport function readArchitectureContext(): string | null {\n return readFileOrNull(CONTEXT_PATHS.architectureMd());\n}\n\nexport function writeProjectContext(content: string): void {\n writeFile(CONTEXT_PATHS.projectMd(), content);\n}\n\nexport function writeArchitectureContext(content: string): void {\n writeFile(CONTEXT_PATHS.architectureMd(), content);\n}\n\n// ---------------------------------------------------------------------------\n// Renderers for auto-generated files\n// ---------------------------------------------------------------------------\n\n/**\n * Build domains.md from the current domain registry.\n * Imported lazily to avoid circular deps at module load time.\n */\nexport function renderDomainsDoc(): string {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { resolveDomains } = require('./domains.js') as typeof import('./domains.js');\n const domains = resolveDomains();\n\n const today = new Date().toISOString().split('T')[0];\n const lines: string[] = [\n versionStamp(),\n `# Domains`,\n ``,\n `> Auto-generated by wairon. The human developer rebuilds this with \\`wairon generate\\`. `,\n `> Last updated: ${today}`,\n ``,\n ];\n\n if (domains.length === 0) {\n lines.push('_No domains yet. Define subsystems in the spec tree, or add free-standing domains with `wairon domains add`._');\n } else {\n lines.push(`**${domains.length} domain(s).**`);\n lines.push('');\n lines.push('| ID | Name | Source | Owned paths |');\n lines.push('|----|------|--------|-------------|');\n for (const d of domains) {\n const name = d.name ?? d.id;\n const source = d.boundTo ? `subsystem \\`${d.boundTo}\\`` : 'free-standing';\n lines.push(`| \\`${d.id}\\` | ${name} | ${source} | \\`${d.ownedPaths.join('`, `') || '—'}\\` |`);\n }\n }\n\n return lines.join('\\n') + '\\n';\n}\n\n/**\n * Build wairon-guide.md — the file AI tools can @-import for full wairon\n * awareness. Contains: project context + domain map + wairon usage guide.\n */\nexport function renderWaironGuide(): string {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { loadProjectConfig } = require('../config/loader.js') as typeof import('../config/loader.js');\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const { resolveDomains } = require('./domains.js') as typeof import('./domains.js');\n\n const domains = resolveDomains();\n\n let projectName = 'this project';\n try {\n projectName = loadProjectConfig().name;\n } catch { /* not initialized or broken — use fallback */ }\n\n const projectCtx = readProjectContext();\n const archCtx = readArchitectureContext();\n\n const lines: string[] = [\n versionStamp(),\n `<!-- wairon-generated — do not edit directly; the human developer rebuilds this with \\`wairon generate\\` -->`,\n ``,\n ];\n\n // Project context block\n if (projectCtx) {\n lines.push(`# Project Context — ${projectName}`);\n lines.push('');\n lines.push(projectCtx.trim());\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n // Architecture block\n if (archCtx) {\n lines.push('# Architecture');\n lines.push('');\n lines.push(archCtx.trim());\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n // Domain map\n lines.push(`# Domain Map (${domains.length} domain${domains.length !== 1 ? 's' : ''})`);\n lines.push('');\n if (domains.length === 0) {\n lines.push('_No domains yet._');\n } else {\n lines.push('| ID | Source | Name |');\n lines.push('|----|--------|------|');\n for (const d of domains) {\n const name = d.name ?? d.id;\n const source = d.boundTo ? `subsystem \\`${d.boundTo}\\`` : 'free-standing';\n lines.push(`| \\`${d.id}\\` | ${source} | ${name} |`);\n }\n }\n lines.push('');\n lines.push('---');\n lines.push('');\n\n // MCP server note (when installed in this project's .claude/settings.json)\n const mcpSettingsPath = require('path').join(process.cwd(), '.claude', 'settings.json');\n let mcpInstalled = false;\n try {\n const s = JSON.parse(require('fs').readFileSync(mcpSettingsPath, 'utf8'));\n mcpInstalled = !!(s?.mcpServers?.wairon);\n } catch { /* not installed */ }\n\n if (mcpInstalled) {\n lines.push('# wairon MCP Tools');\n lines.push('');\n lines.push('The **wairon MCP server** is active in this project. The tools are self-describing; call them directly:');\n lines.push('');\n lines.push('- Authoring: `sdd_initialize_system`, `sdd_add_subsystem`, `sdd_set_public_interfaces`, `sdd_set_subsystem_project_path`, `sdd_add_component`, `sdd_define_interface`, `sdd_set_endpoints`, `sdd_write_narrative`, `sdd_add_type`.');\n lines.push('- Reading & maintenance: `sdd_get_spec`, `sdd_update_spec`, `sdd_delete_spec`, `sdd_validate_tree`, `sdd_get_status`.');\n lines.push('- Topology: `listAgents`, `getAgent`, `listDomains`, `validateTopology`, `getProjectConfig`.');\n lines.push('');\n lines.push('Use these MCP tools to query and change project state — never the `wairon` CLI (that is the human developer\\'s tool).');\n lines.push('');\n lines.push('---');\n lines.push('');\n }\n\n // Full wairon usage guide\n lines.push(GLOBAL_GUIDE_BODY);\n lines.push('');\n\n return lines.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Sync: rebuild all auto-generated context files\n// ---------------------------------------------------------------------------\n\nexport interface SyncResult {\n domainsUpdated: boolean;\n guideUpdated: boolean;\n}\n\n/**\n * Regenerate domains.md and wairon-guide.md from the current registry state.\n * Called by `wairon generate` and `wairon init`.\n */\nexport function syncContextFiles(): SyncResult {\n const domainsContent = renderDomainsDoc();\n const guideContent = renderWaironGuide();\n\n const domainsUpdated = writeFileIfChanged(CONTEXT_PATHS.domainsMd(), domainsContent);\n const guideUpdated = writeFileIfChanged(CONTEXT_PATHS.waironGuideMd(), guideContent);\n\n return { domainsUpdated, guideUpdated };\n}\n","import { WAIRON_VERSION } from '../config/defaults.js';\n\n// ---------------------------------------------------------------------------\n// Version stamp\n//\n// Generated files (the injected guide, the .wai/context guides, the global\n// Antigravity plugin skill) carry a stamp with the wairon version that wrote\n// them. `wairon doctor` reads the stamp and warns when a file was produced by\n// an older wairon than the one currently installed — i.e. it is stale and\n// should be refreshed with `wairon generate`.\n// ---------------------------------------------------------------------------\n\n/** An HTML-comment stamp embedding the current wairon version. */\nexport function versionStamp(): string {\n return `<!-- wairon-version: ${WAIRON_VERSION} -->`;\n}\n\nconst STAMP_RE = /<!--\\s*wairon-version:\\s*([^\\s]+)\\s*-->/;\n\n/** Extract the wairon version stamped in generated content, or null if absent. */\nexport function readStampVersion(content: string): string | null {\n const m = content.match(STAMP_RE);\n return m ? m[1] : null;\n}\n","// ---------------------------------------------------------------------------\n// AI Guide injection\n//\n// Injects a wairon usage guide into AI tool config files (CLAUDE.md,\n// GEMINI.md) so the AI tool knows how to use wairon in this project.\n//\n// Injection is idempotent: the guide is wrapped in HTML comment markers and\n// replaced if already present, so running it twice has no side-effects.\n//\n// Global scope: ~/.claude/CLAUDE.md or ~/.gemini/GEMINI.md\n// Local scope: <project-root>/.claude/CLAUDE.md or <project-root>/.gemini/GEMINI.md\n// ---------------------------------------------------------------------------\n\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { versionStamp } from '../core/stamp.js';\n\nexport const GUIDE_MARKER_START = '<!-- wairon-guide-start -->';\nexport const GUIDE_MARKER_END = '<!-- wairon-guide-end -->';\n\n// ---------------------------------------------------------------------------\n// Guide content\n// ---------------------------------------------------------------------------\n\nexport const GLOBAL_GUIDE_BODY = `\\\n## wairon — Spec-Driven Development (optional)\n\nIf \\`.wai/specs/\\` exists, the wairon SDD workflow is active; otherwise ignore it. wairon does not orchestrate sessions — it equips yours.\n\n### In SDD Projects:\n- **Source of Truth**: All architecture lives in the spec tree under \\`.wai/specs/\\` (L0 System → L1 Subsystem → L2 Component → L3 Interface → L4 Implementation → L5 Narrative). Do not edit generated agent config files under \\`.claude/agents/\\` (rebuilt via \\`wairon generate\\`).\n- **Validation**: Conformance checks (stereotype rules, cycle checks, reference integrity) are run via the \\`sdd_validate_tree\\` MCP tool.\n- **Operating Rules**:\n 1. **Skills**: Use \\`sdd-architect\\` to design (and \\`sdd-implement\\`, \\`sdd-narrative\\`, \\`sdd-auditor\\`). Refer to project's local guide file for detailed constraints.\n 2. **MCP Tools Only**: Author/validate specs *only* via \\`sdd_*\\` tools (e.g. \\`sdd_initialize_system\\`, \\`sdd_validate_tree\\`).\n 3. **No CLI Exec**: Do not run the \\`wairon\\` CLI (human tool). Use MCP tools \\`sdd_validate_tree\\` and \\`sdd_get_status\\` instead.\n 4. **Subagents**: Spawn generated \\`<component>-implementer\\` subagents for coding.\n 5. **Design First**: Complete spec and pass \\`sdd_validate_tree\\` before writing code.\n 6. **Consistency**: Code must match L3 interfaces and L5 narratives exactly. If the spec is wrong, stop and update the spec.\n 7. **Subprojects & Namespacing**: If a subsystem uses \\`projectPath\\` delegation, target its specs using namespaced IDs (e.g. \\`subsystem::component\\`). Use leading \\`::\\` to target root (e.g. \\`::shared::type\\`) and \\`super::\\` to go up a level (e.g. \\`super::sibling\\`). wairon automatically resolves the path and strips the prefix on writes.`;\n\nconst LOCAL_GUIDE_BODY = `\\\n## Wairon — Spec-Driven Development (you are operating inside it)\n\nThis project uses **wairon**. System specs live under \\`.wai/specs/\\` (L0 System → L1 Subsystem → L2 Component → L3 Interface → L4 Implementation → Narrative); agent topology and code are derived from it.\n\n**Do NOT search files or read agent configs to learn about wairon or SDD. Use the context here and the \\`sdd-architect\\` skill to start.**\n\n**Your first move: call the \\`sdd_get_status\\` MCP tool** (or \\`wairon/sdd_get_status\\`) to see the spec tree. Do not parse files or run CLI commands manually.\n\n### How you operate\n- **To design/modify specs**: Use **\\`sdd-architect\\`** skill (in \\`.claude/skills/\\` or \\`.gemini/skills/\\`).\n- **Manage specs via MCP tools only**: Use \\`sdd_initialize_system\\`, \\`sdd_add_subsystem\\`, \\`sdd_add_component\\`, \\`sdd_define_interface\\`, \\`sdd_write_narrative\\`, \\`sdd_add_type\\`, \\`sdd_get_spec\\`, \\`sdd_delete_spec\\`, \\`sdd_validate_tree\\`, and \\`sdd_get_status\\` (namespaced if needed). Do not edit specs manually.\n- **Subprojects & Namespacing (Chaining)**: If a subsystem defines a \\`projectPath\\`, its entire \\`.wai/\\` spec tree is recursively loaded and namespaced with the subsystem ID as a prefix (using \\`::\\`, e.g. \\`billing::invoice::invoice_portal\\`). Use the qualified namespaced ID with the parent MCP tools; wairon will resolve the path and strip the prefix automatically.\n - **Leading \\`::\\`**: Bypasses the local subsystem prefix to resolve absolute from the system root (e.g. \\`::shared::error-type\\`).\n - **\\`super::\\`**: Goes up one parent subsystem level (e.g. \\`super::sibling_comp\\`, \\`super::super::parent_sibling\\`).\n- **Do not run the \\`wairon\\` CLI**: Use \\`sdd_validate_tree\\` and \\`sdd_get_status\\` instead of CLI commands.\n- **Handoff to implementation**: Once design is complete and validates cleanly, tell the human: *\"The specs are complete and validate. Please run \\`wairon lock\\` to confirm and generate the implementer agents, then restart this session to load them.\"*\n- **To implement code**: Spawn the generated \\`<component-id>-implementer\\` subagent. Implementations must match L3 interfaces and L5 narratives exactly. If you are operating inside a subproject directory context (e.g. subfolder) and cannot see or spawn the generated implementer agent or its skills, instruct the user to start a new agent session from the parent wairon project directory root.\n\n### Rules (enforced by \\`sdd_validate_tree\\`)\n1. **Design before code**: Complete spec and pass validator before writing source code.\n2. **Human-in-the-loop**: Ask user approval for each spec layer before proceeding.\n3. **Spec consistency**: If a 1:1 narrative match is incorrect or conflicts with L0 requirements, escalate a spec revision first. Never ship mismatched code.\n4. **No persistence shortcuts & strict layers**: A Portal must never depend directly on a Store, Registry, or Adapter. Portal reads MAY go through a Repository/Index facade (passthrough reads need no per-entity Orchestrator ceremony), but a Portal narrative calling a write-effect facade method is an error (\\`PORTAL_WRITE_SHORTCUT\\`) — writes always route through an Orchestrator. Held domain state always lives in a dedicated data component, never as fields inside an Orchestrator or Specialist. Two sanctioned shapes: the RECOMMENDED Repository pattern (owns Store + Registry + Index; consumers depend on the facade), or — for genuinely simple state — a deliberately standalone Store (workflow-layer consumers only, acknowledged with a lint.allow reason on the UNOWNED_STORE warning). Never combine Store/Registry/Index roles into one component, and never fold state into a consuming component because a link was refused.\n\n### Component Vocabulary\n* **Blocks**: Portal, Orchestrator, Supervisor, Actor, Store, Index, Registry, Adapter, Observer, Specialist.\n* **Patterns**: Repository, Gateway (these composable patterns \\`own\\` member blocks).\n* Use \\`owns\\` for private member containment (exactly one hop) and \\`dependsOn\\` for collaborators. Never use generic suffixes like \"Manager\", \"Helper\", or \"Utils\".`;\n\n// ---------------------------------------------------------------------------\n// Path resolution\n// ---------------------------------------------------------------------------\n\nexport function globalGuideFilePath(targetType: string): string | null {\n // Respect custom config dirs (account aliases) — same as MCP install.\n if (targetType === 'claude') return path.join(process.env['CLAUDE_CONFIG_DIR'] || path.join(os.homedir(), '.claude'), 'CLAUDE.md');\n if (targetType === 'gemini') return path.join(process.env['GEMINI_CONFIG_DIR'] || path.join(os.homedir(), '.gemini'), 'GEMINI.md');\n return null;\n}\n\nexport function localGuideFilePath(projectRoot: string, targetType: string): string | null {\n if (targetType === 'claude') return path.join(projectRoot, '.claude', 'CLAUDE.md');\n if (targetType === 'gemini' || targetType === 'agy') return path.join(projectRoot, '.gemini', 'GEMINI.md');\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Detect / inject\n// ---------------------------------------------------------------------------\n\n/** Returns true if the file exists and already contains the wairon guide. */\nexport function hasWaironGuide(filePath: string): boolean {\n if (!fs.existsSync(filePath)) return false;\n return fs.readFileSync(filePath, 'utf-8').includes(GUIDE_MARKER_START);\n}\n\n/**\n * Inject (or update) the wairon guide section in the given file.\n * Creates the file and any parent directories if they don't exist.\n */\nexport function injectGuide(filePath: string, scope: 'global' | 'local'): void {\n // Use `wairon` literally in injected docs — never substitute a dev path. The\n // guide is documentation (the AI uses MCP tools; the human runs `wairon`).\n const body = scope === 'global' ? GLOBAL_GUIDE_BODY : LOCAL_GUIDE_BODY;\n const section = `\\n\\n${GUIDE_MARKER_START}\\n${versionStamp()}\\n${body}\\n${GUIDE_MARKER_END}\\n`;\n\n const existing = fs.existsSync(filePath)\n ? fs.readFileSync(filePath, 'utf-8')\n : '';\n\n const stripped = stripGuideSection(existing);\n const newContent = stripped.trimEnd() + section;\n\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n fs.writeFileSync(filePath, newContent, 'utf-8');\n}\n\n/** Remove the wairon guide section from a string (for clean replacement). */\nexport function stripGuideSection(content: string): string {\n const start = content.indexOf(GUIDE_MARKER_START);\n const end = content.indexOf(GUIDE_MARKER_END);\n if (start === -1 || end === -1) return content;\n return content.slice(0, start) + content.slice(end + GUIDE_MARKER_END.length);\n}\n\nexport function writeRootGuideDelegator(projectRoot: string, targetType: string): void {\n if (targetType === 'claude') {\n const filePath = path.join(projectRoot, 'CLAUDE.md');\n const content = `@.claude/CLAUDE.md\n\n# Wairon SDD Project\n\nThis project uses the Wairon Spec-Driven Development (SDD) framework. The imported\n\\`.claude/CLAUDE.md\\` above is your complete operating guide — you already have the\nfull context, so don't search the project to learn how wairon or SDD works.\n\nTo design or modify the system, invoke the **\\`sdd-architect\\`** skill\n(in \\`.claude/skills/\\`). Author and validate specs with the \\`sdd_*\\` MCP tools;\nthe \\`wairon\\` CLI is the human developer's tool, not yours.\n`;\n fs.writeFileSync(filePath, content, 'utf-8');\n } else if (targetType === 'gemini' || targetType === 'agy') {\n const filePath = path.join(projectRoot, 'GEMINI.md');\n // Gemini CLI / Antigravity auto-load the ROOT GEMINI.md but NOT .gemini/GEMINI.md,\n // and @-import expansion is not guaranteed — so inline the full guide here so the\n // agent actually has it (otherwise it's told \"the guide is above\" when it isn't).\n const content = `# Wairon SDD Project\n${GUIDE_MARKER_START}\n${versionStamp()}\n${LOCAL_GUIDE_BODY}\n${GUIDE_MARKER_END}\n`;\n fs.writeFileSync(filePath, content, 'utf-8');\n } else if (targetType === 'cursor') {\n const filePath = path.join(projectRoot, '.cursorrules');\n const content = `# Wairon SDD Project\n\nThis project uses the Wairon Spec-Driven Development (SDD) framework.\n\nRefer to the rules in [.cursor/rules/](.cursor/rules/) for full instructions.\n`;\n fs.writeFileSync(filePath, content, 'utf-8');\n } else if (targetType === 'copilot') {\n const filePath = path.join(projectRoot, '.github', 'copilot-instructions.md');\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n const content = `# Wairon SDD Project\n\nThis project uses the Wairon Spec-Driven Development (SDD) framework.\n\nRefer to the prompts in [.github/prompts/](.github/prompts/) for instructions.\n`;\n fs.writeFileSync(filePath, content, 'utf-8');\n } else if (targetType === 'codex') {\n const filePath = path.join(projectRoot, '.codexrules');\n const content = `# Wairon SDD Project\n\nRefer to [.codex/agents/](.codex/agents/) for full instructions.\n`;\n fs.writeFileSync(filePath, content, 'utf-8');\n }\n}\n\n// Target types that carry a guide-bearing root delegator file.\nconst GUIDE_TARGETS = ['claude', 'gemini', 'agy', 'cursor', 'copilot', 'codex'];\n\n/**\n * Re-inject the project-LOCAL wairon guide for each active target and refresh\n * its root delegator. This is what keeps `.claude/CLAUDE.md` / `.gemini/GEMINI.md`\n * current with the installed wairon — without it, `init` is the only thing that\n * ever writes the guide, so it silently goes stale. Global (home) guides are not\n * touched here; those remain opt-in via `wairon init`. Returns the guide file\n * paths that were (re)written.\n */\nexport function reinjectLocalGuides(projectRoot: string, targetTypes: string[]): string[] {\n const written: string[] = [];\n for (const type of targetTypes) {\n if (!GUIDE_TARGETS.includes(type)) continue;\n const guidePath = localGuideFilePath(projectRoot, type);\n if (guidePath) {\n injectGuide(guidePath, 'local');\n if (!written.includes(guidePath)) written.push(guidePath);\n }\n writeRootGuideDelegator(projectRoot, type);\n }\n return written;\n}\n","import { AgentRecord } from '../models/agent.js';\nimport { TargetConfig } from '../models/project.js';\nimport { Template } from '../models/template.js';\n\n// ---------------------------------------------------------------------------\n// Exporter abstraction\n//\n// An Exporter takes an AgentRecord + its rendered template and produces a\n// file at a target path. The separation of concerns is:\n//\n// core/ — knows about agents, templates, registry, topology rules\n// exporters/ — knows about tool-specific file formats and output paths\n//\n// This means adding a new output target (e.g., Cursor) requires only adding\n// a new Exporter implementation, with zero changes to core logic.\n// ---------------------------------------------------------------------------\n\n/**\n * Marker embedded in every wairon-generated agent file. It lets `generate`\n * safely RECONCILE its managed output dirs — pruning agent files that are no\n * longer in the topology (removed components, or the old flat pile after the\n * switch to a layered topology) — while never touching a hand-authored file\n * that lacks the marker.\n */\nexport const WAIRON_MANAGED_MARKER = 'wairon:managed';\nexport const WAIRON_MANAGED_BANNER = `<!-- ${WAIRON_MANAGED_MARKER} — generated by \\`wairon generate\\`; do not edit, changes are overwritten -->`;\n\nexport interface ExportContext {\n agent: AgentRecord;\n template: Template;\n /** Rendered instruction body (template vars already substituted) */\n renderedInstructions: string;\n /** Absolute path to the project root */\n projectRoot: string;\n target: TargetConfig;\n}\n\nexport interface ExportResult {\n /** Absolute path where the file was written */\n outputPath: string;\n /** The content that was written */\n content: string;\n /** True if the file already existed with identical content and was not rewritten */\n unchanged: boolean;\n}\n\nexport interface Exporter {\n /**\n * Returns the target type(s) this exporter handles.\n * For built-ins: 'claude' | 'gemini'.\n * For custom exporters, this returns 'custom'.\n */\n readonly targetType: string;\n\n /**\n * Export an agent definition to the target location.\n * Must be idempotent — calling multiple times produces the same output.\n */\n export(ctx: ExportContext): ExportResult;\n\n /**\n * Return the output file path for an agent without writing it.\n * Useful for validation and dry-run modes.\n */\n outputPath(ctx: Omit<ExportContext, 'renderedInstructions'>): string;\n}\n","import * as path from 'path';\nimport { writeFileIfChanged } from '../utils/fs.js';\nimport { Exporter, ExportContext, ExportResult } from './base.js';\n\n// ---------------------------------------------------------------------------\n// Claude Code exporter\n//\n// Generates agent definition files for Claude Code's sub-agent system.\n// Output format: Markdown with YAML front-matter.\n//\n// Front-matter fields:\n// name — display name shown in the Claude UI\n// description — used by Claude to decide when to invoke this sub-agent;\n// keep it concise and action-oriented\n//\n// Note: the `tools:` front-matter field controls which Claude built-in tools\n// (Bash, Read, Write, Edit, …) the sub-agent may use. wairon does not\n// manage that list — it belongs in the agent template body. ownedPaths is a\n// wairon topology concept and is embedded in the rendered instructions.\n//\n// Reference: https://docs.anthropic.com/en/docs/claude-code/sub-agents\n//\n// Generated file path: <outputDir>/<agent-id>.md\n// ---------------------------------------------------------------------------\n\nexport class ClaudeExporter implements Exporter {\n readonly targetType = 'claude';\n\n outputPath(ctx: Omit<ExportContext, 'renderedInstructions'>): string {\n const { agent, target, projectRoot } = ctx;\n const outputDir = 'outputDir' in target ? target.outputDir : '.claude/agents';\n return path.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, '--')}.md`);\n }\n\n export(ctx: ExportContext): ExportResult {\n const { agent, renderedInstructions } = ctx;\n const filePath = this.outputPath(ctx);\n\n // Escape any characters in description that would break inline YAML\n const safeDescription = agent.description.includes(':') || agent.description.includes('#')\n ? `\"${agent.description.replace(/\"/g, '\\\\\"')}\"`\n : agent.description;\n\n const content = [\n '---',\n `name: ${agent.name}`,\n `description: ${safeDescription}`,\n '---',\n '',\n renderedInstructions,\n '',\n ].join('\\n');\n\n const changed = writeFileIfChanged(filePath, content);\n return { outputPath: filePath, content, unchanged: !changed };\n }\n}\n","import * as path from 'path';\nimport { writeFileIfChanged } from '../utils/fs.js';\nimport { Exporter, ExportContext, ExportResult } from './base.js';\n\n// ---------------------------------------------------------------------------\n// Custom path exporter\n//\n// Used when the target is a user-defined { type: 'custom', outputDir: '...' }.\n// Generates the same Markdown+frontmatter format as the Claude exporter, but\n// at the user-specified path. Users can override this by providing their own\n// exporter via a plugin system (future work).\n// ---------------------------------------------------------------------------\n\nexport class CustomExporter implements Exporter {\n readonly targetType = 'custom';\n\n outputPath(ctx: Omit<ExportContext, 'renderedInstructions'>): string {\n const { agent, target, projectRoot } = ctx;\n if (!('outputDir' in target)) {\n throw new Error('CustomExporter requires target.outputDir');\n }\n return path.resolve(projectRoot, target.outputDir, `${agent.id.replace(/::/g, '--')}.md`);\n }\n\n export(ctx: ExportContext): ExportResult {\n const { agent, target, renderedInstructions } = ctx;\n const label = 'label' in target ? target.label : 'Custom';\n const filePath = this.outputPath(ctx);\n\n const content = [\n '---',\n `name: ${agent.name}`,\n `description: ${agent.description}`,\n `id: ${agent.id}`,\n `target: ${label}`,\n '---',\n '',\n renderedInstructions,\n '',\n ].join('\\n');\n\n const changed = writeFileIfChanged(filePath, content);\n return { outputPath: filePath, content, unchanged: !changed };\n }\n}\n","import * as path from 'path';\nimport { writeFileIfChanged } from '../utils/fs.js';\nimport { Exporter, ExportContext, ExportResult } from './base.js';\n\n// ---------------------------------------------------------------------------\n// Gemini CLI exporter\n//\n// Generates agent definition files for the Gemini CLI agent system.\n// Output format: pure YAML (NOT markdown with frontmatter).\n//\n// Gemini CLI agents live in .gemini/agents/<id>.yaml and are structured as:\n//\n// name: display name\n// description: one-line summary used by Gemini when selecting this agent\n// system_prompt: |\n// Full instruction body in markdown (multi-line YAML literal block)\n//\n// Key differences from Claude:\n// - File extension is .yaml, not .md\n// - No markdown frontmatter — the entire file is YAML\n// - Instructions go into the `system_prompt` key as a literal block scalar\n//\n// Generated file path: <outputDir>/<agent-id>.yaml\n// ---------------------------------------------------------------------------\n\nexport class GeminiExporter implements Exporter {\n readonly targetType = 'gemini';\n\n outputPath(ctx: Omit<ExportContext, 'renderedInstructions'>): string {\n const { agent, target, projectRoot } = ctx;\n const outputDir = 'outputDir' in target ? target.outputDir : '.gemini/agents';\n return path.resolve(projectRoot, outputDir, `${agent.id.replace(/::/g, '--')}.yaml`);\n }\n\n export(ctx: ExportContext): ExportResult {\n const { agent, renderedInstructions } = ctx;\n const filePath = this.outputPath(ctx);\n\n // Indent every line of the instructions by 2 spaces for the YAML literal block\n const indentedInstructions = renderedInstructions\n .split('\\n')\n .map((line) => (line.length > 0 ? ` ${line}` : ''))\n .join('\\n');\n\n const content = [\n `name: ${yamlString(agent.name)}`,\n `description: ${yamlString(agent.description)}`,\n `system_prompt: |`,\n indentedInstructions,\n '',\n ].join('\\n');\n\n const changed = writeFileIfChanged(filePath, content);\n return { outputPath: filePath, content, unchanged: !changed };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap a string in double quotes if it contains characters that would\n * need quoting in a YAML flow scalar (colon, hash, special chars).\n */\nfunction yamlString(value: string): string {\n if (/[:#\\[\\]{},&*!|>'\"%@`]/.test(value) || value.startsWith(' ') || value.endsWith(' ')) {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`;\n }\n return value;\n}\n","import { AgentRecord } from '../models/agent.js';\nimport { ProjectConfig, TargetConfig } from '../models/project.js';\nimport { loadTemplate, renderTemplateInstructions } from '../core/templates.js';\nimport { getProjectRoot } from '../utils/fs.js';\nimport { getExporter } from './registry.js';\nimport { ExportResult, WAIRON_MANAGED_BANNER } from './base.js';\n\n// ---------------------------------------------------------------------------\n// Generate: agent file generation\n//\n// Agents are derived from the SDD spec tree and are written as native subagent\n// files into each target's output dir at the project root. The host AI tool\n// (Claude / Codex / aider) spawns these as its own subagents — wairon does not\n// orchestrate sessions itself, so there is no per-directory or propagation\n// rendering.\n// ---------------------------------------------------------------------------\n\nexport interface GenerateOptions {\n projectRoot?: string;\n filterTargets?: string[];\n /**\n * If set, only generate agents whose domainRoot is in this set.\n * Use the special value 'root' to select agents with no domainRoot.\n */\n filterDomainIds?: string[];\n dryRun?: boolean;\n}\n\nexport interface GenerateSummary {\n agent: AgentRecord;\n results: ExportResult[];\n}\n\nexport function generateAgent(\n agent: AgentRecord,\n projectConfig: ProjectConfig,\n options: GenerateOptions = {},\n): GenerateSummary {\n // Write relative to the BOUND project root (request-scoped), not process.cwd():\n // the layered `generate` cascade binds each subproject's root via\n // runWithProjectRoot so each layer's agents land in its OWN .claude/agents/,\n // and running `generate` from a subdir still targets the project root.\n const projectRoot = options.projectRoot ?? getProjectRoot();\n const template = loadTemplate(agent.template, projectConfig.globalTemplatesDir);\n // Prepend the managed marker so `generate` can later reconcile/prune this file\n // safely (see WAIRON_MANAGED_MARKER). It is an HTML comment — inert in the\n // agent's instructions for every markdown-based target.\n const rendered = `${WAIRON_MANAGED_BANNER}\\n${renderTemplateInstructions(template, buildVars(agent))}`;\n const results: ExportResult[] = [];\n\n for (const agentTarget of agent.targets) {\n const targetConfig = resolveTargetConfig(agentTarget, projectConfig);\n if (!targetConfig) continue;\n if (options.filterTargets) {\n const type = 'type' in targetConfig ? targetConfig.type : targetConfig;\n if (!options.filterTargets.includes(type as string)) continue;\n }\n if (!options.dryRun) {\n results.push(getExporter(targetConfig).export({\n agent, template, renderedInstructions: rendered, projectRoot, target: targetConfig,\n }));\n }\n }\n\n return { agent, results };\n}\n\nexport function generateAll(\n agents: AgentRecord[],\n projectConfig: ProjectConfig,\n options: GenerateOptions = {},\n): GenerateSummary[] {\n let pool = agents;\n\n if (options.filterDomainIds && options.filterDomainIds.length > 0) {\n const ids = new Set(options.filterDomainIds);\n pool = agents.filter((a) => ids.has(a.domainRoot ?? 'root'));\n }\n\n return pool.map((agent) => generateAgent(agent, projectConfig, options));\n}\n\n// ---------------------------------------------------------------------------\n// Template variable builder\n// ---------------------------------------------------------------------------\n\nfunction buildVars(agent: AgentRecord): Record<string, string> {\n return {\n agentId: agent.id,\n agentName: agent.name,\n agentDescription: agent.description,\n ownedPaths: agent.ownedPaths.join('\\n'),\n tags: agent.tags.join(', '),\n renderContext: 'root',\n contextNote: '',\n domainPath: '.',\n domainName: '',\n variantGuidance: agent.variantGuidance ?? '',\n };\n}\n\n/**\n * Match an agent target to the project's TargetConfig.\n */\nfunction resolveTargetConfig(\n agentTarget: AgentRecord['targets'][number],\n projectConfig: ProjectConfig,\n): TargetConfig | undefined {\n const targetType = typeof agentTarget === 'string' ? agentTarget : agentTarget.type;\n return projectConfig.targets.find((t) => {\n if (typeof t === 'string') return t === targetType;\n return t.type === targetType;\n }) as TargetConfig | undefined;\n}\n","import { Exporter } from './base.js';\nimport { ClaudeExporter } from './claude.js';\nimport { CustomExporter } from './custom.js';\nimport { GeminiExporter } from './gemini.js';\nimport { TargetConfig } from '../models/project.js';\nimport { WaironError } from '../utils/errors.js';\n\n// ---------------------------------------------------------------------------\n// Exporter registry\n//\n// Maps target types to their Exporter implementations.\n// To add a new built-in target, register it here.\n// ---------------------------------------------------------------------------\n\nconst EXPORTERS = new Map<string, Exporter>([\n ['claude', new ClaudeExporter()],\n ['gemini', new GeminiExporter()],\n ['agy', new GeminiExporter()],\n ['cursor', new ClaudeExporter()],\n ['copilot', new ClaudeExporter()],\n ['codex', new ClaudeExporter()],\n ['custom', new CustomExporter()],\n]);\n\n/**\n * Return the exporter for a given target config.\n */\nexport function getExporter(target: TargetConfig): Exporter {\n const type = typeof target === 'string' ? target : target.type;\n const exporter = EXPORTERS.get(type);\n if (!exporter) {\n throw new WaironError(`No exporter registered for target type: \"${type}\"`);\n }\n return exporter;\n}\n\n/**\n * Register a custom exporter (for programmatic use / future plugin support).\n */\nexport function registerExporter(type: string, exporter: Exporter): void {\n EXPORTERS.set(type, exporter);\n}\n","export * from './errors.js';\nexport * from './fs.js';\nexport * from './logger.js';\nexport * from './yaml.js';\n","import chalk from 'chalk';\n\n// ---------------------------------------------------------------------------\n// Simple leveled logger for CLI output\n// ---------------------------------------------------------------------------\n\nexport type LogLevel = 'silent' | 'info' | 'verbose';\n\nlet currentLevel: LogLevel = 'info';\n\nexport function setLogLevel(level: LogLevel): void {\n currentLevel = level;\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n if (currentLevel === 'silent') return false;\n if (currentLevel === 'info') return level === 'info';\n return true; // verbose: log everything\n}\n\nexport const logger = {\n info(message: string): void {\n if (shouldLog('info')) {\n console.log(chalk.cyan('ℹ') + ' ' + message);\n }\n },\n\n success(message: string): void {\n if (shouldLog('info')) {\n console.log(chalk.green('✔') + ' ' + message);\n }\n },\n\n warn(message: string): void {\n if (shouldLog('info')) {\n console.warn(chalk.yellow('⚠') + ' ' + chalk.yellow(message));\n }\n },\n\n error(message: string): void {\n // Errors always surface regardless of level\n console.error(chalk.red('✖') + ' ' + chalk.red(message));\n },\n\n verbose(message: string): void {\n if (shouldLog('verbose')) {\n console.log(chalk.gray('·') + ' ' + chalk.gray(message));\n }\n },\n\n /**\n * Print a blank line — use sparingly for visual separation.\n */\n blank(): void {\n if (currentLevel !== 'silent') console.log();\n },\n\n /**\n * Print a section header.\n */\n header(title: string): void {\n if (currentLevel !== 'silent') {\n console.log();\n console.log(chalk.bold.white(title));\n console.log(chalk.gray('─'.repeat(title.length)));\n }\n },\n};\n"],"mappings":"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AA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACjRjB,SAAS,kBAAkB,UAAkB,MAAsB;AACxE,QAAM,OAAO,CAAC,MAAsB,EAAE,YAAY,EAAE,QAAQ,eAAe,GAAG,EAAE,QAAQ,YAAY,EAAE;AACtG,SAAO,GAAG,KAAK,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC;AACxC;AAwDO,SAAS,kBAAoC;AAClD,SAAO,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,UAAU,CAAC,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC,GAAG,UAAU,CAAC,GAAG,YAAY,CAAC,GAAG,YAAY,CAAC,GAAG,QAAQ,CAAC,EAAE;AAClJ;AAeO,SAAS,iBAAyB;AACvC,SAAO,QAAQ,IAAI,oBAAyB,WAAQ,YAAQ,GAAG,WAAW,OAAO;AACnF;AAMO,SAAS,aAAa,KAA4B;AACvD,aAAW,QAAQ,kBAAkB;AACnC,UAAM,IAAS,WAAK,KAAK,IAAI;AAC7B,QAAO,eAAW,CAAC,EAAG,QAAO;AAAA,EAC/B;AACA,SAAO;AACT;AAOO,SAAS,cAAc,KAAuB;AACnD,MAAI;AACJ,MAAI;AACF,cAAa,gBAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,EACvD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,OAAiB,CAAC;AACxB,aAAW,KAAK,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,GAAG;AACpE,UAAM,OAAY,WAAK,KAAK,EAAE,IAAI;AAClC,QAAI,EAAE,YAAY,GAAG;AACnB,UAAI,aAAa,IAAI,EAAG,MAAK,KAAK,IAAI;AAAA,IACxC,WAAW,qBAAqB,KAAK,EAAE,IAAI,GAAG;AAC5C,WAAK,KAAK,IAAI;AAAA,IAChB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,GAA0B;AAC9C,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,SAAS,YAAY,MAAM,QAAQ,EAAE,KAAK,KAAK,OAAO,EAAE,UAAU;AACpF;AAEA,SAAS,UAAU,KAAuB,MAAuB,KAAa,OAAkB,SAAuB;AACrH,MAAI,UAAU,KAAK,KAAK,IAAI;AAC5B,MAAI,MAAM,KAAK,EAAE,MAAM,KAAK,MAAM,KAAK,OAAO,SAAS,KAAK,QAAQ,CAAC;AAErE,SAAO,OAAO,IAAI,UAAU,KAAK,QAAQ;AACzC,aAAW,CAAC,MAAM,GAAG,KAAK,OAAO,QAAQ,KAAK,SAAS,GAAG;AACxD,UAAM,MAAM,KAAK,YAAY;AAC7B,UAAM,WAAW,IAAI,UAAU,GAAG;AAClC,QAAI,UAAU,GAAG,IAAI,WACjB;AAAA,MACA,iBAAiB,EAAE,GAAG,SAAS,iBAAiB,GAAG,IAAI,gBAAgB;AAAA,MACvE,iBAAiB,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,SAAS,iBAAiB,GAAG,IAAI,eAAe,CAAC,CAAC;AAAA,IACrF,IACE;AAAA,EACN;AAGA,aAAW,KAAK,KAAK,OAAQ,KAAI,OAAO,KAAK,EAAE,GAAG,GAAG,MAAM,KAAK,MAAM,aAAa,KAAK,SAAS,YAAiB,cAAQ,SAAS,EAAE,MAAM,EAAE,CAAC;AAC9I,aAAW,KAAK,KAAK,SAAU,KAAI,SAAS,KAAK,EAAE,GAAG,GAAG,MAAM,KAAK,KAAK,CAAC;AAE1E,MAAI,aAAa,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,IAAI,YAAY,GAAG,KAAK,UAAU,CAAC,CAAC;AAErE,aAAW,KAAK,KAAK,WAAY,KAAI,WAAW,KAAK,EAAE,GAAG,GAAG,MAAM,KAAK,MAAM,UAAU,kBAAkB,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC;AAChI;AAgBO,SAAS,eAAe,KAAa,aAA6B;AACvE,QAAM,WAAW,IAAI,WAAW,GAAG,KAAU,iBAAW,GAAG,KAAK,WAAW,GAAG;AAC9E,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,WAAgB,cAAQ,aAAa,GAAG;AAC9C,MAAO,eAAW,QAAQ,KAAQ,aAAS,QAAQ,EAAE,YAAY,GAAG;AAClE,UAAM,QAAQ,aAAa,QAAQ;AACnC,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,qCAAqC,iBAAiB,KAAK,KAAK,CAAC,GAAG;AAChG,WAAO;AAAA,EACT;AACA,SAAO;AACT;AASO,SAAS,aAAa,QAAgB,aAA6D;AACxG,MAAI,WAAW,MAAM,GAAG;AACtB,UAAM,MAAM,aAAa,MAAM;AAC/B,QAAI,OAAO,KAAM,OAAM,IAAI,MAAM,yBAAyB;AAC1D,WAAO,EAAE,GAAG,sBAAsB,MAAM,GAAG,GAAG,OAAO,CAAC,EAAE;AAAA,EAC1D;AACA,QAAM,UAAM,6BAAmB,WAAK,aAAa,cAAc,CAAC;AAChE,QAAM,SAAkB,IAAI,MAAM;AAClC,QAAM,MAAQ,QAAkC,WAAW;AAC3D,QAAM,SAAS,sBAAsB,MAAM;AAAA,IACzC,MAAM,IAAI,QAAQ;AAAA,IAClB,SAAS,IAAI;AAAA,IACb,UAAU,IAAI,YAAY,CAAC;AAAA,IAC3B,WAAW,IAAI,aAAa,CAAC;AAAA,IAC7B,QAAQ,IAAI,UAAU,CAAC;AAAA,IACvB,UAAU,IAAI,YAAY,CAAC;AAAA,IAC3B,YAAY,IAAI,cAAc,CAAC;AAAA,IAC/B,YAAY,IAAI,cAAc,CAAC;AAAA,EACjC,CAAC;AACD,QAAM,QAAmB,CAAC;AAC1B,aAAW,KAAM,IAAI,SAAmC,CAAC,GAAG;AAC1D,QAAI,CAAC,aAAa,CAAC,EAAG,OAAM,IAAI,MAAM,gFAAgF;AACtH,UAAM,KAAK,CAAC;AAAA,EACd;AACA,SAAO,EAAE,GAAG,QAAQ,MAAM;AAC5B;AAEO,SAAS,mBAAmB,MAAiB,aAAuC;AACzF,QAAM,MAAM,gBAAgB;AAC5B,aAAW,EAAE,KAAK,MAAM,KAAK,MAAM;AACjC,QAAI;AACF,YAAM,SAAS,eAAe,KAAK,WAAW;AAC9C,YAAM,WAAW,aAAa,QAAQ,WAAW;AACjD,gBAAU,KAAK,UAAU,KAAK,OAAY,cAAQ,MAAM,CAAC;AACzD,iBAAW,KAAK,SAAS,MAAO,KAAI,MAAM,KAAK,CAAC;AAAA,IAClD,SAAS,GAAG;AACV,UAAI,OAAO,KAAK,mBAAmB,GAAG,qBAAqB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,IACzG;AAAA,EACF;AACA,SAAO;AACT;AAMO,SAAS,eAAe,UAAoB,aAAuC;AACxF,SAAO,mBAAmB,SAAS,IAAI,UAAQ,EAAE,KAAK,OAAO,UAAmB,EAAE,GAAG,WAAW;AAClG;AASO,SAAS,wBAA0C;AACxD,MAAI;AACF,UAAM,SAAS,kBAAkB;AACjC,UAAM,OAAkB,CAAC;AACzB,QAAI,OAAO,YAAY,kBAAkB,MAAM;AAC7C,iBAAW,OAAO,cAAc,eAAe,CAAC,EAAG,MAAK,KAAK,EAAE,KAAK,OAAO,SAAS,CAAC;AAAA,IACvF;AACA,eAAW,OAAO,OAAO,YAAY,SAAS,CAAC,EAAG,MAAK,KAAK,EAAE,KAAK,OAAO,UAAU,CAAC;AACrF,QAAI,KAAK,WAAW,EAAG,QAAO,gBAAgB;AAC9C,WAAO,mBAAmB,MAAM,eAAe,CAAC;AAAA,EAClD,QAAQ;AACN,WAAO,gBAAgB;AAAA,EACzB;AACF;AA7ZA,IAAAC,KACAC,KACAC,OACA,eACAC,aAmCa,kBAgCA,uBAWA,iBAYA,kBAcA,yBAOP,eAcO,qBAuCA,uBA4EA,kBAwEP;AA5TN;AAAA;AAAA;AAAA,IAAAH,MAAoB;AACpB,IAAAC,MAAoB;AACpB,IAAAC,QAAsB;AACtB,oBAA8B;AAC9B,IAAAC,cAAkB;AAClB;AACA;AACA;AAEA;AA8BO,IAAM,mBAAmB,cAAE,OAAO;AAAA,MACvC,QAAQ,cAAE,KAAK,CAAC,gBAAgB,iBAAiB,SAAS,CAAC,EAAE,QAAQ,SAAS;AAAA,MAC9E,sBAAsB,cAAE,MAAM,cAAE,OAAO,EAAE,OAAO,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ,cAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,MACpH,wBAAwB,cAAE,MAAM,cAAE,OAAO,EAAE,OAAO,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,QAAQ,cAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUtH,cAAc,cAAE,MAAM,cAAE,OAAO;AAAA,QAC7B,MAAM,cAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,QACtC,IAAI,cAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,QACpC,QAAQ,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MAC1B,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,MACd,OAAO,kBAAkB,QAAQ,EAAE,SAAS;AAAA,IAC9C,CAAC;AAaM,IAAM,wBAAwB,cAAE,OAAO;AAAA,MAC5C,iBAAiB,cAAE,OAAO,cAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,MAChD,iBAAiB,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,IACjD,CAAC;AAQM,IAAM,kBAAkB,cAAE,OAAO;AAAA,MACtC,IAAI,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACpB,QAAQ,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACxB,SAAS,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,IACzC,CAAC;AAQM,IAAM,mBAAmB,cAAE,OAAO;AAAA,MACvC,IAAI,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACpB,SAAS,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACzB,aAAa,cAAE,OAAO,EAAE,SAAS;AAAA,MACjC,UAAU,cAAE,OAAO,cAAE,QAAQ,CAAC,EAAE,SAAS;AAAA,IAC3C,CAAC;AASM,IAAM,0BAA0B,cAAE,OAAO;AAAA,MAC9C,eAAe,cAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS;AAAA,MACnD,SAAS,cAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS;AAAA,MAC7C,IAAI,cAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,IACjC,CAAC;AAGD,IAAM,gBAAgB;AAAA;AAAA,MAEpB,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACtB,UAAU,cAAE,KAAK,CAAC,WAAW,OAAO,CAAC,EAAE,QAAQ,SAAS;AAAA;AAAA,MAExD,QAAQ,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC1B;AAQO,IAAM,sBAAsB,cAAE,mBAAmB,QAAQ;AAAA,MAC9D,cAAE,OAAO;AAAA,QACP,MAAM,cAAE,QAAQ,aAAa;AAAA,QAC7B,GAAG;AAAA,QACH,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,UAAU,cAAE,MAAM,cAAE,KAAK,CAAC,aAAa,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,aAAa,MAAM,CAAC;AAAA,MAChF,CAAC;AAAA,MACD,cAAE,OAAO;AAAA,QACP,MAAM,cAAE,QAAQ,eAAe;AAAA,QAC/B,GAAG;AAAA,QACH,IAAI;AAAA,QACJ,OAAO,cAAE,KAAK,CAAC,aAAa,aAAa,gBAAgB,CAAC,EAAE,QAAQ,WAAW;AAAA;AAAA,QAE/E,OAAO,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,QAEvB,QAAQ,cAAE,MAAM,cAAE,OAAO,CAAC,EAAE,SAAS;AAAA,MACvC,CAAC;AAAA,MACD,cAAE,OAAO;AAAA,QACP,MAAM,cAAE,QAAQ,gBAAgB;AAAA,QAChC,GAAG;AAAA,QACH,IAAI;AAAA;AAAA,QAEJ,WAAW,cAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,SAAS;AAAA;AAAA,QAE/C,aAAa,cAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,MAC1C,CAAC;AAAA,IACH,CAAC;AAYM,IAAM,wBAAwB,cAAE,OAAO;AAAA,MAC5C,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA,MACtB,SAAS,cAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,UAAU,cAAE,OAAO,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AAAA,MAC/C,WAAW,cAAE,OAAO,qBAAqB,EAAE,QAAQ,CAAC,CAAC;AAAA,MACrD,QAAQ,cAAE,MAAM,eAAe,EAAE,QAAQ,CAAC,CAAC;AAAA,MAC3C,UAAU,cAAE,MAAM,gBAAgB,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA,MAE9C,YAAY,cAAE,MAAM,mBAAmB,EAAE,QAAQ,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOnD,YAAY,cAAE,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,IACnD,CAAC;AA4DM,IAAM,mBAAmB,CAAC,aAAa,YAAY,YAAY,WAAW,aAAa,UAAU;AAwExG,IAAM,aAAa,CAAC,MAAuB,YAAY,KAAK,CAAC;AAAA;AAAA;;;AC5T7D,IAmCa;AAnCb;AAAA;AAAA;AAmCO,IAAM,mBAAmB;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAAA;;;AC3CA,IAMa;AANb;AAAA;AAAA;AAMO,IAAM,gBAAyB;AAAA,MACpC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,sCAAsC;AAAA,QAC9G,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,sCAAsC;AAAA,QAC9G,EAAE,MAAM,sBAAsB,iBAAiB,WAAW,SAAS,6CAA6C;AAAA,QAChH,EAAE,MAAM,+BAA+B,iBAAiB,SAAS,SAAS,wCAAwC;AAAA,QAClH,EAAE,MAAM,+BAA+B,iBAAiB,SAAS,SAAS,gDAAgD;AAAA,QAC1H,EAAE,MAAM,+BAA+B,iBAAiB,SAAS,SAAS,8DAA8D;AAAA,MAC1I;AAAA,MACA,MAAM,KAAK;AAET,mBAAW,OAAO,IAAI,YAAY;AAChC,cAAI,IAAI,WAAW,WAAW,IAAI,WAAW,UAAU;AACrD,gBAAI,SAAS,WAAW,2BAA2B,cAAc,IAAI,EAAE,gCAAgC,IAAI,IAAI,IAAI;AAAA,UACrH;AAAA,QACF;AACA,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,IAAI,iBAAiB,KAAK,EAAE,GAAG;AACjC,gBAAI,SAAS,WAAW,2BAA2B,cAAc,KAAK,EAAE,gCAAgC,KAAK,IAAI,IAAI;AAAA,UACvH;AAAA,QACF;AAGA,mBAAW,OAAO,IAAI,YAAY;AAChC,gBAAM,aAAa,IAAI,WAAW,WAAW,IAAI,WAAW;AAC5D,cAAI,CAAC,IAAI,gBAAiB,IAAI,iBAAiB,IAAI,OAAO,QAAQ,CAAC,IAAI,GAAG,SAAS,IAAI,GAAI;AACzF,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,IAAI,EAAE,gCAAgC,IAAI,OAAO,IAAI;AAAA,cACnE,IAAI;AAAA,cACJ;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAC/C,cAAI,CAAC,IAAI,aAAa,IAAI,KAAK,SAAS,GAAG;AACzC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,wCAAwC,KAAK,SAAS;AAAA,cAC3E,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,SAAS,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW;AACtG,cAAI,CAAC,IAAI,aAAa,IAAI,KAAK,SAAS,GAAG;AACzC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,wCAAwC,KAAK,SAAS;AAAA,cAC3E,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK,QAAQ;AAChE,gBAAM,aAAa,KAAK,WAAW,WAAW,KAAK,WAAW,YAAa,aAAa,IAAI,iBAAiB,SAAS,SAAS,KAAK,SAAS,WAAW,WAAW,SAAS,WAAW;AACvL,cAAI,CAAC,IAAI,aAAa,IAAI,KAAK,QAAQ,GAAG;AACxC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,iDAAiD,KAAK,QAAQ;AAAA,cACxF,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACxFA,IAea;AAfb;AAAA;AAAA;AACA;AAcO,IAAM,qBAA8B;AAAA,MACzC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,+BAA+B,iBAAiB,SAAS,SAAS,kDAAkD;AAAA,QAC5H,EAAE,MAAM,4BAA4B,iBAAiB,SAAS,SAAS,mDAAmD;AAAA,QAC1H,EAAE,MAAM,eAAe,iBAAiB,WAAW,SAAS,4GAAuG;AAAA,MACrK;AAAA,MACA,MAAM,KAAK;AAET,mBAAW,KAAK,IAAI,OAAO;AACzB,gBAAM,MAAM,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,EAAE,SAAS;AACzD,gBAAM,aAAa,MAAO,IAAI,WAAW,WAAW,IAAI,WAAW,WAAY;AAC/E,cAAI,EAAE,aAAa,CAAC,IAAI,aAAa,IAAI,EAAE,SAAS,GAAG;AACrD,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,SAAS,EAAE,EAAE,wCAAwC,EAAE,SAAS;AAAA,cAChE,EAAE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAKA,eAAK,CAAC,EAAE,UAAU,EAAE,OAAO,WAAW,OAAO,CAAC,EAAE,WAAW,EAAE,QAAQ,WAAW,IAAI;AAClF,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI;AAAA,cACzB,EAAE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,cAAI,EAAE,QAAQ;AACZ,kBAAM,eAAe,IAAI;AAAA,cACvB,MAAM,KAAK,oBAAoB,EAAE,IAAI,CAAC,EAAE,IAAI,OAAK,EAAE,YAAY,CAAC;AAAA,YAClE;AACA,uBAAW,SAAS,EAAE,QAAQ;AAC5B,oBAAM,OAAO,uBAAuB,MAAM,IAAI;AAC9C,yBAAW,OAAO,MAAM;AACtB,sBAAM,WAAW,IAAI,YAAY;AACjC,oBAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B;AAAA,gBACF;AACA,oBAAI,aAAa,IAAI,QAAQ,GAAG;AAC9B;AAAA,gBACF;AACA,sBAAM,WAAW,IAAI,MAAM,KAAK,UAAQ;AACtC,wBAAM,kBAAkB,KAAK,aAAa,CAAC,KAAK,GAAG,WAAW,GAAG,KAAK,SAAS,IAAI,IAC/E,GAAG,KAAK,SAAS,KAAK,KAAK,EAAE,KAC7B,KAAK;AACT,yBAAO,aAAa,KAAK,eAAe;AAAA,gBAC1C,CAAC;AACD,oBAAI,CAAC,UAAU;AACb,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,SAAS,EAAE,EAAE,YAAY,MAAM,IAAI,gCAAgC,GAAG,SAAS,MAAM,IAAI;AAAA,oBACzF,EAAE;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,SAAS,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW;AACtG,gBAAM,oBAAoB,IAAI;AAAA,YAC5B,MAAM,KAAK,oBAAoB,KAAK,IAAI,CAAC,EAAE,IAAI,OAAK,EAAE,YAAY,CAAC;AAAA,UACrE;AACA,qBAAW,KAAK,KAAK,SAAS;AAC5B,kBAAM,iBAAiB,IAAI;AAAA,cACzB,MAAM,KAAK,4BAA4B,EAAE,SAAS,CAAC,EAAE,IAAI,OAAK,EAAE,YAAY,CAAC;AAAA,YAC/E;AACA,kBAAM,cAAc,oBAAI,IAAI,CAAC,GAAG,mBAAmB,GAAG,cAAc,CAAC;AACrE,kBAAM,OAAO,eAAe,CAAC;AAC7B,uBAAW,OAAO,MAAM;AACtB,kBAAI,CAAC,IAAI,eAAe,KAAK,WAAW,GAAG;AACzC,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,WAAW,EAAE,IAAI,mBAAmB,KAAK,EAAE,gCAAgC,GAAG;AAAA,kBAC9E,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACpFO,SAAS,iBAA0B;AACxC,QAAM,OAAO;AAAA,IACX,QAAQ,eAAe;AAAA,IACvB,YAAY,mBAAmB;AAAA,IAC/B,YAAY,mBAAmB;AAAA,IAC/B,YAAY,mBAAmB;AAAA,IAC/B,iBAAiB,wBAAwB;AAAA,IACzC,OAAO,cAAc;AAAA,EACvB;AACA,QAAM,SAAgB,kBAAW,QAAQ,EAAE,OAAO,aAAa,IAAI,CAAC,EAAE,OAAO,KAAK;AAClF,SAAO,EAAE,WAAW,UAAU,OAAO;AACvC;AAGO,SAAS,cAAc,GAA+B,GAAwC;AACnG,SAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE;AACrE;AAIA,SAAS,aAAa,OAAwB;AAC5C,SAAO,KAAK,UAAU,SAAS,KAAK,CAAC;AACvC;AAEA,SAAS,SAAS,GAAqB;AACrC,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,EAAE,IAAI,QAAQ;AAC3C,MAAI,KAAK,OAAO,MAAM,UAAU;AAC9B,UAAM,MAAM;AACZ,UAAM,MAA+B,CAAC;AACtC,eAAW,KAAK,OAAO,KAAK,GAAG,EAAE,KAAK,GAAG;AACvC,UAAI,MAAM,eAAe,MAAM,YAAa;AAC5C,UAAI,CAAC,IAAI,SAAS,IAAI,CAAC,CAAC;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAhEA;AAAA;AAAA;AAAA;AAAA,aAAwB;AACxB,IAAAC;AAAA;AAAA;;;ACqCA,SAAS,UAAU,SAAiB,YAAkD;AACpF,QAAM,UAAU,QAAQ,KAAK,EAAE,QAAQ,uBAAuB,IAAI,EAAE,KAAK;AACzE,QAAM,aAAa,aAAa,KAAK,OAAO;AAC5C,MAAI,YAAY;AACd,WAAO,EAAE,MAAM,SAAS,OAAO,UAAU,WAAW,CAAC,GAAG,UAAU,EAAE;AAAA,EACtE;AACA,QAAM,QAAQ,QAAQ,YAAY;AAClC,MAAI,SAAS,YAAY;AACvB,UAAM,IAAI,WAAW,KAAK;AAC1B,WAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;AAAA,EAC9B;AAEA,QAAM,QAAQ,QAAQ,MAAM,OAAO,EAAE,IAAI,EAAG,YAAY,EAAE,QAAQ,gBAAgB,EAAE;AACpF,QAAM,MAAM,CAAC,GAAG,UAAU,EAAE,KAAK,QAAM,GAAG,YAAY,MAAM,KAAK;AACjE,MAAI,IAAK,QAAO,EAAE,MAAM,wBAAwB,GAAG,GAAG;AACtD,SAAO,EAAE,MAAM,UAAU,aAAa,oBAAoB,OAAO,GAAG;AACtE;AAEA,SAAS,aAAa,QAAyB,YAAkD;AAC/F,QAAM,WAAW,OAAO;AACxB,QAAM,WAAW,YAAY,SAAS,cAAc,SAAS,SAAS,OAAO,YAAY,IAAI;AAC7F,QAAM,YAAY,oBAAI,IAAI,CAAC,QAAQ,OAAO,OAAO,CAAC;AAClD,QAAM,SAAS,OAAO,UAAU,CAAC;AAEjC,QAAM,KAA8B;AAAA,IAClC,aAAa,OAAO;AAAA,IACpB,SAAS,OAAO;AAAA,IAChB,WAAW;AAAA,MACT,OAAO;AAAA,QACL,aAAa,OAAO,WAAW;AAAA,QAC/B,GAAI,OAAO,WAAW,OAAO,QAAQ,YAAY,MAAM,SACnD,EAAE,SAAS,EAAE,oBAAoB,EAAE,QAAQ,UAAU,OAAO,SAAS,UAAU,EAAE,EAAE,EAAE,IACrF,CAAC;AAAA,MACP;AAAA,IACF;AAAA,EACF;AACA,MAAI,OAAO,YAAY,OAAQ,IAAG,qBAAqB,IAAI,OAAO;AAClE,MAAI,OAAO,OAAQ,IAAG,iBAAiB,IAAI,OAAO;AAGlD,MAAI,OAAO,OAAO,OAAO,KAAK,OAAO,GAAG,EAAE,OAAQ,IAAG,cAAc,IAAI,OAAO;AAE9E,MAAI,OAAO,QAAQ;AACjB,QAAI,UAAU,IAAI,QAAQ,GAAG;AAC3B,SAAG,cAAc;AAAA,QACf,UAAU;AAAA,QACV,SAAS;AAAA,UACP,oBAAoB;AAAA,YAClB,QAAQ;AAAA,cACN,MAAM;AAAA,cACN,YAAY,OAAO,YAAY,OAAO,IAAI,OAAK,CAAC,EAAE,MAAM,UAAU,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,cACvF,UAAU,OAAO,OAAO,OAAK,CAAC,EAAE,QAAQ,EAAE,IAAI,OAAK,EAAE,IAAI;AAAA,YAC3D;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,SAAG,aAAa,OAAO,IAAI,QAAM;AAAA,QAC/B,MAAM,EAAE;AAAA,QACR,IAAI;AAAA,QACJ,UAAU,CAAC,EAAE;AAAA,QACb,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,QACtD,QAAQ,UAAU,EAAE,MAAM,UAAU;AAAA,MACtC,EAAE;AAAA,IACJ;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,UAAU,UAAmC;AAC3D,QAAM,aAAa,IAAI,IAAI,SAAS,MAAM,IAAI,OAAK,EAAE,EAAE,CAAC;AACxD,QAAM,cAAc,SAAS,WAAW,OAAO,OAC7C,EAAE,SAAS,UAAU,EAAE,QAAQ,KAAK,OAAK,EAAE,UAAU,cAAc,MAAM,CAAC;AAE5E,QAAM,QAAiD,CAAC;AACxD,aAAW,SAAS,aAAa;AAC/B,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,WAAW,OAAO;AACxB,UAAI,CAAC,YAAY,SAAS,cAAc,OAAQ;AAChD,YAAM,IAAI,SAAS,KAAK,WAAW,GAAG,IAAI,SAAS,OAAO,IAAI,SAAS,IAAI;AAC3E,YAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC;AACxB,YAAM,CAAC,EAAE,SAAS,OAAO,YAAY,CAAC,IAAI;AAAA,QACxC,MAAM,CAAC,MAAM,EAAE;AAAA,QACf,GAAG,aAAa,QAAQ,UAAU;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAmC,CAAC;AAC1C,aAAW,KAAK,SAAS,OAAO;AAC9B,YAAQ,EAAE,EAAE,IAAI;AAAA,MACd,MAAM;AAAA,MACN,OAAO,EAAE;AAAA,MACT,YAAY,OAAO,YAAY,EAAE,OAAO,IAAI,OAAK,CAAC,EAAE,MAAM,UAAU,EAAE,MAAM,UAAU,CAAC,CAAC,CAAC;AAAA,MACzF,UAAU,EAAE,OAAO,OAAO,OAAK,CAAC,EAAE,QAAQ,EAAE,IAAI,OAAK,EAAE,IAAI;AAAA,IAC7D;AAAA,EACF;AAEA,QAAM,MAAM;AAAA,IACV,SAAS;AAAA,IACT,MAAM;AAAA,MACJ,OAAO,SAAS;AAAA,MAChB,SAAS,SAAS,WAAW;AAAA,MAC7B,GAAI,SAAS,UAAU,EAAE,qBAAqB,SAAS,QAAQ,IAAI,CAAC;AAAA,MACpE,mBAAmB,SAAS;AAAA,MAC5B,yBAAyB,SAAS;AAAA,IACpC;AAAA,IACA;AAAA,IACA,GAAI,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,CAAC;AAAA,EACnE;AACA,SAAO,KAAK,UAAU,KAAK,MAAM,CAAC;AACpC;AAMO,SAAS,kBAAkB,MAAuB;AACvD,MAAI;AACF,UAAM,SAAc,WAAK,IAAI;AAC7B,WAAO,CAAC,CAAC,UAAU,OAAO,WAAW,YAAY,OAAQ,OAAiC,YAAY;AAAA,EACxG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB,QAAqD;AAC9E,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,MAAM,OAAO;AACnB,MAAI,OAAO,QAAQ,SAAU,QAAO,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK;AAC5D,MAAI,OAAO,SAAS,SAAS;AAC3B,WAAO,GAAG,kBAAkB,OAAO,KAAgC,CAAC;AAAA,EACtE;AACA,QAAM,IAAI,OAAO;AACjB,MAAI,MAAM,UAAW,QAAO;AAC5B,MAAI,OAAO,MAAM,YAAY,MAAM,SAAU,QAAO;AACpD,SAAO;AACT;AAEO,SAAS,YAAY,UAAkB,aAAsC;AAClF,MAAI;AACJ,MAAI;AACF,aAAc,WAAK,QAAQ;AAAA,EAC7B,SAAS,GAAG;AACV,UAAM,IAAI,MAAM,yDAAyD,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,GAAG;AAAA,EACxH;AACA,MAAI,CAAC,UAAU,OAAO,WAAW,YAAY,OAAO,OAAO,YAAY,YAAY,OAAO,OAAO,UAAU,UAAU;AACnH,UAAM,IAAI,MAAM,wEAAwE;AAAA,EAC1F;AAEA,QAAM,OAAQ,OAAO,QAAQ,CAAC;AAC9B,QAAM,UAA6B,CAAC;AACpC,aAAW,CAAC,SAAS,GAAG,KAAK,OAAO,QAAQ,OAAO,KAAgD,GAAG;AACpG,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,OAAO,CAAC,CAAC,GAAG;AACrD,UAAI,CAAC,CAAC,OAAO,QAAQ,OAAO,UAAU,SAAS,WAAW,MAAM,EAAE,SAAS,IAAI,EAAG;AAClF,YAAM,KAAM,SAAS,CAAC;AACtB,YAAM,OAAO,OAAO,GAAG,gBAAgB,YAAY,kBAAkB,KAAK,GAAG,WAAW,IACpF,GAAG,cACH,GAAG,IAAI,IAAI,QAAQ,QAAQ,kBAAkB,GAAG,EAAE,QAAQ,YAAY,EAAE,CAAC;AAE7E,YAAM,SAAqF,CAAC;AAC5F,iBAAW,KAAM,GAAG,cAAwD,CAAC,GAAG;AAC9E,YAAI,OAAO,EAAE,SAAS,SAAU;AAChC,eAAO,KAAK;AAAA,UACV,MAAM,EAAE;AAAA,UACR,MAAM,kBAAkB,EAAE,MAAiC;AAAA,UAC3D,GAAI,EAAE,aAAa,OAAO,CAAC,IAAI,EAAE,UAAU,KAAK;AAAA,UAChD,GAAI,OAAO,EAAE,gBAAgB,WAAW,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,QAC5E,CAAC;AAAA,MACH;AACA,YAAM,aAAe,GAAG,aAAyC,UAAsD,kBAAkB,GAAG;AAC5I,UAAI,YAAY;AACd,cAAM,QAAS,WAAW,cAAc,CAAC;AACzC,cAAM,WAAW,IAAI,IAAK,WAAW,YAAqC,CAAC,CAAC;AAC5E,YAAI,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC7B,qBAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,GAAG;AACpD,mBAAO,KAAK,EAAE,MAAM,OAAO,MAAM,kBAAkB,OAAO,GAAG,GAAI,SAAS,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,UAAU,KAAK,EAAG,CAAC;AAAA,UACnH;AAAA,QACF,OAAO;AACL,iBAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,kBAAkB,UAAU,EAAE,CAAC;AAAA,QACnE;AAAA,MACF;AAEA,YAAM,aAAe,GAAG,YAAwD,KAAK,KAC/E,GAAG,YAAwD,KAAK;AACtE,YAAM,iBAAmB,YAAY,UAAsD,kBAAkB,GAAG;AAChH,YAAM,UAAU,iBAAiB,kBAAkB,cAAc,IAAI;AAMrE,YAAM,gBAAgB,GAAG,qBAAqB;AAC9C,YAAM,aAAa,MAAM,QAAQ,aAAa,IAC1C,cAAc,OAAO,CAAC,MAAmB,OAAO,MAAM,YAAY,EAAE,SAAS,CAAC,IAC9E,CAAC;AACL,YAAM,YAAY,GAAG,iBAAiB;AACtC,YAAM,SAAS,cAAc,UAAU,cAAc,UAAU,YAAY;AAE3E,YAAM,SAAS,GAAG,cAAc;AAChC,YAAM,MAAM,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,IACpE,SACD;AAEJ,cAAQ,KAAK;AAAA,QACX;AAAA,QACA,aAAa,OAAO,GAAG,YAAY,WAAW,GAAG,UAAW,OAAO,GAAG,gBAAgB,WAAW,GAAG,cAAc;AAAA,QAClH,WAAW,GAAG,IAAI,IAAI,OAAO,IAAI,OAAK,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC,MAAM,OAAO;AAAA,QACrF;AAAA,QACA;AAAA,QACA,UAAU,EAAE,WAAW,QAAQ,QAAQ,KAAK,YAAY,GAAY,MAAM,QAAQ;AAAA,QAClF,GAAI,WAAW,SAAS,EAAE,WAAW,IAAI,CAAC;AAAA,QAC1C,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,QAC3B,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;AAAA,MACvB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,QAA0B,CAAC;AACjC,QAAM,UAAY,OAAO,YAAwC,WAAW,CAAC;AAC7E,aAAW,CAAC,IAAI,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,UAAM,QAAS,OAAO,cAAc,CAAC;AACrC,UAAM,WAAW,IAAI,IAAK,OAAO,YAAqC,CAAC,CAAC;AACxE,UAAM,KAAK;AAAA,MACT;AAAA,MACA,MAAM,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ;AAAA,MACxD,MAAM;AAAA,MACN,QAAQ,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,OAAO,OAAO;AAAA,QACvD,MAAM;AAAA,QACN,MAAM,kBAAkB,OAAO;AAAA,QAC/B,GAAI,SAAS,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,UAAU,KAAK;AAAA,MAClD,EAAE;AAAA,IACJ,CAAC;AAAA,EACH;AAEA,QAAM,QAA8B;AAAA,IAClC,IAAI,GAAG,WAAW;AAAA,IAClB,MAAM,OAAO,KAAK,UAAU,WAAW,KAAK,QAAQ;AAAA,IACpD,UAAU;AAAA,IACV,MAAM;AAAA,IACN,WAAW,GAAG,WAAW;AAAA,IACzB;AAAA,IACA,SAAS,OAAO,KAAK,gBAAgB,WAAW,KAAK,cAAc,+BAA+B,WAAW;AAAA,IAC7G,GAAI,OAAO,KAAK,YAAY,WAAW,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,EACtE;AAEA,SAAO,sBAAsB,MAAM;AAAA,IACjC;AAAA,IACA,QAAQ;AAAA,IACR,GAAI,OAAO,KAAK,YAAY,WAAW,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,IACpE,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,YAAY,CAAC,KAAK;AAAA,IAClB;AAAA,EACF,CAAC;AACH;AApSA,IAAAC,OAkBM;AAlBN;AAAA;AAAA;AAAA,IAAAA,QAAsB;AACtB;AAiBA,IAAM,aAAgE;AAAA,MACpE,QAAQ,EAAE,MAAM,SAAS;AAAA,MACzB,QAAQ,EAAE,MAAM,SAAS;AAAA,MACzB,OAAO,EAAE,MAAM,SAAS;AAAA,MACxB,SAAS,EAAE,MAAM,SAAS;AAAA,MAC1B,KAAK,EAAE,MAAM,UAAU;AAAA,MACvB,SAAS,EAAE,MAAM,UAAU;AAAA,MAC3B,SAAS,EAAE,MAAM,UAAU;AAAA,MAC3B,MAAM,EAAE,MAAM,UAAU;AAAA,MACxB,MAAM,EAAE,MAAM,UAAU,QAAQ,YAAY;AAAA,MAC5C,UAAU,EAAE,MAAM,UAAU,QAAQ,YAAY;AAAA,MAChD,MAAM,EAAE,MAAM,UAAU,QAAQ,OAAO;AAAA,MACvC,MAAM,EAAE,MAAM,SAAS;AAAA,MACvB,QAAQ,EAAE,MAAM,SAAS;AAAA,MACzB,KAAK,CAAC;AAAA,MACN,SAAS,CAAC;AAAA,MACV,MAAM,CAAC;AAAA,IACT;AAAA;AAAA;;;ACGA,SAAS,YAAY,SAAyB;AAC5C,SAAY,WAAK,SAAS,QAAQ,gBAAgB;AACpD;AAGO,SAAS,aAAa,UAAsC;AACjE,QAAM,MAAO,kBAAwC,QAAQ,YAAY,UAAU;AACnF,SAAO,QAAQ,KAAM,kBAAwC,QAAQ,UAAU,IAAI;AACrF;AAEO,SAAS,gBAAwB;AACtC,QAAM,IAAI,eAAe;AACzB,SAAO,GAAG,EAAE,SAAS,IAAI,EAAE,MAAM;AACnC;AAaA,SAAS,mBAAmB,SAAiC,OAAqC;AAChG,QAAM,WAAW,oBAAI,IAAsB;AAC3C,QAAM,QAAkB,CAAC;AAEzB,QAAM,aAAa,CAAC,QAAsB;AACxC,QAAI,cAAc,IAAI,IAAI,YAAY,CAAC,EAAG;AAC1C,eAAW,QAAQ,OAAO;AACxB,YAAM,cAAc,KAAK,aAAa,CAAC,KAAK,GAAG,WAAW,GAAG,KAAK,SAAS,IAAI,IAC3E,GAAG,KAAK,SAAS,KAAK,KAAK,EAAE,KAC7B,KAAK;AACT,UAAI,aAAa,KAAK,WAAW,KAAK,CAAC,SAAS,IAAI,KAAK,EAAE,GAAG;AAC5D,iBAAS,IAAI,KAAK,IAAI,IAAI;AAC1B,cAAM,KAAK,KAAK,EAAE;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,aAAW,SAAS,SAAS;AAC3B,eAAW,KAAK,MAAM,SAAS;AAC7B,iBAAW,OAAO,eAAe,CAAC,EAAG,YAAW,GAAG;AAAA,IACrD;AAAA,EACF;AACA,SAAO,MAAM,QAAQ;AACnB,UAAM,OAAO,SAAS,IAAI,MAAM,MAAM,CAAE;AACxC,eAAW,SAAS,KAAK,QAAQ;AAC/B,iBAAW,OAAO,uBAAuB,MAAM,IAAI,EAAG,YAAW,GAAG;AAAA,IACtE;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,SAAS,OAAO,CAAC,EAAE,IAAI,QAAM;AAAA,IACtC,IAAI,EAAE;AAAA,IACN,MAAM,EAAE;AAAA,IACR,MAAM,EAAE;AAAA,IACR,QAAQ,EAAE,OAAO,IAAI,QAAM;AAAA,MACzB,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,MACtD,GAAI,EAAE,WAAW,EAAE,UAAU,KAAK,IAAI,CAAC;AAAA,IACzC,EAAE;AAAA,EACJ,EAAE;AACJ;AAQO,SAAS,kBAAkB,aAAsC;AACtE,QAAM,SAAS,eAAe;AAC9B,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,0DAA0D;AAAA,EAC5E;AACA,QAAM,aAAa,mBAAmB;AACtC,QAAM,aAAa,mBAAmB;AACtC,QAAM,aAAa,mBAAmB;AACtC,QAAM,QAAQ,cAAc;AAE5B,QAAM,QAAQ,aAAa,WAAW;AACtC,QAAM,aAAsC,OAAO,oBAAoB,CAAC;AAExE,QAAM,UAAkC,CAAC;AACzC,aAAW,OAAO,YAAY;AAC5B,UAAM,WAAW,IAAI,YAAY;AACjC,QAAI,aAAa,QAAQ,IAAI,MAAO;AACpC,QAAI,CAAC,IAAI,UAAW;AAEpB,UAAM,OAAO,WAAW,KAAK,OAAK,EAAE,OAAO,IAAI,SAAS;AACxD,QAAI,CAAC,KAAM;AACX,UAAM,iBAAiB,WAAW,OAAO,OACvC,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,aAAa,EAAE,OAAO,IAAI,UAAU;AACvE,UAAM,UAAU,eAAe,QAAQ,OAAK,EAAE,OAAO;AAErD,UAAM,gBAAgB,WACnB,KAAK,OAAK,EAAE,OAAO,KAAK,SAAS,GAAG,iBACpC,KAAK,QAAM,GAAG,cAAc,KAAK,EAAE,GAAG;AAEzC,YAAQ,KAAK;AAAA,MACX,IAAI,IAAI,MAAM,IAAI,aAAa,KAAK;AAAA,MACpC,MAAM,IAAI,QAAQ,KAAK;AAAA,MACvB;AAAA,MACA,MAAM,IAAI,QAAQ,iBAAiB;AAAA,MACnC,WAAW,KAAK;AAAA,MAChB;AAAA,MACA,GAAI,KAAK,YAAY,KAAK,SAAS,SAAS,EAAE,UAAU,KAAK,SAAS,IAAI,CAAC;AAAA,MAC3E,SAAS,IAAI,WAAW;AAAA,MACxB,GAAI,IAAI,UAAU,EAAE,SAAS,IAAI,QAAQ,IAAI,CAAC;AAAA,MAC9C,GAAI,IAAI,YAAY,EAAE,WAAW,IAAI,UAAU,IAAI,CAAC;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,SAAO,sBAAsB,MAAM;AAAA,IACjC,aAAa,OAAO;AAAA,IACpB,QAAQ;AAAA,IACR,SAAS,cAAc;AAAA,IACvB,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,YAAY;AAAA,IACZ,OAAO,mBAAmB,SAAS,KAAK;AAAA,EAC1C,CAAC;AACH;AAGO,SAAS,sBAAuC;AACrD,SAAO,kBAAkB,SAAS;AACpC;AAMO,SAAS,cAAc,UAAkB,eAAe,GAAsB;AACnF,QAAM,MAAM,YAAY,OAAO;AAC/B,MAAI,CAAI,eAAW,GAAG,EAAG,QAAO,CAAC;AACjC,QAAM,MAAyB,CAAC;AAChC,aAAW,QAAW,gBAAY,GAAG,GAAG;AACtC,QAAI,CAAC,KAAK,SAAS,OAAO,KAAK,CAAC,KAAK,SAAS,MAAM,EAAG;AACvD,QAAI;AACF,UAAI,KAAK,sBAAsB,MAAM,aAAkB,WAAK,KAAK,IAAI,CAAC,CAAC,CAAC;AAAA,IAC1E,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,YAAY,aAAqB,UAAkB,eAAe,GAA2B;AAC3G,SAAO,cAAc,OAAO,EAAE,KAAK,OAAK,EAAE,gBAAgB,WAAW,KAAK;AAC5E;AAEO,SAAS,aAAa,UAA2B,UAAkB,eAAe,GAAW;AAClG,QAAM,MAAM,YAAY,OAAO;AAC/B,EAAG,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AACrC,QAAM,IAAS,WAAK,KAAK,GAAG,SAAS,WAAW,OAAO;AACvD,gBAAc,GAAG,sBAAsB,MAAM,QAAQ,CAAC;AACtD,SAAO;AACT;AAEO,SAAS,eAAe,aAAqB,UAAkB,eAAe,GAAY;AAC/F,QAAM,IAAS,WAAK,YAAY,OAAO,GAAG,GAAG,WAAW,OAAO;AAC/D,MAAI,CAAI,eAAW,CAAC,EAAG,QAAO;AAC9B,EAAG,eAAW,CAAC;AACf,SAAO;AACT;AAGO,SAAS,uBAA0C;AACxD,SAAO,cAAc;AACvB;AAcO,SAAS,cAAc,aAAqB,QAAgB,SAAuC;AACxG,QAAM,WAAW,kBAAkB,WAAW;AAC9C,QAAM,WAAW,WAAW,YAAY,UAAU,QAAQ,IAAI;AAC9D,MAAI;AACJ,MAAI,SAAS;AACX,IAAG,cAAe,cAAa,cAAQ,OAAO,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AACrE,QAAI,aAAa,QAAW;AAC1B,MAAG,kBAAmB,cAAQ,OAAO,GAAG,QAAQ;AAAA,IAClD,OAAO;AACL,oBAAmB,cAAQ,OAAO,GAAG,QAAQ;AAAA,IAC/C;AACA,gBAAiB,cAAQ,OAAO;AAAA,EAClC;AACA,SAAO,EAAE,UAAU,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC,GAAI,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG;AAC1G;AAEO,SAAS,cAAc,YAAoB,QAAwC;AACxF,QAAM,WAAgB,cAAQ,UAAU;AACxC,MAAI,CAAI,eAAW,QAAQ,GAAG;AAC5B,UAAM,IAAI,MAAM,+BAA+B,QAAQ,EAAE;AAAA,EAC3D;AACA,QAAM,OAAU,iBAAa,UAAU,MAAM;AAE7C,MAAI;AACJ,MAAI,kBAAkB,IAAI,GAAG;AAC3B,UAAM,cAAmB,eAAS,QAAQ,EAAE,QAAQ,oBAAoB,EAAE;AAC1E,eAAW,YAAY,MAAM,WAAW;AACxC,eAAW,EAAE,GAAG,UAAU,OAAO;AAAA,EACnC,OAAO;AACL,eAAW,sBAAsB,MAAM,aAAa,QAAQ,CAAC;AAC7D,eAAW,EAAE,GAAG,UAAU,OAAO;AAAA,EACnC;AACA,eAAa,QAAQ;AACrB,SAAO;AACT;AAMO,SAAS,uBAAuB,UAAkB,eAAe,GAAa;AACnF,QAAM,WAAW,mBAAmB,EAAE,OAAO,OAAK,EAAE,eAAe,CAAC,EAAE,GAAG,SAAS,IAAI,CAAC;AACvF,MAAI,CAAC,SAAS,OAAQ,QAAO,CAAC;AAC9B,QAAM,WAAW,oBAAoB;AACrC,QAAM,UAAoB,CAAC;AAC3B,aAAW,SAAS,UAAU;AAC5B,UAAM,WAAgB,cAAQ,SAAS,MAAM,WAAY;AACzD,QAAI,CAAI,eAAW,QAAQ,EAAG;AAC9B,YAAQ,KAAK,aAAa,UAAU,QAAQ,CAAC;AAAA,EAC/C;AACA,SAAO;AACT;AASA,SAAS,kBAAkB,UAAmC;AAC5D,QAAM,EAAE,SAAS,aAAa,QAAQ,GAAG,QAAQ,IAAI;AACrD,SAAO,KAAK,UAAU,OAAO;AAC/B;AAEO,SAAS,2BAA2B,UAAkB,eAAe,GAAsB;AAChG,QAAM,SAAS,eAAe;AAC9B,MAAI,CAAC,OAAQ,QAAO,CAAC;AACrB,QAAM,WAAW,mBAAmB,EAAE,OAAO,OAAK,EAAE,eAAe,CAAC,EAAE,GAAG,SAAS,IAAI,CAAC;AACvF,MAAI,CAAC,SAAS,OAAQ,QAAO,CAAC;AAK9B,QAAMC,WAAU,kBAAkB,oBAAoB,CAAC;AACvD,QAAM,SAA4B,CAAC;AACnC,aAAW,SAAS,UAAU;AAC5B,UAAM,WAAgB,cAAQ,SAAS,MAAM,WAAY;AACzD,UAAM,OAAO,YAAY,OAAO,MAAM,QAAQ;AAC9C,QAAI,CAAC,QAAQ,KAAK,WAAW,YAAa;AAC1C,QAAI,kBAAkB,IAAI,MAAMA,UAAS;AACvC,aAAO,KAAK;AAAA,QACV,UAAU;AAAA,QACV,MAAM;AAAA,QACN,SAAS,kBAAkB,MAAM,EAAE;AAAA,QACnC,QAAQ,MAAM;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;AA3TA,IAAAC,KACAC,OAmCM;AApCN;AAAA;AAAA;AAAA,IAAAD,MAAoB;AACpB,IAAAC,QAAsB;AACtB;AACA;AACA;AAUA,IAAAC;AAOA;AACA;AACA;AAaA,IAAM,mBAAmB;AAAA;AAAA;;;AClBlB,SAAS,uBAAuB,KAAkB,KAAsB;AAC7E,MAAI,IAAI,WAAW,IAAI,KAAK,IAAI,WAAW,SAAS,EAAG,QAAO;AAC9D,QAAMC,OAAM,IAAI,QAAQ,IAAI;AAC5B,MAAIA,SAAQ,GAAI,QAAO;AACvB,SAAO,CAAC,IAAI,aAAa,IAAI,IAAI,MAAM,GAAGA,IAAG,CAAC;AAChD;AASO,SAAS,kBACd,KACA,KACmE;AACnE,QAAM,QAAQ,IAAI,MAAM,IAAI,EAAE,OAAO,SAAO,OAAO,QAAQ,OAAO,EAAE,IAAI;AACxE,MAAI,CAAC,MAAO,QAAO;AACnB,aAAW,YAAY,IAAI,kBAAkB;AAC3C,UAAM,QAAQ,SAAS,WAAW,KAAK,OAAK,EAAE,cAAc,SAAS,EAAE,OAAO,KAAK;AACnF,QAAI,MAAO,QAAO,EAAE,UAAU,MAAM;AAAA,EACtC;AACA,SAAO;AACT;AA3CA,IAyDa,eAqBA,sBAcA;AA5Fb;AAAA;AAAA;AAEA,IAAAC;AACA;AAsDO,IAAM,gBAAyB;AAAA,MACpC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,2BAA2B,iBAAiB,SAAS,SAAS,4FAA4F;AAAA,MACpK;AAAA,MACA,MAAM,KAAK;AACT,mBAAWC,UAAS,qBAAqB,IAAI,aAAa,GAAG;AAC3D,cAAI,SAAS,SAAS,2BAA2BA,OAAM,SAASA,OAAM,MAAM;AAAA,QAC9E;AAAA,MACF;AAAA,IACF;AASO,IAAM,uBAAgC;AAAA,MAC3C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,iBAAiB,iBAAiB,WAAW,SAAS,mGAAmG;AAAA,MACnK;AAAA,MACA,MAAM,KAAK;AACT,mBAAWA,UAAS,2BAA2B,GAAG;AAChD,cAAI,SAAS,WAAW,iBAAiBA,OAAM,SAASA,OAAM,MAAM;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AAEO,IAAM,uBAAgC;AAAA,MAC3C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,iDAAiD;AAAA,QACnH,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,uFAAuF;AAAA,MAC3J;AAAA,MACA,MAAM,KAAK;AACT,cAAM,WAAW,IAAI,IAAI,IAAI,WAAW,OAAO,OAAK,CAAC,EAAE,GAAG,SAAS,IAAI,CAAC,EAAE,IAAI,OAAK,EAAE,EAAE,CAAC;AAExF,cAAM,UAAU,CAAC,IAAY,cAA4B;AACvD,cAAI,CAAC,IAAI,cAAc,EAAE,EAAG;AAC5B,gBAAM,WAAW,GAAG,MAAM,IAAI;AAC9B,cAAI,SAAS,SAAS,OAAO,GAAG;AAC9B,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,GAAG,SAAS,QAAQ,EAAE;AAAA,cACtB;AAAA,YACF;AAAA,UACF;AACA,cAAI,SAAS,SAAS,GAAG;AACvB,kBAAM,QAAQ,SAAS,SAAS,SAAS,CAAC;AAC1C,gBAAI,SAAS,IAAI,KAAK,GAAG;AACvB,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,GAAG,SAAS,KAAK,EAAE,6BAA6B,KAAK,uDAAkD,KAAK;AAAA,gBAC5G;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,KAAK,IAAI,WAAY,SAAQ,EAAE,IAAI,WAAW;AACzD,mBAAW,KAAK,IAAI,WAAY,SAAQ,EAAE,IAAI,WAAW;AACzD,mBAAW,KAAK,IAAI,WAAY,SAAQ,EAAE,IAAI,WAAW;AACzD,mBAAW,MAAM,IAAI,gBAAiB,SAAQ,GAAG,IAAI,gBAAgB;AACrE,mBAAW,KAAK,IAAI,MAAO,SAAQ,EAAE,IAAI,MAAM;AAAA,MACjD;AAAA,IACF;AAAA;AAAA;;;ACrIA,IAQa;AARb;AAAA;AAAA;AACA;AAOO,IAAM,gBAAyB;AAAA,MACpC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,oCAAoC,iBAAiB,SAAS,SAAS,oDAAoD;AAAA,QACnI,EAAE,MAAM,iCAAiC,iBAAiB,SAAS,SAAS,kDAAkD;AAAA,QAC9H,EAAE,MAAM,4BAA4B,iBAAiB,SAAS,SAAS,oCAAoC;AAAA,QAC3G,EAAE,MAAM,yBAAyB,iBAAiB,SAAS,SAAS,iCAAiC;AAAA,QACrG,EAAE,MAAM,sCAAsC,iBAAiB,SAAS,SAAS,6CAA6C;AAAA,QAC9H,EAAE,MAAM,6BAA6B,iBAAiB,WAAW,SAAS,2HAAsH;AAAA,QAChM,EAAE,MAAM,2BAA2B,iBAAiB,SAAS,SAAS,wGAAwG;AAAA,QAC9K,EAAE,MAAM,8BAA8B,iBAAiB,SAAS,SAAS,qEAAqE;AAAA,QAC9I,EAAE,MAAM,mCAAmC,iBAAiB,SAAS,SAAS,yDAAyD;AAAA,QACvI,EAAE,MAAM,+BAA+B,iBAAiB,WAAW,SAAS,qEAAqE;AAAA,MACnJ;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,cAAI,CAAC,SAAU;AAEf,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,gBAAM,sBAAsB,IAAI,IAAI,SAAS,QAAQ,IAAI,OAAK,EAAE,IAAI,CAAC;AACrE,gBAAM,kBAAkB,IAAI,IAAI,KAAK,QAAQ,IAAI,OAAK,EAAE,IAAI,CAAC;AAG7D,qBAAW,cAAc,KAAK,SAAS;AACrC,gBAAI,CAAC,oBAAoB,IAAI,WAAW,IAAI,GAAG;AAC7C,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,mBAAmB,KAAK,EAAE,wBAAwB,WAAW,IAAI,uCAAuC,SAAS,EAAE;AAAA,gBACnH,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,qBAAW,kBAAkB,SAAS,SAAS;AAC7C,gBAAI,CAAC,gBAAgB,IAAI,eAAe,IAAI,GAAG;AAC7C,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,mBAAmB,KAAK,EAAE,oDAAoD,eAAe,IAAI,qBAAqB,SAAS,EAAE;AAAA,gBACjI,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAKA,qBAAW,cAAc,KAAK,SAAS;AACrC,uBAAW,QAAQ,WAAW,WAAW;AACvC,kBAAI,KAAK,SAAS,UAAU,KAAK,SAAS,WAAY;AAEtD,kBAAI,CAAC,KAAK,iBAAiB;AACzB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,WAAW,KAAK,IAAI,UAAU,KAAK,UAAU;AAAA,kBACtG,KAAK;AAAA,kBACL;AAAA,gBACF;AACA;AAAA,cACF;AAWA,oBAAM,kBAAkB,uBAAuB,KAAK,KAAK,eAAe;AAExE,kBAAI,KAAK,SAAS,YAAY;AAC5B,sBAAM,iBAAiB,IAAI,aAAa,IAAI,KAAK,eAAe;AAChE,oBAAI,CAAC,gBAAgB;AACnB,sBAAI,iBAAiB;AACnB,0BAAM,WAAW,kBAAkB,KAAK,KAAK,eAAe;AAC5D,wBAAI,UAAU;AAEZ,0BAAI,KAAK,cAAc,EAAE,SAAS,MAAM,YAAY,CAAC,GAAG,KAAK,OAAK,EAAE,eAAe,KAAK,UAAU,GAAG;AACnG,4BAAI;AAAA,0BACF;AAAA,0BACA;AAAA,0BACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,4BAA4B,KAAK,UAAU,gCAAgC,KAAK,eAAe,WAAW,KAAK,UAAU,mCAAmC,SAAS,SAAS,WAAW,wCAAwC,SAAS,MAAM,EAAE;AAAA,0BAC3S,KAAK;AAAA,0BACL;AAAA,wBACF;AAAA,sBACF;AACA;AAAA,oBACF;AACA,wBAAI;AAAA,sBACF;AAAA,sBACA;AAAA,sBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,8CAA8C,KAAK,eAAe,WAAW,KAAK,UAAU;AAAA,sBACrJ,KAAK;AAAA,sBACL;AAAA,oBACF;AAAA,kBACF,OAAO;AACL,wBAAI;AAAA,sBACF;AAAA,sBACA;AAAA,sBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,mCAAmC,KAAK,eAAe,gCAAgC,KAAK,UAAU;AAAA,sBAC/J,KAAK;AAAA,sBACL;AAAA,oBACF;AAAA,kBACF;AACA;AAAA,gBACF;AACA,sBAAM,iBAAiB,IAAI,aAAa,IAAI,SAAS,SAAS;AAC9D,oBAAI,kBAAkB,KAAK,oBAAoB,eAAe,MACvD,CAAC,eAAe,UAAU,SAAS,KAAK,eAAe,KACvD,CAAC,eAAe,KAAK,SAAS,KAAK,eAAe,GAAG;AAC1D,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,iBAAiB,eAAe,EAAE,oCAAoC,KAAK,eAAe,WAAW,KAAK,UAAU,oBAAoB,eAAe,EAAE,oBAAoB,KAAK,eAAe;AAAA,oBAC1P,KAAK;AAAA,oBACL,cAAc,IAAI,iBAAiB,eAAe,EAAE;AAAA,kBACtD;AAAA,gBACF;AACA;AAAA,cACF;AAEA,kBAAI,CAAC,KAAK,cAAc;AACtB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,sBAAsB,KAAK,UAAU;AAAA,kBAC9F,KAAK;AAAA,kBACL;AAAA,gBACF;AACA;AAAA,cACF;AAEA,oBAAM,aAAa,IAAI,aAAa,IAAI,KAAK,eAAe;AAC5D,kBAAI,CAAC,YAAY;AACf,oBAAI,iBAAiB;AACnB,wBAAM,WAAW,kBAAkB,KAAK,KAAK,eAAe;AAC5D,sBAAI,UAAU;AAEZ,0BAAM,gBAAgB,SAAS,MAAM,QAAQ,KAAK,OAAK,EAAE,SAAS,KAAK,YAAY;AACnF,wBAAI,CAAC,eAAe;AAClB,0BAAI;AAAA,wBACF;AAAA,wBACA;AAAA,wBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,YAAY,KAAK,YAAY,8BAA8B,KAAK,eAAe,WAAW,KAAK,UAAU,mCAAmC,SAAS,SAAS,WAAW,qCAAqC,SAAS,MAAM,EAAE;AAAA,wBACxR,KAAK;AAAA,wBACL;AAAA,sBACF;AAAA,oBACF,WAAW,KAAK,mBAAmB;AACjC,4BAAM,WAAW,IAAI,IAAI,cAAc,cAAc,CAAC,CAAC;AACvD,iCAAW,KAAK,KAAK,mBAAmB;AACtC,4BAAI,CAAC,SAAS,IAAI,CAAC,GAAG;AACpB,8BAAI;AAAA,4BACF;AAAA,4BACA;AAAA,4BACA,QAAQ,KAAK,UAAU,QAAQ,WAAW,IAAI,wBAAwB,KAAK,EAAE,wBAAwB,CAAC,mCAAmC,SAAS,SAAS,WAAW,6BAA6B,SAAS,MAAM,EAAE,IAAI,KAAK,YAAY;AAAA,4BACzO,KAAK;AAAA,4BACL;AAAA,0BACF;AAAA,wBACF;AAAA,sBACF;AAAA,oBACF;AACA;AAAA,kBACF;AACA,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,iCAAiC,KAAK,eAAe,WAAW,KAAK,UAAU;AAAA,oBACxI,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF,OAAO;AACL,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,sBAAsB,KAAK,eAAe,gCAAgC,KAAK,UAAU;AAAA,oBAClJ,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AACA;AAAA,cACF;AAGA,oBAAM,mBAAmB,IAAI,aAAa,IAAI,SAAS,SAAS;AAChE,kBAAI,oBAAoB,KAAK,oBAAoB,iBAAiB,IAAI;AACpE,oBAAI,CAAC,iBAAiB,UAAU,SAAS,KAAK,eAAe,KACzD,CAAC,iBAAiB,KAAK,SAAS,KAAK,eAAe,GAAG;AACzD,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,iBAAiB,iBAAiB,EAAE,uBAAuB,KAAK,eAAe,WAAW,KAAK,UAAU,oBAAoB,iBAAiB,EAAE,oBAAoB,KAAK,eAAe;AAAA,oBACjP,KAAK;AAAA,oBACL,cAAc,IAAI,iBAAiB,iBAAiB,EAAE;AAAA,kBACxD;AAAA,gBACF;AAAA,cACF;AAGA,oBAAM,mBAAmB,IAAI,sBAAsB,IAAI,KAAK,eAAe,KAAK,CAAC;AACjF,kBAAI;AACJ,yBAAW,cAAc,kBAAkB;AACzC,sBAAM,QAAQ,WAAW,QAAQ,KAAK,OAAK,EAAE,SAAS,KAAK,YAAY;AACvE,oBAAI,OAAO;AAAE,qCAAmB;AAAO;AAAA,gBAAO;AAAA,cAChD;AAEA,kBAAI,CAAC,kBAAkB;AACrB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,mBAAmB,KAAK,YAAY,mBAAmB,KAAK,eAAe,yDAAyD,KAAK,UAAU;AAAA,kBAC5M,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,KAAK,eAAe;AAAA,gBACzD;AAAA,cACF,OAAO;AAML,sBAAM,WAAW,IAAI,IAAI,iBAAiB,cAAc,CAAC,CAAC;AAC1D,oBAAI,KAAK,mBAAmB;AAC1B,6BAAW,KAAK,KAAK,mBAAmB;AACtC,wBAAI,CAAC,SAAS,IAAI,CAAC,GAAG;AACpB,0BAAI;AAAA,wBACF;AAAA,wBACA;AAAA,wBACA,QAAQ,KAAK,UAAU,QAAQ,WAAW,IAAI,wBAAwB,KAAK,EAAE,mCAAmC,CAAC,sCAAiC,KAAK,YAAY,SAAS,KAAK,eAAe,2BAAsB,CAAC;AAAA,wBACvN,KAAK;AAAA,wBACL,cAAc,IAAI,iBAAiB,KAAK,eAAe;AAAA,sBACzD;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACjPA,SAAS,aAAa,MAA+B;AACnD,SAAO,YAAY,OAAO,OAAK;AAC7B,UAAM,IAAI,KAAK,CAAC;AAChB,QAAI,MAAM,OAAW,QAAO;AAC5B,QAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAG,QAAO;AAC/C,WAAO;AAAA,EACT,CAAC;AACH;AASO,SAAS,UAAU,OAKxB;AACA,QAAM,QAAQ,oBAAI,IAA2B;AAC7C,aAAW,KAAK,MAAO,OAAM,IAAI,EAAE,YAAY,CAAC;AAChD,QAAM,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACnD,QAAM,UAAU,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,QAAM,SAAS,CAAC,MAAkC;AAChD,UAAM,IAAI,QAAQ,IAAI,CAAC;AACvB,WAAO,MAAM,UAAa,IAAI,IAAI,KAAK,SAAS,KAAK,IAAI,CAAC,IAAI;AAAA,EAChE;AACA,QAAM,SAAS,CAAC,MAAkC;AAChD,UAAM,IAAI,QAAQ,IAAI,CAAC;AACvB,WAAO,MAAM,UAAa,IAAI,IAAI,KAAK,IAAI,CAAC,IAAI;AAAA,EAClD;AAMA,QAAM,aAAa,oBAAI,IAAgC;AACvD,QAAM,WAAW,CAAC,MACf,WAAW,IAAI,CAAC,IAAI,WAAW,IAAI,CAAC,IAAI,OAAO,CAAC;AACnD,aAAW,KAAK,MAAM;AACpB,UAAM,IAAI,MAAM,IAAI,CAAC;AACrB,QAAI,EAAE,SAAS,cAAc,EAAE,YAAY,UAAa,CAAC,EAAE,UAAU,OAAQ;AAC7E,UAAM,UAAU,EAAE,SAAS,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAChE,UAAMC,SAAO,SAAS,EAAE,OAAO;AAC/B,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAM,SAAS,IAAI,IAAI,QAAQ,SAAS,OAAO,QAAQ,IAAI,CAAC,CAAC,IAAI,EAAE;AACnE,UAAI,WAAW,UAAa,UAAU,QAAQ,CAAC,EAAG,YAAW,IAAI,QAAQA,MAAI;AAAA,IAC/E;AAAA,EACF;AAEA,QAAM,eAAe,CAAC,MAAwB;AAC5C,UAAM,IAAI,MAAM,IAAI,CAAC;AACrB,QAAI,CAAC,EAAG,QAAO,CAAC;AAChB,UAAM,OAA+B,CAAC;AACtC,YAAQ,EAAE,MAAM;AAAA,MACd,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,aAAK,KAAK,SAAS,CAAC,CAAC;AACrB;AAAA,MACF,KAAK;AACH,aAAK,KAAK,EAAE,cAAc,SAAS,CAAC,GAAG,EAAE,WAAW;AACpD;AAAA,MACF,KAAK;AACH,aAAK,KAAK,IAAI,EAAE,SAAS,CAAC,GAAG,IAAI,OAAK,EAAE,IAAI,GAAG,EAAE,eAAe,SAAS,CAAC,CAAC;AAC3E;AAAA,MACF,KAAK;AACH,aAAK,KAAK,OAAO,CAAC,GAAG,EAAE,YAAY,SAAY,SAAS,EAAE,OAAO,IAAI,MAAS;AAC9E;AAAA,MACF,KAAK;AACH,aAAK;AAAA,UACH,OAAO,CAAC;AAAA,UACR,IAAI,EAAE,WAAW,CAAC,GAAG,IAAI,OAAK,EAAE,IAAI;AAAA,UACpC,EAAE;AAAA,UACF,EAAE,YAAY,SAAY,SAAS,EAAE,OAAO,IAAI;AAAA,QAClD;AACA;AAAA,MACF,KAAK;AAGH,aAAK;AAAA,UACH,IAAI,EAAE,YAAY,CAAC,GAAG,IAAI,OAAK,EAAE,IAAI;AAAA,UACrC,EAAE,YAAY,SAAY,SAAS,EAAE,OAAO,IAAI;AAAA,QAClD;AACA;AAAA,MACF,KAAK;AACH,aAAK,KAAK,EAAE,MAAM;AAClB;AAAA,IAEJ;AACA,WAAO,CAAC,GAAG,IAAI,IAAI,KAAK,OAAO,CAAC,MAAmB,MAAM,UAAa,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;AAAA,EACtF;AACA,SAAO,EAAE,OAAO,MAAM,QAAQ,aAAa;AAC7C;AAhHA,IAWM,aAuGO;AAlHb;AAAA;AAAA;AAWA,IAAM,cAAc;AAAA,MAClB;AAAA,MAAa;AAAA,MAAc;AAAA,MAAe;AAAA,MAAM;AAAA,MAAS;AAAA,MACzD;AAAA,MAAY;AAAA,MAAQ;AAAA,MAAW;AAAA,MAAW;AAAA,MAAe;AAAA,MAAY;AAAA,IACvE;AAoGO,IAAM,oBAA6B;AAAA,MACxC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,0EAA0E;AAAA,QAC5I,EAAE,MAAM,qBAAqB,iBAAiB,SAAS,SAAS,wEAAwE;AAAA,QACxI,EAAE,MAAM,oBAAoB,iBAAiB,WAAW,SAAS,0EAA0E;AAAA,QAC3I,EAAE,MAAM,kBAAkB,iBAAiB,SAAS,SAAS,kGAA6F;AAAA,QAC1J,EAAE,MAAM,oBAAoB,iBAAiB,WAAW,SAAS,2GAAsG;AAAA,QACvK,EAAE,MAAM,4BAA4B,iBAAiB,WAAW,SAAS,+EAA+E;AAAA,QACxJ,EAAE,MAAM,iBAAiB,iBAAiB,WAAW,SAAS,4GAAuG;AAAA,MACvK;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,qBAAW,cAAc,KAAK,SAAS;AACrC,kBAAM,QAAQ,WAAW;AACzB,gBAAI,CAAC,MAAM,OAAQ;AACnB,kBAAM,QAAQ,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE;AAEvE,gBAAI,QAAQ;AACZ,kBAAM,YAAY,CAAC,QAAsB;AACvC,sBAAQ;AACR,kBAAI,SAAS,SAAS,uBAAuB,QAAQ,KAAK,KAAK,IAAI,UAAU;AAAA,YAC/E;AAEA,kBAAM,QAAQ,oBAAI,IAA2B;AAC7C,uBAAW,KAAK,OAAO;AACrB,kBAAI,MAAM,IAAI,EAAE,UAAU,EAAG,WAAU,wBAAwB,EAAE,UAAU,0CAAqC;AAChH,oBAAM,IAAI,EAAE,YAAY,CAAC;AAAA,YAC3B;AACA,kBAAM,OAAO,CAAC,GAAG,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AACnD,kBAAM,UAAU,IAAI,IAAI,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAClD,kBAAM,SAAS,CAAC,MAAkC;AAChD,oBAAM,IAAI,QAAQ,IAAI,CAAC;AACvB,qBAAO,MAAM,UAAa,IAAI,IAAI,KAAK,SAAS,KAAK,IAAI,CAAC,IAAI;AAAA,YAChE;AAEA,uBAAW,KAAK,OAAO;AACrB,kBAAI,EAAE,UAAU,EAAE,SAAS,UAAU,EAAE,SAAS,YAAY;AAC1D,0BAAU,QAAQ,EAAE,UAAU,KAAK,EAAE,IAAI,gFAA2E;AAAA,cACtH;AACA,sBAAQ,EAAE,MAAM;AAAA,gBACd,KAAK;AAAA,gBACL,KAAK;AAAA,gBACL,KAAK,YAAY;AACf,wBAAM,QAAQ,aAAa,CAAC;AAC5B,sBAAI,MAAM,OAAQ,WAAU,QAAQ,EAAE,UAAU,KAAK,EAAE,IAAI,0BAA0B,MAAM,KAAK,IAAI,CAAC,wCAAmC;AACxI;AAAA,gBACF;AAAA,gBACA,KAAK;AACH,sBAAI,CAAC,EAAE,UAAW,WAAU,eAAe,EAAE,UAAU,wBAAwB;AAC/E,sBAAI,EAAE,gBAAgB,OAAW,WAAU,eAAe,EAAE,UAAU,0EAA0E;AAChJ;AAAA,gBACF,KAAK;AACH,sBAAI,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,OAAQ,WAAU,eAAe,EAAE,UAAU,8BAA8B;AACpG;AAAA,gBACF,KAAK,QAAQ;AACX,sBAAI,EAAE,YAAY,OAAW,WAAU,aAAa,EAAE,UAAU,8CAA8C;AAAA,2BACrG,EAAE,WAAW,EAAE,WAAY,WAAU,aAAa,EAAE,UAAU,eAAe,EAAE,OAAO,+BAA+B;AAC9H,wBAAM,OAAO,EAAE,aAAa,EAAE,OAAO,YAAY;AACjD,uBAAK,SAAS,WAAW,SAAS,cAAc,CAAC,EAAE,UAAW,WAAU,GAAG,IAAI,cAAc,EAAE,UAAU,wBAAwB;AACjI,uBAAK,SAAS,aAAa,SAAS,UAAU,CAAC,EAAE,KAAM,WAAU,GAAG,IAAI,cAAc,EAAE,UAAU,0CAA0C;AAC5I;AAAA,gBACF;AAAA,gBACA,KAAK;AACH,sBAAI,EAAE,YAAY,OAAW,WAAU,YAAY,EAAE,UAAU,sDAAsD;AAAA,2BAC5G,EAAE,WAAW,EAAE,WAAY,WAAU,YAAY,EAAE,UAAU,eAAe,EAAE,OAAO,+BAA+B;AAC7H,uBAAK,CAAC,EAAE,WAAW,CAAC,EAAE,QAAQ,WAAW,EAAE,gBAAgB,OAAW,WAAU,YAAY,EAAE,UAAU,8FAAyF;AACjM;AAAA,gBACF,KAAK,YAAY;AACf,sBAAI,EAAE,YAAY,OAAW,WAAU,iBAAiB,EAAE,UAAU,sDAAsD;AAAA,2BACjH,EAAE,WAAW,EAAE,WAAY,WAAU,iBAAiB,EAAE,UAAU,eAAe,EAAE,OAAO,+BAA+B;AAClI,wBAAM,WAAW,EAAE,YAAY,CAAC,GAAG,IAAI,OAAK,EAAE,IAAI;AAClD,sBAAI,QAAQ,SAAS,GAAG;AACtB,8BAAU,iBAAiB,EAAE,UAAU,qFAAgF;AAAA,kBACzH,OAAO;AACL,0BAAM,SAAS,CAAC,GAAG,OAAO,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAChD,wBAAI,QAAQ,KAAK,CAAC,GAAG,MAAM,MAAM,OAAO,CAAC,CAAC,EAAG,WAAU,iBAAiB,EAAE,UAAU,0GAAqG;AACzL,wBAAI,IAAI,IAAI,OAAO,EAAE,SAAS,QAAQ,OAAQ,WAAU,iBAAiB,EAAE,UAAU,8CAA8C;AACnI,0BAAM,YAAY,OAAO,EAAE,UAAU;AACrC,wBAAI,cAAc,UAAa,OAAO,CAAC,MAAM,UAAW,WAAU,iBAAiB,EAAE,UAAU,wDAAwD,SAAS,UAAU,OAAO,CAAC,CAAC,4DAAuD;AAC1O,wBAAI,EAAE,YAAY,UAAa,OAAO,KAAK,OAAK,IAAI,EAAE,OAAQ,EAAG,WAAU,iBAAiB,EAAE,UAAU,iDAAiD,EAAE,OAAO,IAAI;AAAA,kBACxK;AACA;AAAA,gBACF;AAAA,gBACA,KAAK;AACH,sBAAI,EAAE,WAAW,OAAW,WAAU,aAAa,EAAE,UAAU,qBAAqB;AACpF;AAAA,cAEJ;AAEA,oBAAM,aAAiC,CAAC;AACxC,kBAAI,EAAE,eAAe,OAAW,YAAW,KAAK,CAAC,cAAc,EAAE,UAAU,CAAC;AAC5E,kBAAI,EAAE,gBAAgB,OAAW,YAAW,KAAK,CAAC,eAAe,EAAE,WAAW,CAAC;AAC/E,kBAAI,EAAE,gBAAgB,OAAW,YAAW,KAAK,CAAC,eAAe,EAAE,WAAW,CAAC;AAC/E,kBAAI,EAAE,YAAY,OAAW,YAAW,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC;AACnE,kBAAI,EAAE,gBAAgB,OAAW,YAAW,KAAK,CAAC,eAAe,EAAE,WAAW,CAAC;AAC/E,kBAAI,EAAE,WAAW,OAAW,YAAW,KAAK,CAAC,UAAU,EAAE,MAAM,CAAC;AAChE,eAAC,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAM,WAAW,KAAK,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AAC/E,eAAC,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAM,WAAW,KAAK,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACnF,eAAC,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAM,WAAW,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AACrF,yBAAW,CAAC,OAAO,MAAM,KAAK,YAAY;AACxC,oBAAI,CAAC,MAAM,IAAI,MAAM,GAAG;AACtB,0BAAQ;AACR,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,GAAG,KAAK,QAAQ,EAAE,UAAU,KAAK,KAAK,kBAAkB,MAAM;AAAA,oBAC9D,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,CAAC,MAAO;AACZ,kBAAM,QAAQ,UAAU,KAAK;AAC7B,kBAAM,UAAU,oBAAI,IAAY;AAChC,kBAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtB,mBAAO,MAAM,QAAQ;AACnB,oBAAM,IAAI,MAAM,IAAI;AACpB,kBAAI,QAAQ,IAAI,CAAC,EAAG;AACpB,sBAAQ,IAAI,CAAC;AACb,yBAAW,KAAK,MAAM,aAAa,CAAC,GAAG;AACrC,oBAAI,CAAC,QAAQ,IAAI,CAAC,EAAG,OAAM,KAAK,CAAC;AAAA,cACnC;AAAA,YACF;AACA,kBAAM,OAAO,KAAK,OAAO,OAAK,CAAC,QAAQ,IAAI,CAAC,CAAC;AAC7C,gBAAI,KAAK,QAAQ;AACf,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,GAAG,KAAK,WAAW,KAAK,KAAK,IAAI,CAAC,gCAAgC,KAAK,CAAC,CAAC;AAAA,gBACzE,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAKA,kBAAM,UAAsD,CAAC;AAC7D,uBAAW,KAAK,OAAO;AACrB,mBAAK,EAAE,SAAS,UAAU,EAAE,SAAS,SAAS,EAAE,SAAS,eAAe,EAAE,YAAY,QAAW;AAC/F,wBAAQ,KAAK,EAAE,GAAG,EAAE,YAAY,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,CAAC;AAAA,cAChE;AAAA,YACF;AACA,kBAAM,SAAS,CAAC,GAAW,MAA2C,IAAI,EAAE,KAAK,KAAK,EAAE;AAExF,uBAAW,KAAK,SAAS;AACvB,yBAAW,KAAK,SAAS;AACvB,oBAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK;AAC9C,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,GAAG,KAAK,GAAG,EAAE,IAAI,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG,qBAAqB,EAAE,IAAI,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG;AAAA,oBAC5F,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAEA,kBAAM,YAAyE,CAAC;AAChF,uBAAW,KAAK,OAAO;AACrB,oBAAM,OAAO,CAAC,OAAe,OAAiC;AAC5D,oBAAI,OAAO,OAAW,WAAU,KAAK,EAAE,MAAM,EAAE,YAAY,IAAI,OAAO,MAAM,EAAE,KAAK,CAAC;AAAA,cACtF;AACA,mBAAK,cAAc,EAAE,UAAU;AAC/B,mBAAK,eAAe,EAAE,WAAW;AACjC,mBAAK,eAAe,EAAE,WAAW;AACjC,mBAAK,UAAU,EAAE,MAAM;AACvB,mBAAK,eAAe,EAAE,WAAW;AACjC,eAAC,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAM,KAAK,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC;AAClE,eAAC,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,GAAG,MAAM,KAAK,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC;AAAA,YACxE;AAEA,uBAAW,KAAK,WAAW;AACzB,yBAAW,KAAK,SAAS;AACvB,oBAAI,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG;AAC3D,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,GAAG,KAAK,QAAQ,EAAE,IAAI,KAAK,EAAE,KAAK,kCAAkC,EAAE,IAAI,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG,UAAU,EAAE,EAAE;AAAA,oBAChH,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAGA,mBAAK,EAAE,SAAS,YAAY,EAAE,SAAS,YAAY,EAAE,SAAS,WAAW,EAAE,KAAK,EAAE,MAAM;AACtF,sBAAM,iBAAiB,QAAQ,KAAK,OAAK,EAAE,SAAS,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,EAAE,MAAM,CAAC,CAAC;AAC/F,oBAAI,CAAC,gBAAgB;AACnB,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,GAAG,KAAK,QAAQ,EAAE,IAAI,KAAK,EAAE,KAAK,6BAA6B,EAAE,EAAE;AAAA,oBACnE,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAIA,uBAAW,KAAK,OAAO;AACrB,kBAAI,EAAE,SAAS,SAAS,EAAE,YAAY,OAAW;AACjD,oBAAM,gBAAgB,IAAI,KAAa,EAAE,WAAW,CAAC,GAAG,IAAI,OAAK,EAAE,IAAI,CAAC;AACxE,kBAAI,EAAE,gBAAgB,OAAW,eAAc,IAAI,EAAE,WAAW;AAChE,oBAAM,OAAO,MAAM,IAAI,EAAE,OAAO;AAChC,oBAAM,MAAM,OAAO,EAAE,OAAO;AAC5B,kBAAI,SAAS,KAAK,SAAS,WAAW,KAAK,SAAS,UAAU,KAAK,SAAS,eAAe,QAAQ,UAAa,cAAc,IAAI,GAAG,GAAG;AACtI,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,GAAG,KAAK,+BAA+B,EAAE,OAAO,gDAAgD,GAAG;AAAA,kBACnG,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACtQO,SAAS,iBAA4B;AAC1C,SAAO,EAAE,OAAO,CAAC,GAAG,aAAa,GAAG;AACtC;AAGO,SAAS,oBAAoB,GAAmB;AACrD,SAAO,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,SAAS,EAAE;AAClD;AAiIA,SAAS,cAAc,MAAc,UAAoC;AACvE,MAAI,MAAM;AACV,aAAW,CAAC,MAAM,KAAK,KAAK,SAAS,eAAe;AAClD,UAAM,KAAK,IAAI,OAAO,GAAG,SAAS,IAAI,CAAC,aAAa,SAAS,KAAK,CAAC,IAAI,GAAG;AAC1E,UAAM,IAAI,QAAQ,IAAI,GAAG;AAAA,EAC3B;AACA,MAAI,SAAS,aAAa,SAAS,GAAG;AACpC,UAAM,KAAK,IAAI,OAAO,MAAM,SAAS,aAAa,IAAI,QAAQ,EAAE,KAAK,GAAG,CAAC;AAAA,KAAW,GAAG;AACvF,UAAM,IAAI,QAAQ,IAAI,EAAE;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,SAAS,SAAS,GAAmB;AACnC,SAAO,EAAE,QAAQ,uBAAuB,MAAM;AAChD;AAEA,SAAS,eAAe,MAA2B;AACjD,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,KAAK,KAAK,SAAS,SAAS,GAAG;AACxC,UAAM,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC;AACjC,QAAI,MAAO,SAAQ,IAAI,KAAK;AAAA,EAC9B;AACA,SAAO;AACT;AAMA,SAAS,oBAAoB,MAAc,UAAmF;AAC5H,QAAM,WAAW,cAAc,MAAM,QAAQ;AAC7C,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAU,oBAAI,IAAY;AAEhC,aAAW,MAAM,SAAS,cAAc;AACtC,eAAW,KAAK,SAAS,SAAS,EAAE,GAAG;AACrC,YAAM,WAAW,EAAE,CAAC;AACpB,UAAI,CAAC,SAAU;AAEf,iBAAW,SAAS,SAAS,MAAM,GAAG,GAAG;AACvC,cAAM,QAAQ,MAAM,SAAS,MAAM,IAAI,MAAM,MAAM,MAAM,EAAE,CAAC,IAAI,OAAO,KAAK;AAC5E,YAAI,QAAQ,qBAAqB,KAAK,IAAI,EAAG,UAAS,IAAI,IAAI;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,aAAW,MAAM,SAAS,SAAS;AACjC,eAAW,KAAK,SAAS,SAAS,EAAE,GAAG;AACrC,YAAM,OAAO,EAAE,MAAM,CAAC,EAAE,KAAK,OAAK,CAAC;AACnC,UAAI,KAAM,SAAQ,IAAI,IAAI;AAAA,IAC5B;AAAA,EACF;AACA,MAAI,SAAS,cAAc,SAAS,GAAG;AACrC,eAAW,QAAQ,SAAS,MAAM,IAAI,GAAG;AACvC,UAAI,CAAC,SAAS,cAAc,KAAK,QAAM,GAAG,KAAK,IAAI,CAAC,EAAG;AACvD,iBAAW,MAAM,SAAS,cAAc;AACtC,WAAG,YAAY;AACf,cAAM,IAAI,GAAG,KAAK,IAAI;AACtB,YAAI,IAAI,CAAC,EAAG,UAAS,IAAI,EAAE,CAAC,CAAC;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAKA,QAAM,UAAU,eAAe,IAAI;AACnC,aAAW,KAAK,SAAS,SAAS,aAAa,EAAG,SAAQ,IAAI,EAAE,CAAC,CAAC;AAElE,SAAO;AAAA,IACL,eAAe;AAAA,IACf,eAAe,CAAC,GAAG,QAAQ;AAAA,IAC3B,eAAe,CAAC,GAAG,OAAO;AAAA,IAC1B,eAAe,CAAC,GAAG,QAAQ;AAAA,IAC3B,SAAS,CAAC,GAAG,OAAO;AAAA,IACpB,WAAW,CAAC;AAAA,EACd;AACF;AAEA,SAAS,eAAe,MAAqE;AAI3F,QAAM,QAAQ,oBAAI,IAAY;AAC9B,aAAW,KAAK,KAAK,SAAS,aAAa,EAAG,OAAM,IAAI,EAAE,CAAC,CAAC;AAC5D,QAAM,UAAU,IAAI,IAAI,KAAK;AAC7B,aAAW,KAAK,eAAe,IAAI,EAAG,SAAQ,IAAI,CAAC;AACnD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,eAAe,CAAC,GAAG,KAAK;AAAA,IACxB,eAAe,CAAC,GAAG,OAAO;AAAA,IAC1B,eAAe,CAAC;AAAA,IAChB,SAAS,CAAC;AAAA,IACV,WAAW,CAAC;AAAA,EACd;AACF;AAiBA,SAAS,kBAAkB,aAAsC;AAC/D,QAAM,SAAS,kBAAkB,IAAI,WAAW;AAChD,MAAI,WAAW,OAAO,OAAO,QAAQ,KAAK,IAAI,IAAI,OAAO,KAAK,yBAAyB;AACrF,WAAO,OAAO;AAAA,EAChB;AACA,MAAI,KAAsB;AAE1B,QAAM,QAAQ,CAAM,WAAK,aAAa,cAAc,GAAG,UAAU;AACjE,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,UAAM,8BAAc,IAAI;AAC9B,WAAK,IAAI,YAAY;AACrB;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,oBAAkB,IAAI,aAAa,EAAE,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;AACzD,SAAO;AACT;AAmBA,SAAS,UAAU,IAAc,YAAoB,UAA8B;AACjF,QAAM,KAAK,GAAG;AAAA,IAAiB;AAAA,IAAU;AAAA,IAAY,GAAG,aAAa;AAAA;AAAA,IAA2B;AAAA,EAAI;AACpG,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,cAAwB,CAAC;AAC/B,QAAM,aAAa,oBAAI,IAAoB;AAC3C,QAAM,QAAQ,oBAAI,IAAyB;AAC3C,QAAM,kBAAkB,oBAAI,IAAY;AAExC,QAAM,kBAAkB,CAAC,SAAiD;AACxE,QAAI,GAAG,aAAa,IAAI,EAAG,UAAS,IAAI,KAAK,IAAI;AAAA,aACxC,GAAG,uBAAuB,IAAI,KAAK,GAAG,sBAAsB,IAAI,GAAG;AAC1E,iBAAW,MAAM,KAAK,UAAU;AAC9B,YAAI,GAAG,iBAAiB,EAAE,EAAG,iBAAgB,GAAG,IAAI;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,mBAAmB,CAAC,SAAgE;AACxF,QAAI,GAAG,aAAa,IAAI,KAAK,GAAG,gBAAgB,IAAI,KAAK,GAAG,iBAAiB,IAAI,EAAG,QAAO,KAAK;AAChG,QAAI,GAAG,oBAAoB,IAAI,EAAG,QAAO,KAAK;AAC9C,WAAO;AAAA,EACT;AAEA,QAAM,oBAAoB,CAAC,SAA6C;AACtE,UAAM,OAAQ,KAAsE;AACpF,WAAO,CAAC,CAAC,MAAM,KAAK,OAAK,EAAE,SAAS,GAAG,WAAW,aAAa;AAAA,EACjE;AAMA,QAAM,oBAAoB,CAAC,SAAwD;AACjF,QAAI,GAAG,sBAAsB,IAAI,GAAG;AAClC,aAAO,KAAK,QAAQ,GAAG,aAAa,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO;AAAA,IACpE;AACA,QAAI,GAAG,oBAAoB,IAAI,KAAK,GAAG,yBAAyB,IAAI,KAAK,GAAG,yBAAyB,IAAI,GAAG;AAC1G,aAAO,iBAAiB,KAAK,IAAI;AAAA,IACnC;AACA,QAAI,GAAG,qBAAqB,IAAI,KAAK,GAAG,gBAAgB,IAAI,GAAG;AAC7D,YAAM,IAAI,KAAK;AACf,UAAI,KAAK,GAAG,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,QAAQ,GAAG,aAAa,EAAE,IAAI,EAAG,QAAO,EAAE,KAAK;AACzG,UAAI,MAAM,GAAG,qBAAqB,CAAC,KAAK,GAAG,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,MAAM;AAC9F,eAAO,iBAAiB,EAAE,IAAI;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAMA,QAAM,uBAAuB,CAAC,OAAkH;AAC9I,QAAI,QAAQ;AACZ,UAAM,UAAU,oBAAI,IAAY;AAChC,UAAM,QAAQ,CAAC,SAA0C;AACvD,UAAI,kBAAkB,IAAI,MAAM,OAAW;AAC3C,UAAI,GAAG,cAAc,IAAI,KAAK,GAAG,wBAAwB,IAAI,KACxD,GAAG,eAAe,IAAI,KAAK,GAAG,iBAAiB,IAAI,KAAK,GAAG,iBAAiB,IAAI,KAChF,GAAG,iBAAiB,IAAI,KAAK,GAAG,cAAc,IAAI,KAClD,GAAG,aAAa,IAAI,KAAK,GAAG,cAAc,IAAI,GAAG;AACpD;AAAA,MACF,WAAW,GAAG,mBAAmB,IAAI,GAAG;AACtC,cAAM,IAAI,KAAK,cAAc;AAC7B,YAAI,MAAM,GAAG,WAAW,2BAA2B,MAAM,GAAG,WAAW,eAClE,MAAM,GAAG,WAAW,uBAAuB;AAC9C;AAAA,QACF;AAAA,MACF,WAAW,GAAG,iBAAiB,IAAI,GAAG;AACpC,cAAM,SAAS,KAAK;AACpB,YAAI,GAAG,aAAa,MAAM,EAAG,SAAQ,IAAI,OAAO,IAAI;AAAA,iBAC3C,GAAG,2BAA2B,MAAM,EAAG,SAAQ,IAAI,OAAO,KAAK,IAAI;AAAA,MAC9E;AACA,SAAG,aAAa,MAAM,KAAK;AAAA,IAC7B;AAIA,QAAI,GAAG,KAAM,OAAM,GAAG,IAAI;AAC1B,WAAO,EAAE,OAAO,QAAQ;AAAA,EAC1B;AAEA,QAAM,QAAQ,CAAC,SAA0C;AACvD,UAAM,SAAS,kBAAkB,IAAI;AACrC,QAAI,UAAW,KAA8C,MAAM;AACjE,YAAM,QAAQ,qBAAqB,IAAwE;AAC3G,iBAAW,IAAI,QAAQ,KAAK,IAAI,WAAW,IAAI,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC;AACzE,YAAM,MAAM,MAAM,IAAI,MAAM,KAAK,oBAAI,IAAY;AACjD,iBAAW,KAAK,MAAM,QAAS,KAAI,IAAI,CAAC;AACxC,YAAM,IAAI,QAAQ,GAAG;AAAA,IACvB;AACA,QAAI,GAAG,sBAAsB,IAAI,KAAK,GAAG,mBAAmB,IAAI,KAAK,GAAG,uBAAuB,IAAI,KAC9F,GAAG,uBAAuB,IAAI,KAAK,GAAG,kBAAkB,IAAI,KAAK,GAAG,oBAAoB,IAAI,GAAG;AAClG,YAAM,OAAO,KAAK,QAAQ,GAAG,aAAa,KAAK,IAAI,IAAI,KAAK,KAAK,OAAO;AACxE,UAAI,MAAM;AACR,iBAAS,IAAI,IAAI;AACjB,YAAI,kBAAkB,IAAI,EAAG,UAAS,IAAI,IAAI;AAAA,MAChD;AAAA,IACF,WAAW,GAAG,oBAAoB,IAAI,GAAG;AACvC,YAAM,aAAa,kBAAkB,IAAI;AACzC,YAAM,aAAa,KAAK,gBAAgB,QAAQ,GAAG,UAAU,WAAW;AACxE,YAAM,gBAAgB,KAAK,WAAW;AACtC,iBAAW,QAAQ,KAAK,gBAAgB,cAAc;AACpD,wBAAgB,KAAK,IAAI;AACzB,YAAI,cAAc,GAAG,aAAa,KAAK,IAAI,EAAG,UAAS,IAAI,KAAK,KAAK,IAAI;AACzE,YAAI,aAAa,iBAAiB,GAAG,aAAa,KAAK,IAAI,EAAG,iBAAgB,IAAI,KAAK,KAAK,IAAI;AAAA,MAClG;AAAA,IACF,WAAW,GAAG,sBAAsB,IAAI,GAAG;AAEzC,sBAAgB,KAAK,IAAI;AAAA,IAC3B,WAAW,GAAG,oBAAoB,IAAI,KAAK,GAAG,kBAAkB,IAAI,KAAK,GAAG,sBAAsB,IAAI,KACjG,GAAG,oBAAoB,IAAI,KAAK,GAAG,yBAAyB,IAAI,KAAK,GAAG,yBAAyB,IAAI,KACrG,GAAG,qBAAqB,IAAI,GAAG;AAClC,YAAM,OAAO,iBAAiB,KAAK,IAAI;AACvC,UAAI,KAAM,UAAS,IAAI,IAAI;AAAA,IAC7B,WAAW,GAAG,8BAA8B,IAAI,GAAG;AACjD,eAAS,IAAI,KAAK,KAAK,IAAI;AAAA,IAC7B,WAAW,GAAG,oBAAoB,IAAI,GAAG;AACvC,YAAM,SAAS,KAAK;AAGpB,YAAM,WAAW,QAAQ,cAAc;AACvC,UAAI,CAAC,YAAY,GAAG,gBAAgB,KAAK,eAAe,EAAG,SAAQ,IAAI,KAAK,gBAAgB,IAAI;AAChG,UAAI,QAAQ,KAAM,UAAS,IAAI,OAAO,KAAK,IAAI;AAC/C,UAAI,QAAQ,eAAe;AACzB,YAAI,GAAG,kBAAkB,OAAO,aAAa,EAAG,UAAS,IAAI,OAAO,cAAc,KAAK,IAAI;AAAA,YACtF,YAAW,MAAM,OAAO,cAAc,SAAU,UAAS,IAAI,GAAG,KAAK,IAAI;AAAA,MAChF;AAAA,IACF,WAAW,GAAG,oBAAoB,IAAI,GAAG;AACvC,YAAM,OAAO,KAAK,mBAAmB,GAAG,gBAAgB,KAAK,eAAe,IAAI,KAAK,gBAAgB,OAAO;AAC5G,UAAI,KAAM,WAAU,IAAI,IAAI;AAC5B,UAAI,KAAK,gBAAgB,GAAG,eAAe,KAAK,YAAY,GAAG;AAC7D,mBAAW,MAAM,KAAK,aAAa,UAAU;AAC3C,mBAAS,IAAI,GAAG,KAAK,IAAI;AACzB,mBAAS,IAAI,GAAG,KAAK,IAAI;AAAA,QAC3B;AAAA,MACF,WAAW,CAAC,KAAK,gBAAgB,MAAM;AACrC,oBAAY,KAAK,IAAI;AAAA,MACvB;AAAA,IACF,WAAW,GAAG,mBAAmB,IAAI,GAAG;AACtC,eAAS,IAAI,SAAS;AAAA,IACxB,WAAW,GAAG,iBAAiB,IAAI,GAAG;AACpC,YAAM,OAAO,KAAK;AAClB,YAAM,YAAY,GAAG,aAAa,IAAI,KAAK,KAAK,SAAS;AACzD,YAAM,kBAAkB,KAAK,SAAS,GAAG,WAAW;AACpD,WAAK,aAAa,oBAAoB,KAAK,UAAU,SAAS,KAAK,GAAG,gBAAgB,KAAK,UAAU,CAAC,CAAC,GAAG;AACxG,gBAAQ,IAAK,KAAK,UAAU,CAAC,EAAyC,IAAI;AAAA,MAC5E;AAAA,IACF,WAAW,GAAG,gBAAgB,IAAI,KAAK,GAAG,gCAAgC,IAAI,GAAG;AAC/E,cAAQ,IAAI,KAAK,IAAI;AAAA,IACvB,WAAW,GAAG,2BAA2B,IAAI,GAAG;AAI9C,cAAQ,IAAI,KAAK,KAAK,IAAI;AAAA,IAC5B;AACA,OAAG,aAAa,MAAM,KAAK;AAAA,EAC7B;AACA,QAAM,EAAE;AAER,SAAO,EAAE,UAAU,SAAS,UAAU,SAAS,WAAW,aAAa,YAAY,OAAO,gBAAgB;AAC5G;AAGA,SAAS,sBAAsB,UAAkB,WAAkC;AACjF,MAAI,CAAC,UAAU,WAAW,GAAG,EAAG,QAAO;AACvC,QAAM,OAAY,cAAa,cAAQ,QAAQ,GAAG,SAAS;AAC3D,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,KAAK,QAAQ,SAAS,KAAK;AAAA,IAAG,KAAK,QAAQ,SAAS,MAAM;AAAA,IAC1D,GAAG,IAAI;AAAA,IAAO,GAAG,IAAI;AAAA,IAAQ,GAAG,IAAI;AAAA,IAC/B,WAAK,MAAM,UAAU;AAAA,IAAQ,WAAK,MAAM,UAAU;AAAA,EACzD;AACA,aAAW,KAAK,YAAY;AAC1B,QAAI;AACF,UAAO,aAAS,CAAC,EAAE,OAAO,EAAG,QAAO;AAAA,IACtC,QAAQ;AAAA,IAA2B;AAAA,EACrC;AACA,SAAO;AACT;AAOA,SAAS,iBACP,IACA,OACA,UACA,aACA,SACA,YACM;AACN,aAAW,QAAQ,MAAM,aAAa;AACpC,UAAM,SAAS,sBAAsB,UAAU,IAAI;AACnD,QAAI,CAAC,UAAU,QAAQ,IAAI,MAAM,EAAG;AAEpC,QAAS,eAAS,aAAa,MAAM,EAAE,WAAW,IAAI,EAAG;AACzD,YAAQ,IAAI,MAAM;AAElB,QAAI,cAAc,WAAW,IAAI,MAAM;AACvC,QAAI,gBAAgB,QAAW;AAC7B,UAAI;AACF,sBAAc,UAAU,IAAO,iBAAa,QAAQ,MAAM,GAAG,MAAM;AAAA,MACrE,QAAQ;AACN,sBAAc;AAAA,MAChB;AACA,iBAAW,IAAI,QAAQ,WAAW;AAAA,IACpC;AACA,QAAI,CAAC,YAAa;AAClB,qBAAiB,IAAI,aAAa,QAAQ,aAAa,SAAS,UAAU;AAC1E,eAAW,QAAQ,YAAY,UAAU;AACvC,YAAM,SAAS,IAAI,IAAI;AACvB,YAAM,SAAS,IAAI,IAAI;AAIvB,YAAM,IAAI,YAAY,WAAW,IAAI,IAAI;AACzC,UAAI,MAAM,OAAW,OAAM,WAAW,IAAI,MAAM,KAAK,IAAI,MAAM,WAAW,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC;AAC5F,YAAM,cAAc,YAAY,MAAM,IAAI,IAAI;AAC9C,UAAI,aAAa;AACf,cAAM,MAAM,MAAM,MAAM,IAAI,IAAI,KAAK,oBAAI,IAAY;AACrD,mBAAW,UAAU,YAAa,KAAI,IAAI,MAAM;AAChD,cAAM,MAAM,IAAI,MAAM,GAAG;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,YAAY,QAAyB;AAC5C,QAAM,QAAQ,OAAO,SAAS,GAAG,KAAK,IAAI,OAAO,QAAQ,IAAI,CAAC;AAC9D,SAAO,MAAM,SAAS,CAAC;AACzB;AASO,SAAS,eAAe,iBAAuC,aAAgC;AACpG,QAAM,QAA2B,CAAC;AAClC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,aAAa,oBAAI,IAA+B;AAKtD,QAAM,gBAA0B,CAAC;AACjC,aAAW,QAAQ,iBAAiB;AAClC,QAAI,KAAK,WAAY,eAAc,KAAK,KAAK,UAAU;AACvD,QAAI,KAAK,QAAS,eAAc,KAAK,KAAK,OAAO;AAAA,EACnD;AACA,aAAW,YAAY,eAAe;AACpC,UAAM,aAAa,oBAAoB,QAAQ;AAC/C,QAAI,KAAK,IAAI,UAAU,EAAG;AAC1B,SAAK,IAAI,UAAU;AAEnB,UAAM,QAAQ,EAAE,eAAe,CAAC,GAAG,eAAe,CAAC,GAAG,eAAe,CAAC,GAAG,SAAS,CAAC,GAAG,WAAW,CAAC,EAAE;AAKpG,QAAS,iBAAW,UAAU,KAAU,gBAAU,UAAU,EAAE,MAAW,SAAG,EAAE,CAAC,MAAM,MAAM;AACzF,YAAM,KAAK,EAAE,MAAM,YAAY,QAAQ,WAAW,GAAG,MAAM,CAAC;AAC5D;AAAA,IACF;AAEA,UAAM,WAAgB,cAAQ,aAAa,UAAU;AACrD,QAAS,eAAS,aAAa,QAAQ,EAAE,WAAW,IAAI,GAAG;AACzD,YAAM,KAAK,EAAE,MAAM,YAAY,QAAQ,WAAW,GAAG,MAAM,CAAC;AAC5D;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,YAAM,OAAU,aAAS,QAAQ;AACjC,UAAI,CAAC,KAAK,OAAO,GAAG;AAClB,cAAM,KAAK,EAAE,MAAM,YAAY,QAAQ,WAAW,GAAG,MAAM,CAAC;AAC5D;AAAA,MACF;AACA,eAAY,iBAAa,QAAQ;AAAA,IACnC,QAAQ;AACN,YAAM,KAAK,EAAE,MAAM,YAAY,QAAQ,WAAW,GAAG,MAAM,CAAC;AAC5D;AAAA,IACF;AAEA,QAAI,YAAY,MAAM,GAAG;AACvB,YAAM,KAAK,EAAE,MAAM,YAAY,QAAQ,cAAc,GAAG,MAAM,CAAC;AAC/D;AAAA,IACF;AAEA,UAAM,OAAO,OAAO,SAAS,MAAM;AACnC,UAAM,WAAW,mBAAwB,cAAQ,UAAU,EAAE,YAAY,CAAC;AAE1E,QAAI;AACJ,QAAI,aAAa,gBAAgB,aAAa,cAAc;AAC1D,YAAM,KAAK,kBAAkB,WAAW;AACxC,UAAI,IAAI;AACN,YAAI;AACF,gBAAM,QAAQ,UAAU,IAAI,MAAM,QAAQ;AAC1C,2BAAiB,IAAI,OAAO,UAAU,aAAa,oBAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,UAAU;AAClF,qBAAW;AAAA,YACT,eAAe;AAAA,YACf,eAAe,CAAC,GAAG,MAAM,QAAQ;AAAA,YACjC,eAAe,CAAC,GAAG,MAAM,OAAO;AAAA,YAChC,eAAe,CAAC,GAAG,MAAM,QAAQ;AAAA,YACjC,SAAS,CAAC,GAAG,MAAM,OAAO;AAAA,YAC1B,WAAW,CAAC,GAAG,MAAM,SAAS;AAAA,YAC9B,oBAAoB,OAAO,YAAY,MAAM,UAAU;AAAA,YACvD,eAAe,OAAO,YAAY,CAAC,GAAG,MAAM,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAAA,YAC/E,yBAAyB,CAAC,GAAG,MAAM,eAAe;AAAA,UACpD;AAAA,QACF,QAAQ;AACN,qBAAW,eAAe,IAAI;AAAA,QAChC;AAAA,MACF,OAAO;AACL,mBAAW,oBAAoB,MAAM,kBAAkB,QAAQ,CAAC;AAAA,MAClE;AAAA,IACF,WAAW,YAAY,kBAAkB,QAAQ,KAAK,KAAK,UAAU,4BAA4B;AAC/F,iBAAW,oBAAoB,MAAM,kBAAkB,QAAQ,CAAC;AAAA,IAClE,OAAO;AAGL,iBAAW,eAAe,IAAI;AAAA,IAChC;AAEA,UAAM,KAAK,EAAE,MAAM,YAAY,QAAQ,YAAY,UAAU,GAAG,SAAS,CAAC;AAAA,EAC5E;AAEA,SAAO,EAAE,OAAO,YAAY;AAC9B;AAvsBA,IAAAC,KACAC,OACAC,gBA6FM,oBAmBA,mBAEA,aAmBA,mBA8EA,4BAEA,eACA,WAgHA,mBACA;AAzUN;AAAA;AAAA;AAAA,IAAAF,MAAoB;AACpB,IAAAC,QAAsB;AACtB,IAAAC,iBAA8B;AA6F9B,IAAM,qBAA6C;AAAA,MACjD,OAAO;AAAA,MAAc,QAAQ;AAAA,MAAc,QAAQ;AAAA,MAAc,QAAQ;AAAA,MACzE,OAAO;AAAA,MAAc,QAAQ;AAAA,MAAc,QAAQ;AAAA,MAAc,QAAQ;AAAA,MACzE,OAAO;AAAA,MAAU,OAAO;AAAA,MAAQ,OAAO;AAAA,MAAM,OAAO;AAAA,MAAU,SAAS;AAAA,MACvE,MAAM;AAAA,MAAK,MAAM;AAAA,MAAK,QAAQ;AAAA,MAAO,OAAO;AAAA,MAAO,QAAQ;AAAA,MAC3D,OAAO;AAAA,MAAQ,QAAQ;AAAA,MAAO,OAAO;AAAA,MAAU,UAAU;AAAA,IAC3D;AAaA,IAAM,oBAAoB,EAAE,cAAc,CAAC,IAAI,GAAG,eAAe,CAAC,CAAC,MAAM,IAAI,CAAC,EAAwB;AAEtG,IAAM,cAAgC;AAAA,MACpC,GAAG;AAAA,MACH,cAAc;AAAA,QACZ;AAAA,QACA;AAAA;AAAA,QAEA;AAAA,QACA;AAAA;AAAA,QAEA;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAe,CAAC,cAAc;AAAA,IAChC;AAEA,IAAM,oBAAsD;AAAA,MAC1D,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,QAAQ;AAAA,QACN,cAAc,CAAC,GAAG;AAAA,QAAG,eAAe,CAAC,CAAC,OAAO,KAAK,GAAG,CAAC,OAAO,KAAK,CAAC;AAAA,QACnE,cAAc,CAAC,qCAAqC,uBAAuB;AAAA,QAC3E,SAAS,CAAC,oCAAoC,yBAAyB;AAAA,QACvE,eAAe,CAAC;AAAA,MAClB;AAAA,MACA,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,cAAc,CAAC,oEAAoE;AAAA,QACnF,SAAS,CAAC,mBAAmB;AAAA,QAC7B,eAAe,CAAC,WAAW;AAAA,MAC7B;AAAA,MACA,IAAI;AAAA,QACF,GAAG;AAAA,QACH,cAAc,CAAC,6CAA6C,wCAAwC;AAAA,QACpG,SAAS,CAAC,oCAAoC,gCAAgC;AAAA,QAC9E,eAAe,CAAC;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,cAAc;AAAA,UACZ;AAAA;AAAA;AAAA,UAGA;AAAA,QACF;AAAA,QACA,SAAS,CAAC,yBAAyB;AAAA,QACnC,eAAe,CAAC,cAAc;AAAA,MAChC;AAAA,MACA,MAAM;AAAA,QACJ,GAAG;AAAA,QACH,cAAc;AAAA,UACZ;AAAA,UACA;AAAA,QACF;AAAA,QACA,SAAS,CAAC,0BAA0B;AAAA,QACpC,eAAe,CAAC,cAAc;AAAA,MAChC;AAAA,MACA,GAAG;AAAA,QACD,GAAG;AAAA,QACH,cAAc,CAAC,sCAAsC,mDAAmD;AAAA,QACxG,SAAS,CAAC,8BAA8B;AAAA,QACxC,eAAe,CAAC;AAAA,MAClB;AAAA,MACA,MAAM;AAAA,QACJ,cAAc,CAAC,GAAG;AAAA,QAAG,eAAe,CAAC,CAAC,UAAU,MAAM,CAAC;AAAA,QACvD,cAAc,CAAC,+CAA+C;AAAA,QAC9D,SAAS,CAAC,6CAA6C;AAAA,QACvD,eAAe,CAAC;AAAA,MAClB;AAAA,MACA,KAAK;AAAA,QACH,cAAc,CAAC,MAAM,GAAG;AAAA,QAAG,eAAe,CAAC,CAAC,MAAM,IAAI,CAAC;AAAA,QACvD,cAAc,CAAC,wDAAwD;AAAA,QACvE,SAAS,CAAC,6DAA6D,oBAAoB;AAAA,QAC3F,eAAe,CAAC;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,cAAc,CAAC,4DAA4D;AAAA,QAC3E,SAAS,CAAC,sBAAsB;AAAA,QAChC,eAAe,CAAC;AAAA,MAClB;AAAA,MACA,OAAO;AAAA,QACL,GAAG;AAAA,QACH,cAAc,CAAC,iEAAiE;AAAA,QAChF,SAAS,CAAC,sBAAsB;AAAA,QAChC,eAAe,CAAC,cAAc;AAAA,MAChC;AAAA,IACF;AAGA,sBAAkB,MAAM,kBAAkB;AAI1C,IAAM,6BAA6B;AAEnC,IAAM,gBAAgB;AACtB,IAAM,YAAY;AAgHlB,IAAM,oBAAoB,oBAAI,IAAiD;AAC/E,IAAM,yBAAyB;AAAA;AAAA;;;ACvSxB,SAAS,sBAAsB,eAAwC;AAC5E,SAAO,kBAAkB,WAAW,aAAa;AACnD;AAEO,SAAS,sBAAsB,aAAqB,KAA2B;AACpF,QAAM,WAAW,YAAY,MAAM,IAAI;AACvC,MAAI,SAAS;AACb,aAAW,WAAW,UAAU;AAC9B,aAAS,SAAS,GAAG,MAAM,KAAK,OAAO,KAAK;AAC5C,UAAM,MAAM,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,MAAM;AACpD,QAAI,KAAK,YAAa,QAAO;AAAA,EAC/B;AACA,SAAO;AACT;AA/CA,IAuDa;AAvDb;AAAA;AAAA;AACA;AAsDO,IAAM,4BAAqC;AAAA,MAChD,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,uBAAuB,iBAAiB,WAAW,SAAS,qGAAgG;AAAA,QACpK,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,sDAAsD;AAAA,QACxH,EAAE,MAAM,4BAA4B,iBAAiB,SAAS,SAAS,iFAAiF;AAAA,QACxJ,EAAE,MAAM,qBAAqB,iBAAiB,WAAW,SAAS,2GAA4G;AAAA,QAC9K,EAAE,MAAM,gCAAgC,iBAAiB,WAAW,SAAS,oGAA+F;AAAA,QAC5K,EAAE,MAAM,wBAAwB,iBAAiB,WAAW,SAAS,iIAA4H;AAAA,MACnM;AAAA,MAEA,MAAM,KAAwB;AAC5B,cAAM,UAAU,oBAAI,IAAyB;AAC7C,mBAAW,SAAS,IAAI,UAAU,OAAO;AACvC,kBAAQ,IAAI,oBAAoB,MAAM,IAAI,GAAG;AAAA,YAC3C,UAAU,oBAAI,IAAI,CAAC,GAAG,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC;AAAA,YAClE,UAAU,oBAAI,IAAI,CAAC,GAAG,MAAM,eAAe,GAAG,MAAM,eAAe,GAAG,MAAM,aAAa,CAAC;AAAA,YAC1F;AAAA,UACF,CAAC;AAAA,QACH;AAMA,cAAM,kBAAkB,IAAI,UAAU,MAAM;AAAA,UAC1C,OAAK,EAAE,WAAW,eACZ,EAAE,aAAa,gBAAgB,EAAE,aAAa,iBAC/C,EAAE,kBAAkB;AAAA,QAC3B;AACA,YAAI,gBAAgB,SAAS,GAAG;AAC9B,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,GAAG,gBAAgB,MAAM;AAAA,UAC3B;AAAA,QACF;AAEA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,cAAI,CAAC,SAAU;AACf,gBAAM,YAAY,IAAI,aAAa,IAAI,SAAS,SAAS;AACzD,cAAI,CAAC,UAAW;AAChB,cAAI,sBAAsB,UAAU,WAAW,GAAG,EAAG;AAErD,gBAAM,QAAQ,IAAI,sBAAsB,IAAI;AAE5C,cAAI,CAAC,KAAK,YAAY;AACpB,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,iDAA4C,KAAK,QAAQ;AAAA,cACnF,KAAK;AAAA,cACL;AAAA,YACF;AACA;AAAA,UACF;AAEA,gBAAM,SAAS,QAAQ,IAAI,oBAAoB,KAAK,UAAU,CAAC;AAC/D,cAAI,CAAC,OAAQ;AAEb,gBAAM,EAAE,MAAM,IAAI;AAClB,cAAI,MAAM,WAAW,WAAW;AAC9B,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,iBAAiB,KAAK,UAAU;AAAA,cAC1D,KAAK;AAAA,cACL;AAAA,YACF;AACA;AAAA,UACF;AACA,cAAI,MAAM,WAAW,WAAW;AAC9B,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,iBAAiB,KAAK,UAAU;AAAA,cAC1D,KAAK;AAAA,cACL;AAAA,YACF;AACA;AAAA,UACF;AACA,cAAI,MAAM,WAAW,cAAc;AACjC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,iBAAiB,KAAK,UAAU;AAAA,cAC1D,KAAK;AAAA,cACL;AAAA,YACF;AACA;AAAA,UACF;AAEA,gBAAM,WAAY,KAAK,eAClB,sBAAsB,UAAU,aAAa;AAElD,qBAAW,UAAU,SAAS,SAAS;AACrC,kBAAM,aAAa,KAAK,QAAQ,KAAK,OAAK,EAAE,SAAS,OAAO,IAAI;AAChE,kBAAM,OAAQ,YAAY,eAA+C;AACzE,gBAAI,SAAS,MAAO;AAEpB,kBAAM,SAAS,YAAY,UAAU,OAAO;AAC5C,kBAAM,aAAa,OAAO,SAAS,IAAI,MAAM;AAC7C,kBAAM,aAAa,cAAc,OAAO,SAAS,IAAI,MAAM;AAC3D,kBAAM,WAAW,SAAS,aAAa,aAAa;AACpD,gBAAI,SAAU;AAEd,kBAAM,QAAQ,YAAY,SAAS,IAAI,OAAO,IAAI,cAAc,MAAM,OAAO,IAAI,OAAO,IAAI;AAC5F,kBAAM,WAAW,SAAS,cAAc,aACpC,2IACA;AACJ,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,UAAU,KAAK,iBAAiB,KAAK,QAAQ,yBAAyB,KAAK,UAAU,aAAa,IAAI,2BAA2B,MAAM,aAAa,KAAK,QAAQ;AAAA,cACjK,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC/KA,SAAS,oBAAoB,KAAkB,aAAsB;AACnE,QAAM,MAAM,cAAc,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,WAAW,IAAI;AAC3E,QAAM,UAAU,KAAK,WAAW,IAAI;AACpC,SAAO,IAAI,IAAI,SAAS,OAAO;AACjC;AAEA,SAAS,sBAAsB,KAAkB,aAA2D;AAC1G,QAAM,aAAa,IAAI,OAAO;AAC9B,QAAM,UAAU,oBAAoB,KAAK,WAAW;AAEpD,MAAI,SAAS,OAAO,eAAe;AACjC,WAAO,EAAE,GAAG,YAAY,GAAG,QAAQ,MAAM,cAAc;AAAA,EACzD;AACA,SAAO;AACT;AAEO,SAAS,6BAA6B,KAAkB,aAAwD;AACrH,QAAM,cAAc,IAAI,OAAO;AAC/B,QAAM,UAAU,oBAAoB,KAAK,WAAW;AAEpD,MAAI,SAAS,OAAO,YAAY;AAC9B,WAAO,EAAE,GAAG,aAAa,GAAG,QAAQ,MAAM,WAAW;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,iBACP,KACA,MACA,UACA,WACA,QACA,UACA,SACA;AACA,MAAI,aAAa,CAAC,QAAQ,KAAK,KAAK,EAAE,WAAW,IAAI;AACnD,QAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA,GAAG,QAAQ,KAAK,MAAM;AAAA,MACtB;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,QAAQ,aAAa,KAAK,KAAK,EAAE,SAAS,WAAW;AACvD,QAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA,GAAG,QAAQ,KAAK,MAAM,+BAA+B,KAAK,KAAK,EAAE,MAAM,eAAe,SAAS;AAAA,MAC/F;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAzDA,IA2Da;AA3Db;AAAA;AAAA;AA2DO,IAAM,iBAA0B;AAAA,MACrC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,uBAAuB,iBAAiB,WAAW,SAAS,iDAAiD;AAAA,QACrH,EAAE,MAAM,yBAAyB,iBAAiB,WAAW,SAAS,4DAA4D;AAAA,QAClI,EAAE,MAAM,qBAAqB,iBAAiB,WAAW,SAAS,4DAA4D;AAAA,QAC9H,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,sEAAsE;AAAA,QAC9I,EAAE,MAAM,0BAA0B,iBAAiB,WAAW,SAAS,4DAA4D;AAAA,QACnI,EAAE,MAAM,6BAA6B,iBAAiB,WAAW,SAAS,gFAAgF;AAAA,QAC1J,EAAE,MAAM,kCAAkC,iBAAiB,WAAW,SAAS,iEAAiE;AAAA,MAClJ;AAAA,MACA,MAAM,KAAK;AAET,mBAAW,OAAO,IAAI,YAAY;AAChC,gBAAM,YAAY,sBAAsB,KAAK,IAAI,EAAE;AACnD,2BAAiB,KAAK,IAAI,aAAa,WAAW,uBAAuB,OAAO,WAAW,sBAAsB,IAAI,IAAI,aAAa,KAAK;AAE3I,gBAAM,mBAAmB,6BAA6B,KAAK,IAAI,EAAE;AACjE,gBAAM,mBAAmB,IAAI,WAAW,OAAO,OAAK,EAAE,cAAc,IAAI,EAAE,EAAE;AAC5E,cAAI,kBAAkB,2BAA2B,UAAa,mBAAmB,iBAAiB,wBAAwB;AACxH,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,IAAI,EAAE,SAAS,gBAAgB,yDAAyD,iBAAiB,sBAAsB;AAAA,cAC7I,IAAI;AAAA,YACN;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,YAAY,sBAAsB,KAAK,KAAK,SAAS;AAC3D,gBAAM,mBAAmB,6BAA6B,KAAK,KAAK,SAAS;AACzE,gBAAM,UAAU,IAAI,iBAAiB,KAAK,EAAE;AAE5C;AAAA,YACE;AAAA,YACA,KAAK;AAAA,YACL,WAAW,uBAAuB;AAAA,YAClC,WAAW;AAAA,YACX,KAAK;AAAA,YACL;AAAA,YACA;AAAA,UACF;AAEA,cAAI,kBAAkB,6BAA6B,UAAa,KAAK,UAAU,SAAS,iBAAiB,0BAA0B;AACjI,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,SAAS,KAAK,UAAU,MAAM,oDAAoD,iBAAiB,wBAAwB;AAAA,cAChJ,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,OAAO,IAAI,aAAa,IAAI,KAAK,SAAS;AAChD,gBAAM,YAAY,sBAAsB,KAAK,MAAM,SAAS;AAC5D,gBAAM,mBAAmB,6BAA6B,KAAK,MAAM,SAAS;AAC1E,gBAAM,UAAU,IAAI,iBAAiB,KAAK,SAAS,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW;AAEnG;AAAA,YACE;AAAA,YACA,KAAK;AAAA,YACL,WAAW,uBAAuB;AAAA,YAClC,WAAW;AAAA,YACX,KAAK;AAAA,YACL;AAAA,YACA;AAAA,UACF;AAEA,cAAI,kBAAkB,wBAAwB,UAAa,KAAK,QAAQ,SAAS,iBAAiB,qBAAqB;AACrH,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,cAAc,KAAK,QAAQ,MAAM,+CAA+C,iBAAiB,mBAAmB;AAAA,cACzI,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAEA,qBAAW,KAAK,KAAK,SAAS;AAC5B;AAAA,cACE;AAAA,cACA,EAAE;AAAA,cACF,WAAW,6BAA6B;AAAA,cACxC,WAAW;AAAA,cACX,GAAG,KAAK,EAAE,IAAI,EAAE,IAAI;AAAA,cACpB;AAAA,cACA;AAAA,YACF;AAEA,kBAAM,cAAc,EAAE,UAAU,CAAC,GAAG;AACpC,gBAAI,kBAAkB,oBAAoB,UAAa,aAAa,iBAAiB,iBAAiB;AACpG,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,WAAW,EAAE,IAAI,mBAAmB,KAAK,EAAE,cAAc,UAAU,kDAAkD,iBAAiB,eAAe;AAAA,gBACrJ,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,OAAO,IAAI,aAAa,IAAI,KAAK,QAAQ;AAC/C,gBAAM,OAAO,OAAO,IAAI,aAAa,IAAI,KAAK,SAAS,IAAI;AAC3D,gBAAM,mBAAmB,6BAA6B,KAAK,MAAM,SAAS;AAC1E,gBAAM,UAAU,KAAK,WAAW,WAAW,KAAK,WAAW;AAE3D,cAAI,kBAAkB,sBAAsB,QAAW;AACrD,uBAAW,KAAK,KAAK,SAAS;AAC5B,kBAAI,EAAE,UAAU,SAAS,iBAAiB,mBAAmB;AAC3D,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,WAAW,EAAE,IAAI,wBAAwB,KAAK,EAAE,cAAc,EAAE,UAAU,MAAM,uDAAuD,iBAAiB,iBAAiB;AAAA,kBACzK,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,KAAK,IAAI,OAAO;AACzB,gBAAM,YAAY,sBAAsB,KAAK,EAAE,SAAS;AAExD;AAAA,YACE;AAAA,YACA,EAAE;AAAA,YACF,WAAW,uBAAuB;AAAA,YAClC,WAAW;AAAA,YACX,EAAE;AAAA,YACF;AAAA,YACA;AAAA,UACF;AAEA,qBAAW,KAAK,EAAE,QAAQ;AACxB;AAAA,cACE;AAAA,cACA,EAAE;AAAA,cACF,WAAW,4BAA4B;AAAA,cACvC,WAAW;AAAA,cACX,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI;AAAA,cACjB;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAEA,qBAAW,KAAK,EAAE,SAAS;AACzB;AAAA,cACE;AAAA,cACA,EAAE;AAAA,cACF,WAAW,6BAA6B;AAAA,cACxC,WAAW;AAAA,cACX,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI;AAAA,cACjB;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACxMO,SAAS,wBAAwB,eAAoD;AAC1F,MAAI,kBAAkB,YAAY,kBAAkB,cAAc,kBAAkB,WAAW;AAC7F,WAAO;AAAA,EACT;AACA,MAAI,kBAAkB,WAAW,kBAAkB,WAAW,kBAAkB,YAAY;AAC1F,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAQO,SAAS,yBACd,QACA,MACA,WACgB;AAChB,MAAI,OAAO,OAAQ,QAAO,EAAE,OAAO,OAAO,QAAQ,UAAU,KAAK;AACjE,MAAI,KAAK,OAAQ,QAAO,EAAE,OAAO,KAAK,QAAQ,UAAU,KAAK;AAC7D,SAAO,EAAE,OAAO,wBAAwB,WAAW,aAAa,GAAG,UAAU,MAAM;AACrF;AAYO,SAAS,kBAAkB,MAA0B,YAA6B;AACvF,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,IAAI,KAAK,KAAK;AACpB,MAAI,EAAE,SAAS,uBAAwB,QAAO;AAC9C,QAAM,OAAO,CAAC,MAAc,EAAE,YAAY,EAAE,QAAQ,cAAc,EAAE;AACpE,MAAI,KAAK,CAAC,MAAM,KAAK,UAAU,EAAG,QAAO;AACzC,SAAO;AACT;AAxEA,IA2BM,mBAgCO,mCAIP,wBAiBO;AAhFb;AAAA;AAAA;AAMA;AACA;AACA;AAmBA,IAAM,oBAAoB,oBAAI,IAAI,CAAC,gBAAgB,cAAc,SAAS,YAAY,CAAC;AAgChF,IAAM,oCAAoC;AAIjD,IAAM,yBAAyB;AAiBxB,IAAM,sBAA+B;AAAA,MAC1C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,qBAAqB,iBAAiB,WAAW,SAAS,sGAAsG;AAAA,QACxK,EAAE,MAAM,gBAAgB,iBAAiB,WAAW,SAAS,qHAAqH;AAAA,QAClL,EAAE,MAAM,yBAAyB,iBAAiB,WAAW,SAAS,0KAA0K;AAAA,QAChP,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,qGAAqG;AAAA,MAC/K;AAAA,MACA,MAAM,KAAK;AACT,cAAM,cAAc,oBAAI,IAA6B;AACrD,mBAAW,KAAK,IAAI,UAAU,MAAO,aAAY,IAAI,oBAAoB,EAAE,IAAI,GAAG,CAAC;AAEnF,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,cAAI,CAAC,SAAU;AACf,gBAAM,YAAY,IAAI,aAAa,IAAI,SAAS,SAAS;AAEzD,gBAAM,aACJ,KAAK,WAAW,WAAW,KAAK,WAAW,YACxC,SAAS,WAAW,WAAW,SAAS,WAAW,YACnD,IAAI,iBAAiB,SAAS,SAAS;AAE5C,qBAAW,cAAc,KAAK,SAAS;AACrC,kBAAM,iBAAiB,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,WAAW,IAAI;AAC5E,gBAAI,CAAC,eAAgB;AAErB,kBAAM,MAAM,yBAAyB,YAAY,MAAM,SAAS;AAChE,kBAAM,eAAe,WAAW,UAAU,SAAS;AACnD,gBAAI,aAAc;AAElB,gBAAI,IAAI,UAAU,QAAQ;AACxB,kBAAI;AAAA,gBACF,IAAI,WAAW,UAAU;AAAA,gBACzB;AAAA,gBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,gCACtD,IAAI,WAAW,2BAA2B,4BAA4B,WAAW,iBAAiB,WAAW,OAC9G;AAAA,gBACF,KAAK;AAAA,gBACL;AAAA,cACF;AACA;AAAA,YACF;AAMA,gBAAI,kBAAkB;AACtB,kBAAM,OAAO,WAAW,eAAe,KAAK,eACvC,sBAAsB,WAAW,iBAAiB,EAAE;AACzD,gBAAI,KAAK,cAAc,SAAS,SAC3B,EAAE,aAAa,sBAAsB,UAAU,WAAW,GAAG,IAAI;AACpE,oBAAM,QAAQ,YAAY,IAAI,oBAAoB,KAAK,UAAU,CAAC;AAClE,oBAAM,SAAS,WAAW,UAAU,WAAW;AAG/C,oBAAM,aAAa,OAAO,WAAW,cAAc,MAAM,kBAAkB,WACtE,MAAM,sBACN,OAAO,UAAU,eAAe,KAAK,MAAM,oBAAoB,MAAM,IACtE,MAAM,mBAAmB,MAAM,IAC/B;AACJ,oBAAM,QAAQ,6BAA6B,KAAK,WAAW,SAAS,GAAG,2BAClE;AACL,kBAAI,eAAe,UAAa,aAAa,OAAO;AAClD,kCAAkB;AAClB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,qBAAqB,IAAI,KAAK,kDAAkD,MAAM,SAAS,KAAK,UAAU,oCAAoC,UAAU,WAAW,KAAK,4CAAuC,IAAI,KAAK;AAAA,kBACrR,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAKA,gBAAI,CAAC,mBAAmB,IAAI,YACvB,aAAa,kBAAkB,IAAI,UAAU,aAAa,GAAG;AAChE,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,qCAAqC,IAAI,KAAK,2CAA2C,WAAW,iBAAiB,OAAO;AAAA,gBACrL,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAIA,kBAAM,QAAQ,WAAW,UAAU,eAAe;AAClD,gBAAI,CAAC,kBAAkB,OAAO,WAAW,IAAI,GAAG;AAC9C,kBAAI;AAAA,gBACF,IAAI,WAAW,UAAU;AAAA,gBACzB;AAAA,gBACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,+BAA+B,IAAI,KAAK,MAC9F,IAAI,WAAW,2BAA2B,4BAA4B,WAAW,iBAAiB,WAAW,OAC9G;AAAA,gBACF,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC5LA,IAIa,kBAUA;AAdb;AAAA;AAAA;AAIO,IAAM,mBAAuD;AAAA,MAClE,UAAU;AAAA,MAAQ,MAAM;AAAA,MAAQ,SAAS;AAAA,MAAW,YAAY;AAAA,MAChE,WAAW;AAAA,MAAa,KAAK;AAAA,MAAO,KAAK;AAAA,MAAO,QAAQ;AAAA,IAC1D;AAOO,IAAM,cAAuB;AAAA,MAClC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,8BAA8B;AAAA,QAChG,EAAE,MAAM,oBAAoB,iBAAiB,SAAS,SAAS,gDAAgD;AAAA,QAC/G,EAAE,MAAM,+BAA+B,iBAAiB,SAAS,SAAS,0DAA0D;AAAA,QACpI,EAAE,MAAM,2BAA2B,iBAAiB,SAAS,SAAS,gDAAgD;AAAA,QACtH,EAAE,MAAM,8CAA8C,iBAAiB,SAAS,SAAS,oDAAoD;AAAA,MAC/I;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAE/C,cAAI,KAAK,kBAAkB,UAAU;AACnC,gBAAI,CAAC,KAAK,YAAY;AACpB,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE;AAAA,gBACrB,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF,OAAO;AAML,oBAAM,WAAW,iBAAiB,KAAK,UAAU;AACjD,kBAAI,UAAU;AACZ,sBAAM,iBAAiB,IAAI,WAAW,OAAO,OAAK,EAAE,cAAc,KAAK,EAAE;AACzE,2BAAW,QAAQ,gBAAgB;AACjC,wBAAM,cAAc,KAAK,WAAW,WAAW,KAAK,WAAW;AAC/D,6BAAW,KAAK,KAAK,SAAS;AAC5B,wBAAI,CAAC,EAAE,UAAU;AACf,0BAAI;AAAA,wBACF;AAAA,wBACA;AAAA,wBACA,WAAW,EAAE,IAAI,mBAAmB,KAAK,EAAE,aAAa,KAAK,UAAU,kFAAkF,QAAQ;AAAA,wBACjK,KAAK;AAAA,wBACL,cAAc;AAAA,sBAChB;AAAA,oBACF,WAAW,EAAE,SAAS,cAAc,UAAU;AAC5C,0BAAI;AAAA,wBACF;AAAA,wBACA;AAAA,wBACA,WAAW,EAAE,IAAI,mBAAmB,KAAK,EAAE,iBAAiB,EAAE,SAAS,SAAS,+BAA+B,KAAK,EAAE,oBAAoB,KAAK,UAAU,yBAAyB,QAAQ;AAAA,wBAC1L,KAAK;AAAA,wBACL,cAAc;AAAA,sBAChB;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF,OAAO;AACL,gBAAI,KAAK,eAAe,UAAa,KAAK,aAAa,QAAW;AAChE,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE;AAAA,gBACrB,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAGA,kBAAM,iBAAiB,IAAI,WAAW,OAAO,OAAK,EAAE,cAAc,KAAK,EAAE;AACzE,uBAAW,QAAQ,gBAAgB;AACjC,yBAAW,KAAK,KAAK,SAAS;AAC5B,oBAAI,EAAE,UAAU;AACd,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,uCAAuC,KAAK,EAAE,UAAU,KAAK,aAAa,iBAAiB,EAAE,IAAI,uBAAuB,KAAK,EAAE;AAAA,oBAC/H,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACpGA,IAMM,oBAGA,qBAcO;AAvBb;AAAA;AAAA;AACA;AAKA,IAAM,qBACJ;AAEF,IAAM,sBAAsB,CAAC,cAAsB,YAA4B;AAC7E,UAAI,iBAAiB,cAAc;AACjC,eAAO,sBAAsB,OAAO,2GAA2G,kBAAkB;AAAA,MACnK;AAGA,aAAO,sBAAsB,OAAO,kGAAkG,kBAAkB;AAAA,IAC1J;AAOO,IAAM,qBAA8B;AAAA,MACzC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,gCAAgC,iBAAiB,SAAS,SAAS,2CAA2C;AAAA,QACtH,EAAE,MAAM,6BAA6B,iBAAiB,WAAW,SAAS,8EAA8E;AAAA,QACxJ,EAAE,MAAM,+BAA+B,iBAAiB,SAAS,SAAS,sDAAsD;AAAA,QAChI,EAAE,MAAM,kCAAkC,iBAAiB,SAAS,SAAS,yDAAyD;AAAA,QACtI,EAAE,MAAM,qCAAqC,iBAAiB,SAAS,SAAS,oDAAoD;AAAA,QACpI,EAAE,MAAM,qCAAqC,iBAAiB,SAAS,SAAS,2CAA2C;AAAA,QAC3H,EAAE,MAAM,+CAA+C,iBAAiB,SAAS,SAAS,mDAAmD;AAAA,QAC7I,EAAE,MAAM,yCAAyC,iBAAiB,SAAS,SAAS,wDAAwD;AAAA,QAC5I,EAAE,MAAM,oCAAoC,iBAAiB,SAAS,SAAS,qEAAqE;AAAA,QACpJ,EAAE,MAAM,uCAAuC,iBAAiB,WAAW,SAAS,0KAAkK;AAAA,QACtP,EAAE,MAAM,sCAAsC,iBAAiB,SAAS,SAAS,+CAA+C;AAAA,QAChI,EAAE,MAAM,oCAAoC,iBAAiB,SAAS,SAAS,0DAA0D;AAAA,QACzI,EAAE,MAAM,mCAAmC,iBAAiB,SAAS,SAAS,6CAA6C;AAAA,QAC3H,EAAE,MAAM,yBAAyB,iBAAiB,SAAS,SAAS,4NAAuN;AAAA,MAC7R;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAE/C,gBAAM,eAAe,KAAK;AAC1B,qBAAW,SAAS,cAAc;AAChC,kBAAM,UAAU,IAAI,aAAa,IAAI,KAAK;AAC1C,gBAAI,CAAC,SAAS;AAKZ,kBAAI,uBAAuB,KAAK,KAAK,GAAG;AACtC,sBAAM,WAAW,kBAAkB,KAAK,KAAK;AAC7C,oBAAI,UAAU;AACZ,sBAAI,KAAK,kBAAkB,WAAW;AACpC,wBAAI;AAAA,sBACF;AAAA,sBACA;AAAA,sBACA,uBAAuB,KAAK,aAAa,KAAK,KAAK,EAAE,0BAA0B,KAAK,4BAA4B,SAAS,SAAS,WAAW;AAAA,sBAC7I,KAAK;AAAA,sBACL;AAAA,oBACF;AAAA,kBACF;AACA;AAAA,gBACF;AACA,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,cAAc,KAAK,EAAE,sCAAsC,KAAK;AAAA,kBAChE,KAAK;AAAA,kBACL;AAAA,gBACF;AACA;AAAA,cACF;AACA,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE,uBAAuB,KAAK;AAAA,gBACjD,KAAK;AAAA,gBACL;AAAA,cACF;AACA;AAAA,YACF;AAMA,gBAAI,QAAQ,cAAc,KAAK,WAAW;AACxC,oBAAM,aAAa,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAUhE,oBAAM,YAAY,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK,SAAS;AAClE,oBAAM,WAAW,WAAW,cAAc,KAAK,OAAK,EAAE,cAAc,QAAQ,SAAS,KAAK;AAC1F,kBAAI,KAAK,kBAAkB,aAAa,CAAC,UAAU;AACjD,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,uBAAuB,KAAK,aAAa,KAAK,KAAK,EAAE,iBAAiB,KAAK,SAAS,2BAA2B,QAAQ,EAAE,mBAAmB,QAAQ,SAAS,sHAAiH,QAAQ,SAAS,sDAAsD,KAAK,SAAS;AAAA,kBACnW,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAOA,oBAAM,iBAAiB,IAAI,UAAU,IAAI,QAAQ,SAAS,GAAG,IAAI,QAAQ,EAAE,KAAK;AAChF,kBAAI,CAAC,gBAAgB;AACnB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,wBAAwB,KAAK,EAAE,iBAAiB,QAAQ,EAAE,sCAAsC,QAAQ,SAAS;AAAA,kBACjH,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF,WAAW,QAAQ,kBAAkB,YAAY,QAAQ,kBAAkB,WAAW;AACpF,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,uCAAuC,KAAK,EAAE,uBAAuB,QAAQ,SAAS,cAAc,QAAQ,EAAE,MAAM,QAAQ,aAAa,mLAA8K,QAAQ,aAAa,8EAA8E,QAAQ,SAAS;AAAA,kBAC3a,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAEA;AAAA,YACF;AAQA,kBAAM,mBAAmB,IAAI,IAAI,SAAS,IAAI,oBAAoB,KAAK,EAAE,CAAC;AAC1E,gBAAI,kBAAkB,cAAc,KAAK,OAAK,EAAE,KAAK,SAAS,KAAK,aAAa,KAAK,EAAE,GAAG,SAAS,QAAQ,aAAa,CAAC,GAAG;AAC1H;AAAA,YACF;AAGA,gBAAI,QAAQ,kBAAkB,YAAY,QAAQ,kBAAkB,YAAY;AAC9E,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,uCAAuC,KAAK,EAAE,sBAAsB,QAAQ,aAAa,eAAe,QAAQ,EAAE,MAAM,QAAQ,aAAa;AAAA,gBAC7I,KAAK;AAAA,gBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,cAC/C;AAAA,YACF;AASA,gBAAI,KAAK,kBAAkB,YAAY,KAAK,kBAAkB,YAAY;AACxE,oBAAM,iBAAiB,KAAK,kBAAkB,WAC1C,CAAC,SAAS,YAAY,SAAS,IAC/B,CAAC,SAAS,YAAY,cAAc,OAAO;AAC/C,kBAAI,eAAe,SAAS,QAAQ,aAAa,GAAG;AAClD,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,4BAA4B,KAAK,aAAa,eAAe,KAAK,EAAE,gCAAgC,QAAQ,aAAa,gBAAgB,QAAQ,EAAE,MAAM,KAAK,aAAa,sGACxK,QAAQ,kBAAkB,UAAU,oBAAoB,KAAK,eAAe,QAAQ,EAAE,IAAI;AAAA,kBAC7F,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAIA,gBAAI,KAAK,kBAAkB,cAAc;AACvC,oBAAM,iBAAiB,CAAC,UAAU,YAAY,gBAAgB,SAAS,YAAY;AACnF,kBAAI,eAAe,SAAS,QAAQ,aAAa,GAAG;AAClD,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,kDAAkD,KAAK,EAAE,uBAAuB,QAAQ,aAAa,gBAAgB,QAAQ,EAAE,wKAC5H,QAAQ,kBAAkB,UAAU,oBAAoB,KAAK,eAAe,QAAQ,EAAE,IAAI;AAAA,kBAC7F,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAOA,gBAAI,KAAK,kBAAkB,SAAS;AAClC,kBAAI,QAAQ,kBAAkB,WAAW,QAAQ,kBAAkB,WAAW;AAC5E,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,6CAA6C,KAAK,EAAE,uBAAuB,QAAQ,aAAa,gBAAgB,QAAQ,EAAE;AAAA,kBAC1H,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAOA,gBAAI,KAAK,kBAAkB,YAAY;AACrC,kBACE,QAAQ,kBAAkB,WAC1B,QAAQ,kBAAkB,aAC1B,QAAQ,kBAAkB,cAC1B;AACA,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,gDAAgD,KAAK,EAAE,2BAA2B,QAAQ,aAAa,gBAAgB,QAAQ,EAAE;AAAA,kBACjI,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,KAAK,kBAAkB,WAAW;AACpC,kBAAI,QAAQ,kBAAkB,kBAAkB,QAAQ,kBAAkB,SAAS;AACjF,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,+CAA+C,KAAK,EAAE,uBAAuB,QAAQ,aAAa,gBAAgB,QAAQ,EAAE;AAAA,kBAC5H,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,KAAK,kBAAkB,SAAS;AAClC,kBAAI,QAAQ,kBAAkB,WAAW,QAAQ,kBAAkB,WAAW;AAC5E,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,6CAA6C,KAAK,EAAE,uBAAuB,QAAQ,aAAa,gBAAgB,QAAQ,EAAE;AAAA,kBAC1H,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,KAAK,kBAAkB,QAAQ;AACjC,oBAAM,iBAAiB,CAAC,SAAS,YAAY,SAAS,WAAW,UAAU,YAAY,cAAc,WAAW,cAAc;AAC9H,kBAAI,eAAe,SAAS,QAAQ,aAAa,GAAG;AAClD,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,4CAA4C,KAAK,EAAE,uBAAuB,QAAQ,aAAa,gBAAgB,QAAQ,EAAE,kFACtH,QAAQ,kBAAkB,UAAU,oBAAoB,KAAK,eAAe,QAAQ,EAAE,IAAI;AAAA,kBAC7F,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,QAAQ,EAAE;AAAA,gBAC/C;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAQA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,gBAAM,YAAY,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AACxE,cAAI,CAAC,aAAa,UAAU,kBAAkB,SAAU;AACxD,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,qBAAW,cAAc,KAAK,SAAS;AACrC,uBAAW,QAAQ,WAAW,WAAW;AACvC,kBAAI,KAAK,SAAS,UAAU,CAAC,KAAK,mBAAmB,CAAC,KAAK,aAAc;AACzE,oBAAM,SAAS,IAAI,aAAa,IAAI,KAAK,eAAe;AACxD,kBAAI,CAAC,UAAW,OAAO,kBAAkB,gBAAgB,OAAO,kBAAkB,QAAU;AAC5F,oBAAM,gBAAgB,IAAI,sBAAsB,IAAI,OAAO,EAAE,KAAK,CAAC,GAChE,QAAQ,OAAK,EAAE,OAAO,EACtB,KAAK,OAAK,EAAE,SAAS,KAAK,YAAY;AACzC,kBAAI,cAAc,WAAW,QAAS;AACtC,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,WAAW,UAAU,EAAE,WAAW,KAAK,UAAU,QAAQ,WAAW,IAAI,+BAA+B,OAAO,EAAE,IAAI,KAAK,YAAY,8BAAyB,OAAO,aAAa;AAAA,gBAClL,KAAK;AAAA,gBACL,cAAc,IAAI,iBAAiB,OAAO,EAAE;AAAA,cAC9C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC5TA,IAQa;AARb;AAAA;AAAA;AACA;AAOO,IAAM,eAAwB;AAAA,MACnC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,iBAAiB,iBAAiB,SAAS,SAAS,sCAAsC;AAAA,QAClG,EAAE,MAAM,sBAAsB,iBAAiB,SAAS,SAAS,4BAA4B;AAAA,QAC7F,EAAE,MAAM,wBAAwB,iBAAiB,SAAS,SAAS,sCAAsC;AAAA,QACzG,EAAE,MAAM,wBAAwB,iBAAiB,SAAS,SAAS,iCAAiC;AAAA,QACpG,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,8BAA8B;AAAA,QAChG,EAAE,MAAM,0BAA0B,iBAAiB,SAAS,SAAS,8DAA8D;AAAA,QACnI,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,6DAA6D;AAAA,QAC/H,EAAE,MAAM,iCAAiC,iBAAiB,SAAS,SAAS,2EAA2E;AAAA,QACvJ,EAAE,MAAM,gCAAgC,iBAAiB,SAAS,SAAS,wDAAwD;AAAA,QACnI,EAAE,MAAM,wBAAwB,iBAAiB,SAAS,SAAS,2DAA2D;AAAA,QAC9H,EAAE,MAAM,iBAAiB,iBAAiB,WAAW,SAAS,4HAAuH;AAAA,QACrL,EAAE,MAAM,0BAA0B,iBAAiB,WAAW,SAAS,mIAA8H;AAAA,MACvM;AAAA,MACA,MAAM,KAAK;AACT,cAAM,UAAU,oBAAI,IAAoB;AACxC,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAC/C,gBAAM,YAAY,cAAc,IAAI,KAAK,aAAa;AAEtD,cAAI,aAAa,KAAK,KAAK,WAAW,GAAG;AACvC,gBAAI,SAAS,SAAS,iBAAiB,YAAY,KAAK,EAAE,MAAM,KAAK,aAAa,wCAAwC,KAAK,IAAI,UAAU;AAAA,UAC/I;AACA,cAAI,CAAC,aAAa,KAAK,KAAK,SAAS,GAAG;AACtC,gBAAI,SAAS,SAAS,sBAAsB,mBAAmB,KAAK,EAAE,MAAM,KAAK,aAAa,wCAAwC,MAAM,KAAK,aAAa,EAAE,KAAK,GAAG,CAAC,iBAAiB,KAAK,IAAI,UAAU;AAAA,UAC/M;AAEA,qBAAW,YAAY,KAAK,MAAM;AAChC,kBAAM,SAAS,IAAI,aAAa,IAAI,QAAQ;AAC5C,gBAAI,CAAC,QAAQ;AACX,kBAAI,SAAS,SAAS,wBAAwB,cAAc,KAAK,EAAE,WAAW,QAAQ,2BAA2B,KAAK,IAAI,UAAU;AACpI;AAAA,YACF;AACA,gBAAI,cAAc,IAAI,OAAO,aAAa,GAAG;AAC3C,kBAAI,SAAS,SAAS,wBAAwB,YAAY,KAAK,EAAE,WAAW,QAAQ,wHAAmH,KAAK,IAAI,UAAU;AAAA,YAC5N;AACA,kBAAM,OAAO,QAAQ,IAAI,QAAQ;AACjC,gBAAI,QAAQ,SAAS,KAAK,IAAI;AAC5B,kBAAI,SAAS,SAAS,uBAAuB,UAAU,QAAQ,uBAAuB,IAAI,UAAU,KAAK,EAAE,qCAAqC,KAAK,IAAI,UAAU;AAAA,YACrK;AACA,oBAAQ,IAAI,UAAU,KAAK,EAAE;AAAA,UAC/B;AAGA,cAAI,KAAK,kBAAkB,cAAc;AACvC,kBAAM,UAAU,oBAAI,IAAI,CAAC,SAAS,YAAY,SAAS,SAAS,CAAC;AACjE,uBAAW,YAAY,KAAK,MAAM;AAChC,oBAAM,IAAI,IAAI,aAAa,IAAI,QAAQ,GAAG;AAC1C,kBAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,GAAG;AACxB,oBAAI,SAAS,SAAS,0BAA0B,eAAe,KAAK,EAAE,WAAW,QAAQ,aAAa,CAAC,iFAAiF,KAAK,IAAI,UAAU;AAAA,cAC7M;AAAA,YACF;AAAA,UACF;AAGA,cAAI,KAAK,kBAAkB,WAAW;AACpC,kBAAM,UAAU,oBAAI,IAAI,CAAC,UAAU,gBAAgB,YAAY,CAAC;AAChE,uBAAW,YAAY,KAAK,MAAM;AAChC,oBAAM,IAAI,IAAI,aAAa,IAAI,QAAQ,GAAG;AAC1C,kBAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,GAAG;AACxB,oBAAI,SAAS,SAAS,uBAAuB,YAAY,KAAK,EAAE,WAAW,QAAQ,aAAa,CAAC,sEAAsE,KAAK,IAAI,UAAU;AAAA,cAC5L;AAAA,YACF;AAAA,UACF;AAMA,cAAI,KAAK,kBAAkB,oBAAoB;AAC7C,gBAAI,gBAAgB;AACpB,gBAAI,QAAQ;AACZ,gBAAI,SAAS;AACb,uBAAW,YAAY,KAAK,MAAM;AAChC,oBAAM,IAAI,IAAI,aAAa,IAAI,QAAQ,GAAG;AAC1C,kBAAI,MAAM,eAAgB;AAAA,uBACjB,MAAM,OAAQ;AAAA,uBACd,EAAG;AAAA,YACd;AACA,gBAAI,kBAAkB,KAAK,QAAQ,KAAK,SAAS,GAAG;AAClD,kBAAI,SAAS,SAAS,iCAAiC,qBAAqB,KAAK,EAAE,mHAA8G,KAAK,IAAI,UAAU;AAAA,YACtN;AAAA,UACF;AAGA,cAAI,KAAK,kBAAkB,mBAAmB;AAC5C,gBAAI,YAAY;AAChB,gBAAI,cAAc;AAClB,uBAAW,YAAY,KAAK,MAAM;AAChC,oBAAM,IAAI,IAAI,aAAa,IAAI,QAAQ,GAAG;AAC1C,kBAAI,MAAM,SAAU,aAAY;AAAA,uBACvB,EAAG,eAAc;AAAA,YAC5B;AACA,gBAAI,CAAC,WAAW;AACd,kBAAI,SAAS,SAAS,gCAAgC,oBAAoB,KAAK,EAAE,iEAAiE,KAAK,IAAI,UAAU;AAAA,YACvK;AACA,gBAAI,CAAC,aAAa;AAChB,kBAAI,SAAS,SAAS,gCAAgC,oBAAoB,KAAK,EAAE,6DAA6D,KAAK,IAAI,UAAU;AAAA,YACnK;AAAA,UACF;AAAA,QACF;AASA,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,KAAK,kBAAkB,WAAW,QAAQ,IAAI,KAAK,EAAE,EAAG;AAC5D,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,UAAU,KAAK,EAAE,gGAAgG,KAAK,EAAE;AAAA,YACxH,KAAK;AAAA,YACL,IAAI,iBAAiB,KAAK,EAAE;AAAA,UAC9B;AAAA,QACF;AAQA,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,KAAK,kBAAkB,cAAc,QAAQ,IAAI,KAAK,EAAE,EAAG;AAC/D,gBAAM,cAAc,KAAK,UAAU,KAAK,WAAS,IAAI,aAAa,IAAI,KAAK,GAAG,kBAAkB,OAAO;AACvG,cAAI,YAAa;AACjB,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,aAAa,KAAK,EAAE;AAAA,YACpB,KAAK;AAAA,YACL,IAAI,iBAAiB,KAAK,EAAE;AAAA,UAC9B;AAAA,QACF;AAMA,mBAAW,QAAQ,IAAI,YAAY;AACjC,qBAAW,SAAS,KAAK,WAAW;AAClC,kBAAM,QAAQ,QAAQ,IAAI,KAAK;AAC/B,gBAAI,CAAC,MAAO;AACZ,gBAAI,UAAU,KAAK,GAAI;AACvB,gBAAI,QAAQ,IAAI,KAAK,EAAE,MAAM,MAAO;AACpC,gBAAI,SAAS,SAAS,wBAAwB,cAAc,KAAK,EAAE,iBAAiB,KAAK,2CAA2C,KAAK,4BAA4B,KAAK,cAAc,KAAK,IAAI,IAAI,iBAAiB,KAAK,EAAE,KAAK,IAAI,iBAAiB,KAAK,CAAC;AAAA,UAC/P;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACrKA,IAcM,cAEO;AAhBb;AAAA;AAAA;AAcA,IAAM,eAAe,oBAAI,IAAI,CAAC,cAAc,SAAS,CAAC;AAE/C,IAAM,uBAAgC;AAAA,MAC3C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,qBAAqB,iBAAiB,WAAW,SAAS,mEAAmE;AAAA,MACvI;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,cAAI,CAAC,SAAU;AACf,gBAAM,OAAO,IAAI,aAAa,IAAI,SAAS,SAAS;AACpD,cAAI,CAAC,QAAQ,CAAC,aAAa,IAAI,KAAK,aAAa,EAAG;AACpD,gBAAM,QAAQ,IAAI,IAAI,KAAK,IAAI;AAC/B,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,qBAAW,UAAU,KAAK,SAAS;AACjC,kBAAM,QAAQ,OAAO,aAAa,CAAC;AACnC,gBAAI,MAAM,WAAW,EAAG;AAExB,gBAAI;AACJ,gBAAI,MAAM,WAAW,GAAG;AACtB,wBAAU,OAAO,MAAM,MAAM,WAAW,MAAM,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,YAC3E,WAAW,MAAM,CAAC,EAAE,SAAS,QAAQ;AACnC,wBAAU,gBAAgB,MAAM,CAAC,EAAE,IAAI;AAAA,YACzC,WAAW,MAAM,CAAC,EAAE,mBAAmB,CAAC,MAAM,IAAI,MAAM,CAAC,EAAE,eAAe,GAAG;AAC3E,wBAAU,yDAAoD,MAAM,CAAC,EAAE,eAAe,aAAa,KAAK,EAAE;AAAA,YAC5G;AACA,gBAAI,SAAS;AACX,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,kBAAkB,OAAO,IAAI,QAAQ,KAAK,aAAa,KAAK,KAAK,EAAE,sBAAsB,KAAK,EAAE,mFAA8E,KAAK,KAAK,KAAK,IAAI,KAAK,eAAe,8BAAyB,OAAO;AAAA,gBACrP,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACxDA,IAUa;AAVb;AAAA;AAAA;AAUO,IAAM,wBAAiC;AAAA,MAC5C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,uBAAuB,iBAAiB,WAAW,SAAS,yDAAyD;AAAA,QAC7H,EAAE,MAAM,4BAA4B,iBAAiB,WAAW,SAAS,4DAA4D;AAAA,MACvI;AAAA,MACA,MAAM,KAAK;AAET,YAAI,CAAC,IAAI,WAAW,KAAK,OAAK,EAAE,YAAY,EAAE,SAAS,SAAS,CAAC,EAAG;AAEpE,cAAM,eAAe,oBAAI,IAAyB;AAClD,mBAAW,KAAK,IAAI,IAAI,UAAU;AAChC,gBAAM,MAAM,aAAa,IAAI,EAAE,EAAE,KAAK,oBAAI,IAAY;AACtD,cAAI,IAAI,EAAE,OAAO;AACjB,uBAAa,IAAI,EAAE,IAAI,GAAG;AAAA,QAC5B;AAEA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAC/C,qBAAW,OAAO,KAAK,YAAY,CAAC,GAAG;AACrC,kBAAM,WAAW,aAAa,IAAI,IAAI,EAAE;AACxC,gBAAI,CAAC,UAAU;AACb,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE,yBAAyB,IAAI,EAAE;AAAA,gBACpD,KAAK;AAAA,gBACL;AAAA,cACF;AACA;AAAA,YACF;AACA,gBAAI,IAAI,WAAW,CAAC,SAAS,IAAI,IAAI,OAAO,GAAG;AAC7C,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE,mBAAmB,IAAI,EAAE,cAAc,IAAI,OAAO,8CAA8C,CAAC,GAAG,QAAQ,EAAE,KAAK,IAAI,CAAC;AAAA,gBAC7I,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACvDA,IAWa;AAXb;AAAA;AAAA;AAWO,IAAM,wBAAiC;AAAA,MAC5C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,mBAAmB,iBAAiB,WAAW,SAAS,sDAAsD;AAAA,QACtH,EAAE,MAAM,yBAAyB,iBAAiB,SAAS,SAAS,oEAAoE;AAAA,MAC1I;AAAA,MACA,MAAM,KAAK;AACT,YAAI,CAAC,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,EAAG;AAE1C,cAAM,OAAO,IAAI,IAAI,IAAI,SAAS,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAErD,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,CAAC,KAAK,QAAS;AACnB,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAC/C,gBAAM,MAAM,KAAK,IAAI,KAAK,OAAO;AACjC,cAAI,CAAC,KAAK;AACR,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,uBAAuB,KAAK,OAAO;AAAA,cACxD,KAAK;AAAA,cACL;AAAA,YACF;AACA;AAAA,UACF;AACA,cAAI,IAAI,SAAS,KAAK,eAAe;AACnC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,UAAU,KAAK,aAAa,kBAAkB,KAAK,OAAO,uBAAuB,IAAI,IAAI;AAAA,cAC9G,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACpCA,SAAS,aAAa,MAAsB;AAC1C,QAAM,UAAU,KAAK,QAAQ,uBAAuB,QAAO,OAAO,MAAM,OAAO,KAAK,EAAE,EAAG;AACzF,SAAO,IAAI,OAAO,IAAI,OAAO,GAAG;AAClC;AAEA,SAAS,QAAQ,KAAwB,MAAqB,KAA2B;AACvF,MAAI,IAAI,eAAe,UAAU,CAAC,IAAI,cAAc,SAAS,KAAK,aAAa,EAAG,QAAO;AACzF,MAAI,IAAI,SAAS,UAAU,CAAC,IAAI,QAAQ,SAAS,IAAI,oBAAoB,KAAK,EAAE,CAAC,EAAG,QAAO;AAC3F,MAAI,IAAI,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,KAAK,KAAK,EAAE,EAAG,QAAO;AAC1D,SAAO;AACT;AAGA,SAAS,gBAAgB,IAAsB;AAC7C,UAAQ,GAAG,WAAW;AAAA,IACpB,KAAK;AAAQ,aAAO,GAAG;AAAA,IACvB,KAAK;AAAQ,aAAO,GAAG,GAAG,OAAO,IAAI,GAAG,MAAM;AAAA,IAC9C,KAAK;AAAW,aAAO,GAAG;AAAA,IAC1B,KAAK;AAAc,aAAO,GAAG;AAAA,IAC7B,KAAK;AAAa,aAAO,GAAG;AAAA,IAC5B,KAAK;AAAO,aAAO,GAAG;AAAA,IACtB,KAAK;AAAO,aAAO,GAAG;AAAA,IACtB,KAAK;AAAU,aAAO,GAAG;AAAA,EAC3B;AACF;AAGA,SAAS,WAAW,MAA+B,OAAwB;AACzE,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,SAAS,CAAC,MAAM,OAAO;AACzB,WAAO,SAAS,WAAW,IAAI,KAAK,KAAK,IAAI;AAAA,EAC/C;AACA,MAAI,MAAe,KAAK;AACxB,aAAW,OAAO,SAAS,MAAM,CAAC,GAAG;AACnC,QAAI,QAAQ,QAAQ,OAAO,QAAQ,SAAU,QAAO;AACpD,QAAI,CAAC,OAAO,UAAU,eAAe,KAAK,KAAK,GAAG,EAAG,QAAO;AAC5D,UAAO,IAAgC,GAAG;AAAA,EAC5C;AACA,SAAO;AACT;AApDA,IAsDa;AAtDb;AAAA;AAAA;AAsDO,IAAM,4BAAqC;AAAA,MAChD,MAAM;AAAA,MACN,aACE;AAAA;AAAA;AAAA,MAGF,OAAO,CAAC;AAAA,MACR,MAAM,KAAK;AACT,cAAM,aAAgC,IAAI,IAAI;AAC9C,YAAI,CAAC,WAAW,OAAQ;AAExB,cAAM,OAAO,CAAC,GAAoB,SAAiB,QAAgB,eAA8B;AAI/F,gBAAM,WAAqB,cAAc,EAAE,aAAa,UAAU,YAAY,EAAE;AAChF,cAAI,SAAS,UAAU,EAAE,UAAU,GAAG,OAAO,WAAW,EAAE,IAAI,OAAO,EAAE,MAAM,IAAI,QAAQ,UAAU;AAAA,QACrG;AAEA,mBAAW,KAAK,YAAY;AAC1B,cAAI,EAAE,SAAS,eAAe;AAC5B,uBAAW,QAAQ,IAAI,YAAY;AACjC,kBAAI,CAAC,QAAQ,EAAE,MAAM,MAAM,GAAG,EAAG;AACjC,oBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAC/C,yBAAW,YAAY,EAAE,UAAU;AACjC,2BAAW,YAAY,KAAK,QAAQ,GAAG;AACrC,wBAAM,SAAS,IAAI,aAAa,IAAI,QAAQ;AAC5C,sBAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,QAAQ,GAAG,EAAG;AAC5C,uBAAK,GAAG,cAAc,KAAK,EAAE,MAAM,KAAK,aAAa,KAAK,aAAa,SAAS,SAAS,YAAY,KAAK,OAAO,EAAE,MAAM,OAAO,aAAa,6BAA6B,EAAE,IAAI,IAAI,KAAK,IAAI,UAAU;AAAA,gBACzM;AAAA,cACF;AAAA,YACF;AAAA,UACF,WAAW,EAAE,SAAS,iBAAiB;AAErC,kBAAM,UAAoB,CAAC;AAC3B,gBAAI,EAAE,UAAU,aAAa;AAC3B,yBAAW,KAAK,IAAI,WAAY,SAAQ,KAAK,EAAE,MAAM,GAAyC,QAAQ,EAAE,IAAI,MAAM,GAAG,OAAO,IAAI,iBAAiB,EAAE,EAAE,EAAE,CAAC;AAAA,YAC1J,WAAW,EAAE,UAAU,aAAa;AAClC,yBAAW,KAAK,IAAI,YAAY;AAC9B,sBAAM,OAAO,IAAI,aAAa,IAAI,EAAE,SAAS;AAC7C,oBAAI,KAAM,SAAQ,KAAK,EAAE,MAAM,GAAyC,QAAQ,EAAE,IAAI,MAAM,OAAO,IAAI,iBAAiB,KAAK,EAAE,KAAK,EAAE,WAAW,WAAW,EAAE,WAAW,SAAS,CAAC;AAAA,cACrL;AAAA,YACF,OAAO;AACL,yBAAW,QAAQ,IAAI,iBAAiB;AACtC,sBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,sBAAM,OAAO,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AACnE,oBAAI,KAAM,SAAQ,KAAK,EAAE,MAAM,MAA4C,QAAQ,KAAK,IAAI,MAAM,OAAO,IAAI,sBAAsB,IAAI,EAAE,CAAC;AAAA,cAC5I;AAAA,YACF;AACA,uBAAW,KAAK,SAAS;AACvB,kBAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,EAAG;AACjC,oBAAM,IAAI,WAAW,EAAE,MAAM,EAAE,KAAK;AACpC,kBAAI,MAAM,UAAa,MAAM,MAAM;AACjC,qBAAK,GAAG,GAAG,EAAE,KAAK,UAAU,EAAE,MAAM,uBAAuB,EAAE,KAAK,4BAA4B,EAAE,IAAI,IAAI,EAAE,QAAQ,EAAE,KAAK;AAAA,cAC3H,WAAW,EAAE,UAAU,CAAC,EAAE,OAAO,SAAS,OAAO,CAAC,CAAC,GAAG;AACpD,qBAAK,GAAG,GAAG,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,EAAE,KAAK,QAAQ,OAAO,CAAC,CAAC,+BAA+B,EAAE,OAAO,KAAK,IAAI,CAAC,kBAAkB,EAAE,IAAI,IAAI,EAAE,QAAQ,EAAE,KAAK;AAAA,cAC5K;AAAA,YACF;AAAA,UACF,WAAW,EAAE,SAAS,kBAAkB;AACtC,kBAAM,UAAU,EAAE,cAAc,IAAI,OAAO,EAAE,WAAW,IAAI;AAC5D,uBAAW,QAAQ,IAAI,YAAY;AACjC,oBAAM,OAAO,IAAI,aAAa,IAAI,KAAK,SAAS;AAChD,kBAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,MAAM,GAAG,EAAG;AACxC,oBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW;AAC/F,yBAAW,UAAU,KAAK,SAAS;AACjC,oBAAI,CAAC,OAAO,SAAU;AACtB,sBAAM,KAAK,OAAO;AAClB,oBAAI,EAAE,WAAW,UAAU,CAAC,EAAE,UAAU,SAAS,GAAG,SAAS,GAAG;AAC9D,uBAAK,GAAG,gBAAgB,KAAK,EAAE,IAAI,OAAO,IAAI,oBAAoB,GAAG,SAAS,4BAA4B,EAAE,UAAU,KAAK,IAAI,CAAC,kBAAkB,EAAE,IAAI,IAAI,KAAK,IAAI,UAAU;AAC/K;AAAA,gBACF;AACA,sBAAM,UAAU,gBAAgB,EAAE;AAClC,oBAAI,WAAW,CAAC,QAAQ,KAAK,OAAO,GAAG;AACrC,uBAAK,GAAG,gBAAgB,KAAK,EAAE,IAAI,OAAO,IAAI,YAAY,OAAO,2BAA2B,EAAE,WAAW,0BAA0B,EAAE,IAAI,IAAI,KAAK,IAAI,UAAU;AAAA,gBAClK;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACtIA,IAWM,cACA,eAEA,eAEO;AAhBb;AAAA;AAAA;AAAA;AAWA,IAAM,eAAe,oBAAI,IAAI,CAAC,WAAW,eAAe,YAAY,qBAAqB,YAAY,CAAC;AACtG,IAAM,gBAAgB,oBAAI,IAAI,CAAC,qBAAqB,qBAAqB,CAAC;AAE1E,IAAM,gBAAgB,oBAAI,IAAI,CAAC,aAAa,qBAAqB,UAAU,CAAC;AAErE,IAAM,eAAwB;AAAA,MACnC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,kCAAkC,iBAAiB,SAAS,SAAS,sDAAsD;AAAA,QACnI,EAAE,MAAM,oCAAoC,iBAAiB,SAAS,SAAS,gDAAgD;AAAA,QAC/H,EAAE,MAAM,kCAAkC,iBAAiB,WAAW,SAAS,qDAAqD;AAAA,QACpI,EAAE,MAAM,gCAAgC,iBAAiB,SAAS,SAAS,6DAA6D;AAAA,QACxI,EAAE,MAAM,kCAAkC,iBAAiB,WAAW,SAAS,+DAA+D;AAAA,QAC9I,EAAE,MAAM,mBAAmB,iBAAiB,WAAW,SAAS,uEAAuE;AAAA,MACzI;AAAA,MACA,MAAM,KAAK;AACT,cAAM,aAAa,oBAAI,IAAY,CAAC,GAAG,kBAAkB,GAAG,OAAO,KAAK,IAAI,IAAI,QAAQ,CAAC,CAAC;AAE1F,mBAAW,OAAO,IAAI,YAAY;AAChC,cAAI,IAAI,WAAW,CAAC,WAAW,IAAI,IAAI,OAAO,GAAG;AAC/C,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,IAAI,EAAE,uBAAuB,IAAI,OAAO,2CAA2C,iBAAiB,KAAK,IAAI,CAAC;AAAA,cAC5H,IAAI;AAAA,YACN;AAAA,UACF;AAAA,QACF;AACA,YAAI,CAAC,WAAW,IAAI,IAAI,WAAW,KAAK,CAAC,cAAc,IAAI,IAAI,WAAW,GAAG;AAC3E,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,gBAAgB,IAAI,WAAW;AAAA,UACjC;AAAA,QACF;AAEA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAC/C,gBAAM,UAAU,IAAI,oBAAoB,KAAK,EAAE;AAC/C,gBAAM,UAAU,IAAI,IAAI,SAAS,OAAO;AACxC,gBAAM,SAAS,UACX,QAAQ,SACR,cAAc,IAAI,OAAO,IAAI,kBAC3B,aAAa,IAAI,OAAO,IAAI,iBAC1B;AAER,cAAI,WAAW,gBAAgB;AAC7B,kBAAM,gBAAgB,CAAC,QAAQ,oBAAoB,iBAAiB;AACpE,gBAAI,cAAc,SAAS,KAAK,aAAa,GAAG;AAC9C,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,uCAAuC,KAAK,EAAE,+BAA+B,KAAK,aAAa,oBAAoB,KAAK,SAAS;AAAA,gBACjI,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,YAAY,cAAc;AAC5B,kBAAI,KAAK,kBAAkB,WAAW,KAAK,kBAAkB,cAAc;AACzE,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,uCAAuC,KAAK,EAAE,iCAAiC,KAAK,aAAa;AAAA,kBACjG,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF,WAAW,WAAW,iBAAiB;AACrC,kBAAM,mBAAmB,CAAC,cAAc,OAAO;AAC/C,gBAAI,iBAAiB,SAAS,KAAK,aAAa,GAAG;AACjD,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,SAAS,6CAA6C,KAAK,EAAE,8BAA8B,KAAK,aAAa;AAAA,gBAChI,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAGA,cAAI,SAAS;AACX,uBAAW,QAAQ,QAAQ,sBAAsB;AAC/C,kBAAI,KAAK,MAAM,SAAS,KAAK,aAAa,GAAG;AAC3C,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,cAAc,KAAK,EAAE,UAAU,KAAK,aAAa,2BAA2B,OAAO,MAAM,KAAK,MAAM;AAAA,kBACpG,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AACA,uBAAW,QAAQ,QAAQ,wBAAwB;AACjD,kBAAI,KAAK,MAAM,SAAS,KAAK,aAAa,GAAG;AAC3C,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,cAAc,KAAK,EAAE,UAAU,KAAK,aAAa,6BAA6B,OAAO,MAAM,KAAK,MAAM;AAAA,kBACtG,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC3HA,IAEM,gBAgBA,aAEA,aAgBO;AApCb;AAAA;AAAA;AAEA,IAAM,iBAAiB,CAAC,QAAgB,IAAY,eAAiC;AACnF,cAAQ,QAAQ;AAAA,QACd,KAAK;AAAc,iBAAO,OAAO,YAAY,eAAe;AAAA,QAC5D,KAAK;AAAc,iBAAO,OAAO,YAAY,eAAe;AAAA,QAC5D,KAAK;AAAc,iBAAO,OAAO,YAAY,eAAe;AAAA,QAC5D,KAAK;AAAc,iBAAQ,OAAO,YAAY,eAAe,gBAAiB,OAAO;AAAA,QACrF,KAAK;AAAc,iBAAO;AAAA,QAC1B;AAAmB,iBAAO;AAAA,MAC5B;AAAA,IACF;AAOA,IAAM,cAAc;AAEpB,IAAM,cAAc,CAAC,MAAsB;AACzC,cAAQ,GAAG;AAAA,QACT,KAAK;AAAc,iBAAO;AAAA,QAC1B,KAAK;AAAc,iBAAO;AAAA,QAC1B,KAAK;AAAc,iBAAO;AAAA,QAC1B,KAAK;AAAc,iBAAO;AAAA,QAC1B;AAAmB,iBAAO;AAAA,MAC5B;AAAA,IACF;AAQO,IAAM,oBAA6B;AAAA,MACxC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,4BAA4B,iBAAiB,SAAS,SAAS,6CAA6C;AAAA,QACpH,EAAE,MAAM,sCAAsC,iBAAiB,SAAS,SAAS,uDAAuD;AAAA,QACxI,EAAE,MAAM,sCAAsC,iBAAiB,SAAS,SAAS,mDAAmD;AAAA,QACpI,EAAE,MAAM,kCAAkC,iBAAiB,SAAS,SAAS,+DAA+D;AAAA,QAC5I,EAAE,MAAM,sCAAsC,iBAAiB,SAAS,SAAS,+DAA+D;AAAA,QAChJ,EAAE,MAAM,mCAAmC,iBAAiB,WAAW,SAAS,uEAAuE;AAAA,MACzJ;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,OAAO,IAAI,YAAY;AAChC,gBAAM,aAAa,IAAI,WAAW,WAAW,IAAI,WAAW;AAC5D,qBAAW,MAAM,IAAI,kBAAkB;AACrC,gBAAI,CAAC,GAAG,WAAW;AACjB,kBAAI,SAAS,SAAS,4BAA4B,cAAc,IAAI,EAAE,gBAAgB,GAAG,IAAI,0HAA0H,IAAI,IAAI,UAAU;AACzO;AAAA,YACF;AACA,kBAAM,UAAU,IAAI,aAAa,IAAI,GAAG,SAAS;AACjD,gBAAI,CAAC,SAAS;AACZ,kBAAI,SAAS,SAAS,sCAAsC,cAAc,IAAI,EAAE,4CAA4C,GAAG,SAAS,2BAA2B,IAAI,IAAI,UAAU;AACrL;AAAA,YACF;AACA,kBAAM,mBAAmB,QAAQ,cAAc,IAAI,MAAM,QAAQ,UAAU,WAAW,IAAI,KAAK,IAAI;AACnG,gBAAI,CAAC,kBAAkB;AACrB,kBAAI,SAAS,SAAS,sCAAsC,cAAc,IAAI,EAAE,0BAA0B,GAAG,SAAS,mCAAmC,QAAQ,SAAS,uDAAuD,IAAI,IAAI,UAAU;AAAA,YACrP;AACA,gBAAI,CAAC,eAAe,GAAG,MAAM,QAAQ,eAAe,QAAQ,UAAU,GAAG;AACvE,kBAAI,SAAS,SAAS,kCAAkC,cAAc,IAAI,EAAE,gBAAgB,GAAG,IAAI,gCAAgC,GAAG,SAAS,MAAM,QAAQ,aAAa,GAAG,QAAQ,aAAa,IAAI,QAAQ,UAAU,KAAK,EAAE,2BAA2B,GAAG,IAAI,cAAc,YAAY,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,UAAU;AAAA,YAC5T;AACA,gBAAI,GAAG,WAAW;AAChB,oBAAM,OAAO,IAAI,aAAa,IAAI,GAAG,SAAS;AAC9C,kBAAI,CAAC,MAAM;AACT,oBAAI,SAAS,SAAS,sCAAsC,cAAc,IAAI,EAAE,4CAA4C,GAAG,SAAS,2BAA2B,IAAI,IAAI,UAAU;AAAA,cACvL,WAAW,KAAK,cAAc,GAAG,WAAW;AAC1C,oBAAI,SAAS,SAAS,sCAAsC,cAAc,IAAI,EAAE,sBAAsB,GAAG,SAAS,mBAAmB,GAAG,SAAS,+CAA+C,KAAK,SAAS,MAAM,IAAI,IAAI,UAAU;AAAA,cACxO;AAAA,YACF;AAQA,gBAAI,GAAG,SAAS,YAAY,YAAY,KAAK,GAAG,OAAO,GAAG;AACxD,oBAAM,eAAe,QAAQ,kBAAkB,cACzC,QAAQ,kBAAkB,YAAY,QAAQ,eAAe;AACnE,kBAAI,CAAC,cAAc;AACjB,oBAAI,SAAS,WAAW,mCAAmC,cAAc,IAAI,EAAE,4FAA4F,GAAG,OAAO,4BAA4B,GAAG,SAAS,MAAM,QAAQ,aAAa,GAAG,QAAQ,aAAa,IAAI,QAAQ,UAAU,KAAK,EAAE,qNAAqN,IAAI,IAAI,UAAU;AAAA,cACthB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACEO,SAAS,mBACd,KACA,OACA,OAAoB,CAAC,GAC4C;AACjE,QAAM,uBAAuB,KAAK,wBAAwB;AAC1D,QAAM,oBAAoB,oBAAI,IAAY;AAC1C,QAAM,iBAAiB,oBAAI,IAAY;AACvC,QAAM,QAAkD,CAAC;AAEzD,QAAM,gBAAgB,CAAC,QAAgB,eAA6B;AAClE,UAAM,MAAM,UAAU,QAAQ,UAAU;AACxC,QAAI,CAAC,eAAe,IAAI,GAAG,GAAG;AAC5B,qBAAe,IAAI,GAAG;AACtB,YAAM,KAAK,EAAE,QAAQ,WAAW,CAAC;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,WAAyB;AAC/C,QAAI,kBAAkB,IAAI,MAAM,EAAG;AACnC,sBAAkB,IAAI,MAAM;AAC5B,QAAI,CAAC,qBAAsB;AAG3B,UAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,eAAW,KAAK,MAAM,YAAY,CAAC,GAAG;AACpC,UAAI,IAAI,aAAa,IAAI,EAAE,SAAS,GAAG;AACrC,uBAAe,EAAE,SAAS;AAC1B,sBAAc,EAAE,WAAW,EAAE,MAAM;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB,CAAC,WAAyB;AAClD,eAAW,QAAQ,IAAI,sBAAsB,IAAI,MAAM,KAAK,CAAC,GAAG;AAC9D,iBAAW,KAAK,KAAK,SAAS;AAC5B,sBAAc,QAAQ,EAAE,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAEA,aAAW,QAAQ,OAAO;AACxB,mBAAe,KAAK,MAAM;AAC1B,QAAI,KAAK,YAAY;AACnB,oBAAc,KAAK,QAAQ,KAAK,UAAU;AAAA,IAC5C,OAAO;AACL,wBAAkB,KAAK,MAAM;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO,MAAM,SAAS,GAAG;AACvB,UAAM,EAAE,QAAQ,WAAW,IAAI,MAAM,MAAM;AAG3C,QAAI;AACJ,QAAI;AACJ,eAAW,QAAQ,IAAI,sBAAsB,IAAI,MAAM,KAAK,CAAC,GAAG;AAC9D,iBAAW,aAAa,IAAI,0BAA0B,IAAI,KAAK,EAAE,KAAK,CAAC,GAAG;AACxE,cAAM,IAAI,UAAU,QAAQ,KAAK,QAAM,GAAG,SAAS,UAAU;AAC7D,YAAI,GAAG;AAAE,iBAAO;AAAW,uBAAa;AAAG;AAAA,QAAO;AAAA,MACpD;AACA,UAAI,KAAM;AAAA,IACZ;AACA,QAAI,CAAC,QAAQ,CAAC,WAAY;AAE1B,eAAW,QAAQ,WAAW,WAAW;AACvC,UAAI,KAAK,SAAS,UAAU,KAAK,mBAAmB,KAAK,cAAc;AACrE,uBAAe,KAAK,eAAe;AACnC,sBAAc,KAAK,iBAAiB,KAAK,YAAY;AAAA,MACvD;AACA,UAAI,KAAK,SAAS,cAAc,KAAK,iBAAiB;AACpD,uBAAe,KAAK,eAAe;AACnC,cAAM,SAAS,IAAI,aAAa,IAAI,KAAK,eAAe;AACxD,cAAM,UAAU,QAAQ,UAAU,KAAK,OAAK,EAAE,eAAe,KAAK,UAAU;AAC5E,YAAI,WAAW,IAAI,aAAa,IAAI,QAAQ,SAAS,GAAG;AACtD,yBAAe,QAAQ,SAAS;AAChC,wBAAc,QAAQ,WAAW,QAAQ,MAAM;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAQA,QAAI,WAAW,UAAU,WAAW,GAAG;AACrC,YAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,UAAI,QAAQ,yBAAyB,YAAY,MAAM,IAAI,EAAE,UAAU,QAAQ;AAC7E,mBAAW,SAAS,CAAC,GAAG,KAAK,WAAW,GAAG,KAAK,IAAI,GAAG;AACrD,cAAI,CAAC,IAAI,aAAa,IAAI,KAAK,EAAG;AAClC,yBAAe,KAAK;AACpB,4BAAkB,KAAK;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,mBAAmB,eAAe;AAC7C;AAnMA,IAKa,YA4DA,WAyIA;AA1Mb;AAAA;AAAA;AACA;AACA;AAGO,IAAM,aAAsB;AAAA,MACjC,MAAM;AAAA,MACN,aAAa;AAAA,MACb,OAAO;AAAA,QACL,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,yCAAyC;AAAA,MAC7G;AAAA,MACA,MAAM,KAAK;AACT,cAAM,UAAU,oBAAI,IAAY;AAChC,cAAM,WAAW,oBAAI,IAAY;AAEjC,cAAM,MAAM,CAAC,QAAgB,cAAiC;AAC5D,kBAAQ,IAAI,MAAM;AAClB,mBAAS,IAAI,MAAM;AACnB,oBAAU,KAAK,MAAM;AAErB,gBAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,cAAI,MAAM;AACR,uBAAW,SAAS,KAAK,WAAW;AAClC,kBAAI,CAAC,QAAQ,IAAI,KAAK,GAAG;AACvB,oBAAI,IAAI,OAAO,SAAS,GAAG;AACzB,2BAAS,OAAO,MAAM;AACtB,4BAAU,IAAI;AACd,yBAAO;AAAA,gBACT;AAAA,cACF,WAAW,SAAS,IAAI,KAAK,GAAG;AAC9B,0BAAU,KAAK,KAAK;AACpB,sBAAM,YAAY,UAAU,MAAM,UAAU,QAAQ,KAAK,CAAC,EAAE,KAAK,MAAM;AACvE,sBAAM,aAAa,IAAI,iBAAiB,MAAM,KAAK,IAAI,iBAAiB,KAAK;AAC7E,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,iCAAiC,SAAS;AAAA,kBAC1C;AAAA,kBACA;AAAA,gBACF;AACA,0BAAU,IAAI;AACd,yBAAS,OAAO,MAAM;AACtB,0BAAU,IAAI;AACd,uBAAO;AAAA,cACT;AAAA,YACF;AAAA,UACF;AAEA,mBAAS,OAAO,MAAM;AACtB,oBAAU,IAAI;AACd,iBAAO;AAAA,QACT;AAEA,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,CAAC,QAAQ,IAAI,KAAK,EAAE,GAAG;AACzB,gBAAI,IAAI,KAAK,IAAI,CAAC,CAAC,GAAG;AACpB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAIO,IAAM,YAAY,CAAC,QAAgB,eAA+B,GAAG,MAAM,IAAI,UAAU;AAyIzF,IAAM,mBAA4B;AAAA,MACvC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,oBAAoB,iBAAiB,WAAW,SAAS,sDAAsD;AAAA,QACvH,EAAE,MAAM,iBAAiB,iBAAiB,WAAW,SAAS,4CAA4C;AAAA,QAC1G,EAAE,MAAM,eAAe,iBAAiB,WAAW,SAAS,gDAAgD;AAAA,MAC9G;AAAA,MACA,MAAM,KAAK;AAIT,cAAM,QAAoB,CAAC;AAC3B,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,KAAK,kBAAkB,YAAY,KAAK,kBAAkB,YAAY;AACxE,kBAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC;AAAA,UAChC;AAAA,QACF;AACA,mBAAW,OAAO,IAAI,YAAY;AAChC,qBAAW,MAAM,IAAI,kBAAkB;AACrC,gBAAI,GAAG,WAAW;AAChB,oBAAM,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;AAAA,YACrC;AAAA,UACF;AACA,qBAAW,MAAM,IAAI,aAAa,CAAC,GAAG;AACpC,kBAAM,KAAK,EAAE,QAAQ,GAAG,WAAW,YAAY,GAAG,OAAO,CAAC;AAAA,UAC5D;AAAA,QACF;AAEA,cAAM,EAAE,mBAAmB,eAAe,IAAI,mBAAmB,KAAK,KAAK;AAG3E,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,CAAC,IAAI,cAAc,KAAK,EAAE,EAAG;AACjC,cAAI,CAAC,kBAAkB,IAAI,KAAK,EAAE,GAAG;AACnC,kBAAM,aAAa,KAAK,WAAW,WAAW,KAAK,WAAW;AAC9D,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE;AAAA,cACrB,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF,OAAO;AAEL,uBAAW,QAAQ,IAAI,sBAAsB,IAAI,KAAK,EAAE,KAAK,CAAC,GAAG;AAC/D,yBAAW,KAAK,KAAK,SAAS;AAC5B,oBAAI,CAAC,eAAe,IAAI,UAAU,KAAK,IAAI,EAAE,IAAI,CAAC,GAAG;AACnD,wBAAM,aAAa,KAAK,WAAW,WAAW,KAAK,WAAW,YAAY,KAAK,WAAW,WAAW,KAAK,WAAW;AACrH,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,WAAW,EAAE,IAAI,mBAAmB,KAAK,EAAE;AAAA,oBAC3C,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,kBAAkB,oBAAI,IAAY;AACxC,cAAM,qBAAqB,CAAC,QAAgB;AAC1C,gBAAM,WAAW,IAAI,YAAY;AACjC,cAAI,cAAc,IAAI,QAAQ,EAAG;AACjC,qBAAW,QAAQ,IAAI,OAAO;AAC5B,kBAAM,kBAAkB,KAAK,aAAa,CAAC,KAAK,GAAG,WAAW,GAAG,KAAK,SAAS,IAAI,IAC/E,GAAG,KAAK,SAAS,KAAK,KAAK,EAAE,KAC7B,KAAK;AACT,gBAAI,aAAa,KAAK,eAAe,GAAG;AACtC,8BAAgB,IAAI,KAAK,EAAE;AAAA,YAC7B;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,KAAK,IAAI,OAAO;AACzB,qBAAW,SAAS,EAAE,QAAQ;AAC5B,kBAAM,OAAO,uBAAuB,MAAM,IAAI;AAC9C,uBAAW,OAAO,MAAM;AACtB,oBAAM,eAAe,IAAI;AAAA,gBACvB,MAAM,KAAK,oBAAoB,EAAE,IAAI,CAAC,EAAE,IAAI,OAAK,EAAE,YAAY,CAAC;AAAA,cAClE;AACA,kBAAI,aAAa,IAAI,IAAI,YAAY,CAAC,GAAG;AACvC;AAAA,cACF;AACA,iCAAmB,GAAG;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,qBAAW,KAAK,KAAK,SAAS;AAC5B,kBAAM,OAAO,eAAe,CAAC;AAC7B,uBAAW,OAAO,MAAM;AACtB,iCAAmB,GAAG;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,KAAK,IAAI,OAAO;AACzB,cAAI,CAAC,IAAI,cAAc,EAAE,EAAE,EAAG;AAC9B,cAAI,CAAC,gBAAgB,IAAI,EAAE,EAAE,GAAG;AAC9B,kBAAM,MAAM,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,EAAE,SAAS;AACzD,kBAAM,aAAa,MAAO,IAAI,WAAW,WAAW,IAAI,WAAW,WAAY;AAC/E,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,SAAS,EAAE,EAAE;AAAA,cACb,EAAE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC/SA,SAAS,mBAAmB,KAAkB,QAAmC;AAC/E,QAAM,MAAyB,CAAC;AAChC,aAAW,QAAQ,IAAI,sBAAsB,IAAI,MAAM,KAAK,CAAC,GAAG;AAC9D,QAAI,KAAK,GAAG,KAAK,OAAO;AAAA,EAC1B;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAkB,cAAiD;AAC1F,QAAM,WAAW,IAAI,aAAa,IAAI,YAAY;AAClD,SAAO,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AAC/D;AAyUA,SAAS,cAAc,SAAyB;AAC9C,QAAM,IAAI,sBAAsB,KAAK,QAAQ,KAAK,CAAC;AACnD,UAAQ,IAAI,EAAE,CAAC,IAAI,SAAS,KAAK;AACnC;AAzWA,IAgBM,kBAsBO,cAgKA,eAwDA,gBAsGP,iBAOO,iBAuDP,eAEO;AApab;AAAA;AAAA;AAEA;AAcA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,SAAS,YAAY,SAAS,WAAW,YAAY,CAAC;AAsBjF,IAAM,eAAwB;AAAA,MACnC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,0BAA0B,iBAAiB,SAAS,SAAS,8DAA8D;AAAA,QACnI,EAAE,MAAM,wBAAwB,iBAAiB,SAAS,SAAS,wDAAwD;AAAA,QAC3H,EAAE,MAAM,uBAAuB,iBAAiB,SAAS,SAAS,gIAAgI;AAAA,QAClM,EAAE,MAAM,4BAA4B,iBAAiB,SAAS,SAAS,sEAAuE;AAAA,QAC9I,EAAE,MAAM,8BAA8B,iBAAiB,SAAS,SAAS,4EAA4E;AAAA,QACrJ,EAAE,MAAM,2BAA2B,iBAAiB,SAAS,SAAS,kGAAmG;AAAA,QACzK,EAAE,MAAM,+BAA+B,iBAAiB,WAAW,SAAS,iFAAiF;AAAA,MAC/J;AAAA,MACA,MAAM,KAAK;AAET,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,CAAC,KAAK,YAAY,KAAK,SAAS,WAAW,EAAG;AAClD,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAE/C,cAAI,KAAK,kBAAkB,UAAU;AACnC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,MAAM,KAAK,aAAa;AAAA,cAC7C,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,OAAO,oBAAI,IAAY;AAC7B,qBAAW,KAAK,KAAK,UAAU;AAC7B,gBAAI,KAAK,IAAI,EAAE,UAAU,GAAG;AAC1B,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,sBAAsB,KAAK,EAAE,uBAAuB,EAAE,UAAU;AAAA,gBAChE,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AACA,iBAAK,IAAI,EAAE,UAAU;AAErB,kBAAM,SAAS,IAAI,aAAa,IAAI,EAAE,SAAS;AAC/C,gBAAI,CAAC,QAAQ;AACX,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,sBAAsB,KAAK,EAAE,uBAAuB,EAAE,UAAU,mBAAmB,EAAE,SAAS;AAAA,gBAC9F,KAAK;AAAA,gBACL;AAAA,cACF;AACA;AAAA,YACF;AACA,gBAAI,CAAC,mBAAmB,KAAK,OAAO,EAAE,EAAE,KAAK,YAAU,OAAO,SAAS,EAAE,MAAM,GAAG;AAChF,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,sBAAsB,KAAK,EAAE,uBAAuB,EAAE,UAAU,SAAS,EAAE,SAAS,IAAI,EAAE,MAAM,WAAW,OAAO,EAAE;AAAA,gBACpH,KAAK;AAAA,gBACL,cAAc,IAAI,iBAAiB,OAAO,EAAE;AAAA,cAC9C;AAAA,YACF;AACA,gBAAI,OAAO,cAAc,KAAK,WAAW;AACvC,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,sBAAsB,KAAK,EAAE,iBAAiB,KAAK,SAAS,wBAAwB,EAAE,UAAU,SAAS,EAAE,SAAS,mBAAmB,OAAO,SAAS;AAAA,gBACvJ,KAAK;AAAA,gBACL,cAAc,IAAI,iBAAiB,OAAO,EAAE;AAAA,cAC9C;AAAA,YACF;AAGA,gBAAI,OAAO,OAAO,KAAK,MAAM,CAAC,KAAK,UAAU,SAAS,OAAO,EAAE,KAAK,CAAC,KAAK,KAAK,SAAS,OAAO,EAAE,GAAG;AAClG,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,sBAAsB,KAAK,EAAE,uBAAuB,EAAE,UAAU,SAAS,EAAE,SAAS,WAAW,KAAK,EAAE;AAAA,gBACtG,KAAK;AAAA,gBACL,cAAc,IAAI,iBAAiB,OAAO,EAAE;AAAA,cAC9C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,qBAAW,cAAc,KAAK,SAAS;AACrC,uBAAW,QAAQ,WAAW,WAAW;AACvC,kBAAI,KAAK,SAAS,WAAY;AAC9B,oBAAM,QAAQ,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,oBAAoB,KAAK,UAAU;AAE1G,kBAAI,CAAC,KAAK,YAAY;AACpB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,GAAG,KAAK;AAAA,kBACR,KAAK;AAAA,kBACL;AAAA,gBACF;AACA;AAAA,cACF;AAEA,kBAAI,CAAC,KAAK,gBAAiB;AAC3B,oBAAM,SAAS,IAAI,aAAa,IAAI,KAAK,eAAe;AACxD,kBAAI,CAAC,OAAQ;AAEb,kBAAI,OAAO,kBAAkB,YAAY,CAAC,OAAO,YAAY,OAAO,SAAS,WAAW,GAAG;AACzF,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,GAAG,KAAK,uBAAuB,KAAK,UAAU,cAAc,OAAO,EAAE,YAAY,OAAO,kBAAkB,WAAW,QAAQ,OAAO,aAAa,mBAAmB,4BAA4B;AAAA,kBAChM,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,OAAO,EAAE;AAAA,gBAC9C;AACA;AAAA,cACF;AAEA,oBAAM,UAAU,OAAO,SAAS,KAAK,OAAK,EAAE,eAAe,KAAK,UAAU;AAC1E,kBAAI,CAAC,SAAS;AACZ,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,GAAG,KAAK,uBAAuB,KAAK,UAAU,cAAc,OAAO,EAAE,oEAAoE,OAAO,SAAS,IAAI,OAAK,IAAI,EAAE,UAAU,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,kBACjM,KAAK;AAAA,kBACL,cAAc,IAAI,iBAAiB,OAAO,EAAE;AAAA,gBAC9C;AACA;AAAA,cACF;AAIA,kBAAI,KAAK,mBAAmB,QAAQ;AAClC,sBAAM,cAAc,mBAAmB,KAAK,QAAQ,SAAS,EAAE,KAAK,OAAK,EAAE,SAAS,QAAQ,MAAM;AAClG,sBAAM,WAAW,IAAI,IAAI,aAAa,cAAc,CAAC,CAAC;AACtD,2BAAW,KAAK,KAAK,mBAAmB;AACtC,sBAAI,CAAC,SAAS,IAAI,CAAC,GAAG;AACpB,wBAAI;AAAA,sBACF;AAAA,sBACA;AAAA,sBACA,GAAG,KAAK,uBAAuB,CAAC,sBAAsB,KAAK,UAAU,kBAAkB,QAAQ,SAAS,IAAI,QAAQ,MAAM,2BAA2B,CAAC;AAAA,sBACtJ,KAAK;AAAA,sBACL,cAAc,IAAI,iBAAiB,QAAQ,SAAS;AAAA,oBACtD;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAOO,IAAM,gBAAyB;AAAA,MACpC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,gCAAgC,iBAAiB,SAAS,SAAS,2DAA2D;AAAA,QACtI,EAAE,MAAM,6BAA6B,iBAAiB,SAAS,SAAS,qEAAsE;AAAA,MAChJ;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,OAAO,IAAI,YAAY;AAChC,gBAAM,aAAa,IAAI,WAAW,WAAW,IAAI,WAAW;AAC5D,qBAAW,MAAM,IAAI,aAAa,CAAC,GAAG;AACpC,kBAAM,OAAO,IAAI,aAAa,IAAI,GAAG,SAAS;AAC9C,gBAAI,CAAC,MAAM;AACT,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,IAAI,EAAE,cAAc,GAAG,KAAK,0BAA0B,GAAG,SAAS,IAAI,GAAG,MAAM,qBAAqB,GAAG,SAAS;AAAA,gBAC9H,IAAI;AAAA,gBACJ;AAAA,cACF;AACA;AAAA,YACF;AAIA,gBAAI,KAAK,cAAc,IAAI,IAAI;AAC7B,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,IAAI,EAAE,cAAc,GAAG,KAAK,0BAA0B,GAAG,SAAS,IAAI,GAAG,MAAM,WAAW,KAAK,EAAE,2BAA2B,KAAK,SAAS;AAAA,gBACxJ,IAAI;AAAA,gBACJ,cAAc,IAAI,iBAAiB,KAAK,EAAE;AAAA,cAC5C;AAAA,YACF;AACA,gBAAI,CAAC,mBAAmB,KAAK,KAAK,EAAE,EAAE,KAAK,YAAU,OAAO,SAAS,GAAG,MAAM,GAAG;AAC/E,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,IAAI,EAAE,cAAc,GAAG,KAAK,0BAA0B,GAAG,SAAS,IAAI,GAAG,MAAM,WAAW,KAAK,EAAE,yBAAyB,GAAG,MAAM;AAAA,gBACjJ,IAAI;AAAA,gBACJ,cAAc,IAAI,iBAAiB,KAAK,EAAE;AAAA,cAC5C;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AASO,IAAM,iBAA0B;AAAA,MACrC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,2BAA2B,iBAAiB,SAAS,SAAS,yDAAyD;AAAA,QAC/H,EAAE,MAAM,sBAAsB,iBAAiB,WAAW,SAAS,wHAAmH;AAAA,QACtL,EAAE,MAAM,sBAAsB,iBAAiB,WAAW,SAAS,kEAAkE;AAAA,QACrI,EAAE,MAAM,qBAAqB,iBAAiB,SAAS,SAAS,4FAA4F;AAAA,MAC9J;AAAA,MACA,MAAM,KAAK;AAET,cAAM,YAAwB,CAAC;AAC/B,mBAAW,OAAO,IAAI,YAAY;AAChC,qBAAW,MAAM,IAAI,aAAa,CAAC,GAAG;AACpC,gBAAI,GAAG,UAAU,UAAU,IAAI,aAAa,IAAI,GAAG,SAAS,GAAG;AAC7D,wBAAU,KAAK,EAAE,QAAQ,GAAG,WAAW,YAAY,GAAG,OAAO,CAAC;AAAA,YAChE;AAAA,UACF;AAAA,QACF;AAKA,cAAM,YAAY,UAAU,SAAS,mBAAmB,KAAK,WAAW,EAAE,sBAAsB,MAAM,CAAC,IAAI;AAE3G,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,IAAI,iBAAiB,KAAK,EAAE;AAE/C,cAAI,CAAC,KAAK,YAAY;AAIpB,gBAAI,KAAK,kBAAkB,SAAS;AAClC,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,UAAU,KAAK,EAAE;AAAA,gBACjB,KAAK;AAAA,gBACL;AAAA,cACF;AAAA,YACF;AACA;AAAA,UACF;AAEA,cAAI,KAAK,kBAAkB,SAAS;AAClC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,MAAM,KAAK,aAAa,0BAA0B,KAAK,UAAU;AAAA,cACtF,KAAK;AAAA,cACL;AAAA,YACF;AACA;AAAA,UACF;AAIA,cAAI,KAAK,eAAe,UAAW;AAEnC,gBAAM,UAAU,mBAAmB,KAAK,KAAK,EAAE;AAC/C,gBAAM,WAAW,QAAQ,OAAO,YAAU,CAAC,OAAO,MAAM;AACxD,cAAI,SAAS,QAAQ;AACnB,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,kBAAkB,KAAK,EAAE,iDAAiD,SAAS,IAAI,OAAK,IAAI,EAAE,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC;AAAA,cACrH,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,SAAS,QAAQ,OAAO,YAAU,OAAO,WAAW,OAAO;AACjE,gBAAM,QAAQ,QAAQ,OAAO,YAAU,OAAO,WAAW,MAAM;AAC/D,cAAI,OAAO,WAAW,EAAG;AAEzB,gBAAM,WAAW,cAAc,QAC1B,MAAM,KAAK,YAAU,UAAU,eAAe,IAAI,UAAU,KAAK,IAAI,OAAO,IAAI,CAAC,CAAC;AACvF,cAAI,CAAC,UAAU;AACb,kBAAM,UAAU,cAAc,OAC1B,6DACA,MAAM,WAAW,IACf,6DACA,oCAAoC,MAAM,IAAI,OAAK,IAAI,EAAE,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC;AAClF,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,kBAAkB,KAAK,EAAE,iBAAiB,OAAO,IAAI,OAAK,IAAI,EAAE,IAAI,GAAG,EAAE,KAAK,IAAI,CAAC,SAAS,OAAO;AAAA,cACnG,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAQA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,QAAQ,OAAO,WAAW,QAAQ,CAAC;AAO7D,IAAM,kBAA2B;AAAA,MACtC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,gBAAgB,iBAAiB,WAAW,SAAS,gFAAgF;AAAA,MAC/I;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,OAAO,IAAI,YAAY;AAChC,gBAAM,YAAY,IAAI,UAAU,IAAI,IAAI,EAAE;AAC1C,cAAI,CAAC,aAAa,UAAU,SAAS,EAAG;AAExC,qBAAW,UAAU,WAAW;AAC9B,kBAAM,OAAO,IAAI,aAAa,IAAI,MAAM;AACxC,gBAAI,CAAC,KAAM;AAIX,gBAAI,KAAK,kBAAkB,YAAY,KAAK,YAAY,KAAK,SAAS,SAAS,EAAG;AAElF,uBAAW,QAAQ,IAAI,sBAAsB,IAAI,MAAM,KAAK,CAAC,GAAG;AAC9D,oBAAM,aAAa,IAAI,iBAAiB,MAAM,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW;AAC9F,yBAAW,KAAK,KAAK,SAAS;AAC5B,sBAAM,YAAsB,CAAC;AAC7B,2BAAW,KAAK,EAAE,UAAU,CAAC,GAAG;AAC9B,sBAAI,gBAAgB,IAAI,cAAc,EAAE,IAAI,EAAE,YAAY,CAAC,GAAG;AAC5D,8BAAU,KAAK,UAAU,EAAE,IAAI,KAAK,EAAE,IAAI,GAAG;AAAA,kBAC/C;AAAA,gBACF;AACA,sBAAM,MAAM,cAAc,EAAE,WAAW,EAAE;AACzC,oBAAI,gBAAgB,IAAI,IAAI,YAAY,CAAC,GAAG;AAC1C,4BAAU,KAAK,WAAW,EAAE,OAAO,GAAG;AAAA,gBACxC;AACA,oBAAI,UAAU,QAAQ;AACpB,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,WAAW,EAAE,IAAI,6BAA6B,MAAM,mCAAmC,IAAI,EAAE,oCAAoC,UAAU,KAAK,IAAI,CAAC;AAAA,oBACrJ,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAQA,IAAM,gBAAgB;AAEf,IAAM,iBAA0B;AAAA,MACrC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,oBAAoB,iBAAiB,WAAW,SAAS,yEAAyE;AAAA,MAC5I;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,OAAO,gBAAgB,KAAK,KAAK,QAAQ;AAC/C,cAAI,CAAC,KAAM;AAEX,cAAI,iBAAiB,IAAI,KAAK,aAAa,EAAG;AAE9C,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,qBAAW,cAAc,KAAK,SAAS;AAGrC,kBAAM,aAAa,WAAW,UAC3B,OAAO,UAAQ,KAAK,SAAS,OAAO,EACpC,IAAI,WAAS,EAAE,MAAM,OAAO,cAAc,KAAK,KAAK,WAAW,EAAE,EAAE,EACnE,OAAO,CAAC,MAAoF,EAAE,UAAU,IAAI;AAC/G,kBAAM,cAAc,WAAW,SAAS,cAAc,KAAK,WAAW,MAAM,IAAI;AAChF,gBAAI,CAAC,WAAW,UAAU,CAAC,YAAa;AAExC,kBAAM,cAAc,WAAW,UAAU,KAAK,UAAQ;AACpD,kBAAI,KAAK,SAAS,UAAU,KAAK,SAAS,WAAY,QAAO;AAC7D,kBAAI,CAAC,KAAK,gBAAiB,QAAO;AAClC,oBAAM,SAAS,IAAI,aAAa,IAAI,KAAK,eAAe;AACxD,kBAAI,UAAU,iBAAiB,IAAI,OAAO,aAAa,EAAG,QAAO;AAEjE,oBAAM,UAAU,QAAQ,UAAU,KAAK,OAAK,EAAE,eAAe,KAAK,UAAU;AAC5E,oBAAM,SAAS,UAAU,IAAI,aAAa,IAAI,QAAQ,SAAS,IAAI;AACnE,qBAAO,SAAS,iBAAiB,IAAI,OAAO,aAAa,IAAI;AAAA,YAC/D,CAAC;AAKD,uBAAW,EAAE,MAAM,MAAM,KAAK,YAAY;AACxC,kBAAI,CAAC,aAAa;AAChB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,QAAQ,KAAK,UAAU,QAAQ,WAAW,IAAI,wBAAwB,KAAK,EAAE,aAAa,MAAM,CAAC,CAAC;AAAA,kBAClG,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAKA,gBAAI,eAAe,CAAC,aAAa;AAC/B,oBAAM,qBAAqB,CAAC,GAAG,KAAK,WAAW,GAAG,KAAK,IAAI,EAAE,KAAK,WAAS;AACzE,sBAAM,MAAM,IAAI,aAAa,IAAI,KAAK;AACtC,uBAAO,MAAM,iBAAiB,IAAI,IAAI,aAAa,IAAI;AAAA,cACzD,CAAC;AACD,kBAAI,CAAC,oBAAoB;AACvB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,kBAAkB,WAAW,IAAI,wBAAwB,KAAK,EAAE,aAAa,YAAY,CAAC,CAAC,oBAAoB,KAAK,EAAE;AAAA,kBACtH,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACtdA,SAAS,kBAAkB,KAA8D;AACvF,QAAM,KAAK,IAAI,YAAY,GAAG;AAC9B,MAAI,MAAM,KAAK,OAAO,IAAI,SAAS,EAAG,QAAO;AAC7C,SAAO,EAAE,SAAS,IAAI,MAAM,GAAG,EAAE,GAAG,aAAa,IAAI,MAAM,KAAK,CAAC,EAAE;AACrE;AAEA,SAAS,gBAAgB,MAAwB;AAC/C,SAAO,KAAK,aAAa,CAAC,KAAK,GAAG,WAAW,GAAG,KAAK,SAAS,IAAI,IAC9D,GAAG,KAAK,SAAS,KAAK,KAAK,EAAE,KAC7B,KAAK;AACX;AAGO,SAAS,oBAAoB,KAAa,OAAmE;AAClH,QAAM,QAAQ,kBAAkB,GAAG;AACnC,MAAI,CAAC,MAAO,QAAO;AACnB,aAAW,KAAK,OAAO;AACrB,QAAI,CAAC,EAAE,YAAY,OAAQ;AAC3B,QAAI,CAAC,aAAa,MAAM,SAAS,gBAAgB,CAAC,CAAC,EAAG;AACtD,QAAI,EAAE,WAAW,KAAK,SAAO,IAAI,OAAO,MAAM,WAAW,GAAG;AAC1D,aAAO,EAAE,MAAM,GAAG,aAAa,MAAM,YAAY;AAAA,IACnD;AAAA,EACF;AACA,SAAO;AACT;AAWA,SAAS,oBAAoB,KAAa,MAAgB,aAA8B;AACtF,QAAM,QAAQ,kBAAkB,GAAG;AACnC,MAAI,CAAC,SAAS,MAAM,gBAAgB,YAAa,QAAO;AACxD,MAAI,EAAE,KAAK,cAAc,CAAC,GAAG,KAAK,SAAO,IAAI,OAAO,WAAW,EAAG,QAAO;AACzE,SAAO,aAAa,MAAM,SAAS,gBAAgB,IAAI,CAAC;AAC1D;AAEA,SAAS,YAAY,MAA0B,YAAoB,MAAgB,aAA8B;AAC/G,QAAM,SAAS,KAAK,QAAQ,KAAK,OAAK,EAAE,SAAS,UAAU;AAC3D,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,OAAO,UAAU;AAAA,IAAK,WAC1B,KAAK,qBAAqB,CAAC,GAAG,KAAK,SAAO,oBAAoB,KAAK,MAAM,WAAW,CAAC;AAAA,EACxF;AACF;AAQA,SAAS,sBAAsB,GAAa,KAA6C;AACvF,MAAI,CAAC,EAAE,eAAgB,QAAO;AAC9B,QAAM,SAAS,IAAI,aAAa,IAAI,EAAE,cAAc;AACpD,MAAI,OAAQ,QAAO;AACnB,QAAM,KAAK,EAAE,GAAG,YAAY,IAAI;AAChC,MAAI,OAAO,GAAI,QAAO;AACtB,SAAO,IAAI,aAAa,IAAI,GAAG,EAAE,GAAG,MAAM,GAAG,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE;AACzE;AAtFA,IAwFa;AAxFb;AAAA;AAAA;AAEA;AAsFO,IAAM,uBAAgC;AAAA,MAC3C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,0BAA0B,iBAAiB,SAAS,SAAS,qDAAqD;AAAA,QAC1H,EAAE,MAAM,wBAAwB,iBAAiB,WAAW,SAAS,kKAAkK;AAAA,QACvO,EAAE,MAAM,wBAAwB,iBAAiB,WAAW,SAAS,+FAAgG;AAAA,QACrK,EAAE,MAAM,yBAAyB,iBAAiB,SAAS,SAAS,gEAAgE;AAAA,MACtI;AAAA,MACA,MAAM,KAAK;AAET,mBAAW,KAAK,IAAI,OAAO;AACzB,gBAAM,aAAa,EAAE,cAAc,CAAC;AACpC,cAAI,WAAW,WAAW,EAAG;AAE7B,gBAAM,OAAO,oBAAI,IAAY;AAC7B,qBAAW,OAAO,YAAY;AAC5B,gBAAI,KAAK,IAAI,IAAI,EAAE,GAAG;AACpB,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,WAAW,EAAE,EAAE,4BAA4B,IAAI,EAAE;AAAA,gBACjD,EAAE;AAAA,cACJ;AAAA,YACF;AACA,iBAAK,IAAI,IAAI,EAAE;AAAA,UACjB;AAEA,gBAAM,OAAO,sBAAsB,GAAG,GAAG;AACzC,cAAI,CAAC,MAAM;AACT,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,WAAW,EAAE,EAAE,cAAc,WAAW,MAAM,qBAAqB,EAAE,iBAAiB,uBAAuB,EAAE,cAAc,sCAAsC,uBAAuB;AAAA,cAC1L,EAAE;AAAA,YACJ;AACA;AAAA,UACF;AAEA,gBAAM,YAA6B,IAAI,sBAAsB,IAAI,KAAK,EAAE,KAAK,CAAC;AAC9E,gBAAM,eAAe,UAAU;AAAA,YAAQ,UACrC,KAAK,QAAQ,OAAO,OAAK,EAAE,WAAW,OAAO,EAAE,IAAI,QAAM,EAAE,MAAM,QAAQ,EAAE,EAAE;AAAA,UAC/E;AACA,cAAI,aAAa,WAAW,GAAG;AAC7B,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,WAAW,EAAE,EAAE,cAAc,WAAW,MAAM,8BAA8B,KAAK,EAAE;AAAA,cACnF,EAAE;AAAA,cACF,IAAI,iBAAiB,KAAK,EAAE;AAAA,YAC9B;AACA;AAAA,UACF;AAEA,qBAAW,EAAE,MAAM,OAAO,KAAK,cAAc;AAC3C,uBAAW,QAAQ,IAAI,0BAA0B,IAAI,KAAK,EAAE,KAAK,CAAC,GAAG;AACnE,oBAAM,aAAa,IAAI,sBAAsB,IAAI;AACjD,yBAAW,OAAO,YAAY;AAC5B,oBAAI,YAAY,MAAM,OAAO,MAAM,GAAG,IAAI,EAAE,EAAG;AAC/C,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,iBAAiB,OAAO,IAAI,SAAS,KAAK,EAAE,sBAAsB,KAAK,EAAE,iDAAiD,EAAE,EAAE,IAAI,IAAI,EAAE,MAAM,IAAI,WAAW;AAAA,kBAC7J,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AACjD,qBAAW,UAAU,KAAK,SAAS;AACjC,uBAAW,QAAQ,OAAO,WAAW;AACnC,yBAAW,OAAO,KAAK,qBAAqB,CAAC,GAAG;AAC9C,oBAAI,oBAAoB,KAAK,IAAI,KAAK,EAAG;AACzC,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,QAAQ,KAAK,UAAU,QAAQ,OAAO,IAAI,wBAAwB,KAAK,EAAE,wBAAwB,GAAG;AAAA,kBACpG,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACnLA,IAYa;AAZb;AAAA;AAAA;AAAA;AAYO,IAAM,sBAA+B;AAAA,MAC1C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,qBAAqB,iBAAiB,WAAW,SAAS,uDAAuD;AAAA,MAC3H;AAAA,MACA,MAAM,KAAK;AACT,cAAM,QAAQ,oBAAI,IAAY,CAAC,GAAG,qBAAqB,GAAG,IAAI,IAAI,UAAU,CAAC;AAC7E,cAAM,UAAU,yBAAyB,oBAAoB,KAAK,IAAI,CAAC,GAAG,IAAI,IAAI,WAAW,SAAS,mBAAmB,IAAI,IAAI,WAAW,KAAK,IAAI,CAAC,KAAK,EAAE;AAE7J,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,aAAa,KAAK,WAAW,WAAW,KAAK,WAAW,YAAY,IAAI,iBAAiB,KAAK,SAAS;AAC7G,qBAAW,UAAU,KAAK,SAAS;AACjC,uBAAW,KAAK,OAAO,cAAc,CAAC,GAAG;AACvC,kBAAI,CAAC,MAAM,IAAI,CAAC,GAAG;AACjB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,WAAW,OAAO,IAAI,mBAAmB,KAAK,EAAE,yBAAyB,CAAC,sIAAiI,OAAO;AAAA,kBAClN,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAEA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AACjD,qBAAW,UAAU,KAAK,SAAS;AACjC,uBAAW,QAAQ,OAAO,aAAa,CAAC,GAAG;AACzC,yBAAW,KAAK,KAAK,qBAAqB,CAAC,GAAG;AAC5C,oBAAI,CAAC,MAAM,IAAI,CAAC,GAAG;AACjB,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,QAAQ,KAAK,UAAU,QAAQ,OAAO,IAAI,wBAAwB,KAAK,EAAE,wBAAwB,CAAC,6HAAwH,OAAO;AAAA,oBACjO,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACpCA,SAAS,YAAY,KAAqE;AACxF,QAAM,WAAuB,CAAC;AAC9B,QAAM,cAA0B,CAAC;AAEjC,aAAW,QAAQ,IAAI,YAAY;AACjC,eAAW,KAAK,KAAK,SAAS,CAAC,GAAG;AAChC,eAAS,KAAK,EAAE,OAAO,EAAE,OAAO,QAAQ,KAAK,IAAI,KAAK,oBAAoB,CAAC;AAAA,IAC7E;AACA,eAAW,KAAK,KAAK,gBAAgB,CAAC,GAAG;AACvC,kBAAY,KAAK,EAAE,OAAO,EAAE,OAAO,QAAQ,KAAK,IAAI,KAAK,2BAA2B,CAAC;AAAA,IACvF;AAAA,EACF;AAEA,aAAW,QAAQ,IAAI,YAAY;AACjC,eAAW,UAAU,KAAK,SAAS;AACjC,YAAM,KAAK,OAAO;AAClB,UAAI,CAAC,MAAM,GAAG,cAAc,aAAc;AAC1C,YAAM,MAAgB;AAAA,QACpB,OAAO,GAAG;AAAA,QACV,QAAQ,KAAK;AAAA,QACb,KAAK,0BAA0B,KAAK,EAAE,IAAI,OAAO,IAAI;AAAA,MACvD;AACA,UAAI,GAAG,cAAc,UAAW,UAAS,KAAK,GAAG;AAAA,UAC5C,aAAY,KAAK,GAAG;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO,EAAE,UAAU,YAAY;AACjC;AAnDA,IAqDa;AArDb;AAAA;AAAA;AAqDO,IAAM,oBAA6B;AAAA,MACxC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,oBAAoB,iBAAiB,WAAW,SAAS,4DAA4D;AAAA,QAC7H,EAAE,MAAM,0BAA0B,iBAAiB,WAAW,SAAS,0DAA0D;AAAA,MACnI;AAAA,MACA,MAAM,KAAK;AACT,cAAM,EAAE,UAAU,YAAY,IAAI,YAAY,GAAG;AACjD,YAAI,SAAS,WAAW,KAAK,YAAY,WAAW,EAAG;AAEvD,cAAM,gBAAgB,IAAI,IAAI,SAAS,IAAI,OAAK,EAAE,KAAK,CAAC;AACxD,cAAM,mBAAmB,IAAI,IAAI,YAAY,IAAI,OAAK,EAAE,KAAK,CAAC;AAE9D,mBAAW,KAAK,UAAU;AACxB,cAAI,iBAAiB,IAAI,EAAE,KAAK,EAAG;AACnC,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,cAAc,EAAE,MAAM,kBAAkB,EAAE,KAAK,MAAM,EAAE,GAAG;AAAA,YAC1D,EAAE;AAAA,YACF,IAAI,iBAAiB,EAAE,MAAM;AAAA,UAC/B;AAAA,QACF;AACA,mBAAW,KAAK,aAAa;AAC3B,cAAI,cAAc,IAAI,EAAE,KAAK,EAAG;AAChC,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,cAAc,EAAE,MAAM,0BAA0B,EAAE,KAAK,MAAM,EAAE,GAAG;AAAA,YAClE,EAAE;AAAA,YACF,IAAI,iBAAiB,EAAE,MAAM;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC/DA,SAAS,WAAW,MAAqB,QAAoD;AAC3F,MAAI,KAAK,SAAS,YAAY,KAAK,SAAS,QAAS,QAAO;AAC5D,QAAM,IAAI,KAAK;AACf,UAAQ,KAAK,MAAM;AAAA,IACjB,KAAK;AAAA,IAAS,KAAK;AAAA,IAAQ,KAAK;AAC9B,aAAO,OAAO,CAAC,MAAM;AAAA,IACvB,KAAK;AACH,aAAO,KAAK,eAAe,UAAa,OAAO,CAAC,MAAM;AAAA,IACxD,KAAK;AACH,aAAO,KAAK,gBAAgB,UAAa,OAAO,CAAC,MAAM;AAAA,IACzD,KAAK;AAAA,IAAQ,KAAK;AAChB,aAAO,KAAK,YAAY,UAAa,OAAO,KAAK,OAAO,MAAM;AAAA,IAChE;AACE,aAAO;AAAA,EACX;AACF;AAOO,SAAS,cAAc,OAAwB,QAAyB;AAC7E,QAAM,EAAE,MAAM,OAAO,QAAQ,aAAa,IAAI,UAAU,KAAK;AAC7D,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,MAAI,KAAK,CAAC,MAAM,OAAQ,QAAO;AAE/B,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;AACtB,SAAO,MAAM,QAAQ;AACnB,UAAM,IAAI,MAAM,IAAI;AACpB,QAAI,MAAM,UAAU,QAAQ,IAAI,CAAC,EAAG;AACpC,YAAQ,IAAI,CAAC;AACb,UAAM,IAAI,MAAM,IAAI,CAAC;AACrB,QAAI,WAAW,GAAG,MAAM,EAAG,QAAO;AAClC,eAAW,KAAK,aAAa,CAAC,GAAG;AAC/B,UAAI,MAAM,UAAU,CAAC,QAAQ,IAAI,CAAC,EAAG,OAAM,KAAK,CAAC;AAAA,IACnD;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,kBAAkB,MAAgB,cAAmD;AAC5F,QAAM,QAAQ,oBAAI,IAAoB;AACtC,QAAM,MAAM,oBAAI,IAAoB;AACpC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAmB,CAAC;AAC1B,MAAI,UAAU;AAEd,aAAW,QAAQ,MAAM;AACvB,QAAI,MAAM,IAAI,IAAI,EAAG;AACrB,UAAM,OAAmD,CAAC,EAAE,GAAG,MAAM,MAAM,aAAa,IAAI,GAAG,GAAG,EAAE,CAAC;AACrG,UAAM,IAAI,MAAM,OAAO;AAAG,QAAI,IAAI,MAAM,OAAO;AAAG;AAClD,UAAM,KAAK,IAAI;AAAG,YAAQ,IAAI,IAAI;AAElC,WAAO,KAAK,QAAQ;AAClB,YAAM,QAAQ,KAAK,KAAK,SAAS,CAAC;AAClC,UAAI,MAAM,IAAI,MAAM,KAAK,QAAQ;AAC/B,cAAM,IAAI,MAAM,KAAK,MAAM,GAAG;AAC9B,YAAI,CAAC,MAAM,IAAI,CAAC,GAAG;AACjB,gBAAM,IAAI,GAAG,OAAO;AAAG,cAAI,IAAI,GAAG,OAAO;AAAG;AAC5C,gBAAM,KAAK,CAAC;AAAG,kBAAQ,IAAI,CAAC;AAC5B,eAAK,KAAK,EAAE,GAAG,GAAG,MAAM,aAAa,CAAC,GAAG,GAAG,EAAE,CAAC;AAAA,QACjD,WAAW,QAAQ,IAAI,CAAC,GAAG;AACzB,cAAI,IAAI,MAAM,GAAG,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,GAAI,MAAM,IAAI,CAAC,CAAE,CAAC;AAAA,QAC7D;AAAA,MACF,OAAO;AACL,aAAK,IAAI;AACT,YAAI,KAAK,QAAQ;AACf,gBAAM,SAAS,KAAK,KAAK,SAAS,CAAC;AACnC,cAAI,IAAI,OAAO,GAAG,KAAK,IAAI,IAAI,IAAI,OAAO,CAAC,GAAI,IAAI,IAAI,MAAM,CAAC,CAAE,CAAC;AAAA,QACnE;AACA,YAAI,IAAI,IAAI,MAAM,CAAC,MAAM,MAAM,IAAI,MAAM,CAAC,GAAG;AAC3C,gBAAM,MAAgB,CAAC;AACvB,cAAI;AACJ,aAAG;AAAE,gBAAI,MAAM,IAAI;AAAI,oBAAQ,OAAO,CAAC;AAAG,gBAAI,KAAK,CAAC;AAAA,UAAG,SAAS,MAAM,MAAM;AAC5E,eAAK,KAAK,GAAG;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AA9GA,IA0Ha;AA1Hb;AAAA;AAAA;AAEA;AAwHO,IAAM,4BAAqC;AAAA,MAChD,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,qBAAqB,iBAAiB,WAAW,SAAS,kGAA6F;AAAA,QAC/J,EAAE,MAAM,sBAAsB,iBAAiB,WAAW,SAAS,wFAAmF;AAAA,QACtJ,EAAE,MAAM,4BAA4B,iBAAiB,WAAW,SAAS,gHAA2G;AAAA,MACtL;AAAA,MACA,MAAM,KAAkB;AACtB,cAAM,YAAwB,CAAC;AAE/B,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,gBAAM,YAAY,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AACxE,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,qBAAW,cAAc,KAAK,SAAS;AACrC,kBAAM,QAAQ,WAAW;AACzB,gBAAI,CAAC,MAAM,OAAQ;AACnB,kBAAM,QAAQ,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE;AACvE,kBAAM,QAAQ,UAAU,KAAK;AAG7B,uBAAW,KAAK,OAAO;AACrB,kBAAI,EAAE,SAAS,YAAY,EAAE,gBAAgB,QAAW;AACtD,sBAAM,SAAS,EAAE,cAAc,MAAM,OAAO,EAAE,UAAU;AACxD,oBAAI,WAAW,UAAa,WAAW,EAAE,aAAa;AACpD,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,GAAG,KAAK,eAAe,EAAE,UAAU,4BAA4B,MAAM;AAAA,oBACrE,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AACA,kBAAI,EAAE,SAAS,YAAY,EAAE,OAAO,QAAQ;AAC1C,sBAAM,UAAU,IAAI,IAAY,EAAE,MAAM,IAAI,OAAK,EAAE,IAAI,CAAC;AACxD,sBAAM,MAAM,EAAE,eAAe,MAAM,OAAO,EAAE,UAAU;AACtD,oBAAI,QAAQ,OAAW,SAAQ,IAAI,GAAG;AACtC,oBAAI,QAAQ,SAAS,GAAG;AACtB,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,GAAG,KAAK,eAAe,EAAE,UAAU,+CAA+C,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC;AAAA,oBACjG,KAAK;AAAA,oBACL;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,uBAAW,OAAO,kBAAkB,MAAM,MAAM,MAAM,YAAY,GAAG;AACnE,oBAAM,QAAQ,IAAI,IAAI,GAAG;AACzB,oBAAM,UAAU,IAAI,SAAS,KACxB,MAAM,aAAa,IAAI,CAAC,CAAC,EAAE,SAAS,IAAI,CAAC,CAAC;AAC/C,kBAAI,CAAC,QAAS;AACd,oBAAM,UAAU,IAAI,KAAK,OAAK,MAAM,aAAa,CAAC,EAAE,KAAK,OAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;AAC5E,oBAAM,gBAAgB,IAAI,KAAK,OAAK;AAClC,sBAAM,IAAI,MAAM,MAAM,IAAI,CAAC;AAC3B,uBAAO,EAAE,SAAS,YAAY,EAAE,SAAS;AAAA,cAC3C,CAAC;AACD,kBAAI,CAAC,WAAW,CAAC,eAAe;AAC9B,sBAAM,SAAS,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC5C,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,GAAG,KAAK,SAAS,OAAO,KAAK,UAAK,CAAC;AAAA,kBACnC,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,CAAC,UAAW;AAChB,kBAAM,UAAU,GAAG,UAAU,EAAE,KAAK,WAAW,IAAI;AACnD,uBAAW,KAAK,OAAO;AACrB,kBAAI;AACJ,kBAAI;AACJ,kBAAI,EAAE,SAAS,UAAU,EAAE,mBAAmB,EAAE,cAAc;AAC5D,8BAAc,EAAE;AAChB,2BAAW,EAAE;AAAA,cACf,WAAW,EAAE,SAAS,cAAc,EAAE,mBAAmB,EAAE,YAAY;AACrE,sBAAM,SAAS,IAAI,aAAa,IAAI,EAAE,eAAe;AACrD,sBAAM,UAAU,QAAQ,UAAU,KAAK,OAAK,EAAE,eAAe,EAAE,UAAU;AACzE,oBAAI,SAAS;AAAE,gCAAc,QAAQ;AAAW,6BAAW,QAAQ;AAAA,gBAAQ;AAAA,cAC7E;AACA,kBAAI,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,aAAa,IAAI,WAAW,EAAG;AACrE,wBAAU,KAAK;AAAA,gBACb;AAAA,gBACA,OAAO,GAAG,WAAW,KAAK,QAAQ;AAAA,gBAClC,eAAe,cAAc,OAAO,EAAE,UAAU;AAAA,gBAChD;AAAA,gBACA,YAAY,WAAW;AAAA,gBACvB,YAAY,EAAE;AAAA,gBACd,SAAS,GAAG,WAAW,IAAI,QAAQ;AAAA,cACrC,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAGA,cAAM,YAAY,oBAAI,IAAwB;AAC9C,mBAAW,KAAK,WAAW;AACzB,cAAI,CAAC,EAAE,cAAe;AACtB,gBAAM,OAAO,UAAU,IAAI,EAAE,OAAO;AACpC,cAAI,KAAM,MAAK,KAAK,CAAC;AAAA,cAChB,WAAU,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AAAA,QACnC;AACA,cAAM,QAAQ,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,UAAU,KAAK,GAAG,GAAG,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,OAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AACrG,cAAM,YAAY,IAAI,IAAI,MAAM,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,cAAM,SAAS,CAAC,OACb,UAAU,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,IAAI,OAAK,UAAU,IAAI,EAAE,KAAK,CAAE,EAAE,OAAO,OAAK,MAAM,MAAS;AAE/F,mBAAW,OAAO,kBAAkB,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,GAAG;AAC9D,gBAAM,OAAO,IAAI,IAAI,OAAK,MAAM,CAAC,CAAC;AAClC,gBAAM,QAAQ,IAAI,IAAI,IAAI;AAC1B,gBAAM,UAAU,KAAK,SAAS,MACxB,UAAU,IAAI,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,KAAK,OAAK,EAAE,UAAU,KAAK,CAAC,CAAC;AACjE,cAAI,CAAC,QAAS;AACd,gBAAM,cAAc,KAAK,QAAQ,QAAM,UAAU,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO,OAAK,MAAM,IAAI,EAAE,KAAK,CAAC,CAAC;AAC9F,cAAI,YAAY,WAAW,EAAG;AAG9B,gBAAM,SAAS,CAAC,GAAG,WAAW,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,cAAc,EAAE,OAAO,CAAC,EAAE,CAAC;AACpF,gBAAMC,SAAO,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,UAAK;AACxC,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,6BAA6BA,MAAI,iGAA4F,OAAO,UAAU,QAAQ,OAAO,UAAU,SAAS,OAAO,KAAK,EAAE,kBAAkB,OAAO,OAAO;AAAA,YAC9N,OAAO,KAAK;AAAA,YACZ,YAAY,KAAK,OAAK,IAAI,sBAAsB,EAAE,IAAI,CAAC;AAAA,UACzD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACzOA,SAAS,SAAY,QAAuC,KAA4B;AACtF,SAAO,UAAU,OAAO,UAAU,eAAe,KAAK,QAAQ,GAAG,IAAI,OAAO,GAAG,IAAI;AACrF;AAGO,SAAS,cAAc,OAAwB,IAAqC;AACzF,QAAM,SAAS,SAAS,MAAM,eAAe,EAAE;AAC/C,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,SAAS,IAAI,IAAY,MAAM;AACrC,QAAM,QAAQ,CAAC,GAAG,MAAM;AACxB,SAAO,MAAM,QAAQ;AACnB,UAAM,OAAO,MAAM,IAAI;AACvB,eAAW,QAAQ,SAAS,MAAM,eAAe,IAAI,KAAK,CAAC,GAAG;AAC5D,UAAI,CAAC,OAAO,IAAI,IAAI,GAAG;AACrB,eAAO,IAAI,IAAI;AACf,cAAM,KAAK,IAAI;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AA/CA,IAiDa;AAjDb;AAAA;AAAA;AACA;AAEA;AA8CO,IAAM,sBAA+B;AAAA,MAC1C,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,wBAAwB,iBAAiB,WAAW,SAAS,6IAA8I;AAAA,MACrN;AAAA,MACA,MAAM,KAAkB;AACtB,cAAM,cAAc,oBAAI,IAA6B;AACrD,mBAAW,KAAK,IAAI,UAAU,MAAO,aAAY,IAAI,oBAAoB,EAAE,IAAI,GAAG,CAAC;AAEnF,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,cAAI,CAAC,KAAK,WAAY;AACtB,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,cAAI,CAAC,SAAU;AACf,gBAAM,YAAY,IAAI,aAAa,IAAI,SAAS,SAAS;AACzD,cAAI,CAAC,UAAW;AAChB,cAAI,sBAAsB,UAAU,WAAW,GAAG,EAAG;AAErD,gBAAM,QAAQ,YAAY,IAAI,oBAAoB,KAAK,UAAU,CAAC;AAClE,cAAI,CAAC,SAAS,MAAM,WAAW,cAAc,MAAM,kBAAkB,QAAS;AAE9E,gBAAM,WAAW,KAAK,eAAe,sBAAsB,UAAU,aAAa;AAClF,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AAEjD,qBAAW,cAAc,KAAK,SAAS;AACrC,kBAAM,OAAO,WAAW,eAAe;AACvC,gBAAI,SAAS,MAAO;AACpB,gBAAI,CAAC,WAAW,UAAU,OAAQ;AAElC,kBAAM,WAAW,WAAW,UAAU,WAAW;AACjD,kBAAM,UAAU,cAAc,OAAO,QAAQ;AAG7C,gBAAI,CAAC,QAAS;AAKd,kBAAM,UAAkE,CAAC;AACzE,uBAAW,QAAQ,WAAW,WAAW;AACvC,kBAAI,KAAK,SAAS,UAAU,CAAC,KAAK,mBAAmB,CAAC,KAAK,aAAc;AAEzE,kBAAI,CAAC,IAAI,aAAa,IAAI,KAAK,eAAe,EAAG;AAIjD,oBAAM,WAAW,oBAAI,IAAY,CAAC,KAAK,YAAY,CAAC;AACpD,yBAAW,cAAc,IAAI,sBAAsB,IAAI,KAAK,eAAe,KAAK,CAAC,GAAG;AAClF,2BAAW,cAAc,IAAI,0BAA0B,IAAI,WAAW,EAAE,KAAK,CAAC,GAAG;AAC/E,wBAAM,eAAe,WAAW,QAAQ,KAAK,OAAK,EAAE,SAAS,KAAK,YAAY;AAC9E,sBAAI,cAAc,OAAQ,UAAS,IAAI,aAAa,MAAM;AAAA,gBAC5D;AAAA,cACF;AAMA,kBAAI,SAAS,IAAI,QAAQ,EAAG;AAC5B,kBAAI,CAAC,GAAG,QAAQ,EAAE,KAAK,UAAQ,QAAQ,IAAI,IAAI,CAAC,EAAG;AACnD,sBAAQ,KAAK;AAAA,gBACX,MAAM,KAAK;AAAA,gBACX,QAAQ,GAAG,KAAK,eAAe,IAAI,KAAK,YAAY;AAAA,gBACpD,UAAU,CAAC,GAAG,QAAQ;AAAA,cACxB,CAAC;AAAA,YACH;AACA,gBAAI,QAAQ,WAAW,EAAG;AAC1B,kBAAM,SAAS,QACZ,IAAI,OAAK,QAAQ,EAAE,IAAI,WAAM,EAAE,MAAM,gBAAgB,EAAE,SAAS,IAAI,OAAK,IAAI,CAAC,GAAG,EAAE,KAAK,KAAK,CAAC,GAAG,EACjG,KAAK,IAAI;AACZ,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,WAAW,WAAW,IAAI,wBAAwB,KAAK,EAAE,MAAM,QAAQ,MAAM,sEAAsE,QAAQ,SAAS,KAAK,UAAU,YAAO,MAAM;AAAA,cAChM,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AClIA,IAMM,iCAQO;AAdb;AAAA;AAAA;AACA,IAAAC;AAKA,IAAM,kCAAkC;AAQjC,IAAM,eAAwB;AAAA,MACnC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,+BAA+B,iBAAiB,WAAW,SAAS,kEAAkE;AAAA,QAC9I,EAAE,MAAM,wBAAwB,iBAAiB,SAAS,SAAS,mDAAmD;AAAA,QACtH,EAAE,MAAM,uBAAuB,iBAAiB,WAAW,SAAS,8DAA8D;AAAA,QAClI,EAAE,MAAM,iBAAiB,iBAAiB,WAAW,SAAS,8CAA8C;AAAA,MAC9G;AAAA,MACA,MAAM,KAAK;AAET,cAAM,gBAAgB,oBAAI,IAAyB;AACnD,cAAM,cAAc,oBAAI,IAAoB;AAC5C,mBAAW,QAAQ,IAAI,YAAY;AACjC,qBAAW,SAAS,KAAK,WAAW;AAClC,kBAAM,MAAM,IAAI,aAAa,IAAI,KAAK;AACtC,gBAAI,CAAC,OAAO,IAAI,cAAc,KAAK,UAAW;AAC9C,kBAAM,MAAM,cAAc,IAAI,KAAK,SAAS,KAAK,oBAAI,IAAY;AACjE,gBAAI,IAAI,IAAI,SAAS;AACrB,0BAAc,IAAI,KAAK,WAAW,GAAG;AACrC,kBAAM,MAAM,GAAG,KAAK,SAAS,KAAK,IAAI,SAAS;AAC/C,gBAAI,CAAC,YAAY,IAAI,GAAG,EAAG,aAAY,IAAI,KAAK,GAAG,KAAK,EAAE,WAAM,IAAI,EAAE,EAAE;AAAA,UAC1E;AAAA,QACF;AAIA,cAAM,kBAAkB,oBAAI,IAAY;AACxC,cAAM,UAAU,CAAC,GAAW,MAAc,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK;AAClE,cAAM,gBAAgB,oBAAI,IAAyB;AACnD,mBAAW,OAAO,IAAI,YAAY;AAChC,gBAAM,aAAa,IAAI,WAAW,WAAW,IAAI,WAAW;AAC5D,qBAAW,QAAQ,IAAI,gBAAgB,CAAC,GAAG;AAEzC,kBAAM,EAAE,OAAO,IAAI,eAAe,IAAI,EAAE;AACxC,kBAAM,aAAa,CAAC,KAAK,WAAW,SAAS,GAAG,MAAM,KAAK,KAAK,SAAS,KAAK,KAAK,SAAS;AAC5F,kBAAM,OAAO,IAAI,WAAW,KAAK,OAAK,WAAW,SAAS,EAAE,EAAE,CAAC;AAC/D,gBAAI,CAAC,MAAM;AACT,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,IAAI,EAAE,iCAAiC,KAAK,SAAS;AAAA,gBACnE,IAAI;AAAA,gBACJ;AAAA,cACF;AACA;AAAA,YACF;AACA,4BAAgB,IAAI,QAAQ,IAAI,IAAI,KAAK,EAAE,CAAC;AAC5C,kBAAM,QAAQ,cAAc,IAAI,IAAI,EAAE,KAAK,oBAAI,IAAY;AAC3D,kBAAM,IAAI,KAAK,EAAE;AACjB,0BAAc,IAAI,IAAI,IAAI,KAAK;AAG/B,kBAAM,WAAW,cAAc,IAAI,IAAI,EAAE,GAAG,IAAI,KAAK,EAAE,KAAK;AAC5D,kBAAM,UAAU,cAAc,IAAI,KAAK,EAAE,GAAG,IAAI,IAAI,EAAE,KAAK;AAC3D,gBAAI,CAAC,YAAY,CAAC,SAAS;AACzB,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,IAAI,EAAE,iCAAiC,KAAK,EAAE,eAAe,KAAK,MAAM;AAAA,gBACtF,IAAI;AAAA,gBACJ;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,WAAW,oBAAI,IAAY;AACjC,mBAAW,CAAC,MAAM,GAAG,KAAK,eAAe;AACvC,qBAAW,MAAM,KAAK;AACpB,gBAAI,CAAE,cAAc,IAAI,EAAE,GAAG,IAAI,IAAI,EAAI;AACzC,kBAAM,MAAM,QAAQ,MAAM,EAAE;AAC5B,gBAAI,SAAS,IAAI,GAAG,EAAG;AACvB,qBAAS,IAAI,GAAG;AAChB,gBAAI,gBAAgB,IAAI,GAAG,EAAG;AAE9B,kBAAM,OAAO,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,IAAI;AACnD,kBAAM,OAAO,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,EAAE;AACjD,kBAAM,cAAc,MAAM,WAAW,WAAW,MAAM,WAAW,cAC3D,MAAM,WAAW,WAAW,MAAM,WAAW;AACnD,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,eAAe,IAAI,UAAU,EAAE,2BAA2B,YAAY,IAAI,GAAG,IAAI,KAAK,EAAE,EAAE,CAAC,KAAK,YAAY,IAAI,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,cACjI;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,cAAM,YAAY,IAAI,OAAO,YAAY,4BAA4B;AACrE,mBAAW,QAAQ,IAAI,YAAY;AACjC,cAAI,KAAK,UAAU,SAAS,WAAW;AACrC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,KAAK,EAAE,gBAAgB,KAAK,UAAU,MAAM,kBAAkB,SAAS;AAAA,cACrF,KAAK;AAAA,cACL,IAAI,iBAAiB,KAAK,EAAE;AAAA,YAC9B;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACxHA,IAUM,kBA8BO;AAxCb;AAAA;AAAA;AACA;AASA,IAAM,mBAA2D;AAAA,MAC/D,MAAM;AAAA,QACJ,KAAK;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,MACA,IAAI;AAAA,QACF,KAAK;AAAA,QACL,OAAO;AAAA,QACP,SAAS;AAAA,MACX;AAAA,MACA,GAAG;AAAA,QACD,KAAK;AAAA,QACL,OAAO;AAAA,MACT;AAAA,MACA,QAAQ;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AAYO,IAAM,eAAwB;AAAA,MACnC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,4BAA4B,iBAAiB,WAAW,SAAS,4DAA4D;AAAA,QACrI,EAAE,MAAM,yBAAyB,iBAAiB,WAAW,SAAS,yEAAyE;AAAA,MACjJ;AAAA,MACA,MAAM,KAAK;AAIT,cAAM,aAAa,CAAC,WAAoD;AACtE,gBAAM,OAAO,iBAAiB,MAAM;AACpC,gBAAM,QAAQ,IAAI,IAAI,UAAU,MAAM,GAAG;AACzC,cAAI,CAAC,OAAO,OAAQ,QAAO;AAC3B,iBAAO,oBAAI,IAAI,CAAC,GAAI,QAAQ,CAAC,GAAI,GAAG,MAAM,IAAI,OAAK,EAAE,YAAY,CAAC,CAAC,CAAC;AAAA,QACtE;AACA,cAAM,WAAW,oBAAI,IAAI,CAAC,GAAG,OAAO,KAAK,gBAAgB,GAAG,GAAG,OAAO,KAAK,IAAI,IAAI,SAAS,CAAC,CAAC;AAC9F,cAAM,UAAU,CAAC,UAA0C;AAAA,UACzD,GAAI,iBAAiB,IAAI,KAAK,CAAC;AAAA,UAC/B,GAAI,IAAI,IAAI,UAAU,IAAI,GAAG,mBAAmB,CAAC;AAAA,QACnD;AAEA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,OAAO,IAAI,aAAa,IAAI,KAAK,SAAS;AAChD,gBAAM,OAAO,IAAI,kBAAkB,MAAM,SAAS;AAClD,cAAI,CAAC,KAAM;AACX,gBAAM,aAAa,kBAAkB,IAAI;AACzC,gBAAM,aAAa,WAAW,UAAU;AAIxC,cAAI,CAAC,cAAc,WAAW,SAAS,EAAG;AAE1C,gBAAM,aAAa,IAAI,iBAAiB,KAAK,SAAS,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW;AACtG,qBAAW,KAAK,KAAK,SAAS;AAC5B,kBAAM,OAAO,eAAe,CAAC;AAC7B,uBAAW,OAAO,MAAM;AACtB,oBAAM,WAAW,IAAI,YAAY;AACjC,kBAAI,WAAW,IAAI,QAAQ,EAAG;AAC9B,yBAAW,UAAU,UAAU;AAC7B,oBAAI,WAAW,WAAY;AAC3B,oBAAI,WAAW,MAAM,GAAG,IAAI,QAAQ,GAAG;AACrC,sBAAI;AAAA,oBACF;AAAA,oBACA;AAAA,oBACA,WAAW,EAAE,IAAI,mBAAmB,KAAK,EAAE,WAAW,GAAG,QAAQ,MAAM,6CAA6C,UAAU,aAAa,UAAU;AAAA,oBACrJ,KAAK;AAAA,oBACL;AAAA,kBACF;AACA;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,cAAI,CAAC,SAAU;AACf,gBAAM,OAAO,IAAI,aAAa,IAAI,SAAS,SAAS;AACpD,gBAAM,OAAO,IAAI,kBAAkB,MAAM,SAAS;AAClD,cAAI,CAAC,KAAM;AACX,gBAAM,OAAO,QAAQ,kBAAkB,IAAI,CAAC;AAC5C,cAAI,OAAO,KAAK,IAAI,EAAE,WAAW,EAAG;AAEpC,gBAAM,aAAa,KAAK,WAAW,WAAW,KAAK,WAAW,YACzD,SAAS,WAAW,WAAW,SAAS,WAAW,YACnD,IAAI,iBAAiB,SAAS,SAAS;AAE5C,qBAAW,cAAc,KAAK,SAAS;AACrC,uBAAW,QAAQ,WAAW,WAAW;AAKvC,oBAAM,aAAuB;AAAA,gBAC3B,KAAK,SAAS,SACT,KAAK,aAAa,KAAK,OAAO,YAAY,WAC3C,KAAK;AAAA,cACX;AACA,kBAAI,KAAK,OAAQ,YAAW,KAAK,QAAQ;AACzC,yBAAW,aAAa,YAAY;AAClC,sBAAM,WAAW,KAAK,SAAS;AAC/B,oBAAI,CAAC,SAAU;AACf,sBAAM,QAAQ,cAAc,YAAY,oBACnC,cAAc,aAAa,cAAc,SAAS,cAAc,UAAW,KAAK,SAAS,UACxF,cAAc,WAAW,sCACvB,KAAK,SAAS;AACtB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,QAAQ,KAAK,UAAU,QAAQ,WAAW,IAAI,wBAAwB,KAAK,EAAE,UAAU,KAAK,gCAAgC,kBAAkB,IAAI,CAAC,KAAK,QAAQ;AAAA,kBAChK,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACtHA,SAAS,YAAY,MAAqE;AACxF,QAAM,QAAQ,KAAK,YAAY,EAAE,MAAM,YAAY,EAAE,OAAO,OAAO;AACnE,QAAM,SAAS,MAAM,KAAK,EAAE;AAC5B,MAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,QAAM,IAAI,MAAM;AAChB,SAAO,CAAC,SAAS;AACf,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,QAAQ,KAAK,YAAY,EAAE,MAAM,YAAY,EAAE,OAAO,OAAO;AACnE,QAAI,MAAM,KAAK,OAAK,EAAE,SAAS,MAAM,CAAC,EAAG,QAAO;AAChD,QAAI,IAAI,EAAG,QAAO;AAClB,aAAS,IAAI,GAAG,IAAI,KAAK,MAAM,QAAQ,KAAK;AAC1C,UAAI,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,SAAS,MAAM,EAAG,QAAO;AAAA,IAC9D;AACA,WAAO;AAAA,EACT;AACF;AAGA,SAAS,oBAAoB,GAA4B;AACvD,QAAM,QAAkB,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO;AACvD,aAAW,KAAK,EAAE,UAAU,CAAC,EAAG,OAAM,KAAK,EAAE,MAAM,EAAE,IAAI;AACzD,MAAI,EAAE,SAAU,OAAM,KAAK,OAAO,OAAO,EAAE,QAAQ,EAAE,IAAI,MAAM,EAAE,KAAK,GAAG,CAAC;AAC1E,SAAO,MAAM,KAAK,GAAG;AACvB;AAhDA,IAaM,YAqCO;AAlDb;AAAA;AAAA;AAaA,IAAM,aAAa,oBAAI,IAAI,CAAC,WAAW,SAAS,YAAY,OAAO,CAAC;AAqC7D,IAAM,iBAA0B;AAAA,MACrC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,gBAAgB,iBAAiB,WAAW,SAAS,oDAAoD;AAAA,QACjH,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,6CAA6C;AAAA,QACrH,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,kDAAkD;AAAA,MAC5H;AAAA,MACA,MAAM,KAAK;AAET,cAAM,UAAU,oBAAI,IAAoB;AACxC,mBAAW,KAAK,IAAI,WAAY,YAAW,KAAK,EAAE,KAAM,SAAQ,IAAI,GAAG,EAAE,EAAE;AAE3E,cAAM,gBAAgB,CAAC,OAAuB;AAC5C,gBAAM,OAAO,oBAAI,IAAY;AAC7B,cAAI,MAAM;AACV,iBAAO,QAAQ,IAAI,GAAG,KAAK,CAAC,KAAK,IAAI,GAAG,GAAG;AACzC,iBAAK,IAAI,GAAG;AACZ,kBAAM,QAAQ,IAAI,GAAG;AAAA,UACvB;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,cAAc,CAAC,WAAgC;AACnD,gBAAM,MAAM,oBAAI,IAAY,CAAC,MAAM,CAAC;AACpC,gBAAM,QAAQ,CAAC,MAAM;AACrB,iBAAO,MAAM,QAAQ;AACnB,kBAAM,IAAI,IAAI,aAAa,IAAI,MAAM,MAAM,CAAE;AAC7C,uBAAW,KAAK,GAAG,QAAQ,CAAC,GAAG;AAC7B,kBAAI,CAAC,IAAI,IAAI,CAAC,GAAG;AAAE,oBAAI,IAAI,CAAC;AAAG,sBAAM,KAAK,CAAC;AAAA,cAAG;AAAA,YAChD;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AASA,cAAM,QAAQ,oBAAI,IAAsB;AAExC,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,cAAI,CAAC,KAAK,cAAc,OAAQ;AAChC,gBAAM,OAAO,IAAI,aAAa,IAAI,KAAK,QAAQ;AAC/C,gBAAM,OAAO,OAAO,IAAI,aAAa,IAAI,KAAK,SAAS,IAAI;AAC3D,cAAI,CAAC,KAAM;AAEX,cAAI,CAAC,WAAW,IAAI,KAAK,aAAa,GAAG;AACvC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,uBAAuB,KAAK,aAAa,KAAK,IAAI,CAAC,mBAAmB,KAAK,EAAE,MAAM,KAAK,aAAa;AAAA,cAC/H,KAAK;AAAA,cACL,IAAI,iBAAiB,KAAK,EAAE;AAAA,YAC9B;AAAA,UACF;AAKA,gBAAM,UAAU,YAAY,cAAc,KAAK,EAAE,CAAC;AAClD,gBAAM,QAAQ,IAAI,IAAY,OAAO;AACrC,qBAAW,KAAK,IAAI,WAAY,KAAI,QAAQ,IAAI,EAAE,SAAS,EAAG,OAAM,IAAI,EAAE,EAAE;AAC5E,qBAAW,MAAM,IAAI,iBAAiB;AACpC,kBAAM,QAAQ,IAAI,aAAa,IAAI,GAAG,QAAQ,GAAG;AACjD,gBAAI,SAAS,QAAQ,IAAI,KAAK,EAAG,OAAM,IAAI,GAAG,EAAE;AAAA,UAClD;AACA,qBAAW,OAAO,SAAS;AACzB,kBAAM,QAAQ,IAAI,aAAa,IAAI,GAAG,GAAG;AACzC,gBAAI,CAAC,MAAO;AACZ,uBAAW,KAAK,IAAI,YAAY;AAC9B,kBAAI,UAAU,EAAE,MAAM,MAAM,WAAW,GAAG,EAAE,EAAE,IAAI,EAAG,OAAM,IAAI,EAAE,EAAE;AAAA,YACrE;AAAA,UACF;AAEA,qBAAW,QAAQ,KAAK,cAAc;AACpC,kBAAM,QAAQ,YAAY,IAAI;AAC9B,gBAAI,CAAC,MAAO;AACZ,kBAAM,MAAM,KAAK,YAAY,EAAE,MAAM,YAAY,EAAE,OAAO,OAAO,EAAE,KAAK,EAAE;AAC1E,kBAAM,OAAO,MAAM,IAAI,GAAG,KAAK,EAAE,OAAO,MAAM,OAAO,iBAAiB,oBAAI,IAAY,GAAG,OAAO,oBAAI,IAAY,EAAE;AAClH,iBAAK,gBAAgB,IAAI,KAAK,EAAE;AAChC,uBAAW,MAAM,MAAO,MAAK,MAAM,IAAI,EAAE;AACzC,kBAAM,IAAI,KAAK,IAAI;AAAA,UACrB;AAAA,QACF;AACA,YAAI,MAAM,SAAS,EAAG;AAEtB,cAAM,aAAa,CAAC,MAAwB,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,OAAK,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI;AAE/F,mBAAW,QAAQ,MAAM,OAAO,GAAG;AAKjC,qBAAW,QAAQ,IAAI,YAAY;AACjC,kBAAM,YAAY,KAAK,QAAQ,OAAO,OAAK,KAAK,MAAM,oBAAoB,CAAC,CAAC,CAAC,EAAE,IAAI,OAAK,EAAE,IAAI;AAC9F,gBAAI,UAAU,QAAQ;AACpB,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE,yBAAyB,KAAK,KAAK,oCAAoC,UAAU,SAAS,IAAI,MAAM,EAAE,KAAK,UAAU,KAAK,IAAI,CAAC,kFAA6E,WAAW,IAAI,CAAC;AAAA,gBACjP,KAAK;AAAA,gBACL,IAAI,iBAAiB,KAAK,SAAS;AAAA,cACrC;AAAA,YACF;AAAA,UACF;AAGA,qBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAI,KAAK,MAAM,IAAI,KAAK,EAAE,EAAG;AAC7B,kBAAM,WAA2C;AAAA,cAC/C,CAAC,WAAW,GAAG,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE;AAAA,cACrC,CAAC,eAAe,KAAK,WAAW;AAAA,cAChC,CAAC,aAAa,KAAK,UAAU,KAAK,GAAG,CAAC;AAAA,cACtC,CAAC,QAAQ,KAAK,KAAK,KAAK,GAAG,CAAC;AAAA,cAC5B,CAAC,YAAY,KAAK,QAAQ;AAAA,YAC5B;AACA,kBAAM,QAAQ,SAAS,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AACtE,gBAAI,MAAM,QAAQ;AAChB,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE,iBAAiB,KAAK,KAAK,MAAM,MAAM,KAAK,IAAI,CAAC,8EAAyE,WAAW,IAAI,CAAC;AAAA,gBAC/J,KAAK;AAAA,gBACL,IAAI,iBAAiB,KAAK,EAAE;AAAA,cAC9B;AAAA,YACF;AAAA,UACF;AAEA,qBAAW,OAAO,IAAI,YAAY;AAChC,gBAAI,KAAK,MAAM,IAAI,IAAI,EAAE,EAAG;AAC5B,gBAAI,KAAK,MAAM,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,WAAW,EAAE,GAAG;AAC1D,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,IAAI,EAAE,iBAAiB,KAAK,KAAK,yDAAyD,WAAW,IAAI,CAAC;AAAA,gBACxH,IAAI;AAAA,cACN;AAAA,YACF;AAAA,UACF;AAEA,qBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAI,KAAK,MAAM,IAAI,KAAK,EAAE,EAAG;AAC7B,kBAAM,QAAQ,CAAC,KAAK,aAAa,GAAG,KAAK,QAAQ,IAAI,OAAK,EAAE,WAAW,CAAC,EAAE,KAAK,GAAG;AAClF,gBAAI,KAAK,MAAM,KAAK,GAAG;AACrB,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,cAAc,KAAK,EAAE,gBAAgB,KAAK,KAAK,4CAA4C,WAAW,IAAI,CAAC;AAAA,gBAC3G,KAAK;AAAA,gBACL,IAAI,iBAAiB,KAAK,SAAS;AAAA,cACrC;AAAA,YACF;AAAA,UACF;AAEA,qBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAI,KAAK,MAAM,IAAI,KAAK,EAAE,EAAG;AAC7B,kBAAM,QAAgC,CAAC,KAAK,aAAa,KAAK,UAAU;AACxE,uBAAW,KAAK,KAAK,SAAS;AAC5B,oBAAM,KAAK,EAAE,MAAM;AACnB,yBAAW,KAAK,EAAE,aAAa,CAAC,GAAG;AACjC,sBAAM,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK;AAC1G,2BAAW,KAAK,EAAE,SAAS,CAAC,EAAG,OAAM,KAAK,EAAE,KAAK;AACjD,2BAAW,KAAK,EAAE,WAAW,CAAC,EAAG,OAAM,KAAK,EAAE,KAAK;AAAA,cACrD;AAAA,YACF;AACA,gBAAI,KAAK,MAAM,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG,CAAC,GAAG;AAC/C,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,mBAAmB,KAAK,EAAE,iBAAiB,KAAK,KAAK,+EAA0E,WAAW,IAAI,CAAC;AAAA,gBAC/I,KAAK;AAAA,cACP;AAAA,YACF;AAAA,UACF;AAIA,qBAAW,KAAK,IAAI,OAAO;AACzB,kBAAM,QAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,eAAe,EAAE;AAC1D,uBAAW,KAAK,EAAE,UAAU,CAAC,EAAG,OAAM,KAAK,EAAE,MAAM,EAAE,IAAI;AACzD,uBAAW,KAAK,EAAE,WAAW,CAAC,EAAG,OAAM,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO;AAC1E,gBAAI,KAAK,MAAM,MAAM,KAAK,GAAG,CAAC,GAAG;AAC/B,kBAAI;AAAA,gBACF;AAAA,gBACA;AAAA,gBACA,SAAS,EAAE,EAAE,yBAAyB,KAAK,KAAK,yGAAoG,WAAW,IAAI,CAAC;AAAA,gBACpK,EAAE;AAAA,cACJ;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC5OA,SAASC,qBAAoB,KAAkB,aAAsB;AACnE,QAAM,MAAM,cAAc,IAAI,WAAW,KAAK,OAAK,EAAE,OAAO,WAAW,IAAI;AAC3E,QAAM,UAAU,KAAK,WAAW,IAAI;AACpC,SAAO,IAAI,IAAI,SAAS,OAAO;AACjC;AAEA,SAAS,yBAAyB,KAAkB,aAAoD;AACtG,QAAM,gBAAgB,IAAI,OAAO;AACjC,QAAM,UAAUA,qBAAoB,KAAK,WAAW;AAEpD,MAAI,SAAS,OAAO,QAAQ;AAC1B,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,QAAQ,MAAM;AAAA,MACjB,aAAa;AAAA,QACX,GAAI,eAAe,eAAe,CAAC;AAAA,QACnC,GAAI,QAAQ,MAAM,OAAO,eAAe,CAAC;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,eAAe,iBAAwC;AAC9D,MAAI,eAAe,eAAe,EAAG,QAAO,eAAe,eAAe;AAC1E,MAAI;AACF,WAAO,IAAI,OAAO,eAAe;AAAA,EACnC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,mBAAmB,OAAe,iBAAyC;AAClF,MAAI,CAAC,gBAAiB,QAAO;AAG7B,QAAM,cAAc,MAAM,MAAM,GAAG,EAAE,CAAC,EAAE,KAAK;AAC7C,QAAM,QAAQ,eAAe,eAAe;AAC5C,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,MAAM,KAAK,WAAW;AAC/B;AAEA,SAAS,gBACP,KACA,OACA,SACA,SACA,QACA,SACM;AACN,QAAM,SAAS,mBAAmB,OAAO,OAAO;AAChD,MAAI,WAAW,MAAM;AACnB,QAAI;AAAA,MACF;AAAA,MACA;AAAA,MACA,mBAAmB,OAAO;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AACA;AAAA,EACF;AACA,MAAI,CAAC,QAAQ;AACX,QAAI,SAAS,WAAW,+BAA+B,SAAS,QAAQ,OAAO;AAAA,EACjF;AACF;AAEA,SAAS,UAAU,IAAoB;AACrC,QAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,SAAO,MAAM,MAAM,SAAS,CAAC;AAC/B;AAhFA,IAGM,gBA+EA,gBAEO;AApFb;AAAA;AAAA;AAGA,IAAM,iBAAyC;AAAA,MAC7C,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,YAAY;AAAA,IACd;AAyEA,IAAM,iBAAiB,CAAC,MAAc,eAAe,KAAK,CAAC;AAEpD,IAAM,aAAsB;AAAA,MACjC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,+BAA+B,iBAAiB,WAAW,SAAS,wEAAwE;AAAA,QACpJ,EAAE,MAAM,+BAA+B,iBAAiB,WAAW,SAAS,2EAA2E;AAAA,QACvJ,EAAE,MAAM,0BAA0B,iBAAiB,SAAS,SAAS,oFAAoF;AAAA,MAC3J;AAAA,MACA,MAAM,KAAK;AAET,mBAAW,OAAO,IAAI,YAAY;AAChC,gBAAM,eAAe,yBAAyB,KAAK,IAAI,EAAE;AACzD,cAAI,CAAC,cAAc,WAAY;AAE/B,gBAAM,SAAS,UAAU,IAAI,EAAE;AAC/B,0BAAgB,KAAK,QAAQ,aAAa,YAAY,iBAAiB,IAAI,EAAE,uCAAuC,aAAa,UAAU,MAAM,IAAI,EAAE;AACvJ,0BAAgB,KAAK,IAAI,MAAM,aAAa,YAAY,mBAAmB,IAAI,IAAI,uCAAuC,aAAa,UAAU,MAAM,IAAI,EAAE;AAAA,QAC/J;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,eAAe,yBAAyB,KAAK,KAAK,SAAS;AACjE,gBAAM,UAAU,IAAI,iBAAiB,KAAK,EAAE;AAE5C,cAAI,cAAc,YAAY;AAC5B,kBAAM,SAAS,UAAU,KAAK,EAAE;AAChC,4BAAgB,KAAK,QAAQ,aAAa,YAAY,iBAAiB,KAAK,EAAE,uCAAuC,aAAa,UAAU,MAAM,KAAK,IAAI,OAAO;AAClK,4BAAgB,KAAK,KAAK,MAAM,aAAa,YAAY,mBAAmB,KAAK,IAAI,uCAAuC,aAAa,UAAU,MAAM,KAAK,IAAI,OAAO;AAAA,UAC3K;AAGA,gBAAM,oBAAoB,cAAc,cAAc,KAAK,aAAa;AACxE,cAAI,mBAAmB;AACrB,kBAAM,YAAY,kBAAkB,SAAS;AAC7C,kBAAM,SAAS,kBAAkB;AACjC,kBAAM,SAAS,kBAAkB;AACjC,kBAAM,WAAW,kBAAkB;AAEnC,kBAAM,SAAS,UAAU,KAAK,EAAE;AAChC,kBAAM,YAAY,cAAc,QAAQ,cAAc,SAAS,CAAC,MAAM,IAAI,CAAC;AAC3E,kBAAM,cAAc,cAAc,UAAU,cAAc,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC;AAClF,kBAAM,YAAY,CAAC,GAAG,WAAW,GAAG,WAAW;AAE/C,uBAAW,OAAO,WAAW;AAC3B,kBAAI,UAAU,CAAC,IAAI,WAAW,MAAM,GAAG;AACrC,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,cAAc,KAAK,EAAE,MAAM,KAAK,aAAa,2BAA2B,GAAG,6BAA6B,MAAM;AAAA,kBAC9G,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AACA,kBAAI,UAAU,CAAC,IAAI,SAAS,MAAM,GAAG;AACnC,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,cAAc,KAAK,EAAE,MAAM,KAAK,aAAa,2BAA2B,GAAG,2BAA2B,MAAM;AAAA,kBAC5G,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AACA,oBAAM,QAAQ,WAAW,eAAe,QAAQ,IAAI;AACpD,kBAAI,YAAY,CAAC,OAAO;AACtB,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,4BAA4B,QAAQ,yBAAyB,KAAK,aAAa;AAAA,kBAC/E,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF,WAAW,SAAS,CAAC,MAAM,KAAK,GAAG,GAAG;AACpC,oBAAI;AAAA,kBACF;AAAA,kBACA;AAAA,kBACA,cAAc,KAAK,EAAE,MAAM,KAAK,aAAa,2BAA2B,GAAG,2BAA2B,QAAQ;AAAA,kBAC9G,KAAK;AAAA,kBACL;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,YAAY;AACjC,gBAAM,OAAO,IAAI,aAAa,IAAI,KAAK,SAAS;AAChD,gBAAM,eAAe,yBAAyB,KAAK,MAAM,SAAS;AAClE,gBAAM,UAAU,IAAI,iBAAiB,KAAK,SAAS,KAAK,KAAK,WAAW,WAAW,KAAK,WAAW;AAEnG,cAAI,cAAc,YAAY;AAC5B,kBAAM,SAAS,UAAU,KAAK,EAAE;AAEhC,kBAAM,UAAU,OAAO,WAAW,GAAG,IAAI,OAAO,MAAM,CAAC,IAAI;AAC3D,4BAAgB,KAAK,SAAS,aAAa,YAAY,iBAAiB,KAAK,EAAE,uCAAuC,aAAa,UAAU,MAAM,KAAK,IAAI,OAAO;AACnK,4BAAgB,KAAK,KAAK,MAAM,aAAa,YAAY,mBAAmB,KAAK,IAAI,uCAAuC,aAAa,UAAU,MAAM,KAAK,IAAI,OAAO;AAAA,UAC3K;AAEA,qBAAW,KAAK,KAAK,SAAS;AAC5B,gBAAI,cAAc,SAAS;AACzB,8BAAgB,KAAK,EAAE,MAAM,aAAa,SAAS,qBAAqB,EAAE,IAAI,SAAS,KAAK,EAAE,uCAAuC,aAAa,OAAO,MAAM,KAAK,IAAI,OAAO;AAAA,YACjL;AAGA,gBAAI,cAAc,WAAW;AAC3B,yBAAW,SAAS,EAAE,UAAU,CAAC,GAAG;AAClC,gCAAgB,KAAK,MAAM,MAAM,aAAa,WAAW,qBAAqB,MAAM,IAAI,gBAAgB,EAAE,IAAI,SAAS,KAAK,EAAE,uCAAuC,aAAa,SAAS,MAAM,KAAK,IAAI,OAAO;AAAA,cACnN;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,OAAO,IAAI,aAAa,IAAI,KAAK,QAAQ;AAC/C,gBAAM,OAAO,OAAO,IAAI,aAAa,IAAI,KAAK,SAAS,IAAI;AAC3D,gBAAM,eAAe,yBAAyB,KAAK,MAAM,SAAS;AAClE,gBAAM,UAAU,KAAK,WAAW,WAAW,KAAK,WAAW;AAE3D,cAAI,cAAc,SAAS;AACzB,uBAAW,KAAK,KAAK,SAAS;AAC5B,8BAAgB,KAAK,EAAE,MAAM,aAAa,SAAS,0BAA0B,EAAE,IAAI,SAAS,KAAK,EAAE,uCAAuC,aAAa,OAAO,MAAM,KAAK,IAAI,OAAO;AAAA,YACtL;AAAA,UACF;AAAA,QACF;AAGA,mBAAW,KAAK,IAAI,OAAO;AACzB,gBAAM,eAAe,yBAAyB,KAAK,EAAE,SAAS;AAG9D,cAAI,cAAc,cAAc;AAChC,cAAI,EAAE,SAAS,YAAY,cAAc,UAAU;AACjD,0BAAc,aAAa;AAAA,UAC7B,WAAW,EAAE,SAAS,kBAAkB,cAAc,cAAc;AAClE,0BAAc,aAAa;AAAA,UAC7B;AAEA,cAAI,aAAa;AACf,kBAAM,SAAS,UAAU,EAAE,EAAE;AAC7B,4BAAgB,KAAK,QAAQ,aAAa,YAAY,EAAE,EAAE,MAAM,EAAE,IAAI,uCAAuC,WAAW,MAAM,EAAE,EAAE;AAClI,4BAAgB,KAAK,EAAE,MAAM,aAAa,cAAc,EAAE,IAAI,MAAM,EAAE,IAAI,uCAAuC,WAAW,MAAM,EAAE,EAAE;AAAA,UACxI;AAGA,qBAAW,KAAK,EAAE,QAAQ;AAExB,kBAAM,UAAU,eAAe,EAAE,IAAI;AACrC,kBAAM,eAAgB,WAAW,cAAc,YAAa,aAAa,YAAY,cAAc;AAEnG,gBAAI,cAAc;AAChB,8BAAgB,KAAK,EAAE,MAAM,cAAc,GAAG,UAAU,aAAa,OAAO,KAAK,EAAE,IAAI,cAAc,EAAE,EAAE,uCAAuC,YAAY,MAAM,EAAE,EAAE;AAAA,YACxK;AAAA,UACF;AAEA,cAAI,cAAc,SAAS;AACzB,uBAAW,KAAK,EAAE,SAAS;AACzB,8BAAgB,KAAK,EAAE,MAAM,aAAa,SAAS,WAAW,EAAE,IAAI,cAAc,EAAE,EAAE,uCAAuC,aAAa,OAAO,MAAM,EAAE,EAAE;AAAA,YAC7J;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC7NA,SAAS,eAAe,QAAqB,UAAkB,WAAkC;AAC/F,MAAI,CAAC,UAAU,WAAW,GAAG,EAAG,QAAO;AACvC,QAAM,SAAS,cAAmB,YAAM,UAAe,YAAM,KAAU,YAAM,QAAQ,QAAQ,GAAG,SAAS,CAAC,CAAC;AAC3G,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,OAAO,QAAQ,SAAS,KAAK;AAAA,IAAG,OAAO,QAAQ,SAAS,MAAM;AAAA,IAC9D,GAAG,MAAM;AAAA,IAAO,GAAG,MAAM;AAAA,IAAQ,GAAG,MAAM;AAAA,IAC1C,GAAG,MAAM;AAAA,IAAa,GAAG,MAAM;AAAA,EACjC;AACA,aAAW,KAAK,YAAY;AAC1B,QAAI,OAAO,IAAI,CAAC,EAAG,QAAO;AAAA,EAC5B;AACA,SAAO;AACT;AAvCA,IAAAC,OAuBM,eAkBO;AAzCb;AAAA;AAAA;AAAA,IAAAA,QAAsB;AAEtB;AAEA;AAmBA,IAAM,gBAAgB;AAkBf,IAAM,6BAAsC;AAAA,MACjD,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,mFAAmF;AAAA,QAC3J,EAAE,MAAM,oBAAoB,iBAAiB,WAAW,SAAS,+DAA+D;AAAA,QAChI,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,8DAA8D;AAAA,QACtI,EAAE,MAAM,sBAAsB,iBAAiB,WAAW,SAAS,8GAA+G;AAAA,MACpL;AAAA,MACA,MAAM,KAAwB;AAC5B,cAAM,cAAc,IAAI,IAAI,IAAI,UAAU,MAAM,IAAI,OAAK,CAAC,cAAc,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;AACpF,cAAM,WAAW,IAAI,IAAI,YAAY,KAAK,CAAC;AAO3C,cAAM,mBAAmB,oBAAI,IAAyB;AACtD,cAAM,mBAAmB,oBAAI,IAAyB;AACtD,cAAM,mBAAmB,oBAAI,IAAkC;AAC/D,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,gBAAM,OAAO,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AACnE,cAAI,CAAC,KAAM;AACX,cAAI,CAAC,iBAAiB,IAAI,KAAK,EAAE,EAAG,kBAAiB,IAAI,KAAK,IAAI,CAAC,CAAC;AACpE,2BAAiB,IAAI,KAAK,EAAE,EAAG,KAAK,IAAI;AACxC,cAAI,KAAK,YAAY;AACnB,kBAAM,IAAI,cAAc,KAAK,UAAU;AACvC,gBAAI,CAAC,iBAAiB,IAAI,KAAK,EAAE,EAAG,kBAAiB,IAAI,KAAK,IAAI,oBAAI,IAAI,CAAC;AAC3E,6BAAiB,IAAI,KAAK,EAAE,EAAG,IAAI,CAAC;AACpC,gBAAI,CAAC,iBAAiB,IAAI,KAAK,SAAS,EAAG,kBAAiB,IAAI,KAAK,WAAW,oBAAI,IAAI,CAAC;AACzF,6BAAiB,IAAI,KAAK,SAAS,EAAG,IAAI,CAAC;AAAA,UAC7C;AAAA,QACF;AAKA,cAAM,iBAAiB,CAAC,YACrB,iBAAiB,IAAI,MAAM,KAAK,CAAC,GAAG,KAAK,QAAM,EAAE,gBAAgB,CAAC,GAAG,SAAS,CAAC;AAGlF,cAAM,UAAU,oBAAI,IAAY;AAChC,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,cAAI,CAAC,KAAK,QAAS;AACnB,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,gBAAM,OAAO,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AACnE,cAAI,KAAM,SAAQ,IAAI,KAAK,SAAS;AAAA,QACtC;AAIA,cAAM,YAAY,CAAC,UAA+B;AAChD,gBAAM,OAAO,oBAAI,IAAY,CAAC,KAAK,CAAC;AACpC,gBAAM,QAAQ,CAAC,KAAK;AACpB,iBAAO,MAAM,QAAQ;AACnB,kBAAM,OAAO,MAAM,IAAI;AACvB,kBAAM,QAAQ,YAAY,IAAI,IAAI;AAClC,gBAAI,CAAC,SAAS,MAAM,WAAW,WAAY;AAC3C,uBAAW,QAAQ,CAAC,GAAG,MAAM,SAAS,GAAG,MAAM,SAAS,GAAG;AACzD,oBAAM,KAAK,eAAe,UAAU,MAAM,IAAI;AAC9C,kBAAI,MAAM,CAAC,KAAK,IAAI,EAAE,GAAG;AAAE,qBAAK,IAAI,EAAE;AAAG,sBAAM,KAAK,EAAE;AAAA,cAAG;AAAA,YAC3D;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAEA,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,gBAAM,OAAO,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AACnE,cAAI,CAAC,KAAM;AACX,cAAI,sBAAsB,KAAK,WAAW,GAAG,EAAG;AAEhD,gBAAM,OAAO,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,KAAK,WAAW,GAAG,KAAK,IAAI,CAAC,CAAC,EAAE,OAAO,OAAK,IAAI,aAAa,IAAI,CAAC,CAAC;AAEhG,cAAI,CAAC,KAAK,SAAS;AAIjB,gBAAI,CAAC,QAAQ,IAAI,KAAK,SAAS,EAAG;AAClC,gBAAI,IAAI,sBAAsB,IAAI,EAAG;AACrC,gBAAI,KAAK,WAAW,EAAG;AACvB,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,iBAAiB,KAAK,EAAE,uBAAuB,KAAK,MAAM,sBAAsB,KAAK,WAAW,IAAI,MAAM,KAAK,oBAAoB,KAAK,SAAS;AAAA,cAC3K,KAAK;AAAA,YACP;AACA;AAAA,UACF;AAGA,gBAAM,UAAU,cAAc,KAAK,OAAO;AAC1C,gBAAM,QAAQ,YAAY,IAAI,OAAO;AACrC,gBAAM,aAAa,IAAI,sBAAsB,IAAI;AACjD,cAAI,CAAC,SAAS,MAAM,WAAW,aAAa,MAAM,WAAW,aAAa,MAAM,WAAW,cAAc;AACvG,kBAAM,MAAM,CAAC,SAAS,MAAM,WAAW,YACnC,wBACA,MAAM,WAAW,YAAY,+EAC3B;AACN,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,mBAAmB,KAAK,EAAE,uBAAuB,KAAK,OAAO,YAAY,GAAG;AAAA,cAC5E,KAAK;AAAA,cACL;AAAA,YACF;AACA;AAAA,UACF;AAGA,cAAI,MAAM,kBAAkB,QAAS;AAErC,gBAAM,QAAQ,UAAU,OAAO;AAC/B,gBAAM,WAAW,iBAAiB,IAAI,KAAK,EAAE,KAAK,oBAAI,IAAY;AAClE,gBAAM,UAAoB,CAAC;AAC3B,cAAI,SAAS,OAAO,KAAK,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,OAAK,MAAM,IAAI,CAAC,CAAC,GAAG;AAC/D,oBAAQ,KAAK,+BAA+B,CAAC,GAAG,QAAQ,EAAE,KAAK,KAAK,CAAC,GAAG;AAAA,UAC1E;AACA,qBAAW,OAAO,MAAM;AACtB,gBAAI,eAAe,GAAG,EAAG;AACzB,kBAAM,UAAU,IAAI,aAAa,IAAI,GAAG;AAIxC,kBAAM,WAAW,QAAQ,cAAc,KAAK,YACxC,iBAAiB,IAAI,QAAQ,SAAS,IACtC,iBAAiB,IAAI,GAAG;AAC5B,gBAAI,CAAC,YAAY,SAAS,SAAS,EAAG;AACtC,gBAAI,CAAC,CAAC,GAAG,QAAQ,EAAE,KAAK,OAAK,MAAM,IAAI,CAAC,CAAC,GAAG;AAC1C,oBAAM,QAAQ,QAAQ,cAAc,KAAK,YAAY,IAAI,GAAG,+BAA+B,QAAQ,SAAS,OAAO,IAAI,GAAG,MAAM,CAAC,GAAG,QAAQ,EAAE,KAAK,KAAK,CAAC;AACzJ,sBAAQ,KAAK,KAAK;AAAA,YACpB;AAAA,UACF;AACA,cAAI,QAAQ,QAAQ;AAClB,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,QAAQ,KAAK,OAAO,wBAAwB,KAAK,EAAE,oBAAoB,QAAQ,KAAK,QAAQ,CAAC;AAAA,cAC7F,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAOA,gBAAM,aAAa,IAAI,IAAI,MAAM,cAAc,OAAO,OAAK,EAAE,WAAW,MAAM,CAAC,CAAC;AAChF,cAAI,WAAW,SAAS,EAAG;AAC3B,gBAAM,aAAa,OAAO,KAAK,EAAE;AACjC,cAAI,CAAC,CAAC,GAAG,UAAU,EAAE,KAAK,OAAK,EAAE,WAAW,UAAU,CAAC,EAAG;AAE1D,gBAAM,YAAsB,CAAC;AAC7B,qBAAW,UAAU,KAAK,SAAS;AACjC,kBAAM,QAAQ,OAAO,aAAa,CAAC;AACnC,gBAAI,CAAC,MAAM,OAAQ;AACnB,kBAAM,QAAQ,OAAO,KAAK,EAAE,IAAI,OAAO,IAAI;AAC3C,gBAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,wBAAU,KAAK,sBAAsB,OAAO,IAAI,cAAc,KAAK,IAAI;AAAA,YACzE;AACA,uBAAW,QAAQ,OAAO;AACxB,kBAAI,KAAK,SAAS,WAAW,CAAC,KAAK,MAAO;AAC1C,oBAAM,aAAa,OAAO,KAAK,EAAE,IAAI,OAAO,IAAI,IAAI,KAAK,KAAK;AAC9D,kBAAI,CAAC,WAAW,IAAI,UAAU,GAAG;AAC/B,0BAAU,KAAK,eAAe,KAAK,KAAK,SAAS,OAAO,IAAI,cAAc,UAAU,IAAI;AAAA,cAC1F;AAAA,YACF;AAAA,UACF;AACA,cAAI,UAAU,QAAQ;AACpB,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,QAAQ,KAAK,OAAO,2CAA2C,KAAK,EAAE,iDAAiD,UAAU,KAAK,QAAQ,CAAC;AAAA,cAC/I,KAAK;AAAA,cACL;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AChOA,IA0BMC,oBAEO;AA5Bb;AAAA;AAAA;AACA;AAEA;AAuBA,IAAMA,qBAAoB,oBAAI,IAAI,CAAC,gBAAgB,cAAc,SAAS,YAAY,CAAC;AAEhF,IAAM,kBAA2B;AAAA,MACtC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,gBAAgB,iBAAiB,WAAW,SAAS,6HAAwH;AAAA,MACvL;AAAA,MACA,MAAM,KAAkB;AAEtB,cAAM,SAAS,oBAAI,IAAmF;AACtG,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,cAAI,CAAC,KAAK,WAAY;AACtB,cAAI,KAAK,gBAAgB,MAAO;AAChC,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,gBAAM,YAAY,WAAW,IAAI,aAAa,IAAI,SAAS,SAAS,IAAI;AACxE,cAAI,CAAC,UAAW;AAChB,cAAI,sBAAsB,UAAU,WAAW,GAAG,EAAG;AACrD,gBAAM,MAAM,oBAAoB,KAAK,UAAU;AAC/C,gBAAM,OAAO,OAAO,IAAI,GAAG,KAAK,CAAC;AACjC,eAAK,KAAK,EAAE,MAAM,eAAe,UAAU,eAAe,QAAQ,UAAU,GAAG,CAAC;AAChF,iBAAO,IAAI,KAAK,IAAI;AAAA,QACtB;AAEA,mBAAW,SAAS,IAAI,UAAU,OAAO;AACvC,cAAI,MAAM,WAAW,cAAc,MAAM,kBAAkB,QAAS;AACpE,gBAAM,WAAW,MAAM,2BAA2B,CAAC;AACnD,cAAI,SAAS,WAAW,EAAG;AAE3B,gBAAM,SAAS,OAAO,IAAI,oBAAoB,MAAM,IAAI,CAAC,KAAK,CAAC;AAC/D,cAAI,OAAO,WAAW,EAAG;AACzB,cAAI,CAAC,OAAO,MAAM,OAAKA,mBAAkB,IAAI,EAAE,aAAa,CAAC,EAAG;AAEhE,gBAAM,SAAS,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,GAAG,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAC/E,gBAAM,WAAW,CAAC,GAAG,IAAI,IAAI,OAAO,IAAI,OAAK,GAAG,EAAE,MAAM,KAAK,EAAE,aAAa,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI;AAC5F,cAAI;AAAA,YACF;AAAA,YACA;AAAA,YACA,IAAI,MAAM,IAAI,2CAA2C,SAAS,IAAI,OAAK,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC,2CAA2C,QAAQ;AAAA,YAClJ,OAAO,KAAK;AAAA,YACZ,OAAO,KAAK,OAAK,IAAI,sBAAsB,EAAE,IAAI,CAAC;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACpBA,SAASC,gBAAe,QAAqB,UAAkB,WAAkC;AAC/F,MAAI,CAAC,UAAU,WAAW,GAAG,EAAG,QAAO;AACvC,QAAM,SAASC,eAAmB,YAAM,UAAe,YAAM,KAAU,YAAM,QAAQ,QAAQ,GAAG,SAAS,CAAC,CAAC;AAC3G,QAAM,aAAa;AAAA,IACjB;AAAA,IACA,OAAO,QAAQ,SAAS,KAAK;AAAA,IAAG,OAAO,QAAQ,SAAS,MAAM;AAAA,IAC9D,GAAG,MAAM;AAAA,IAAO,GAAG,MAAM;AAAA,IAAQ,GAAG,MAAM;AAAA,IAC1C,GAAG,MAAM;AAAA,IAAa,GAAG,MAAM;AAAA,EACjC;AACA,aAAW,KAAK,YAAY;AAC1B,QAAI,OAAO,IAAI,CAAC,EAAG,QAAO;AAAA,EAC5B;AACA,SAAO;AACT;AAhEA,IAAAC,OAgDMD,gBAkBO;AAlEb;AAAA;AAAA;AAAA,IAAAC,QAAsB;AAEtB;AAEA;AA4CA,IAAMD,iBAAgB;AAkBf,IAAM,4BAAqC;AAAA,MAChD,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,yBAAyB,iBAAiB,WAAW,SAAS,sHAAsH;AAAA,QAC5L,EAAE,MAAM,yBAAyB,iBAAiB,WAAW,SAAS,gGAAgG;AAAA,MACxK;AAAA,MAEA,MAAM,KAAwB;AAE5B,cAAM,cAAc,IAAI,IAAI,IAAI,UAAU,MAAM,IAAI,OAAK,CAACA,eAAc,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;AACpF,cAAM,QAAQ,oBAAI,IAAsB;AACxC,cAAM,mBAAmB,oBAAI,IAAyB;AACtD,cAAM,mBAAmB,oBAAI,IAAkC;AAE/D,mBAAW,QAAQ,IAAI,iBAAiB;AACtC,cAAI,CAAC,KAAK,WAAY;AACtB,gBAAM,WAAW,IAAI,aAAa,IAAI,KAAK,QAAQ;AACnD,cAAI,CAAC,SAAU;AACf,gBAAM,YAAY,IAAI,aAAa,IAAI,SAAS,SAAS;AACzD,cAAI,CAAC,UAAW;AAChB,cAAI,sBAAsB,UAAU,WAAW,GAAG,EAAG;AAErD,gBAAM,IAAIA,eAAc,KAAK,UAAU;AACvC,gBAAM,QAAQ,YAAY,IAAI,CAAC;AAC/B,cAAI,CAAC,SAAS,MAAM,WAAW,cAAc,MAAM,kBAAkB,QAAS;AAE9E,cAAI,OAAO,MAAM,IAAI,CAAC;AACtB,cAAI,CAAC,MAAM;AACT,mBAAO,EAAE,MAAM,GAAG,YAAY,CAAC,GAAG,cAAc,KAAK,IAAI,SAAS,MAAM,SAAS,WAAW,MAAM,WAAW,OAAO,MAAM;AAC1H,kBAAM,IAAI,GAAG,IAAI;AAAA,UACnB;AACA,cAAI,CAAC,KAAK,WAAW,KAAK,OAAK,EAAE,OAAO,UAAU,EAAE,EAAG,MAAK,WAAW,KAAK,SAAS;AACrF,eAAK,QAAQ,KAAK,SAAS,IAAI,sBAAsB,IAAI;AAEzD,cAAI,CAAC,iBAAiB,IAAI,UAAU,EAAE,EAAG,kBAAiB,IAAI,UAAU,IAAI,oBAAI,IAAI,CAAC;AACrF,2BAAiB,IAAI,UAAU,EAAE,EAAG,IAAI,CAAC;AACzC,cAAI,CAAC,iBAAiB,IAAI,UAAU,EAAE,EAAG,kBAAiB,IAAI,UAAU,IAAI,CAAC,CAAC;AAC9E,2BAAiB,IAAI,UAAU,EAAE,EAAG,KAAK,IAAI;AAAA,QAC/C;AAEA,cAAM,cAAc,IAAI,IAAI,MAAM,KAAK,CAAC;AAMxC,cAAM,QAAQ,oBAAI,IAAyB;AAC3C,cAAM,mBAAmB,oBAAI,IAAyB;AACtD,mBAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,gBAAM,UAAU,oBAAI,IAAY;AAChC,qBAAW,QAAQ,KAAK,SAAS;AAC/B,kBAAM,WAAWD,gBAAe,aAAa,KAAK,MAAM,IAAI;AAC5D,gBAAI,YAAY,aAAa,KAAK,KAAM,SAAQ,IAAI,QAAQ;AAAA,UAC9D;AACA,gBAAM,IAAI,KAAK,MAAM,OAAO;AAC5B,gBAAM,WAAW,IAAI,IAAI,OAAO;AAChC,qBAAW,QAAQ,KAAK,WAAW;AACjC,kBAAM,WAAWA,gBAAe,aAAa,KAAK,MAAM,IAAI;AAC5D,gBAAI,YAAY,aAAa,KAAK,KAAM,UAAS,IAAI,QAAQ;AAAA,UAC/D;AACA,2BAAiB,IAAI,KAAK,MAAM,QAAQ;AAAA,QAC1C;AAGA,cAAM,gBAAgB,CAAC,MAAqB,SAC1C,KAAK,UAAU,SAAS,IAAI,MAAM,KAAK,QAAQ,CAAC,GAAG,SAAS,IAAI;AAGlE,cAAM,UAAU,oBAAI,IAA2B;AAC/C,mBAAW,KAAK,IAAI,YAAY;AAC9B,qBAAW,UAAU,EAAE,QAAQ,CAAC,EAAG,SAAQ,IAAI,QAAQ,CAAC;AAAA,QAC1D;AAGA,cAAM,sBAAsB,CAAC,MAAqB,gBAAiC;AACjF,gBAAM,YAAY,IAAI,UAAU,IAAI,WAAW;AAC/C,cAAI,CAAC,aAAa,UAAU,SAAS,EAAG,QAAO;AAC/C,iBAAO,KAAK,UAAU,KAAK,OAAK,UAAU,IAAI,CAAC,CAAC;AAAA,QAClD;AAEA,cAAM,gBAAgB,CAAC,UAAoB,WAA8B;AACvE,qBAAW,MAAM,SAAS,YAAY;AACpC,uBAAW,MAAM,OAAO,YAAY;AAClC,kBAAI,GAAG,OAAO,GAAG,GAAI,QAAO;AAC5B,kBAAI,cAAc,IAAI,GAAG,EAAE,EAAG,QAAO;AAQrC,kBACE,GAAG,cAAc,GAAG,aACjB,cAAc,IAAI,GAAG,EAAE,MACtB,GAAG,kBAAkB,YAAY,GAAG,kBAAkB,YAC1D,QAAO;AAMT,oBAAM,SAAS,QAAQ,IAAI,GAAG,EAAE;AAChC,kBAAI,WAAW,cAAc,IAAI,OAAO,EAAE,KAAK,GAAG,OAAO,OAAO,IAAK,QAAO;AAC5E,oBAAM,SAAS,QAAQ,IAAI,GAAG,EAAE;AAChC,kBAAI,WAAW,cAAc,QAAQ,GAAG,EAAE,KAAK,OAAO,OAAO,GAAG,IAAK,QAAO;AAC5E,kBAAI,UAAU,UAAU,OAAO,OAAO,OAAO,GAAI,QAAO;AAExD,kBAAI,GAAG,cAAc,GAAG,aAAa,oBAAoB,IAAI,GAAG,SAAS,EAAG,QAAO;AAAA,YACrF;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAGA,mBAAW,CAAC,UAAU,OAAO,KAAK,OAAO;AACvC,gBAAM,WAAW,MAAM,IAAI,QAAQ;AACnC,qBAAW,UAAU,SAAS;AAC5B,kBAAM,SAAS,MAAM,IAAI,MAAM;AAC/B,gBAAI,cAAc,UAAU,MAAM,EAAG;AACrC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,IAAI,QAAQ,gBAAgB,SAAS,WAAW,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,cAAc,MAAM,gBAAgB,OAAO,WAAW,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,cACxJ,SAAS;AAAA,cACT,SAAS,SAAS,OAAO;AAAA,YAC3B;AAAA,UACF;AAAA,QACF;AAMA,cAAM,mBAAmB,CAAC,WAAwB,SAAsB,iBAAmC;AACzG,qBAAW,KAAK,WAAW;AACzB,kBAAM,UAAU,iBAAiB,IAAI,CAAC;AACtC,gBAAI,CAAC,QAAS;AACd,uBAAW,KAAK,QAAS,KAAI,QAAQ,IAAI,CAAC,EAAG,QAAO;AAAA,UACtD;AACA,cAAI,cAAc;AAChB,uBAAW,KAAK,SAAS;AACvB,oBAAM,UAAU,iBAAiB,IAAI,CAAC;AACtC,kBAAI,CAAC,QAAS;AACd,yBAAW,KAAK,UAAW,KAAI,QAAQ,IAAI,CAAC,EAAG,QAAO;AAAA,YACxD;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAEA,mBAAW,aAAa,IAAI,YAAY;AACtC,gBAAM,YAAY,iBAAiB,IAAI,UAAU,EAAE;AACnD,cAAI,CAAC,UAAW;AAEhB,gBAAM,qBAAqB,UAAU,kBAAkB,YAAY,UAAU,kBAAkB;AAC/F,gBAAM,kBAAkB,CAAC,GAAG,UAAU,WAAW,GAAI,UAAU,QAAQ,CAAC,CAAE;AAC1E,qBAAW,YAAY,iBAAiB;AACtC,kBAAM,SAAS,IAAI,aAAa,IAAI,QAAQ;AAC5C,gBAAI,CAAC,OAAQ;AAEb,gBAAI,UAAU,cAAc,OAAO,WAAW;AAG5C,oBAAM,iBAAiB,oBAAI,IAAY;AACvC,yBAAW,QAAQ,MAAM,OAAO,GAAG;AACjC,oBAAI,KAAK,WAAW,KAAK,OAAK,EAAE,cAAc,OAAO,SAAS,EAAG,gBAAe,IAAI,KAAK,IAAI;AAAA,cAC/F;AACA,kBAAI,eAAe,SAAS,EAAG;AAC/B,yBAAW,KAAK,UAAW,gBAAe,OAAO,CAAC;AAClD,kBAAI,eAAe,SAAS,EAAG;AAC/B,kBAAI,iBAAiB,WAAW,gBAAgB,kBAAkB,EAAG;AAAA,YACvE,OAAO;AACL,oBAAM,UAAU,iBAAiB,IAAI,QAAQ;AAC7C,kBAAI,CAAC,QAAS;AACd,kBAAI,CAAC,GAAG,SAAS,EAAE,KAAK,OAAK,QAAQ,IAAI,CAAC,CAAC,EAAG;AAC9C,kBAAI,iBAAiB,WAAW,SAAS,kBAAkB,EAAG;AAAA,YAChE;AAEA,kBAAM,QAAQ,iBAAiB,IAAI,UAAU,EAAE,KAAK,CAAC;AACrD,kBAAM,SAAS,MAAM,CAAC;AACtB,kBAAM,QAAQ,IAAI,iBAAiB,UAAU,EAAE,KAAK,IAAI,iBAAiB,QAAQ,KAC5E,MAAM,KAAK,OAAK,IAAI,sBAAsB,CAAC,CAAC;AACjD,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,cAAc,UAAU,EAAE,cAAc,UAAU,UAAU,SAAS,QAAQ,IAAI,cAAc,MAAM,KAAK,QAAQ,yDAAyD,CAAC,GAAG,SAAS,EAAE,KAAK,IAAI,CAAC,WAAM,OAAO,cAAc,UAAU,YAAY,aAAa,OAAO,SAAS,KAAK,CAAC,GAAI,iBAAiB,IAAI,QAAQ,KAAK,CAAC,CAAE,EAAE,KAAK,IAAI,CAAC;AAAA,cAC7U,QAAQ,MAAM,UAAU;AAAA,cACxB;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACpQA,IAgBa;AAhBb;AAAA;AAAA;AAgBO,IAAM,iBAA0B;AAAA,MACrC,MAAM;AAAA,MACN,aACE;AAAA,MACF,OAAO;AAAA,QACL,EAAE,MAAM,2BAA2B,iBAAiB,WAAW,SAAS,0DAA0D;AAAA,QAClI,EAAE,MAAM,qBAAqB,iBAAiB,WAAW,SAAS,6EAAwE;AAAA,MAC5I;AAAA,MACA,MAAM,KAAK;AACT,mBAAW,KAAK,IAAI,YAAY;AAC9B,cAAI,CAAC,IAAI,gBAAgB,IAAI,EAAE,IAAI,GAAG;AACpC,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,SAAS,EAAE,MAAM,gCAAgC,EAAE,IAAI;AAAA,cACvD,EAAE;AAAA,YACJ;AACA;AAAA,UACF;AACA,cAAI,CAAC,EAAE,MAAM;AACX,gBAAI;AAAA,cACF;AAAA,cACA;AAAA,cACA,SAAS,EAAE,MAAM,aAAa,EAAE,IAAI,cAAc,EAAE,MAAM;AAAA,cAC1D,EAAE;AAAA,YACJ;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACoFO,SAAS,oBAAoB,aAAwB,CAAC,GAAc;AACzE,QAAM,OAAO,UAAU,OAAO,OAAK,MAAM,cAAc;AACvD,SAAO,CAAC,GAAG,MAAM,GAAG,YAAY,cAAc;AAChD;AAmGO,SAAS,gBAAgB,MAAuD;AACrF,QAAM,EAAE,YAAY,YAAY,iBAAiB,OAAO,eAAe,IAAI;AAC3E,SAAO,CAAC,WAA4B;AAClC,QAAI,CAAC,eAAgB,QAAO;AAC5B,QAAI,WAAW,eAAgB,QAAO;AAEtC,UAAM,OAAO,WAAW,KAAK,OAAK,EAAE,OAAO,MAAM;AACjD,QAAI,KAAM,QAAO,KAAK,cAAc,kBAAkB,KAAK,UAAU,WAAW,GAAG,cAAc,IAAI;AAErG,UAAM,OAAO,WAAW,KAAK,OAAK,EAAE,OAAO,MAAM;AACjD,QAAI,MAAM;AACR,YAAM,aAAa,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK,SAAS;AAC/D,aAAO,aAAc,WAAW,cAAc,kBAAkB,WAAW,UAAU,WAAW,GAAG,cAAc,IAAI,IAAK;AAAA,IAC5H;AAEA,UAAM,OAAO,gBAAgB,KAAK,OAAK,EAAE,OAAO,MAAM;AACtD,QAAI,MAAM;AACR,YAAM,eAAe,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK,QAAQ;AAChE,UAAI,cAAc;AAChB,cAAM,aAAa,WAAW,KAAK,OAAK,EAAE,OAAO,aAAa,SAAS;AACvE,eAAO,aAAc,WAAW,cAAc,kBAAkB,WAAW,UAAU,WAAW,GAAG,cAAc,IAAI,IAAK;AAAA,MAC5H;AACA,aAAO;AAAA,IACT;AAEA,UAAM,IAAI,MAAM,KAAK,UAAQ,KAAK,OAAO,MAAM;AAC/C,QAAI,EAAG,QAAO,EAAE,cAAc,mBAAmB,EAAE,YAAY,EAAE,UAAU,WAAW,GAAG,cAAc,IAAI,IAAI;AAE/G,QAAI,OAAO,WAAW,GAAG,cAAc,IAAI,EAAG,QAAO;AAErD,WAAO;AAAA,EACT;AACF;AAwBO,SAAS,iBAAiB,MAAwC;AACvE,QAAM,EAAE,QAAQ,YAAY,YAAY,YAAY,iBAAiB,OAAO,OAAO,aAAa,gBAAgB,OAAO,IAAI;AAC3H,QAAM,aAAa,KAAK,cAAc,gBAAgB;AAEtD,QAAM,eAAe,IAAI,IAAI,WAAW,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC3D,QAAM,eAAe,IAAI,IAAI,WAAW,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAC3D,QAAM,eAAe,IAAI,IAAI,WAAW,IAAI,OAAK,EAAE,EAAE,CAAC;AACtD,QAAM,eAAe,IAAI,IAAI,WAAW,IAAI,OAAK,EAAE,EAAE,CAAC;AACtD,QAAM,eAAe,IAAI,IAAI,WAAW,IAAI,OAAK,EAAE,EAAE,CAAC;AAEtD,QAAM,wBAAwB,oBAAI,IAA6B;AAC/D,aAAW,QAAQ,YAAY;AAC7B,UAAM,OAAO,sBAAsB,IAAI,KAAK,SAAS;AACrD,QAAI,KAAM,MAAK,KAAK,IAAI;AAAA,QACnB,uBAAsB,IAAI,KAAK,WAAW,CAAC,IAAI,CAAC;AAAA,EACvD;AACA,QAAM,4BAA4B,oBAAI,IAAkC;AACxE,aAAW,QAAQ,iBAAiB;AAClC,UAAM,OAAO,0BAA0B,IAAI,KAAK,QAAQ;AACxD,QAAI,KAAM,MAAK,KAAK,IAAI;AAAA,QACnB,2BAA0B,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC;AAAA,EAC1D;AAIA,QAAM,YAAY,oBAAI,IAAyB;AAC/C,aAAW,OAAO,YAAY;AAC5B,cAAU;AAAA,MACR,IAAI;AAAA,MACJ,IAAI,IAAI,IAAI,iBAAiB,IAAI,QAAM,GAAG,SAAS,EAAE,OAAO,CAAC,MAAmB,CAAC,CAAC,CAAC,CAAC;AAAA,IACtF;AAAA,EACF;AAEA,QAAM,gBAAgB,gBAAgB,EAAE,YAAY,YAAY,iBAAiB,OAAO,eAAe,CAAC;AAKxG,QAAM,kBAAkB,oBAAI,IAAoB;AAChD,aAAW,KAAK,WAAY,iBAAgB,IAAI,EAAE,IAAI,EAAE,EAAE;AAC1D,aAAW,KAAK,WAAY,iBAAgB,IAAI,EAAE,IAAI,EAAE,SAAS;AACjE,aAAW,KAAK,YAAY;AAC1B,UAAM,OAAO,aAAa,IAAI,EAAE,SAAS;AACzC,QAAI,KAAM,iBAAgB,IAAI,EAAE,IAAI,KAAK,SAAS;AAAA,EACpD;AACA,aAAW,MAAM,iBAAiB;AAChC,UAAM,WAAW,aAAa,IAAI,GAAG,QAAQ;AAC7C,UAAM,OAAO,WAAW,aAAa,IAAI,SAAS,SAAS,IAAI;AAC/D,QAAI,KAAM,iBAAgB,IAAI,GAAG,IAAI,KAAK,SAAS;AAAA,EACrD;AACA,aAAW,KAAK,OAAO;AACrB,QAAI,EAAE,UAAW,iBAAgB,IAAI,EAAE,IAAI,EAAE,SAAS;AAAA,EACxD;AAEA,QAAM,eAAe,CAAC,gBACpB,cAAc,WAAW,SAAS,WAAW,GAAG,OAAO,cAAc;AAEvE,QAAM,uBAAuB,CAAC,gBAAiF;AAC7G,UAAM,MAAM,cAAc,WAAW,KAAK,OAAK,EAAE,OAAO,WAAW,IAAI;AACvE,WAAO,KAAK,eACP,OAAO,eACP,aAAa,KAAK,OAAO,KACzB,aAAa,WAAW,KACxB;AAAA,EACP;AAEA,QAAM,mBAAmB,CAAC,WAA4B;AACpD,UAAM,OAAO,aAAa,IAAI,MAAM;AACpC,QAAI,CAAC,UAAU,CAAC,KAAM,QAAO;AAC7B,QAAI,KAAK,WAAW,WAAW,KAAK,WAAW,SAAU,QAAO;AAEhE,UAAM,MAAM,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK,SAAS;AACxD,QAAI,QAAQ,IAAI,WAAW,WAAW,IAAI,WAAW,UAAW,QAAO;AAEvE,WAAO;AAAA,EACT;AAEA,QAAM,wBAAwB,CAAC,SAAsC;AACnE,QAAI,KAAK,WAAW,WAAW,KAAK,WAAW,SAAU,QAAO;AAChE,UAAM,WAAW,aAAa,IAAI,KAAK,QAAQ;AAC/C,QAAI,CAAC,SAAU,QAAO;AACtB,WAAO,SAAS,WAAW,WAAW,SAAS,WAAW,YAAY,iBAAiB,SAAS,SAAS;AAAA,EAC3G;AAEA,QAAM,sBAAsB,CAAC,WAAgC;AAC3D,UAAM,OAAO,aAAa,IAAI,MAAM;AACpC,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,MAAM,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK,SAAS;AACxD,QAAI,OAAO,IAAI,SAAS;AACtB,aAAO,IAAI;AAAA,IACb;AACA,QAAK,iBAAuC,SAAS,WAAW,KAAK,eAAe,WAAW,UAAU;AACvG,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,CAAC,KAAa,aAAmC;AACtE,UAAM,WAAW,IAAI,YAAY;AACjC,QAAI,cAAc,IAAI,QAAQ,EAAG,QAAO;AACxC,QAAI,SAAS,IAAI,QAAQ,EAAG,QAAO;AAEnC,WAAO,MAAM,KAAK,UAAQ;AACxB,YAAM,kBAAkB,KAAK,aAAa,CAAC,KAAK,GAAG,WAAW,GAAG,KAAK,SAAS,IAAI,IAC/E,GAAG,KAAK,SAAS,KAAK,KAAK,EAAE,KAC7B,KAAK;AACT,aAAO,aAAa,KAAK,eAAe;AAAA,IAC1C,CAAC;AAAA,EACH;AAEA,QAAM,oBAAoB,CAAC,gBAAwD;AACjF,QAAI,aAAa;AACf,YAAM,MAAM,WAAW,KAAK,OAAK,EAAE,OAAO,WAAW;AACrD,UAAI,KAAK,eAAgB,QAAO,kBAAkB,IAAI,cAAc;AAAA,IACtE;AACA,WAAO,OAAO,iBAAiB,kBAAkB,OAAO,cAAc,IAAI;AAAA,EAC5E;AAEA,QAAM,kBAAkB,CACtB,UACA,iBACA,gBACA,gBACqB;AAErB,QAAI,OAAO,kBAAkB,QAAQ,GAAG;AACtC,aAAO,MAAM,gBAAgB,QAAQ;AAAA,IACvC;AAIA,UAAM,MAAM,cAAc,WAAW,KAAK,OAAK,EAAE,OAAO,WAAW,IAAI;AACvE,UAAM,kBAAkB,WAAW,SAAS,KAAK,WAAW,WAAW,GAAG,OAAO,kBAAkB,QAAQ;AAC3G,QAAI,iBAAiB;AACnB,aAAO;AAAA,IACT;AACA,QAAI,kBAAkB,mBAAmB,IAAI,QAAQ,GAAG;AACtD,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAOA,QAAM,aAAwC,CAAC;AAC/C,QAAM,cAAc,oBAAI,IAA4D;AACpF,QAAM,gBAAgB,CAAC,QAAgB,SAA+D;AACpG,eAAW,KAAK,MAAM,SAAS,CAAC,GAAG;AACjC,YAAM,QAAQ,EAAE,QAAQ,MAAM,EAAE,MAAM,QAAQ,EAAE,QAAQ,MAAM,MAAM;AACpE,iBAAW,KAAK,KAAK;AACrB,UAAI,CAAC,YAAY,IAAI,MAAM,EAAG,aAAY,IAAI,QAAQ,oBAAI,IAAI,CAAC;AAC/D,kBAAY,IAAI,MAAM,EAAG,IAAI,EAAE,MAAM,KAAK;AAAA,IAC5C;AAAA,EACF;AACA,aAAW,KAAK,WAAY,eAAc,EAAE,IAAI,EAAE,IAAI;AACtD,aAAW,KAAK,WAAY,eAAc,EAAE,IAAI,EAAE,IAAI;AACtD,aAAW,KAAK,WAAY,eAAc,EAAE,IAAI,EAAE,IAAI;AACtD,aAAW,MAAM,gBAAiB,eAAc,GAAG,IAAI,GAAG,IAAI;AAC9D,aAAW,KAAK,MAAO,eAAc,EAAE,IAAI,EAAE,IAAI;AAEjD,QAAM,kBAAkB,oBAAI,IAAI;AAAA,IAC9B,GAAG,CAAC,GAAG,WAAW,GAAG,WAAW,KAAK,EAAE,QAAQ,OAAK,EAAE,MAAM,IAAI,OAAK,EAAE,IAAI,CAAC;AAAA;AAAA;AAAA,IAG5E,GAAG,WAAW,WAAW,IAAI,OAAK,EAAE,QAAQ;AAAA,EAC9C,CAAC;AAED,QAAM,WAAW,CACf,iBACA,MACA,SACA,QACA,mBACS;AACT,QAAI,kBAAkB,UAAU,CAAC,cAAc,MAAM,GAAG;AACtD;AAAA,IACF;AACA,UAAM,QAAQ,SAAS,gBAAgB,IAAI,MAAM,IAAI;AAIrD,UAAM,gBAAgB,kBAAkB,IAAI;AAC5C,QAAI,eAAe;AACjB,UAAI,WAAW,qBAAqB,KAAK,CAAC,IAAI,WAAW,aAAa,EAAG;AAAA,IAC3E;AACA,UAAM,WAAW,gBAAgB,MAAM,iBAAiB,gBAAgB,KAAK;AAC7E,QAAI,aAAa,MAAO;AACxB,QAAI,QAAQ;AACV,YAAM,QAAQ,YAAY,IAAI,MAAM,GAAG,IAAI,IAAI;AAC/C,UAAI,OAAO;AACT,cAAM,OAAO;AACb,YAAI,aAAa,UAAW;AAAA,MAC9B;AAAA,IACF;AAIA,WAAO,KAAK,EAAE,UAAU,MAAM,SAAS,QAAQ,GAAI,iBAAiB,EAAE,cAAc,KAAK,IAAI,CAAC,EAAG,CAAC;AAAA,EACpG;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,EAAE,UAAU,WAAW,UAAU,WAAW,WAAW,WAAW,UAAU,WAAW,UAAU,YAAY,WAAW,YAAY,YAAY,WAAW,WAAW;AAAA,IAC3K,UAAU,KAAK,YAAY,CAAC;AAAA,IAC5B,kBAAkB,KAAK,oBAAoB,CAAC;AAAA,IAC5C,WAAW,KAAK,aAAa,eAAe;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AA1gBA,IAyDa,WAwFP,YAQA,mBA+BA;AAxLN;AAAA;AAAA;AAUA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AAOO,IAAM,YAAuB;AAAA,MAClC;AAAA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA;AAAA,MAEA;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA,MAGA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,IACF;AAuBA,IAAM,aAA0C;AAAA,MAC9C,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,iBAAiB;AAAA,MACjB,YAAY;AAAA,IACd;AAGA,IAAM,oBAAiD;AAAA;AAAA,MAErD,kBAAkB;AAAA,MAClB,oBAAoB;AAAA,MACpB,aAAa;AAAA;AAAA,MAEb,+BAA+B;AAAA,MAC/B,qBAAqB;AAAA,MACrB,qBAAqB;AAAA,MACrB,0BAA0B;AAAA,MAC1B,mBAAmB;AAAA,MACnB,8BAA8B;AAAA,MAC9B,sBAAsB;AAAA,MACtB,uBAAuB;AAAA,MACvB,uBAAuB;AAAA,MACvB,yBAAyB;AAAA;AAAA;AAAA;AAAA,MAIzB,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,uBAAuB;AAAA,MACvB,yBAAyB;AAAA,MACzB,sBAAsB;AAAA,MACtB,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,MAClB,eAAe;AAAA,IACjB;AAIA,IAAM,qBAAqB,oBAAI,IAAI;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA;AAAA,MAGA;AAAA;AAAA;AAAA,MAGA;AAAA;AAAA;AAAA,MAGA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA;;;AC1MD,SAAS,QAAQ,MAAqB;AACpC,UAAQ,KAAK,IAAI;AACnB;AAQO,SAAS,uBAA6B;AAC3C,YAAU,CAAC;AACX,aAAW,QAAQ,UAAW,SAAQ,IAAI;AAC5C;AAGO,SAAS,kBAAkB,WAA4B;AAC5D,aAAW,QAAQ,UAAW,SAAQ,IAAI;AAC5C;AAGO,SAAS,eAA0B;AACxC,QAAM,OAAO,QAAQ,OAAO,OAAK,MAAM,cAAc;AACrD,SAAO,QAAQ,SAAS,cAAc,IAAI,CAAC,GAAG,MAAM,cAAc,IAAI;AACxE;AAvCA,IAYI;AAZJ;AAAA;AAAA;AACA;AACA;AAUA,IAAI,UAAqB,CAAC;AAAA;AAAA;;;AC8BnB,SAAS,oBAA4B;AAC1C,SAAO,QAAQ,IAAI,uBAA4B,WAAQ,YAAQ,GAAG,WAAW,UAAU;AACzF;AAQA,SAAS,gBAAgB,KAA2B;AAClD,MAAI;AACJ,MAAI;AACF,cAAa,gBAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAAA,EACvD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,MAAoB,CAAC;AAC3B,aAAW,KAAK,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC,GAAG;AACpE,QAAI,CAAC,EAAE,OAAO,KAAK,CAAC,YAAY,KAAK,EAAE,IAAI,EAAG;AAC9C,UAAM,OAAY,WAAK,KAAK,EAAE,IAAI;AAClC,QAAI;AACF,YAAM,MAAM,aAAa,IAAI;AAC7B,UAAI,OAAO,KAAM;AACjB,YAAM,QAAQ,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG;AAC7C,iBAAW,QAAQ,MAAO,KAAI,KAAK,iBAAiB,MAAM,IAAI,CAAC;AAAA,IACjE,SAAS,KAAK;AACZ,cAAQ,MAAM,uBAAuB,IAAI,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,IACnG;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,sBAAoC;AAClD,MAAI;AACF,UAAM,OAAO,oBAAI,IAAwB;AACzC,eAAW,KAAK,gBAAgB,kBAAkB,CAAC,EAAG,MAAK,IAAI,EAAE,IAAI,CAAC;AACtE,eAAW,KAAK,gBAAqB,WAAK,eAAe,GAAG,QAAQ,UAAU,CAAC,EAAG,MAAK,IAAI,EAAE,IAAI,CAAC;AAClG,WAAO,CAAC,GAAG,KAAK,OAAO,CAAC;AAAA,EAC1B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAzFA,IAAAG,KACAC,KACAC,OACAC,aAoBa;AAvBb;AAAA;AAAA;AAAA,IAAAH,MAAoB;AACpB,IAAAC,MAAoB;AACpB,IAAAC,QAAsB;AACtB,IAAAC,cAAkB;AAClB;AACA;AAkBO,IAAM,mBAAmB,cAAE,OAAO;AAAA;AAAA,MAEvC,IAAI,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,MAEpB,MAAM,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,MAEtB,UAAU,cAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,MAE1B,QAAQ,cAAE,OAAO,EAAE,SAAS;AAAA;AAAA,MAE5B,SAAS,cAAE,OAAO,EAAE,SAAS;AAAA,IAC/B,CAAC;AAAA;AAAA;;;AC8DD,SAAS,MACP,UACA,MACA,SACA,SACA,QACiB;AACjB,SAAO,EAAE,UAAU,MAAM,SAAS,SAAS,OAAO;AACpD;AAMO,SAAS,iBAAiB,UAAoB,OAAsC;AACzF,QAAM,SAA4B,CAAC;AAGnC,QAAM,WAAW,oBAAI,IAAoB;AACzC,aAAW,SAAS,SAAS,QAAQ;AACnC,aAAS,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,EAAE,KAAK,KAAK,CAAC;AAAA,EAC1D;AACA,aAAW,CAAC,IAAI,KAAK,KAAK,UAAU;AAClC,QAAI,QAAQ,GAAG;AACb,aAAO,KAAK,MAAM,SAAS,sBAAsB,wBAAwB,EAAE,KAAK,EAAE,CAAC;AAAA,IACrF;AAAA,EACF;AAGA,aAAW,SAAS,SAAS,QAAQ;AACnC,kBAAc,OAAO,OAAO,MAAM;AAAA,EACpC;AAGA,MAAI,MAAM,wBAAwB;AAChC,8BAA0B,SAAS,QAAQ,MAAM;AAAA,EACnD;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,MAAM,CAAC,MAAM,EAAE,aAAa,OAAO;AAAA,IACjD;AAAA,EACF;AACF;AAEA,SAAS,cACP,OACA,OACA,QACM;AACN,QAAM,SAAS,MAAM,KAAK,KAAK,CAAC,MAAM,MAAM,cAAc,SAAS,CAAC,CAAC;AAErE,MAAI,MAAM,qBAAqB,CAAC,UAAU,MAAM,WAAW,WAAW,GAAG;AACvE,WAAO;AAAA,MACL;AAAA,QACE;AAAA,QACA;AAAA,QACA,UAAU,MAAM,EAAE;AAAA,QAClB,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,WAAW,GAAG;AAC9B,WAAO;AAAA,MACL,MAAM,WAAW,cAAc,UAAU,MAAM,EAAE,uCAAuC,MAAM,EAAE;AAAA,IAClG;AAAA,EACF;AACF;AAEA,SAAS,0BAA0B,QAAuB,QAAiC;AAEzF,QAAM,eAAe,oBAAI,IAAsB;AAE/C,aAAW,SAAS,QAAQ;AAC1B,eAAW,KAAK,MAAM,YAAY;AAChC,YAAM,SAAS,aAAa,IAAI,CAAC,KAAK,CAAC;AACvC,aAAO,KAAK,MAAM,EAAE;AACpB,mBAAa,IAAI,GAAG,MAAM;AAAA,IAC5B;AAAA,EACF;AAEA,aAAW,CAAC,GAAG,MAAM,KAAK,cAAc;AACtC,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA;AAAA,UACA,SAAS,CAAC,oCAAoC,OAAO,KAAK,IAAI,CAAC;AAAA,QACjE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,sBAAsB,QAAyC;AAC7E,QAAM,SAA4B,CAAC;AAEnC,MAAI,OAAO,QAAQ,WAAW,GAAG;AAC/B,WAAO,KAAK,MAAM,SAAS,cAAc,8CAA8C,CAAC;AAAA,EAC1F;AAEA,QAAM,UAAU,OAAO,QAAQ,OAAO,CAAC,MAAM;AAC3C,QAAI,OAAO,MAAM,SAAU,QAAO;AAClC,WAAO,EAAE,YAAY;AAAA,EACvB,CAAC;AAED,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,KAAK,MAAM,SAAS,sBAAsB,qCAAqC,CAAC;AAAA,EACzF;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,MAAM,CAAC,MAAM,EAAE,aAAa,OAAO;AAAA,IACjD;AAAA,EACF;AACF;AAkCO,SAAS,YAAuB;AACrC,QAAM,aAAa,sBAAsB;AACzC,uBAAqB;AACrB,oBAAkB,WAAW,KAAK;AAClC,SAAO,aAAa;AACtB;AAEO,SAAS,gBACd,gBACA,cAAsB,WACJ;AAClB,MAAI,QAAQ;AACZ,MAAI;AACJ,MAAI,YAA8B;AAClC,MAAI;AACJ,MAAI,qBAAqB;AAEzB,MAAI,mBAAmB,oBAAoB,kBAAkB,eAAe,kBAAkB,WAAW,kBAAkB,iBAAiB,kBAAkB,gBAAgB,kBAAkB,wBAAwB,iBAAiB;AACvO,UAAM,OAAO;AACb,YAAQ,KAAK;AACb,kBAAc,KAAK,eAAe;AAClC,qBAAiB,KAAK;AACtB,gBAAY,KAAK,aAAa;AAC9B,iBAAa,KAAK;AAClB,yBAAqB,KAAK,sBAAsB;AAAA,EAClD;AACA,iBAAe,sBAAsB;AAGrC,eAAa,EAAE,UAAU,CAAC;AAE1B,QAAM,SAA4B,CAAC;AAGnC,oBAAkB;AAClB,QAAM,SAAS,eAAe;AAC9B,QAAM,aAAa,mBAAmB;AACtC,QAAM,aAAa,mBAAmB;AACtC,QAAM,aAAa,mBAAmB;AACtC,QAAM,kBAAkB,wBAAwB;AAChD,QAAM,QAAQ,cAAc;AAG5B,QAAM,mBAAmB,qBAAqB;AAG9C,QAAM,YAAY,eAAe,iBAAiB,eAAe,CAAC;AAOlE,QAAM,gBAAgE,qBAClE,CAAC,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,GAAG,eAAe,IAChE,CAAC;AACL,QAAM,iBAAiB,cAAc,IAAI,CAAC,MAAM,EAAE,MAAM;AACxD,aAAW,KAAK,cAAe,GAAE,SAAS;AAE1C,MAAI;AAEF,UAAM,gBAAgB,gBAAgB,EAAE,YAAY,YAAY,iBAAiB,OAAO,eAAe,CAAC;AACxG,UAAM,eAAe,gBAAgB;AACrC,QAAI,gBAAgB;AAClB,aAAO,KAAK,GAAG,aAAa,OAAO,OAAK,EAAE,UAAU,cAAc,EAAE,MAAM,CAAC,CAAC;AAAA,IAC9E,OAAO;AACL,aAAO,KAAK,GAAG,YAAY;AAAA,IAC7B;AAKA,QAAI,CAAC,QAAQ;AACX,aAAO,KAAK,MAAM,SAAS,uBAAuB,oDAAoD,CAAC;AACvG,aAAO,EAAE,OAAO,OAAO,OAAO;AAAA,IAChC;AAMA,QAAI,gBAAgB;AAClB,YAAM,eAAe,WAAW;AAAA,QAC9B,OAAK,EAAE,OAAO,kBAAkB,EAAE,GAAG,WAAW,GAAG,cAAc,IAAI;AAAA,MACvE;AACA,UAAI,CAAC,cAAc;AACjB,cAAM,QAAQ,WAAW,IAAI,OAAK,EAAE,EAAE,EAAE,KAAK;AAC7C,cAAM,OAAO,MAAM,SACf,sBAAsB,MAAM,KAAK,IAAI,CAAC,MACtC;AACJ,eAAO;AAAA,UACL;AAAA,YACE;AAAA,YACA;AAAA,YACA,gBAAgB,cAAc,0CAA0C,IAAI;AAAA,YAC5E;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO,EAAE,OAAO,OAAO,OAAO;AAAA,MAChC;AAAA,IACF;AAIA,eAAW,OAAO,WAAW,QAAQ;AACnC,aAAO,KAAK,MAAM,SAAS,wBAAwB,GAAG,CAAC;AAAA,IACzD;AAEA,UAAM,MAAM,iBAAiB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,oBAAoB;AAAA,MAC9B;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAID,yBAAqB;AACrB,sBAAkB,WAAW,KAAK;AAClC,eAAW,QAAQ,aAAa,GAAG;AACjC,WAAK,MAAM,GAAG;AAAA,IAChB;AAgBA,UAAM,uBAAuB,OAAO,KAAK,OAAK,yBAAyB,IAAI,EAAE,IAAI,CAAC;AAClF,UAAM,iBAAiB,uBAAuB,mBAAmB,eAAe,CAAC,IAAI;AACrF,QAAI,gBAAgB;AAClB,UAAI,aAAa;AACjB,iBAAW,OAAO,QAAQ;AACxB,YAAI,CAAC,yBAAyB,IAAI,IAAI,IAAI,EAAG;AAC7C,YAAI,IAAI,aAAa,SAAS;AAC5B,cAAI,WAAW;AACf;AAAA,QACF;AACA,YAAI,mBAAmB;AAAA,MACzB;AACA,UAAI,aAAa,GAAG;AAClB,eAAO,QAAQ;AAAA,UACb,UAAU;AAAA,UACV,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,SACE,0CAA0C,eAAe,WAAW,gCAChE,eAAe,UAAU,MAAM,UAAU;AAAA,QAIjD,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,MACL,OAAO,OAAO,MAAM,CAAC,MAAM,EAAE,aAAa,OAAO;AAAA,MACjD;AAAA,IACF;AAAA,EACF,UAAE;AACA,kBAAc,QAAQ,CAAC,GAAG,MAAM;AAAE,QAAE,SAAS,eAAe,CAAC;AAAA,IAAG,CAAC;AAAA,EACnE;AACF;AAcO,SAAS,mBAAmB,SAA+C;AAChF,SAAO,gBAAgB,EAAE,GAAI,WAAW,CAAC,GAAI,oBAAoB,KAAK,CAAC;AACzE;AA9bA,IAmCM;AAnCN;AAAA;AAAA;AAIA,IAAAC;AAWA;AACA;AACA;AACA;AACA;AACA;AACA,IAAAA;AACA;AAaA,IAAM,2BAA2B,oBAAI,IAAI;AAAA;AAAA,MAEvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,CAAC;AAAA;AAAA;;;ACvBM,SAAS,cAAc,QAAwB;AACpD,UAAQ,QAAQ;AAAA,IACd,KAAK;AAAc,aAAO,iBAAiB,iBAAiB,cAAc,CAAC,CAAC;AAAA,IAC5E,KAAK;AAAc,aAAO,yBAAyB;AAAA,IACnD,KAAK;AAAc,aAAO,kBAAkB,iBAAiB,CAAC;AAAA,IAC9D,KAAK;AAAc,aAAO,wBAAwB,iBAAiB,CAAC;AAAA,IACpE;AACE,YAAM,IAAI,MAAM,+BAA+B,MAAM,6CAA6C;AAAA,EACtG;AACF;AAQO,SAAS,uBAAoC;AAClD,SAAO,iBAAiB,cAAc,CAAC;AACzC;AAEA,SAAS,gBAAmC;AAC1C,MAAI;AACF,UAAM,SAAS,kBAAkB;AACjC,WAAO,gBAAgB,EAAE,OAAO,OAAO,OAAO,aAAa,OAAO,YAAY,CAAC,EAAE;AAAA,EACnF,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAcO,SAAS,gBAAgB,OAA8B;AAC5D,QAAM,QAAQ,iBAAiB;AAK/B,QAAM,SAAS,MAAM,OAAO;AAC5B,QAAM,QAAwB;AAAA,IAC5B,EAAE,IAAI,QAAQ,OAAO,MAAM,OAAO,MAAM,MAAM,WAAW,OAAO,EAAE;AAAA,EACpE;AACA,QAAM,aAA8B,CAAC;AAMrC,aAAW,KAAK,MAAM,YAAY;AAChC,UAAM,MAAM,EAAE,GAAG,YAAY,IAAI;AACjC,UAAM,WAAW,OAAO,IAAI,EAAE,GAAG,MAAM,GAAG,GAAG,IAAI;AACjD,UAAM,KAAK;AAAA,MACT,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,MACP;AAAA,MACA,GAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,IACzC,CAAC;AACD,eAAW,KAAK,EAAE,MAAM,UAAU,IAAI,EAAE,IAAI,UAAU,WAAW,CAAC;AAAA,EACpE;AAGA,aAAW,KAAK,MAAM,YAAY;AAChC,UAAM,KAAK;AAAA,MACT,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,MACP,UAAU,EAAE;AAAA,MACZ,GAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,IACzC,CAAC;AACD,eAAW,KAAK,EAAE,MAAM,EAAE,WAAW,IAAI,EAAE,IAAI,UAAU,WAAW,CAAC;AAAA,EACvE;AAGA,aAAW,KAAK,MAAM,YAAY;AAChC,eAAW,QAAQ,EAAE,YAAY;AAC/B,YAAM,KAAK,EAAE,IAAI,KAAK,IAAI,OAAO,KAAK,MAAM,MAAM,aAAa,OAAO,GAAG,UAAU,EAAE,GAAG,CAAC;AACzF,iBAAW,KAAK,EAAE,MAAM,EAAE,IAAI,IAAI,KAAK,IAAI,UAAU,OAAO,CAAC;AAAA,IAC/D;AAAA,EACF;AACA,aAAW,KAAK,MAAM,OAAO;AAC3B,UAAM,KAAK;AAAA,MACT,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,MAAM;AAAA,MACN,OAAO;AAAA,MACP,GAAI,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,IAAI,CAAC;AAAA,IACjD,CAAC;AAAA,EACH;AAGA,aAAW,KAAK,MAAM,OAAO;AAC3B,eAAW,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,IAAI,UAAU,aAAa,CAAC;AAAA,EACpE;AAIA,QAAM,OAAO,MAAM,OAAO,OAAK,EAAE,SAAS,KAAK;AAC/C,QAAM,UAAU,IAAI,IAAI,KAAK,IAAI,OAAK,EAAE,EAAE,CAAC;AAC3C,QAAM,QAAQ,WAAW,OAAO,OAAK,QAAQ,IAAI,EAAE,IAAI,KAAK,QAAQ,IAAI,EAAE,EAAE,CAAC;AAE7E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,OAAO,MAAM,OAAO;AAAA,EACtB;AACF;AAmCO,SAAS,gBAA2B;AACzC,QAAM,SAAS,eAAe;AAC9B,QAAM,aAAa,mBAAmB;AACtC,QAAM,aAAa,mBAAmB;AACtC,QAAM,aAAa,mBAAmB;AACtC,QAAM,kBAAkB,wBAAwB;AAChD,QAAM,mBAAmB,oBAAI,IAAY;AACzC,aAAW,OAAO,YAAY;AAC5B,eAAW,MAAM,IAAI,kBAAkB;AACrC,UAAI,GAAG,UAAW,kBAAiB,IAAI,GAAG,SAAS;AAAA,IACrD;AAAA,EACF;AACA,SAAO;AAAA,IACL,YAAY,QAAQ,QAAQ;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AA0BA,SAAS,YAAY,MAAsB;AACzC,SAAO,KAAK,QAAQ,MAAM,QAAQ;AACpC;AAEA,SAAS,SAAS,MAAc,KAAqB;AACnD,QAAM,QAAQ,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC7C,SAAO,MAAM,UAAU,MAAM,QAAQ,GAAG,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC;AACjE;AAGA,SAAS,SAAS,IAAY,OAAe,MAA6B;AACxE,QAAM,IAAI,YAAY,KAAK;AAC3B,MAAI,KAAK,kBAAkB,YAAY,KAAK,kBAAkB,WAAY,QAAO,GAAG,EAAE,MAAM,CAAC;AAC7F,MAAI,KAAK,kBAAkB,WAAW,KAAK,kBAAkB,QAAS,QAAO,GAAG,EAAE,MAAM,CAAC;AACzF,MAAI,cAAc,IAAI,KAAK,aAAa,EAAG,QAAO,GAAG,EAAE,MAAM,CAAC;AAC9D,SAAO,GAAG,EAAE,KAAK,CAAC;AACpB;AAEA,SAAS,gBAAgB,MAA6B;AACpD,UAAQ,KAAK,eAAe;AAAA,IAC1B,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAoBO,SAAS,yBAAyB,SAA2C;AAClF,QAAM,QAAQ,cAAc;AAC5B,QAAM,QAAQ,SAAS;AAEvB,MAAI,aAAa,MAAM;AACvB,MAAI,OAAO;AACT,UAAM,UAAU,MAAM,WAAW;AAAA,MAC/B,OAAK,EAAE,cAAc,SAAS,EAAE,UAAU,WAAW,GAAG,KAAK,IAAI;AAAA,IACnE;AACA,QAAI,QAAQ,WAAW,GAAG;AACxB,YAAM,IAAI,MAAM,sCAAsC,KAAK,IAAI;AAAA,IACjE;AACA,UAAM,WAAW,IAAI,IAAI,QAAQ,IAAI,OAAK,EAAE,EAAE,CAAC;AAE/C,UAAM,YAAY,MAAM,WAAW,OAAO,OAAK;AAC7C,UAAI,SAAS,IAAI,EAAE,EAAE,EAAG,QAAO;AAC/B,YAAM,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,EAAE,IAAI,EAAE,KAAK,OAAK,SAAS,IAAI,CAAC,CAAC;AAC7E,YAAM,oBAAoB,QAAQ,KAAK,OAAK,EAAE,UAAU,SAAS,EAAE,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,EAAE,CAAC;AAC/F,aAAO,mBAAmB;AAAA,IAC5B,CAAC;AACD,iBAAa,CAAC,GAAG,SAAS,GAAG,SAAS;AAAA,EACxC;AAEA,QAAM,eAAe,IAAI,IAAI,WAAW,IAAI,OAAK,EAAE,EAAE,CAAC;AACtD,QAAM,MAAM,IAAI,OAAO;AACvB,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAQ,QACV,GAAG,MAAM,UAAU,WAAM,KAAK,kBAC9B,GAAG,MAAM,UAAU;AACvB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,WAAW,YAAY,KAAK,CAAC,GAAG;AAC3C,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,cAAc;AAGzB,QAAM,cAAc,oBAAI,IAA6B;AACrD,aAAW,QAAQ,YAAY;AAC7B,UAAM,OAAO,YAAY,IAAI,KAAK,SAAS,KAAK,CAAC;AACjD,SAAK,KAAK,IAAI;AACd,gBAAY,IAAI,KAAK,WAAW,IAAI;AAAA,EACtC;AAEA,QAAM,mBAAmB,oBAAI,IAAsB;AACnD,QAAM,cAAc,CAAC,KAAa,WAAmB;AACnD,UAAM,OAAO,iBAAiB,IAAI,GAAG,KAAK,CAAC;AAC3C,SAAK,KAAK,MAAM;AAChB,qBAAiB,IAAI,KAAK,IAAI;AAAA,EAChC;AAEA,aAAW,CAAC,OAAO,KAAK,KAAK,aAAa;AACxC,UAAM,MAAM,MAAM,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK;AACrD,UAAM,WAAW,YAAY,KAAK,QAAQ,KAAK;AAC/C,UAAM,KAAK,cAAc,IAAI,MAAM,OAAO,KAAK,EAAE,CAAC,KAAK,QAAQ,IAAI;AACnE,eAAW,QAAQ,OAAO;AACxB,YAAM,SAAS,IAAI,MAAM,KAAK,EAAE;AAChC,YAAM,QAAQ,GAAG,KAAK,IAAI,YAAS,KAAK,aAAa;AACrD,YAAM,KAAK,OAAO,SAAS,QAAQ,OAAO,IAAI,CAAC,EAAE;AACjD,kBAAY,gBAAgB,IAAI,GAAG,MAAM;AACzC,UAAI,MAAM,iBAAiB,IAAI,KAAK,EAAE,EAAG,aAAY,iBAAiB,MAAM;AAAA,IAC9E;AACA,UAAM,KAAK,OAAO;AAAA,EACpB;AAGA,aAAW,QAAQ,YAAY;AAC7B,UAAM,SAAS,IAAI,MAAM,KAAK,EAAE;AAChC,eAAW,YAAY,KAAK,MAAM;AAChC,UAAI,CAAC,aAAa,IAAI,QAAQ,EAAG;AACjC,YAAM,KAAK,KAAK,MAAM,gBAAgB,IAAI,MAAM,QAAQ,CAAC,EAAE;AAAA,IAC7D;AACA,eAAW,SAAS,KAAK,WAAW;AAClC,UAAI,CAAC,aAAa,IAAI,KAAK,EAAG;AAC9B,YAAM,MAAM,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK;AAC/C,YAAM,kBAAkB,IAAI,cAAc,KAAK;AAC/C,YAAM,KAAK,kBACP,KAAK,MAAM,QAAQ,IAAI,MAAM,KAAK,CAAC,KACnC,KAAK,MAAM,QAAQ,IAAI,MAAM,KAAK,CAAC,EAAE;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,GAAG,WAAW,IAAI,OAAK,KAAK,CAAC,EAAE,CAAC;AAC3C,aAAW,CAAC,KAAK,OAAO,KAAK,kBAAkB;AAC7C,UAAM,KAAK,WAAW,QAAQ,KAAK,GAAG,CAAC,IAAI,GAAG,EAAE;AAAA,EAClD;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAWO,SAAS,wBACd,aACA,YACA,SACQ;AACR,QAAM,QAAQ,cAAc;AAC5B,QAAM,WAAW,SAAS,SAAS;AAEnC,QAAM,gBAAgB,IAAI,IAAI,MAAM,WAAW,IAAI,OAAK,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAClE,QAAM,mBAAmB,CAAC,OAA0C;AAClE,QAAI,cAAc,IAAI,EAAE,EAAG,QAAO,cAAc,IAAI,EAAE;AAEtD,UAAMC,WAAU,MAAM,WAAW,OAAO,OAAK,EAAE,GAAG,SAAS,KAAK,EAAE,EAAE,CAAC;AACrE,WAAOA,SAAQ,WAAW,IAAIA,SAAQ,CAAC,IAAI;AAAA,EAC7C;AAEA,QAAM,QAAQ,iBAAiB,WAAW;AAC1C,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,cAAc,WAAW,+BAA+B;AAAA,EAC1E;AAEA,QAAM,iBAAiB,CAAC,QAAgB,WAAmB;AACzD,UAAM,cAAc,IAAI;AAAA,MACtB,MAAM,WAAW,OAAO,OAAK,EAAE,cAAc,MAAM,EAAE,IAAI,OAAK,EAAE,EAAE;AAAA,IACpE;AACA,UAAM,OAAO,MAAM,gBAAgB;AAAA,MACjC,QAAM,YAAY,IAAI,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK,OAAK,EAAE,SAAS,MAAM;AAAA,IAC9E;AACA,WAAO,MAAM,QAAQ,KAAK,OAAK,EAAE,SAAS,MAAM,KAAK;AAAA,EACvD;AAEA,MAAI,CAAC,eAAe,MAAM,IAAI,UAAU,GAAG;AACzC,UAAM,IAAI;AAAA,MACR,8BAA8B,UAAU,mBAAmB,MAAM,EAAE;AAAA,IAErE;AAAA,EACF;AAEA,QAAM,MAAM,IAAI,OAAO;AACvB,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,WAAW,YAAY,GAAG,MAAM,IAAI,IAAI,UAAU,4BAAuB,CAAC,GAAG;AACxF,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,iBAAiB;AAC5B,QAAM,KAAK,cAAc;AAEzB,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAU,CAAC,SAAgC;AAC/C,UAAM,MAAM,IAAI,MAAM,KAAK,EAAE;AAC7B,QAAI,CAAC,SAAS,IAAI,GAAG,GAAG;AACtB,eAAS,IAAI,GAAG;AAChB,YAAM,KAAK,iBAAiB,GAAG,OAAO,YAAY,KAAK,IAAI,CAAC,QAAK,KAAK,aAAa,MAAG;AAAA,IACxF;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,QAAQ,KAAK;AAI5B,QAAM,OAAO,CAAC,MAAqB,QAAgB,OAAe,UAA6B;AAC7F,UAAM,MAAM,GAAG,KAAK,EAAE,IAAI,MAAM;AAChC,QAAI,MAAM,IAAI,GAAG,GAAG;AAClB,YAAM,KAAK,eAAe,IAAI,MAAM,KAAK,EAAE,CAAC,KAAK,YAAY,GAAG,MAAM,8BAAyB,CAAC,EAAE;AAClG;AAAA,IACF;AACA,UAAM,aAAa,eAAe,KAAK,IAAI,MAAM;AACjD,QAAI,CAAC,WAAY;AAEjB,UAAM,YAAY,IAAI,IAAI,KAAK;AAC/B,cAAU,IAAI,GAAG;AACjB,UAAM,SAAS,IAAI,MAAM,KAAK,EAAE;AAMhC,UAAM,cAAwB,CAAC;AAK/B,UAAM,eAAkE,CAAC;AACzE,UAAM,oBAAoB,CAAC,eAA6B;AACtD,aAAO,YAAY,UAAU,YAAY,YAAY,SAAS,CAAC,KAAK,YAAY;AAC9E,oBAAY,IAAI;AAChB,cAAM,KAAK,OAAO;AAAA,MACpB;AACA,aAAO,aAAa,UAAU,aAAa,aAAa,SAAS,CAAC,EAAE,OAAO,YAAY;AACrF,qBAAa,IAAI;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,QAAQ,CAAC,GAAG,WAAW,SAAS,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,UAAU;AAClF,eAAW,QAAQ,OAAO;AAGxB,iBAAW,OAAO,cAAc;AAC9B,cAAMC,OAAM,IAAI,UAAU,IAAI,KAAK,UAAU;AAC7C,YAAIA,SAAQ,OAAW,OAAM,KAAK,SAAS,YAAYA,IAAG,CAAC,EAAE;AAAA,MAC/D;AACA,cAAQ,KAAK,MAAM;AAAA,QACjB,KAAK;AACH,gBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,KAAK,aAAa,EAAE,CAAC,CAAC,EAAE;AAClF;AAAA,QACF,KAAK;AACH,gBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,aAAQ,KAAK,aAAa,KAAK,WAAW,GAAG,KAAK,gBAAgB,SAAY,4BAAkB,KAAK,WAAW,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;AAC3L;AAAA,QACF,KAAK;AACH,gBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,oBAAe,KAAK,MAAM,KAAK,WAAW,KAAK,KAAK,OAAO,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE;AACjJ;AAAA,QACF,KAAK;AACH,cAAI,KAAK,YAAY,QAAW;AAC9B,kBAAM,KAAK,UAAU,YAAY,SAAS,KAAK,QAAQ,KAAK,aAAa,KAAK,aAAa,EAAE,CAAC,CAAC,EAAE;AACjG,wBAAY,KAAK,KAAK,OAAO;AAAA,UAC/B,OAAO;AACL,kBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,UAAK,KAAK,WAAW,IAAI,EAAE,CAAC,CAAC,EAAE;AAAA,UAC3F;AACA;AAAA,QACF,KAAK;AACH,cAAI,KAAK,YAAY,QAAW;AAC9B,kBAAM,KAAK,cAAc,YAAY,SAAS,KAAK,aAAa,EAAE,CAAC,CAAC,EAAE;AACtE,wBAAY,KAAK,KAAK,OAAO;AAAA,UAC/B;AACA,qBAAW,KAAK,KAAK,WAAW,CAAC,GAAG;AAClC,kBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,aAAQ,EAAE,KAAK,gBAAW,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE;AAAA,UACtG;AACA;AAAA,QACF,KAAK,YAAY;AACf,gBAAM,OAAO,KAAK,YAAY,CAAC;AAC/B,cAAI,KAAK,YAAY,UAAa,KAAK,UAAU,GAAG;AAClD,kBAAM,OAAO,SAAS,KAAK,aAAa,EAAE,KAAK,KAAK,CAAC,EAAE,OAAO,WAAM,KAAK,CAAC,EAAE,IAAI,KAAK;AACrF,kBAAM,KAAK,SAAS,YAAY,IAAI,CAAC,EAAE;AACvC,kBAAM,YAAY,oBAAI,IAAoB;AAC1C,iBAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,GAAG,MAAM,UAAU,IAAI,EAAE,MAAM,EAAE,QAAQ,OAAO,IAAI,CAAC,EAAE,CAAC;AAC/E,yBAAa,KAAK,EAAE,KAAK,KAAK,SAAS,UAAU,CAAC;AAClD,wBAAY,KAAK,KAAK,OAAO;AAAA,UAC/B,OAAO;AACL,kBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,UAAK,KAAK,WAAW,IAAI,EAAE,CAAC,CAAC,EAAE;AAAA,UAC3F;AACA;AAAA,QACF;AAAA,QACA,KAAK;AACH,gBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,sBAAY,KAAK,MAAM,EAAE,CAAC,EAAE;AAC7E;AAAA,QACF,KAAK;AACH,gBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,gBAAW,KAAK,UAAU,WAAM,KAAK,OAAO,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;AACvH;AAAA,QACF,KAAK;AACH,gBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,SAAS,eAAU,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;AAChH;AAAA,QACF,KAAK,YAAY;AACf,cAAI,CAAC,KAAK,gBAAiB;AAC3B,gBAAM,SAAS,cAAc,IAAI,KAAK,eAAe;AACrD,cAAI,CAAC,QAAQ;AACX,kBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,2BAA2B,KAAK,eAAe,GAAG,CAAC,EAAE;AACtG;AAAA,UACF;AACA,gBAAM,WAAW,QAAQ,MAAM;AAG/B,gBAAM,KAAK,KAAK,SACZ,KAAK,MAAM,KAAK,QAAQ,KAAK,YAAY,SAAI,KAAK,cAAc,GAAG,QAAG,CAAC,qBACvE,KAAK,MAAM,MAAM,QAAQ,KAAK,YAAY,SAAI,KAAK,cAAc,GAAG,QAAG,CAAC,EAAE;AAI9E,gBAAM,UAAU,OAAO,UAAU,KAAK,OAAK,EAAE,eAAe,KAAK,UAAU;AAC3E,gBAAM,SAAS,UAAU,cAAc,IAAI,QAAQ,SAAS,IAAI;AAChE,cAAI,WAAW,QAAQ;AACrB,kBAAM,WAAW,QAAQ,MAAM;AAC/B,kBAAM,aAAa,QAAQ,YACtB,CAAC,CAAC,eAAe,OAAO,IAAI,QAAQ,MAAM,KAC1C,OAAO,OAAO,KAAK;AACxB,gBAAI,YAAY;AACd,oBAAM,KAAK,KAAK,QAAQ,OAAO,QAAQ,KAAK,YAAY,QAAQ,MAAM,CAAC,IAAI;AAC3E,mBAAK,QAAQ,QAAQ,QAAQ,QAAQ,GAAG,SAAS;AACjD,oBAAM,KAAK,KAAK,QAAQ,QAAQ,QAAQ,UAAU;AAAA,YACpD,OAAO;AACL,oBAAM,KAAK,KAAK,QAAQ,MAAM,QAAQ,KAAK,YAAY,QAAQ,MAAM,CAAC,IAAI;AAAA,YAC5E;AAAA,UACF;AACA;AAAA,QACF;AAAA,QACA,KAAK,QAAQ;AACX,cAAI,CAAC,KAAK,mBAAmB,CAAC,KAAK,aAAc;AACjD,gBAAM,SAAS,cAAc,IAAI,KAAK,eAAe;AACrD,cAAI,CAAC,QAAQ;AACX,kBAAM,KAAK,eAAe,MAAM,KAAK,YAAY,kBAAkB,KAAK,eAAe,GAAG,CAAC,EAAE;AAC7F;AAAA,UACF;AACA,gBAAM,WAAW,QAAQ,MAAM;AAC/B,gBAAM,aAAa,QAAQ,YACtB,CAAC,CAAC,eAAe,OAAO,IAAI,KAAK,YAAY,KAC7C,OAAO,OAAO,KAAK;AACxB,cAAI,KAAK,QAAQ;AAIf,kBAAM,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,YAAY,KAAK,YAAY,CAAC,oBAAe;AACrF,gBAAI,WAAY,MAAK,QAAQ,KAAK,cAAc,QAAQ,GAAG,SAAS;AAAA,UACtE,WAAW,YAAY;AACrB,kBAAM,KAAK,KAAK,MAAM,OAAO,QAAQ,KAAK,YAAY,KAAK,YAAY,CAAC,IAAI;AAC5E,iBAAK,QAAQ,KAAK,cAAc,QAAQ,GAAG,SAAS;AACpD,kBAAM,KAAK,KAAK,QAAQ,QAAQ,MAAM,UAAU;AAAA,UAClD,OAAO;AACL,kBAAM,KAAK,KAAK,MAAM,MAAM,QAAQ,KAAK,YAAY,KAAK,YAAY,CAAC,IAAI;AAAA,UAC7E;AACA;AAAA,QACF;AAAA,MACF;AACA,wBAAkB,KAAK,UAAU;AAAA,IACnC;AAEA,WAAO,YAAY,QAAQ;AAAE,kBAAY,IAAI;AAAG,YAAM,KAAK,OAAO;AAAA,IAAG;AAAA,EACvE;AAEA,QAAM,KAAK,eAAe,MAAM,KAAK,YAAY,GAAG,UAAU,IAAI,CAAC,EAAE;AACrE,OAAK,OAAO,YAAY,GAAG,oBAAI,IAAI,CAAC;AAEpC,SAAO,MAAM,KAAK,IAAI;AACxB;AAMO,SAAS,qBAAoC;AAClD,QAAM,QAAQ,cAAc;AAC5B,QAAM,QAAuB,CAAC;AAE9B,QAAM,KAAK;AAAA,IACT,SAAS;AAAA,IACT,OAAO,GAAG,MAAM,UAAU;AAAA,IAC1B,SAAS,yBAAyB;AAAA,EACpC,CAAC;AAED,aAAW,OAAO,MAAM,YAAY;AAClC,UAAM,gBAAgB,MAAM,WAAW;AAAA,MACrC,OAAK,EAAE,cAAc,IAAI,MAAM,EAAE,UAAU,WAAW,GAAG,IAAI,EAAE,IAAI;AAAA,IACrE;AACA,QAAI,CAAC,cAAe;AACpB,UAAM,KAAK;AAAA,MACT,SAAS,cAAc,IAAI,GAAG,QAAQ,OAAO,IAAI,CAAC;AAAA,MAClD,OAAO,GAAG,IAAI,IAAI;AAAA,MAClB,SAAS,yBAAyB,EAAE,WAAW,IAAI,GAAG,CAAC;AAAA,IACzD,CAAC;AAAA,EACH;AAGA,QAAM,QAAQ,MAAM,WAAW;AAAA,IAC7B,OAAK,EAAE,kBAAkB,YAAY,EAAE,kBAAkB,cAAc,MAAM,iBAAiB,IAAI,EAAE,EAAE;AAAA,EACxG;AACA,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,IAAI,KAAK,EAAE,EAAG;AACvB,SAAK,IAAI,KAAK,EAAE;AAChB,UAAM,cAAc,IAAI,IAAI,MAAM,WAAW,OAAO,OAAK,EAAE,cAAc,KAAK,EAAE,EAAE,IAAI,OAAK,EAAE,EAAE,CAAC;AAChG,UAAM,QAAQ,MAAM,gBAAgB,OAAO,QAAM,YAAY,IAAI,GAAG,QAAQ,CAAC;AAC7E,eAAW,QAAQ,OAAO;AACxB,iBAAW,KAAK,KAAK,SAAS;AAC5B,YAAI,CAAC,EAAE,UAAU,OAAQ;AACzB,cAAM,KAAK;AAAA,UACT,SAAS,aAAa,KAAK,GAAG,QAAQ,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI;AAAA,UAC5D,OAAO,GAAG,KAAK,IAAI,IAAI,EAAE,IAAI;AAAA,UAC7B,SAAS,wBAAwB,KAAK,IAAI,EAAE,IAAI;AAAA,QAClD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAGO,SAAS,WAAW,MAA2B;AACpD,SAAO,KAAK,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAAmH,KAAK,OAAO;AAAA;AAAA;AACvJ;AAGO,SAAS,gBAAgB,OAAsB,YAA4B;AAChF,QAAM,QAAkB,CAAC;AACzB,QAAM,KAAK,KAAK,UAAU,+BAA0B;AACpD,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,8FAAyF;AACpG,QAAM,KAAK,yFAAyF;AACpG,QAAM,KAAK,EAAE;AACb,aAAW,KAAK,OAAO;AACrB,UAAM,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,QAAQ,QAAQ,OAAO,GAAG,CAAC,GAAG;AAAA,EAC/D;AACA,QAAM,KAAK,EAAE;AACb,SAAO,MAAM,KAAK,IAAI;AACxB;AAxqBA,IAsNM,QA0DA;AAhRN;AAAA;AAAA;AAAA,IAAAC;AAOA;AAOA;AACA;AACA;AACA;AAqMA,IAAM,SAAN,MAAa;AAAA,MAAb;AACE,aAAQ,aAAa,oBAAI,IAAoB;AAC7C,aAAQ,QAAQ,oBAAI,IAAY;AAAA;AAAA,MAEhC,MAAM,UAA0B;AAC9B,cAAM,WAAW,KAAK,WAAW,IAAI,QAAQ;AAC7C,YAAI,SAAU,QAAO;AACrB,cAAM,OAAO,SAAS,QAAQ,kBAAkB,GAAG;AACnD,YAAI,YAAY;AAChB,YAAI,IAAI;AACR,eAAO,KAAK,MAAM,IAAI,SAAS,GAAG;AAChC,sBAAY,GAAG,IAAI,IAAI,GAAG;AAAA,QAC5B;AACA,aAAK,WAAW,IAAI,UAAU,SAAS;AACvC,aAAK,MAAM,IAAI,SAAS;AACxB,eAAO;AAAA,MACT;AAAA,IACF;AAyCA,IAAM,aAAa;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAAA;;;AC7NA,SAAS,aAAwB;AAC/B,SAAO;AAAA,IACL,YAAY,CAAC;AAAA,IACb,YAAY,CAAC;AAAA,IACb,YAAY,CAAC;AAAA,IACb,iBAAiB,CAAC;AAAA,IAClB,OAAO,CAAC;AAAA,IACR,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,MACL,WAAW,CAAC;AAAA,MACZ,WAAW,CAAC;AAAA,MACZ,WAAW,CAAC;AAAA,MACZ,gBAAgB,CAAC;AAAA,MACjB,MAAM,CAAC;AAAA,MACP,OAAO,CAAC;AAAA,IACV;AAAA,EACF;AACF;AAQA,SAAS,UAAU,IAAwB,QAAgB,gBAAyD;AAClH,MAAI,CAAC,GAAI,QAAO;AAChB,MAAI,GAAG,WAAW,IAAI,GAAG;AACvB,WAAO,GAAG,MAAM,CAAC;AAAA,EACnB;AACA,MAAI,GAAG,WAAW,SAAS,GAAG;AAC5B,UAAM,cAAc,OAAO,MAAM,IAAI;AACrC,UAAM,UAAU,GAAG,MAAM,IAAI;AAC7B,WAAO,QAAQ,CAAC,MAAM,SAAS;AAC7B,cAAQ,MAAM;AACd,kBAAY,IAAI;AAAA,IAClB;AACA,WAAO,CAAC,GAAG,aAAa,GAAG,OAAO,EAAE,KAAK,IAAI;AAAA,EAC/C;AACA,QAAM,eAAe,GAAG,MAAM,IAAI,EAAE,CAAC;AACrC,MAAI,eAAe,IAAI,YAAY,GAAG;AACpC,WAAO;AAAA,EACT;AACA,SAAO,SAAS,GAAG,MAAM,KAAK,EAAE,KAAK;AACvC;AAEO,SAAS,eAAe,aAA0D;AACvF,MAAI,CAAC,YAAY,SAAS,IAAI,GAAG;AAC/B,WAAO,EAAE,QAAQ,IAAI,SAAS,YAAY;AAAA,EAC5C;AACA,QAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,QAAM,UAAU,MAAM,IAAI;AAC1B,SAAO,EAAE,QAAQ,MAAM,KAAK,IAAI,GAAG,QAAQ;AAC7C;AAgBA,SAAS,aAAa,IAAY,QAAwB;AACxD,MAAI,GAAG,WAAW,IAAI,KAAK,GAAG,WAAW,SAAS,GAAG;AACnD,WAAO;AAAA,EACT;AAGA,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AACA,MAAI,GAAG,WAAW,GAAG,MAAM,IAAI,GAAG;AAChC,WAAO,GAAG,MAAM,OAAO,SAAS,CAAC;AAAA,EACnC;AAKA,MAAI,OAAO,QAAQ;AACjB,WAAO,GAAG,MAAM,IAAI,EAAE,IAAI;AAAA,EAC5B;AAWA,QAAM,cAAc,OAAO,MAAM,IAAI;AACrC,QAAM,UAAU,GAAG,MAAM,IAAI;AAC7B,MAAI,SAAS;AACb,SAAO,SAAS,YAAY,UAAU,SAAS,QAAQ,UAAU,YAAY,MAAM,MAAM,QAAQ,MAAM,GAAG;AACxG;AAAA,EACF;AAEA,MAAI,WAAW,QAAQ,OAAQ;AAC/B,SAAO,GAAG,UAAU,OAAO,YAAY,SAAS,MAAM,CAAC,GAAG,QAAQ,MAAM,MAAM,EAAE,KAAK,IAAI,CAAC;AAC5F;AAGA,SAAS,SAAS,KAAa,MAAuB;AACpD,QAAM,IAAS,eAAQ,GAAG;AAC1B,QAAM,IAAS,eAAQ,IAAI;AAC3B,SAAO,MAAM,KAAK,EAAE,WAAW,IAAS,UAAG;AAC7C;AAoBA,SAAS,uBACP,aACA,aACA,kBACS;AACT,SAAY,kBAAW,WAAW,KAAK,CAAC,SAAS,aAAa,gBAAgB;AAChF;AASO,SAAS,2BAA2B,aAAqB,aAA6B;AAC3F,QAAM,OAAY,eAAQ,WAAW;AACrC,QAAM,WAAgB,eAAQ,MAAM,WAAW;AAC/C,MAAI,uBAAuB,MAAM,aAAa,QAAQ,GAAG;AACvD,UAAM,IAAI;AAAA,MACR,gBAAgB,WAAW,2CAA2C,IAAI,uBACjE,QAAQ;AAAA,IAEnB;AAAA,EACF;AACA,SAAO;AACT;AAcO,SAAS,mBAAmB,WAAuE;AACxG,MAAI;AACJ,MAAI;AACF,oBAAqB,eAAQ,SAAS;AAAA,EACxC,QAAQ;AACN,WAAO;AAAA,EACT;AACA,MAAI,MAAW,eAAQ,aAAa;AACpC,WAAS,OAAO,GAAG,OAAO,IAAI,QAAQ;AACpC,UAAM,WAAW,UAAU,GAAG,EAAE,SAAS;AACzC,QAAI,WAAW,QAAQ,GAAG;AACxB,iBAAW,QAAQ,mBAAmB,UAAU,OAAO,GAAG;AACxD,YAAI;AACJ,YAAI;AACF,gBAAM,aAAa,IAAI;AAAA,QACzB,QAAQ;AACN;AAAA,QACF;AAEA,YAAI,OAAO,OAAO,QAAQ,YAAY,kBAAkB,KAAK;AAC3D,gBAAM,cAAe,IAAkC;AACvD,cAAI,OAAO,gBAAgB,YAAY,YAAY,KAAK,MAAM,IAAI;AAChE,gBAAI;AACF,kBAAS,eAAQ,KAAK,WAAW,MAAM,eAAe;AACpD,sBAAM,KAAM,IAAyB;AACrC,uBAAO,EAAE,YAAY,KAAK,aAAa,OAAO,OAAO,WAAW,KAAK,IAAI;AAAA,cAC3E;AAAA,YACF,QAAQ;AAAA,YAER;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,UAAM,KAAU,eAAQ,GAAG;AAC3B,QAAI,OAAO,IAAK;AAChB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAQA,SAAS,uBAAuB,MAAwC;AACtE,QAAM,SAA0B,CAAC;AACjC,QAAM,YAAY,oBAAI,IAAoB;AAC1C,aAAW,OAAO,MAAM;AACtB,UAAM,KAAK,UAAU,IAAI,IAAI,EAAE;AAC/B,QAAI,OAAO,QAAW;AACpB,gBAAU,IAAI,IAAI,IAAI,OAAO,MAAM;AACnC,aAAO,KAAK,GAAG;AACf;AAAA,IACF;AACA,UAAM,OAAO,OAAO,EAAE;AACtB,UAAM,eAAe,CAAC,CAAC,KAAK;AAC5B,UAAM,cAAc,CAAC,CAAC,IAAI;AAC1B,QAAI,iBAAiB,aAAa;AAChC,YAAM,QAAQ,eAAe,OAAO;AACpC,YAAM,QAAQ,eAAe,MAAM;AACnC,aAAO,EAAE,IAAI,EAAE,GAAG,OAAO,aAAa,MAAM,YAAY;AAAA,IAC1D,OAAO;AACL,aAAO,KAAK,GAAG;AAAA,IACjB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,4BAA4B,MAAqB,QAA+B;AAUvF,QAAM,eAAe,KAAK,cAAc,KAAK,KAAK;AAClD,QAAM,YAAY,CAAC,OAAwB,GAAG,SAAS,IAAI,IAAI,aAAa,IAAI,YAAY,IAAI;AAChG,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,aAAa,KAAK,IAAI,MAAM;AAAA,IAChC,kBAAkB,KAAK,iBAAiB,IAAI,SAAO;AAAA,MACjD,GAAG;AAAA,MACH,WAAW,GAAG,YAAY,UAAU,GAAG,SAAS,IAAI;AAAA,MACpD,WAAW,GAAG,YAAY,UAAU,GAAG,SAAS,IAAI;AAAA,IACtD,EAAE;AAAA,IACF,WAAW,KAAK,WAAW,IAAI,SAAO;AAAA,MACpC,GAAG;AAAA,MACH,WAAW,UAAU,GAAG,SAAS;AAAA,IACnC,EAAE;AAAA,EACJ;AACF;AAEA,SAAS,4BAA4B,MAAqB,QAA+B;AACvF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,aAAa,KAAK,IAAI,MAAM;AAAA,IAChC,WAAW,aAAa,KAAK,WAAW,MAAM;AAAA,IAC9C,MAAM,KAAK,KAAK,IAAI,OAAK,aAAa,GAAG,MAAM,CAAC;AAAA,IAChD,WAAW,KAAK,UAAU,IAAI,OAAK,aAAa,GAAG,MAAM,CAAC;AAAA,IAC1D,UAAU,KAAK,UAAU,IAAI,QAAM;AAAA,MACjC,GAAG;AAAA,MACH,WAAW,aAAa,EAAE,WAAW,MAAM;AAAA,IAC7C,EAAE;AAAA,EACJ;AACF;AAEA,SAAS,4BAA4B,MAAqB,QAA+B;AACvF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,aAAa,KAAK,IAAI,MAAM;AAAA,IAChC,WAAW,aAAa,KAAK,WAAW,MAAM;AAAA,EAChD;AACF;AAEA,SAAS,iCAAiC,MAA0B,QAAoC;AACtG,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,aAAa,KAAK,IAAI,MAAM;AAAA,IAChC,UAAU,aAAa,KAAK,UAAU,MAAM;AAAA,IAC5C,SAAS,KAAK,QAAQ,IAAI,QAAM;AAAA,MAC9B,GAAG;AAAA,MACH,WAAW,EAAE,UAAU,IAAI,WAAS;AAAA,QAClC,GAAG;AAAA,QACH,iBAAiB,KAAK,kBAAkB,aAAa,KAAK,iBAAiB,MAAM,IAAI;AAAA,MACvF,EAAE;AAAA,IACJ,EAAE;AAAA,EACJ;AACF;AAEA,SAAS,uBAAuB,MAAgB,QAA0B;AACxE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,aAAa,KAAK,IAAI,MAAM;AAAA,IAChC,WAAW,KAAK,YAAY,aAAa,KAAK,WAAW,MAAM,IAAI;AAAA,EACrE;AACF;AAEA,SAAS,wBAAwB,MAAiB,QAA2B;AAC3E,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,aAAa,KAAK,IAAI,MAAM;AAAA,EAClC;AACF;AAYA,SAAS,UAAU,IAAY,YAAmD;AAChF,QAAM,EAAE,QAAQ,IAAI,eAAe,EAAE;AACrC,SAAO,WAAW,KAAK,CAAC,MAAM;AAC5B,UAAM,EAAE,SAAS,SAAS,IAAI,eAAe,EAAE,EAAE;AACjD,QAAI,aAAa,QAAS,QAAO;AACjC,YAAQ,EAAE,QAAQ,CAAC,GAAG,KAAK,aAAW;AACpC,YAAM,EAAE,SAAS,aAAa,IAAI,eAAe,OAAO;AACxD,aAAO,iBAAiB;AAAA,IAC1B,CAAC;AAAA,EACH,CAAC,KAAK;AACR;AAEA,SAAS,oBAAoB,SAAiB,OAAwB;AACpE,MAAS,iBAAU,OAAO,MAAW,iBAAU,KAAK,EAAG,QAAO;AAC9D,MAAI,CAAI,eAAW,OAAO,KAAQ,eAAW,KAAK,EAAG,QAAO;AAC5D,YAAe,eAAQ,KAAK,CAAC;AAC7B,EAAG,eAAW,SAAS,KAAK;AAC5B,SAAO;AACT;AAGA,SAAS,eAAe,UAAkB,WAAyB;AACjE,MAAI,MAAW,eAAQ,QAAQ;AAC/B,SAAO,QAAQ,aAAa,IAAI,WAAW,SAAS,GAAG;AACrD,QAAO,eAAW,GAAG,KAAQ,gBAAY,GAAG,EAAE,WAAW,GAAG;AAC1D,MAAG,cAAU,GAAG;AAChB,YAAW,eAAQ,GAAG;AAAA,IACxB,OAAO;AACL;AAAA,IACF;AAAA,EACF;AACF;AASA,SAAS,gBAAgB,OAA2B;AAClD,SAAO,MAAM,OAAO,IAAI,OAAK,GAAG,EAAE,KAAK,KAAK,GAAG,KAAK,QAAQ,KAAK,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI;AACzF;AAEA,SAAS,aAAqC,QAAW,OAAgB,MAAc,IAAwB;AAC7G,QAAM,MAAM,OAAO,UAAU,KAAK;AAClC,MAAI,CAAC,IAAI,SAAS;AAChB,UAAM,IAAI,MAAM,6BAA6B,IAAI,UAAU,EAAE,MAAM,gBAAgB,IAAI,KAAK,CAAC,EAAE;AAAA,EACjG;AACA,SAAO,IAAI;AACb;AAMA,SAAS,yBAAyB,MAAwB;AACxD,QAAM,QAAkB,CAAC;AACzB,aAAW,OAAO,MAAM;AACtB,QAAI,CAAI,eAAW,GAAG,GAAG;AACvB,YAAM,KAAK,GAAG,GAAG,UAAU;AAC3B;AAAA,IACF;AACA,eAAW,KAAK,mBAAmB,KAAK,OAAO,GAAG;AAChD,UAAI;AACF,cAAM,KAAQ,aAAS,CAAC;AACxB,cAAM,KAAK,GAAG,CAAC,IAAI,GAAG,OAAO,IAAI,GAAG,IAAI,EAAE;AAAA,MAC5C,QAAQ;AACN,cAAM,KAAK,GAAG,CAAC,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACA,SAAO,MAAM,KAAK,GAAG;AACvB;AAuvDO,SAAS,aAAa,SAAgC;AAC3D,QAAM,MAAW,eAAQ,OAAO;AAChC,MAAI,KAAK,WAAW,IAAI,GAAG;AAC3B,MAAI,CAAC,IAAI;AACP,SAAK,IAAI,cAAc,GAAG;AAC1B,eAAW,IAAI,KAAK,EAAE;AAAA,EACxB;AACA,SAAO;AACT;AAGA,SAAS,UAAyB;AAChC,SAAO,aAAa,eAAe,CAAC;AACtC;AASO,SAAS,sBAA4B;AAM1C,aAAW,MAAM,WAAW,OAAO,EAAG,IAAG,WAAW;AACtD;AAEO,SAAS,kBAAqC;AACnD,SAAO,QAAQ,EAAE;AACnB;AAEO,SAAS,oBAA0B;AACxC,UAAQ,EAAE,eAAe,CAAC;AAC1B,sBAAoB;AACtB;AAEO,SAAS,aAAa,SAAuD;AAClF,SAAO,QAAQ,EAAE,QAAQ,OAAO;AAClC;AAEO,SAAS,8BAA8B,WAAkC;AAC9E,SAAO,QAAQ,EAAE,8BAA8B,SAAS;AAC1D;AAEO,SAAS,oBAAoB,aAAoC;AACtE,SAAO,QAAQ,EAAE,oBAAoB,WAAW;AAClD;AAEO,SAAS,iBAAiB,IAAoB;AACnD,SAAO,QAAQ,EAAE,iBAAiB,EAAE;AACtC;AAEO,SAAS,iBAAiB,IAAY,aAA8B;AACzE,SAAO,QAAQ,EAAE,iBAAiB,IAAI,WAAW;AACnD;AAEO,SAAS,iBAAiB,IAAY,aAA8B;AACzE,SAAO,QAAQ,EAAE,iBAAiB,IAAI,WAAW;AACnD;AAEO,SAAS,sBAAsB,IAAY,YAA6B;AAC7E,SAAO,QAAQ,EAAE,sBAAsB,IAAI,UAAU;AACvD;AAEO,SAAS,YAAY,IAAY,aAAsB,OAAwB;AACpF,SAAO,QAAQ,EAAE,YAAY,IAAI,aAAa,KAAK;AACrD;AAEO,SAAS,aAAa,IAAY,aAA8B;AACrE,SAAO,QAAQ,EAAE,aAAa,IAAI,WAAW;AAC/C;AAEO,SAAS,iBAAoC;AAClD,SAAO,QAAQ,EAAE,eAAe;AAClC;AAEO,SAAS,eAAe,MAAwB;AACrD,UAAQ,EAAE,eAAe,IAAI;AAC/B;AAEO,SAAS,qBAAsC;AACpD,SAAO,QAAQ,EAAE,mBAAmB;AACtC;AAEO,SAAS,kBAAkB,IAAkC;AAClE,SAAO,QAAQ,EAAE,kBAAkB,EAAE;AACvC;AAEO,SAAS,kBAAkB,MAA2B;AAC3D,UAAQ,EAAE,kBAAkB,IAAI;AAClC;AAEO,SAAS,oBAAoB,IAAqB;AACvD,SAAO,QAAQ,EAAE,oBAAoB,EAAE;AACzC;AAEO,SAAS,qBAAsC;AACpD,SAAO,QAAQ,EAAE,mBAAmB;AACtC;AAEO,SAAS,kBAAkB,IAAkC;AAClE,SAAO,QAAQ,EAAE,kBAAkB,EAAE;AACvC;AAEO,SAAS,kBAAkB,MAAqB,MAAkC;AACvF,SAAO,QAAQ,EAAE,kBAAkB,MAAM,IAAI;AAC/C;AAEO,SAAS,oBAAoB,IAAqB;AACvD,SAAO,QAAQ,EAAE,oBAAoB,EAAE;AACzC;AAEO,SAAS,2BAAqC;AACnD,SAAO,QAAQ,EAAE,yBAAyB;AAC5C;AAEO,SAAS,qBAAsC;AACpD,SAAO,QAAQ,EAAE,mBAAmB;AACtC;AAEO,SAAS,kBAAkB,IAAkC;AAClE,SAAO,QAAQ,EAAE,kBAAkB,EAAE;AACvC;AAEO,SAAS,kBAAkB,MAAqB,MAAkC;AACvF,SAAO,QAAQ,EAAE,kBAAkB,MAAM,IAAI;AAC/C;AAEO,SAAS,oBAAoB,IAAqB;AACvD,SAAO,QAAQ,EAAE,oBAAoB,EAAE;AACzC;AAEO,SAAS,0BAAgD;AAC9D,SAAO,QAAQ,EAAE,wBAAwB;AAC3C;AAEO,SAAS,uBAAuB,IAAuC;AAC5E,SAAO,QAAQ,EAAE,uBAAuB,EAAE;AAC5C;AAEO,SAAS,uBAAuB,MAA0B,MAAkC;AACjG,SAAO,QAAQ,EAAE,uBAAuB,MAAM,IAAI;AACpD;AAEO,SAAS,yBAAyB,IAAqB;AAC5D,SAAO,QAAQ,EAAE,yBAAyB,EAAE;AAC9C;AAEO,SAAS,gBAA4B;AAC1C,SAAO,QAAQ,EAAE,cAAc;AACjC;AAEO,SAAS,aAAa,IAA6B;AACxD,SAAO,QAAQ,EAAE,aAAa,EAAE;AAClC;AAEO,SAAS,aAAa,MAA0B;AACrD,SAAO,QAAQ,EAAE,aAAa,IAAI;AACpC;AAEO,SAAS,qBAAqB,SAA0D;AAC7F,SAAO,QAAQ,EAAE,qBAAqB,OAAO;AAC/C;AAKO,SAAS,kBAAkB,OAA8B;AAC9D,SAAO,gBAAgB,KAAK;AAC9B;AAEO,SAAS,eAAe,IAAqB;AAClD,SAAO,QAAQ,EAAE,eAAe,EAAE;AACpC;AAEO,SAAS,iBAA8B;AAC5C,SAAO,QAAQ,EAAE,eAAe;AAClC;AAEO,SAAS,cAAc,IAA8B;AAC1D,SAAO,QAAQ,EAAE,cAAc,EAAE;AACnC;AAEO,SAAS,cAAc,MAAuB;AACnD,UAAQ,EAAE,cAAc,IAAI;AAC9B;AAEO,SAAS,gBAAgB,IAAqB;AACnD,SAAO,QAAQ,EAAE,gBAAgB,EAAE;AACrC;AAEO,SAAS,uBAAuB,gBAA2C;AAChF,SAAO,QAAQ,EAAE,uBAAuB,cAAc;AACxD;AAEO,SAAS,gBAAgB,MAAgB,IAAY,QAA0B;AACpF,UAAQ,EAAE,gBAAgB,MAAM,IAAI,MAAM;AAC5C;AAEO,SAAS,oBAAyC;AACvD,SAAO,QAAQ,EAAE,kBAAkB;AACrC;AAGO,SAAS,iBAAiB,UAAqC;AACpE,aAAW,CAAC,MAAM,OAAO,KAAK,UAAU;AACtC,IAAG,kBAAc,MAAM,OAAO;AAAA,EAChC;AACF;AAEO,SAAS,sBAA4D;AAC1E,SAAO,QAAQ,EAAE,oBAAoB;AACvC;AAEO,SAAS,WACd,MACA,IACA,OACU;AACV,SAAO,QAAQ,EAAE,WAAW,MAAM,IAAI,KAAK;AAC7C;AAx6EA,IAAAC,KACAC,QA6bM,kBAiDO,eAstDP;AArsEN,IAAAC,cAAA;AAAA;AAAA;AAAA,IAAAF,MAAoB;AACpB,IAAAC,SAAsB;AAEtB;AACA;AACA;AACA;AAkBA;AACA;AAqaA,IAAM,mBAAmB;AAiDlB,IAAM,gBAAN,MAAoB;AAAA,MAazB,YAAY,SAAiB;AAT7B,aAAQ,cAAgC;AACxC,aAAQ,kBAA2C;AACnD,aAAQ,iBAA2B,CAAC;AACpC,aAAQ,kBAAiC;AACzC,aAAQ,uBAAuB;AAC/B,aAAQ,iBAAiB,oBAAI,IAAY;AACzC,aAAQ,sBAAgC,CAAC;AACzC,4BAAkC,CAAC;AAGjC,aAAK,UAAe,eAAQ,OAAO;AACnC,aAAK,QAAQ,UAAU,KAAK,OAAO;AAAA,MACrC;AAAA,MAEA,aAAmB;AACjB,aAAK,cAAc;AACnB,aAAK,kBAAkB;AACvB,aAAK,iBAAiB,CAAC;AACvB,aAAK,kBAAkB;AACvB,aAAK,uBAAuB;AAC5B,aAAK,eAAe,MAAM;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAMA,QAAQ,SAAuD;AAC7D,cAAM,YAAY,SAAS,aAAa;AACxC,YAAI,KAAK,eAAe,KAAK,oBAAoB,WAAW;AAI1D,gBAAM,MAAM,KAAK,IAAI;AACrB,cAAI,MAAM,KAAK,wBAAwB,iBAAkB,QAAO,KAAK;AACrE,eAAK,uBAAuB;AAC5B,cAAI,yBAAyB,KAAK,cAAc,MAAM,KAAK,gBAAiB,QAAO,KAAK;AACxF,eAAK,WAAW;AAAA,QAClB;AAEA,aAAK,eAAe,CAAC;AACrB,aAAK,eAAe,MAAM;AAC1B,aAAK,kBAAkB;AACvB,aAAK,sBAAsB,CAAC;AAC5B,cAAM,UAAU,oBAAI,IAAY,CAAM,eAAQ,KAAK,OAAO,CAAC,CAAC;AAE5D,cAAM,WAAW,OAAO,cAAc,WAAW,YAAa,YAAY,WAAW;AACrF,aAAK,cAAc,KAAK,oBAAoB,KAAK,SAAS,IAAI,SAAS,UAAU,CAAC;AAClF,aAAK,iBAAiB,KAAK;AAC3B,aAAK,kBAAkB,yBAAyB,KAAK,cAAc;AACnE,aAAK,uBAAuB,KAAK,IAAI;AACrC,eAAO,KAAK;AAAA,MACd;AAAA,MAEQ,oBACN,YACA,iBACA,aACA,UACA,cACW;AACX,cAAM,QAAQ,WAAW;AACzB,cAAM,eAAe,UAAU,UAAU;AAEzC,cAAM,WAAW,aAAa,SAAS;AAGvC,aAAK,oBAAoB,KAAK,QAAQ;AACtC,YAAI,CAAC,WAAW,QAAQ,EAAG,QAAO;AAElC,cAAM,QAAQ,mBAAmB,UAAU,OAAO;AAClD,cAAM,aAAkB,iBAAU,aAAa,YAAY,CAAC;AAE5D,cAAM,mBAAmE,CAAC;AAE1E,mBAAW,QAAQ,OAAO;AACxB,gBAAM,WAAgB,iBAAU,IAAI;AACpC,cAAI,aAAa,WAAY;AAE7B,cAAI,eAAe;AACnB,cAAI;AACF,kBAAM,MAAM,aAAa,IAAI;AAC7B,gBAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,mBAAK,aAAa,KAAK;AAAA,gBACrB,UAAU;AAAA,gBACV,MAAM;AAAA,gBACN,SAAS,cAAc,IAAI;AAAA,gBAC3B,QAAa,gBAAS,MAAM,OAAO;AAAA,cACrC,CAAC;AACD;AAAA,YACF;AAEA,gBAAI,kBAAkB,KAAK;AACzB,6BAAe;AACf,oBAAM,SAAS,oBAAoB,MAAM,GAAG;AAC5C,kBAAI,iBAAiB,GAAG;AACtB,qBAAK,eAAe,IAAI,OAAO,EAAE;AAAA,cACnC;AACA,kBAAI,OAAO,aAAa;AACtB,iCAAiB,KAAK;AAAA,kBACpB,aAAa,OAAO;AAAA,kBACpB,aAAa,OAAO;AAAA,gBACtB,CAAC;AAAA,cACH;AACA,oBAAM,WAAW,KAAK,MAAM;AAC5B,oBAAM,MAAM,UAAU,OAAO,EAAE,IAAI;AAAA,YACrC,WAAW,mBAAmB,KAAK;AACjC,6BAAe;AACf,oBAAM,SAAS,oBAAoB,MAAM,GAAG;AAC5C,oBAAM,WAAW,KAAK,MAAM;AAC5B,oBAAM,MAAM,UAAU,OAAO,EAAE,IAAI;AAAA,YACrC,WAAW,eAAe,KAAK;AAC7B,6BAAe;AACf,oBAAM,SAAS,oBAAoB,MAAM,GAAG;AAC5C,oBAAM,WAAW,KAAK,MAAM;AAC5B,oBAAM,MAAM,UAAU,OAAO,EAAE,IAAI;AAAA,YACrC,WAAW,cAAc,KAAK;AAC5B,6BAAe;AACf,oBAAM,SAAS,yBAAyB,MAAM,GAAG;AACjD,kBAAI,OAAO,YAAY;AACrB,sBAAM,gBAAqB,eAAQ,YAAY,OAAO,UAAU;AAChE,uBAAO,aAAkB,gBAAS,YAAY,aAAa,EAAE,QAAQ,OAAO,GAAG;AAAA,cACjF;AACA,oBAAM,gBAAgB,KAAK,MAAM;AACjC,oBAAM,MAAM,eAAe,OAAO,EAAE,IAAI;AAAA,YAC1C,WAAW,UAAU,KAAK;AACxB,kBAAI,IAAI,SAAS,SAAS;AACxB,+BAAe;AACf,sBAAM,SAAS,gBAAgB,MAAM,GAAG;AACxC,sBAAM,OAAO,KAAK,MAAM;AACxB,sBAAM,MAAM,MAAM,OAAO,EAAE,IAAI;AAAA,cACjC,OAAO;AACL,+BAAe;AACf,sBAAM,SAAS,eAAe,MAAM,GAAG;AACvC,sBAAM,MAAM,KAAK,MAAM;AACvB,sBAAM,MAAM,KAAK,OAAO,EAAE,IAAI;AAAA,cAChC;AAAA,YACF;AAEA,gBAAI,iBAAiB,QAAQ;AAC3B,mBAAK,aAAa,KAAK;AAAA,gBACrB,UAAU;AAAA,gBACV,MAAM;AAAA,gBACN,SAAS,cAAc,IAAI;AAAA,gBAC3B,QAAa,gBAAS,MAAM,OAAO;AAAA,cACrC,CAAC;AAAA,YACH;AAAA,UACF,SAAS,GAAQ;AACf,kBAAM,WAAgB,gBAAS,MAAM,OAAO;AAC5C,iBAAK,aAAa,KAAK;AAAA,cACrB,UAAU;AAAA,cACV,MAAM;AAAA,cACN,SAAS,mBAAmB,YAAY,UAAU,IAAI,MAAM,EAAE,WAAW,OAAO,CAAC,CAAC;AAAA,cAClF,QAAQ;AAAA,YACV,CAAC;AAAA,UACH;AAAA,QACF;AAGA,cAAM,aAAa,MAAM,WAAW,IAAI,SAAO;AAC7C,gBAAM,iBAAiB,kBAAkB,UAAU,IAAI,IAAI,iBAAiB,KAAK,cAAc,IAAI,IAAI;AACvG,gBAAM,kBAAkB,IAAI,cAAc,iBAAiB;AAC3D,iBAAO;AAAA,YACL,GAAG;AAAA,YACH,IAAI;AAAA,YACJ,kBAAkB,IAAI,iBAAiB,IAAI,QAAM;AAAA,cAC/C,GAAG;AAAA,cACH,WAAW,EAAE,YAAY,UAAU,EAAE,WAAW,iBAAiB,KAAK,cAAc,IAAI;AAAA,cACxF,WAAW,EAAE,YAAY,UAAU,EAAE,WAAW,iBAAiB,KAAK,cAAc,IAAI;AAAA,YAC1F,EAAE;AAAA,YACF,WAAW,IAAI,WAAW,IAAI,SAAO;AAAA,cACnC,GAAG;AAAA,cACH,WAAW,UAAU,GAAG,WAAW,iBAAiB,KAAK,cAAc;AAAA,YACzE,EAAE;AAAA,UACJ;AAAA,QACF,CAAC;AAED,cAAM,yBAAyB,MAAM,MAAM;AAC3C,cAAM,MAAM,YAAY,CAAC;AACzB,mBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,sBAAsB,GAAG;AAC3D,gBAAM,aAAa,kBAAkB,UAAU,GAAG,iBAAiB,KAAK,cAAc,IAAI;AAC1F,gBAAM,MAAM,UAAU,UAAU,IAAI;AAAA,QACtC;AAEA,YAAI,iBAAiB;AACnB,gBAAM,aAAa,MAAM,WAAW,IAAI,WAAS;AAAA,YAC/C,GAAG;AAAA,YACH,IAAI,UAAU,KAAK,IAAI,iBAAiB,KAAK,cAAc;AAAA,YAC3D,WAAW,UAAU,KAAK,WAAW,iBAAiB,KAAK,cAAc;AAAA,YACzE,MAAM,KAAK,KAAK,IAAI,OAAK,UAAU,GAAG,iBAAiB,KAAK,cAAc,CAAC;AAAA,YAC3E,WAAW,KAAK,UAAU,IAAI,OAAK,UAAU,GAAG,iBAAiB,KAAK,cAAc,CAAC;AAAA,YACrF,UAAU,KAAK,UAAU,IAAI,QAAM;AAAA,cACjC,GAAG;AAAA,cACH,WAAW,UAAU,EAAE,WAAW,iBAAiB,KAAK,cAAc;AAAA,YACxE,EAAE;AAAA,UACJ,EAAE;AAEF,gBAAM,aAAa,MAAM,WAAW,IAAI,WAAS;AAAA,YAC/C,GAAG;AAAA,YACH,IAAI,UAAU,KAAK,IAAI,iBAAiB,KAAK,cAAc;AAAA,YAC3D,WAAW,UAAU,KAAK,WAAW,iBAAiB,KAAK,cAAc;AAAA,UAC3E,EAAE;AAEF,gBAAM,kBAAkB,MAAM,gBAAgB,IAAI,WAAS;AAAA,YACzD,GAAG;AAAA,YACH,IAAI,UAAU,KAAK,IAAI,iBAAiB,KAAK,cAAc;AAAA,YAC3D,UAAU,UAAU,KAAK,UAAU,iBAAiB,KAAK,cAAc;AAAA,YACvE,SAAS,KAAK,QAAQ,IAAI,QAAM;AAAA,cAC9B,GAAG;AAAA,cACH,WAAW,EAAE,UAAU,IAAI,WAAS;AAAA,gBAClC,GAAG;AAAA,gBACH,iBAAiB,KAAK,kBAAkB,UAAU,KAAK,iBAAiB,iBAAiB,KAAK,cAAc,IAAI;AAAA,cAClH,EAAE;AAAA,YACJ,EAAE;AAAA,UACJ,EAAE;AAEF,gBAAM,QAAQ,MAAM,MAAM,IAAI,QAAM;AAAA,YAClC,GAAG;AAAA,YACH,IAAI,UAAU,EAAE,IAAI,iBAAiB,KAAK,cAAc;AAAA,YACxD,WAAW,EAAE,YAAY,UAAU,EAAE,WAAW,iBAAiB,KAAK,cAAc,IAAI;AAAA,YACxF,OAAO,EAAE,QAAQ,UAAU,EAAE,OAAO,iBAAiB,KAAK,cAAc,IAAI;AAAA,UAC9E,EAAE;AAEF,gBAAM,SAAS,MAAM,OAAO,IAAI,QAAM;AAAA,YACpC,GAAG;AAAA,YACH,IAAI,UAAU,EAAE,IAAI,iBAAiB,KAAK,cAAc;AAAA,UAC1D,EAAE;AAEF,gBAAM,gBAAgB,MAAM;AAC5B,gBAAM,QAAQ;AAAA,YACZ,WAAW,MAAM,MAAM;AAAA,YACvB,WAAW,CAAC;AAAA,YACZ,WAAW,CAAC;AAAA,YACZ,gBAAgB,CAAC;AAAA,YACjB,MAAM,CAAC;AAAA,YACP,OAAO,CAAC;AAAA,UACV;AAEA,qBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,cAAc,SAAS,GAAG;AAC5D,kBAAM,MAAM,UAAU,UAAU,GAAG,iBAAiB,KAAK,cAAc,CAAC,IAAI;AAAA,UAC9E;AACA,qBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,cAAc,SAAS,GAAG;AAC5D,kBAAM,MAAM,UAAU,UAAU,GAAG,iBAAiB,KAAK,cAAc,CAAC,IAAI;AAAA,UAC9E;AACA,qBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,cAAc,cAAc,GAAG;AACjE,kBAAM,MAAM,eAAe,UAAU,GAAG,iBAAiB,KAAK,cAAc,CAAC,IAAI;AAAA,UACnF;AACA,qBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,cAAc,IAAI,GAAG;AACvD,kBAAM,MAAM,KAAK,UAAU,GAAG,iBAAiB,KAAK,cAAc,CAAC,IAAI;AAAA,UACzE;AACA,qBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,cAAc,KAAK,GAAG;AACxD,kBAAM,MAAM,MAAM,UAAU,GAAG,iBAAiB,KAAK,cAAc,CAAC,IAAI;AAAA,UAC1E;AAAA,QACF;AAEA,YAAI,eAAe,UAAU;AAC3B,qBAAW,WAAW,kBAAkB;AACtC,kBAAM,WAAgB,eAAQ,YAAY,QAAQ,WAAW;AAQ7D,gBAAI,uBAAuB,KAAK,SAAS,QAAQ,aAAa,QAAQ,GAAG;AACvE,mBAAK,aAAa,KAAK;AAAA,gBACrB,UAAU;AAAA,gBACV,MAAM;AAAA,gBACN,SAAS,oBAAoB,QAAQ,WAAW,4BAA4B,QAAQ,WAAW,+BAA+B,KAAK,OAAO,mBAAmB,QAAQ;AAAA,gBACrK,QAAQ,QAAQ;AAAA,cAClB,CAAC;AACD;AAAA,YACF;AAEA,gBAAI,YAAY,IAAI,QAAQ,GAAG;AAC7B,mBAAK,aAAa,KAAK;AAAA,gBACrB,UAAU;AAAA,gBACV,MAAM;AAAA,gBACN,SAAS,2CAA2C,QAAQ,WAAW,2BAA2B,QAAQ;AAAA,gBAC1G,QAAQ,QAAQ;AAAA,cAClB,CAAC;AACD;AAAA,YACF;AAEA,gBAAI,CAAI,eAAW,QAAQ,GAAG;AAC5B,mBAAK,aAAa,KAAK;AAAA,gBACrB,UAAU;AAAA,gBACV,MAAM;AAAA,gBACN,SAAS,yBAAyB,QAAQ,4BAA4B,QAAQ,WAAW;AAAA,gBACzF,QAAQ,QAAQ;AAAA,cAClB,CAAC;AACD;AAAA,YACF;AAEA,kBAAM,iBAAiB,kBACnB,GAAG,eAAe,KAAK,QAAQ,WAAW,KAC1C,QAAQ;AAEZ,kBAAM,aAAa,IAAI,IAAI,WAAW;AACtC,uBAAW,IAAI,QAAQ;AAEvB,kBAAM,aAAa,KAAK,oBAAoB,UAAU,gBAAgB,YAAY,UAAU,eAAe,CAAC;AAE5G,kBAAM,WAAW,KAAK,GAAG,WAAW,UAAU;AAC9C,kBAAM,WAAW,KAAK,GAAG,WAAW,UAAU;AAC9C,kBAAM,WAAW,KAAK,GAAG,WAAW,UAAU;AAC9C,kBAAM,gBAAgB,KAAK,GAAG,WAAW,eAAe;AACxD,kBAAM,MAAM,KAAK,GAAG,WAAW,KAAK;AACpC,kBAAM,OAAO,KAAK,GAAG,WAAW,MAAM;AAEtC,mBAAO,OAAO,MAAM,MAAM,WAAW,WAAW,MAAM,SAAS;AAC/D,mBAAO,OAAO,MAAM,MAAM,WAAW,WAAW,MAAM,SAAS;AAC/D,mBAAO,OAAO,MAAM,MAAM,WAAW,WAAW,MAAM,SAAS;AAC/D,mBAAO,OAAO,MAAM,MAAM,gBAAgB,WAAW,MAAM,cAAc;AACzE,mBAAO,OAAO,MAAM,MAAM,MAAM,WAAW,MAAM,IAAI;AACrD,mBAAO,OAAO,MAAM,MAAM,OAAO,WAAW,MAAM,KAAK;AAAA,UACzD;AAAA,QACF;AAMA,cAAM,aAAa,uBAAuB,MAAM,UAAU;AAE1D,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,8BAA8B,WAAkC;AAC9D,cAAM,QAAQ,UAAU,MAAM,IAAI;AAClC,YAAI,aAAa,KAAK;AACtB,YAAI,cAAc;AAClB,YAAI,gBAAgB;AACpB,mBAAW,QAAQ,OAAO;AACxB,0BAAgB,gBAAgB,GAAG,aAAa,KAAK,IAAI,KAAK;AAC9D,gBAAM,QAAQ,KAAK,QAAQ;AAC3B,gBAAM,MAAM,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,aAAa;AAC/D,cAAI,OAAO,IAAI,aAAa;AAC1B,kBAAM,UAAe,eAAQ,YAAY,IAAI,WAAW;AAKxD,gBAAI,uBAAuB,KAAK,SAAS,IAAI,aAAa,OAAO,GAAG;AAClE,mBAAK,aAAa,KAAK;AAAA,gBACrB,UAAU;AAAA,gBACV,MAAM;AAAA,gBACN,SAAS,oBAAoB,IAAI,WAAW,4BAA4B,aAAa,+BAA+B,KAAK,OAAO,mBAAmB,OAAO;AAAA,gBAC1J,QAAQ;AAAA,cACV,CAAC;AACD;AAAA,YACF;AACA,yBAAa;AACb,0BAAc;AAAA,UAChB;AAAA,QACF;AACA,eAAO,cAAc,aAAa;AAAA,MACpC;AAAA,MAEA,oBAAoB,aAAoC;AACtD,cAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,YAAI,MAAM,UAAU,EAAG,QAAO;AAC9B,cAAM,QAAQ,KAAK,QAAQ;AAM3B,YAAI,UAAyB;AAC7B,YAAI,gBAAgB;AACpB,iBAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,0BAAgB,gBAAgB,GAAG,aAAa,KAAK,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC;AACzE,gBAAM,MAAM,MAAM,WAAW,KAAK,OAAK,EAAE,OAAO,aAAa;AAC7D,cAAI,OAAO,IAAI,aAAa;AAC1B,sBAAU;AAAA,UACZ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,iBAAiB,IAAoB;AACnC,cAAM,QAAQ,KAAK,QAAQ;AAC3B,YAAI,MAAM,MAAM,UAAU,EAAE,GAAG;AAC7B,iBAAO,MAAM,MAAM,UAAU,EAAE;AAAA,QACjC;AACA,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,mBAAO,aAAa,SAAS,EAAE,iBAAiB,MAAM,MAAM,SAAS,CAAC,CAAC;AAAA,UACzE;AAAA,QACF;AAGA,cAAM,SAAS,KAAK,EAAE;AACtB,cAAME,WAAU,OAAO,KAAK,MAAM,MAAM,SAAS,EAAE,OAAO,SAAO,IAAI,SAAS,MAAM,CAAC;AACrF,YAAIA,SAAQ,WAAW,GAAG;AACxB,iBAAO,MAAM,MAAM,UAAUA,SAAQ,CAAC,CAAC;AAAA,QACzC;AAEA,YAAI,WAAW,KAAK,MAAM,mBAAmB,CAAC,KAAK,UAAU,KAAK,MAAM,mBAAmB,GAAG,OAAO,EAAE,SAAS,GAAG;AACjH,iBAAY,YAAK,KAAK,MAAM,mBAAmB,GAAG,GAAG,EAAE,OAAO;AAAA,QAChE;AACA,eAAY,YAAK,KAAK,MAAM,SAAS,GAAG,IAAI,aAAa;AAAA,MAC3D;AAAA,MAEA,iBAAiB,IAAY,aAA8B;AACzD,cAAM,QAAQ,KAAK,QAAQ;AAC3B,YAAI,MAAM,MAAM,UAAU,EAAE,GAAG;AAC7B,iBAAO,MAAM,MAAM,UAAU,EAAE;AAAA,QACjC;AAEA,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,cAAc,MAAM,MAAM,SAAS,CAAC;AAC1C,kBAAM,qBAAqB,cAAc,YAAY,MAAM,IAAI,EAAE,IAAI,IAAI;AACzE,mBAAO,aAAa,SAAS,EAAE,iBAAiB,aAAa,kBAAkB;AAAA,UACjF;AAAA,QACF;AAIA,cAAM,QAAQ,UAAU,IAAI,MAAM,UAAU;AAC5C,YAAI,OAAO;AACT,gBAAM,YAAY,MAAM,MAAM,UAAU,MAAM,EAAE;AAChD,cAAI,aAAa,UAAU,SAAS,aAAa,GAAG;AAClD,mBAAY,YAAU,eAAQ,SAAS,GAAG,IAAI,aAAa;AAAA,UAC7D;AAAA,QACF;AAEA,YAAI,aAAa;AACf,gBAAM,UAAU,KAAK,iBAAiB,WAAW;AACjD,gBAAM,SAAc,eAAQ,OAAO;AACnC,cAAI,QAAQ,SAAS,aAAa,GAAG;AACnC,mBAAY,YAAK,QAAQ,IAAI,aAAa;AAAA,UAC5C;AAAA,QACF;AAEA,YAAI,WAAW,KAAK,MAAM,mBAAmB,CAAC,KAAK,UAAU,KAAK,MAAM,mBAAmB,GAAG,OAAO,EAAE,SAAS,GAAG;AACjH,iBAAY,YAAK,KAAK,MAAM,mBAAmB,GAAG,GAAG,EAAE,OAAO;AAAA,QAChE;AAEA,cAAM,kBAAkB,eAAe;AACvC,eAAY,YAAK,KAAK,MAAM,SAAS,GAAG,iBAAiB,IAAI,aAAa;AAAA,MAC5E;AAAA,MAEA,iBAAiB,IAAY,aAA8B;AACzD,cAAM,QAAQ,KAAK,QAAQ;AAC3B,YAAI,MAAM,MAAM,UAAU,EAAE,GAAG;AAC7B,iBAAO,MAAM,MAAM,UAAU,EAAE;AAAA,QACjC;AAEA,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,cAAc,MAAM,MAAM,SAAS,CAAC;AAC1C,kBAAM,qBAAqB,cAAc,YAAY,MAAM,IAAI,EAAE,IAAI,IAAI;AACzE,mBAAO,aAAa,SAAS,EAAE,iBAAiB,aAAa,kBAAkB;AAAA,UACjF;AAAA,QACF;AAEA,YAAI,eAAe,YAAY,SAAS,IAAI,GAAG;AAC7C,gBAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,qBAAqB,MAAM,MAAM,SAAS,CAAC;AACjD,mBAAO,aAAa,SAAS,EAAE,iBAAiB,IAAI,kBAAkB;AAAA,UACxE;AAAA,QACF;AAEA,YAAI,aAAa;AACf,gBAAM,WAAW,KAAK,iBAAiB,WAAW;AAClD,gBAAM,UAAe,eAAQ,QAAQ;AACrC,cAAI,SAAS,SAAS,aAAa,GAAG;AACpC,mBAAY,YAAK,SAAS,iBAAiB;AAAA,UAC7C;AAAA,QACF;AAEA,YAAI,WAAW,KAAK,MAAM,mBAAmB,CAAC,KAAK,UAAU,KAAK,MAAM,mBAAmB,GAAG,OAAO,EAAE,SAAS,GAAG;AACjH,iBAAY,YAAK,KAAK,MAAM,mBAAmB,GAAG,GAAG,EAAE,OAAO;AAAA,QAChE;AAEA,cAAM,kBAAkB,eAAe;AACvC,eAAY,YAAK,KAAK,MAAM,SAAS,GAAG,WAAW,iBAAiB,iBAAiB;AAAA,MACvF;AAAA,MAEA,sBAAsB,IAAY,YAA6B;AAC7D,cAAM,QAAQ,KAAK,QAAQ;AAC3B,YAAI,MAAM,MAAM,eAAe,EAAE,GAAG;AAClC,iBAAO,MAAM,MAAM,eAAe,EAAE;AAAA,QACtC;AAEA,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,cAAc,MAAM,MAAM,SAAS,CAAC;AAC1C,kBAAM,oBAAoB,aAAa,WAAW,MAAM,IAAI,EAAE,IAAI,IAAI;AACtE,mBAAO,aAAa,SAAS,EAAE,sBAAsB,aAAa,iBAAiB;AAAA,UACrF;AAAA,QACF;AAEA,YAAI,cAAc,WAAW,SAAS,IAAI,GAAG;AAC3C,gBAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,oBAAoB,MAAM,MAAM,SAAS,CAAC;AAChD,mBAAO,aAAa,SAAS,EAAE,sBAAsB,IAAI,iBAAiB;AAAA,UAC5E;AAAA,QACF;AAEA,YAAI,YAAY;AACd,gBAAM,WAAW,KAAK,iBAAiB,UAAU;AACjD,gBAAM,UAAe,eAAQ,QAAQ;AACrC,cAAI,SAAS,SAAS,iBAAiB,GAAG;AACxC,mBAAY,YAAK,SAAS,sBAAsB;AAAA,UAClD;AAAA,QACF;AAEA,YAAI,WAAW,KAAK,MAAM,wBAAwB,CAAC,KAAK,UAAU,KAAK,MAAM,wBAAwB,GAAG,OAAO,EAAE,SAAS,GAAG;AAC3H,iBAAY,YAAK,KAAK,MAAM,wBAAwB,GAAG,GAAG,EAAE,OAAO;AAAA,QACrE;AAEA,cAAM,iBAAiB,aAAa,WAAW,QAAQ,MAAM,EAAE,IAAI;AACnE,eAAY,YAAK,KAAK,MAAM,SAAS,GAAG,WAAW,gBAAgB,sBAAsB;AAAA,MAC3F;AAAA,MAEA,YAAY,IAAY,aAAsB,OAAwB;AACpE,cAAM,QAAQ,KAAK,QAAQ;AAC3B,YAAI,MAAM,MAAM,KAAK,EAAE,EAAG,QAAO,MAAM,MAAM,KAAK,EAAE;AAEpD,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,cAAc,MAAM,MAAM,SAAS,CAAC;AAC1C,kBAAM,qBAAqB,cAAc,YAAY,MAAM,IAAI,EAAE,IAAI,IAAI;AACzE,kBAAM,iBAAiB,QAAQ,MAAM,MAAM,IAAI,EAAE,IAAI,IAAI;AACzD,mBAAO,aAAa,SAAS,EAAE,YAAY,aAAa,oBAAoB,cAAc;AAAA,UAC5F;AAAA,QACF;AAEA,YAAI,eAAe,YAAY,SAAS,IAAI,GAAG;AAC7C,gBAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,qBAAqB,MAAM,MAAM,SAAS,CAAC;AACjD,kBAAM,iBAAiB,QAAQ,MAAM,MAAM,IAAI,EAAE,IAAI,IAAI;AACzD,mBAAO,aAAa,SAAS,EAAE,YAAY,IAAI,oBAAoB,cAAc;AAAA,UACnF;AAAA,QACF;AAEA,cAAM,EAAE,SAAS,QAAQ,IAAI,eAAe,EAAE;AAC9C,cAAM,cAAc,SAAS,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,MAAM,EAAE,OAAO,OAAO,GAAG;AACvF,YAAI,aAAa;AACf,gBAAM,EAAE,SAAS,WAAW,IAAI,eAAe,WAAW;AAC1D,gBAAM,YAAY,MAAM,MAAM,MAAM,WAAW,KAAK,MAAM,MAAM,MAAM,UAAU;AAChF,cAAI,WAAW;AACb,kBAAMC,WAAU,GAAG,MAAM,IAAI,EAAE,IAAI;AACnC,mBAAY,YAAU,eAAQ,SAAS,GAAG,GAAGA,QAAO,OAAO;AAAA,UAC7D;AAAA,QACF;AAEA,YAAI,UAAU;AACd,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,oBAAU,MAAM,MAAM,SAAS,CAAC;AAChC,cAAI,CAAC,aAAa;AAChB,0BAAc,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI;AAAA,UAC5C;AAAA,QACF;AAEA,YAAI,aAAa;AACf,gBAAM,UAAU,KAAK,iBAAiB,WAAW;AACjD,gBAAM,SAAc,eAAQ,OAAO;AACnC,cAAI,QAAQ,SAAS,aAAa,GAAG;AACnC,mBAAY,YAAK,QAAQ,SAAS,GAAG,OAAO,OAAO;AAAA,UACrD;AAAA,QACF;AACA,eAAY,YAAK,KAAK,MAAM,cAAc,GAAG,GAAG,OAAO,OAAO;AAAA,MAChE;AAAA,MAEA,aAAa,IAAY,aAA8B;AACrD,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,EAAE,SAAS,QAAQ,IAAI,eAAe,EAAE;AAC9C,YAAI,MAAM,MAAM,MAAM,EAAE,EAAG,QAAO,MAAM,MAAM,MAAM,EAAE;AACtD,YAAI,MAAM,MAAM,MAAM,OAAO,EAAG,QAAO,MAAM,MAAM,MAAM,OAAO;AAEhE,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,cAAc,MAAM,MAAM,SAAS,CAAC;AAC1C,kBAAM,qBAAqB,cAAc,YAAY,MAAM,IAAI,EAAE,IAAI,IAAI;AACzE,mBAAO,aAAa,SAAS,EAAE,aAAa,aAAa,kBAAkB;AAAA,UAC7E;AAAA,QACF;AAEA,YAAI,eAAe,YAAY,SAAS,IAAI,GAAG;AAC7C,gBAAM,QAAQ,YAAY,MAAM,IAAI;AACpC,gBAAM,YAAY,KAAK,8BAA8B,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC;AAClF,cAAI,WAAW;AACb,kBAAM,qBAAqB,MAAM,MAAM,SAAS,CAAC;AACjD,mBAAO,aAAa,SAAS,EAAE,aAAa,IAAI,kBAAkB;AAAA,UACpE;AAAA,QACF;AAEA,YAAI,UAAU;AACd,YAAI,GAAG,SAAS,IAAI,GAAG;AACrB,gBAAM,QAAQ,GAAG,MAAM,IAAI;AAC3B,oBAAU,MAAM,MAAM,SAAS,CAAC;AAChC,cAAI,CAAC,aAAa;AAChB,0BAAc,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI;AAAA,UAC5C;AAAA,QACF;AAEA,YAAI,aAAa;AACf,gBAAM,UAAU,KAAK,iBAAiB,WAAW;AACjD,gBAAM,SAAc,eAAQ,OAAO;AACnC,cAAI,QAAQ,SAAS,aAAa,GAAG;AACnC,mBAAY,YAAK,QAAQ,SAAS,SAAS,aAAa;AAAA,UAC1D;AAAA,QACF;AACA,eAAY,YAAK,KAAK,MAAM,cAAc,GAAG,SAAS,aAAa;AAAA,MACrE;AAAA;AAAA;AAAA;AAAA,MAMA,iBAAoC;AAClC,cAAM,IAAI,KAAK,MAAM,YAAY;AACjC,YAAI,CAAC,WAAW,CAAC,EAAG,QAAO;AAC3B,YAAI;AACF,gBAAM,MAAM,aAAa,CAAC;AAC1B,iBAAO,iBAAiB,MAAM,GAAG;AAAA,QACnC,SAAS,GAAQ;AACf,eAAK,aAAa,KAAK;AAAA,YACrB,UAAU;AAAA,YACV,MAAM;AAAA,YACN,SAAS,gCAAgC,EAAE,WAAW,OAAO,CAAC,CAAC;AAAA,YAC/D,QAAQ;AAAA,UACV,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MAEA,eAAe,MAAwB;AACrC,cAAM,IAAI,KAAK,MAAM,YAAY;AACjC,kBAAe,eAAQ,CAAC,CAAC;AACzB,sBAAc,GAAG,aAAa,kBAAkB,MAAM,UAAU,KAAK,IAAI,CAAC;AAC1E,4BAAoB;AAAA,MACtB;AAAA;AAAA;AAAA;AAAA,MAMA,qBAAsC;AACpC,eAAO,KAAK,QAAQ,EAAE;AAAA,MACxB;AAAA,MAEA,kBAAkB,IAAkC;AAClD,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,SAAS,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACvD,YAAI,OAAQ,QAAO;AAEnB,cAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,YAAI,CAAC,WAAW,CAAC,EAAG,QAAO;AAC3B,YAAI;AACF,gBAAM,MAAM,aAAa,CAAC;AAC1B,iBAAO,oBAAoB,MAAM,GAAG;AAAA,QACtC,SAAS,GAAQ;AACf,eAAK,aAAa,KAAK;AAAA,YACrB,UAAU;AAAA,YACV,MAAM;AAAA,YACN,SAAS,mCAAmC,EAAE,MAAM,EAAE,WAAW,OAAO,CAAC,CAAC;AAAA,YAC1E,QAAQ;AAAA,UACV,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAeA,eAAe,aAA6B;AAC1C,eAAO,KAAK,oBAAoB,WAAW,KAAK,eAAe,WAAW,EAAE;AAAA,MAC9E;AAAA,MAEA,yBAAyB,MAAoC;AAC3D,cAAM,EAAE,OAAO,IAAI,eAAe,KAAK,EAAE;AACzC,eAAO,4BAA4B,MAAM,MAAM;AAAA,MACjD;AAAA,MAEA,yBAAyB,MAAoC;AAC3D,cAAM,SAAS,KAAK,eAAe,KAAK,EAAE;AAC1C,eAAO,SAAS,4BAA4B,MAAM,MAAM,IAAI;AAAA,MAC9D;AAAA,MAEA,yBAAyB,MAAoC;AAC3D,cAAM,SAAS,KAAK,eAAe,KAAK,EAAE;AAC1C,eAAO,SAAS,4BAA4B,MAAM,MAAM,IAAI;AAAA,MAC9D;AAAA,MAEA,8BAA8B,MAA8C;AAC1E,cAAM,SAAS,KAAK,eAAe,KAAK,EAAE;AAC1C,eAAO,SAAS,iCAAiC,MAAM,MAAM,IAAI;AAAA,MACnE;AAAA,MAEA,oBAAoB,MAA0B;AAC5C,cAAM,SAAS,KAAK,eAAe,KAAK,EAAE;AAC1C,eAAO,SAAS,uBAAuB,MAAM,MAAM,IAAI;AAAA,MACzD;AAAA,MAEA,qBAAqB,MAA4B;AAC/C,cAAM,SAAS,KAAK,eAAe,KAAK,EAAE;AAC1C,eAAO,SAAS,wBAAwB,MAAM,MAAM,IAAI;AAAA,MAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,qBAAqB,SAA0D;AAC7E,cAAM,SAA4B,CAAC;AACnC,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,UAAU,YAAY,MAAe;AAE3C,cAAM,QAAQ,CAAC,MAAc,IAAY,WAA0D;AACjG,cAAI,OAAO,QAAS;AACpB,iBAAO,KAAK;AAAA,YACV,UAAU;AAAA,YACV,MAAM;AAAA,YACN,SAAS,GAAG,IAAI,UAAU,EAAE,2FAA2F,gBAAgB,OAAO,KAAK,CAAC;AAAA,YACpJ,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAEA,mBAAW,OAAO,MAAM,YAAY;AAClC,cAAI,CAAC,QAAQ,IAAI,EAAE,EAAG;AACtB,gBAAM,aAAa,IAAI,IAAI,oBAAoB,UAAU,KAAK,yBAAyB,GAAG,CAAC,CAAC;AAAA,QAC9F;AACA,mBAAW,QAAQ,MAAM,YAAY;AACnC,cAAI,CAAC,QAAQ,KAAK,EAAE,EAAG;AACvB,gBAAM,aAAa,KAAK,IAAI,oBAAoB,UAAU,KAAK,yBAAyB,IAAI,CAAC,CAAC;AAAA,QAChG;AACA,mBAAW,QAAQ,MAAM,YAAY;AACnC,cAAI,CAAC,QAAQ,KAAK,EAAE,EAAG;AACvB,gBAAM,aAAa,KAAK,IAAI,oBAAoB,UAAU,KAAK,yBAAyB,IAAI,CAAC,CAAC;AAAA,QAChG;AACA,mBAAW,QAAQ,MAAM,iBAAiB;AACxC,cAAI,CAAC,QAAQ,KAAK,EAAE,EAAG;AACvB,gBAAM,kBAAkB,KAAK,IAAI,yBAAyB,UAAU,KAAK,8BAA8B,IAAI,CAAC,CAAC;AAAA,QAC/G;AACA,mBAAW,KAAK,MAAM,OAAO;AAC3B,cAAI,CAAC,QAAQ,EAAE,EAAE,EAAG;AACpB,gBAAM,QAAQ,EAAE,IAAI,eAAe,UAAU,KAAK,oBAAoB,CAAC,CAAC,CAAC;AAAA,QAC3E;AACA,mBAAW,KAAK,MAAM,QAAQ;AAC5B,cAAI,CAAC,QAAQ,EAAE,EAAE,EAAG;AACpB,gBAAM,SAAS,EAAE,IAAI,gBAAgB,UAAU,KAAK,qBAAqB,CAAC,CAAC,CAAC;AAAA,QAC9E;AACA,eAAO;AAAA,MACT;AAAA,MAEA,kBAAkB,MAA2B;AAC3C,cAAM,IAAI,KAAK,iBAAiB,KAAK,EAAE;AACvC,kBAAe,eAAQ,CAAC,CAAC;AAEzB,cAAM,EAAE,OAAO,IAAI,eAAe,KAAK,EAAE;AAMzC,YAAI,CAAC,UAAU,KAAK,eAAe,KAAK,YAAY,KAAK,MAAM,IAAI;AACjE,qCAA2B,KAAK,SAAS,KAAK,WAAW;AAAA,QAC3D;AAKA,YAAI,cAAc,KAAK,yBAAyB,IAAI;AAEpD,YAAI,QAAQ;AACV,gBAAM,YAAY,KAAK,8BAA8B,MAAM;AAC3D,cAAI,WAAW;AACb,kBAAM,cAAc,aAAa,SAAS,EAAE,eAAe;AAC3D,gBAAI,aAAa;AACf,4BAAc;AAAA,gBACZ,GAAG;AAAA,gBACH,cAAc,YAAY;AAAA,cAC5B;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAMA,YAAI,CAAC,KAAK,GAAG,SAAS,IAAI,KAAK,YAAY,eAAe,CAAC,SAAS,KAAK,MAAM,SAAS,GAAG,CAAC,GAAG;AAC7F,wBAAc,EAAE,GAAG,aAAa,aAAa,OAAU;AAAA,QACzD;AAEA,cAAM,WAAW,KAAK,kBAAkB,KAAK,EAAE;AAC/C,YAAI,UAAU;AACZ,sBAAY,YAAY,SAAS;AAAA,QACnC;AACA,oBAAY,aAAY,oBAAI,KAAK,GAAE,YAAY;AAC/C,sBAAc,GAAG,aAAa,qBAAqB,aAAa,aAAa,KAAK,EAAE,CAAC;AACrF,4BAAoB;AAAA,MACtB;AAAA,MAEA,oBAAoB,IAAqB;AACvC,cAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,YAAI,CAAI,eAAW,CAAC,EAAG,QAAO;AAC9B,QAAG,eAAW,CAAC;AACf,uBAAe,GAAQ,eAAQ,KAAK,MAAM,SAAS,CAAC,CAAC;AACrD,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,qBAAsC;AACpC,eAAO,KAAK,QAAQ,EAAE;AAAA,MACxB;AAAA,MAEA,kBAAkB,IAAkC;AAClD,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,OAAO,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACrD,YAAI,KAAM,QAAO;AAEjB,cAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,YAAI,CAAC,WAAW,CAAC,EAAG,QAAO;AAC3B,YAAI;AACF,gBAAM,MAAM,aAAa,CAAC;AAC1B,iBAAO,oBAAoB,MAAM,GAAG;AAAA,QACtC,SAAS,GAAQ;AACf,eAAK,aAAa,KAAK;AAAA,YACrB,UAAU;AAAA,YACV,MAAM;AAAA,YACN,SAAS,mCAAmC,EAAE,MAAM,EAAE,WAAW,OAAO,CAAC,CAAC;AAAA,YAC1E,QAAQ;AAAA,UACV,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA,MAGA,kBAAkB,MAAqB,MAAkC;AACvE,cAAM,UAAoB,CAAC;AAC3B,cAAM,IAAI,KAAK,iBAAiB,KAAK,IAAI,KAAK,SAAS;AACvD,kBAAe,eAAQ,CAAC,CAAC;AAEzB,cAAM,cAAc,KAAK,yBAAyB,IAAI;AAEtD,cAAM,WAAW,KAAK,kBAAkB,KAAK,EAAE;AAC/C,YAAI,UAAU;AACZ,sBAAY,YAAY,SAAS;AACjC,cAAI,CAAC,MAAM,uBAAuB,SAAS,WAAW,CAAC,KAAK,UAAU,KAAK,WAAW,UAAU;AAC9F,wBAAY,SAAS,SAAS;AAAA,UAChC;AAAA,QACF;AAKA,YAAI,CAAC,YAAY,KAAK,kBAAkB,WACnC,CAAC,UAAU,KAAK,IAAI,KAAK,QAAQ,EAAE,UAAU,GAAG;AACnD,kBAAQ;AAAA,YACN,UAAU,KAAK,EAAE;AAAA,UAKnB;AAAA,QACF;AAIA,cAAM,mBAAmB,YACpB,SAAS,cAAc,KAAK,aAC5B,eAAe,SAAS,SAAS,EAAE,YAAY,eAAe,KAAK,SAAS,EAAE;AACnF,YAAI,oBAAoB,CAAC,EAAE,SAAS,aAAa,GAAG;AAClD,kBAAQ;AAAA,YACN,cAAc,KAAK,EAAE,uBAA4B,gBAAS,KAAK,SAAS,CAAC,CAAC,uGACzC,KAAK,SAAS,WAAW,SAAS,SAAS;AAAA,UAC9E;AAAA,QACF;AACA,oBAAY,aAAY,oBAAI,KAAK,GAAE,YAAY;AAC/C,sBAAc,GAAG,aAAa,qBAAqB,aAAa,aAAa,KAAK,EAAE,CAAC;AACrF,4BAAoB;AAGpB,aAAK,yBAAyB;AAC9B,eAAO;AAAA,MACT;AAAA,MAEA,oBAAoB,IAAqB;AACvC,cAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,YAAI,CAAI,eAAW,CAAC,EAAG,QAAO;AAC9B,QAAG,eAAW,CAAC;AACf,uBAAe,GAAQ,eAAQ,KAAK,MAAM,SAAS,CAAC,CAAC;AACrD,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA;AAAA,MAGQ,oBAAoB,MAAqB,OAAiC;AAChF,cAAM,cAAc,MAAM,MAAM,UAAU,KAAK,EAAE;AAEjD,YAAI,CAAC,eAAe,CAAC,YAAY,SAAS,aAAa,EAAG,QAAO;AACjE,YAAI,KAAK,GAAG,SAAS,IAAI,EAAG,QAAO;AAEnC,cAAM,QAAQ,UAAU,KAAK,IAAI,MAAM,UAAU;AACjD,YAAI,OAAO;AACT,gBAAM,YAAY,MAAM,MAAM,UAAU,MAAM,EAAE;AAChD,cAAI,aAAa,UAAU,SAAS,aAAa,GAAG;AAElD,kBAAM,cAAmB,eAAQ,KAAK,iBAAiB,MAAM,SAAS,CAAC;AACvE,mBAAY,YAAK,aAAa,MAAM,IAAI,KAAK,EAAE;AAAA,UACjD;AAAA,QACF;AAEA,cAAM,SAAc,eAAQ,KAAK,iBAAiB,KAAK,SAAS,CAAC;AACjE,eAAY,YAAK,QAAQ,KAAK,EAAE;AAAA,MAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,2BAAqC;AACnC,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,QAAkB,CAAC;AACzB,mBAAW,QAAQ,MAAM,YAAY;AACnC,gBAAM,cAAc,MAAM,MAAM,UAAU,KAAK,EAAE;AACjD,cAAI,CAAC,YAAa;AAClB,gBAAM,aAAa,KAAK,oBAAoB,MAAM,KAAK;AACvD,cAAI,CAAC,WAAY;AACjB,cAAI,oBAAyB,eAAQ,WAAW,GAAG,UAAU,EAAG,OAAM,KAAK,KAAK,EAAE;AAAA,QACpF;AACA,YAAI,MAAM,OAAQ,qBAAoB;AACtC,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,qBAAsC;AACpC,eAAO,KAAK,QAAQ,EAAE;AAAA,MACxB;AAAA,MAEA,kBAAkB,IAAkC;AAClD,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,OAAO,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACrD,YAAI,KAAM,QAAO;AAEjB,cAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,YAAI,CAAC,WAAW,CAAC,EAAG,QAAO;AAC3B,YAAI;AACF,gBAAM,MAAM,aAAa,CAAC;AAC1B,iBAAO,oBAAoB,MAAM,GAAG;AAAA,QACtC,SAAS,GAAQ;AACf,eAAK,aAAa,KAAK;AAAA,YACrB,UAAU;AAAA,YACV,MAAM;AAAA,YACN,SAAS,mCAAmC,EAAE,MAAM,EAAE,WAAW,OAAO,CAAC,CAAC;AAAA,YAC1E,QAAQ;AAAA,UACV,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA,MAGA,kBAAkB,MAAqB,MAAkC;AACvE,cAAM,UAAoB,CAAC;AAC3B,cAAM,IAAI,KAAK,iBAAiB,KAAK,IAAI,KAAK,SAAS;AACvD,kBAAe,eAAQ,CAAC,CAAC;AAEzB,cAAM,cAAc,KAAK,yBAAyB,IAAI;AAEtD,cAAM,WAAW,KAAK,kBAAkB,KAAK,EAAE;AAC/C,YAAI,YAAY,SAAS,cAAc,KAAK,aACvC,eAAe,SAAS,SAAS,EAAE,YAAY,eAAe,KAAK,SAAS,EAAE,SAAS;AAC1F,kBAAQ;AAAA,YACN,cAAc,KAAK,EAAE,uBAA4B,gBAAS,KAAK,SAAS,CAAC,CAAC,wEAC/D,KAAK,SAAS,WAAW,SAAS,SAAS;AAAA,UACxD;AAAA,QACF;AACA,YAAI,UAAU;AACZ,sBAAY,YAAY,SAAS;AACjC,cAAI,CAAC,MAAM,uBAAuB,SAAS,WAAW,CAAC,KAAK,UAAU,KAAK,WAAW,UAAU;AAC9F,wBAAY,SAAS,SAAS;AAAA,UAChC;AAEA,qBAAW,KAAK,YAAY,SAAS;AACnC,gBAAI,EAAE,SAAU;AAChB,kBAAM,iBAAiB,SAAS,QAAQ,KAAK,OAAK,EAAE,SAAS,EAAE,IAAI;AACnE,gBAAI,kBAAkB,eAAe,UAAU;AAC7C,gBAAE,WAAW,eAAe;AAAA,YAC9B;AAAA,UACF;AAAA,QACF;AACA,oBAAY,aAAY,oBAAI,KAAK,GAAE,YAAY;AAC/C,sBAAc,GAAG,aAAa,qBAAqB,aAAa,aAAa,KAAK,EAAE,CAAC;AACrF,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA,MAEA,oBAAoB,IAAqB;AACvC,cAAM,IAAI,KAAK,iBAAiB,EAAE;AAClC,YAAI,CAAI,eAAW,CAAC,EAAG,QAAO;AAC9B,QAAG,eAAW,CAAC;AACf,uBAAe,GAAQ,eAAQ,KAAK,MAAM,SAAS,CAAC,CAAC;AACrD,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,0BAAgD;AAC9C,eAAO,KAAK,QAAQ,EAAE;AAAA,MACxB;AAAA,MAEA,uBAAuB,IAAuC;AAC5D,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,OAAO,MAAM,gBAAgB,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAChE,YAAI,KAAM,QAAO;AAEjB,cAAM,IAAI,KAAK,sBAAsB,EAAE;AACvC,YAAI,CAAC,WAAW,CAAC,EAAG,QAAO;AAC3B,YAAI;AACF,gBAAM,MAAM,aAAa,CAAC;AAC1B,iBAAO,yBAAyB,MAAM,GAAG;AAAA,QAC3C,SAAS,GAAQ;AACf,eAAK,aAAa,KAAK;AAAA,YACrB,UAAU;AAAA,YACV,MAAM;AAAA,YACN,SAAS,wCAAwC,EAAE,MAAM,EAAE,WAAW,OAAO,CAAC,CAAC;AAAA,YAC/E,QAAQ;AAAA,UACV,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA,MAGA,uBAAuB,MAA0B,MAAkC;AACjF,cAAM,UAAoB,CAAC;AAC3B,cAAM,IAAI,KAAK,sBAAsB,KAAK,IAAI,KAAK,QAAQ;AAC3D,kBAAe,eAAQ,CAAC,CAAC;AAEzB,cAAM,cAAc,KAAK,8BAA8B,IAAI;AAE3D,cAAM,WAAW,KAAK,uBAAuB,KAAK,EAAE;AACpD,YAAI,YAAY,SAAS,aAAa,KAAK,YACtC,eAAe,SAAS,QAAQ,EAAE,YAAY,eAAe,KAAK,QAAQ,EAAE,SAAS;AACxF,kBAAQ;AAAA,YACN,mBAAmB,KAAK,EAAE,uBAA4B,gBAAS,KAAK,SAAS,CAAC,CAAC,uEACpE,KAAK,QAAQ,WAAW,SAAS,QAAQ;AAAA,UACtD;AAAA,QACF;AACA,YAAI,UAAU;AACZ,sBAAY,YAAY,SAAS;AACjC,cAAI,CAAC,MAAM,uBAAuB,SAAS,WAAW,CAAC,KAAK,UAAU,KAAK,WAAW,UAAU;AAC9F,wBAAY,SAAS,SAAS;AAAA,UAChC;AAAA,QACF;AACA,oBAAY,aAAY,oBAAI,KAAK,GAAE,YAAY;AAC/C,sBAAc,GAAG,aAAa,0BAA0B,aAAa,kBAAkB,KAAK,EAAE,CAAC;AAC/F,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA,MAEA,yBAAyB,IAAqB;AAC5C,cAAM,IAAI,KAAK,sBAAsB,EAAE;AACvC,YAAI,CAAI,eAAW,CAAC,EAAG,QAAO;AAC9B,QAAG,eAAW,CAAC;AACf,uBAAe,GAAQ,eAAQ,KAAK,MAAM,SAAS,CAAC,CAAC;AACrD,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,gBAA4B;AAC1B,eAAO,KAAK,QAAQ,EAAE;AAAA,MACxB;AAAA,MAEA,aAAa,IAA6B;AACxC,eAAO,KAAK,QAAQ,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK;AAAA,MAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,aAAa,MAA0B;AACrC,cAAM,UAAoB,CAAC;AAC3B,cAAM,WAAW,KAAK,aAAa,KAAK,EAAE;AAC1C,cAAM,QAAQ,KAAK,UAAU,WAAW,SAAS,QAAQ;AACzD,cAAM,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,WAAW,KAAK;AACzD,kBAAe,eAAQ,CAAC,CAAC;AAEzB,cAAM,mBAAmB,aACnB,SAAS,aAAa,SAAS,KAAK,aAAa,OAClD,eAAe,SAAS,aAAa,EAAE,EAAE,YAAY,eAAe,KAAK,aAAa,EAAE,EAAE;AAC/F,YAAI,kBAAkB;AACpB,kBAAQ;AAAA,YACN,SAAS,KAAK,EAAE,uBAA4B,gBAAS,KAAK,SAAS,CAAC,CAAC,uGACpC,KAAK,aAAa,QAAQ,WAAW,SAAS,aAAa,QAAQ;AAAA,UACtG;AAAA,QACF;AACA,YAAI,KAAK,cAAc,CAAC,YAAY,qBAC/B,CAAC,KAAK,iBAAiB,KAAK,SAAS,EAAE,SAAS,aAAa,GAAG;AACnE,kBAAQ;AAAA,YACN,sBAAsB,KAAK,EAAE,kCAAkC,KAAK,SAAS;AAAA,UAG/E;AAAA,QACF;AAEA,cAAM,cAAc,KAAK,oBAAoB,IAAI;AAEjD,YAAI,UAAU;AACZ,sBAAY,YAAY,SAAS;AACjC,cAAI,CAAC,YAAY,SAAS,SAAS,OAAO;AACxC,wBAAY,QAAQ,aAAa,SAAS,OAAO,KAAK,eAAe,KAAK,EAAE,CAAC;AAAA,UAC/E;AAAA,QACF;AACA,oBAAY,aAAY,oBAAI,KAAK,GAAE,YAAY;AAC/C,sBAAc,GAAG,aAAa,gBAAgB,aAAa,QAAQ,KAAK,EAAE,CAAC;AAC3E,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA,MAEA,eAAe,IAAqB;AAClC,cAAM,OAAO,KAAK,aAAa,EAAE;AACjC,cAAM,IAAI,KAAK,YAAY,IAAI,MAAM,WAAW,MAAM,KAAK;AAC3D,YAAI,CAAI,eAAW,CAAC,EAAG,QAAO;AAC9B,QAAG,eAAW,CAAC;AACf,uBAAe,GAAQ,eAAQ,KAAK,MAAM,SAAS,CAAC,CAAC;AACrD,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,iBAA8B;AAC5B,eAAO,KAAK,QAAQ,EAAE;AAAA,MACxB;AAAA,MAEA,cAAc,IAA8B;AAC1C,eAAO,KAAK,QAAQ,EAAE,OAAO,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK;AAAA,MAC3D;AAAA,MAEA,cAAc,MAAuB;AACnC,cAAM,IAAI,KAAK,aAAa,KAAK,EAAE;AACnC,kBAAe,eAAQ,CAAC,CAAC;AAEzB,cAAM,cAAc,KAAK,qBAAqB,IAAI;AAElD,cAAM,WAAW,KAAK,cAAc,KAAK,EAAE;AAC3C,YAAI,UAAU;AACZ,sBAAY,YAAY,SAAS;AAAA,QACnC;AACA,oBAAY,aAAY,oBAAI,KAAK,GAAE,YAAY;AAC/C,sBAAc,GAAG,aAAa,iBAAiB,aAAa,SAAS,KAAK,EAAE,CAAC;AAC7E,4BAAoB;AAAA,MACtB;AAAA,MAEA,gBAAgB,IAAqB;AACnC,cAAM,IAAI,KAAK,aAAa,EAAE;AAC9B,YAAI,CAAI,eAAW,CAAC,EAAG,QAAO;AAC9B,QAAG,eAAW,CAAC;AACf,uBAAe,GAAQ,eAAQ,KAAK,MAAM,SAAS,CAAC,CAAC;AACrD,4BAAoB;AACpB,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,uBAAuB,gBAA2C;AAChE,cAAM,MAAwB,CAAC;AAC/B,cAAM,aAAa,KAAK,mBAAmB;AAC3C,cAAM,aAAa,KAAK,mBAAmB;AAC3C,cAAM,aAAa,KAAK,mBAAmB;AAC3C,cAAM,kBAAkB,KAAK,wBAAwB;AAErD,cAAM,yBAAyB,CAAC,kBAA+C;AAC7E,cAAI,CAAC,eAAgB,QAAO;AAC5B,cAAI,CAAC,cAAe,QAAO;AAC3B,iBAAO,kBAAkB,kBAAkB,cAAc,WAAW,GAAG,cAAc,IAAI;AAAA,QAC3F;AAEA,mBAAW,KAAK,YAAY;AAC1B,cAAI,EAAE,WAAW,eAAe,CAAC,kBAAkB,EAAE,OAAO,kBAAkB,EAAE,GAAG,WAAW,iBAAiB,IAAI,IAAI;AACrH,gBAAI,KAAK,EAAE,MAAM,aAAa,IAAI,EAAE,IAAI,QAAS,EAAE,UAAU,WAA0B,CAAC;AAAA,UAC1F;AAAA,QACF;AACA,mBAAW,KAAK,YAAY;AAC1B,cAAI,EAAE,WAAW,cAAc,uBAAuB,EAAE,SAAS,GAAG;AAClE,gBAAI,KAAK,EAAE,MAAM,aAAa,IAAI,EAAE,IAAI,QAAS,EAAE,UAAU,WAA0B,CAAC;AAAA,UAC1F;AAAA,QACF;AACA,mBAAW,KAAK,YAAY;AAC1B,cAAI,EAAE,WAAW,YAAY;AAC3B,kBAAM,OAAO,WAAW,KAAK,OAAK,EAAE,OAAO,EAAE,SAAS;AACtD,gBAAI,QAAQ,uBAAuB,KAAK,SAAS,GAAG;AAClD,kBAAI,KAAK,EAAE,MAAM,aAAa,IAAI,EAAE,IAAI,QAAS,EAAE,UAAU,WAA0B,CAAC;AAAA,YAC1F;AAAA,UACF;AAAA,QACF;AACA,mBAAW,KAAK,iBAAiB;AAC/B,cAAI,EAAE,WAAW,YAAY;AAC3B,kBAAM,OAAO,WAAW,KAAK,OAAK,EAAE,OAAO,EAAE,QAAQ;AACrD,kBAAM,OAAO,OAAO,WAAW,KAAK,OAAK,EAAE,OAAO,KAAK,SAAS,IAAI;AACpE,gBAAI,QAAQ,uBAAuB,KAAK,SAAS,GAAG;AAClD,kBAAI,KAAK,EAAE,MAAM,kBAAkB,IAAI,EAAE,IAAI,QAAS,EAAE,UAAU,WAA0B,CAAC;AAAA,YAC/F;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA;AAAA,MAGA,gBAAgB,MAAgB,IAAY,QAA0B;AACpE,gBAAQ,MAAM;AAAA,UACZ,KAAK,aAAkB;AAAE,kBAAM,IAAI,KAAK,kBAAkB,EAAE;AAAQ,gBAAI,EAAG,MAAK,kBAAkB,EAAE,GAAG,GAAG,OAAO,CAAC;AAAG;AAAA,UAAO;AAAA,UAC5H,KAAK,aAAkB;AAAE,kBAAM,IAAI,KAAK,kBAAkB,EAAE;AAAQ,gBAAI,EAAG,MAAK,kBAAkB,EAAE,GAAG,GAAG,OAAO,CAAC;AAAG;AAAA,UAAO;AAAA,UAC5H,KAAK,aAAkB;AAAE,kBAAM,IAAI,KAAK,kBAAkB,EAAE;AAAQ,gBAAI,EAAG,MAAK,kBAAkB,EAAE,GAAG,GAAG,OAAO,CAAC;AAAG;AAAA,UAAO;AAAA,UAC5H,KAAK,kBAAkB;AAAE,kBAAM,IAAI,KAAK,uBAAuB,EAAE;AAAG,gBAAI,EAAG,MAAK,uBAAuB,EAAE,GAAG,GAAG,OAAO,CAAC;AAAG;AAAA,UAAO;AAAA,QACnI;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,oBAAyC;AACvC,cAAM,QAAQ,KAAK,QAAQ;AAC3B,cAAM,WAAW,oBAAI,IAAoB;AACzC,cAAM,QAAQ,oBAAI,IAAY;AAE9B,cAAM,UAAU,KAAK,MAAM,YAAY;AACvC,YAAI,WAAW,OAAO,GAAG;AACvB,gBAAM,IAAS,eAAQ,OAAO,CAAC;AAAA,QACjC;AAEA,mBAAW,SAAS,OAAO,OAAO,MAAM,KAAK,GAAG;AAC9C,qBAAW,QAAQ,OAAO,OAAO,KAAK,GAAG;AACvC,kBAAM,IAAS,eAAQ,IAAI,CAAC;AAAA,UAC9B;AAAA,QACF;AAEA,mBAAW,QAAQ,OAAO;AACxB,cAAO,eAAW,IAAI,GAAG;AACvB,qBAAS,IAAI,MAAS,iBAAa,MAAM,MAAM,CAAC;AAAA,UAClD;AAAA,QACF;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAMA,sBAA4D;AAC1D,cAAM,WAAW,KAAK,MAAM,SAAS;AACrC,YAAI,CAAC,WAAW,QAAQ,EAAG,QAAO,CAAC;AACnC,cAAM,QAAQ,mBAAmB,UAAU,OAAO;AAClD,cAAM,SAA+C,CAAC;AACtD,mBAAW,KAAK,OAAO;AACrB,gBAAM,OAAY,gBAAS,CAAC;AAC5B,gBAAM,MAAW,eAAQ,CAAC;AAC1B,cAAI,SAAS,eAAe;AAC1B,mBAAO,KAAK,EAAE,MAAM,GAAG,UAAe,YAAK,KAAK,aAAa,EAAE,CAAC;AAAA,UAClE,WAAW,SAAS,kBAAkB;AACpC,mBAAO,KAAK,EAAE,MAAM,GAAG,UAAe,YAAK,KAAK,aAAa,EAAE,CAAC;AAAA,UAClE,WAAW,SAAS,kBAAkB;AACpC,mBAAO,KAAK,EAAE,MAAM,GAAG,UAAe,YAAK,KAAK,aAAa,EAAE,CAAC;AAAA,UAClE,WAAW,SAAS,cAAc;AAChC,mBAAO,KAAK,EAAE,MAAM,GAAG,UAAe,YAAK,KAAK,aAAa,EAAE,CAAC;AAAA,UAClE,WAAW,SAAS,kBAAkB;AACpC,mBAAO,KAAK,EAAE,MAAM,GAAG,UAAe,YAAK,KAAK,iBAAiB,EAAE,CAAC;AAAA,UACtE,WAAW,SAAS,uBAAuB;AACzC,mBAAO,KAAK,EAAE,MAAM,GAAG,UAAe,YAAK,KAAK,sBAAsB,EAAE,CAAC;AAAA,UAC3E;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAWA,WACE,MACA,IACA,OACU;AACV,cAAM,UAAoB,CAAC;AAC3B,cAAM,UAAU,MAAM;AACpB,kBAAQ,MAAM;AAAA,YACZ,KAAK;AAAkB,qBAAO,KAAK,eAAe;AAAA;AAAA,YAClD,KAAK;AAAkB,qBAAO,KAAK,kBAAkB,EAAE;AAAA,YACvD,KAAK;AAAkB,qBAAO,KAAK,kBAAkB,EAAE;AAAA,YACvD,KAAK;AAAkB,qBAAO,KAAK,kBAAkB,EAAE;AAAA,YACvD,KAAK;AAAkB,qBAAO,KAAK,uBAAuB,EAAE;AAAA,YAC5D,KAAK;AAAkB,qBAAO,KAAK,aAAa,EAAE;AAAA,UACpD;AAAA,QACF,GAAG;AAEH,YAAI,CAAC,QAAQ;AACX,gBAAM,IAAI,MAAM,iBAAiB,IAAI,cAAc,EAAE,oCAAoC;AAAA,QAC3F;AAIA,YAAI,SAAS,YAAY,MAAM,OAAO,YAAY,OAAQ,OAAsB,MAAM;AACpF,gBAAM,IAAI;AAAA,YACR,6DAA8D,OAAsB,IAAI,uDAAkD,EAAE;AAAA,UAC9I;AAAA,QACF;AAKA,cAAM,cAAc,CAAC,cAAc,eAAe,eAAe,WAAW,eAAe,QAAQ;AACnG,cAAM,mBAAmB,CAAC,SAAS,WAAW,UAAU;AAQxD,cAAM,gBAAgB,CAAC,MAAW,WAAmB,QAAgB,sBAAsB,UAAe;AACxG,gBAAM,MAAM,CAAC,GAAW,eAAe,UACpC,SAAS,IAAM,uBAAuB,CAAC,eAAgB,IAAI,YAAY,KAAK,YAAa,IAAI;AAChG,gBAAM,MAAM,EAAE,GAAG,KAAK;AACtB,qBAAW,KAAK,aAAa;AAC3B,gBAAI,OAAO,IAAI,CAAC,MAAM,YAAY,IAAI,IAAI,CAAC,GAAG,MAAM,SAAS,EAAG,KAAI,CAAC,IAAI,IAAI,CAAC,IAAI;AAAA,UACpF;AACA,qBAAW,MAAM,kBAAkB;AACjC,gBAAI,MAAM,QAAQ,IAAI,EAAE,CAAC,GAAG;AAC1B,kBAAI,EAAE,IAAI,IAAI,EAAE,EAAE;AAAA,gBAAI,CAAC,MACrB,OAAO,GAAG,SAAS,YAAY,IAAI,EAAE,IAAI,IAAI,EAAE,GAAG,GAAG,MAAM,EAAE,OAAO,OAAO,IAAI;AAAA,cACjF;AAAA,YACF;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,aAAa,CAAC,MAAW,WAA6B;AAC1D,gBAAM,OAAiB,CAAC;AACxB,qBAAW,KAAK,YAAa,KAAI,KAAK,CAAC,MAAM,OAAQ,MAAK,KAAK,CAAC;AAChE,qBAAW,MAAM,kBAAkB;AACjC,aAAC,MAAM,QAAQ,KAAK,EAAE,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAQ,MAAc;AACvE,kBAAI,GAAG,SAAS,OAAQ,MAAK,KAAK,GAAG,EAAE,IAAI,CAAC,QAAQ;AAAA,YACtD,CAAC;AAAA,UACH;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,iBAAiB,CAAC,eAAsB,eAA6B;AACzE,cAAI,QAAQ,CAAC,GAAG,aAAa;AAC7B,gBAAM,eAAe,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,UAAU;AAC/E,qBAAW,aAAa,cAAc;AACpC,kBAAM,UAAU,UAAU;AAC1B,gBAAI,UAAU,WAAW,YAAY,UAAU,WAAW,MAAM;AAC9D,oBAAM,MAAM,MAAM,UAAU,OAAK,EAAE,eAAe,OAAO;AACzD,kBAAI,QAAQ,IAAI;AACd,sBAAM,YAAY,MACf,OAAO,OAAK,EAAE,eAAe,OAAO,EACpC,IAAI,QAAM,EAAE,GAAG,EAAE,YAAY,MAAM,WAAW,GAAG,OAAO,EAAE,EAAE,EAC5D,OAAO,OAAK,EAAE,KAAK,SAAS,CAAC;AAChC,oBAAI,UAAU,QAAQ;AACpB,wBAAM,IAAI;AAAA,oBACR,gCAAgC,OAAO,sCACrC,UAAU,IAAI,OAAK,GAAG,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,IAC7D;AAAA,kBACJ;AAAA,gBACF;AACA,sBAAM,OAAO,KAAK,CAAC;AACnB,wBAAQ,MAAM,IAAI,OAAK;AAAA,kBACrB,EAAE,aAAa,UAAU,EAAE,GAAG,GAAG,YAAY,EAAE,aAAa,EAAE,IAAI;AAAA,kBAClE;AAAA,kBACA;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF,WAAW,UAAU,WAAW,UAAU;AAMxC,oBAAM,UAAU,UAAU,iBAAiB;AAC3C,kBAAI,CAAC,SAAS;AACZ,sBAAM,WAAW,MACd,IAAI,QAAM,EAAE,GAAG,EAAE,YAAY,MAAM,WAAW,GAAG,OAAO,EAAE,EAAE,EAC5D,OAAO,OAAK,EAAE,KAAK,SAAS,CAAC;AAChC,oBAAI,SAAS,QAAQ;AACnB,0BAAQ;AAAA,oBACN,iBAAiB,OAAO,yBACtB,SAAS,IAAI,OAAK,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,IACjE,yCAAyC,UAAU,CAAC;AAAA,kBAExD;AAAA,gBACF;AAAA,cACF;AACA,sBAAQ,MAAM,IAAI,OAAK;AAAA,gBACrB,EAAE,cAAc,UAAU,EAAE,GAAG,GAAG,YAAY,EAAE,aAAa,EAAE,IAAI;AAAA,gBACnE;AAAA,gBACA;AAAA,gBACA;AAAA,cACF,CAAC;AACD,oBAAM,EAAE,QAAQ,QAAQ,cAAc,GAAG,UAAU,IAAI;AACvD,oBAAM,KAAK,SAAS;AAAA,YACtB,OAAO;AACL,oBAAM,MAAM,MAAM,UAAU,OAAK,EAAE,eAAe,OAAO;AACzD,kBAAI,QAAQ,IAAI;AACd,sBAAM,EAAE,QAAQ,QAAQ,GAAG,UAAU,IAAI;AACzC,sBAAM,GAAG,IAAI;AAAA,kBACX,GAAG,MAAM,GAAG;AAAA,kBACZ,GAAG;AAAA,gBACL;AAAA,cACF,OAAO;AACL,sBAAM,EAAE,QAAQ,QAAQ,GAAG,UAAU,IAAI;AACzC,sBAAM,KAAK,SAAS;AAAA,cACtB;AAAA,YACF;AAAA,UACF;AACA,iBAAO,MAAM,KAAK,CAAC,GAAG,MAAM,EAAE,aAAa,EAAE,UAAU;AAAA,QACzD;AAWA,cAAM,gBAAgB,CAAC,MACrB,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AACzD,cAAM,WAAW,CAAC,UAAeC,WAAoB;AACnD,cAAI,CAAC,cAAc,QAAQ,KAAK,CAAC,cAAcA,MAAK,EAAG,QAAOA,UAAS;AACvE,gBAAM,MAA+B,EAAE,GAAG,SAAS;AACnD,qBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQA,MAAK,GAAG;AAChD,gBAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,gBAAI,GAAG,IAAI,cAAc,KAAK,KAAK,cAAc,IAAI,GAAG,CAAC,IAAI,SAAS,IAAI,GAAG,GAAG,KAAK,IAAI;AAAA,UAC3F;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,eAAe,CAAC,iBAAwB,iBAA+B;AAC3E,gBAAM,SAAS,CAAC,GAAG,eAAe;AAClC,qBAAW,eAAe,cAAc;AACtC,kBAAM,MAAM,OAAO,UAAU,OAAK,EAAE,SAAS,YAAY,IAAI;AAC7D,gBAAI,QAAQ,IAAI;AACd,kBAAI,YAAY,WAAW,QAAQ,YAAY,WAAW,UAAU;AAClE,uBAAO,OAAO,KAAK,CAAC;AAAA,cACtB,OAAO;AACL,sBAAM,iBAAiB,OAAO,GAAG;AACjC,oBAAI,YAAY,eAAe,YAAY,CAAC,GAAG,eAAe,SAAS,IAAI,CAAC;AAC5E,oBAAI,YAAY,aAAa,MAAM,QAAQ,YAAY,SAAS,GAAG;AACjE,8BAAY,eAAe,WAAW,YAAY,SAAS;AAAA,gBAC7D;AACA,sBAAM,EAAE,WAAW,GAAG,GAAG,YAAY,IAAI;AACzC,uBAAO,GAAG,IAAI;AAAA,kBACZ,GAAG;AAAA,kBACH,GAAG;AAAA,kBACH,GAAI,YAAY,QAAQ,SAAY,EAAE,KAAK,SAAS,eAAe,KAAK,YAAY,GAAG,EAAE,IAAI,CAAC;AAAA,kBAC9F;AAAA,gBACF;AAAA,cACF;AAAA,YACF,OAAO;AACL,kBAAI,YAAY,WAAW,QAAQ,YAAY,WAAW,UAAU;AAClE,uBAAO,KAAK,WAAW;AAAA,cACzB;AAAA,YACF;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,kBAAkB,CAAC,UAAiBA,WAAwB;AAChE,gBAAM,SAAS,CAAC,GAAG,QAAQ;AAC3B,qBAAW,aAAaA,QAAO;AAC7B,kBAAM,MAAM,OAAO,UAAU,UAAQ,KAAK,SAAS,UAAU,IAAI;AACjE,gBAAI,QAAQ,IAAI;AACd,kBAAI,UAAU,WAAW,QAAQ,UAAU,WAAW,UAAU;AAC9D,uBAAO,OAAO,KAAK,CAAC;AAAA,cACtB,OAAO;AACL,uBAAO,GAAG,IAAI;AAAA,kBACZ,GAAG,OAAO,GAAG;AAAA,kBACb,GAAG;AAAA,kBACH,GAAI,UAAU,QAAQ,SAAY,EAAE,KAAK,SAAS,OAAO,GAAG,EAAE,KAAK,UAAU,GAAG,EAAE,IAAI,CAAC;AAAA,gBACzF;AAAA,cACF;AAAA,YACF,OAAO;AACL,kBAAI,UAAU,WAAW,QAAQ,UAAU,WAAW,UAAU;AAC9D,uBAAO,KAAK,SAAS;AAAA,cACvB;AAAA,YACF;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAMA,cAAM,kBAAkB,CAAC,UAAiBA,QAAc,UAAwC;AAC9F,gBAAM,SAAS,CAAC,GAAG,QAAQ;AAC3B,qBAAW,aAAaA,QAAO;AAC7B,kBAAM,MAAM,OAAO,UAAU,UAAQ,MAAM,IAAI,MAAM,MAAM,SAAS,CAAC;AACrE,gBAAI,QAAQ,IAAI;AACd,kBAAI,UAAU,WAAW,QAAQ,UAAU,WAAW,UAAU;AAC9D,uBAAO,OAAO,KAAK,CAAC;AAAA,cACtB,OAAO;AACL,uBAAO,GAAG,IAAI,EAAE,GAAG,OAAO,GAAG,GAAG,GAAG,UAAU;AAAA,cAC/C;AAAA,YACF,WAAW,UAAU,WAAW,QAAQ,UAAU,WAAW,UAAU;AACrE,qBAAO,KAAK,SAAS;AAAA,YACvB;AAAA,UACF;AACA,iBAAO,OAAO,IAAI,CAAC,EAAE,QAAQ,QAAQ,GAAG,KAAK,MAAM,IAAI;AAAA,QACzD;AAEA,cAAM,wBAAwB,CAAC,UAAiBA,WAAwB;AACtE,gBAAM,SAAS,CAAC,GAAG,QAAQ;AAC3B,qBAAW,aAAaA,QAAO;AAC7B,kBAAM,MAAM,OAAO,UAAU,UAAQ,KAAK,cAAc,UAAU,aAAa,KAAK,cAAc,UAAU,SAAS;AACrH,gBAAI,QAAQ,IAAI;AACd,kBAAI,UAAU,WAAW,QAAQ,UAAU,WAAW,UAAU;AAC9D,uBAAO,OAAO,KAAK,CAAC;AAAA,cACtB,OAAO;AACL,uBAAO,GAAG,IAAI;AAAA,kBACZ,GAAG,OAAO,GAAG;AAAA,kBACb,GAAG;AAAA,gBACL;AAAA,cACF;AAAA,YACF,OAAO;AACL,kBAAI,UAAU,WAAW,QAAQ,UAAU,WAAW,UAAU;AAC9D,uBAAO,KAAK,SAAS;AAAA,cACvB;AAAA,YACF;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,aAAa,CAAC,UAAe,WAAqB;AACtD,gBAAM,MAAM,EAAE,GAAG,SAAS;AAC1B,qBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,gBAAI,UAAU,UAAa,UAAU,MAAM;AACzC;AAAA,YACF;AACA,gBAAI,QAAQ,aAAa,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,SAAS,OAAO,GAAG;AAChF,kBAAI,SAAS,kBAAkB;AAC7B,oBAAI,UAAU,aAAa,SAAS,SAAS,KAAK;AAAA,cACpD,OAAO;AACL,oBAAI,UAAU,gBAAgB,SAAS,SAAS,KAAK;AAAA,cACvD;AAAA,YACF,WAAW,QAAQ,YAAY,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,SAAS,MAAM,GAAG;AACrF,kBAAI,SAAS,gBAAgB,SAAS,QAAQ,KAAK;AAAA,YACrD,WAAW,QAAQ,sBAAsB,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,SAAS,gBAAgB,GAAG;AACzG,kBAAI,mBAAmB,sBAAsB,SAAS,kBAAkB,KAAK;AAAA,YAC/E,WAAW,QAAQ,cAAc,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,SAAS,QAAQ,GAAG;AACzF,kBAAI,WAAW,gBAAgB,SAAS,UAAU,OAAO,OAAK,OAAO,GAAG,UAAU,CAAC;AAAA,YACrF,WAAW,QAAQ,eAAe,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,SAAS,SAAS,GAAG;AAC3F,kBAAI,YAAY,gBAAgB,SAAS,WAAW,OAAO,QAAM,GAAG,IAAI,KAAK,IAAI,IAAI,SAAS,IAAI,IAAI,MAAM,EAAE;AAAA,YAChH,YAAY,QAAQ,WAAW,QAAQ,mBAAmB,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,SAAS,GAAG,CAAC,GAAG;AAC9G,kBAAI,GAAG,IAAI,gBAAgB,SAAS,GAAG,GAAG,OAAO,CAAC,MAA0C,GAAG,GAAG,KAAK,IAAI,GAAG,SAAS,EAAE,EAAE;AAAA,YAC7H,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,kBAAI,GAAG,IAAI;AAAA,YACb,WAAW,OAAO,UAAU,YAAY,OAAO,SAAS,GAAG,MAAM,YAAY,SAAS,GAAG,MAAM,MAAM;AACnG,kBAAI,GAAG,IAAI,WAAW,SAAS,GAAG,GAAG,KAAK;AAAA,YAC5C,OAAO;AACL,kBAAI,GAAG,IAAI;AAAA,YACb;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAQA,cAAM,mBAAmB,CAAC,MAAgD;AACxE,cAAI,SAAS,SAAU,QAAO;AAC9B,gBAAM,SAAS,KAAK,eAAe,EAAE;AACrC,cAAI,CAAC,OAAQ,QAAO;AACpB,gBAAM,IAAI,CAAC,QACT,OAAO,QAAQ,WAAW,UAAU,KAAK,QAAQ,KAAK,cAAc,IAAI;AAC1E,gBAAM,MAA2B,EAAE,GAAG,EAAE;AACxC,kBAAQ,MAAM;AAAA,YACZ,KAAK,aAAa;AAChB,oBAAM,aAAa,CAAC,EAAE,IAAI,eAAgB,OAAyB;AACnE,oBAAM,eAAe,aAAa,KAAK;AACvC,oBAAM,KAAK,CAAC,QACV,OAAO,QAAQ,WAAW,UAAU,KAAK,cAAc,KAAK,cAAc,IAAI;AAChF,kBAAI,MAAM,QAAQ,IAAI,gBAAgB,GAAG;AACvC,oBAAI,mBAAmB,IAAI,iBAAiB,IAAI,CAAC,QAAa;AAAA,kBAC5D,GAAG;AAAA,kBACH,GAAI,OAAO,IAAI,cAAc,WAAW,EAAE,WAAW,GAAG,GAAG,SAAS,EAAE,IAAI,CAAC;AAAA,kBAC3E,GAAI,OAAO,IAAI,cAAc,WAAW,EAAE,WAAW,GAAG,GAAG,SAAS,EAAE,IAAI,CAAC;AAAA,gBAC7E,EAAE;AAAA,cACJ;AACA,kBAAI,MAAM,QAAQ,IAAI,SAAS,GAAG;AAChC,oBAAI,YAAY,IAAI,UAAU,IAAI,CAAC,OAChC,OAAO,IAAI,cAAc,WAAW,EAAE,GAAG,IAAI,WAAW,GAAG,GAAG,SAAS,EAAE,IAAI,EAAG;AAAA,cACrF;AACA;AAAA,YACF;AAAA,YACA,KAAK;AACH,kBAAI,OAAO,IAAI,cAAc,SAAU,KAAI,YAAY,EAAE,IAAI,SAAS;AACtE,kBAAI,MAAM,QAAQ,IAAI,IAAI,EAAG,KAAI,OAAO,IAAI,KAAK,IAAI,CAAC;AACtD,kBAAI,MAAM,QAAQ,IAAI,SAAS,EAAG,KAAI,YAAY,IAAI,UAAU,IAAI,CAAC;AACrE,kBAAI,MAAM,QAAQ,IAAI,QAAQ,GAAG;AAC/B,oBAAI,WAAW,IAAI,SAAS,IAAI,CAAC,MAC9B,OAAO,GAAG,cAAc,WAAW,EAAE,GAAG,GAAG,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,CAAE;AAAA,cAChF;AACA;AAAA,YACF,KAAK;AACH,kBAAI,OAAO,IAAI,cAAc,SAAU,KAAI,YAAY,EAAE,IAAI,SAAS;AACtE;AAAA,YACF,KAAK;AACH,kBAAI,OAAO,IAAI,aAAa,SAAU,KAAI,WAAW,EAAE,IAAI,QAAQ;AACnE,kBAAI,MAAM,QAAQ,IAAI,OAAO,GAAG;AAC9B,oBAAI,UAAU,IAAI,QAAQ,IAAI,CAAC,MAC5B,MAAM,QAAQ,GAAG,SAAS,IACvB;AAAA,kBACA,GAAG;AAAA,kBACH,WAAW,EAAE,UAAU,IAAI,CAAC,MACzB,OAAO,GAAG,oBAAoB,WAAW,EAAE,GAAG,GAAG,iBAAiB,EAAE,EAAE,eAAe,EAAE,IAAI,CAAE;AAAA,gBAClG,IACE,CAAE;AAAA,cACV;AACA;AAAA,YACF,KAAK;AACH,kBAAI,OAAO,IAAI,cAAc,SAAU,KAAI,YAAY,EAAE,IAAI,SAAS;AACtE,kBAAI,OAAO,IAAI,UAAU,SAAU,KAAI,QAAQ,EAAE,IAAI,KAAK;AAC1D;AAAA,UACJ;AACA,iBAAO;AAAA,QACT;AAEA,cAAM,eAAe,WAAW,QAAQ,iBAAiB,KAAK,CAAC;AAC/D,qBAAa,aAAY,oBAAI,KAAK,GAAE,YAAY;AAMhD,YAAI,SAAS,oBAAoB,MAAM,QAAQ,aAAa,OAAO,GAAG;AACpE,gBAAM,cAAwB,CAAC;AAC/B,qBAAW,KAAK,aAAa,SAAS;AACpC,gBAAI,KAAK,MAAM,QAAQ,EAAE,SAAS,EAAG,aAAY,KAAK,GAAG,uBAAuB,OAAO,EAAE,IAAI,GAAG,EAAE,SAAS,CAAC;AAAA,UAC9G;AACA,cAAI,YAAY,QAAQ;AACtB,kBAAM,IAAI,MAAM;AAAA,IAAiE,YAAY,KAAK,MAAM,CAAC,EAAE;AAAA,UAC7G;AAAA,QACF;AAIA,cAAM,OAAwB;AAAA,UAC5B,qBAAqB,OAAO,UAAU,eAAe,KAAK,OAAO,QAAQ;AAAA,QAC3E;AAEA,gBAAQ,MAAM;AAAA,UACZ,KAAK;AAAkB,iBAAK,eAAe,YAAY;AAAG;AAAA,UAC1D,KAAK;AAAkB,iBAAK,kBAAkB,YAAY;AAAG;AAAA,UAC7D,KAAK;AAAkB,oBAAQ,KAAK,GAAG,KAAK,kBAAkB,cAAc,IAAI,CAAC;AAAG;AAAA,UACpF,KAAK;AAAkB,oBAAQ,KAAK,GAAG,KAAK,kBAAkB,cAAc,IAAI,CAAC;AAAG;AAAA,UACpF,KAAK;AAAkB,oBAAQ,KAAK,GAAG,KAAK,uBAAuB,cAAc,IAAI,CAAC;AAAG;AAAA,UACzF,KAAK;AAAkB,oBAAQ,KAAK,GAAG,KAAK,aAAa,YAAY,CAAC;AAAG;AAAA,QAC3E;AAEA,eAAO;AAAA,MACT;AAAA,IACF;AAMA,IAAM,aAAa,oBAAI,IAA2B;AAAA;AAAA;;;ACrsElD;AAAA;AAAA;AAAA;AAuBA,SAAS,uBAAuB,SAAiB,KAAuB;AACtE,MAAI,CAAI,eAAW,OAAO,EAAG,QAAO,CAAC;AACrC,QAAM,YAAiB,gBAAS,OAAO,EAAE,YAAY;AACrD,QAAM,eAAe,oBAAI,IAAI;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,MAAI,aAAa,IAAI,SAAS,EAAG,QAAO,CAAC;AAEzC,QAAM,UAAa,gBAAY,SAAS,EAAE,eAAe,KAAK,CAAC;AAC/D,QAAM,QAAkB,CAAC;AACzB,aAAW,SAAS,SAAS;AAC3B,UAAM,WAAgB,YAAK,SAAS,MAAM,IAAI;AAC9C,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,KAAK,GAAG,uBAAuB,UAAU,GAAG,CAAC;AAAA,IACrD,WAAW,MAAM,OAAO,KAAK,MAAM,KAAK,SAAS,GAAG,GAAG;AACrD,YAAM,KAAK,QAAQ;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,YAA8B;AACrD,MAAI,QAAQ,kBAAkB,IAAI,UAAU;AAC5C,MAAI,CAAC,OAAO;AACV,YAAQ,CAAC;AACT,UAAM,SAAc,YAAK,YAAY,KAAK;AAC1C,UAAM,eAAoB,YAAK,YAAY,YAAY;AAEvD,QAAI,YAAY;AAChB,QAAI,WAAW,MAAM,GAAG;AACtB,kBAAY;AAAA,IACd,WAAW,WAAW,YAAY,GAAG;AACnC,kBAAY;AAAA,IACd,WAAW,eAAe,eAAe,GAAG;AAE1C,wBAAkB,IAAI,YAAY,CAAC,CAAC;AACpC,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,aAAa,CAAC,OAAO,OAAO,QAAQ,OAAO,QAAQ,OAAO,OAAO,MAAM,QAAQ,OAAO,SAAS,OAAO,UAAU,OAAO,QAAQ,MAAM;AAC3I,eAAW,OAAO,YAAY;AAC5B,YAAM,KAAK,GAAG,uBAAuB,WAAW,GAAG,CAAC;AAAA,IACtD;AACA,UAAM,UAAU,eAAe;AAC/B,YAAQ,MAAM,IAAI,OAAU,gBAAS,SAAS,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AACpE,sBAAkB,IAAI,YAAY,KAAK;AAAA,EACzC;AACA,SAAO;AACT;AAEA,SAAS,4BAA4B,MAAqB,YAAkC;AAC1F,MAAI;AACF,UAAM,aAAa,8BAA8B,KAAK,SAAS,KAAK,eAAe;AACnF,UAAM,QAAQ,gBAAgB,UAAU;AACxC,QAAI,MAAM,WAAW,EAAG,QAAO;AAE/B,UAAM,iBAAiB,KAAK,GAAG,MAAM,IAAI,EAAE,IAAI,KAAK,KAAK;AACzD,UAAM,gBAAgB,KAAK,UAAU,MAAM,IAAI,EAAE,IAAI,KAAK,KAAK;AAE/D,QAAI,YAAY;AAChB,QAAI,UAAU,WAAW,GAAG,aAAa,GAAG,GAAG;AAC7C,kBAAY,UAAU,MAAM,cAAc,SAAS,CAAC;AAAA,IACtD;AAEA,UAAM,aAAa,oBAAI,IAAY;AACnC,eAAW,IAAI,UAAU,YAAY,CAAC;AACtC,eAAW,IAAI,UAAU,QAAQ,MAAM,GAAG,EAAE,YAAY,CAAC;AACzD,eAAW,IAAI,eAAe,YAAY,CAAC;AAC3C,eAAW,IAAI,eAAe,QAAQ,MAAM,GAAG,EAAE,YAAY,CAAC;AAC9D,eAAW,IAAI,KAAK,cAAc,YAAY,CAAC;AAE/C,QAAI,WAA0B;AAC9B,QAAI,YAAY;AAEhB,eAAW,KAAK,OAAO;AACrB,YAAM,MAAW,eAAQ,CAAC;AAC1B,YAAM,OAAY,gBAAS,GAAG,GAAG,EAAE,YAAY;AAC/C,UAAI,WAAW,IAAI,IAAI,GAAG;AACxB,YAAI,QAAQ;AACZ,cAAM,iBAAiB,EAAE,YAAY;AAGrC,cAAM,cAAc,IAAI,cAAc,YAAY,CAAC;AACnD,cAAM,cAAc,IAAI,cAAc,QAAQ,MAAM,GAAG,EAAE,YAAY,CAAC;AACtE,cAAM,2BAA2B,cAC9B,MAAM,MAAM,EACZ,KAAK,CAAC,QAAgB,IAAI,UAAU,KAAK,eAAe,SAAS,IAAI,IAAI,YAAY,CAAC,GAAG,CAAC;AAE7F,cAAM,oBAAoB,eAAe,SAAS,WAAW,KACnC,eAAe,SAAS,WAAW,KACnC;AAE1B,YAAI,mBAAmB;AACrB,mBAAS;AAAA,QACX;AAGA,YAAI,0BAA0B;AAC9B,mBAAW,YAAY,YAAY;AACjC,cAAI,SAAS,OAAO,KAAK,UAAW;AACpC,gBAAM,qBAAqB,SAAS,GAAG,MAAM,IAAI,EAAE,IAAI,KAAK,SAAS;AACrE,gBAAM,gBAAgB,IAAI,mBAAmB,YAAY,CAAC;AAC1D,gBAAM,gBAAgB,IAAI,mBAAmB,QAAQ,MAAM,GAAG,EAAE,YAAY,CAAC;AAC7E,gBAAM,oBAAoB,mBACvB,MAAM,MAAM,EACZ,KAAK,CAAC,QAAgB,IAAI,UAAU,KAAK,eAAe,SAAS,IAAI,IAAI,YAAY,CAAC,GAAG,CAAC;AAE7F,cAAI,eAAe,SAAS,aAAa,KACrC,eAAe,SAAS,aAAa,KACrC,mBAAmB;AACrB,sCAA0B;AAC1B;AAAA,UACF;AAAA,QACF;AACA,YAAI,yBAAyB;AAC3B;AAAA,QACF;AAGA,cAAM,mBAAmB,SAAS,UAAU,YAAY,KAAK,SAAS,UAAU,QAAQ,MAAM,GAAG,EAAE,YAAY;AAC/G,YAAI,kBAAkB;AACpB,mBAAS;AAAA,QACX;AAGA,cAAM,YAAY,SAAS,eAAe,YAAY,KAAK,SAAS,eAAe,QAAQ,MAAM,GAAG,EAAE,YAAY;AAClH,YAAI,WAAW;AACb,mBAAS;AAAA,QACX;AAGA,cAAM,sBAAsB,oBAAoB,UAAU,YAAY,MAAM,KAAK,cAAc,YAAY;AAG3G,YAAI,CAAC,qBAAqB,CAAC,uBAAuB,CAAC,WAAW;AAC5D;AAAA,QACF;AAGA,YAAI,eAAe,WAAW,MAAM,KAAK,eAAe,SAAS,OAAO,KACpE,eAAe,WAAW,aAAa,KAAK,eAAe,SAAS,cAAc,GAAG;AACvF,mBAAS;AAAA,QACX;AAGA,YAAI,SAAS,KAAK,cAAc,YAAY,GAAG;AAC7C,mBAAS;AAAA,QACX;AAEA,YAAI,QAAQ,WAAW;AACrB,sBAAY;AACZ,qBAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQA,SAAS,UAAU,MAAc,MAAM,KAAa;AAClD,QAAM,QAAQ,KAAK,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAC7C,QAAM,SAAS,MAAM,QAAQ,IAAI;AACjC,QAAM,gBAAgB,SAAS,IAAI,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI;AAChE,MAAI,cAAc,UAAU,IAAK,QAAO;AACxC,SAAO,GAAG,cAAc,MAAM,GAAG,MAAM,CAAC,EAAE,QAAQ,CAAC;AACrD;AAQA,SAAS,qBACP,OACA,eACA,cACQ;AACR,QAAM,SAAS,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,aAAa,IAAI,EAAE,OAAO,CAAC;AAC3E,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,KAAK,QAAQ;AACtB,UAAM,IAAI,aAAa,IAAI,EAAE,OAAQ;AACrC,UAAM,WAAW,cAAc,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;AACtG,QAAI,OAAO,OAAO,EAAE,EAAE,uBAAkB,EAAE,OAAO,iBAAiB,EAAE,IAAI,MAAM,EAAE,QAAQ;AACxF,QAAI,SAAS,SAAS,GAAG;AACvB,cAAQ,uCAAuC,SAAS,KAAK,IAAI,CAAC;AAAA,IACpE;AACA,UAAM,KAAK,IAAI;AAAA,EACjB;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAKO,SAAS,uBAAsC;AACpD,oBAAkB,MAAM;AAExB,QAAM,SAAS,eAAe;AAC9B,MAAI,CAAC,OAAQ,QAAO,CAAC;AASrB,QAAM,UAAU,CAAC,OAAwB,CAAC,GAAG,SAAS,IAAI;AAC1D,QAAM,aAAa,mBAAmB,EAAE,OAAO,CAAC,MAAM,QAAQ,EAAE,EAAE,CAAC;AACnE,QAAM,aAAa,mBAAmB,EAAE,OAAO,CAAC,MAAM,QAAQ,EAAE,EAAE,KAAK,QAAQ,EAAE,SAAS,CAAC;AAC3F,QAAM,aAAa,mBAAmB;AACtC,QAAM,kBAAkB,wBAAwB;AAGhD,QAAM,eAAe,IAAI,IAAI,oBAAoB,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAExE,QAAM,SAAS,kBAAkB;AACjC,QAAM,gBAAgB,OAAO,QAC1B,OAAO,CAAC,MAAM,EAAE,aAAa,MAAM,EAAE,OAAO,EAC5C,IAAI,CAAC,MAAM,OAAO,MAAM,WAAW,IAAI,EAAE,IAAI;AAEhD,QAAM,SAAwB,CAAC;AAG/B,SAAO,KAAK;AAAA,IACV,IAAI;AAAA,IACJ,MAAM,GAAG,OAAO,IAAI;AAAA,IACpB,aAAa,wBAAwB,OAAO,IAAI,4CAAuC,UAAU,OAAO,MAAM,CAAC;AAAA,IAC/G,UAAU;AAAA,IACV,gBAAgB;AAAA,IAChB,YAAY,CAAC,eAAe;AAAA,IAC5B,WAAW,CAAC,IAAI;AAAA,IAChB,YAAY,CAAC,eAAe;AAAA,IAC5B,MAAM,CAAC,aAAa,UAAU,KAAK;AAAA,IACnC,cAAc,WAAW,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,QAAQ;AAAA,IACnD,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO;AAAA,EACpB,CAAC;AAGD,aAAW,OAAO,YAAY;AAM5B,QAAI,IAAI,aAAa;AACnB,YAAM,gBAAqB,gBAAS,eAAe,GAAG,iBAAiB,IAAI,EAAE,CAAC,EAAE,QAAQ,OAAO,GAAG;AAClG,aAAO,KAAK;AAAA,QACV,IAAI,GAAG,IAAI,EAAE;AAAA,QACb,MAAM,GAAG,IAAI,IAAI;AAAA,QACjB,aAAa,uBAAuB,IAAI,EAAE,2BAA2B,IAAI,WAAW,uGAAkG,IAAI,WAAW;AAAA,QACrM,UAAU;AAAA,QACV,gBAAgB,+DAA+D,IAAI,EAAE;AAAA,QACrF,YAAY,IAAI;AAAA,QAChB,YAAY,CAAC,aAAa;AAAA,QAC1B,WAAW,CAAC,IAAI;AAAA,QAChB,YAAY,CAAC,aAAa;AAAA,QAC1B,MAAM,CAAC,SAAS,cAAc,YAAY,KAAK;AAAA,QAC/C,cAAc,CAAC;AAAA,QACf,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW,IAAI;AAAA,QACf,WAAW,IAAI;AAAA,MACjB,CAAC;AACD;AAAA,IACF;AAEA,UAAM,gBAAgB,WAAW,OAAO,CAAC,MAAM,EAAE,cAAc,IAAI,EAAE;AAErE,UAAM,aAAuB,CAAC;AAE9B,eAAW,KAAU,gBAAS,eAAe,GAAG,iBAAiB,IAAI,EAAE,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AAC7F,eAAW,KAAK,eAAe;AAC7B,iBAAW,KAAU,gBAAS,eAAe,GAAG,iBAAiB,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA,IACrG;AAEA,QAAI,CAAC,OAAO,MAAM,+BAA+B;AAI/C,iBAAW,QAAQ,eAAe;AAEhC,cAAM,iBAAiB,WAAW,OAAO,CAAC,MAAM,EAAE,cAAc,KAAK,EAAE;AACvE,cAAM,mBAAmB,eAAe,IAAI,CAAC,MAAM,EAAE,EAAE;AAGvD,cAAM,YAAY,gBAAgB,OAAO,CAAC,SAAS,iBAAiB,SAAS,KAAK,QAAQ,CAAC;AAE3F,YAAI,oBAAoB;AACxB,mBAAW,QAAQ,WAAW;AAC5B,cAAI,KAAK,YAAY;AACnB,gCAAoB;AACpB,gBAAI,CAAC,WAAW,SAAS,KAAK,UAAU,EAAG,YAAW,KAAK,KAAK,UAAU;AAAA,UAC5E;AAAA,QACF;AAOA,YAAI,CAAC,mBAAmB;AACtB,gBAAM,WAAW,4BAA4B,MAAM,UAAU;AAC7D,cAAI,YAAY,CAAC,WAAW,SAAS,QAAQ,GAAG;AAC9C,uBAAW,KAAK,QAAQ;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,eAAyB,CAAC;AAC9B,QAAI,OAAO,MAAM,+BAA+B;AAC9C,qBAAe,cAAc,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,cAAc;AAAA,IAC/D,OAAO;AAEL,YAAM,gBAAgB,oBAAI,IAAY;AACtC,iBAAW,KAAK,eAAe;AAC7B,mBAAW,SAAS,EAAE,WAAW;AAC/B,gBAAM,UAAU,WAAW,KAAK,CAAC,UAAU,MAAM,OAAO,KAAK;AAC7D,cAAI,WAAW,QAAQ,cAAc,IAAI,IAAI;AAC3C,0BAAc,IAAI,GAAG,QAAQ,SAAS,QAAQ;AAAA,UAChD;AAAA,QACF;AAAA,MACF;AACA,qBAAe,MAAM,KAAK,aAAa;AAAA,IACzC;AAEA,WAAO,KAAK;AAAA,MACV,IAAI,GAAG,IAAI,EAAE;AAAA,MACb,MAAM,GAAG,IAAI,IAAI;AAAA,MACjB,aAAa,YAAY,IAAI,EAAE,eAAe,UAAU,IAAI,WAAW,CAAC;AAAA,MACxE,UAAU;AAAA,MACV,gBAAgB,kDAAkD,IAAI,EAAE;AAAA,MACxE,YAAY,IAAI;AAAA,MAChB;AAAA,MACA,WAAW,CAAC,IAAI;AAAA,MAChB,YAAY;AAAA,MACZ,MAAM,CAAC,SAAS,UAAU,KAAK;AAAA,MAC/B;AAAA,MACA,iBAAiB,qBAAqB,eAAe,YAAY,YAAY;AAAA,MAC7E,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,WAAW,IAAI;AAAA,MACf,WAAW,IAAI;AAAA,IACjB,CAAC;AAAA,EACH;AAGA,MAAI,OAAO,MAAM,+BAA+B;AAC9C,eAAW,QAAQ,YAAY;AAE7B,YAAM,iBAAiB,WAAW,OAAO,CAAC,MAAM,EAAE,cAAc,KAAK,EAAE;AACvE,YAAM,mBAAmB,eAAe,IAAI,CAAC,MAAM,EAAE,EAAE;AAGvD,YAAM,YAAY,gBAAgB,OAAO,CAAC,SAAS,iBAAiB,SAAS,KAAK,QAAQ,CAAC;AAE3F,YAAM,aAAuB,CAAC;AAC9B,iBAAW,QAAQ,WAAW;AAC5B,YAAI,KAAK,WAAY,YAAW,KAAK,KAAK,UAAU;AAAA,MACtD;AAEA,UAAI,WAAW,WAAW,GAAG;AAC3B,cAAM,WAAW,4BAA4B,MAAM,UAAU;AAC7D,YAAI,UAAU;AACZ,qBAAW,KAAK,QAAQ;AAAA,QAC1B;AAAA,MACF;AAEA,YAAM,eAAe,KAAK,UAAU,IAAI,CAAC,UAAU,GAAG,KAAK,cAAc;AAGzE,YAAM,YAAY;AAAA,QACX,gBAAS,eAAe,GAAG,SAAS,YAAY,CAAC,EAAE,QAAQ,OAAO,GAAG;AAAA,QACrE,gBAAS,eAAe,GAAG,iBAAiB,KAAK,IAAI,KAAK,SAAS,CAAC,EAAE,QAAQ,OAAO,GAAG;AAAA,QAC7F,GAAG,eAAe,IAAI,CAAC,MAAW,gBAAS,eAAe,GAAG,iBAAiB,EAAE,IAAI,KAAK,EAAE,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA,QACjH,GAAG,UAAU,IAAI,CAAC,SAAc,gBAAS,eAAe,GAAG,sBAAsB,KAAK,IAAI,KAAK,QAAQ,CAAC,EAAE,QAAQ,OAAO,GAAG,CAAC;AAAA,MAC/H;AAEA,aAAO,KAAK;AAAA,QACV,IAAI,GAAG,KAAK,EAAE;AAAA,QACd,MAAM,GAAG,KAAK,IAAI;AAAA,QAClB,aAAa,gCAAgC,KAAK,IAAI,KAAK,KAAK,aAAa;AAAA,QAC7E,UAAU;AAAA,QACV,gBAAgB,kDAAkD,KAAK,EAAE;AAAA,QACzE,YAAY,KAAK;AAAA,QACjB;AAAA,QACA;AAAA,QACA,YAAY;AAAA,QACZ,MAAM,CAAC,eAAe,aAAa,OAAO,KAAK,cAAc,YAAY,CAAC;AAAA,QAC1E;AAAA,QACA,iBAAiB,qBAAqB,CAAC,IAAI,GAAG,YAAY,YAAY;AAAA,QACtE,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,WAAW,KAAK;AAAA,QAChB,WAAW,KAAK;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,EACF;AAIA,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,aAAW,OAAO,mBAAmB,EAAE,SAAS;AAC9C,WAAO,KAAK;AAAA,MACV,IAAI,GAAG,IAAI,EAAE;AAAA,MACb,MAAM,GAAG,IAAI,QAAQ,IAAI,EAAE;AAAA,MAC3B,aAAa,IAAI,cAAc,UAAU,IAAI,WAAW,IAAI,sCAAsC,IAAI,EAAE;AAAA,MACxG,UAAU;AAAA,MACV,gBAAgB;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,WAAW,CAAC,IAAI;AAAA,MAChB,YAAY,IAAI;AAAA,MAChB,MAAM,CAAC,SAAS,QAAQ;AAAA,MACxB,cAAc,CAAC;AAAA,MACf,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AA5dA,IAAAC,QACAC,KAoBM;AArBN;AAAA;AAAA;AAAA,IAAAD,SAAsB;AACtB,IAAAC,MAAoB;AAEpB;AACA;AACA,IAAAC;AAaA;AAGA,IAAM,oBAAoB,oBAAI,IAAsB;AAAA;AAAA;;;ACrBpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CO,SAAS,UAAU,SAA2B;AACnD,QAAM,eAAoB,eAAQ,OAAO;AAEzC,QAAM,UAAU,IAAI,aAA+B;AACjD,UAAM,UAAe,YAAK,cAAc,MAAM;AAC9C,UAAM,aAAkB,YAAK,cAAc,SAAS;AACpD,UAAM,OAAO,CAAI,eAAW,OAAO,KAAQ,eAAW,UAAU,IAAI,aAAa;AACjF,WAAY,YAAK,MAAM,GAAG,QAAQ;AAAA,EACpC;AACA,QAAM,WAAW,MAAc;AAC7B,QAAI;AACF,YAAM,aAAa,QAAQ,cAAc;AACzC,UAAI,WAAW,UAAU,GAAG;AAC1B,cAAM,MAAM,aAAa,UAAU;AACnC,YAAI,OAAO,IAAI,SAAS,IAAI,MAAM,UAAU;AAC1C,iBAAY,eAAQ,cAAc,IAAI,MAAM,QAAQ;AAAA,QACtD;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AACA,WAAO,QAAQ,OAAO;AAAA,EACxB;AACA,SAAO;AAAA,IACL,MAAM,MAAM,QAAQ;AAAA,IACpB,eAAe,MAAM,QAAQ,cAAc;AAAA,IAC3C,gBAAgB,MAAM,QAAQ,eAAe;AAAA,IAC7C,cAAc,MAAM,QAAQ,WAAW;AAAA,IACvC,UAAU,MAAM,QAAQ,OAAO;AAAA,IAC/B,SAAS,MAAM,QAAQ,MAAM;AAAA,IAC7B,cAAc,MAAM,QAAQ,WAAW;AAAA,IACvC,YAAY,MAAM,QAAQ,SAAS;AAAA,IACnC,kBAAkB,MAAM,QAAQ,WAAW,YAAY;AAAA,IACvD,uBAAuB,MAAM,QAAQ,WAAW,iBAAiB;AAAA,IACjE,kBAAkB,MAAM,QAAQ,WAAW,YAAY;AAAA,IACvD,sBAAsB,MAAM,QAAQ,WAAW,iBAAiB;AAAA,IAChE;AAAA,IACA,aAAa,MAAW,YAAK,SAAS,GAAG,aAAa;AAAA,IACtD,oBAAoB,MAAW,YAAK,SAAS,GAAG,YAAY;AAAA,IAC5D,oBAAoB,MAAW,YAAK,SAAS,GAAG,YAAY;AAAA,IAC5D,oBAAoB,MAAW,YAAK,SAAS,GAAG,YAAY;AAAA,IAC5D,yBAAyB,MAAW,YAAK,SAAS,GAAG,iBAAiB;AAAA,IACtE,eAAe,MAAW,YAAK,SAAS,GAAG,OAAO;AAAA,EACpD;AACF;AAgCO,SAAS,uBAAgC;AAC9C,SAAO,WAAW,SAAS,KAAK,CAAC,KAAK,WAAW,SAAS,cAAc,CAAC;AAC3E;AAKO,SAAS,2BAAiC;AAC/C,MAAI,CAAC,qBAAqB,GAAG;AAC3B,UAAM,IAAI,2BAA2B;AAAA,EACvC;AACF;AAKO,SAAS,oBAAmC;AACjD,2BAAyB;AACzB,QAAM,MAAM,aAAa,SAAS,cAAc,CAAC;AACjD,MAAI;AACF,WAAO,oBAAoB,MAAM,GAAG;AAAA,EACtC,SAAS,GAAY;AACnB,UAAM,IAAI,YAAY,8BAA8B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AAAA,EAClG;AACF;AAKO,SAAS,kBAAkB,QAA6B;AAC7D,gBAAc,SAAS,cAAc,GAAG,MAAM;AAChD;AAYO,SAAS,eAAyB;AACvC,2BAAyB;AACzB,MAAI,CAAC,WAAW,SAAS,YAAY,CAAC,EAAG,QAAO,oBAAoB;AACpE,QAAM,EAAE,sBAAAC,sBAAqB,IAAI;AACjC,SAAO;AAAA,IACL,eAAe;AAAA,IACf,QAAQA,sBAAqB;AAAA,IAC7B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACF;AASO,SAAS,qBAAqC;AACnD,2BAAyB;AACzB,MAAI,CAAC,WAAW,SAAS,eAAe,CAAC,EAAG,QAAO,0BAA0B;AAC7E,QAAM,MAAM,aAAa,SAAS,eAAe,CAAC;AAClD,MAAI,CAAC,IAAK,QAAO,0BAA0B;AAC3C,SAAO,qBAAqB,MAAM,GAAG;AACvC;AAEO,SAAS,mBAAmB,QAA8B;AAC/D,gBAAc,SAAS,eAAe,GAAG,MAAM;AACjD;AAjMA,IAAAC,KACAC,QA4Fa;AA7Fb;AAAA;AAAA;AAAA,IAAAD,MAAoB;AACpB,IAAAC,SAAsB;AACtB;AACA;AACA;AACA;AAwFO,IAAM,WAAqB;AAAA,MAChC,MAAM,MAAM,UAAU,eAAe,CAAC,EAAE,KAAK;AAAA,MAC7C,eAAe,MAAM,UAAU,eAAe,CAAC,EAAE,cAAc;AAAA,MAC/D,gBAAgB,MAAM,UAAU,eAAe,CAAC,EAAE,eAAe;AAAA,MACjE,cAAc,MAAM,UAAU,eAAe,CAAC,EAAE,aAAa;AAAA,MAC7D,UAAU,MAAM,UAAU,eAAe,CAAC,EAAE,SAAS;AAAA,MACrD,SAAS,MAAM,UAAU,eAAe,CAAC,EAAE,QAAQ;AAAA,MACnD,cAAc,MAAM,UAAU,eAAe,CAAC,EAAE,aAAa;AAAA,MAC7D,YAAY,MAAM,UAAU,eAAe,CAAC,EAAE,WAAW;AAAA,MACzD,kBAAkB,MAAM,UAAU,eAAe,CAAC,EAAE,iBAAiB;AAAA,MACrE,uBAAuB,MAAM,UAAU,eAAe,CAAC,EAAE,sBAAsB;AAAA,MAC/E,kBAAkB,MAAM,UAAU,eAAe,CAAC,EAAE,iBAAiB;AAAA,MACrE,sBAAsB,MAAM,UAAU,eAAe,CAAC,EAAE,qBAAqB;AAAA,MAC7E,UAAU,MAAM,UAAU,eAAe,CAAC,EAAE,SAAS;AAAA,MACrD,aAAa,MAAM,UAAU,eAAe,CAAC,EAAE,YAAY;AAAA,MAC3D,oBAAoB,MAAM,UAAU,eAAe,CAAC,EAAE,mBAAmB;AAAA,MACzE,oBAAoB,MAAM,UAAU,eAAe,CAAC,EAAE,mBAAmB;AAAA,MACzE,oBAAoB,MAAM,UAAU,eAAe,CAAC,EAAE,mBAAmB;AAAA,MACzE,yBAAyB,MAAM,UAAU,eAAe,CAAC,EAAE,wBAAwB;AAAA,MACnF,eAAe,MAAM,UAAU,eAAe,CAAC,EAAE,cAAc;AAAA,IACjE;AAAA;AAAA;;;ACjHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBA,SAAS,IAAI,GAAmB;AAC9B,SAAY,gBAAS,QAAQ,IAAI,GAAG,CAAC,EAAE,QAAQ,OAAO,GAAG;AAC3D;AAGO,SAAS,yBAAmC;AACjD,QAAM,aAAa,mBAAmB;AACtC,QAAM,aAAa,mBAAmB;AAEtC,SAAO,WAAW,IAAI,CAAC,QAAQ;AAC7B,UAAM,aAAa;AAAA,MACjB,IAAI,iBAAiB,IAAI,EAAE,CAAC;AAAA,MAC5B,GAAG,WACA,OAAO,CAAC,MAAM,EAAE,cAAc,IAAI,EAAE,EACpC,IAAI,CAAC,MAAM,IAAI,iBAAiB,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;AAAA,IACnD;AACA,WAAO;AAAA,MACL,IAAI,IAAI;AAAA,MACR,MAAM,IAAI;AAAA,MACV,aAAa,IAAI;AAAA,MACjB,SAAS,IAAI;AAAA,MACb;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAGO,SAAS,0BAAoC;AAClD,SAAO,mBAAmB,EAAE;AAC9B;AAGO,SAAS,iBAA2B;AACzC,SAAO,CAAC,GAAG,uBAAuB,GAAG,GAAG,wBAAwB,CAAC;AACnE;AAEO,SAAS,WAAW,IAAgC;AACzD,SAAO,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACjD;AAMO,SAAS,sBAAsB,QAAsB;AAC1D,QAAM,SAAS,mBAAmB;AAClC,MAAI,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,EAAE,GAAG;AAClD,UAAM,IAAI,YAAY,2BAA2B,OAAO,EAAE,yCAAyC;AAAA,EACrG;AACA,MAAI,uBAAuB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,OAAO,EAAE,GAAG;AAC5D,UAAM,IAAI,YAAY,cAAc,OAAO,EAAE,6CAA6C;AAAA,EAC5F;AACA,SAAO,QAAQ,KAAK,MAAM;AAC1B,qBAAmB,MAAM;AAC3B;AAEO,SAAS,yBAAyB,IAAkB;AACzD,QAAM,SAAS,mBAAmB;AAClC,QAAM,MAAM,OAAO,QAAQ,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE;AACvD,MAAI,QAAQ,IAAI;AACd,UAAM,IAAI;AAAA,MACR,IAAI,EAAE;AAAA,IACR;AAAA,EACF;AACA,SAAO,QAAQ,OAAO,KAAK,CAAC;AAC5B,qBAAmB,MAAM;AAC3B;AAvFA,IAAAC;AAAA;AAAA;AAAA;AAAA,IAAAA,SAAsB;AAEtB;AACA,IAAAC;AAMA;AAAA;AAAA;;;ACTA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA;;;ACRA,SAAoB;AACpB,WAAsB;AAUf,IAAM,sBAA8C;AAAA,EACzD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AACT;AAEO,SAAS,oBAAoB,MAAyF;AAC3H,SAAO;AAAA,IACL;AAAA,IACA,WAAW,oBAAoB,IAAI;AAAA,IACnC,SAAS;AAAA,EACX;AACF;AAMO,IAAM,iBAAiB;AAMvB,IAAM,cAAc;AAMpB,IAAM,qBAAqB;AAC3B,IAAM,wBAAwB;AAY9B,SAAS,mBAAmB,iBAAkC;AAEnE,MAAI,QAAQ,IAAI,sBAAsB;AACpC,WAAO,QAAQ,IAAI;AAAA,EACrB;AAEA,MAAI,iBAAiB;AACnB,WAAO;AAAA,EACT;AAEA,SAAY,UAAQ,WAAQ,GAAG,WAAW,WAAW;AACvD;AAOO,IAAM,mBAA2C;AAAA,EACtD,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,SAAS,eAAe,SAAyB;AACtD,SAAO,iBAAiB,OAAO,KAAK;AACtC;AAWO,IAAM,oBAAoB,CAAC,KAAK;AAOhC,IAAM,oBAAoB,oBAAI,IAAI;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AACF,CAAC;;;AChHD;;;ACDA,IAAAC,OAAoB;AACpB,IAAAC,SAAsB;AAiBtB,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,iBAAiB;AAgBhB,SAAS,uBACd,aACA,sBAAmC,oBAAI,IAAI,GAC3C,oBAAiC,oBAAI,IAAI,GACd;AAC3B,QAAM,aAAa,oBAAI,IAAqC;AAG5D,aAAW,KAAK,oBAAoB,WAAW,GAAG;AAChD,eAAW,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,gBAAgB,oBAAoB,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,EAClF;AAGA,aAAW,KAAK,qBAAqB,WAAW,GAAG;AACjD,QAAI,CAAC,WAAW,IAAI,EAAE,IAAI,GAAG;AAC3B,iBAAW,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,gBAAgB,oBAAoB,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,IAClF;AAAA,EACF;AAGA,QAAM,WAAW,IAAI;AAAA,IACnB,MAAM,KAAK,WAAW,OAAO,CAAC,EAC3B,OAAO,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,SAAS,UAAU,EACjE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACtB;AAEA,aAAW,KAAK,mBAAmB,WAAW,GAAG;AAC/C,QAAI,WAAW,IAAI,EAAE,IAAI,EAAG;AAE5B,UAAM,YAAY,MAAM,KAAK,QAAQ,EAAE;AAAA,MACrC,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,KAAK,WAAW,KAAK,GAAG;AAAA,IACrD;AACA,QAAI,UAAW;AACf,eAAW,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,gBAAgB,oBAAoB,IAAI,EAAE,IAAI,EAAE,CAAC;AAAA,EAClF;AAEA,QAAM,SAAS,MAAM,KAAK,WAAW,OAAO,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAG1F,SAAO,eAAe,QAAQ,iBAAiB;AACjD;AAOA,SAAS,eACP,YACA,cAA2B,oBAAI,IAAI,GACR;AAC3B,QAAM,UAAU,oBAAI,IAAoB;AAGxC,aAAW,MAAM,aAAa;AAC5B,YAAQ,IAAI,KAAK,QAAQ,IAAI,EAAE,KAAK,KAAK,CAAC;AAAA,EAC5C;AACA,aAAW,KAAK,YAAY;AAC1B,YAAQ,IAAI,EAAE,cAAc,QAAQ,IAAI,EAAE,WAAW,KAAK,KAAK,CAAC;AAAA,EAClE;AAEA,SAAO,WAAW,IAAI,CAAC,MAAM;AAC3B,SAAK,QAAQ,IAAI,EAAE,WAAW,KAAK,MAAM,EAAG,QAAO;AAEnD,UAAM,QAAQ,EAAE,KAAK,MAAM,GAAG;AAC9B,UAAM,cAAc,MAAM,UAAU,IAChC,SAAS,GAAG,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,IAChE,EAAE;AACN,WAAO,EAAE,GAAG,GAAG,aAAa,YAAY;AAAA,EAC1C,CAAC;AACH;AAYA,SAAS,gBAAgB,UAAuC;AAC9D,QAAM,UAAa,kBAAa,UAAU,OAAO;AACjD,QAAM,UAA+B,CAAC;AACtC,MAAIC,WAAsC,CAAC;AAE3C,aAAW,QAAQ,QAAQ,MAAM,IAAI,GAAG;AACtC,UAAM,UAAU,KAAK,KAAK;AAE1B,UAAM,cAAc,QAAQ,MAAM,wBAAwB;AAC1D,QAAI,aAAa;AACf,UAAIA,SAAQ,KAAM,SAAQ,KAAKA,QAA4B;AAC3D,MAAAA,WAAU,EAAE,MAAM,YAAY,CAAC,EAAE;AACjC;AAAA,IACF;AAEA,UAAM,SAAS,QAAQ,MAAM,oBAAoB;AACjD,QAAI,QAAQ;AACV,YAAM,CAAC,EAAE,KAAK,KAAK,IAAI;AACvB,UAAI,QAAQ,OAAQ,CAAAA,SAAQ,OAAO,MAAM,KAAK;AAC9C,UAAI,QAAQ,MAAO,CAAAA,SAAQ,MAAM,MAAM,KAAK;AAAA,IAC9C;AAAA,EACF;AAEA,MAAIA,SAAQ,KAAM,SAAQ,KAAKA,QAA4B;AAC3D,SAAO;AACT;AAEA,SAAS,oBAAoB,aAAgD;AAC3E,QAAM,iBAAsB,YAAK,aAAa,aAAa;AAC3D,MAAI,CAAI,gBAAW,cAAc,EAAG,QAAO,CAAC;AAE5C,SAAO,gBAAgB,cAAc,EAAE,IAAI,CAAC,WAAW;AAAA,IACrD,aAAa,SAAS,MAAM,IAAI;AAAA,IAChC,eAAe,WAAW,MAAM,IAAI;AAAA,IACpC,MAAMC,eAAc,MAAM,IAAI;AAAA,IAC9B,MAAM;AAAA,IACN,gBAAgB;AAAA,EAClB,EAAE;AACJ;AAMA,SAAS,qBAAqB,aAAgD;AAC5E,QAAM,UAAqC,CAAC;AAC5C,aAAW,aAAa,aAAa,GAAG,OAAO;AAC/C,SAAO;AACT;AAEA,SAAS,WACP,aACA,YACA,OACA,SACM;AACN,MAAI,QAAQ,eAAgB;AAE5B,MAAI;AACJ,MAAI;AACF,cAAa,iBAAY,YAAY,EAAE,eAAe,KAAK,CAAC;AAAA,EAC9D,QAAQ;AACN;AAAA,EACF;AAEA,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,YAAY,EAAG;AAC1B,QAAI,kBAAkB,IAAI,MAAM,IAAI,EAAG;AAEvC,UAAM,WAAgB,YAAK,YAAY,MAAM,IAAI;AACjD,UAAM,UAAUA,eAAmB,gBAAS,aAAa,QAAQ,CAAC;AAGlE,QAAI,YAAY,MAAM,YAAY,IAAK;AAEvC,UAAM,UAAe,YAAK,UAAU,MAAM;AAC1C,QAAO,gBAAW,OAAO,GAAG;AAC1B,cAAQ,KAAK;AAAA,QACX,aAAa,SAAS,OAAO;AAAA,QAC7B,eAAe,WAAW,OAAO;AAAA,QACjC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,gBAAgB;AAAA,MAClB,CAAC;AAED;AAAA,IACF;AAEA,eAAW,aAAa,UAAU,QAAQ,GAAG,OAAO;AAAA,EACtD;AACF;AAMA,SAAS,mBAAmB,aAAgD;AAC1E,QAAM,UAAqC,CAAC;AAC5C,kBAAgB,aAAa,aAAa,GAAG,OAAO;AACpD,SAAO;AACT;AAEA,SAAS,gBACP,aACA,YACA,OACA,SACM;AACN,MAAI,QAAQ,eAAgB;AAE5B,MAAI;AACJ,MAAI;AACF,cAAa,iBAAY,YAAY,EAAE,eAAe,KAAK,CAAC;AAAA,EAC9D,QAAQ;AACN;AAAA,EACF;AAEA,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,YAAY,EAAG;AAC1B,QAAI,kBAAkB,IAAI,MAAM,IAAI,EAAG;AAEvC,UAAM,WAAgB,YAAK,YAAY,MAAM,IAAI;AACjD,UAAM,UAAUA,eAAmB,gBAAS,aAAa,QAAQ,CAAC;AAClE,QAAI,YAAY,MAAM,YAAY,IAAK;AAEvC,UAAM,YAAY,gBAAgB,KAAK,CAAC,MAAS,gBAAgB,YAAK,UAAU,CAAC,CAAC,CAAC;AACnF,QAAI,WAAW;AACb,cAAQ,KAAK;AAAA,QACX,aAAa,SAAS,OAAO;AAAA,QAC7B,eAAe,WAAW,OAAO;AAAA,QACjC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,gBAAgB;AAAA,MAClB,CAAC;AAAA,IACH;AAEA,oBAAgB,aAAa,UAAU,QAAQ,GAAG,OAAO;AAAA,EAC3D;AACF;AAOA,SAAS,SAAS,SAAyB;AACzC,QAAMC,YAAgB,gBAAS,OAAO;AACtC,SAAOA,UACJ,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,EAAE;AACzB;AAGA,SAAS,WAAW,SAAyB;AAC3C,QAAM,KAAK,SAAS,OAAO;AAC3B,SAAO,GACJ,MAAM,GAAG,EACT,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EACjD,KAAK,GAAG;AACb;AAGA,SAASD,eAAc,GAAmB;AACxC,SAAO,EAAE,QAAQ,OAAO,GAAG;AAC7B;;;ACnSA;;;ACDA,IAAAE,SAAsB;AACtB;AACA;AACA;AACA;AACA;AAeA,SAAS,sBAA8B;AACrC,SAAY,eAAQ,WAAW,MAAM,WAAW;AAClD;AAQO,SAAS,aAAa,IAAY,gBAAmC;AAC1E,QAAM,OAAO,mBAAmB,cAAc;AAC9C,aAAW,OAAO,MAAM;AACtB,UAAM,WAAgB,YAAK,KAAK,GAAG,EAAE,OAAO;AAC5C,QAAI,WAAW,QAAQ,GAAG;AACxB,YAAM,MAAM,aAAa,QAAQ;AACjC,aAAO,eAAe,MAAM,GAAG;AAAA,IACjC;AAAA,EACF;AACA,QAAM,IAAI,sBAAsB,EAAE;AACpC;AAMO,SAAS,gBAAgB,gBAAmC;AACjE,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,OAAO,mBAAmB,cAAc,GAAG;AACpD,eAAW,QAAQ,UAAU,KAAK,OAAO,GAAG;AAC1C,WAAK,IAAS,gBAAS,MAAM,OAAO,CAAC;AAAA,IACvC;AAAA,EACF;AACA,SAAO,MAAM,KAAK,IAAI,EAAE,KAAK;AAC/B;AAKA,SAAS,mBAAmB,gBAAmC;AAC7D,SAAO;AAAA,IACL,SAAS,aAAa;AAAA;AAAA,IACtB,mBAAiB,cAAc;AAAA;AAAA,IAC/B,oBAAoB;AAAA;AAAA,EACtB;AACF;AAKO,SAAS,2BACd,UACA,MACQ;AACR,SAAO,SAAS,aAAa,QAAQ,kBAAkB,CAAC,QAAQ,QAAgB;AAC9E,WAAO,OAAO,OAAO,KAAK,GAAG,IAAI,KAAK,GAAG;AAAA,EAC3C,CAAC;AACH;AAKO,SAAS,cAAc,aAA+B;AAC3D,SAAO,eAAe,MAAM,UAAU,WAAW,CAAC;AACpD;;;ADjFA;AACA;AACA;AACA;AACAC;;;AEPA,IAAAC,OAAoB;AACpB,IAAAC,SAAsB;AACtBC;AAcA;AACA;AACA;AACA;AAcA,SAAS,qBAAqB,MAAc,KAA4B;AACtE,SAAO;AAAA,IACL,eAAe;AAAA,IACf;AAAA,IACA,aAAa;AAAA,IACb,SAAS,CAAC,EAAE,MAAM,UAAU,WAAW,kBAAkB,SAAS,KAAK,CAAC;AAAA,IACxE,OAAO;AAAA,MACL,wBAAwB;AAAA,MACxB,mBAAmB;AAAA,MACnB,eAAe,CAAC,QAAQ,YAAY,WAAW;AAAA,MAC/C,wBAAwB;AAAA;AAAA;AAAA;AAAA,MAIxB,+BAA+B;AAAA,MAC/B,iBAAiB,CAAC;AAAA,IACpB;AAAA,IACA,OAAO,EAAE,UAAU,aAAa;AAAA,IAChC,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AACF;AAGO,SAAS,iBAAiB,MAAoB;AACnD,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,oBAAkB,qBAAqB,MAAM,GAAG,CAAC;AACjD,iBAAe;AAAA,IACb,eAAe;AAAA,IACf;AAAA,IACA,QAAQ,mBAAmB,IAAI;AAAA,IAC/B,YAAY,CAAC;AAAA,IACb,oBAAoB,CAAC;AAAA,IACrB,WAAW,CAAC;AAAA,IACZ,WAAW;AAAA,IACX,WAAW;AAAA,EACb,CAAC;AACH;AAaO,SAAS,yBAAyB,cAAsE;AAC7G,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,QAAM,QAAQ,UAAU,eAAe,CAAC;AACxC,QAAM,YAAe,gBAAW,MAAM,YAAY,CAAC;AACnD,MAAI,OAAO;AACX,MAAI,WAAW;AACb,UAAM,WAAW,eAAe;AAChC,QAAI,UAAU,KAAM,QAAO,SAAS;AAAA,EACtC;AACA,MAAI,cAAc;AAClB,MAAI,cAAc;AAClB,MAAI,CAAI,gBAAW,MAAM,cAAc,CAAC,GAAG;AACzC,sBAAkB,qBAAqB,MAAM,GAAG,CAAC;AACjD,kBAAc;AAAA,EAChB;AACA,MAAI,CAAC,WAAW;AACd,mBAAe;AAAA,MACb,eAAe;AAAA,MACf;AAAA,MACA,QAAQ,mBAAmB,IAAI;AAAA,MAC/B,YAAY,CAAC;AAAA,MACb,oBAAoB,CAAC;AAAA,MACrB,WAAW,CAAC;AAAA,MACZ,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AACD,kBAAc;AAAA,EAChB;AACA,MAAI,eAAe,YAAa,qBAAoB;AACpD,SAAO,EAAE,aAAa,YAAY;AACpC;AAGO,SAAS,qBAA2B;AACzC,aAAW,KAAK,uBAAuB,GAAG;AACxC,oBAAgB,EAAE,MAAM,EAAE,IAAI,UAAU;AAAA,EAC1C;AACA,sBAAoB;AACtB;AAgBA,SAAS,uBACP,aACA,SACM;AACN,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,OAAO,CAAC,QAAsB;AAClC,UAAM,WAAgB,eAAQ,GAAG;AACjC,QAAI,QAAQ,IAAI,QAAQ,EAAG;AAC3B,YAAQ,IAAI,QAAQ;AACpB,UAAM,WAAW,UAAU,GAAG,EAAE,SAAS;AACzC,QAAI,CAAI,gBAAW,QAAQ,EAAG;AAC9B,eAAW,QAAQ,mBAAmB,UAAU,OAAO,GAAG;AACxD,UAAI;AACJ,UAAI;AACF,cAAM,aAAa,IAAI;AAAA,MACzB,QAAQ;AACN;AAAA,MACF;AACA,UAAI,EAAE,OAAO,OAAO,QAAQ,YAAY,kBAAkB,KAAM;AAChE,YAAM,KAAM,IAAkC;AAC9C,UAAI,OAAO,OAAO,YAAY,GAAG,KAAK,MAAM,GAAI;AAChD,UAAI;AACJ,UAAI;AACF,mBAAW,2BAA2B,KAAK,EAAE;AAAA,MAC/C,QAAQ;AACN;AAAA,MACF;AACA,YAAM,KAAM,IAAyB;AACrC,cAAQ,UAAU,OAAO,OAAO,WAAW,KAAU,gBAAS,QAAQ,CAAC;AACvE,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AACA,OAAK,WAAW;AAClB;AAUO,SAAS,6BAA6B,aAA6D;AACxG,QAAM,MAA8C,CAAC;AACrD,QAAM,WAAW,UAAU,WAAW,EAAE,SAAS;AACjD,MAAI,CAAI,gBAAW,QAAQ,EAAG,QAAO;AACrC,aAAW,QAAQ,mBAAmB,UAAU,OAAO,GAAG;AACxD,QAAI;AACJ,QAAI;AACF,YAAM,aAAa,IAAI;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AACA,QAAI,EAAE,OAAO,OAAO,QAAQ,YAAY,kBAAkB,KAAM;AAChE,UAAM,KAAM,IAAkC;AAC9C,QAAI,OAAO,OAAO,YAAY,GAAG,KAAK,MAAM,GAAI;AAChD,QAAI;AACJ,QAAI;AACF,YAAM,2BAA2B,aAAa,EAAE;AAAA,IAClD,QAAQ;AACN;AAAA,IACF;AACA,UAAM,KAAM,IAAyB;AACrC,QAAI,KAAK,EAAE,KAAK,aAAa,OAAO,OAAO,WAAW,KAAU,gBAAS,GAAG,EAAE,CAAC;AAAA,EACjF;AACA,SAAO;AACT;AAGA,SAAS,yBAAyB,UAA2B;AAC3D,SAAU,gBAAW,UAAU,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAI,gBAAW,UAAU,QAAQ,EAAE,cAAc,CAAC;AAC5G;AAQO,SAAS,qCAAqC,aAA+B;AAClF,QAAM,UAAoB,CAAC;AAC3B,yBAAuB,aAAa,CAAC,aAAa;AAChD,QAAI,yBAAyB,QAAQ,EAAG,SAAQ,KAAK,QAAQ;AAAA,EAC/D,CAAC;AACD,SAAO;AACT;AAOO,SAAS,iCAAiC,aAA+B;AAC9E,QAAM,aAAuB,CAAC;AAC9B,yBAAuB,aAAa,CAAC,UAAU,gBAAgB;AAC7D,QAAI,yBAAyB,QAAQ,GAAG;AACtC,yBAAmB,UAAU,MAAM;AACjC,iCAAyB,WAAW;AAAA,MACtC,CAAC;AACD,iBAAW,KAAK,QAAQ;AAAA,IAC1B;AAAA,EACF,CAAC;AACD,SAAO;AACT;AAQO,SAAS,uBAAuB,WAA0B,aAA2B;AAC1F,MAAI,CAAC,UAAU,eAAe,UAAU,YAAY,KAAK,MAAM,IAAI;AACjE,UAAM,IAAI,YAAY,wDAAwD;AAAA,EAChF;AAIA,QAAM,cAAc,YAAY,UAAU,WAAW;AAGrD,oBAAkB,EAAE,GAAG,WAAW,YAAY,CAAC;AAM/C,QAAM,WAAW,2BAA2B,eAAe,GAAG,WAAW;AAQzE,qBAAmB,UAAU,MAAM;AACjC,cAAU,UAAU,QAAQ,EAAE,SAAS,CAAC;AACxC,6BAAyB,WAAW;AAAA,EACtC,CAAC;AAED,sBAAoB;AACtB;AAOO,SAAS,qBAAqB,aAAqB,gBAA8B;AACtF,QAAM,MAAM,kBAAkB,WAAW;AACzC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,YAAY,cAAc,WAAW,mBAAmB;AAAA,EACpE;AACA,MAAI,CAAC,IAAI,eAAe,IAAI,YAAY,KAAK,MAAM,IAAI;AACrD,UAAM,IAAI;AAAA,MACR,cAAc,WAAW;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,WAAW,YAAY,cAAc;AAC3C,QAAM,OAAO,eAAe;AAI5B,QAAM,SAAS,2BAA2B,MAAM,IAAI,WAAW;AAC/D,QAAM,SAAS,2BAA2B,MAAM,QAAQ;AAExD,MAAI,WAAW,QAAQ;AACrB,QAAI,CAAI,gBAAW,MAAM,GAAG;AAC1B,YAAM,IAAI,YAAY,uDAAuD,MAAM,EAAE;AAAA,IACvF;AACA,QAAO,gBAAW,MAAM,GAAG;AACzB,YAAM,IAAI,YAAY,oCAAoC,MAAM,EAAE;AAAA,IACpE;AACA,cAAe,eAAQ,MAAM,CAAC;AAC9B,IAAG,gBAAW,QAAQ,MAAM;AAAA,EAC9B;AAEA,oBAAkB,EAAE,GAAG,KAAK,aAAa,UAAU,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC;AACxF,sBAAoB;AACtB;AAGA,SAAS,YAAY,GAAmB;AACtC,SAAO,EAAE,QAAQ,OAAO,GAAG;AAC7B;AAGA,SAAS,YAAY,KAAa,MAAuB;AACvD,QAAM,IAAS,eAAQ,GAAG;AAC1B,QAAM,IAAS,eAAQ,IAAI;AAC3B,SAAO,MAAM,KAAK,EAAE,WAAW,IAAS,UAAG;AAC7C;AAgBO,SAAS,qBAAqB,aAAqB,aAA2B;AACnF,MAAI,YAAY,SAAS,IAAI,GAAG;AAC9B,UAAM,IAAI,YAAY,gFAAgF;AAAA,EACxG;AACA,QAAM,MAAM,kBAAkB,WAAW;AACzC,MAAI,CAAC,OAAO,IAAI,aAAa;AAC3B,UAAM,IAAI,YAAY,kCAAkC,WAAW,mCAAmC;AAAA,EACxG;AAEA,QAAM,aAAa,eAAe;AAClC,QAAM,iBAAiB,UAAU,UAAU,EAAE,SAAS;AACtD,QAAM,SAAc,YAAK,gBAAgB,WAAW;AACpD,MAAI,CAAI,gBAAW,MAAM,GAAG;AAC1B,UAAM,IAAI,YAAY,wCAAwC,MAAM,EAAE;AAAA,EACxE;AAEA,QAAM,UAAU,YAAY,WAAW;AAGvC,QAAM,WAAW,2BAA2B,YAAY,OAAO;AAC/D,QAAM,cAAmB,YAAK,UAAU,QAAQ,SAAS,WAAW;AACpE,MAAO,gBAAW,WAAW,GAAG;AAC9B,UAAM,IAAI,YAAY,8BAA8B,WAAW,gBAAgB,WAAW,EAAE;AAAA,EAC9F;AAGA,QAAM,YAAY;AAAA,IAAe;AAAA;AAAA,IAA+B;AAAA,EAAI;AAGpE,QAAM,kBAAkB,IAAI,QAAQ;AACpC,qBAAmB,UAAU,MAAM;AACjC,cAAe,YAAK,UAAU,QAAQ,OAAO,CAAC;AAC9C,qBAAiB,eAAe;AAAA,EAClC,CAAC;AACD,YAAe,eAAQ,WAAW,CAAC;AACnC,EAAG,gBAAW,QAAQ,WAAW;AAGjC,sBAAyB,YAAK,aAAa,aAAa,GAAG,CAAC,MAAM;AAChE,MAAE,eAAe;AACjB,WAAO,EAAE;AAAA,EACX,CAAC;AAGD,YAAU,MAAM;AAChB,gBAAmB,YAAK,QAAQ,aAAa,GAAG;AAAA,IAC9C,IAAI;AAAA,IACJ,MAAM,IAAI;AAAA,IACV,aAAa,IAAI;AAAA,IACjB,cAAc,IAAI;AAAA,IAClB,kBAAkB,CAAC;AAAA,IACnB,aAAa;AAAA,IACb,cAAc,CAAC;AAAA,IACf,QAAQ,IAAI,UAAU;AAAA,IACtB,WAAW,IAAI,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACnD,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC,CAAC;AAGD,mBAAiB,gBAAgB,WAAW,MAAM;AAClD,sBAAoB;AACtB;AAQO,SAAS,qBAAqB,aAA2B;AAC9D,MAAI,YAAY,SAAS,IAAI,GAAG;AAC9B,UAAM,IAAI,YAAY,gFAAgF;AAAA,EACxG;AACA,QAAM,MAAM,kBAAkB,WAAW;AACzC,MAAI,CAAC,OAAO,CAAC,IAAI,aAAa;AAC5B,UAAM,IAAI,YAAY,kCAAkC,WAAW,+BAA+B;AAAA,EACpG;AAEA,QAAM,aAAa,eAAe;AAClC,QAAM,iBAAiB,UAAU,UAAU,EAAE,SAAS;AAItD,QAAM,WAAW,2BAA2B,YAAY,IAAI,WAAW;AACvE,QAAM,WAAgB,YAAK,UAAU,MAAM;AAC3C,QAAM,cAAmB,YAAK,UAAU,QAAQ,SAAS,WAAW;AACpE,MAAI,CAAI,gBAAW,WAAW,GAAG;AAC/B,UAAM,IAAI,YAAY,0CAA0C,WAAW,MAAM,WAAW,EAAE;AAAA,EAChG;AAGA,QAAM,eAAe,mBAAmB,UAAU,MAAM,mBAAmB,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,IAAI,CAAC;AAChH,MAAI,aAAa,WAAW,KAAK,aAAa,CAAC,EAAE,OAAO,aAAa;AACnE,UAAM,IAAI,YAAY,2EAA2E,WAAW,IAAI;AAAA,EAClH;AAGA,QAAM,YAAY;AAAA,IAAe;AAAA;AAAA,IAA+B;AAAA,EAAK;AACrE,QAAM,mBAAmB,eAAe,GAAG,QAAQ,IAAI;AAGvD,QAAM,SAAc,YAAK,gBAAgB,WAAW;AACpD,EAAG,YAAO,QAAQ,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAClD,YAAe,eAAQ,MAAM,CAAC;AAC9B,EAAG,gBAAW,aAAa,MAAM;AAGjC,sBAAyB,YAAK,QAAQ,aAAa,GAAG,CAAC,MAAM;AAC3D,MAAE,eAAe;AACjB,WAAO,EAAE;AAAA,EACX,CAAC;AAGD,EAAG,YAAO,UAAU,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAGpD,mBAAiB,gBAAgB,WAAW,MAAM;AAClD,sBAAoB;AACtB;AAOA,SAAS,eAAe,aAAqB,aAA2C;AACtF,QAAM,MAAM,oBAAI,IAAoB;AACpC,QAAM,SAAS,GAAG,WAAW;AAC7B,QAAM,MAAM,CAAC,MAAc,eACzB,cAAc,IAAI,IAAI,MAAM,UAAU,IAAI,IAAI,IAAI,YAAY,IAAI;AAEpE,QAAM,QAAQ,mBAAmB,EAAE,OAAO,CAAC,MAAM,EAAE,cAAc,WAAW;AAC5E,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAC9C,aAAW,KAAK,OAAO;AACrB,UAAM,OAAO,EAAE,GAAG,WAAW,MAAM,IAAI,EAAE,GAAG,MAAM,OAAO,MAAM,IAAI,EAAE;AACrE,QAAI,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE;AAAA,EAC9B;AACA,aAAW,KAAK,mBAAmB,GAAG;AACpC,QAAI,CAAC,QAAQ,IAAI,EAAE,SAAS,EAAG;AAC/B,UAAM,OAAO,EAAE,GAAG,WAAW,MAAM,IAAI,EAAE,GAAG,MAAM,OAAO,MAAM,IAAI,EAAE;AACrE,QAAI,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE;AAAA,EAC9B;AACA,aAAW,KAAK,cAAc,GAAG;AAC/B,QAAI,EAAE,cAAc,YAAa;AACjC,UAAM,OAAO,EAAE,GAAG,WAAW,MAAM,IAAI,EAAE,GAAG,MAAM,OAAO,MAAM,IAAI,EAAE;AACrE,QAAI,MAAM,GAAG,MAAM,GAAG,IAAI,EAAE;AAAA,EAC9B;AACA,SAAO;AACT;AAGA,SAAS,iBAAiB,UAAkB,WAAgC,YAA2B;AACrG,MAAI,UAAU,SAAS,EAAG;AAC1B,QAAM,QAAQ,CAAC,OACb,OAAO,UAAa,UAAU,IAAI,EAAE,IAAI,UAAU,IAAI,EAAE,IAAK;AAE/D,aAAW,QAAQ,mBAAmB,UAAU,OAAO,GAAG;AACxD,QAAI,cAAc,YAAY,YAAY,IAAI,EAAG;AACjD,QAAI;AACJ,QAAI;AACF,YAAM,aAAa,IAAI;AAAA,IACzB,QAAQ;AACN;AAAA,IACF;AACA,QAAI,CAAC,OAAO,OAAO,QAAQ,SAAU;AACrC,QAAI,UAAU;AAEd,QAAI,mBAAmB,OAAO,MAAM,QAAQ,IAAI,SAAS,GAAG;AAC1D,YAAM,OAAO,IAAI,UAAU,IAAI,CAAC,MAAc,MAAM,CAAC,CAAC;AACtD,UAAI,KAAK,KAAK,CAAC,GAAW,MAAc,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG;AAC/D,YAAI,YAAY;AAChB,kBAAU;AAAA,MACZ;AAEA,UAAI,MAAM,QAAQ,IAAI,QAAQ,GAAG;AAC/B,mBAAW,KAAK,IAAI,UAAU;AAC5B,gBAAM,KAAK,MAAM,EAAE,SAAS;AAC5B,cAAI,OAAO,EAAE,WAAW;AACtB,cAAE,YAAY;AACd,sBAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,kBAAkB,OAAO,MAAM,QAAQ,IAAI,SAAS,GAAG;AAIhE,iBAAW,MAAM,IAAI,WAAW;AAC9B,cAAM,KAAK,MAAM,GAAG,SAAS;AAC7B,YAAI,OAAO,GAAG,WAAW;AACvB,aAAG,YAAY;AACf,oBAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF,WAAW,eAAe,OAAO,MAAM,QAAQ,IAAI,OAAO,GAAG;AAC3D,iBAAW,KAAK,IAAI,SAAS;AAC3B,YAAI,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAG;AAC9B,mBAAW,KAAK,EAAE,QAAQ;AACxB,gBAAM,KAAK,MAAM,EAAE,IAAI;AACvB,cAAI,OAAO,EAAE,MAAM;AACjB,cAAE,OAAO;AACT,sBAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,cAAc,OAAO,MAAM,QAAQ,IAAI,OAAO,GAAG;AAC1D,iBAAW,KAAK,IAAI,SAAS;AAC3B,YAAI,CAAC,MAAM,QAAQ,EAAE,SAAS,EAAG;AACjC,mBAAW,QAAQ,EAAE,WAAW;AAC9B,gBAAM,KAAK,MAAM,KAAK,eAAe;AACrC,cAAI,OAAO,KAAK,iBAAiB;AAC/B,iBAAK,kBAAkB;AACvB,sBAAU;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,UAAU,OAAO,MAAM,QAAQ,IAAI,MAAM,GAAG;AACrD,iBAAW,KAAK,IAAI,QAAQ;AAC1B,cAAM,KAAK,MAAM,EAAE,IAAI;AACvB,YAAI,OAAO,EAAE,MAAM;AACjB,YAAE,OAAO;AACT,oBAAU;AAAA,QACZ;AAAA,MACF;AAAA,IACF;AAEA,QAAI,QAAS,eAAc,MAAM,GAAG;AAAA,EACtC;AACF;AAGA,SAAS,oBAAoB,WAAmB,QAAmC;AACjF,MAAI,CAAI,gBAAW,SAAS,EAAG;AAC/B,QAAM,MAAM,aAAa,SAAS;AAClC,SAAO,GAAG;AACV,MAAI,aAAY,oBAAI,KAAK,GAAE,YAAY;AACvC,gBAAc,WAAW,GAAG;AAC9B;;;AF9jBA;;;AGTA,IAAAC,OAAoB;AACpB,IAAAC,SAAsB;AACtB;AAiCA,SAAS,WAAmB;AAC1B,SAAO,MAAM,WAAW;AAC1B;AAGO,SAAS,iBAAoC;AAClD,MAAI;AACF,WAAO,KAAK,MAAS,kBAAa,SAAS,GAAG,MAAM,CAAC;AAAA,EACvD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,gBAAgB,QAA0B;AACxD,QAAM,IAAI,SAAS;AACnB,EAAG,eAAe,eAAQ,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AACjD,QAAM,MAAM,GAAG,CAAC;AAChB,EAAG,mBAAc,KAAK,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,IAAI;AAC5D,EAAG,gBAAW,KAAK,CAAC;AACtB;;;AH5CA;AACA;;;AIZA,IAAAC,SAAsB;AACtB,IAAAC,OAAoB;AACpB;AAEA;AAWA,IAAM,cAAc,CAAC,iBAAiB,iBAAiB,eAAe,eAAe;AAGrF,SAASC,yBAAwB;AAC/B,SAAO,sBAAmB;AAC5B;AAMA,SAAS,YAAY,OAAgC;AACnD,QAAM,KAAK,MAAM,KAAK,YAAY,EAAE,QAAQ,eAAe,GAAG,EAAE,QAAQ,YAAY,EAAE;AACtF,SAAO,GAAG,EAAE,IAAI,MAAM,EAAE;AAC1B;AAGA,SAAS,gBAAgB,KAAa,cAA6D;AACjG,QAAM,QAAQ,8BAA8B,KAAK,GAAG;AACpD,QAAM,QAAQ,QAAQ,MAAM,CAAC,IAAI;AACjC,QAAM,QAAQ,CAAC,QAAwB;AACrC,UAAM,IAAI,IAAI,OAAO,IAAI,GAAG,cAAc,GAAG,EAAE,KAAK,KAAK;AACzD,WAAO,IAAI,EAAE,CAAC,EAAE,KAAK,IAAI;AAAA,EAC3B;AACA,SAAO,EAAE,MAAM,MAAM,MAAM,KAAK,cAAc,aAAa,MAAM,aAAa,EAAE;AAClF;AAEA,SAAS,mBAA2B;AAClC,SAAY,eAAQ,WAAW,MAAM,aAAa,QAAQ;AAC5D;AAGA,SAAS,kBAAkB,MAAsB;AAC/C,SAAY,YAAK,iBAAiB,GAAG,GAAG,IAAI,KAAK;AACnD;AAUA,SAAS,cAAc,MAAc,SAAiB,MAAsB;AAC1E,MAAI,SAAS,YAAY,SAAS,WAAW,SAAS,YAAY,SAAS,OAAO;AAChF,WAAY,YAAK,SAAS,MAAM,UAAU;AAAA,EAC5C;AACA,SAAY,YAAK,SAAS,GAAG,IAAI,KAAK;AACxC;AASO,SAAS,mBAAmB,MAA6B;AAC9D,UAAQ,MAAM;AAAA,IACZ,KAAK;AAAU,aAAO,gBAAgB,WAAW,QAAQ;AAAA,IACzD,KAAK;AAAA;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAU,aAAO,gBAAgB,WAAW,QAAQ;AAAA,IACzD,KAAK;AAAU,aAAO,gBAAgB,WAAW,QAAQ;AAAA,IACzD;AAAe,aAAO;AAAA,EACxB;AACF;AAGO,SAAS,iBAA2B;AACzC,SAAO,CAAC,GAAG,WAAW;AACxB;AAeO,SAAS,gBAAgB,aAA4C;AAC1E,QAAM,QAAQ,eAAe,kBAAkB;AAE/C,QAAM,eAAyB,CAAC;AAChC,QAAM,UAAoB,CAAC;AAC3B,MAAI,YAAY;AAIhB,QAAM,aAAaA,uBAAsB,EAAE;AAE3C,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,mBAAmB,IAAI;AACvC,QAAI,CAAC,SAAS;AACZ,cAAQ,KAAK,IAAI;AACjB;AAAA,IACF;AACA,cAAU,OAAO;AACjB,iBAAa,KAAK,OAAO;AAEzB,eAAW,QAAQ,aAAa;AAC9B,YAAM,UAAU,kBAAkB,IAAI;AACtC,UAAI,CAAI,gBAAW,OAAO,EAAG;AAG7B,YAAM,UAAa,kBAAa,SAAS,OAAO;AAChD,YAAM,WAAW,cAAc,MAAM,SAAS,IAAI;AAClD,gBAAe,eAAQ,QAAQ,CAAC;AAChC,MAAG,mBAAc,UAAU,SAAS,OAAO;AAC3C;AAAA,IACF;AAGA,eAAW,SAAS,YAAY;AAC9B,UAAI,CAAC,MAAM,QAAQ,SAAS,IAAI,EAAG;AACnC,UAAI,CAAI,gBAAW,MAAM,UAAU,EAAG;AACtC,YAAM,KAAK,YAAY,KAAK;AAC5B,YAAM,UAAa,kBAAa,MAAM,YAAY,OAAO;AACzD,YAAM,WAAW,cAAc,MAAM,SAAS,EAAE;AAChD,gBAAe,eAAQ,QAAQ,CAAC;AAChC,MAAG,mBAAc,UAAU,SAAS,OAAO;AAC3C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,cAAc,WAAW,QAAQ;AAC5C;AAiBO,SAAS,oBAAoB,MAA8B;AAChE,QAAM,MAAM,mBAAmB,IAAI;AACnC,QAAM,SAAyB,EAAE,KAAK,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,EAAE;AACrE,MAAI,CAAC,IAAK,QAAO;AAEjB,aAAW,QAAQ,aAAa;AAC9B,UAAM,WAAW,cAAc,MAAM,KAAK,IAAI;AAC9C,QAAI,CAAI,gBAAW,QAAQ,GAAG;AAAE,aAAO,QAAQ,KAAK,IAAI;AAAG;AAAA,IAAU;AACrE,UAAM,UAAU,kBAAkB,IAAI;AACtC,UAAM,OAAU,gBAAW,OAAO,IAAO,kBAAa,SAAS,OAAO,IAAI;AAC1E,UAAM,OAAU,kBAAa,UAAU,OAAO;AAC9C,QAAI,SAAS,KAAM,QAAO,GAAG,KAAK,IAAI;AAAA,QACjC,QAAO,MAAM,KAAK,IAAI;AAAA,EAC7B;AACA,SAAO;AACT;AAEO,SAAS,oBAA8B;AAE5C,QAAM,EAAE,mBAAAC,mBAAkB,IAAI;AAC9B,QAAM,SAASA,mBAAkB;AACjC,SAAO,OAAO,QACX,OAAO,CAAC,MAA6B,EAAE,aAAa,MAAM,EAAE,OAAO,EACnE,IAAI,CAAC,MAAkC,OAAO,MAAM,WAAW,IAAI,EAAE,IAAK;AAC/E;AAkBA,IAAM,wBAAwB;AAO9B,IAAM,qBAA+B,CAAC,GAAG,WAAW,EAAE,KAAK;AAmBpD,IAAM,6BAAN,cAAyC,MAAM;AAAA,EACpD,YAAY,YAAoB;AAC9B,UAAM,mCAAmC,UAAU,IAAI;AACvD,SAAK,OAAO;AAAA,EACd;AACF;AAGA,SAAS,qBAAqB,MAAqD;AACjF,SAAO,gBAAmB,kBAAa,kBAAkB,IAAI,GAAG,OAAO,GAAG,IAAI;AAChF;AAKO,SAAS,qBAAgD;AAC9D,QAAM,UAAqC,mBAAmB,IAAI,CAAC,OAAO;AACxE,UAAM,KAAK,qBAAqB,EAAE;AAClC,WAAO;AAAA,MACL;AAAA,MACA,MAAM,GAAG;AAAA,MACT,aAAa,GAAG;AAAA,MAChB,SAAS;AAAA,MACT,aAAa,GAAG,qBAAqB,MAAM,EAAE;AAAA,MAC7C,qBAAqB;AAAA,IACvB;AAAA,EACF,CAAC;AAED,QAAM,OAAkCD,uBAAsB,EAAE,OAC7D,OAAO,CAAC,MAAS,gBAAW,EAAE,UAAU,CAAC,EACzC,IAAI,CAAC,UAAU;AACd,UAAM,KAAK,YAAY,KAAK;AAC5B,UAAM,KAAK,gBAAmB,kBAAa,MAAM,YAAY,OAAO,GAAG,EAAE;AACzE,WAAO;AAAA,MACL;AAAA,MACA,MAAM,GAAG;AAAA,MACT,aAAa,GAAG;AAAA,MAChB,SAAS,MAAM,eAAe;AAAA,MAC9B,aAAa,GAAG,qBAAqB,MAAM,EAAE;AAAA,MAC7C,qBAAqB;AAAA,IACvB;AAAA,EACF,CAAC;AACH,SAAO,CAAC,GAAG,SAAS,GAAG,IAAI;AAC7B;AAGO,SAAS,kBAAkB,YAA4B;AAC5D,QAAM,YAAYA,uBAAsB,EAAE,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC,MAAM,UAAU;AAC1F,MAAI,UAAW,QAAU,kBAAa,UAAU,YAAY,OAAO;AACnE,SAAU,kBAAa,kBAAkB,UAAU,GAAG,OAAO;AAC/D;AAKO,SAAS,gBAA2C;AACzD,SAAO,mBAAmB;AAC5B;AAMO,SAAS,aAAa,YAA4B;AACvD,QAAM,QAAQ,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAClE,MAAI,CAAC,MAAO,OAAM,IAAI,2BAA2B,UAAU;AAC3D,SAAO,kBAAkB,UAAU;AACrC;;;AC5SA;;;ACaO,SAAS,eAAuB;AACrC,SAAO,wBAAwB,cAAc;AAC/C;;;ACUO,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AFR1B,SAAS,cAAc,UAA4B;AACxD,SAAO,MAAM,WAAW,GAAG,QAAQ;AACrC;AAEO,IAAM,gBAAgB;AAAA,EAC3B,KAAe,MAAM,WAAW;AAAA,EAChC,WAAe,MAAM,WAAW,YAAY;AAAA,EAC5C,gBAAe,MAAM,WAAW,iBAAiB;AAAA,EACjD,WAAe,MAAM,WAAW,YAAY;AAAA,EAC5C,eAAe,MAAM,WAAW,iBAAiB;AACnD;AAMO,SAAS,aAAsB;AACpC,SAAO,WAAW,cAAc,UAAU,CAAC;AAC7C;AAEO,SAAS,yBAAkC;AAChD,SAAO,WAAW,cAAc,eAAe,CAAC;AAClD;AAMO,SAAS,qBAAoC;AAClD,SAAO,eAAe,cAAc,UAAU,CAAC;AACjD;AAEO,SAAS,0BAAyC;AACvD,SAAO,eAAe,cAAc,eAAe,CAAC;AACtD;AAEO,SAAS,oBAAoB,SAAuB;AACzD,YAAU,cAAc,UAAU,GAAG,OAAO;AAC9C;AAEO,SAAS,yBAAyB,SAAuB;AAC9D,YAAU,cAAc,eAAe,GAAG,OAAO;AACnD;AAUO,SAAS,mBAA2B;AAEzC,QAAM,EAAE,gBAAAE,gBAAe,IAAI;AAC3B,QAAM,UAAUA,gBAAe;AAE/B,QAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACnD,QAAM,QAAkB;AAAA,IACtB,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,KAAK;AAAA,IACxB;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,KAAK,+GAA+G;AAAA,EAC5H,OAAO;AACL,UAAM,KAAK,KAAK,QAAQ,MAAM,eAAe;AAC7C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,sCAAsC;AACjD,UAAM,KAAK,sCAAsC;AACjD,eAAW,KAAK,SAAS;AACvB,YAAM,OAAO,EAAE,QAAQ,EAAE;AACzB,YAAM,SAAS,EAAE,UAAU,eAAe,EAAE,OAAO,OAAO;AAC1D,YAAM,KAAK,OAAO,EAAE,EAAE,QAAQ,IAAI,MAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,MAAM,KAAK,QAAG,MAAM;AAAA,IAC9F;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI,IAAI;AAC5B;AAMO,SAAS,oBAA4B;AAE1C,QAAM,EAAE,mBAAAC,mBAAkB,IAAI;AAE9B,QAAM,EAAE,gBAAAD,gBAAe,IAAI;AAE3B,QAAM,UAAUA,gBAAe;AAE/B,MAAI,cAAc;AAClB,MAAI;AACF,kBAAcC,mBAAkB,EAAE;AAAA,EACpC,QAAQ;AAAA,EAAiD;AAEzD,QAAM,aAAa,mBAAmB;AACtC,QAAM,UAAU,wBAAwB;AAExC,QAAM,QAAkB;AAAA,IACtB,aAAa;AAAA,IACb;AAAA,IACA;AAAA,EACF;AAGA,MAAI,YAAY;AACd,UAAM,KAAK,4BAAuB,WAAW,EAAE;AAC/C,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,WAAW,KAAK,CAAC;AAC5B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,SAAS;AACX,UAAM,KAAK,gBAAgB;AAC3B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,QAAQ,KAAK,CAAC;AACzB,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,QAAM,KAAK,iBAAiB,QAAQ,MAAM,UAAU,QAAQ,WAAW,IAAI,MAAM,EAAE,GAAG;AACtF,QAAM,KAAK,EAAE;AACb,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,KAAK,mBAAmB;AAAA,EAChC,OAAO;AACL,UAAM,KAAK,wBAAwB;AACnC,UAAM,KAAK,wBAAwB;AACnC,eAAW,KAAK,SAAS;AACvB,YAAM,OAAO,EAAE,QAAQ,EAAE;AACzB,YAAM,SAAS,EAAE,UAAU,eAAe,EAAE,OAAO,OAAO;AAC1D,YAAM,KAAK,OAAO,EAAE,EAAE,QAAQ,MAAM,MAAM,IAAI,IAAI;AAAA,IACpD;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAGb,QAAM,kBAAkB,QAAQ,MAAM,EAAE,KAAK,QAAQ,IAAI,GAAG,WAAW,eAAe;AACtF,MAAI,eAAe;AACnB,MAAI;AACF,UAAM,IAAI,KAAK,MAAM,QAAQ,IAAI,EAAE,aAAa,iBAAiB,MAAM,CAAC;AACxE,mBAAe,CAAC,CAAE,GAAG,YAAY;AAAA,EACnC,QAAQ;AAAA,EAAsB;AAE9B,MAAI,cAAc;AAChB,UAAM,KAAK,oBAAoB;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,yGAAyG;AACpH,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,oOAAoO;AAC/O,UAAM,KAAK,uHAAuH;AAClI,UAAM,KAAK,8FAA8F;AACzG,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,2HAAuH;AAClI,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,QAAM,KAAK,iBAAiB;AAC5B,QAAM,KAAK,EAAE;AAEb,SAAO,MAAM,KAAK,IAAI;AACxB;AAeO,SAAS,mBAA+B;AAC7C,QAAM,iBAAkB,iBAAiB;AACzC,QAAM,eAAkB,kBAAkB;AAE1C,QAAM,iBAAkB,mBAAmB,cAAc,UAAU,GAAO,cAAc;AACxF,QAAM,eAAkB,mBAAmB,cAAc,cAAc,GAAI,YAAY;AAEvF,SAAO,EAAE,gBAAgB,aAAa;AACxC;;;ALzMA;AACA;;;AQQO,IAAM,wBAAwB;AAC9B,IAAM,wBAAwB,QAAQ,qBAAqB;;;ACzBlE,IAAAC,SAAsB;AACtB;AAwBO,IAAM,iBAAN,MAAyC;AAAA,EAAzC;AACL,SAAS,aAAa;AAAA;AAAA,EAEtB,WAAW,KAA0D;AACnE,UAAM,EAAE,OAAO,QAAQ,YAAY,IAAI;AACvC,UAAM,YAAY,eAAe,SAAS,OAAO,YAAY;AAC7D,WAAY,eAAQ,aAAa,WAAW,GAAG,MAAM,GAAG,QAAQ,OAAO,IAAI,CAAC,KAAK;AAAA,EACnF;AAAA,EAEA,OAAO,KAAkC;AACvC,UAAM,EAAE,OAAO,qBAAqB,IAAI;AACxC,UAAM,WAAW,KAAK,WAAW,GAAG;AAGpC,UAAM,kBAAkB,MAAM,YAAY,SAAS,GAAG,KAAK,MAAM,YAAY,SAAS,GAAG,IACrF,IAAI,MAAM,YAAY,QAAQ,MAAM,KAAK,CAAC,MAC1C,MAAM;AAEV,UAAM,UAAU;AAAA,MACd;AAAA,MACA,SAAS,MAAM,IAAI;AAAA,MACnB,gBAAgB,eAAe;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,UAAM,UAAU,mBAAmB,UAAU,OAAO;AACpD,WAAO,EAAE,YAAY,UAAU,SAAS,WAAW,CAAC,QAAQ;AAAA,EAC9D;AACF;;;ACxDA,IAAAC,SAAsB;AACtB;AAYO,IAAM,iBAAN,MAAyC;AAAA,EAAzC;AACL,SAAS,aAAa;AAAA;AAAA,EAEtB,WAAW,KAA0D;AACnE,UAAM,EAAE,OAAO,QAAQ,YAAY,IAAI;AACvC,QAAI,EAAE,eAAe,SAAS;AAC5B,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AACA,WAAY,eAAQ,aAAa,OAAO,WAAW,GAAG,MAAM,GAAG,QAAQ,OAAO,IAAI,CAAC,KAAK;AAAA,EAC1F;AAAA,EAEA,OAAO,KAAkC;AACvC,UAAM,EAAE,OAAO,QAAQ,qBAAqB,IAAI;AAChD,UAAM,QAAQ,WAAW,SAAS,OAAO,QAAQ;AACjD,UAAM,WAAW,KAAK,WAAW,GAAG;AAEpC,UAAM,UAAU;AAAA,MACd;AAAA,MACA,SAAS,MAAM,IAAI;AAAA,MACnB,gBAAgB,MAAM,WAAW;AAAA,MACjC,OAAO,MAAM,EAAE;AAAA,MACf,WAAW,KAAK;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,UAAM,UAAU,mBAAmB,UAAU,OAAO;AACpD,WAAO,EAAE,YAAY,UAAU,SAAS,WAAW,CAAC,QAAQ;AAAA,EAC9D;AACF;;;AC5CA,IAAAC,SAAsB;AACtB;AAwBO,IAAM,iBAAN,MAAyC;AAAA,EAAzC;AACL,SAAS,aAAa;AAAA;AAAA,EAEtB,WAAW,KAA0D;AACnE,UAAM,EAAE,OAAO,QAAQ,YAAY,IAAI;AACvC,UAAM,YAAY,eAAe,SAAS,OAAO,YAAY;AAC7D,WAAY,eAAQ,aAAa,WAAW,GAAG,MAAM,GAAG,QAAQ,OAAO,IAAI,CAAC,OAAO;AAAA,EACrF;AAAA,EAEA,OAAO,KAAkC;AACvC,UAAM,EAAE,OAAO,qBAAqB,IAAI;AACxC,UAAM,WAAW,KAAK,WAAW,GAAG;AAGpC,UAAM,uBAAuB,qBAC1B,MAAM,IAAI,EACV,IAAI,CAAC,SAAU,KAAK,SAAS,IAAI,KAAK,IAAI,KAAK,EAAG,EAClD,KAAK,IAAI;AAEZ,UAAM,UAAU;AAAA,MACd,SAAS,WAAW,MAAM,IAAI,CAAC;AAAA,MAC/B,gBAAgB,WAAW,MAAM,WAAW,CAAC;AAAA,MAC7C;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAEX,UAAM,UAAU,mBAAmB,UAAU,OAAO;AACpD,WAAO,EAAE,YAAY,UAAU,SAAS,WAAW,CAAC,QAAQ;AAAA,EAC9D;AACF;AAUA,SAAS,WAAW,OAAuB;AACzC,MAAI,wBAAwB,KAAK,KAAK,KAAK,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AACvF,WAAO,IAAI,MAAM,QAAQ,OAAO,MAAM,EAAE,QAAQ,MAAM,KAAK,CAAC;AAAA,EAC9D;AACA,SAAO;AACT;;;ACnEA;;;ACEA;AASA,IAAM,YAAY,oBAAI,IAAsB;AAAA,EAC1C,CAAC,UAAU,IAAI,eAAe,CAAC;AAAA,EAC/B,CAAC,UAAU,IAAI,eAAe,CAAC;AAAA,EAC/B,CAAC,OAAO,IAAI,eAAe,CAAC;AAAA,EAC5B,CAAC,UAAU,IAAI,eAAe,CAAC;AAAA,EAC/B,CAAC,WAAW,IAAI,eAAe,CAAC;AAAA,EAChC,CAAC,SAAS,IAAI,eAAe,CAAC;AAAA,EAC9B,CAAC,UAAU,IAAI,eAAe,CAAC;AACjC,CAAC;AAKM,SAAS,YAAY,QAAgC;AAC1D,QAAM,OAAO,OAAO,WAAW,WAAW,SAAS,OAAO;AAC1D,QAAM,WAAW,UAAU,IAAI,IAAI;AACnC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,YAAY,4CAA4C,IAAI,GAAG;AAAA,EAC3E;AACA,SAAO;AACT;AAKO,SAAS,iBAAiB,MAAc,UAA0B;AACvE,YAAU,IAAI,MAAM,QAAQ;AAC9B;;;ADRO,SAAS,cACd,OACA,eACA,UAA2B,CAAC,GACX;AAKjB,QAAM,cAAc,QAAQ,eAAe,eAAe;AAC1D,QAAM,WAAW,aAAa,MAAM,UAAU,cAAc,kBAAkB;AAI9E,QAAM,WAAW,GAAG,qBAAqB;AAAA,EAAK,2BAA2B,UAAU,UAAU,KAAK,CAAC,CAAC;AACpG,QAAM,UAA0B,CAAC;AAEjC,aAAW,eAAe,MAAM,SAAS;AACvC,UAAM,eAAe,oBAAoB,aAAa,aAAa;AACnE,QAAI,CAAC,aAAc;AACnB,QAAI,QAAQ,eAAe;AACzB,YAAM,OAAO,UAAU,eAAe,aAAa,OAAO;AAC1D,UAAI,CAAC,QAAQ,cAAc,SAAS,IAAc,EAAG;AAAA,IACvD;AACA,QAAI,CAAC,QAAQ,QAAQ;AACnB,cAAQ,KAAK,YAAY,YAAY,EAAE,OAAO;AAAA,QAC5C;AAAA,QAAO;AAAA,QAAU,sBAAsB;AAAA,QAAU;AAAA,QAAa,QAAQ;AAAA,MACxE,CAAC,CAAC;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAEO,SAAS,YACd,QACA,eACA,UAA2B,CAAC,GACT;AACnB,MAAI,OAAO;AAEX,MAAI,QAAQ,mBAAmB,QAAQ,gBAAgB,SAAS,GAAG;AACjE,UAAM,MAAM,IAAI,IAAI,QAAQ,eAAe;AAC3C,WAAO,OAAO,OAAO,CAAC,MAAM,IAAI,IAAI,EAAE,cAAc,MAAM,CAAC;AAAA,EAC7D;AAEA,SAAO,KAAK,IAAI,CAAC,UAAU,cAAc,OAAO,eAAe,OAAO,CAAC;AACzE;AAMA,SAAS,UAAU,OAA4C;AAC7D,SAAO;AAAA,IACL,SAAS,MAAM;AAAA,IACf,WAAW,MAAM;AAAA,IACjB,kBAAkB,MAAM;AAAA,IACxB,YAAY,MAAM,WAAW,KAAK,IAAI;AAAA,IACtC,MAAM,MAAM,KAAK,KAAK,IAAI;AAAA,IAC1B,eAAe;AAAA,IACf,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,iBAAiB,MAAM,mBAAmB;AAAA,EAC5C;AACF;AAKA,SAAS,oBACP,aACA,eAC0B;AAC1B,QAAM,aAAa,OAAO,gBAAgB,WAAW,cAAc,YAAY;AAC/E,SAAO,cAAc,QAAQ,KAAK,CAAC,MAAM;AACvC,QAAI,OAAO,MAAM,SAAU,QAAO,MAAM;AACxC,WAAO,EAAE,SAAS;AAAA,EACpB,CAAC;AACH;;;AEjHA;AACA;;;ACDA,mBAAkB;AAQlB,IAAI,eAAyB;AAEtB,SAAS,YAAY,OAAuB;AACjD,iBAAe;AACjB;AAEA,SAAS,UAAU,OAA0B;AAC3C,MAAI,iBAAiB,SAAU,QAAO;AACtC,MAAI,iBAAiB,OAAQ,QAAO,UAAU;AAC9C,SAAO;AACT;AAEO,IAAM,SAAS;AAAA,EACpB,KAAK,SAAuB;AAC1B,QAAI,UAAU,MAAM,GAAG;AACrB,cAAQ,IAAI,aAAAC,QAAM,KAAK,QAAG,IAAI,OAAO,OAAO;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,QAAQ,SAAuB;AAC7B,QAAI,UAAU,MAAM,GAAG;AACrB,cAAQ,IAAI,aAAAA,QAAM,MAAM,QAAG,IAAI,OAAO,OAAO;AAAA,IAC/C;AAAA,EACF;AAAA,EAEA,KAAK,SAAuB;AAC1B,QAAI,UAAU,MAAM,GAAG;AACrB,cAAQ,KAAK,aAAAA,QAAM,OAAO,QAAG,IAAI,OAAO,aAAAA,QAAM,OAAO,OAAO,CAAC;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,MAAM,SAAuB;AAE3B,YAAQ,MAAM,aAAAA,QAAM,IAAI,QAAG,IAAI,OAAO,aAAAA,QAAM,IAAI,OAAO,CAAC;AAAA,EAC1D;AAAA,EAEA,QAAQ,SAAuB;AAC7B,QAAI,UAAU,SAAS,GAAG;AACxB,cAAQ,IAAI,aAAAA,QAAM,KAAK,MAAG,IAAI,OAAO,aAAAA,QAAM,KAAK,OAAO,CAAC;AAAA,IAC1D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,QAAI,iBAAiB,SAAU,SAAQ,IAAI;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,OAAqB;AAC1B,QAAI,iBAAiB,UAAU;AAC7B,cAAQ,IAAI;AACZ,cAAQ,IAAI,aAAAA,QAAM,KAAK,MAAM,KAAK,CAAC;AACnC,cAAQ,IAAI,aAAAA,QAAM,KAAK,SAAI,OAAO,MAAM,MAAM,CAAC,CAAC;AAAA,IAClD;AAAA,EACF;AACF;;;ADhEA;","names":["import_zod","import_zod","import_zod","import_zod","import_zod","path","matches","PATTERN_TYPES","order","x","PATTERN_TYPES","fs","path","init_specs","fs","os","path","import_zod","init_specs","yaml","current","fs","path","init_specs","sep","init_specs","issue","join","fs","path","import_module","path","init_specs","extensionProfileFor","path","LOGIC_STEREOTYPES","resolveAgainst","normalizePath","path","fs","os","path","import_zod","init_specs","matches","sep","init_specs","fs","path","init_specs","matches","localId","delta","path","fs","init_specs","resolveAgentTopology","fs","path","path","init_specs","fs","path","current","normalizePath","basename","path","init_specs","fs","path","init_specs","fs","path","path","fs","loadProjectExtensions","loadProjectConfig","resolveDomains","loadProjectConfig","path","path","path","chalk"]}