@cyberart-io/engine 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -93,6 +93,9 @@ Full API for the event router, deterministic replay, and CI harness (so agents c
93
93
  - [Presentation adapter](docs/presentation-adapter.md) — host-owned render model, intents, loading / error / unsupported
94
94
  - [Asset resolver](docs/asset-resolver.md) — host-pluggable images/audio/fonts/spritesheets, cache, preload, fallbacks
95
95
  - [Presentation cue](docs/presentation-cue.md) — deterministic `createPresentationTimeline`, duplicate policy, reduced-motion, lifecycle events
96
+ - [Capability manifest](docs/capability-manifest.md) — versioned JSON for runtime features, phases, managers, assets, events, permissions, integrations
97
+ - [Normalized geometry](docs/normalized-geometry.md) — coordinate spaces, contain/cover/crop layout, landmarks, hit regions, debug overlay
98
+ - [Runtime group](docs/runtime-group.md) — `createRuntimeGroup`, shared router attach, lockstep clock; `createHeadlessMultiCartHarness` from `@cyberart-io/engine/headless`
96
99
 
97
100
  ## Write a cart
98
101
 
@@ -170,7 +173,7 @@ const cart = runtime.mount(artProject, {
170
173
 
171
174
  `runtime.destroy()` tears down the runtime. `runtime.unlockAudio()` is for an early click before `mount`. `runtime.onError` receives frame errors (`phase`, `consecutive`, `stopped`).
172
175
 
173
- One cart per runtime. A second `mount` unloads the first. Several pieces on a page means several `createRuntime()` calls.
176
+ One cart per runtime. A second `mount` unloads the first. Several pieces on a page means several `createRuntime()` calls, or one `createRuntimeGroup()` that attaches each mailbox to a shared router and locksteps a deterministic clock.
174
177
 
175
178
  ## Audio
176
179
 
@@ -239,7 +242,7 @@ const replay = await cart.getReplayMetadata();
239
242
  CI and agents should drive the **same** `createRuntime({ deterministic })` path. Import the harness from **`@cyberart-io/engine/headless`** so browser production builds never walk `node:fs/promises`.
240
243
 
241
244
  - Carts and production hosts: `import { createRuntime } from '@cyberart-io/engine'`
242
- - Tests, CI, and frame capture: `import { createHeadlessHarness } from '@cyberart-io/engine/headless'`
245
+ - Tests, CI, and frame capture: `import { createHeadlessHarness, createHeadlessMultiCartHarness } from '@cyberart-io/engine/headless'`
243
246
 
244
247
  `@cyberart-io/engine` does not re-export the harness. `installHeadlessCanvas` is the documented jsdom install (test-only). `createHeadlessHarness` sizes a container, mounts, and wraps step / input / inspect / snapshot.
245
248
 
@@ -258,7 +261,7 @@ harness.destroy();
258
261
 
259
262
  ## Events
260
263
 
261
- Default path: per-runtime **mailbox** (`dispatch` / `consume` / `emit`). Multi-cart hosts attach each `HostChannel` to `createEventRouter` — carts never see the router.
264
+ Default path: per-runtime **mailbox** (`dispatch` / `consume` / `emit`). Multi-cart hosts should prefer `createRuntimeGroup()` (it calls `router.attach` for each mailbox). You can still attach each `HostChannel` to `createEventRouter` yourself — carts never see the router.
262
265
 
263
266
  ```ts
264
267
  const cart = runtime.mount(artProject, {
@@ -299,25 +302,83 @@ const router = createEventRouter({
299
302
  router.attach('presentation', runtime.hostChannel, deriveAttachOptions(contracts, 'cart'));
300
303
  ```
301
304
 
302
- ## Presentation cue
305
+ ## Capability manifest
303
306
 
304
- Frame-stepped effects (checkmarks, ripples, room fades). No `setTimeout` / rAF. Drive `step` from the same clock as deterministic `cart.step`.
307
+ JSON for what a cart needs from the host. `validateCapabilityManifest` returns structured diagnostics instead of throwing.
305
308
 
306
309
  ```ts
307
- import { createPresentationTimeline } from '@cyberart-io/engine';
308
-
309
- const timeline = createPresentationTimeline({ originFrame: 0, reducedMotion: false });
310
- timeline.play({
311
- name: 'checkmark',
312
- idempotencyKey: 'gold',
313
- durationFrames: 90,
314
- easing: 'ease-out',
315
- onDuplicate: 'replace',
310
+ import {
311
+ defineCapabilityManifest,
312
+ validateCapabilityManifest,
313
+ } from '@cyberart-io/engine';
314
+
315
+ const defined = defineCapabilityManifest({
316
+ id: 'adventure.presentation',
317
+ runtime: { minContractVersion: 1, features: ['router'] },
318
+ phases: ['loading', 'ready', 'error', 'unsupported'],
319
+ managers: ['pointer', 'hostChannel'],
320
+ assets: { kinds: ['image'], declarations: [{ id: 'room-bg', kind: 'image' }] },
321
+ acceptedEvents: ['adventure.state.*'],
322
+ emittedEvents: ['adventure.intent.exit-requested'],
323
+ permissions: { emit: ['adventure.intent.*'], subscribe: ['adventure.state.*'] },
324
+ integrations: ['tone'],
325
+ });
326
+ if (!defined.ok) throw new Error(defined.errors.map((e) => e.detail).join('; '));
327
+ validateCapabilityManifest(defined.manifest, {
328
+ contractVersion: 1,
329
+ features: ['router'],
330
+ integrations: ['tone'],
331
+ emit: ['adventure.intent.*'],
332
+ subscribe: ['adventure.state.*'],
333
+ });
334
+ ```
335
+
336
+ Fields, host allowlists, and diagnostic codes: [capability manifest](docs/capability-manifest.md).
337
+
338
+ ## Runtime group
339
+
340
+ Several production carts, one router, one lockstep clock. Use this instead of intercepting each `onEvent` and republishing by hand.
341
+
342
+ ```ts
343
+ import { createRuntimeGroup } from '@cyberart-io/engine';
344
+
345
+ const group = createRuntimeGroup({
346
+ origin: 0,
347
+ participants: [
348
+ { id: 'effects', cart: effectsCart, emit: ['ambience.intent.*'], subscribe: ['adventure.state.*'] },
349
+ { id: 'ambience', cart: ambienceCart, subscribe: ['ambience.intent.*'] },
350
+ ],
351
+ });
352
+ group.publish({ type: 'adventure.state.loon-whistle', kind: 'state', payload: { habitat: 'pond' } });
353
+ await group.step(2);
354
+ const { trace } = await group.inspect();
355
+ group.destroy();
356
+ ```
357
+
358
+ Headless / CI: `createHeadlessMultiCartHarness` from `@cyberart-io/engine/headless` is the same handle after `installHeadlessCanvas()`. Full options: [runtime group](docs/runtime-group.md).
359
+
360
+ ## Normalized geometry
361
+
362
+ Shared 0–1 content-box coordinates, landmarks, and hit regions. Pixel `PresentationRegion` on the presentation adapter is unchanged.
363
+
364
+ ```ts
365
+ import {
366
+ createPresentationLayout,
367
+ pointerToRegion,
368
+ ROUND_TRIP_TOLERANCE,
369
+ } from '@cyberart-io/engine';
370
+
371
+ const layout = createPresentationLayout({
372
+ contentWidth: 1920,
373
+ contentHeight: 1080,
374
+ viewportWidth: 1280,
375
+ viewportHeight: 800,
376
+ mode: 'contain',
316
377
  });
317
- timeline.step(90);
378
+ const hit = pointerToRegion({ x: canvasX, y: canvasY }, layout, doc);
318
379
  ```
319
380
 
320
- Lifecycle names `cue.started` / `cue.completed` / `cue.cancelled` / `cue.replaced` are local to the timeline. They are not router envelopes unless you define a contract. Duplicate policy, late-play catch-up, and reduced-motion: [presentation cue](docs/presentation-cue.md).
381
+ Spaces, contain/cover/crop, debug overlay, and the reproduce command: [normalized geometry](docs/normalized-geometry.md).
321
382
 
322
383
  ## Presentation adapter
323
384
 
@@ -166,7 +166,31 @@ declare class PointerManager {
166
166
  destroy(): void;
167
167
  }
168
168
 
169
+ /**
170
+ * Copyright (c) 2026 Aaron Boyarsky
171
+ * SPDX-License-Identifier: LicenseRef-CyberArt-Engine
172
+ * See packages/engine/LICENSE
173
+ *
174
+ * Versioned envelope for routed host ↔ cart events. Unattached HostChannel
175
+ * mailboxes still accept thin `{ type, payload }` events; this module is the
176
+ * schema the EventRouter normalizes to.
177
+ */
178
+ declare const EVENT_ENVELOPE_VERSION: 1;
169
179
  type EventKind = 'intent' | 'state' | 'diagnostic';
180
+ type EventEnvelope = {
181
+ schemaVersion: typeof EVENT_ENVELOPE_VERSION;
182
+ type: string;
183
+ kind: EventKind;
184
+ source: string;
185
+ target?: string;
186
+ id: string;
187
+ correlationId: string;
188
+ causationId?: string;
189
+ seq: number;
190
+ hops: number;
191
+ idempotencyKey?: string;
192
+ payload?: unknown;
193
+ };
170
194
  type EventInput = {
171
195
  type: string;
172
196
  payload?: unknown;
@@ -634,4 +658,148 @@ type HeadlessHarness<T = unknown> = {
634
658
  };
635
659
  declare function createHeadlessHarness<T>(options: CreateHeadlessHarnessOptions<T>): HeadlessHarness<T>;
636
660
 
637
- export { type CreateHeadlessHarnessOptions, DEFAULT_HEADLESS_HEIGHT, DEFAULT_HEADLESS_WIDTH, HEADLESS_PNG_DATA_URL, type HeadlessFrameError, type HeadlessHarness, type HeadlessInspect, createHeadlessHarness, installHeadlessCanvas };
661
+ /**
662
+ * Copyright (c) 2026 Aaron Boyarsky
663
+ * SPDX-License-Identifier: LicenseRef-CyberArt-Engine
664
+ * See packages/engine/LICENSE
665
+ *
666
+ * Host-side event router. Carts keep a dumb HostChannel mailbox; the host
667
+ * attaches those channels here so events are permissioned, budgeted, and
668
+ * loop-checked before they reach another cart. Carts never receive this
669
+ * object.
670
+ */
671
+
672
+ type ValidateResult = true | {
673
+ reason: 'host-rejected';
674
+ detail?: string;
675
+ };
676
+ type AttachOptions = {
677
+ emit?: string[];
678
+ subscribe?: string[];
679
+ authoritative?: boolean;
680
+ };
681
+ type EventRouterOptions = {
682
+ validate?: (event: EventEnvelope) => ValidateResult;
683
+ createId?: () => string;
684
+ now?: () => number;
685
+ hostSource?: string;
686
+ maxPerTurn?: number;
687
+ maxPerWindow?: number;
688
+ windowMs?: number;
689
+ maxCausationDepth?: number;
690
+ maxHops?: number;
691
+ maxCorrelationPerTurn?: number;
692
+ maxIndex?: number;
693
+ };
694
+ type PublishExtras = {
695
+ cause?: EventEnvelope;
696
+ };
697
+ type EventRouter = {
698
+ attach(id: string, channel: HostChannel, options?: AttachOptions): void;
699
+ detach(id: string): void;
700
+ publish(event: EventInput, extras?: PublishExtras): EventEnvelope | undefined;
701
+ subscribe(patterns: string[], listener: (event: EventEnvelope) => void): () => void;
702
+ turn(): void;
703
+ };
704
+
705
+ /**
706
+ * Copyright (c) 2026 Aaron Boyarsky
707
+ * SPDX-License-Identifier: LicenseRef-CyberArt-Engine
708
+ * See packages/engine/LICENSE
709
+ *
710
+ * First-class multi-cart runtime group. Creates production `createRuntime`
711
+ * instances, attaches each mailbox to one shared `createEventRouter`, and
712
+ * locksteps a deterministic clock. Carts never receive the router object.
713
+ */
714
+
715
+ type RuntimeGroupKind = 'render' | 'calculation';
716
+ /**
717
+ * Optional capability-shaped attach hints. Explicit participant `emit` /
718
+ * `subscribe` / `authoritative` win. Do not import the capability manifest
719
+ * module from this file.
720
+ */
721
+ type RuntimeGroupCapability = {
722
+ emit?: string[];
723
+ subscribe?: string[];
724
+ authoritative?: boolean;
725
+ };
726
+ type RuntimeGroupFrameError = {
727
+ error: unknown;
728
+ info: FrameErrorInfo;
729
+ };
730
+ type RuntimeGroupParticipantConfig<T = unknown> = {
731
+ id: string;
732
+ cart: AnimationCart<T>;
733
+ /** Rendered surface vs calculation cart (still a real `AnimationCart`). */
734
+ kind?: RuntimeGroupKind;
735
+ seed?: CreateRuntimeOptions['seed'];
736
+ container?: HTMLElement;
737
+ width?: number;
738
+ height?: number;
739
+ initialState?: Partial<T>;
740
+ gameManager?: unknown;
741
+ onEvent?: HostEventListener;
742
+ emit?: string[];
743
+ subscribe?: string[];
744
+ authoritative?: boolean;
745
+ capability?: RuntimeGroupCapability;
746
+ };
747
+ type CreateRuntimeGroupOptions = {
748
+ participants: RuntimeGroupParticipantConfig[];
749
+ /** Shared virtual-clock origin (ms). Default 0. */
750
+ origin?: number;
751
+ width?: number;
752
+ height?: number;
753
+ validate?: EventRouterOptions['validate'];
754
+ createId?: () => string;
755
+ now?: () => number;
756
+ /** Extra router options. Group injects shared `createId` / `now` unless set here. */
757
+ router?: EventRouterOptions;
758
+ };
759
+ type RuntimeGroupParticipantInspect = {
760
+ state: unknown;
761
+ events: HostEvent[];
762
+ errors: RuntimeGroupFrameError[];
763
+ kind: RuntimeGroupKind;
764
+ clock: ClockSnapshot;
765
+ };
766
+ type RuntimeGroupDiagnostics = {
767
+ paused: boolean;
768
+ participantIds: string[];
769
+ clocks: Record<string, ClockSnapshot>;
770
+ rejections: unknown[];
771
+ };
772
+ type RuntimeGroupInspect = {
773
+ participants: Record<string, RuntimeGroupParticipantInspect>;
774
+ trace: EventEnvelope[];
775
+ diagnostics: RuntimeGroupDiagnostics;
776
+ };
777
+ type RuntimeGroupParticipantHandle = {
778
+ readonly id: string;
779
+ readonly kind: RuntimeGroupKind;
780
+ readonly runtime: CyberArtRuntime;
781
+ readonly container: HTMLElement;
782
+ readonly events: readonly HostEvent[];
783
+ readonly errors: readonly RuntimeGroupFrameError[];
784
+ get cart(): CartHandle;
785
+ };
786
+ type RuntimeGroup = {
787
+ readonly router: EventRouter;
788
+ readonly origin: number;
789
+ readonly paused: boolean;
790
+ participant(id: string): RuntimeGroupParticipantHandle;
791
+ step(frames?: number): Promise<void>;
792
+ pause(): void;
793
+ resume(): void;
794
+ reset(): void;
795
+ dispatch(participantId: string, event: HostEvent): void;
796
+ publish(event: EventInput, extras?: PublishExtras): EventEnvelope | undefined;
797
+ inspect(): Promise<RuntimeGroupInspect>;
798
+ destroy(): void;
799
+ };
800
+
801
+ type CreateHeadlessMultiCartHarnessOptions = CreateRuntimeGroupOptions;
802
+ type HeadlessMultiCartHarness = RuntimeGroup;
803
+ declare function createHeadlessMultiCartHarness(options: CreateHeadlessMultiCartHarnessOptions): HeadlessMultiCartHarness;
804
+
805
+ export { type CreateHeadlessHarnessOptions, type CreateHeadlessMultiCartHarnessOptions, DEFAULT_HEADLESS_HEIGHT, DEFAULT_HEADLESS_WIDTH, HEADLESS_PNG_DATA_URL, type HeadlessFrameError, type HeadlessHarness, type HeadlessInspect, type HeadlessMultiCartHarness, createHeadlessHarness, createHeadlessMultiCartHarness, installHeadlessCanvas };
package/dist/headless.js CHANGED
@@ -5,4 +5,4 @@
5
5
  * Not an OSI open-source license.
6
6
  */
7
7
 
8
- var ft=(t,e)=>()=>(t&&(e=t(t=0)),e);var Ct={};function St(t,e){let n=t.indexOf(Ke);if(n===-1)return null;let r=n+Ke.length,s=`const __cyberSkip=new Set(${JSON.stringify(e)});const __cyberOrig=registerProcessor;registerProcessor=(n,p)=>__cyberSkip.has(n)?undefined:__cyberOrig(n,p);`;return t.slice(0,r)+s+t.slice(r)}var fe,ae,wt,X,Ke,je=ft(()=>{"use strict";fe=/AudioWorkletProcessor with name:\s*["'`][^"'`]+["'`]\s+is already registered/i,ae="__cyberartWorkletPatchApplied";typeof window<"u"&&!window[ae]&&(window.addEventListener("error",t=>{let e=t?.message??"";fe.test(e)&&(t.preventDefault(),t.stopImmediatePropagation())},!0),window.addEventListener("unhandledrejection",t=>{let e=t?.reason,n=typeof e=="string"?e:e?.message??"";fe.test(n)&&t.preventDefault()}),window[ae]=!0);wt=!1,X=(...t)=>{wt&&console.log("[workletPatch]",...t)},Ke="((AudioWorkletProcessor,registerProcessor)=>{";if(typeof AudioWorklet<"u"&&!AudioWorklet.prototype[ae]){let t=new WeakMap,e=/registerProcessor\s*\(\s*['"`]([^'"`]+)['"`]/g,n=AudioWorklet.prototype.addModule,r=0;AudioWorklet.prototype.addModule=async function(s,o){let d=++r,l=t.get(this);l||(l=new Set,t.set(this,l)),X(`#${d} addModule`,{url:s.slice(0,64),isBlob:s.startsWith("blob:"),knownBefore:[...l]});let y=s,f=null;if(s.startsWith("blob:")){let u=null;try{u=await(await fetch(s)).text()}catch(g){X(`#${d} blob fetch failed`,g)}if(u!==null){let g=new Set;for(let C of u.matchAll(e))g.add(C[1]);if(g.size>0){let C=[...g].filter(k=>l.has(k)),m=[...g].filter(k=>!l.has(k));if(C.length>0&&m.length===0){X(`#${d} short-circuit \u2014 all processors already registered`,C);return}if(C.length>0&&m.length>0){let k=St(u,C);if(k!==null){let c=new Blob([k],{type:"application/javascript"});f=URL.createObjectURL(c),y=f,X(`#${d} rewrote blob; skipping`,C,"allowing",m)}else X(`#${d} blob rewrite failed; passing original through`)}m.forEach(k=>l.add(k))}}}return n.call(this,y,o).then(()=>{f&&URL.revokeObjectURL(f)},u=>{f&&URL.revokeObjectURL(f);let g=(u&&u.message)??"";if(!(fe.test(g)||/already registered/i.test(g)))throw u})},AudioWorklet.prototype[ae]=!0}});var Te=()=>{let t=["ms","moz","webkit","o"];for(let e=0;e<t.length&&!window.requestAnimationFrame;++e)window.requestAnimationFrame=window[t[e]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[t[e]+"CancelAnimationFrame"]||window[t[e]+"CancelRequestAnimationFrame"]},M=window.devicePixelRatio||1,$=/Headless/i.test(navigator.userAgent),tn=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)||/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.platform);function Pe(){return Math.min(window.innerWidth,window.innerHeight)}var ce="data-cyberart-canvas",B=class{constructor(e,n,r=1,a={}){this.width=e,this.height=n;let s=a.container,o=a.adoptFromDocument??!s,d=s?s.querySelector(`canvas[${ce}]`)??s.querySelector("canvas"):null;if(d)this.canvas=d,this.adopted=!0;else if(o){let l=document.getElementById("canvas")??document.querySelector("canvas");l?(this.canvas=l,this.adopted=!0):(this.canvas=document.createElement("canvas"),this.canvas.setAttribute("id","canvas"),this.adopted=!1)}else this.canvas=document.createElement("canvas"),this.adopted=!1;this.canvas.hasAttribute(ce)||this.canvas.setAttribute(ce,""),this.canvas.style.display="block",this.canvas.style.margin="auto",this.ctx=this.canvas.getContext("2d",{colorSpace:"display-p3",alpha:!1}),this.ctx.globalAlpha=r,this.ctx.imageSmoothingEnabled=!1,this.setSize(e,n)}setSize(e,n){this.width=e,this.height=n,this.canvas.width=e,this.canvas.height=n,this.canvas.style.width=`${e/M}px`,this.canvas.style.height=`${n/M}px`,this.imageData=this.ctx.createImageData(e,n),this.ctx.putImageData(this.imageData,0,0)}_blank(e=1){let n=e?Math.max(e,.03):1;this.ctx.fillStyle=`rgba(0,0,0,${n})`,this.ctx.fillRect(0,0,this.width,this.height)}clearAll(){this.ctx.save(),this.ctx.globalAlpha=1,this._blank(),this.ctx.restore()}};function De(t,e){let n=t/e,r,a;return n>1?(r=t,a=~~(t/n)):(a=e,r=~~(e*n)),{width:r,height:a,iWidth:1/r,iHeight:1/a,area:r*a,largeDim:Math.max(r,a),smallDim:Math.min(r,a),aspectRatio:n}}function Me(t,e=window.innerWidth,n=window.innerHeight){let r=Pe(),a,s;return n<e?t>1?e>=r*t?(a=r*t,s=r):(a=e,s=a/t):(a=r*t,s=r):t>1?(a=r,s=r/t):n<r/t?(s=n,a=s*t):(a=r,s=r/t),[a,s]}var le=class{constructor(e=!1,n=!0){this.debugMode=e,this.actionMap={},this.listening=n,this.checkKeypress=this.checkKeypress.bind(this),this.registerAction=this.registerAction.bind(this),this.listening&&window.addEventListener("keydown",this.checkKeypress,!1)}checkKeypress({key:e}){this.debugMode&&console.log(`Pressed ${e}`),e in this.actionMap&&this.actionMap[e]()}inject(e){this.checkKeypress({key:e})}registerAction(e,n,r=!1){if(e.length!==1)throw new Error(`Only single-character actions may be registered. Cannot register: ${e}`);if(e in this.actionMap&&!r)throw new Error(`Action already exists for code: ${e}`);this.actionMap[e]=n}destroy(){this.listening&&window.removeEventListener("keydown",this.checkKeypress,!1),this.actionMap={}}},Fe=le;var he=class{constructor(e,n={}){this.x=-1;this.y=-1;this.isDown=!1;this.clicks=[];this.canvas=e,this.listening=n.listen!==!1,this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.listening&&(e.addEventListener("pointerdown",this.onPointerDown),e.addEventListener("pointermove",this.onPointerMove),e.addEventListener("pointerup",this.onPointerUp))}toCanvasCoords(e){let n=this.canvas.getBoundingClientRect();return{x:(e.clientX-n.left)*(this.canvas.width/n.width),y:(e.clientY-n.top)*(this.canvas.height/n.height)}}onPointerDown(e){let{x:n,y:r}=this.toCanvasCoords(e);this.x=n,this.y=r,this.isDown=!0,this.clicks.push({x:n,y:r})}onPointerMove(e){let{x:n,y:r}=this.toCanvasCoords(e);this.x=n,this.y=r}onPointerUp(e){let{x:n,y:r}=this.toCanvasCoords(e);this.x=n,this.y=r,this.isDown=!1}hasClick(){return this.clicks.length>0}consumeClick(){return this.clicks.shift()??null}inject(e,n,r){this.x=n,this.y=r,e==="down"?(this.isDown=!0,this.clicks.push({x:n,y:r})):e==="up"&&(this.isDown=!1)}destroy(){this.listening&&(this.canvas.removeEventListener("pointerdown",this.onPointerDown),this.canvas.removeEventListener("pointermove",this.onPointerMove),this.canvas.removeEventListener("pointerup",this.onPointerUp))}},He=he;function te(){return{now:()=>performance.now()}}function Le(t=0){let e=t;return{now:()=>e,set(n){e=n},advance(n){e+=n}}}var Ie=(t,e,n,r)=>({now:t,startTime:e,elapsedSinceStart:t-e,deltaSinceLastUpdate:n===null?0:t-n,deltaSinceLastRender:r===null?0:t-r}),ne=class{constructor(e,n,r,a,s,o={}){this.startTime=0;this.lastUpdateAt=null;this.lastRenderAt=null;this.clockOffsetMs=0;this.pauseStartedAt=null;this.renderAnimation=this.renderAnimation.bind(this),this.dimensionContext=De(e,n),this.R=r,this.gameManager=o.gameManager,this.hostChannel=o.hostChannel,this.clock=o.clock??te(),this.canvas=new B(this.dimensionContext.width,this.dimensionContext.height,1,o.canvasMount),this.drawingContext=this.canvas.ctx,this.keyboardManager=new Fe(!1,o.captureKeyboard??!0),this.pointerManager=new He(this.canvas.canvas,{listen:o.listenToPointer!==!1}),this.animationCart=s;let d=o.customState;this.featureState=s.getDefaultFeatureState?.(this.R,this.dimensionContext,a,this.keyboardManager,d,this.pointerManager,this.gameManager,this.hostChannel),this.cartState=s.getDefaultState(this.R,this.dimensionContext,a,this.keyboardManager,d,this.pointerManager,this.gameManager,this.featureState,this.hostChannel),this.startTime=this.clock.now(),this.canvas.clearAll()}captureFramebuffer(){let e=this.canvas.imageData,n=new ImageData(e.width,e.height);return n.data.set(e.data),n}restoreFramebuffer(e){let n=this.canvas.imageData;return n.width!==e.width||n.height!==e.height||n.data.length!==e.data.length?!1:(n.data.set(e.data),this.drawingContext.putImageData(n,0,0),!0)}setPaused(e){let n=this.clock.now();if(e){this.pauseStartedAt===null&&(this.pauseStartedAt=n);return}this.pauseStartedAt!==null&&(this.clockOffsetMs+=n-this.pauseStartedAt,this.pauseStartedAt=null)}resolveNow(e){let n=this.pauseStartedAt!==null?e-this.pauseStartedAt:0;return e-this.clockOffsetMs-n}getElapsedSinceStart(e=this.clock.now()){return Math.max(0,this.resolveNow(e)-this.startTime)}restoreClock(e,n){this.pauseStartedAt=null,this.lastUpdateAt=null,this.lastRenderAt=null;let r=Math.max(0,e);if(typeof n=="number"&&Number.isFinite(n)){this.startTime=n,this.clockOffsetMs=this.clock.now()-n-r;return}this.clockOffsetMs=0,this.startTime=this.clock.now()-r}getRandomState(){return this.R.getState()}injectKey(e){this.keyboardManager.inject(e)}injectPointer(e,n,r){this.pointerManager.inject(e,n,r)}async updateAnimationState(e,n,r=this.clock.now()){let a=this.resolveNow(r),s=Ie(a,this.startTime,this.lastUpdateAt,this.lastRenderAt);this.cartState=this.animationCart.update(this.R,e,n,this.dimensionContext,this.cartState,this.keyboardManager,this.pointerManager,this.gameManager,s,this.featureState,this.hostChannel),this.lastUpdateAt=a}async renderAnimation(e,n,r=this.clock.now()){let a=this.resolveNow(r),s=Ie(a,this.startTime,this.lastUpdateAt,this.lastRenderAt);this.animationCart.render(this.R,e,n,this.dimensionContext,this.cartState,this.drawingContext,this.canvas.imageData,this.pointerManager,this.gameManager,s,this.featureState,this.hostChannel),this.lastRenderAt=a}getCanvas(){return this.canvas.canvas}getDrawDetails(){return[this.canvas.canvas,0,0,this.dimensionContext.width,this.dimensionContext.height]}teardown(){try{this.animationCart.teardown?.(this.cartState,this.featureState)}catch(e){console.error("Error during cart teardown",e)}this.keyboardManager.destroy(),this.pointerManager.destroy()}};var re=class extends B{constructor(e,n,r=1,a=!0,s={}){if(super(e,n,r,s),this.adopted)return;let o=s.container;if(o){this.canvas.parentNode!==o&&o.appendChild(this.canvas);return}if(a){let d=document.getElementById("canvas");d&&d!==this.canvas&&d.parentNode===document.body&&document.body.removeChild(d),document.body.appendChild(this.canvas)}}};function Oe(t){let e=parseInt(t.substring(0,8),16),n=parseInt(t.substring(8,8),16),r=parseInt(t.substring(16,8),16),a=parseInt(t.substring(24,8),16);return{next:()=>{e|=0,n|=0,r|=0,a|=0;let o=(e+n|0)+a|0;return a=a+1|0,e=n^n>>>9,n=r+(r<<3)|0,r=r<<21|r>>>11,r=r+o|0,(o>>>0)/4294967296},getRegs:()=>({a:e,b:n,c:r,d:a}),setRegs:o=>{e=o.a,n=o.b,r=o.c,a=o.d}}}var ie=class{constructor(e){this.seed=e.hash,this.useA=!1,this.genA=Oe(e.hash.substring(2,32)),this.genB=Oe(e.hash.substring(34,32)),this.prngA=this.genA.next,this.prngB=this.genB.next;for(let n=0;n<1e6;n+=2)this.prngA(),this.prngB()}getState(){let e=this.genA.getRegs(),n=this.genB.getRegs();return{seed:this.seed,useA:this.useA,prngA:{a:e.a,b:e.b,c:e.c,d:e.d},prngB:{a:n.a,b:n.b,c:n.c,d:n.d}}}setState(e){if(e.seed!==this.seed)throw new Error(`Random.setState: seed ${e.seed} does not match ${this.seed}`);this.useA=e.useA,this.genA.setRegs(e.prngA),this.genB.setRegs(e.prngB)}r_zero_one(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}dec(e,n){return e===void 0?this.r_zero_one():n===void 0?e*this.r_zero_one():e+(n-e)*this.r_zero_one()}int(e,n){return n===void 0&&(n=e,e=0),Math.floor(this.dec(e,n))}bool(e=.5){return this.r_zero_one()<e}sign(){return this.bool()?1:-1}choose(e){return e[this.int(e.length)]}};var Ne="bafybeicjwcq5lxxtfnyj4p2ugcr7ctyb5wl62cbcechj6tsabdq5whcs7u",_e="https://ipfs.io/ipfs/";function mt(t){return t.endsWith("/")?t:`${t}/`}var J=null;function gt(t){return[...Array(t)].map(()=>Math.floor(Math.random()*16).toString(16)).join("")}function yt(t){return t&&t.length>0?t:[{cid:Ne}]}function bt(t){return t.startsWith("0x")?t:`0x${t}`}var We=/^(0[xX])?[0-9a-fA-F]{64}$/;function vt(t){let e="",n=2166136261,r=522970236;for(let a=0;e.length<64;a++){for(let s=0;s<t.length;s++)n^=t.charCodeAt(s)+a,n=Math.imul(n,16777619),r^=t.charCodeAt(s)+a*17,r=Math.imul(r,16777619);e+=(n>>>0).toString(16).padStart(8,"0"),e+=(r>>>0).toString(16).padStart(8,"0")}return`0x${e.slice(0,64)}`}function Ue(t){let e=typeof t=="number"?String(t):t;return We.test(e)?`0x${(e.startsWith("0x")||e.startsWith("0X")?e.slice(2):e).toLowerCase()}`:vt(e)}function $e(t,e){if(typeof t=="number"||e==="deterministic")return Ue(t);let n=String(t);return We.test(n)?Ue(n):n.startsWith("0x")||n.startsWith("0X")?n:`0x${n}`}function At(t){if(!t&&typeof tokenData<"u"&&tokenData?.hash)return{hash:tokenData.hash,tokenId:String(tokenData.tokenId),externalAssetDependencies:yt(tokenData.externalAssetDependencies),preferredIPFSGateway:mt(tokenData.preferredIPFSGateway||_e),preferredArweaveGateway:tokenData.preferredArweaveGateway};let e=typeof window<"u"?new URLSearchParams(window.location.search):new URLSearchParams;return{hash:t?bt(t):e.get("hash")||`0x${gt(64)}`,tokenId:"18009999",externalAssetDependencies:[{cid:Ne}],preferredIPFSGateway:_e}}function pe(t){let e=t?.useCache!==!1;if(e&&J&&!t?.hash)return J;let n=At(t?.hash);return e?J=n:J||(J=n),n}function Be(t){return new Array(32).fill(null).map((e,n)=>parseInt(t.hash.slice(2+n*2,4+n*2),16))}async function me(){let t=await import("tone");if(typeof t.start=="function")return t;let e=t.default;return e&&typeof e.start=="function"?e:t}var Ve={id:"tone",async load(){await Promise.resolve().then(()=>(je(),Ct))},async unlock(){await Ve.load(),await(await me()).start()},async resumeIfSuspended(){let t=await me();t.context.state==="suspended"&&await t.context.resume()},async suspendIfRunning(){let e=(await me()).context.rawContext;"suspend"in e&&e.state==="running"&&await e.suspend()}},ze={tone:Ve};function ge(t){if(!t)return[];let e=Array.isArray(t)?t:[t],n=[];for(let r of e){if(!(r in ze)){console.warn(`Unknown audio library "${r}"`);continue}let a=r;n.includes(a)||n.push(a)}return n}function ye(t){return t.map(e=>ze[e])}var se="$cyberartTa",F=class extends Error{constructor(e){super(e),this.name="IncompatibleCartStateError"}},be={Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array};function kt(t){for(let e of Object.keys(be))if(t instanceof be[e])return e}function Ye(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}function H(t){if(t===null||typeof t!="object"||Array.isArray(t))return!1;let e=Object.getPrototypeOf(t);return e===Object.prototype||e===null}function ve(t){return H(t)?typeof t[se]=="string"&&Array.isArray(t.d):!1}function Et(t){return t==null?!1:typeof t=="function"?!0:!(typeof t!="object"||Array.isArray(t)||Ye(t)||H(t))}var Rt=new Set(["audioContextStarted","midiSynths","keepRatioPrimed","audioInitStarted","musicSeekApplied"]);function Ge(t){return t===null?"null":ve(t)?String(t[se]):Array.isArray(t)?"array":H(t)?"object":typeof t}function xt(t,e){return t===e||t==="null"||e==="null"}function qe(t){return t.trim().toLowerCase().replace(/^0x/,"")}function Je(t,e,n,r){if(!(!n&&!r)&&qe(t)!==qe(e))throw new F(`Generative cart state is for seed "${e}", but the live token is "${t}"`)}function K(t){return typeof t=="number"&&Number.isFinite(t)&&t>0}function Xe(t,e){let n=t.dimensions;if(n&&K(n.width)&&K(n.height))return n;if(e&&K(e.width)&&K(e.height))return{width:e.width,height:e.height};if(H(t.state)){let r=t.state.containerWidth,a=t.state.containerHeight;if(K(r)&&K(a))return{width:r,height:a}}return null}function j(t,e=new WeakSet){if(t===null||typeof t=="string"||typeof t=="boolean")return t;if(typeof t=="number")return Number.isFinite(t)?t:null;if(!(typeof t=="function"||typeof t>"u"||typeof t=="bigint"||typeof t=="symbol")){if(Ye(t)){let n=kt(t);return n?{[se]:n,d:Array.from(t)}:void 0}if(typeof t=="object"&&!e.has(t)){e.add(t);try{if(Array.isArray(t)){let a=[],s=0;for(let o of t){let d=j(o,e);d!==void 0&&(a.push(d),s++)}return t.length>0&&s===0?void 0:a}if(!H(t)||Et(t))return;let n=Object.keys(t),r={};for(let a of n){if(Rt.has(a))continue;let s=j(t[a],e);s!==void 0&&(r[a]=s)}return n.length>0&&Object.keys(r).length===0?void 0:r}finally{e.delete(t)}}}}function Q(t){if(ve(t)){let e=be[t[se]];return e?new e(t.d.map(n=>Number(n))):t}if(Array.isArray(t))return t.map(e=>Q(e));if(H(t)){let e={};for(let n of Object.keys(t))e[n]=Q(t[n]);return e}return t}function Ae(t,e,n,r,a=!0){if(a&&n&&r&&n!==r)throw new F(`Cart state is for "${r}", but the live cart is "${n}"`);if(!H(e)){if(a)throw new F("Cart state snapshot is empty");return}let s=Object.keys(e);if(s.length===0){if(a)throw new F("Cart state snapshot is empty");return}let o=j(t);if(!H(o)||Object.keys(o).length===0){if(a)throw new F("Live cart has no serializable state");return}let d=s.filter(l=>l in o);if(d.length===0){if(a)throw new F("Cart state snapshot does not overlap the live cart shape");return}for(let l of d){let y=Ge(o[l]),f=Ge(e[l]);if(!xt(y,f))throw new F(`Cart state field "${l}" has type ${f}, live cart expects ${y}`);if(y==="object"){let u=e[l],g=t[l];H(u)&&!ve(u)&&Ae(g,u,void 0,void 0,!1)}}}function Qe(t,e){if(!H(t)||!H(e))return;let n=j(t);if(H(n))for(let r of Object.keys(e))r in n&&(t[r]=Q(e[r]))}function Ze(t){let e=typeof t=="string"?JSON.parse(t):t;if(!e||typeof e!="object")throw new F("Cart state bundle is not an object");if(e.version!==1)throw new F(`Unsupported cart state version ${String(e.version)}`);if(typeof e.seed!="string"||typeof e.framesElapsed!="number")throw new F("Cart state bundle is missing seed or framesElapsed");return e}var we="cyberart.asset.ready",Se="cyberart.asset.failed";function U(t){try{return JSON.parse(JSON.stringify(t))}catch{return t}}function et(t){return{type:t.status==="ready"?we:Se,kind:"state",payload:t.detail===void 0?{id:t.id}:{id:t.id,detail:t.detail}}}function Pt(t){if(!t||typeof t!="object")return 0;let e=t;return typeof e.startTime=="number"&&typeof e.lastSimulationUpdateAt=="number"?Math.max(0,e.lastSimulationUpdateAt-e.startTime):0}function Dt(t,e){if(typeof window.resizeTo!="function")return!1;try{if(window.top!==window)return!1}catch{return!1}let n=Math.max(1,Math.round(t)),r=Math.max(1,Math.round(e)),a=Math.max(0,window.outerWidth-window.innerWidth),s=Math.max(0,window.outerHeight-window.innerHeight);try{window.resizeTo(n+a,r+s)}catch{return!1}return Math.abs(window.innerWidth-n)<=8&&Math.abs(window.innerHeight-r)<=8}var Mt=[[0,0],[16,9],[9,16],[4,3],[3,4],[2,1],[1,2],[3,1],[1,3],[1,1]],ke=Mt[0],Ft=ke[0]/ke[1],Ce=30,Ht=120,Lt=3840/2160,It=2160/3840,oe=class{constructor(e=Ce,n=!1,r=window.innerWidth,a=window.innerHeight,s=!0,o,d={}){this.framesElapsed=0;this.frameRate=Ce;this._paused=!1;this.savedToken=!1;this.prepared=!1;this.loopRunning=!1;this.fallbackAudio=[];this.audioLibrariesInternal=[];this.virtualClock=null;this.scriptedActions=[];this.initialScriptedActions=[];this.appliedActions=[];this.consumedActionIndexes=new Set;this.outboundEvents=[];this.consecutiveErrorCount=0;this.lastErrorLogAt=0;this.reinitStayPaused=!1;this.reinitPending=!1;this.lastExportedFramebuffer=null;this.pinnedOutput=null;this.pinViewportAtImport=null;this.importing=!1;this.drawLoop=this.drawLoop.bind(this),this.loadCart=this.loadCart.bind(this),this.prepareCart=this.prepareCart.bind(this),this.beginPlayback=this.beginPlayback.bind(this),this.reinit=this.reinit.bind(this),this.tuneFramerate=this.tuneFramerate.bind(this),this.container=d.container,this.seed=d.seed,this.captureKeyboard=d.captureKeyboard??!0,this.customState=d.customState,this.hostChannel=d.hostChannel,this.fallbackAudio=ge(d.audio),this.audioLibrariesInternal=this.fallbackAudio;let l=d.deterministic;this.deterministic=!!l;let y=l&&typeof l=="object"?l:{};if(this.deterministic){if(d.clock){let f=d.clock;if(typeof f.advance!="function")throw new Error("deterministic mode requires a virtual clock with advance()");this.virtualClock=f,this.clock=f}else this.virtualClock=Le(y.origin??0),this.clock=this.virtualClock;this.initialScriptedActions=U(y.actions??[]),this.scriptedActions=U(this.initialScriptedActions)}else this.clock=d.clock??te();this.isBodyCanvas=this.container?!1:s,this.autoMode=n,this.aspectRatio=Ft,this.selectedAsp=ke,this.isFullscreen=!!document.fullscreenElement,this.updateFrameRate(e),this.tempUnpause=!1,this.synchronous=$,this.containerWidth=r,this.containerHeight=a,this.gameManager=o,this.init(!0)}setGameManager(e){this.gameManager=e}reinit(e){if(!this.importing){if(this.shouldKeepPinnedOutput()){this.fitPinnedCanvas();return}this.reinitPending||(this.reinitStayPaused=this._paused,this.reinitPending=!0),this.paused=!0,clearTimeout(this.reinitTimeout),this.reinitTimeout=setTimeout(()=>{if(this.importing){this.paused=this.reinitStayPaused,this.reinitPending=!1;return}this.updateInProgress?this.reinit(e):(this.requestedAnimationFrame&&cancelAnimationFrame(this.requestedAnimationFrame),this.clearPinnedOutput(),this.init(),this.reloadCart(),this.paused=this.reinitStayPaused,this.reinitPending=!1)},150)}}initSeed(){this.tokenData=this.seed?pe({hash:this.seed,useCache:!1}):pe(),this.rawParams=Be(this.tokenData),this.mintNo=parseInt(this.tokenData.tokenId)%1e6,console.log("token",this.mintNo,this.tokenData.hash)}init(e=!1){e&&this.initSeed(),this.pureAspectUpdate(this.selectedAsp);let n=this.aspectRatio,[r,a]=Me(n,this.containerWidth,this.containerHeight);r*=M,a*=M,this.width=~~r,this.height=~~a,this.atCenterX=this.width/2,this.atCenterY=this.height/2,this.mainCanvas?this.mainCanvas.setSize(this.width,this.height):this.mainCanvas=new re(this.width,this.height,1,this.isBodyCanvas,this.canvasMountOptions())}loadCart(e){this.prepareCart(e)&&this.beginPlayback()}prepareCart(e){if(this.prepared)return!0;try{let n=~~(this.width/1),r=~~(this.height/this.width*n),a=new ie(this.tokenData),s=new ne(n,r,a,this.rawParams,e,{gameManager:this.gameManager,canvasMount:this.canvasMountOptions(),customState:this.customState,captureKeyboard:this.deterministic?!1:this.captureKeyboard,hostChannel:this.hostChannel,clock:this.clock,listenToPointer:!this.deterministic});return this.animation=s,this.animationCart=e,this.paused=!1,this.framesElapsed=0,this.outboundEvents=[],this.scriptedActions=U(this.initialScriptedActions),this.appliedActions=[],this.consumedActionIndexes=new Set,this.outboundUnsubscribe?.(),this.outboundUnsubscribe=void 0,this.deterministic&&this.hostChannel&&(this.outboundUnsubscribe=this.hostChannel.onEvent(o=>{this.outboundEvents.push(o)})),this.R=a,this.applyCartFrameRate(e,s),this.resolveAudioLibraries(e),this.prepared=!0,!0}catch(n){return console.error(n),!1}}applyCartFrameRate(e,n){let r=e.metadata,a=r?.frameRate??Ce,s=n.cartState?.visualMode??n.featureState?.visualMode,o=s&&r?.frameRateByVisualMode?r.frameRateByVisualMode[s]:void 0;this.updateFrameRate(typeof o=="number"&&o>0?o:a)}get audioLibraries(){return this.audioLibrariesInternal}get needsAudio(){return this.audioLibrariesInternal.length>0}resolveAudioLibraries(e){this.audioLibrariesInternal=ge(e.metadata?.audio)}async unlockAudio(){if(this.audioLibrariesInternal.length===0)return;let e=ye(this.audioLibrariesInternal);if($){for(let n of e)await n.load();return}for(let n of e)await n.unlock()}async resumeAudioLibraries(){if(!(this.paused||$))for(let e of ye(this.audioLibrariesInternal))try{await e.resumeIfSuspended()}catch(n){console.error(`Failed to resume audio library "${e.id}" after reload`,n)}}beginPlayback(){!this.prepared||this.loopRunning||(this.prepared=!1,this.loopRunning=!0,this.consecutiveErrorCount=0,!this.deterministic&&(this.requestedAnimationFrame=requestAnimationFrame(this.drawLoop)))}get isPrepared(){return this.prepared}get isLoopRunning(){return this.loopRunning}get isDeterministic(){return this.deterministic}getClock(){return{now:this.clock.now(),framesElapsed:this.framesElapsed,frameRate:this.frameRate}}getRandomState(){return this.requirePreparedAnimation().getRandomState()}schedule(e){this.scriptedActions.push(U(e))}async getReplayMetadata(){let e=await this.exportState();return{seed:this.tokenData.hash,clock:this.getClock(),rng:this.getRandomState(),actions:U(this.scriptedActions),applied:U(this.appliedActions),events:U(this.outboundEvents),state:e.state}}async step(e=1){if(!this.deterministic)throw new Error("step() requires createRuntime({ deterministic: true })");this.requirePreparedAnimation(),this.prepared&&!this.loopRunning&&this.beginPlayback(),this.paused=!1;let n=Math.max(0,Math.floor(e));for(let r=0;r<n&&this.animation;r++){let a=this.framesElapsed;if(this.applyScheduledActions(a),await this.processFrame(this.clock.now(),{ignorePause:!0,scheduleNext:!1}),this.framesElapsed===a||(this.virtualClock?.advance(this.targetDrawTime),!this.loopRunning))break}}async advance(e){let n=Math.max(0,Math.round(e/this.targetDrawTime));await this.step(n)}applyScheduledActions(e){let n=this.animation;n&&this.scriptedActions.forEach((r,a)=>{r.atFrame===e&&(this.consumedActionIndexes.has(a)||(this.consumedActionIndexes.add(a),r.type==="pointer"?n.injectPointer(r.pointer.kind,r.pointer.x,r.pointer.y):r.type==="key"?n.injectKey(r.key):r.type==="event"?this.hostChannel?.dispatch(r.event):r.type==="asset"&&this.hostChannel?.dispatch(et(r)),this.appliedActions.push({frame:e,action:r})))})}get paused(){return this._paused}set paused(e){this._paused!==e&&(this._paused=e,this.animation?.setPaused(e))}async waitUntilUpdateIdle(){for(;this.updateInProgress;)await new Promise(e=>{this.deterministic?queueMicrotask(e):typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>e()):setTimeout(e,0)})}requirePreparedAnimation(){if(!this.animation)throw new Error("No prepared cart");return this.animation}async exportState(){let e=this.requirePreparedAnimation(),n=this._paused;this.paused=!0,await this.waitUntilUpdateIdle();try{this.lastExportedFramebuffer=e.captureFramebuffer();let r=e.getCanvas();return{version:1,cartId:this.animationCart?.metadata?.id,generative:this.animationCart?.metadata?.generative,seed:this.tokenData.hash,framesElapsed:this.framesElapsed,elapsedSinceStart:e.getElapsedSinceStart(),dimensions:{width:r.width,height:r.height,cssWidth:this.containerWidth,cssHeight:this.containerHeight,dpr:M},state:j(e.cartState)}}finally{this.paused=n}}async exportStateJSON(){return JSON.stringify(await this.exportState())}peekExportedFramebuffer(){return this.lastExportedFramebuffer}peekSeed(){return this.tokenData?.hash}isGenerative(){return this.animationCart?.metadata?.generative===!0}async importState(e,n){let r=this.requirePreparedAnimation(),a=Ze(e),s=this._paused,o=this.loopRunning;this.paused=!0,await this.waitUntilUpdateIdle(),Ae(r.cartState,a.state,this.animationCart?.metadata?.id,a.cartId),Je(this.tokenData.hash,a.seed,this.animationCart?.metadata?.generative,a.generative),clearTimeout(this.reinitTimeout),this.reinitPending=!1,this.importing=!0;let d=Xe(a,n?.framebuffer??this.lastExportedFramebuffer);if(d){this.pinOutputSize(d);let f=d.cssWidth??d.width/M,u=d.cssHeight??d.height/M;Dt(f,u),this.syncContainerFromDom(),this.pinViewportAtImport={w:this.containerWidth,h:this.containerHeight}}let l=this.customState,y=!1;try{if(this.customState=Q(a.state),this.unloadCart(),!this.prepareCart(this.animationCart))throw new Error("Failed to prepare cart while loading state");this.animation.cartState!==this.customState&&Qe(this.animation.cartState,a.state),this.framesElapsed=a.framesElapsed;let f=this.animation,u=f.cartState,g=typeof a.elapsedSinceStart=="number"?a.elapsedSinceStart:Pt(u);f.restoreClock(g,typeof u?.startTime=="number"?u.startTime:void 0),s&&f.setPaused(!0);let C=n?.framebuffer??this.lastExportedFramebuffer;C&&f.restoreFramebuffer(C)?u.keepRatioPrimed=!0:await f.renderAnimation(this.framesElapsed,this.rawParams),this.fitPinnedCanvas(),y=!0}catch(f){throw this.clearPinnedOutput(),this.customState=l,this.paused=s,this.animationCart&&(this.syncContainerFromDom(),this.init(),this.reloadCart()),f}finally{this.importing=!1,y&&(this.customState=l,this.paused=s,o&&this.beginPlayback())}}unloadCart(){this.loopRunning=!1,this.requestedAnimationFrame&&cancelAnimationFrame(this.requestedAnimationFrame),this.drawLoopTimeout&&clearTimeout(this.drawLoopTimeout),this.animation?.teardown(),this.animation=void 0,this.prepared=!1,this.audioLibrariesInternal=this.fallbackAudio,this.mainCanvas?.clearAll()}reloadCart(e=!1){let n=this.animationCart;if(!n)return;this.pinnedOutput&&(this.clearPinnedOutput(),this.syncContainerFromDom(),this.init());let r=this.reinitPending?this.reinitStayPaused:this._paused;this.unloadCart(),e&&this.initSeed(),this.loadCart(n),this.paused=r,!this.paused&&!$&&this.resumeAudioLibraries()}getFrameRate(){return this.frameRate}updateFrameRate(e){if(this.frameRate=e,e>=1)this.targetDrawTime=1e3/e;else{let r=1/(2-e);this.targetDrawTime=1e3/r}this.drawTime=this.targetDrawTime}canvasMountOptions(){return{container:this.container,adoptFromDocument:!this.container}}syncContainerFromDom(){if(this.container){this.containerWidth=this.container.clientWidth||this.containerWidth,this.containerHeight=this.container.clientHeight||this.containerHeight;return}this.containerWidth=window.innerWidth,this.containerHeight=window.innerHeight}pinOutputSize(e){this.pinnedOutput=e,this.width=~~e.width,this.height=~~e.height,this.atCenterX=this.width/2,this.atCenterY=this.height/2,this.aspectRatio=this.width/this.height,this.mainCanvas&&this.mainCanvas.setSize(this.width,this.height)}shouldKeepPinnedOutput(){return this.pinnedOutput?(this.syncContainerFromDom(),this.viewportMatches(this.pinnedCssSize())?!0:!!(this.pinViewportAtImport&&this.viewportMatches(this.pinViewportAtImport))):!1}pinnedCssSize(){let e=this.pinnedOutput;return{w:e.cssWidth??e.width/M,h:e.cssHeight??e.height/M}}viewportMatches(e){return Math.abs(this.containerWidth-e.w)<8&&Math.abs(this.containerHeight-e.h)<8}fitPinnedCanvas(){let e=this.pinnedOutput,n=this.canvas;if(!e||!n)return;this.container&&!this.container.style.position&&(this.container.style.position="relative");let r=this.containerWidth||window.innerWidth,a=this.containerHeight||window.innerHeight,s=e.width/M,o=e.height/M;if(s<1||o<1||r<1||a<1)return;let d=Math.min(r/s,a/o),l=s*d,y=o*d;n.style.position="absolute",n.style.left="50%",n.style.top="50%",n.style.transform="translate(-50%, -50%)",n.style.margin="0",n.style.width=`${l}px`,n.style.height=`${y}px`,n.style.imageRendering=Math.abs(d-1)<.01?"auto":"pixelated"}clearPinnedOutput(){let e=this.canvas;this.pinnedOutput=null,this.pinViewportAtImport=null,e&&(e.style.position="",e.style.left="",e.style.top="",e.style.transform="",e.style.imageRendering="",e.style.width="",e.style.height="",e.style.margin="auto")}get canvas(){return this.animation?.getCanvas()??this.mainCanvas?.canvas}destroy(){this.outboundUnsubscribe?.(),this.outboundUnsubscribe=void 0,this.clearPinnedOutput(),this.unloadCart(),clearTimeout(this.reinitTimeout),this.mainCanvas&&!this.mainCanvas.adopted&&this.mainCanvas.canvas.remove()}drawIt(){}tuneFramerate(e){let n=this.lastCall||e;this.lastCall=e,this.drawTime=Math.max(0,this.drawTime+this.targetDrawTime-this.lastCall+n)}async processFrame(e,n={}){let r=n.ignorePause===!0,a=n.scheduleNext!==!1;if(!this.loopRunning&&!r)return;let s=!1,o,d="update";try{if(r||!this.paused||this.tempUnpause){if(!$&&!r&&this.tuneFramerate(e),!this.animation)return;if(d="update",this.updateInProgress=!0,await this.animation.updateAnimationState(this.framesElapsed,this.rawParams,e),this.updateInProgress=!1,d="render",await this.animation.renderAnimation(this.framesElapsed,this.rawParams,e),this.autoMode&&this.animation.cartState.saveToken&&!this.savedToken&&!new URLSearchParams(window.location.search).get("hash")){let f=localStorage.getItem("goodones"),u=JSON.stringify(f?[...JSON.parse(f),this.tokenData.hash]:[this.tokenData.hash]);localStorage.setItem("goodones",u),this.savedToken=!0,localStorage.setItem(this.tokenData.hash,this.mainCanvas.canvas.toDataURL("image/png")),window.location.reload(),this.loopRunning=!1;return}this.framesElapsed++,this.tempUnpause&&(this.tempUnpause=!1)}d="draw",this.drawIt()}catch(l){s=!0,o=l,this.handleFrameError(l,d)}finally{this.updateInProgress=!1}s?(this.consecutiveErrorCount++,this.consecutiveErrorCount>=Ht&&(this.loopRunning=!1,this.onError?.(o,{phase:d,consecutive:this.consecutiveErrorCount,stopped:!0}))):this.consecutiveErrorCount=0,!(!this.loopRunning||!a)&&(this.drawLoopTimeout=setTimeout(()=>{this.requestedAnimationFrame=requestAnimationFrame(this.drawLoop)},this.drawTime))}async drawLoop(e){await this.processFrame(e,{scheduleNext:!0})}handleFrameError(e,n){let r=performance.now();r-this.lastErrorLogAt>=1e3&&(this.lastErrorLogAt=r,console.error(`Animation ${n} error:`,e)),this.consecutiveErrorCount===0&&this.onError?.(e,{phase:n,consecutive:1,stopped:!1})}pureAspectUpdate(e){if(e[0]===0&&e[1]===0){let r=this.containerWidth||window.innerWidth,a=this.containerHeight||window.innerHeight,s=r/a;this.aspectRatio=Math.min(Lt,Math.max(It,s))}else this.aspectRatio=e[0]/e[1]}};var Ot="HostChannel has been destroyed",de=class{constructor(){this.inbound=[];this.listeners=[];this.closed=!1}dispatch(e){this.requireOpen(),this.inbound.push(e),this.inbound.length>32&&this.inbound.splice(0,this.inbound.length-32)}consume(){if(this.requireOpen(),this.inbound.length===0)return[];let e=this.inbound;return this.inbound=[],e}emit(e){this.requireOpen();for(let n of this.listeners)n(e)}onEvent(e){return this.requireOpen(),this.listeners.push(e),()=>{this.listeners=this.listeners.filter(n=>n!==e)}}clearInbound(){this.requireOpen(),this.inbound=[]}clear(){this.inbound=[],this.listeners=[]}close(){this.closed=!0,this.clear()}requireOpen(){if(this.closed)throw new Error(Ot)}};var _t=["image","audio","font","spritesheet"],Ut=["timeout","cors","not-found","invalid","aborted","resolver"],Z="cyberart:fallback/silent",tt="Asset preloader has been destroyed",Nt=4,Wt=new Set(_t),$t=new Set(Ut),Bt={timeout:"asset load timed out",cors:"CORS blocked this asset","not-found":"asset was not found",invalid:"asset declaration or resource is invalid",aborted:"asset load was aborted",resolver:"asset resolver failed"};function Kt(t){return typeof t=="string"&&Wt.has(t)}function jt(t){return typeof t=="string"&&$t.has(t)}function Ee(t){if(!t||typeof t!="object")return!1;let e=t;return typeof e.id=="string"&&typeof e.ref=="string"&&jt(e.code)&&typeof e.message=="string"}function x(t){return{id:t.id,ref:t.ref,code:t.code,message:t.message&&t.message.length>0?t.message:Bt[t.code]}}function V(t,e){return{type:t==="ready"?we:Se,kind:"state",payload:e}}function Vt(t){return t instanceof Error&&t.name==="AbortError"||typeof DOMException<"u"&&t instanceof DOMException&&t.name==="AbortError"}function Re(t){return t?{...t}:void 0}function L(t){let e={id:t.id,ref:t.ref,type:t.type,url:t.url};return t.integrity!==void 0&&(e.integrity=t.integrity),t.provenance&&(e.provenance=Re(t.provenance)),t.cors!==void 0&&(e.cors=t.cors),t.usedFallback&&(e.usedFallback=!0),t.managed&&(e.managed=!0),e}function ee(t){return{id:t.id,ref:t.ref,code:t.code,message:t.message}}function zt(t){if(t.state==="ready"){let e={state:"ready",resource:L(t.resource)};return t.failure&&(e.failure=ee(t.failure)),e}return t.state==="failed"?{state:"failed",failure:ee(t.failure)}:{state:t.state}}function Gt(t){if(!t||typeof t!="object")return x({id:"",ref:"",code:"invalid",message:"declaration is required"});if(typeof t.id!="string"||t.id.length===0)return x({id:typeof t.id=="string"?t.id:"",ref:typeof t.ref=="string"?t.ref:"",code:"invalid",message:"id is required"});if(typeof t.ref!="string"||t.ref.length===0)return x({id:t.id,ref:"",code:"invalid",message:"ref is required"});if(!Kt(t.type))return x({id:t.id,ref:t.ref,code:"invalid",message:`unsupported type ${String(t.type)}`});if(t.integrity!==void 0&&typeof t.integrity!="string")return x({id:t.id,ref:t.ref,code:"invalid",message:"integrity must be a string"});if(t.timeoutMs!==void 0&&(typeof t.timeoutMs!="number"||!Number.isFinite(t.timeoutMs)||t.timeoutMs<0))return x({id:t.id,ref:t.ref,code:"invalid",message:"timeoutMs must be a non-negative finite number"})}function nt(t){return{id:t.id,ref:Z,type:t.type,url:Z,usedFallback:!0,cors:"omit"}}function rt(t,e){return Ee(e)?{id:t.id,ref:t.ref,code:e.code,message:e.message}:Vt(e)?x({id:t.id,ref:t.ref,code:"aborted"}):x({id:t.id,ref:t.ref,code:"resolver",message:e instanceof Error?e.message:String(e)})}function it(t,e){if(!e||typeof e.url!="string"||e.url.length===0)throw x({id:t.id,ref:t.ref,code:"invalid",message:"resolver returned no url"});if(e.integrity&&t.integrity&&e.integrity!==t.integrity)throw x({id:t.id,ref:t.ref,code:"invalid",message:"integrity mismatch"});let n=L(e);return n.id=t.id,n.ref=e.ref||t.ref,n.type=t.type,!n.integrity&&t.integrity&&(n.integrity=t.integrity),!n.provenance&&t.provenance&&(n.provenance=Re(t.provenance)),n}function at(t){if(typeof t?.resolver?.resolve!="function")throw new Error("createAssetPreloader: resolver is required");let e=t.emitEvents!==!1,n=t.wallClockTimeout!==!1,r=new Map,a=[],s=new Map,o=new Map,d=new Map,l=new Map,y=new Map,f=new Set,u=!1;function g(i){return i.code==="aborted"||i.code==="timeout"}function C(i,h,p){let v=rt(i,p);return v.code==="timeout"?v:h.aborted?x({id:i.id,ref:i.ref,code:"aborted"}):v}function m(i,h){let p=y.get(i);p||(p=new Set,y.set(i,p)),p.add(h)}function k(i){if(i?.state==="ready")return`${i.resource.type}\0${i.resource.ref}`}function c(i,h){for(let[p,v]of y)if(p!==h&&v.has(i))return!0;for(let[p,v]of r)if(p!==h&&k(v)===i)return!0;return!1}function z(i,h){let p=new Set(y.get(i)),v=k(h);v&&p.add(v),y.delete(i);for(let D of p)c(D,i)||d.delete(D)}function I(){let i=0,h=0,p=0,v=0,D={};for(let[S,w]of r)D[S]=zt(w),w.state==="pending"||w.state==="loading"?i+=1:w.state==="failed"?p+=1:(h+=1,(w.resource.usedFallback||w.failure)&&(v+=1));return{total:r.size,pending:i,ready:h,failed:p,fallbacks:v,items:D,failures:a.map(ee)}}function G(){if(f.size===0)return;let i=I();for(let h of f)h(i)}function R(i){a.push(ee(i))}function P(i){u||!e||!t.dispatch||t.dispatch(i)}function N(i){if(i?.managed&&i.url.startsWith("blob:")&&!(typeof URL>"u"||typeof URL.revokeObjectURL!="function"))try{URL.revokeObjectURL(i.url)}catch{}}function A(i,h){if(u)return;let p=r.get(i);p?.state==="ready"&&N(p.resource),r.set(i,h),G()}function q(i){if(i.fallback!==void 0)return i.fallback==="silent"?{id:`${i.id}::fallback`,ref:Z,type:i.type}:typeof i.fallback=="string"?{id:`${i.id}::fallback`,ref:i.fallback,type:i.type}:{...i.fallback,id:typeof i.fallback.id=="string"&&i.fallback.id.length>0?i.fallback.id:`${i.id}::fallback`}}function T(i,h,p){let v=`${i.type}\0${i.ref}`,D=d.get(v);if(D)return h.aborted?Promise.reject(x({id:i.id,ref:i.ref,code:"aborted"})):(m(p,v),Promise.resolve(L(D.resource)));if(h.aborted)return Promise.reject(x({id:i.id,ref:i.ref,code:"aborted"}));let S=l.get(v);if(!S){let b=new AbortController,E={id:i.id,ref:i.ref,type:i.type};i.integrity!==void 0&&(E.integrity=i.integrity),i.provenance&&(E.provenance=Re(i.provenance)),S={promise:Promise.resolve().then(()=>t.resolver.resolve(E,b.signal)).then(W=>{let _=it(i,W);if(b.signal.aborted)throw x({id:i.id,ref:i.ref,code:"aborted"});return d.set(v,{resource:L(_)}),_}).catch(W=>{throw rt(i,W)}).finally(()=>{l.delete(v)}),controller:b,waiters:0},l.set(v,S)}let w=S;return w.waiters+=1,new Promise((b,E)=>{let O=!1,W=(Y,pt)=>{O||(O=!0,h.removeEventListener("abort",_),w.waiters-=1,pt&&w.waiters<=0&&w.controller.abort(),Y())},_=()=>{W(()=>E(x({id:i.id,ref:i.ref,code:"aborted"})),!0)};if(h.aborted){_();return}h.addEventListener("abort",_,{once:!0}),w.promise.then(Y=>{if(!O){if(h.aborted){_();return}m(p,v),W(()=>b(L(Y)),!1)}},Y=>{if(!O){if(h.aborted){_();return}W(()=>E(Y),!1)}})})}function ue(i,h,p){if(h.aborted)return Promise.reject(x({id:i.id,ref:i.ref,code:"aborted"}));if(i.ref===Z)return Promise.resolve(nt(i));let v=new AbortController,D=()=>v.abort();h.addEventListener("abort",D,{once:!0});let S=i.timeoutMs??t.timeoutMs,w,b=!1;return n&&S!==void 0&&S>0&&Number.isFinite(S)&&(w=setTimeout(()=>{b=!0,v.abort()},S)),T(i,v.signal,p).then(E=>{let O=it(i,E);return O.id=i.id,O}).catch(E=>{throw b?x({id:i.id,ref:i.ref,code:"timeout"}):E}).finally(()=>{w!==void 0&&clearTimeout(w),h.removeEventListener("abort",D)})}async function xe(i,h,p,v){try{return{resource:await ue(i,h,v)}}catch(D){let S=C(i,h,D);if(g(S)||h.aborted||p>=Nt)throw S;let w=q(i);if(!w)throw S;if(h.aborted)throw x({id:i.id,ref:i.ref,code:"aborted"});if(i.fallback==="silent"||w.ref===Z)return{resource:nt(i),failure:S};try{let b=await xe(w,h,p+1,v);return{resource:{...L(b.resource),id:i.id,usedFallback:!0},failure:S}}catch(b){let E=Ee(b)&&!g(b)&&!h.aborted?b:C(i,h,b);throw!g(E)&&!h.aborted&&R(S),E}}}async function ht(i,h){if(u)throw new Error(tt);let p=r.get(i.id);if(p?.state==="ready"||p?.state==="failed")return;let v=s.get(i.id);if(v){await v;return}let D=(async()=>{let S=Gt(i);if(S){A(i.id,{state:"failed",failure:S}),R(S),P(V("failed",{id:i.id,ref:i.ref,failure:S}));return}A(i.id,{state:"loading"});let w=o.get(i.id)??new AbortController;o.has(i.id)||o.set(i.id,w);try{let b=await xe(i,w.signal,h,i.id);if(u)return;if(w.signal.aborted){let E=x({id:i.id,ref:i.ref,code:"aborted"});A(i.id,{state:"failed",failure:E}),R(E),P(V("failed",{id:i.id,ref:i.ref,failure:E}));return}if(b.resource.id=i.id,b.failure){A(i.id,{state:"ready",resource:b.resource,failure:b.failure}),R(b.failure),P(V("failed",{id:i.id,ref:i.ref,failure:b.failure,resource:L(b.resource)})),P(V("ready",{id:i.id,ref:b.resource.ref,resource:L(b.resource),failure:b.failure}));return}A(i.id,{state:"ready",resource:b.resource}),P(V("ready",{id:i.id,ref:i.ref,resource:L(b.resource)}))}catch(b){if(u)return;let E=Ee(b)&&!g(b)&&!w.signal.aborted?{...ee(b),id:i.id}:C(i,w.signal,b);A(i.id,{state:"failed",failure:E}),R(E),P(V("failed",{id:i.id,ref:i.ref,failure:E}))}finally{o.get(i.id)===w&&o.delete(i.id)}})();s.set(i.id,D);try{await D}finally{s.delete(i.id)}}return{async preload(i){if(u)throw new Error(tt);let h=Array.isArray(i)?i:[];for(let p of h)p&&typeof p.id=="string"&&p.id.length>0&&(r.has(p.id)||r.set(p.id,{state:"pending"}),o.has(p.id)||o.set(p.id,new AbortController));return G(),await Promise.all(h.map(p=>ht(p,0))),I()},get(i){let h=r.get(i);if(h?.state==="ready")return L(h.resource)},getProgress(){return I()},onProgress(i){return f.add(i),()=>{f.delete(i)}},abort(i){if(!u){if(i!==void 0){o.get(i)?.abort();return}for(let h of o.values())h.abort()}},forget(i){if(u)return;if(i===void 0){for(let p of r.values())p.state==="ready"&&N(p.resource);r.clear(),a.length=0,d.clear(),y.clear(),G();return}let h=r.get(i);h?.state==="ready"&&N(h.resource),z(i,h),r.delete(i);for(let p=a.length-1;p>=0;p--)a[p].id===i&&a.splice(p,1);G()},dispose(){if(!u){u=!0;for(let i of o.values())i.abort();o.clear();for(let i of r.values())i.state==="ready"&&N(i.resource);r.clear(),a.length=0,s.clear();for(let i of l.values())i.controller.abort();d.clear(),l.clear(),y.clear(),f.clear()}}}}function st(t){Te();let{container:e,seed:n,captureKeyboard:r=!1,audio:a,deterministic:s,assets:o}=t,d=n===void 0?void 0:$e(n,s?"deterministic":"live"),l=new de;if(o&&typeof o.resolver?.resolve!="function")throw new Error("createRuntime: assets.resolver is required");let y=o?at({resolver:o.resolver,timeoutMs:o.timeoutMs,emitEvents:o.emitEvents??!s,wallClockTimeout:!s,dispatch:R=>l.dispatch(R)}):void 0,f=!1,u=null,g,C=!1,m=e.clientWidth||window.innerWidth,k=e.clientHeight||window.innerHeight,c=new oe(30,!1,m,k,!1,void 0,{container:e,seed:d,captureKeyboard:r,hostChannel:l,audio:a,deterministic:s}),z=()=>{let R=e.clientWidth||window.innerWidth,P=e.clientHeight||window.innerHeight;return R===c.containerWidth&&P===c.containerHeight?!1:(c.containerWidth=R,c.containerHeight=P,!0)},I=null;return!c.isDeterministic&&typeof ResizeObserver<"u"&&(I=new ResizeObserver(()=>{if(f||!u)return;z()&&C&&c.reinit()}),I.observe(e)),c.onError=(R,P)=>{g?.(R,P)},{get tokenData(){return c.tokenData},get hostChannel(){return l},get assets(){return y},get onError(){return g},set onError(R){g=R},mount(R,P={}){if(f)throw new Error("createRuntime: cannot mount on a destroyed runtime");u?.destroy(),C=!1,c.customState=P.initialState,c.setGameManager(P.gameManager);let N=P.onEvent?l.onEvent(P.onEvent):()=>{};if(!c.prepareCart(R))throw N(),new Error("createRuntime: failed to prepare cart");let A=!1,q={async start(){if(!A){if(z()&&c.isPrepared&&(c.init(),c.unloadCart(),!c.prepareCart(R)))throw new Error("createRuntime: failed to prepare cart");c.needsAudio&&(await c.unlockAudio(),A)||(C=!0,c.beginPlayback())}},pause(){A||(c.paused=!0)},resume(){A||(c.paused=!1)},dispatch(T){A||l.dispatch(T)},snapshot(){if(A)return{seed:"",pngDataUrl:""};let T=c.canvas;return{seed:c.tokenData.hash,metadata:R.metadata,pngDataUrl:T?T.toDataURL("image/png"):""}},destroy(){A||(A=!0,C=!1,N(),l.clearInbound(),c.unloadCart(),u===q&&(u=null))},reload(){if(!A){if(!C){if(c.isPrepared&&(c.unloadCart(),!c.prepareCart(R)))throw new Error("createRuntime: failed to prepare cart");return}c.reloadCart()}},reinit(T){if(!A){if(!C){z();return}c.reinit(T)}},getCartState(){return c.animation?.cartState},exportState(){return A?Promise.reject(new Error("Cart handle has been destroyed")):c.exportState()},exportStateJSON(){return A?Promise.reject(new Error("Cart handle has been destroyed")):c.exportStateJSON()},async importState(T,ue){if(A)throw new Error("Cart handle has been destroyed");await c.importState(T,ue)},peekExportedFramebuffer(){return A?null:c.peekExportedFramebuffer()},peekSeed(){if(!A)return c.peekSeed()},isGenerative(){return A?!1:c.isGenerative()},async step(T=1){if(A)throw new Error("Cart handle has been destroyed");await c.step(T)},async advance(T){if(A)throw new Error("Cart handle has been destroyed");await c.advance(T)},schedule(T){A||c.schedule(T)},getClock(){if(A)throw new Error("Cart handle has been destroyed");return c.getClock()},getRandomState(){if(A)throw new Error("Cart handle has been destroyed");return c.getRandomState()},getReplayMetadata(){return A?Promise.reject(new Error("Cart handle has been destroyed")):c.getReplayMetadata()},get canvas(){return c.canvas},get paused(){return c.paused},set paused(T){A||(c.paused=T)},get tokenData(){return c.tokenData},get isPrepared(){return c.isPrepared},get isLoopRunning(){return c.isLoopRunning},get needsAudio(){return c.needsAudio},get audioLibraries(){return c.audioLibraries}};return u=q,q},async unlockAudio(){await c.unlockAudio()},destroy(){f||(f=!0,u?.destroy(),u=null,I?.disconnect(),I=null,y?.dispose(),l.close(),c.destroy())}}}var ot="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==",dt=320,ut=180,qt="Headless harness has been destroyed",ct=!1;function lt(){if(typeof globalThis.ImageData>"u"){class e{constructor(r,a){this.colorSpace="srgb";this.width=r,this.height=a,this.data=new Uint8ClampedArray(r*a*4)}}globalThis.ImageData=e}let t=HTMLCanvasElement.prototype;t.getContext=function(){return{globalAlpha:1,imageSmoothingEnabled:!1,fillStyle:"",save(){},restore(){},fillRect(){},putImageData(){},createImageData(r,a){return{data:new Uint8ClampedArray(r*a*4),width:r,height:a}}}},t.toDataURL=()=>ot,ct=!0}function Yt(t,e){let n=document.createElement("div");return Object.defineProperty(n,"clientWidth",{value:t,configurable:!0}),Object.defineProperty(n,"clientHeight",{value:e,configurable:!0}),document.body.appendChild(n),n}function Jt(t){let e=t.indexOf(","),n=e>=0?t.slice(e+1):t,r=globalThis.atob(n),a=new Uint8Array(r.length);for(let s=0;s<r.length;s++)a[s]=r.charCodeAt(s);return a}function Xt(){return typeof process<"u"&&!!process.versions?.node}async function Qt(t,e){if(!Xt())throw new Error("captureFrame(path) requires Node.js; omit the path to get the snapshot only");let n;try{({writeFile:n}=await import("node:fs/promises"))}catch(r){let a=r instanceof Error?r.message:String(r);throw new Error(`captureFrame(path) could not load node:fs/promises (${a}). Omit the path, or run under Node.`)}try{await n(t,Jt(e))}catch(r){let a=r instanceof Error?r.message:String(r);throw new Error(`captureFrame could not write ${t}: ${a}`)}}function Zt(t){ct||lt();let e=t.width??dt,n=t.height??ut,r=Yt(e,n),a=[],s=[],o=!1,d=t.onEvent,l=t.onError,y=st({container:r,seed:t.seed,deterministic:{origin:t.origin,actions:t.actions??[]}});y.onError=(m,k)=>{s.push({error:m,info:k}),l?.(m,k)},Object.defineProperty(y,"onError",{configurable:!0,enumerable:!0,get(){return l},set(m){l=m}});let f=m=>{a.push(m),d?.(m)},u=y.mount(t.cart,{initialState:t.initialState,gameManager:t.gameManager,onEvent:f}),g=()=>{if(o)throw new Error(qt)};return{runtime:y,container:r,get events(){return a.slice()},get errors(){return s.slice()},get cart(){return u},async step(m=1){g(),await u.step(m)},async advance(m){g(),await u.advance(m)},schedule(m){g(),u.schedule(m)},dispatch(m){g(),u.dispatch(m)},start(){return g(),u.start()},pause(){g(),u.pause()},resume(){g(),u.resume()},get paused(){return u.paused},key(m){g(),u.schedule({type:"key",atFrame:u.getClock().framesElapsed,key:m})},click(m,k){g(),u.schedule({type:"pointer",atFrame:u.getClock().framesElapsed,pointer:{kind:"down",x:m,y:k}})},async inspect(){g();let m=await u.getReplayMetadata();return{state:m.state,events:a.slice(),errors:s.slice(),replay:m,clock:u.getClock()}},async captureFrame(m){g();let k=u.snapshot();return m&&await Qt(m,k.pngDataUrl),k},remount(m={}){return g(),a.length=0,s.length=0,"onEvent"in m&&(d=m.onEvent),u=y.mount(t.cart,{initialState:m.initialState??t.initialState,gameManager:m.gameManager??t.gameManager,onEvent:f}),u},destroy(){if(!o){o=!0;try{u.destroy()}finally{try{y.destroy()}finally{r.remove()}}}}}}export{ut as DEFAULT_HEADLESS_HEIGHT,dt as DEFAULT_HEADLESS_WIDTH,ot as HEADLESS_PNG_DATA_URL,Zt as createHeadlessHarness,lt as installHeadlessCanvas};
8
+ var Kt=(e,t)=>()=>(e&&(t=e(e=0)),t);var Jt={};function qt(e,t){let n=e.indexOf(ct);if(n===-1)return null;let r=n+ct.length,o=`const __cyberSkip=new Set(${JSON.stringify(t)});const __cyberOrig=registerProcessor;registerProcessor=(n,p)=>__cyberSkip.has(n)?undefined:__cyberOrig(n,p);`;return e.slice(0,r)+o+e.slice(r)}var Ie,we,zt,le,ct,lt=Kt(()=>{"use strict";Ie=/AudioWorkletProcessor with name:\s*["'`][^"'`]+["'`]\s+is already registered/i,we="__cyberartWorkletPatchApplied";typeof window<"u"&&!window[we]&&(window.addEventListener("error",e=>{let t=e?.message??"";Ie.test(t)&&(e.preventDefault(),e.stopImmediatePropagation())},!0),window.addEventListener("unhandledrejection",e=>{let t=e?.reason,n=typeof t=="string"?t:t?.message??"";Ie.test(n)&&e.preventDefault()}),window[we]=!0);zt=!1,le=(...e)=>{zt&&console.log("[workletPatch]",...e)},ct="((AudioWorkletProcessor,registerProcessor)=>{";if(typeof AudioWorklet<"u"&&!AudioWorklet.prototype[we]){let e=new WeakMap,t=/registerProcessor\s*\(\s*['"`]([^'"`]+)['"`]/g,n=AudioWorklet.prototype.addModule,r=0;AudioWorklet.prototype.addModule=async function(o,u){let p=++r,m=e.get(this);m||(m=new Set,e.set(this,m)),le(`#${p} addModule`,{url:o.slice(0,64),isBlob:o.startsWith("blob:"),knownBefore:[...m]});let C=o,v=null;if(o.startsWith("blob:")){let l=null;try{l=await(await fetch(o)).text()}catch(w){le(`#${p} blob fetch failed`,w)}if(l!==null){let w=new Set;for(let E of l.matchAll(t))w.add(E[1]);if(w.size>0){let E=[...w].filter(M=>m.has(M)),b=[...w].filter(M=>!m.has(M));if(E.length>0&&b.length===0){le(`#${p} short-circuit \u2014 all processors already registered`,E);return}if(E.length>0&&b.length>0){let M=qt(l,E);if(M!==null){let h=new Blob([M],{type:"application/javascript"});v=URL.createObjectURL(h),C=v,le(`#${p} rewrote blob; skipping`,E,"allowing",b)}else le(`#${p} blob rewrite failed; passing original through`)}b.forEach(M=>m.add(M))}}}return n.call(this,C,u).then(()=>{v&&URL.revokeObjectURL(v)},l=>{v&&URL.revokeObjectURL(v);let w=(l&&l.message)??"";if(!(Ie.test(w)||/already registered/i.test(w)))throw l})},AudioWorklet.prototype[we]=!0}});var Je=()=>{let e=["ms","moz","webkit","o"];for(let t=0;t<e.length&&!window.requestAnimationFrame;++t)window.requestAnimationFrame=window[e[t]+"RequestAnimationFrame"],window.cancelAnimationFrame=window[e[t]+"CancelAnimationFrame"]||window[e[t]+"CancelRequestAnimationFrame"]},G=window.devicePixelRatio||1,re=/Headless/i.test(navigator.userAgent),jn=/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)||/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.platform);function Ye(){return Math.min(window.innerWidth,window.innerHeight)}var Te="data-cyberart-canvas",ie=class{constructor(t,n,r=1,a={}){this.width=t,this.height=n;let o=a.container,u=a.adoptFromDocument??!o,p=o?o.querySelector(`canvas[${Te}]`)??o.querySelector("canvas"):null;if(p)this.canvas=p,this.adopted=!0;else if(u){let m=document.getElementById("canvas")??document.querySelector("canvas");m?(this.canvas=m,this.adopted=!0):(this.canvas=document.createElement("canvas"),this.canvas.setAttribute("id","canvas"),this.adopted=!1)}else this.canvas=document.createElement("canvas"),this.adopted=!1;this.canvas.hasAttribute(Te)||this.canvas.setAttribute(Te,""),this.canvas.style.display="block",this.canvas.style.margin="auto",this.ctx=this.canvas.getContext("2d",{colorSpace:"display-p3",alpha:!1}),this.ctx.globalAlpha=r,this.ctx.imageSmoothingEnabled=!1,this.setSize(t,n)}setSize(t,n){this.width=t,this.height=n,this.canvas.width=t,this.canvas.height=n,this.canvas.style.width=`${t/G}px`,this.canvas.style.height=`${n/G}px`,this.imageData=this.ctx.createImageData(t,n),this.ctx.putImageData(this.imageData,0,0)}_blank(t=1){let n=t?Math.max(t,.03):1;this.ctx.fillStyle=`rgba(0,0,0,${n})`,this.ctx.fillRect(0,0,this.width,this.height)}clearAll(){this.ctx.save(),this.ctx.globalAlpha=1,this._blank(),this.ctx.restore()}};function Xe(e,t){let n=e/t,r,a;return n>1?(r=e,a=~~(e/n)):(a=t,r=~~(t*n)),{width:r,height:a,iWidth:1/r,iHeight:1/a,area:r*a,largeDim:Math.max(r,a),smallDim:Math.min(r,a),aspectRatio:n}}function Qe(e,t=window.innerWidth,n=window.innerHeight){let r=Ye(),a,o;return n<t?e>1?t>=r*e?(a=r*e,o=r):(a=t,o=a/e):(a=r*e,o=r):e>1?(a=r,o=r/e):n<r/e?(o=n,a=o*e):(a=r,o=r/e),[a,o]}var Pe=class{constructor(t=!1,n=!0){this.debugMode=t,this.actionMap={},this.listening=n,this.checkKeypress=this.checkKeypress.bind(this),this.registerAction=this.registerAction.bind(this),this.listening&&window.addEventListener("keydown",this.checkKeypress,!1)}checkKeypress({key:t}){this.debugMode&&console.log(`Pressed ${t}`),t in this.actionMap&&this.actionMap[t]()}inject(t){this.checkKeypress({key:t})}registerAction(t,n,r=!1){if(t.length!==1)throw new Error(`Only single-character actions may be registered. Cannot register: ${t}`);if(t in this.actionMap&&!r)throw new Error(`Action already exists for code: ${t}`);this.actionMap[t]=n}destroy(){this.listening&&window.removeEventListener("keydown",this.checkKeypress,!1),this.actionMap={}}},Ze=Pe;var Me=class{constructor(t,n={}){this.x=-1;this.y=-1;this.isDown=!1;this.clicks=[];this.canvas=t,this.listening=n.listen!==!1,this.onPointerDown=this.onPointerDown.bind(this),this.onPointerMove=this.onPointerMove.bind(this),this.onPointerUp=this.onPointerUp.bind(this),this.listening&&(t.addEventListener("pointerdown",this.onPointerDown),t.addEventListener("pointermove",this.onPointerMove),t.addEventListener("pointerup",this.onPointerUp))}toCanvasCoords(t){let n=this.canvas.getBoundingClientRect();return{x:(t.clientX-n.left)*(this.canvas.width/n.width),y:(t.clientY-n.top)*(this.canvas.height/n.height)}}onPointerDown(t){let{x:n,y:r}=this.toCanvasCoords(t);this.x=n,this.y=r,this.isDown=!0,this.clicks.push({x:n,y:r})}onPointerMove(t){let{x:n,y:r}=this.toCanvasCoords(t);this.x=n,this.y=r}onPointerUp(t){let{x:n,y:r}=this.toCanvasCoords(t);this.x=n,this.y=r,this.isDown=!1}hasClick(){return this.clicks.length>0}consumeClick(){return this.clicks.shift()??null}inject(t,n,r){this.x=n,this.y=r,t==="down"?(this.isDown=!0,this.clicks.push({x:n,y:r})):t==="up"&&(this.isDown=!1)}destroy(){this.listening&&(this.canvas.removeEventListener("pointerdown",this.onPointerDown),this.canvas.removeEventListener("pointermove",this.onPointerMove),this.canvas.removeEventListener("pointerup",this.onPointerUp))}},et=Me;function ge(){return{now:()=>performance.now()}}function tt(e=0){let t=e;return{now:()=>t,set(n){t=n},advance(n){t+=n}}}var nt=(e,t,n,r)=>({now:e,startTime:t,elapsedSinceStart:e-t,deltaSinceLastUpdate:n===null?0:e-n,deltaSinceLastRender:r===null?0:e-r}),ye=class{constructor(t,n,r,a,o,u={}){this.startTime=0;this.lastUpdateAt=null;this.lastRenderAt=null;this.clockOffsetMs=0;this.pauseStartedAt=null;this.renderAnimation=this.renderAnimation.bind(this),this.dimensionContext=Xe(t,n),this.R=r,this.gameManager=u.gameManager,this.hostChannel=u.hostChannel,this.clock=u.clock??ge(),this.canvas=new ie(this.dimensionContext.width,this.dimensionContext.height,1,u.canvasMount),this.drawingContext=this.canvas.ctx,this.keyboardManager=new Ze(!1,u.captureKeyboard??!0),this.pointerManager=new et(this.canvas.canvas,{listen:u.listenToPointer!==!1}),this.animationCart=o;let p=u.customState;this.featureState=o.getDefaultFeatureState?.(this.R,this.dimensionContext,a,this.keyboardManager,p,this.pointerManager,this.gameManager,this.hostChannel),this.cartState=o.getDefaultState(this.R,this.dimensionContext,a,this.keyboardManager,p,this.pointerManager,this.gameManager,this.featureState,this.hostChannel),this.startTime=this.clock.now(),this.canvas.clearAll()}captureFramebuffer(){let t=this.canvas.imageData,n=new ImageData(t.width,t.height);return n.data.set(t.data),n}restoreFramebuffer(t){let n=this.canvas.imageData;return n.width!==t.width||n.height!==t.height||n.data.length!==t.data.length?!1:(n.data.set(t.data),this.drawingContext.putImageData(n,0,0),!0)}setPaused(t){let n=this.clock.now();if(t){this.pauseStartedAt===null&&(this.pauseStartedAt=n);return}this.pauseStartedAt!==null&&(this.clockOffsetMs+=n-this.pauseStartedAt,this.pauseStartedAt=null)}resolveNow(t){let n=this.pauseStartedAt!==null?t-this.pauseStartedAt:0;return t-this.clockOffsetMs-n}getElapsedSinceStart(t=this.clock.now()){return Math.max(0,this.resolveNow(t)-this.startTime)}restoreClock(t,n){this.pauseStartedAt=null,this.lastUpdateAt=null,this.lastRenderAt=null;let r=Math.max(0,t);if(typeof n=="number"&&Number.isFinite(n)){this.startTime=n,this.clockOffsetMs=this.clock.now()-n-r;return}this.clockOffsetMs=0,this.startTime=this.clock.now()-r}getRandomState(){return this.R.getState()}injectKey(t){this.keyboardManager.inject(t)}injectPointer(t,n,r){this.pointerManager.inject(t,n,r)}async updateAnimationState(t,n,r=this.clock.now()){let a=this.resolveNow(r),o=nt(a,this.startTime,this.lastUpdateAt,this.lastRenderAt);this.cartState=this.animationCart.update(this.R,t,n,this.dimensionContext,this.cartState,this.keyboardManager,this.pointerManager,this.gameManager,o,this.featureState,this.hostChannel),this.lastUpdateAt=a}async renderAnimation(t,n,r=this.clock.now()){let a=this.resolveNow(r),o=nt(a,this.startTime,this.lastUpdateAt,this.lastRenderAt);this.animationCart.render(this.R,t,n,this.dimensionContext,this.cartState,this.drawingContext,this.canvas.imageData,this.pointerManager,this.gameManager,o,this.featureState,this.hostChannel),this.lastRenderAt=a}getCanvas(){return this.canvas.canvas}getDrawDetails(){return[this.canvas.canvas,0,0,this.dimensionContext.width,this.dimensionContext.height]}teardown(){try{this.animationCart.teardown?.(this.cartState,this.featureState)}catch(t){console.error("Error during cart teardown",t)}this.keyboardManager.destroy(),this.pointerManager.destroy()}};var be=class extends ie{constructor(t,n,r=1,a=!0,o={}){if(super(t,n,r,o),this.adopted)return;let u=o.container;if(u){this.canvas.parentNode!==u&&u.appendChild(this.canvas);return}if(a){let p=document.getElementById("canvas");p&&p!==this.canvas&&p.parentNode===document.body&&document.body.removeChild(p),document.body.appendChild(this.canvas)}}};function rt(e){let t=parseInt(e.substring(0,8),16),n=parseInt(e.substring(8,8),16),r=parseInt(e.substring(16,8),16),a=parseInt(e.substring(24,8),16);return{next:()=>{t|=0,n|=0,r|=0,a|=0;let u=(t+n|0)+a|0;return a=a+1|0,t=n^n>>>9,n=r+(r<<3)|0,r=r<<21|r>>>11,r=r+u|0,(u>>>0)/4294967296},getRegs:()=>({a:t,b:n,c:r,d:a}),setRegs:u=>{t=u.a,n=u.b,r=u.c,a=u.d}}}var ve=class{constructor(t){this.seed=t.hash,this.useA=!1,this.genA=rt(t.hash.substring(2,32)),this.genB=rt(t.hash.substring(34,32)),this.prngA=this.genA.next,this.prngB=this.genB.next;for(let n=0;n<1e6;n+=2)this.prngA(),this.prngB()}getState(){let t=this.genA.getRegs(),n=this.genB.getRegs();return{seed:this.seed,useA:this.useA,prngA:{a:t.a,b:t.b,c:t.c,d:t.d},prngB:{a:n.a,b:n.b,c:n.c,d:n.d}}}setState(t){if(t.seed!==this.seed)throw new Error(`Random.setState: seed ${t.seed} does not match ${this.seed}`);this.useA=t.useA,this.genA.setRegs(t.prngA),this.genB.setRegs(t.prngB)}r_zero_one(){return this.useA=!this.useA,this.useA?this.prngA():this.prngB()}dec(t,n){return t===void 0?this.r_zero_one():n===void 0?t*this.r_zero_one():t+(n-t)*this.r_zero_one()}int(t,n){return n===void 0&&(n=t,t=0),Math.floor(this.dec(t,n))}bool(t=.5){return this.r_zero_one()<t}sign(){return this.bool()?1:-1}choose(t){return t[this.int(t.length)]}};var st="bafybeicjwcq5lxxtfnyj4p2ugcr7ctyb5wl62cbcechj6tsabdq5whcs7u",it="https://ipfs.io/ipfs/";function $t(e){return e.endsWith("/")?e:`${e}/`}var ce=null;function Wt(e){return[...Array(e)].map(()=>Math.floor(Math.random()*16).toString(16)).join("")}function Gt(e){return e&&e.length>0?e:[{cid:st}]}function Bt(e){return e.startsWith("0x")?e:`0x${e}`}var ot=/^(0[xX])?[0-9a-fA-F]{64}$/;function Vt(e){let t="",n=2166136261,r=522970236;for(let a=0;t.length<64;a++){for(let o=0;o<e.length;o++)n^=e.charCodeAt(o)+a,n=Math.imul(n,16777619),r^=e.charCodeAt(o)+a*17,r=Math.imul(r,16777619);t+=(n>>>0).toString(16).padStart(8,"0"),t+=(r>>>0).toString(16).padStart(8,"0")}return`0x${t.slice(0,64)}`}function at(e){let t=typeof e=="number"?String(e):e;return ot.test(t)?`0x${(t.startsWith("0x")||t.startsWith("0X")?t.slice(2):t).toLowerCase()}`:Vt(t)}function dt(e,t){if(typeof e=="number"||t==="deterministic")return at(e);let n=String(e);return ot.test(n)?at(n):n.startsWith("0x")||n.startsWith("0X")?n:`0x${n}`}function jt(e){if(!e&&typeof tokenData<"u"&&tokenData?.hash)return{hash:tokenData.hash,tokenId:String(tokenData.tokenId),externalAssetDependencies:Gt(tokenData.externalAssetDependencies),preferredIPFSGateway:$t(tokenData.preferredIPFSGateway||it),preferredArweaveGateway:tokenData.preferredArweaveGateway};let t=typeof window<"u"?new URLSearchParams(window.location.search):new URLSearchParams;return{hash:e?Bt(e):t.get("hash")||`0x${Wt(64)}`,tokenId:"18009999",externalAssetDependencies:[{cid:st}],preferredIPFSGateway:it}}function De(e){let t=e?.useCache!==!1;if(t&&ce&&!e?.hash)return ce;let n=jt(e?.hash);return t?ce=n:ce||(ce=n),n}function ut(e){return new Array(32).fill(null).map((t,n)=>parseInt(e.hash.slice(2+n*2,4+n*2),16))}async function He(){let e=await import("tone");if(typeof e.start=="function")return e;let t=e.default;return t&&typeof t.start=="function"?t:e}var pt={id:"tone",async load(){await Promise.resolve().then(()=>(lt(),Jt))},async unlock(){await pt.load(),await(await He()).start()},async resumeIfSuspended(){let e=await He();e.context.state==="suspended"&&await e.context.resume()},async suspendIfRunning(){let t=(await He()).context.rawContext;"suspend"in t&&t.state==="running"&&await t.suspend()}},ht={tone:pt};function Fe(e){if(!e)return[];let t=Array.isArray(e)?e:[e],n=[];for(let r of t){if(!(r in ht)){console.warn(`Unknown audio library "${r}"`);continue}let a=r;n.includes(a)||n.push(a)}return n}function Le(e){return e.map(t=>ht[t])}var Ae="$cyberartTa",j=class extends Error{constructor(t){super(t),this.name="IncompatibleCartStateError"}},Oe={Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array};function Yt(e){for(let t of Object.keys(Oe))if(e instanceof Oe[t])return t}function gt(e){return ArrayBuffer.isView(e)&&!(e instanceof DataView)}function z(e){if(e===null||typeof e!="object"||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function _e(e){return z(e)?typeof e[Ae]=="string"&&Array.isArray(e.d):!1}function Xt(e){return e==null?!1:typeof e=="function"?!0:!(typeof e!="object"||Array.isArray(e)||gt(e)||z(e))}var Qt=new Set(["audioContextStarted","midiSynths","keepRatioPrimed","audioInitStarted","musicSeekApplied"]);function mt(e){return e===null?"null":_e(e)?String(e[Ae]):Array.isArray(e)?"array":z(e)?"object":typeof e}function Zt(e,t){return e===t||e==="null"||t==="null"}function ft(e){return e.trim().toLowerCase().replace(/^0x/,"")}function yt(e,t,n,r){if(!(!n&&!r)&&ft(e)!==ft(t))throw new j(`Generative cart state is for seed "${t}", but the live token is "${e}"`)}function ae(e){return typeof e=="number"&&Number.isFinite(e)&&e>0}function bt(e,t){let n=e.dimensions;if(n&&ae(n.width)&&ae(n.height))return n;if(t&&ae(t.width)&&ae(t.height))return{width:t.width,height:t.height};if(z(e.state)){let r=e.state.containerWidth,a=e.state.containerHeight;if(ae(r)&&ae(a))return{width:r,height:a}}return null}function se(e,t=new WeakSet){if(e===null||typeof e=="string"||typeof e=="boolean")return e;if(typeof e=="number")return Number.isFinite(e)?e:null;if(!(typeof e=="function"||typeof e>"u"||typeof e=="bigint"||typeof e=="symbol")){if(gt(e)){let n=Yt(e);return n?{[Ae]:n,d:Array.from(e)}:void 0}if(typeof e=="object"&&!t.has(e)){t.add(e);try{if(Array.isArray(e)){let a=[],o=0;for(let u of e){let p=se(u,t);p!==void 0&&(a.push(p),o++)}return e.length>0&&o===0?void 0:a}if(!z(e)||Xt(e))return;let n=Object.keys(e),r={};for(let a of n){if(Qt.has(a))continue;let o=se(e[a],t);o!==void 0&&(r[a]=o)}return n.length>0&&Object.keys(r).length===0?void 0:r}finally{t.delete(e)}}}}function pe(e){if(_e(e)){let t=Oe[e[Ae]];return t?new t(e.d.map(n=>Number(n))):e}if(Array.isArray(e))return e.map(t=>pe(t));if(z(e)){let t={};for(let n of Object.keys(e))t[n]=pe(e[n]);return t}return e}function Ne(e,t,n,r,a=!0){if(a&&n&&r&&n!==r)throw new j(`Cart state is for "${r}", but the live cart is "${n}"`);if(!z(t)){if(a)throw new j("Cart state snapshot is empty");return}let o=Object.keys(t);if(o.length===0){if(a)throw new j("Cart state snapshot is empty");return}let u=se(e);if(!z(u)||Object.keys(u).length===0){if(a)throw new j("Live cart has no serializable state");return}let p=o.filter(m=>m in u);if(p.length===0){if(a)throw new j("Cart state snapshot does not overlap the live cart shape");return}for(let m of p){let C=mt(u[m]),v=mt(t[m]);if(!Zt(C,v))throw new j(`Cart state field "${m}" has type ${v}, live cart expects ${C}`);if(C==="object"){let l=t[m],w=e[m];z(l)&&!_e(l)&&Ne(w,l,void 0,void 0,!1)}}}function vt(e,t){if(!z(e)||!z(t))return;let n=se(e);if(z(n))for(let r of Object.keys(t))r in n&&(e[r]=pe(t[r]))}function wt(e){let t=typeof e=="string"?JSON.parse(e):e;if(!t||typeof t!="object")throw new j("Cart state bundle is not an object");if(t.version!==1)throw new j(`Unsupported cart state version ${String(t.version)}`);if(typeof t.seed!="string"||typeof t.framesElapsed!="number")throw new j("Cart state bundle is missing seed or framesElapsed");return t}var Ue="cyberart.asset.ready",Ke="cyberart.asset.failed";function ee(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function At(e){return{type:e.status==="ready"?Ue:Ke,kind:"state",payload:e.detail===void 0?{id:e.id}:{id:e.id,detail:e.detail}}}function tn(e){if(!e||typeof e!="object")return 0;let t=e;return typeof t.startTime=="number"&&typeof t.lastSimulationUpdateAt=="number"?Math.max(0,t.lastSimulationUpdateAt-t.startTime):0}function nn(e,t){if(typeof window.resizeTo!="function")return!1;try{if(window.top!==window)return!1}catch{return!1}let n=Math.max(1,Math.round(e)),r=Math.max(1,Math.round(t)),a=Math.max(0,window.outerWidth-window.innerWidth),o=Math.max(0,window.outerHeight-window.innerHeight);try{window.resizeTo(n+a,r+o)}catch{return!1}return Math.abs(window.innerWidth-n)<=8&&Math.abs(window.innerHeight-r)<=8}var rn=[[0,0],[16,9],[9,16],[4,3],[3,4],[2,1],[1,2],[3,1],[1,3],[1,1]],We=rn[0],an=We[0]/We[1],$e=30,sn=120,on=3840/2160,dn=2160/3840,Ee=class{constructor(t=$e,n=!1,r=window.innerWidth,a=window.innerHeight,o=!0,u,p={}){this.framesElapsed=0;this.frameRate=$e;this._paused=!1;this.savedToken=!1;this.prepared=!1;this.loopRunning=!1;this.fallbackAudio=[];this.audioLibrariesInternal=[];this.virtualClock=null;this.scriptedActions=[];this.initialScriptedActions=[];this.appliedActions=[];this.consumedActionIndexes=new Set;this.outboundEvents=[];this.consecutiveErrorCount=0;this.lastErrorLogAt=0;this.reinitStayPaused=!1;this.reinitPending=!1;this.lastExportedFramebuffer=null;this.pinnedOutput=null;this.pinViewportAtImport=null;this.importing=!1;this.drawLoop=this.drawLoop.bind(this),this.loadCart=this.loadCart.bind(this),this.prepareCart=this.prepareCart.bind(this),this.beginPlayback=this.beginPlayback.bind(this),this.reinit=this.reinit.bind(this),this.tuneFramerate=this.tuneFramerate.bind(this),this.container=p.container,this.seed=p.seed,this.captureKeyboard=p.captureKeyboard??!0,this.customState=p.customState,this.hostChannel=p.hostChannel,this.fallbackAudio=Fe(p.audio),this.audioLibrariesInternal=this.fallbackAudio;let m=p.deterministic;this.deterministic=!!m;let C=m&&typeof m=="object"?m:{};if(this.deterministic){if(p.clock){let v=p.clock;if(typeof v.advance!="function")throw new Error("deterministic mode requires a virtual clock with advance()");this.virtualClock=v,this.clock=v}else this.virtualClock=tt(C.origin??0),this.clock=this.virtualClock;this.initialScriptedActions=ee(C.actions??[]),this.scriptedActions=ee(this.initialScriptedActions)}else this.clock=p.clock??ge();this.isBodyCanvas=this.container?!1:o,this.autoMode=n,this.aspectRatio=an,this.selectedAsp=We,this.isFullscreen=!!document.fullscreenElement,this.updateFrameRate(t),this.tempUnpause=!1,this.synchronous=re,this.containerWidth=r,this.containerHeight=a,this.gameManager=u,this.init(!0)}setGameManager(t){this.gameManager=t}reinit(t){if(!this.importing){if(this.shouldKeepPinnedOutput()){this.fitPinnedCanvas();return}this.reinitPending||(this.reinitStayPaused=this._paused,this.reinitPending=!0),this.paused=!0,clearTimeout(this.reinitTimeout),this.reinitTimeout=setTimeout(()=>{if(this.importing){this.paused=this.reinitStayPaused,this.reinitPending=!1;return}this.updateInProgress?this.reinit(t):(this.requestedAnimationFrame&&cancelAnimationFrame(this.requestedAnimationFrame),this.clearPinnedOutput(),this.init(),this.reloadCart(),this.paused=this.reinitStayPaused,this.reinitPending=!1)},150)}}initSeed(){this.tokenData=this.seed?De({hash:this.seed,useCache:!1}):De(),this.rawParams=ut(this.tokenData),this.mintNo=parseInt(this.tokenData.tokenId)%1e6,console.log("token",this.mintNo,this.tokenData.hash)}init(t=!1){t&&this.initSeed(),this.pureAspectUpdate(this.selectedAsp);let n=this.aspectRatio,[r,a]=Qe(n,this.containerWidth,this.containerHeight);r*=G,a*=G,this.width=~~r,this.height=~~a,this.atCenterX=this.width/2,this.atCenterY=this.height/2,this.mainCanvas?this.mainCanvas.setSize(this.width,this.height):this.mainCanvas=new be(this.width,this.height,1,this.isBodyCanvas,this.canvasMountOptions())}loadCart(t){this.prepareCart(t)&&this.beginPlayback()}prepareCart(t){if(this.prepared)return!0;try{let n=~~(this.width/1),r=~~(this.height/this.width*n),a=new ve(this.tokenData),o=new ye(n,r,a,this.rawParams,t,{gameManager:this.gameManager,canvasMount:this.canvasMountOptions(),customState:this.customState,captureKeyboard:this.deterministic?!1:this.captureKeyboard,hostChannel:this.hostChannel,clock:this.clock,listenToPointer:!this.deterministic});return this.animation=o,this.animationCart=t,this.paused=!1,this.framesElapsed=0,this.outboundEvents=[],this.scriptedActions=ee(this.initialScriptedActions),this.appliedActions=[],this.consumedActionIndexes=new Set,this.outboundUnsubscribe?.(),this.outboundUnsubscribe=void 0,this.deterministic&&this.hostChannel&&(this.outboundUnsubscribe=this.hostChannel.onEvent(u=>{this.outboundEvents.push(u)})),this.R=a,this.applyCartFrameRate(t,o),this.resolveAudioLibraries(t),this.prepared=!0,!0}catch(n){return console.error(n),!1}}applyCartFrameRate(t,n){let r=t.metadata,a=r?.frameRate??$e,o=n.cartState?.visualMode??n.featureState?.visualMode,u=o&&r?.frameRateByVisualMode?r.frameRateByVisualMode[o]:void 0;this.updateFrameRate(typeof u=="number"&&u>0?u:a)}get audioLibraries(){return this.audioLibrariesInternal}get needsAudio(){return this.audioLibrariesInternal.length>0}resolveAudioLibraries(t){this.audioLibrariesInternal=Fe(t.metadata?.audio)}async unlockAudio(){if(this.audioLibrariesInternal.length===0)return;let t=Le(this.audioLibrariesInternal);if(re){for(let n of t)await n.load();return}for(let n of t)await n.unlock()}async resumeAudioLibraries(){if(!(this.paused||re))for(let t of Le(this.audioLibrariesInternal))try{await t.resumeIfSuspended()}catch(n){console.error(`Failed to resume audio library "${t.id}" after reload`,n)}}beginPlayback(){!this.prepared||this.loopRunning||(this.prepared=!1,this.loopRunning=!0,this.consecutiveErrorCount=0,!this.deterministic&&(this.requestedAnimationFrame=requestAnimationFrame(this.drawLoop)))}get isPrepared(){return this.prepared}get isLoopRunning(){return this.loopRunning}get isDeterministic(){return this.deterministic}getClock(){return{now:this.clock.now(),framesElapsed:this.framesElapsed,frameRate:this.frameRate}}getRandomState(){return this.requirePreparedAnimation().getRandomState()}schedule(t){this.scriptedActions.push(ee(t))}async getReplayMetadata(){let t=await this.exportState();return{seed:this.tokenData.hash,clock:this.getClock(),rng:this.getRandomState(),actions:ee(this.scriptedActions),applied:ee(this.appliedActions),events:ee(this.outboundEvents),state:t.state}}async step(t=1){if(!this.deterministic)throw new Error("step() requires createRuntime({ deterministic: true })");this.requirePreparedAnimation(),this.prepared&&!this.loopRunning&&this.beginPlayback(),this.paused=!1;let n=Math.max(0,Math.floor(t));for(let r=0;r<n&&this.animation;r++){let a=this.framesElapsed;if(this.applyScheduledActions(a),await this.processFrame(this.clock.now(),{ignorePause:!0,scheduleNext:!1}),this.framesElapsed===a||(this.virtualClock?.advance(this.targetDrawTime),!this.loopRunning))break}}async advance(t){let n=Math.max(0,Math.round(t/this.targetDrawTime));await this.step(n)}applyScheduledActions(t){let n=this.animation;n&&this.scriptedActions.forEach((r,a)=>{r.atFrame===t&&(this.consumedActionIndexes.has(a)||(this.consumedActionIndexes.add(a),r.type==="pointer"?n.injectPointer(r.pointer.kind,r.pointer.x,r.pointer.y):r.type==="key"?n.injectKey(r.key):r.type==="event"?this.hostChannel?.dispatch(r.event):r.type==="asset"&&this.hostChannel?.dispatch(At(r)),this.appliedActions.push({frame:t,action:r})))})}get paused(){return this._paused}set paused(t){this._paused!==t&&(this._paused=t,this.animation?.setPaused(t))}async waitUntilUpdateIdle(){for(;this.updateInProgress;)await new Promise(t=>{this.deterministic?queueMicrotask(t):typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>t()):setTimeout(t,0)})}requirePreparedAnimation(){if(!this.animation)throw new Error("No prepared cart");return this.animation}async exportState(){let t=this.requirePreparedAnimation(),n=this._paused;this.paused=!0,await this.waitUntilUpdateIdle();try{this.lastExportedFramebuffer=t.captureFramebuffer();let r=t.getCanvas();return{version:1,cartId:this.animationCart?.metadata?.id,generative:this.animationCart?.metadata?.generative,seed:this.tokenData.hash,framesElapsed:this.framesElapsed,elapsedSinceStart:t.getElapsedSinceStart(),dimensions:{width:r.width,height:r.height,cssWidth:this.containerWidth,cssHeight:this.containerHeight,dpr:G},state:se(t.cartState)}}finally{this.paused=n}}async exportStateJSON(){return JSON.stringify(await this.exportState())}peekExportedFramebuffer(){return this.lastExportedFramebuffer}peekSeed(){return this.tokenData?.hash}isGenerative(){return this.animationCart?.metadata?.generative===!0}async importState(t,n){let r=this.requirePreparedAnimation(),a=wt(t),o=this._paused,u=this.loopRunning;this.paused=!0,await this.waitUntilUpdateIdle(),Ne(r.cartState,a.state,this.animationCart?.metadata?.id,a.cartId),yt(this.tokenData.hash,a.seed,this.animationCart?.metadata?.generative,a.generative),clearTimeout(this.reinitTimeout),this.reinitPending=!1,this.importing=!0;let p=bt(a,n?.framebuffer??this.lastExportedFramebuffer);if(p){this.pinOutputSize(p);let v=p.cssWidth??p.width/G,l=p.cssHeight??p.height/G;nn(v,l),this.syncContainerFromDom(),this.pinViewportAtImport={w:this.containerWidth,h:this.containerHeight}}let m=this.customState,C=!1;try{if(this.customState=pe(a.state),this.unloadCart(),!this.prepareCart(this.animationCart))throw new Error("Failed to prepare cart while loading state");this.animation.cartState!==this.customState&&vt(this.animation.cartState,a.state),this.framesElapsed=a.framesElapsed;let v=this.animation,l=v.cartState,w=typeof a.elapsedSinceStart=="number"?a.elapsedSinceStart:tn(l);v.restoreClock(w,typeof l?.startTime=="number"?l.startTime:void 0),o&&v.setPaused(!0);let E=n?.framebuffer??this.lastExportedFramebuffer;E&&v.restoreFramebuffer(E)?l.keepRatioPrimed=!0:await v.renderAnimation(this.framesElapsed,this.rawParams),this.fitPinnedCanvas(),C=!0}catch(v){throw this.clearPinnedOutput(),this.customState=m,this.paused=o,this.animationCart&&(this.syncContainerFromDom(),this.init(),this.reloadCart()),v}finally{this.importing=!1,C&&(this.customState=m,this.paused=o,u&&this.beginPlayback())}}unloadCart(){this.loopRunning=!1,this.requestedAnimationFrame&&cancelAnimationFrame(this.requestedAnimationFrame),this.drawLoopTimeout&&clearTimeout(this.drawLoopTimeout),this.animation?.teardown(),this.animation=void 0,this.prepared=!1,this.audioLibrariesInternal=this.fallbackAudio,this.mainCanvas?.clearAll()}reloadCart(t=!1){let n=this.animationCart;if(!n)return;this.pinnedOutput&&(this.clearPinnedOutput(),this.syncContainerFromDom(),this.init());let r=this.reinitPending?this.reinitStayPaused:this._paused;this.unloadCart(),t&&this.initSeed(),this.loadCart(n),this.paused=r,!this.paused&&!re&&this.resumeAudioLibraries()}getFrameRate(){return this.frameRate}updateFrameRate(t){if(this.frameRate=t,t>=1)this.targetDrawTime=1e3/t;else{let r=1/(2-t);this.targetDrawTime=1e3/r}this.drawTime=this.targetDrawTime}canvasMountOptions(){return{container:this.container,adoptFromDocument:!this.container}}syncContainerFromDom(){if(this.container){this.containerWidth=this.container.clientWidth||this.containerWidth,this.containerHeight=this.container.clientHeight||this.containerHeight;return}this.containerWidth=window.innerWidth,this.containerHeight=window.innerHeight}pinOutputSize(t){this.pinnedOutput=t,this.width=~~t.width,this.height=~~t.height,this.atCenterX=this.width/2,this.atCenterY=this.height/2,this.aspectRatio=this.width/this.height,this.mainCanvas&&this.mainCanvas.setSize(this.width,this.height)}shouldKeepPinnedOutput(){return this.pinnedOutput?(this.syncContainerFromDom(),this.viewportMatches(this.pinnedCssSize())?!0:!!(this.pinViewportAtImport&&this.viewportMatches(this.pinViewportAtImport))):!1}pinnedCssSize(){let t=this.pinnedOutput;return{w:t.cssWidth??t.width/G,h:t.cssHeight??t.height/G}}viewportMatches(t){return Math.abs(this.containerWidth-t.w)<8&&Math.abs(this.containerHeight-t.h)<8}fitPinnedCanvas(){let t=this.pinnedOutput,n=this.canvas;if(!t||!n)return;this.container&&!this.container.style.position&&(this.container.style.position="relative");let r=this.containerWidth||window.innerWidth,a=this.containerHeight||window.innerHeight,o=t.width/G,u=t.height/G;if(o<1||u<1||r<1||a<1)return;let p=Math.min(r/o,a/u),m=o*p,C=u*p;n.style.position="absolute",n.style.left="50%",n.style.top="50%",n.style.transform="translate(-50%, -50%)",n.style.margin="0",n.style.width=`${m}px`,n.style.height=`${C}px`,n.style.imageRendering=Math.abs(p-1)<.01?"auto":"pixelated"}clearPinnedOutput(){let t=this.canvas;this.pinnedOutput=null,this.pinViewportAtImport=null,t&&(t.style.position="",t.style.left="",t.style.top="",t.style.transform="",t.style.imageRendering="",t.style.width="",t.style.height="",t.style.margin="auto")}get canvas(){return this.animation?.getCanvas()??this.mainCanvas?.canvas}destroy(){this.outboundUnsubscribe?.(),this.outboundUnsubscribe=void 0,this.clearPinnedOutput(),this.unloadCart(),clearTimeout(this.reinitTimeout),this.mainCanvas&&!this.mainCanvas.adopted&&this.mainCanvas.canvas.remove()}drawIt(){}tuneFramerate(t){let n=this.lastCall||t;this.lastCall=t,this.drawTime=Math.max(0,this.drawTime+this.targetDrawTime-this.lastCall+n)}async processFrame(t,n={}){let r=n.ignorePause===!0,a=n.scheduleNext!==!1;if(!this.loopRunning&&!r)return;let o=!1,u,p="update";try{if(r||!this.paused||this.tempUnpause){if(!re&&!r&&this.tuneFramerate(t),!this.animation)return;if(p="update",this.updateInProgress=!0,await this.animation.updateAnimationState(this.framesElapsed,this.rawParams,t),this.updateInProgress=!1,p="render",await this.animation.renderAnimation(this.framesElapsed,this.rawParams,t),this.autoMode&&this.animation.cartState.saveToken&&!this.savedToken&&!new URLSearchParams(window.location.search).get("hash")){let v=localStorage.getItem("goodones"),l=JSON.stringify(v?[...JSON.parse(v),this.tokenData.hash]:[this.tokenData.hash]);localStorage.setItem("goodones",l),this.savedToken=!0,localStorage.setItem(this.tokenData.hash,this.mainCanvas.canvas.toDataURL("image/png")),window.location.reload(),this.loopRunning=!1;return}this.framesElapsed++,this.tempUnpause&&(this.tempUnpause=!1)}p="draw",this.drawIt()}catch(m){o=!0,u=m,this.handleFrameError(m,p)}finally{this.updateInProgress=!1}o?(this.consecutiveErrorCount++,this.consecutiveErrorCount>=sn&&(this.loopRunning=!1,this.onError?.(u,{phase:p,consecutive:this.consecutiveErrorCount,stopped:!0}))):this.consecutiveErrorCount=0,!(!this.loopRunning||!a)&&(this.drawLoopTimeout=setTimeout(()=>{this.requestedAnimationFrame=requestAnimationFrame(this.drawLoop)},this.drawTime))}async drawLoop(t){await this.processFrame(t,{scheduleNext:!0})}handleFrameError(t,n){let r=performance.now();r-this.lastErrorLogAt>=1e3&&(this.lastErrorLogAt=r,console.error(`Animation ${n} error:`,t)),this.consecutiveErrorCount===0&&this.onError?.(t,{phase:n,consecutive:1,stopped:!1})}pureAspectUpdate(t){if(t[0]===0&&t[1]===0){let r=this.containerWidth||window.innerWidth,a=this.containerHeight||window.innerHeight,o=r/a;this.aspectRatio=Math.min(on,Math.max(dn,o))}else this.aspectRatio=t[0]/t[1]}};var un="HostChannel has been destroyed",Ce=class{constructor(){this.inbound=[];this.listeners=[];this.closed=!1}dispatch(t){this.requireOpen(),this.inbound.push(t),this.inbound.length>32&&this.inbound.splice(0,this.inbound.length-32)}consume(){if(this.requireOpen(),this.inbound.length===0)return[];let t=this.inbound;return this.inbound=[],t}emit(t){this.requireOpen();for(let n of this.listeners)n(t)}onEvent(t){return this.requireOpen(),this.listeners.push(t),()=>{this.listeners=this.listeners.filter(n=>n!==t)}}clearInbound(){this.requireOpen(),this.inbound=[]}clear(){this.inbound=[],this.listeners=[]}close(){this.closed=!0,this.clear()}requireOpen(){if(this.closed)throw new Error(un)}};var cn=["image","audio","font","spritesheet"],ln=["timeout","cors","not-found","invalid","aborted","resolver"],he="cyberart:fallback/silent",Et="Asset preloader has been destroyed",pn=4,hn=new Set(cn),mn=new Set(ln),fn={timeout:"asset load timed out",cors:"CORS blocked this asset","not-found":"asset was not found",invalid:"asset declaration or resource is invalid",aborted:"asset load was aborted",resolver:"asset resolver failed"};function gn(e){return typeof e=="string"&&hn.has(e)}function yn(e){return typeof e=="string"&&mn.has(e)}function Ge(e){if(!e||typeof e!="object")return!1;let t=e;return typeof t.id=="string"&&typeof t.ref=="string"&&yn(t.code)&&typeof t.message=="string"}function N(e){return{id:e.id,ref:e.ref,code:e.code,message:e.message&&e.message.length>0?e.message:fn[e.code]}}function oe(e,t){return{type:e==="ready"?Ue:Ke,kind:"state",payload:t}}function bn(e){return e instanceof Error&&e.name==="AbortError"||typeof DOMException<"u"&&e instanceof DOMException&&e.name==="AbortError"}function Be(e){return e?{...e}:void 0}function Q(e){let t={id:e.id,ref:e.ref,type:e.type,url:e.url};return e.integrity!==void 0&&(t.integrity=e.integrity),e.provenance&&(t.provenance=Be(e.provenance)),e.cors!==void 0&&(t.cors=e.cors),e.usedFallback&&(t.usedFallback=!0),e.managed&&(t.managed=!0),t}function me(e){return{id:e.id,ref:e.ref,code:e.code,message:e.message}}function vn(e){if(e.state==="ready"){let t={state:"ready",resource:Q(e.resource)};return e.failure&&(t.failure=me(e.failure)),t}return e.state==="failed"?{state:"failed",failure:me(e.failure)}:{state:e.state}}function wn(e){if(!e||typeof e!="object")return N({id:"",ref:"",code:"invalid",message:"declaration is required"});if(typeof e.id!="string"||e.id.length===0)return N({id:typeof e.id=="string"?e.id:"",ref:typeof e.ref=="string"?e.ref:"",code:"invalid",message:"id is required"});if(typeof e.ref!="string"||e.ref.length===0)return N({id:e.id,ref:"",code:"invalid",message:"ref is required"});if(!gn(e.type))return N({id:e.id,ref:e.ref,code:"invalid",message:`unsupported type ${String(e.type)}`});if(e.integrity!==void 0&&typeof e.integrity!="string")return N({id:e.id,ref:e.ref,code:"invalid",message:"integrity must be a string"});if(e.timeoutMs!==void 0&&(typeof e.timeoutMs!="number"||!Number.isFinite(e.timeoutMs)||e.timeoutMs<0))return N({id:e.id,ref:e.ref,code:"invalid",message:"timeoutMs must be a non-negative finite number"})}function Ct(e){return{id:e.id,ref:he,type:e.type,url:he,usedFallback:!0,cors:"omit"}}function St(e,t){return Ge(t)?{id:e.id,ref:e.ref,code:t.code,message:t.message}:bn(t)?N({id:e.id,ref:e.ref,code:"aborted"}):N({id:e.id,ref:e.ref,code:"resolver",message:t instanceof Error?t.message:String(t)})}function kt(e,t){if(!t||typeof t.url!="string"||t.url.length===0)throw N({id:e.id,ref:e.ref,code:"invalid",message:"resolver returned no url"});if(t.integrity&&e.integrity&&t.integrity!==e.integrity)throw N({id:e.id,ref:e.ref,code:"invalid",message:"integrity mismatch"});let n=Q(t);return n.id=e.id,n.ref=t.ref||e.ref,n.type=e.type,!n.integrity&&e.integrity&&(n.integrity=e.integrity),!n.provenance&&e.provenance&&(n.provenance=Be(e.provenance)),n}function Rt(e){if(typeof e?.resolver?.resolve!="function")throw new Error("createAssetPreloader: resolver is required");let t=e.emitEvents!==!1,n=e.wallClockTimeout!==!1,r=new Map,a=[],o=new Map,u=new Map,p=new Map,m=new Map,C=new Map,v=new Set,l=!1;function w(i){return i.code==="aborted"||i.code==="timeout"}function E(i,g,y){let x=St(i,y);return x.code==="timeout"?x:g.aborted?N({id:i.id,ref:i.ref,code:"aborted"}):x}function b(i,g){let y=C.get(i);y||(y=new Set,C.set(i,y)),y.add(g)}function M(i){if(i?.state==="ready")return`${i.resource.type}\0${i.resource.ref}`}function h(i,g){for(let[y,x]of C)if(y!==g&&x.has(i))return!0;for(let[y,x]of r)if(y!==g&&M(x)===i)return!0;return!1}function K(i,g){let y=new Set(C.get(i)),x=M(g);x&&y.add(x),C.delete(i);for(let U of y)h(U,i)||p.delete(U)}function $(){let i=0,g=0,y=0,x=0,U={};for(let[I,P]of r)U[I]=vn(P),P.state==="pending"||P.state==="loading"?i+=1:P.state==="failed"?y+=1:(g+=1,(P.resource.usedFallback||P.failure)&&(x+=1));return{total:r.size,pending:i,ready:g,failed:y,fallbacks:x,items:U,failures:a.map(me)}}function J(){if(v.size===0)return;let i=$();for(let g of v)g(i)}function F(i){a.push(me(i))}function d(i){l||!t||!e.dispatch||e.dispatch(i)}function T(i){if(i?.managed&&i.url.startsWith("blob:")&&!(typeof URL>"u"||typeof URL.revokeObjectURL!="function"))try{URL.revokeObjectURL(i.url)}catch{}}function A(i,g){if(l)return;let y=r.get(i);y?.state==="ready"&&T(y.resource),r.set(i,g),J()}function D(i){if(i.fallback!==void 0)return i.fallback==="silent"?{id:`${i.id}::fallback`,ref:he,type:i.type}:typeof i.fallback=="string"?{id:`${i.id}::fallback`,ref:i.fallback,type:i.type}:{...i.fallback,id:typeof i.fallback.id=="string"&&i.fallback.id.length>0?i.fallback.id:`${i.id}::fallback`}}function H(i,g,y){let x=`${i.type}\0${i.ref}`,U=p.get(x);if(U)return g.aborted?Promise.reject(N({id:i.id,ref:i.ref,code:"aborted"})):(b(y,x),Promise.resolve(Q(U.resource)));if(g.aborted)return Promise.reject(N({id:i.id,ref:i.ref,code:"aborted"}));let I=m.get(x);if(!I){let R=new AbortController,L={id:i.id,ref:i.ref,type:i.type};i.integrity!==void 0&&(L.integrity=i.integrity),i.provenance&&(L.provenance=Be(i.provenance)),I={promise:Promise.resolve().then(()=>e.resolver.resolve(L,R.signal)).then(O=>{let X=kt(i,O);if(R.signal.aborted)throw N({id:i.id,ref:i.ref,code:"aborted"});return p.set(x,{resource:Q(X)}),X}).catch(O=>{throw St(i,O)}).finally(()=>{m.delete(x)}),controller:R,waiters:0},m.set(x,I)}let P=I;return P.waiters+=1,new Promise((R,L)=>{let Y=!1,O=(Z,xe)=>{Y||(Y=!0,g.removeEventListener("abort",X),P.waiters-=1,xe&&P.waiters<=0&&P.controller.abort(),Z())},X=()=>{O(()=>L(N({id:i.id,ref:i.ref,code:"aborted"})),!0)};if(g.aborted){X();return}g.addEventListener("abort",X,{once:!0}),P.promise.then(Z=>{if(!Y){if(g.aborted){X();return}b(y,x),O(()=>R(Q(Z)),!1)}},Z=>{if(!Y){if(g.aborted){X();return}O(()=>L(Z),!1)}})})}function W(i,g,y){if(g.aborted)return Promise.reject(N({id:i.id,ref:i.ref,code:"aborted"}));if(i.ref===he)return Promise.resolve(Ct(i));let x=new AbortController,U=()=>x.abort();g.addEventListener("abort",U,{once:!0});let I=i.timeoutMs??e.timeoutMs,P,R=!1;return n&&I!==void 0&&I>0&&Number.isFinite(I)&&(P=setTimeout(()=>{R=!0,x.abort()},I)),H(i,x.signal,y).then(L=>{let Y=kt(i,L);return Y.id=i.id,Y}).catch(L=>{throw R?N({id:i.id,ref:i.ref,code:"timeout"}):L}).finally(()=>{P!==void 0&&clearTimeout(P),g.removeEventListener("abort",U)})}async function B(i,g,y,x){try{return{resource:await W(i,g,x)}}catch(U){let I=E(i,g,U);if(w(I)||g.aborted||y>=pn)throw I;let P=D(i);if(!P)throw I;if(g.aborted)throw N({id:i.id,ref:i.ref,code:"aborted"});if(i.fallback==="silent"||P.ref===he)return{resource:Ct(i),failure:I};try{let R=await B(P,g,y+1,x);return{resource:{...Q(R.resource),id:i.id,usedFallback:!0},failure:I}}catch(R){let L=Ge(R)&&!w(R)&&!g.aborted?R:E(i,g,R);throw!w(L)&&!g.aborted&&F(I),L}}}async function te(i,g){if(l)throw new Error(Et);let y=r.get(i.id);if(y?.state==="ready"||y?.state==="failed")return;let x=o.get(i.id);if(x){await x;return}let U=(async()=>{let I=wn(i);if(I){A(i.id,{state:"failed",failure:I}),F(I),d(oe("failed",{id:i.id,ref:i.ref,failure:I}));return}A(i.id,{state:"loading"});let P=u.get(i.id)??new AbortController;u.has(i.id)||u.set(i.id,P);try{let R=await B(i,P.signal,g,i.id);if(l)return;if(P.signal.aborted){let L=N({id:i.id,ref:i.ref,code:"aborted"});A(i.id,{state:"failed",failure:L}),F(L),d(oe("failed",{id:i.id,ref:i.ref,failure:L}));return}if(R.resource.id=i.id,R.failure){A(i.id,{state:"ready",resource:R.resource,failure:R.failure}),F(R.failure),d(oe("failed",{id:i.id,ref:i.ref,failure:R.failure,resource:Q(R.resource)})),d(oe("ready",{id:i.id,ref:R.resource.ref,resource:Q(R.resource),failure:R.failure}));return}A(i.id,{state:"ready",resource:R.resource}),d(oe("ready",{id:i.id,ref:i.ref,resource:Q(R.resource)}))}catch(R){if(l)return;let L=Ge(R)&&!w(R)&&!P.signal.aborted?{...me(R),id:i.id}:E(i,P.signal,R);A(i.id,{state:"failed",failure:L}),F(L),d(oe("failed",{id:i.id,ref:i.ref,failure:L}))}finally{u.get(i.id)===P&&u.delete(i.id)}})();o.set(i.id,U);try{await U}finally{o.delete(i.id)}}return{async preload(i){if(l)throw new Error(Et);let g=Array.isArray(i)?i:[];for(let y of g)y&&typeof y.id=="string"&&y.id.length>0&&(r.has(y.id)||r.set(y.id,{state:"pending"}),u.has(y.id)||u.set(y.id,new AbortController));return J(),await Promise.all(g.map(y=>te(y,0))),$()},get(i){let g=r.get(i);if(g?.state==="ready")return Q(g.resource)},getProgress(){return $()},onProgress(i){return v.add(i),()=>{v.delete(i)}},abort(i){if(!l){if(i!==void 0){u.get(i)?.abort();return}for(let g of u.values())g.abort()}},forget(i){if(l)return;if(i===void 0){for(let y of r.values())y.state==="ready"&&T(y.resource);r.clear(),a.length=0,p.clear(),C.clear(),J();return}let g=r.get(i);g?.state==="ready"&&T(g.resource),K(i,g),r.delete(i);for(let y=a.length-1;y>=0;y--)a[y].id===i&&a.splice(y,1);J()},dispose(){if(!l){l=!0;for(let i of u.values())i.abort();u.clear();for(let i of r.values())i.state==="ready"&&T(i.resource);r.clear(),a.length=0,o.clear();for(let i of m.values())i.controller.abort();p.clear(),m.clear(),C.clear(),v.clear()}}}}function Se(e){Je();let{container:t,seed:n,captureKeyboard:r=!1,audio:a,deterministic:o,assets:u}=e,p=n===void 0?void 0:dt(n,o?"deterministic":"live"),m=new Ce;if(u&&typeof u.resolver?.resolve!="function")throw new Error("createRuntime: assets.resolver is required");let C=u?Rt({resolver:u.resolver,timeoutMs:u.timeoutMs,emitEvents:u.emitEvents??!o,wallClockTimeout:!o,dispatch:F=>m.dispatch(F)}):void 0,v=!1,l=null,w,E=!1,b=t.clientWidth||window.innerWidth,M=t.clientHeight||window.innerHeight,h=new Ee(30,!1,b,M,!1,void 0,{container:t,seed:p,captureKeyboard:r,hostChannel:m,audio:a,deterministic:o}),K=()=>{let F=t.clientWidth||window.innerWidth,d=t.clientHeight||window.innerHeight;return F===h.containerWidth&&d===h.containerHeight?!1:(h.containerWidth=F,h.containerHeight=d,!0)},$=null;return!h.isDeterministic&&typeof ResizeObserver<"u"&&($=new ResizeObserver(()=>{if(v||!l)return;K()&&E&&h.reinit()}),$.observe(t)),h.onError=(F,d)=>{w?.(F,d)},{get tokenData(){return h.tokenData},get hostChannel(){return m},get assets(){return C},get onError(){return w},set onError(F){w=F},mount(F,d={}){if(v)throw new Error("createRuntime: cannot mount on a destroyed runtime");l?.destroy(),E=!1,h.customState=d.initialState,h.setGameManager(d.gameManager);let T=d.onEvent?m.onEvent(d.onEvent):()=>{};if(!h.prepareCart(F))throw T(),new Error("createRuntime: failed to prepare cart");let A=!1,D={async start(){if(!A){if(K()&&h.isPrepared&&(h.init(),h.unloadCart(),!h.prepareCart(F)))throw new Error("createRuntime: failed to prepare cart");h.needsAudio&&(await h.unlockAudio(),A)||(E=!0,h.beginPlayback())}},pause(){A||(h.paused=!0)},resume(){A||(h.paused=!1)},dispatch(H){A||m.dispatch(H)},snapshot(){if(A)return{seed:"",pngDataUrl:""};let H=h.canvas;return{seed:h.tokenData.hash,metadata:F.metadata,pngDataUrl:H?H.toDataURL("image/png"):""}},destroy(){A||(A=!0,E=!1,T(),m.clearInbound(),h.unloadCart(),l===D&&(l=null))},reload(){if(!A){if(!E){if(h.isPrepared&&(h.unloadCart(),!h.prepareCart(F)))throw new Error("createRuntime: failed to prepare cart");return}h.reloadCart()}},reinit(H){if(!A){if(!E){K();return}h.reinit(H)}},getCartState(){return h.animation?.cartState},exportState(){return A?Promise.reject(new Error("Cart handle has been destroyed")):h.exportState()},exportStateJSON(){return A?Promise.reject(new Error("Cart handle has been destroyed")):h.exportStateJSON()},async importState(H,W){if(A)throw new Error("Cart handle has been destroyed");await h.importState(H,W)},peekExportedFramebuffer(){return A?null:h.peekExportedFramebuffer()},peekSeed(){if(!A)return h.peekSeed()},isGenerative(){return A?!1:h.isGenerative()},async step(H=1){if(A)throw new Error("Cart handle has been destroyed");await h.step(H)},async advance(H){if(A)throw new Error("Cart handle has been destroyed");await h.advance(H)},schedule(H){A||h.schedule(H)},getClock(){if(A)throw new Error("Cart handle has been destroyed");return h.getClock()},getRandomState(){if(A)throw new Error("Cart handle has been destroyed");return h.getRandomState()},getReplayMetadata(){return A?Promise.reject(new Error("Cart handle has been destroyed")):h.getReplayMetadata()},get canvas(){return h.canvas},get paused(){return h.paused},set paused(H){A||(h.paused=H)},get tokenData(){return h.tokenData},get isPrepared(){return h.isPrepared},get isLoopRunning(){return h.isLoopRunning},get needsAudio(){return h.needsAudio},get audioLibraries(){return h.audioLibraries}};return l=D,D},async unlockAudio(){await h.unlockAudio()},destroy(){v||(v=!0,l?.destroy(),l=null,$?.disconnect(),$=null,C?.dispose(),m.close(),h.destroy())}}}var xt="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==",Tt=320,Pt=180,An="Headless harness has been destroyed",Mt=!1;function ke(){if(typeof globalThis.ImageData>"u"){class t{constructor(r,a){this.colorSpace="srgb";this.width=r,this.height=a,this.data=new Uint8ClampedArray(r*a*4)}}globalThis.ImageData=t}let e=HTMLCanvasElement.prototype;e.getContext=function(){return{globalAlpha:1,imageSmoothingEnabled:!1,fillStyle:"",save(){},restore(){},fillRect(){},putImageData(){},createImageData(r,a){return{data:new Uint8ClampedArray(r*a*4),width:r,height:a}}}},e.toDataURL=()=>xt,Mt=!0}function En(e,t){let n=document.createElement("div");return Object.defineProperty(n,"clientWidth",{value:e,configurable:!0}),Object.defineProperty(n,"clientHeight",{value:t,configurable:!0}),document.body.appendChild(n),n}function Cn(e){let t=e.indexOf(","),n=t>=0?e.slice(t+1):e,r=globalThis.atob(n),a=new Uint8Array(r.length);for(let o=0;o<r.length;o++)a[o]=r.charCodeAt(o);return a}function Sn(){return typeof process<"u"&&!!process.versions?.node}async function kn(e,t){if(!Sn())throw new Error("captureFrame(path) requires Node.js; omit the path to get the snapshot only");let n;try{({writeFile:n}=await import("node:fs/promises"))}catch(r){let a=r instanceof Error?r.message:String(r);throw new Error(`captureFrame(path) could not load node:fs/promises (${a}). Omit the path, or run under Node.`)}try{await n(e,Cn(t))}catch(r){let a=r instanceof Error?r.message:String(r);throw new Error(`captureFrame could not write ${e}: ${a}`)}}function Rn(e){Mt||ke();let t=e.width??Tt,n=e.height??Pt,r=En(t,n),a=[],o=[],u=!1,p=e.onEvent,m=e.onError,C=Se({container:r,seed:e.seed,deterministic:{origin:e.origin,actions:e.actions??[]}});C.onError=(b,M)=>{o.push({error:b,info:M}),m?.(b,M)},Object.defineProperty(C,"onError",{configurable:!0,enumerable:!0,get(){return m},set(b){m=b}});let v=b=>{a.push(b),p?.(b)},l=C.mount(e.cart,{initialState:e.initialState,gameManager:e.gameManager,onEvent:v}),w=()=>{if(u)throw new Error(An)};return{runtime:C,container:r,get events(){return a.slice()},get errors(){return o.slice()},get cart(){return l},async step(b=1){w(),await l.step(b)},async advance(b){w(),await l.advance(b)},schedule(b){w(),l.schedule(b)},dispatch(b){w(),l.dispatch(b)},start(){return w(),l.start()},pause(){w(),l.pause()},resume(){w(),l.resume()},get paused(){return l.paused},key(b){w(),l.schedule({type:"key",atFrame:l.getClock().framesElapsed,key:b})},click(b,M){w(),l.schedule({type:"pointer",atFrame:l.getClock().framesElapsed,pointer:{kind:"down",x:b,y:M}})},async inspect(){w();let b=await l.getReplayMetadata();return{state:b.state,events:a.slice(),errors:o.slice(),replay:b,clock:l.getClock()}},async captureFrame(b){w();let M=l.snapshot();return b&&await kn(b,M.pngDataUrl),M},remount(b={}){return w(),a.length=0,o.length=0,"onEvent"in b&&(p=b.onEvent),l=C.mount(e.cart,{initialState:b.initialState??e.initialState,gameManager:b.gameManager??e.gameManager,onEvent:v}),l},destroy(){if(!u){u=!0;try{l.destroy()}finally{try{C.destroy()}finally{r.remove()}}}}}}var Dt="cyberart.state.save",It="cyberart.state.load";var Re=1,fe="cyberart.diagnostic.rejected",Ve=8,xn=new Set(["intent","state","diagnostic"]),Tn=new Set([Dt,It]);function Ht(e){return typeof e=="string"&&xn.has(e)}function Pn(e){if(e.kind!==void 0)return Ht(e.kind)?e.kind:void 0;if(!(typeof e.type!="string"||e.type.length===0)){if(Tn.has(e.type))return"intent";for(let t of e.type.split("."))if(Ht(t))return t}}function Mn(e,t){let n=e.split("."),r=t.split(".");if(n.length!==r.length)return!1;for(let a=0;a<n.length;a++)if(n[a]!=="*"&&n[a]!==r[a])return!1;return!0}function de(e,t){for(let n of e)if(Mn(n,t))return!0;return!1}function Dn(e){if(e===void 0)return{ok:!0,value:void 0};try{return{ok:!0,value:JSON.parse(JSON.stringify(e))}}catch{return{ok:!1}}}function je(e,t){if(!e||typeof e.type!="string"||e.type.length===0)return{ok:!1,reason:"malformed",detail:"type is required"};if(e.schemaVersion!==void 0&&e.schemaVersion!==Re)return{ok:!1,reason:"malformed",detail:`unsupported schemaVersion ${String(e.schemaVersion)}`};let n=Pn(e);if(!n)return{ok:!1,reason:"malformed",detail:`cannot infer kind from type "${e.type}"`};let r=Dn(e.payload);if(!r.ok)return{ok:!1,reason:"malformed",detail:"payload is not JSON-serializable"};let a=t.createId(),o=typeof e.correlationId=="string"&&e.correlationId.length>0?e.correlationId:a,u=typeof e.causationId=="string"&&e.causationId.length>0?e.causationId:t.causationId,p=typeof e.target=="string"&&e.target.length>0?e.target:void 0,m=t.maxHops??Ve,C=t.parentHops===void 0?m:Math.max(0,t.parentHops-1),v=typeof e.idempotencyKey=="string"&&e.idempotencyKey.length>0?e.idempotencyKey:void 0,l={schemaVersion:Re,type:e.type,kind:n,source:t.source,id:a,correlationId:o,seq:t.seq,hops:C};return p&&(l.target=p),u&&(l.causationId=u),v&&(l.idempotencyKey=v),r.value!==void 0&&(l.payload=r.value),{ok:!0,envelope:l}}var In=new Set(["rate-limited","storm-detected","hop-limit","loop-detected","not-subscribed"]),Hn=8,Fn=8,Ln=16,On=256,_n=["*.intent.*"];function Ft(e={}){let t=e.hostSource??"host",n="router",r=e.maxPerTurn??Hn,a=e.maxCausationDepth??Fn,o=e.maxHops??Ve,u=e.maxCorrelationPerTurn??Ln,p=e.maxIndex??On,m=e.maxPerWindow,C=e.windowMs??1e3,v=e.now??Date.now,l=0,w=e.createId??(()=>`evt-${++l}`),E=new Map,b=[],M=new Map,h=new Map,K=new Map,$=0,J=0,F=[],d=!1;function T(s,c,S){for(s.set(c,S);s.size>p;){let k=s.keys().next().value;if(k===void 0)break;s.delete(k)}}function A(s){T(M,s.id,{type:s.type,source:s.source,causationId:s.causationId,hops:s.hops,correlationId:s.correlationId,idempotencyKey:s.idempotencyKey})}function D(s,c){c&&(s.correlationId||(s.correlationId=c.correlationId),s.causationId||(s.causationId=c.id),!s.idempotencyKey&&c.idempotencyKey&&(s.idempotencyKey=`${c.idempotencyKey}::${s.type}`))}function H(s,c){if(s){let S=M.get(s);return S?S.hops:o}return c}function W(s,c){return`${s}\0${c}`}function B(s,c){s.idempotencyKey&&T(K,W(s.source,s.idempotencyKey),c)}function te(s,c){if(c)return K.get(W(s,c))}function i(s){return te(s.source,s.idempotencyKey)}function g(s){return s.seq+=1,s.seq}function y(s,c){if(!(typeof c.causationId=="string"&&c.causationId.length>0))return s.lastDelivered}function x(s){let c=new Set,S=new Set([`${s.type}\0${s.source}`]),k=s.causationId,f=0;for(;k;){if(f+=1,f>a||c.has(k))return!0;c.add(k);let _=M.get(k);if(!_)break;let V=`${_.type}\0${_.source}`;if(S.has(V))return!0;S.add(V),k=_.causationId}return!1}function U(s){let c=(h.get(s)??0)+1;return h.set(s,c),c}function I(s,c){m!==void 0&&(s.emitTimestamps=s.emitTimestamps.filter(S=>c-S<C))}function P(s,c){return(c.kind==="state"||c.kind==="diagnostic")&&!s.authoritative?!1:de(s.emit,c.type)}function R(s){for(let c of b)if(de(c.patterns,s.type))try{c.listener(s)}catch{}}function L(s){if(s.target){let c=E.get(s.target);if(!c||!de(c.subscribe,s.type))return;c.channel.dispatch(s),c.lastDelivered={id:s.id,hops:s.hops,correlationId:s.correlationId,idempotencyKey:s.idempotencyKey};return}for(let c of E.values())de(c.subscribe,s.type)&&(c.channel.dispatch(s),c.lastDelivered={id:s.id,hops:s.hops,correlationId:s.correlationId,idempotencyKey:s.idempotencyKey})}function Y(s,c,S,k,f,_,V){let q={reason:k,eventType:c,source:S};f&&(q.detail=f),J+=1;let ue=w(),ne={schemaVersion:Re,type:fe,kind:"diagnostic",source:n,id:ue,correlationId:_??ue,seq:J,hops:0,payload:q};V&&(ne.causationId=V),A(ne);let qe=E.get(s);qe&&qe.channel.dispatch(ne),R(ne)}function O(s,c,S,k,f){Y(s,f?.type??(typeof c.type=="string"?c.type:""),f?.source??s,S,k,f?.correlationId,f?.id),f?.idempotencyKey&&!In.has(S)&&B(f,{status:"rejected"})}function X(s){A(s),B(s,{status:"accepted",envelope:s}),U(s.correlationId),R(s),L(s)}function Z(s,c,S,k){if(!S.ok){O(s,c,"malformed",S.detail);return}let f=S.envelope,_=i(f);if(_)return _.status==="accepted"?_.envelope:void 0;if(f.hops<1){O(s,c,"hop-limit","no hops remaining",f);return}if(f.target&&f.target!==t){let V=E.get(f.target);if(!V){O(s,c,"unknown-target",`unknown target "${f.target}"`,f);return}if(!de(V.subscribe,f.type)){O(s,c,"not-subscribed",`target "${f.target}" does not subscribe to ${f.type}`,f);return}}if(k){if(!P(k,f)){O(s,c,"unauthorized","source may not emit this event",f);return}if(k.emitsThisTurn+=1,k.emitsThisTurn>r){O(s,c,"rate-limited","maxPerTurn exceeded",f);return}if(m!==void 0){let q=v();if(I(k,q),k.emitTimestamps.push(q),k.emitTimestamps.length>m){O(s,c,"rate-limited","maxPerWindow exceeded",f);return}}if(x(f)){O(s,c,"loop-detected","causation chain cycle or depth exceeded",f);return}if((h.get(f.correlationId)??0)+1>u){O(s,c,"storm-detected","correlationId storm",f);return}if(e.validate){let q;try{q=e.validate(f)}catch(ue){let ne=ue instanceof Error?ue.message:"validate threw";O(s,c,"host-rejected",ne,f);return}if(q!==!0){O(s,c,"host-rejected",q.detail,f);return}}}else{if(x(f)){O(s,c,"loop-detected","causation chain cycle or depth exceeded",f);return}if((h.get(f.correlationId)??0)+1>u){O(s,c,"storm-detected","correlationId storm",f);return}}return X(f),f}function xe(s,c){let S=E.get(s);if(!S)return;let k={...c},f=y(S,k);if(D(k,f),te(S.id,k.idempotencyKey))return;let V=g(S),q=je(k,{source:S.id,createId:w,seq:V,causationId:f?.id,maxHops:o,parentHops:H(k.causationId??f?.id,f?.hops)});Z(s,k,q,S)}function Nt(s,c){let S=c?.cause,k={...s};D(k,S);let f=te(t,k.idempotencyKey);if(f)return f.status==="accepted"?f.envelope:void 0;$+=1;let _=je(k,{source:t,createId:w,seq:$,causationId:k.causationId,maxHops:o,parentHops:H(k.causationId,S?.hops)});return Z(t,k,_,void 0)}function Ut(){if(!d){d=!0;try{for(;F.length>0;){let s=F.shift();s&&(s.kind==="cart"?xe(s.participantId,s.event):s.result=Nt(s.event,s.extras))}}finally{d=!1}}}function ze(s){F.push(s),Ut()}return{attach(s,c,S={}){if(s===t||s===n)throw new Error(`createEventRouter: "${s}" is a reserved participant id`);for(let _ of E.values())if(_.channel===c&&_.id!==s)throw new Error(`createEventRouter: channel already attached as "${_.id}"`);E.get(s)?.unsubscribe();let f={id:s,channel:c,emit:S.emit??_n,subscribe:S.subscribe??[],authoritative:S.authoritative===!0,seq:0,emitsThisTurn:0,emitTimestamps:[],unsubscribe:()=>{}};f.unsubscribe=c.onEvent(_=>{ze({kind:"cart",participantId:s,event:_})}),E.set(s,f)},detach(s){let c=E.get(s);c&&(c.unsubscribe(),E.delete(s))},publish(s,c){let S={kind:"publish",event:s,extras:c};return ze(S),S.result},subscribe(s,c){let S={patterns:s,listener:c};return b.push(S),()=>{let k=b.indexOf(S);k>=0&&b.splice(k,1)}},turn(){h.clear();for(let s of E.values())s.emitsThisTurn=0,s.lastDelivered=void 0,m!==void 0&&I(s,v())}}}var Nn=320,Un=180,Kn="Runtime group has been destroyed";function $n(e){let t="";for(let n=0;n<32;n++){let r=e.charCodeAt(n%Math.max(e.length,1))+n*17&255;t+=r.toString(16).padStart(2,"0")}return`0x${t}`}function Wn(e,t){let n=document.createElement("div");return Object.defineProperty(n,"clientWidth",{value:e,configurable:!0}),Object.defineProperty(n,"clientHeight",{value:t,configurable:!0}),document.body.appendChild(n),n}function Ot(e){let t=e.capability,n={},r=e.emit??t?.emit,a=e.subscribe??t?.subscribe,o=e.authoritative??t?.authoritative;return r&&(n.emit=r),a&&(n.subscribe=a),o!==void 0&&(n.authoritative=o),n}function Lt(e){try{return JSON.parse(JSON.stringify(e))}catch{return e}}function Gn(e){let t=new Set([fe,"*.*","*.*.*","*.*.*.*","*.*.*.*.*"]);for(let n of e){let r=Ot(n);for(let a of r.emit??[])t.add(a);for(let a of r.subscribe??[])t.add(a)}return[...t]}function _t(e){if(!e.participants.length)throw new Error("createRuntimeGroup: at least one participant is required");let t=new Set;for(let d of e.participants){if(!d.id)throw new Error("createRuntimeGroup: participant id is required");if(t.has(d.id))throw new Error(`createRuntimeGroup: duplicate participant id "${d.id}"`);t.add(d.id)}let n=e.origin??0,r=e.width??Nn,a=e.height??Un,o=[...e.participants].sort((d,T)=>d.id.localeCompare(T.id)),u=[],p=new Map,m=0,C=e.createId??e.router?.createId??(()=>`evt-${++m}`),v=e.now??e.router?.now??(()=>{let d=u[0];if(!d)return n;try{return d.cart.getClock().now}catch{return n}}),l=Ft({...e.router,createId:C,now:v,validate:e.validate??e.router?.validate}),w=[],E=!1,b=!1,M=()=>{},h=d=>T=>{d.events.push(T),d.userOnEvent?.(T)},K=()=>{if(b)throw new Error(Kn)},$=()=>{M();for(let d of u){try{l.detach(d.id)}catch{}try{d.runtime.destroy()}catch{}d.ownsContainer&&d.container.remove()}u.length=0,p.clear()};try{for(let d of o){let T=d.width??r,A=d.height??a,D=!d.container,H=d.container??Wn(T,A),W=Se({container:H,seed:d.seed??$n(d.id),deterministic:{origin:n}}),B={id:d.id,kind:d.kind??"render",cartDef:d.cart,initialState:d.initialState,gameManager:d.gameManager,userOnEvent:d.onEvent,runtime:W,container:H,ownsContainer:D,cart:void 0,events:[],errors:[]};W.onError=(te,i)=>{B.errors.push({error:te,info:i})},l.attach(d.id,W.hostChannel,Ot(d)),B.cart=W.mount(d.cart,{initialState:d.initialState,gameManager:d.gameManager,onEvent:h(B)}),u.push(B),p.set(B.id,B)}M=l.subscribe(Gn(o),d=>{w.push(Lt(d))})}catch(d){throw $(),d}let J=d=>({id:d.id,kind:d.kind,runtime:d.runtime,container:d.container,get events(){return d.events.slice()},get errors(){return d.errors.slice()},get cart(){return d.cart}});return{router:l,origin:n,get paused(){return E},participant(d){K();let T=p.get(d);if(!T)throw new Error(`createRuntimeGroup: unknown participant "${d}"`);return J(T)},async step(d=1){if(K(),E)return;let T=Math.max(0,Math.floor(d));for(let A=0;A<T;A++){l.turn();for(let D of u)await D.cart.step(1)}},pause(){K(),E=!0;for(let d of u)d.cart.pause()},resume(){K(),E=!1;for(let d of u)d.cart.resume()},reset(){K(),w.length=0;for(let d of u)d.events.length=0,d.errors.length=0,d.cart=d.runtime.mount(d.cartDef,{initialState:d.initialState,gameManager:d.gameManager,onEvent:h(d)});l.turn()},dispatch(d,T){K();let A=p.get(d);if(!A)throw new Error(`createRuntimeGroup: unknown participant "${d}"`);A.cart.dispatch(T)},publish(d,T){return K(),l.publish(d,T)},async inspect(){K();let d={},T={};for(let D of u){let H=await D.cart.getReplayMetadata(),W=D.cart.getClock();T[D.id]=W,d[D.id]={state:H.state,events:D.events.slice(),errors:D.errors.slice(),kind:D.kind,clock:W}}let A=w.map(D=>Lt(D));return{participants:d,trace:A,diagnostics:{paused:E,participantIds:u.map(D=>D.id),clocks:T,rejections:A.filter(D=>D.type===fe).map(D=>D.payload)}}},destroy(){if(!b){b=!0,E=!1;try{$()}finally{w.length=0}}}}}function Bn(e){return ke(),_t(e)}export{Pt as DEFAULT_HEADLESS_HEIGHT,Tt as DEFAULT_HEADLESS_WIDTH,xt as HEADLESS_PNG_DATA_URL,Rn as createHeadlessHarness,Bn as createHeadlessMultiCartHarness,ke as installHeadlessCanvas};