@zylem/game-lib 0.8.9 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +7 -1
  2. package/dist/api/game-lib.api.json +37952 -19547
  3. package/dist/api/game-lib.api.md +1302 -7
  4. package/dist/api/game-lib.d.ts +1696 -3
  5. package/dist/api/game-lib.typedoc.json +174596 -76562
  6. package/dist/audio.d.ts +193 -1
  7. package/dist/audio.js +1 -1
  8. package/dist/bridge.d.ts +17 -2
  9. package/dist/bridge.js +1 -1
  10. package/dist/catalog.js +1 -1
  11. package/dist/chunk-2PFNNGTV.js +1 -0
  12. package/dist/chunk-2XMG3NJS.js +1 -0
  13. package/dist/chunk-4CZZZCFB.js +9 -0
  14. package/dist/chunk-7CBJKE42.js +1 -0
  15. package/dist/{chunk-CBUQBP2U.js → chunk-BQRMYLYD.js} +1 -1
  16. package/dist/chunk-FZNEWOC5.js +1 -0
  17. package/dist/chunk-GPCSX3M6.js +1 -0
  18. package/dist/chunk-K3NNXZIJ.js +1 -0
  19. package/dist/{chunk-JNFFTNMH.js → chunk-KSEP7AUF.js} +1 -1
  20. package/dist/{chunk-7JSZEEAE.js → chunk-LI43BZQN.js} +1 -1
  21. package/dist/chunk-NVVLLWIM.js +1 -0
  22. package/dist/chunk-QGIYILYI.js +1 -0
  23. package/dist/chunk-SHDHPDOV.js +24 -0
  24. package/dist/chunk-STVEILJJ.js +1 -0
  25. package/dist/chunk-SWDNK4GG.js +1 -0
  26. package/dist/chunk-UUOPT2N4.js +1 -0
  27. package/dist/chunk-VMXSE3EC.js +0 -0
  28. package/dist/{chunk-EYDC2PMO.js → chunk-VSFULLND.js} +1 -1
  29. package/dist/chunk-YNX3Q3CL.js +1 -0
  30. package/dist/chunk-ZZO4CKRU.js +1 -0
  31. package/dist/cinematics.d.ts +279 -0
  32. package/dist/cinematics.js +1 -0
  33. package/dist/core.d.ts +124 -10
  34. package/dist/core.js +1 -1
  35. package/dist/cutscene-definition-C479fkei.d.ts +509 -0
  36. package/dist/debug.d.ts +1 -0
  37. package/dist/debug.js +1 -1
  38. package/dist/{entity-type-map-D6BeAdvg.d.ts → entity-type-map-CrsrKT8c.d.ts} +12 -3
  39. package/dist/entity.d.ts +2 -1
  40. package/dist/entity.js +1 -1
  41. package/dist/game-D8KTP3fD.d.ts +652 -0
  42. package/dist/game-default-JV3Q6JAL.js +1 -0
  43. package/dist/graphics.d.ts +1 -1
  44. package/dist/graphics.js +1 -1
  45. package/dist/public.d.ts +12 -6
  46. package/dist/public.js +1 -1
  47. package/dist/schema/cutscene.schema.json +782 -0
  48. package/dist/schema/song.schema.json +430 -0
  49. package/dist/schema.d.ts +2 -0
  50. package/dist/schema.js +1 -1
  51. package/dist/selection-bounds-BKmSo9aG.d.ts +50 -0
  52. package/dist/song-definition-rEKksP0B.d.ts +263 -0
  53. package/dist/song-player-7QPLFLAS.js +1 -0
  54. package/dist/{game-DyKbOeck.d.ts → stage-CAPlk_cN.d.ts} +146 -647
  55. package/dist/web-components.d.ts +5 -3
  56. package/dist/web-components.js +1 -1
  57. package/dist/{zylem-camera-DZTpPOiD.d.ts → zylem-camera-CYDtrVgi.d.ts} +134 -102
  58. package/package.json +11 -4
  59. package/dist/chunk-34MYRTRP.js +0 -9
  60. package/dist/chunk-AXJTUVGC.js +0 -24
  61. package/dist/chunk-BWOZF5YK.js +0 -1
  62. package/dist/chunk-EVMLNMGU.js +0 -1
  63. package/dist/chunk-G3TBBZUI.js +0 -1
  64. package/dist/chunk-J6KD2G6F.js +0 -1
  65. package/dist/chunk-X7T7QRYP.js +0 -1
  66. package/dist/chunk-YVWDCZNT.js +0 -1
  67. package/dist/chunk-ZRT3ZQVH.js +0 -1
  68. package/dist/game-default-6YXFFZ2Q.js +0 -1
  69. /package/dist/{chunk-MSCVL5OK.js → chunk-ELQN62PQ.js} +0 -0
package/dist/audio.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  export { Howl } from 'howler';
2
+ import { q as TimeSignature, g as SongDefinition, l as SongTrack, n as NoteClip, o as AudioClip, h as InstrumentDefinition, r as SongLoop } from './song-definition-rEKksP0B.js';
3
+ export { A as AudioClipSchema, k as EffectType, E as Envelope, I as InstrumentDefinitionSchema, i as InstrumentEffect, a as InstrumentEffectSchema, j as InstrumentPreset, b as InstrumentPresetSchema, N as NoteClipSchema, O as OscillatorType, m as SongClip, d as SongClipSchema, S as SongDefinitionSchema, f as SongLoopSchema, p as SongNote, e as SongNoteSchema, c as SongTrackSchema, T as TimeSignatureSchema } from './song-definition-rEKksP0B.js';
4
+ import * as ToneNs from 'tone';
5
+ import '@sinclair/typebox';
2
6
 
3
7
  /**
4
8
  * Plays a ricochet sound effect when boundary collision occurs
@@ -10,4 +14,192 @@ declare function ricochetSound(frequency?: number, duration?: number): void;
10
14
  */
11
15
  declare function pingPongBeep(frequency?: number, duration?: number): void;
12
16
 
13
- export { pingPongBeep, ricochetSound };
17
+ /**
18
+ * Pure timing and scheduling math for songs. Everything here runs without
19
+ * an AudioContext so the player, the offline renderer and the editor agree
20
+ * on when things happen.
21
+ */
22
+ /** Quarter-note beats per bar: 4/4 → 4, 6/8 → 3, 3/4 → 3. */
23
+ declare function beatsPerBar(signature: TimeSignature): number;
24
+ declare function songLengthBeats(song: Pick<SongDefinition, 'lengthBars' | 'timeSignature'>): number;
25
+ declare function beatsToSeconds(beats: number, bpm: number): number;
26
+ declare function secondsToBeats(seconds: number, bpm: number): number;
27
+ declare function songLengthSeconds(song: Pick<SongDefinition, 'lengthBars' | 'timeSignature' | 'bpm'>): number;
28
+ /** MIDI pitch to Hz with A4 = 440. */
29
+ declare function midiToFrequency(pitch: number): number;
30
+ /** `60` → `C4`, the spelling Tone.js accepts as a note name. */
31
+ declare function midiToNoteName(pitch: number): string;
32
+ declare function dbToGain(db: number): number;
33
+ declare function gainToDb(gain: number): number;
34
+ /**
35
+ * Tracks that actually make sound: when any track is soloed only the soloed,
36
+ * unmuted ones play; otherwise everything not muted.
37
+ */
38
+ declare function audibleTrackIds(tracks: readonly SongTrack[]): Set<string>;
39
+ interface ScheduledNote {
40
+ trackId: string;
41
+ clipId: string;
42
+ instrumentId: string;
43
+ /** Seconds from the song start. */
44
+ time: number;
45
+ /** Seconds. */
46
+ duration: number;
47
+ pitch: number;
48
+ velocity: number;
49
+ }
50
+ interface ScheduledAudio {
51
+ trackId: string;
52
+ clipId: string;
53
+ url: string;
54
+ /** Seconds from the song start. */
55
+ time: number;
56
+ /** Seconds into the file. */
57
+ offset: number;
58
+ /** Seconds. */
59
+ duration: number;
60
+ /** dB. */
61
+ gain: number;
62
+ }
63
+ interface SongSchedule {
64
+ notes: ScheduledNote[];
65
+ audio: ScheduledAudio[];
66
+ /** Seconds. */
67
+ length: number;
68
+ }
69
+ interface ScheduleOptions {
70
+ /** Only schedule these tracks (mute/solo are still honored). */
71
+ trackIds?: Iterable<string>;
72
+ /** Ignore mute/solo and schedule every listed track. */
73
+ ignoreMix?: boolean;
74
+ }
75
+ /**
76
+ * Flattens a song into absolute note and audio events in seconds. Notes are
77
+ * clipped to their clip's length and to the song end; audio clips are
78
+ * clipped to the song end.
79
+ */
80
+ declare function scheduleSong(song: SongDefinition, options?: ScheduleOptions): SongSchedule;
81
+ /** Clips whose window covers `beat` on a track. */
82
+ declare function clipsAt(song: SongDefinition, trackId: string, beat: number): Array<NoteClip | AudioClip>;
83
+
84
+ /**
85
+ * Tone.js is loaded on demand so games without music never download it, and
86
+ * so the AudioContext is only started after a user gesture (browsers refuse
87
+ * to start one otherwise).
88
+ */
89
+ type ToneModule = typeof ToneNs;
90
+ /** Loads Tone.js (once) without touching the AudioContext. */
91
+ declare function loadTone(): Promise<ToneModule>;
92
+ /**
93
+ * Loads Tone.js and resumes the AudioContext. Call from a click or key
94
+ * handler the first time; later calls are cheap.
95
+ */
96
+ declare function ensureAudio(): Promise<ToneModule>;
97
+ /** True once `ensureAudio()` has successfully started the context. */
98
+ declare function isAudioReady(): boolean;
99
+
100
+ /**
101
+ * A playable instrument: a Tone.js synth for the preset, its effects chain,
102
+ * and an output node the song player routes into a track channel.
103
+ */
104
+ interface Instrument {
105
+ readonly definition: InstrumentDefinition;
106
+ /** Connect this to a channel or destination. */
107
+ readonly output: ToneNs.ToneAudioNode;
108
+ /** Plays a note. `time` is in the Tone context clock (seconds); omit for now. */
109
+ trigger(pitch: number, duration: number, time?: number, velocity?: number): void;
110
+ /** Silences ringing notes. */
111
+ releaseAll(time?: number): void;
112
+ dispose(): void;
113
+ }
114
+ /**
115
+ * Builds the synth and effects chain for an instrument definition. The
116
+ * returned `output` is not connected anywhere; the caller routes it.
117
+ */
118
+ declare function createInstrument(Tone: ToneModule, def: InstrumentDefinition): Instrument;
119
+
120
+ type SongPlayerState = 'stopped' | 'playing' | 'paused';
121
+ interface SongPlayerEvents {
122
+ /** Fires at the start of every bar with the 0-based bar index. */
123
+ bar: (bar: number) => void;
124
+ /** Fires at the start of every beat with the 0-based beat index. */
125
+ beat: (beat: number) => void;
126
+ /** Fires when a non-looping song reaches its end. */
127
+ complete: () => void;
128
+ state: (state: SongPlayerState) => void;
129
+ }
130
+ interface SongPlayerOptions {
131
+ /** Resolve clip URLs (for example, relative asset paths) before loading. */
132
+ resolveUrl?: (url: string) => string;
133
+ /** Route the master output here instead of the speakers. */
134
+ destination?: ToneNs.InputNode;
135
+ }
136
+ interface SongPlayer {
137
+ readonly definition: SongDefinition;
138
+ readonly state: SongPlayerState;
139
+ /** Resolves once Tone.js and every audio clip are loaded. */
140
+ readonly ready: Promise<void>;
141
+ /** Starts (or resumes) playback; needs a prior user gesture the first time. */
142
+ play(fromBeat?: number): Promise<void>;
143
+ pause(): void;
144
+ /** Stops and rewinds to the start. */
145
+ stop(): void;
146
+ seek(beat: number): void;
147
+ /** Playhead in beats. */
148
+ position(): number;
149
+ /** Playhead in seconds at the current tempo. */
150
+ seconds(): number;
151
+ setBpm(bpm: number): void;
152
+ setLoop(loop: SongLoop | null): void;
153
+ setTrackMute(trackId: string, mute: boolean): void;
154
+ setTrackSolo(trackId: string, solo: boolean): void;
155
+ /** dB. */
156
+ setTrackVolume(trackId: string, volume: number): void;
157
+ setTrackPan(trackId: string, pan: number): void;
158
+ /** dB. */
159
+ setMasterVolume(volume: number): void;
160
+ /** Plays one note on a track's instrument right now (for auditioning). */
161
+ preview(trackId: string, pitch: number, duration?: number, velocity?: number): Promise<void>;
162
+ /** Swaps in a new definition, keeping the playhead and state. */
163
+ update(definition: SongDefinition): Promise<void>;
164
+ on<K extends keyof SongPlayerEvents>(event: K, handler: SongPlayerEvents[K]): () => void;
165
+ dispose(): void;
166
+ }
167
+ /**
168
+ * Plays a song on Tone.js's transport. The transport is shared, so creating
169
+ * a player disposes the previous one: one song plays at a time. Tone.js is
170
+ * loaded lazily; the first `play()` must follow a user gesture.
171
+ */
172
+ declare function createSongPlayer(definition: SongDefinition, options?: SongPlayerOptions): SongPlayer;
173
+ /** The most recently created, still-live song player, if any. */
174
+ declare function getActiveSongPlayer(): SongPlayer | null;
175
+
176
+ interface RenderSongOptions {
177
+ /** Render only these tracks (mute/solo are ignored so a muted track can still be bounced). */
178
+ trackIds?: Iterable<string>;
179
+ sampleRate?: number;
180
+ /** Extra seconds after the song end so releases and reverb tails finish. */
181
+ tail?: number;
182
+ resolveUrl?: (url: string) => string;
183
+ }
184
+ /**
185
+ * Renders a song (or a subset of its tracks) to an `AudioBuffer` offline,
186
+ * faster than real time. Pair with `encodeWav` to get a file. Works without
187
+ * a user gesture: offline contexts do not need to be resumed.
188
+ */
189
+ declare function renderSong(song: SongDefinition, options?: RenderSongOptions): Promise<AudioBuffer>;
190
+
191
+ /**
192
+ * Minimal WAV (RIFF, 16-bit PCM) encoder for rendered audio. Works on any
193
+ * `AudioBuffer`-shaped object so it can run without a Web Audio context.
194
+ */
195
+ interface PcmSource {
196
+ numberOfChannels: number;
197
+ sampleRate: number;
198
+ length: number;
199
+ getChannelData(channel: number): Float32Array;
200
+ }
201
+ declare function encodeWav(buffer: PcmSource): ArrayBuffer;
202
+ /** `encodeWav` as a `Blob` ready for upload or download. */
203
+ declare function encodeWavBlob(buffer: PcmSource): Blob;
204
+
205
+ export { AudioClip, type Instrument, InstrumentDefinition, NoteClip, type PcmSource, type RenderSongOptions, type ScheduleOptions, type ScheduledAudio, type ScheduledNote, SongDefinition, SongLoop, type SongPlayer, type SongPlayerEvents, type SongPlayerOptions, type SongPlayerState, type SongSchedule, SongTrack, TimeSignature, type ToneModule, audibleTrackIds, beatsPerBar, beatsToSeconds, clipsAt, createInstrument, createSongPlayer, dbToGain, encodeWav, encodeWavBlob, ensureAudio, gainToDb, getActiveSongPlayer, isAudioReady, loadTone, midiToFrequency, midiToNoteName, pingPongBeep, renderSong, ricochetSound, scheduleSong, secondsToBeats, songLengthBeats, songLengthSeconds };
package/dist/audio.js CHANGED
@@ -1 +1 @@
1
- import{a,b,c}from"./chunk-ZRT3ZQVH.js";import"./chunk-WOT6VMZA.js";export{c as Howl,b as pingPongBeep,a as ricochetSound};
1
+ import{a as s,b as t,c as F,d as G,e as H,f as I}from"./chunk-ZZO4CKRU.js";import{a as u,b as v,c as w,d as x,e as y,f as z,g as A,h as B,i as C,j as D,k as E}from"./chunk-NVVLLWIM.js";import{a as m,c as n,d as o,e as p,f as q,g as r}from"./chunk-2PFNNGTV.js";import{a,b,c,d,e,f,g,h,i,j,k,l}from"./chunk-QGIYILYI.js";import"./chunk-WOT6VMZA.js";export{A as AudioClipSchema,I as Howl,w as InstrumentDefinitionSchema,v as InstrumentEffectSchema,u as InstrumentPresetSchema,z as NoteClipSchema,B as SongClipSchema,E as SongDefinitionSchema,D as SongLoopSchema,x as SongNoteSchema,y as SongTrackSchema,C as TimeSignatureSchema,j as audibleTrackIds,a as beatsPerBar,c as beatsToSeconds,l as clipsAt,m as createInstrument,q as createSongPlayer,h as dbToGain,G as encodeWav,H as encodeWavBlob,o as ensureAudio,i as gainToDb,r as getActiveSongPlayer,p as isAudioReady,n as loadTone,f as midiToFrequency,g as midiToNoteName,t as pingPongBeep,F as renderSong,s as ricochetSound,k as scheduleSong,d as secondsToBeats,b as songLengthBeats,e as songLengthSeconds};
package/dist/bridge.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { BridgePose, SceneOperationPayload, BridgeNdc, EntitySummaryPayload, EntityApplySwatchPayload, SwatchApplyResult, SceneOperationEntry, GameConfigPayload, GameLoadingPayload, GameVariablePayload, GameNoticePayload, StageSnapshotPayload, EntityThumbnailPayload, EntityTypeDescriptor } from '@zylem/bridge';
2
- export { BRIDGE_READY_EVENT, BridgeChannel, BridgeDebugTool, BridgeHandler, GameLoadingPayload as BridgeLoadingPayload, BridgeMessageType, BridgeMessages, BridgeNdc, BridgeVec3, EditorToGameMessages, EntityApplySwatchPayload, EntityPickPayload, EntityPickResultPayload, EntitySummaryPayload, EntitySwatchAppliedPayload, EntityThumbnailPayload, GameConfigPayload, GameToEditorMessages, GameVariablePayload, StageConfigPayload, StageSnapshotPayload, SwatchApplyFailureReason, SwatchApplyResult, SwatchKind, SwatchSpec, ZylemBridge, announceBridgeReady, applySwatchesToSelection, getZylemBridge } from '@zylem/bridge';
1
+ import { BridgePose, SceneOperationPayload, BridgeNdc, EntitySummaryPayload, EntityApplySwatchPayload, SwatchApplyResult, SceneOperationEntry, CutsceneLoadPayload, CameraPosePayload, CutsceneStatusPayload, CutsceneViewPayload, GameConfigPayload, GameLoadingPayload, GameVariablePayload, GameNoticePayload, StageSnapshotPayload, EntityThumbnailPayload, EntityTypeDescriptor } from '@zylem/bridge';
2
+ export { BRIDGE_READY_EVENT, BridgeChannel, BridgeDebugTool, BridgeHandler, GameLoadingPayload as BridgeLoadingPayload, BridgeMessageType, BridgeMessages, BridgeNdc, BridgeVec3, CameraPosePayload, CutsceneLoadPayload, CutscenePlaybackState, CutsceneStatusPayload, CutsceneViewPayload, EditorToGameMessages, EntityApplySwatchPayload, EntityPickPayload, EntityPickResultPayload, EntitySummaryPayload, EntitySwatchAppliedPayload, EntityThumbnailPayload, GameConfigPayload, GameToEditorMessages, GameVariablePayload, StageConfigPayload, StageSnapshotPayload, SwatchApplyFailureReason, SwatchApplyResult, SwatchKind, SwatchSpec, ZylemBridge, announceBridgeReady, applySwatchesToSelection, getZylemBridge } from '@zylem/bridge';
3
3
  import { G as GameEntity } from './entity-XqvuWgPm.js';
