@dreamboard-games/sdk 0.5.0-alpha.2 → 0.5.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +186 -45
- package/dist/board-target-B0QG6OYx.d.ts +8 -0
- package/dist/chunk-3JXUL4VN.js +139 -0
- package/dist/chunk-3JXUL4VN.js.map +1 -0
- package/dist/{chunk-S2JEDVWH.js → chunk-C77SYIVT.js} +6102 -6505
- package/dist/chunk-C77SYIVT.js.map +1 -0
- package/dist/chunk-DMFVAZI2.js +16 -0
- package/dist/chunk-DMFVAZI2.js.map +1 -0
- package/dist/chunk-OOFMBCFF.js +1338 -0
- package/dist/chunk-OOFMBCFF.js.map +1 -0
- package/dist/chunk-UG2Q4NLG.js +590 -0
- package/dist/chunk-UG2Q4NLG.js.map +1 -0
- package/dist/chunk-XU6WJW6K.js +847 -0
- package/dist/chunk-XU6WJW6K.js.map +1 -0
- package/dist/diagnostics-B8d5aLad.d.ts +65 -0
- package/dist/extract-gVKcB8Og.d.ts +4736 -0
- package/dist/index.d.ts +3782 -1
- package/dist/index.js +1096 -6
- package/dist/index.js.map +1 -1
- package/dist/model-vdpLHrxh.d.ts +432 -0
- package/dist/react.d.ts +60 -0
- package/dist/react.js +208 -0
- package/dist/react.js.map +1 -0
- package/dist/reducer.d.ts +1244 -78
- package/dist/reducer.js +4204 -121
- package/dist/reducer.js.map +1 -1
- package/dist/testing.d.ts +520 -564
- package/dist/testing.js +2451 -915
- package/dist/testing.js.map +1 -1
- package/dist/types-Bj5ZLTUV.d.ts +114 -0
- package/package.json +40 -142
- package/dist/HandView-Bi2lxzQP.d.ts +0 -79
- package/dist/ResourceCounter-BFxJknqp.d.ts +0 -98
- package/dist/ThemeProvider-CElaL2ik.d.ts +0 -99
- package/dist/attributes-DbvyMbXw.d.ts +0 -68
- package/dist/browser-interaction.d.ts +0 -910
- package/dist/browser-interaction.js +0 -119
- package/dist/browser-interaction.js.map +0 -1
- package/dist/chunk-32PFKDV7.js +0 -11705
- package/dist/chunk-32PFKDV7.js.map +0 -1
- package/dist/chunk-3BAD4VC2.js +0 -263
- package/dist/chunk-3BAD4VC2.js.map +0 -1
- package/dist/chunk-3SKDNDPG.js +0 -104
- package/dist/chunk-3SKDNDPG.js.map +0 -1
- package/dist/chunk-5YV2WHJ4.js +0 -25
- package/dist/chunk-5YV2WHJ4.js.map +0 -1
- package/dist/chunk-ANRB4XKA.js +0 -90
- package/dist/chunk-ANRB4XKA.js.map +0 -1
- package/dist/chunk-BI4G3PM2.js +0 -1864
- package/dist/chunk-BI4G3PM2.js.map +0 -1
- package/dist/chunk-EVCLTY4Q.js +0 -935
- package/dist/chunk-EVCLTY4Q.js.map +0 -1
- package/dist/chunk-GDPKTBUR.js +0 -564
- package/dist/chunk-GDPKTBUR.js.map +0 -1
- package/dist/chunk-H6VDGFL5.js +0 -2903
- package/dist/chunk-H6VDGFL5.js.map +0 -1
- package/dist/chunk-LR3ZTWQF.js +0 -5960
- package/dist/chunk-LR3ZTWQF.js.map +0 -1
- package/dist/chunk-PF7L4BMG.js +0 -117
- package/dist/chunk-PF7L4BMG.js.map +0 -1
- package/dist/chunk-PN5O6GG2.js +0 -32
- package/dist/chunk-PN5O6GG2.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -10
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-S2JEDVWH.js.map +0 -1
- package/dist/chunk-T3ZKNUZ7.js +0 -1
- package/dist/chunk-T3ZKNUZ7.js.map +0 -1
- package/dist/chunk-UGH54WZ2.js +0 -223
- package/dist/chunk-UGH54WZ2.js.map +0 -1
- package/dist/chunk-VCDWP5VL.js +0 -746
- package/dist/chunk-VCDWP5VL.js.map +0 -1
- package/dist/chunk-VDXOF4FW.js +0 -69
- package/dist/chunk-VDXOF4FW.js.map +0 -1
- package/dist/chunk-WHR5UW3F.js +0 -1988
- package/dist/chunk-WHR5UW3F.js.map +0 -1
- package/dist/chunk-Y75CFE77.js +0 -17
- package/dist/chunk-Y75CFE77.js.map +0 -1
- package/dist/chunk-Z7QCREWI.js +0 -3435
- package/dist/chunk-Z7QCREWI.js.map +0 -1
- package/dist/chunk-ZZGN2ATS.js +0 -1941
- package/dist/chunk-ZZGN2ATS.js.map +0 -1
- package/dist/components-gAbIz7hK.d.ts +0 -1284
- package/dist/definitions-BgmV_GhC.d.ts +0 -300
- package/dist/diagnostics-DIi3ina7.d.ts +0 -50
- package/dist/digest.d.ts +0 -8
- package/dist/game-CsZScpcn.d.ts +0 -763
- package/dist/hex-board-view-aKkblDp6.d.ts +0 -1228
- package/dist/index-CcT9Q7N7.d.ts +0 -193
- package/dist/index.d-DjzoK7zn.d.ts +0 -2101
- package/dist/package-set.d.ts +0 -13
- package/dist/package-set.js +0 -12
- package/dist/package-set.js.map +0 -1
- package/dist/player-state-Cqpyeql0.d.ts +0 -371
- package/dist/plugin-runtime-contract.d.ts +0 -17
- package/dist/plugin-runtime-contract.js +0 -92
- package/dist/plugin-runtime-contract.js.map +0 -1
- package/dist/primitive-props-BNHDkgd7.d.ts +0 -16
- package/dist/protocol-dYgafTYY.d.ts +0 -314
- package/dist/reducer/advanced.d.ts +0 -82
- package/dist/reducer/advanced.js +0 -51
- package/dist/reducer/advanced.js.map +0 -1
- package/dist/reducer-contract.d.ts +0 -11
- package/dist/reducer-contract.js +0 -16
- package/dist/reducer-contract.js.map +0 -1
- package/dist/reference-games/index.d.ts +0 -31
- package/dist/reference-games/index.js +0 -48
- package/dist/reference-games/index.js.map +0 -1
- package/dist/runtime/primitives.d.ts +0 -250
- package/dist/runtime/primitives.js +0 -189
- package/dist/runtime/primitives.js.map +0 -1
- package/dist/runtime/runtime-api.d.ts +0 -2
- package/dist/runtime/runtime-api.js +0 -1
- package/dist/runtime/runtime-api.js.map +0 -1
- package/dist/runtime/workspace-contract.d.ts +0 -392
- package/dist/runtime/workspace-contract.js +0 -28
- package/dist/runtime/workspace-contract.js.map +0 -1
- package/dist/runtime-RJ5orDJU.d.ts +0 -1699
- package/dist/runtime-api-Bz5pwNU_.d.ts +0 -296
- package/dist/runtime-json-CQ9QbLZ5.d.ts +0 -5
- package/dist/runtime.d.ts +0 -83
- package/dist/runtime.js +0 -242
- package/dist/runtime.js.map +0 -1
- package/dist/schema.d.ts +0 -379
- package/dist/stale-contract-artifact-error-XLaweZtF.d.ts +0 -18
- package/dist/testing-compiler.d.ts +0 -37
- package/dist/testing-compiler.js +0 -272
- package/dist/testing-compiler.js.map +0 -1
- package/dist/testing-runtime.d.ts +0 -119
- package/dist/testing-runtime.js +0 -212
- package/dist/testing-runtime.js.map +0 -1
- package/dist/types-DJj5MJkl.d.ts +0 -256
- package/dist/types-DR7DoB1x.d.ts +0 -28
- package/dist/types-JWCYHmu7.d.ts +0 -122
- package/dist/types.d.ts +0 -1958
- package/dist/types.js +0 -14
- package/dist/types.js.map +0 -1
- package/dist/ui/components.d.ts +0 -17
- package/dist/ui/components.js +0 -216
- package/dist/ui/components.js.map +0 -1
- package/dist/ui/defaults.d.ts +0 -19
- package/dist/ui/defaults.js +0 -104
- package/dist/ui/defaults.js.map +0 -1
- package/dist/ui/player-state.d.ts +0 -2
- package/dist/ui/player-state.js +0 -1
- package/dist/ui/player-state.js.map +0 -1
- package/dist/ui/plugin-styles.css +0 -2
- package/dist/ui-contract-GTUPkf8z.d.ts +0 -1168
- package/dist/ui.d.ts +0 -317
- package/dist/ui.js +0 -277
- package/dist/ui.js.map +0 -1
- package/dist/views-BpuWcOyN.d.ts +0 -1641
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/package-set.ts","../src/headless/sources/iframe.ts","../src/shared/protocol/gameplay-wire.ts","../src/headless/sources/host-websocket.ts","../src/headless/features/hand.ts","../src/headless/features/board.ts","../src/headless/features/drag.ts","../src/headless/features/pointer-session.ts","../src/headless/features/pan-zoom.ts"],"sourcesContent":["declare const __DREAMBOARD_SDK_VERSION__: string;\n\nexport const DREAMBOARD_SDK_VERSION =\n typeof __DREAMBOARD_SDK_VERSION__ === \"string\"\n ? __DREAMBOARD_SDK_VERSION__\n : \"0.0.0-development\";\n\nexport const DREAMBOARD_SDK_PACKAGES = {\n \"@dreamboard-games/sdk\": DREAMBOARD_SDK_VERSION,\n} as const;\n\nexport type DreamboardSdkPackageName = keyof typeof DREAMBOARD_SDK_PACKAGES;\n\nexport type DreamboardSdkPackageSet = {\n version: 1;\n sdkVersion: string;\n packages: Record<DreamboardSdkPackageName, string>;\n};\n\nexport const DREAMBOARD_SDK_PACKAGE_SET: DreamboardSdkPackageSet = {\n version: 1,\n sdkVersion: DREAMBOARD_SDK_VERSION,\n packages: DREAMBOARD_SDK_PACKAGES,\n};\n","import {\n DREAMBOARD_PLUGIN_PROTOCOL,\n DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n} from \"../../shared/protocol/protocol.js\";\nimport { HostToPluginEnvelopeSchema } from \"../../shared/protocol/schema.js\";\nimport type { PluginToHostPayload } from \"../../shared/protocol/protocol.js\";\nimport { createSourceLifecycle } from \"./lifecycle.js\";\nimport type { CommandSource } from \"./types.js\";\n\n/** Pins its parent window, origin and channel at the first valid initialization. */\nexport function iframeSource(\n options: {\n timeoutMs?: number;\n } = {},\n): CommandSource {\n const target = window;\n const parent = target.parent;\n let channel: { id: string; origin: string } | null = null;\n let sequence = 0;\n let receivedSequence = -1;\n const send = (payload: PluginToHostPayload) => {\n if (!channel) throw new Error(\"Iframe source is not initialized.\");\n parent.postMessage(\n {\n protocol: DREAMBOARD_PLUGIN_PROTOCOL,\n version: DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n channelId: channel.id,\n sequence: ++sequence,\n payload,\n },\n channel.origin,\n );\n };\n const lifecycle = createSourceLifecycle({\n timeoutMs: options.timeoutMs,\n send,\n recover: () => send({ type: \"runtime.resume\" }),\n close: () => target.removeEventListener(\"message\", receive),\n });\n const isOpen = () => {\n const { connection } = lifecycle.source.store.get();\n return connection !== \"closed\" && connection !== \"failed\";\n };\n function receive(event: MessageEvent) {\n if (event.source !== parent) return;\n const parsed = HostToPluginEnvelopeSchema.safeParse(event.data);\n if (!parsed.success) {\n const data: unknown = event.data;\n if (\n channel &&\n event.origin === channel.origin &&\n typeof data === \"object\" &&\n data !== null &&\n \"channelId\" in data &&\n data.channelId === channel.id\n ) {\n try {\n send({\n type: \"runtime.error\",\n code: \"host-runtime-protocol-mismatch\",\n message: \"Iframe source received an invalid host envelope.\",\n });\n } finally {\n lifecycle.fail(new Error(\"Invalid iframe host envelope.\"));\n }\n }\n return;\n }\n const envelope = parsed.data;\n if (!channel) {\n if (envelope.payload.type !== \"runtime.init\") return;\n channel = { id: envelope.channelId, origin: event.origin };\n }\n if (\n channel.id !== envelope.channelId ||\n channel.origin !== event.origin ||\n envelope.sequence <= receivedSequence\n )\n return;\n receivedSequence = envelope.sequence;\n const payload = envelope.payload;\n if (payload.type === \"runtime.init\") {\n lifecycle.session(payload.session);\n if (isOpen()) send({ type: \"runtime.ready\" });\n } else if (payload.type === \"gameplay.frame\")\n lifecycle.frame(payload.frame);\n else lifecycle.result(payload);\n if (isOpen()) send({ type: \"runtime.ack\", sequence: envelope.sequence });\n }\n target.addEventListener(\"message\", receive);\n return lifecycle.source;\n}\n","import { z } from \"zod\";\nimport {\n InteractionResultSchema,\n PluginGameplayFrameSchema,\n SubmitInteractionCommandSchema,\n CancelInteractionCommandSchema,\n} from \"./schema.js\";\nexport const GameplayCloseCode = {\n GoingAway: 1001,\n CredentialExpired: 4000,\n CredentialInvalid: 4001,\n RefreshContextMismatch: 4002,\n PermissionDenied: 4100,\n ProtocolViolation: 4200,\n FrameBeforeAuth: 4201,\n SlowConsumer: 4300,\n TooManyRequests: 4301,\n} as const;\n\nexport const GameplayCredentialSchema = z.discriminatedUnion(\"kind\", [\n z\n .object({ kind: z.literal(\"user\"), token: z.string().min(1).max(16384) })\n .strict(),\n z\n .object({ kind: z.literal(\"demo\"), secret: z.string().min(1).max(1024) })\n .strict(),\n]);\nexport const AuthConnectFrameSchema = z\n .object({\n type: z.literal(\"auth.connect\"),\n credential: GameplayCredentialSchema,\n sessionId: z.string().uuid(),\n playerId: z.string().min(1).max(128),\n })\n .strict();\nexport const AuthRefreshFrameSchema = z\n .object({\n type: z.literal(\"auth.refresh\"),\n credential: GameplayCredentialSchema,\n })\n .strict();\n\nexport const SessionResumeFrameSchema = z.object({\n type: z.literal(\"session.resume\"),\n lastSeenLogCursor: z.number().int().nonnegative().nullable(),\n unacknowledgedClientActionIds: z.array(z.string().min(1)).max(32),\n});\n\nexport const AuthAcceptedFrameSchema = z.object({\n type: z.literal(\"auth.accepted\"),\n expiresAt: z.string().datetime(),\n});\n\nexport const GameplayBackpressureReasonSchema = z.enum([\n \"queue_full\",\n \"capacity_full\",\n]);\n\nexport const GameplayBackpressureOperationSchema = z.enum([\n \"session.resume\",\n \"interaction.submit\",\n \"interaction.cancel\",\n]);\nexport const GameplayBackpressureFrameSchema = z.object({\n type: z.literal(\"gameplay.backpressure\"),\n reason: GameplayBackpressureReasonSchema,\n retryAfterMs: z.number().int().positive(),\n message: z.string().min(1),\n operation: GameplayBackpressureOperationSchema,\n clientActionId: z.string().min(1).optional(),\n});\nexport const SessionSnapshotFrameSchema = z.object({\n type: z.literal(\"session.snapshot\"),\n frame: PluginGameplayFrameSchema,\n});\nexport const ClientGameplayFrameSchema = z.discriminatedUnion(\"type\", [\n AuthConnectFrameSchema,\n AuthRefreshFrameSchema,\n SessionResumeFrameSchema,\n SubmitInteractionCommandSchema,\n CancelInteractionCommandSchema,\n]);\nexport const ServerGameplayFrameSchema = z.discriminatedUnion(\"type\", [\n AuthAcceptedFrameSchema,\n GameplayBackpressureFrameSchema,\n SessionSnapshotFrameSchema,\n InteractionResultSchema,\n]);\nexport type GameplayCredential = z.infer<typeof GameplayCredentialSchema>;\nexport type ClientGameplayFrame = z.infer<typeof ClientGameplayFrameSchema>;\nexport type ServerGameplayFrame = z.infer<typeof ServerGameplayFrameSchema>;\n","import type { PluginSessionDescriptor } from \"../../shared/protocol/frame.js\";\nimport {\n ClientGameplayFrameSchema,\n ServerGameplayFrameSchema,\n GameplayCloseCode,\n type ClientGameplayFrame,\n type GameplayCredential,\n} from \"../../shared/protocol/gameplay-wire.js\";\nimport { createSourceLifecycle } from \"./lifecycle.js\";\nimport type { CommandSource, SourceCommand } from \"./types.js\";\n\nexport function hostSource(options: {\n url: string;\n session: PluginSessionDescriptor;\n playerId: string;\n getCredential(): Promise<GameplayCredential>;\n timeoutMs?: number;\n}): CommandSource {\n const { url, playerId, getCredential } = options;\n const sessionId = options.session.sessionId;\n let socket: WebSocket | null = null;\n let generation = 0;\n let disposed = false;\n let authenticated = false;\n let queued: SourceCommand | null = null;\n let reconnects = 0;\n let refreshTimer: ReturnType<typeof setTimeout> | undefined;\n let snapshotTimer: ReturnType<typeof setTimeout> | undefined;\n let openTimer: ReturnType<typeof setTimeout> | undefined;\n let cleanup = () => {};\n const timeoutMs = options.timeoutMs ?? 10_000;\n const send = (frame: ClientGameplayFrame) => {\n if (!socket || socket.readyState !== WebSocket.OPEN)\n throw new Error(\"Gameplay socket is not open.\");\n socket.send(JSON.stringify(ClientGameplayFrameSchema.parse(frame)));\n };\n const resume = () =>\n send({\n type: \"session.resume\",\n lastSeenLogCursor: null,\n unacknowledgedClientActionIds: queued ? [queued.clientActionId] : [],\n });\n const lifecycle = createSourceLifecycle({\n context: {\n sessionId,\n playerId,\n },\n timeoutMs,\n send(command) {\n if (!authenticated) {\n queued = command;\n return;\n }\n send(command);\n },\n recover() {\n if (authenticated) resume();\n else if (!openTimer) void connect();\n },\n close() {\n disposed = true;\n generation++;\n clearTimeout(refreshTimer);\n clearTimeout(openTimer);\n clearTimeout(snapshotTimer);\n cleanup();\n socket?.close();\n socket = null;\n queued = null;\n },\n });\n lifecycle.session(options.session);\n async function connect() {\n if (disposed) return;\n const current = ++generation;\n authenticated = false;\n clearTimeout(refreshTimer);\n clearTimeout(openTimer);\n clearTimeout(snapshotTimer);\n cleanup();\n socket?.close();\n socket = null;\n openTimer = setTimeout(\n () =>\n lifecycle.fail(new Error(\"Gameplay socket authentication timed out.\")),\n timeoutMs,\n );\n try {\n const credential = await getCredential();\n if (disposed || current !== generation) return;\n const next = new WebSocket(url);\n socket = next;\n const active = () => !disposed && current === generation;\n const onOpen = () => {\n if (!active()) return;\n try {\n send({\n type: \"auth.connect\",\n credential,\n sessionId,\n playerId,\n });\n } catch (error) {\n lifecycle.fail(asError(error));\n }\n };\n const onMessage = (event: MessageEvent) => {\n if (!active()) return;\n try {\n const value: unknown = JSON.parse(String(event.data));\n if (typeof value !== \"object\" || value === null || !(\"type\" in value))\n throw new Error(\"Invalid gameplay frame.\");\n if (\n ![\n \"auth.accepted\",\n \"session.snapshot\",\n \"interaction.result\",\n \"gameplay.backpressure\",\n ].includes(String(value.type))\n )\n return;\n const frame = ServerGameplayFrameSchema.parse(value);\n if (frame.type === \"auth.accepted\") {\n clearTimeout(openTimer);\n openTimer = undefined;\n const first = !authenticated;\n authenticated = true;\n if (first) {\n snapshotTimer = setTimeout(\n () => lifecycle.fail(new Error(\"Gameplay snapshot timed out.\")),\n timeoutMs,\n );\n resume();\n if (queued) {\n send(queued);\n queued = null;\n }\n }\n clearTimeout(refreshTimer);\n if (credential.kind === \"user\") {\n const ttl = Date.parse(frame.expiresAt) - Date.now();\n if (ttl <= 0)\n throw new Error(\"Gameplay credential is already expired.\");\n refreshTimer = setTimeout(\n () => {\n openTimer = setTimeout(\n () =>\n lifecycle.fail(\n new Error(\"Gameplay credential refresh timed out.\"),\n ),\n timeoutMs,\n );\n void getCredential()\n .then((updated) => {\n if (active())\n send({ type: \"auth.refresh\", credential: updated });\n })\n .catch((error) => {\n if (active()) lifecycle.fail(asError(error));\n });\n },\n Math.max(0, ttl - Math.min(60_000, ttl * 0.2)),\n );\n }\n } else if (!authenticated)\n throw new Error(\"Gameplay frame arrived before authentication.\");\n else if (frame.type === \"session.snapshot\") {\n clearTimeout(snapshotTimer);\n snapshotTimer = undefined;\n reconnects = 0;\n lifecycle.frame(frame.frame);\n } else if (frame.type === \"interaction.result\")\n lifecycle.result(frame);\n else lifecycle.fail(new Error(frame.message));\n } catch (error) {\n lifecycle.fail(asError(error));\n }\n };\n const onClose = (event: CloseEvent) => {\n if (!active()) return;\n authenticated = false;\n lifecycle.recovering();\n if (\n new Set<number>([\n GameplayCloseCode.CredentialInvalid,\n GameplayCloseCode.RefreshContextMismatch,\n GameplayCloseCode.PermissionDenied,\n GameplayCloseCode.ProtocolViolation,\n GameplayCloseCode.FrameBeforeAuth,\n ]).has(event.code) ||\n reconnects++ > 0\n ) {\n lifecycle.fail(new Error(`Gameplay socket closed (${event.code}).`));\n return;\n }\n void connect();\n lifecycle.retry();\n };\n const onError = () => {\n if (active()) next.close();\n };\n next.addEventListener(\"open\", onOpen);\n next.addEventListener(\"message\", onMessage);\n next.addEventListener(\"close\", onClose);\n next.addEventListener(\"error\", onError);\n cleanup = () => {\n next.removeEventListener(\"open\", onOpen);\n next.removeEventListener(\"message\", onMessage);\n next.removeEventListener(\"close\", onClose);\n next.removeEventListener(\"error\", onError);\n };\n } catch (error) {\n if (!disposed && current === generation) lifecycle.fail(asError(error));\n }\n }\n void connect();\n return lifecycle.source;\n}\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n","import type { Card, CoreInstance, IdOf, Zone } from \"../model.js\";\n\nexport interface HandOptions<G> {\n /** Compare projected card data only; hidden cards never expose private fields. */\n readonly sort?: (\n left: Card<G, Record<never, never>>,\n right: Card<G, Record<never, never>>,\n ) => number;\n}\n\n/** Optional hand helpers reuse the zone order and the core selection router. */\nexport function handFeature<G>(\n _game: CoreInstance<G>,\n options: HandOptions<G> = {},\n) {\n return {\n zone: {\n getSortedCardIds(\n this: Zone<G, Record<never, never>>,\n ): readonly IdOf<G, \"cardId\">[] {\n return this.getCards({ sort: options.sort }).map((card) => card.id);\n },\n getSelectedCardIds(\n this: Zone<G, Record<never, never>>,\n ): readonly IdOf<G, \"cardId\">[] {\n return this.getCards()\n .filter((card) => card.getIsSelected())\n .map((card) => card.id);\n },\n getSelectableCardIds(\n this: Zone<G, Record<never, never>>,\n ): readonly IdOf<G, \"cardId\">[] {\n return this.getCards()\n .filter((card) => card.getCanSelect())\n .map((card) => card.id);\n },\n },\n };\n}\n","import type {\n BoardDataOf,\n BoardSpaceId,\n BoardSpaceCollection,\n TargetOptions,\n} from \"../model.js\";\nimport { requireLookup } from \"../../shared/lookup.js\";\nimport { AmbiguousTargetError } from \"../instance.js\";\nimport { createHexBoardGeometry } from \"../../shared/hex-board.js\";\nimport type {\n RuntimeBoardCollections,\n RuntimeBoardState,\n RuntimeSquareBoardState,\n} from \"../../reducer/model/table.js\";\nimport type {\n BoardBase,\n BoardCollection,\n CoreInstance,\n FeatureContext,\n IdOf,\n ReadModel,\n} from \"../model.js\";\nimport type { Point } from \"./pointer-session.js\";\nimport type { ViewportTransform } from \"./pan-zoom.js\";\n\ntype TargetKind = \"space\" | \"edge\" | \"vertex\";\nexport interface BoardLayoutOptions {\n /** Hex radius, or square cell width and height. */\n readonly hexSize: number;\n readonly origin?: Point;\n readonly viewport?: ViewportTransform;\n}\ninterface Geometry {\n readonly viewBox: { x: number; y: number; width: number; height: number };\n readonly spaces: readonly {\n id: string;\n center: Point;\n corners: readonly Point[];\n }[];\n readonly edges: readonly { id: string; from: Point; to: Point }[];\n readonly vertices: readonly { id: string; center: Point }[];\n pointToSpace(point: Point): string | undefined;\n}\n\nfunction squareGeometry(\n board: RuntimeSquareBoardState,\n size: number,\n origin: Point,\n): Geometry {\n const spaces = Object.values(board.spaces).map((space) => {\n const x = origin.x + space.col * size;\n const y = origin.y + space.row * size;\n return {\n id: space.id,\n center: { x: x + size / 2, y: y + size / 2 },\n corners: [\n { x, y },\n { x: x + size, y },\n { x: x + size, y: y + size },\n { x, y: y + size },\n ],\n };\n });\n const byId = new Map(spaces.map((space) => [space.id, space]));\n function sharedCorners(ids: readonly string[]) {\n const first = byId.get(ids[0] ?? \"\")?.corners ?? [];\n return first.filter((point) =>\n ids.every((id) =>\n byId\n .get(id)\n ?.corners.some(\n (candidate) => candidate.x === point.x && candidate.y === point.y,\n ),\n ),\n );\n }\n const points = spaces.flatMap((space) => space.corners);\n const xs = points.map((point) => point.x);\n const ys = points.map((point) => point.y);\n const x = xs.length ? Math.min(...xs) : 0;\n const y = ys.length ? Math.min(...ys) : 0;\n return {\n viewBox: {\n x,\n y,\n width: xs.length ? Math.max(...xs) - x : 0,\n height: ys.length ? Math.max(...ys) - y : 0,\n },\n spaces,\n // Incidence is authored. Only a unique geometric line/point is representable.\n edges: board.edges.flatMap((edge) => {\n const corners = sharedCorners(edge.spaceIds);\n return corners.length === 2\n ? [{ id: edge.id, from: corners[0]!, to: corners[1]! }]\n : [];\n }),\n vertices: board.vertices.flatMap((vertex) => {\n const corners = sharedCorners(vertex.spaceIds);\n return corners.length === 1\n ? [{ id: vertex.id, center: corners[0]! }]\n : [];\n }),\n pointToSpace(point) {\n const col = Math.floor((point.x - origin.x) / size);\n const row = Math.floor((point.y - origin.y) / size);\n return Object.values(board.spaces).find(\n (space) => space.col === col && space.row === row,\n )?.id;\n },\n };\n}\n\n/** Semantic board spaces and captured selection, with optional spatial geometry. */\nexport function boardFeature<G>(\n game: CoreInstance<G>,\n context: FeatureContext<G>,\n) {\n const captures = new WeakMap<\n object,\n {\n model: ReadModel<G>;\n source: ReturnType<typeof game.getOptions>[\"source\"];\n geometry?: ReturnType<typeof createHexBoardGeometry>;\n }\n >();\n const geometries = new WeakMap<\n object,\n ReturnType<typeof createHexBoardGeometry>\n >();\n let cached:\n | {\n view: unknown;\n interactions: ReadModel<G>[\"interactions\"];\n source: ReturnType<typeof game.getOptions>[\"source\"];\n collection: BoardCollection<G>;\n }\n | undefined;\n function collection(): BoardCollection<G> {\n const model = game.getSnapshot();\n const source = game.getOptions().source;\n if (\n cached?.view === model.view &&\n cached.interactions === model.interactions &&\n cached.source === source\n )\n return cached.collection;\n // The canonical materializer joins manifest.staticBoards at view.boards.\n // Do not infer topology from arbitrary authored overlay fields.\n const projected = model.view as {\n boards?: Pick<RuntimeBoardCollections, \"byId\" | \"hex\" | \"square\">;\n } | null;\n const boards = Object.values(projected?.boards?.byId ?? {}).map((data) => {\n const board = context.createBoard(\n data.id as IdOf<G, \"boardId\">,\n data as BoardDataOf<G, IdOf<G, \"boardId\">>,\n );\n let geometry = geometries.get(data);\n if (!geometry && data.layout === \"hex\") {\n geometry = createHexBoardGeometry({\n id: data.baseId ?? data.id,\n orientation: data.orientation,\n spaces: Object.values(data.spaces),\n });\n geometries.set(data, geometry);\n }\n captures.set(board, { model, source, geometry });\n return board;\n });\n const byId = new Map(boards.map((board) => [board.id, board]));\n const result: BoardCollection<G> = Object.freeze({\n get<K extends IdOf<G, \"boardId\">>(id: K) {\n return requireLookup(byId.get(id), \"Board\", id) as BoardBase<G, K> & {\n readonly game: CoreInstance<G>;\n };\n },\n find<K extends IdOf<G, \"boardId\">>(id: K) {\n return byId.get(id) as\n (BoardBase<G, K> & { readonly game: CoreInstance<G> }) | undefined;\n },\n getAll: () => Object.freeze(boards),\n });\n cached = {\n view: model.view,\n interactions: model.interactions,\n source,\n collection: result,\n };\n return result;\n }\n function targetsFor(owner: BoardBase<G>) {\n const board = owner.data as RuntimeBoardState;\n const captured = captures.get(owner)!;\n function matchingTargets(\n model: ReadModel<G>,\n kind: TargetKind,\n id: string,\n ) {\n const inputKinds = kind === \"space\" ? [\"space\", \"tile\"] : [kind];\n return (model as unknown as ReadModel<unknown>).interactions\n .list()\n .flatMap((interaction) =>\n interaction\n .getInputs()\n .filter((input) => {\n const domain = input.getDomain();\n return (\n domain.type === \"boardTarget\" &&\n inputKinds.includes(String(domain.targetKind)) &&\n (domain.valueKind === \"player-board-space\"\n ? board.scope === \"perPlayer\" &&\n domain.boardId === board.baseId\n : domain.boardId === board.id)\n );\n })\n .map((input) => {\n const domain = input.getDomain();\n return {\n interaction,\n input,\n value:\n domain.type === \"boardTarget\" &&\n domain.valueKind === \"player-board-space\"\n ? Object.freeze({\n boardId: board.baseId!,\n playerId: board.playerId!,\n spaceId: id,\n })\n : id,\n };\n }),\n );\n }\n function target(kind: TargetKind, id: string) {\n const matches = matchingTargets(captured.model, kind, id);\n const eligible = matches.some(({ input, value }) =>\n input.getIsEligible(value),\n );\n const selected = matches.some(({ input, value }) =>\n input.getIsSelected(value),\n );\n const selectable = matches.some(\n ({ input, value }) => !input.getTargetProps(value).disabled,\n );\n function select(options?: TargetOptions<G>) {\n if (\n game.getOptions().source !== captured.source ||\n game.snapshot?.me !== captured.model.snapshot?.me\n )\n return;\n const matching = matchingTargets(game.getSnapshot(), kind, id).filter(\n ({ interaction, input, value }) =>\n (!options?.interaction ||\n options.interaction === interaction.key) &&\n (!options?.input || options.input === input.key) &&\n !input.getTargetProps(value).disabled,\n );\n if (!matching.length) return;\n if (matching.length > 1) throw new AmbiguousTargetError(id);\n const domain = matching[0]!.input.getDomain();\n if (domain.type !== \"boardTarget\") return;\n const value = matching[0]!.value;\n const target =\n domain.valueKind === \"player-board-space\" && typeof value !== \"string\"\n ? { kind: \"space\" as const, valueKind: domain.valueKind, value }\n : {\n kind,\n valueKind: \"board-id\" as const,\n value: id,\n boardId: board.id,\n };\n (context as unknown as FeatureContext<unknown>).routeTarget(target, {\n interaction: matching[0]!.interaction.key,\n input: matching[0]!.input.key,\n });\n }\n return {\n id,\n getIsEligible: () => eligible,\n getIsSelectable: () => selectable,\n getIsSelected: () => selected,\n getSelectHandler: (options?: TargetOptions<G>) => () => select(options),\n getTargetProps(options?: TargetOptions<G>) {\n const candidates = matches.filter(\n ({ interaction, input, value }) =>\n (!options?.interaction ||\n interaction.key === options.interaction) &&\n (!options?.input || options.input === input.key) &&\n !input.getTargetProps(value).disabled,\n );\n const only = candidates.length === 1 ? candidates[0] : undefined;\n return {\n type: \"button\" as const,\n disabled: candidates.length === 0,\n \"data-action\": \"select\",\n \"data-value\":\n only && typeof only.value !== \"string\"\n ? JSON.stringify(only.value)\n : id,\n \"data-board\": board.id,\n \"data-interaction\": options?.interaction ?? only?.interaction.key,\n \"data-input\": only?.input.key,\n \"data-eligible\": eligible,\n \"data-selected\": selected,\n \"data-disabled\": candidates.length === 0,\n onClick: () => select(options),\n };\n },\n };\n }\n return target;\n }\n const spaceCollections = new WeakMap<object, BoardSpaceCollection<G>>();\n function spacesFor(owner: BoardBase<G>): BoardSpaceCollection<G> {\n const cached = spaceCollections.get(owner);\n if (cached) return cached;\n const target = targetsFor(owner);\n const data = owner.data as RuntimeBoardState;\n const values = Object.freeze(\n Object.values(data.spaces).map((space) =>\n Object.freeze({\n ...target(\"space\", space.id),\n data: space,\n board: owner,\n }),\n ),\n );\n const byId = new Map(values.map((space) => [space.id, space]));\n const spaces = Object.freeze({\n get: (id: string) =>\n requireLookup(byId.get(id), `Space on board ${owner.id}`, id),\n find: (id: string) => byId.get(id),\n getAll: () => values,\n }) as unknown as BoardSpaceCollection<G>;\n spaceCollections.set(owner, spaces);\n return spaces;\n }\n return {\n root: {\n get boards() {\n return collection();\n },\n },\n board: {\n get spaces(): BoardSpaceCollection<G> {\n return spacesFor(this as unknown as BoardBase<G>);\n },\n getLayout(this: BoardBase<G>, options: BoardLayoutOptions) {\n const board = this.data as RuntimeBoardState;\n if (board.layout === \"generic\")\n throw new Error(\n `Board '${board.id}' has no spatial geometry; use board.spaces for semantic selection.`,\n );\n const {\n hexSize,\n origin: suppliedOrigin = { x: 0, y: 0 },\n viewport: suppliedViewport = { x: 0, y: 0, scale: 1 },\n } = options;\n const origin = { ...suppliedOrigin };\n const viewport = { ...suppliedViewport };\n if (!Number.isFinite(hexSize) || hexSize <= 0)\n throw new Error(\"hexSize must be positive and finite.\");\n if (\n ![origin.x, origin.y, viewport.x, viewport.y, viewport.scale].every(\n Number.isFinite,\n ) ||\n viewport.scale <= 0\n )\n throw new Error(\n \"Layout transform must be finite with positive scale.\",\n );\n const captured = captures.get(this)!;\n const geometry: Geometry =\n board.layout === \"hex\"\n ? captured.geometry!.getLayout({ hexSize, origin })\n : squareGeometry(board, hexSize, origin);\n const point = (value: Point): Point =>\n Object.freeze({\n x: value.x * viewport.scale + viewport.x,\n y: value.y * viewport.scale + viewport.y,\n });\n const target = targetsFor(this);\n const semanticSpaces = spacesFor(this);\n const spaces = Object.freeze(\n geometry.spaces.map((space) => {\n const corners = Object.freeze(space.corners.map(point));\n const center = point(space.center);\n return Object.freeze({\n ...semanticSpaces.get(\n space.id as BoardSpaceId<G, IdOf<G, \"boardId\">>,\n ),\n center,\n points: () => corners,\n transform: `translate(${center.x} ${center.y})`,\n });\n }),\n );\n const edges = Object.freeze(\n geometry.edges.map((edge) =>\n Object.freeze({\n ...target(\"edge\", edge.id),\n data: board.edges.find((data) => data.id === edge.id),\n center: point({\n x: (edge.from.x + edge.to.x) / 2,\n y: (edge.from.y + edge.to.y) / 2,\n }),\n line: Object.freeze([point(edge.from), point(edge.to)] as const),\n }),\n ),\n );\n const vertices = Object.freeze(\n geometry.vertices.map((vertex) =>\n Object.freeze({\n ...target(\"vertex\", vertex.id),\n data: board.vertices.find((data) => data.id === vertex.id),\n center: point(vertex.center),\n }),\n ),\n );\n return Object.freeze({\n viewBox: Object.freeze({ ...geometry.viewBox }),\n getSpaces: () => spaces,\n getEdges: () => edges,\n getVertices: () => vertices,\n pointToSpace(x: number, y: number) {\n return geometry.pointToSpace({\n x: (x - viewport.x) / viewport.scale,\n y: (y - viewport.y) / viewport.scale,\n });\n },\n });\n },\n },\n };\n}\n","import type { DropTarget, TargetOptions } from \"../targets.js\";\nexport type { DropTarget } from \"../targets.js\";\nimport { inputValueKey } from \"../../shared/input-domain.js\";\nimport type { CoreInstance, FeatureContext, IdOf } from \"../model.js\";\nexport interface DragState<G> {\n readonly cardId: IdOf<G, \"cardId\">;\n readonly target: DropTarget<G> | null;\n}\n\nexport interface DragController<G> {\n readonly active: DragState<G> | null;\n getCanDrag(cardId: IdOf<G, \"cardId\">, options?: TargetOptions<G>): boolean;\n begin(cardId: IdOf<G, \"cardId\">, options?: TargetOptions<G>): boolean;\n getDropTargets(): readonly DropTarget<G>[];\n setDropTarget(target: DropTarget<G> | null): void;\n drop(): void;\n cancel(): void;\n}\n\n/** Semantic card/drop routing. Browser sensors and feedback belong to /react. */\nexport function dragFeature<G>(\n game: CoreInstance<G>,\n context: FeatureContext<G>,\n) {\n let active: DragState<G> | null = null;\n let selection: TargetOptions<G> | undefined;\n let source = game.getOptions().source;\n let seat = game.snapshot?.me;\n let disposed = false;\n let version = game.snapshot?.version;\n let lastInteractions = game.interactions;\n let lastCards = game.cards;\n let branch = snapshot();\n function update(next: DragState<G> | null) {\n if (disposed) return;\n active = next === null ? null : Object.freeze(next);\n branch = snapshot();\n context.invalidate();\n }\n function targets(\n cardId = active?.cardId,\n selected = selection,\n ): readonly DropTarget<G>[] {\n if (!cardId || game.connection !== \"ready\") return [];\n // Runtime projections are validated by the source; public results carry the bound game types.\n const runtime = game as unknown as CoreInstance<unknown>;\n const options = selected as TargetOptions<unknown> | undefined;\n const resolved = (\n runtime.cards.find(cardId)?.getInteractions() ?? []\n ).flatMap((candidate) => {\n if (\n !candidate.getIsAvailable() ||\n (options?.interaction && candidate.key !== options.interaction)\n )\n return [];\n const inputs = candidate.getInputs();\n const cardInputs = inputs.filter(\n (input) =>\n input.getDomain().type === \"cardTarget\" &&\n (!options?.input || input.key === options.input) &&\n input.getIsEligible(cardId),\n );\n return cardInputs.flatMap((cardInput) =>\n inputs.flatMap((input): DropTarget<unknown>[] => {\n const domain = input.getDomain();\n if (domain.type !== \"boardTarget\") return [];\n const route = {\n interactionKey: candidate.key,\n cardInputKey: cardInput.key,\n inputKey: input.key,\n };\n if (domain.valueKind === \"player-board-space\")\n return domain.eligibleTargets\n .filter((value) => !input.getTargetProps(value).disabled)\n .map((value) =>\n Object.freeze({\n kind: \"space\",\n valueKind: domain.valueKind,\n value,\n ...route,\n }),\n );\n return domain.eligibleTargets\n .filter((value) => !input.getTargetProps(value).disabled)\n .map((value) =>\n Object.freeze({\n kind: domain.targetKind,\n valueKind: domain.valueKind,\n value,\n boardId: domain.boardId,\n ...route,\n }),\n );\n }),\n );\n });\n return resolved as unknown as readonly DropTarget<G>[];\n }\n function sameTarget(left: DropTarget<G>, right: DropTarget<G>) {\n return (\n left.kind === right.kind &&\n left.valueKind === right.valueKind &&\n inputValueKey(left.value) === inputValueKey(right.value) &&\n (left.valueKind !== \"board-id\" ||\n (right.valueKind === \"board-id\" && left.boardId === right.boardId)) &&\n left.interactionKey === right.interactionKey &&\n left.cardInputKey === right.cardInputKey &&\n left.inputKey === right.inputKey\n );\n }\n function cancel() {\n if (active) update(null);\n }\n function snapshot(): DragController<G> {\n const captured = active;\n const dropTargets = Object.freeze(targets());\n return Object.freeze<DragController<G>>({\n active: captured,\n getCanDrag: (cardId, options) =>\n !disposed && targets(cardId, options).length > 0,\n begin(cardId, options) {\n if (disposed || !targets(cardId, options).length) return false;\n selection = options;\n update({ cardId, target: null });\n return true;\n },\n getDropTargets: () => dropTargets,\n setDropTarget(target: DropTarget<G> | null) {\n if (!active || disposed) return;\n if (\n target &&\n !targets().some((candidate) => sameTarget(candidate, target))\n ) {\n update({ ...active, target: null });\n return;\n }\n update({ ...active, target });\n },\n drop() {\n const finished = active;\n const eligible =\n finished?.target &&\n targets().some((target) => sameTarget(target, finished.target!));\n cancel();\n if (!disposed && finished?.target && eligible)\n context.routeCardDrop(finished.cardId, finished.target);\n },\n cancel,\n });\n }\n const unsubscribe = game.subscribe(() => {\n const nextSource = game.getOptions().source;\n const nextSeat = game.snapshot?.me;\n const nextVersion = game.snapshot?.version;\n if (\n nextSource !== source ||\n nextSeat !== seat ||\n nextVersion !== version ||\n game.connection !== \"ready\"\n ) {\n source = nextSource;\n seat = nextSeat;\n version = nextVersion;\n cancel();\n }\n });\n return {\n root: {\n get drag() {\n if (\n lastInteractions !== game.interactions ||\n lastCards !== game.cards\n ) {\n lastInteractions = game.interactions;\n lastCards = game.cards;\n branch = snapshot();\n }\n return branch;\n },\n },\n dispose() {\n unsubscribe();\n cancel();\n disposed = true;\n },\n };\n}\n","/** Native pointer surface; importing a feature never requires browser globals. */\nexport interface PointerSurface {\n setPointerCapture(pointerId: number): void;\n hasPointerCapture(pointerId: number): boolean;\n releasePointerCapture(pointerId: number): void;\n}\n\nexport interface PointerInput {\n readonly pointerId: number;\n readonly button: number;\n readonly clientX: number;\n readonly clientY: number;\n readonly currentTarget: PointerSurface;\n preventDefault(): void;\n}\n\nexport interface Point {\n readonly x: number;\n readonly y: number;\n}\n\nexport interface PointerMove {\n readonly origin: Point;\n readonly point: Point;\n readonly delta: Point;\n}\n\n/** One captured gesture. Pointer cancellation and disposal never commit a drop. */\nexport function createPointerSession(callbacks: {\n move(value: PointerMove): void;\n end(value: PointerMove): void;\n cancel(): void;\n}) {\n let disposed = false;\n let active:\n | { id: number; surface: PointerSurface; origin: Point; point: Point }\n | undefined;\n\n function value(): PointerMove {\n const { origin, point } = active!;\n return {\n origin,\n point,\n delta: { x: point.x - origin.x, y: point.y - origin.y },\n };\n }\n\n function release() {\n const previous = active;\n active = undefined;\n if (previous?.surface.hasPointerCapture(previous.id)) {\n previous.surface.releasePointerCapture(previous.id);\n }\n }\n\n function cancel() {\n if (!active) return;\n release();\n callbacks.cancel();\n }\n\n return {\n start(event: PointerInput): boolean {\n if (disposed || active || event.button !== 0) return false;\n event.currentTarget.setPointerCapture(event.pointerId);\n const point = { x: event.clientX, y: event.clientY };\n active = {\n id: event.pointerId,\n surface: event.currentTarget,\n origin: point,\n point,\n };\n event.preventDefault();\n return true;\n },\n move(event: PointerInput) {\n if (event.pointerId !== active?.id) return;\n active.point = { x: event.clientX, y: event.clientY };\n event.preventDefault();\n callbacks.move(value());\n },\n end(event: PointerInput) {\n if (event.pointerId !== active?.id) return;\n active.point = { x: event.clientX, y: event.clientY };\n const result = value();\n release();\n callbacks.end(result);\n },\n cancel(event?: Pick<PointerInput, \"pointerId\">) {\n if (event && event.pointerId !== active?.id) return;\n cancel();\n },\n dispose() {\n disposed = true;\n cancel();\n },\n };\n}\n","import type { CoreInstance, FeatureContext } from \"../model.js\";\nimport {\n createPointerSession,\n type PointerInput,\n type PointerSurface,\n} from \"./pointer-session.js\";\n\nexport interface ViewportTransform {\n readonly x: number;\n readonly y: number;\n readonly scale: number;\n}\nexport interface ViewportSurface extends PointerSurface {\n getBoundingClientRect(): {\n readonly left: number;\n readonly top: number;\n readonly height: number;\n };\n}\nexport interface WheelInput {\n readonly clientX: number;\n readonly clientY: number;\n readonly deltaY: number;\n readonly deltaMode: number;\n readonly currentTarget: ViewportSurface;\n preventDefault(): void;\n}\nexport interface PanZoomOptions {\n readonly initial?: ViewportTransform;\n readonly minScale?: number;\n readonly maxScale?: number;\n}\n\n/** Native pointer panning and wheel zoom around the cursor. No document listeners. */\nexport function panZoomFeature<G>(\n game: CoreInstance<G>,\n context: FeatureContext<G>,\n options: PanZoomOptions = {},\n) {\n const minScale = options.minScale ?? 0.25;\n const maxScale = options.maxScale ?? 4;\n if (\n !Number.isFinite(minScale) ||\n !Number.isFinite(maxScale) ||\n minScale <= 0 ||\n maxScale < minScale\n ) {\n throw new Error(\n \"Viewport scale limits must be positive, finite, and ordered.\",\n );\n }\n const initial = options.initial ?? { x: 0, y: 0, scale: 1 };\n let disposed = false;\n let source = game.getOptions().source;\n let seat = game.snapshot?.me;\n let dragOrigin = initial;\n let transform = admit(initial);\n let branch = snapshot();\n\n function admit(value: ViewportTransform): ViewportTransform {\n if (\n ![value.x, value.y, value.scale].every(Number.isFinite) ||\n value.scale <= 0\n ) {\n throw new Error(\n \"Viewport transform must have finite coordinates and positive scale.\",\n );\n }\n return Object.freeze({\n x: value.x,\n y: value.y,\n scale: Math.min(maxScale, Math.max(minScale, value.scale)),\n });\n }\n function update(value: ViewportTransform) {\n if (disposed) return;\n const next = admit(value);\n if (\n next.x === transform.x &&\n next.y === transform.y &&\n next.scale === transform.scale\n )\n return;\n transform = next;\n branch = snapshot();\n context.invalidate();\n }\n const pointer = createPointerSession({\n move: ({ delta }) =>\n update({\n ...dragOrigin,\n x: dragOrigin.x + delta.x,\n y: dragOrigin.y + delta.y,\n }),\n end: ({ delta }) =>\n update({\n ...dragOrigin,\n x: dragOrigin.x + delta.x,\n y: dragOrigin.y + delta.y,\n }),\n cancel() {},\n });\n function props() {\n return {\n style: { touchAction: \"none\" as const },\n onPointerDown(event: PointerInput) {\n if (pointer.start(event)) dragOrigin = transform;\n },\n onPointerMove: pointer.move,\n onPointerUp: pointer.end,\n onPointerCancel: pointer.cancel,\n onLostPointerCapture: pointer.cancel,\n onWheel(event: WheelInput) {\n if (disposed) return;\n event.preventDefault();\n const rect = event.currentTarget.getBoundingClientRect();\n const unit =\n event.deltaMode === 1 ? 16 : event.deltaMode === 2 ? rect.height : 1;\n const scale = Math.min(\n maxScale,\n Math.max(\n minScale,\n transform.scale * Math.exp(-event.deltaY * unit * 0.002),\n ),\n );\n const x = event.clientX - rect.left;\n const y = event.clientY - rect.top;\n const ratio = scale / transform.scale;\n update({\n x: x - (x - transform.x) * ratio,\n y: y - (y - transform.y) * ratio,\n scale,\n });\n },\n };\n }\n function snapshot() {\n const captured = transform;\n return Object.freeze({\n transform: captured,\n getTransform: () => captured,\n getProps: props,\n setTransform: update,\n reset: () => {\n pointer.cancel();\n update(initial);\n },\n });\n }\n const unsubscribe = game.subscribe(() => {\n const nextSource = game.getOptions().source;\n const nextSeat = game.snapshot?.me;\n if (nextSource !== source || nextSeat !== seat) {\n source = nextSource;\n seat = nextSeat;\n pointer.cancel();\n update(initial);\n }\n });\n return {\n root: {\n get viewport() {\n return branch;\n },\n },\n dispose() {\n disposed = true;\n unsubscribe();\n pointer.dispose();\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEO,IAAM,yBACX,OACI,kBACA;AAEC,IAAM,0BAA0B;AAAA,EACrC,yBAAyB;AAC3B;AAUO,IAAM,6BAAsD;AAAA,EACjE,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,UAAU;AACZ;;;ACbO,SAAS,aACd,UAEI,CAAC,GACU;AACf,QAAM,SAAS;AACf,QAAM,SAAS,OAAO;AACtB,MAAI,UAAiD;AACrD,MAAI,WAAW;AACf,MAAI,mBAAmB;AACvB,QAAM,OAAO,CAAC,YAAiC;AAC7C,QAAI,CAAC,QAAS,OAAM,IAAI,MAAM,mCAAmC;AACjE,WAAO;AAAA,MACL;AAAA,QACE,UAAU;AAAA,QACV,SAAS;AAAA,QACT,WAAW,QAAQ;AAAA,QACnB,UAAU,EAAE;AAAA,QACZ;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,IACV;AAAA,EACF;AACA,QAAM,YAAY,sBAAsB;AAAA,IACtC,WAAW,QAAQ;AAAA,IACnB;AAAA,IACA,SAAS,MAAM,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAAA,IAC9C,OAAO,MAAM,OAAO,oBAAoB,WAAW,OAAO;AAAA,EAC5D,CAAC;AACD,QAAM,SAAS,MAAM;AACnB,UAAM,EAAE,WAAW,IAAI,UAAU,OAAO,MAAM,IAAI;AAClD,WAAO,eAAe,YAAY,eAAe;AAAA,EACnD;AACA,WAAS,QAAQ,OAAqB;AACpC,QAAI,MAAM,WAAW,OAAQ;AAC7B,UAAM,SAAS,2BAA2B,UAAU,MAAM,IAAI;AAC9D,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,OAAgB,MAAM;AAC5B,UACE,WACA,MAAM,WAAW,QAAQ,UACzB,OAAO,SAAS,YAChB,SAAS,QACT,eAAe,QACf,KAAK,cAAc,QAAQ,IAC3B;AACA,YAAI;AACF,eAAK;AAAA,YACH,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,UACX,CAAC;AAAA,QACH,UAAE;AACA,oBAAU,KAAK,IAAI,MAAM,+BAA+B,CAAC;AAAA,QAC3D;AAAA,MACF;AACA;AAAA,IACF;AACA,UAAM,WAAW,OAAO;AACxB,QAAI,CAAC,SAAS;AACZ,UAAI,SAAS,QAAQ,SAAS,eAAgB;AAC9C,gBAAU,EAAE,IAAI,SAAS,WAAW,QAAQ,MAAM,OAAO;AAAA,IAC3D;AACA,QACE,QAAQ,OAAO,SAAS,aACxB,QAAQ,WAAW,MAAM,UACzB,SAAS,YAAY;AAErB;AACF,uBAAmB,SAAS;AAC5B,UAAM,UAAU,SAAS;AACzB,QAAI,QAAQ,SAAS,gBAAgB;AACnC,gBAAU,QAAQ,QAAQ,OAAO;AACjC,UAAI,OAAO,EAAG,MAAK,EAAE,MAAM,gBAAgB,CAAC;AAAA,IAC9C,WAAW,QAAQ,SAAS;AAC1B,gBAAU,MAAM,QAAQ,KAAK;AAAA,QAC1B,WAAU,OAAO,OAAO;AAC7B,QAAI,OAAO,EAAG,MAAK,EAAE,MAAM,eAAe,UAAU,SAAS,SAAS,CAAC;AAAA,EACzE;AACA,SAAO,iBAAiB,WAAW,OAAO;AAC1C,SAAO,UAAU;AACnB;;;AC3FA,SAAS,SAAS;AAOX,IAAM,oBAAoB;AAAA,EAC/B,WAAW;AAAA,EACX,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,wBAAwB;AAAA,EACxB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,iBAAiB;AACnB;AAEO,IAAM,2BAA2B,EAAE,mBAAmB,QAAQ;AAAA,EACnE,EACG,OAAO,EAAE,MAAM,EAAE,QAAQ,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,EAAE,CAAC,EACvE,OAAO;AAAA,EACV,EACG,OAAO,EAAE,MAAM,EAAE,QAAQ,MAAM,GAAG,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC,EACvE,OAAO;AACZ,CAAC;AACM,IAAM,yBAAyB,EACnC,OAAO;AAAA,EACN,MAAM,EAAE,QAAQ,cAAc;AAAA,EAC9B,YAAY;AAAA,EACZ,WAAW,EAAE,OAAO,EAAE,KAAK;AAAA,EAC3B,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AACrC,CAAC,EACA,OAAO;AACH,IAAM,yBAAyB,EACnC,OAAO;AAAA,EACN,MAAM,EAAE,QAAQ,cAAc;AAAA,EAC9B,YAAY;AACd,CAAC,EACA,OAAO;AAEH,IAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,MAAM,EAAE,QAAQ,gBAAgB;AAAA,EAChC,mBAAmB,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS;AAAA,EAC3D,+BAA+B,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE;AAClE,CAAC;AAEM,IAAM,0BAA0B,EAAE,OAAO;AAAA,EAC9C,MAAM,EAAE,QAAQ,eAAe;AAAA,EAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AACjC,CAAC;AAEM,IAAM,mCAAmC,EAAE,KAAK;AAAA,EACrD;AAAA,EACA;AACF,CAAC;AAEM,IAAM,sCAAsC,EAAE,KAAK;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACM,IAAM,kCAAkC,EAAE,OAAO;AAAA,EACtD,MAAM,EAAE,QAAQ,uBAAuB;AAAA,EACvC,QAAQ;AAAA,EACR,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;AAAA,EACxC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,WAAW;AAAA,EACX,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAC7C,CAAC;AACM,IAAM,6BAA6B,EAAE,OAAO;AAAA,EACjD,MAAM,EAAE,QAAQ,kBAAkB;AAAA,EAClC,OAAO;AACT,CAAC;AACM,IAAM,4BAA4B,EAAE,mBAAmB,QAAQ;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACM,IAAM,4BAA4B,EAAE,mBAAmB,QAAQ;AAAA,EACpE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;AC5EM,SAAS,WAAW,SAMT;AAChB,QAAM,EAAE,KAAK,UAAU,cAAc,IAAI;AACzC,QAAM,YAAY,QAAQ,QAAQ;AAClC,MAAI,SAA2B;AAC/B,MAAI,aAAa;AACjB,MAAI,WAAW;AACf,MAAI,gBAAgB;AACpB,MAAI,SAA+B;AACnC,MAAI,aAAa;AACjB,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI,UAAU,MAAM;AAAA,EAAC;AACrB,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,OAAO,CAAC,UAA+B;AAC3C,QAAI,CAAC,UAAU,OAAO,eAAe,UAAU;AAC7C,YAAM,IAAI,MAAM,8BAA8B;AAChD,WAAO,KAAK,KAAK,UAAU,0BAA0B,MAAM,KAAK,CAAC,CAAC;AAAA,EACpE;AACA,QAAM,SAAS,MACb,KAAK;AAAA,IACH,MAAM;AAAA,IACN,mBAAmB;AAAA,IACnB,+BAA+B,SAAS,CAAC,OAAO,cAAc,IAAI,CAAC;AAAA,EACrE,CAAC;AACH,QAAM,YAAY,sBAAsB;AAAA,IACtC,SAAS;AAAA,MACP;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,IACA,KAAK,SAAS;AACZ,UAAI,CAAC,eAAe;AAClB,iBAAS;AACT;AAAA,MACF;AACA,WAAK,OAAO;AAAA,IACd;AAAA,IACA,UAAU;AACR,UAAI,cAAe,QAAO;AAAA,eACjB,CAAC,UAAW,MAAK,QAAQ;AAAA,IACpC;AAAA,IACA,QAAQ;AACN,iBAAW;AACX;AACA,mBAAa,YAAY;AACzB,mBAAa,SAAS;AACtB,mBAAa,aAAa;AAC1B,cAAQ;AACR,cAAQ,MAAM;AACd,eAAS;AACT,eAAS;AAAA,IACX;AAAA,EACF,CAAC;AACD,YAAU,QAAQ,QAAQ,OAAO;AACjC,iBAAe,UAAU;AACvB,QAAI,SAAU;AACd,UAAM,UAAU,EAAE;AAClB,oBAAgB;AAChB,iBAAa,YAAY;AACzB,iBAAa,SAAS;AACtB,iBAAa,aAAa;AAC1B,YAAQ;AACR,YAAQ,MAAM;AACd,aAAS;AACT,gBAAY;AAAA,MACV,MACE,UAAU,KAAK,IAAI,MAAM,2CAA2C,CAAC;AAAA,MACvE;AAAA,IACF;AACA,QAAI;AACF,YAAM,aAAa,MAAM,cAAc;AACvC,UAAI,YAAY,YAAY,WAAY;AACxC,YAAM,OAAO,IAAI,UAAU,GAAG;AAC9B,eAAS;AACT,YAAM,SAAS,MAAM,CAAC,YAAY,YAAY;AAC9C,YAAM,SAAS,MAAM;AACnB,YAAI,CAAC,OAAO,EAAG;AACf,YAAI;AACF,eAAK;AAAA,YACH,MAAM;AAAA,YACN;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH,SAAS,OAAO;AACd,oBAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,QAC/B;AAAA,MACF;AACA,YAAM,YAAY,CAAC,UAAwB;AACzC,YAAI,CAAC,OAAO,EAAG;AACf,YAAI;AACF,gBAAM,QAAiB,KAAK,MAAM,OAAO,MAAM,IAAI,CAAC;AACpD,cAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,UAAU;AAC7D,kBAAM,IAAI,MAAM,yBAAyB;AAC3C,cACE,CAAC;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,EAAE,SAAS,OAAO,MAAM,IAAI,CAAC;AAE7B;AACF,gBAAM,QAAQ,0BAA0B,MAAM,KAAK;AACnD,cAAI,MAAM,SAAS,iBAAiB;AAClC,yBAAa,SAAS;AACtB,wBAAY;AACZ,kBAAM,QAAQ,CAAC;AACf,4BAAgB;AAChB,gBAAI,OAAO;AACT,8BAAgB;AAAA,gBACd,MAAM,UAAU,KAAK,IAAI,MAAM,8BAA8B,CAAC;AAAA,gBAC9D;AAAA,cACF;AACA,qBAAO;AACP,kBAAI,QAAQ;AACV,qBAAK,MAAM;AACX,yBAAS;AAAA,cACX;AAAA,YACF;AACA,yBAAa,YAAY;AACzB,gBAAI,WAAW,SAAS,QAAQ;AAC9B,oBAAM,MAAM,KAAK,MAAM,MAAM,SAAS,IAAI,KAAK,IAAI;AACnD,kBAAI,OAAO;AACT,sBAAM,IAAI,MAAM,yCAAyC;AAC3D,6BAAe;AAAA,gBACb,MAAM;AACJ,8BAAY;AAAA,oBACV,MACE,UAAU;AAAA,sBACR,IAAI,MAAM,wCAAwC;AAAA,oBACpD;AAAA,oBACF;AAAA,kBACF;AACA,uBAAK,cAAc,EAChB,KAAK,CAAC,YAAY;AACjB,wBAAI,OAAO;AACT,2BAAK,EAAE,MAAM,gBAAgB,YAAY,QAAQ,CAAC;AAAA,kBACtD,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,wBAAI,OAAO,EAAG,WAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,kBAC7C,CAAC;AAAA,gBACL;AAAA,gBACA,KAAK,IAAI,GAAG,MAAM,KAAK,IAAI,KAAQ,MAAM,GAAG,CAAC;AAAA,cAC/C;AAAA,YACF;AAAA,UACF,WAAW,CAAC;AACV,kBAAM,IAAI,MAAM,+CAA+C;AAAA,mBACxD,MAAM,SAAS,oBAAoB;AAC1C,yBAAa,aAAa;AAC1B,4BAAgB;AAChB,yBAAa;AACb,sBAAU,MAAM,MAAM,KAAK;AAAA,UAC7B,WAAW,MAAM,SAAS;AACxB,sBAAU,OAAO,KAAK;AAAA,cACnB,WAAU,KAAK,IAAI,MAAM,MAAM,OAAO,CAAC;AAAA,QAC9C,SAAS,OAAO;AACd,oBAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,QAC/B;AAAA,MACF;AACA,YAAM,UAAU,CAAC,UAAsB;AACrC,YAAI,CAAC,OAAO,EAAG;AACf,wBAAgB;AAChB,kBAAU,WAAW;AACrB,aACE,oBAAI,IAAY;AAAA,UACd,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,QACpB,CAAC,GAAE,IAAI,MAAM,IAAI,KACjB,eAAe,GACf;AACA,oBAAU,KAAK,IAAI,MAAM,2BAA2B,MAAM,IAAI,IAAI,CAAC;AACnE;AAAA,QACF;AACA,aAAK,QAAQ;AACb,kBAAU,MAAM;AAAA,MAClB;AACA,YAAM,UAAU,MAAM;AACpB,YAAI,OAAO,EAAG,MAAK,MAAM;AAAA,MAC3B;AACA,WAAK,iBAAiB,QAAQ,MAAM;AACpC,WAAK,iBAAiB,WAAW,SAAS;AAC1C,WAAK,iBAAiB,SAAS,OAAO;AACtC,WAAK,iBAAiB,SAAS,OAAO;AACtC,gBAAU,MAAM;AACd,aAAK,oBAAoB,QAAQ,MAAM;AACvC,aAAK,oBAAoB,WAAW,SAAS;AAC7C,aAAK,oBAAoB,SAAS,OAAO;AACzC,aAAK,oBAAoB,SAAS,OAAO;AAAA,MAC3C;AAAA,IACF,SAAS,OAAO;AACd,UAAI,CAAC,YAAY,YAAY,WAAY,WAAU,KAAK,QAAQ,KAAK,CAAC;AAAA,IACxE;AAAA,EACF;AACA,OAAK,QAAQ;AACb,SAAO,UAAU;AACnB;AACA,SAAS,QAAQ,OAAuB;AACtC,SAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AACjE;;;ACjNO,SAAS,YACd,OACA,UAA0B,CAAC,GAC3B;AACA,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,mBAEgC;AAC9B,eAAO,KAAK,SAAS,EAAE,MAAM,QAAQ,KAAK,CAAC,EAAE,IAAI,CAAC,SAAS,KAAK,EAAE;AAAA,MACpE;AAAA,MACA,qBAEgC;AAC9B,eAAO,KAAK,SAAS,EAClB,OAAO,CAAC,SAAS,KAAK,cAAc,CAAC,EACrC,IAAI,CAAC,SAAS,KAAK,EAAE;AAAA,MAC1B;AAAA,MACA,uBAEgC;AAC9B,eAAO,KAAK,SAAS,EAClB,OAAO,CAAC,SAAS,KAAK,aAAa,CAAC,EACpC,IAAI,CAAC,SAAS,KAAK,EAAE;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF;;;ACMA,SAAS,eACP,OACA,MACA,QACU;AACV,QAAM,SAAS,OAAO,OAAO,MAAM,MAAM,EAAE,IAAI,CAAC,UAAU;AACxD,UAAMA,KAAI,OAAO,IAAI,MAAM,MAAM;AACjC,UAAMC,KAAI,OAAO,IAAI,MAAM,MAAM;AACjC,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV,QAAQ,EAAE,GAAGD,KAAI,OAAO,GAAG,GAAGC,KAAI,OAAO,EAAE;AAAA,MAC3C,SAAS;AAAA,QACP,EAAE,GAAAD,IAAG,GAAAC,GAAE;AAAA,QACP,EAAE,GAAGD,KAAI,MAAM,GAAAC,GAAE;AAAA,QACjB,EAAE,GAAGD,KAAI,MAAM,GAAGC,KAAI,KAAK;AAAA,QAC3B,EAAE,GAAAD,IAAG,GAAGC,KAAI,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,EACF,CAAC;AACD,QAAM,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC7D,WAAS,cAAc,KAAwB;AAC7C,UAAM,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,EAAE,GAAG,WAAW,CAAC;AAClD,WAAO,MAAM;AAAA,MAAO,CAAC,UACnB,IAAI;AAAA,QAAM,CAAC,OACT,KACG,IAAI,EAAE,GACL,QAAQ;AAAA,UACR,CAAC,cAAc,UAAU,MAAM,MAAM,KAAK,UAAU,MAAM,MAAM;AAAA,QAClE;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACA,QAAM,SAAS,OAAO,QAAQ,CAAC,UAAU,MAAM,OAAO;AACtD,QAAM,KAAK,OAAO,IAAI,CAAC,UAAU,MAAM,CAAC;AACxC,QAAM,KAAK,OAAO,IAAI,CAAC,UAAU,MAAM,CAAC;AACxC,QAAM,IAAI,GAAG,SAAS,KAAK,IAAI,GAAG,EAAE,IAAI;AACxC,QAAM,IAAI,GAAG,SAAS,KAAK,IAAI,GAAG,EAAE,IAAI;AACxC,SAAO;AAAA,IACL,SAAS;AAAA,MACP;AAAA,MACA;AAAA,MACA,OAAO,GAAG,SAAS,KAAK,IAAI,GAAG,EAAE,IAAI,IAAI;AAAA,MACzC,QAAQ,GAAG,SAAS,KAAK,IAAI,GAAG,EAAE,IAAI,IAAI;AAAA,IAC5C;AAAA,IACA;AAAA;AAAA,IAEA,OAAO,MAAM,MAAM,QAAQ,CAAC,SAAS;AACnC,YAAM,UAAU,cAAc,KAAK,QAAQ;AAC3C,aAAO,QAAQ,WAAW,IACtB,CAAC,EAAE,IAAI,KAAK,IAAI,MAAM,QAAQ,CAAC,GAAI,IAAI,QAAQ,CAAC,EAAG,CAAC,IACpD,CAAC;AAAA,IACP,CAAC;AAAA,IACD,UAAU,MAAM,SAAS,QAAQ,CAAC,WAAW;AAC3C,YAAM,UAAU,cAAc,OAAO,QAAQ;AAC7C,aAAO,QAAQ,WAAW,IACtB,CAAC,EAAE,IAAI,OAAO,IAAI,QAAQ,QAAQ,CAAC,EAAG,CAAC,IACvC,CAAC;AAAA,IACP,CAAC;AAAA,IACD,aAAa,OAAO;AAClB,YAAM,MAAM,KAAK,OAAO,MAAM,IAAI,OAAO,KAAK,IAAI;AAClD,YAAM,MAAM,KAAK,OAAO,MAAM,IAAI,OAAO,KAAK,IAAI;AAClD,aAAO,OAAO,OAAO,MAAM,MAAM,EAAE;AAAA,QACjC,CAAC,UAAU,MAAM,QAAQ,OAAO,MAAM,QAAQ;AAAA,MAChD,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAGO,SAAS,aACd,MACA,SACA;AACA,QAAM,WAAW,oBAAI,QAOnB;AACF,QAAM,aAAa,oBAAI,QAGrB;AACF,MAAI;AAQJ,WAAS,aAAiC;AACxC,UAAM,QAAQ,KAAK,YAAY;AAC/B,UAAM,SAAS,KAAK,WAAW,EAAE;AACjC,QACE,QAAQ,SAAS,MAAM,QACvB,OAAO,iBAAiB,MAAM,gBAC9B,OAAO,WAAW;AAElB,aAAO,OAAO;AAGhB,UAAM,YAAY,MAAM;AAGxB,UAAM,SAAS,OAAO,OAAO,WAAW,QAAQ,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,SAAS;AACxE,YAAM,QAAQ,QAAQ;AAAA,QACpB,KAAK;AAAA,QACL;AAAA,MACF;AACA,UAAI,WAAW,WAAW,IAAI,IAAI;AAClC,UAAI,CAAC,YAAY,KAAK,WAAW,OAAO;AACtC,mBAAW,uBAAuB;AAAA,UAChC,IAAI,KAAK,UAAU,KAAK;AAAA,UACxB,aAAa,KAAK;AAAA,UAClB,QAAQ,OAAO,OAAO,KAAK,MAAM;AAAA,QACnC,CAAC;AACD,mBAAW,IAAI,MAAM,QAAQ;AAAA,MAC/B;AACA,eAAS,IAAI,OAAO,EAAE,OAAO,QAAQ,SAAS,CAAC;AAC/C,aAAO;AAAA,IACT,CAAC;AACD,UAAM,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC7D,UAAM,SAA6B,OAAO,OAAO;AAAA,MAC/C,IAAkC,IAAO;AACvC,eAAO,cAAc,KAAK,IAAI,EAAE,GAAG,SAAS,EAAE;AAAA,MAGhD;AAAA,MACA,KAAmC,IAAO;AACxC,eAAO,KAAK,IAAI,EAAE;AAAA,MAEpB;AAAA,MACA,QAAQ,MAAM,OAAO,OAAO,MAAM;AAAA,IACpC,CAAC;AACD,aAAS;AAAA,MACP,MAAM,MAAM;AAAA,MACZ,cAAc,MAAM;AAAA,MACpB;AAAA,MACA,YAAY;AAAA,IACd;AACA,WAAO;AAAA,EACT;AACA,WAAS,WAAW,OAAqB;AACvC,UAAM,QAAQ,MAAM;AACpB,UAAM,WAAW,SAAS,IAAI,KAAK;AACnC,aAAS,gBACP,OACA,MACA,IACA;AACA,YAAM,aAAa,SAAS,UAAU,CAAC,SAAS,MAAM,IAAI,CAAC,IAAI;AAC/D,aAAQ,MAAwC,aAC7C,KAAK,EACL;AAAA,QAAQ,CAAC,gBACR,YACG,UAAU,EACV,OAAO,CAAC,UAAU;AACjB,gBAAM,SAAS,MAAM,UAAU;AAC/B,iBACE,OAAO,SAAS,iBAChB,WAAW,SAAS,OAAO,OAAO,UAAU,CAAC,MAC5C,OAAO,cAAc,uBAClB,MAAM,UAAU,eAChB,OAAO,YAAY,MAAM,SACzB,OAAO,YAAY,MAAM;AAAA,QAEjC,CAAC,EACA,IAAI,CAAC,UAAU;AACd,gBAAM,SAAS,MAAM,UAAU;AAC/B,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA,OACE,OAAO,SAAS,iBAChB,OAAO,cAAc,uBACjB,OAAO,OAAO;AAAA,cACZ,SAAS,MAAM;AAAA,cACf,UAAU,MAAM;AAAA,cAChB,SAAS;AAAA,YACX,CAAC,IACD;AAAA,UACR;AAAA,QACF,CAAC;AAAA,MACL;AAAA,IACJ;AACA,aAAS,OAAO,MAAkB,IAAY;AAC5C,YAAM,UAAU,gBAAgB,SAAS,OAAO,MAAM,EAAE;AACxD,YAAM,WAAW,QAAQ;AAAA,QAAK,CAAC,EAAE,OAAO,MAAM,MAC5C,MAAM,cAAc,KAAK;AAAA,MAC3B;AACA,YAAM,WAAW,QAAQ;AAAA,QAAK,CAAC,EAAE,OAAO,MAAM,MAC5C,MAAM,cAAc,KAAK;AAAA,MAC3B;AACA,YAAM,aAAa,QAAQ;AAAA,QACzB,CAAC,EAAE,OAAO,MAAM,MAAM,CAAC,MAAM,eAAe,KAAK,EAAE;AAAA,MACrD;AACA,eAAS,OAAO,SAA4B;AAC1C,YACE,KAAK,WAAW,EAAE,WAAW,SAAS,UACtC,KAAK,UAAU,OAAO,SAAS,MAAM,UAAU;AAE/C;AACF,cAAM,WAAW,gBAAgB,KAAK,YAAY,GAAG,MAAM,EAAE,EAAE;AAAA,UAC7D,CAAC,EAAE,aAAa,OAAO,OAAAC,OAAM,OAC1B,CAAC,SAAS,eACT,QAAQ,gBAAgB,YAAY,SACrC,CAAC,SAAS,SAAS,QAAQ,UAAU,MAAM,QAC5C,CAAC,MAAM,eAAeA,MAAK,EAAE;AAAA,QACjC;AACA,YAAI,CAAC,SAAS,OAAQ;AACtB,YAAI,SAAS,SAAS,EAAG,OAAM,IAAI,qBAAqB,EAAE;AAC1D,cAAM,SAAS,SAAS,CAAC,EAAG,MAAM,UAAU;AAC5C,YAAI,OAAO,SAAS,cAAe;AACnC,cAAM,QAAQ,SAAS,CAAC,EAAG;AAC3B,cAAMC,UACJ,OAAO,cAAc,wBAAwB,OAAO,UAAU,WAC1D,EAAE,MAAM,SAAkB,WAAW,OAAO,WAAW,MAAM,IAC7D;AAAA,UACE;AAAA,UACA,WAAW;AAAA,UACX,OAAO;AAAA,UACP,SAAS,MAAM;AAAA,QACjB;AACN,QAAC,QAA+C,YAAYA,SAAQ;AAAA,UAClE,aAAa,SAAS,CAAC,EAAG,YAAY;AAAA,UACtC,OAAO,SAAS,CAAC,EAAG,MAAM;AAAA,QAC5B,CAAC;AAAA,MACH;AACA,aAAO;AAAA,QACL;AAAA,QACA,eAAe,MAAM;AAAA,QACrB,iBAAiB,MAAM;AAAA,QACvB,eAAe,MAAM;AAAA,QACrB,kBAAkB,CAAC,YAA+B,MAAM,OAAO,OAAO;AAAA,QACtE,eAAe,SAA4B;AACzC,gBAAM,aAAa,QAAQ;AAAA,YACzB,CAAC,EAAE,aAAa,OAAO,MAAM,OAC1B,CAAC,SAAS,eACT,YAAY,QAAQ,QAAQ,iBAC7B,CAAC,SAAS,SAAS,QAAQ,UAAU,MAAM,QAC5C,CAAC,MAAM,eAAe,KAAK,EAAE;AAAA,UACjC;AACA,gBAAM,OAAO,WAAW,WAAW,IAAI,WAAW,CAAC,IAAI;AACvD,iBAAO;AAAA,YACL,MAAM;AAAA,YACN,UAAU,WAAW,WAAW;AAAA,YAChC,eAAe;AAAA,YACf,cACE,QAAQ,OAAO,KAAK,UAAU,WAC1B,KAAK,UAAU,KAAK,KAAK,IACzB;AAAA,YACN,cAAc,MAAM;AAAA,YACpB,oBAAoB,SAAS,eAAe,MAAM,YAAY;AAAA,YAC9D,cAAc,MAAM,MAAM;AAAA,YAC1B,iBAAiB;AAAA,YACjB,iBAAiB;AAAA,YACjB,iBAAiB,WAAW,WAAW;AAAA,YACvC,SAAS,MAAM,OAAO,OAAO;AAAA,UAC/B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACA,QAAM,mBAAmB,oBAAI,QAAyC;AACtE,WAAS,UAAU,OAA8C;AAC/D,UAAMC,UAAS,iBAAiB,IAAI,KAAK;AACzC,QAAIA,QAAQ,QAAOA;AACnB,UAAM,SAAS,WAAW,KAAK;AAC/B,UAAM,OAAO,MAAM;AACnB,UAAM,SAAS,OAAO;AAAA,MACpB,OAAO,OAAO,KAAK,MAAM,EAAE;AAAA,QAAI,CAAC,UAC9B,OAAO,OAAO;AAAA,UACZ,GAAG,OAAO,SAAS,MAAM,EAAE;AAAA,UAC3B,MAAM;AAAA,UACN,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AACA,UAAM,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC7D,UAAM,SAAS,OAAO,OAAO;AAAA,MAC3B,KAAK,CAAC,OACJ,cAAc,KAAK,IAAI,EAAE,GAAG,kBAAkB,MAAM,EAAE,IAAI,EAAE;AAAA,MAC9D,MAAM,CAAC,OAAe,KAAK,IAAI,EAAE;AAAA,MACjC,QAAQ,MAAM;AAAA,IAChB,CAAC;AACD,qBAAiB,IAAI,OAAO,MAAM;AAClC,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,IAAI,SAAS;AACX,eAAO,WAAW;AAAA,MACpB;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,IAAI,SAAkC;AACpC,eAAO,UAAU,IAA+B;AAAA,MAClD;AAAA,MACA,UAA8B,SAA6B;AACzD,cAAM,QAAQ,KAAK;AACnB,YAAI,MAAM,WAAW;AACnB,gBAAM,IAAI;AAAA,YACR,UAAU,MAAM,EAAE;AAAA,UACpB;AACF,cAAM;AAAA,UACJ;AAAA,UACA,QAAQ,iBAAiB,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,UACtC,UAAU,mBAAmB,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,EAAE;AAAA,QACtD,IAAI;AACJ,cAAM,SAAS,EAAE,GAAG,eAAe;AACnC,cAAM,WAAW,EAAE,GAAG,iBAAiB;AACvC,YAAI,CAAC,OAAO,SAAS,OAAO,KAAK,WAAW;AAC1C,gBAAM,IAAI,MAAM,sCAAsC;AACxD,YACE,CAAC,CAAC,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,KAAK,EAAE;AAAA,UAC5D,OAAO;AAAA,QACT,KACA,SAAS,SAAS;AAElB,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AACF,cAAM,WAAW,SAAS,IAAI,IAAI;AAClC,cAAM,WACJ,MAAM,WAAW,QACb,SAAS,SAAU,UAAU,EAAE,SAAS,OAAO,CAAC,IAChD,eAAe,OAAO,SAAS,MAAM;AAC3C,cAAM,QAAQ,CAAC,UACb,OAAO,OAAO;AAAA,UACZ,GAAG,MAAM,IAAI,SAAS,QAAQ,SAAS;AAAA,UACvC,GAAG,MAAM,IAAI,SAAS,QAAQ,SAAS;AAAA,QACzC,CAAC;AACH,cAAM,SAAS,WAAW,IAAI;AAC9B,cAAM,iBAAiB,UAAU,IAAI;AACrC,cAAM,SAAS,OAAO;AAAA,UACpB,SAAS,OAAO,IAAI,CAAC,UAAU;AAC7B,kBAAM,UAAU,OAAO,OAAO,MAAM,QAAQ,IAAI,KAAK,CAAC;AACtD,kBAAM,SAAS,MAAM,MAAM,MAAM;AACjC,mBAAO,OAAO,OAAO;AAAA,cACnB,GAAG,eAAe;AAAA,gBAChB,MAAM;AAAA,cACR;AAAA,cACA;AAAA,cACA,QAAQ,MAAM;AAAA,cACd,WAAW,aAAa,OAAO,CAAC,IAAI,OAAO,CAAC;AAAA,YAC9C,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AACA,cAAM,QAAQ,OAAO;AAAA,UACnB,SAAS,MAAM;AAAA,YAAI,CAAC,SAClB,OAAO,OAAO;AAAA,cACZ,GAAG,OAAO,QAAQ,KAAK,EAAE;AAAA,cACzB,MAAM,MAAM,MAAM,KAAK,CAAC,SAAS,KAAK,OAAO,KAAK,EAAE;AAAA,cACpD,QAAQ,MAAM;AAAA,gBACZ,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG,KAAK;AAAA,gBAC/B,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG,KAAK;AAAA,cACjC,CAAC;AAAA,cACD,MAAM,OAAO,OAAO,CAAC,MAAM,KAAK,IAAI,GAAG,MAAM,KAAK,EAAE,CAAC,CAAU;AAAA,YACjE,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM,WAAW,OAAO;AAAA,UACtB,SAAS,SAAS;AAAA,YAAI,CAAC,WACrB,OAAO,OAAO;AAAA,cACZ,GAAG,OAAO,UAAU,OAAO,EAAE;AAAA,cAC7B,MAAM,MAAM,SAAS,KAAK,CAAC,SAAS,KAAK,OAAO,OAAO,EAAE;AAAA,cACzD,QAAQ,MAAM,OAAO,MAAM;AAAA,YAC7B,CAAC;AAAA,UACH;AAAA,QACF;AACA,eAAO,OAAO,OAAO;AAAA,UACnB,SAAS,OAAO,OAAO,EAAE,GAAG,SAAS,QAAQ,CAAC;AAAA,UAC9C,WAAW,MAAM;AAAA,UACjB,UAAU,MAAM;AAAA,UAChB,aAAa,MAAM;AAAA,UACnB,aAAa,GAAW,GAAW;AACjC,mBAAO,SAAS,aAAa;AAAA,cAC3B,IAAI,IAAI,SAAS,KAAK,SAAS;AAAA,cAC/B,IAAI,IAAI,SAAS,KAAK,SAAS;AAAA,YACjC,CAAC;AAAA,UACH;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AC7ZO,SAAS,YACd,MACA,SACA;AACA,MAAI,SAA8B;AAClC,MAAI;AACJ,MAAI,SAAS,KAAK,WAAW,EAAE;AAC/B,MAAI,OAAO,KAAK,UAAU;AAC1B,MAAI,WAAW;AACf,MAAI,UAAU,KAAK,UAAU;AAC7B,MAAI,mBAAmB,KAAK;AAC5B,MAAI,YAAY,KAAK;AACrB,MAAI,SAAS,SAAS;AACtB,WAAS,OAAO,MAA2B;AACzC,QAAI,SAAU;AACd,aAAS,SAAS,OAAO,OAAO,OAAO,OAAO,IAAI;AAClD,aAAS,SAAS;AAClB,YAAQ,WAAW;AAAA,EACrB;AACA,WAAS,QACP,SAAS,QAAQ,QACjB,WAAW,WACe;AAC1B,QAAI,CAAC,UAAU,KAAK,eAAe,QAAS,QAAO,CAAC;AAEpD,UAAM,UAAU;AAChB,UAAM,UAAU;AAChB,UAAM,YACJ,QAAQ,MAAM,KAAK,MAAM,GAAG,gBAAgB,KAAK,CAAC,GAClD,QAAQ,CAAC,cAAc;AACvB,UACE,CAAC,UAAU,eAAe,KACzB,SAAS,eAAe,UAAU,QAAQ,QAAQ;AAEnD,eAAO,CAAC;AACV,YAAM,SAAS,UAAU,UAAU;AACnC,YAAM,aAAa,OAAO;AAAA,QACxB,CAAC,UACC,MAAM,UAAU,EAAE,SAAS,iBAC1B,CAAC,SAAS,SAAS,MAAM,QAAQ,QAAQ,UAC1C,MAAM,cAAc,MAAM;AAAA,MAC9B;AACA,aAAO,WAAW;AAAA,QAAQ,CAAC,cACzB,OAAO,QAAQ,CAAC,UAAiC;AAC/C,gBAAM,SAAS,MAAM,UAAU;AAC/B,cAAI,OAAO,SAAS,cAAe,QAAO,CAAC;AAC3C,gBAAM,QAAQ;AAAA,YACZ,gBAAgB,UAAU;AAAA,YAC1B,cAAc,UAAU;AAAA,YACxB,UAAU,MAAM;AAAA,UAClB;AACA,cAAI,OAAO,cAAc;AACvB,mBAAO,OAAO,gBACX,OAAO,CAAC,UAAU,CAAC,MAAM,eAAe,KAAK,EAAE,QAAQ,EACvD;AAAA,cAAI,CAAC,UACJ,OAAO,OAAO;AAAA,gBACZ,MAAM;AAAA,gBACN,WAAW,OAAO;AAAA,gBAClB;AAAA,gBACA,GAAG;AAAA,cACL,CAAC;AAAA,YACH;AACJ,iBAAO,OAAO,gBACX,OAAO,CAAC,UAAU,CAAC,MAAM,eAAe,KAAK,EAAE,QAAQ,EACvD;AAAA,YAAI,CAAC,UACJ,OAAO,OAAO;AAAA,cACZ,MAAM,OAAO;AAAA,cACb,WAAW,OAAO;AAAA,cAClB;AAAA,cACA,SAAS,OAAO;AAAA,cAChB,GAAG;AAAA,YACL,CAAC;AAAA,UACH;AAAA,QACJ,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AACA,WAAS,WAAW,MAAqB,OAAsB;AAC7D,WACE,KAAK,SAAS,MAAM,QACpB,KAAK,cAAc,MAAM,aACzB,cAAc,KAAK,KAAK,MAAM,cAAc,MAAM,KAAK,MACtD,KAAK,cAAc,cACjB,MAAM,cAAc,cAAc,KAAK,YAAY,MAAM,YAC5D,KAAK,mBAAmB,MAAM,kBAC9B,KAAK,iBAAiB,MAAM,gBAC5B,KAAK,aAAa,MAAM;AAAA,EAE5B;AACA,WAAS,SAAS;AAChB,QAAI,OAAQ,QAAO,IAAI;AAAA,EACzB;AACA,WAAS,WAA8B;AACrC,UAAM,WAAW;AACjB,UAAM,cAAc,OAAO,OAAO,QAAQ,CAAC;AAC3C,WAAO,OAAO,OAA0B;AAAA,MACtC,QAAQ;AAAA,MACR,YAAY,CAAC,QAAQ,YACnB,CAAC,YAAY,QAAQ,QAAQ,OAAO,EAAE,SAAS;AAAA,MACjD,MAAM,QAAQ,SAAS;AACrB,YAAI,YAAY,CAAC,QAAQ,QAAQ,OAAO,EAAE,OAAQ,QAAO;AACzD,oBAAY;AACZ,eAAO,EAAE,QAAQ,QAAQ,KAAK,CAAC;AAC/B,eAAO;AAAA,MACT;AAAA,MACA,gBAAgB,MAAM;AAAA,MACtB,cAAc,QAA8B;AAC1C,YAAI,CAAC,UAAU,SAAU;AACzB,YACE,UACA,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,WAAW,WAAW,MAAM,CAAC,GAC5D;AACA,iBAAO,EAAE,GAAG,QAAQ,QAAQ,KAAK,CAAC;AAClC;AAAA,QACF;AACA,eAAO,EAAE,GAAG,QAAQ,OAAO,CAAC;AAAA,MAC9B;AAAA,MACA,OAAO;AACL,cAAM,WAAW;AACjB,cAAM,WACJ,UAAU,UACV,QAAQ,EAAE,KAAK,CAAC,WAAW,WAAW,QAAQ,SAAS,MAAO,CAAC;AACjE,eAAO;AACP,YAAI,CAAC,YAAY,UAAU,UAAU;AACnC,kBAAQ,cAAc,SAAS,QAAQ,SAAS,MAAM;AAAA,MAC1D;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AACA,QAAM,cAAc,KAAK,UAAU,MAAM;AACvC,UAAM,aAAa,KAAK,WAAW,EAAE;AACrC,UAAM,WAAW,KAAK,UAAU;AAChC,UAAM,cAAc,KAAK,UAAU;AACnC,QACE,eAAe,UACf,aAAa,QACb,gBAAgB,WAChB,KAAK,eAAe,SACpB;AACA,eAAS;AACT,aAAO;AACP,gBAAU;AACV,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,IAAI,OAAO;AACT,YACE,qBAAqB,KAAK,gBAC1B,cAAc,KAAK,OACnB;AACA,6BAAmB,KAAK;AACxB,sBAAY,KAAK;AACjB,mBAAS,SAAS;AAAA,QACpB;AACA,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,UAAU;AACR,kBAAY;AACZ,aAAO;AACP,iBAAW;AAAA,IACb;AAAA,EACF;AACF;;;AC9JO,SAAS,qBAAqB,WAIlC;AACD,MAAI,WAAW;AACf,MAAI;AAIJ,WAAS,QAAqB;AAC5B,UAAM,EAAE,QAAQ,MAAM,IAAI;AAC1B,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO,EAAE,GAAG,MAAM,IAAI,OAAO,GAAG,GAAG,MAAM,IAAI,OAAO,EAAE;AAAA,IACxD;AAAA,EACF;AAEA,WAAS,UAAU;AACjB,UAAM,WAAW;AACjB,aAAS;AACT,QAAI,UAAU,QAAQ,kBAAkB,SAAS,EAAE,GAAG;AACpD,eAAS,QAAQ,sBAAsB,SAAS,EAAE;AAAA,IACpD;AAAA,EACF;AAEA,WAAS,SAAS;AAChB,QAAI,CAAC,OAAQ;AACb,YAAQ;AACR,cAAU,OAAO;AAAA,EACnB;AAEA,SAAO;AAAA,IACL,MAAM,OAA8B;AAClC,UAAI,YAAY,UAAU,MAAM,WAAW,EAAG,QAAO;AACrD,YAAM,cAAc,kBAAkB,MAAM,SAAS;AACrD,YAAM,QAAQ,EAAE,GAAG,MAAM,SAAS,GAAG,MAAM,QAAQ;AACnD,eAAS;AAAA,QACP,IAAI,MAAM;AAAA,QACV,SAAS,MAAM;AAAA,QACf,QAAQ;AAAA,QACR;AAAA,MACF;AACA,YAAM,eAAe;AACrB,aAAO;AAAA,IACT;AAAA,IACA,KAAK,OAAqB;AACxB,UAAI,MAAM,cAAc,QAAQ,GAAI;AACpC,aAAO,QAAQ,EAAE,GAAG,MAAM,SAAS,GAAG,MAAM,QAAQ;AACpD,YAAM,eAAe;AACrB,gBAAU,KAAK,MAAM,CAAC;AAAA,IACxB;AAAA,IACA,IAAI,OAAqB;AACvB,UAAI,MAAM,cAAc,QAAQ,GAAI;AACpC,aAAO,QAAQ,EAAE,GAAG,MAAM,SAAS,GAAG,MAAM,QAAQ;AACpD,YAAM,SAAS,MAAM;AACrB,cAAQ;AACR,gBAAU,IAAI,MAAM;AAAA,IACtB;AAAA,IACA,OAAO,OAAyC;AAC9C,UAAI,SAAS,MAAM,cAAc,QAAQ,GAAI;AAC7C,aAAO;AAAA,IACT;AAAA,IACA,UAAU;AACR,iBAAW;AACX,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;AC/DO,SAAS,eACd,MACA,SACA,UAA0B,CAAC,GAC3B;AACA,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,WAAW,QAAQ,YAAY;AACrC,MACE,CAAC,OAAO,SAAS,QAAQ,KACzB,CAAC,OAAO,SAAS,QAAQ,KACzB,YAAY,KACZ,WAAW,UACX;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,QAAQ,WAAW,EAAE,GAAG,GAAG,GAAG,GAAG,OAAO,EAAE;AAC1D,MAAI,WAAW;AACf,MAAI,SAAS,KAAK,WAAW,EAAE;AAC/B,MAAI,OAAO,KAAK,UAAU;AAC1B,MAAI,aAAa;AACjB,MAAI,YAAY,MAAM,OAAO;AAC7B,MAAI,SAAS,SAAS;AAEtB,WAAS,MAAM,OAA6C;AAC1D,QACE,CAAC,CAAC,MAAM,GAAG,MAAM,GAAG,MAAM,KAAK,EAAE,MAAM,OAAO,QAAQ,KACtD,MAAM,SAAS,GACf;AACA,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,OAAO,OAAO;AAAA,MACnB,GAAG,MAAM;AAAA,MACT,GAAG,MAAM;AAAA,MACT,OAAO,KAAK,IAAI,UAAU,KAAK,IAAI,UAAU,MAAM,KAAK,CAAC;AAAA,IAC3D,CAAC;AAAA,EACH;AACA,WAAS,OAAO,OAA0B;AACxC,QAAI,SAAU;AACd,UAAM,OAAO,MAAM,KAAK;AACxB,QACE,KAAK,MAAM,UAAU,KACrB,KAAK,MAAM,UAAU,KACrB,KAAK,UAAU,UAAU;AAEzB;AACF,gBAAY;AACZ,aAAS,SAAS;AAClB,YAAQ,WAAW;AAAA,EACrB;AACA,QAAM,UAAU,qBAAqB;AAAA,IACnC,MAAM,CAAC,EAAE,MAAM,MACb,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,WAAW,IAAI,MAAM;AAAA,MACxB,GAAG,WAAW,IAAI,MAAM;AAAA,IAC1B,CAAC;AAAA,IACH,KAAK,CAAC,EAAE,MAAM,MACZ,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,WAAW,IAAI,MAAM;AAAA,MACxB,GAAG,WAAW,IAAI,MAAM;AAAA,IAC1B,CAAC;AAAA,IACH,SAAS;AAAA,IAAC;AAAA,EACZ,CAAC;AACD,WAAS,QAAQ;AACf,WAAO;AAAA,MACL,OAAO,EAAE,aAAa,OAAgB;AAAA,MACtC,cAAc,OAAqB;AACjC,YAAI,QAAQ,MAAM,KAAK,EAAG,cAAa;AAAA,MACzC;AAAA,MACA,eAAe,QAAQ;AAAA,MACvB,aAAa,QAAQ;AAAA,MACrB,iBAAiB,QAAQ;AAAA,MACzB,sBAAsB,QAAQ;AAAA,MAC9B,QAAQ,OAAmB;AACzB,YAAI,SAAU;AACd,cAAM,eAAe;AACrB,cAAM,OAAO,MAAM,cAAc,sBAAsB;AACvD,cAAM,OACJ,MAAM,cAAc,IAAI,KAAK,MAAM,cAAc,IAAI,KAAK,SAAS;AACrE,cAAM,QAAQ,KAAK;AAAA,UACjB;AAAA,UACA,KAAK;AAAA,YACH;AAAA,YACA,UAAU,QAAQ,KAAK,IAAI,CAAC,MAAM,SAAS,OAAO,IAAK;AAAA,UACzD;AAAA,QACF;AACA,cAAM,IAAI,MAAM,UAAU,KAAK;AAC/B,cAAM,IAAI,MAAM,UAAU,KAAK;AAC/B,cAAM,QAAQ,QAAQ,UAAU;AAChC,eAAO;AAAA,UACL,GAAG,KAAK,IAAI,UAAU,KAAK;AAAA,UAC3B,GAAG,KAAK,IAAI,UAAU,KAAK;AAAA,UAC3B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACA,WAAS,WAAW;AAClB,UAAM,WAAW;AACjB,WAAO,OAAO,OAAO;AAAA,MACnB,WAAW;AAAA,MACX,cAAc,MAAM;AAAA,MACpB,UAAU;AAAA,MACV,cAAc;AAAA,MACd,OAAO,MAAM;AACX,gBAAQ,OAAO;AACf,eAAO,OAAO;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AACA,QAAM,cAAc,KAAK,UAAU,MAAM;AACvC,UAAM,aAAa,KAAK,WAAW,EAAE;AACrC,UAAM,WAAW,KAAK,UAAU;AAChC,QAAI,eAAe,UAAU,aAAa,MAAM;AAC9C,eAAS;AACT,aAAO;AACP,cAAQ,OAAO;AACf,aAAO,OAAO;AAAA,IAChB;AAAA,EACF,CAAC;AACD,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,IAAI,WAAW;AACb,eAAO;AAAA,MACT;AAAA,IACF;AAAA,IACA,UAAU;AACR,iBAAW;AACX,kBAAY;AACZ,cAAQ,QAAQ;AAAA,IAClB;AAAA,EACF;AACF;","names":["x","y","value","target","cached"]}
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
import { c as BoardIdOfTable, aP as SpaceIdOfTable, aW as TiledBoardIdOfTable, aX as TiledEdgeIdOfTable, aZ as TiledVertexIdOfTable, d as BoardStateOfTable, ae as PlayerIdOfTable, ab as PhaseNamesOfDefinition, T as InteractionIdOfDefinitionPhase, aC as RuntimeJson, i as ClientParamsOfInteractionOfDefinition, y as InputCollectorOfDefinition, U as InteractionInputDescriptor, b3 as ViewOfDefinition, aw as RuntimeBoardState, G as GameEvent, z as InputDomain } from './extract-gVKcB8Og.js';
|
|
2
|
+
import { P as PlayerBoardSpaceTarget } from './board-target-B0QG6OYx.js';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { Store } from '@tanstack/store';
|
|
5
|
+
import { h as SourceSnapshot, i as SourceState, I as InteractionDescriptor, j as SubmitResult, G as GameSource } from './types-Bj5ZLTUV.js';
|
|
6
|
+
|
|
7
|
+
type RuntimeBoardTarget = {
|
|
8
|
+
readonly valueKind: "board-id";
|
|
9
|
+
readonly kind: "space" | "tile" | "edge" | "vertex";
|
|
10
|
+
readonly boardId: string;
|
|
11
|
+
readonly value: string;
|
|
12
|
+
} | {
|
|
13
|
+
readonly valueKind: "player-board-space";
|
|
14
|
+
readonly kind: "space";
|
|
15
|
+
readonly value: PlayerBoardSpaceTarget;
|
|
16
|
+
};
|
|
17
|
+
type TargetOnBoard<Table, B extends BoardIdOfTable<Table>> = ({
|
|
18
|
+
readonly valueKind: "board-id";
|
|
19
|
+
readonly boardId: B;
|
|
20
|
+
} & ({
|
|
21
|
+
readonly kind: "space";
|
|
22
|
+
readonly value: SpaceIdOfTable<Table, B>;
|
|
23
|
+
} | (B extends TiledBoardIdOfTable<Table> ? {
|
|
24
|
+
readonly kind: "tile";
|
|
25
|
+
readonly value: SpaceIdOfTable<Table, B>;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: "edge";
|
|
28
|
+
readonly value: TiledEdgeIdOfTable<Table, B>;
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: "vertex";
|
|
31
|
+
readonly value: TiledVertexIdOfTable<Table, B>;
|
|
32
|
+
} : never))) | (BoardStateOfTable<Table, B> extends {
|
|
33
|
+
scope: "perPlayer";
|
|
34
|
+
baseId: infer Base extends string;
|
|
35
|
+
} ? {
|
|
36
|
+
readonly valueKind: "player-board-space";
|
|
37
|
+
readonly kind: "space";
|
|
38
|
+
readonly value: PlayerBoardSpaceTarget<Base, SpaceIdOfTable<Table, B>, PlayerIdOfTable<Table>>;
|
|
39
|
+
} : never);
|
|
40
|
+
/** One target identity; player-space tuples already contain their board identity. */
|
|
41
|
+
type BoardTarget<G> = [TableOfGame<G>] extends [never] ? RuntimeBoardTarget : {
|
|
42
|
+
[B in BoardIdOfTable<TableOfGame<G>>]: TargetOnBoard<TableOfGame<G>, B>;
|
|
43
|
+
}[BoardIdOfTable<TableOfGame<G>>];
|
|
44
|
+
type SelectionTarget<G> = BoardTarget<G> | {
|
|
45
|
+
readonly kind: "card";
|
|
46
|
+
readonly value: IdOf<G, "cardId">;
|
|
47
|
+
};
|
|
48
|
+
/** Input disambiguation belongs to a particular interaction. */
|
|
49
|
+
type TargetOptions<G> = {
|
|
50
|
+
readonly interaction?: undefined;
|
|
51
|
+
readonly input?: never;
|
|
52
|
+
} | {
|
|
53
|
+
[K in InteractionKey<G>]: {
|
|
54
|
+
readonly interaction: K;
|
|
55
|
+
readonly input?: InputKey<G, K>;
|
|
56
|
+
};
|
|
57
|
+
}[InteractionKey<G>];
|
|
58
|
+
type KeysOfKind<G, K extends InteractionKey<G>, Kind extends string> = unknown extends G ? string : {
|
|
59
|
+
[N in InputKey<G, K>]: InputKind<G, K, N> extends Kind ? N : never;
|
|
60
|
+
}[InputKey<G, K>];
|
|
61
|
+
/** A resolved atomic card/drop route retains both input identities. */
|
|
62
|
+
type DropTarget<G> = BoardTarget<G> & {
|
|
63
|
+
[K in InteractionKey<G>]: {
|
|
64
|
+
readonly interactionKey: K;
|
|
65
|
+
readonly cardInputKey: KeysOfKind<G, K, "card">;
|
|
66
|
+
readonly inputKey: KeysOfKind<G, K, "board-space" | "board-tile" | "board-edge" | "board-vertex">;
|
|
67
|
+
};
|
|
68
|
+
}[InteractionKey<G>];
|
|
69
|
+
|
|
70
|
+
type PhaseName<G> = [PhaseNamesOfDefinition<G>] extends [never] ? string : PhaseNamesOfDefinition<G>;
|
|
71
|
+
type InteractionKey<G> = unknown extends G ? string : [PhaseNamesOfDefinition<G>] extends [never] ? string : {
|
|
72
|
+
[P in PhaseNamesOfDefinition<G>]: `${P}.${InteractionIdOfDefinitionPhase<G, P>}`;
|
|
73
|
+
}[PhaseNamesOfDefinition<G>];
|
|
74
|
+
type InteractionIdentity<G, K> = {
|
|
75
|
+
[P in PhaseNamesOfDefinition<G>]: {
|
|
76
|
+
[I in InteractionIdOfDefinitionPhase<G, P>]: `${P}.${I}` extends K ? {
|
|
77
|
+
phase: P;
|
|
78
|
+
id: I;
|
|
79
|
+
} : never;
|
|
80
|
+
}[InteractionIdOfDefinitionPhase<G, P>];
|
|
81
|
+
}[PhaseNamesOfDefinition<G>];
|
|
82
|
+
type RawInteractionParams<G, K extends InteractionKey<G>> = unknown extends G ? Record<string, RuntimeJson> : [PhaseNamesOfDefinition<G>] extends [never] ? Record<string, RuntimeJson> : InteractionIdentity<G, K> extends infer Identity ? Identity extends {
|
|
83
|
+
phase: infer P extends PhaseNamesOfDefinition<G>;
|
|
84
|
+
id: infer I;
|
|
85
|
+
} ? I extends InteractionIdOfDefinitionPhase<G, P> ? ClientParamsOfInteractionOfDefinition<G, P, I> : never : never : never;
|
|
86
|
+
type UnionKeys<T> = T extends unknown ? keyof T : never;
|
|
87
|
+
type UnionValue<T, Key> = T extends unknown ? Key extends keyof T ? T[Key] : never : never;
|
|
88
|
+
type InteractionParams<G, K extends InteractionKey<G>> = {
|
|
89
|
+
[N in UnionKeys<RawInteractionParams<G, K>>]: UnionValue<RawInteractionParams<G, K>, N>;
|
|
90
|
+
};
|
|
91
|
+
type CollectorOf<G, K, N extends string> = InteractionIdentity<G, K> extends infer Identity ? Identity extends {
|
|
92
|
+
phase: infer P extends PhaseNamesOfDefinition<G>;
|
|
93
|
+
id: infer I;
|
|
94
|
+
} ? I extends InteractionIdOfDefinitionPhase<G, P> ? InputCollectorOfDefinition<G, P, I, N> : never : never : never;
|
|
95
|
+
type InputKind<G, K extends InteractionKey<G>, N extends InputKey<G, K>> = [CollectorOf<G, K, N>] extends [never] ? InteractionInputDescriptor["kind"] : CollectorOf<G, K, N> extends {
|
|
96
|
+
readonly kind: infer Kind extends InteractionInputDescriptor["kind"];
|
|
97
|
+
} ? Kind : InteractionInputDescriptor["kind"];
|
|
98
|
+
type SelectionValue<Collector, Value> = Collector extends {
|
|
99
|
+
readonly selection: {
|
|
100
|
+
readonly mode: "many";
|
|
101
|
+
};
|
|
102
|
+
} | {
|
|
103
|
+
readonly domain: (...args: never[]) => {
|
|
104
|
+
readonly type: "choiceList";
|
|
105
|
+
};
|
|
106
|
+
} ? Value extends readonly (infer Item)[] ? Item : never : Value;
|
|
107
|
+
type InputTarget<G, K extends InteractionKey<G>, N extends InputKey<G, K>> = [CollectorOf<G, K, N>] extends [never] ? Exclude<InteractionParams<G, K>[N], undefined> : SelectionValue<CollectorOf<G, K, N>, Exclude<InteractionParams<G, K>[N], undefined>>;
|
|
108
|
+
type AnyInput<G, F extends Features, K extends InteractionKey<G>> = {
|
|
109
|
+
[N in InputKey<G, K>]: Input<G, F, K, N>;
|
|
110
|
+
}[InputKey<G, K>];
|
|
111
|
+
type AnyInteraction<G, F extends Features = Record<never, never>> = {
|
|
112
|
+
[K in InteractionKey<G>]: Interaction<G, F, K>;
|
|
113
|
+
}[InteractionKey<G>];
|
|
114
|
+
type InputKey<G, K extends InteractionKey<G>> = keyof InteractionParams<G, K> & string;
|
|
115
|
+
type IdOf<G, K extends string> = G extends {
|
|
116
|
+
contract: {
|
|
117
|
+
manifest: {
|
|
118
|
+
ids: Record<K, infer Schema extends z.ZodType>;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
} ? z.output<Schema> & string : string;
|
|
122
|
+
type ViewOf<G> = [ViewOfDefinition<G>] extends [never] ? unknown : ViewOfDefinition<G>;
|
|
123
|
+
type Drafts<G> = Readonly<Partial<{
|
|
124
|
+
[K in InteractionKey<G>]: Readonly<Partial<InteractionParams<G, K>>>;
|
|
125
|
+
}>>;
|
|
126
|
+
interface LocalState<G> {
|
|
127
|
+
readonly drafts: Drafts<G>;
|
|
128
|
+
readonly activeInteraction: InteractionKey<G> | null;
|
|
129
|
+
}
|
|
130
|
+
interface Feature {
|
|
131
|
+
readonly root?: object;
|
|
132
|
+
readonly interaction?: object;
|
|
133
|
+
readonly input?: object;
|
|
134
|
+
readonly zone?: object;
|
|
135
|
+
readonly card?: object;
|
|
136
|
+
readonly board?: object;
|
|
137
|
+
readonly dispose?: () => void;
|
|
138
|
+
}
|
|
139
|
+
type Features = Readonly<Record<string, Feature>>;
|
|
140
|
+
type Intersection<U> = (U extends unknown ? (value: U) => void : never) extends (value: infer I) => void ? I : never;
|
|
141
|
+
type Hook<F extends Features, H extends keyof Feature> = keyof F extends never ? Record<never, never> : Intersection<{
|
|
142
|
+
[K in keyof F]: F[K] extends Record<H, infer A> ? A : Record<never, never>;
|
|
143
|
+
}[keyof F]>;
|
|
144
|
+
type TableOfGame<G> = G extends {
|
|
145
|
+
contract: {
|
|
146
|
+
manifest: {
|
|
147
|
+
tableSchema: infer Schema extends z.ZodType;
|
|
148
|
+
};
|
|
149
|
+
};
|
|
150
|
+
} ? z.output<Schema> : never;
|
|
151
|
+
type BoardDataOf<G, K extends string> = [TableOfGame<G>] extends [never] ? ReadonlyData<RuntimeBoardState> : TableOfGame<G> extends {
|
|
152
|
+
boards: {
|
|
153
|
+
byId: infer Boards;
|
|
154
|
+
};
|
|
155
|
+
} ? K extends keyof Boards ? ReadonlyData<Boards[K]> & {
|
|
156
|
+
readonly id: K;
|
|
157
|
+
} : never : never;
|
|
158
|
+
type BoardSpaceId<G, B extends IdOf<G, "boardId">> = B extends unknown ? BoardDataOf<G, B> extends {
|
|
159
|
+
readonly spaces: infer Spaces;
|
|
160
|
+
} ? keyof Spaces & string : never : never;
|
|
161
|
+
type BoardSpaceData<G, B extends IdOf<G, "boardId">, S extends BoardSpaceId<G, B>> = B extends unknown ? BoardDataOf<G, B> extends {
|
|
162
|
+
readonly spaces: infer Spaces;
|
|
163
|
+
} ? S extends keyof Spaces ? ReadonlyData<Spaces[S]> & {
|
|
164
|
+
readonly id: S;
|
|
165
|
+
} : never : never : never;
|
|
166
|
+
interface BoardSpace<G, F extends Features = Record<never, never>, B extends IdOf<G, "boardId"> = IdOf<G, "boardId">, S extends BoardSpaceId<G, B> = BoardSpaceId<G, B>> {
|
|
167
|
+
readonly id: S;
|
|
168
|
+
readonly data: BoardSpaceData<G, B, S>;
|
|
169
|
+
readonly board: Board<G, F, B>;
|
|
170
|
+
getIsEligible(): boolean;
|
|
171
|
+
getIsSelectable(): boolean;
|
|
172
|
+
getIsSelected(): boolean;
|
|
173
|
+
getSelectHandler(options?: TargetOptions<G>): () => void;
|
|
174
|
+
getTargetProps(options?: TargetOptions<G>): ActionProps;
|
|
175
|
+
}
|
|
176
|
+
interface BoardSpaceCollection<G, F extends Features = Record<never, never>, B extends IdOf<G, "boardId"> = IdOf<G, "boardId">> {
|
|
177
|
+
get<S extends BoardSpaceId<G, B>>(id: S): BoardSpace<G, F, B, S>;
|
|
178
|
+
find<S extends BoardSpaceId<G, B>>(id: S): BoardSpace<G, F, B, S> | undefined;
|
|
179
|
+
getAll(): readonly BoardSpace<G, F, B>[];
|
|
180
|
+
}
|
|
181
|
+
type BoardHooks<G, F extends Features, B extends IdOf<G, "boardId">> = {
|
|
182
|
+
[K in keyof Hook<F, "board">]: Hook<F, "board">[K] extends BoardSpaceCollection<G> ? BoardSpaceCollection<G, F, B> : Hook<F, "board">[K];
|
|
183
|
+
};
|
|
184
|
+
interface BoardBase<G, K extends IdOf<G, "boardId"> = IdOf<G, "boardId">> {
|
|
185
|
+
readonly id: K;
|
|
186
|
+
readonly game: CoreInstance<G>;
|
|
187
|
+
readonly data: BoardDataOf<G, K>;
|
|
188
|
+
}
|
|
189
|
+
type Board<G, F extends Features, K extends IdOf<G, "boardId"> = IdOf<G, "boardId">> = BoardBase<G, K> & BoardHooks<G, F, K> & {
|
|
190
|
+
readonly game: GameInstance<G, F>;
|
|
191
|
+
};
|
|
192
|
+
interface BoardCollection<G, F extends Features = Record<never, never>> {
|
|
193
|
+
get<K extends IdOf<G, "boardId">>(id: K): Board<G, F, K>;
|
|
194
|
+
find<K extends IdOf<G, "boardId">>(id: K): Board<G, F, K> | undefined;
|
|
195
|
+
getAll(): readonly Board<G, F>[];
|
|
196
|
+
}
|
|
197
|
+
type RootHooks<G, F extends Features> = {
|
|
198
|
+
[K in keyof Hook<F, "root">]: Hook<F, "root">[K] extends BoardCollection<G> ? BoardCollection<G, F> : Hook<F, "root">[K];
|
|
199
|
+
};
|
|
200
|
+
interface FeatureContext<G> {
|
|
201
|
+
createBoard<K extends IdOf<G, "boardId">>(id: K, data: BoardDataOf<G, K>): BoardBase<G, K>;
|
|
202
|
+
routeTarget(target: SelectionTarget<G>, options?: TargetOptions<G>): void;
|
|
203
|
+
routeCardDrop(cardId: IdOf<G, "cardId">, target: DropTarget<G>): void;
|
|
204
|
+
invalidate(): void;
|
|
205
|
+
}
|
|
206
|
+
interface NativeEvent {
|
|
207
|
+
preventDefault(): void;
|
|
208
|
+
}
|
|
209
|
+
interface FieldEvent {
|
|
210
|
+
readonly currentTarget: {
|
|
211
|
+
readonly value: string;
|
|
212
|
+
readonly valueAsNumber?: number;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
type ActionProps = {
|
|
216
|
+
readonly onClick: (event?: NativeEvent) => void;
|
|
217
|
+
readonly disabled: boolean;
|
|
218
|
+
readonly type: "button";
|
|
219
|
+
readonly [key: `data-${string}`]: string | number | boolean | undefined;
|
|
220
|
+
};
|
|
221
|
+
interface Player<G, K extends IdOf<G, "playerId"> = IdOf<G, "playerId">> {
|
|
222
|
+
readonly id: K;
|
|
223
|
+
readonly index: number;
|
|
224
|
+
readonly name: string;
|
|
225
|
+
readonly color?: string;
|
|
226
|
+
readonly isMe: boolean;
|
|
227
|
+
readonly game: CoreInstance<G>;
|
|
228
|
+
}
|
|
229
|
+
interface Phase<G> {
|
|
230
|
+
readonly current: PhaseName<G> | null;
|
|
231
|
+
is(name: PhaseName<G>): boolean;
|
|
232
|
+
switch<R>(routes: {
|
|
233
|
+
[P in PhaseName<G>]: () => R;
|
|
234
|
+
}): R | null;
|
|
235
|
+
}
|
|
236
|
+
interface Turn<G> {
|
|
237
|
+
readonly activePlayerIds: readonly IdOf<G, "playerId">[];
|
|
238
|
+
readonly currentPlayerId: IdOf<G, "playerId"> | null;
|
|
239
|
+
readonly order: readonly IdOf<G, "playerId">[];
|
|
240
|
+
readonly isMine: boolean;
|
|
241
|
+
}
|
|
242
|
+
interface InputBase<G, K extends InteractionKey<G>, N extends InputKey<G, K>> {
|
|
243
|
+
readonly key: N;
|
|
244
|
+
readonly kind: InputKind<G, K, N>;
|
|
245
|
+
readonly game: CoreInstance<G>;
|
|
246
|
+
readonly interaction: InteractionBase<G, K>;
|
|
247
|
+
getDomain(): InputDomain;
|
|
248
|
+
getValue(): InteractionParams<G, K>[N] | undefined;
|
|
249
|
+
setValue(value: Exclude<InteractionParams<G, K>[N], undefined>): void;
|
|
250
|
+
clear(): void;
|
|
251
|
+
getIsReady(): boolean;
|
|
252
|
+
getEligibleTargets(): readonly InputTarget<G, K, N>[];
|
|
253
|
+
getIsEligible(value: InputTarget<G, K, N>): boolean;
|
|
254
|
+
getIsSelected(value: InputTarget<G, K, N>): boolean;
|
|
255
|
+
getSelectHandler(value: InputTarget<G, K, N>): () => void;
|
|
256
|
+
getTargetProps(value: InputTarget<G, K, N>): ActionProps;
|
|
257
|
+
getFieldProps(): {
|
|
258
|
+
value: Exclude<InteractionParams<G, K>[N], null | undefined> | "";
|
|
259
|
+
disabled: boolean;
|
|
260
|
+
onChange(event: FieldEvent): void;
|
|
261
|
+
readonly [key: `data-${string}`]: string | number | boolean | undefined;
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
type Input<G, F extends Features, K extends InteractionKey<G>, N extends InputKey<G, K>> = Omit<InputBase<G, K, N>, "interaction" | "game"> & Hook<F, "input"> & {
|
|
265
|
+
readonly game: GameInstance<G, F>;
|
|
266
|
+
readonly interaction: Interaction<G, F, K>;
|
|
267
|
+
};
|
|
268
|
+
interface InteractionBase<G, K extends InteractionKey<G>> {
|
|
269
|
+
readonly key: K;
|
|
270
|
+
readonly id: [InteractionIdentity<G, K>] extends [never] ? string : InteractionIdentity<G, K>["id"];
|
|
271
|
+
readonly phase: [InteractionIdentity<G, K>] extends [never] ? PhaseName<G> : InteractionIdentity<G, K>["phase"];
|
|
272
|
+
readonly label: string;
|
|
273
|
+
readonly help?: string;
|
|
274
|
+
readonly kind: "inputs" | "steps";
|
|
275
|
+
readonly game: CoreInstance<G>;
|
|
276
|
+
getAvailability(): InteractionDescriptor["availability"];
|
|
277
|
+
getIsAvailable(): boolean;
|
|
278
|
+
getUnavailableReason(): string | null;
|
|
279
|
+
getStep(): InteractionDescriptor["step"] | null;
|
|
280
|
+
getStepIndex(): number | null;
|
|
281
|
+
getIsReady(): boolean;
|
|
282
|
+
getMissingInputs(): readonly InputKey<G, K>[];
|
|
283
|
+
getStatus(): "open" | "submitting" | "submitted";
|
|
284
|
+
submit(): Promise<SubmitResult>;
|
|
285
|
+
cancel(): Promise<SubmitResult>;
|
|
286
|
+
reset(): void;
|
|
287
|
+
activate(): void;
|
|
288
|
+
getSubmitHandler(): (event?: NativeEvent) => void;
|
|
289
|
+
getSubmitProps(): ActionProps;
|
|
290
|
+
}
|
|
291
|
+
type Interaction<G, F extends Features, K extends InteractionKey<G>> = InteractionBase<G, K> & Hook<F, "interaction"> & {
|
|
292
|
+
readonly game: GameInstance<G, F>;
|
|
293
|
+
getInput<N extends InputKey<G, K>>(key: N): Input<G, F, K, N>;
|
|
294
|
+
findInput<N extends InputKey<G, K>>(key: N): Input<G, F, K, N> | undefined;
|
|
295
|
+
getInputs(): readonly AnyInput<G, F, K>[];
|
|
296
|
+
};
|
|
297
|
+
type ReadonlyData<T> = T extends readonly (infer Item)[] ? readonly ReadonlyData<Item>[] : T extends object ? {
|
|
298
|
+
readonly [K in keyof T]: ReadonlyData<T[K]>;
|
|
299
|
+
} : T;
|
|
300
|
+
type CardDataOf<G, K extends string> = G extends {
|
|
301
|
+
contract: {
|
|
302
|
+
manifest: {
|
|
303
|
+
tableSchema: infer Schema extends z.ZodType;
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
} ? z.output<Schema> extends {
|
|
307
|
+
cards: infer Cards;
|
|
308
|
+
} ? K extends keyof Cards ? ReadonlyData<Cards[K]> & {
|
|
309
|
+
readonly id: K;
|
|
310
|
+
} : never : never : Readonly<Record<string, RuntimeJson>>;
|
|
311
|
+
interface CardEntity<G, K extends IdOf<G, "cardId"> = IdOf<G, "cardId">> {
|
|
312
|
+
readonly id: K;
|
|
313
|
+
readonly zone: IdOf<G, "zoneId">;
|
|
314
|
+
readonly index: number;
|
|
315
|
+
readonly game: CoreInstance<G>;
|
|
316
|
+
getInteractions(): readonly AnyInteraction<G>[];
|
|
317
|
+
getIsEligible(): boolean;
|
|
318
|
+
getIsSelected(): boolean;
|
|
319
|
+
getCanSelect(options?: TargetOptions<G>): boolean;
|
|
320
|
+
select(options?: TargetOptions<G>): void;
|
|
321
|
+
getSelectHandler(options?: TargetOptions<G>): () => void;
|
|
322
|
+
getProps(options?: TargetOptions<G>): ActionProps;
|
|
323
|
+
}
|
|
324
|
+
type CardVisibility<G, K extends string> = {
|
|
325
|
+
readonly hidden: true;
|
|
326
|
+
readonly view: null;
|
|
327
|
+
} | {
|
|
328
|
+
readonly hidden: false;
|
|
329
|
+
readonly view: CardDataOf<G, K>;
|
|
330
|
+
};
|
|
331
|
+
type CardBase<G, K extends IdOf<G, "cardId"> = IdOf<G, "cardId">> = CardEntity<G, K> & CardVisibility<G, K>;
|
|
332
|
+
type Card<G, F extends Features, K extends IdOf<G, "cardId"> = IdOf<G, "cardId">> = Omit<CardEntity<G, K>, "getInteractions" | "game"> & CardVisibility<G, K> & Hook<F, "card"> & {
|
|
333
|
+
readonly game: GameInstance<G, F>;
|
|
334
|
+
getInteractions(): readonly AnyInteraction<G, F>[];
|
|
335
|
+
};
|
|
336
|
+
interface ZoneBase<G, K extends IdOf<G, "zoneId"> = IdOf<G, "zoneId">> {
|
|
337
|
+
readonly id: K;
|
|
338
|
+
readonly count: number;
|
|
339
|
+
readonly game: CoreInstance<G>;
|
|
340
|
+
getIsEmpty(): boolean;
|
|
341
|
+
}
|
|
342
|
+
type Zone<G, F extends Features, K extends IdOf<G, "zoneId"> = IdOf<G, "zoneId">> = ZoneBase<G, K> & Hook<F, "zone"> & {
|
|
343
|
+
readonly game: GameInstance<G, F>;
|
|
344
|
+
getCards(options?: {
|
|
345
|
+
sort?: (a: Card<G, F>, b: Card<G, F>) => number;
|
|
346
|
+
}): readonly Card<G, F>[];
|
|
347
|
+
getCard<K extends IdOf<G, "cardId">>(id: K): Card<G, F, K>;
|
|
348
|
+
findCard<K extends IdOf<G, "cardId">>(id: K): Card<G, F, K> | undefined;
|
|
349
|
+
};
|
|
350
|
+
interface ReadModel<G, F extends Features = Record<never, never>> {
|
|
351
|
+
readonly snapshot: SourceSnapshot | null;
|
|
352
|
+
readonly view: ViewOf<G> | null;
|
|
353
|
+
readonly version: number | null;
|
|
354
|
+
readonly connection: SourceState["connection"];
|
|
355
|
+
readonly failure: SourceState["failure"];
|
|
356
|
+
readonly request: SourceState["request"];
|
|
357
|
+
readonly state: LocalState<G>;
|
|
358
|
+
readonly phase: Phase<G>;
|
|
359
|
+
readonly turn: Turn<G>;
|
|
360
|
+
readonly me: {
|
|
361
|
+
readonly id: IdOf<G, "playerId">;
|
|
362
|
+
readonly player: Player<G>;
|
|
363
|
+
getCanAct(): boolean;
|
|
364
|
+
} | null;
|
|
365
|
+
readonly players: {
|
|
366
|
+
get<K extends IdOf<G, "playerId">>(id: K): Player<G, K>;
|
|
367
|
+
find<K extends IdOf<G, "playerId">>(id: K): Player<G, K> | undefined;
|
|
368
|
+
getAll(): readonly Player<G>[];
|
|
369
|
+
next(id: IdOf<G, "playerId">): Player<G>;
|
|
370
|
+
readonly order: readonly IdOf<G, "playerId">[];
|
|
371
|
+
};
|
|
372
|
+
readonly interactions: {
|
|
373
|
+
get<K extends InteractionKey<G>>(key: K): Interaction<G, F, K>;
|
|
374
|
+
find<K extends InteractionKey<G>>(key: K): Interaction<G, F, K> | undefined;
|
|
375
|
+
list(): readonly AnyInteraction<G, F>[];
|
|
376
|
+
listAvailable(): readonly AnyInteraction<G, F>[];
|
|
377
|
+
};
|
|
378
|
+
readonly inputs: {
|
|
379
|
+
get<K extends InteractionKey<G>, N extends InputKey<G, K>>(interaction: K, input: N): Input<G, F, K, N>;
|
|
380
|
+
find<K extends InteractionKey<G>, N extends InputKey<G, K>>(interaction: K, input: N): Input<G, F, K, N> | undefined;
|
|
381
|
+
};
|
|
382
|
+
readonly zones: {
|
|
383
|
+
get<K extends IdOf<G, "zoneId">>(id: K): Zone<G, F, K>;
|
|
384
|
+
find<K extends IdOf<G, "zoneId">>(id: K): Zone<G, F, K> | undefined;
|
|
385
|
+
getAll(): readonly Zone<G, F>[];
|
|
386
|
+
};
|
|
387
|
+
readonly cards: {
|
|
388
|
+
get<K extends IdOf<G, "cardId">>(id: K): Card<G, F, K>;
|
|
389
|
+
find<K extends IdOf<G, "cardId">>(id: K): Card<G, F, K> | undefined;
|
|
390
|
+
};
|
|
391
|
+
readonly events: {
|
|
392
|
+
readonly recent: readonly GameEvent[];
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
interface InstanceOptions<G, S extends GameSource = GameSource> {
|
|
396
|
+
readonly source: S;
|
|
397
|
+
readonly initialState?: Partial<LocalState<G>>;
|
|
398
|
+
readonly state?: Partial<LocalState<G>>;
|
|
399
|
+
readonly onDraftsChange?: (drafts: Drafts<G>) => void;
|
|
400
|
+
readonly onActiveInteractionChange?: (key: InteractionKey<G> | null) => void;
|
|
401
|
+
readonly onError?: (error: unknown) => void;
|
|
402
|
+
readonly coverage?: Readonly<Record<InteractionKey<G>, unknown>>;
|
|
403
|
+
readonly debug?: boolean;
|
|
404
|
+
}
|
|
405
|
+
type CoreInstance<G> = ReadModel<G> & {
|
|
406
|
+
readonly store: Pick<Store<ReadModel<G>>, "get" | "subscribe">;
|
|
407
|
+
getSnapshot(): ReadModel<G>;
|
|
408
|
+
getOptions(): InstanceOptions<G>;
|
|
409
|
+
setOptions(options: InstanceOptions<G>): void;
|
|
410
|
+
subscribe(listener: () => void): () => void;
|
|
411
|
+
dispose(): void;
|
|
412
|
+
assertCoverage(): void;
|
|
413
|
+
inspect(): ReadModel<G>;
|
|
414
|
+
};
|
|
415
|
+
type GameSnapshot<G, F extends Features = Record<never, never>> = ReadModel<G, F> & RootHooks<G, F>;
|
|
416
|
+
type GameInstance<G, F extends Features = Record<never, never>, S extends GameSource = GameSource> = Omit<CoreInstance<G>, keyof ReadModel<G> | "store" | "getSnapshot" | "getOptions" | "setOptions" | "inspect"> & ReadModel<G, F> & RootHooks<G, F> & {
|
|
417
|
+
readonly store: Pick<Store<GameSnapshot<G, F>>, "get" | "subscribe">;
|
|
418
|
+
getSnapshot(): GameSnapshot<G, F>;
|
|
419
|
+
inspect(): GameSnapshot<G, F>;
|
|
420
|
+
getOptions(): InstanceOptions<G, S>;
|
|
421
|
+
setOptions(options: InstanceOptions<G, S>): void;
|
|
422
|
+
} & (S extends {
|
|
423
|
+
apply(action: infer A): infer R;
|
|
424
|
+
} ? {
|
|
425
|
+
apply(action: A): R;
|
|
426
|
+
} : Record<never, never>) & (S extends {
|
|
427
|
+
explore(...args: infer A): infer R;
|
|
428
|
+
} ? {
|
|
429
|
+
explore(...args: A): R;
|
|
430
|
+
} : Record<never, never>);
|
|
431
|
+
|
|
432
|
+
export type { ActionProps as A, Board as B, Card as C, Drafts as D, InteractionKey as E, Feature as F, GameInstance as G, Hook as H, IdOf as I, InteractionParams as J, PhaseName as K, LocalState as L, Player as M, NativeEvent as N, ReadonlyData as O, Phase as P, RuntimeBoardTarget as Q, ReadModel as R, SelectionTarget as S, TableOfGame as T, TargetOptions as U, Turn as V, ViewOf as W, ZoneBase as X, Zone as Z, AnyInput as a, AnyInteraction as b, BoardBase as c, BoardCollection as d, BoardDataOf as e, BoardSpace as f, BoardSpaceCollection as g, BoardSpaceData as h, BoardSpaceId as i, BoardTarget as j, CardBase as k, CardDataOf as l, CoreInstance as m, DropTarget as n, FeatureContext as o, Features as p, FieldEvent as q, GameSnapshot as r, Input as s, InputBase as t, InputKey as u, InputKind as v, InputTarget as w, InstanceOptions as x, Interaction as y, InteractionBase as z };
|