@dreamboard-games/sdk 0.4.0-alpha.7 → 0.4.0-alpha.9

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.
Files changed (112) hide show
  1. package/REFERENCE.md +1292 -287
  2. package/dist/authoring/index.d.ts +4 -9
  3. package/dist/authoring/index.js +11 -547
  4. package/dist/authoring/index.js.map +1 -1
  5. package/dist/authoring-compiler.d.ts +27 -0
  6. package/dist/authoring-compiler.js +12 -0
  7. package/dist/authoring-compiler.js.map +1 -0
  8. package/dist/authoring-materialize-cli.d.ts +1 -0
  9. package/dist/authoring-materialize-cli.js +46 -0
  10. package/dist/authoring-materialize-cli.js.map +1 -0
  11. package/dist/browser-interaction.d.ts +1 -1
  12. package/dist/{chunk-TGMXBRKY.js → chunk-3PFDHTR7.js} +19 -7
  13. package/dist/chunk-3PFDHTR7.js.map +1 -0
  14. package/dist/chunk-45P5CEGH.js +176 -0
  15. package/dist/chunk-45P5CEGH.js.map +1 -0
  16. package/dist/chunk-5XTAQ4EQ.js +32 -0
  17. package/dist/chunk-5XTAQ4EQ.js.map +1 -0
  18. package/dist/chunk-7ADPYKFT.js +532 -0
  19. package/dist/chunk-7ADPYKFT.js.map +1 -0
  20. package/dist/{chunk-RKGJ64UN.js → chunk-BUOODBVO.js} +2 -2
  21. package/dist/{chunk-VLG4YST5.js → chunk-GMOBG7Y7.js} +4 -4
  22. package/dist/{chunk-Q322XCY2.js → chunk-JRGP6W4V.js} +3 -3
  23. package/dist/chunk-L3W2FPRQ.js +1793 -0
  24. package/dist/chunk-L3W2FPRQ.js.map +1 -0
  25. package/dist/{chunk-3QIZKXJ2.js → chunk-NGYFBNBP.js} +3 -3
  26. package/dist/chunk-P6IJ5YVY.js +154 -0
  27. package/dist/chunk-P6IJ5YVY.js.map +1 -0
  28. package/dist/{chunk-5IHU5CUK.js → chunk-QQNL4WTX.js} +25 -22
  29. package/dist/chunk-QQNL4WTX.js.map +1 -0
  30. package/dist/{chunk-52DH7VQF.js → chunk-SACZWUA6.js} +143 -47
  31. package/dist/chunk-SACZWUA6.js.map +1 -0
  32. package/dist/{chunk-KYEWGZ2Y.js → chunk-SFOAY5H4.js} +2 -2
  33. package/dist/{chunk-KYEWGZ2Y.js.map → chunk-SFOAY5H4.js.map} +1 -1
  34. package/dist/chunk-UNVCT5Z7.js +73 -0
  35. package/dist/chunk-UNVCT5Z7.js.map +1 -0
  36. package/dist/{chunk-NO537WSS.js → chunk-WDR7SKBM.js} +2 -2
  37. package/dist/chunk-XDGRC6OR.js +7039 -0
  38. package/dist/chunk-XDGRC6OR.js.map +1 -0
  39. package/dist/chunk-XLHLFTLI.js +399 -0
  40. package/dist/chunk-XLHLFTLI.js.map +1 -0
  41. package/dist/{chunk-B2YBS3SG.js → chunk-YNW3KBDE.js} +41 -13
  42. package/dist/chunk-YNW3KBDE.js.map +1 -0
  43. package/dist/codegen.js +1 -1
  44. package/dist/{components-BTwSIjXj.d.ts → components-BPzsSRs8.d.ts} +1 -1
  45. package/dist/definitions-0kjPV9wh.d.ts +294 -0
  46. package/dist/{diagnostics-1BWjRo6-.d.ts → diagnostics-DIi3ina7.d.ts} +2 -1
  47. package/dist/{index-CFTjJIXd.d.ts → index-CWzWpQzM.d.ts} +1 -1
  48. package/dist/{index.d-DMASeF6M.d.ts → index.d-C7Ztirg6.d.ts} +234 -5
  49. package/dist/index.js +2 -2
  50. package/dist/package-set.d.ts +2 -2
  51. package/dist/package-set.js +2 -2
  52. package/dist/{protocol-835hEGne.d.ts → protocol-B2LWcqB4.d.ts} +14 -0
  53. package/dist/reducer/advanced.d.ts +4 -4
  54. package/dist/reducer/advanced.js +7 -26
  55. package/dist/reducer/advanced.js.map +1 -1
  56. package/dist/reducer-contract.d.ts +1 -1
  57. package/dist/reducer-contract.js +2 -2
  58. package/dist/reducer.d.ts +37 -28
  59. package/dist/reducer.js +43 -6018
  60. package/dist/reducer.js.map +1 -1
  61. package/dist/reference-game-compiler.d.ts +45 -0
  62. package/dist/reference-game-compiler.js +25 -0
  63. package/dist/reference-game-compiler.js.map +1 -0
  64. package/dist/reference-game-source-manifest-cli.d.ts +1 -0
  65. package/dist/reference-game-source-manifest-cli.js +84 -0
  66. package/dist/reference-game-source-manifest-cli.js.map +1 -0
  67. package/dist/reference-games/index.d.ts +7 -217
  68. package/dist/reference-games/index.js +28 -208
  69. package/dist/reference-games/index.js.map +1 -1
  70. package/dist/runtime/primitives.d.ts +3 -3
  71. package/dist/runtime/primitives.js +3 -3
  72. package/dist/runtime/runtime-api.d.ts +1 -1
  73. package/dist/runtime/workspace-contract.d.ts +4 -4
  74. package/dist/runtime/workspace-contract.js +4 -4
  75. package/dist/{runtime-Dkfm1x2r.d.ts → runtime-B_w9AO2n.d.ts} +60 -5
  76. package/dist/{runtime-api-C6aWo9c0.d.ts → runtime-api-xCWLMQRT.d.ts} +2 -0
  77. package/dist/runtime.d.ts +7 -7
  78. package/dist/runtime.js +13 -13
  79. package/dist/schema-9jZzlEWZ.d.ts +220 -0
  80. package/dist/{stale-contract-artifact-error-C5AaZPJ8.d.ts → stale-contract-artifact-error-XLaweZtF.d.ts} +1 -1
  81. package/dist/testing-compiler.d.ts +36 -0
  82. package/dist/testing-compiler.js +236 -0
  83. package/dist/testing-compiler.js.map +1 -0
  84. package/dist/testing-runtime.d.ts +97 -21
  85. package/dist/testing-runtime.js +154 -95
  86. package/dist/testing-runtime.js.map +1 -1
  87. package/dist/testing.d.ts +178 -60
  88. package/dist/testing.js +641 -26
  89. package/dist/testing.js.map +1 -1
  90. package/dist/types-Bvptkukh.d.ts +122 -0
  91. package/dist/{types-aI4V9CWe.d.ts → types-_zfC_7CD.d.ts} +1 -1
  92. package/dist/types.d.ts +4 -0
  93. package/dist/ui/components.d.ts +2 -2
  94. package/dist/ui/plugin-styles.css +1 -1
  95. package/dist/{ui-contract-Ue6SywvO.d.ts → ui-contract-CUC7Lyoc.d.ts} +1 -1
  96. package/dist/ui.d.ts +3 -3
  97. package/dist/{views-32rSsfeU.d.ts → views-DE2eZxPz.d.ts} +42 -13
  98. package/package.json +22 -3
  99. package/dist/chunk-3OZMHZK3.js +0 -40
  100. package/dist/chunk-3OZMHZK3.js.map +0 -1
  101. package/dist/chunk-52DH7VQF.js.map +0 -1
  102. package/dist/chunk-5IHU5CUK.js.map +0 -1
  103. package/dist/chunk-B2YBS3SG.js.map +0 -1
  104. package/dist/chunk-IU6KGPY7.js +0 -659
  105. package/dist/chunk-IU6KGPY7.js.map +0 -1
  106. package/dist/chunk-TGMXBRKY.js.map +0 -1
  107. package/dist/types-DcADVHe9.d.ts +0 -192
  108. /package/dist/{chunk-RKGJ64UN.js.map → chunk-BUOODBVO.js.map} +0 -0
  109. /package/dist/{chunk-VLG4YST5.js.map → chunk-GMOBG7Y7.js.map} +0 -0
  110. /package/dist/{chunk-Q322XCY2.js.map → chunk-JRGP6W4V.js.map} +0 -0
  111. /package/dist/{chunk-3QIZKXJ2.js.map → chunk-NGYFBNBP.js.map} +0 -0
  112. /package/dist/{chunk-NO537WSS.js.map → chunk-WDR7SKBM.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/definitions.ts","../src/testing/ui-fixture/canonical.ts","../src/testing/reducer-scenario/create-reducer-scenario-runner.ts","../src/testing/ui-scenario/define-ui-scenario.ts","../src/testing/ui-fixture/parity.ts","../src/testing/ui-fixture/create-fixture-host-harness.ts","../src/testing/ui-fixture/FixturePluginRuntime.tsx","../src/testing/ui-fixture/compile-plugin-protocol-tape.ts","../src/testing/ui-fixture/deterministic-environment.ts","../src/testing/ui-fixture/schema.ts","../src/testing/ui-fixture/compiler.ts","../src/testing/ui-scenario/replay-builders.ts"],"sourcesContent":["import type {\n DispatchTraceSummaryEntry,\n ReducerDiagnosticEvent,\n} from \"../reducer/diagnostics.js\";\n\nexport type TestRunner = \"reducer\" | \"remote\" | \"browser\";\n\nexport type InteractionDescriptorLike = {\n interactionId?: string;\n surface?: string;\n kind?: string;\n availability?: InteractionAvailabilityLike;\n context?: {\n to?: string;\n };\n} & Record<string, unknown>;\n\nexport type InteractionAvailabilityLike =\n | { status: \"available\" }\n | { status: \"notYourTurn\"; reason: string }\n | {\n status: \"insufficientResources\";\n reason: string;\n missingResources?: Record<string, unknown>;\n }\n | { status: \"blocked\"; reason: string };\n\nexport type InteractionExplanationLike = {\n interactionId: string;\n phase: string;\n step: string | null;\n availability:\n | \"available\"\n | \"notYourTurn\"\n | \"wrongPhase\"\n | \"wrongStep\"\n | \"blocked\";\n rules: ReadonlyArray<{\n ruleId: string;\n outcome: \"passed\" | \"failed\" | \"notEvaluated\";\n errorCode?: string;\n message?: string;\n }>;\n actor: { required: readonly string[]; playerIsActor: boolean };\n inputs: ReadonlyArray<{\n key: string;\n kind: string;\n eligibleCount: number | \"lazy\";\n }>;\n};\n\nexport type SnapshotMatcherHandler = (\n name: string | undefined,\n actual: unknown,\n) => void;\n\nexport type RejectionExpectation = {\n errorCode?: string;\n message?: string | RegExp;\n};\n\nexport type ExpectMatchers = {\n toBe: (expected: unknown) => void;\n toEqual: (expected: unknown) => void;\n toMatchObject: (expected: Record<string, unknown>) => void;\n toBeDefined: () => void;\n toBeUndefined: () => void;\n toBeNull: () => void;\n toContain: (expected: unknown) => void;\n toContainEqual: (expected: unknown) => void;\n toHaveLength: (expected: number) => void;\n toBeGreaterThan: (expected: number) => void;\n toBeGreaterThanOrEqual: (expected: number) => void;\n toThrow: (predicate?: string | RegExp | ((error: Error) => boolean)) => void;\n toMatchSnapshot: (filename?: string) => void;\n toRejectWith: (expected: RejectionExpectation) => Promise<void>;\n toHaveInteraction: (\n interactionId: string,\n opts?: Partial<InteractionDescriptorLike>,\n ) => void;\n toBeGatedBy: (reason: string, opts?: { interactionId?: string }) => void;\n toBeAvailable: (explanation?: InteractionExplanationLike) => void;\n toBeActiveFor: (playerId: string, opts?: { interactionId?: string }) => void;\n not: {\n toHaveInteraction: (interactionId: string) => void;\n };\n};\n\nexport type ExpectFn = (actual: unknown) => ExpectMatchers;\n\nexport interface BaseContext<PlayerId extends string = string> {\n game: {\n start(): Promise<void>;\n patchState?(\n mutator: (state: Record<string, unknown>) => void,\n ): Promise<void>;\n submit(\n playerId: PlayerId,\n interactionId: string,\n params?: unknown,\n ): Promise<void>;\n };\n players(): readonly PlayerId[];\n seat(index: number): PlayerId;\n}\n\nexport interface SharedScenarioContext<\n PlayerId extends string = string,\n StateName extends string = string,\n View = unknown,\n Descriptor extends InteractionDescriptorLike = InteractionDescriptorLike,\n> extends BaseContext<PlayerId> {\n state(): StateName;\n view(playerId: PlayerId): View;\n interactions(playerId: PlayerId): readonly Descriptor[];\n explain(\n playerId: PlayerId,\n interactionId: string,\n ): InteractionExplanationLike;\n diagnostics: {\n readonly events: readonly ReducerDiagnosticEvent[];\n readonly lastDispatch: {\n submissionId: string;\n trace: readonly DispatchTraceSummaryEntry[];\n } | null;\n clear(): void;\n };\n expect: ExpectFn;\n}\n\nexport interface BaseDefinition {\n id: string;\n seed?: number;\n players?: number;\n setupProfileId?: string | null;\n extends?: string;\n setup: (ctx: BaseContext) => void | Promise<void>;\n}\n\nexport interface ScenarioDefinition<\n Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n PhaseName extends string = string,\n StageName extends string = string,\n> {\n id: string;\n description?: string;\n from: string;\n runners?: Runners;\n phase?: PhaseName;\n stage?: StageName;\n when: (ctx: SharedScenarioContext) => void | Promise<void>;\n then: (ctx: SharedScenarioContext) => void | Promise<void>;\n}\n\nexport function defineBase<const Definition extends BaseDefinition>(\n definition: Definition,\n): Definition {\n return definition;\n}\n\nexport function defineScenario<\n const Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n const PhaseName extends string = string,\n const StageName extends string = string,\n>(\n definition: ScenarioDefinition<Runners, PhaseName, StageName>,\n): ScenarioDefinition<Runners, PhaseName, StageName> {\n return definition;\n}\n","import { createHash } from \"node:crypto\";\nimport type {\n PluginProtocolTape,\n UIReplayRequest,\n UIScenarioFixture,\n} from \"./schema.js\";\n\ntype CanonicalJson =\n | null\n | boolean\n | number\n | string\n | readonly CanonicalJson[]\n | { readonly [key: string]: CanonicalJson };\n\nconst sha256DigestPattern = /^sha256:[a-f0-9]{64}$/;\n\nexport function isSha256Digest(value: string): boolean {\n return sha256DigestPattern.test(value);\n}\n\nexport function canonicalizeUIFixtureJson(value: unknown): CanonicalJson {\n if (value === null) {\n return null;\n }\n switch (typeof value) {\n case \"boolean\":\n case \"string\":\n return value;\n case \"number\":\n if (Number.isFinite(value)) {\n return value;\n }\n break;\n case \"object\": {\n if (Array.isArray(value)) {\n return value.map((item) => canonicalizeUIFixtureJson(item));\n }\n if (Object.getPrototypeOf(value) !== Object.prototype) {\n break;\n }\n const entries = Object.entries(value as Record<string, unknown>);\n return Object.fromEntries(\n entries\n .filter(([, item]) => item !== undefined)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, item]) => [key, canonicalizeUIFixtureJson(item)]),\n );\n }\n }\n throw new Error(\n `UI fixture values must be deterministic JSON. Received ${typeof value}.`,\n );\n}\n\nexport function canonicalUIFixtureJson(value: unknown): string {\n return JSON.stringify(canonicalizeUIFixtureJson(value));\n}\n\nexport function digestUIFixtureJson(value: unknown): string {\n return sha256(canonicalUIFixtureJson(value));\n}\n\nexport function digestUIFixtureRequest(request: UIReplayRequest): string {\n return digestUIFixtureJson({\n digestVersion: \"ui-replay-request@2\",\n request,\n });\n}\n\nexport function digestUIFixtureTransportRequest(request: {\n readonly operation: \"validate\" | \"submit\";\n readonly basis?: {\n readonly gameVersion: number;\n readonly actionSetVersion: string;\n readonly perspectivePlayerId: string | null;\n };\n readonly interactionId?: string;\n readonly payload?: unknown;\n}): string {\n return digestUIFixtureJson({\n digestVersion: \"ui-fixture-runtime-command@2\",\n request,\n });\n}\n\nexport function digestPluginProtocolTape(tape: PluginProtocolTape): string {\n return digestUIFixtureJson({\n digestVersion: \"plugin-protocol-tape@2\",\n tape,\n });\n}\n\nexport function canonicalizeUIScenarioFixture(\n fixture: UIScenarioFixture,\n): UIScenarioFixture {\n return canonicalizeUIFixtureJson({\n ...fixture,\n tags: [...fixture.tags].sort(),\n environment: {\n ...fixture.environment,\n viewportTags: [...fixture.environment.viewportTags].sort(),\n },\n }) as unknown as UIScenarioFixture;\n}\n\nexport function serializeUIScenarioFixture(fixture: UIScenarioFixture): string {\n return `${JSON.stringify(canonicalizeUIScenarioFixture(fixture), null, 2)}\\n`;\n}\n\nexport function digestUIScenarioFixture(fixture: UIScenarioFixture): string {\n return sha256(serializeUIScenarioFixture(fixture));\n}\n\nfunction sha256(value: string): string {\n return `sha256:${createHash(\"sha256\").update(value).digest(\"hex\")}`;\n}\n","import {\n computePluginActionSetVersion,\n materializePluginGameplayFrame,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport { digestUIFixtureJson } from \"../ui-fixture/canonical.js\";\nimport type {\n CreateReducerScenarioRunnerOptions,\n ReducerScenarioFrame,\n ReducerScenarioExchange,\n ReducerScenarioOperation,\n ReducerScenarioRunner,\n ReducerScenarioTrace,\n} from \"./types.js\";\n\nexport function createReducerScenarioRunner(\n options: CreateReducerScenarioRunnerOptions,\n): ReducerScenarioRunner {\n return {\n async run(\n operations: readonly ReducerScenarioOperation[],\n ): Promise<ReducerScenarioTrace> {\n let state = structuredClone(options.initialState);\n let gameVersion = options.initialGameVersion ?? 1;\n const frames: ReducerScenarioFrame[] = [];\n const exchanges: ReducerScenarioExchange[] = [];\n\n const appendFrame = (id: string): ReducerScenarioFrame => {\n const dynamicProjection = options.bundle.projectSeatsDynamic({\n state,\n playerIds: [options.viewer.playerId],\n });\n const staticProjection = options.bundle.projectStatic?.() ?? null;\n const flow = readFlowState(state);\n const materialized = materializePluginGameplayFrame({\n currentPhase: flow.currentPhase,\n activePlayers: flow.activePlayers,\n dynamicProjection,\n staticProjection,\n perspectivePlayerId: options.viewer.playerId,\n gameVersion,\n actionSetVersion: \"pending\",\n });\n const actionSetVersion = computePluginActionSetVersion({\n gameVersion,\n availableInteractions: materialized.availableInteractions,\n });\n const frame = {\n id,\n reducerState: structuredClone(state),\n dynamicProjection,\n staticProjection,\n gameVersion,\n actionSetVersion,\n projectionDigest: digestUIFixtureJson({\n digestVersion: \"reducer-scenario-frame@2\",\n scenarioId: options.scenarioId,\n frameId: id,\n dynamicProjection,\n staticProjection,\n gameVersion,\n actionSetVersion,\n }),\n } satisfies ReducerScenarioFrame;\n frames.push(frame);\n return frame;\n };\n\n appendFrame(\"frame-1\");\n\n for (const operation of operations) {\n const fromFrame = frames[frames.length - 1];\n if (!fromFrame) {\n throw new Error(\"Reducer scenario runner lost its initial frame.\");\n }\n if (operation.operation === \"validate\") {\n const result = await options.bundle.validateInput({\n state,\n input: operation.input,\n });\n exchanges.push({\n id: operation.id,\n operation: \"validate\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result,\n });\n continue;\n }\n\n const result = await options.bundle.dispatch({\n state,\n input: operation.input,\n });\n if (result.kind === \"reject\") {\n exchanges.push({\n id: operation.id,\n operation: \"submit\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result: {\n kind: \"rejected\",\n diagnostics: [\n {\n code: result.errorCode,\n message: result.message ?? result.errorCode,\n },\n ],\n },\n });\n continue;\n }\n\n state = structuredClone(result.state);\n gameVersion += 1;\n const toFrame = appendFrame(`frame-${frames.length + 1}`);\n exchanges.push({\n id: operation.id,\n operation: \"submit\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result: {\n kind: \"accepted\",\n toFrameId: toFrame.id,\n },\n });\n }\n\n return {\n scenarioId: options.scenarioId,\n gameId: options.gameId,\n viewer: options.viewer,\n frames,\n exchanges,\n };\n },\n };\n}\n\nfunction readFlowState(state: {\n readonly domain?: {\n readonly flow?: {\n readonly currentPhase?: string;\n readonly activePlayers?: readonly string[];\n };\n };\n}): { currentPhase: string | null; activePlayers: readonly string[] } {\n return {\n currentPhase: state.domain?.flow?.currentPhase ?? null,\n activePlayers: [...(state.domain?.flow?.activePlayers ?? [])],\n };\n}\n","import type {\n ReferenceGameUIScenarioDefinition,\n UIScenarioDefinition,\n} from \"./types.js\";\n\nexport function defineUIScenario<const TScenario extends UIScenarioDefinition>(\n scenario: TScenario,\n): Readonly<TScenario> {\n return Object.freeze(scenario);\n}\n\nexport function defineReferenceGameUIScenario<\n const TScenario extends ReferenceGameUIScenarioDefinition,\n>(scenario: TScenario): Readonly<TScenario> {\n return Object.freeze(scenario);\n}\n","import {\n canonicalUIFixtureJson,\n digestUIFixtureJson,\n digestUIScenarioFixture,\n} from \"./canonical.js\";\nimport type { UIScenarioFixture } from \"./schema.js\";\n\nexport interface UIParityViewport {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface UIParityObservationEnvironmentV1 {\n readonly project: string;\n readonly viewport: UIParityViewport;\n}\n\nexport interface UIParityDiagnosticV1 {\n readonly code: string;\n readonly message: string;\n}\n\nexport interface UIParityObservationCheckpointV1 {\n readonly stepId: string;\n readonly interactionKey?: string;\n readonly interactionId?: string;\n readonly actuatorId?: string;\n readonly descriptorDigest?: string;\n readonly draftDigest?: string;\n readonly gameVersion: number;\n readonly actionSetVersion: string;\n readonly perspectivePlayerId: string | null;\n readonly projectionDigest: string;\n readonly semanticDigest: string;\n readonly submissionDigest?: string;\n readonly screenshot?: string;\n}\n\nexport interface UIParityObservationProvenanceV1 {\n readonly kind:\n | \"fixture-expectation\"\n | \"source-workbench\"\n | \"packed-real-host\";\n readonly evidence?: string;\n}\n\nexport interface UIParityObservationV1 {\n readonly schemaVersion: 1;\n readonly scenarioId: string;\n readonly fixtureDigest: string;\n readonly sdkCandidateDigest: string;\n readonly pluginRuntimeProtocol: 3;\n readonly browserInteractionProtocol: string;\n readonly environment: UIParityObservationEnvironmentV1;\n readonly provenance: UIParityObservationProvenanceV1;\n readonly checkpoints: readonly UIParityObservationCheckpointV1[];\n readonly diagnostics: readonly UIParityDiagnosticV1[];\n}\n\nexport type UIParityFailureCode =\n | \"candidate-mismatch\"\n | \"fixture-source-mismatch\"\n | \"protocol-mismatch\"\n | \"interaction-resolution-mismatch\"\n | \"preparation-mismatch\"\n | \"draft-mismatch\"\n | \"submission-mismatch\"\n | \"projection-mismatch\"\n | \"semantic-snapshot-mismatch\"\n | \"visual-mismatch\"\n | \"host-setup-failure\";\n\nexport interface UIParityComparisonFailure {\n readonly code: UIParityFailureCode;\n readonly message: string;\n readonly path: string;\n readonly expected: unknown;\n readonly actual: unknown;\n readonly checkpointIndex?: number;\n readonly stepId?: string;\n}\n\nexport type UIParityComparisonResult =\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly failure: UIParityComparisonFailure;\n };\n\ntype UIParityComparisonFailureInput = Omit<\n UIParityComparisonFailure,\n \"message\"\n>;\n\nexport interface CreateUIParityObservationFromFixtureOptions {\n readonly fixture: UIScenarioFixture;\n readonly sdkCandidateDigest: string;\n readonly environment: UIParityObservationEnvironmentV1;\n readonly fixtureDigest?: string;\n readonly screenshotsByStepId?: Readonly<Record<string, string>>;\n readonly diagnostics?: readonly UIParityDiagnosticV1[];\n}\n\ntype ComparablePath = {\n readonly path: string;\n readonly code: UIParityFailureCode;\n};\n\nconst topLevelComparisons: readonly ComparablePath[] = [\n { path: \"scenarioId\", code: \"fixture-source-mismatch\" },\n { path: \"fixtureDigest\", code: \"candidate-mismatch\" },\n { path: \"sdkCandidateDigest\", code: \"candidate-mismatch\" },\n { path: \"pluginRuntimeProtocol\", code: \"protocol-mismatch\" },\n { path: \"browserInteractionProtocol\", code: \"protocol-mismatch\" },\n { path: \"environment.project\", code: \"host-setup-failure\" },\n { path: \"environment.viewport.width\", code: \"host-setup-failure\" },\n { path: \"environment.viewport.height\", code: \"host-setup-failure\" },\n];\n\nconst checkpointComparisons: readonly ComparablePath[] = [\n { path: \"stepId\", code: \"interaction-resolution-mismatch\" },\n { path: \"interactionKey\", code: \"interaction-resolution-mismatch\" },\n { path: \"interactionId\", code: \"interaction-resolution-mismatch\" },\n { path: \"actuatorId\", code: \"interaction-resolution-mismatch\" },\n { path: \"descriptorDigest\", code: \"interaction-resolution-mismatch\" },\n { path: \"gameVersion\", code: \"projection-mismatch\" },\n { path: \"actionSetVersion\", code: \"projection-mismatch\" },\n { path: \"perspectivePlayerId\", code: \"projection-mismatch\" },\n { path: \"projectionDigest\", code: \"projection-mismatch\" },\n { path: \"semanticDigest\", code: \"semantic-snapshot-mismatch\" },\n { path: \"draftDigest\", code: \"draft-mismatch\" },\n { path: \"submissionDigest\", code: \"submission-mismatch\" },\n { path: \"screenshot\", code: \"visual-mismatch\" },\n];\n\nexport function createUIParityObservationFromFixture({\n fixture,\n sdkCandidateDigest,\n environment,\n fixtureDigest = digestUIScenarioFixture(fixture),\n screenshotsByStepId = {},\n diagnostics = [],\n}: CreateUIParityObservationFromFixtureOptions): UIParityObservationV1 {\n const frameById = new Map(\n fixture.protocol.frames.map((frame) => [frame.id, frame]),\n );\n const firstFrame = fixture.protocol.frames[0];\n if (!firstFrame) {\n throw new Error(\n `Fixture '${fixture.id}' does not contain protocol frames.`,\n );\n }\n\n const checkpoints = fixture.replay.map((step, index) => {\n const expectedFrameId = step.expect.frameId ?? firstFrame.id;\n const frame = frameById.get(expectedFrameId);\n if (!frame) {\n throw new Error(\n `Fixture '${fixture.id}' replay step '${step.stepId}' references missing frame '${expectedFrameId}'.`,\n );\n }\n const identity = \"expectedIdentity\" in step ? step.expectedIdentity : null;\n const projectionDigest =\n step.expect.projectionDigest ?? frame.projectionDigest;\n const isFinal = index === fixture.replay.length - 1;\n const semanticDigest =\n step.expect.semanticDigest ??\n (isFinal\n ? fixture.expected.finalSemanticDigest\n : digestUIFixtureJson({\n scenarioId: fixture.id,\n stepId: step.stepId,\n frameId: frame.id,\n projectionDigest,\n }));\n const submissionDigest =\n step.expect.submissionDigest ??\n (isFinal ? fixture.expected.submissionDigest : undefined);\n\n return {\n stepId: step.stepId,\n interactionKey: identity?.interactionKey,\n interactionId: identity?.interactionId,\n actuatorId: identity?.actuatorId,\n descriptorDigest: identity?.descriptorDigest,\n draftDigest: step.expect.draftDigest ?? identity?.draftDigest,\n gameVersion: frame.frame.gameVersion,\n actionSetVersion: frame.frame.actionSetVersion,\n perspectivePlayerId: frame.frame.perspectivePlayerId,\n projectionDigest,\n semanticDigest,\n submissionDigest,\n screenshot: screenshotsByStepId[step.stepId],\n } satisfies UIParityObservationCheckpointV1;\n });\n\n return {\n schemaVersion: 1,\n scenarioId: fixture.id,\n fixtureDigest,\n sdkCandidateDigest,\n pluginRuntimeProtocol: fixture.pluginRuntimeProtocol,\n browserInteractionProtocol: fixture.browserInteractionProtocol,\n environment,\n provenance: {\n kind: \"fixture-expectation\",\n },\n checkpoints,\n diagnostics,\n };\n}\n\nexport function parseUIParityObservationV1(\n value: unknown,\n): UIParityObservationV1 {\n const observation = assertRecord(value, \"observation\");\n if (observation.schemaVersion !== 1) {\n throw new Error(\"UI parity observation schemaVersion must be 1.\");\n }\n assertString(observation.scenarioId, \"scenarioId\");\n assertString(observation.fixtureDigest, \"fixtureDigest\");\n assertString(observation.sdkCandidateDigest, \"sdkCandidateDigest\");\n if (observation.pluginRuntimeProtocol !== 3) {\n throw new Error(\"UI parity observation pluginRuntimeProtocol must be 3.\");\n }\n assertString(\n observation.browserInteractionProtocol,\n \"browserInteractionProtocol\",\n );\n const environment = assertRecord(observation.environment, \"environment\");\n assertString(environment.project, \"environment.project\");\n const viewport = assertRecord(environment.viewport, \"environment.viewport\");\n assertNumber(viewport.width, \"environment.viewport.width\");\n assertNumber(viewport.height, \"environment.viewport.height\");\n const provenance = assertRecord(\n observation.provenance,\n \"observation.provenance\",\n );\n if (\n provenance.kind !== \"fixture-expectation\" &&\n provenance.kind !== \"source-workbench\" &&\n provenance.kind !== \"packed-real-host\"\n ) {\n throw new Error(\n \"observation.provenance.kind must identify fixture, source Workbench, or packed real-host measurement.\",\n );\n }\n assertOptionalString(provenance.evidence, \"observation.provenance.evidence\");\n const checkpoints = assertArray(observation.checkpoints, \"checkpoints\");\n for (let index = 0; index < checkpoints.length; index += 1) {\n const checkpoint = assertRecord(\n checkpoints[index],\n `checkpoints[${index}]`,\n );\n assertString(checkpoint.stepId, `checkpoints[${index}].stepId`);\n assertOptionalString(\n checkpoint.interactionKey,\n `checkpoints[${index}].interactionKey`,\n );\n assertOptionalString(\n checkpoint.interactionId,\n `checkpoints[${index}].interactionId`,\n );\n assertOptionalString(\n checkpoint.actuatorId,\n `checkpoints[${index}].actuatorId`,\n );\n assertOptionalString(\n checkpoint.descriptorDigest,\n `checkpoints[${index}].descriptorDigest`,\n );\n assertOptionalString(\n checkpoint.draftDigest,\n `checkpoints[${index}].draftDigest`,\n );\n assertNumber(checkpoint.gameVersion, `checkpoints[${index}].gameVersion`);\n assertString(\n checkpoint.actionSetVersion,\n `checkpoints[${index}].actionSetVersion`,\n );\n if (\n checkpoint.perspectivePlayerId !== null &&\n typeof checkpoint.perspectivePlayerId !== \"string\"\n ) {\n throw new Error(\n `checkpoints[${index}].perspectivePlayerId must be a string or null.`,\n );\n }\n assertString(\n checkpoint.projectionDigest,\n `checkpoints[${index}].projectionDigest`,\n );\n assertString(\n checkpoint.semanticDigest,\n `checkpoints[${index}].semanticDigest`,\n );\n assertOptionalString(\n checkpoint.submissionDigest,\n `checkpoints[${index}].submissionDigest`,\n );\n assertOptionalString(\n checkpoint.screenshot,\n `checkpoints[${index}].screenshot`,\n );\n }\n const diagnostics = assertArray(observation.diagnostics, \"diagnostics\");\n for (let index = 0; index < diagnostics.length; index += 1) {\n const diagnostic = assertRecord(\n diagnostics[index],\n `diagnostics[${index}]`,\n );\n assertString(diagnostic.code, `diagnostics[${index}].code`);\n assertString(diagnostic.message, `diagnostics[${index}].message`);\n }\n return observation as unknown as UIParityObservationV1;\n}\n\nexport function compareUIParityObservations(\n expected: UIParityObservationV1,\n actual: UIParityObservationV1,\n): UIParityComparisonResult {\n for (const comparison of topLevelComparisons) {\n const result = comparePath(expected, actual, comparison);\n if (result) {\n return result;\n }\n }\n\n if (expected.checkpoints.length !== actual.checkpoints.length) {\n return mismatch({\n code: \"interaction-resolution-mismatch\",\n path: \"checkpoints.length\",\n expected: expected.checkpoints.length,\n actual: actual.checkpoints.length,\n });\n }\n\n for (let index = 0; index < expected.checkpoints.length; index += 1) {\n const expectedCheckpoint = expected.checkpoints[index]!;\n const actualCheckpoint = actual.checkpoints[index]!;\n for (const comparison of checkpointComparisons) {\n const result = comparePath(\n expectedCheckpoint,\n actualCheckpoint,\n comparison,\n {\n prefix: `checkpoints[${index}]`,\n checkpointIndex: index,\n stepId: expectedCheckpoint.stepId,\n },\n );\n if (result) {\n return result;\n }\n }\n }\n\n if (!sameValue(expected.diagnostics, actual.diagnostics)) {\n return mismatch({\n code: \"host-setup-failure\",\n path: \"diagnostics\",\n expected: expected.diagnostics,\n actual: actual.diagnostics,\n });\n }\n\n return { ok: true };\n}\n\nfunction comparePath(\n expected: unknown,\n actual: unknown,\n comparison: ComparablePath,\n options: {\n readonly prefix?: string;\n readonly checkpointIndex?: number;\n readonly stepId?: string;\n } = {},\n): UIParityComparisonResult | null {\n const expectedValue = getPath(expected, comparison.path);\n const actualValue = getPath(actual, comparison.path);\n if (sameValue(expectedValue, actualValue)) {\n return null;\n }\n const path = options.prefix\n ? `${options.prefix}.${comparison.path}`\n : comparison.path;\n return mismatch({\n code: comparison.code,\n path,\n expected: expectedValue,\n actual: actualValue,\n checkpointIndex: options.checkpointIndex,\n stepId: options.stepId,\n });\n}\n\nfunction mismatch(\n input: UIParityComparisonFailureInput,\n): UIParityComparisonResult {\n return {\n ok: false,\n failure: {\n ...input,\n message: `${input.code} at ${input.path}`,\n },\n };\n}\n\nfunction sameValue(left: unknown, right: unknown): boolean {\n if (left === undefined || right === undefined) {\n return left === right;\n }\n return canonicalUIFixtureJson(left) === canonicalUIFixtureJson(right);\n}\n\nfunction getPath(value: unknown, path: string): unknown {\n return path.split(\".\").reduce<unknown>((current, key) => {\n if (current === null || typeof current !== \"object\") {\n return undefined;\n }\n return (current as Record<string, unknown>)[key];\n }, value);\n}\n\nfunction assertRecord(value: unknown, path: string): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(`${path} must be an object.`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction assertArray(value: unknown, path: string): readonly unknown[] {\n if (!Array.isArray(value)) {\n throw new Error(`${path} must be an array.`);\n }\n return value;\n}\n\nfunction assertString(value: unknown, path: string): void {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`${path} must be a non-empty string.`);\n }\n}\n\nfunction assertOptionalString(value: unknown, path: string): void {\n if (\n value !== undefined &&\n (typeof value !== \"string\" || value.length === 0)\n ) {\n throw new Error(`${path} must be a non-empty string when present.`);\n }\n}\n\nfunction assertNumber(value: unknown, path: string): void {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`${path} must be a finite number.`);\n }\n}\n","import {\n DREAMBOARD_PLUGIN_PROTOCOL,\n DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n type HostToPluginEnvelope,\n type PluginProtocolTape,\n type PluginToHostPayload,\n type SubmitInteractionCommand,\n type ValidateInteractionCommand,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport type { PluginTransport } from \"../../runtime/core/types.js\";\nimport { digestUIFixtureTransportRequest } from \"./canonical.js\";\n\nexport interface FixtureHostEvent {\n readonly sequence: number;\n readonly atMs: number;\n readonly kind:\n | \"frame-sent\"\n | \"validate-received\"\n | \"submit-received\"\n | \"ack-received\"\n | \"ready-received\"\n | \"diagnostic\";\n readonly requestDigest?: string;\n readonly frameId?: string;\n readonly projectionDigest?: string;\n readonly result?: \"accepted\" | \"rejected\";\n}\n\nexport interface FixtureHostHarness {\n readonly transport: PluginTransport;\n readonly tape: PluginProtocolTape;\n reset(): void;\n flush(): Promise<void>;\n advanceHost(): Promise<void>;\n getCurrentFrameId(): string;\n getEvents(): readonly FixtureHostEvent[];\n assertConsumed(): void;\n}\n\nexport interface CreateFixtureHostHarnessOptions {\n readonly tape: PluginProtocolTape;\n readonly strict?: boolean;\n readonly latencyMs?: number;\n readonly channelId?: string;\n readonly onEvent?: (event: FixtureHostEvent) => void;\n readonly nowMs?: () => number;\n}\n\nconst DEFAULT_CHANNEL_ID = \"fixture-channel\";\n\nexport function createFixtureHostHarness(\n options: CreateFixtureHostHarnessOptions,\n): FixtureHostHarness {\n const strict = options.strict ?? true;\n const latencyMs = options.latencyMs ?? 0;\n const channelId = options.channelId ?? DEFAULT_CHANNEL_ID;\n const events: FixtureHostEvent[] = [];\n const frameById = new Map(\n options.tape.frames.map((frame) => [frame.id, frame]),\n );\n let eventSequence = 0;\n let envelopeSequence = 0;\n let stepCursor = 0;\n let currentFrameId: string | null = null;\n let onMessage: ((message: HostToPluginEnvelope) => void) | null = null;\n let firstFixtureError: Error | null = null;\n const pendingHandlers = new Set<Promise<void>>();\n\n const record = (event: Omit<FixtureHostEvent, \"sequence\" | \"atMs\">) => {\n const entry = {\n sequence: ++eventSequence,\n atMs: options.nowMs?.() ?? eventSequence,\n ...event,\n };\n events.push(entry);\n options.onEvent?.(entry);\n };\n\n const createFixtureError = (code: string, message: string): Error => {\n record({ kind: \"diagnostic\" });\n const error = new Error(message);\n error.name = \"FixtureHostHarnessError\";\n Object.assign(error, { errorCode: code });\n return error;\n };\n\n const rememberFixtureError = (error: unknown) => {\n if (firstFixtureError) {\n return;\n }\n firstFixtureError =\n error instanceof Error\n ? error\n : createFixtureError(\n \"fixture-unknown-error\",\n \"Fixture host failed with an unknown error.\",\n );\n };\n\n const throwFixtureError = () => {\n if (firstFixtureError) {\n throw firstFixtureError;\n }\n };\n\n const sendHostPayload = (payload: HostToPluginEnvelope[\"payload\"]) => {\n if (!onMessage) {\n return;\n }\n onMessage({\n protocol: DREAMBOARD_PLUGIN_PROTOCOL,\n version: DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n channelId,\n sequence: ++envelopeSequence,\n payload,\n });\n };\n\n const sendInit = () => {\n sendHostPayload({\n type: \"runtime.init\",\n session: options.tape.session,\n });\n };\n\n const publishFrame = (frameId: string) => {\n const frame = frameById.get(frameId);\n if (!frame) {\n throw createFixtureError(\n \"fixture-missing-frame\",\n `Plugin protocol tape references missing frame '${frameId}'.`,\n );\n }\n currentFrameId = frame.id;\n record({\n kind: \"frame-sent\",\n frameId: frame.id,\n projectionDigest: frame.projectionDigest,\n });\n sendHostPayload({\n type: \"gameplay.frame\",\n frame: frame.frame,\n });\n };\n\n const drainHostFrames = () => {\n while (options.tape.steps[stepCursor]?.kind === \"host.frame\") {\n const step = options.tape.steps[stepCursor] as Extract<\n PluginProtocolTape[\"steps\"][number],\n { kind: \"host.frame\" }\n >;\n stepCursor += 1;\n publishFrame(step.frameId);\n }\n };\n\n const drainOneHostFrame = () => {\n if (options.tape.steps[stepCursor]?.kind !== \"host.frame\") {\n return;\n }\n const step = options.tape.steps[stepCursor] as Extract<\n PluginProtocolTape[\"steps\"][number],\n { kind: \"host.frame\" }\n >;\n stepCursor += 1;\n publishFrame(step.frameId);\n };\n\n const waitForConfiguredLatency = async () => {\n if (latencyMs <= 0) {\n await Promise.resolve();\n return;\n }\n await new Promise<void>((resolve) => setTimeout(resolve, latencyMs));\n };\n\n const consumeExpectedStep = <\n Kind extends \"client.validate\" | \"client.submit\",\n >(\n kind: Kind,\n requestDigest: string,\n ): Extract<PluginProtocolTape[\"steps\"][number], { kind: Kind }> => {\n const step = options.tape.steps[stepCursor];\n if (!step) {\n throw createFixtureError(\n \"fixture-protocol-exhausted\",\n `Plugin protocol tape has no remaining step for ${kind}.`,\n );\n }\n if (step.kind !== kind) {\n throw createFixtureError(\n \"fixture-protocol-step-mismatch\",\n `Expected protocol step '${step.kind}' but received '${kind}'.`,\n );\n }\n if (step.fromFrameId !== currentFrameId) {\n throw createFixtureError(\n \"fixture-protocol-frame-mismatch\",\n `Expected protocol from frame '${step.fromFrameId}' but current frame is '${currentFrameId ?? \"<none>\"}'.`,\n );\n }\n if (step.requestDigest !== requestDigest) {\n const mode = strict ? \"strict\" : \"compatible\";\n throw createFixtureError(\n \"fixture-protocol-digest-mismatch\",\n `${mode} fixture protocol digest mismatch for ${kind}: expected ${step.requestDigest}, received ${requestDigest}.`,\n );\n }\n stepCursor += 1;\n return step as Extract<PluginProtocolTape[\"steps\"][number], { kind: Kind }>;\n };\n\n const handleValidate = async (command: ValidateInteractionCommand) => {\n const requestDigest = digestUIFixtureTransportRequest({\n operation: \"validate\",\n basis: command.basis,\n interactionId: command.interactionId,\n payload: command.params,\n });\n const step = consumeExpectedStep(\"client.validate\", requestDigest);\n record({\n kind: \"validate-received\",\n requestDigest,\n result: step.response.valid ? \"accepted\" : \"rejected\",\n });\n await waitForConfiguredLatency();\n sendHostPayload({\n type: \"interaction.validation-result\",\n requestId: command.requestId,\n result: step.response,\n });\n };\n\n const handleSubmit = async (command: SubmitInteractionCommand) => {\n const requestDigest = digestUIFixtureTransportRequest({\n operation: \"submit\",\n basis: command.basis,\n interactionId: command.interactionId,\n payload: command.params,\n });\n const step = consumeExpectedStep(\"client.submit\", requestDigest);\n record({\n kind: \"submit-received\",\n requestDigest,\n result: step.response.accepted ? \"accepted\" : \"rejected\",\n });\n await waitForConfiguredLatency();\n sendHostPayload({\n type: \"interaction.submit-result\",\n requestId: command.requestId,\n result: step.response,\n });\n if (step.response.accepted) {\n await waitForConfiguredLatency();\n drainHostFrames();\n }\n };\n\n const handleClientPayload = (payload: PluginToHostPayload) => {\n const trackHandler = (promise: Promise<void>) => {\n pendingHandlers.add(promise);\n promise\n .catch((error) => {\n rememberFixtureError(error);\n })\n .finally(() => {\n pendingHandlers.delete(promise);\n });\n };\n\n switch (payload.type) {\n case \"runtime.ready\":\n record({ kind: \"ready-received\" });\n break;\n case \"runtime.ack\":\n record({ kind: \"ack-received\" });\n break;\n case \"interaction.validate\":\n trackHandler(handleValidate(payload));\n break;\n case \"interaction.submit\":\n trackHandler(handleSubmit(payload));\n break;\n case \"runtime.error\":\n record({ kind: \"diagnostic\" });\n break;\n default: {\n const _exhaustive: never = payload;\n return _exhaustive;\n }\n }\n };\n\n const transport: PluginTransport = {\n start(nextOnMessage) {\n onMessage = nextOnMessage;\n queueMicrotask(() => {\n sendInit();\n drainOneHostFrame();\n });\n return () => {\n onMessage = null;\n };\n },\n send(message) {\n handleClientPayload(message);\n },\n };\n\n return {\n transport,\n tape: options.tape,\n reset() {\n eventSequence = 0;\n envelopeSequence = 0;\n stepCursor = 0;\n currentFrameId = null;\n firstFixtureError = null;\n pendingHandlers.clear();\n events.length = 0;\n if (onMessage) {\n sendInit();\n drainOneHostFrame();\n }\n },\n async flush() {\n await waitForConfiguredLatency();\n await Promise.resolve();\n while (pendingHandlers.size > 0) {\n await Promise.allSettled([...pendingHandlers]);\n }\n throwFixtureError();\n },\n async advanceHost() {\n await waitForConfiguredLatency();\n drainHostFrames();\n throwFixtureError();\n },\n getCurrentFrameId() {\n if (!currentFrameId) {\n throw createFixtureError(\n \"fixture-frame-not-started\",\n \"Fixture host has not emitted a gameplay frame.\",\n );\n }\n return currentFrameId;\n },\n getEvents() {\n return events.map((event) => ({ ...event }));\n },\n assertConsumed() {\n throwFixtureError();\n if (stepCursor !== options.tape.steps.length) {\n throw createFixtureError(\n \"fixture-unconsumed-protocol-steps\",\n `Plugin protocol tape consumed ${stepCursor} of ${options.tape.steps.length} protocol step(s).`,\n );\n }\n },\n };\n}\n","import React, { useMemo } from \"react\";\nimport { createPluginRuntimeClient } from \"../../runtime/core/create-plugin-runtime-client.js\";\nimport { PluginRuntimeBoundary } from \"../../runtime/components/PluginRuntimeBoundary.js\";\nimport type { PluginRuntimeClient } from \"../../runtime/core/types.js\";\nimport type { FixtureHostHarness } from \"./create-fixture-host-harness.js\";\n\nexport function FixturePluginRuntime({\n harness,\n runtime,\n children,\n}: {\n harness: FixtureHostHarness;\n runtime?: PluginRuntimeClient;\n children: React.ReactNode;\n}) {\n const fixtureRuntime = useMemo(\n () =>\n runtime ?? createPluginRuntimeClient({ transport: harness.transport }),\n [harness.transport, runtime],\n );\n return (\n <PluginRuntimeBoundary runtime={fixtureRuntime}>\n {children}\n </PluginRuntimeBoundary>\n );\n}\n","import {\n materializePluginGameplayFrame,\n type PluginSessionDescriptor,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport { digestUIFixtureTransportRequest } from \"./canonical.js\";\nimport type { PluginProtocolTape, UIFixtureFrame } from \"./schema.js\";\nimport type { UIFixtureProtocolStep } from \"./schema.js\";\nimport type {\n ReducerScenarioExchange,\n ReducerScenarioFrame,\n ReducerScenarioTrace,\n} from \"../reducer-scenario/types.js\";\n\nexport interface CompilePluginProtocolTapeOptions {\n readonly trace: ReducerScenarioTrace;\n readonly session: PluginSessionDescriptor;\n}\n\nexport function compilePluginProtocolTape(\n options: CompilePluginProtocolTapeOptions,\n): PluginProtocolTape {\n const frames = options.trace.frames.map((frame) =>\n materializeTraceFrame(frame, options.trace.viewer.playerId),\n );\n const frameById = new Map(frames.map((frame) => [frame.id, frame]));\n const steps: UIFixtureProtocolStep[] = [];\n\n const firstFrame = frames[0];\n if (!firstFrame) {\n throw new Error(\n `Reducer scenario '${options.trace.scenarioId}' did not record frames.`,\n );\n }\n steps.push({\n id: `${firstFrame.id}.host-frame`,\n kind: \"host.frame\",\n frameId: firstFrame.id,\n });\n\n for (const exchange of options.trace.exchanges) {\n const fromFrame = frameById.get(exchange.fromFrameId);\n if (!fromFrame) {\n throw new Error(\n `Reducer exchange '${exchange.id}' references missing frame '${exchange.fromFrameId}'.`,\n );\n }\n if (exchange.operation === \"validate\") {\n steps.push({\n id: exchange.id,\n kind: \"client.validate\",\n fromFrameId: exchange.fromFrameId,\n requestDigest: digestRuntimeCommand(exchange, fromFrame),\n response: {\n valid: exchange.result.valid,\n errorCode: exchange.result.errorCode,\n message: exchange.result.message,\n },\n });\n continue;\n }\n\n steps.push({\n id: exchange.id,\n kind: \"client.submit\",\n fromFrameId: exchange.fromFrameId,\n requestDigest: digestRuntimeCommand(exchange, fromFrame),\n response:\n exchange.result.kind === \"accepted\"\n ? { accepted: true }\n : {\n accepted: false,\n errorCode:\n exchange.result.diagnostics[0]?.code ?? \"fixture-rejected\",\n message: exchange.result.diagnostics[0]?.message,\n },\n });\n if (exchange.result.kind === \"accepted\") {\n if (!frameById.has(exchange.result.toFrameId)) {\n throw new Error(\n `Reducer exchange '${exchange.id}' references missing toFrameId '${exchange.result.toFrameId}'.`,\n );\n }\n steps.push({\n id: `${exchange.id}.host-frame`,\n kind: \"host.frame\",\n frameId: exchange.result.toFrameId,\n });\n }\n }\n\n return {\n session: options.session,\n frames,\n steps,\n };\n}\n\nfunction materializeTraceFrame(\n frame: ReducerScenarioFrame,\n perspectivePlayerId: string,\n): UIFixtureFrame {\n const flow = readFlowState(frame.reducerState);\n return {\n id: frame.id,\n frame: materializePluginGameplayFrame({\n currentPhase: flow.currentPhase,\n activePlayers: flow.activePlayers,\n dynamicProjection: frame.dynamicProjection,\n staticProjection: frame.staticProjection,\n perspectivePlayerId,\n gameVersion: frame.gameVersion,\n actionSetVersion: frame.actionSetVersion,\n }),\n projectionDigest: frame.projectionDigest,\n };\n}\n\nfunction digestRuntimeCommand(\n exchange: ReducerScenarioExchange,\n frame: UIFixtureFrame,\n): string {\n return digestUIFixtureTransportRequest({\n operation: exchange.operation === \"validate\" ? \"validate\" : \"submit\",\n basis: {\n gameVersion: frame.frame.gameVersion,\n actionSetVersion: frame.frame.actionSetVersion,\n perspectivePlayerId: frame.frame.perspectivePlayerId,\n },\n interactionId: exchange.input.interactionId,\n payload: exchange.input.params,\n });\n}\n\nfunction readFlowState(state: {\n readonly domain?: {\n readonly flow?: {\n readonly currentPhase?: string;\n readonly activePlayers?: readonly string[];\n };\n };\n}): { currentPhase: string | null; activePlayers: readonly string[] } {\n return {\n currentPhase: state.domain?.flow?.currentPhase ?? null,\n activePlayers: [...(state.domain?.flow?.activePlayers ?? [])],\n };\n}\n","export interface FixtureEnvironmentInit {\n readonly clockIso: string;\n readonly randomSeed: string;\n readonly locale: \"en-US\";\n readonly timezone: \"UTC\";\n readonly reducedMotion: true;\n readonly network: \"blocked\";\n}\n\nexport const defaultFixtureEnvironmentInit: FixtureEnvironmentInit = {\n clockIso: \"2026-01-01T00:00:00.000Z\",\n randomSeed: \"dreamboard-ui-fixture\",\n locale: \"en-US\",\n timezone: \"UTC\",\n reducedMotion: true,\n network: \"blocked\",\n};\n\nexport type DeterministicIdFactory = () => string;\n\nexport function createDeterministicIdFactory(\n seed: string,\n): DeterministicIdFactory {\n let cursor = 0;\n return () => {\n cursor += 1;\n return `fixture-${slug(seed)}-${cursor.toString(36).padStart(4, \"0\")}`;\n };\n}\n\nexport function fixtureEnvironmentInitFor(options: {\n readonly clockIso: string;\n readonly randomSeed: string;\n}): FixtureEnvironmentInit {\n return {\n ...defaultFixtureEnvironmentInit,\n clockIso: options.clockIso,\n randomSeed: options.randomSeed,\n };\n}\n\nfunction slug(value: string): string {\n return (\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 48) || \"seed\"\n );\n}\n","import { z } from \"zod\";\nimport {\n BROWSER_INTERACTION_ACTUATOR_KINDS,\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n browserInteractionEffectSchema,\n} from \"../../browser-interaction/index.js\";\nimport type {\n BrowserInteractionEffectRequest,\n BrowserInteractionIntentRequest,\n} from \"../../browser-interaction/index.js\";\nimport { RuntimeJsonSchema } from \"../../runtime-json.js\";\nimport { digestUIFixtureRequest, isSha256Digest } from \"./canonical.js\";\nimport {\n DREAMBOARD_PLUGIN_PROTOCOL_VERSION as PLUGIN_RUNTIME_PROTOCOL_VERSION,\n PluginProtocolFrameSchema,\n PluginProtocolStepSchema,\n PluginProtocolTapeSchema,\n type PluginProtocolFrame,\n type PluginProtocolStep,\n type PluginProtocolTape as RuntimePluginProtocolTape,\n} from \"@dreamboard-games/plugin-runtime-contract\";\n\nexport const UI_SCENARIO_FIXTURE_SCHEMA_VERSION = 2;\nexport const UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION = 2;\nexport const UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR = 3;\nexport const UI_SCENARIO_FIXTURE_PLUGIN_RUNTIME_PROTOCOL =\n PLUGIN_RUNTIME_PROTOCOL_VERSION;\n\nconst digestSchema = z.string().refine(isSha256Digest, {\n message: \"Expected a sha256:<64 lowercase hex> digest.\",\n});\n\nconst nonEmptyStringSchema = z.string().min(1);\nconst jsonSchema = RuntimeJsonSchema;\n\nconst environmentSchema = z\n .object({\n clockIso: nonEmptyStringSchema,\n randomSeed: nonEmptyStringSchema,\n locale: z.literal(\"en-US\"),\n timezone: z.literal(\"UTC\"),\n viewportTags: z.array(z.enum([\"desktop\", \"tablet\", \"phone\", \"touch\"])),\n })\n .strict();\n\nexport const uiFixtureFrameSchema = PluginProtocolFrameSchema;\nexport const uiFixtureProtocolStepSchema = PluginProtocolStepSchema;\nexport const pluginProtocolTapeSchema = PluginProtocolTapeSchema.refine(\n (tape) => tape.frames.length > 0,\n \"UI fixture protocol tapes require at least one gameplay frame.\",\n);\n\nconst browserInteractionIntentRequestSchema = z\n .object({\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema.optional(),\n interactionKey: nonEmptyStringSchema.optional(),\n interactionId: nonEmptyStringSchema.optional(),\n intent: nonEmptyStringSchema,\n inputKey: nonEmptyStringSchema.optional(),\n candidateValue: jsonSchema.optional(),\n candidateValueKey: nonEmptyStringSchema.optional(),\n actuatorKind: z.enum(BROWSER_INTERACTION_ACTUATOR_KINDS).optional(),\n allowDisabled: z.boolean().optional(),\n })\n .strict();\n\nconst browserInteractionEffectRequestSchema = z\n .object({\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema.optional(),\n interactionKey: nonEmptyStringSchema.optional(),\n interactionId: nonEmptyStringSchema.optional(),\n effect: browserInteractionEffectSchema,\n allowDisabled: z.boolean().optional(),\n })\n .strict();\n\nexport const uiReplayRequestSchema = z.union([\n browserInteractionIntentRequestSchema,\n browserInteractionEffectRequestSchema,\n]);\n\nexport const uiReplayExecutionSchema = z.union([\n z\n .object({\n kind: z.literal(\"activate\"),\n })\n .strict(),\n z\n .object({\n kind: z.literal(\"fill\"),\n value: z.string(),\n })\n .strict(),\n z\n .object({\n kind: z.literal(\"drag\"),\n target: browserInteractionEffectRequestSchema,\n })\n .strict(),\n]);\n\nexport const uiStepExpectationSchema = z\n .object({\n frameId: nonEmptyStringSchema.optional(),\n projectionDigest: digestSchema.optional(),\n semanticDigest: digestSchema.optional(),\n draftDigest: digestSchema.optional(),\n submissionDigest: digestSchema.optional(),\n focusedInteractionKey: nonEmptyStringSchema.optional(),\n visibleInteractionKeys: z.array(nonEmptyStringSchema).optional(),\n })\n .strict();\n\nexport const uiResolvedReplayIdentitySchema = z\n .object({\n stepId: nonEmptyStringSchema,\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema,\n interactionKey: nonEmptyStringSchema,\n interactionId: nonEmptyStringSchema,\n actuatorId: nonEmptyStringSchema,\n descriptorDigest: digestSchema.optional(),\n draftDigest: digestSchema.optional(),\n })\n .strict();\n\nexport const portableSemanticReplayStepSchema = z\n .object({\n stepId: nonEmptyStringSchema,\n requestDigest: digestSchema,\n resolve: uiReplayRequestSchema,\n execute: uiReplayExecutionSchema,\n expectedIdentity: uiResolvedReplayIdentitySchema.optional(),\n expect: uiStepExpectationSchema,\n })\n .strict();\n\nexport const uiScenarioReplayStepSchema = z.union([\n portableSemanticReplayStepSchema,\n z\n .object({\n stepId: nonEmptyStringSchema,\n kind: z.literal(\"assert\"),\n expect: uiStepExpectationSchema,\n })\n .strict(),\n]);\n\nexport const uiScenarioFixtureSchema = z\n .object({\n schemaVersion: z.literal(UI_SCENARIO_FIXTURE_SCHEMA_VERSION),\n browserInteractionProtocol: z.literal(\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n ),\n pluginRuntimeProtocol: z.literal(PLUGIN_RUNTIME_PROTOCOL_VERSION),\n id: nonEmptyStringSchema,\n title: nonEmptyStringSchema,\n gameId: nonEmptyStringSchema,\n tags: z.array(nonEmptyStringSchema),\n source: z\n .object({\n scenarioId: nonEmptyStringSchema,\n reducerFingerprint: nonEmptyStringSchema,\n uiContractFingerprint: nonEmptyStringSchema,\n renderModule: nonEmptyStringSchema,\n renderModuleDigest: digestSchema,\n sourceDigest: digestSchema,\n sourceFiles: z.array(nonEmptyStringSchema).optional(),\n })\n .strict(),\n viewer: z\n .object({\n seatId: nonEmptyStringSchema,\n playerId: nonEmptyStringSchema.optional(),\n })\n .strict(),\n environment: environmentSchema,\n protocol: pluginProtocolTapeSchema,\n replay: z.array(uiScenarioReplayStepSchema),\n expected: z\n .object({\n initialProjectionDigest: digestSchema,\n finalProjectionDigest: digestSchema,\n finalSemanticDigest: digestSchema,\n submissionDigest: digestSchema,\n })\n .strict(),\n })\n .strict();\n\nexport const uiScenarioFixtureBundleIndexSchema = z\n .object({\n schemaVersion: z.literal(UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION),\n bundleId: nonEmptyStringSchema,\n sdkCommit: nonEmptyStringSchema,\n pluginRuntimeProtocol: z.literal(PLUGIN_RUNTIME_PROTOCOL_VERSION),\n browserInteractionProtocol: z.literal(\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n ),\n fixtures: z.array(\n z\n .object({\n id: nonEmptyStringSchema,\n file: nonEmptyStringSchema,\n sha256: digestSchema,\n renderModule: nonEmptyStringSchema,\n renderModuleSha256: digestSchema,\n components: z.array(nonEmptyStringSchema),\n capabilities: z.array(nonEmptyStringSchema),\n })\n .strict(),\n ),\n })\n .strict();\n\nexport type UIReplayRequest =\n | BrowserInteractionIntentRequest\n | BrowserInteractionEffectRequest;\nexport type UIReplayExecution = z.infer<typeof uiReplayExecutionSchema>;\nexport type UIStepExpectation = z.infer<typeof uiStepExpectationSchema>;\nexport type UIResolvedReplayIdentity = z.infer<\n typeof uiResolvedReplayIdentitySchema\n>;\nexport type PortableSemanticReplayStep = z.infer<\n typeof portableSemanticReplayStepSchema\n>;\nexport type UIScenarioReplayStep = z.infer<typeof uiScenarioReplayStepSchema>;\nexport type UIFixtureFrame = PluginProtocolFrame;\nexport type UIFixtureProtocolStep = PluginProtocolStep;\nexport type PluginProtocolTape = RuntimePluginProtocolTape;\nexport type UIScenarioFixture = Omit<\n z.infer<typeof uiScenarioFixtureSchema>,\n \"protocol\" | \"replay\"\n> & {\n readonly protocol: PluginProtocolTape;\n readonly replay: readonly UIScenarioReplayStep[];\n};\nexport type UIScenarioFixtureBundleIndex = z.infer<\n typeof uiScenarioFixtureBundleIndexSchema\n>;\n\nexport function parseUIScenarioFixture(value: unknown): UIScenarioFixture {\n const fixture = uiScenarioFixtureSchema.parse(\n value,\n ) as unknown as UIScenarioFixture;\n validateUIScenarioFixtureReferences(fixture);\n return fixture;\n}\n\nexport function parseUIScenarioFixtureBundleIndex(\n value: unknown,\n): UIScenarioFixtureBundleIndex {\n const bundle = uiScenarioFixtureBundleIndexSchema.parse(value);\n assertSupportedBrowserInteractionProtocol(bundle.browserInteractionProtocol);\n const ids = new Set<string>();\n for (const entry of bundle.fixtures) {\n if (ids.has(entry.id)) {\n throw new Error(`Duplicate fixture id '${entry.id}' in bundle index.`);\n }\n ids.add(entry.id);\n }\n return bundle;\n}\n\nexport function assertSupportedBrowserInteractionProtocol(\n version: string,\n): void {\n const major = Number(version.split(\".\")[0]);\n if (major !== UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR) {\n throw new Error(\n `Unsupported browser-interaction protocol '${version}'. Expected major ${UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR}.`,\n );\n }\n}\n\nfunction validateUIScenarioFixtureReferences(fixture: UIScenarioFixture): void {\n assertSupportedBrowserInteractionProtocol(fixture.browserInteractionProtocol);\n const frameIds = new Set<string>();\n const stepIds = new Set<string>();\n\n for (const frame of fixture.protocol.frames) {\n if (frameIds.has(frame.id)) {\n throw new Error(`Duplicate fixture frame id '${frame.id}'.`);\n }\n frameIds.add(frame.id);\n }\n\n for (const step of fixture.protocol.steps) {\n if (stepIds.has(step.id)) {\n throw new Error(`Duplicate protocol step id '${step.id}'.`);\n }\n stepIds.add(step.id);\n if (step.kind === \"host.frame\") {\n if (!frameIds.has(step.frameId)) {\n throw new Error(\n `Protocol step '${step.id}' references missing frameId '${step.frameId}'.`,\n );\n }\n continue;\n }\n if (!frameIds.has(step.fromFrameId)) {\n throw new Error(\n `Protocol step '${step.id}' references missing fromFrameId '${step.fromFrameId}'.`,\n );\n }\n }\n\n for (const step of fixture.replay) {\n if (\"resolve\" in step) {\n const actualDigest = digestUIFixtureRequest(\n step.resolve as unknown as UIReplayRequest,\n );\n if (step.requestDigest !== actualDigest) {\n throw new Error(\n `Replay step '${step.stepId}' requestDigest ${step.requestDigest} does not match ${actualDigest}.`,\n );\n }\n }\n const expectedFrameId = step.expect.frameId;\n if (expectedFrameId && !frameIds.has(expectedFrameId)) {\n throw new Error(\n `Replay step '${step.stepId}' expects missing frameId '${expectedFrameId}'.`,\n );\n }\n }\n}\n","import {\n canonicalizeUIScenarioFixture,\n digestUIFixtureJson,\n serializeUIScenarioFixture,\n} from \"./canonical.js\";\nimport { DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION } from \"../../browser-interaction/index.js\";\nimport { DREAMBOARD_PLUGIN_PROTOCOL_VERSION as PLUGIN_RUNTIME_PROTOCOL_VERSION } from \"@dreamboard-games/plugin-runtime-contract\";\nimport {\n parseUIScenarioFixture,\n type PortableSemanticReplayStep,\n type PluginProtocolTape,\n type UIResolvedReplayIdentity,\n type UIScenarioFixture,\n type UIScenarioReplayStep,\n type UIStepExpectation,\n} from \"./schema.js\";\n\nexport interface CompileUIScenarioFixtureOptions {\n readonly id: string;\n readonly title: string;\n readonly gameId: string;\n readonly tags?: readonly string[];\n readonly source: UIScenarioFixture[\"source\"];\n readonly viewer: UIScenarioFixture[\"viewer\"];\n readonly environment: UIScenarioFixture[\"environment\"];\n readonly protocol: PluginProtocolTape;\n readonly replay?: readonly UIScenarioReplayStep[];\n readonly expected?: Partial<UIScenarioFixture[\"expected\"]>;\n}\n\nexport type UIReplayIdentityCandidate = UIResolvedReplayIdentity;\n\nexport function compileUIScenarioFixture(\n options: CompileUIScenarioFixtureOptions,\n): UIScenarioFixture {\n const firstFrame = options.protocol.frames[0];\n const finalFrame = lastPublishedFrame(options.protocol);\n if (!firstFrame || !finalFrame) {\n throw new Error(\n \"compileUIScenarioFixture requires at least one protocol frame.\",\n );\n }\n\n const replay = options.replay ?? [];\n const submissionDigest =\n options.expected?.submissionDigest ??\n digestUIFixtureJson({\n digestVersion: \"ui-submission@1\",\n fixtureId: options.id,\n replay: replay.map((step) =>\n \"requestDigest\" in step ? step.requestDigest : step.stepId,\n ),\n });\n const finalSemanticDigest =\n options.expected?.finalSemanticDigest ??\n digestUIFixtureJson({\n digestVersion: \"ui-semantic@1\",\n fixtureId: options.id,\n frameId: finalFrame.id,\n projectionDigest: finalFrame.projectionDigest,\n });\n\n return parseUIScenarioFixture(\n canonicalizeUIScenarioFixture({\n schemaVersion: 2,\n browserInteractionProtocol:\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n pluginRuntimeProtocol: PLUGIN_RUNTIME_PROTOCOL_VERSION,\n id: options.id,\n title: options.title,\n gameId: options.gameId,\n tags: [...(options.tags ?? [])],\n source: options.source,\n viewer: options.viewer,\n environment: options.environment,\n protocol: options.protocol,\n replay,\n expected: {\n initialProjectionDigest:\n options.expected?.initialProjectionDigest ??\n firstFrame.projectionDigest,\n finalProjectionDigest:\n options.expected?.finalProjectionDigest ??\n finalFrame.projectionDigest,\n finalSemanticDigest,\n submissionDigest,\n },\n }),\n );\n}\n\nfunction lastPublishedFrame(\n protocol: PluginProtocolTape,\n): PluginProtocolTape[\"frames\"][number] | undefined {\n const frameById = new Map(protocol.frames.map((frame) => [frame.id, frame]));\n for (let index = protocol.steps.length - 1; index >= 0; index -= 1) {\n const step = protocol.steps[index];\n if (step?.kind === \"host.frame\") {\n return frameById.get(step.frameId);\n }\n }\n return protocol.frames[protocol.frames.length - 1];\n}\n\nexport function assertDeterministicUIScenarioFixture(\n first: UIScenarioFixture,\n second: UIScenarioFixture,\n): void {\n const firstBytes = serializeUIScenarioFixture(first);\n const secondBytes = serializeUIScenarioFixture(second);\n if (firstBytes !== secondBytes) {\n throw new Error(\n `UI scenario fixture '${first.id}' is non-deterministic across compilation runs.`,\n );\n }\n}\n\nexport function assertUniqueReplayIdentity(\n step: Pick<PortableSemanticReplayStep, \"stepId\" | \"expectedIdentity\">,\n candidates: readonly UIReplayIdentityCandidate[],\n): UIReplayIdentityCandidate {\n if (candidates.length !== 1) {\n throw new Error(\n `Replay step '${step.stepId}' resolved ${candidates.length} identities; expected exactly one.`,\n );\n }\n const candidate = candidates[0];\n if (!candidate) {\n throw new Error(`Replay step '${step.stepId}' did not resolve.`);\n }\n\n const expected = step.expectedIdentity;\n if (!expected) {\n return candidate;\n }\n for (const key of [\n \"surface\",\n \"scopeId\",\n \"interactionKey\",\n \"interactionId\",\n \"actuatorId\",\n \"descriptorDigest\",\n \"draftDigest\",\n ] as const) {\n const expectedValue = expected[key];\n if (expectedValue !== undefined && candidate[key] !== expectedValue) {\n throw new Error(\n `Replay step '${step.stepId}' resolved ${key} '${String(\n candidate[key],\n )}', expected '${expectedValue}'.`,\n );\n }\n }\n return candidate;\n}\n\nexport function assertUIStepExpectationSatisfied(\n stepId: string,\n expected: UIStepExpectation,\n actual: UIStepExpectation,\n): void {\n for (const key of [\n \"frameId\",\n \"projectionDigest\",\n \"semanticDigest\",\n \"draftDigest\",\n \"submissionDigest\",\n \"focusedInteractionKey\",\n ] as const) {\n if (expected[key] !== undefined && expected[key] !== actual[key]) {\n throw new Error(\n `Replay step '${stepId}' expected ${key} '${expected[key]}', received '${actual[key]}'.`,\n );\n }\n }\n if (expected.visibleInteractionKeys) {\n const actualKeys = new Set(actual.visibleInteractionKeys ?? []);\n const missing = expected.visibleInteractionKeys.filter(\n (key) => !actualKeys.has(key),\n );\n if (missing.length > 0) {\n throw new Error(\n `Replay step '${stepId}' missing visible interactions: ${missing.join(\n \", \",\n )}.`,\n );\n }\n }\n}\n","import {\n digestUIFixtureRequest,\n type PortableSemanticReplayStep,\n type UIResolvedReplayIdentity,\n type UIScenarioReplayStep,\n type UIStepExpectation,\n} from \"../ui-fixture/index.js\";\n\ntype ReplayRequest = PortableSemanticReplayStep[\"resolve\"];\ntype DragTarget = Extract<\n PortableSemanticReplayStep[\"execute\"],\n { kind: \"drag\" }\n>[\"target\"];\n\ninterface ReplayStepOptions {\n readonly stepId: string;\n readonly resolve: ReplayRequest;\n readonly expect: UIStepExpectation;\n readonly expectedIdentity?: UIResolvedReplayIdentity;\n}\n\ninterface FillReplayStepOptions extends ReplayStepOptions {\n readonly value: string;\n}\n\ninterface DragReplayStepOptions extends ReplayStepOptions {\n readonly target: DragTarget;\n}\n\nfunction semanticStep(\n options: ReplayStepOptions,\n execute: Exclude<UIScenarioReplayStep, { kind: \"assert\" }>[\"execute\"],\n): UIScenarioReplayStep {\n return {\n stepId: options.stepId,\n requestDigest: digestUIFixtureRequest(options.resolve),\n resolve: options.resolve,\n execute,\n expectedIdentity: options.expectedIdentity,\n expect: options.expect,\n };\n}\n\nexport function activate(options: ReplayStepOptions): UIScenarioReplayStep {\n return semanticStep(options, { kind: \"activate\" });\n}\n\nexport function fill(options: FillReplayStepOptions): UIScenarioReplayStep {\n return semanticStep(options, { kind: \"fill\", value: options.value });\n}\n\nexport function press(options: ReplayStepOptions): UIScenarioReplayStep {\n return activate(options);\n}\n\nexport function drag(options: DragReplayStepOptions): UIScenarioReplayStep {\n return semanticStep(options, { kind: \"drag\", target: options.target });\n}\n\nexport function submit(options: ReplayStepOptions): UIScenarioReplayStep {\n return activate(options);\n}\n\nexport function assertStep(\n stepId: string,\n expect: UIStepExpectation,\n): UIScenarioReplayStep {\n return {\n stepId,\n kind: \"assert\",\n expect,\n };\n}\n"],"mappings":"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","names":["result","readFlowState"]}
