@graphrefly/graphrefly 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +234 -0
- package/dist/chunk-5X3LAO3B.js +1571 -0
- package/dist/chunk-5X3LAO3B.js.map +1 -0
- package/dist/chunk-6W5SGIGB.js +1793 -0
- package/dist/chunk-6W5SGIGB.js.map +1 -0
- package/dist/chunk-CP6MNKAA.js +97 -0
- package/dist/chunk-CP6MNKAA.js.map +1 -0
- package/dist/chunk-HP7OKEOE.js +107 -0
- package/dist/chunk-HP7OKEOE.js.map +1 -0
- package/dist/chunk-KWXPDASV.js +781 -0
- package/dist/chunk-KWXPDASV.js.map +1 -0
- package/dist/chunk-O3PI7W45.js +68 -0
- package/dist/chunk-O3PI7W45.js.map +1 -0
- package/dist/chunk-QW7H3ICI.js +1372 -0
- package/dist/chunk-QW7H3ICI.js.map +1 -0
- package/dist/chunk-VPS7L64N.js +4785 -0
- package/dist/chunk-VPS7L64N.js.map +1 -0
- package/dist/chunk-Z4Y4FMQN.js +1097 -0
- package/dist/chunk-Z4Y4FMQN.js.map +1 -0
- package/dist/compat/nestjs/index.cjs +4883 -0
- package/dist/compat/nestjs/index.cjs.map +1 -0
- package/dist/compat/nestjs/index.d.cts +7 -0
- package/dist/compat/nestjs/index.d.ts +7 -0
- package/dist/compat/nestjs/index.js +84 -0
- package/dist/compat/nestjs/index.js.map +1 -0
- package/dist/core/index.cjs +1632 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +2 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +90 -0
- package/dist/core/index.js.map +1 -0
- package/dist/extra/index.cjs +6885 -0
- package/dist/extra/index.cjs.map +1 -0
- package/dist/extra/index.d.cts +5 -0
- package/dist/extra/index.d.ts +5 -0
- package/dist/extra/index.js +290 -0
- package/dist/extra/index.js.map +1 -0
- package/dist/graph/index.cjs +3225 -0
- package/dist/graph/index.cjs.map +1 -0
- package/dist/graph/index.d.cts +3 -0
- package/dist/graph/index.d.ts +3 -0
- package/dist/graph/index.js +25 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph-CL_ZDAj9.d.cts +605 -0
- package/dist/graph-D18qmsNm.d.ts +605 -0
- package/dist/index-B6SsZs2h.d.cts +3463 -0
- package/dist/index-B7eOdgEx.d.ts +449 -0
- package/dist/index-BHUvlQ3v.d.ts +3463 -0
- package/dist/index-BtK55IE2.d.ts +231 -0
- package/dist/index-BvhgZRHK.d.cts +231 -0
- package/dist/index-Bvy_6CaN.d.ts +452 -0
- package/dist/index-C3BMRmmp.d.cts +449 -0
- package/dist/index-C5mqLhMX.d.cts +452 -0
- package/dist/index-CP_QvbWu.d.ts +940 -0
- package/dist/index-D_geH2Bm.d.cts +940 -0
- package/dist/index.cjs +14843 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1517 -0
- package/dist/index.d.ts +1517 -0
- package/dist/index.js +3649 -0
- package/dist/index.js.map +1 -0
- package/dist/meta-BsF6Sag9.d.cts +607 -0
- package/dist/meta-BsF6Sag9.d.ts +607 -0
- package/dist/patterns/reactive-layout/index.cjs +4143 -0
- package/dist/patterns/reactive-layout/index.cjs.map +1 -0
- package/dist/patterns/reactive-layout/index.d.cts +3 -0
- package/dist/patterns/reactive-layout/index.d.ts +3 -0
- package/dist/patterns/reactive-layout/index.js +38 -0
- package/dist/patterns/reactive-layout/index.js.map +1 -0
- package/dist/reactive-log-BfvfNWQh.d.cts +137 -0
- package/dist/reactive-log-ohLmTXoZ.d.ts +137 -0
- package/package.json +256 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/compat/nestjs/index.ts","../src/compat/nestjs/decorators.ts","../src/compat/nestjs/tokens.ts","../src/compat/nestjs/explorer.ts","../src/compat/nestjs/gateway.ts","../src/compat/nestjs/guard.ts","../src/compat/nestjs/module.ts","../src/patterns/cqrs.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// NestJS integration — Module, DI, Lifecycle, RxJS bridge (Phase 5.5)\n// ---------------------------------------------------------------------------\n// Bridges GraphReFly into NestJS's DI container and RxJS-based ecosystem.\n// NestJS and RxJS are peer dependencies — install them in your NestJS app.\n//\n// Usage:\n// import { GraphReflyModule, InjectGraph, InjectNode, toObservable }\n// from '@graphrefly/graphrefly-ts/compat/nestjs';\n// ---------------------------------------------------------------------------\n\n// RxJS bridge (re-exported from extra for convenience)\nexport { observeGraph$, observeNode$, toMessages$, toObservable } from \"../../extra/observable.js\";\n\n// Decorators\nexport {\n\tCOMMAND_HANDLERS,\n\tCommandHandler,\n\ttype CommandHandlerMeta,\n\tCQRS_EVENT_HANDLERS,\n\tCRON_HANDLERS,\n\tEVENT_HANDLERS,\n\tEventHandler,\n\ttype EventHandlerMeta,\n\tGraphCron,\n\ttype GraphCronMeta,\n\tGraphInterval,\n\ttype GraphIntervalMeta,\n\tINTERVAL_HANDLERS,\n\tInjectCqrsGraph,\n\tInjectGraph,\n\tInjectNode,\n\tOnGraphEvent,\n\ttype OnGraphEventMeta,\n\tQUERY_HANDLERS,\n\tQueryHandler,\n\ttype QueryHandlerMeta,\n\tSAGA_HANDLERS,\n\tSagaHandler,\n\ttype SagaHandlerMeta,\n} from \"./decorators.js\";\n// Explorer (event/schedule discovery)\nexport { GraphReflyEventExplorer } from \"./explorer.js\";\n// Gateway helpers (Phase 5.1)\nexport {\n\tObserveGateway,\n\ttype ObserveGatewayOptions,\n\ttype ObserveSSEOptions,\n\ttype ObserveSubscriptionOptions,\n\ttype ObserveWsCommand,\n\ttype ObserveWsMessage,\n\tobserveSSE,\n\tobserveSubscription,\n} from \"./gateway.js\";\n// Actor bridge (Phase 5.1)\nexport {\n\tACTOR_KEY,\n\ttype ActorExtractor,\n\tfromHeader,\n\tfromJwtPayload,\n\tGraphReflyGuard,\n\tGraphReflyGuardImpl,\n\tgetActor,\n} from \"./guard.js\";\n// Module & DI\nexport {\n\ttype GraphReflyCqrsOptions,\n\ttype GraphReflyFeatureOptions,\n\tGraphReflyModule,\n\ttype GraphReflyRootOptions,\n} from \"./module.js\";\n// Injection tokens\nexport {\n\tGRAPHREFLY_REQUEST_GRAPH,\n\tGRAPHREFLY_ROOT_GRAPH,\n\tgetGraphToken,\n\tgetNodeToken,\n} from \"./tokens.js\";\n","// ---------------------------------------------------------------------------\n// NestJS decorators for GraphReFly DI, events, and scheduling.\n// ---------------------------------------------------------------------------\n// NOTE: esbuild (used by vitest/vite) uses TC39 Stage 3 decorators, not\n// legacy TypeScript experimental decorators. Method decorators receive\n// (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext). We use\n// context.addInitializer() to register metadata when the class instance is\n// created, which runs before NestJS lifecycle hooks.\n// ---------------------------------------------------------------------------\n\nimport { Inject } from \"@nestjs/common\";\nimport {\n\tGRAPHREFLY_REQUEST_GRAPH,\n\tGRAPHREFLY_ROOT_GRAPH,\n\tgetGraphToken,\n\tgetNodeToken,\n} from \"./tokens.js\";\n\n/** Class constructor key for decorator registries and Nest `ModuleRef.get()`. */\nexport type DecoratorHostConstructor = abstract new (...args: unknown[]) => unknown;\n\n/**\n * TC39 Stage 3 class method decorator first argument (the method itself).\n * Narrower than `Function` for Biome `noBannedTypes`.\n */\nexport type DecoratorBoundMethod = (...args: unknown[]) => unknown;\n\n// ---------------------------------------------------------------------------\n// Global registries (populated by decorator initializers, read by explorer)\n// ---------------------------------------------------------------------------\n\nexport interface OnGraphEventMeta {\n\tnodeName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface GraphIntervalMeta {\n\tms: number;\n\tmethodKey: string | symbol;\n}\n\nexport interface GraphCronMeta {\n\texpr: string;\n\tmethodKey: string | symbol;\n}\n\n/** Registry: constructor → event handler metadata. */\nexport const EVENT_HANDLERS = new Map<DecoratorHostConstructor, OnGraphEventMeta[]>();\n/** Registry: constructor → interval metadata. */\nexport const INTERVAL_HANDLERS = new Map<DecoratorHostConstructor, GraphIntervalMeta[]>();\n/** Registry: constructor → cron metadata. */\nexport const CRON_HANDLERS = new Map<DecoratorHostConstructor, GraphCronMeta[]>();\n\n// ---------------------------------------------------------------------------\n// CQRS decorator metadata & registries (Phase 5.5 — CQRS replacement)\n// ---------------------------------------------------------------------------\n\nexport interface CommandHandlerMeta {\n\tcqrsName: string;\n\tcommandName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface EventHandlerMeta {\n\tcqrsName: string;\n\teventName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface QueryHandlerMeta {\n\tcqrsName: string;\n\tprojectionName: string;\n\tmethodKey: string | symbol;\n}\n\nexport interface SagaHandlerMeta {\n\tcqrsName: string;\n\teventNames: readonly string[];\n\tsagaName: string;\n\tmethodKey: string | symbol;\n}\n\n/** Registry: constructor → command handler metadata. */\nexport const COMMAND_HANDLERS = new Map<DecoratorHostConstructor, CommandHandlerMeta[]>();\n/** Registry: constructor → event handler metadata. */\nexport const CQRS_EVENT_HANDLERS = new Map<DecoratorHostConstructor, EventHandlerMeta[]>();\n/** Registry: constructor → query handler metadata. */\nexport const QUERY_HANDLERS = new Map<DecoratorHostConstructor, QueryHandlerMeta[]>();\n/** Registry: constructor → saga handler metadata. */\nexport const SAGA_HANDLERS = new Map<DecoratorHostConstructor, SagaHandlerMeta[]>();\n\n// ---------------------------------------------------------------------------\n// DI decorators\n// ---------------------------------------------------------------------------\n\n/**\n * Inject a `Graph` instance into a NestJS service or controller.\n *\n * - No argument → injects the root graph (from `forRoot()`).\n * - With `name` → injects the named feature graph (from `forFeature({ name })`).\n * - With `\"request\"` → injects the request-scoped graph (requires `requestScope: true`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class PaymentService {\n * constructor(\n * @InjectGraph() private root: Graph,\n * @InjectGraph(\"payments\") private payments: Graph,\n * ) {}\n * }\n * ```\n */\nexport function InjectGraph(name?: string): ParameterDecorator & PropertyDecorator {\n\tif (name === \"request\") return Inject(GRAPHREFLY_REQUEST_GRAPH);\n\treturn Inject(name ? getGraphToken(name) : GRAPHREFLY_ROOT_GRAPH);\n}\n\n/**\n * Inject a `CqrsGraph` instance into a NestJS service or controller.\n *\n * Typed alternative to `@InjectGraph(name)` — returns `CqrsGraph` instead of `Graph`,\n * giving access to `.command()`, `.dispatch()`, `.event()`, `.projection()`, `.saga()`.\n *\n * @param name - The CQRS graph name (from `forCqrs({ name })`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class OrderService {\n * constructor(@InjectCqrsGraph(\"orders\") private orders: CqrsGraph) {\n * orders.dispatch(\"placeOrder\", { id: \"1\" }); // fully typed\n * }\n * }\n * ```\n */\nexport function InjectCqrsGraph(name: string): ParameterDecorator & PropertyDecorator {\n\treturn Inject(getGraphToken(name));\n}\n\n/**\n * Inject a `Node` from the graph by its qualified path.\n *\n * The path must be declared in the `nodes` array of `forRoot()` or `forFeature()`.\n * The module registers a factory provider that resolves the node from the root graph\n * at injection time.\n *\n * @example\n * ```ts\n * GraphReflyModule.forRoot({ nodes: [\"payment::validate\"] })\n *\n * @Injectable()\n * export class PaymentService {\n * constructor(@InjectNode(\"payment::validate\") private validate: Node<boolean>) {}\n * }\n * ```\n */\nexport function InjectNode(path: string): ParameterDecorator & PropertyDecorator {\n\treturn Inject(getNodeToken(path));\n}\n\n// ---------------------------------------------------------------------------\n// Event & schedule method decorators (TC39 Stage 3 decorator API)\n// ---------------------------------------------------------------------------\n\n/**\n * Subscribe a method to a graph node's DATA emissions — replaces `@OnEvent()`.\n *\n * The method is called with the value payload on each `DATA` message from the\n * named node. Routes through `graph.observe()` so actor guards are respected.\n * Subscription is created on module init and disposed on destroy.\n *\n * For full protocol access (DIRTY, COMPLETE, ERROR, custom types), use\n * `graph.observe()` directly instead of this decorator.\n *\n * @param nodeName - Qualified node path (e.g. `\"orders::placed\"`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class OrderService {\n * @OnGraphEvent(\"orders::placed\")\n * handleOrder(value: Order) { ... }\n * }\n * ```\n */\nexport function OnGraphEvent(\n\tnodeName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = EVENT_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ nodeName, methodKey });\n\t\t\tEVENT_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Run a method on a fixed interval — replaces `@Interval()` from `@nestjs/schedule`.\n *\n * Backed by a `fromTimer` node added to the root graph as `__schedule__.<className>.<methodName>`.\n * Visible in `graph.describe()`, pausable via `graph.signal(name, [[PAUSE]])`.\n *\n * @param ms - Interval in milliseconds.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class CleanupService {\n * @GraphInterval(5000)\n * pruneStale() { ... }\n * }\n * ```\n */\nexport function GraphInterval(\n\tms: number,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = INTERVAL_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ ms, methodKey });\n\t\t\tINTERVAL_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Run a method on a cron schedule — replaces `@Cron()` from `@nestjs/schedule`.\n *\n * Backed by a `fromCron` node added to the root graph as `__schedule__.<className>.<methodName>`.\n * Visible in `graph.describe()`, pausable via PAUSE/RESUME signals.\n *\n * @param expr - 5-field cron expression (`min hour dom month dow`).\n *\n * @example\n * ```ts\n * @Injectable()\n * export class ReportService {\n * @GraphCron(\"0 9 * * 1\")\n * weeklyReport() { ... }\n * }\n * ```\n */\nexport function GraphCron(\n\texpr: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = CRON_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ expr, methodKey });\n\t\t\tCRON_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// CQRS method decorators (Phase 5.5 — CQRS replacement)\n// ---------------------------------------------------------------------------\n\n/**\n * Register a method as a CQRS command handler — replaces `@CommandHandler()` from `@nestjs/cqrs`.\n *\n * The method receives `(payload, { emit })` — same signature as `CqrsGraph.command()` handlers.\n * Wired reactively via the explorer on module init.\n *\n * @param cqrsName - Name of the CQRS graph (from `forCqrs({ name })`).\n * @param commandName - Command to handle.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class OrderService {\n * @CommandHandler(\"orders\", \"placeOrder\")\n * handlePlace(payload: PlaceOrderDto, { emit }: CommandActions) {\n * emit(\"orderPlaced\", { orderId: payload.id, amount: payload.amount });\n * }\n * }\n * ```\n */\nexport function CommandHandler(\n\tcqrsName: string,\n\tcommandName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = COMMAND_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, commandName, methodKey });\n\t\t\tCOMMAND_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Subscribe a method to CQRS event stream DATA — replaces `@EventsHandler()` from `@nestjs/cqrs`.\n *\n * The method receives each `CqrsEvent` envelope as events arrive. Subscription is reactive\n * via `graph.observe()` — actor guards are respected.\n *\n * @param cqrsName - Name of the CQRS graph.\n * @param eventName - Event stream to subscribe to.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class NotificationService {\n * @EventHandler(\"orders\", \"orderPlaced\")\n * onOrderPlaced(event: CqrsEvent<{ orderId: string }>) {\n * console.log(\"Order placed:\", event.payload.orderId);\n * }\n * }\n * ```\n */\nexport function EventHandler(\n\tcqrsName: string,\n\teventName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = CQRS_EVENT_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, eventName, methodKey });\n\t\t\tCQRS_EVENT_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Subscribe a method to CQRS projection changes — replaces `@QueryHandler()` from `@nestjs/cqrs`.\n *\n * The method is called reactively whenever the projection's value changes (DATA emission).\n * This is push-based, not request-response — the projection recomputes on upstream events.\n *\n * @param cqrsName - Name of the CQRS graph.\n * @param projectionName - Projection to observe.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class DashboardService {\n * @QueryHandler(\"orders\", \"orderCount\")\n * onCountChanged(count: number) {\n * this.broadcast({ type: \"orderCount\", value: count });\n * }\n * }\n * ```\n */\nexport function QueryHandler(\n\tcqrsName: string,\n\tprojectionName: string,\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = QUERY_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, projectionName, methodKey });\n\t\t\tQUERY_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n\n/**\n * Register a method as a CQRS saga — replaces RxJS saga streams from `@nestjs/cqrs`.\n *\n * The method receives each new `CqrsEvent` from the specified event streams. Backed by\n * `CqrsGraph.saga()` — tracks last-processed entry, only delivers new events.\n *\n * @param cqrsName - Name of the CQRS graph.\n * @param sagaName - Name for this saga node in the graph.\n * @param eventNames - Event streams to react to.\n *\n * @example\n * ```ts\n * @Injectable()\n * export class FulfillmentService {\n * @SagaHandler(\"orders\", \"fulfillment\", [\"orderPlaced\", \"paymentConfirmed\"])\n * onOrderFlow(event: CqrsEvent) {\n * if (event.type === \"paymentConfirmed\") this.shipOrder(event.payload);\n * }\n * }\n * ```\n */\nexport function SagaHandler(\n\tcqrsName: string,\n\tsagaName: string,\n\teventNames: readonly string[],\n): (value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => void {\n\treturn (_value: DecoratorBoundMethod, context: ClassMethodDecoratorContext) => {\n\t\tconst methodKey = context.name;\n\t\tcontext.addInitializer(function (this: unknown) {\n\t\t\tconst ctor = (this as { constructor: DecoratorHostConstructor }).constructor;\n\t\t\tconst existing = SAGA_HANDLERS.get(ctor) ?? [];\n\t\t\texisting.push({ cqrsName, eventNames, sagaName, methodKey });\n\t\t\tSAGA_HANDLERS.set(ctor, existing);\n\t\t});\n\t};\n}\n","// ---------------------------------------------------------------------------\n// NestJS DI tokens for GraphReFly integration.\n// ---------------------------------------------------------------------------\n\n/** Injection token for the root `Graph` singleton created by `forRoot()`. */\nexport const GRAPHREFLY_ROOT_GRAPH = Symbol.for(\"graphrefly:root-graph\");\n\n/** Injection token for `forRoot()` / `forFeature()` options. */\nexport const GRAPHREFLY_MODULE_OPTIONS = Symbol.for(\"graphrefly:module-options\");\n\n/** Injection token for the request-scoped `Graph` created by request scope config. */\nexport const GRAPHREFLY_REQUEST_GRAPH = Symbol.for(\"graphrefly:request-graph\");\n\n/**\n * Get the injection token for a named feature graph.\n *\n * Feature graphs registered via `GraphReflyModule.forFeature({ name })` are\n * injectable using this token (or via the `@InjectGraph(name)` decorator).\n */\nexport function getGraphToken(name: string): symbol {\n\treturn Symbol.for(`graphrefly:graph:${name}`);\n}\n\n/**\n * Get the injection token for a node at a qualified path.\n *\n * Nodes declared in `forRoot({ nodes })` or `forFeature({ nodes })` are\n * injectable using this token (or via the `@InjectNode(path)` decorator).\n */\nexport function getNodeToken(path: string): symbol {\n\treturn Symbol.for(`graphrefly:node:${path}`);\n}\n","// ---------------------------------------------------------------------------\n// GraphReflyEventExplorer — discovers @OnGraphEvent, @GraphInterval, @GraphCron\n// decorated methods and wires them to the root graph.\n// ---------------------------------------------------------------------------\n// Registered by `forRoot()`. On module init, reads global decorator registries,\n// resolves provider instances via ModuleRef, and creates reactive subscriptions\n// / timer nodes. On module destroy, disposes all subscriptions and removes\n// schedule nodes from the graph.\n//\n// Runtime is fully reactive — push-based via graph.observe().\n// No polling, no microtasks, no promises. Timer nodes use central fromTimer /\n// fromCron primitives.\n// ---------------------------------------------------------------------------\n\nimport type { OnModuleDestroy, OnModuleInit } from \"@nestjs/common\";\nimport type { ModuleRef } from \"@nestjs/core\";\nimport { DATA, type Messages } from \"../../core/messages.js\";\nimport { fromCron, fromTimer } from \"../../extra/sources.js\";\nimport type { Graph, GraphObserveOne } from \"../../graph/graph.js\";\nimport type { CqrsGraph } from \"../../patterns/cqrs.js\";\nimport {\n\tCOMMAND_HANDLERS,\n\ttype CommandHandlerMeta,\n\tCQRS_EVENT_HANDLERS,\n\tCRON_HANDLERS,\n\ttype DecoratorBoundMethod,\n\ttype DecoratorHostConstructor,\n\tEVENT_HANDLERS,\n\ttype EventHandlerMeta,\n\ttype GraphCronMeta,\n\ttype GraphIntervalMeta,\n\tINTERVAL_HANDLERS,\n\ttype OnGraphEventMeta,\n\tQUERY_HANDLERS,\n\ttype QueryHandlerMeta,\n\tSAGA_HANDLERS,\n\ttype SagaHandlerMeta,\n} from \"./decorators.js\";\nimport { getGraphToken } from \"./tokens.js\";\n\n/** Monotonic counter for schedule node name disambiguation. */\nlet scheduleSeq = 0;\n\nexport class GraphReflyEventExplorer implements OnModuleInit, OnModuleDestroy {\n\tprivate readonly disposers: Array<() => void> = [];\n\tprivate readonly scheduleNodeNames: string[] = [];\n\n\tconstructor(\n\t\tprivate readonly graph: Graph,\n\t\tprivate readonly moduleRef: ModuleRef,\n\t) {}\n\n\tonModuleInit(): void {\n\t\tthis.wireEvents();\n\t\tthis.wireIntervals();\n\t\tthis.wireCrons();\n\t\tthis.wireCqrsCommands();\n\t\tthis.wireCqrsEvents();\n\t\tthis.wireCqrsQueries();\n\t\tthis.wireCqrsSagas();\n\t}\n\n\tonModuleDestroy(): void {\n\t\tfor (const dispose of this.disposers) dispose();\n\t\tthis.disposers.length = 0;\n\n\t\tfor (const name of this.scheduleNodeNames) {\n\t\t\ttry {\n\t\t\t\tthis.graph.remove(name);\n\t\t\t} catch {\n\t\t\t\t// Node may already be gone if graph.destroy() ran first.\n\t\t\t}\n\t\t}\n\t\tthis.scheduleNodeNames.length = 0;\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @OnGraphEvent — reactive subscription via graph.observe()\n\t// -----------------------------------------------------------------------\n\n\tprivate wireEvents(): void {\n\t\tfor (const [ctor, metas] of EVENT_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireEventHandler(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireEventHandler(instance: object, meta: OnGraphEventMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\n\t\t// Route through graph.observe() so actor guards are respected.\n\t\tconst handle = this.observeNode(meta.nodeName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbound(m[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @GraphInterval — reactive via fromTimer central timer primitive\n\t// -----------------------------------------------------------------------\n\n\tprivate wireIntervals(): void {\n\t\tfor (const [ctor, metas] of INTERVAL_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireIntervalHandler(instance, ctor, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireIntervalHandler(\n\t\tinstance: object,\n\t\tctor: DecoratorHostConstructor,\n\t\tmeta: GraphIntervalMeta,\n\t): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst className = ctor.name ?? \"anonymous\";\n\t\tconst nodeName = `__schedule__.${className}.${String(meta.methodKey)}.${scheduleSeq++}`;\n\n\t\tconst timerNode = fromTimer(meta.ms, { period: meta.ms, name: nodeName });\n\t\tthis.graph.add(nodeName, timerNode);\n\t\tthis.scheduleNodeNames.push(nodeName);\n\n\t\t// Subscribe through graph.observe() for consistency.\n\t\tconst handle = this.observeNode(nodeName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) bound(m[1]);\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @GraphCron — reactive via fromCron central timer primitive\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCrons(): void {\n\t\tfor (const [ctor, metas] of CRON_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCronHandler(instance, ctor, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCronHandler(\n\t\tinstance: object,\n\t\tctor: DecoratorHostConstructor,\n\t\tmeta: GraphCronMeta,\n\t): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst className = ctor.name ?? \"anonymous\";\n\t\tconst nodeName = `__schedule__.${className}.${String(meta.methodKey)}.${scheduleSeq++}`;\n\n\t\tconst cronNode = fromCron(meta.expr, { name: nodeName });\n\t\tthis.graph.add(nodeName, cronNode);\n\t\tthis.scheduleNodeNames.push(nodeName);\n\n\t\t// Subscribe through graph.observe() for consistency.\n\t\tconst handle = this.observeNode(nodeName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) bound(m[1]);\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @CommandHandler — register method as CqrsGraph command handler\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsCommands(): void {\n\t\tfor (const [ctor, metas] of COMMAND_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsCommand(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsCommand(instance: object, meta: CommandHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\tcqrsGraph.command(meta.commandName, bound);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @EventHandler — subscribe method to CQRS event stream\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsEvents(): void {\n\t\tfor (const [ctor, metas] of CQRS_EVENT_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsEventHandler(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsEventHandler(instance: object, meta: EventHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\t// Ensure the event stream exists.\n\t\tcqrsGraph.event(meta.eventName);\n\n\t\t// Snapshot the highest seq already in the log so we only deliver new events.\n\t\t// Tracking by seq (monotonic per-graph) is robust against reactive log trim.\n\t\tconst eventNode = cqrsGraph.resolve(meta.eventName);\n\t\tconst currentSnap = eventNode.get() as\n\t\t\t| { value: { entries: readonly { seq: number }[] } }\n\t\t\t| undefined;\n\t\tconst existingEntries = currentSnap?.value?.entries;\n\t\tlet lastSeq =\n\t\t\texistingEntries && existingEntries.length > 0\n\t\t\t\t? existingEntries[existingEntries.length - 1].seq\n\t\t\t\t: 0;\n\n\t\t// Subscribe reactively via graph.observe() — respects actor guards.\n\t\tconst handle = this.observeNodeOn(cqrsGraph, meta.eventName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tconst snap = m[1] as { value: { entries: readonly { seq: number }[] } };\n\t\t\t\t\tfor (const entry of snap.value.entries) {\n\t\t\t\t\t\tif (entry.seq > lastSeq) {\n\t\t\t\t\t\t\tbound(entry);\n\t\t\t\t\t\t\tlastSeq = entry.seq;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @QueryHandler — subscribe method to CQRS projection changes\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsQueries(): void {\n\t\tfor (const [ctor, metas] of QUERY_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsQuery(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsQuery(instance: object, meta: QueryHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\t// Subscribe reactively to the projection node — push on every DATA.\n\t\tconst handle = this.observeNodeOn(cqrsGraph, meta.projectionName);\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const m of msgs) {\n\t\t\t\tif (m[0] === DATA) {\n\t\t\t\t\tbound(m[1]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tthis.disposers.push(unsub);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// @SagaHandler — register method as CqrsGraph saga (subgraph side effect)\n\t// -----------------------------------------------------------------------\n\n\tprivate wireCqrsSagas(): void {\n\t\tfor (const [ctor, metas] of SAGA_HANDLERS) {\n\t\t\tconst instance = this.resolveInstance(ctor);\n\t\t\tif (!instance) continue;\n\n\t\t\tfor (const meta of metas) {\n\t\t\t\tthis.wireCqrsSaga(instance, meta);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate wireCqrsSaga(instance: object, meta: SagaHandlerMeta): void {\n\t\tconst method = (instance as Record<string | symbol, DecoratorBoundMethod>)[meta.methodKey];\n\t\tif (typeof method !== \"function\") return;\n\n\t\tconst bound = method.bind(instance);\n\t\tconst cqrsGraph = this.resolveCqrsGraph(meta.cqrsName);\n\t\tif (!cqrsGraph) return;\n\n\t\tcqrsGraph.saga(meta.sagaName, meta.eventNames, bound);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Helpers\n\t// -----------------------------------------------------------------------\n\n\tprivate observeNode(name: string): GraphObserveOne {\n\t\t// Overload resolution picks ObserveResult; cast to the correct single-node type.\n\t\treturn this.graph.observe(name) as unknown as GraphObserveOne;\n\t}\n\n\tprivate observeNodeOn(graph: Graph, name: string): GraphObserveOne {\n\t\treturn graph.observe(name) as unknown as GraphObserveOne;\n\t}\n\n\tprivate resolveCqrsGraph(name: string): CqrsGraph | null {\n\t\ttry {\n\t\t\treturn this.moduleRef.get(getGraphToken(name), { strict: false }) as CqrsGraph;\n\t\t} catch {\n\t\t\tconsole.warn(\n\t\t\t\t`[GraphReFly] CqrsGraph \"${name}\" not found in DI — ` +\n\t\t\t\t\t`did you import GraphReflyModule.forCqrs({ name: \"${name}\" })?`,\n\t\t\t);\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprivate resolveInstance(ctor: DecoratorHostConstructor): object | null {\n\t\ttry {\n\t\t\treturn this.moduleRef.get(ctor, { strict: false });\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n}\n","// ---------------------------------------------------------------------------\n// NestJS Gateway helpers — reactive bridges from graph.observe() to transports.\n// ---------------------------------------------------------------------------\n// All helpers are push-based: they subscribe to `graph.observe()` with actor\n// context and forward DATA messages to the transport. No polling.\n//\n// Actor-scoped observation respects node guards (Phase 1.5). Clients only\n// see DATA values from nodes their Actor is allowed to observe.\n// ---------------------------------------------------------------------------\n\nimport type { Actor } from \"../../core/actor.js\";\nimport { COMPLETE, DATA, ERROR, type Messages, TEARDOWN } from \"../../core/messages.js\";\nimport { createWatermarkController, type WatermarkController } from \"../../extra/backpressure.js\";\nimport type { Graph, GraphObserveOne } from \"../../graph/graph.js\";\n\n// ---------------------------------------------------------------------------\n// Shared types\n// ---------------------------------------------------------------------------\n\n/**\n * Client-to-server commands for the WebSocket observe protocol.\n */\nexport type ObserveWsCommand =\n\t| { type: \"subscribe\"; path: string }\n\t| { type: \"unsubscribe\"; path: string }\n\t| { type: \"ack\"; path: string; count?: number };\n\n/**\n * Server-to-client messages for the WebSocket observe protocol.\n */\nexport type ObserveWsMessage<T = unknown> =\n\t| { type: \"data\"; path: string; value: T }\n\t| { type: \"error\"; path: string; error: string }\n\t| { type: \"complete\"; path: string }\n\t| { type: \"subscribed\"; path: string }\n\t| { type: \"unsubscribed\"; path: string }\n\t| { type: \"err\"; message: string };\n\n// ---------------------------------------------------------------------------\n// observeSSE — graph.observe() → SSE ReadableStream\n// ---------------------------------------------------------------------------\n\nexport type ObserveSSEOptions = {\n\tactor?: Actor;\n\tserialize?: (value: unknown) => string;\n\tkeepAliveMs?: number;\n\tsignal?: AbortSignal;\n\t/** Pending DATA count at which PAUSE is sent upstream. Enables backpressure when set. */\n\thighWaterMark?: number;\n\t/** Pending DATA count at which RESUME is sent upstream. Defaults to `Math.floor(highWaterMark / 2)`. */\n\tlowWaterMark?: number;\n};\n\n/**\n * Creates an SSE `ReadableStream` that streams DATA values from a graph node.\n *\n * Routes through `graph.observe(path, { actor })` so node guards are respected.\n * The stream emits `event: data` for DATA, `event: error` for ERROR, and\n * `event: complete` for COMPLETE (then closes). TEARDOWN also closes the stream.\n *\n * @param graph - The graph to observe.\n * @param path - Qualified node path to observe.\n * @param opts - Actor context, serialization, keep-alive.\n * @returns A `ReadableStream<Uint8Array>` suitable for NestJS SSE endpoints.\n *\n * @example\n * ```ts\n * @Sse(\"events/:path\")\n * streamEvents(@Param(\"path\") path: string, @Req() req: Request) {\n * return observeSSE(this.graph, path, { actor: getActor(req) });\n * }\n * ```\n */\nexport function observeSSE(\n\tgraph: Graph,\n\tpath: string,\n\topts?: ObserveSSEOptions,\n): ReadableStream<Uint8Array> {\n\tconst { actor, serialize = defaultSerialize, keepAliveMs, signal } = opts ?? {};\n\tconst encoder = new TextEncoder();\n\tlet stop: (() => void) | undefined;\n\tconst useBackpressure = opts?.highWaterMark != null;\n\n\tlet wm: WatermarkController | undefined;\n\tlet pullResolve: (() => void) | undefined;\n\n\t// When backpressure is enabled we tag buffered entries so pull() only calls\n\t// onDequeue for DATA frames (not keepalive, ERROR, or COMPLETE frames).\n\ttype BufEntry = { frame: Uint8Array; counted: boolean };\n\tconst taggedBuf: BufEntry[] = [];\n\tlet closed = false;\n\n\treturn new ReadableStream<Uint8Array>({\n\t\tstart(controller) {\n\t\t\tlet keepAlive: ReturnType<typeof setInterval> | undefined;\n\t\t\tlet unsub: () => void = () => {};\n\t\t\tconst close = () => {\n\t\t\t\tif (closed) return;\n\t\t\t\tclosed = true;\n\t\t\t\tif (keepAlive !== undefined) clearInterval(keepAlive);\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t// Unsub first to prevent further sink callbacks during dispose.\n\t\t\t\tunsub();\n\t\t\t\twm?.dispose();\n\t\t\t\t// Resolve any parked pull() promise so the stream can finish.\n\t\t\t\tpullResolve?.();\n\t\t\t\tpullResolve = undefined;\n\t\t\t\t// Flush remaining buffered frames before closing.\n\t\t\t\tfor (const entry of taggedBuf) controller.enqueue(entry.frame);\n\t\t\t\ttaggedBuf.length = 0;\n\t\t\t\tcontroller.close();\n\t\t\t};\n\t\t\tstop = close;\n\t\t\tconst onAbort = () => close();\n\n\t\t\tconst handle = graph.observe(path, { actor }) as unknown as GraphObserveOne;\n\n\t\t\tif (useBackpressure) {\n\t\t\t\twm = createWatermarkController((msgs) => handle.up(msgs), {\n\t\t\t\t\thighWaterMark: opts!.highWaterMark!,\n\t\t\t\t\tlowWaterMark: opts!.lowWaterMark ?? Math.floor(opts!.highWaterMark! / 2),\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tunsub = handle.subscribe((msgs: Messages) => {\n\t\t\t\tfor (const msg of msgs) {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tconst t = msg[0];\n\t\t\t\t\tif (t === DATA) {\n\t\t\t\t\t\tconst frame = encoder.encode(sseFrame(\"data\", serialize(msg[1])));\n\t\t\t\t\t\tif (useBackpressure) {\n\t\t\t\t\t\t\ttaggedBuf.push({ frame, counted: true });\n\t\t\t\t\t\t\twm!.onEnqueue();\n\t\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontroller.enqueue(frame);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\t\tconst frame = encoder.encode(sseFrame(\"error\", serialize(msg[1])));\n\t\t\t\t\t\tif (useBackpressure) {\n\t\t\t\t\t\t\ttaggedBuf.push({ frame, counted: false });\n\t\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontroller.enqueue(frame);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t} else if (t === COMPLETE || t === TEARDOWN) {\n\t\t\t\t\t\tif (t === COMPLETE) {\n\t\t\t\t\t\t\tconst frame = encoder.encode(sseFrame(\"complete\"));\n\t\t\t\t\t\t\tif (useBackpressure) {\n\t\t\t\t\t\t\t\ttaggedBuf.push({ frame, counted: false });\n\t\t\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcontroller.enqueue(frame);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tclose();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t// DIRTY, RESOLVED, and other protocol internals are not exposed to SSE clients\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (keepAliveMs !== undefined && keepAliveMs > 0) {\n\t\t\t\tkeepAlive = setInterval(() => {\n\t\t\t\t\tif (closed) return;\n\t\t\t\t\tif (useBackpressure) {\n\t\t\t\t\t\t// Keepalive frames bypass watermark accounting entirely.\n\t\t\t\t\t\ttaggedBuf.push({ frame: encoder.encode(\": keepalive\\n\\n\"), counted: false });\n\t\t\t\t\t\tpullResolve?.();\n\t\t\t\t\t\tpullResolve = undefined;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontroller.enqueue(encoder.encode(\": keepalive\\n\\n\"));\n\t\t\t\t\t}\n\t\t\t\t}, keepAliveMs);\n\t\t\t}\n\t\t\tif (signal?.aborted) onAbort();\n\t\t\telse signal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t},\n\t\tpull(controller) {\n\t\t\tif (!useBackpressure) return;\n\t\t\tif (closed) return;\n\t\t\tif (taggedBuf.length > 0) {\n\t\t\t\tconst entry = taggedBuf.shift()!;\n\t\t\t\tcontroller.enqueue(entry.frame);\n\t\t\t\tif (entry.counted) wm!.onDequeue();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// No data available — park until the sink callback pushes more.\n\t\t\treturn new Promise<void>((resolve) => {\n\t\t\t\tpullResolve = resolve;\n\t\t\t});\n\t\t},\n\t\tcancel() {\n\t\t\t// Guard against double-close (cancel may fire after COMPLETE/ERROR already closed).\n\t\t\ttry {\n\t\t\t\tstop?.();\n\t\t\t} catch {\n\t\t\t\t/* already closed */\n\t\t\t}\n\t\t},\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// observeSubscription — graph.observe() → AsyncIterableIterator (GraphQL)\n// ---------------------------------------------------------------------------\n\nexport type ObserveSubscriptionOptions<T = unknown> = {\n\tactor?: Actor;\n\t/**\n\t * Optional value filter. Only matching DATA values are enqueued.\n\t *\n\t * **Note:** `filter` and `highWaterMark` are semantically decoupled — the\n\t * watermark counts items that pass the filter, not total upstream work.\n\t * If the filter rejects most items, backpressure may never engage despite\n\t * high upstream throughput. For upstream-level resource protection, place a\n\t * filtering derived node in the graph before the observe point instead.\n\t */\n\tfilter?: (value: T) => boolean;\n\t/** Pending DATA count at which PAUSE is sent upstream. Enables backpressure when set. */\n\thighWaterMark?: number;\n\t/** Pending DATA count at which RESUME is sent upstream. Defaults to `Math.floor(highWaterMark / 2)`. */\n\tlowWaterMark?: number;\n};\n\n/**\n * Creates an `AsyncIterableIterator` that yields DATA values from a graph node.\n *\n * Designed for GraphQL subscription resolvers (Apollo, Mercurius, etc.).\n * Routes through `graph.observe(path, { actor })` for guard-scoped access.\n *\n * The iterator completes on COMPLETE/TEARDOWN and throws on ERROR.\n *\n * @param graph - The graph to observe.\n * @param path - Qualified node path to observe.\n * @param opts - Actor context, optional value filter.\n * @returns An async iterable that yields DATA payloads.\n *\n * @example\n * ```ts\n * // Apollo-style resolver\n * Subscription: {\n * orderStatus: {\n * subscribe: (_parent, args, ctx) =>\n * observeSubscription(ctx.graph, `orders::${args.id}::status`, {\n * actor: ctx.actor,\n * }),\n * },\n * }\n * ```\n */\nexport function observeSubscription<T = unknown>(\n\tgraph: Graph,\n\tpath: string,\n\topts?: ObserveSubscriptionOptions<T>,\n): AsyncIterableIterator<T> {\n\tconst { actor, filter } = opts ?? {};\n\n\ttype QueueItem = { done: false; value: T } | { done: true; value?: undefined; error?: Error };\n\n\tconst queue: QueueItem[] = [];\n\tconst waiters: Array<{\n\t\tresolve: (result: IteratorResult<T>) => void;\n\t\treject: (err: unknown) => void;\n\t}> = [];\n\tlet disposed = false;\n\n\tconst handle = graph.observe(path, { actor }) as unknown as GraphObserveOne;\n\n\tconst wm =\n\t\topts?.highWaterMark != null\n\t\t\t? createWatermarkController((msgs) => handle.up(msgs), {\n\t\t\t\t\thighWaterMark: opts.highWaterMark,\n\t\t\t\t\tlowWaterMark: opts.lowWaterMark ?? Math.floor(opts.highWaterMark / 2),\n\t\t\t\t})\n\t\t\t: undefined;\n\n\tconst dispose = () => {\n\t\tif (disposed) return;\n\t\tdisposed = true;\n\t\twm?.dispose();\n\t\tunsub();\n\t};\n\n\tconst push = (item: QueueItem) => {\n\t\tif (disposed) return;\n\t\tif (waiters.length > 0) {\n\t\t\tconst w = waiters.shift()!;\n\t\t\tif (item.done && item.error) w.reject(item.error);\n\t\t\telse if (item.done) w.resolve({ done: true, value: undefined });\n\t\t\telse w.resolve({ done: false, value: item.value as T });\n\t\t\t// Direct handoff to waiter — no queue growth, no watermark increment.\n\t\t} else {\n\t\t\tqueue.push(item);\n\t\t\tif (!item.done) wm?.onEnqueue();\n\t\t}\n\t};\n\n\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\tfor (const msg of msgs) {\n\t\t\tconst t = msg[0];\n\t\t\tif (t === DATA) {\n\t\t\t\tconst value = msg[1] as T;\n\t\t\t\tif (filter && !filter(value)) continue;\n\t\t\t\tpush({ done: false, value });\n\t\t\t} else if (t === ERROR) {\n\t\t\t\tconst err = msg[1] instanceof Error ? msg[1] : new Error(String(msg[1]));\n\t\t\t\tpush({ done: true, error: err });\n\t\t\t\tdispose();\n\t\t\t\treturn;\n\t\t\t} else if (t === COMPLETE || t === TEARDOWN) {\n\t\t\t\tpush({ done: true });\n\t\t\t\tdispose();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t});\n\n\tconst iterator: AsyncIterableIterator<T> = {\n\t\tnext(): Promise<IteratorResult<T>> {\n\t\t\tif (queue.length > 0) {\n\t\t\t\tconst item = queue.shift()!;\n\t\t\t\tif (!item.done) wm?.onDequeue();\n\t\t\t\tif (item.done && item.error) return Promise.reject(item.error);\n\t\t\t\treturn Promise.resolve(\n\t\t\t\t\titem.done ? { done: true, value: undefined } : { done: false, value: item.value as T },\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (disposed) return Promise.resolve({ done: true, value: undefined });\n\t\t\treturn new Promise<IteratorResult<T>>((resolve, reject) => {\n\t\t\t\twaiters.push({ resolve, reject });\n\t\t\t});\n\t\t},\n\t\treturn(): Promise<IteratorReturnResult<undefined>> {\n\t\t\tdispose();\n\t\t\t// Resolve any pending waiters\n\t\t\tfor (const w of waiters) w.resolve({ done: true, value: undefined });\n\t\t\twaiters.length = 0;\n\t\t\treturn Promise.resolve({ done: true, value: undefined });\n\t\t},\n\t\tthrow(err: unknown): Promise<IteratorResult<T>> {\n\t\t\tdispose();\n\t\t\treturn Promise.reject(err);\n\t\t},\n\t\t[Symbol.asyncIterator]() {\n\t\t\treturn this;\n\t\t},\n\t};\n\n\treturn iterator;\n}\n\n// ---------------------------------------------------------------------------\n// ObserveGateway — graph.observe() → WebSocket (multi-path subscription)\n// ---------------------------------------------------------------------------\n\nexport type ObserveGatewayOptions = {\n\textractActor?: (client: unknown) => Actor | undefined;\n\tparse?: (data: string) => ObserveWsCommand;\n\t/** Pending DATA count per subscription at which PAUSE is sent upstream. Enables backpressure when set. */\n\thighWaterMark?: number;\n\t/** Pending DATA count per subscription at which RESUME is sent upstream. Defaults to `Math.floor(highWaterMark / 2)`. */\n\tlowWaterMark?: number;\n};\n\n/**\n * Manages per-client WebSocket subscriptions to graph nodes via `observe()`.\n *\n * Not a NestJS decorator or base class — a standalone helper that can be\n * wired into any WebSocket gateway. Each client can subscribe/unsubscribe\n * to individual node paths. Actor-scoped observation respects node guards.\n *\n * @example\n * ```ts\n * @WebSocketGateway()\n * export class GraphGateway {\n * private gw = new ObserveGateway(this.graph);\n *\n * constructor(@InjectGraph() private graph: Graph) {}\n *\n * handleConnection(client: WebSocket) {\n * this.gw.handleConnection(client);\n * }\n *\n * handleDisconnect(client: WebSocket) {\n * this.gw.handleDisconnect(client);\n * }\n *\n * @SubscribeMessage(\"observe\")\n * onObserve(client: WebSocket, data: unknown) {\n * this.gw.handleMessage(client, data);\n * }\n * }\n * ```\n */\nexport class ObserveGateway {\n\tprivate readonly clients = new Map<\n\t\tunknown,\n\t\tMap<string, { unsub: () => void; wm?: WatermarkController }>\n\t>();\n\tprivate readonly extractActor: (client: unknown) => Actor | undefined;\n\tprivate readonly parse: (data: string) => ObserveWsCommand;\n\tprivate readonly highWaterMark: number | undefined;\n\tprivate readonly lowWaterMark: number | undefined;\n\n\tconstructor(\n\t\tprivate readonly graph: Graph,\n\t\topts?: ObserveGatewayOptions,\n\t) {\n\t\tthis.extractActor = opts?.extractActor ?? (() => undefined);\n\t\tthis.parse = opts?.parse ?? defaultParseCommand;\n\t\tthis.highWaterMark = opts?.highWaterMark;\n\t\tthis.lowWaterMark = opts?.lowWaterMark;\n\t}\n\n\t/**\n\t * Register a new client. Call from `handleConnection`.\n\t */\n\thandleConnection(client: unknown): void {\n\t\tif (!this.clients.has(client)) {\n\t\t\tthis.clients.set(client, new Map());\n\t\t}\n\t}\n\n\t/**\n\t * Unregister a client and dispose all its subscriptions. Call from `handleDisconnect`.\n\t */\n\thandleDisconnect(client: unknown): void {\n\t\tconst subs = this.clients.get(client);\n\t\tif (!subs) return;\n\t\tfor (const entry of subs.values()) {\n\t\t\tentry.wm?.dispose();\n\t\t\tentry.unsub();\n\t\t}\n\t\tthis.clients.delete(client);\n\t}\n\n\t/**\n\t * Handle an incoming client message (subscribe/unsubscribe/ack command).\n\t *\n\t * @param client - The WebSocket client reference.\n\t * @param raw - Raw message data (string or parsed object).\n\t * @param send - Function to send a message back to the client.\n\t * Defaults to `client.send(JSON.stringify(msg))`.\n\t */\n\thandleMessage(client: unknown, raw: unknown, send?: (msg: ObserveWsMessage) => void): void {\n\t\tconst sender = send ?? defaultSend.bind(null, client);\n\t\tlet cmd: ObserveWsCommand;\n\t\ttry {\n\t\t\tcmd = typeof raw === \"string\" ? this.parse(raw) : (raw as ObserveWsCommand);\n\t\t} catch {\n\t\t\tsender({ type: \"err\", message: \"invalid command\" });\n\t\t\treturn;\n\t\t}\n\n\t\tif (cmd.type === \"subscribe\") {\n\t\t\tthis.subscribe(client, cmd.path, sender);\n\t\t} else if (cmd.type === \"unsubscribe\") {\n\t\t\tthis.unsubscribe(client, cmd.path, sender);\n\t\t} else if (cmd.type === \"ack\") {\n\t\t\tthis.ack(client, cmd.path, cmd.count ?? 1);\n\t\t} else {\n\t\t\tsender({ type: \"err\", message: `unknown command type: ${(cmd as { type: string }).type}` });\n\t\t}\n\t}\n\n\t/**\n\t * Number of active subscriptions for a client. Useful for tests.\n\t */\n\tsubscriptionCount(client: unknown): number {\n\t\treturn this.clients.get(client)?.size ?? 0;\n\t}\n\n\t/**\n\t * Dispose all clients and subscriptions.\n\t */\n\tdestroy(): void {\n\t\tfor (const [client] of this.clients) {\n\t\t\tthis.handleDisconnect(client);\n\t\t}\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Internal\n\t// -----------------------------------------------------------------------\n\n\tprivate subscribe(client: unknown, path: string, send: (msg: ObserveWsMessage) => void): void {\n\t\tlet subs = this.clients.get(client);\n\t\tif (!subs) {\n\t\t\tsubs = new Map();\n\t\t\tthis.clients.set(client, subs);\n\t\t}\n\t\tif (subs.has(path)) {\n\t\t\tsend({ type: \"subscribed\", path });\n\t\t\treturn;\n\t\t}\n\n\t\tconst actor = this.extractActor(client);\n\t\tlet handle: GraphObserveOne;\n\t\ttry {\n\t\t\thandle = this.graph.observe(path, { actor }) as unknown as GraphObserveOne;\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\tsend({ type: \"err\", message });\n\t\t\treturn;\n\t\t}\n\n\t\tconst wm =\n\t\t\tthis.highWaterMark != null\n\t\t\t\t? createWatermarkController((msgs) => handle.up(msgs), {\n\t\t\t\t\t\thighWaterMark: this.highWaterMark,\n\t\t\t\t\t\tlowWaterMark: this.lowWaterMark ?? Math.floor(this.highWaterMark / 2),\n\t\t\t\t\t})\n\t\t\t\t: undefined;\n\n\t\tconst cleanup = () => {\n\t\t\twm?.dispose();\n\t\t\tunsub();\n\t\t\tsubs!.delete(path);\n\t\t};\n\n\t\tconst unsub = handle.subscribe((msgs: Messages) => {\n\t\t\tfor (const msg of msgs) {\n\t\t\t\tconst t = msg[0];\n\t\t\t\tif (t === DATA) {\n\t\t\t\t\twm?.onEnqueue();\n\t\t\t\t\ttrySend(send, { type: \"data\", path, value: msg[1] });\n\t\t\t\t} else if (t === ERROR) {\n\t\t\t\t\tconst errMsg = msg[1] instanceof Error ? msg[1].message : String(msg[1]);\n\t\t\t\t\ttrySend(send, { type: \"error\", path, error: errMsg });\n\t\t\t\t\tcleanup();\n\t\t\t\t\treturn;\n\t\t\t\t} else if (t === COMPLETE || t === TEARDOWN) {\n\t\t\t\t\ttrySend(send, { type: \"complete\", path });\n\t\t\t\t\tcleanup();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t// DIRTY, RESOLVED not exposed to WS clients\n\t\t\t}\n\t\t});\n\n\t\tsubs.set(path, { unsub, wm });\n\t\tsend({ type: \"subscribed\", path });\n\t}\n\n\tprivate unsubscribe(client: unknown, path: string, send: (msg: ObserveWsMessage) => void): void {\n\t\tconst subs = this.clients.get(client);\n\t\tconst entry = subs?.get(path);\n\t\tif (entry) {\n\t\t\tentry.wm?.dispose();\n\t\t\tentry.unsub();\n\t\t\tsubs!.delete(path);\n\t\t}\n\t\tsend({ type: \"unsubscribed\", path });\n\t}\n\n\tprivate ack(client: unknown, path: string, count: number): void {\n\t\tconst entry = this.clients.get(client)?.get(path);\n\t\tif (!entry?.wm) return;\n\t\tconst n = Math.min(Math.max(0, Math.floor(count)), 1024);\n\t\tfor (let i = 0; i < n; i++) entry.wm.onDequeue();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction defaultSerialize(value: unknown): string {\n\tif (value instanceof Error) return value.message;\n\ttry {\n\t\treturn JSON.stringify(value);\n\t} catch {\n\t\treturn String(value);\n\t}\n}\n\nfunction sseFrame(event: string, data?: string): string {\n\tlet frame = `event: ${event}\\n`;\n\tif (data !== undefined) {\n\t\tfor (const line of data.split(\"\\n\")) {\n\t\t\tframe += `data: ${line}\\n`;\n\t\t}\n\t}\n\tframe += \"\\n\";\n\treturn frame;\n}\n\nfunction defaultParseCommand(data: string): ObserveWsCommand {\n\treturn JSON.parse(data) as ObserveWsCommand;\n}\n\nfunction defaultSend(client: unknown, msg: ObserveWsMessage): void {\n\ttry {\n\t\t(client as { send: (data: string) => void }).send(JSON.stringify(msg));\n\t} catch {\n\t\t/* client may have disconnected — swallow transport errors */\n\t}\n}\n\nfunction trySend(send: (msg: ObserveWsMessage) => void, msg: ObserveWsMessage): void {\n\ttry {\n\t\tsend(msg);\n\t} catch {\n\t\t/* transport error — client may have disconnected */\n\t}\n}\n","// ---------------------------------------------------------------------------\n// NestJS Actor bridge — maps NestJS ExecutionContext to GraphReFly Actor.\n// ---------------------------------------------------------------------------\n// Implements the NestJS `CanActivate` interface to extract an `Actor` from the\n// request (JWT payload, session, custom header, etc.) and attach it to the\n// request object for downstream graph operations.\n//\n// The decorator does NOT enforce access control — it merely bridges the NestJS\n// authentication context to GraphReFly's ABAC model. Actual access control\n// flows through node `policy()` guards reactively.\n// ---------------------------------------------------------------------------\n\nimport type { CanActivate, ExecutionContext } from \"@nestjs/common\";\nimport { type Actor, DEFAULT_ACTOR, normalizeActor } from \"../../core/actor.js\";\n\n/**\n * Property name under which the extracted {@link Actor} is stored on the\n * request object. Downstream code (controllers, gateways) reads\n * `req[ACTOR_KEY]` to pass actor context to graph operations.\n */\nexport const ACTOR_KEY = \"graphReflyActor\" as const;\n\n/**\n * Extracts a GraphReFly {@link Actor} from a NestJS {@link ExecutionContext}.\n *\n * Return `undefined` to fall back to {@link DEFAULT_ACTOR}.\n */\nexport type ActorExtractor = (context: ExecutionContext) => Actor | undefined;\n\n/**\n * Creates an {@link ActorExtractor} that reads a JWT payload from `req.user`\n * (the standard Passport.js location) and maps it to a GraphReFly {@link Actor}.\n *\n * @param mapping - Optional transform from the JWT payload to an Actor.\n * When omitted, the payload is used directly (must have `type` and `id`).\n *\n * @example\n * ```ts\n * // Default: req.user is already { type, id, ... }\n * GraphReflyGuard(fromJwtPayload())\n *\n * // Custom mapping from your JWT claims\n * GraphReflyGuard(fromJwtPayload((payload) => ({\n * type: payload.role === \"admin\" ? \"human\" : \"llm\",\n * id: payload.sub,\n * org: payload.org_id,\n * })))\n * ```\n */\nexport function fromJwtPayload(mapping?: (payload: unknown) => Actor): ActorExtractor {\n\treturn (context: ExecutionContext): Actor | undefined => {\n\t\tconst req = context.switchToHttp().getRequest();\n\t\tconst user = req?.user;\n\t\tif (user == null) return undefined;\n\t\tif (mapping) return mapping(user);\n\t\treturn user as Actor;\n\t};\n}\n\n/**\n * Creates an {@link ActorExtractor} that reads an Actor from a request header.\n *\n * The header value is parsed as JSON. Useful for service-to-service calls\n * where the caller embeds actor context in a custom header.\n *\n * @param headerName - HTTP header name (case-insensitive). Default: `\"x-graphrefly-actor\"`.\n *\n * @example\n * ```ts\n * GraphReflyGuard(fromHeader(\"x-actor\"))\n * ```\n */\nexport function fromHeader(headerName = \"x-graphrefly-actor\"): ActorExtractor {\n\treturn (context: ExecutionContext): Actor | undefined => {\n\t\tconst req = context.switchToHttp().getRequest();\n\t\tconst raw = req?.headers?.[headerName.toLowerCase()];\n\t\tif (typeof raw !== \"string\" || raw.length === 0) return undefined;\n\t\ttry {\n\t\t\treturn JSON.parse(raw) as Actor;\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t};\n}\n\n/**\n * Reads the extracted {@link Actor} from a request object (set by {@link GraphReflyGuardImpl}).\n *\n * Returns {@link DEFAULT_ACTOR} if no actor was attached.\n *\n * @example\n * ```ts\n * @Get(\"status\")\n * getStatus(@Req() req: Request) {\n * const actor = getActor(req);\n * return this.graph.describe({ actor });\n * }\n * ```\n */\nexport function getActor(req: unknown): Actor {\n\tconst actor = (req as Record<string, unknown>)?.[ACTOR_KEY];\n\treturn actor != null ? normalizeActor(actor as Actor) : DEFAULT_ACTOR;\n}\n\n/**\n * NestJS guard that extracts a GraphReFly {@link Actor} from the execution\n * context and attaches it to the request as `req.graphReflyActor`.\n *\n * This guard always returns `true` (allows the request through). Access\n * control is handled by GraphReFly node guards (`policy()`), not by this\n * NestJS guard. The purpose is purely to **bridge** authentication context.\n *\n * @example\n * ```ts\n * // Global guard — every request gets an Actor\n * app.useGlobalGuards(new GraphReflyGuardImpl(fromJwtPayload()));\n *\n * // Controller-scoped\n * @UseGuards(GraphReflyGuard(fromJwtPayload()))\n * @Controller(\"api\")\n * export class ApiController { ... }\n * ```\n */\nexport class GraphReflyGuardImpl implements CanActivate {\n\tconstructor(private readonly extractor: ActorExtractor) {}\n\n\tcanActivate(context: ExecutionContext): boolean {\n\t\tconst actor = normalizeActor(this.extractor(context));\n\t\tconst req = context.switchToHttp().getRequest();\n\t\tif (req != null) {\n\t\t\t(req as Record<string, unknown>)[ACTOR_KEY] = actor;\n\t\t}\n\t\treturn true;\n\t}\n}\n\n/**\n * Factory that creates a {@link GraphReflyGuardImpl} instance. Use with\n * NestJS `@UseGuards()` or `app.useGlobalGuards()`.\n *\n * @param extractor - How to extract an Actor from the request context.\n * Defaults to {@link fromJwtPayload} (reads `req.user`).\n *\n * @example\n * ```ts\n * import { GraphReflyGuard, fromJwtPayload } from \"@graphrefly/graphrefly-ts/compat/nestjs\";\n *\n * @UseGuards(GraphReflyGuard())\n * @Controller(\"graph\")\n * export class GraphController { ... }\n * ```\n */\nexport function GraphReflyGuard(extractor?: ActorExtractor): GraphReflyGuardImpl {\n\treturn new GraphReflyGuardImpl(extractor ?? fromJwtPayload());\n}\n","// ---------------------------------------------------------------------------\n// GraphReflyModule — NestJS dynamic module for GraphReFly integration.\n// ---------------------------------------------------------------------------\n// Provides `forRoot()` and `forFeature()` following the standard NestJS\n// dynamic-module pattern. Lifecycle hooks wire graph creation on init and\n// `graph.destroy()` on teardown — TEARDOWN propagates through the graph\n// per GRAPHREFLY-SPEC §3.7.\n//\n// No decorator usage in this file — all DI is done via factory providers\n// so the library doesn't require `experimentalDecorators` in consumer's\n// tsconfig (only the consumer's NestJS app needs it).\n// ---------------------------------------------------------------------------\n\nimport {\n\ttype DynamicModule,\n\tModule,\n\ttype OnModuleDestroy,\n\ttype Provider,\n\tScope,\n} from \"@nestjs/common\";\nimport { ModuleRef } from \"@nestjs/core\";\nimport { Graph, type GraphPersistSnapshot } from \"../../graph/graph.js\";\nimport {\n\ttype CqrsGraph,\n\ttype CqrsOptions,\n\tcqrs,\n\ttype EventStoreAdapter,\n} from \"../../patterns/cqrs.js\";\nimport { GraphReflyEventExplorer } from \"./explorer.js\";\nimport {\n\tGRAPHREFLY_REQUEST_GRAPH,\n\tGRAPHREFLY_ROOT_GRAPH,\n\tgetGraphToken,\n\tgetNodeToken,\n} from \"./tokens.js\";\n\n// ---------------------------------------------------------------------------\n// Option types\n// ---------------------------------------------------------------------------\n\nexport interface GraphReflyRootOptions {\n\t/** Root graph name (default: `\"root\"`). */\n\tname?: string;\n\t/** Snapshot to hydrate via `graph.restore()` after build. */\n\tsnapshot?: GraphPersistSnapshot;\n\t/** Build callback — registers nodes/mounts on the graph. */\n\tbuild?: (graph: Graph) => void;\n\t/** Qualified node paths to expose as injectable providers. */\n\tnodes?: readonly string[];\n\t/** Enable a request-scoped graph (injectable via `@InjectGraph(\"request\")`). */\n\trequestScope?: boolean;\n}\n\nexport interface GraphReflyCqrsOptions {\n\t/** Feature name — becomes the mount name in the root graph. */\n\tname: string;\n\t/** CQRS graph options (forwarded to `cqrs()` factory). */\n\tcqrs?: CqrsOptions;\n\t/** Build callback — registers commands, events, projections, sagas on the CqrsGraph. */\n\tbuild?: (graph: CqrsGraph) => void;\n\t/** Event store adapter for persistence (wired via `useEventStore()`). */\n\teventStore?: EventStoreAdapter;\n\t/**\n\t * Node paths (local to this feature) to expose as injectable providers.\n\t * Tokens are auto-qualified as `featureName::path`.\n\t */\n\tnodes?: readonly string[];\n}\n\nexport interface GraphReflyFeatureOptions {\n\t/** Feature name — becomes the mount name in the root graph. */\n\tname: string;\n\t/** Build callback — registers nodes/mounts on the feature graph. */\n\tbuild?: (graph: Graph) => void;\n\t/** Snapshot to hydrate after build. */\n\tsnapshot?: GraphPersistSnapshot;\n\t/**\n\t * Node paths (local to this feature) to expose as injectable providers.\n\t * Tokens are auto-qualified as `featureName::path` to avoid collisions.\n\t */\n\tnodes?: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Lifecycle classes (no decorators — DI is handled via factory providers)\n// ---------------------------------------------------------------------------\n\nclass GraphReflyRootLifecycle implements OnModuleDestroy {\n\tconstructor(readonly graph: Graph) {}\n\n\tonModuleDestroy(): void {\n\t\tthis.graph.destroy();\n\t}\n}\n\nclass GraphReflyRequestLifecycle implements OnModuleDestroy {\n\treadonly graph = new Graph(\"request\");\n\n\tonModuleDestroy(): void {\n\t\tthis.graph.destroy();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Module\n// ---------------------------------------------------------------------------\n\n// NestJS dynamic modules convention: static `forRoot` / `forFeature` factories on a `@Module` class.\n@Module({})\n// biome-ignore lint/complexity/noStaticOnlyClass: NestJS `DynamicModule` pattern (`@Module` + static factories)\nexport class GraphReflyModule {\n\t/**\n\t * Register the root `Graph` singleton in the NestJS DI container.\n\t *\n\t * The root graph is `@Global()` — injectable everywhere without importing\n\t * the module again. Use `@InjectGraph()` to inject it.\n\t *\n\t * Lifecycle:\n\t * - **init:** Graph created in factory. If `build` is provided, it runs\n\t * first (registers nodes/mounts). If `snapshot` is provided, values\n\t * are restored via `graph.restore()`.\n\t * - **destroy:** Calls `graph.destroy()` — sends `[[TEARDOWN]]` to all\n\t * nodes, including mounted feature subgraphs (cascading teardown).\n\t */\n\tstatic forRoot(opts?: GraphReflyRootOptions): DynamicModule {\n\t\tconst options = opts ?? {};\n\t\tconst graphName = options.name ?? \"root\";\n\n\t\tconst providers: Provider[] = [\n\t\t\t{\n\t\t\t\tprovide: GRAPHREFLY_ROOT_GRAPH,\n\t\t\t\tuseFactory: () => {\n\t\t\t\t\tconst g = new Graph(graphName);\n\t\t\t\t\tif (options.build) options.build(g);\n\t\t\t\t\tif (options.snapshot) g.restore(options.snapshot);\n\t\t\t\t\treturn g;\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tprovide: Symbol.for(\"graphrefly:root-lifecycle\"),\n\t\t\t\tuseFactory: (graph: Graph) => new GraphReflyRootLifecycle(graph),\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t},\n\t\t\t{\n\t\t\t\tprovide: GraphReflyEventExplorer,\n\t\t\t\tuseFactory: (graph: Graph, moduleRef: InstanceType<typeof ModuleRef>) =>\n\t\t\t\t\tnew GraphReflyEventExplorer(graph, moduleRef),\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH, ModuleRef],\n\t\t\t},\n\t\t];\n\n\t\t// Node factory providers — each declared path gets a factory that\n\t\t// resolves the node from the root graph at injection time.\n\t\tif (options.nodes) {\n\t\t\tfor (const path of options.nodes) {\n\t\t\t\tproviders.push({\n\t\t\t\t\tprovide: getNodeToken(path),\n\t\t\t\t\tuseFactory: (graph: Graph) => graph.resolve(path),\n\t\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Request-scoped graph provider (opt-in).\n\t\tif (options.requestScope) {\n\t\t\tproviders.push(\n\t\t\t\t{\n\t\t\t\t\tprovide: Symbol.for(\"graphrefly:request-lifecycle\"),\n\t\t\t\t\tuseFactory: () => new GraphReflyRequestLifecycle(),\n\t\t\t\t\tscope: Scope.REQUEST,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tprovide: GRAPHREFLY_REQUEST_GRAPH,\n\t\t\t\t\tuseFactory: (lifecycle: GraphReflyRequestLifecycle) => lifecycle.graph,\n\t\t\t\t\tinject: [Symbol.for(\"graphrefly:request-lifecycle\")],\n\t\t\t\t\tscope: Scope.REQUEST,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: GraphReflyModule,\n\t\t\tglobal: true,\n\t\t\tproviders,\n\t\t\texports: [\n\t\t\t\tGRAPHREFLY_ROOT_GRAPH,\n\t\t\t\t...(options.nodes ?? []).map(getNodeToken),\n\t\t\t\t...(options.requestScope ? [GRAPHREFLY_REQUEST_GRAPH] : []),\n\t\t\t],\n\t\t};\n\t}\n\n\t/**\n\t * Register a feature subgraph that auto-mounts into the root graph.\n\t *\n\t * The feature graph is created in the factory, built/restored, then\n\t * mounted into root via `root.mount(name, featureGraph)`. On app\n\t * shutdown, root's `graph.destroy()` cascades TEARDOWN through all\n\t * mounted subgraphs (no explicit remove needed).\n\t *\n\t * Node tokens are auto-qualified as `featureName::path` to prevent\n\t * collisions between features declaring nodes with the same local name.\n\t *\n\t * Injectable via `@InjectGraph(name)`.\n\t */\n\tstatic forFeature(opts: GraphReflyFeatureOptions): DynamicModule {\n\t\tconst providers: Provider[] = [\n\t\t\t{\n\t\t\t\tprovide: getGraphToken(opts.name),\n\t\t\t\tuseFactory: (rootGraph: Graph) => {\n\t\t\t\t\tconst g = new Graph(opts.name);\n\t\t\t\t\tif (opts.build) opts.build(g);\n\t\t\t\t\tif (opts.snapshot) g.restore(opts.snapshot);\n\t\t\t\t\trootGraph.mount(opts.name, g);\n\t\t\t\t\treturn g;\n\t\t\t\t},\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t},\n\t\t];\n\n\t\t// Node factory providers for feature-scoped nodes.\n\t\t// Tokens are qualified as `featureName::path` to avoid cross-feature collisions.\n\t\tif (opts.nodes) {\n\t\t\tfor (const path of opts.nodes) {\n\t\t\t\tproviders.push({\n\t\t\t\t\tprovide: getNodeToken(`${opts.name}::${path}`),\n\t\t\t\t\tuseFactory: (graph: Graph) => graph.resolve(path),\n\t\t\t\t\tinject: [getGraphToken(opts.name)],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: GraphReflyModule,\n\t\t\tproviders,\n\t\t\texports: [\n\t\t\t\tgetGraphToken(opts.name),\n\t\t\t\t...(opts.nodes ?? []).map((p) => getNodeToken(`${opts.name}::${p}`)),\n\t\t\t],\n\t\t};\n\t}\n\n\t/**\n\t * Register a CQRS subgraph that auto-mounts into the root graph.\n\t *\n\t * Creates a `CqrsGraph` via the `cqrs()` factory (roadmap §4.5), mounts it\n\t * into the root graph, and exposes it for DI via `@InjectGraph(name)`.\n\t *\n\t * CQRS decorators (`@CommandHandler`, `@EventHandler`, `@QueryHandler`,\n\t * `@SagaHandler`) are discovered by the explorer and wired to this graph\n\t * on module init.\n\t *\n\t * @example\n\t * ```ts\n\t * GraphReflyModule.forCqrs({\n\t * name: \"orders\",\n\t * build: (g) => {\n\t * g.event(\"orderPlaced\");\n\t * g.projection(\"orderCount\", [\"orderPlaced\"], (_s, evts) => evts.length, 0);\n\t * },\n\t * })\n\t * ```\n\t */\n\tstatic forCqrs(opts: GraphReflyCqrsOptions): DynamicModule {\n\t\tconst providers: Provider[] = [\n\t\t\t{\n\t\t\t\tprovide: getGraphToken(opts.name),\n\t\t\t\tuseFactory: (rootGraph: Graph) => {\n\t\t\t\t\tconst g = cqrs(opts.name, opts.cqrs);\n\t\t\t\t\t// `useEventStore` is CqrsGraph API, not a React hook (Biome false positive).\n\t\t\t\t\t// biome-ignore lint/correctness/useHookAtTopLevel: not React; Nest provider factory\n\t\t\t\t\tif (opts.eventStore) g.useEventStore(opts.eventStore);\n\t\t\t\t\tif (opts.build) opts.build(g);\n\t\t\t\t\trootGraph.mount(opts.name, g);\n\t\t\t\t\treturn g;\n\t\t\t\t},\n\t\t\t\tinject: [GRAPHREFLY_ROOT_GRAPH],\n\t\t\t},\n\t\t];\n\n\t\tif (opts.nodes) {\n\t\t\tfor (const path of opts.nodes) {\n\t\t\t\tproviders.push({\n\t\t\t\t\tprovide: getNodeToken(`${opts.name}::${path}`),\n\t\t\t\t\tuseFactory: (graph: Graph) => graph.resolve(path),\n\t\t\t\t\tinject: [getGraphToken(opts.name)],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tmodule: GraphReflyModule,\n\t\t\tproviders,\n\t\t\texports: [\n\t\t\t\tgetGraphToken(opts.name),\n\t\t\t\t...(opts.nodes ?? []).map((p) => getNodeToken(`${opts.name}::${p}`)),\n\t\t\t],\n\t\t};\n\t}\n}\n","/**\n * CQRS patterns (roadmap §4.5).\n *\n * Composition layer over reactiveLog (3.2), pipeline/sagas (4.1), event bus (4.2),\n * projections (4.3). Guards (1.5) enforce command/query boundary.\n *\n * - `cqrs(name, opts?)` → `CqrsGraph` — top-level factory\n * - `CqrsGraph.command(name, handler)` — write-only node; guard rejects `observe`\n * - `CqrsGraph.event(name)` — backed by `reactiveLog`; append-only\n * - `CqrsGraph.projection(name, events, reducer, initial)` — read-only derived; guard rejects `write`\n * - `CqrsGraph.saga(name, events, handler)` — event-driven side effects\n */\n\nimport { batch } from \"../core/batch.js\";\nimport { wallClockNs } from \"../core/clock.js\";\nimport { policy } from \"../core/guard.js\";\nimport { DATA, derived, type Node, node, state } from \"../core/index.js\";\nimport { type ReactiveLogSnapshot, reactiveLog } from \"../extra/reactive-log.js\";\nimport { Graph, type GraphOptions } from \"../graph/index.js\";\n\n// ---------------------------------------------------------------------------\n// Guards\n// ---------------------------------------------------------------------------\n\n/** Commands: write + signal allowed, observe denied. */\nconst COMMAND_GUARD = policy((allow, deny) => {\n\tallow(\"write\");\n\tallow(\"signal\");\n\tdeny(\"observe\");\n});\n\n/** Projections: observe + signal allowed, write denied. */\nconst PROJECTION_GUARD = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n/** Events: observe + signal allowed, write denied (appended internally). */\nconst EVENT_GUARD = policy((allow, deny) => {\n\tallow(\"observe\");\n\tallow(\"signal\");\n\tdeny(\"write\");\n});\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction cqrsMeta(kind: string, extra?: Record<string, unknown>): Record<string, unknown> {\n\treturn { cqrs: true, cqrs_type: kind, ...(extra ?? {}) };\n}\n\n/**\n * Keep a derived node's dep wiring alive for `get()` without a user sink.\n * Returns the unsubscribe handle so callers can clean up.\n */\nfunction keepalive(n: Node<unknown>): () => void {\n\treturn n.subscribe(() => {});\n}\n\n// ---------------------------------------------------------------------------\n// Event envelope\n// ---------------------------------------------------------------------------\n\n/**\n * Immutable envelope for events emitted by command handlers.\n *\n * `seq` is a per-graph monotonic counter that provides stable ordering when\n * multiple events share the same `timestampNs` (same wall-clock tick).\n */\nexport type CqrsEvent<T = unknown> = {\n\ttype: string;\n\tpayload: T;\n\t/** Wall-clock nanoseconds (via `wallClockNs()`). */\n\ttimestampNs: number;\n\t/** Monotonic sequence within this CqrsGraph instance. */\n\tseq: number;\n\t/** V0 identity of the event log node at append time (§6.0b). */\n\tv0?: { id: string; version: number };\n};\n\n// ---------------------------------------------------------------------------\n// Event store adapter\n// ---------------------------------------------------------------------------\n\n/**\n * Opaque replay cursor returned by `loadEvents`. Pass it back to\n * `loadEvents` to resume from the last position.\n */\nexport type EventStoreCursor = {\n\treadonly __brand?: \"EventStoreCursor\";\n\t[key: string]: unknown;\n};\n\n/**\n * Result of `loadEvents` — events plus an opaque cursor for resumption.\n */\nexport type LoadEventsResult = {\n\tevents: CqrsEvent[];\n\tcursor: EventStoreCursor | undefined;\n};\n\n/**\n * Pluggable persistence for CQRS events.\n *\n * **`persist`:** Must be synchronous. Called from the dispatch path inside\n * `batch()`. Adapters that need async I/O should buffer internally and\n * expose a `flush()` method for explicit drain.\n */\nexport interface EventStoreAdapter {\n\tpersist(event: CqrsEvent): void;\n\t/**\n\t * Load persisted events. When `cursor` is provided, returns only events\n\t * after that position. The returned `cursor` should be passed to the next\n\t * `loadEvents` call for incremental replay.\n\t */\n\tloadEvents(\n\t\teventType: string,\n\t\tcursor?: EventStoreCursor,\n\t): LoadEventsResult | Promise<LoadEventsResult>;\n\t/** Optional explicit flush for adapters with async I/O. */\n\tflush?(): Promise<void>;\n}\n\nexport class MemoryEventStore implements EventStoreAdapter {\n\tprivate readonly _store = new Map<string, CqrsEvent[]>();\n\n\tpersist(event: CqrsEvent): void {\n\t\tlet list = this._store.get(event.type);\n\t\tif (!list) {\n\t\t\tlist = [];\n\t\t\tthis._store.set(event.type, list);\n\t\t}\n\t\tlist.push(event);\n\t}\n\n\tloadEvents(eventType: string, cursor?: EventStoreCursor): LoadEventsResult {\n\t\tconst list = this._store.get(eventType) ?? [];\n\t\tconst sinceTs = (cursor as { timestampNs?: number } | undefined)?.timestampNs;\n\t\tconst sinceSeq = (cursor as { seq?: number } | undefined)?.seq;\n\t\tconst events =\n\t\t\tsinceTs == null\n\t\t\t\t? [...list]\n\t\t\t\t: list.filter(\n\t\t\t\t\t\t(e) =>\n\t\t\t\t\t\t\te.timestampNs > sinceTs || (e.timestampNs === sinceTs && e.seq > (sinceSeq ?? -1)),\n\t\t\t\t\t);\n\t\tconst lastEvent = events.length > 0 ? events[events.length - 1] : undefined;\n\t\treturn {\n\t\t\tevents,\n\t\t\tcursor: lastEvent ? { timestampNs: lastEvent.timestampNs, seq: lastEvent.seq } : cursor,\n\t\t};\n\t}\n\n\tclear(): void {\n\t\tthis._store.clear();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Handler types\n// ---------------------------------------------------------------------------\n\nexport type CommandActions = {\n\t/** Append an event to a named event log (bypasses event guard). */\n\temit: (eventName: string, payload: unknown) => void;\n};\n\n/**\n * Command handler receives the dispatch payload and actions to emit events.\n *\n * **Purity:** Handlers should not mutate the payload. Event emission via\n * `actions.emit()` is the only sanctioned side effect.\n */\nexport type CommandHandler<T = unknown> = (payload: T, actions: CommandActions) => void;\n\n/**\n * Projection reducer folds events into a read model.\n *\n * **Purity contract:** Reducers MUST be pure — return a new state value\n * without mutating `state` or any event. The `state` parameter is the\n * original `initial` value on every invocation (full event-sourcing replay),\n * so mutation would corrupt future recomputations.\n */\nexport type ProjectionReducer<TState = unknown, TEvent = unknown> = (\n\tstate: TState,\n\tevents: readonly CqrsEvent<TEvent>[],\n) => TState;\n\nexport type SagaHandler<T = unknown> = (event: CqrsEvent<T>) => void;\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport type CqrsOptions = {\n\tgraph?: GraphOptions;\n};\n\n// ---------------------------------------------------------------------------\n// CqrsGraph\n// ---------------------------------------------------------------------------\n\ntype EventEntry = {\n\tlog: ReturnType<typeof reactiveLog<CqrsEvent>>;\n\tnode: Node<ReactiveLogSnapshot<CqrsEvent>>;\n};\n\nexport class CqrsGraph extends Graph {\n\tprivate readonly _eventLogs = new Map<string, EventEntry>();\n\tprivate readonly _commandHandlers = new Map<string, CommandHandler<any>>();\n\tprivate readonly _projections = new Set<string>();\n\tprivate readonly _sagas = new Set<string>();\n\tprivate readonly _keepaliveDisposers: Array<() => void> = [];\n\tprivate _eventStore: EventStoreAdapter | undefined;\n\tprivate _seq = 0;\n\n\tconstructor(name: string, opts: CqrsOptions = {}) {\n\t\tsuper(name, opts.graph);\n\t}\n\n\toverride destroy(): void {\n\t\tfor (const dispose of this._keepaliveDisposers) dispose();\n\t\tthis._keepaliveDisposers.length = 0;\n\t\tsuper.destroy();\n\t}\n\n\t// -- Events ---------------------------------------------------------------\n\n\t/**\n\t * Register a named event stream backed by `reactiveLog`.\n\t * Guard denies external `write` — only commands append internally.\n\t */\n\tevent(name: string): Node<ReactiveLogSnapshot<CqrsEvent>> {\n\t\tconst existing = this._eventLogs.get(name);\n\t\tif (existing) return existing.node;\n\n\t\tconst log = reactiveLog<CqrsEvent>([], { name });\n\t\tconst entries = log.entries;\n\t\tconst guarded = derived<ReactiveLogSnapshot<CqrsEvent>>(\n\t\t\t[entries],\n\t\t\t([snapshot]) => snapshot as ReactiveLogSnapshot<CqrsEvent>,\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"state\",\n\t\t\t\tmeta: cqrsMeta(\"event\", { event_name: name }),\n\t\t\t\tguard: EVENT_GUARD,\n\t\t\t\tinitial: entries.get() as ReactiveLogSnapshot<CqrsEvent>,\n\t\t\t},\n\t\t);\n\t\tthis.add(name, guarded);\n\t\tthis._keepaliveDisposers.push(keepalive(guarded));\n\t\tthis._eventLogs.set(name, { log, node: guarded });\n\t\treturn guarded;\n\t}\n\n\t/** Internal: append to an event log, auto-registering if needed. */\n\tprivate _appendEvent(eventName: string, payload: unknown): void {\n\t\tlet entry = this._eventLogs.get(eventName);\n\t\tif (!entry) {\n\t\t\tthis.event(eventName);\n\t\t\tentry = this._eventLogs.get(eventName)!;\n\t\t}\n\t\t// Guard: reject dispatch to terminated event streams\n\t\tif (entry.node.status === \"completed\" || entry.node.status === \"errored\") {\n\t\t\tthrow new Error(\n\t\t\t\t`Cannot dispatch to terminated event stream \"${eventName}\" (status: ${entry.node.status}).`,\n\t\t\t);\n\t\t}\n\t\tconst nv = entry.log.entries.v;\n\t\tconst evt: CqrsEvent = {\n\t\t\ttype: eventName,\n\t\t\tpayload,\n\t\t\ttimestampNs: wallClockNs(),\n\t\t\tseq: ++this._seq,\n\t\t\t...(nv != null ? { v0: { id: nv.id, version: nv.version } } : {}),\n\t\t};\n\t\tentry.log.append(evt);\n\t\tif (this._eventStore) {\n\t\t\tthis._eventStore.persist(evt);\n\t\t}\n\t}\n\n\t// -- Commands -------------------------------------------------------------\n\n\t/**\n\t * Register a command with its handler. Guard denies `observe` (write-only).\n\t * Use `dispatch(name, payload)` to execute.\n\t *\n\t * The command node carries dynamic `meta.error` — a reactive companion\n\t * that holds the last handler error (or `null` on success).\n\t */\n\tcommand<T = unknown>(name: string, handler: CommandHandler<T>): Node<T> {\n\t\tconst cmdNode = state<T>(undefined as T, {\n\t\t\tname,\n\t\t\tdescribeKind: \"state\",\n\t\t\tmeta: {\n\t\t\t\t...cqrsMeta(\"command\", { command_name: name }),\n\t\t\t\terror: null,\n\t\t\t},\n\t\t\tguard: COMMAND_GUARD,\n\t\t});\n\t\tthis.add(name, cmdNode);\n\t\tthis._commandHandlers.set(name, handler as CommandHandler<any>);\n\t\treturn cmdNode;\n\t}\n\n\t/**\n\t * Execute a registered command. Wraps the entire dispatch in `batch()` so\n\t * the command node DATA and all emitted events settle atomically.\n\t *\n\t * If the handler throws, `meta.error` on the command node is set to the\n\t * error and the exception is re-thrown.\n\t */\n\tdispatch<T = unknown>(commandName: string, payload: T): void {\n\t\tconst handler = this._commandHandlers.get(commandName);\n\t\tif (!handler) {\n\t\t\tthrow new Error(`Unknown command: \"${commandName}\". Register with .command() first.`);\n\t\t}\n\t\tconst cmdNode = this.resolve(commandName);\n\t\tbatch(() => {\n\t\t\tcmdNode.down([[DATA, payload]], { internal: true });\n\t\t\ttry {\n\t\t\t\thandler(payload, { emit: (eName, data) => this._appendEvent(eName, data) });\n\t\t\t\tcmdNode.meta.error.down([[DATA, null]], { internal: true });\n\t\t\t} catch (err) {\n\t\t\t\tcmdNode.meta.error.down([[DATA, err]], { internal: true });\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t});\n\t}\n\n\t// -- Projections ----------------------------------------------------------\n\n\t/**\n\t * Register a read-only projection derived from event streams.\n\t * Guard denies `write` — value is computed from events only.\n\t *\n\t * **Purity contract:** The `reducer` must be a pure function — it receives\n\t * the original `initial` on every invocation (full event-sourcing replay).\n\t * Never mutate `initial`; always return a new value.\n\t */\n\tprojection<TState>(\n\t\tname: string,\n\t\teventNames: readonly string[],\n\t\treducer: ProjectionReducer<TState>,\n\t\tinitial: TState,\n\t): Node<TState> {\n\t\tconst eventNodes = eventNames.map((eName) => {\n\t\t\tif (!this._eventLogs.has(eName)) this.event(eName);\n\t\t\treturn this._eventLogs.get(eName)!.node;\n\t\t});\n\n\t\tconst projNode = derived<TState>(\n\t\t\teventNodes,\n\t\t\t(snapshots) => {\n\t\t\t\tconst allEvents: CqrsEvent[] = [];\n\t\t\t\tfor (const snapshot of snapshots) {\n\t\t\t\t\tconst snap = snapshot as ReactiveLogSnapshot<CqrsEvent>;\n\t\t\t\t\tallEvents.push(...snap.value.entries);\n\t\t\t\t}\n\t\t\t\tallEvents.sort((a, b) => a.timestampNs - b.timestampNs || a.seq - b.seq);\n\t\t\t\treturn reducer(initial, allEvents);\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"derived\",\n\t\t\t\tmeta: cqrsMeta(\"projection\", { projection_name: name, source_events: eventNames }),\n\t\t\t\tguard: PROJECTION_GUARD,\n\t\t\t\tinitial,\n\t\t\t},\n\t\t);\n\n\t\tthis.add(name, projNode);\n\t\tfor (const eName of eventNames) this.connect(eName, name);\n\t\tthis._keepaliveDisposers.push(keepalive(projNode));\n\t\tthis._projections.add(name);\n\t\treturn projNode;\n\t}\n\n\t// -- Sagas ----------------------------------------------------------------\n\n\t/**\n\t * Register an event-driven side effect. Runs handler for each **new** event\n\t * from the specified streams (tracks last-processed entry count per stream).\n\t *\n\t * The saga node carries dynamic `meta.error` — a reactive companion that\n\t * holds the last handler error (or `null` on success). Handler errors do\n\t * not propagate out of the saga run (the event cursor still advances so\n\t * the same entry is not delivered twice).\n\t */\n\tsaga<T = unknown>(\n\t\tname: string,\n\t\teventNames: readonly string[],\n\t\thandler: SagaHandler<T>,\n\t): Node<unknown> {\n\t\tconst eventNodes = eventNames.map((eName) => {\n\t\t\tif (!this._eventLogs.has(eName)) this.event(eName);\n\t\t\treturn this._eventLogs.get(eName)!.node;\n\t\t});\n\n\t\t// Track last-processed entry count per event to only process new entries\n\t\tconst lastCounts = new Map<string, number>();\n\n\t\tconst sagaRef: { n?: Node<unknown> } = {};\n\t\tconst sagaNode = node(\n\t\t\teventNodes,\n\t\t\t(snapshots) => {\n\t\t\t\tconst errNode = sagaRef.n!.meta.error as Node<unknown>;\n\t\t\t\tfor (let i = 0; i < snapshots.length; i++) {\n\t\t\t\t\tconst snap = snapshots[i] as ReactiveLogSnapshot<CqrsEvent<T>>;\n\t\t\t\t\tconst eName = eventNames[i];\n\t\t\t\t\tconst entries = snap.value.entries;\n\t\t\t\t\tconst lastCount = lastCounts.get(eName) ?? 0;\n\t\t\t\t\tif (entries.length > lastCount) {\n\t\t\t\t\t\tconst newEntries = entries.slice(lastCount);\n\t\t\t\t\t\tfor (const entry of newEntries) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\thandler(entry as CqrsEvent<T>);\n\t\t\t\t\t\t\t\terrNode.down([[DATA, null]], { internal: true });\n\t\t\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t\t\terrNode.down([[DATA, err]], { internal: true });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlastCounts.set(eName, entries.length);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tname,\n\t\t\t\tdescribeKind: \"effect\",\n\t\t\t\tmeta: {\n\t\t\t\t\t...cqrsMeta(\"saga\", { saga_name: name, source_events: eventNames }),\n\t\t\t\t\terror: null,\n\t\t\t\t},\n\t\t\t},\n\t\t) as Node<unknown>;\n\t\tsagaRef.n = sagaNode;\n\n\t\tthis.add(name, sagaNode);\n\t\tfor (const eName of eventNames) this.connect(eName, name);\n\t\tthis._keepaliveDisposers.push(keepalive(sagaNode));\n\t\tthis._sagas.add(name);\n\t\treturn sagaNode;\n\t}\n\n\t// -- Event store ----------------------------------------------------------\n\n\tuseEventStore(adapter: EventStoreAdapter): void {\n\t\tthis._eventStore = adapter;\n\t}\n\n\t/**\n\t * Replay persisted events through a reducer to rebuild a read model.\n\t * Requires an event store adapter wired via `useEventStore()`.\n\t */\n\tasync rebuildProjection<TState>(\n\t\teventNames: readonly string[],\n\t\treducer: ProjectionReducer<TState>,\n\t\tinitial: TState,\n\t): Promise<TState> {\n\t\tif (!this._eventStore) {\n\t\t\tthrow new Error(\"No event store wired. Call useEventStore() first.\");\n\t\t}\n\t\tconst allEvents: CqrsEvent[] = [];\n\t\tfor (const eName of eventNames) {\n\t\t\tconst result = await this._eventStore.loadEvents(eName);\n\t\t\tallEvents.push(...result.events);\n\t\t}\n\t\tallEvents.sort((a, b) => a.timestampNs - b.timestampNs || a.seq - b.seq);\n\t\treturn reducer(initial, allEvents);\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a CQRS graph container.\n *\n * @example\n * ```ts\n * const app = cqrs(\"orders\");\n * app.event(\"orderPlaced\");\n * app.command(\"placeOrder\", (payload, { emit }) => {\n * emit(\"orderPlaced\", { orderId: payload.id, amount: payload.amount });\n * });\n * app.projection(\"orderCount\", [\"orderPlaced\"], (_s, events) => events.length, 0);\n * app.dispatch(\"placeOrder\", { id: \"1\", amount: 100 });\n * ```\n */\nexport function cqrs(name: string, opts?: CqrsOptions): CqrsGraph {\n\treturn new CqrsGraph(name, opts);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACUA,SAAS,cAAc;;;ACLhB,IAAM,wBAAwB,uBAAO,IAAI,uBAAuB;AAMhE,IAAM,2BAA2B,uBAAO,IAAI,0BAA0B;AAQtE,SAAS,cAAc,MAAsB;AACnD,SAAO,uBAAO,IAAI,oBAAoB,IAAI,EAAE;AAC7C;AAQO,SAAS,aAAa,MAAsB;AAClD,SAAO,uBAAO,IAAI,mBAAmB,IAAI,EAAE;AAC5C;;;ADgBO,IAAM,iBAAiB,oBAAI,IAAkD;AAE7E,IAAM,oBAAoB,oBAAI,IAAmD;AAEjF,IAAM,gBAAgB,oBAAI,IAA+C;AAgCzE,IAAM,mBAAmB,oBAAI,IAAoD;AAEjF,IAAM,sBAAsB,oBAAI,IAAkD;AAElF,IAAM,iBAAiB,oBAAI,IAAkD;AAE7E,IAAM,gBAAgB,oBAAI,IAAiD;AAwB3E,SAAS,YAAY,MAAuD;AAClF,MAAI,SAAS,UAAW,QAAO,OAAO,wBAAwB;AAC9D,SAAO,OAAO,OAAO,cAAc,IAAI,IAAI,qBAAqB;AACjE;AAoBO,SAAS,gBAAgB,MAAsD;AACrF,SAAO,OAAO,cAAc,IAAI,CAAC;AAClC;AAmBO,SAAS,WAAW,MAAsD;AAChF,SAAO,OAAO,aAAa,IAAI,CAAC;AACjC;AA2BO,SAAS,aACf,UAC8E;AAC9E,SAAO,CAAC,QAA8B,YAAyC;AAC9E,UAAM,YAAY,QAAQ;AAC1B,YAAQ,eAAe,WAAyB;AAC/C,YAAM,OAAQ,KAAmD;AACjE,YAAM,WAAW,eAAe,IAAI,IAAI,KAAK,CAAC;AAC9C,eAAS,KAAK,EAAE,UAAU,UAAU,CAAC;AACrC,qBAAe,IAAI,MAAM,QAAQ;AAAA,IAClC,CAAC;AAAA,EACF;AACD;AAmBO,SAAS,cACf,IAC8E;AAC9E,SAAO,CAAC,QAA8B,YAAyC;AAC9E,UAAM,YAAY,QAAQ;AAC1B,YAAQ,eAAe,WAAyB;AAC/C,YAAM,OAAQ,KAAmD;AACjE,YAAM,WAAW,kBAAkB,IAAI,IAAI,KAAK,CAAC;AACjD,eAAS,KAAK,EAAE,IAAI,UAAU,CAAC;AAC/B,wBAAkB,IAAI,MAAM,QAAQ;AAAA,IACrC,CAAC;AAAA,EACF;AACD;AAmBO,SAAS,UACf,MAC8E;AAC9E,SAAO,CAAC,QAA8B,YAAyC;AAC9E,UAAM,YAAY,QAAQ;AAC1B,YAAQ,eAAe,WAAyB;AAC/C,YAAM,OAAQ,KAAmD;AACjE,YAAM,WAAW,cAAc,IAAI,IAAI,KAAK,CAAC;AAC7C,eAAS,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,oBAAc,IAAI,MAAM,QAAQ;AAAA,IACjC,CAAC;AAAA,EACF;AACD;AA0BO,SAAS,eACf,UACA,aAC8E;AAC9E,SAAO,CAAC,QAA8B,YAAyC;AAC9E,UAAM,YAAY,QAAQ;AAC1B,YAAQ,eAAe,WAAyB;AAC/C,YAAM,OAAQ,KAAmD;AACjE,YAAM,WAAW,iBAAiB,IAAI,IAAI,KAAK,CAAC;AAChD,eAAS,KAAK,EAAE,UAAU,aAAa,UAAU,CAAC;AAClD,uBAAiB,IAAI,MAAM,QAAQ;AAAA,IACpC,CAAC;AAAA,EACF;AACD;AAsBO,SAAS,aACf,UACA,WAC8E;AAC9E,SAAO,CAAC,QAA8B,YAAyC;AAC9E,UAAM,YAAY,QAAQ;AAC1B,YAAQ,eAAe,WAAyB;AAC/C,YAAM,OAAQ,KAAmD;AACjE,YAAM,WAAW,oBAAoB,IAAI,IAAI,KAAK,CAAC;AACnD,eAAS,KAAK,EAAE,UAAU,WAAW,UAAU,CAAC;AAChD,0BAAoB,IAAI,MAAM,QAAQ;AAAA,IACvC,CAAC;AAAA,EACF;AACD;AAsBO,SAAS,aACf,UACA,gBAC8E;AAC9E,SAAO,CAAC,QAA8B,YAAyC;AAC9E,UAAM,YAAY,QAAQ;AAC1B,YAAQ,eAAe,WAAyB;AAC/C,YAAM,OAAQ,KAAmD;AACjE,YAAM,WAAW,eAAe,IAAI,IAAI,KAAK,CAAC;AAC9C,eAAS,KAAK,EAAE,UAAU,gBAAgB,UAAU,CAAC;AACrD,qBAAe,IAAI,MAAM,QAAQ;AAAA,IAClC,CAAC;AAAA,EACF;AACD;AAuBO,SAAS,YACf,UACA,UACA,YAC8E;AAC9E,SAAO,CAAC,QAA8B,YAAyC;AAC9E,UAAM,YAAY,QAAQ;AAC1B,YAAQ,eAAe,WAAyB;AAC/C,YAAM,OAAQ,KAAmD;AACjE,YAAM,WAAW,cAAc,IAAI,IAAI,KAAK,CAAC;AAC7C,eAAS,KAAK,EAAE,UAAU,YAAY,UAAU,UAAU,CAAC;AAC3D,oBAAc,IAAI,MAAM,QAAQ;AAAA,IACjC,CAAC;AAAA,EACF;AACD;;;AE7WA,IAAI,cAAc;AAEX,IAAM,0BAAN,MAAuE;AAAA,EAI7E,YACkB,OACA,WAChB;AAFgB;AACA;AAAA,EACf;AAAA,EANc,YAA+B,CAAC;AAAA,EAChC,oBAA8B,CAAC;AAAA,EAOhD,eAAqB;AACpB,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,UAAU;AACf,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,cAAc;AAAA,EACpB;AAAA,EAEA,kBAAwB;AACvB,eAAW,WAAW,KAAK,UAAW,SAAQ;AAC9C,SAAK,UAAU,SAAS;AAExB,eAAW,QAAQ,KAAK,mBAAmB;AAC1C,UAAI;AACH,aAAK,MAAM,OAAO,IAAI;AAAA,MACvB,QAAQ;AAAA,MAER;AAAA,IACD;AACA,SAAK,kBAAkB,SAAS;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAMQ,aAAmB;AAC1B,eAAW,CAAC,MAAM,KAAK,KAAK,gBAAgB;AAC3C,YAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,UAAI,CAAC,SAAU;AAEf,iBAAW,QAAQ,OAAO;AACzB,aAAK,iBAAiB,UAAU,IAAI;AAAA,MACrC;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,iBAAiB,UAAkB,MAA8B;AACxE,UAAM,SAAU,SAA2D,KAAK,SAAS;AACzF,QAAI,OAAO,WAAW,WAAY;AAElC,UAAM,QAAQ,OAAO,KAAK,QAAQ;AAGlC,UAAM,SAAS,KAAK,YAAY,KAAK,QAAQ;AAC7C,UAAM,QAAQ,OAAO,UAAU,CAAC,SAAmB;AAClD,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,MAAM;AAClB,gBAAM,EAAE,CAAC,CAAC;AAAA,QACX;AAAA,MACD;AAAA,IACD,CAAC;AACD,SAAK,UAAU,KAAK,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAsB;AAC7B,eAAW,CAAC,MAAM,KAAK,KAAK,mBAAmB;AAC9C,YAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,UAAI,CAAC,SAAU;AAEf,iBAAW,QAAQ,OAAO;AACzB,aAAK,oBAAoB,UAAU,MAAM,IAAI;AAAA,MAC9C;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,oBACP,UACA,MACA,MACO;AACP,UAAM,SAAU,SAA2D,KAAK,SAAS;AACzF,QAAI,OAAO,WAAW,WAAY;AAElC,UAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,UAAM,YAAY,KAAK,QAAQ;AAC/B,UAAM,WAAW,gBAAgB,SAAS,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,aAAa;AAErF,UAAM,YAAY,UAAU,KAAK,IAAI,EAAE,QAAQ,KAAK,IAAI,MAAM,SAAS,CAAC;AACxE,SAAK,MAAM,IAAI,UAAU,SAAS;AAClC,SAAK,kBAAkB,KAAK,QAAQ;AAGpC,UAAM,SAAS,KAAK,YAAY,QAAQ;AACxC,UAAM,QAAQ,OAAO,UAAU,CAAC,SAAmB;AAClD,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,KAAM,OAAM,EAAE,CAAC,CAAC;AAAA,MAC9B;AAAA,IACD,CAAC;AACD,SAAK,UAAU,KAAK,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAkB;AACzB,eAAW,CAAC,MAAM,KAAK,KAAK,eAAe;AAC1C,YAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,UAAI,CAAC,SAAU;AAEf,iBAAW,QAAQ,OAAO;AACzB,aAAK,gBAAgB,UAAU,MAAM,IAAI;AAAA,MAC1C;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,gBACP,UACA,MACA,MACO;AACP,UAAM,SAAU,SAA2D,KAAK,SAAS;AACzF,QAAI,OAAO,WAAW,WAAY;AAElC,UAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,UAAM,YAAY,KAAK,QAAQ;AAC/B,UAAM,WAAW,gBAAgB,SAAS,IAAI,OAAO,KAAK,SAAS,CAAC,IAAI,aAAa;AAErF,UAAM,WAAW,SAAS,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AACvD,SAAK,MAAM,IAAI,UAAU,QAAQ;AACjC,SAAK,kBAAkB,KAAK,QAAQ;AAGpC,UAAM,SAAS,KAAK,YAAY,QAAQ;AACxC,UAAM,QAAQ,OAAO,UAAU,CAAC,SAAmB;AAClD,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,KAAM,OAAM,EAAE,CAAC,CAAC;AAAA,MAC9B;AAAA,IACD,CAAC;AACD,SAAK,UAAU,KAAK,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAAyB;AAChC,eAAW,CAAC,MAAM,KAAK,KAAK,kBAAkB;AAC7C,YAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,UAAI,CAAC,SAAU;AAEf,iBAAW,QAAQ,OAAO;AACzB,aAAK,gBAAgB,UAAU,IAAI;AAAA,MACpC;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,gBAAgB,UAAkB,MAAgC;AACzE,UAAM,SAAU,SAA2D,KAAK,SAAS;AACzF,QAAI,OAAO,WAAW,WAAY;AAElC,UAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,UAAM,YAAY,KAAK,iBAAiB,KAAK,QAAQ;AACrD,QAAI,CAAC,UAAW;AAEhB,cAAU,QAAQ,KAAK,aAAa,KAAK;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAMQ,iBAAuB;AAC9B,eAAW,CAAC,MAAM,KAAK,KAAK,qBAAqB;AAChD,YAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,UAAI,CAAC,SAAU;AAEf,iBAAW,QAAQ,OAAO;AACzB,aAAK,qBAAqB,UAAU,IAAI;AAAA,MACzC;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,qBAAqB,UAAkB,MAA8B;AAC5E,UAAM,SAAU,SAA2D,KAAK,SAAS;AACzF,QAAI,OAAO,WAAW,WAAY;AAElC,UAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,UAAM,YAAY,KAAK,iBAAiB,KAAK,QAAQ;AACrD,QAAI,CAAC,UAAW;AAGhB,cAAU,MAAM,KAAK,SAAS;AAI9B,UAAM,YAAY,UAAU,QAAQ,KAAK,SAAS;AAClD,UAAM,cAAc,UAAU,IAAI;AAGlC,UAAM,kBAAkB,aAAa,OAAO;AAC5C,QAAI,UACH,mBAAmB,gBAAgB,SAAS,IACzC,gBAAgB,gBAAgB,SAAS,CAAC,EAAE,MAC5C;AAGJ,UAAM,SAAS,KAAK,cAAc,WAAW,KAAK,SAAS;AAC3D,UAAM,QAAQ,OAAO,UAAU,CAAC,SAAmB;AAClD,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,MAAM;AAClB,gBAAM,OAAO,EAAE,CAAC;AAChB,qBAAW,SAAS,KAAK,MAAM,SAAS;AACvC,gBAAI,MAAM,MAAM,SAAS;AACxB,oBAAM,KAAK;AACX,wBAAU,MAAM;AAAA,YACjB;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAC;AACD,SAAK,UAAU,KAAK,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAMQ,kBAAwB;AAC/B,eAAW,CAAC,MAAM,KAAK,KAAK,gBAAgB;AAC3C,YAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,UAAI,CAAC,SAAU;AAEf,iBAAW,QAAQ,OAAO;AACzB,aAAK,cAAc,UAAU,IAAI;AAAA,MAClC;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,cAAc,UAAkB,MAA8B;AACrE,UAAM,SAAU,SAA2D,KAAK,SAAS;AACzF,QAAI,OAAO,WAAW,WAAY;AAElC,UAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,UAAM,YAAY,KAAK,iBAAiB,KAAK,QAAQ;AACrD,QAAI,CAAC,UAAW;AAGhB,UAAM,SAAS,KAAK,cAAc,WAAW,KAAK,cAAc;AAChE,UAAM,QAAQ,OAAO,UAAU,CAAC,SAAmB;AAClD,iBAAW,KAAK,MAAM;AACrB,YAAI,EAAE,CAAC,MAAM,MAAM;AAClB,gBAAM,EAAE,CAAC,CAAC;AAAA,QACX;AAAA,MACD;AAAA,IACD,CAAC;AACD,SAAK,UAAU,KAAK,KAAK;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAsB;AAC7B,eAAW,CAAC,MAAM,KAAK,KAAK,eAAe;AAC1C,YAAM,WAAW,KAAK,gBAAgB,IAAI;AAC1C,UAAI,CAAC,SAAU;AAEf,iBAAW,QAAQ,OAAO;AACzB,aAAK,aAAa,UAAU,IAAI;AAAA,MACjC;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,aAAa,UAAkB,MAA6B;AACnE,UAAM,SAAU,SAA2D,KAAK,SAAS;AACzF,QAAI,OAAO,WAAW,WAAY;AAElC,UAAM,QAAQ,OAAO,KAAK,QAAQ;AAClC,UAAM,YAAY,KAAK,iBAAiB,KAAK,QAAQ;AACrD,QAAI,CAAC,UAAW;AAEhB,cAAU,KAAK,KAAK,UAAU,KAAK,YAAY,KAAK;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAMQ,YAAY,MAA+B;AAElD,WAAO,KAAK,MAAM,QAAQ,IAAI;AAAA,EAC/B;AAAA,EAEQ,cAAc,OAAc,MAA+B;AAClE,WAAO,MAAM,QAAQ,IAAI;AAAA,EAC1B;AAAA,EAEQ,iBAAiB,MAAgC;AACxD,QAAI;AACH,aAAO,KAAK,UAAU,IAAI,cAAc,IAAI,GAAG,EAAE,QAAQ,MAAM,CAAC;AAAA,IACjE,QAAQ;AACP,cAAQ;AAAA,QACP,2BAA2B,IAAI,6EACsB,IAAI;AAAA,MAC1D;AACA,aAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEQ,gBAAgB,MAA+C;AACtE,QAAI;AACH,aAAO,KAAK,UAAU,IAAI,MAAM,EAAE,QAAQ,MAAM,CAAC;AAAA,IAClD,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AACD;;;ACrSO,SAAS,WACf,OACA,MACA,MAC6B;AAC7B,QAAM,EAAE,OAAO,YAAY,kBAAkB,aAAa,OAAO,IAAI,QAAQ,CAAC;AAC9E,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI;AACJ,QAAM,kBAAkB,MAAM,iBAAiB;AAE/C,MAAI;AACJ,MAAI;AAKJ,QAAM,YAAwB,CAAC;AAC/B,MAAI,SAAS;AAEb,SAAO,IAAI,eAA2B;AAAA,IACrC,MAAM,YAAY;AACjB,UAAI;AACJ,UAAI,QAAoB,MAAM;AAAA,MAAC;AAC/B,YAAM,QAAQ,MAAM;AACnB,YAAI,OAAQ;AACZ,iBAAS;AACT,YAAI,cAAc,OAAW,eAAc,SAAS;AACpD,gBAAQ,oBAAoB,SAAS,OAAO;AAE5C,cAAM;AACN,YAAI,QAAQ;AAEZ,sBAAc;AACd,sBAAc;AAEd,mBAAW,SAAS,UAAW,YAAW,QAAQ,MAAM,KAAK;AAC7D,kBAAU,SAAS;AACnB,mBAAW,MAAM;AAAA,MAClB;AACA,aAAO;AACP,YAAM,UAAU,MAAM,MAAM;AAE5B,YAAM,SAAS,MAAM,QAAQ,MAAM,EAAE,MAAM,CAAC;AAE5C,UAAI,iBAAiB;AACpB,aAAK,0BAA0B,CAAC,SAAS,OAAO,GAAG,IAAI,GAAG;AAAA,UACzD,eAAe,KAAM;AAAA,UACrB,cAAc,KAAM,gBAAgB,KAAK,MAAM,KAAM,gBAAiB,CAAC;AAAA,QACxE,CAAC;AAAA,MACF;AAEA,cAAQ,OAAO,UAAU,CAAC,SAAmB;AAC5C,mBAAW,OAAO,MAAM;AACvB,cAAI,OAAQ;AACZ,gBAAM,IAAI,IAAI,CAAC;AACf,cAAI,MAAM,MAAM;AACf,kBAAM,QAAQ,QAAQ,OAAO,SAAS,QAAQ,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC;AAChE,gBAAI,iBAAiB;AACpB,wBAAU,KAAK,EAAE,OAAO,SAAS,KAAK,CAAC;AACvC,iBAAI,UAAU;AACd,4BAAc;AACd,4BAAc;AAAA,YACf,OAAO;AACN,yBAAW,QAAQ,KAAK;AAAA,YACzB;AAAA,UACD,WAAW,MAAM,OAAO;AACvB,kBAAM,QAAQ,QAAQ,OAAO,SAAS,SAAS,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC;AACjE,gBAAI,iBAAiB;AACpB,wBAAU,KAAK,EAAE,OAAO,SAAS,MAAM,CAAC;AACxC,4BAAc;AACd,4BAAc;AAAA,YACf,OAAO;AACN,yBAAW,QAAQ,KAAK;AAAA,YACzB;AACA,kBAAM;AACN;AAAA,UACD,WAAW,MAAM,YAAY,MAAM,UAAU;AAC5C,gBAAI,MAAM,UAAU;AACnB,oBAAM,QAAQ,QAAQ,OAAO,SAAS,UAAU,CAAC;AACjD,kBAAI,iBAAiB;AACpB,0BAAU,KAAK,EAAE,OAAO,SAAS,MAAM,CAAC;AACxC,8BAAc;AACd,8BAAc;AAAA,cACf,OAAO;AACN,2BAAW,QAAQ,KAAK;AAAA,cACzB;AAAA,YACD;AACA,kBAAM;AACN;AAAA,UACD;AAAA,QAED;AAAA,MACD,CAAC;AAED,UAAI,gBAAgB,UAAa,cAAc,GAAG;AACjD,oBAAY,YAAY,MAAM;AAC7B,cAAI,OAAQ;AACZ,cAAI,iBAAiB;AAEpB,sBAAU,KAAK,EAAE,OAAO,QAAQ,OAAO,iBAAiB,GAAG,SAAS,MAAM,CAAC;AAC3E,0BAAc;AACd,0BAAc;AAAA,UACf,OAAO;AACN,uBAAW,QAAQ,QAAQ,OAAO,iBAAiB,CAAC;AAAA,UACrD;AAAA,QACD,GAAG,WAAW;AAAA,MACf;AACA,UAAI,QAAQ,QAAS,SAAQ;AAAA,UACxB,SAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAAA,IAC/D;AAAA,IACA,KAAK,YAAY;AAChB,UAAI,CAAC,gBAAiB;AACtB,UAAI,OAAQ;AACZ,UAAI,UAAU,SAAS,GAAG;AACzB,cAAM,QAAQ,UAAU,MAAM;AAC9B,mBAAW,QAAQ,MAAM,KAAK;AAC9B,YAAI,MAAM,QAAS,IAAI,UAAU;AACjC;AAAA,MACD;AAEA,aAAO,IAAI,QAAc,CAAC,YAAY;AACrC,sBAAc;AAAA,MACf,CAAC;AAAA,IACF;AAAA,IACA,SAAS;AAER,UAAI;AACH,eAAO;AAAA,MACR,QAAQ;AAAA,MAER;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAkDO,SAAS,oBACf,OACA,MACA,MAC2B;AAC3B,QAAM,EAAE,OAAO,OAAO,IAAI,QAAQ,CAAC;AAInC,QAAM,QAAqB,CAAC;AAC5B,QAAM,UAGD,CAAC;AACN,MAAI,WAAW;AAEf,QAAM,SAAS,MAAM,QAAQ,MAAM,EAAE,MAAM,CAAC;AAE5C,QAAM,KACL,MAAM,iBAAiB,OACpB,0BAA0B,CAAC,SAAS,OAAO,GAAG,IAAI,GAAG;AAAA,IACrD,eAAe,KAAK;AAAA,IACpB,cAAc,KAAK,gBAAgB,KAAK,MAAM,KAAK,gBAAgB,CAAC;AAAA,EACrE,CAAC,IACA;AAEJ,QAAM,UAAU,MAAM;AACrB,QAAI,SAAU;AACd,eAAW;AACX,QAAI,QAAQ;AACZ,UAAM;AAAA,EACP;AAEA,QAAM,OAAO,CAAC,SAAoB;AACjC,QAAI,SAAU;AACd,QAAI,QAAQ,SAAS,GAAG;AACvB,YAAM,IAAI,QAAQ,MAAM;AACxB,UAAI,KAAK,QAAQ,KAAK,MAAO,GAAE,OAAO,KAAK,KAAK;AAAA,eACvC,KAAK,KAAM,GAAE,QAAQ,EAAE,MAAM,MAAM,OAAO,OAAU,CAAC;AAAA,UACzD,GAAE,QAAQ,EAAE,MAAM,OAAO,OAAO,KAAK,MAAW,CAAC;AAAA,IAEvD,OAAO;AACN,YAAM,KAAK,IAAI;AACf,UAAI,CAAC,KAAK,KAAM,KAAI,UAAU;AAAA,IAC/B;AAAA,EACD;AAEA,QAAM,QAAQ,OAAO,UAAU,CAAC,SAAmB;AAClD,eAAW,OAAO,MAAM;AACvB,YAAM,IAAI,IAAI,CAAC;AACf,UAAI,MAAM,MAAM;AACf,cAAM,QAAQ,IAAI,CAAC;AACnB,YAAI,UAAU,CAAC,OAAO,KAAK,EAAG;AAC9B,aAAK,EAAE,MAAM,OAAO,MAAM,CAAC;AAAA,MAC5B,WAAW,MAAM,OAAO;AACvB,cAAM,MAAM,IAAI,CAAC,aAAa,QAAQ,IAAI,CAAC,IAAI,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC,CAAC;AACvE,aAAK,EAAE,MAAM,MAAM,OAAO,IAAI,CAAC;AAC/B,gBAAQ;AACR;AAAA,MACD,WAAW,MAAM,YAAY,MAAM,UAAU;AAC5C,aAAK,EAAE,MAAM,KAAK,CAAC;AACnB,gBAAQ;AACR;AAAA,MACD;AAAA,IACD;AAAA,EACD,CAAC;AAED,QAAM,WAAqC;AAAA,IAC1C,OAAmC;AAClC,UAAI,MAAM,SAAS,GAAG;AACrB,cAAM,OAAO,MAAM,MAAM;AACzB,YAAI,CAAC,KAAK,KAAM,KAAI,UAAU;AAC9B,YAAI,KAAK,QAAQ,KAAK,MAAO,QAAO,QAAQ,OAAO,KAAK,KAAK;AAC7D,eAAO,QAAQ;AAAA,UACd,KAAK,OAAO,EAAE,MAAM,MAAM,OAAO,OAAU,IAAI,EAAE,MAAM,OAAO,OAAO,KAAK,MAAW;AAAA,QACtF;AAAA,MACD;AACA,UAAI,SAAU,QAAO,QAAQ,QAAQ,EAAE,MAAM,MAAM,OAAO,OAAU,CAAC;AACrE,aAAO,IAAI,QAA2B,CAAC,SAAS,WAAW;AAC1D,gBAAQ,KAAK,EAAE,SAAS,OAAO,CAAC;AAAA,MACjC,CAAC;AAAA,IACF;AAAA,IACA,SAAmD;AAClD,cAAQ;AAER,iBAAW,KAAK,QAAS,GAAE,QAAQ,EAAE,MAAM,MAAM,OAAO,OAAU,CAAC;AACnE,cAAQ,SAAS;AACjB,aAAO,QAAQ,QAAQ,EAAE,MAAM,MAAM,OAAO,OAAU,CAAC;AAAA,IACxD;AAAA,IACA,MAAM,KAA0C;AAC/C,cAAQ;AACR,aAAO,QAAQ,OAAO,GAAG;AAAA,IAC1B;AAAA,IACA,CAAC,OAAO,aAAa,IAAI;AACxB,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;AA6CO,IAAM,iBAAN,MAAqB;AAAA,EAU3B,YACkB,OACjB,MACC;AAFgB;AAGjB,SAAK,eAAe,MAAM,iBAAiB,MAAM;AACjD,SAAK,QAAQ,MAAM,SAAS;AAC5B,SAAK,gBAAgB,MAAM;AAC3B,SAAK,eAAe,MAAM;AAAA,EAC3B;AAAA,EAjBiB,UAAU,oBAAI,IAG7B;AAAA,EACe;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAejB,iBAAiB,QAAuB;AACvC,QAAI,CAAC,KAAK,QAAQ,IAAI,MAAM,GAAG;AAC9B,WAAK,QAAQ,IAAI,QAAQ,oBAAI,IAAI,CAAC;AAAA,IACnC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiB,QAAuB;AACvC,UAAM,OAAO,KAAK,QAAQ,IAAI,MAAM;AACpC,QAAI,CAAC,KAAM;AACX,eAAW,SAAS,KAAK,OAAO,GAAG;AAClC,YAAM,IAAI,QAAQ;AAClB,YAAM,MAAM;AAAA,IACb;AACA,SAAK,QAAQ,OAAO,MAAM;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,cAAc,QAAiB,KAAc,MAA8C;AAC1F,UAAM,SAAS,QAAQ,YAAY,KAAK,MAAM,MAAM;AACpD,QAAI;AACJ,QAAI;AACH,YAAM,OAAO,QAAQ,WAAW,KAAK,MAAM,GAAG,IAAK;AAAA,IACpD,QAAQ;AACP,aAAO,EAAE,MAAM,OAAO,SAAS,kBAAkB,CAAC;AAClD;AAAA,IACD;AAEA,QAAI,IAAI,SAAS,aAAa;AAC7B,WAAK,UAAU,QAAQ,IAAI,MAAM,MAAM;AAAA,IACxC,WAAW,IAAI,SAAS,eAAe;AACtC,WAAK,YAAY,QAAQ,IAAI,MAAM,MAAM;AAAA,IAC1C,WAAW,IAAI,SAAS,OAAO;AAC9B,WAAK,IAAI,QAAQ,IAAI,MAAM,IAAI,SAAS,CAAC;AAAA,IAC1C,OAAO;AACN,aAAO,EAAE,MAAM,OAAO,SAAS,yBAA0B,IAAyB,IAAI,GAAG,CAAC;AAAA,IAC3F;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,QAAyB;AAC1C,WAAO,KAAK,QAAQ,IAAI,MAAM,GAAG,QAAQ;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACf,eAAW,CAAC,MAAM,KAAK,KAAK,SAAS;AACpC,WAAK,iBAAiB,MAAM;AAAA,IAC7B;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAMQ,UAAU,QAAiB,MAAc,MAA6C;AAC7F,QAAI,OAAO,KAAK,QAAQ,IAAI,MAAM;AAClC,QAAI,CAAC,MAAM;AACV,aAAO,oBAAI,IAAI;AACf,WAAK,QAAQ,IAAI,QAAQ,IAAI;AAAA,IAC9B;AACA,QAAI,KAAK,IAAI,IAAI,GAAG;AACnB,WAAK,EAAE,MAAM,cAAc,KAAK,CAAC;AACjC;AAAA,IACD;AAEA,UAAM,QAAQ,KAAK,aAAa,MAAM;AACtC,QAAI;AACJ,QAAI;AACH,eAAS,KAAK,MAAM,QAAQ,MAAM,EAAE,MAAM,CAAC;AAAA,IAC5C,SAAS,KAAK;AACb,YAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC/D,WAAK,EAAE,MAAM,OAAO,QAAQ,CAAC;AAC7B;AAAA,IACD;AAEA,UAAM,KACL,KAAK,iBAAiB,OACnB,0BAA0B,CAAC,SAAS,OAAO,GAAG,IAAI,GAAG;AAAA,MACrD,eAAe,KAAK;AAAA,MACpB,cAAc,KAAK,gBAAgB,KAAK,MAAM,KAAK,gBAAgB,CAAC;AAAA,IACrE,CAAC,IACA;AAEJ,UAAM,UAAU,MAAM;AACrB,UAAI,QAAQ;AACZ,YAAM;AACN,WAAM,OAAO,IAAI;AAAA,IAClB;AAEA,UAAM,QAAQ,OAAO,UAAU,CAAC,SAAmB;AAClD,iBAAW,OAAO,MAAM;AACvB,cAAM,IAAI,IAAI,CAAC;AACf,YAAI,MAAM,MAAM;AACf,cAAI,UAAU;AACd,kBAAQ,MAAM,EAAE,MAAM,QAAQ,MAAM,OAAO,IAAI,CAAC,EAAE,CAAC;AAAA,QACpD,WAAW,MAAM,OAAO;AACvB,gBAAM,SAAS,IAAI,CAAC,aAAa,QAAQ,IAAI,CAAC,EAAE,UAAU,OAAO,IAAI,CAAC,CAAC;AACvE,kBAAQ,MAAM,EAAE,MAAM,SAAS,MAAM,OAAO,OAAO,CAAC;AACpD,kBAAQ;AACR;AAAA,QACD,WAAW,MAAM,YAAY,MAAM,UAAU;AAC5C,kBAAQ,MAAM,EAAE,MAAM,YAAY,KAAK,CAAC;AACxC,kBAAQ;AACR;AAAA,QACD;AAAA,MAED;AAAA,IACD,CAAC;AAED,SAAK,IAAI,MAAM,EAAE,OAAO,GAAG,CAAC;AAC5B,SAAK,EAAE,MAAM,cAAc,KAAK,CAAC;AAAA,EAClC;AAAA,EAEQ,YAAY,QAAiB,MAAc,MAA6C;AAC/F,UAAM,OAAO,KAAK,QAAQ,IAAI,MAAM;AACpC,UAAM,QAAQ,MAAM,IAAI,IAAI;AAC5B,QAAI,OAAO;AACV,YAAM,IAAI,QAAQ;AAClB,YAAM,MAAM;AACZ,WAAM,OAAO,IAAI;AAAA,IAClB;AACA,SAAK,EAAE,MAAM,gBAAgB,KAAK,CAAC;AAAA,EACpC;AAAA,EAEQ,IAAI,QAAiB,MAAc,OAAqB;AAC/D,UAAM,QAAQ,KAAK,QAAQ,IAAI,MAAM,GAAG,IAAI,IAAI;AAChD,QAAI,CAAC,OAAO,GAAI;AAChB,UAAM,IAAI,KAAK,IAAI,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,CAAC,GAAG,IAAI;AACvD,aAAS,IAAI,GAAG,IAAI,GAAG,IAAK,OAAM,GAAG,UAAU;AAAA,EAChD;AACD;AAMA,SAAS,iBAAiB,OAAwB;AACjD,MAAI,iBAAiB,MAAO,QAAO,MAAM;AACzC,MAAI;AACH,WAAO,KAAK,UAAU,KAAK;AAAA,EAC5B,QAAQ;AACP,WAAO,OAAO,KAAK;AAAA,EACpB;AACD;AAEA,SAAS,SAAS,OAAe,MAAuB;AACvD,MAAI,QAAQ,UAAU,KAAK;AAAA;AAC3B,MAAI,SAAS,QAAW;AACvB,eAAW,QAAQ,KAAK,MAAM,IAAI,GAAG;AACpC,eAAS,SAAS,IAAI;AAAA;AAAA,IACvB;AAAA,EACD;AACA,WAAS;AACT,SAAO;AACR;AAEA,SAAS,oBAAoB,MAAgC;AAC5D,SAAO,KAAK,MAAM,IAAI;AACvB;AAEA,SAAS,YAAY,QAAiB,KAA6B;AAClE,MAAI;AACH,IAAC,OAA4C,KAAK,KAAK,UAAU,GAAG,CAAC;AAAA,EACtE,QAAQ;AAAA,EAER;AACD;AAEA,SAAS,QAAQ,MAAuC,KAA6B;AACpF,MAAI;AACH,SAAK,GAAG;AAAA,EACT,QAAQ;AAAA,EAER;AACD;;;AC/kBO,IAAM,YAAY;AA6BlB,SAAS,eAAe,SAAuD;AACrF,SAAO,CAAC,YAAiD;AACxD,UAAM,MAAM,QAAQ,aAAa,EAAE,WAAW;AAC9C,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ,KAAM,QAAO;AACzB,QAAI,QAAS,QAAO,QAAQ,IAAI;AAChC,WAAO;AAAA,EACR;AACD;AAeO,SAAS,WAAW,aAAa,sBAAsC;AAC7E,SAAO,CAAC,YAAiD;AACxD,UAAM,MAAM,QAAQ,aAAa,EAAE,WAAW;AAC9C,UAAM,MAAM,KAAK,UAAU,WAAW,YAAY,CAAC;AACnD,QAAI,OAAO,QAAQ,YAAY,IAAI,WAAW,EAAG,QAAO;AACxD,QAAI;AACH,aAAO,KAAK,MAAM,GAAG;AAAA,IACtB,QAAQ;AACP,aAAO;AAAA,IACR;AAAA,EACD;AACD;AAgBO,SAAS,SAAS,KAAqB;AAC7C,QAAM,QAAS,MAAkC,SAAS;AAC1D,SAAO,SAAS,OAAO,eAAe,KAAc,IAAI;AACzD;AAqBO,IAAM,sBAAN,MAAiD;AAAA,EACvD,YAA6B,WAA2B;AAA3B;AAAA,EAA4B;AAAA,EAEzD,YAAY,SAAoC;AAC/C,UAAM,QAAQ,eAAe,KAAK,UAAU,OAAO,CAAC;AACpD,UAAM,MAAM,QAAQ,aAAa,EAAE,WAAW;AAC9C,QAAI,OAAO,MAAM;AAChB,MAAC,IAAgC,SAAS,IAAI;AAAA,IAC/C;AACA,WAAO;AAAA,EACR;AACD;AAkBO,SAAS,gBAAgB,WAAiD;AAChF,SAAO,IAAI,oBAAoB,aAAa,eAAe,CAAC;AAC7D;;;AC7IA;AAAA,EAEC;AAAA,EAGA;AAAA,OACM;AACP,SAAS,iBAAiB;;;ACpB1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBA,IAAM,gBAAgB,OAAO,CAAC,OAAO,SAAS;AAC7C,QAAM,OAAO;AACb,QAAM,QAAQ;AACd,OAAK,SAAS;AACf,CAAC;AAGD,IAAM,mBAAmB,OAAO,CAAC,OAAO,SAAS;AAChD,QAAM,SAAS;AACf,QAAM,QAAQ;AACd,OAAK,OAAO;AACb,CAAC;AAGD,IAAM,cAAc,OAAO,CAAC,OAAO,SAAS;AAC3C,QAAM,SAAS;AACf,QAAM,QAAQ;AACd,OAAK,OAAO;AACb,CAAC;AAMD,SAAS,SAAS,MAAc,OAA0D;AACzF,SAAO,EAAE,MAAM,MAAM,WAAW,MAAM,GAAI,SAAS,CAAC,EAAG;AACxD;AAMA,SAAS,UAAU,GAA8B;AAChD,SAAO,EAAE,UAAU,MAAM;AAAA,EAAC,CAAC;AAC5B;AAkEO,IAAM,mBAAN,MAAoD;AAAA,EACzC,SAAS,oBAAI,IAAyB;AAAA,EAEvD,QAAQ,OAAwB;AAC/B,QAAI,OAAO,KAAK,OAAO,IAAI,MAAM,IAAI;AACrC,QAAI,CAAC,MAAM;AACV,aAAO,CAAC;AACR,WAAK,OAAO,IAAI,MAAM,MAAM,IAAI;AAAA,IACjC;AACA,SAAK,KAAK,KAAK;AAAA,EAChB;AAAA,EAEA,WAAW,WAAmB,QAA6C;AAC1E,UAAM,OAAO,KAAK,OAAO,IAAI,SAAS,KAAK,CAAC;AAC5C,UAAM,UAAW,QAAiD;AAClE,UAAM,WAAY,QAAyC;AAC3D,UAAM,SACL,WAAW,OACR,CAAC,GAAG,IAAI,IACR,KAAK;AAAA,MACL,CAAC,MACA,EAAE,cAAc,WAAY,EAAE,gBAAgB,WAAW,EAAE,OAAO,YAAY;AAAA,IAChF;AACH,UAAM,YAAY,OAAO,SAAS,IAAI,OAAO,OAAO,SAAS,CAAC,IAAI;AAClE,WAAO;AAAA,MACN;AAAA,MACA,QAAQ,YAAY,EAAE,aAAa,UAAU,aAAa,KAAK,UAAU,IAAI,IAAI;AAAA,IAClF;AAAA,EACD;AAAA,EAEA,QAAc;AACb,SAAK,OAAO,MAAM;AAAA,EACnB;AACD;AAmDO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnB,aAAa,oBAAI,IAAwB;AAAA,EACzC,mBAAmB,oBAAI,IAAiC;AAAA,EACxD,eAAe,oBAAI,IAAY;AAAA,EAC/B,SAAS,oBAAI,IAAY;AAAA,EACzB,sBAAyC,CAAC;AAAA,EACnD;AAAA,EACA,OAAO;AAAA,EAEf,YAAY,MAAc,OAAoB,CAAC,GAAG;AACjD,UAAM,MAAM,KAAK,KAAK;AAAA,EACvB;AAAA,EAES,UAAgB;AACxB,eAAW,WAAW,KAAK,oBAAqB,SAAQ;AACxD,SAAK,oBAAoB,SAAS;AAClC,UAAM,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,MAAoD;AACzD,UAAM,WAAW,KAAK,WAAW,IAAI,IAAI;AACzC,QAAI,SAAU,QAAO,SAAS;AAE9B,UAAM,MAAM,YAAuB,CAAC,GAAG,EAAE,KAAK,CAAC;AAC/C,UAAM,UAAU,IAAI;AACpB,UAAM,UAAU;AAAA,MACf,CAAC,OAAO;AAAA,MACR,CAAC,CAAC,QAAQ,MAAM;AAAA,MAChB;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,MAAM,SAAS,SAAS,EAAE,YAAY,KAAK,CAAC;AAAA,QAC5C,OAAO;AAAA,QACP,SAAS,QAAQ,IAAI;AAAA,MACtB;AAAA,IACD;AACA,SAAK,IAAI,MAAM,OAAO;AACtB,SAAK,oBAAoB,KAAK,UAAU,OAAO,CAAC;AAChD,SAAK,WAAW,IAAI,MAAM,EAAE,KAAK,MAAM,QAAQ,CAAC;AAChD,WAAO;AAAA,EACR;AAAA;AAAA,EAGQ,aAAa,WAAmB,SAAwB;AAC/D,QAAI,QAAQ,KAAK,WAAW,IAAI,SAAS;AACzC,QAAI,CAAC,OAAO;AACX,WAAK,MAAM,SAAS;AACpB,cAAQ,KAAK,WAAW,IAAI,SAAS;AAAA,IACtC;AAEA,QAAI,MAAM,KAAK,WAAW,eAAe,MAAM,KAAK,WAAW,WAAW;AACzE,YAAM,IAAI;AAAA,QACT,+CAA+C,SAAS,cAAc,MAAM,KAAK,MAAM;AAAA,MACxF;AAAA,IACD;AACA,UAAM,KAAK,MAAM,IAAI,QAAQ;AAC7B,UAAM,MAAiB;AAAA,MACtB,MAAM;AAAA,MACN;AAAA,MACA,aAAa,YAAY;AAAA,MACzB,KAAK,EAAE,KAAK;AAAA,MACZ,GAAI,MAAM,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,SAAS,GAAG,QAAQ,EAAE,IAAI,CAAC;AAAA,IAChE;AACA,UAAM,IAAI,OAAO,GAAG;AACpB,QAAI,KAAK,aAAa;AACrB,WAAK,YAAY,QAAQ,GAAG;AAAA,IAC7B;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QAAqB,MAAc,SAAqC;AACvE,UAAM,UAAU,MAAS,QAAgB;AAAA,MACxC;AAAA,MACA,cAAc;AAAA,MACd,MAAM;AAAA,QACL,GAAG,SAAS,WAAW,EAAE,cAAc,KAAK,CAAC;AAAA,QAC7C,OAAO;AAAA,MACR;AAAA,MACA,OAAO;AAAA,IACR,CAAC;AACD,SAAK,IAAI,MAAM,OAAO;AACtB,SAAK,iBAAiB,IAAI,MAAM,OAA8B;AAC9D,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,SAAsB,aAAqB,SAAkB;AAC5D,UAAM,UAAU,KAAK,iBAAiB,IAAI,WAAW;AACrD,QAAI,CAAC,SAAS;AACb,YAAM,IAAI,MAAM,qBAAqB,WAAW,oCAAoC;AAAA,IACrF;AACA,UAAM,UAAU,KAAK,QAAQ,WAAW;AACxC,UAAM,MAAM;AACX,cAAQ,KAAK,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC;AAClD,UAAI;AACH,gBAAQ,SAAS,EAAE,MAAM,CAAC,OAAO,SAAS,KAAK,aAAa,OAAO,IAAI,EAAE,CAAC;AAC1E,gBAAQ,KAAK,MAAM,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC;AAAA,MAC3D,SAAS,KAAK;AACb,gBAAQ,KAAK,MAAM,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC;AACzD,cAAM;AAAA,MACP;AAAA,IACD,CAAC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,WACC,MACA,YACA,SACA,SACe;AACf,UAAM,aAAa,WAAW,IAAI,CAAC,UAAU;AAC5C,UAAI,CAAC,KAAK,WAAW,IAAI,KAAK,EAAG,MAAK,MAAM,KAAK;AACjD,aAAO,KAAK,WAAW,IAAI,KAAK,EAAG;AAAA,IACpC,CAAC;AAED,UAAM,WAAW;AAAA,MAChB;AAAA,MACA,CAAC,cAAc;AACd,cAAM,YAAyB,CAAC;AAChC,mBAAW,YAAY,WAAW;AACjC,gBAAM,OAAO;AACb,oBAAU,KAAK,GAAG,KAAK,MAAM,OAAO;AAAA,QACrC;AACA,kBAAU,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG;AACvE,eAAO,QAAQ,SAAS,SAAS;AAAA,MAClC;AAAA,MACA;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,MAAM,SAAS,cAAc,EAAE,iBAAiB,MAAM,eAAe,WAAW,CAAC;AAAA,QACjF,OAAO;AAAA,QACP;AAAA,MACD;AAAA,IACD;AAEA,SAAK,IAAI,MAAM,QAAQ;AACvB,eAAW,SAAS,WAAY,MAAK,QAAQ,OAAO,IAAI;AACxD,SAAK,oBAAoB,KAAK,UAAU,QAAQ,CAAC;AACjD,SAAK,aAAa,IAAI,IAAI;AAC1B,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,KACC,MACA,YACA,SACgB;AAChB,UAAM,aAAa,WAAW,IAAI,CAAC,UAAU;AAC5C,UAAI,CAAC,KAAK,WAAW,IAAI,KAAK,EAAG,MAAK,MAAM,KAAK;AACjD,aAAO,KAAK,WAAW,IAAI,KAAK,EAAG;AAAA,IACpC,CAAC;AAGD,UAAM,aAAa,oBAAI,IAAoB;AAE3C,UAAM,UAAiC,CAAC;AACxC,UAAM,WAAW;AAAA,MAChB;AAAA,MACA,CAAC,cAAc;AACd,cAAM,UAAU,QAAQ,EAAG,KAAK;AAChC,iBAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AAC1C,gBAAM,OAAO,UAAU,CAAC;AACxB,gBAAM,QAAQ,WAAW,CAAC;AAC1B,gBAAM,UAAU,KAAK,MAAM;AAC3B,gBAAM,YAAY,WAAW,IAAI,KAAK,KAAK;AAC3C,cAAI,QAAQ,SAAS,WAAW;AAC/B,kBAAM,aAAa,QAAQ,MAAM,SAAS;AAC1C,uBAAW,SAAS,YAAY;AAC/B,kBAAI;AACH,wBAAQ,KAAqB;AAC7B,wBAAQ,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC;AAAA,cAChD,SAAS,KAAK;AACb,wBAAQ,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,EAAE,UAAU,KAAK,CAAC;AAAA,cAC/C;AAAA,YACD;AACA,uBAAW,IAAI,OAAO,QAAQ,MAAM;AAAA,UACrC;AAAA,QACD;AAAA,MACD;AAAA,MACA;AAAA,QACC;AAAA,QACA,cAAc;AAAA,QACd,MAAM;AAAA,UACL,GAAG,SAAS,QAAQ,EAAE,WAAW,MAAM,eAAe,WAAW,CAAC;AAAA,UAClE,OAAO;AAAA,QACR;AAAA,MACD;AAAA,IACD;AACA,YAAQ,IAAI;AAEZ,SAAK,IAAI,MAAM,QAAQ;AACvB,eAAW,SAAS,WAAY,MAAK,QAAQ,OAAO,IAAI;AACxD,SAAK,oBAAoB,KAAK,UAAU,QAAQ,CAAC;AACjD,SAAK,OAAO,IAAI,IAAI;AACpB,WAAO;AAAA,EACR;AAAA;AAAA,EAIA,cAAc,SAAkC;AAC/C,SAAK,cAAc;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,kBACL,YACA,SACA,SACkB;AAClB,QAAI,CAAC,KAAK,aAAa;AACtB,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACpE;AACA,UAAM,YAAyB,CAAC;AAChC,eAAW,SAAS,YAAY;AAC/B,YAAM,SAAS,MAAM,KAAK,YAAY,WAAW,KAAK;AACtD,gBAAU,KAAK,GAAG,OAAO,MAAM;AAAA,IAChC;AACA,cAAU,KAAK,CAAC,GAAG,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,EAAE,GAAG;AACvE,WAAO,QAAQ,SAAS,SAAS;AAAA,EAClC;AACD;AAoBO,SAAS,KAAK,MAAc,MAA+B;AACjE,SAAO,IAAI,UAAU,MAAM,IAAI;AAChC;;;ADxZA,IAAM,0BAAN,MAAyD;AAAA,EACxD,YAAqB,OAAc;AAAd;AAAA,EAAe;AAAA,EAEpC,kBAAwB;AACvB,SAAK,MAAM,QAAQ;AAAA,EACpB;AACD;AAEA,IAAM,6BAAN,MAA4D;AAAA,EAClD,QAAQ,IAAI,MAAM,SAAS;AAAA,EAEpC,kBAAwB;AACvB,SAAK,MAAM,QAAQ;AAAA,EACpB;AACD;AArGA;AA4GA,gCAAC,OAAO,CAAC,CAAC;AAEH,IAAM,oBAAN,MAAM,kBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAc7B,OAAO,QAAQ,MAA6C;AAC3D,UAAM,UAAU,QAAQ,CAAC;AACzB,UAAM,YAAY,QAAQ,QAAQ;AAElC,UAAM,YAAwB;AAAA,MAC7B;AAAA,QACC,SAAS;AAAA,QACT,YAAY,MAAM;AACjB,gBAAM,IAAI,IAAI,MAAM,SAAS;AAC7B,cAAI,QAAQ,MAAO,SAAQ,MAAM,CAAC;AAClC,cAAI,QAAQ,SAAU,GAAE,QAAQ,QAAQ,QAAQ;AAChD,iBAAO;AAAA,QACR;AAAA,MACD;AAAA,MACA;AAAA,QACC,SAAS,uBAAO,IAAI,2BAA2B;AAAA,QAC/C,YAAY,CAAC,UAAiB,IAAI,wBAAwB,KAAK;AAAA,QAC/D,QAAQ,CAAC,qBAAqB;AAAA,MAC/B;AAAA,MACA;AAAA,QACC,SAAS;AAAA,QACT,YAAY,CAAC,OAAc,cAC1B,IAAI,wBAAwB,OAAO,SAAS;AAAA,QAC7C,QAAQ,CAAC,uBAAuB,SAAS;AAAA,MAC1C;AAAA,IACD;AAIA,QAAI,QAAQ,OAAO;AAClB,iBAAW,QAAQ,QAAQ,OAAO;AACjC,kBAAU,KAAK;AAAA,UACd,SAAS,aAAa,IAAI;AAAA,UAC1B,YAAY,CAAC,UAAiB,MAAM,QAAQ,IAAI;AAAA,UAChD,QAAQ,CAAC,qBAAqB;AAAA,QAC/B,CAAC;AAAA,MACF;AAAA,IACD;AAGA,QAAI,QAAQ,cAAc;AACzB,gBAAU;AAAA,QACT;AAAA,UACC,SAAS,uBAAO,IAAI,8BAA8B;AAAA,UAClD,YAAY,MAAM,IAAI,2BAA2B;AAAA,UACjD,OAAO,MAAM;AAAA,QACd;AAAA,QACA;AAAA,UACC,SAAS;AAAA,UACT,YAAY,CAAC,cAA0C,UAAU;AAAA,UACjE,QAAQ,CAAC,uBAAO,IAAI,8BAA8B,CAAC;AAAA,UACnD,OAAO,MAAM;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,SAAS;AAAA,QACR;AAAA,QACA,IAAI,QAAQ,SAAS,CAAC,GAAG,IAAI,YAAY;AAAA,QACzC,GAAI,QAAQ,eAAe,CAAC,wBAAwB,IAAI,CAAC;AAAA,MAC1D;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAO,WAAW,MAA+C;AAChE,UAAM,YAAwB;AAAA,MAC7B;AAAA,QACC,SAAS,cAAc,KAAK,IAAI;AAAA,QAChC,YAAY,CAAC,cAAqB;AACjC,gBAAM,IAAI,IAAI,MAAM,KAAK,IAAI;AAC7B,cAAI,KAAK,MAAO,MAAK,MAAM,CAAC;AAC5B,cAAI,KAAK,SAAU,GAAE,QAAQ,KAAK,QAAQ;AAC1C,oBAAU,MAAM,KAAK,MAAM,CAAC;AAC5B,iBAAO;AAAA,QACR;AAAA,QACA,QAAQ,CAAC,qBAAqB;AAAA,MAC/B;AAAA,IACD;AAIA,QAAI,KAAK,OAAO;AACf,iBAAW,QAAQ,KAAK,OAAO;AAC9B,kBAAU,KAAK;AAAA,UACd,SAAS,aAAa,GAAG,KAAK,IAAI,KAAK,IAAI,EAAE;AAAA,UAC7C,YAAY,CAAC,UAAiB,MAAM,QAAQ,IAAI;AAAA,UAChD,QAAQ,CAAC,cAAc,KAAK,IAAI,CAAC;AAAA,QAClC,CAAC;AAAA,MACF;AAAA,IACD;AAEA,WAAO;AAAA,MACN,QAAQ;AAAA,MACR;AAAA,MACA,SAAS;AAAA,QACR,cAAc,KAAK,IAAI;AAAA,QACvB,IAAI,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,aAAa,GAAG,KAAK,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,MACpE;AAAA,IACD;AAAA,EACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,OAAO,QAAQ,MAA4C;AAC1D,UAAM,YAAwB;AAAA,MAC7B;AAAA,QACC,SAAS,cAAc,KAAK,IAAI;AAAA,QAChC,YAAY,CAAC,cAAqB;AACjC,gBAAM,IAAI,KAAK,KAAK,MAAM,KAAK,IAAI;AAGnC,cAAI,KAAK,WAAY,GAAE,cAAc,KAAK,UAAU;AACpD,cAAI,KAAK,MAAO,MAAK,MAAM,CAAC;AAC5B,oBAAU,MAAM,KAAK,MAAM,CAAC;AAC5B,iBAAO;AAAA,QACR;AAAA,QACA,QAAQ,CAAC,qBAAqB;AAAA,MAC/B;AAAA,IACD;AAEA,QAAI,KAAK,OAAO;AACf,iBAAW,QAAQ,KAAK,OAAO;AAC9B,kBAAU,KAAK;AAAA,UACd,SAAS,aAAa,GAAG,KAAK,IAAI,KAAK,IAAI,EAAE;AAAA,UAC7C,YAAY,CAAC,UAAiB,MAAM,QAAQ,IAAI;AAAA,UAChD,QAAQ,CAAC,cAAc,KAAK,IAAI,CAAC;AAAA,QAClC,CAAC;AAAA,MACF;AAAA,IACD;AAEA,WAAO;AAAA,MACN,QAAQ;AAAA,MACR;AAAA,MACA,SAAS;AAAA,QACR,cAAc,KAAK,IAAI;AAAA,QACvB,IAAI,KAAK,SAAS,CAAC,GAAG,IAAI,CAAC,MAAM,aAAa,GAAG,KAAK,IAAI,KAAK,CAAC,EAAE,CAAC;AAAA,MACpE;AAAA,IACD;AAAA,EACD;AACD;AA7LO;AAAM,oBAAN,gDAFP,8BAEa;AAAN,4BAAM;AAAN,IAAM,mBAAN;","names":[]}
|