4
4
  import 'three';
5
5
  import '@zylem/behaviors/core';
@@ -51,6 +51,17 @@ interface GameBridgeHost {
51
51
  applySwatches?(payload: EntityApplySwatchPayload & {
52
52
  opId: string;
53
53
  }): SwatchApplyOutcome;
54
+ /** Cutscene preview hooks (`cutscene:*`); publish progress via `publishCutsceneStatus`. */
55
+ cutscene?: {
56
+ load(payload: CutsceneLoadPayload): void;
57
+ play(from?: number): void;
58
+ pause(): void;
59
+ stop(): void;
60
+ seek(time: number): void;
61
+ unload(): void;
62
+ };
63
+ /** Describe the live camera (`camera:pose:get`), for capturing framing into a cutscene. */
64
+ cameraPose?(): Omit<CameraPosePayload, 'requestId'> | null;
54
65
  }
55
66
  /** What a host reports back from a swatch batch. */
56
67
  interface SwatchApplyOutcome {
@@ -79,6 +90,10 @@ declare class GameBridge {
79
90
  * @param announceTarget DOM node the `zylem:bridge:ready` event bubbles from
80
91
  */
81
92
  connect(host: GameBridgeHost, announceTarget?: EventTarget): void;
93
+ /** Cutscene playback progress for Director mode's transport. */
94
+ publishCutsceneStatus(status: CutsceneStatusPayload): void;
95
+ /** The previewing camera's projection, for Director mode's viewport overlays. */
96
+ publishCutsceneView(view: CutsceneViewPayload): void;
82
97
  disconnect(): void;
83
98
  /**
84
99
  * Run a swatch batch and report back.
package/dist/bridge.js CHANGED
@@ -1 +1 @@
1
- import{a as b,b as c,c as d,d as e}from"./chunk-J6KD2G6F.js";import{g as a}from"./chunk-G3TBBZUI.js";import"./chunk-CBUQBP2U.js";import"./chunk-EVMLNMGU.js";import"./chunk-WOT6VMZA.js";export{e as BRIDGE_READY_EVENT,a as GameBridge,c as announceBridgeReady,d as applySwatchesToSelection,b as getZylemBridge};
1
+ import{a as b,b as c,c as d,d as e}from"./chunk-FZNEWOC5.js";import{h as a}from"./chunk-7CBJKE42.js";import"./chunk-BQRMYLYD.js";import"./chunk-GPCSX3M6.js";import"./chunk-WOT6VMZA.js";export{e as BRIDGE_READY_EVENT,a as GameBridge,c as announceBridgeReady,d as applySwatchesToSelection,b as getZylemBridge};
package/dist/catalog.js CHANGED
@@ -1 +1 @@
1
- import{a,b as S,c as T}from"./chunk-EYDC2PMO.js";import{a as t,b as e,c as r,d as i,e as o,f as y,g as c,h as s,i as p,j as h,k as n,l as g,m as w,n as u,o as E}from"./chunk-2HSR5XDQ.js";import"./chunk-X7T7QRYP.js";import"./chunk-KP6DLLJO.js";import"./chunk-6FGXC4T6.js";import"./chunk-AIQ6IVT5.js";import"./chunk-QXVH6POE.js";import"./chunk-EVYHPR3J.js";import"./chunk-VUJXR5K5.js";import"./chunk-4QLJUQSJ.js";import"./chunk-7WRQ2UAN.js";import"./chunk-XRP4JJXL.js";import"./chunk-WOT6VMZA.js";export{a as BUILT_IN_ENTITY_TYPES,o as buildCatalogDescriptors,c as clearEntityRegistry,w as clearSwatchRegistry,r as getEntityType,h as getSwatchSource,u as isBehaviorDescriptor,i as listEntityTypes,n as listSwatchSources,y as onEntityRegistryChanged,g as onSwatchRegistryChanged,T as registerBuiltInBehaviorSwatchSources,S as registerBuiltInEntityTypes,t as registerEntityType,e as registerEntityTypes,s as registerSwatchSource,p as registerSwatchSources,E as registerSwatchSourcesFromModule};
1
+ import{a,b as S,c as T}from"./chunk-VSFULLND.js";import{a as t,b as e,c as r,d as i,e as o,f as y,g as c,h as s,i as p,j as h,k as n,l as g,m as w,n as u,o as E}from"./chunk-2HSR5XDQ.js";import"./chunk-STVEILJJ.js";import"./chunk-KP6DLLJO.js";import"./chunk-6FGXC4T6.js";import"./chunk-AIQ6IVT5.js";import"./chunk-QXVH6POE.js";import"./chunk-UUOPT2N4.js";import"./chunk-EVYHPR3J.js";import"./chunk-VUJXR5K5.js";import"./chunk-4QLJUQSJ.js";import"./chunk-7WRQ2UAN.js";import"./chunk-XRP4JJXL.js";import"./chunk-WOT6VMZA.js";export{a as BUILT_IN_ENTITY_TYPES,o as buildCatalogDescriptors,c as clearEntityRegistry,w as clearSwatchRegistry,r as getEntityType,h as getSwatchSource,u as isBehaviorDescriptor,i as listEntityTypes,n as listSwatchSources,y as onEntityRegistryChanged,g as onSwatchRegistryChanged,T as registerBuiltInBehaviorSwatchSources,S as registerBuiltInEntityTypes,t as registerEntityType,e as registerEntityTypes,s as registerSwatchSource,p as registerSwatchSources,E as registerSwatchSourcesFromModule};
@@ -0,0 +1 @@
1
+ import{b as A,c as P,g as V,k as L}from"./chunk-QGIYILYI.js";var O={attack:.01,decay:.2,sustain:.5,release:.4};function Q(r,a){let n=a.envelope??O,l={type:a.oscillator??"triangle"},u=a.volume??-6;switch(a.preset){case"polySynth":return{synth:new r.PolySynth(r.Synth,{oscillator:l,envelope:n,volume:u}),pitched:!0};case"fmSynth":return{synth:new r.FMSynth({oscillator:l,envelope:n,volume:u}),pitched:!0};case"amSynth":return{synth:new r.AMSynth({oscillator:l,envelope:n,volume:u}),pitched:!0};case"membraneSynth":return{synth:new r.MembraneSynth({envelope:n,volume:u,octaves:6,pitchDecay:.05}),pitched:!0};case"metalSynth":return{synth:new r.MetalSynth({envelope:{attack:n.attack,decay:n.decay,release:n.release},volume:u}),pitched:!0};case"noiseSynth":return{synth:new r.NoiseSynth({envelope:{attack:n.attack,decay:n.decay,sustain:n.sustain,release:n.release},volume:u}),pitched:!1};case"pluckSynth":return{synth:new r.PluckSynth({volume:u,release:n.release}),pitched:!0};default:return{synth:new r.Synth({oscillator:l,envelope:n,volume:u}),pitched:!0}}}function C(r,a){let n=a.options??{},l=a.wet??1;switch(a.type){case"reverb":return new r.Reverb({decay:S(n.decay,2),preDelay:S(n.preDelay,.01),wet:l});case"delay":return new r.FeedbackDelay({delayTime:S(n.delayTime,.25),feedback:S(n.feedback,.35),wet:l});case"distortion":return new r.Distortion({distortion:S(n.distortion,.4),wet:l});case"filter":return new r.Filter({frequency:S(n.frequency,1200),type:typeof n.type=="string"?n.type:"lowpass",Q:S(n.Q,1)});default:return new r.Gain(1)}}function S(r,a){return typeof r=="number"&&Number.isFinite(r)?r:a}function R(r,a){let{synth:n,pitched:l}=Q(r,a),u=(a.effects??[]).map(c=>C(r,c)),t=new r.Gain(1);return u.length>0?n.chain(...u,t):n.connect(t),{definition:a,output:t,trigger(c,p,m,o=.8){let d=Math.max(.01,p);l?n.triggerAttackRelease(V(c),d,m,o):n.triggerAttackRelease(d,m,o)},releaseAll(c){n.releaseAll?n.releaseAll(c):n.triggerRelease?.(c)},dispose(){n.dispose();for(let c of u)c.dispose();t.dispose()}}}function K(r,a,n){let l=new Map,u=new Map,t=[],c=[],p=new Map(a.instruments.map(o=>[o.id,o]));for(let o of a.tracks){let d=new r.Channel({volume:o.volume??0,pan:o.pan??0,mute:o.mute??!1,solo:o.solo??!1});if(d.connect(n.master),l.set(o.id,d),o.kind==="instrument"&&o.instrumentId){let f=p.get(o.instrumentId);if(f){let y=R(r,f);y.output.connect(d),u.set(o.id,y)}}}let m=new Map;for(let o of n.schedule.notes){let d=m.get(o.trackId)??[];d.push({time:o.time,pitch:o.pitch,duration:o.duration,velocity:o.velocity}),m.set(o.trackId,d)}for(let[o,d]of m){let f=u.get(o);if(!f)continue;let y=new r.Part((g,v)=>{f.trigger(v.pitch,v.duration,g,v.velocity)},d);y.start(0),t.push(y)}for(let o of n.schedule.audio){let d=l.get(o.trackId);if(!d)continue;let f=n.resolveUrl?n.resolveUrl(o.url):o.url,y=n.buffers?.get(o.url)??n.buffers?.get(f),g=y?new r.Player(y):new r.Player(f);g.volume.value=o.gain,g.connect(d),g.sync().start(o.time,o.offset,o.duration),c.push(g)}return{channels:l,instruments:u,parts:t,players:c,dispose(){for(let o of t)o.dispose();for(let o of c)o.unsync(),o.dispose();for(let o of u.values())o.dispose();for(let o of l.values())o.dispose()}}}var N=null,I=!1;function D(){return N||(N=import("tone").then(r=>{let a=r;return typeof a.start=="function"?a:a.default??a})),N}async function x(){let r=await D();if(!I||r.getContext().state!=="running")try{await r.start(),I=!0}catch{}return r}function $(){return I}var w=null;function Y(r,a={}){w?.dispose();let n=r,l="stopped",u=null,t=null,c=null,p=null,m=!1,o=[],d={bar:new Set,beat:new Set,complete:new Set,state:new Set},f=new Map,y=(e,...i)=>{for(let s of d[e])s(...i)},g=e=>{l!==e&&(l=e,y("state",e))},v=()=>n.timeSignature.numerator*4/n.timeSignature.denominator,E=()=>{if(t){for(let e of o)t.clear(e);o.length=0}},B=async e=>{let i=new Set(n.clips.flatMap(s=>s.kind==="audio"?[s.url]:[]));await Promise.all([...i].map(async s=>{if(f.has(s))return;let h=a.resolveUrl?a.resolveUrl(s):s;try{f.set(s,await e.ToneAudioBuffer.fromUrl(h))}catch(b){console.warn(`[zylem/audio] could not load "${h}"`,b)}}))},G=e=>{if(!t||!c)return;p?.dispose(),E(),t.bpm.value=n.bpm,t.timeSignature=[n.timeSignature.numerator,n.timeSignature.denominator],c.volume.value=n.masterVolume??0;let i=L(n);p=K(e,n,{master:c,schedule:i,buffers:f,resolveUrl:a.resolveUrl}),T(n.loop??null);let s=i.length;o.push(t.schedule(()=>{t?.loop||e.getDraw().schedule(()=>{U(),y("complete")},e.now())},s)),o.push(t.scheduleRepeat(h=>{let b=Math.round(t.getSecondsAtTime(h)/P(1,t.bpm.value));e.getDraw().schedule(()=>{y("beat",b),b%v()===0&&y("bar",Math.floor(b/v()))},h)},"4n",0))},T=e=>{t&&(e?.enabled&&e.end>e.start?(t.loopStart=P(e.start,t.bpm.value),t.loopEnd=P(e.end,t.bpm.value),t.loop=!0):t.loop=!1)},k=(async()=>{let e=await D();m||(u=e,t=e.getTransport(),t.stop(),t.cancel(),t.position=0,c=new e.Volume(n.masterVolume??0),c.connect(a.destination??e.getDestination()),await B(e),!m&&G(e))})(),F=e=>t?e/t.PPQ:0,U=()=>{if(t){t.stop(),t.position=0;for(let e of p?.instruments.values()??[])e.releaseAll();g("stopped")}},M={get definition(){return n},get state(){return l},ready:k,async play(e){m||(await x(),await k,!(m||!t)&&(e!==void 0&&(t.ticks=Math.max(0,e)*t.PPQ),t.start(),g("playing")))},pause(){if(!(!t||l!=="playing")){t.pause();for(let e of p?.instruments.values()??[])e.releaseAll();g("paused")}},stop:U,seek(e){if(!t)return;let i=Math.min(Math.max(0,e),A(n));t.ticks=i*t.PPQ;for(let s of p?.instruments.values()??[])s.releaseAll()},position(){return t?F(t.ticks):0},seconds(){return t?t.seconds:0},setBpm(e){n={...n,bpm:e},t&&(t.bpm.value=e,T(n.loop??null))},setLoop(e){n={...n,loop:e??void 0},T(e)},setTrackMute(e,i){let s=p?.channels.get(e);s&&(s.mute=i)},setTrackSolo(e,i){let s=p?.channels.get(e);s&&(s.solo=i)},setTrackVolume(e,i){let s=p?.channels.get(e);s&&(s.volume.value=i)},setTrackPan(e,i){let s=p?.channels.get(e);s&&(s.pan.value=i)},setMasterVolume(e){n={...n,masterVolume:e},c&&(c.volume.value=e)},async preview(e,i,s=.4,h=.8){await x(),await k,p?.instruments.get(e)?.trigger(i,s,void 0,h)},async update(e){if(n=e,await k,m||!u||!t)return;let i=l==="playing",s=t.ticks;i&&t.pause(),await B(u),!m&&(G(u),t.ticks=Math.min(s,A(n)*t.PPQ),i&&t.start())},on(e,i){return d[e].add(i),()=>{d[e].delete(i)}},dispose(){if(!m){m=!0,t&&(t.stop(),E(),t.loop=!1),p?.dispose(),p=null,c?.dispose(),c=null;for(let e of Object.keys(d))d[e].clear();w===M&&(w=null),l="stopped"}}};return w=M,M}function Z(){return w}export{R as a,K as b,D as c,x as d,$ as e,Y as f,Z as g};
@@ -0,0 +1 @@
1
+ import{b as R}from"./chunk-7GYFZKK7.js";import{b as K}from"./chunk-QGIYILYI.js";import{Vector3 as L}from"three";var I="cutscene",w=class{priority=1e3;enabled=!1;target=null;smoothed=null;damping=0;setPose(t,e=0){this.target=t,this.damping=e,this.enabled=t!==null,t||(this.smoothed=null)}snap(){this.smoothed=null}onDetach(){this.smoothed=null}update(t,e){let i=this.target;if(!i)return e;let a=new L(i.position.x,i.position.y,i.position.z),s=new L(i.lookAt.x,i.lookAt.y,i.lookAt.z);if(this.damping>0&&this.smoothed){let r=1-Math.pow(this.damping,t.dt*60);this.smoothed.position.lerp(a,r),this.smoothed.lookAt.lerp(s,r)}else this.smoothed={position:a.clone(),lookAt:s.clone()};return{...e,position:this.smoothed.position.clone(),lookAt:this.smoothed.lookAt.clone(),fov:i.fov}}};import{CatmullRomCurve3 as oe,Vector3 as re}from"three";function z(n,t){let e=Math.min(1,Math.max(0,t));switch(n){case"easeIn":return e*e;case"easeOut":return 1-(1-e)*(1-e);case"easeInOut":return e<.5?2*e*e:1-(-2*e+2)**2/2;default:return e}}function x(n,t,e){return{x:n.x+(t.x-n.x)*e,y:n.y+(t.y-n.y)*e,z:n.z+(t.z-n.z)*e}}function ae(n,t,e){return{position:x(n.position,t.position,e),lookAt:x(n.lookAt,t.lookAt,e),fov:n.fov+(t.fov-n.fov)*e}}function se(n,t){let e;for(let i of n)t>=i.start&&t<i.end&&(e=i);return e??n[n.length-1]}function le(n,t){let e;for(let i of n)t>=i.start&&t<i.end&&(e=i);return e}function ue(n,t){for(let e of n.tracks){if(e.kind!=="camera")continue;let i=le(e.items,t);if(i)return i}}function ce(n,t){let e;for(let i of n.tracks)if(i.kind==="camera")for(let a of i.items)a.id===t.id||a.end>t.start+1e-6||(!e||a.end>e.end)&&(e=a);return e}var F=new WeakMap;function de(n){let t=JSON.stringify([n.points,n.closed,n.tension]),e=F.get(n);if(e&&e.key===t)return e.curve;let i=new oe(n.points.map(a=>new re(a.x,a.y,a.z)),n.closed,n.tension===.5?"centripetal":"catmullrom",n.tension);return F.set(n,{key:t,curve:i}),i}function q(n,t){if(n.points.length<2)return{...n.points[0]??{x:0,y:0,z:0}};let e=de(n).getPointAt(Math.min(1,Math.max(0,t)));return{x:e.x,y:e.y,z:e.z}}function we(n,t=32){let e=[];for(let i=0;i<=t;i+=1)e.push(q(n,i/t));return e}function M(n,t,e,i,a,s){let r={value:e,time:i},c=!0,u;for(let p of n){let y=t(p);y!==void 0&&(p.time<=a?(c||p.time>=r.time)&&(r={value:y,time:p.time},c=!1):(!u||p.time<u.time)&&(u={value:y,time:p.time,easing:p.easing}))}if(!u)return r.value;let f=u.time-r.time,d=f<=0?1:(a-r.time)/f;return s(r.value,u.value,z(u.easing,d))}function N(n,t,e,i,a){let s={...n.pose.position},r={...n.pose.lookAt},c=n.target?a?.(n.target):void 0;if(n.kind==="dolly"&&n.dollyId){let d=t.dollies.find(p=>p.id===n.dollyId);if(d){let p=e.end-e.start,y=p<=0?1:(i-e.start)/p;s=q(d,z(n.dollyEasing,y))}c&&(r=c)}else if(n.kind==="follow"&&c){let d=n.offset??{x:0,y:3,z:8};s={x:c.x+d.x,y:c.y+d.y,z:c.z+d.z},r=c}let u=[...n.keyframes].sort((d,p)=>d.time-p.time);s=M(u,d=>d.position,s,e.start,i,x),r=M(u,d=>d.lookAt,r,e.start,i,x);let f=M(u,d=>d.fov,n.fov,e.start,i,(d,p,y)=>d+(p-d)*y);return{position:s,lookAt:r,fov:f}}function T(n,t,e){let i=se(n.scenes,t),a=ue(n,t);if(!a)return{scene:i,shot:void 0,camera:void 0,pose:void 0,blend:1};let s=n.cameras.find(u=>u.id===a.cameraId);if(!s)return{scene:i,shot:a,camera:void 0,pose:void 0,blend:1};let r=N(s,n,a,t,e),c=1;if(a.blend.duration>0&&t<a.start+a.blend.duration){let u=ce(n,a),f=u?n.cameras.find(d=>d.id===u.cameraId):void 0;if(u&&f){let d=N(f,n,u,Math.min(t,u.end),e);c=z(a.blend.easing,(t-a.start)/a.blend.duration),r=ae(d,r,c)}}return{scene:i,shot:a,camera:s,pose:r,blend:c}}function O(n,t,e){return n.filter(i=>i.time>t&&i.time<=e).sort((i,a)=>i.time-a.time)}function xe(n){return n.tracks.filter(t=>t.kind==="camera")}function _(n){return Math.max(n.duration,...n.scenes.map(t=>t.end))}import{PerspectiveCamera as fe,Vector3 as pe}from"three";var me=1e-6;function J(n,t){let{host:e}=t,i=new w,a=n,s="idle",r=0,c,u,f,d=null,p=.15,y=0,g=0,v=!1,k={time:new Set,state:new Set,scene:new Set,shot:new Set,event:new Set,audio:new Set,complete:new Set,skip:new Set},h=(o,...l)=>{for(let m of k[o])try{m(...l)}catch(V){console.error(`CutscenePlayer: ${o} listener failed`,V)}},S=o=>{s!==o&&(s=o,h("state",o))},$=()=>{let o=e.camera();!o||o===d||(E(),d=o,p=o.pipeline.damping,o.pipeline.damping=1,o.pipeline.addBehavior(I,i))},E=()=>{d&&(d.pipeline.removeBehavior(I),d.pipeline.damping=p,d=null,i.setPose(null))},G=o=>{let l=d?.camera;l&&(l.position.set(o.position.x,o.position.y,o.position.z),l.lookAt(new pe(o.lookAt.x,o.lookAt.y,o.lookAt.z)),l instanceof fe&&(l.fov=o.fov,l.updateProjectionMatrix()))},A=o=>e.entityPosition?.(o),P=(o={})=>{$();let l=T(a,r,A);c=l.pose;let m=l.camera?.kind==="follow"?Math.min(.98,l.camera.damping):0;return i.setPose(c??null,m),o.snap&&(i.snap(),c&&G(c)),l.shot?.id!==f&&(f=l.shot?.id,h("shot",l.shot)),l},X=o=>{let{event:l}=o;try{switch(l.type){case"emit":e.dispatch?.(l.name,l.payload);break;case"playAnimation":e.playAnimation?.(l.entity,l.key);break;case"playSong":e.playSong?.(l.song,{loop:l.loop,volume:0});break;case"stopSong":e.stopSong?.(l.song);break;case"setVariable":e.setVariable?.(l.name,l.value);break;default:break}}catch(m){console.error("CutscenePlayer: event failed",o,m)}h("event",o)},ee=o=>{try{o.kind==="song"?e.playSong?.(o.ref,{loop:o.loop,volume:o.volume}):e.playSfx?.(o.ref,{volume:o.volume,loop:o.loop})}catch(l){console.error("CutscenePlayer: audio failed",o,l)}h("audio",o)},te=(o,l)=>{for(let m of a.tracks)m.kind==="event"?O(m.items,o,l).forEach(X):m.kind==="audio"&&O(m.items,o,l).forEach(ee)},ne=o=>t.transitionShader?.(o),Z=(o,l)=>{if(o?.id===u)return;let m=u;u=o?.id,o&&l.transition&&m!==void 0&&o.transitionIn.type!=="cut"&&e.beginTransition?.(o.transitionIn,ne(o.transitionIn.type)),h("scene",o)},C=()=>_(a),D=(o,l,m)=>{r=Math.min(Math.max(0,l),C());let V=T(a,r,A).scene;Z(V,{transition:m.transitions}),P({snap:!m.transitions}),m.fireEvents&&te(o,r),h("time",r),r>=C()-me&&s==="playing"&&j()},j=()=>{S("finished"),b(),h("complete")},B=o=>{if(v||s!=="playing")return;let l=g?Math.min(.1,(o-g)/1e3):0;g=o,H.update(l),s==="playing"&&(y=requestAnimationFrame(B))},ie=()=>{t.tick==="manual"||typeof requestAnimationFrame!="function"||(cancelAnimationFrame(y),g=0,y=requestAnimationFrame(B))},b=()=>{typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(y),g=0},H={get definition(){return a},get state(){return s},get time(){return r},get length(){return C()},get pose(){return c},play(o){v||(o!==void 0&&(r=Math.min(Math.max(0,o),C()),u=void 0),s==="finished"&&o===void 0&&(r=0,u=void 0),S("playing"),Z(T(a,r,A).scene,{transition:!1}),P({snap:!0}),h("time",r),ie())},pause(){s==="playing"&&(S("paused"),b())},stop(){b(),r=0,u=void 0,f=void 0,c=void 0,E(),S("idle"),h("time",0)},seek(o){if(v)return;D(r,o,{fireEvents:!!t.fireEventsOnSeek,transitions:!1}),(s==="idle"||s==="finished")&&S("paused")},skip(){return!a.skippable||v?!1:(h("skip"),D(r,C(),{fireEvents:!1,transitions:!1}),s!=="finished"&&j(),!0)},update(o){if(v||s!=="playing")return;let l=o*(t.timeScale??1);if(l<=0){P();return}D(r,r+l,{fireEvents:!0,transitions:!0})},setDefinition(o){a=o,s!=="idle"&&P({snap:s!=="playing"})},on(o,l){return k[o].add(l),()=>k[o].delete(l)},dispose(){if(!v){v=!0,b(),E();for(let o of Object.values(k))o.clear()}}};return H}import{Howl as ye}from"howler";var W=null;function Oe(n){W=n}function he(n){return"wrappedStage"in n?n.wrappedStage:n}function ve(n){let t=n?.group??n?.mesh;if(t)return{x:t.position.x,y:t.position.y,z:t.position.z}}function U(n,t={}){let e=()=>he(n),i=new Map,a=new Set,s=r=>{for(let[c,u]of i)r!==void 0&&c!==r||(u.stop(),u.dispose(),i.delete(c))};return{camera:()=>e()?.cameraRef??null,entityPosition:r=>ve(e()?.getEntityByName(r)),playAnimation:(r,c)=>{e()?.getEntityByName(r)?.playAnimation?.({key:c})},dispatch:(r,c)=>{t.onEvent?.(r,c),e()?.wrapperRef?.dispatch?.(r,c)},setVariable:(r,c)=>{let u=e()?.state;u&&(u.variables[r]=c)},playSong:(r,{loop:c,volume:u})=>{t.resolveSong&&(async()=>{let f=await t.resolveSong(r);if(!f)return;let d=await import("./song-player-7QPLFLAS.js");s(r);let p=d.createSongPlayer({...f,loop:c?{enabled:!0,start:0,end:K(f)}:f.loop,masterVolume:(f.masterVolume??0)+u});i.set(r,p),await p.play()})().catch(f=>console.error("Cutscene: could not play song",r,f))},stopSong:s,playSfx:(r,{volume:c,loop:u})=>{let f=new ye({src:[r],volume:Math.pow(10,c/20),loop:u,html5:!0});a.add(f),f.once("end",()=>{u||a.delete(f)}),f.play()},beginTransition:(r,c)=>{let u=e(),f=u?.rendererManager,d=u?.scene?.scene,p=u?.cameraRef?.camera;!f||!d||!p||f.beginInStageTransition(R({duration:r.duration,easing:r.easing==="linear"?"linear":"easeInOut",shader:c??t.transitionShader?.(r.type)??W?.(r.type)}),d,p)}}}import{Matrix4 as Y,PerspectiveCamera as ge,Vector3 as Se}from"three";var Q=class{constructor(t,e,i={},a){this.getStage=t;this.publish=e;this.hostOptions=i;this.publishView=a}player=null;lastStatus=null;pending=null;viewInverse=new Y;viewProjection=new Y;lastView=null;get active(){return this.player!==null}stageReady(){let t=this.pending;t&&(this.pending=null,this.load(t))}load(t){let e=t.definition;if(!Array.isArray(e?.tracks)||!Array.isArray(e?.cameras)){console.warn("CutscenePreview: ignoring malformed cutscene definition");return}if(this.player&&this.player.definition.id===e.id)this.player.setDefinition(e);else{this.unload();let i=this.getStage();if(!i){this.pending=t;return}let a=J(e,{host:U(i,this.hostOptions),fireEventsOnSeek:!1});a.on("time",()=>this.report()),a.on("state",()=>this.report()),a.on("shot",()=>this.report()),a.on("scene",()=>this.report()),this.player=a}t.time!==void 0&&this.player.seek(t.time),t.autoplay&&this.player.play(t.time),this.report(!0)}play(t){this.player?.play(t)}pause(){this.player?.pause()}stop(){this.player?.stop()}seek(t){this.player?.seek(t)}releaseStage(){this.player&&(this.player.dispose(),this.player=null,this.lastView=null,this.report(!0))}frame(){if(!this.player||!this.publishView)return;let t=this.getStage(),e=t?.cameraRef?.camera,i=t?.rendererManager?.getDomElement()??t?.cameraRef?.renderer?.domElement;if(!e||!i)return;e.updateMatrixWorld(),this.viewInverse.copy(e.matrixWorld).invert(),this.viewProjection.multiplyMatrices(e.projectionMatrix,this.viewInverse);let a=i.getBoundingClientRect(),s={viewProjection:this.viewProjection.toArray(),inverseViewProjection:[],viewport:{x:Math.round(a.left),y:Math.round(a.top),width:Math.round(a.width),height:Math.round(a.height)}},r=JSON.stringify(s);r!==this.lastView&&(this.lastView=r,s.inverseViewProjection=this.viewProjection.clone().invert().toArray(),this.publishView(s))}unload(){this.pending=null,this.releaseStage()}cameraPose(){let t=this.getStage()?.cameraRef?.camera;if(!t)return null;let e=new Se(0,0,-1).applyQuaternion(t.quaternion),i=t.position.clone().add(e.multiplyScalar(10));return{position:{x:t.position.x,y:t.position.y,z:t.position.z},lookAt:{x:i.x,y:i.y,z:i.z},fov:t instanceof ge?t.fov:void 0}}report(t=!1){let e=this.player,i=e?{cutsceneId:e.definition.id,state:e.state,time:Math.round(e.time*1e3)/1e3,sceneId:null,shotId:null}:{cutsceneId:null,state:"idle",time:0,sceneId:null,shotId:null};if(e){let s=Ce(e);i.sceneId=s.sceneId,i.shotId=s.shotId}let a=JSON.stringify(i);!t&&a===this.lastStatus||(this.lastStatus=a,this.publish(i))}};function Ce(n){let{definition:t,time:e}=n,i=null;for(let s of t.scenes)e>=s.start&&e<s.end&&(i=s.id);let a=null;for(let s of t.tracks)if(!(s.kind!=="camera"||a))for(let r of s.items)e>=r.start&&e<r.end&&(a=r.id);return{sceneId:i,shotId:a}}export{I as a,w as b,z as c,x as d,ae as e,se as f,le as g,ue as h,ce as i,q as j,we as k,N as l,T as m,O as n,xe as o,_ as p,J as q,Oe as r,U as s,Q as t};
@@ -0,0 +1,9 @@
1
+ import{d as s,h as o,j as a}from"./chunk-GPCSX3M6.js";import{announceBridgeReady as h}from"@zylem/bridge";var n=class r extends HTMLElement{_game=null;_state={};container;resizeObserver=null;_viewportProfile="auto";static HOST_CONFIG_MARKER=Symbol("zylem:host-config");constructor(){super(),this.attachShadow({mode:"open"});let e=document.createElement("style");e.textContent=`
2
+ :host {
3
+ display: block;
4
+ width: 100%;
5
+ height: 100%;
6
+ min-width: 0;
7
+ min-height: 0;
8
+ }
9
+ `,this.container=document.createElement("div"),this.container.style.width="100%",this.container.style.height="100%",this.container.style.position="relative",this.container.style.outline="none",this.container.tabIndex=0,this.shadowRoot.append(e,this.container)}focus(){this.container.focus()}connectedCallback(){typeof ResizeObserver<"u"&&!this.resizeObserver&&(this.resizeObserver=new ResizeObserver(()=>{this.syncDisplayRuntime()}),this.resizeObserver.observe(this)),this.syncDisplayRuntime()}set game(e){this._game&&this._game.dispose(),this._game=e,this.attachHostContainer(e),this.syncDisplayRuntime(),e.start().then(()=>{this._game===e&&h(this)})}get game(){return this._game}set state(e){this._state=e,this.syncDebugState(),this.syncToolbarState()}get state(){return this._state}set viewportProfile(e){let t=e==="mobile"||e==="desktop"?e:"auto";this._viewportProfile!==t&&(this._viewportProfile=t,this.syncDisplayRuntime())}get viewportProfile(){return this._viewportProfile}static get observedAttributes(){return["viewport-profile"]}attributeChangedCallback(e,t,i){e==="viewport-profile"&&(this.viewportProfile=i??"auto")}syncDebugState(){let e=this._state.gameState?.debugFlag;e!==void 0&&(s.enabled=e)}syncToolbarState(){let{tool:e,paused:t}=this._state.toolbarState??{};e!==void 0&&a(e),t!==void 0&&o(t)}disconnectedCallback(){this.resizeObserver?.disconnect(),this.resizeObserver=null,this._game&&(this._game.dispose(),this._game=null)}attachHostContainer(e){let t=r.HOST_CONFIG_MARKER,i=e.options.find(l=>!!l?.[t]);if(i){i.container=this.container;return}e.options.push({container:this.container,[t]:!0})}syncDisplayRuntime(){if(!this._game)return;let e=this.getBoundingClientRect(),t=Math.round(e.width||this.clientWidth||0),i=Math.round(e.height||this.clientHeight||0);this._game.setDisplayRuntime({deviceProfile:this._viewportProfile,viewportSize:t>0&&i>0?{width:t,height:i}:void 0})}};customElements.define("zylem-game",n);export{n as a};
@@ -0,0 +1 @@
1
+ import{b as V,c as k,d as D}from"./chunk-BQRMYLYD.js";import{d as a,h as f,j as b,l as g,o as S,q as u,r as w,s as v,t as P,v as E,w as C,x}from"./chunk-GPCSX3M6.js";import{subscribe as T}from"valtio/vanilla";import{announceBridgeReady as R,getZylemBridge as d}from"@zylem/bridge";var c="custom",p=new Set;function B(t){if(t!==c){c=t;for(let e of p)e(c)}}function J(t){return p.add(t),t(c),()=>{p.delete(t)}}function h(t,e){return[t[0]*e.x,t[1]*e.y,t[2]*e.z]}function O(t,e){let i=new Float32Array(t.length);for(let n=0;n<t.length;n+=3)i[n]=t[n]*e.x,i[n+1]=t[n+1]*e.y,i[n+2]=t[n+2]*e.z;return i}function K(t,e){let{shape:i}=t,n=t.offset?h(t.offset,e):t.offset,o;switch(i.type){case"box":o={type:"box",halfExtents:h(i.halfExtents,e)};break;case"sphere":o={type:"sphere",radius:i.radius*Math.max(e.x,e.y,e.z)};break;case"capsule":case"cylinder":case"cone":o={type:i.type,halfHeight:i.halfHeight*e.y,radius:i.radius*Math.max(e.x,e.z)};break;case"convexHull":o={type:"convexHull",vertices:O(i.vertices,e)};break;case"trimesh":o={type:"trimesh",vertices:O(i.vertices,e),indices:i.indices};break;case"heightfield":o={...i,scale:h(i.scale,e)};break;default:o=i;break}return{...t,shape:o,offset:n}}function G(t){if(!t.colliderBaseline){let e=t.colliderDescs.length?t.colliderDescs:t.colliderDesc?[t.colliderDesc]:[];t.colliderBaseline=e.map(i=>({...i}))}return t.colliderBaseline}function I(t){if(!t.colliderScaleDirty)return!1;t.colliderScaleDirty=!1;let e=G(t);if(!e.length)return!1;let i=t.getScale(),n=e.map(r=>K(r,i));t.colliderDescs=n,t.colliderDesc=n[0];let o=t.physicsWorldRef;if(!o)return!0;let s=t.getPose();return o.destroyEntity(t),s&&t.bodyDesc&&(t.bodyDesc.position=[s.position.x,s.position.y,s.position.z],t.bodyDesc.rotation=[s.rotation.x,s.rotation.y,s.rotation.z,s.rotation.w]),o.addEntity(t),!0}function U(t){return(t?.group??t?.mesh)?.scale}function N(t){let i=(typeof t?.getScale=="function"?t.getScale():void 0)??t?.scale??U(t)??{};return{x:i.x??1,y:i.y??1,z:i.z??1}}function ae(t){let e=typeof t?.getPose=="function"?t.getPose():null;if(!e?.rotation)return;let{x:i,y:n,z:o,w:s}=e.rotation;return{x:i,y:n,z:o,w:s}}function y(t){let e=typeof t?.getPose=="function"?t.getPose():null,i=e?.position??{x:0,y:0,z:0},n=e?.rotation??{x:0,y:0,z:0,w:1};return{position:{x:i.x,y:i.y,z:i.z},rotation:D(n),quaternion:{x:n.x,y:n.y,z:n.z,w:n.w},scale:N(t)}}function $(t,e){if(typeof t?.setScale=="function"){t.setScale(e.x,e.y,e.z);return}U(t)?.set?.(e.x,e.y,e.z)}function H(t){!t||typeof t.getScale!="function"||I(t)}function L(t,e){if(!t)return!1;let i=e.quaternion??(e.rotation?k(e.rotation):void 0),n=!1;return(e.position||i)&&typeof t.setPose=="function"&&(n=t.setPose({position:e.position,rotation:i})),e.scale&&($(t,e.scale),n=!0),n}function M(t){let e=t?.constructor?.type;return e?String(e).replace("Symbol(","").replace(")",""):"Unknown"}function Q(t){let e=t;if(!e?.uuid)return;let i=d().channel;if(!i.hasSubscribers("entity:upsert"))return;let n=y(t);i.queue("entity:upsert",[{uuid:e.uuid,name:e.name||"Unnamed",type:M(t),position:n.position,rotation:n.rotation,scale:n.scale,quaternion:n.quaternion}])}function re(t,e){d().channel.send("game:notice",{level:t,message:e})}function W(t,e,i){let n=[...new Set(t.swatches.map(r=>r.source))],o=[...new Set(e.map(r=>r.uuid))],s=o.length===1?i(o[0])||"entity":`${o.length} entities`;return`Apply ${n.join(", ")} to ${s}`}function j(t,e){return!e||t.length!==e.length?!1:t.every((i,n)=>i===e[n])}function F(t,e){switch(e){case"add":w(t);break;case"subtract":v(t);break;case"toggle":for(let i of t)P(i);break;default:u(t);break}}function Z(t,e){return t.on.bind(t)("camera:view:set",({preset:n})=>e(n))}var z=class{channel;unsubscribes=[];host=null;editorKnown={};applyingSceneOperation=!1;constructor(){this.channel=d().channel}connect(e,i){this.disconnect(),this.host=e,this.unsubscribes.push(this.channel.on("debug:set",({enabled:n})=>{this.editorKnown.debug=n,a.enabled=n}),this.channel.on("tool:set",({tool:n})=>{b(n)}),this.channel.on("playback:set",({paused:n})=>{this.editorKnown.paused=n,f(n)}),this.channel.on("entity:select",({uuid:n,uuids:o,mode:s})=>{o?F(o,s??"replace"):S(n),this.editorKnown.selectedUuid=a.selectedEntityId,this.editorKnown.selectedUuids=[...a.selectedEntityIds]}),this.channel.on("entity:focus",({uuid:n})=>{V(n)}),this.channel.on("entity:transform",({uuid:n,position:o,rotation:s,quaternion:r,scale:m})=>{let l=this.host?.resolveEntity(n);if(!l)return;let q=y(l);if(L(l,{position:o,rotation:s,quaternion:r,scale:m}),m&&H(l),Q(l),this.applyingSceneOperation)return;let A=y(l);this.channel.send("scene:operation",{opId:`tx-${n}-${Date.now().toString(36)}`,kind:"transform",label:`Set ${l.name||"entity"} transform`,entries:[{uuid:n,before:q,after:A}]})}),this.channel.on("entity:create",({typeId:n,props:o,pose:s})=>{this.host?.createEntity?.(n,o,s)}),this.channel.on("scene:operation:apply",({op:n,direction:o})=>{this.applyingSceneOperation=!0;try{this.host?.applySceneOperation?.(n,o)}finally{this.applyingSceneOperation=!1}}),this.channel.on("add:type:set",({typeId:n,props:o})=>{x(n,o??null)}),this.channel.on("snap:set",n=>{E(n)}),this.channel.on("grid:set",({visible:n})=>{C(n)}),this.channel.on("stage:variable:set",({key:n,value:o})=>{this.host?.setStageVariable?.(n,o)}),this.channel.on("pick:mode:set",({enabled:n})=>{g(n)}),this.channel.on("entity:pick",({requestId:n,ndc:o})=>{let s=this.host?.pickEntity?.(o)??null;this.channel.send("entity:pick:result",{requestId:n,hit:s})}),this.channel.on("entity:apply-swatch",n=>{this.handleApplySwatch(n)}),this.channel.on("cutscene:load",n=>this.host?.cutscene?.load(n)),this.channel.on("cutscene:play",({from:n})=>this.host?.cutscene?.play(n)),this.channel.on("cutscene:pause",()=>this.host?.cutscene?.pause()),this.channel.on("cutscene:stop",()=>this.host?.cutscene?.stop()),this.channel.on("cutscene:seek",({time:n})=>this.host?.cutscene?.seek(n)),this.channel.on("cutscene:unload",()=>this.host?.cutscene?.unload()),this.channel.on("camera:pose:get",({requestId:n})=>{let o=this.host?.cameraPose?.();o&&this.channel.send("camera:pose",{requestId:n,...o})}),Z(this.channel,B),T(a,()=>this.publishDebugStateChanges())),this.publishDebugStateChanges(),R(i)}publishCutsceneStatus(e){this.channel.queue("cutscene:status",e)}publishCutsceneView(e){this.channel.queue("cutscene:view",e)}disconnect(){for(let e of this.unsubscribes)e();this.unsubscribes=[],this.host=null,this.editorKnown={}}handleApplySwatch(e){let i=e.opId??`swatch-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`,n=this.host?.applySwatches?this.host.applySwatches({...e,opId:i}):{results:e.uuids.flatMap(s=>e.swatches.map(r=>({uuid:s,kind:r.kind,source:r.source,ok:!1,reason:"entity-not-found"}))),entries:[]},o=[...new Set(n.entries.map(s=>s.uuid))];e.select&&o.length>0&&u(o),n.entries.length>0&&!this.applyingSceneOperation&&this.channel.send("scene:operation",{opId:i,kind:"swatch",label:W(e,n.entries,s=>this.host?.resolveEntity(s)?.name),entries:n.entries}),this.channel.send("entity:swatch-applied",{opId:i,results:n.results})}publishDebugStateChanges(){let e={};a.paused!==this.editorKnown.paused&&(this.editorKnown.paused=a.paused,e.paused=a.paused),a.enabled!==this.editorKnown.debug&&(this.editorKnown.debug=a.enabled,e.debug=a.enabled),(e.paused!==void 0||e.debug!==void 0)&&this.publishStatus(e),(a.selectedEntityId!==this.editorKnown.selectedUuid||a.hoveredEntityId!==this.editorKnown.hoveredUuid||!j(a.selectedEntityIds,this.editorKnown.selectedUuids))&&(this.editorKnown.selectedUuid=a.selectedEntityId,this.editorKnown.selectedUuids=[...a.selectedEntityIds],this.editorKnown.hoveredUuid=a.hoveredEntityId,this.channel.queue("entity:selection",{selectedUuid:a.selectedEntityId,hoveredUuid:a.hoveredEntityId,selectedUuids:[...a.selectedEntityIds]}))}wantsEntityUpdates(){return this.channel.hasSubscribers("entity:upsert")||this.channel.hasSubscribers("stage:snapshot")}wantsThumbnails(){return this.channel.hasSubscribers("entity:thumbnail")}onEditorAttached(e){return this.channel.onSubscriberAdded(i=>{if(i!=="entity:upsert"&&i!=="entity:thumbnail")return;let n=i==="entity:upsert"?"entity:thumbnail":"entity:upsert";this.channel.subscriberCount(n)>0||e()})}publishConfig(e){this.channel.send("game:config",e)}publishLoading(e){this.channel.send("game:loading",e)}publishStatus(e){this.channel.queue("game:status",e)}publishVariable(e){this.channel.send("game:variable",e)}publishNotice(e,i){this.channel.send("game:notice",{level:e,message:i})}publishStageSnapshot(e){this.channel.send("stage:snapshot",e)}queueEntityUpsert(e){e.length&&this.channel.queue("entity:upsert",e)}queueEntityRemoved(e){e.length&&this.channel.queue("entity:removed",{uuids:e})}queueThumbnails(e){e.length&&this.channel.queue("entity:thumbnail",e)}publishCatalog(e){this.channel.send("catalog:snapshot",{entities:e})}publishSceneOperation(e){this.channel.send("scene:operation",e)}wantsSceneOperations(){return this.channel.hasSubscribers("scene:operation")}};function le(t){d().channel.send("scene:operation",t)}export{J as a,I as b,N as c,ae as d,y as e,M as f,re as g,z as h,le as i};
@@ -1 +1 @@
1
- import{d as i,o as f}from"./chunk-EVMLNMGU.js";var n=null;function b(e){return n=e,()=>{n===e&&(n=null)}}function x(e){if(!n)return console.warn("focusEntity: no active stage focus context"),!1;let t=n.resolveEntity(e);if(!t)return console.warn(`focusEntity: entity ${e} not found`),!1;let o=t.group??t.mesh??null;return o?(i.enabled||(i.enabled=!0),n.ensureDebugReady?.(),f(e),n.frameObject(o),!0):(console.warn(`focusEntity: entity ${e} has no group/mesh`),!1)}import{Euler as y,Quaternion as m}from"three";var u=new y,r=new m;function d(e){return u.set(e.x,e.y,e.z,"XYZ"),r.setFromEuler(u),{x:r.x,y:r.y,z:r.z,w:r.w}}function g(e){return r.set(e.x,e.y,e.z,e.w),u.setFromQuaternion(r,"XYZ"),{x:u.x,y:u.y,z:u.z}}function s(e,t){return!Number.isFinite(t)||t<=0?e:Math.round(e/t)*t}function h(e,t){return{x:s(e.x,t),y:s(e.y,t),z:s(e.z,t)}}function z(e,t){let o=a=>{let c=s(a,t);return c!==0?c:t>0?t:a};return{x:o(e.x),y:o(e.y),z:o(e.z)}}function w(e){return e*Math.PI/180}function I(e){return e*180/Math.PI}export{b as a,x as b,d as c,g as d,s as e,h as f,z as g,w as h,I as i};
1
+ import{d as i,o as f}from"./chunk-GPCSX3M6.js";var n=null;function b(e){return n=e,()=>{n===e&&(n=null)}}function x(e){if(!n)return console.warn("focusEntity: no active stage focus context"),!1;let t=n.resolveEntity(e);if(!t)return console.warn(`focusEntity: entity ${e} not found`),!1;let o=t.group??t.mesh??null;return o?(i.enabled||(i.enabled=!0),n.ensureDebugReady?.(),f(e),n.frameObject(o),!0):(console.warn(`focusEntity: entity ${e} has no group/mesh`),!1)}import{Euler as y,Quaternion as m}from"three";var u=new y,r=new m;function d(e){return u.set(e.x,e.y,e.z,"XYZ"),r.setFromEuler(u),{x:r.x,y:r.y,z:r.z,w:r.w}}function g(e){return r.set(e.x,e.y,e.z,e.w),u.setFromQuaternion(r,"XYZ"),{x:u.x,y:u.y,z:u.z}}function s(e,t){return!Number.isFinite(t)||t<=0?e:Math.round(e/t)*t}function h(e,t){return{x:s(e.x,t),y:s(e.y,t),z:s(e.z,t)}}function z(e,t){let o=a=>{let c=s(a,t);return c!==0?c:t>0?t:a};return{x:o(e.x),y:o(e.y),z:o(e.z)}}function w(e){return e*Math.PI/180}function I(e){return e*180/Math.PI}export{b as a,x as b,d as c,g as d,s as e,h as f,z as g,w as h,I as i};
@@ -0,0 +1 @@
1
+ import{getZylemBridge as p,announceBridgeReady as d,applySwatchesToSelection as o,BRIDGE_READY_EVENT as i}from"@zylem/bridge";export{p as a,d as b,o as c,i as d};
@@ -0,0 +1 @@
1
+ import{proxy as c}from"valtio/vanilla";var a=["translate","rotate","scale"];function b(t){return a.includes(t)}var y={enabled:!0,translate:.25,rotate:Math.PI/12,scale:.1},e=c({enabled:!1,paused:!1,tool:"none",selectedEntityId:null,selectedEntityIds:[],hoveredEntityId:null,snap:{...y},gridVisible:!1,addTypeId:null,addTypeProps:null,pickMode:!1,flags:new Set}),l=null;function S(t){return l=t,()=>{l===t&&(l=null)}}function d(t){return!t||!l?null:l(t)}function s(t,n){if(t==null)return null;if(typeof t=="string")return t;let o=t.uuid;if(typeof o=="string")return console.warn(`${n}: received a live entity. Pass the UUID instead \u2014 storing entities in debugState makes valtio deep-proxy the scene graph.`),o;throw new TypeError(`${n} expects an entity UUID string or null, received ${typeof t}.`)}function v(){return e.paused}function T(t){e.paused=t}function m(){return e.tool}function D(t){e.tool=t}function h(){return e.enabled||e.tool!=="none"||e.pickMode}function k(t){e.pickMode=t,!t&&e.tool!=="select"&&e.tool!=="delete"&&x()}function P(){return e.pickMode}function R(){return e.selectedEntityId}function p(t){let n=s(t,"setSelectedEntityId");e.selectedEntityId!==n&&(e.selectedEntityId=n,e.selectedEntityIds=n?[n]:[])}function M(){return[...e.selectedEntityIds]}function u(t){let n=t.map((i,r)=>s(i,`setSelectedEntityIds[${r}]`)).filter(i=>i!==null);n.length===e.selectedEntityIds.length&&n.every((i,r)=>e.selectedEntityIds[r]===i)||(e.selectedEntityIds=n,e.selectedEntityId=n[0]??null)}function g(t){let n=e.selectedEntityIds,o=t.filter((i,r)=>!n.includes(i)&&t.indexOf(i)===r);o.length!==0&&u([...n,...o])}function f(t){let n=new Set(t);u(e.selectedEntityIds.filter(o=>!n.has(o)))}function w(t){let n=s(t,"toggleSelectedEntityId");n&&(e.selectedEntityIds.includes(n)?f([n]):g([n]))}function G(){return{...e.snap}}function O(t){Object.assign(e.snap,t)}function H(t){e.gridVisible=t}function A(t,n){e.addTypeId=t,e.addTypeProps=t?n??null:null}function U(){return e.hoveredEntityId}function E(t){let n=s(t,"setHoveredEntityId");e.hoveredEntityId!==n&&(e.hoveredEntityId=n)}function x(){E(null)}function F(){return d(e.selectedEntityId)}function N(){return d(e.hoveredEntityId)}function V(t){p(s(t,"setSelectedEntity"))}export{a,b,y as c,e as d,S as e,d as f,v as g,T as h,m as i,D as j,h as k,k as l,P as m,R as n,p as o,M as p,u as q,g as r,f as s,w as t,G as u,O as v,H as w,A as x,U as y,E as z,x as A,F as B,N as C,V as D};
@@ -0,0 +1 @@
1
+ import{a as I,b as y,r as Z,t as f,v as d}from"./chunk-KP6DLLJO.js";import{e as R}from"./chunk-UUOPT2N4.js";import{j as E}from"./chunk-4QLJUQSJ.js";import{a as O,g as b,i as T,j as w}from"./chunk-7WRQ2UAN.js";import{Group as W,Quaternion as X,Vector3 as S}from"three";import{ParticleEmitterBehavior as x}from"@zylem/behaviors/particle-emitter";var U={...Z,effect:{create(){throw new Error("createParticleSystem(...) requires an effect or preset definition.")}},preset:void 0,autoplay:!0,localOffset:void 0,followPosition:!0,followRotation:!0,autoDestroy:!1},M=Symbol("ParticleSystem"),C=1,Q=new S(C,C,C),H=new S;function $(n){return{effect:n.preset??n.effect,autoplay:n.autoplay,localOffset:n.localOffset,followPosition:n.followPosition,followRotation:n.followRotation,autoDestroy:n.autoDestroy}}var P=class n extends f{static type=M;particleHandle=null;getSelectionBounds(o){return this.group?(this.group.getWorldPosition(H),o.setFromCenterAndSize(H,Q),R(o)):null}constructor(o,e=!0){super(),this.options=y(U,o),this.group=new W;let t=this.options.position;t&&this.group.position.copy(w(t)),this.__zylemParticleSystemEntity=!0,this.bindStandaloneTransforms(),e&&(this.particleHandle=this.use(x,$(this.options)))}bindStandaloneTransforms(){let o=()=>{this.options.position=new S(this.group?.position.x??0,this.group?.position.y??0,this.group?.position.z??0)},e=()=>{this.group&&(this._rotation2DAngle=this.group.rotation.z)};this.setPosition=(t,i,r)=>{this.group?.position.set(t,i,r),o()},this.setPositionX=t=>{this.group&&(this.group.position.x=t,o())},this.setPositionY=t=>{this.group&&(this.group.position.y=t,o())},this.setPositionZ=t=>{this.group&&(this.group.position.z=t,o())},this.getPosition=()=>this.group?{x:this.group.position.x,y:this.group.position.y,z:this.group.position.z}:null,this.setRotation=(t,i,r)=>{this.group?.rotation.set(t,i,r),e()},this.setRotationX=t=>{this.group&&(this.group.rotation.x=t,e())},this.setRotationY=t=>{this.group&&(this.group.rotation.y=t,e())},this.setRotationZ=t=>{this.group&&(this.group.rotation.z=t,e())},this.setRotationDegrees=(t,i,r)=>{this.group?.rotation.set(t*Math.PI/180,i*Math.PI/180,r*Math.PI/180),e()},this.setRotationDegreesX=t=>{this.group&&(this.group.rotation.x=t*Math.PI/180,e())},this.setRotationDegreesY=t=>{this.group&&(this.group.rotation.y=t*Math.PI/180,e())},this.setRotationDegreesZ=t=>{this.group&&(this.group.rotation.z=t*Math.PI/180,e())},this.rotateX=t=>{this.group?.rotateX(t),e()},this.rotateY=t=>{this.group?.rotateY(t),e()},this.rotateZ=t=>{this.group?.rotateZ(t),e()},this.getRotation=()=>{if(!this.group)return null;let t=new X;return this.group.getWorldQuaternion(t),t}}resolveParticleHandle(){if(this.particleHandle)return this.particleHandle;let o=this.getBehaviorRefs().find(i=>i.descriptor.key===x.key);if(!o)return null;let e={getFSM:()=>o.fsm??null,getOptions:()=>o.options,ref:o},t=x.createHandle?.(o)??{};return this.particleHandle={...e,...t},this.particleHandle}play(){this.resolveParticleHandle()?.play()}stop(){this.resolveParticleHandle()?.stop()}pause(){this.resolveParticleHandle()?.pause()}restart(){this.resolveParticleHandle()?.restart()}burst(){this.resolveParticleHandle()?.burst()}isPlaying(){return this.resolveParticleHandle()?.isPlaying()??!1}getSystem(){return this.resolveParticleHandle()?.getSystem()}buildInfo(){return{...super.buildInfo(),type:String(n.type)}}};function z(n,o=!0){let e=new P(n,o);return d(e,t=>z(t,!1))}function q(n){return z(n,!0)}import{Group as K,Sprite as j,SpriteMaterial as J,CanvasTexture as tt,LinearFilter as D,Color as Y,ClampToEdgeWrapping as B}from"three";import{getCooldown as L}from"@zylem/behaviors/cooldown";var et={"top-left":{fx:0,fy:0},"top-center":{fx:.5,fy:0},"top-right":{fx:1,fy:0},"center-left":{fx:0,fy:.5},center:{fx:.5,fy:.5},"center-right":{fx:1,fy:.5},"bottom-left":{fx:0,fy:1},"bottom-center":{fx:.5,fy:1},"bottom-right":{fx:1,fy:1}},A=192,ot={xs:8,sm:16,md:32,lg:48,xl:64},_={position:void 0,cooldown:"",iconSize:"md",fillColor:"#333333",showTimer:!0,stickToViewport:!0,screenAnchor:"top-left",screenPosition:{x:0,y:0},zDistance:1,overlayColor:"rgba(0, 0, 0, 0.65)"},it=Symbol("CooldownIcon"),v=class extends f{static type=it;_sprite=null;_texture=null;_canvas=null;_ctx=null;_cameraRef=null;_iconTexture=null;_iconImage=null;_lastRenderedProgress=-1;constructor(o){super(),this.options=y(_,o),this.options.screenPosition=T(this.options.screenPosition,_.screenPosition),this.group=new K,this.createSprite(),this.prependSetup(this.iconSetup.bind(this)),this.prependUpdate(this.iconUpdate.bind(this)),this.onCleanup(this.iconDestroy.bind(this))}createSprite(){this._canvas=document.createElement("canvas"),this._canvas.width=256,this._canvas.height=256,this._ctx=this._canvas.getContext("2d"),this._texture=new tt(this._canvas),this._texture.minFilter=D,this._texture.magFilter=D,this._texture.wrapS=B,this._texture.wrapT=B;let e=new J({map:this._texture,transparent:!0,depthTest:!1,depthWrite:!1});if(this._sprite=new j(e),this.group?.add(this._sprite),this.options.icon){let t=new Image;t.crossOrigin="anonymous",t.onload=()=>{this._iconImage=t,this.redraw(this._lastRenderedProgress>=0?this._lastRenderedProgress:1)},t.src=this.options.icon}this.redraw(1)}redraw(o){if(!this._canvas||!this._ctx)return;let e=this._ctx,t=this._canvas.width,i=this._canvas.height,r=t/2,s=i/2,l=Math.min(r,s);if(e.clearRect(0,0,t,i),this._iconImage?e.drawImage(this._iconImage,0,0,t,i):(e.fillStyle=this.toCssColor(this.options.fillColor??"#333333"),e.fillRect(0,0,t,i)),o<1){let p=(1-o)*Math.PI*2,c=-Math.PI/2,h=c+p;if(e.save(),e.fillStyle=this.options.overlayColor??"rgba(0, 0, 0, 0.65)",e.beginPath(),e.moveTo(r,s),e.arc(r,s,l+1,c,h,!1),e.closePath(),e.fill(),e.restore(),this.options.showTimer){let a=L(this.options.cooldown);if(a){let m=Math.max(0,a.duration-a.elapsed),g=m>=10?Math.ceil(m).toString():m.toFixed(1),u=Math.floor(t*.3);e.font=`bold ${u}px sans-serif`,e.textAlign="center",e.textBaseline="middle",e.fillStyle="#FFFFFF",e.strokeStyle="#000000",e.lineWidth=2,e.strokeText(g,r,s),e.fillText(g,r,s)}}}this._texture&&(this._texture.needsUpdate=!0),this._lastRenderedProgress=o}toCssColor(o){return typeof o=="string"?o:`#${(o instanceof Y?o:new Y(o)).getHexString()}`}getResolution(){try{let o=this._cameraRef?.renderer?.domElement;if(o)return{width:o.clientWidth||1,height:o.clientHeight||1}}catch{}return{width:this._cameraRef?.screenResolution?.x??1,height:this._cameraRef?.screenResolution?.y??1}}iconSetup(o){this._sprite||this.createSprite(),this._cameraRef=o.camera,this.options.stickToViewport&&this._cameraRef&&(this._cameraRef.camera.add(this.group),this.updateStickyTransform())}iconUpdate(o){let t=L(this.options.cooldown)?.progress??1;(Math.abs(t-this._lastRenderedProgress)>.02||t===1&&this._lastRenderedProgress!==1)&&this.redraw(t),this.options.stickToViewport&&this._cameraRef&&this.updateStickyTransform()}resolveScreenPosition(o,e){let t=this.options.screenAnchor??"top-left",i=b(this.options.screenPosition,O),r=i.x,s=i.y,{fx:l,fy:p}=et[t],c=l*o,h=p*e,a=e/A;return{px:c+r*a,py:h+s*a}}resolveIconSize(o){let e=this.options.iconSize??"md",t,i;typeof e=="string"?t=i=ot[e]:typeof e=="number"?t=i=e:(t=e.width,i=e.height);let r=o/A;return{widthPx:t*r,heightPx:i*r}}computeWorldExtents(o,e){let t=1,i=1;if(o.isPerspectiveCamera){let r=o,s=Math.tan(r.fov*Math.PI/180/2)*e;t=s*r.aspect,i=s}else if(o.isOrthographicCamera){let r=o;t=(r.right-r.left)/2,i=(r.top-r.bottom)/2}return{worldHalfW:t,worldHalfH:i}}updateStickyTransform(){if(!this._sprite||!this._cameraRef)return;let o=this._cameraRef.camera,{width:e,height:t}=this.getResolution(),{px:i,py:r}=this.resolveScreenPosition(e,t),s=Math.max(.001,this.options.zDistance??1),{worldHalfW:l,worldHalfH:p}=this.computeWorldExtents(o,s),c=i/e*2-1,h=1-r/t*2,a=c*l,m=h*p;{let u=p*2/t,{widthPx:k,heightPx:N}=this.resolveIconSize(t),G=Math.max(1e-4,k*u),V=Math.max(1e-4,N*u);this._sprite.scale.set(G,V,1)}this.group?.position.set(a,m,-s)}iconDestroy(){this._texture?.dispose(),this._sprite?.material&&this._sprite.material.dispose(),this._sprite&&this._sprite.removeFromParent(),this.group?.removeFromParent(),this._iconTexture?.dispose(),this._sprite=null,this._texture=null,this._canvas=null,this._ctx=null,this._cameraRef=null,this._iconTexture=null,this._iconImage=null}};function F(...n){let o=n.filter(t=>!(t instanceof I)),e={..._};for(let t of o)e={...e,...t};return d(new v(e),t=>F(t??{}))}function rt(n,o,e){e({me:n,globals:o})}function nt(n,o){let e=o??E();rt(n,e,n.nodeDestroy.bind(n))}export{M as a,P as b,q as c,F as d,nt as e};
@@ -1 +1 @@
1
- import{Type as e}from"@sinclair/typebox";var n=e.Tuple([e.Number(),e.Number()],{title:"Vector2",description:"A 2D position as [x, y]."}),s=e.Object({id:e.String(),type:e.String({minLength:1}),position:e.Optional(n),data:e.Optional(e.Record(e.String(),e.Any()))},{$id:"EntityBlueprint",title:"EntityBlueprint",additionalProperties:!1}),D=e.Object({id:e.String(),name:e.Optional(e.String()),entities:e.Array(s),assets:e.Optional(e.Array(e.String()))},{$id:"StageBlueprint",title:"StageBlueprint",additionalProperties:!1}),S=e.Object({value:e.Optional(e.String()),color:e.Optional(e.String()),fontSize:e.Optional(e.Number()),fontFamily:e.Optional(e.String())},{title:"TextEntityData",additionalProperties:!0}),m=e.Tuple([e.Number(),e.Number(),e.Number()],{title:"Vector3Tuple"}),g=e.Object({points:e.Array(m,{minItems:2}),color:e.Optional(e.String()),colors:e.Optional(e.Array(e.String())),linewidth:e.Optional(e.Number()),worldUnits:e.Optional(e.Boolean()),alphaToCoverage:e.Optional(e.Boolean()),opacity:e.Optional(e.Number()),transparent:e.Optional(e.Boolean()),dashed:e.Optional(e.Boolean()),dashSize:e.Optional(e.Number()),gapSize:e.Optional(e.Number()),pickThreshold:e.Optional(e.Number())},{title:"LineEntityData",additionalProperties:!0}),u=e.Object({imagePath:e.Optional(e.String()),width:e.Optional(e.Number()),height:e.Optional(e.Number())},{title:"SpriteEntityData",additionalProperties:!0}),h=e.Union([e.Object({id:e.String(),type:e.Literal("text"),position:e.Optional(n),data:e.Optional(S)}),e.Object({id:e.String(),type:e.Literal("sprite"),position:e.Optional(n),data:e.Optional(u)}),e.Object({id:e.String(),type:e.Literal("line"),position:e.Optional(n),data:e.Optional(g)}),e.Object({id:e.String(),type:e.String({minLength:1}),position:e.Optional(n),data:e.Optional(e.Record(e.String(),e.Unknown()))})],{$id:"EntityJson",title:"EntityJson"}),B=e.Object({id:e.String(),name:e.Optional(e.String()),entities:e.Array(h),assets:e.Optional(e.Array(e.String()))},{$id:"StageJson",title:"StageJson",additionalProperties:!1});import{Type as t}from"@sinclair/typebox";var y=t.Record(t.String(),t.Array(t.String()),{title:"KeyboardMapping"}),O=t.Record(t.String(),t.Array(t.String()),{title:"MouseMapping"}),a=t.Record(t.String(),t.Union([t.String(),t.Number()]),{title:"VirtualTouchStyle"}),p=t.Object({top:t.Optional(t.Union([t.String(),t.Number()])),right:t.Optional(t.Union([t.String(),t.Number()])),bottom:t.Optional(t.Union([t.String(),t.Number()])),left:t.Optional(t.Union([t.String(),t.Number()])),transform:t.Optional(t.String())},{title:"VirtualTouchPosition",additionalProperties:!1}),f=t.Object({enabled:t.Optional(t.Boolean()),className:t.Optional(t.String()),style:t.Optional(a),position:t.Optional(p),size:t.Optional(t.Number()),label:t.Optional(t.String()),svg:t.Optional(t.String())},{title:"VirtualTouchButtonConfig",additionalProperties:!1}),r=t.Object({enabled:t.Optional(t.Boolean()),className:t.Optional(t.String()),style:t.Optional(a),position:t.Optional(p),size:t.Optional(t.Number()),thumbSize:t.Optional(t.Number()),maxDistance:t.Optional(t.Number()),deadzone:t.Optional(t.Number()),directionThreshold:t.Optional(t.Number()),horizontalAxis:t.Optional(t.Union([t.Literal("Horizontal"),t.Literal("SecondaryHorizontal")])),verticalAxis:t.Optional(t.Union([t.Literal("Vertical"),t.Literal("SecondaryVertical")])),emitDirections:t.Optional(t.Boolean()),svg:t.Optional(t.Object({base:t.Optional(t.String()),thumb:t.Optional(t.String())}))},{title:"VirtualTouchJoystickConfig",additionalProperties:!1}),j=t.Union([f,t.Literal(!1)]),d=t.Record(t.String(),j,{title:"VirtualTouchButtonsConfig",description:"Keys are touch button slots: A, B, X, Y, Start, Select, L, R, LTrigger, RTrigger, Up, Down, Left, Right."}),C=t.Object({left:t.Optional(t.Union([r,t.Literal(!1)])),right:t.Optional(t.Union([r,t.Literal(!1)]))},{title:"VirtualTouchJoysticksConfig",additionalProperties:!1}),b=t.Object({enabled:t.Optional(t.Union([t.Boolean(),t.Literal("auto")])),className:t.Optional(t.String()),style:t.Optional(a),joysticks:t.Optional(t.Union([C,t.Literal(!1)])),buttons:t.Optional(t.Union([d,t.Literal(!1)]))},{title:"VirtualTouchConfig",additionalProperties:!1}),x=t.Object({mapping:t.Optional(O),pointerLock:t.Optional(t.Boolean()),sensitivity:t.Optional(t.Number()),lookMode:t.Optional(t.Union([t.Literal("delta"),t.Literal("screenCenter")])),maxLookDegrees:t.Optional(t.Number()),lookSensitivity:t.Optional(t.Number())},{title:"MouseConfig",additionalProperties:!1}),J=t.Object({key:t.Optional(y),mouse:t.Optional(x),touch:t.Optional(b),includeDefaults:t.Optional(t.Boolean())},{title:"GameInputPlayerConfig",additionalProperties:!1}),l=t.Record(t.String(),J,{$id:"GameInputConfig",title:"GameInputConfig",description:"Keys are player slots: p1, p2, p3, p4, p5, p6, p7, p8."});import{Type as i}from"@sinclair/typebox";var T=i.Union([i.String(),i.Number()],{title:"ColorJson",description:"CSS color string or numeric hex (Three.js Color-compatible)."}),L=i.Tuple([i.Number(),i.Number(),i.Number()],{title:"Vec3Components"}),E=i.Object({meshopt:i.Optional(i.Boolean()),ktx2TranscoderPath:i.Optional(i.String())},{title:"StageGLTFAssetLoaderConfig",additionalProperties:!1}),V=i.Object({gltf:i.Optional(E)},{title:"StageAssetLoaderConfig",additionalProperties:!1}),G=i.Object({inputs:i.Optional(i.Record(i.String(),i.Array(i.String()))),backgroundColor:i.Optional(T),backgroundImage:i.Optional(i.Union([i.String(),i.Null()])),gravity:i.Optional(L),variables:i.Optional(i.Record(i.String(),i.Unknown())),physicsRate:i.Optional(i.Number({exclusiveMinimum:0})),assetLoaders:i.Optional(V),defaultLighting:i.Optional(i.Boolean())},{$id:"StageConfigJson",title:"StageConfigJson",additionalProperties:!1});import{Type as o}from"@sinclair/typebox";var c=o.Union([o.String(),o.Object({width:o.Number({exclusiveMinimum:0}),height:o.Number({exclusiveMinimum:0})}),o.Literal("native")],{title:"ResolutionInput"}),N=o.Object({aspectRatio:o.Optional(o.Union([o.Number(),o.String()])),preset:o.Optional(o.String()),resolution:o.Optional(c),controls:o.Optional(o.Boolean())},{title:"GameDeviceConfigJson",additionalProperties:!1}),P=o.Object({id:o.Optional(o.String()),globals:o.Optional(o.Record(o.String(),o.Unknown())),debug:o.Optional(o.Boolean()),time:o.Optional(o.Number()),input:o.Optional(l),aspectRatio:o.Optional(o.Union([o.Number(),o.String()])),preset:o.Optional(o.String()),resolution:o.Optional(c),mobile:o.Optional(N),fullscreen:o.Optional(o.Boolean()),bodyBackground:o.Optional(o.String()),containerId:o.Optional(o.String())},{$id:"GameConfigJson",title:"GameConfigJson",additionalProperties:!1});export{n as a,s as b,D as c,S as d,m as e,g as f,u as g,h,B as i,y as j,O as k,a as l,p as m,f as n,r as o,d as p,C as q,b as r,x as s,J as t,l as u,T as v,L as w,E as x,V as y,G as z,c as A,N as B,P as C};
1
+ import{Type as e}from"@sinclair/typebox";var n=e.Tuple([e.Number(),e.Number()],{title:"Vector2",description:"A 2D position as [x, y]."}),s=e.Object({id:e.String(),type:e.String({minLength:1}),position:e.Optional(n),data:e.Optional(e.Record(e.String(),e.Any()))},{$id:"EntityBlueprint",title:"EntityBlueprint",additionalProperties:!1}),N=e.Object({id:e.String(),name:e.Optional(e.String()),entities:e.Array(s),assets:e.Optional(e.Array(e.String()))},{$id:"StageBlueprint",title:"StageBlueprint",additionalProperties:!1}),S=e.Object({value:e.Optional(e.String()),color:e.Optional(e.String()),fontSize:e.Optional(e.Number()),fontFamily:e.Optional(e.String())},{title:"TextEntityData",additionalProperties:!0}),m=e.Tuple([e.Number(),e.Number(),e.Number()],{title:"Vector3Tuple"}),g=e.Object({points:e.Array(m,{minItems:2}),color:e.Optional(e.String()),colors:e.Optional(e.Array(e.String())),linewidth:e.Optional(e.Number()),worldUnits:e.Optional(e.Boolean()),alphaToCoverage:e.Optional(e.Boolean()),opacity:e.Optional(e.Number()),transparent:e.Optional(e.Boolean()),dashed:e.Optional(e.Boolean()),dashSize:e.Optional(e.Number()),gapSize:e.Optional(e.Number()),pickThreshold:e.Optional(e.Number())},{title:"LineEntityData",additionalProperties:!0}),u=e.Object({imagePath:e.Optional(e.String()),width:e.Optional(e.Number()),height:e.Optional(e.Number())},{title:"SpriteEntityData",additionalProperties:!0}),h=e.Union([e.Object({id:e.String(),type:e.Literal("text"),position:e.Optional(n),data:e.Optional(S)}),e.Object({id:e.String(),type:e.Literal("sprite"),position:e.Optional(n),data:e.Optional(u)}),e.Object({id:e.String(),type:e.Literal("line"),position:e.Optional(n),data:e.Optional(g)}),e.Object({id:e.String(),type:e.String({minLength:1}),position:e.Optional(n),data:e.Optional(e.Record(e.String(),e.Unknown()))})],{$id:"EntityJson",title:"EntityJson"}),B=e.Object({id:e.String(),name:e.Optional(e.String()),entities:e.Array(h),assets:e.Optional(e.Array(e.String()))},{$id:"StageJson",title:"StageJson",additionalProperties:!1});import{Type as t}from"@sinclair/typebox";var y=t.Record(t.String(),t.Array(t.String()),{title:"KeyboardMapping"}),f=t.Record(t.String(),t.Array(t.String()),{title:"MouseMapping"}),a=t.Record(t.String(),t.Union([t.String(),t.Number()]),{title:"VirtualTouchStyle"}),p=t.Object({top:t.Optional(t.Union([t.String(),t.Number()])),right:t.Optional(t.Union([t.String(),t.Number()])),bottom:t.Optional(t.Union([t.String(),t.Number()])),left:t.Optional(t.Union([t.String(),t.Number()])),transform:t.Optional(t.String())},{title:"VirtualTouchPosition",additionalProperties:!1}),O=t.Object({enabled:t.Optional(t.Boolean()),className:t.Optional(t.String()),style:t.Optional(a),position:t.Optional(p),size:t.Optional(t.Number()),label:t.Optional(t.String()),svg:t.Optional(t.String())},{title:"VirtualTouchButtonConfig",additionalProperties:!1}),r=t.Object({enabled:t.Optional(t.Boolean()),className:t.Optional(t.String()),style:t.Optional(a),position:t.Optional(p),size:t.Optional(t.Number()),thumbSize:t.Optional(t.Number()),maxDistance:t.Optional(t.Number()),deadzone:t.Optional(t.Number()),directionThreshold:t.Optional(t.Number()),horizontalAxis:t.Optional(t.Union([t.Literal("Horizontal"),t.Literal("SecondaryHorizontal")])),verticalAxis:t.Optional(t.Union([t.Literal("Vertical"),t.Literal("SecondaryVertical")])),emitDirections:t.Optional(t.Boolean()),svg:t.Optional(t.Object({base:t.Optional(t.String()),thumb:t.Optional(t.String())}))},{title:"VirtualTouchJoystickConfig",additionalProperties:!1}),j=t.Union([O,t.Literal(!1)]),d=t.Record(t.String(),j,{title:"VirtualTouchButtonsConfig",description:"Keys are touch button slots: A, B, X, Y, Start, Select, L, R, LTrigger, RTrigger, Up, Down, Left, Right."}),C=t.Object({left:t.Optional(t.Union([r,t.Literal(!1)])),right:t.Optional(t.Union([r,t.Literal(!1)]))},{title:"VirtualTouchJoysticksConfig",additionalProperties:!1}),b=t.Object({enabled:t.Optional(t.Union([t.Boolean(),t.Literal("auto")])),className:t.Optional(t.String()),style:t.Optional(a),joysticks:t.Optional(t.Union([C,t.Literal(!1)])),buttons:t.Optional(t.Union([d,t.Literal(!1)]))},{title:"VirtualTouchConfig",additionalProperties:!1}),x=t.Object({mapping:t.Optional(f),pointerLock:t.Optional(t.Boolean()),sensitivity:t.Optional(t.Number()),lookMode:t.Optional(t.Union([t.Literal("delta"),t.Literal("screenCenter")])),maxLookDegrees:t.Optional(t.Number()),lookSensitivity:t.Optional(t.Number())},{title:"MouseConfig",additionalProperties:!1}),J=t.Object({key:t.Optional(y),mouse:t.Optional(x),touch:t.Optional(b),includeDefaults:t.Optional(t.Boolean())},{title:"GameInputPlayerConfig",additionalProperties:!1}),l=t.Record(t.String(),J,{$id:"GameInputConfig",title:"GameInputConfig",description:"Keys are player slots: p1, p2, p3, p4, p5, p6, p7, p8."});import{Type as i}from"@sinclair/typebox";var T=i.Union([i.String(),i.Number()],{title:"ColorJson",description:"CSS color string or numeric hex (Three.js Color-compatible)."}),L=i.Tuple([i.Number(),i.Number(),i.Number()],{title:"Vec3Components"}),D=i.Object({meshopt:i.Optional(i.Boolean()),ktx2TranscoderPath:i.Optional(i.String())},{title:"StageGLTFAssetLoaderConfig",additionalProperties:!1}),E=i.Object({gltf:i.Optional(D)},{title:"StageAssetLoaderConfig",additionalProperties:!1}),G=i.Object({inputs:i.Optional(i.Record(i.String(),i.Array(i.String()))),backgroundColor:i.Optional(T),backgroundImage:i.Optional(i.Union([i.String(),i.Null()])),gravity:i.Optional(L),variables:i.Optional(i.Record(i.String(),i.Unknown())),physicsRate:i.Optional(i.Number({exclusiveMinimum:0})),assetLoaders:i.Optional(E),defaultLighting:i.Optional(i.Boolean())},{$id:"StageConfigJson",title:"StageConfigJson",additionalProperties:!1});import{Type as o}from"@sinclair/typebox";var c=o.Union([o.String(),o.Object({width:o.Number({exclusiveMinimum:0}),height:o.Number({exclusiveMinimum:0})}),o.Literal("native")],{title:"ResolutionInput"}),V=o.Object({aspectRatio:o.Optional(o.Union([o.Number(),o.String()])),preset:o.Optional(o.String()),resolution:o.Optional(c),controls:o.Optional(o.Boolean())},{title:"GameDeviceConfigJson",additionalProperties:!1}),P=o.Object({id:o.Optional(o.String()),globals:o.Optional(o.Record(o.String(),o.Unknown())),debug:o.Optional(o.Boolean()),time:o.Optional(o.Number()),input:o.Optional(l),aspectRatio:o.Optional(o.Union([o.Number(),o.String()])),preset:o.Optional(o.String()),resolution:o.Optional(c),mobile:o.Optional(V),fullscreen:o.Optional(o.Boolean()),bodyBackground:o.Optional(o.String()),containerId:o.Optional(o.String())},{$id:"GameConfigJson",title:"GameConfigJson",additionalProperties:!1});export{n as a,s as b,N as c,S as d,m as e,g as f,u as g,h,B as i,y as j,f as k,a as l,p as m,O as n,r as o,d as p,C as q,b as r,x as s,J as t,l as u,T as v,L as w,D as x,E as y,G as z,c as A,V as B,P as C};
@@ -1 +1 @@
1
- import{a as f}from"./chunk-X7T7QRYP.js";import{b as u,r as C,s as G,t as d,v as D,w as U,y as v,z as b}from"./chunk-KP6DLLJO.js";import{e as V}from"./chunk-6FGXC4T6.js";import{c as h,d as y,h as m,i as E,j as x}from"./chunk-7WRQ2UAN.js";import{Color as B,Group as st,Sprite as ot,SpriteMaterial as at,CanvasTexture as H,LinearFilter as w,Vector2 as pt,ClampToEdgeWrapping as W}from"three";var g={position:void 0,text:"",fontFamily:'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',fontSize:18,fontColor:"#FFFFFF",backgroundColor:null,padding:4,stickToViewport:!0,screenPosition:new pt(24,24),zDistance:1},O=class extends v{createEntity(t){return new _(t)}},lt=Symbol("Text"),_=class i extends d{static type=lt;_sprite=null;_texture=null;_canvas=null;_ctx=null;_cameraRef=null;_lastCanvasW=0;_lastCanvasH=0;constructor(t){super(),this.options=u(g,t),this.options.screenPosition=E(this.options.screenPosition,g.screenPosition),this.prependSetup(this.textSetup.bind(this)),this.prependUpdate(this.textUpdate.bind(this)),this.onCleanup(this.textDestroy.bind(this))}create(){return this._sprite=null,this._texture=null,this._canvas=null,this._ctx=null,this._lastCanvasW=0,this._lastCanvasH=0,this.group=new st,this.createSprite(),super.create()}createSprite(){this._canvas=document.createElement("canvas"),this._ctx=this._canvas.getContext("2d"),this._texture=new H(this._canvas),this._texture.minFilter=w,this._texture.magFilter=w;let t=new at({map:this._texture,transparent:!0,depthTest:!1,depthWrite:!1,alphaTest:.5});this._sprite=new ot(t),this.group?.add(this._sprite),this.redrawText(this.options.text??"")}measureAndResizeCanvas(t,e,n,s){if(!this._canvas||!this._ctx)return{sizeChanged:!1};this._ctx.font=`${e}px ${n}`;let r=this._ctx.measureText(t),o=Math.ceil(r.width),a=Math.ceil(e*1.4),p=Math.max(2,o+s*2),l=Math.max(2,a+s*2),T=p!==this._lastCanvasW||l!==this._lastCanvasH;return this._canvas.width=p,this._canvas.height=l,this._lastCanvasW=p,this._lastCanvasH=l,{sizeChanged:T}}drawCenteredText(t,e,n){!this._canvas||!this._ctx||(this._ctx.font=`${e}px ${n}`,this._ctx.textAlign="center",this._ctx.textBaseline="middle",this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this.options.backgroundColor&&(this._ctx.fillStyle=this.toCssColor(this.options.backgroundColor),this._ctx.fillRect(0,0,this._canvas.width,this._canvas.height)),this._ctx.fillStyle=this.toCssColor(this.options.fontColor??"#FFFFFF"),this._ctx.fillText(t,this._canvas.width/2,this._canvas.height/2))}updateTexture(t){!this._texture||!this._canvas||(t&&(this._texture.dispose(),this._texture=new H(this._canvas),this._texture.minFilter=w,this._texture.magFilter=w,this._texture.wrapS=W,this._texture.wrapT=W),this._texture.image=this._canvas,this._texture.needsUpdate=!0,this._sprite&&this._sprite.material&&(this._sprite.material.map=this._texture,this._sprite.material.needsUpdate=!0))}redrawText(t){if(!this._canvas||!this._ctx)return;let e=this.options.fontSize??18,n=this.options.fontFamily??g.fontFamily,s=this.options.padding??4,{sizeChanged:r}=this.measureAndResizeCanvas(t,e,n,s);this.drawCenteredText(t,e,n),this.updateTexture(!!r),this.options.stickToViewport&&this._cameraRef?this.updateStickyTransform():this.updateWorldSpriteScale()}toCssColor(t){return typeof t=="string"?t:`#${(t instanceof B?t:new B(t)).getHexString()}`}textSetup(t){this._cameraRef=t.camera,this.options.stickToViewport&&this._cameraRef&&(this._cameraRef.camera.add(this.group),this.updateStickyTransform())}textUpdate(t){this._sprite&&this.options.stickToViewport&&this._cameraRef&&this.updateStickyTransform()}getResolution(){return{width:this._cameraRef?.screenResolution.x??1,height:this._cameraRef?.screenResolution.y??1}}getScreenPixels(t,e,n){let s=t.x>=0&&t.x<=1,r=t.y>=0&&t.y<=1;return{px:s?t.x*e:t.x,py:r?t.y*n:t.y}}computeWorldExtents(t,e){let n=1,s=1;if(t.isPerspectiveCamera){let r=t,o=Math.tan(r.fov*Math.PI/180/2)*e;n=o*r.aspect,s=o}else if(t.isOrthographicCamera){let r=t;n=(r.right-r.left)/2,s=(r.top-r.bottom)/2}return{worldHalfW:n,worldHalfH:s}}updateSpriteScale(t,e){if(!this._canvas||!this._sprite)return;let s=t*2/e,r=this._canvas.height,o=Math.max(1e-4,r*s),a=this._canvas.width/this._canvas.height,p=o*a;this._sprite.scale.set(p,o,1)}updateWorldSpriteScale(){if(!this._canvas||!this._sprite)return;let t=this._canvas.width/Math.max(1,this._canvas.height),e=Math.max(1,this.options.fontSize??18),n=Math.max(.25,e/32),s=n*t;this._sprite.scale.set(s,n,1)}updateStickyTransform(){if(!this._sprite||!this._cameraRef)return;let t=this._cameraRef.camera,{width:e,height:n}=this.getResolution(),s=E(this.options.screenPosition,g.screenPosition),{px:r,py:o}=this.getScreenPixels(s,e,n),a=Math.max(.001,this.options.zDistance??1),{worldHalfW:p,worldHalfH:l}=this.computeWorldExtents(t,a),T=r/e*2-1,it=1-o/n*2,nt=T*p,rt=it*l;this.group?.position.set(nt,rt,-a),this.updateSpriteScale(l,n)}updateText(t){this.options.text=t,this.redrawText(t),this.options.stickToViewport&&this._cameraRef&&this.updateStickyTransform()}buildInfo(){return{...new f(this).buildDebugInfo(),type:String(i.type),text:this.options.text??"",sticky:this.options.stickToViewport}}textDestroy(){this._texture?.dispose(),this._sprite?.material&&this._sprite.material.dispose(),this._sprite&&this._sprite.removeFromParent(),this.group?.removeFromParent(),this._sprite=null,this._texture=null,this._canvas=null,this._ctx=null,this._cameraRef=null}};function F(...i){return b({args:i,defaultConfig:{...g},EntityClass:_,BuilderClass:O,entityType:_.type,cloneFactory:t=>F(t??{})})}import{Euler as ct,Group as X,Quaternion as ht,Vector3 as mt}from"three";import{TextureLoader as N,SpriteMaterial as Y,Sprite as $,SRGBColorSpace as j}from"three";import{ClampToEdgeWrapping as Q,LinearFilter as ut,NearestFilter as dt}from"three";var q={...C,size:new mt(1,1,1),images:[],animations:[]},L=class extends U{collider(t){let e=x(t.collisionSize,t.size??y);return{shape:{type:"box",halfExtents:[e.x/2,e.y/2,e.z/2]}}}},I=class extends v{createEntity(t){return new S(t)}},ft=Symbol("Sprite"),S=class i extends d{static type=ft;sprites=[];spriteMap=new Map;currentSpriteIndex=0;animations=new Map;currentAnimation=null;currentAnimationFrame="";currentAnimationIndex=0;currentAnimationTime=0;sheetTexture=null;flippedX=!1;constructor(t){super(),this.options=u(q,t),this.prependSetup(this.spriteSetup.bind(this)),this.prependUpdate(this.spriteUpdate.bind(this)),this.onCleanup(this.spriteDestroy.bind(this))}create(){return this.sprites=[],this.spriteMap.clear(),this.animations.clear(),this.currentAnimation=null,this.currentAnimationFrame="",this.currentAnimationIndex=0,this.currentAnimationTime=0,this.sheetTexture=null,this.group=void 0,this.options?.sheet?this.createSpriteFromSheet(this.options.sheet):this.createSpritesFromImages(this.options?.images||[]),this.createAnimations(this.options?.animations||[]),super.create()}createSpritesFromImages(t){let e=new N,n=x(this.options.size,y);t.forEach((s,r)=>{let o=e.load(s.file);o.colorSpace=j,o.anisotropy=V;let a=new Y({map:o,transparent:!0}),p=new $(a);p.position.normalize(),p.scale.set(n.x,n.y,n.z),p.visible=r===0,this.sprites.push(p),this.spriteMap.set(s.name,r)}),this.group=new X,this.group.add(...this.sprites)}createSpriteFromSheet(t){let e=x(this.options.size,y),n=new N().load(t.file);n.colorSpace=j,n.wrapS=Q,n.wrapT=Q;let s=t.filter==="linear"?ut:dt;n.magFilter=s,n.minFilter=s,n.generateMipmaps=!1,n.repeat.set(1/t.columns,1/t.rows);let r=new Y({map:n,transparent:!0}),o=new $(r);o.position.normalize(),o.scale.set(e.x,e.y,e.z),this.sheetTexture=n,this.sprites.push(o),t.frames.forEach((p,l)=>{p&&this.spriteMap.set(p,l)}),this.group=new X,this.group.add(o);let a=t.frames.find(p=>!!p);a&&this.setSprite(a)}createAnimations(t){t.forEach(e=>{let{name:n,frames:s,loop:r=!1,speed:o=1}=e,a={frames:s.map((p,l)=>({key:p,index:l,duration:typeof o=="number"?o:o[l]})),loop:r};this.animations.set(n,a)})}setSprite(t){let n=this.spriteMap.get(t)??0;if(this.currentSpriteIndex=n,this.sheetTexture){this.applySheetFrame(n);return}this.sprites.forEach((s,r)=>{s.visible=this.currentSpriteIndex===r})}setFlipX(t){if(this.flippedX!==t){if(this.flippedX=t,this.sheetTexture){this.applySheetFrame(this.currentSpriteIndex);return}this.sprites.forEach(e=>{e.material.map?.repeat.setX(t?-1:1),e.material.map?.offset.setX(t?1:0)})}}isFlippedX(){return this.flippedX}applySheetFrame(t){let e=this.options.sheet,n=this.sheetTexture;if(!e||!n)return;let s=t%e.columns,r=Math.floor(t/e.columns),o=1/e.columns,a=1/e.rows;n.repeat.x=this.flippedX?-o:o,n.offset.x=this.flippedX?(s+1)*o:s*o,n.offset.y=1-(r+1)*a}setAnimation(t,e){let n=this.animations.get(t);if(!n)return;let{loop:s,frames:r}=n;if(r.length!==0){for(t!==this.currentAnimation?(this.currentAnimation=t,this.currentAnimationIndex=0,this.currentAnimationTime=0):this.currentAnimationTime+=e;;){let o=r[this.currentAnimationIndex].duration;if(!(o>0)||this.currentAnimationTime<o)break;if(this.currentAnimationTime-=o,this.currentAnimationIndex+1<r.length)this.currentAnimationIndex++;else if(s)this.currentAnimationIndex=0;else{this.currentAnimationTime=0;break}}this.currentAnimationFrame=r[this.currentAnimationIndex].key,this.setSprite(this.currentAnimationFrame)}}getCurrentRotationQuaternion(){return this.transformStore?.dirty.rotation?this.transformStore.rotation:this.body?.rotation?.()??null}syncSpriteMaterials(){let t=this.getCurrentRotationQuaternion();this.sprites.forEach(e=>{if(e.material&&t){let s=new ht(t.x,t.y,t.z,t.w),r=new ct().setFromQuaternion(s,"XYZ");e.material.rotation=r.z}let n=x(this.options.size,y);e.scale.set(n.x,n.y,n.z)})}spriteSetup(t){this.syncSpriteMaterials()}spriteUpdate(t){this.syncSpriteMaterials()}spriteDestroy(t){this.sprites.forEach(e=>{e.removeFromParent()}),this.group?.remove(...this.sprites),this.group?.removeFromParent(),this.sheetTexture?.dispose(),this.sheetTexture=null}buildInfo(){return{...new f(this).buildDebugInfo(),type:String(i.type)}}};function z(...i){return b({args:i,defaultConfig:q,EntityClass:S,BuilderClass:I,CollisionBuilderClass:L,entityType:S.type,cloneFactory:t=>z(t??{})})}import{Color as tt,Group as xt}from"three";import{Line2NodeMaterial as gt}from"three/webgpu";import{Line2 as _t}from"three/addons/lines/webgpu/Line2.js";import{Color as J}from"three";import{LineGeometry as yt}from"three/addons/lines/LineGeometry.js";function R(i){let t=[];for(let e of i){let{x:n,y:s,z:r}=m(e,h);t.push(n,s,r)}return t}function P(i,t,e){if(!i||i.length===0)return;let n=[],s=new J(e);for(let r=0;r<t;r++){let o=i[r]??i[i.length-1]??e,a=new J(o??s);n.push(a.r,a.g,a.b)}return n}function K(i){let t=new yt,e=R(i.points);t.setPositions(e);let n=P(i.colors,i.points.length,"#ffffff");return n&&t.setColors(n),t}var c={...C,points:[{x:0,y:0,z:0},{x:1,y:0,z:0}],linewidth:1,worldUnits:!0,alphaToCoverage:!1,opacity:1,transparent:!1,dashed:!1,dashSize:1,gapSize:1,pickThreshold:0},St=Symbol("Line");function Z(i,t){if(!i||i.length<2)throw new Error(`${t}: at least two points are required`);return i}function et(i){return i instanceof tt?i.clone():new tt(i??"#ffffff")}function Ct(i){let t=!!i.colors?.length,e=new gt({color:et(i.color).getHex(),linewidth:i.linewidth??c.linewidth,worldUnits:i.worldUnits??c.worldUnits,vertexColors:t,dashed:i.dashed??!1,dashSize:i.dashSize??c.dashSize,gapSize:i.gapSize??c.gapSize,transparent:i.transparent??!1,opacity:i.opacity??1});return e.alphaToCoverage=i.alphaToCoverage??!1,e}function vt(i){return!i.point||!i.pointOnLine||i.faceIndex==null?null:{point:i.point.clone(),pointOnLine:i.pointOnLine.clone(),faceIndex:i.faceIndex,distance:i.distance}}function bt(i,t,e={}){let n=t.getLineObject();if(!n)return null;let s=e.threshold??t.options.pickThreshold??0,r=i.params.Line2??{threshold:0};r.threshold=s,i.params.Line2=r;let a=i.intersectObject(n,!1)[0];return a?vt(a):null}var A=class i extends d{static type=St;_line=null;_geometry=null;_material=null;constructor(t){super();let e=u(c,t);e.points=Z(e.points,"ZylemLine").map(n=>m(n,h)),this.options=e}create(){return this.disposeLineResources(),this.group=new xt,this.rebuildLine(),this.applyGroupPosition(),super.create()}setPoints(t,e){if(Z(t,"setPoints"),this.options.points=t.map(s=>m(s,h)),e&&(this.options.colors=e),!this._line||!this._geometry||!this._material)return this;this._geometry.setPositions(R(this.options.points));let n=P(this.options.colors,this.options.points.length,et(this.options.color));return n&&this._geometry.setColors(n),this._material.vertexColors=!!this.options.colors?.length,this.options.dashed&&this._line.computeLineDistances(),this._geometry.computeBoundingBox(),this._geometry.computeBoundingSphere(),this}getLineObject(){return this._line}pickFromRaycaster(t,e={}){return bt(t,this,e)}buildInfo(){return{...new f(this).buildDebugInfo(),type:String(i.type),points:this.options.points.length,linewidth:this.options.linewidth??c.linewidth,worldUnits:this.options.worldUnits??c.worldUnits}}rebuildLine(){this._geometry=K({points:this.options.points,colors:this.options.colors}),this._material=Ct(this.options),this._line=new _t(this._geometry,this._material),this.options.dashed&&this._line.computeLineDistances(),this.group?.add(this._line)}applyGroupPosition(){if(!this.group)return;let t=m(this.options.position,h);this.group.position.set(t.x,t.y,t.z)}_cleanup(t){this.disposeLineResources(),super._cleanup(t)}disposeLineResources(){this._line?.removeFromParent(),this._geometry?.dispose(),this._material?.dispose(),this._line=null,this._geometry=null,this._material=null}};function M(...i){let t=G(i,c);Z(t.points,"createLine");let e=new A(t);return D(e,n=>M(n??{}))}var k={registry:new Map,register(i,t){this.registry.set(i,t)},createFromBlueprint(i){let t=this.registry.get(i.type);if(!t)throw new Error(`Unknown entity type: ${i.type}`);let e={...i.data,position:i.position?{x:i.position[0],y:i.position[1],z:0}:void 0,name:i.id};return t(e)}};k.register("text",i=>F(i));k.register("sprite",i=>z(i));k.register("line",i=>M(i));function ge(i){return{template:i,generate(t){let e=[];for(let n=0;n<t;n++)e.push(i.clone());return e}}}export{lt as a,_ as b,F as c,ft as d,S as e,z as f,St as g,bt as h,A as i,M as j,k,ge as l};
1
+ import{a as f}from"./chunk-STVEILJJ.js";import{b as u,r as C,s as G,t as d,v as D,w as U,y as v,z as b}from"./chunk-KP6DLLJO.js";import{e as V}from"./chunk-6FGXC4T6.js";import{c as h,d as y,h as m,i as E,j as x}from"./chunk-7WRQ2UAN.js";import{Color as B,Group as st,Sprite as ot,SpriteMaterial as at,CanvasTexture as H,LinearFilter as w,Vector2 as pt,ClampToEdgeWrapping as W}from"three";var g={position:void 0,text:"",fontFamily:'Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',fontSize:18,fontColor:"#FFFFFF",backgroundColor:null,padding:4,stickToViewport:!0,screenPosition:new pt(24,24),zDistance:1},O=class extends v{createEntity(t){return new _(t)}},lt=Symbol("Text"),_=class i extends d{static type=lt;_sprite=null;_texture=null;_canvas=null;_ctx=null;_cameraRef=null;_lastCanvasW=0;_lastCanvasH=0;constructor(t){super(),this.options=u(g,t),this.options.screenPosition=E(this.options.screenPosition,g.screenPosition),this.prependSetup(this.textSetup.bind(this)),this.prependUpdate(this.textUpdate.bind(this)),this.onCleanup(this.textDestroy.bind(this))}create(){return this._sprite=null,this._texture=null,this._canvas=null,this._ctx=null,this._lastCanvasW=0,this._lastCanvasH=0,this.group=new st,this.createSprite(),super.create()}createSprite(){this._canvas=document.createElement("canvas"),this._ctx=this._canvas.getContext("2d"),this._texture=new H(this._canvas),this._texture.minFilter=w,this._texture.magFilter=w;let t=new at({map:this._texture,transparent:!0,depthTest:!1,depthWrite:!1,alphaTest:.5});this._sprite=new ot(t),this.group?.add(this._sprite),this.redrawText(this.options.text??"")}measureAndResizeCanvas(t,e,n,s){if(!this._canvas||!this._ctx)return{sizeChanged:!1};this._ctx.font=`${e}px ${n}`;let r=this._ctx.measureText(t),o=Math.ceil(r.width),a=Math.ceil(e*1.4),p=Math.max(2,o+s*2),l=Math.max(2,a+s*2),T=p!==this._lastCanvasW||l!==this._lastCanvasH;return this._canvas.width=p,this._canvas.height=l,this._lastCanvasW=p,this._lastCanvasH=l,{sizeChanged:T}}drawCenteredText(t,e,n){!this._canvas||!this._ctx||(this._ctx.font=`${e}px ${n}`,this._ctx.textAlign="center",this._ctx.textBaseline="middle",this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this.options.backgroundColor&&(this._ctx.fillStyle=this.toCssColor(this.options.backgroundColor),this._ctx.fillRect(0,0,this._canvas.width,this._canvas.height)),this._ctx.fillStyle=this.toCssColor(this.options.fontColor??"#FFFFFF"),this._ctx.fillText(t,this._canvas.width/2,this._canvas.height/2))}updateTexture(t){!this._texture||!this._canvas||(t&&(this._texture.dispose(),this._texture=new H(this._canvas),this._texture.minFilter=w,this._texture.magFilter=w,this._texture.wrapS=W,this._texture.wrapT=W),this._texture.image=this._canvas,this._texture.needsUpdate=!0,this._sprite&&this._sprite.material&&(this._sprite.material.map=this._texture,this._sprite.material.needsUpdate=!0))}redrawText(t){if(!this._canvas||!this._ctx)return;let e=this.options.fontSize??18,n=this.options.fontFamily??g.fontFamily,s=this.options.padding??4,{sizeChanged:r}=this.measureAndResizeCanvas(t,e,n,s);this.drawCenteredText(t,e,n),this.updateTexture(!!r),this.options.stickToViewport&&this._cameraRef?this.updateStickyTransform():this.updateWorldSpriteScale()}toCssColor(t){return typeof t=="string"?t:`#${(t instanceof B?t:new B(t)).getHexString()}`}textSetup(t){this._cameraRef=t.camera,this.options.stickToViewport&&this._cameraRef&&(this._cameraRef.camera.add(this.group),this.updateStickyTransform())}textUpdate(t){this._sprite&&this.options.stickToViewport&&this._cameraRef&&this.updateStickyTransform()}getResolution(){return{width:this._cameraRef?.screenResolution.x??1,height:this._cameraRef?.screenResolution.y??1}}getScreenPixels(t,e,n){let s=t.x>=0&&t.x<=1,r=t.y>=0&&t.y<=1;return{px:s?t.x*e:t.x,py:r?t.y*n:t.y}}computeWorldExtents(t,e){let n=1,s=1;if(t.isPerspectiveCamera){let r=t,o=Math.tan(r.fov*Math.PI/180/2)*e;n=o*r.aspect,s=o}else if(t.isOrthographicCamera){let r=t;n=(r.right-r.left)/2,s=(r.top-r.bottom)/2}return{worldHalfW:n,worldHalfH:s}}updateSpriteScale(t,e){if(!this._canvas||!this._sprite)return;let s=t*2/e,r=this._canvas.height,o=Math.max(1e-4,r*s),a=this._canvas.width/this._canvas.height,p=o*a;this._sprite.scale.set(p,o,1)}updateWorldSpriteScale(){if(!this._canvas||!this._sprite)return;let t=this._canvas.width/Math.max(1,this._canvas.height),e=Math.max(1,this.options.fontSize??18),n=Math.max(.25,e/32),s=n*t;this._sprite.scale.set(s,n,1)}updateStickyTransform(){if(!this._sprite||!this._cameraRef)return;let t=this._cameraRef.camera,{width:e,height:n}=this.getResolution(),s=E(this.options.screenPosition,g.screenPosition),{px:r,py:o}=this.getScreenPixels(s,e,n),a=Math.max(.001,this.options.zDistance??1),{worldHalfW:p,worldHalfH:l}=this.computeWorldExtents(t,a),T=r/e*2-1,it=1-o/n*2,nt=T*p,rt=it*l;this.group?.position.set(nt,rt,-a),this.updateSpriteScale(l,n)}updateText(t){this.options.text=t,this.redrawText(t),this.options.stickToViewport&&this._cameraRef&&this.updateStickyTransform()}buildInfo(){return{...new f(this).buildDebugInfo(),type:String(i.type),text:this.options.text??"",sticky:this.options.stickToViewport}}textDestroy(){this._texture?.dispose(),this._sprite?.material&&this._sprite.material.dispose(),this._sprite&&this._sprite.removeFromParent(),this.group?.removeFromParent(),this._sprite=null,this._texture=null,this._canvas=null,this._ctx=null,this._cameraRef=null}};function F(...i){return b({args:i,defaultConfig:{...g},EntityClass:_,BuilderClass:O,entityType:_.type,cloneFactory:t=>F(t??{})})}import{Euler as ct,Group as X,Quaternion as ht,Vector3 as mt}from"three";import{TextureLoader as N,SpriteMaterial as Y,Sprite as $,SRGBColorSpace as j}from"three";import{ClampToEdgeWrapping as Q,LinearFilter as ut,NearestFilter as dt}from"three";var q={...C,size:new mt(1,1,1),images:[],animations:[]},L=class extends U{collider(t){let e=x(t.collisionSize,t.size??y);return{shape:{type:"box",halfExtents:[e.x/2,e.y/2,e.z/2]}}}},I=class extends v{createEntity(t){return new S(t)}},ft=Symbol("Sprite"),S=class i extends d{static type=ft;sprites=[];spriteMap=new Map;currentSpriteIndex=0;animations=new Map;currentAnimation=null;currentAnimationFrame="";currentAnimationIndex=0;currentAnimationTime=0;sheetTexture=null;flippedX=!1;constructor(t){super(),this.options=u(q,t),this.prependSetup(this.spriteSetup.bind(this)),this.prependUpdate(this.spriteUpdate.bind(this)),this.onCleanup(this.spriteDestroy.bind(this))}create(){return this.sprites=[],this.spriteMap.clear(),this.animations.clear(),this.currentAnimation=null,this.currentAnimationFrame="",this.currentAnimationIndex=0,this.currentAnimationTime=0,this.sheetTexture=null,this.group=void 0,this.options?.sheet?this.createSpriteFromSheet(this.options.sheet):this.createSpritesFromImages(this.options?.images||[]),this.createAnimations(this.options?.animations||[]),super.create()}createSpritesFromImages(t){let e=new N,n=x(this.options.size,y);t.forEach((s,r)=>{let o=e.load(s.file);o.colorSpace=j,o.anisotropy=V;let a=new Y({map:o,transparent:!0}),p=new $(a);p.position.normalize(),p.scale.set(n.x,n.y,n.z),p.visible=r===0,this.sprites.push(p),this.spriteMap.set(s.name,r)}),this.group=new X,this.group.add(...this.sprites)}createSpriteFromSheet(t){let e=x(this.options.size,y),n=new N().load(t.file);n.colorSpace=j,n.wrapS=Q,n.wrapT=Q;let s=t.filter==="linear"?ut:dt;n.magFilter=s,n.minFilter=s,n.generateMipmaps=!1,n.repeat.set(1/t.columns,1/t.rows);let r=new Y({map:n,transparent:!0}),o=new $(r);o.position.normalize(),o.scale.set(e.x,e.y,e.z),this.sheetTexture=n,this.sprites.push(o),t.frames.forEach((p,l)=>{p&&this.spriteMap.set(p,l)}),this.group=new X,this.group.add(o);let a=t.frames.find(p=>!!p);a&&this.setSprite(a)}createAnimations(t){t.forEach(e=>{let{name:n,frames:s,loop:r=!1,speed:o=1}=e,a={frames:s.map((p,l)=>({key:p,index:l,duration:typeof o=="number"?o:o[l]})),loop:r};this.animations.set(n,a)})}setSprite(t){let n=this.spriteMap.get(t)??0;if(this.currentSpriteIndex=n,this.sheetTexture){this.applySheetFrame(n);return}this.sprites.forEach((s,r)=>{s.visible=this.currentSpriteIndex===r})}setFlipX(t){if(this.flippedX!==t){if(this.flippedX=t,this.sheetTexture){this.applySheetFrame(this.currentSpriteIndex);return}this.sprites.forEach(e=>{e.material.map?.repeat.setX(t?-1:1),e.material.map?.offset.setX(t?1:0)})}}isFlippedX(){return this.flippedX}applySheetFrame(t){let e=this.options.sheet,n=this.sheetTexture;if(!e||!n)return;let s=t%e.columns,r=Math.floor(t/e.columns),o=1/e.columns,a=1/e.rows;n.repeat.x=this.flippedX?-o:o,n.offset.x=this.flippedX?(s+1)*o:s*o,n.offset.y=1-(r+1)*a}setAnimation(t,e){let n=this.animations.get(t);if(!n)return;let{loop:s,frames:r}=n;if(r.length!==0){for(t!==this.currentAnimation?(this.currentAnimation=t,this.currentAnimationIndex=0,this.currentAnimationTime=0):this.currentAnimationTime+=e;;){let o=r[this.currentAnimationIndex].duration;if(!(o>0)||this.currentAnimationTime<o)break;if(this.currentAnimationTime-=o,this.currentAnimationIndex+1<r.length)this.currentAnimationIndex++;else if(s)this.currentAnimationIndex=0;else{this.currentAnimationTime=0;break}}this.currentAnimationFrame=r[this.currentAnimationIndex].key,this.setSprite(this.currentAnimationFrame)}}getCurrentRotationQuaternion(){return this.transformStore?.dirty.rotation?this.transformStore.rotation:this.body?.rotation?.()??null}syncSpriteMaterials(){let t=this.getCurrentRotationQuaternion();this.sprites.forEach(e=>{if(e.material&&t){let s=new ht(t.x,t.y,t.z,t.w),r=new ct().setFromQuaternion(s,"XYZ");e.material.rotation=r.z}let n=x(this.options.size,y);e.scale.set(n.x,n.y,n.z)})}spriteSetup(t){this.syncSpriteMaterials()}spriteUpdate(t){this.syncSpriteMaterials()}spriteDestroy(t){this.sprites.forEach(e=>{e.removeFromParent()}),this.group?.remove(...this.sprites),this.group?.removeFromParent(),this.sheetTexture?.dispose(),this.sheetTexture=null}buildInfo(){return{...new f(this).buildDebugInfo(),type:String(i.type)}}};function z(...i){return b({args:i,defaultConfig:q,EntityClass:S,BuilderClass:I,CollisionBuilderClass:L,entityType:S.type,cloneFactory:t=>z(t??{})})}import{Color as tt,Group as xt}from"three";import{Line2NodeMaterial as gt}from"three/webgpu";import{Line2 as _t}from"three/addons/lines/webgpu/Line2.js";import{Color as J}from"three";import{LineGeometry as yt}from"three/addons/lines/LineGeometry.js";function R(i){let t=[];for(let e of i){let{x:n,y:s,z:r}=m(e,h);t.push(n,s,r)}return t}function P(i,t,e){if(!i||i.length===0)return;let n=[],s=new J(e);for(let r=0;r<t;r++){let o=i[r]??i[i.length-1]??e,a=new J(o??s);n.push(a.r,a.g,a.b)}return n}function K(i){let t=new yt,e=R(i.points);t.setPositions(e);let n=P(i.colors,i.points.length,"#ffffff");return n&&t.setColors(n),t}var c={...C,points:[{x:0,y:0,z:0},{x:1,y:0,z:0}],linewidth:1,worldUnits:!0,alphaToCoverage:!1,opacity:1,transparent:!1,dashed:!1,dashSize:1,gapSize:1,pickThreshold:0},St=Symbol("Line");function Z(i,t){if(!i||i.length<2)throw new Error(`${t}: at least two points are required`);return i}function et(i){return i instanceof tt?i.clone():new tt(i??"#ffffff")}function Ct(i){let t=!!i.colors?.length,e=new gt({color:et(i.color).getHex(),linewidth:i.linewidth??c.linewidth,worldUnits:i.worldUnits??c.worldUnits,vertexColors:t,dashed:i.dashed??!1,dashSize:i.dashSize??c.dashSize,gapSize:i.gapSize??c.gapSize,transparent:i.transparent??!1,opacity:i.opacity??1});return e.alphaToCoverage=i.alphaToCoverage??!1,e}function vt(i){return!i.point||!i.pointOnLine||i.faceIndex==null?null:{point:i.point.clone(),pointOnLine:i.pointOnLine.clone(),faceIndex:i.faceIndex,distance:i.distance}}function bt(i,t,e={}){let n=t.getLineObject();if(!n)return null;let s=e.threshold??t.options.pickThreshold??0,r=i.params.Line2??{threshold:0};r.threshold=s,i.params.Line2=r;let a=i.intersectObject(n,!1)[0];return a?vt(a):null}var A=class i extends d{static type=St;_line=null;_geometry=null;_material=null;constructor(t){super();let e=u(c,t);e.points=Z(e.points,"ZylemLine").map(n=>m(n,h)),this.options=e}create(){return this.disposeLineResources(),this.group=new xt,this.rebuildLine(),this.applyGroupPosition(),super.create()}setPoints(t,e){if(Z(t,"setPoints"),this.options.points=t.map(s=>m(s,h)),e&&(this.options.colors=e),!this._line||!this._geometry||!this._material)return this;this._geometry.setPositions(R(this.options.points));let n=P(this.options.colors,this.options.points.length,et(this.options.color));return n&&this._geometry.setColors(n),this._material.vertexColors=!!this.options.colors?.length,this.options.dashed&&this._line.computeLineDistances(),this._geometry.computeBoundingBox(),this._geometry.computeBoundingSphere(),this}getLineObject(){return this._line}pickFromRaycaster(t,e={}){return bt(t,this,e)}buildInfo(){return{...new f(this).buildDebugInfo(),type:String(i.type),points:this.options.points.length,linewidth:this.options.linewidth??c.linewidth,worldUnits:this.options.worldUnits??c.worldUnits}}rebuildLine(){this._geometry=K({points:this.options.points,colors:this.options.colors}),this._material=Ct(this.options),this._line=new _t(this._geometry,this._material),this.options.dashed&&this._line.computeLineDistances(),this.group?.add(this._line)}applyGroupPosition(){if(!this.group)return;let t=m(this.options.position,h);this.group.position.set(t.x,t.y,t.z)}_cleanup(t){this.disposeLineResources(),super._cleanup(t)}disposeLineResources(){this._line?.removeFromParent(),this._geometry?.dispose(),this._material?.dispose(),this._line=null,this._geometry=null,this._material=null}};function M(...i){let t=G(i,c);Z(t.points,"createLine");let e=new A(t);return D(e,n=>M(n??{}))}var k={registry:new Map,register(i,t){this.registry.set(i,t)},createFromBlueprint(i){let t=this.registry.get(i.type);if(!t)throw new Error(`Unknown entity type: ${i.type}`);let e={...i.data,position:i.position?{x:i.position[0],y:i.position[1],z:0}:void 0,name:i.id};return t(e)}};k.register("text",i=>F(i));k.register("sprite",i=>z(i));k.register("line",i=>M(i));function ge(i){return{template:i,generate(t){let e=[];for(let n=0;n<t;n++)e.push(i.clone());return e}}}export{lt as a,_ as b,F as c,ft as d,S as e,z as f,St as g,bt as h,A as i,M as j,k,ge as l};
@@ -0,0 +1 @@
1
+ import{Type as t}from"@sinclair/typebox";var e=t.Union([t.Literal("synth"),t.Literal("polySynth"),t.Literal("fmSynth"),t.Literal("amSynth"),t.Literal("membraneSynth"),t.Literal("metalSynth"),t.Literal("noiseSynth"),t.Literal("pluckSynth")],{title:"InstrumentPreset"}),i=t.Union([t.Literal("sine"),t.Literal("square"),t.Literal("sawtooth"),t.Literal("triangle")],{title:"OscillatorType"}),n=t.Object({attack:t.Number({minimum:0}),decay:t.Number({minimum:0}),sustain:t.Number({minimum:0,maximum:1}),release:t.Number({minimum:0})},{title:"Envelope",additionalProperties:!1}),o=t.Union([t.Literal("reverb"),t.Literal("delay"),t.Literal("distortion"),t.Literal("filter")],{title:"EffectType"}),r=t.Object({id:t.String(),type:o,wet:t.Optional(t.Number({minimum:0,maximum:1})),options:t.Optional(t.Record(t.String(),t.Union([t.Number(),t.String(),t.Boolean()])))},{title:"InstrumentEffect",additionalProperties:!1}),a=t.Object({id:t.String(),name:t.String(),preset:e,oscillator:t.Optional(i),envelope:t.Optional(n),volume:t.Optional(t.Number()),effects:t.Optional(t.Array(r))},{title:"InstrumentDefinition",additionalProperties:!1}),m=t.Object({id:t.Optional(t.String()),pitch:t.Integer({minimum:0,maximum:127}),start:t.Number({minimum:0}),duration:t.Number({exclusiveMinimum:0}),velocity:t.Optional(t.Number({minimum:0,maximum:1}))},{title:"SongNote",additionalProperties:!1}),l=t.Object({id:t.String(),name:t.String(),kind:t.Union([t.Literal("instrument"),t.Literal("audio")]),instrumentId:t.Optional(t.String()),color:t.Optional(t.String()),volume:t.Optional(t.Number()),pan:t.Optional(t.Number({minimum:-1,maximum:1})),mute:t.Optional(t.Boolean()),solo:t.Optional(t.Boolean())},{title:"SongTrack",additionalProperties:!1}),p=t.Object({kind:t.Literal("notes"),id:t.String(),trackId:t.String(),name:t.Optional(t.String()),start:t.Number({minimum:0}),length:t.Number({exclusiveMinimum:0}),notes:t.Array(m)},{title:"NoteClip",additionalProperties:!1}),c=t.Object({kind:t.Literal("audio"),id:t.String(),trackId:t.String(),name:t.Optional(t.String()),url:t.String(),start:t.Number({minimum:0}),offset:t.Optional(t.Number({minimum:0})),length:t.Number({exclusiveMinimum:0}),gain:t.Optional(t.Number())},{title:"AudioClip",additionalProperties:!1}),S=t.Union([p,c],{title:"SongClip"}),u=t.Object({numerator:t.Integer({minimum:1}),denominator:t.Integer({minimum:1})},{title:"TimeSignature",additionalProperties:!1}),s=t.Object({enabled:t.Boolean(),start:t.Number({minimum:0}),end:t.Number({exclusiveMinimum:0})},{title:"SongLoop",additionalProperties:!1}),y=t.Object({id:t.String(),name:t.String(),bpm:t.Number({exclusiveMinimum:0}),timeSignature:u,lengthBars:t.Integer({minimum:1}),loop:t.Optional(s),instruments:t.Array(a),tracks:t.Array(l),clips:t.Array(S),masterVolume:t.Optional(t.Number())},{$id:"SongDefinition",title:"SongDefinition",additionalProperties:!1});export{e as a,r as b,a as c,m as d,l as e,p as f,c as g,S as h,u as i,s as j,y as k};
@@ -0,0 +1 @@
1
+ function g(t){return t.numerator*4/t.denominator}function p(t){return t.lengthBars*g(t.timeSignature)}function u(t,n){return t*60/n}function I(t,n){return t*n/60}function k(t){return u(p(t),t.bpm)}function x(t){return 440*2**((t-69)/12)}var h=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function T(t){let n=Math.round(t);return`${h[(n%12+12)%12]}${Math.floor(n/12)-1}`}function N(t){return 10**(t/20)}function A(t){return t<=0?Number.NEGATIVE_INFINITY:20*Math.log10(t)}function S(t){let n=t.some(r=>r.solo),o=new Set;for(let r of t)r.mute||n&&!r.solo||o.add(r.id);return o}function M(t,n={}){let o=p(t),r=n.ignoreMix?new Set(t.tracks.map(e=>e.id)):S(t.tracks),l=n.trackIds?new Set(n.trackIds):null,b=new Map(t.tracks.map(e=>[e.id,e])),a=[],s=[];for(let e of t.clips){let i=b.get(e.trackId);if(!i||!r.has(i.id)||l&&!l.has(i.id)||e.start>=o)continue;let m=Math.min(e.start+e.length,o);if(e.kind==="notes"){if(i.kind!=="instrument"||!i.instrumentId)continue;for(let d of e.notes){let c=e.start+d.start;if(c>=m)continue;let f=Math.min(c+d.duration,m);f<=c||a.push({trackId:i.id,clipId:e.id,instrumentId:i.instrumentId,time:u(c,t.bpm),duration:u(f-c,t.bpm),pitch:d.pitch,velocity:d.velocity??.8})}}else s.push({trackId:i.id,clipId:e.id,url:e.url,time:u(e.start,t.bpm),offset:e.offset??0,duration:u(m-e.start,t.bpm),gain:e.gain??0})}return a.sort((e,i)=>e.time-i.time),s.sort((e,i)=>e.time-i.time),{notes:a,audio:s,length:u(o,t.bpm)}}function y(t,n,o){return t.clips.filter(r=>r.trackId===n&&o>=r.start&&o<r.start+r.length)}export{g as a,p as b,u as c,I as d,k as e,x as f,T as g,N as h,A as i,S as j,M as k,y as l};