1
+ {"version":3,"sources":["../src/testing/inspection/flow-diagnostic.ts","../src/testing/inspection/inspect-scenario.ts","../src/testing/exploration/cursor.ts","../src/testing/exploration/explore-scenario.ts","../src/testing/ui-fixture/canonical.ts","../src/testing/reducer-scenario/create-reducer-scenario-runner.ts","../src/testing/ui-scenario/define-ui-scenario.ts","../src/testing/ui-fixture/parity.ts","../src/testing/ui-fixture/create-fixture-host-harness.ts","../src/testing/ui-fixture/FixturePluginRuntime.tsx","../src/testing/ui-fixture/compile-plugin-protocol-tape.ts","../src/testing/ui-fixture/deterministic-environment.ts","../src/testing/ui-fixture/schema.ts","../src/testing/ui-fixture/compiler.ts","../src/testing/ui-scenario/replay-builders.ts"],"sourcesContent":["import type { ActorRef, FlowDiagnostic } from \"./types.js\";\n\nexport type SchedulerFlowProjection = {\n readonly phase: string;\n readonly step: string | null;\n readonly activePlayerIds: readonly string[];\n readonly pendingPlayerIds: readonly string[];\n /**\n * Causal continuation ownership supplied by trusted scheduler authority.\n * An empty list means the scheduler has proved no edge or cannot prove one;\n * callers must never infer an edge from inactive turns or descriptor prose.\n */\n readonly continuationDependencies?: readonly {\n readonly waiterPlayerId: string;\n readonly blockerPlayerIds: readonly string[];\n }[];\n};\n\nexport function createFlowDiagnostic(options: {\n readonly scheduler: SchedulerFlowProjection;\n readonly playerIds: readonly string[];\n}): FlowDiagnostic {\n const actor = (playerId: string): ActorRef | null => {\n const seat = options.playerIds.indexOf(playerId);\n return seat < 0 ? null : { seat, playerId };\n };\n const actors = (playerIds: readonly string[]): ActorRef[] =>\n [...new Set(playerIds)]\n .flatMap((playerId) => {\n const resolved = actor(playerId);\n return resolved ? [resolved] : [];\n })\n .sort((left, right) => left.seat - right.seat);\n\n const blockedBy = (options.scheduler.continuationDependencies ?? [])\n .flatMap((dependency) => {\n const waiter = actor(dependency.waiterPlayerId);\n const blockers = actors(dependency.blockerPlayerIds);\n return waiter && blockers.length > 0\n ? [\n {\n actor: waiter,\n blockers,\n source: \"scheduler\" as const,\n },\n ]\n : [];\n })\n .sort((left, right) => left.actor.seat - right.actor.seat);\n\n return {\n phase: options.scheduler.phase,\n step: options.scheduler.step,\n activeActors: actors(options.scheduler.activePlayerIds),\n pendingActors: actors(options.scheduler.pendingPlayerIds),\n continuationWaiters: actors(\n blockedBy.map((dependency) => dependency.actor.playerId),\n ),\n blockedBy,\n };\n}\n","import type { InteractionDescriptorLike } from \"../definitions.js\";\nimport type {\n ScenarioCheckpoint,\n ScenarioCommandTraceEntry,\n ScenarioReplay,\n ScenarioReplayDefinition,\n} from \"../definitions.js\";\nimport type { ScenarioDefinitionGameLike } from \"../scenario-definition-validation.js\";\nimport {\n inspectScenarioReplayAuthority,\n replayScenario,\n} from \"../scenario-replay.js\";\nimport { createFlowDiagnostic } from \"./flow-diagnostic.js\";\nimport type {\n ActorRef,\n InspectAction,\n InspectInteraction,\n InspectNode,\n InspectScenarioResult,\n PerspectiveRef,\n PerspectiveSelector,\n ScenarioDispatchTraceEntry,\n ScenarioIdentity,\n Sha256Digest,\n} from \"./types.js\";\n\nexport class ScenarioInspectionError extends Error {\n readonly code:\n | \"TEST_PERSPECTIVE_INVALID\"\n | \"TEST_SCENARIO_INVALID\"\n | \"TEST_SEED_RANGE_INVALID\";\n readonly context: Readonly<Record<string, string | number | boolean>>;\n\n constructor(options: {\n readonly code: ScenarioInspectionError[\"code\"];\n readonly message: string;\n readonly context?: Readonly<Record<string, string | number | boolean>>;\n }) {\n super(options.message);\n this.name = \"ScenarioInspectionError\";\n this.code = options.code;\n this.context = options.context ?? {};\n }\n}\n\nexport type InspectScenarioOptions<Game extends ScenarioDefinitionGameLike> = {\n readonly game: Game;\n readonly scenario: ScenarioReplayDefinition<Game>;\n readonly identity: ScenarioIdentity;\n readonly perspective: PerspectiveSelector;\n readonly at?: ScenarioCheckpoint;\n readonly seed?: number;\n};\n\nexport async function inspectScenario<\n const Game extends ScenarioDefinitionGameLike,\n>(options: InspectScenarioOptions<Game>): Promise<InspectScenarioResult> {\n assertScenarioIdentity(options.identity, options.scenario);\n assertSeed(options.seed);\n const selectedScenario =\n options.seed === undefined\n ? options.scenario\n : {\n ...options.scenario,\n setup: { ...options.scenario.setup, seed: options.seed },\n };\n const checkpoint =\n options.at ??\n ({\n segment: \"given\",\n completed: selectedScenario.given.length,\n } satisfies ScenarioCheckpoint);\n const replay = await replayScenario({\n game: options.game,\n scenario: selectedScenario,\n at: checkpoint,\n });\n const node = inspectScenarioReplayNode({\n replay,\n perspective: options.perspective,\n });\n return {\n schemaVersion: 1,\n scenario: structuredClone(options.identity),\n node,\n seedSource: options.seed === undefined ? \"scenario\" : \"override\",\n };\n}\n\nexport function inspectScenarioReplayNode<Game>(options: {\n readonly replay: ScenarioReplay<Game>;\n readonly perspective: PerspectiveSelector;\n}): InspectNode {\n const baseAuthority = inspectScenarioReplayAuthority({\n replay: options.replay,\n perspective: { kind: \"spectator\" },\n });\n const perspective = resolvePerspective(\n options.perspective,\n baseAuthority.scenario.setup.players,\n baseAuthority.playerIds,\n );\n const authority = inspectScenarioReplayAuthority({\n replay: options.replay,\n perspective:\n perspective.kind === \"spectator\"\n ? perspective\n : { kind: \"player\", seat: perspective.actor.seat },\n });\n const actor = perspective.kind === \"player\" ? perspective.actor : null;\n const interactions = actor\n ? authority.interactions.map(({ descriptor, explanation }) =>\n inspectInteraction(actor, descriptor, explanation),\n )\n : [];\n const actions = actor\n ? authority.interactions.flatMap(\n ({ explanation, actionability }): InspectAction[] => {\n if (\n !actionability.found ||\n !actionability.visible ||\n actionability.descriptor.availability.status !== \"available\" ||\n actionability.inputSatisfiability?.status !== \"yes\"\n ) {\n return [];\n }\n return [\n {\n actor,\n interactionId: actionability.descriptor.interactionId,\n inputs: explanation.inputs,\n explanation,\n hasConcreteCommand: true,\n },\n ];\n },\n )\n : [];\n const node: InspectNode = {\n checkpoint: authority.checkpoint,\n checkpointDigest: authority.checkpointDigest as Sha256Digest,\n setup: structuredClone(authority.scenario.setup),\n flow: createFlowDiagnostic({\n playerIds: authority.playerIds,\n scheduler: authority.scheduler,\n }),\n perspective,\n publicState: authority.publicState,\n view: authority.view,\n interactions,\n actions,\n entropy: {\n seed: authority.entropy.seed ?? authority.scenario.setup.seed,\n draws: structuredClone(authority.entropy.draws),\n },\n dispatchTrace: projectDispatchTrace(\n authority.commandTrace,\n authority.playerIds,\n perspective,\n ),\n };\n return node;\n}\n\nfunction resolvePerspective(\n selector: PerspectiveSelector,\n playerCount: number,\n declaredPlayerIds: readonly string[],\n): PerspectiveRef {\n if (selector.kind === \"spectator\") return { kind: \"spectator\" };\n const seat = selector.seat;\n if (!Number.isSafeInteger(seat) || seat < 0 || seat >= playerCount) {\n throw new ScenarioInspectionError({\n code: \"TEST_PERSPECTIVE_INVALID\",\n message: `Perspective seat ${String(seat)} is outside this ${playerCount}-player scenario.`,\n context: {\n requestedSeat: seat,\n minimumSeat: 0,\n maximumSeat: Math.max(0, playerCount - 1),\n },\n });\n }\n return {\n kind: \"player\",\n actor: {\n seat,\n playerId: declaredPlayerIds[seat] ?? `player-${seat + 1}`,\n },\n };\n}\n\nfunction inspectInteraction(\n actor: ActorRef,\n descriptor: InteractionDescriptorLike,\n explanation: InspectInteraction[\"explanation\"],\n): InspectInteraction {\n const availability = descriptor.availability ?? {\n status: \"blocked\" as const,\n reason: \"Interaction descriptor has no availability.\",\n };\n return {\n actor,\n interactionId: String(descriptor.interactionId ?? \"\"),\n availability: {\n status: availability.status,\n ...(\"code\" in availability && typeof availability.code === \"string\"\n ? { code: availability.code }\n : {}),\n ...(\"reason\" in availability && typeof availability.reason === \"string\"\n ? { reason: availability.reason }\n : {}),\n },\n inputs: explanation.inputs,\n explanation,\n };\n}\n\nfunction projectDispatchTrace<Game>(\n commandTrace: readonly ScenarioCommandTraceEntry<Game>[],\n playerIds: readonly string[],\n perspective: PerspectiveRef,\n): ScenarioDispatchTraceEntry[] {\n if (perspective.kind === \"spectator\") return [];\n const selectedSeat = perspective.actor.seat;\n return commandTrace.flatMap((entry): ScenarioDispatchTraceEntry[] => {\n if (entry.command.actor.seat !== selectedSeat) return [];\n return entry.trace.flatMap((trace): ScenarioDispatchTraceEntry[] => {\n switch (trace.kind) {\n case \"acceptedClientInput\": {\n const seat = playerIds.indexOf(trace.playerId);\n return seat < 0\n ? []\n : [\n {\n kind: \"acceptedCommand\",\n actor: { seat, playerId: trace.playerId },\n interactionId: trace.interactionId,\n },\n ];\n }\n case \"appliedInstruction\":\n return [\n {\n kind: \"appliedInstruction\",\n instructionKind: trace.instruction,\n },\n ];\n case \"rngConsumption\":\n return [{ kind: \"entropyDraw\", drawIndex: trace.drawIndex }];\n }\n });\n });\n}\n\nfunction assertScenarioIdentity<Game>(\n identity: ScenarioIdentity,\n scenario: ScenarioReplayDefinition<Game>,\n): void {\n if (identity.id !== scenario.id) {\n throw new ScenarioInspectionError({\n code: \"TEST_SCENARIO_INVALID\",\n message: \"Scenario identity does not match the authored default export.\",\n context: { identityId: identity.id, scenarioId: scenario.id },\n });\n }\n}\n\nfunction assertSeed(seed: number | undefined): void {\n if (seed !== undefined && !Number.isSafeInteger(seed)) {\n throw new ScenarioInspectionError({\n code: \"TEST_SEED_RANGE_INVALID\",\n message: \"Seed override must be a safe integer.\",\n context: { requestedSeed: seed },\n });\n }\n}\n","import { Buffer } from \"node:buffer\";\nimport { digestPluginRuntimeJson } from \"@dreamboard-games/plugin-runtime-contract\";\nimport type {\n PerspectiveRef,\n ScenarioIdentity,\n Sha256Digest,\n} from \"../inspection/types.js\";\n\nconst CURSOR_VERSION = 1;\n\ntype CursorPayload = {\n readonly version: typeof CURSOR_VERSION;\n readonly scenarioSourceDigest: Sha256Digest;\n readonly checkpointDigest: Sha256Digest;\n readonly perspective: PerspectiveRef;\n readonly seedOverride: number | null;\n readonly nextOrdinal: number;\n};\n\nexport class ExploreCursorError extends Error {\n readonly code = \"TEST_EXPLORE_CURSOR_STALE\";\n readonly scenarioSourceDigest: Sha256Digest;\n readonly checkpointDigest: Sha256Digest;\n\n constructor(options: {\n readonly scenarioSourceDigest: Sha256Digest;\n readonly checkpointDigest: Sha256Digest;\n }) {\n super(\"The exploration cursor no longer matches scenario authority.\");\n this.name = \"ExploreCursorError\";\n this.scenarioSourceDigest = options.scenarioSourceDigest;\n this.checkpointDigest = options.checkpointDigest;\n }\n}\n\nexport function createExploreCursor(options: {\n readonly scenario: ScenarioIdentity;\n readonly checkpointDigest: Sha256Digest;\n readonly perspective: PerspectiveRef;\n readonly seedOverride?: number;\n readonly nextOrdinal: number;\n}): string {\n assertOrdinal(options.nextOrdinal);\n const payload: CursorPayload = {\n version: CURSOR_VERSION,\n scenarioSourceDigest: options.scenario.sourceDigest,\n checkpointDigest: options.checkpointDigest,\n perspective: options.perspective,\n seedOverride: options.seedOverride ?? null,\n nextOrdinal: options.nextOrdinal,\n };\n const encoded = Buffer.from(JSON.stringify(payload), \"utf8\").toString(\n \"base64url\",\n );\n const digest = digestPluginRuntimeJson(payload).slice(\"sha256:\".length);\n return `dbx1.${encoded}.${digest}`;\n}\n\nexport function readExploreCursor(options: {\n readonly cursor: string;\n readonly scenario: ScenarioIdentity;\n readonly checkpointDigest: Sha256Digest;\n readonly perspective: PerspectiveRef;\n readonly seedOverride?: number;\n}): number {\n const stale = () => {\n throw new ExploreCursorError({\n scenarioSourceDigest: options.scenario.sourceDigest,\n checkpointDigest: options.checkpointDigest,\n });\n };\n const [prefix, encoded, digest, extra] = options.cursor.split(\".\");\n if (prefix !== \"dbx1\" || !encoded || !digest || extra !== undefined) stale();\n\n let payload: CursorPayload;\n try {\n payload = JSON.parse(\n Buffer.from(encoded, \"base64url\").toString(\"utf8\"),\n ) as CursorPayload;\n } catch {\n return stale();\n }\n\n if (\n digestPluginRuntimeJson(payload).slice(\"sha256:\".length) !== digest ||\n payload.version !== CURSOR_VERSION ||\n payload.scenarioSourceDigest !== options.scenario.sourceDigest ||\n payload.checkpointDigest !== options.checkpointDigest ||\n payload.seedOverride !== (options.seedOverride ?? null) ||\n JSON.stringify(payload.perspective) !== JSON.stringify(options.perspective)\n ) {\n return stale();\n }\n assertOrdinal(payload.nextOrdinal);\n return payload.nextOrdinal;\n}\n\nfunction assertOrdinal(value: number): void {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new RangeError(\n \"Explore cursor ordinal must be a non-negative safe integer.\",\n );\n }\n}\n","import {\n advanceScenarioReplay,\n enumerateScenarioInteractionParams,\n replayScenario,\n} from \"../scenario-replay.js\";\nimport type {\n ScenarioCheckpoint,\n ScenarioCommand,\n ScenarioReplay,\n ScenarioReplayDefinition,\n} from \"../definitions.js\";\nimport { ScenarioReplayError } from \"../definitions.js\";\nimport type { ScenarioDefinitionGameLike } from \"../scenario-definition-validation.js\";\nimport { projectScenarioCommandParams } from \"../scenario-player-refs.js\";\nimport {\n compareCanonicalScenarioJson,\n digestScenarioJson,\n} from \"../canonical.js\";\nimport {\n inspectScenario,\n inspectScenarioReplayNode,\n type InspectScenarioOptions,\n} from \"../inspection/inspect-scenario.js\";\nimport type { InspectNode, Sha256Digest } from \"../inspection/types.js\";\nimport { createExploreCursor, readExploreCursor } from \"./cursor.js\";\nimport type {\n ExploreScenarioResult,\n ExploreSeedResult,\n ExploreTransitionResult,\n} from \"./types.js\";\n\nexport const DEFAULT_EXPLORE_LIMIT = 50;\nexport const MAX_EXPLORE_LIMIT = 200;\nexport const DEFAULT_EXPLORE_EVALUATIONS = 5_000;\nexport const MAX_EXPLORE_EVALUATIONS = 100_000;\nexport const MAX_EXPLORE_SEEDS = 64;\n\nexport class ScenarioExploreError extends Error {\n readonly code: \"TEST_EXPLORE_LIMIT_INVALID\" | \"TEST_SEED_RANGE_INVALID\";\n readonly context: Readonly<Record<string, string | number | boolean>>;\n\n constructor(options: {\n readonly code: ScenarioExploreError[\"code\"];\n readonly message: string;\n readonly context: Readonly<Record<string, string | number | boolean>>;\n }) {\n super(options.message);\n this.name = \"ScenarioExploreError\";\n this.code = options.code;\n this.context = options.context;\n }\n}\n\ntype SeedRange = {\n readonly start: number;\n readonly end: number;\n};\n\nexport type ExploreScenarioOptions<Game extends ScenarioDefinitionGameLike> =\n Omit<InspectScenarioOptions<Game>, \"seed\"> & {\n readonly seed?: number;\n readonly seedRange?: SeedRange;\n readonly limit?: number;\n readonly maxEvaluations?: number;\n readonly cursor?: string;\n };\n\nexport async function exploreScenario<\n const Game extends ScenarioDefinitionGameLike,\n>(options: ExploreScenarioOptions<Game>): Promise<ExploreScenarioResult> {\n if (options.seedRange) {\n if (\n options.seed !== undefined ||\n options.cursor !== undefined ||\n options.limit !== undefined\n ) {\n throw new ScenarioExploreError({\n code: \"TEST_SEED_RANGE_INVALID\",\n message:\n \"Seed-range exploration cannot be combined with a seed override, cursor, or transition-page limit.\",\n context: { start: options.seedRange.start, end: options.seedRange.end },\n });\n }\n return exploreSeeds(options, options.seedRange);\n }\n return exploreTransitions(options);\n}\n\nasync function exploreTransitions<Game extends ScenarioDefinitionGameLike>(\n options: ExploreScenarioOptions<Game>,\n): Promise<ExploreTransitionResult> {\n const limit = options.limit ?? DEFAULT_EXPLORE_LIMIT;\n const maxEvaluations = options.maxEvaluations ?? DEFAULT_EXPLORE_EVALUATIONS;\n assertTransitionLimits(limit, maxEvaluations);\n const selectedScenario = scenarioWithSeed(options.scenario, options.seed);\n const checkpoint = defaultCheckpoint(selectedScenario, options.at);\n const replay = await replayScenario({\n game: options.game,\n scenario: selectedScenario,\n at: checkpoint,\n });\n const node = inspectScenarioReplayNode({\n replay,\n perspective: options.perspective,\n });\n const startOrdinal = options.cursor\n ? readExploreCursor({\n cursor: options.cursor,\n scenario: options.identity,\n checkpointDigest: node.checkpointDigest,\n perspective: node.perspective,\n seedOverride: options.seed,\n })\n : 0;\n if (node.perspective.kind === \"spectator\") {\n return {\n schemaVersion: 1,\n mode: \"transitions\",\n scenario: options.identity,\n perspective: node.perspective,\n node,\n candidates: [],\n omissions: [],\n page: {\n limit,\n evaluated: 0,\n truncated: false,\n nextCursor: null,\n },\n };\n }\n\n const accepted: ExploreTransitionResult[\"candidates\"][number][] = [];\n const omissions: ExploreTransitionResult[\"omissions\"][number][] = [];\n let evaluated = 0;\n for (const action of node.actions) {\n const remaining = maxEvaluations - evaluated;\n if (remaining <= 0) {\n omissions.push({\n actor: action.actor,\n interactionId: action.interactionId,\n code: \"INPUT_DOMAIN_BUDGET\",\n });\n continue;\n }\n const enumeration = enumerateScenarioInteractionParams({\n replay,\n seat: action.actor.seat,\n interactionId: action.interactionId,\n maxEvaluations: remaining,\n });\n if (\n !enumeration.found ||\n !enumeration.visible ||\n !enumeration.enumeration\n ) {\n continue;\n }\n evaluated += enumeration.enumeration.evaluated;\n if (enumeration.enumeration.status !== \"enumerated\") {\n omissions.push({\n actor: action.actor,\n interactionId: action.interactionId,\n code:\n enumeration.enumeration.status === \"budget\"\n ? \"INPUT_DOMAIN_BUDGET\"\n : \"INPUT_DOMAIN_NOT_ENUMERABLE\",\n ...(enumeration.enumeration.inputKey\n ? { inputKey: enumeration.enumeration.inputKey }\n : {}),\n });\n continue;\n }\n const assignments = [...enumeration.enumeration.assignments].sort(\n compareCanonicalScenarioJson,\n );\n for (const assignment of assignments) {\n const command: ScenarioCommand = {\n actor: { seat: action.actor.seat },\n interactionId: action.interactionId,\n params: projectScenarioCommandParams({\n game: options.game,\n phase: node.flow.phase,\n interactionId: action.interactionId,\n params: assignment,\n playerIds: node.setup.players\n ? Array.from(\n { length: node.setup.players },\n (_, seat) =>\n options.game.contract.manifest.literals.playerIds[seat] ??\n `player-${seat + 1}`,\n )\n : [],\n path: `explore.${action.interactionId}`,\n }),\n };\n const advanced = await advanceScenarioReplay({\n replay,\n command: command as never,\n });\n if (advanced.kind !== \"accepted\") continue;\n const afterNode = inspectScenarioReplayNode({\n replay: advanced.replay,\n perspective: options.perspective,\n });\n accepted.push({\n ordinal: accepted.length,\n command,\n after: {\n checkpointDigest: afterNode.checkpointDigest,\n flow: afterNode.flow,\n publicStateDigest: digestScenarioJson(\n afterNode.publicState,\n ) as Sha256Digest,\n viewDigest: digestScenarioJson(afterNode.view) as Sha256Digest,\n actions: afterNode.actions.map(({ actor, interactionId }) => ({\n actor,\n interactionId,\n })),\n entropy: afterNode.entropy,\n dispatchTrace: afterNode.dispatchTrace,\n },\n });\n }\n }\n\n const candidates = accepted.slice(startOrdinal, startOrdinal + limit);\n const nextOrdinal = startOrdinal + candidates.length;\n const truncated = nextOrdinal < accepted.length;\n return {\n schemaVersion: 1,\n mode: \"transitions\",\n scenario: structuredClone(options.identity),\n perspective: node.perspective,\n node,\n candidates,\n omissions,\n page: {\n limit,\n evaluated,\n truncated,\n nextCursor: truncated\n ? createExploreCursor({\n scenario: options.identity,\n checkpointDigest: node.checkpointDigest,\n perspective: node.perspective,\n seedOverride: options.seed,\n nextOrdinal,\n })\n : null,\n },\n };\n}\n\nasync function exploreSeeds<Game extends ScenarioDefinitionGameLike>(\n options: ExploreScenarioOptions<Game>,\n range: SeedRange,\n): Promise<ExploreSeedResult> {\n assertSeedRange(range);\n const checkpoint = defaultCheckpoint(options.scenario, options.at);\n const variants: ExploreSeedResult[\"variants\"][number][] = [];\n for (let seed = range.start; seed <= range.end; seed += 1) {\n try {\n const inspected = await inspectScenario({\n game: options.game,\n scenario: options.scenario,\n identity: options.identity,\n perspective: options.perspective,\n at: checkpoint,\n seed,\n });\n const replay = await replayScenario({\n game: options.game,\n scenario: scenarioWithSeed(options.scenario, seed),\n at: checkpoint,\n });\n const counts = await concreteOptionCounts({\n replay,\n node: inspected.node,\n maxEvaluations: options.maxEvaluations ?? DEFAULT_EXPLORE_EVALUATIONS,\n });\n variants.push({\n seed,\n status: \"replayed\",\n checkpointDigest: inspected.node.checkpointDigest,\n entropy: inspected.node.entropy,\n observable: {\n publicState: inspected.node.publicState,\n view: inspected.node.view,\n },\n signature: {\n phase: inspected.node.flow.phase,\n step: inspected.node.flow.step,\n actions: inspected.node.actions.map(({ actor, interactionId }) => ({\n seat: actor.seat,\n interactionId,\n concreteOptionCount:\n counts.get(`${actor.seat}:${interactionId}`) ?? \"lazy\",\n })),\n },\n });\n } catch (error) {\n if (!(error instanceof ScenarioReplayError)) throw error;\n variants.push({\n seed,\n status: \"rejected\",\n rejection: {\n segment: error.segment,\n sourceIndex: error.index,\n interactionId: error.interactionId,\n errorCode: error.errorCode,\n },\n });\n }\n }\n return {\n schemaVersion: 1,\n mode: \"seeds\",\n scenario: structuredClone(options.identity),\n perspective: (await inspectSeedPerspective(options)).node.perspective,\n checkpoint,\n variants,\n };\n}\n\nasync function inspectSeedPerspective<Game extends ScenarioDefinitionGameLike>(\n options: ExploreScenarioOptions<Game>,\n) {\n return inspectScenario({\n game: options.game,\n scenario: options.scenario,\n identity: options.identity,\n perspective: options.perspective,\n at: { segment: \"setup\", completed: 0 },\n });\n}\n\nasync function concreteOptionCounts<Game>(options: {\n readonly replay: ScenarioReplay<Game>;\n readonly node: InspectNode;\n readonly maxEvaluations: number;\n}): Promise<Map<string, number | \"lazy\">> {\n assertTransitionLimits(DEFAULT_EXPLORE_LIMIT, options.maxEvaluations);\n const counts = new Map<string, number | \"lazy\">();\n let evaluated = 0;\n for (const action of options.node.actions) {\n const remaining = options.maxEvaluations - evaluated;\n if (remaining <= 0) {\n counts.set(`${action.actor.seat}:${action.interactionId}`, \"lazy\");\n continue;\n }\n const result = enumerateScenarioInteractionParams({\n replay: options.replay,\n seat: action.actor.seat,\n interactionId: action.interactionId,\n maxEvaluations: remaining,\n });\n if (!result.found || !result.visible || !result.enumeration) continue;\n evaluated += result.enumeration.evaluated;\n counts.set(\n `${action.actor.seat}:${action.interactionId}`,\n result.enumeration.status === \"enumerated\"\n ? result.enumeration.assignments.length\n : \"lazy\",\n );\n }\n return counts;\n}\n\nfunction scenarioWithSeed<Game>(\n scenario: ScenarioReplayDefinition<Game>,\n seed: number | undefined,\n): ScenarioReplayDefinition<Game> {\n return seed === undefined\n ? scenario\n : { ...scenario, setup: { ...scenario.setup, seed } };\n}\n\nfunction defaultCheckpoint<Game>(\n scenario: ScenarioReplayDefinition<Game>,\n at: ScenarioCheckpoint | undefined,\n): ScenarioCheckpoint {\n return (at ?? {\n segment: \"given\",\n completed: scenario.given.length,\n }) as ScenarioCheckpoint;\n}\n\nfunction assertTransitionLimits(limit: number, maxEvaluations: number): void {\n if (!Number.isSafeInteger(limit) || limit < 1 || limit > MAX_EXPLORE_LIMIT) {\n throw new ScenarioExploreError({\n code: \"TEST_EXPLORE_LIMIT_INVALID\",\n message: `Explore limit must be between 1 and ${MAX_EXPLORE_LIMIT}.`,\n context: { requested: limit, minimum: 1, maximum: MAX_EXPLORE_LIMIT },\n });\n }\n if (\n !Number.isSafeInteger(maxEvaluations) ||\n maxEvaluations < 1 ||\n maxEvaluations > MAX_EXPLORE_EVALUATIONS\n ) {\n throw new ScenarioExploreError({\n code: \"TEST_EXPLORE_LIMIT_INVALID\",\n message: `Explore max evaluations must be between 1 and ${MAX_EXPLORE_EVALUATIONS}.`,\n context: {\n requested: maxEvaluations,\n minimum: 1,\n maximum: MAX_EXPLORE_EVALUATIONS,\n },\n });\n }\n}\n\nfunction assertSeedRange(range: SeedRange): void {\n const width = range.end - range.start + 1;\n if (\n !Number.isSafeInteger(range.start) ||\n !Number.isSafeInteger(range.end) ||\n range.start > range.end ||\n !Number.isSafeInteger(width) ||\n width < 1 ||\n width > MAX_EXPLORE_SEEDS\n ) {\n throw new ScenarioExploreError({\n code: \"TEST_SEED_RANGE_INVALID\",\n message: `Seed range must contain 1 through ${MAX_EXPLORE_SEEDS} inclusive safe-integer seeds.`,\n context: {\n start: range.start,\n end: range.end,\n maximumWidth: MAX_EXPLORE_SEEDS,\n },\n });\n }\n}\n","import { createHash } from \"node:crypto\";\nimport type {\n PluginProtocolTape,\n UIReplayRequest,\n UIScenarioFixture,\n} from \"./schema.js\";\n\ntype CanonicalJson =\n | null\n | boolean\n | number\n | string\n | readonly CanonicalJson[]\n | { readonly [key: string]: CanonicalJson };\n\nconst sha256DigestPattern = /^sha256:[a-f0-9]{64}$/;\n\nfunction compareCanonicalStrings(left: string, right: string): number {\n return left === right ? 0 : left < right ? -1 : 1;\n}\n\nexport function isSha256Digest(value: string): boolean {\n return sha256DigestPattern.test(value);\n}\n\nexport function canonicalizeUIFixtureJson(value: unknown): CanonicalJson {\n if (value === null) {\n return null;\n }\n switch (typeof value) {\n case \"boolean\":\n case \"string\":\n return value;\n case \"number\":\n if (Number.isFinite(value)) {\n return value;\n }\n break;\n case \"object\": {\n if (Array.isArray(value)) {\n return value.map((item) => canonicalizeUIFixtureJson(item));\n }\n if (Object.getPrototypeOf(value) !== Object.prototype) {\n break;\n }\n const entries = Object.entries(value as Record<string, unknown>);\n return Object.fromEntries(\n entries\n .filter(([, item]) => item !== undefined)\n .sort(([left], [right]) => compareCanonicalStrings(left, right))\n .map(([key, item]) => [key, canonicalizeUIFixtureJson(item)]),\n );\n }\n }\n throw new Error(\n `UI fixture values must be deterministic JSON. Received ${typeof value}.`,\n );\n}\n\nexport function canonicalUIFixtureJson(value: unknown): string {\n return JSON.stringify(canonicalizeUIFixtureJson(value));\n}\n\nexport function digestUIFixtureJson(value: unknown): string {\n return sha256(canonicalUIFixtureJson(value));\n}\n\nexport function digestUIFixtureRequest(request: UIReplayRequest): string {\n return digestUIFixtureJson({\n digestVersion: \"ui-replay-request@2\",\n request,\n });\n}\n\nexport function digestUIFixtureTransportRequest(request: {\n readonly operation: \"validate\" | \"submit\";\n readonly basis?: {\n readonly gameVersion: number;\n readonly actionSetVersion: string;\n readonly perspectivePlayerId: string | null;\n };\n readonly interactionId?: string;\n readonly payload?: unknown;\n}): string {\n return digestUIFixtureJson({\n digestVersion: \"ui-fixture-runtime-command@2\",\n request,\n });\n}\n\nexport function digestPluginProtocolTape(tape: PluginProtocolTape): string {\n return digestUIFixtureJson({\n digestVersion: \"plugin-protocol-tape@2\",\n tape,\n });\n}\n\nexport function canonicalizeUIScenarioFixture(\n fixture: UIScenarioFixture,\n): UIScenarioFixture {\n return canonicalizeUIFixtureJson({\n ...fixture,\n tags: [...fixture.tags].sort(),\n environment: {\n ...fixture.environment,\n viewportTags: [...fixture.environment.viewportTags].sort(),\n },\n }) as unknown as UIScenarioFixture;\n}\n\nexport function serializeUIScenarioFixture(fixture: UIScenarioFixture): string {\n return `${JSON.stringify(canonicalizeUIScenarioFixture(fixture), null, 2)}\\n`;\n}\n\nexport function digestUIScenarioFixture(fixture: UIScenarioFixture): string {\n return sha256(serializeUIScenarioFixture(fixture));\n}\n\nfunction sha256(value: string): string {\n return `sha256:${createHash(\"sha256\").update(value).digest(\"hex\")}`;\n}\n","import {\n computePluginActionSetVersion,\n materializePluginGameplayFrame,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport { digestUIFixtureJson } from \"../ui-fixture/canonical.js\";\nimport type {\n CreateReducerScenarioRunnerOptions,\n ReducerScenarioFrame,\n ReducerScenarioExchange,\n ReducerScenarioOperation,\n ReducerScenarioRunner,\n ReducerScenarioTrace,\n} from \"./types.js\";\n\nexport function createReducerScenarioRunner(\n options: CreateReducerScenarioRunnerOptions,\n): ReducerScenarioRunner {\n return {\n async run(\n operations: readonly ReducerScenarioOperation[],\n ): Promise<ReducerScenarioTrace> {\n let state = structuredClone(options.initialState);\n let gameVersion = options.initialGameVersion ?? 1;\n const frames: ReducerScenarioFrame[] = [];\n const exchanges: ReducerScenarioExchange[] = [];\n\n const appendFrame = (id: string): ReducerScenarioFrame => {\n const dynamicProjection = options.bundle.projectSeatsDynamic({\n state,\n playerIds: [options.viewer.playerId],\n });\n const staticProjection = options.bundle.projectStatic?.() ?? null;\n const flow = readFlowState(state);\n const materialized = materializePluginGameplayFrame({\n currentPhase: flow.currentPhase,\n activePlayers: flow.activePlayers,\n dynamicProjection,\n staticProjection,\n perspectivePlayerId: options.viewer.playerId,\n gameVersion,\n actionSetVersion: \"pending\",\n });\n const actionSetVersion = computePluginActionSetVersion({\n gameVersion,\n availableInteractions: materialized.availableInteractions,\n });\n const frame = {\n id,\n reducerState: structuredClone(state),\n dynamicProjection,\n staticProjection,\n gameVersion,\n actionSetVersion,\n projectionDigest: digestUIFixtureJson({\n digestVersion: \"reducer-scenario-frame@2\",\n scenarioId: options.scenarioId,\n frameId: id,\n dynamicProjection,\n staticProjection,\n gameVersion,\n actionSetVersion,\n }),\n } satisfies ReducerScenarioFrame;\n frames.push(frame);\n return frame;\n };\n\n appendFrame(\"frame-1\");\n\n for (const operation of operations) {\n const fromFrame = frames[frames.length - 1];\n if (!fromFrame) {\n throw new Error(\"Reducer scenario runner lost its initial frame.\");\n }\n if (operation.operation === \"validate\") {\n const result = await options.bundle.validateInput({\n state,\n input: operation.input,\n });\n exchanges.push({\n id: operation.id,\n operation: \"validate\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result,\n });\n continue;\n }\n\n const result = await options.bundle.dispatch({\n state,\n input: operation.input,\n });\n if (result.kind === \"reject\") {\n exchanges.push({\n id: operation.id,\n operation: \"submit\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result: {\n kind: \"rejected\",\n diagnostics: [\n {\n code: result.errorCode,\n message: result.message ?? result.errorCode,\n },\n ],\n },\n });\n continue;\n }\n\n state = structuredClone(result.state);\n gameVersion += 1;\n const toFrame = appendFrame(`frame-${frames.length + 1}`);\n exchanges.push({\n id: operation.id,\n operation: \"submit\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result: {\n kind: \"accepted\",\n toFrameId: toFrame.id,\n },\n });\n }\n\n return {\n scenarioId: options.scenarioId,\n gameId: options.gameId,\n viewer: options.viewer,\n frames,\n exchanges,\n };\n },\n };\n}\n\nfunction readFlowState(state: {\n readonly domain?: {\n readonly flow?: {\n readonly currentPhase?: string;\n readonly activePlayers?: readonly string[];\n };\n };\n}): { currentPhase: string | null; activePlayers: readonly string[] } {\n return {\n currentPhase: state.domain?.flow?.currentPhase ?? null,\n activePlayers: [...(state.domain?.flow?.activePlayers ?? [])],\n };\n}\n","import type {\n ReferenceGameUIScenarioDefinition,\n UIScenarioDefinition,\n} from \"./types.js\";\n\nexport function defineUIScenario<const TScenario extends UIScenarioDefinition>(\n scenario: TScenario,\n): Readonly<TScenario> {\n return Object.freeze(scenario);\n}\n\nexport function defineReferenceGameUIScenario<\n const TScenario extends ReferenceGameUIScenarioDefinition,\n>(scenario: TScenario): Readonly<TScenario> {\n return Object.freeze(scenario);\n}\n","import {\n canonicalUIFixtureJson,\n digestUIFixtureJson,\n digestUIScenarioFixture,\n} from \"./canonical.js\";\nimport type { UIScenarioFixture } from \"./schema.js\";\n\nexport interface UIParityViewport {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface UIParityObservationEnvironmentV1 {\n readonly project: string;\n readonly viewport: UIParityViewport;\n}\n\nexport interface UIParityDiagnosticV1 {\n readonly code: string;\n readonly message: string;\n}\n\nexport interface UIParityObservationCheckpointV1 {\n readonly stepId: string;\n readonly interactionKey?: string;\n readonly interactionId?: string;\n readonly actuatorId?: string;\n readonly descriptorDigest?: string;\n readonly draftDigest?: string;\n readonly gameVersion: number;\n readonly actionSetVersion: string;\n readonly perspectivePlayerId: string | null;\n readonly projectionDigest: string;\n readonly semanticDigest: string;\n readonly submissionDigest?: string;\n readonly screenshot?: string;\n}\n\nexport interface UIParityObservationProvenanceV1 {\n readonly kind:\n | \"fixture-expectation\"\n | \"source-workbench\"\n | \"packed-real-host\";\n readonly evidence?: string;\n}\n\nexport interface UIParityObservationV1 {\n readonly schemaVersion: 1;\n readonly scenarioId: string;\n readonly fixtureDigest: string;\n readonly sdkCandidateDigest: string;\n readonly pluginRuntimeProtocol: 3;\n readonly browserInteractionProtocol: string;\n readonly environment: UIParityObservationEnvironmentV1;\n readonly provenance: UIParityObservationProvenanceV1;\n readonly checkpoints: readonly UIParityObservationCheckpointV1[];\n readonly diagnostics: readonly UIParityDiagnosticV1[];\n}\n\nexport type UIParityFailureCode =\n | \"candidate-mismatch\"\n | \"fixture-source-mismatch\"\n | \"protocol-mismatch\"\n | \"interaction-resolution-mismatch\"\n | \"preparation-mismatch\"\n | \"draft-mismatch\"\n | \"submission-mismatch\"\n | \"projection-mismatch\"\n | \"semantic-snapshot-mismatch\"\n | \"visual-mismatch\"\n | \"host-setup-failure\";\n\nexport interface UIParityComparisonFailure {\n readonly code: UIParityFailureCode;\n readonly message: string;\n readonly path: string;\n readonly expected: unknown;\n readonly actual: unknown;\n readonly checkpointIndex?: number;\n readonly stepId?: string;\n}\n\nexport type UIParityComparisonResult =\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly failure: UIParityComparisonFailure;\n };\n\ntype UIParityComparisonFailureInput = Omit<\n UIParityComparisonFailure,\n \"message\"\n>;\n\nexport interface CreateUIParityObservationFromFixtureOptions {\n readonly fixture: UIScenarioFixture;\n readonly sdkCandidateDigest: string;\n readonly environment: UIParityObservationEnvironmentV1;\n readonly fixtureDigest?: string;\n readonly screenshotsByStepId?: Readonly<Record<string, string>>;\n readonly diagnostics?: readonly UIParityDiagnosticV1[];\n}\n\ntype ComparablePath = {\n readonly path: string;\n readonly code: UIParityFailureCode;\n};\n\nconst topLevelComparisons: readonly ComparablePath[] = [\n { path: \"scenarioId\", code: \"fixture-source-mismatch\" },\n { path: \"fixtureDigest\", code: \"candidate-mismatch\" },\n { path: \"sdkCandidateDigest\", code: \"candidate-mismatch\" },\n { path: \"pluginRuntimeProtocol\", code: \"protocol-mismatch\" },\n { path: \"browserInteractionProtocol\", code: \"protocol-mismatch\" },\n { path: \"environment.project\", code: \"host-setup-failure\" },\n { path: \"environment.viewport.width\", code: \"host-setup-failure\" },\n { path: \"environment.viewport.height\", code: \"host-setup-failure\" },\n];\n\nconst checkpointComparisons: readonly ComparablePath[] = [\n { path: \"stepId\", code: \"interaction-resolution-mismatch\" },\n { path: \"interactionKey\", code: \"interaction-resolution-mismatch\" },\n { path: \"interactionId\", code: \"interaction-resolution-mismatch\" },\n { path: \"actuatorId\", code: \"interaction-resolution-mismatch\" },\n { path: \"descriptorDigest\", code: \"interaction-resolution-mismatch\" },\n { path: \"gameVersion\", code: \"projection-mismatch\" },\n { path: \"actionSetVersion\", code: \"projection-mismatch\" },\n { path: \"perspectivePlayerId\", code: \"projection-mismatch\" },\n { path: \"projectionDigest\", code: \"projection-mismatch\" },\n { path: \"semanticDigest\", code: \"semantic-snapshot-mismatch\" },\n { path: \"draftDigest\", code: \"draft-mismatch\" },\n { path: \"submissionDigest\", code: \"submission-mismatch\" },\n { path: \"screenshot\", code: \"visual-mismatch\" },\n];\n\nexport function createUIParityObservationFromFixture({\n fixture,\n sdkCandidateDigest,\n environment,\n fixtureDigest = digestUIScenarioFixture(fixture),\n screenshotsByStepId = {},\n diagnostics = [],\n}: CreateUIParityObservationFromFixtureOptions): UIParityObservationV1 {\n const frameById = new Map(\n fixture.protocol.frames.map((frame) => [frame.id, frame]),\n );\n const firstFrame = fixture.protocol.frames[0];\n if (!firstFrame) {\n throw new Error(\n `Fixture '${fixture.id}' does not contain protocol frames.`,\n );\n }\n\n const checkpoints = fixture.replay.map((step, index) => {\n const expectedFrameId = step.expect.frameId ?? firstFrame.id;\n const frame = frameById.get(expectedFrameId);\n if (!frame) {\n throw new Error(\n `Fixture '${fixture.id}' replay step '${step.stepId}' references missing frame '${expectedFrameId}'.`,\n );\n }\n const identity = \"expectedIdentity\" in step ? step.expectedIdentity : null;\n const projectionDigest =\n step.expect.projectionDigest ?? frame.projectionDigest;\n const isFinal = index === fixture.replay.length - 1;\n const semanticDigest =\n step.expect.semanticDigest ??\n (isFinal\n ? fixture.expected.finalSemanticDigest\n : digestUIFixtureJson({\n scenarioId: fixture.id,\n stepId: step.stepId,\n frameId: frame.id,\n projectionDigest,\n }));\n const submissionDigest =\n step.expect.submissionDigest ??\n (isFinal ? fixture.expected.submissionDigest : undefined);\n\n return {\n stepId: step.stepId,\n interactionKey: identity?.interactionKey,\n interactionId: identity?.interactionId,\n actuatorId: identity?.actuatorId,\n descriptorDigest: identity?.descriptorDigest,\n draftDigest: step.expect.draftDigest ?? identity?.draftDigest,\n gameVersion: frame.frame.gameVersion,\n actionSetVersion: frame.frame.actionSetVersion,\n perspectivePlayerId: frame.frame.perspectivePlayerId,\n projectionDigest,\n semanticDigest,\n submissionDigest,\n screenshot: screenshotsByStepId[step.stepId],\n } satisfies UIParityObservationCheckpointV1;\n });\n\n return {\n schemaVersion: 1,\n scenarioId: fixture.id,\n fixtureDigest,\n sdkCandidateDigest,\n pluginRuntimeProtocol: fixture.pluginRuntimeProtocol,\n browserInteractionProtocol: fixture.browserInteractionProtocol,\n environment,\n provenance: {\n kind: \"fixture-expectation\",\n },\n checkpoints,\n diagnostics,\n };\n}\n\nexport function parseUIParityObservationV1(\n value: unknown,\n): UIParityObservationV1 {\n const observation = assertRecord(value, \"observation\");\n if (observation.schemaVersion !== 1) {\n throw new Error(\"UI parity observation schemaVersion must be 1.\");\n }\n assertString(observation.scenarioId, \"scenarioId\");\n assertString(observation.fixtureDigest, \"fixtureDigest\");\n assertString(observation.sdkCandidateDigest, \"sdkCandidateDigest\");\n if (observation.pluginRuntimeProtocol !== 3) {\n throw new Error(\"UI parity observation pluginRuntimeProtocol must be 3.\");\n }\n assertString(\n observation.browserInteractionProtocol,\n \"browserInteractionProtocol\",\n );\n const environment = assertRecord(observation.environment, \"environment\");\n assertString(environment.project, \"environment.project\");\n const viewport = assertRecord(environment.viewport, \"environment.viewport\");\n assertNumber(viewport.width, \"environment.viewport.width\");\n assertNumber(viewport.height, \"environment.viewport.height\");\n const provenance = assertRecord(\n observation.provenance,\n \"observation.provenance\",\n );\n if (\n provenance.kind !== \"fixture-expectation\" &&\n provenance.kind !== \"source-workbench\" &&\n provenance.kind !== \"packed-real-host\"\n ) {\n throw new Error(\n \"observation.provenance.kind must identify fixture, source Workbench, or packed real-host measurement.\",\n );\n }\n assertOptionalString(provenance.evidence, \"observation.provenance.evidence\");\n const checkpoints = assertArray(observation.checkpoints, \"checkpoints\");\n for (let index = 0; index < checkpoints.length; index += 1) {\n const checkpoint = assertRecord(\n checkpoints[index],\n `checkpoints[${index}]`,\n );\n assertString(checkpoint.stepId, `checkpoints[${index}].stepId`);\n assertOptionalString(\n checkpoint.interactionKey,\n `checkpoints[${index}].interactionKey`,\n );\n assertOptionalString(\n checkpoint.interactionId,\n `checkpoints[${index}].interactionId`,\n );\n assertOptionalString(\n checkpoint.actuatorId,\n `checkpoints[${index}].actuatorId`,\n );\n assertOptionalString(\n checkpoint.descriptorDigest,\n `checkpoints[${index}].descriptorDigest`,\n );\n assertOptionalString(\n checkpoint.draftDigest,\n `checkpoints[${index}].draftDigest`,\n );\n assertNumber(checkpoint.gameVersion, `checkpoints[${index}].gameVersion`);\n assertString(\n checkpoint.actionSetVersion,\n `checkpoints[${index}].actionSetVersion`,\n );\n if (\n checkpoint.perspectivePlayerId !== null &&\n typeof checkpoint.perspectivePlayerId !== \"string\"\n ) {\n throw new Error(\n `checkpoints[${index}].perspectivePlayerId must be a string or null.`,\n );\n }\n assertString(\n checkpoint.projectionDigest,\n `checkpoints[${index}].projectionDigest`,\n );\n assertString(\n checkpoint.semanticDigest,\n `checkpoints[${index}].semanticDigest`,\n );\n assertOptionalString(\n checkpoint.submissionDigest,\n `checkpoints[${index}].submissionDigest`,\n );\n assertOptionalString(\n checkpoint.screenshot,\n `checkpoints[${index}].screenshot`,\n );\n }\n const diagnostics = assertArray(observation.diagnostics, \"diagnostics\");\n for (let index = 0; index < diagnostics.length; index += 1) {\n const diagnostic = assertRecord(\n diagnostics[index],\n `diagnostics[${index}]`,\n );\n assertString(diagnostic.code, `diagnostics[${index}].code`);\n assertString(diagnostic.message, `diagnostics[${index}].message`);\n }\n return observation as unknown as UIParityObservationV1;\n}\n\nexport function compareUIParityObservations(\n expected: UIParityObservationV1,\n actual: UIParityObservationV1,\n): UIParityComparisonResult {\n for (const comparison of topLevelComparisons) {\n const result = comparePath(expected, actual, comparison);\n if (result) {\n return result;\n }\n }\n\n if (expected.checkpoints.length !== actual.checkpoints.length) {\n return mismatch({\n code: \"interaction-resolution-mismatch\",\n path: \"checkpoints.length\",\n expected: expected.checkpoints.length,\n actual: actual.checkpoints.length,\n });\n }\n\n for (let index = 0; index < expected.checkpoints.length; index += 1) {\n const expectedCheckpoint = expected.checkpoints[index]!;\n const actualCheckpoint = actual.checkpoints[index]!;\n for (const comparison of checkpointComparisons) {\n const result = comparePath(\n expectedCheckpoint,\n actualCheckpoint,\n comparison,\n {\n prefix: `checkpoints[${index}]`,\n checkpointIndex: index,\n stepId: expectedCheckpoint.stepId,\n },\n );\n if (result) {\n return result;\n }\n }\n }\n\n if (!sameValue(expected.diagnostics, actual.diagnostics)) {\n return mismatch({\n code: \"host-setup-failure\",\n path: \"diagnostics\",\n expected: expected.diagnostics,\n actual: actual.diagnostics,\n });\n }\n\n return { ok: true };\n}\n\nfunction comparePath(\n expected: unknown,\n actual: unknown,\n comparison: ComparablePath,\n options: {\n readonly prefix?: string;\n readonly checkpointIndex?: number;\n readonly stepId?: string;\n } = {},\n): UIParityComparisonResult | null {\n const expectedValue = getPath(expected, comparison.path);\n const actualValue = getPath(actual, comparison.path);\n if (sameValue(expectedValue, actualValue)) {\n return null;\n }\n const path = options.prefix\n ? `${options.prefix}.${comparison.path}`\n : comparison.path;\n return mismatch({\n code: comparison.code,\n path,\n expected: expectedValue,\n actual: actualValue,\n checkpointIndex: options.checkpointIndex,\n stepId: options.stepId,\n });\n}\n\nfunction mismatch(\n input: UIParityComparisonFailureInput,\n): UIParityComparisonResult {\n return {\n ok: false,\n failure: {\n ...input,\n message: `${input.code} at ${input.path}`,\n },\n };\n}\n\nfunction sameValue(left: unknown, right: unknown): boolean {\n if (left === undefined || right === undefined) {\n return left === right;\n }\n return canonicalUIFixtureJson(left) === canonicalUIFixtureJson(right);\n}\n\nfunction getPath(value: unknown, path: string): unknown {\n return path.split(\".\").reduce<unknown>((current, key) => {\n if (current === null || typeof current !== \"object\") {\n return undefined;\n }\n return (current as Record<string, unknown>)[key];\n }, value);\n}\n\nfunction assertRecord(value: unknown, path: string): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(`${path} must be an object.`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction assertArray(value: unknown, path: string): readonly unknown[] {\n if (!Array.isArray(value)) {\n throw new Error(`${path} must be an array.`);\n }\n return value;\n}\n\nfunction assertString(value: unknown, path: string): void {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`${path} must be a non-empty string.`);\n }\n}\n\nfunction assertOptionalString(value: unknown, path: string): void {\n if (\n value !== undefined &&\n (typeof value !== \"string\" || value.length === 0)\n ) {\n throw new Error(`${path} must be a non-empty string when present.`);\n }\n}\n\nfunction assertNumber(value: unknown, path: string): void {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`${path} must be a finite number.`);\n }\n}\n","import {\n DREAMBOARD_PLUGIN_PROTOCOL,\n DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n type HostToPluginEnvelope,\n type PluginProtocolTape,\n type PluginToHostPayload,\n type SubmitInteractionCommand,\n type ValidateInteractionCommand,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport type { PluginTransport } from \"../../runtime/core/types.js\";\nimport { digestUIFixtureTransportRequest } from \"./canonical.js\";\n\nexport interface FixtureHostEvent {\n readonly sequence: number;\n readonly atMs: number;\n readonly kind:\n | \"frame-sent\"\n | \"validate-received\"\n | \"submit-received\"\n | \"ack-received\"\n | \"ready-received\"\n | \"diagnostic\";\n readonly requestDigest?: string;\n readonly frameId?: string;\n readonly projectionDigest?: string;\n readonly result?: \"accepted\" | \"rejected\";\n}\n\nexport interface FixtureHostHarness {\n readonly transport: PluginTransport;\n readonly tape: PluginProtocolTape;\n reset(): void;\n flush(): Promise<void>;\n advanceHost(): Promise<void>;\n getCurrentFrameId(): string;\n getEvents(): readonly FixtureHostEvent[];\n assertConsumed(): void;\n}\n\nexport interface CreateFixtureHostHarnessOptions {\n readonly tape: PluginProtocolTape;\n readonly strict?: boolean;\n readonly latencyMs?: number;\n readonly channelId?: string;\n readonly onEvent?: (event: FixtureHostEvent) => void;\n readonly nowMs?: () => number;\n}\n\nconst DEFAULT_CHANNEL_ID = \"fixture-channel\";\n\nexport function createFixtureHostHarness(\n options: CreateFixtureHostHarnessOptions,\n): FixtureHostHarness {\n const strict = options.strict ?? true;\n const latencyMs = options.latencyMs ?? 0;\n const channelId = options.channelId ?? DEFAULT_CHANNEL_ID;\n const events: FixtureHostEvent[] = [];\n const frameById = new Map(\n options.tape.frames.map((frame) => [frame.id, frame]),\n );\n let eventSequence = 0;\n let envelopeSequence = 0;\n let stepCursor = 0;\n let currentFrameId: string | null = null;\n let onMessage: ((message: HostToPluginEnvelope) => void) | null = null;\n let firstFixtureError: Error | null = null;\n const pendingHandlers = new Set<Promise<void>>();\n\n const record = (event: Omit<FixtureHostEvent, \"sequence\" | \"atMs\">) => {\n const entry = {\n sequence: ++eventSequence,\n atMs: options.nowMs?.() ?? eventSequence,\n ...event,\n };\n events.push(entry);\n options.onEvent?.(entry);\n };\n\n const createFixtureError = (code: string, message: string): Error => {\n record({ kind: \"diagnostic\" });\n const error = new Error(message);\n error.name = \"FixtureHostHarnessError\";\n Object.assign(error, { errorCode: code });\n return error;\n };\n\n const rememberFixtureError = (error: unknown) => {\n if (firstFixtureError) {\n return;\n }\n firstFixtureError =\n error instanceof Error\n ? error\n : createFixtureError(\n \"fixture-unknown-error\",\n \"Fixture host failed with an unknown error.\",\n );\n };\n\n const throwFixtureError = () => {\n if (firstFixtureError) {\n throw firstFixtureError;\n }\n };\n\n const sendHostPayload = (payload: HostToPluginEnvelope[\"payload\"]) => {\n if (!onMessage) {\n return;\n }\n onMessage({\n protocol: DREAMBOARD_PLUGIN_PROTOCOL,\n version: DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n channelId,\n sequence: ++envelopeSequence,\n payload,\n });\n };\n\n const sendInit = () => {\n sendHostPayload({\n type: \"runtime.init\",\n session: options.tape.session,\n });\n };\n\n const publishFrame = (frameId: string) => {\n const frame = frameById.get(frameId);\n if (!frame) {\n throw createFixtureError(\n \"fixture-missing-frame\",\n `Plugin protocol tape references missing frame '${frameId}'.`,\n );\n }\n currentFrameId = frame.id;\n record({\n kind: \"frame-sent\",\n frameId: frame.id,\n projectionDigest: frame.projectionDigest,\n });\n sendHostPayload({\n type: \"gameplay.frame\",\n frame: frame.frame,\n });\n };\n\n const drainHostFrames = () => {\n while (options.tape.steps[stepCursor]?.kind === \"host.frame\") {\n const step = options.tape.steps[stepCursor] as Extract<\n PluginProtocolTape[\"steps\"][number],\n { kind: \"host.frame\" }\n >;\n stepCursor += 1;\n publishFrame(step.frameId);\n }\n };\n\n const drainOneHostFrame = () => {\n if (options.tape.steps[stepCursor]?.kind !== \"host.frame\") {\n return;\n }\n const step = options.tape.steps[stepCursor] as Extract<\n PluginProtocolTape[\"steps\"][number],\n { kind: \"host.frame\" }\n >;\n stepCursor += 1;\n publishFrame(step.frameId);\n };\n\n const waitForConfiguredLatency = async () => {\n if (latencyMs <= 0) {\n await Promise.resolve();\n return;\n }\n await new Promise<void>((resolve) => setTimeout(resolve, latencyMs));\n };\n\n const consumeExpectedStep = <\n Kind extends \"client.validate\" | \"client.submit\",\n >(\n kind: Kind,\n requestDigest: string,\n ): Extract<PluginProtocolTape[\"steps\"][number], { kind: Kind }> => {\n const step = options.tape.steps[stepCursor];\n if (!step) {\n throw createFixtureError(\n \"fixture-protocol-exhausted\",\n `Plugin protocol tape has no remaining step for ${kind}.`,\n );\n }\n if (step.kind !== kind) {\n throw createFixtureError(\n \"fixture-protocol-step-mismatch\",\n `Expected protocol step '${step.kind}' but received '${kind}'.`,\n );\n }\n if (step.fromFrameId !== currentFrameId) {\n throw createFixtureError(\n \"fixture-protocol-frame-mismatch\",\n `Expected protocol from frame '${step.fromFrameId}' but current frame is '${currentFrameId ?? \"<none>\"}'.`,\n );\n }\n if (step.requestDigest !== requestDigest) {\n const mode = strict ? \"strict\" : \"compatible\";\n throw createFixtureError(\n \"fixture-protocol-digest-mismatch\",\n `${mode} fixture protocol digest mismatch for ${kind}: expected ${step.requestDigest}, received ${requestDigest}.`,\n );\n }\n stepCursor += 1;\n return step as Extract<PluginProtocolTape[\"steps\"][number], { kind: Kind }>;\n };\n\n const handleValidate = async (command: ValidateInteractionCommand) => {\n const requestDigest = digestUIFixtureTransportRequest({\n operation: \"validate\",\n basis: command.basis,\n interactionId: command.interactionId,\n payload: command.params,\n });\n const step = consumeExpectedStep(\"client.validate\", requestDigest);\n record({\n kind: \"validate-received\",\n requestDigest,\n result: step.response.valid ? \"accepted\" : \"rejected\",\n });\n await waitForConfiguredLatency();\n sendHostPayload({\n type: \"interaction.validation-result\",\n requestId: command.requestId,\n result: step.response,\n });\n };\n\n const handleSubmit = async (command: SubmitInteractionCommand) => {\n const requestDigest = digestUIFixtureTransportRequest({\n operation: \"submit\",\n basis: command.basis,\n interactionId: command.interactionId,\n payload: command.params,\n });\n const step = consumeExpectedStep(\"client.submit\", requestDigest);\n record({\n kind: \"submit-received\",\n requestDigest,\n result: step.response.accepted ? \"accepted\" : \"rejected\",\n });\n await waitForConfiguredLatency();\n sendHostPayload({\n type: \"interaction.submit-result\",\n requestId: command.requestId,\n result: step.response,\n });\n if (step.response.accepted) {\n await waitForConfiguredLatency();\n drainHostFrames();\n }\n };\n\n const handleClientPayload = (payload: PluginToHostPayload) => {\n const trackHandler = (promise: Promise<void>) => {\n pendingHandlers.add(promise);\n promise\n .catch((error) => {\n rememberFixtureError(error);\n })\n .finally(() => {\n pendingHandlers.delete(promise);\n });\n };\n\n switch (payload.type) {\n case \"runtime.ready\":\n record({ kind: \"ready-received\" });\n break;\n case \"runtime.ack\":\n record({ kind: \"ack-received\" });\n break;\n case \"interaction.validate\":\n trackHandler(handleValidate(payload));\n break;\n case \"interaction.submit\":\n trackHandler(handleSubmit(payload));\n break;\n case \"runtime.error\":\n record({ kind: \"diagnostic\" });\n break;\n default: {\n const _exhaustive: never = payload;\n return _exhaustive;\n }\n }\n };\n\n const transport: PluginTransport = {\n start(nextOnMessage) {\n onMessage = nextOnMessage;\n queueMicrotask(() => {\n sendInit();\n drainOneHostFrame();\n });\n return () => {\n onMessage = null;\n };\n },\n send(message) {\n handleClientPayload(message);\n },\n };\n\n return {\n transport,\n tape: options.tape,\n reset() {\n eventSequence = 0;\n envelopeSequence = 0;\n stepCursor = 0;\n currentFrameId = null;\n firstFixtureError = null;\n pendingHandlers.clear();\n events.length = 0;\n if (onMessage) {\n sendInit();\n drainOneHostFrame();\n }\n },\n async flush() {\n await waitForConfiguredLatency();\n await Promise.resolve();\n while (pendingHandlers.size > 0) {\n await Promise.allSettled([...pendingHandlers]);\n }\n throwFixtureError();\n },\n async advanceHost() {\n await waitForConfiguredLatency();\n drainHostFrames();\n throwFixtureError();\n },\n getCurrentFrameId() {\n if (!currentFrameId) {\n throw createFixtureError(\n \"fixture-frame-not-started\",\n \"Fixture host has not emitted a gameplay frame.\",\n );\n }\n return currentFrameId;\n },\n getEvents() {\n return events.map((event) => ({ ...event }));\n },\n assertConsumed() {\n throwFixtureError();\n if (stepCursor !== options.tape.steps.length) {\n throw createFixtureError(\n \"fixture-unconsumed-protocol-steps\",\n `Plugin protocol tape consumed ${stepCursor} of ${options.tape.steps.length} protocol step(s).`,\n );\n }\n },\n };\n}\n","import React, { useMemo } from \"react\";\nimport { createPluginRuntimeClient } from \"../../runtime/core/create-plugin-runtime-client.js\";\nimport { PluginRuntimeBoundary } from \"../../runtime/components/PluginRuntimeBoundary.js\";\nimport type { PluginRuntimeClient } from \"../../runtime/core/types.js\";\nimport type { FixtureHostHarness } from \"./create-fixture-host-harness.js\";\n\nexport function FixturePluginRuntime({\n harness,\n runtime,\n children,\n}: {\n harness: FixtureHostHarness;\n runtime?: PluginRuntimeClient;\n children: React.ReactNode;\n}) {\n const fixtureRuntime = useMemo(\n () =>\n runtime ?? createPluginRuntimeClient({ transport: harness.transport }),\n [harness.transport, runtime],\n );\n return (\n <PluginRuntimeBoundary runtime={fixtureRuntime}>\n {children}\n </PluginRuntimeBoundary>\n );\n}\n","import {\n materializePluginGameplayFrame,\n type PluginSessionDescriptor,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport { digestUIFixtureTransportRequest } from \"./canonical.js\";\nimport type { PluginProtocolTape, UIFixtureFrame } from \"./schema.js\";\nimport type { UIFixtureProtocolStep } from \"./schema.js\";\nimport type {\n ReducerScenarioExchange,\n ReducerScenarioFrame,\n ReducerScenarioTrace,\n} from \"../reducer-scenario/types.js\";\n\nexport interface CompilePluginProtocolTapeOptions {\n readonly trace: ReducerScenarioTrace;\n readonly session: PluginSessionDescriptor;\n}\n\nexport function compilePluginProtocolTape(\n options: CompilePluginProtocolTapeOptions,\n): PluginProtocolTape {\n const frames = options.trace.frames.map((frame) =>\n materializeTraceFrame(frame, options.trace.viewer.playerId),\n );\n const frameById = new Map(frames.map((frame) => [frame.id, frame]));\n const steps: UIFixtureProtocolStep[] = [];\n\n const firstFrame = frames[0];\n if (!firstFrame) {\n throw new Error(\n `Reducer scenario '${options.trace.scenarioId}' did not record frames.`,\n );\n }\n steps.push({\n id: `${firstFrame.id}.host-frame`,\n kind: \"host.frame\",\n frameId: firstFrame.id,\n });\n\n for (const exchange of options.trace.exchanges) {\n const fromFrame = frameById.get(exchange.fromFrameId);\n if (!fromFrame) {\n throw new Error(\n `Reducer exchange '${exchange.id}' references missing frame '${exchange.fromFrameId}'.`,\n );\n }\n if (exchange.operation === \"validate\") {\n steps.push({\n id: exchange.id,\n kind: \"client.validate\",\n fromFrameId: exchange.fromFrameId,\n requestDigest: digestRuntimeCommand(exchange, fromFrame),\n response: {\n valid: exchange.result.valid,\n errorCode: exchange.result.errorCode,\n message: exchange.result.message,\n },\n });\n continue;\n }\n\n steps.push({\n id: exchange.id,\n kind: \"client.submit\",\n fromFrameId: exchange.fromFrameId,\n requestDigest: digestRuntimeCommand(exchange, fromFrame),\n response:\n exchange.result.kind === \"accepted\"\n ? { accepted: true }\n : {\n accepted: false,\n errorCode:\n exchange.result.diagnostics[0]?.code ?? \"fixture-rejected\",\n message: exchange.result.diagnostics[0]?.message,\n },\n });\n if (exchange.result.kind === \"accepted\") {\n if (!frameById.has(exchange.result.toFrameId)) {\n throw new Error(\n `Reducer exchange '${exchange.id}' references missing toFrameId '${exchange.result.toFrameId}'.`,\n );\n }\n steps.push({\n id: `${exchange.id}.host-frame`,\n kind: \"host.frame\",\n frameId: exchange.result.toFrameId,\n });\n }\n }\n\n return {\n session: options.session,\n frames,\n steps,\n };\n}\n\nfunction materializeTraceFrame(\n frame: ReducerScenarioFrame,\n perspectivePlayerId: string,\n): UIFixtureFrame {\n const flow = readFlowState(frame.reducerState);\n return {\n id: frame.id,\n frame: materializePluginGameplayFrame({\n currentPhase: flow.currentPhase,\n activePlayers: flow.activePlayers,\n dynamicProjection: frame.dynamicProjection,\n staticProjection: frame.staticProjection,\n perspectivePlayerId,\n gameVersion: frame.gameVersion,\n actionSetVersion: frame.actionSetVersion,\n }),\n projectionDigest: frame.projectionDigest,\n };\n}\n\nfunction digestRuntimeCommand(\n exchange: ReducerScenarioExchange,\n frame: UIFixtureFrame,\n): string {\n return digestUIFixtureTransportRequest({\n operation: exchange.operation === \"validate\" ? \"validate\" : \"submit\",\n basis: {\n gameVersion: frame.frame.gameVersion,\n actionSetVersion: frame.frame.actionSetVersion,\n perspectivePlayerId: frame.frame.perspectivePlayerId,\n },\n interactionId: exchange.input.interactionId,\n payload: exchange.input.params,\n });\n}\n\nfunction readFlowState(state: {\n readonly domain?: {\n readonly flow?: {\n readonly currentPhase?: string;\n readonly activePlayers?: readonly string[];\n };\n };\n}): { currentPhase: string | null; activePlayers: readonly string[] } {\n return {\n currentPhase: state.domain?.flow?.currentPhase ?? null,\n activePlayers: [...(state.domain?.flow?.activePlayers ?? [])],\n };\n}\n","export interface FixtureEnvironmentInit {\n readonly clockIso: string;\n readonly randomSeed: string;\n readonly locale: \"en-US\";\n readonly timezone: \"UTC\";\n readonly reducedMotion: true;\n readonly network: \"blocked\";\n}\n\nexport const defaultFixtureEnvironmentInit: FixtureEnvironmentInit = {\n clockIso: \"2026-01-01T00:00:00.000Z\",\n randomSeed: \"dreamboard-ui-fixture\",\n locale: \"en-US\",\n timezone: \"UTC\",\n reducedMotion: true,\n network: \"blocked\",\n};\n\nexport type DeterministicIdFactory = () => string;\n\nexport function createDeterministicIdFactory(\n seed: string,\n): DeterministicIdFactory {\n let cursor = 0;\n return () => {\n cursor += 1;\n return `fixture-${slug(seed)}-${cursor.toString(36).padStart(4, \"0\")}`;\n };\n}\n\nexport function fixtureEnvironmentInitFor(options: {\n readonly clockIso: string;\n readonly randomSeed: string;\n}): FixtureEnvironmentInit {\n return {\n ...defaultFixtureEnvironmentInit,\n clockIso: options.clockIso,\n randomSeed: options.randomSeed,\n };\n}\n\nfunction slug(value: string): string {\n return (\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 48) || \"seed\"\n );\n}\n","import { z } from \"zod\";\nimport {\n BROWSER_INTERACTION_ACTUATOR_KINDS,\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n browserInteractionEffectSchema,\n} from \"../../browser-interaction/index.js\";\nimport type {\n BrowserInteractionEffectRequest,\n BrowserInteractionIntentRequest,\n} from \"../../browser-interaction/index.js\";\nimport { RuntimeJsonSchema } from \"../../runtime-json.js\";\nimport { digestUIFixtureRequest, isSha256Digest } from \"./canonical.js\";\nimport {\n DREAMBOARD_PLUGIN_PROTOCOL_VERSION as PLUGIN_RUNTIME_PROTOCOL_VERSION,\n PluginProtocolFrameSchema,\n PluginProtocolStepSchema,\n PluginProtocolTapeSchema,\n type PluginProtocolFrame,\n type PluginProtocolStep,\n type PluginProtocolTape as RuntimePluginProtocolTape,\n} from \"@dreamboard-games/plugin-runtime-contract\";\n\nexport const UI_SCENARIO_FIXTURE_SCHEMA_VERSION = 2;\nexport const UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION = 2;\nexport const UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR = 3;\nexport const UI_SCENARIO_FIXTURE_PLUGIN_RUNTIME_PROTOCOL =\n PLUGIN_RUNTIME_PROTOCOL_VERSION;\n\nconst digestSchema = z.string().refine(isSha256Digest, {\n message: \"Expected a sha256:<64 lowercase hex> digest.\",\n});\n\nconst nonEmptyStringSchema = z.string().min(1);\nconst jsonSchema = RuntimeJsonSchema;\n\nconst environmentSchema = z\n .object({\n clockIso: nonEmptyStringSchema,\n randomSeed: nonEmptyStringSchema,\n locale: z.literal(\"en-US\"),\n timezone: z.literal(\"UTC\"),\n viewportTags: z.array(z.enum([\"desktop\", \"tablet\", \"phone\", \"touch\"])),\n })\n .strict();\n\nexport const uiFixtureFrameSchema = PluginProtocolFrameSchema;\nexport const uiFixtureProtocolStepSchema = PluginProtocolStepSchema;\nexport const pluginProtocolTapeSchema = PluginProtocolTapeSchema.refine(\n (tape) => tape.frames.length > 0,\n \"UI fixture protocol tapes require at least one gameplay frame.\",\n);\n\nconst browserInteractionIntentRequestSchema = z\n .object({\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema.optional(),\n interactionKey: nonEmptyStringSchema.optional(),\n interactionId: nonEmptyStringSchema.optional(),\n intent: nonEmptyStringSchema,\n inputKey: nonEmptyStringSchema.optional(),\n candidateValue: jsonSchema.optional(),\n candidateValueKey: nonEmptyStringSchema.optional(),\n actuatorKind: z.enum(BROWSER_INTERACTION_ACTUATOR_KINDS).optional(),\n allowDisabled: z.boolean().optional(),\n })\n .strict();\n\nconst browserInteractionEffectRequestSchema = z\n .object({\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema.optional(),\n interactionKey: nonEmptyStringSchema.optional(),\n interactionId: nonEmptyStringSchema.optional(),\n effect: browserInteractionEffectSchema,\n allowDisabled: z.boolean().optional(),\n })\n .strict();\n\nexport const uiReplayRequestSchema = z.union([\n browserInteractionIntentRequestSchema,\n browserInteractionEffectRequestSchema,\n]);\n\nexport const uiReplayExecutionSchema = z.union([\n z\n .object({\n kind: z.literal(\"activate\"),\n })\n .strict(),\n z\n .object({\n kind: z.literal(\"fill\"),\n value: z.string(),\n })\n .strict(),\n z\n .object({\n kind: z.literal(\"drag\"),\n target: browserInteractionEffectRequestSchema,\n })\n .strict(),\n]);\n\nexport const uiStepExpectationSchema = z\n .object({\n frameId: nonEmptyStringSchema.optional(),\n projectionDigest: digestSchema.optional(),\n semanticDigest: digestSchema.optional(),\n draftDigest: digestSchema.optional(),\n submissionDigest: digestSchema.optional(),\n focusedInteractionKey: nonEmptyStringSchema.optional(),\n visibleInteractionKeys: z.array(nonEmptyStringSchema).optional(),\n })\n .strict();\n\nexport const uiResolvedReplayIdentitySchema = z\n .object({\n stepId: nonEmptyStringSchema,\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema,\n interactionKey: nonEmptyStringSchema,\n interactionId: nonEmptyStringSchema,\n actuatorId: nonEmptyStringSchema,\n descriptorDigest: digestSchema.optional(),\n draftDigest: digestSchema.optional(),\n })\n .strict();\n\nexport const portableSemanticReplayStepSchema = z\n .object({\n stepId: nonEmptyStringSchema,\n requestDigest: digestSchema,\n resolve: uiReplayRequestSchema,\n execute: uiReplayExecutionSchema,\n expectedIdentity: uiResolvedReplayIdentitySchema.optional(),\n expect: uiStepExpectationSchema,\n })\n .strict();\n\nexport const uiScenarioReplayStepSchema = z.union([\n portableSemanticReplayStepSchema,\n z\n .object({\n stepId: nonEmptyStringSchema,\n kind: z.literal(\"assert\"),\n expect: uiStepExpectationSchema,\n })\n .strict(),\n]);\n\nexport const uiScenarioFixtureSchema = z\n .object({\n schemaVersion: z.literal(UI_SCENARIO_FIXTURE_SCHEMA_VERSION),\n browserInteractionProtocol: z.literal(\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n ),\n pluginRuntimeProtocol: z.literal(PLUGIN_RUNTIME_PROTOCOL_VERSION),\n id: nonEmptyStringSchema,\n title: nonEmptyStringSchema,\n gameId: nonEmptyStringSchema,\n tags: z.array(nonEmptyStringSchema),\n source: z\n .object({\n scenarioId: nonEmptyStringSchema,\n reducerFingerprint: nonEmptyStringSchema,\n uiContractFingerprint: nonEmptyStringSchema,\n renderModule: nonEmptyStringSchema,\n renderModuleDigest: digestSchema,\n sourceDigest: digestSchema,\n sourceFiles: z.array(nonEmptyStringSchema).optional(),\n })\n .strict(),\n viewer: z\n .object({\n seatId: nonEmptyStringSchema,\n playerId: nonEmptyStringSchema.optional(),\n })\n .strict(),\n environment: environmentSchema,\n protocol: pluginProtocolTapeSchema,\n replay: z.array(uiScenarioReplayStepSchema),\n expected: z\n .object({\n initialProjectionDigest: digestSchema,\n finalProjectionDigest: digestSchema,\n finalSemanticDigest: digestSchema,\n submissionDigest: digestSchema,\n })\n .strict(),\n })\n .strict();\n\nexport const uiScenarioFixtureBundleIndexSchema = z\n .object({\n schemaVersion: z.literal(UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION),\n bundleId: nonEmptyStringSchema,\n sdkCommit: nonEmptyStringSchema,\n pluginRuntimeProtocol: z.literal(PLUGIN_RUNTIME_PROTOCOL_VERSION),\n browserInteractionProtocol: z.literal(\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n ),\n fixtures: z.array(\n z\n .object({\n id: nonEmptyStringSchema,\n file: nonEmptyStringSchema,\n sha256: digestSchema,\n renderModule: nonEmptyStringSchema,\n renderModuleSha256: digestSchema,\n components: z.array(nonEmptyStringSchema),\n capabilities: z.array(nonEmptyStringSchema),\n })\n .strict(),\n ),\n })\n .strict();\n\nexport type UIReplayRequest =\n | BrowserInteractionIntentRequest\n | BrowserInteractionEffectRequest;\nexport type UIReplayExecution = z.infer<typeof uiReplayExecutionSchema>;\nexport type UIStepExpectation = z.infer<typeof uiStepExpectationSchema>;\nexport type UIResolvedReplayIdentity = z.infer<\n typeof uiResolvedReplayIdentitySchema\n>;\nexport type PortableSemanticReplayStep = z.infer<\n typeof portableSemanticReplayStepSchema\n>;\nexport type UIScenarioReplayStep = z.infer<typeof uiScenarioReplayStepSchema>;\nexport type UIFixtureFrame = PluginProtocolFrame;\nexport type UIFixtureProtocolStep = PluginProtocolStep;\nexport type PluginProtocolTape = RuntimePluginProtocolTape;\nexport type UIScenarioFixture = Omit<\n z.infer<typeof uiScenarioFixtureSchema>,\n \"protocol\" | \"replay\"\n> & {\n readonly protocol: PluginProtocolTape;\n readonly replay: readonly UIScenarioReplayStep[];\n};\nexport type UIScenarioFixtureBundleIndex = z.infer<\n typeof uiScenarioFixtureBundleIndexSchema\n>;\n\nexport function parseUIScenarioFixture(value: unknown): UIScenarioFixture {\n const fixture = uiScenarioFixtureSchema.parse(\n value,\n ) as unknown as UIScenarioFixture;\n validateUIScenarioFixtureReferences(fixture);\n return fixture;\n}\n\nexport function parseUIScenarioFixtureBundleIndex(\n value: unknown,\n): UIScenarioFixtureBundleIndex {\n const bundle = uiScenarioFixtureBundleIndexSchema.parse(value);\n assertSupportedBrowserInteractionProtocol(bundle.browserInteractionProtocol);\n const ids = new Set<string>();\n for (const entry of bundle.fixtures) {\n if (ids.has(entry.id)) {\n throw new Error(`Duplicate fixture id '${entry.id}' in bundle index.`);\n }\n ids.add(entry.id);\n }\n return bundle;\n}\n\nexport function assertSupportedBrowserInteractionProtocol(\n version: string,\n): void {\n const major = Number(version.split(\".\")[0]);\n if (major !== UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR) {\n throw new Error(\n `Unsupported browser-interaction protocol '${version}'. Expected major ${UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR}.`,\n );\n }\n}\n\nfunction validateUIScenarioFixtureReferences(fixture: UIScenarioFixture): void {\n assertSupportedBrowserInteractionProtocol(fixture.browserInteractionProtocol);\n const frameIds = new Set<string>();\n const stepIds = new Set<string>();\n\n for (const frame of fixture.protocol.frames) {\n if (frameIds.has(frame.id)) {\n throw new Error(`Duplicate fixture frame id '${frame.id}'.`);\n }\n frameIds.add(frame.id);\n }\n\n for (const step of fixture.protocol.steps) {\n if (stepIds.has(step.id)) {\n throw new Error(`Duplicate protocol step id '${step.id}'.`);\n }\n stepIds.add(step.id);\n if (step.kind === \"host.frame\") {\n if (!frameIds.has(step.frameId)) {\n throw new Error(\n `Protocol step '${step.id}' references missing frameId '${step.frameId}'.`,\n );\n }\n continue;\n }\n if (!frameIds.has(step.fromFrameId)) {\n throw new Error(\n `Protocol step '${step.id}' references missing fromFrameId '${step.fromFrameId}'.`,\n );\n }\n }\n\n for (const step of fixture.replay) {\n if (\"resolve\" in step) {\n const actualDigest = digestUIFixtureRequest(\n step.resolve as unknown as UIReplayRequest,\n );\n if (step.requestDigest !== actualDigest) {\n throw new Error(\n `Replay step '${step.stepId}' requestDigest ${step.requestDigest} does not match ${actualDigest}.`,\n );\n }\n }\n const expectedFrameId = step.expect.frameId;\n if (expectedFrameId && !frameIds.has(expectedFrameId)) {\n throw new Error(\n `Replay step '${step.stepId}' expects missing frameId '${expectedFrameId}'.`,\n );\n }\n }\n}\n","import {\n canonicalizeUIScenarioFixture,\n digestUIFixtureJson,\n serializeUIScenarioFixture,\n} from \"./canonical.js\";\nimport { DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION } from \"../../browser-interaction/index.js\";\nimport { DREAMBOARD_PLUGIN_PROTOCOL_VERSION as PLUGIN_RUNTIME_PROTOCOL_VERSION } from \"@dreamboard-games/plugin-runtime-contract\";\nimport {\n parseUIScenarioFixture,\n type PortableSemanticReplayStep,\n type PluginProtocolTape,\n type UIResolvedReplayIdentity,\n type UIScenarioFixture,\n type UIScenarioReplayStep,\n type UIStepExpectation,\n} from \"./schema.js\";\n\nexport interface CompileUIScenarioFixtureOptions {\n readonly id: string;\n readonly title: string;\n readonly gameId: string;\n readonly tags?: readonly string[];\n readonly source: UIScenarioFixture[\"source\"];\n readonly viewer: UIScenarioFixture[\"viewer\"];\n readonly environment: UIScenarioFixture[\"environment\"];\n readonly protocol: PluginProtocolTape;\n readonly replay?: readonly UIScenarioReplayStep[];\n readonly expected?: Partial<UIScenarioFixture[\"expected\"]>;\n}\n\nexport type UIReplayIdentityCandidate = UIResolvedReplayIdentity;\n\nexport function compileUIScenarioFixture(\n options: CompileUIScenarioFixtureOptions,\n): UIScenarioFixture {\n const firstFrame = options.protocol.frames[0];\n const finalFrame = lastPublishedFrame(options.protocol);\n if (!firstFrame || !finalFrame) {\n throw new Error(\n \"compileUIScenarioFixture requires at least one protocol frame.\",\n );\n }\n\n const replay = options.replay ?? [];\n const submissionDigest =\n options.expected?.submissionDigest ??\n digestUIFixtureJson({\n digestVersion: \"ui-submission@1\",\n fixtureId: options.id,\n replay: replay.map((step) =>\n \"requestDigest\" in step ? step.requestDigest : step.stepId,\n ),\n });\n const finalSemanticDigest =\n options.expected?.finalSemanticDigest ??\n digestUIFixtureJson({\n digestVersion: \"ui-semantic@1\",\n fixtureId: options.id,\n frameId: finalFrame.id,\n projectionDigest: finalFrame.projectionDigest,\n });\n\n return parseUIScenarioFixture(\n canonicalizeUIScenarioFixture({\n schemaVersion: 2,\n browserInteractionProtocol:\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n pluginRuntimeProtocol: PLUGIN_RUNTIME_PROTOCOL_VERSION,\n id: options.id,\n title: options.title,\n gameId: options.gameId,\n tags: [...(options.tags ?? [])],\n source: options.source,\n viewer: options.viewer,\n environment: options.environment,\n protocol: options.protocol,\n replay,\n expected: {\n initialProjectionDigest:\n options.expected?.initialProjectionDigest ??\n firstFrame.projectionDigest,\n finalProjectionDigest:\n options.expected?.finalProjectionDigest ??\n finalFrame.projectionDigest,\n finalSemanticDigest,\n submissionDigest,\n },\n }),\n );\n}\n\nfunction lastPublishedFrame(\n protocol: PluginProtocolTape,\n): PluginProtocolTape[\"frames\"][number] | undefined {\n const frameById = new Map(protocol.frames.map((frame) => [frame.id, frame]));\n for (let index = protocol.steps.length - 1; index >= 0; index -= 1) {\n const step = protocol.steps[index];\n if (step?.kind === \"host.frame\") {\n return frameById.get(step.frameId);\n }\n }\n return protocol.frames[protocol.frames.length - 1];\n}\n\nexport function assertDeterministicUIScenarioFixture(\n first: UIScenarioFixture,\n second: UIScenarioFixture,\n): void {\n const firstBytes = serializeUIScenarioFixture(first);\n const secondBytes = serializeUIScenarioFixture(second);\n if (firstBytes !== secondBytes) {\n throw new Error(\n `UI scenario fixture '${first.id}' is non-deterministic across compilation runs.`,\n );\n }\n}\n\nexport function assertUniqueReplayIdentity(\n step: Pick<PortableSemanticReplayStep, \"stepId\" | \"expectedIdentity\">,\n candidates: readonly UIReplayIdentityCandidate[],\n): UIReplayIdentityCandidate {\n if (candidates.length !== 1) {\n throw new Error(\n `Replay step '${step.stepId}' resolved ${candidates.length} identities; expected exactly one.`,\n );\n }\n const candidate = candidates[0];\n if (!candidate) {\n throw new Error(`Replay step '${step.stepId}' did not resolve.`);\n }\n\n const expected = step.expectedIdentity;\n if (!expected) {\n return candidate;\n }\n for (const key of [\n \"surface\",\n \"scopeId\",\n \"interactionKey\",\n \"interactionId\",\n \"actuatorId\",\n \"descriptorDigest\",\n \"draftDigest\",\n ] as const) {\n const expectedValue = expected[key];\n if (expectedValue !== undefined && candidate[key] !== expectedValue) {\n throw new Error(\n `Replay step '${step.stepId}' resolved ${key} '${String(\n candidate[key],\n )}', expected '${expectedValue}'.`,\n );\n }\n }\n return candidate;\n}\n\nexport function assertUIStepExpectationSatisfied(\n stepId: string,\n expected: UIStepExpectation,\n actual: UIStepExpectation,\n): void {\n for (const key of [\n \"frameId\",\n \"projectionDigest\",\n \"semanticDigest\",\n \"draftDigest\",\n \"submissionDigest\",\n \"focusedInteractionKey\",\n ] as const) {\n if (expected[key] !== undefined && expected[key] !== actual[key]) {\n throw new Error(\n `Replay step '${stepId}' expected ${key} '${expected[key]}', received '${actual[key]}'.`,\n );\n }\n }\n if (expected.visibleInteractionKeys) {\n const actualKeys = new Set(actual.visibleInteractionKeys ?? []);\n const missing = expected.visibleInteractionKeys.filter(\n (key) => !actualKeys.has(key),\n );\n if (missing.length > 0) {\n throw new Error(\n `Replay step '${stepId}' missing visible interactions: ${missing.join(\n \", \",\n )}.`,\n );\n }\n }\n}\n","import {\n digestUIFixtureRequest,\n type PortableSemanticReplayStep,\n type UIResolvedReplayIdentity,\n type UIScenarioReplayStep,\n type UIStepExpectation,\n} from \"../ui-fixture/index.js\";\n\ntype ReplayRequest = PortableSemanticReplayStep[\"resolve\"];\ntype DragTarget = Extract<\n PortableSemanticReplayStep[\"execute\"],\n { kind: \"drag\" }\n>[\"target\"];\n\ninterface ReplayStepOptions {\n readonly stepId: string;\n readonly resolve: ReplayRequest;\n readonly expect: UIStepExpectation;\n readonly expectedIdentity?: UIResolvedReplayIdentity;\n}\n\ninterface FillReplayStepOptions extends ReplayStepOptions {\n readonly value: string;\n}\n\ninterface DragReplayStepOptions extends ReplayStepOptions {\n readonly target: DragTarget;\n}\n\nfunction semanticStep(\n options: ReplayStepOptions,\n execute: Exclude<UIScenarioReplayStep, { kind: \"assert\" }>[\"execute\"],\n): UIScenarioReplayStep {\n return {\n stepId: options.stepId,\n requestDigest: digestUIFixtureRequest(options.resolve),\n resolve: options.resolve,\n execute,\n expectedIdentity: options.expectedIdentity,\n expect: options.expect,\n };\n}\n\nexport function activate(options: ReplayStepOptions): UIScenarioReplayStep {\n return semanticStep(options, { kind: \"activate\" });\n}\n\nexport function fill(options: FillReplayStepOptions): UIScenarioReplayStep {\n return semanticStep(options, { kind: \"fill\", value: options.value });\n}\n\nexport function press(options: ReplayStepOptions): UIScenarioReplayStep {\n return activate(options);\n}\n\nexport function drag(options: DragReplayStepOptions): UIScenarioReplayStep {\n return semanticStep(options, { kind: \"drag\", target: options.target });\n}\n\nexport function submit(options: ReplayStepOptions): UIScenarioReplayStep {\n return activate(options);\n}\n\nexport function assertStep(\n stepId: string,\n expect: UIStepExpectation,\n): UIScenarioReplayStep {\n return {\n stepId,\n kind: \"assert\",\n expect,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBO,SAAS,qBAAqB,SAGlB;AACjB,QAAM,QAAQ,CAAC,aAAsC;AACnD,UAAM,OAAO,QAAQ,UAAU,QAAQ,QAAQ;AAC/C,WAAO,OAAO,IAAI,OAAO,EAAE,MAAM,SAAS;AAAA,EAC5C;AACA,QAAM,SAAS,CAAC,cACd,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC,EACnB,QAAQ,CAAC,aAAa;AACrB,UAAM,WAAW,MAAM,QAAQ;AAC/B,WAAO,WAAW,CAAC,QAAQ,IAAI,CAAC;AAAA,EAClC,CAAC,EACA,KAAK,CAAC,MAAM,UAAU,KAAK,OAAO,MAAM,IAAI;AAEjD,QAAM,aAAa,QAAQ,UAAU,4BAA4B,CAAC,GAC/D,QAAQ,CAAC,eAAe;AACvB,UAAM,SAAS,MAAM,WAAW,cAAc;AAC9C,UAAM,WAAW,OAAO,WAAW,gBAAgB;AACnD,WAAO,UAAU,SAAS,SAAS,IAC/B;AAAA,MACE;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,QAAQ;AAAA,MACV;AAAA,IACF,IACA,CAAC;AAAA,EACP,CAAC,EACA,KAAK,CAAC,MAAM,UAAU,KAAK,MAAM,OAAO,MAAM,MAAM,IAAI;AAE3D,SAAO;AAAA,IACL,OAAO,QAAQ,UAAU;AAAA,IACzB,MAAM,QAAQ,UAAU;AAAA,IACxB,cAAc,OAAO,QAAQ,UAAU,eAAe;AAAA,IACtD,eAAe,OAAO,QAAQ,UAAU,gBAAgB;AAAA,IACxD,qBAAqB;AAAA,MACnB,UAAU,IAAI,CAAC,eAAe,WAAW,MAAM,QAAQ;AAAA,IACzD;AAAA,IACA;AAAA,EACF;AACF;;;AClCO,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACxC;AAAA,EAIA;AAAA,EAET,YAAY,SAIT;AACD,UAAM,QAAQ,OAAO;AACrB,SAAK,OAAO;AACZ,SAAK,OAAO,QAAQ;AACpB,SAAK,UAAU,QAAQ,WAAW,CAAC;AAAA,EACrC;AACF;AAWA,eAAsB,gBAEpB,SAAuE;AACvE,yBAAuB,QAAQ,UAAU,QAAQ,QAAQ;AACzD,aAAW,QAAQ,IAAI;AACvB,QAAM,mBACJ,QAAQ,SAAS,SACb,QAAQ,WACR;AAAA,IACE,GAAG,QAAQ;AAAA,IACX,OAAO,EAAE,GAAG,QAAQ,SAAS,OAAO,MAAM,QAAQ,KAAK;AAAA,EACzD;AACN,QAAM,aACJ,QAAQ,MACP;AAAA,IACC,SAAS;AAAA,IACT,WAAW,iBAAiB,MAAM;AAAA,EACpC;AACF,QAAM,SAAS,MAAM,eAAe;AAAA,IAClC,MAAM,QAAQ;AAAA,IACd,UAAU;AAAA,IACV,IAAI;AAAA,EACN,CAAC;AACD,QAAM,OAAO,0BAA0B;AAAA,IACrC;AAAA,IACA,aAAa,QAAQ;AAAA,EACvB,CAAC;AACD,SAAO;AAAA,IACL,eAAe;AAAA,IACf,UAAU,gBAAgB,QAAQ,QAAQ;AAAA,IAC1C;AAAA,IACA,YAAY,QAAQ,SAAS,SAAY,aAAa;AAAA,EACxD;AACF;AAEO,SAAS,0BAAgC,SAGhC;AACd,QAAM,gBAAgB,+BAA+B;AAAA,IACnD,QAAQ,QAAQ;AAAA,IAChB,aAAa,EAAE,MAAM,YAAY;AAAA,EACnC,CAAC;AACD,QAAM,cAAc;AAAA,IAClB,QAAQ;AAAA,IACR,cAAc,SAAS,MAAM;AAAA,IAC7B,cAAc;AAAA,EAChB;AACA,QAAM,YAAY,+BAA+B;AAAA,IAC/C,QAAQ,QAAQ;AAAA,IAChB,aACE,YAAY,SAAS,cACjB,cACA,EAAE,MAAM,UAAU,MAAM,YAAY,MAAM,KAAK;AAAA,EACvD,CAAC;AACD,QAAM,QAAQ,YAAY,SAAS,WAAW,YAAY,QAAQ;AAClE,QAAM,eAAe,QACjB,UAAU,aAAa;AAAA,IAAI,CAAC,EAAE,YAAY,YAAY,MACpD,mBAAmB,OAAO,YAAY,WAAW;AAAA,EACnD,IACA,CAAC;AACL,QAAM,UAAU,QACZ,UAAU,aAAa;AAAA,IACrB,CAAC,EAAE,aAAa,cAAc,MAAuB;AACnD,UACE,CAAC,cAAc,SACf,CAAC,cAAc,WACf,cAAc,WAAW,aAAa,WAAW,eACjD,cAAc,qBAAqB,WAAW,OAC9C;AACA,eAAO,CAAC;AAAA,MACV;AACA,aAAO;AAAA,QACL;AAAA,UACE;AAAA,UACA,eAAe,cAAc,WAAW;AAAA,UACxC,QAAQ,YAAY;AAAA,UACpB;AAAA,UACA,oBAAoB;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF,IACA,CAAC;AACL,QAAM,OAAoB;AAAA,IACxB,YAAY,UAAU;AAAA,IACtB,kBAAkB,UAAU;AAAA,IAC5B,OAAO,gBAAgB,UAAU,SAAS,KAAK;AAAA,IAC/C,MAAM,qBAAqB;AAAA,MACzB,WAAW,UAAU;AAAA,MACrB,WAAW,UAAU;AAAA,IACvB,CAAC;AAAA,IACD;AAAA,IACA,aAAa,UAAU;AAAA,IACvB,MAAM,UAAU;AAAA,IAChB;AAAA,IACA;AAAA,IACA,SAAS;AAAA,MACP,MAAM,UAAU,QAAQ,QAAQ,UAAU,SAAS,MAAM;AAAA,MACzD,OAAO,gBAAgB,UAAU,QAAQ,KAAK;AAAA,IAChD;AAAA,IACA,eAAe;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBACP,UACA,aACA,mBACgB;AAChB,MAAI,SAAS,SAAS,YAAa,QAAO,EAAE,MAAM,YAAY;AAC9D,QAAM,OAAO,SAAS;AACtB,MAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,KAAK,QAAQ,aAAa;AAClE,UAAM,IAAI,wBAAwB;AAAA,MAChC,MAAM;AAAA,MACN,SAAS,oBAAoB,OAAO,IAAI,CAAC,oBAAoB,WAAW;AAAA,MACxE,SAAS;AAAA,QACP,eAAe;AAAA,QACf,aAAa;AAAA,QACb,aAAa,KAAK,IAAI,GAAG,cAAc,CAAC;AAAA,MAC1C;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,MACL;AAAA,MACA,UAAU,kBAAkB,IAAI,KAAK,UAAU,OAAO,CAAC;AAAA,IACzD;AAAA,EACF;AACF;AAEA,SAAS,mBACP,OACA,YACA,aACoB;AACpB,QAAM,eAAe,WAAW,gBAAgB;AAAA,IAC9C,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACA,SAAO;AAAA,IACL;AAAA,IACA,eAAe,OAAO,WAAW,iBAAiB,EAAE;AAAA,IACpD,cAAc;AAAA,MACZ,QAAQ,aAAa;AAAA,MACrB,GAAI,UAAU,gBAAgB,OAAO,aAAa,SAAS,WACvD,EAAE,MAAM,aAAa,KAAK,IAC1B,CAAC;AAAA,MACL,GAAI,YAAY,gBAAgB,OAAO,aAAa,WAAW,WAC3D,EAAE,QAAQ,aAAa,OAAO,IAC9B,CAAC;AAAA,IACP;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB;AAAA,EACF;AACF;AAEA,SAAS,qBACP,cACA,WACA,aAC8B;AAC9B,MAAI,YAAY,SAAS,YAAa,QAAO,CAAC;AAC9C,QAAM,eAAe,YAAY,MAAM;AACvC,SAAO,aAAa,QAAQ,CAAC,UAAwC;AACnE,QAAI,MAAM,QAAQ,MAAM,SAAS,aAAc,QAAO,CAAC;AACvD,WAAO,MAAM,MAAM,QAAQ,CAAC,UAAwC;AAClE,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK,uBAAuB;AAC1B,gBAAM,OAAO,UAAU,QAAQ,MAAM,QAAQ;AAC7C,iBAAO,OAAO,IACV,CAAC,IACD;AAAA,YACE;AAAA,cACE,MAAM;AAAA,cACN,OAAO,EAAE,MAAM,UAAU,MAAM,SAAS;AAAA,cACxC,eAAe,MAAM;AAAA,YACvB;AAAA,UACF;AAAA,QACN;AAAA,QACA,KAAK;AACH,iBAAO;AAAA,YACL;AAAA,cACE,MAAM;AAAA,cACN,iBAAiB,MAAM;AAAA,YACzB;AAAA,UACF;AAAA,QACF,KAAK;AACH,iBAAO,CAAC,EAAE,MAAM,eAAe,WAAW,MAAM,UAAU,CAAC;AAAA,MAC/D;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACH;AAEA,SAAS,uBACP,UACA,UACM;AACN,MAAI,SAAS,OAAO,SAAS,IAAI;AAC/B,UAAM,IAAI,wBAAwB;AAAA,MAChC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,EAAE,YAAY,SAAS,IAAI,YAAY,SAAS,GAAG;AAAA,IAC9D,CAAC;AAAA,EACH;AACF;AAEA,SAAS,WAAW,MAAgC;AAClD,MAAI,SAAS,UAAa,CAAC,OAAO,cAAc,IAAI,GAAG;AACrD,UAAM,IAAI,wBAAwB;AAAA,MAChC,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,EAAE,eAAe,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AACF;;;ACnRA,SAAS,cAAc;AAQvB,IAAM,iBAAiB;AAWhB,IAAM,qBAAN,cAAiC,MAAM;AAAA,EACnC,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EAET,YAAY,SAGT;AACD,UAAM,8DAA8D;AACpE,SAAK,OAAO;AACZ,SAAK,uBAAuB,QAAQ;AACpC,SAAK,mBAAmB,QAAQ;AAAA,EAClC;AACF;AAEO,SAAS,oBAAoB,SAMzB;AACT,gBAAc,QAAQ,WAAW;AACjC,QAAM,UAAyB;AAAA,IAC7B,SAAS;AAAA,IACT,sBAAsB,QAAQ,SAAS;AAAA,IACvC,kBAAkB,QAAQ;AAAA,IAC1B,aAAa,QAAQ;AAAA,IACrB,cAAc,QAAQ,gBAAgB;AAAA,IACtC,aAAa,QAAQ;AAAA,EACvB;AACA,QAAM,UAAU,OAAO,KAAK,KAAK,UAAU,OAAO,GAAG,MAAM,EAAE;AAAA,IAC3D;AAAA,EACF;AACA,QAAM,SAAS,wBAAwB,OAAO,EAAE,MAAM,UAAU,MAAM;AACtE,SAAO,QAAQ,OAAO,IAAI,MAAM;AAClC;AAEO,SAAS,kBAAkB,SAMvB;AACT,QAAM,QAAQ,MAAM;AAClB,UAAM,IAAI,mBAAmB;AAAA,MAC3B,sBAAsB,QAAQ,SAAS;AAAA,MACvC,kBAAkB,QAAQ;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,QAAM,CAAC,QAAQ,SAAS,QAAQ,KAAK,IAAI,QAAQ,OAAO,MAAM,GAAG;AACjE,MAAI,WAAW,UAAU,CAAC,WAAW,CAAC,UAAU,UAAU,OAAW,OAAM;AAE3E,MAAI;AACJ,MAAI;AACF,cAAU,KAAK;AAAA,MACb,OAAO,KAAK,SAAS,WAAW,EAAE,SAAS,MAAM;AAAA,IACnD;AAAA,EACF,QAAQ;AACN,WAAO,MAAM;AAAA,EACf;AAEA,MACE,wBAAwB,OAAO,EAAE,MAAM,UAAU,MAAM,MAAM,UAC7D,QAAQ,YAAY,kBACpB,QAAQ,yBAAyB,QAAQ,SAAS,gBAClD,QAAQ,qBAAqB,QAAQ,oBACrC,QAAQ,kBAAkB,QAAQ,gBAAgB,SAClD,KAAK,UAAU,QAAQ,WAAW,MAAM,KAAK,UAAU,QAAQ,WAAW,GAC1E;AACA,WAAO,MAAM;AAAA,EACf;AACA,gBAAc,QAAQ,WAAW;AACjC,SAAO,QAAQ;AACjB;AAEA,SAAS,cAAc,OAAqB;AAC1C,MAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GAAG;AAC7C,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;ACxEO,IAAM,wBAAwB;AAC9B,IAAM,oBAAoB;AAC1B,IAAM,8BAA8B;AACpC,IAAM,0BAA0B;AAChC,IAAM,oBAAoB;AAE1B,IAAM,uBAAN,cAAmC,MAAM;AAAA,EACrC;AAAA,EACA;AAAA,EAET,YAAY,SAIT;AACD,UAAM,QAAQ,OAAO;AACrB,SAAK,OAAO;AACZ,SAAK,OAAO,QAAQ;AACpB,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;AAgBA,eAAsB,gBAEpB,SAAuE;AACvE,MAAI,QAAQ,WAAW;AACrB,QACE,QAAQ,SAAS,UACjB,QAAQ,WAAW,UACnB,QAAQ,UAAU,QAClB;AACA,YAAM,IAAI,qBAAqB;AAAA,QAC7B,MAAM;AAAA,QACN,SACE;AAAA,QACF,SAAS,EAAE,OAAO,QAAQ,UAAU,OAAO,KAAK,QAAQ,UAAU,IAAI;AAAA,MACxE,CAAC;AAAA,IACH;AACA,WAAO,aAAa,SAAS,QAAQ,SAAS;AAAA,EAChD;AACA,SAAO,mBAAmB,OAAO;AACnC;AAEA,eAAe,mBACb,SACkC;AAClC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,yBAAuB,OAAO,cAAc;AAC5C,QAAM,mBAAmB,iBAAiB,QAAQ,UAAU,QAAQ,IAAI;AACxE,QAAM,aAAa,kBAAkB,kBAAkB,QAAQ,EAAE;AACjE,QAAM,SAAS,MAAM,eAAe;AAAA,IAClC,MAAM,QAAQ;AAAA,IACd,UAAU;AAAA,IACV,IAAI;AAAA,EACN,CAAC;AACD,QAAM,OAAO,0BAA0B;AAAA,IACrC;AAAA,IACA,aAAa,QAAQ;AAAA,EACvB,CAAC;AACD,QAAM,eAAe,QAAQ,SACzB,kBAAkB;AAAA,IAChB,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,kBAAkB,KAAK;AAAA,IACvB,aAAa,KAAK;AAAA,IAClB,cAAc,QAAQ;AAAA,EACxB,CAAC,IACD;AACJ,MAAI,KAAK,YAAY,SAAS,aAAa;AACzC,WAAO;AAAA,MACL,eAAe;AAAA,MACf,MAAM;AAAA,MACN,UAAU,QAAQ;AAAA,MAClB,aAAa,KAAK;AAAA,MAClB;AAAA,MACA,YAAY,CAAC;AAAA,MACb,WAAW,CAAC;AAAA,MACZ,MAAM;AAAA,QACJ;AAAA,QACA,WAAW;AAAA,QACX,WAAW;AAAA,QACX,YAAY;AAAA,MACd;AAAA,IACF;AAAA,EACF;AAEA,QAAM,WAA4D,CAAC;AACnE,QAAM,YAA4D,CAAC;AACnE,MAAI,YAAY;AAChB,aAAW,UAAU,KAAK,SAAS;AACjC,UAAM,YAAY,iBAAiB;AACnC,QAAI,aAAa,GAAG;AAClB,gBAAU,KAAK;AAAA,QACb,OAAO,OAAO;AAAA,QACd,eAAe,OAAO;AAAA,QACtB,MAAM;AAAA,MACR,CAAC;AACD;AAAA,IACF;AACA,UAAM,cAAc,mCAAmC;AAAA,MACrD;AAAA,MACA,MAAM,OAAO,MAAM;AAAA,MACnB,eAAe,OAAO;AAAA,MACtB,gBAAgB;AAAA,IAClB,CAAC;AACD,QACE,CAAC,YAAY,SACb,CAAC,YAAY,WACb,CAAC,YAAY,aACb;AACA;AAAA,IACF;AACA,iBAAa,YAAY,YAAY;AACrC,QAAI,YAAY,YAAY,WAAW,cAAc;AACnD,gBAAU,KAAK;AAAA,QACb,OAAO,OAAO;AAAA,QACd,eAAe,OAAO;AAAA,QACtB,MACE,YAAY,YAAY,WAAW,WAC/B,wBACA;AAAA,QACN,GAAI,YAAY,YAAY,WACxB,EAAE,UAAU,YAAY,YAAY,SAAS,IAC7C,CAAC;AAAA,MACP,CAAC;AACD;AAAA,IACF;AACA,UAAM,cAAc,CAAC,GAAG,YAAY,YAAY,WAAW,EAAE;AAAA,MAC3D;AAAA,IACF;AACA,eAAW,cAAc,aAAa;AACpC,YAAM,UAA2B;AAAA,QAC/B,OAAO,EAAE,MAAM,OAAO,MAAM,KAAK;AAAA,QACjC,eAAe,OAAO;AAAA,QACtB,QAAQ,6BAA6B;AAAA,UACnC,MAAM,QAAQ;AAAA,UACd,OAAO,KAAK,KAAK;AAAA,UACjB,eAAe,OAAO;AAAA,UACtB,QAAQ;AAAA,UACR,WAAW,KAAK,MAAM,UAClB,MAAM;AAAA,YACJ,EAAE,QAAQ,KAAK,MAAM,QAAQ;AAAA,YAC7B,CAAC,GAAG,SACF,QAAQ,KAAK,SAAS,SAAS,SAAS,UAAU,IAAI,KACtD,UAAU,OAAO,CAAC;AAAA,UACtB,IACA,CAAC;AAAA,UACL,MAAM,WAAW,OAAO,aAAa;AAAA,QACvC,CAAC;AAAA,MACH;AACA,YAAM,WAAW,MAAM,sBAAsB;AAAA,QAC3C;AAAA,QACA;AAAA,MACF,CAAC;AACD,UAAI,SAAS,SAAS,WAAY;AAClC,YAAM,YAAY,0BAA0B;AAAA,QAC1C,QAAQ,SAAS;AAAA,QACjB,aAAa,QAAQ;AAAA,MACvB,CAAC;AACD,eAAS,KAAK;AAAA,QACZ,SAAS,SAAS;AAAA,QAClB;AAAA,QACA,OAAO;AAAA,UACL,kBAAkB,UAAU;AAAA,UAC5B,MAAM,UAAU;AAAA,UAChB,mBAAmB;AAAA,YACjB,UAAU;AAAA,UACZ;AAAA,UACA,YAAY,mBAAmB,UAAU,IAAI;AAAA,UAC7C,SAAS,UAAU,QAAQ,IAAI,CAAC,EAAE,OAAO,cAAc,OAAO;AAAA,YAC5D;AAAA,YACA;AAAA,UACF,EAAE;AAAA,UACF,SAAS,UAAU;AAAA,UACnB,eAAe,UAAU;AAAA,QAC3B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,aAAa,SAAS,MAAM,cAAc,eAAe,KAAK;AACpE,QAAM,cAAc,eAAe,WAAW;AAC9C,QAAM,YAAY,cAAc,SAAS;AACzC,SAAO;AAAA,IACL,eAAe;AAAA,IACf,MAAM;AAAA,IACN,UAAU,gBAAgB,QAAQ,QAAQ;AAAA,IAC1C,aAAa,KAAK;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA,MAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,YACR,oBAAoB;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,kBAAkB,KAAK;AAAA,QACvB,aAAa,KAAK;AAAA,QAClB,cAAc,QAAQ;AAAA,QACtB;AAAA,MACF,CAAC,IACD;AAAA,IACN;AAAA,EACF;AACF;AAEA,eAAe,aACb,SACA,OAC4B;AAC5B,kBAAgB,KAAK;AACrB,QAAM,aAAa,kBAAkB,QAAQ,UAAU,QAAQ,EAAE;AACjE,QAAM,WAAoD,CAAC;AAC3D,WAAS,OAAO,MAAM,OAAO,QAAQ,MAAM,KAAK,QAAQ,GAAG;AACzD,QAAI;AACF,YAAM,YAAY,MAAM,gBAAgB;AAAA,QACtC,MAAM,QAAQ;AAAA,QACd,UAAU,QAAQ;AAAA,QAClB,UAAU,QAAQ;AAAA,QAClB,aAAa,QAAQ;AAAA,QACrB,IAAI;AAAA,QACJ;AAAA,MACF,CAAC;AACD,YAAM,SAAS,MAAM,eAAe;AAAA,QAClC,MAAM,QAAQ;AAAA,QACd,UAAU,iBAAiB,QAAQ,UAAU,IAAI;AAAA,QACjD,IAAI;AAAA,MACN,CAAC;AACD,YAAM,SAAS,MAAM,qBAAqB;AAAA,QACxC;AAAA,QACA,MAAM,UAAU;AAAA,QAChB,gBAAgB,QAAQ,kBAAkB;AAAA,MAC5C,CAAC;AACD,eAAS,KAAK;AAAA,QACZ;AAAA,QACA,QAAQ;AAAA,QACR,kBAAkB,UAAU,KAAK;AAAA,QACjC,SAAS,UAAU,KAAK;AAAA,QACxB,YAAY;AAAA,UACV,aAAa,UAAU,KAAK;AAAA,UAC5B,MAAM,UAAU,KAAK;AAAA,QACvB;AAAA,QACA,WAAW;AAAA,UACT,OAAO,UAAU,KAAK,KAAK;AAAA,UAC3B,MAAM,UAAU,KAAK,KAAK;AAAA,UAC1B,SAAS,UAAU,KAAK,QAAQ,IAAI,CAAC,EAAE,OAAO,cAAc,OAAO;AAAA,YACjE,MAAM,MAAM;AAAA,YACZ;AAAA,YACA,qBACE,OAAO,IAAI,GAAG,MAAM,IAAI,IAAI,aAAa,EAAE,KAAK;AAAA,UACpD,EAAE;AAAA,QACJ;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,qBAAsB,OAAM;AACnD,eAAS,KAAK;AAAA,QACZ;AAAA,QACA,QAAQ;AAAA,QACR,WAAW;AAAA,UACT,SAAS,MAAM;AAAA,UACf,aAAa,MAAM;AAAA,UACnB,eAAe,MAAM;AAAA,UACrB,WAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AAAA,IACL,eAAe;AAAA,IACf,MAAM;AAAA,IACN,UAAU,gBAAgB,QAAQ,QAAQ;AAAA,IAC1C,cAAc,MAAM,uBAAuB,OAAO,GAAG,KAAK;AAAA,IAC1D;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,uBACb,SACA;AACA,SAAO,gBAAgB;AAAA,IACrB,MAAM,QAAQ;AAAA,IACd,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ;AAAA,IACrB,IAAI,EAAE,SAAS,SAAS,WAAW,EAAE;AAAA,EACvC,CAAC;AACH;AAEA,eAAe,qBAA2B,SAIA;AACxC,yBAAuB,uBAAuB,QAAQ,cAAc;AACpE,QAAM,SAAS,oBAAI,IAA6B;AAChD,MAAI,YAAY;AAChB,aAAW,UAAU,QAAQ,KAAK,SAAS;AACzC,UAAM,YAAY,QAAQ,iBAAiB;AAC3C,QAAI,aAAa,GAAG;AAClB,aAAO,IAAI,GAAG,OAAO,MAAM,IAAI,IAAI,OAAO,aAAa,IAAI,MAAM;AACjE;AAAA,IACF;AACA,UAAM,SAAS,mCAAmC;AAAA,MAChD,QAAQ,QAAQ;AAAA,MAChB,MAAM,OAAO,MAAM;AAAA,MACnB,eAAe,OAAO;AAAA,MACtB,gBAAgB;AAAA,IAClB,CAAC;AACD,QAAI,CAAC,OAAO,SAAS,CAAC,OAAO,WAAW,CAAC,OAAO,YAAa;AAC7D,iBAAa,OAAO,YAAY;AAChC,WAAO;AAAA,MACL,GAAG,OAAO,MAAM,IAAI,IAAI,OAAO,aAAa;AAAA,MAC5C,OAAO,YAAY,WAAW,eAC1B,OAAO,YAAY,YAAY,SAC/B;AAAA,IACN;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBACP,UACA,MACgC;AAChC,SAAO,SAAS,SACZ,WACA,EAAE,GAAG,UAAU,OAAO,EAAE,GAAG,SAAS,OAAO,KAAK,EAAE;AACxD;AAEA,SAAS,kBACP,UACA,IACoB;AACpB,SAAQ,MAAM;AAAA,IACZ,SAAS;AAAA,IACT,WAAW,SAAS,MAAM;AAAA,EAC5B;AACF;AAEA,SAAS,uBAAuB,OAAe,gBAA8B;AAC3E,MAAI,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,KAAK,QAAQ,mBAAmB;AAC1E,UAAM,IAAI,qBAAqB;AAAA,MAC7B,MAAM;AAAA,MACN,SAAS,uCAAuC,iBAAiB;AAAA,MACjE,SAAS,EAAE,WAAW,OAAO,SAAS,GAAG,SAAS,kBAAkB;AAAA,IACtE,CAAC;AAAA,EACH;AACA,MACE,CAAC,OAAO,cAAc,cAAc,KACpC,iBAAiB,KACjB,iBAAiB,yBACjB;AACA,UAAM,IAAI,qBAAqB;AAAA,MAC7B,MAAM;AAAA,MACN,SAAS,iDAAiD,uBAAuB;AAAA,MACjF,SAAS;AAAA,QACP,WAAW;AAAA,QACX,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,QAAM,QAAQ,MAAM,MAAM,MAAM,QAAQ;AACxC,MACE,CAAC,OAAO,cAAc,MAAM,KAAK,KACjC,CAAC,OAAO,cAAc,MAAM,GAAG,KAC/B,MAAM,QAAQ,MAAM,OACpB,CAAC,OAAO,cAAc,KAAK,KAC3B,QAAQ,KACR,QAAQ,mBACR;AACA,UAAM,IAAI,qBAAqB;AAAA,MAC7B,MAAM;AAAA,MACN,SAAS,qCAAqC,iBAAiB;AAAA,MAC/D,SAAS;AAAA,QACP,OAAO,MAAM;AAAA,QACb,KAAK,MAAM;AAAA,QACX,cAAc;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjbA,SAAS,kBAAkB;AAe3B,IAAM,sBAAsB;AAE5B,SAAS,wBAAwB,MAAc,OAAuB;AACpE,SAAO,SAAS,QAAQ,IAAI,OAAO,QAAQ,KAAK;AAClD;AAEO,SAAS,eAAe,OAAwB;AACrD,SAAO,oBAAoB,KAAK,KAAK;AACvC;AAEO,SAAS,0BAA0B,OAA+B;AACvE,MAAI,UAAU,MAAM;AAClB,WAAO;AAAA,EACT;AACA,UAAQ,OAAO,OAAO;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,UAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,eAAO;AAAA,MACT;AACA;AAAA,IACF,KAAK,UAAU;AACb,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAO,MAAM,IAAI,CAAC,SAAS,0BAA0B,IAAI,CAAC;AAAA,MAC5D;AACA,UAAI,OAAO,eAAe,KAAK,MAAM,OAAO,WAAW;AACrD;AAAA,MACF;AACA,YAAM,UAAU,OAAO,QAAQ,KAAgC;AAC/D,aAAO,OAAO;AAAA,QACZ,QACG,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,SAAS,MAAS,EACvC,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,wBAAwB,MAAM,KAAK,CAAC,EAC9D,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,0BAA0B,IAAI,CAAC,CAAC;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI;AAAA,IACR,0DAA0D,OAAO,KAAK;AAAA,EACxE;AACF;AAEO,SAAS,uBAAuB,OAAwB;AAC7D,SAAO,KAAK,UAAU,0BAA0B,KAAK,CAAC;AACxD;AAEO,SAAS,oBAAoB,OAAwB;AAC1D,SAAO,OAAO,uBAAuB,KAAK,CAAC;AAC7C;AAEO,SAAS,uBAAuB,SAAkC;AACvE,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAEO,SAAS,gCAAgC,SASrC;AACT,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAEO,SAAS,yBAAyB,MAAkC;AACzE,SAAO,oBAAoB;AAAA,IACzB,eAAe;AAAA,IACf;AAAA,EACF,CAAC;AACH;AAEO,SAAS,8BACd,SACmB;AACnB,SAAO,0BAA0B;AAAA,IAC/B,GAAG;AAAA,IACH,MAAM,CAAC,GAAG,QAAQ,IAAI,EAAE,KAAK;AAAA,IAC7B,aAAa;AAAA,MACX,GAAG,QAAQ;AAAA,MACX,cAAc,CAAC,GAAG,QAAQ,YAAY,YAAY,EAAE,KAAK;AAAA,IAC3D;AAAA,EACF,CAAC;AACH;AAEO,SAAS,2BAA2B,SAAoC;AAC7E,SAAO,GAAG,KAAK,UAAU,8BAA8B,OAAO,GAAG,MAAM,CAAC,CAAC;AAAA;AAC3E;AAEO,SAAS,wBAAwB,SAAoC;AAC1E,SAAO,OAAO,2BAA2B,OAAO,CAAC;AACnD;AAEA,SAAS,OAAO,OAAuB;AACrC,SAAO,UAAU,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK,CAAC;AACnE;;;AC1GO,SAAS,4BACd,SACuB;AACvB,SAAO;AAAA,IACL,MAAM,IACJ,YAC+B;AAC/B,UAAI,QAAQ,gBAAgB,QAAQ,YAAY;AAChD,UAAI,cAAc,QAAQ,sBAAsB;AAChD,YAAM,SAAiC,CAAC;AACxC,YAAM,YAAuC,CAAC;AAE9C,YAAM,cAAc,CAAC,OAAqC;AACxD,cAAM,oBAAoB,QAAQ,OAAO,oBAAoB;AAAA,UAC3D;AAAA,UACA,WAAW,CAAC,QAAQ,OAAO,QAAQ;AAAA,QACrC,CAAC;AACD,cAAM,mBAAmB,QAAQ,OAAO,gBAAgB,KAAK;AAC7D,cAAM,OAAO,cAAc,KAAK;AAChC,cAAM,eAAe,+BAA+B;AAAA,UAClD,cAAc,KAAK;AAAA,UACnB,eAAe,KAAK;AAAA,UACpB;AAAA,UACA;AAAA,UACA,qBAAqB,QAAQ,OAAO;AAAA,UACpC;AAAA,UACA,kBAAkB;AAAA,QACpB,CAAC;AACD,cAAM,mBAAmB,8BAA8B;AAAA,UACrD;AAAA,UACA,uBAAuB,aAAa;AAAA,QACtC,CAAC;AACD,cAAM,QAAQ;AAAA,UACZ;AAAA,UACA,cAAc,gBAAgB,KAAK;AAAA,UACnC;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,kBAAkB,oBAAoB;AAAA,YACpC,eAAe;AAAA,YACf,YAAY,QAAQ;AAAA,YACpB,SAAS;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAAA,QACH;AACA,eAAO,KAAK,KAAK;AACjB,eAAO;AAAA,MACT;AAEA,kBAAY,SAAS;AAErB,iBAAW,aAAa,YAAY;AAClC,cAAM,YAAY,OAAO,OAAO,SAAS,CAAC;AAC1C,YAAI,CAAC,WAAW;AACd,gBAAM,IAAI,MAAM,iDAAiD;AAAA,QACnE;AACA,YAAI,UAAU,cAAc,YAAY;AACtC,gBAAMA,UAAS,MAAM,QAAQ,OAAO,cAAc;AAAA,YAChD;AAAA,YACA,OAAO,UAAU;AAAA,UACnB,CAAC;AACD,oBAAU,KAAK;AAAA,YACb,IAAI,UAAU;AAAA,YACd,WAAW;AAAA,YACX,aAAa,UAAU;AAAA,YACvB,OAAO,UAAU;AAAA,YACjB,QAAAA;AAAA,UACF,CAAC;AACD;AAAA,QACF;AAEA,cAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;AAAA,UAC3C;AAAA,UACA,OAAO,UAAU;AAAA,QACnB,CAAC;AACD,YAAI,OAAO,SAAS,UAAU;AAC5B,oBAAU,KAAK;AAAA,YACb,IAAI,UAAU;AAAA,YACd,WAAW;AAAA,YACX,aAAa,UAAU;AAAA,YACvB,OAAO,UAAU;AAAA,YACjB,QAAQ;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,gBACX;AAAA,kBACE,MAAM,OAAO;AAAA,kBACb,SAAS,OAAO,WAAW,OAAO;AAAA,gBACpC;AAAA,cACF;AAAA,YACF;AAAA,UACF,CAAC;AACD;AAAA,QACF;AAEA,gBAAQ,gBAAgB,OAAO,KAAK;AACpC,uBAAe;AACf,cAAM,UAAU,YAAY,SAAS,OAAO,SAAS,CAAC,EAAE;AACxD,kBAAU,KAAK;AAAA,UACb,IAAI,UAAU;AAAA,UACd,WAAW;AAAA,UACX,aAAa,UAAU;AAAA,UACvB,OAAO,UAAU;AAAA,UACjB,QAAQ;AAAA,YACN,MAAM;AAAA,YACN,WAAW,QAAQ;AAAA,UACrB;AAAA,QACF,CAAC;AAAA,MACH;AAEA,aAAO;AAAA,QACL,YAAY,QAAQ;AAAA,QACpB,QAAQ,QAAQ;AAAA,QAChB,QAAQ,QAAQ;AAAA,QAChB;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,cAAc,OAO+C;AACpE,SAAO;AAAA,IACL,cAAc,MAAM,QAAQ,MAAM,gBAAgB;AAAA,IAClD,eAAe,CAAC,GAAI,MAAM,QAAQ,MAAM,iBAAiB,CAAC,CAAE;AAAA,EAC9D;AACF;;;ACjJO,SAAS,iBACd,UACqB;AACrB,SAAO,OAAO,OAAO,QAAQ;AAC/B;;;ACmGA,IAAM,sBAAiD;AAAA,EACrD,EAAE,MAAM,cAAc,MAAM,0BAA0B;AAAA,EACtD,EAAE,MAAM,iBAAiB,MAAM,qBAAqB;AAAA,EACpD,EAAE,MAAM,sBAAsB,MAAM,qBAAqB;AAAA,EACzD,EAAE,MAAM,yBAAyB,MAAM,oBAAoB;AAAA,EAC3D,EAAE,MAAM,8BAA8B,MAAM,oBAAoB;AAAA,EAChE,EAAE,MAAM,uBAAuB,MAAM,qBAAqB;AAAA,EAC1D,EAAE,MAAM,8BAA8B,MAAM,qBAAqB;AAAA,EACjE,EAAE,MAAM,+BAA+B,MAAM,qBAAqB;AACpE;AAEA,IAAM,wBAAmD;AAAA,EACvD,EAAE,MAAM,UAAU,MAAM,kCAAkC;AAAA,EAC1D,EAAE,MAAM,kBAAkB,MAAM,kCAAkC;AAAA,EAClE,EAAE,MAAM,iBAAiB,MAAM,kCAAkC;AAAA,EACjE,EAAE,MAAM,cAAc,MAAM,kCAAkC;AAAA,EAC9D,EAAE,MAAM,oBAAoB,MAAM,kCAAkC;AAAA,EACpE,EAAE,MAAM,eAAe,MAAM,sBAAsB;AAAA,EACnD,EAAE,MAAM,oBAAoB,MAAM,sBAAsB;AAAA,EACxD,EAAE,MAAM,uBAAuB,MAAM,sBAAsB;AAAA,EAC3D,EAAE,MAAM,oBAAoB,MAAM,sBAAsB;AAAA,EACxD,EAAE,MAAM,kBAAkB,MAAM,6BAA6B;AAAA,EAC7D,EAAE,MAAM,eAAe,MAAM,iBAAiB;AAAA,EAC9C,EAAE,MAAM,oBAAoB,MAAM,sBAAsB;AAAA,EACxD,EAAE,MAAM,cAAc,MAAM,kBAAkB;AAChD;AAEO,SAAS,qCAAqC;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB,wBAAwB,OAAO;AAAA,EAC/C,sBAAsB,CAAC;AAAA,EACvB,cAAc,CAAC;AACjB,GAAuE;AACrE,QAAM,YAAY,IAAI;AAAA,IACpB,QAAQ,SAAS,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC;AAAA,EAC1D;AACA,QAAM,aAAa,QAAQ,SAAS,OAAO,CAAC;AAC5C,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR,YAAY,QAAQ,EAAE;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,cAAc,QAAQ,OAAO,IAAI,CAAC,MAAM,UAAU;AACtD,UAAM,kBAAkB,KAAK,OAAO,WAAW,WAAW;AAC1D,UAAM,QAAQ,UAAU,IAAI,eAAe;AAC3C,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,YAAY,QAAQ,EAAE,kBAAkB,KAAK,MAAM,+BAA+B,eAAe;AAAA,MACnG;AAAA,IACF;AACA,UAAM,WAAW,sBAAsB,OAAO,KAAK,mBAAmB;AACtE,UAAM,mBACJ,KAAK,OAAO,oBAAoB,MAAM;AACxC,UAAM,UAAU,UAAU,QAAQ,OAAO,SAAS;AAClD,UAAM,iBACJ,KAAK,OAAO,mBACX,UACG,QAAQ,SAAS,sBACjB,oBAAoB;AAAA,MAClB,YAAY,QAAQ;AAAA,MACpB,QAAQ,KAAK;AAAA,MACb,SAAS,MAAM;AAAA,MACf;AAAA,IACF,CAAC;AACP,UAAM,mBACJ,KAAK,OAAO,qBACX,UAAU,QAAQ,SAAS,mBAAmB;AAEjD,WAAO;AAAA,MACL,QAAQ,KAAK;AAAA,MACb,gBAAgB,UAAU;AAAA,MAC1B,eAAe,UAAU;AAAA,MACzB,YAAY,UAAU;AAAA,MACtB,kBAAkB,UAAU;AAAA,MAC5B,aAAa,KAAK,OAAO,eAAe,UAAU;AAAA,MAClD,aAAa,MAAM,MAAM;AAAA,MACzB,kBAAkB,MAAM,MAAM;AAAA,MAC9B,qBAAqB,MAAM,MAAM;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,oBAAoB,KAAK,MAAM;AAAA,IAC7C;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,eAAe;AAAA,IACf,YAAY,QAAQ;AAAA,IACpB;AAAA,IACA;AAAA,IACA,uBAAuB,QAAQ;AAAA,IAC/B,4BAA4B,QAAQ;AAAA,IACpC;AAAA,IACA,YAAY;AAAA,MACV,MAAM;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,2BACd,OACuB;AACvB,QAAM,cAAc,aAAa,OAAO,aAAa;AACrD,MAAI,YAAY,kBAAkB,GAAG;AACnC,UAAM,IAAI,MAAM,gDAAgD;AAAA,EAClE;AACA,eAAa,YAAY,YAAY,YAAY;AACjD,eAAa,YAAY,eAAe,eAAe;AACvD,eAAa,YAAY,oBAAoB,oBAAoB;AACjE,MAAI,YAAY,0BAA0B,GAAG;AAC3C,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AACA;AAAA,IACE,YAAY;AAAA,IACZ;AAAA,EACF;AACA,QAAM,cAAc,aAAa,YAAY,aAAa,aAAa;AACvE,eAAa,YAAY,SAAS,qBAAqB;AACvD,QAAM,WAAW,aAAa,YAAY,UAAU,sBAAsB;AAC1E,eAAa,SAAS,OAAO,4BAA4B;AACzD,eAAa,SAAS,QAAQ,6BAA6B;AAC3D,QAAM,aAAa;AAAA,IACjB,YAAY;AAAA,IACZ;AAAA,EACF;AACA,MACE,WAAW,SAAS,yBACpB,WAAW,SAAS,sBACpB,WAAW,SAAS,oBACpB;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,uBAAqB,WAAW,UAAU,iCAAiC;AAC3E,QAAM,cAAc,YAAY,YAAY,aAAa,aAAa;AACtE,WAAS,QAAQ,GAAG,QAAQ,YAAY,QAAQ,SAAS,GAAG;AAC1D,UAAM,aAAa;AAAA,MACjB,YAAY,KAAK;AAAA,MACjB,eAAe,KAAK;AAAA,IACtB;AACA,iBAAa,WAAW,QAAQ,eAAe,KAAK,UAAU;AAC9D;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA,iBAAa,WAAW,aAAa,eAAe,KAAK,eAAe;AACxE;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA,QACE,WAAW,wBAAwB,QACnC,OAAO,WAAW,wBAAwB,UAC1C;AACA,YAAM,IAAI;AAAA,QACR,eAAe,KAAK;AAAA,MACtB;AAAA,IACF;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AACA;AAAA,MACE,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB;AAAA,EACF;AACA,QAAM,cAAc,YAAY,YAAY,aAAa,aAAa;AACtE,WAAS,QAAQ,GAAG,QAAQ,YAAY,QAAQ,SAAS,GAAG;AAC1D,UAAM,aAAa;AAAA,MACjB,YAAY,KAAK;AAAA,MACjB,eAAe,KAAK;AAAA,IACtB;AACA,iBAAa,WAAW,MAAM,eAAe,KAAK,QAAQ;AAC1D,iBAAa,WAAW,SAAS,eAAe,KAAK,WAAW;AAAA,EAClE;AACA,SAAO;AACT;AAEO,SAAS,4BACd,UACA,QAC0B;AAC1B,aAAW,cAAc,qBAAqB;AAC5C,UAAM,SAAS,YAAY,UAAU,QAAQ,UAAU;AACvD,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,SAAS,YAAY,WAAW,OAAO,YAAY,QAAQ;AAC7D,WAAO,SAAS;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU,SAAS,YAAY;AAAA,MAC/B,QAAQ,OAAO,YAAY;AAAA,IAC7B,CAAC;AAAA,EACH;AAEA,WAAS,QAAQ,GAAG,QAAQ,SAAS,YAAY,QAAQ,SAAS,GAAG;AACnE,UAAM,qBAAqB,SAAS,YAAY,KAAK;AACrD,UAAM,mBAAmB,OAAO,YAAY,KAAK;AACjD,eAAW,cAAc,uBAAuB;AAC9C,YAAM,SAAS;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,UACE,QAAQ,eAAe,KAAK;AAAA,UAC5B,iBAAiB;AAAA,UACjB,QAAQ,mBAAmB;AAAA,QAC7B;AAAA,MACF;AACA,UAAI,QAAQ;AACV,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,UAAU,SAAS,aAAa,OAAO,WAAW,GAAG;AACxD,WAAO,SAAS;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU,SAAS;AAAA,MACnB,QAAQ,OAAO;AAAA,IACjB,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,IAAI,KAAK;AACpB;AAEA,SAAS,YACP,UACA,QACA,YACA,UAII,CAAC,GAC4B;AACjC,QAAM,gBAAgB,QAAQ,UAAU,WAAW,IAAI;AACvD,QAAM,cAAc,QAAQ,QAAQ,WAAW,IAAI;AACnD,MAAI,UAAU,eAAe,WAAW,GAAG;AACzC,WAAO;AAAA,EACT;AACA,QAAM,OAAO,QAAQ,SACjB,GAAG,QAAQ,MAAM,IAAI,WAAW,IAAI,KACpC,WAAW;AACf,SAAO,SAAS;AAAA,IACd,MAAM,WAAW;AAAA,IACjB;AAAA,IACA,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,iBAAiB,QAAQ;AAAA,IACzB,QAAQ,QAAQ;AAAA,EAClB,CAAC;AACH;AAEA,SAAS,SACP,OAC0B;AAC1B,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS;AAAA,MACP,GAAG;AAAA,MACH,SAAS,GAAG,MAAM,IAAI,OAAO,MAAM,IAAI;AAAA,IACzC;AAAA,EACF;AACF;AAEA,SAAS,UAAU,MAAe,OAAyB;AACzD,MAAI,SAAS,UAAa,UAAU,QAAW;AAC7C,WAAO,SAAS;AAAA,EAClB;AACA,SAAO,uBAAuB,IAAI,MAAM,uBAAuB,KAAK;AACtE;AAEA,SAAS,QAAQ,OAAgB,MAAuB;AACtD,SAAO,KAAK,MAAM,GAAG,EAAE,OAAgB,CAAC,SAAS,QAAQ;AACvD,QAAI,YAAY,QAAQ,OAAO,YAAY,UAAU;AACnD,aAAO;AAAA,IACT;AACA,WAAQ,QAAoC,GAAG;AAAA,EACjD,GAAG,KAAK;AACV;AAEA,SAAS,aAAa,OAAgB,MAAuC;AAC3E,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GAAG;AACvE,UAAM,IAAI,MAAM,GAAG,IAAI,qBAAqB;AAAA,EAC9C;AACA,SAAO;AACT;AAEA,SAAS,YAAY,OAAgB,MAAkC;AACrE,MAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AACzB,UAAM,IAAI,MAAM,GAAG,IAAI,oBAAoB;AAAA,EAC7C;AACA,SAAO;AACT;AAEA,SAAS,aAAa,OAAgB,MAAoB;AACxD,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,GAAG;AACnD,UAAM,IAAI,MAAM,GAAG,IAAI,8BAA8B;AAAA,EACvD;AACF;AAEA,SAAS,qBAAqB,OAAgB,MAAoB;AAChE,MACE,UAAU,WACT,OAAO,UAAU,YAAY,MAAM,WAAW,IAC/C;AACA,UAAM,IAAI,MAAM,GAAG,IAAI,2CAA2C;AAAA,EACpE;AACF;AAEA,SAAS,aAAa,OAAgB,MAAoB;AACxD,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,UAAM,IAAI,MAAM,GAAG,IAAI,2BAA2B;AAAA,EACpD;AACF;;;AC1ZA,IAAM,qBAAqB;AAEpB,SAAS,yBACd,SACoB;AACpB,QAAM,SAAS,QAAQ,UAAU;AACjC,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,SAA6B,CAAC;AACpC,QAAM,YAAY,IAAI;AAAA,IACpB,QAAQ,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC;AAAA,EACtD;AACA,MAAI,gBAAgB;AACpB,MAAI,mBAAmB;AACvB,MAAI,aAAa;AACjB,MAAI,iBAAgC;AACpC,MAAI,YAA8D;AAClE,MAAI,oBAAkC;AACtC,QAAM,kBAAkB,oBAAI,IAAmB;AAE/C,QAAM,SAAS,CAAC,UAAuD;AACrE,UAAM,QAAQ;AAAA,MACZ,UAAU,EAAE;AAAA,MACZ,MAAM,QAAQ,QAAQ,KAAK;AAAA,MAC3B,GAAG;AAAA,IACL;AACA,WAAO,KAAK,KAAK;AACjB,YAAQ,UAAU,KAAK;AAAA,EACzB;AAEA,QAAM,qBAAqB,CAAC,MAAc,YAA2B;AACnE,WAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,UAAM,QAAQ,IAAI,MAAM,OAAO;AAC/B,UAAM,OAAO;AACb,WAAO,OAAO,OAAO,EAAE,WAAW,KAAK,CAAC;AACxC,WAAO;AAAA,EACT;AAEA,QAAM,uBAAuB,CAAC,UAAmB;AAC/C,QAAI,mBAAmB;AACrB;AAAA,IACF;AACA,wBACE,iBAAiB,QACb,QACA;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EACR;AAEA,QAAM,oBAAoB,MAAM;AAC9B,QAAI,mBAAmB;AACrB,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,kBAAkB,CAAC,YAA6C;AACpE,QAAI,CAAC,WAAW;AACd;AAAA,IACF;AACA,cAAU;AAAA,MACR,UAAU;AAAA,MACV,SAAS;AAAA,MACT;AAAA,MACA,UAAU,EAAE;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,MAAM;AACrB,oBAAgB;AAAA,MACd,MAAM;AAAA,MACN,SAAS,QAAQ,KAAK;AAAA,IACxB,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,CAAC,YAAoB;AACxC,UAAM,QAAQ,UAAU,IAAI,OAAO;AACnC,QAAI,CAAC,OAAO;AACV,YAAM;AAAA,QACJ;AAAA,QACA,kDAAkD,OAAO;AAAA,MAC3D;AAAA,IACF;AACA,qBAAiB,MAAM;AACvB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,MAAM;AAAA,MACf,kBAAkB,MAAM;AAAA,IAC1B,CAAC;AACD,oBAAgB;AAAA,MACd,MAAM;AAAA,MACN,OAAO,MAAM;AAAA,IACf,CAAC;AAAA,EACH;AAEA,QAAM,kBAAkB,MAAM;AAC5B,WAAO,QAAQ,KAAK,MAAM,UAAU,GAAG,SAAS,cAAc;AAC5D,YAAM,OAAO,QAAQ,KAAK,MAAM,UAAU;AAI1C,oBAAc;AACd,mBAAa,KAAK,OAAO;AAAA,IAC3B;AAAA,EACF;AAEA,QAAM,oBAAoB,MAAM;AAC9B,QAAI,QAAQ,KAAK,MAAM,UAAU,GAAG,SAAS,cAAc;AACzD;AAAA,IACF;AACA,UAAM,OAAO,QAAQ,KAAK,MAAM,UAAU;AAI1C,kBAAc;AACd,iBAAa,KAAK,OAAO;AAAA,EAC3B;AAEA,QAAM,2BAA2B,YAAY;AAC3C,QAAI,aAAa,GAAG;AAClB,YAAM,QAAQ,QAAQ;AACtB;AAAA,IACF;AACA,UAAM,IAAI,QAAc,CAAC,YAAY,WAAW,SAAS,SAAS,CAAC;AAAA,EACrE;AAEA,QAAM,sBAAsB,CAG1B,MACA,kBACiE;AACjE,UAAM,OAAO,QAAQ,KAAK,MAAM,UAAU;AAC1C,QAAI,CAAC,MAAM;AACT,YAAM;AAAA,QACJ;AAAA,QACA,kDAAkD,IAAI;AAAA,MACxD;AAAA,IACF;AACA,QAAI,KAAK,SAAS,MAAM;AACtB,YAAM;AAAA,QACJ;AAAA,QACA,2BAA2B,KAAK,IAAI,mBAAmB,IAAI;AAAA,MAC7D;AAAA,IACF;AACA,QAAI,KAAK,gBAAgB,gBAAgB;AACvC,YAAM;AAAA,QACJ;AAAA,QACA,iCAAiC,KAAK,WAAW,2BAA2B,kBAAkB,QAAQ;AAAA,MACxG;AAAA,IACF;AACA,QAAI,KAAK,kBAAkB,eAAe;AACxC,YAAM,OAAO,SAAS,WAAW;AACjC,YAAM;AAAA,QACJ;AAAA,QACA,GAAG,IAAI,yCAAyC,IAAI,cAAc,KAAK,aAAa,cAAc,aAAa;AAAA,MACjH;AAAA,IACF;AACA,kBAAc;AACd,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,OAAO,YAAwC;AACpE,UAAM,gBAAgB,gCAAgC;AAAA,MACpD,WAAW;AAAA,MACX,OAAO,QAAQ;AAAA,MACf,eAAe,QAAQ;AAAA,MACvB,SAAS,QAAQ;AAAA,IACnB,CAAC;AACD,UAAM,OAAO,oBAAoB,mBAAmB,aAAa;AACjE,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,QAAQ,KAAK,SAAS,QAAQ,aAAa;AAAA,IAC7C,CAAC;AACD,UAAM,yBAAyB;AAC/B,oBAAgB;AAAA,MACd,MAAM;AAAA,MACN,WAAW,QAAQ;AAAA,MACnB,QAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH;AAEA,QAAM,eAAe,OAAO,YAAsC;AAChE,UAAM,gBAAgB,gCAAgC;AAAA,MACpD,WAAW;AAAA,MACX,OAAO,QAAQ;AAAA,MACf,eAAe,QAAQ;AAAA,MACvB,SAAS,QAAQ;AAAA,IACnB,CAAC;AACD,UAAM,OAAO,oBAAoB,iBAAiB,aAAa;AAC/D,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA,QAAQ,KAAK,SAAS,WAAW,aAAa;AAAA,IAChD,CAAC;AACD,UAAM,yBAAyB;AAC/B,oBAAgB;AAAA,MACd,MAAM;AAAA,MACN,WAAW,QAAQ;AAAA,MACnB,QAAQ,KAAK;AAAA,IACf,CAAC;AACD,QAAI,KAAK,SAAS,UAAU;AAC1B,YAAM,yBAAyB;AAC/B,sBAAgB;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,sBAAsB,CAAC,YAAiC;AAC5D,UAAM,eAAe,CAAC,YAA2B;AAC/C,sBAAgB,IAAI,OAAO;AAC3B,cACG,MAAM,CAAC,UAAU;AAChB,6BAAqB,KAAK;AAAA,MAC5B,CAAC,EACA,QAAQ,MAAM;AACb,wBAAgB,OAAO,OAAO;AAAA,MAChC,CAAC;AAAA,IACL;AAEA,YAAQ,QAAQ,MAAM;AAAA,MACpB,KAAK;AACH,eAAO,EAAE,MAAM,iBAAiB,CAAC;AACjC;AAAA,MACF,KAAK;AACH,eAAO,EAAE,MAAM,eAAe,CAAC;AAC/B;AAAA,MACF,KAAK;AACH,qBAAa,eAAe,OAAO,CAAC;AACpC;AAAA,MACF,KAAK;AACH,qBAAa,aAAa,OAAO,CAAC;AAClC;AAAA,MACF,KAAK;AACH,eAAO,EAAE,MAAM,aAAa,CAAC;AAC7B;AAAA,MACF,SAAS;AACP,cAAM,cAAqB;AAC3B,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,QAAM,YAA6B;AAAA,IACjC,MAAM,eAAe;AACnB,kBAAY;AACZ,qBAAe,MAAM;AACnB,iBAAS;AACT,0BAAkB;AAAA,MACpB,CAAC;AACD,aAAO,MAAM;AACX,oBAAY;AAAA,MACd;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AACZ,0BAAoB,OAAO;AAAA,IAC7B;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,MAAM,QAAQ;AAAA,IACd,QAAQ;AACN,sBAAgB;AAChB,yBAAmB;AACnB,mBAAa;AACb,uBAAiB;AACjB,0BAAoB;AACpB,sBAAgB,MAAM;AACtB,aAAO,SAAS;AAChB,UAAI,WAAW;AACb,iBAAS;AACT,0BAAkB;AAAA,MACpB;AAAA,IACF;AAAA,IACA,MAAM,QAAQ;AACZ,YAAM,yBAAyB;AAC/B,YAAM,QAAQ,QAAQ;AACtB,aAAO,gBAAgB,OAAO,GAAG;AAC/B,cAAM,QAAQ,WAAW,CAAC,GAAG,eAAe,CAAC;AAAA,MAC/C;AACA,wBAAkB;AAAA,IACpB;AAAA,IACA,MAAM,cAAc;AAClB,YAAM,yBAAyB;AAC/B,sBAAgB;AAChB,wBAAkB;AAAA,IACpB;AAAA,IACA,oBAAoB;AAClB,UAAI,CAAC,gBAAgB;AACnB,cAAM;AAAA,UACJ;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAAA,IACA,YAAY;AACV,aAAO,OAAO,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,EAAE;AAAA,IAC7C;AAAA,IACA,iBAAiB;AACf,wBAAkB;AAClB,UAAI,eAAe,QAAQ,KAAK,MAAM,QAAQ;AAC5C,cAAM;AAAA,UACJ;AAAA,UACA,iCAAiC,UAAU,OAAO,QAAQ,KAAK,MAAM,MAAM;AAAA,QAC7E;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACxWA,SAAgB,eAAe;AAqB3B;AAfG,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,iBAAiB;AAAA,IACrB,MACE,WAAW,0BAA0B,EAAE,WAAW,QAAQ,UAAU,CAAC;AAAA,IACvE,CAAC,QAAQ,WAAW,OAAO;AAAA,EAC7B;AACA,SACE,oBAAC,yBAAsB,SAAS,gBAC7B,UACH;AAEJ;;;ACPO,SAAS,0BACd,SACoB;AACpB,QAAM,SAAS,QAAQ,MAAM,OAAO;AAAA,IAAI,CAAC,UACvC,sBAAsB,OAAO,QAAQ,MAAM,OAAO,QAAQ;AAAA,EAC5D;AACA,QAAM,YAAY,IAAI,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAClE,QAAM,QAAiC,CAAC;AAExC,QAAM,aAAa,OAAO,CAAC;AAC3B,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR,qBAAqB,QAAQ,MAAM,UAAU;AAAA,IAC/C;AAAA,EACF;AACA,QAAM,KAAK;AAAA,IACT,IAAI,GAAG,WAAW,EAAE;AAAA,IACpB,MAAM;AAAA,IACN,SAAS,WAAW;AAAA,EACtB,CAAC;AAED,aAAW,YAAY,QAAQ,MAAM,WAAW;AAC9C,UAAM,YAAY,UAAU,IAAI,SAAS,WAAW;AACpD,QAAI,CAAC,WAAW;AACd,YAAM,IAAI;AAAA,QACR,qBAAqB,SAAS,EAAE,+BAA+B,SAAS,WAAW;AAAA,MACrF;AAAA,IACF;AACA,QAAI,SAAS,cAAc,YAAY;AACrC,YAAM,KAAK;AAAA,QACT,IAAI,SAAS;AAAA,QACb,MAAM;AAAA,QACN,aAAa,SAAS;AAAA,QACtB,eAAe,qBAAqB,UAAU,SAAS;AAAA,QACvD,UAAU;AAAA,UACR,OAAO,SAAS,OAAO;AAAA,UACvB,WAAW,SAAS,OAAO;AAAA,UAC3B,SAAS,SAAS,OAAO;AAAA,QAC3B;AAAA,MACF,CAAC;AACD;AAAA,IACF;AAEA,UAAM,KAAK;AAAA,MACT,IAAI,SAAS;AAAA,MACb,MAAM;AAAA,MACN,aAAa,SAAS;AAAA,MACtB,eAAe,qBAAqB,UAAU,SAAS;AAAA,MACvD,UACE,SAAS,OAAO,SAAS,aACrB,EAAE,UAAU,KAAK,IACjB;AAAA,QACE,UAAU;AAAA,QACV,WACE,SAAS,OAAO,YAAY,CAAC,GAAG,QAAQ;AAAA,QAC1C,SAAS,SAAS,OAAO,YAAY,CAAC,GAAG;AAAA,MAC3C;AAAA,IACR,CAAC;AACD,QAAI,SAAS,OAAO,SAAS,YAAY;AACvC,UAAI,CAAC,UAAU,IAAI,SAAS,OAAO,SAAS,GAAG;AAC7C,cAAM,IAAI;AAAA,UACR,qBAAqB,SAAS,EAAE,mCAAmC,SAAS,OAAO,SAAS;AAAA,QAC9F;AAAA,MACF;AACA,YAAM,KAAK;AAAA,QACT,IAAI,GAAG,SAAS,EAAE;AAAA,QAClB,MAAM;AAAA,QACN,SAAS,SAAS,OAAO;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,sBACP,OACA,qBACgB;AAChB,QAAM,OAAOC,eAAc,MAAM,YAAY;AAC7C,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,OAAO,+BAA+B;AAAA,MACpC,cAAc,KAAK;AAAA,MACnB,eAAe,KAAK;AAAA,MACpB,mBAAmB,MAAM;AAAA,MACzB,kBAAkB,MAAM;AAAA,MACxB;AAAA,MACA,aAAa,MAAM;AAAA,MACnB,kBAAkB,MAAM;AAAA,IAC1B,CAAC;AAAA,IACD,kBAAkB,MAAM;AAAA,EAC1B;AACF;AAEA,SAAS,qBACP,UACA,OACQ;AACR,SAAO,gCAAgC;AAAA,IACrC,WAAW,SAAS,cAAc,aAAa,aAAa;AAAA,IAC5D,OAAO;AAAA,MACL,aAAa,MAAM,MAAM;AAAA,MACzB,kBAAkB,MAAM,MAAM;AAAA,MAC9B,qBAAqB,MAAM,MAAM;AAAA,IACnC;AAAA,IACA,eAAe,SAAS,MAAM;AAAA,IAC9B,SAAS,SAAS,MAAM;AAAA,EAC1B,CAAC;AACH;AAEA,SAASA,eAAc,OAO+C;AACpE,SAAO;AAAA,IACL,cAAc,MAAM,QAAQ,MAAM,gBAAgB;AAAA,IAClD,eAAe,CAAC,GAAI,MAAM,QAAQ,MAAM,iBAAiB,CAAC,CAAE;AAAA,EAC9D;AACF;;;ACxIO,IAAM,gCAAwD;AAAA,EACnE,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,eAAe;AAAA,EACf,SAAS;AACX;AAIO,SAAS,6BACd,MACwB;AACxB,MAAI,SAAS;AACb,SAAO,MAAM;AACX,cAAU;AACV,WAAO,WAAW,KAAK,IAAI,CAAC,IAAI,OAAO,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,EACtE;AACF;AAEO,SAAS,0BAA0B,SAGf;AACzB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,QAAQ;AAAA,IAClB,YAAY,QAAQ;AAAA,EACtB;AACF;AAEA,SAAS,KAAK,OAAuB;AACnC,SACE,MACG,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,UAAU,EAAE,EACpB,MAAM,GAAG,EAAE,KAAK;AAEvB;;;ACjDA,SAAS,SAAS;AAsBX,IAAM,qCAAqC;AAC3C,IAAM,4CAA4C;AAClD,IAAM,uDAAuD;AAC7D,IAAM,8CACX;AAEF,IAAM,eAAe,EAAE,OAAO,EAAE,OAAO,gBAAgB;AAAA,EACrD,SAAS;AACX,CAAC;AAED,IAAM,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC;AAC7C,IAAM,aAAa;AAEnB,IAAM,oBAAoB,EACvB,OAAO;AAAA,EACN,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,QAAQ,EAAE,QAAQ,OAAO;AAAA,EACzB,UAAU,EAAE,QAAQ,KAAK;AAAA,EACzB,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,WAAW,UAAU,SAAS,OAAO,CAAC,CAAC;AACvE,CAAC,EACA,OAAO;AAEH,IAAM,uBAAuB;AAC7B,IAAM,8BAA8B;AACpC,IAAM,2BAA2B,yBAAyB;AAAA,EAC/D,CAAC,SAAS,KAAK,OAAO,SAAS;AAAA,EAC/B;AACF;AAEA,IAAM,wCAAwC,EAC3C,OAAO;AAAA,EACN,SAAS;AAAA,EACT,SAAS,qBAAqB,SAAS;AAAA,EACvC,gBAAgB,qBAAqB,SAAS;AAAA,EAC9C,eAAe,qBAAqB,SAAS;AAAA,EAC7C,QAAQ;AAAA,EACR,UAAU,qBAAqB,SAAS;AAAA,EACxC,gBAAgB,WAAW,SAAS;AAAA,EACpC,mBAAmB,qBAAqB,SAAS;AAAA,EACjD,cAAc,EAAE,KAAK,kCAAkC,EAAE,SAAS;AAAA,EAClE,eAAe,EAAE,QAAQ,EAAE,SAAS;AACtC,CAAC,EACA,OAAO;AAEV,IAAM,wCAAwC,EAC3C,OAAO;AAAA,EACN,SAAS;AAAA,EACT,SAAS,qBAAqB,SAAS;AAAA,EACvC,gBAAgB,qBAAqB,SAAS;AAAA,EAC9C,eAAe,qBAAqB,SAAS;AAAA,EAC7C,QAAQ;AAAA,EACR,eAAe,EAAE,QAAQ,EAAE,SAAS;AACtC,CAAC,EACA,OAAO;AAEH,IAAM,wBAAwB,EAAE,MAAM;AAAA,EAC3C;AAAA,EACA;AACF,CAAC;AAEM,IAAM,0BAA0B,EAAE,MAAM;AAAA,EAC7C,EACG,OAAO;AAAA,IACN,MAAM,EAAE,QAAQ,UAAU;AAAA,EAC5B,CAAC,EACA,OAAO;AAAA,EACV,EACG,OAAO;AAAA,IACN,MAAM,EAAE,QAAQ,MAAM;AAAA,IACtB,OAAO,EAAE,OAAO;AAAA,EAClB,CAAC,EACA,OAAO;AAAA,EACV,EACG,OAAO;AAAA,IACN,MAAM,EAAE,QAAQ,MAAM;AAAA,IACtB,QAAQ;AAAA,EACV,CAAC,EACA,OAAO;AACZ,CAAC;AAEM,IAAM,0BAA0B,EACpC,OAAO;AAAA,EACN,SAAS,qBAAqB,SAAS;AAAA,EACvC,kBAAkB,aAAa,SAAS;AAAA,EACxC,gBAAgB,aAAa,SAAS;AAAA,EACtC,aAAa,aAAa,SAAS;AAAA,EACnC,kBAAkB,aAAa,SAAS;AAAA,EACxC,uBAAuB,qBAAqB,SAAS;AAAA,EACrD,wBAAwB,EAAE,MAAM,oBAAoB,EAAE,SAAS;AACjE,CAAC,EACA,OAAO;AAEH,IAAM,iCAAiC,EAC3C,OAAO;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,YAAY;AAAA,EACZ,kBAAkB,aAAa,SAAS;AAAA,EACxC,aAAa,aAAa,SAAS;AACrC,CAAC,EACA,OAAO;AAEH,IAAM,mCAAmC,EAC7C,OAAO;AAAA,EACN,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,SAAS;AAAA,EACT,SAAS;AAAA,EACT,kBAAkB,+BAA+B,SAAS;AAAA,EAC1D,QAAQ;AACV,CAAC,EACA,OAAO;AAEH,IAAM,6BAA6B,EAAE,MAAM;AAAA,EAChD;AAAA,EACA,EACG,OAAO;AAAA,IACN,QAAQ;AAAA,IACR,MAAM,EAAE,QAAQ,QAAQ;AAAA,IACxB,QAAQ;AAAA,EACV,CAAC,EACA,OAAO;AACZ,CAAC;AAEM,IAAM,0BAA0B,EACpC,OAAO;AAAA,EACN,eAAe,EAAE,QAAQ,kCAAkC;AAAA,EAC3D,4BAA4B,EAAE;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,uBAAuB,EAAE,QAAQ,kCAA+B;AAAA,EAChE,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM,EAAE,MAAM,oBAAoB;AAAA,EAClC,QAAQ,EACL,OAAO;AAAA,IACN,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB,cAAc;AAAA,IACd,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,aAAa,EAAE,MAAM,oBAAoB,EAAE,SAAS;AAAA,EACtD,CAAC,EACA,OAAO;AAAA,EACV,QAAQ,EACL,OAAO;AAAA,IACN,QAAQ;AAAA,IACR,UAAU,qBAAqB,SAAS;AAAA,EAC1C,CAAC,EACA,OAAO;AAAA,EACV,aAAa;AAAA,EACb,UAAU;AAAA,EACV,QAAQ,EAAE,MAAM,0BAA0B;AAAA,EAC1C,UAAU,EACP,OAAO;AAAA,IACN,yBAAyB;AAAA,IACzB,uBAAuB;AAAA,IACvB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,EACpB,CAAC,EACA,OAAO;AACZ,CAAC,EACA,OAAO;AAEH,IAAM,qCAAqC,EAC/C,OAAO;AAAA,EACN,eAAe,EAAE,QAAQ,yCAAyC;AAAA,EAClE,UAAU;AAAA,EACV,WAAW;AAAA,EACX,uBAAuB,EAAE,QAAQ,kCAA+B;AAAA,EAChE,4BAA4B,EAAE;AAAA,IAC5B;AAAA,EACF;AAAA,EACA,UAAU,EAAE;AAAA,IACV,EACG,OAAO;AAAA,MACN,IAAI;AAAA,MACJ,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,oBAAoB;AAAA,MACpB,YAAY,EAAE,MAAM,oBAAoB;AAAA,MACxC,cAAc,EAAE,MAAM,oBAAoB;AAAA,IAC5C,CAAC,EACA,OAAO;AAAA,EACZ;AACF,CAAC,EACA,OAAO;AA4BH,SAAS,uBAAuB,OAAmC;AACxE,QAAM,UAAU,wBAAwB;AAAA,IACtC;AAAA,EACF;AACA,sCAAoC,OAAO;AAC3C,SAAO;AACT;AAEO,SAAS,kCACd,OAC8B;AAC9B,QAAM,SAAS,mCAAmC,MAAM,KAAK;AAC7D,4CAA0C,OAAO,0BAA0B;AAC3E,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,SAAS,OAAO,UAAU;AACnC,QAAI,IAAI,IAAI,MAAM,EAAE,GAAG;AACrB,YAAM,IAAI,MAAM,yBAAyB,MAAM,EAAE,oBAAoB;AAAA,IACvE;AACA,QAAI,IAAI,MAAM,EAAE;AAAA,EAClB;AACA,SAAO;AACT;AAEO,SAAS,0CACd,SACM;AACN,QAAM,QAAQ,OAAO,QAAQ,MAAM,GAAG,EAAE,CAAC,CAAC;AAC1C,MAAI,UAAU,sDAAsD;AAClE,UAAM,IAAI;AAAA,MACR,6CAA6C,OAAO,qBAAqB,oDAAoD;AAAA,IAC/H;AAAA,EACF;AACF;AAEA,SAAS,oCAAoC,SAAkC;AAC7E,4CAA0C,QAAQ,0BAA0B;AAC5E,QAAM,WAAW,oBAAI,IAAY;AACjC,QAAM,UAAU,oBAAI,IAAY;AAEhC,aAAW,SAAS,QAAQ,SAAS,QAAQ;AAC3C,QAAI,SAAS,IAAI,MAAM,EAAE,GAAG;AAC1B,YAAM,IAAI,MAAM,+BAA+B,MAAM,EAAE,IAAI;AAAA,IAC7D;AACA,aAAS,IAAI,MAAM,EAAE;AAAA,EACvB;AAEA,aAAW,QAAQ,QAAQ,SAAS,OAAO;AACzC,QAAI,QAAQ,IAAI,KAAK,EAAE,GAAG;AACxB,YAAM,IAAI,MAAM,+BAA+B,KAAK,EAAE,IAAI;AAAA,IAC5D;AACA,YAAQ,IAAI,KAAK,EAAE;AACnB,QAAI,KAAK,SAAS,cAAc;AAC9B,UAAI,CAAC,SAAS,IAAI,KAAK,OAAO,GAAG;AAC/B,cAAM,IAAI;AAAA,UACR,kBAAkB,KAAK,EAAE,iCAAiC,KAAK,OAAO;AAAA,QACxE;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI,CAAC,SAAS,IAAI,KAAK,WAAW,GAAG;AACnC,YAAM,IAAI;AAAA,QACR,kBAAkB,KAAK,EAAE,qCAAqC,KAAK,WAAW;AAAA,MAChF;AAAA,IACF;AAAA,EACF;AAEA,aAAW,QAAQ,QAAQ,QAAQ;AACjC,QAAI,aAAa,MAAM;AACrB,YAAM,eAAe;AAAA,QACnB,KAAK;AAAA,MACP;AACA,UAAI,KAAK,kBAAkB,cAAc;AACvC,cAAM,IAAI;AAAA,UACR,gBAAgB,KAAK,MAAM,mBAAmB,KAAK,aAAa,mBAAmB,YAAY;AAAA,QACjG;AAAA,MACF;AAAA,IACF;AACA,UAAM,kBAAkB,KAAK,OAAO;AACpC,QAAI,mBAAmB,CAAC,SAAS,IAAI,eAAe,GAAG;AACrD,YAAM,IAAI;AAAA,QACR,gBAAgB,KAAK,MAAM,8BAA8B,eAAe;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AACF;;;ACvSO,SAAS,yBACd,SACmB;AACnB,QAAM,aAAa,QAAQ,SAAS,OAAO,CAAC;AAC5C,QAAM,aAAa,mBAAmB,QAAQ,QAAQ;AACtD,MAAI,CAAC,cAAc,CAAC,YAAY;AAC9B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,UAAU,CAAC;AAClC,QAAM,mBACJ,QAAQ,UAAU,oBAClB,oBAAoB;AAAA,IAClB,eAAe;AAAA,IACf,WAAW,QAAQ;AAAA,IACnB,QAAQ,OAAO;AAAA,MAAI,CAAC,SAClB,mBAAmB,OAAO,KAAK,gBAAgB,KAAK;AAAA,IACtD;AAAA,EACF,CAAC;AACH,QAAM,sBACJ,QAAQ,UAAU,uBAClB,oBAAoB;AAAA,IAClB,eAAe;AAAA,IACf,WAAW,QAAQ;AAAA,IACnB,SAAS,WAAW;AAAA,IACpB,kBAAkB,WAAW;AAAA,EAC/B,CAAC;AAEH,SAAO;AAAA,IACL,8BAA8B;AAAA,MAC5B,eAAe;AAAA,MACf,4BACE;AAAA,MACF,uBAAuB;AAAA,MACvB,IAAI,QAAQ;AAAA,MACZ,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,MAChB,MAAM,CAAC,GAAI,QAAQ,QAAQ,CAAC,CAAE;AAAA,MAC9B,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,aAAa,QAAQ;AAAA,MACrB,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,UAAU;AAAA,QACR,yBACE,QAAQ,UAAU,2BAClB,WAAW;AAAA,QACb,uBACE,QAAQ,UAAU,yBAClB,WAAW;AAAA,QACb;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,mBACP,UACkD;AAClD,QAAM,YAAY,IAAI,IAAI,SAAS,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC3E,WAAS,QAAQ,SAAS,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AAClE,UAAM,OAAO,SAAS,MAAM,KAAK;AACjC,QAAI,MAAM,SAAS,cAAc;AAC/B,aAAO,UAAU,IAAI,KAAK,OAAO;AAAA,IACnC;AAAA,EACF;AACA,SAAO,SAAS,OAAO,SAAS,OAAO,SAAS,CAAC;AACnD;AAEO,SAAS,qCACd,OACA,QACM;AACN,QAAM,aAAa,2BAA2B,KAAK;AACnD,QAAM,cAAc,2BAA2B,MAAM;AACrD,MAAI,eAAe,aAAa;AAC9B,UAAM,IAAI;AAAA,MACR,wBAAwB,MAAM,EAAE;AAAA,IAClC;AAAA,EACF;AACF;AAEO,SAAS,2BACd,MACA,YAC2B;AAC3B,MAAI,WAAW,WAAW,GAAG;AAC3B,UAAM,IAAI;AAAA,MACR,gBAAgB,KAAK,MAAM,cAAc,WAAW,MAAM;AAAA,IAC5D;AAAA,EACF;AACA,QAAM,YAAY,WAAW,CAAC;AAC9B,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,gBAAgB,KAAK,MAAM,oBAAoB;AAAA,EACjE;AAEA,QAAM,WAAW,KAAK;AACtB,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AACA,aAAW,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAY;AACV,UAAM,gBAAgB,SAAS,GAAG;AAClC,QAAI,kBAAkB,UAAa,UAAU,GAAG,MAAM,eAAe;AACnE,YAAM,IAAI;AAAA,QACR,gBAAgB,KAAK,MAAM,cAAc,GAAG,KAAK;AAAA,UAC/C,UAAU,GAAG;AAAA,QACf,CAAC,gBAAgB,aAAa;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,iCACd,QACA,UACA,QACM;AACN,aAAW,OAAO;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAY;AACV,QAAI,SAAS,GAAG,MAAM,UAAa,SAAS,GAAG,MAAM,OAAO,GAAG,GAAG;AAChE,YAAM,IAAI;AAAA,QACR,gBAAgB,MAAM,cAAc,GAAG,KAAK,SAAS,GAAG,CAAC,gBAAgB,OAAO,GAAG,CAAC;AAAA,MACtF;AAAA,IACF;AAAA,EACF;AACA,MAAI,SAAS,wBAAwB;AACnC,UAAM,aAAa,IAAI,IAAI,OAAO,0BAA0B,CAAC,CAAC;AAC9D,UAAM,UAAU,SAAS,uBAAuB;AAAA,MAC9C,CAAC,QAAQ,CAAC,WAAW,IAAI,GAAG;AAAA,IAC9B;AACA,QAAI,QAAQ,SAAS,GAAG;AACtB,YAAM,IAAI;AAAA,QACR,gBAAgB,MAAM,mCAAmC,QAAQ;AAAA,UAC/D;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AC/JA,SAAS,aACP,SACA,SACsB;AACtB,SAAO;AAAA,IACL,QAAQ,QAAQ;AAAA,IAChB,eAAe,uBAAuB,QAAQ,OAAO;AAAA,IACrD,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA,kBAAkB,QAAQ;AAAA,IAC1B,QAAQ,QAAQ;AAAA,EAClB;AACF;AAEO,SAAS,SAAS,SAAkD;AACzE,SAAO,aAAa,SAAS,EAAE,MAAM,WAAW,CAAC;AACnD;AAEO,SAAS,KAAK,SAAsD;AACzE,SAAO,aAAa,SAAS,EAAE,MAAM,QAAQ,OAAO,QAAQ,MAAM,CAAC;AACrE;AAEO,SAAS,MAAM,SAAkD;AACtE,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,KAAK,SAAsD;AACzE,SAAO,aAAa,SAAS,EAAE,MAAM,QAAQ,QAAQ,QAAQ,OAAO,CAAC;AACvE;AAEO,SAAS,OAAO,SAAkD;AACvE,SAAO,SAAS,OAAO;AACzB;AAEO,SAAS,WACd,QACA,QACsB;AACtB,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN;AAAA,EACF;AACF;","names":["result","readFlowState"]}