gapless.js 2.2.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2017 Daniel Saewitz, Jim Geurts
3
+ Copyright (c) 2017-2025 Daniel Saewitz
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -19,4 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
-
package/README.md CHANGED
@@ -1,29 +1,33 @@
1
1
  # gapless.js
2
2
 
3
+ (this is changing)
4
+
3
5
  gapless.js is a library for gapless audio playback. It is not intended to be a flawless solution for every use-case, but rather a balance between the needs of my use-case over at <Relisten.net>.
4
6
 
5
7
  In short, it takes an array of audio tracks and utilizes HTML5 audio and the web audio API to enable gapless playback of individual tracks.
6
8
 
7
- This library targets ES2018, which should be supported by all evergreen browsers: Safari v12+, Chrome 75+, Firefox 58+.
9
+ I will expand this README with more details in time. If you're interested in this library, don't hesitate to leave me a note with any questions.
8
10
 
9
11
  You can see a sample of the library in use currently at <Relisten.live> which is the not-yet-released beta of the next version of <Relisten.net>
10
12
 
11
13
  ## Sample usage
12
14
 
13
15
  ```javascript
14
- const player = new Gapless.Queue({
15
- tracks: [
16
- "http://phish.in/audio/000/012/321/12321.mp3",
17
- "http://phish.in/audio/000/012/322/12322.mp3",
18
- "http://phish.in/audio/000/012/323/12323.mp3",
19
- "http://phish.in/audio/000/012/324/12324.mp3"
20
- ],
21
- onProgress: function(track) {
22
- track && console.log(track.completeState);
23
- }
24
- });
25
-
26
- player.play();
16
+ import GaplessQueue from 'gapless.js';
17
+
18
+ const player = new GaplessQueue({
19
+ tracks: [
20
+ "http://phish.in/audio/000/012/321/12321.mp3",
21
+ "http://phish.in/audio/000/012/322/12322.mp3",
22
+ "http://phish.in/audio/000/012/323/12323.mp3",
23
+ "http://phish.in/audio/000/012/324/12324.mp3"
24
+ ],
25
+ onProgress: function(track) {
26
+ track && console.log(track.completeState);
27
+ }
28
+ });
29
+
30
+ player.play();
27
31
  ```
28
32
 
29
33
  ## Gapless.Queue Options
@@ -0,0 +1,214 @@
1
+ type PlaybackType = 'HTML5' | 'WEBAUDIO';
2
+ type WebAudioLoadingState = 'NONE' | 'LOADING' | 'LOADED' | 'ERROR';
3
+ /** Metadata attached to a track (arbitrary user data). */
4
+ interface TrackMetadata {
5
+ title?: string;
6
+ artist?: string;
7
+ album?: string;
8
+ artwork?: MediaImage[];
9
+ [key: string]: unknown;
10
+ }
11
+ /** Options accepted by the Queue constructor. */
12
+ interface GaplessOptions {
13
+ /** Initial list of track URLs. */
14
+ tracks?: string[];
15
+ /** Called at ~60fps while playing. */
16
+ onProgress?: (info: TrackInfo) => void;
17
+ /** Called when the last track in the queue ends. */
18
+ onEnded?: () => void;
19
+ /** Called when the queue advances to the next track. */
20
+ onPlayNextTrack?: (info: TrackInfo) => void;
21
+ /** Called when the queue goes back to the previous track. */
22
+ onPlayPreviousTrack?: (info: TrackInfo) => void;
23
+ /** Called whenever a new track becomes the current track. */
24
+ onStartNewTrack?: (info: TrackInfo) => void;
25
+ /** Called on HTML5 audio errors. */
26
+ onError?: (error: Error) => void;
27
+ /** Called with internal debug messages. Only use for development. */
28
+ onDebug?: (msg: string) => void;
29
+ /** Called when autoplay is blocked by the browser. */
30
+ onPlayBlocked?: () => void;
31
+ /**
32
+ * Set true to disable Web Audio API entirely and use HTML5 audio only.
33
+ * Gapless playback will not be available in this mode.
34
+ */
35
+ webAudioIsDisabled?: boolean;
36
+ /** Per-track metadata (aligned to the tracks array by index). */
37
+ trackMetadata?: TrackMetadata[];
38
+ /** Initial volume, 0.0–1.0. Defaults to 1. */
39
+ volume?: number;
40
+ }
41
+ /** Options for dynamically adding a track. */
42
+ interface AddTrackOptions {
43
+ /**
44
+ * Skip the HEAD request used to resolve redirects.
45
+ * Set true when the URL is already a direct, final URL.
46
+ */
47
+ skipHEAD?: boolean;
48
+ metadata?: TrackMetadata;
49
+ }
50
+ /**
51
+ * A plain-data snapshot of a track's current state.
52
+ * Returned by Queue getters and passed to callbacks.
53
+ * No methods — pure data.
54
+ */
55
+ interface TrackInfo {
56
+ /** Zero-based position of this track in the queue. */
57
+ index: number;
58
+ /** Current playback position in seconds. */
59
+ currentTime: number;
60
+ /** Total duration in seconds (NaN until loaded). */
61
+ duration: number;
62
+ /** True if currently playing. */
63
+ isPlaying: boolean;
64
+ /** True if explicitly paused. */
65
+ isPaused: boolean;
66
+ /** Current volume, 0.0–1.0. */
67
+ volume: number;
68
+ /** The resolved URL of the audio file. */
69
+ trackUrl: string;
70
+ /** Which backend is currently producing sound. */
71
+ playbackType: PlaybackType;
72
+ /** Whether the Web Audio buffer has been decoded. */
73
+ webAudioLoadingState: WebAudioLoadingState;
74
+ /** Arbitrary metadata supplied when the track was added. */
75
+ metadata?: TrackMetadata;
76
+ /** Current xstate machine state for this track (e.g. 'idle', 'html5', 'webaudio'). */
77
+ machineState: string;
78
+ }
79
+
80
+ interface TrackQueueRef {
81
+ onTrackEnded(track: Track): void;
82
+ onTrackBufferReady(track: Track): void;
83
+ onProgress(info: TrackInfo): void;
84
+ onError(error: Error): void;
85
+ onPlayBlocked(): void;
86
+ onDebug(msg: string): void;
87
+ readonly volume: number;
88
+ readonly webAudioIsDisabled: boolean;
89
+ readonly currentTrackIndex: number;
90
+ }
91
+ declare class Track {
92
+ readonly index: number;
93
+ readonly metadata: TrackMetadata;
94
+ private _trackUrl;
95
+ private _resolvedUrl;
96
+ private readonly skipHEAD;
97
+ private loadedHEAD;
98
+ private abortController;
99
+ readonly audio: HTMLAudioElement;
100
+ private readonly _webAudioDisabled;
101
+ private get ctx();
102
+ private gainNode;
103
+ private sourceNode;
104
+ audioBuffer: AudioBuffer | null;
105
+ /** AudioContext.currentTime when the current source node was started. */
106
+ private webAudioStartedAt;
107
+ /** Track-time (seconds) frozen at the moment of the most recent pause. */
108
+ private pausedAtTrackTime;
109
+ scheduledStartContextTime: number | null;
110
+ private readonly _actor;
111
+ private readonly queueRef;
112
+ private rafId;
113
+ private _notifiedLookahead;
114
+ constructor(opts: {
115
+ trackUrl: string;
116
+ index: number;
117
+ queue: TrackQueueRef;
118
+ skipHEAD?: boolean;
119
+ metadata?: TrackMetadata;
120
+ });
121
+ play(): void;
122
+ pause(): void;
123
+ seek(time: number): void;
124
+ setVolume(v: number): void;
125
+ preload(): void;
126
+ seekToEnd(secondsFromEnd?: number): void;
127
+ activate(): void;
128
+ deactivate(): void;
129
+ destroy(): void;
130
+ cancelGaplessStart(): void;
131
+ scheduleGaplessStart(when: number): void;
132
+ get currentTime(): number;
133
+ get duration(): number;
134
+ get isPaused(): boolean;
135
+ get isPlaying(): boolean;
136
+ get trackUrl(): string;
137
+ get playbackType(): PlaybackType;
138
+ get webAudioLoadingState(): WebAudioLoadingState;
139
+ get hasSourceNode(): boolean;
140
+ get machineState(): string;
141
+ get isBufferLoaded(): boolean;
142
+ toInfo(): TrackInfo;
143
+ private _playHtml5;
144
+ private get _isUsingWebAudio();
145
+ private _playWebAudio;
146
+ private _startSourceNode;
147
+ private _stopSourceNode;
148
+ private _disconnectGain;
149
+ private _handleWebAudioEnded;
150
+ private _startLoad;
151
+ startProgressLoop(): void;
152
+ private _stopProgressLoop;
153
+ }
154
+
155
+ declare class Queue implements TrackQueueRef {
156
+ private _tracks;
157
+ private readonly _actor;
158
+ private readonly _onProgress?;
159
+ private readonly _onEnded?;
160
+ private readonly _onPlayNextTrack?;
161
+ private readonly _onPlayPreviousTrack?;
162
+ private readonly _onStartNewTrack?;
163
+ private readonly _onError?;
164
+ private readonly _onPlayBlocked?;
165
+ private readonly _onDebug?;
166
+ readonly webAudioIsDisabled: boolean;
167
+ private _volume;
168
+ /** Track indices for which a gapless start has been pre-scheduled. */
169
+ private _scheduledIndices;
170
+ constructor(options?: GaplessOptions);
171
+ play(): void;
172
+ pause(): void;
173
+ togglePlayPause(): void;
174
+ next(): void;
175
+ previous(): void;
176
+ gotoTrack(index: number, playImmediately?: boolean): void;
177
+ seek(time: number): void;
178
+ setVolume(volume: number): void;
179
+ addTrack(url: string, options?: AddTrackOptions): void;
180
+ removeTrack(index: number): void;
181
+ resumeAudioContext(): Promise<void>;
182
+ destroy(): void;
183
+ get currentTrack(): TrackInfo | undefined;
184
+ get currentTrackIndex(): number;
185
+ get tracks(): readonly TrackInfo[];
186
+ get isPlaying(): boolean;
187
+ get isPaused(): boolean;
188
+ get volume(): number;
189
+ /** Snapshot of the queue state machine (state name + context). For debugging. */
190
+ get queueSnapshot(): {
191
+ state: string;
192
+ context: {
193
+ currentTrackIndex: number;
194
+ trackCount: number;
195
+ };
196
+ };
197
+ onTrackEnded(track: Track): void;
198
+ onTrackBufferReady(track: Track): void;
199
+ onProgress(info: TrackInfo): void;
200
+ onError(error: Error): void;
201
+ onPlayBlocked(): void;
202
+ onDebug(msg: string): void;
203
+ private get _currentTrack();
204
+ private _deactivateCurrent;
205
+ private _activateCurrent;
206
+ private _preloadAhead;
207
+ private _cancelScheduledGapless;
208
+ private _cancelAllScheduledGapless;
209
+ private _cancelAndRescheduleGapless;
210
+ private _tryScheduleGapless;
211
+ private _computeTrackEndTime;
212
+ }
213
+
214
+ export { type AddTrackOptions, type GaplessOptions, type PlaybackType, Queue, type TrackInfo, type TrackMetadata, type WebAudioLoadingState, Queue as default };
package/dist/index.mjs ADDED
@@ -0,0 +1,4 @@
1
+ function me(){if(typeof globalThis<"u")return globalThis;if(typeof self<"u")return self;if(typeof window<"u")return window;if(typeof global<"u")return global}function ve(){let n=me();if(n.__xstate__)return n.__xstate__}var Pt=n=>{if(typeof window>"u")return;let t=ve();t&&t.register(n)};var Z=class{constructor(t){this._process=t,this._active=!1,this._current=null,this._last=null}start(){this._active=!0,this.flush()}clear(){this._current&&(this._current.next=null,this._last=this._current)}enqueue(t){let e={value:t,next:null};if(this._current){this._last.next=e,this._last=e;return}this._current=e,this._last=e,this._active&&this.flush()}flush(){for(;this._current;){let t=this._current;this._process(t.value),this._current=t.next}this._last=null}},vt=".",Te="",Tt="",Se="#",xe="*",Mt="xstate.init",Nt="xstate.error",pt="xstate.stop";function ke(n,t){return{type:`xstate.after.${n}.${t}`}}function gt(n,t){return{type:`xstate.done.state.${n}`,output:t}}function be(n,t){return{type:`xstate.done.actor.${n}`,output:t,actorId:n}}function St(n,t){return{type:`xstate.error.actor.${n}`,error:t,actorId:n}}function nt(n){return{type:Mt,input:n}}function T(n){setTimeout(()=>{throw n})}var Ae=typeof Symbol=="function"&&Symbol.observable||"@@observable";function xt(n,t){let e=Ot(n),s=Ot(t);return typeof s=="string"?typeof e=="string"?s===e:!1:typeof e=="string"?e in s:Object.keys(e).every(i=>i in s?xt(e[i],s[i]):!1)}function st(n){if(Gt(n))return n;let t=[],e="";for(let s=0;s<n.length;s++){switch(n.charCodeAt(s)){case 92:e+=n[s+1],s++;continue;case 46:t.push(e),e="";continue}e+=n[s]}return t.push(e),t}function Ot(n){if(re(n))return n.value;if(typeof n!="string")return n;let t=st(n);return Ut(t)}function Ut(n){if(n.length===1)return n[0];let t={},e=t;for(let s=0;s<n.length-1;s++)if(s===n.length-2)e[n[s]]=n[s+1];else{let i=e;e={},i[n[s]]=e}return t}function kt(n,t){let e={},s=Object.keys(n);for(let i=0;i<s.length;i++){let r=s[i];e[r]=t(n[r],r,n,i)}return e}function Bt(n){return Gt(n)?n:[n]}function S(n){return n===void 0?[]:Bt(n)}function yt(n,t,e,s){return typeof n=="function"?n({context:t,event:e,self:s}):n}function Gt(n){return Array.isArray(n)}function Ee(n){return n.type.startsWith("xstate.error.actor")}function A(n){return Bt(n).map(t=>typeof t>"u"||typeof t=="string"?{target:t}:t)}function qt(n){if(!(n===void 0||n===Te))return S(n)}function tt(n,t,e){var r,o,a;let s=typeof n=="object",i=s?n:void 0;return{next:(r=s?n.next:n)==null?void 0:r.bind(i),error:(o=s?n.error:t)==null?void 0:o.bind(i),complete:(a=s?n.complete:e)==null?void 0:a.bind(i)}}function bt(n,t){return`${t}.${n}`}function H(n,t){let e=t.match(/^xstate\.invoke\.(\d+)\.(.*)/);if(!e)return n.implementations.actors[t];let[,s,i]=e,o=n.getStateNodeById(i).config.invoke;return(Array.isArray(o)?o[s]:o).src}function Wt(n,t){if(t===n||t===xe)return!0;if(!t.endsWith(".*"))return!1;let e=t.split("."),s=n.split(".");for(let i=0;i<e.length;i++){let r=e[i],o=s[i];if(r==="*")return i===e.length-1;if(r!==o)return!1}return!0}function Rt(n,t){return`${n.sessionId}.${t}`}var Ie=0;function we(n,t){let e=new Map,s=new Map,i=new WeakMap,r=new Set,o={},{clock:a,logger:c}=t,f={schedule:(u,l,h,y,_=Math.random().toString(36).slice(2))=>{let P={source:u,target:l,event:h,delay:y,id:_,startedAt:Date.now()},O=Rt(u,_);d._snapshot._scheduledEvents[O]=P;let _e=a.setTimeout(()=>{delete o[O],delete d._snapshot._scheduledEvents[O],d._relay(u,l,h)},y);o[O]=_e},cancel:(u,l)=>{let h=Rt(u,l),y=o[h];delete o[h],delete d._snapshot._scheduledEvents[h],y!==void 0&&a.clearTimeout(y)},cancelAll:u=>{for(let l in d._snapshot._scheduledEvents){let h=d._snapshot._scheduledEvents[l];h.source===u&&f.cancel(u,h.id)}}},p=u=>{if(!r.size)return;let l={...u,rootId:n.sessionId};r.forEach(h=>{var y;return(y=h.next)==null?void 0:y.call(h,l)})},d={_snapshot:{_scheduledEvents:((t==null?void 0:t.snapshot)&&t.snapshot.scheduler)??{}},_bookId:()=>`x:${Ie++}`,_register:(u,l)=>(e.set(u,l),u),_unregister:u=>{e.delete(u.sessionId);let l=i.get(u);l!==void 0&&(s.delete(l),i.delete(u))},get:u=>s.get(u),getAll:()=>Object.fromEntries(s.entries()),_set:(u,l)=>{let h=s.get(u);if(h&&h!==l)throw new Error(`Actor with system ID '${u}' already exists.`);s.set(u,l),i.set(l,u)},inspect:u=>{let l=tt(u);return r.add(l),{unsubscribe(){r.delete(l)}}},_sendInspectionEvent:p,_relay:(u,l,h)=>{d._sendInspectionEvent({type:"@xstate.event",sourceRef:u,actorRef:l,event:h}),l._send(h)},scheduler:f,getSnapshot:()=>({_scheduledEvents:{...d._snapshot._scheduledEvents}}),start:()=>{let u=d._snapshot._scheduledEvents;d._snapshot._scheduledEvents={};for(let l in u){let{source:h,target:y,event:_,delay:P,id:O}=u[l];f.schedule(h,y,_,P,O)}},_clock:a,_logger:c};return d}var lt=!1,it=1,m=(function(n){return n[n.NotStarted=0]="NotStarted",n[n.Running=1]="Running",n[n.Stopped=2]="Stopped",n})({}),De={clock:{setTimeout:(n,t)=>setTimeout(n,t),clearTimeout:n=>clearTimeout(n)},logger:console.log.bind(console),devTools:!1},et=class{constructor(t,e){this.logic=t,this._snapshot=void 0,this.clock=void 0,this.options=void 0,this.id=void 0,this.mailbox=new Z(this._process.bind(this)),this.observers=new Set,this.eventListeners=new Map,this.logger=void 0,this._processingStatus=m.NotStarted,this._parent=void 0,this._syncSnapshot=void 0,this.ref=void 0,this._actorScope=void 0,this.systemId=void 0,this.sessionId=void 0,this.system=void 0,this._doneEvent=void 0,this.src=void 0,this._deferred=[];let s={...De,...e},{clock:i,logger:r,parent:o,syncSnapshot:a,id:c,systemId:f,inspect:p}=s;this.system=o?o.system:we(this,{clock:i,logger:r}),p&&!o&&this.system.inspect(tt(p)),this.sessionId=this.system._bookId(),this.id=c??this.sessionId,this.logger=(e==null?void 0:e.logger)??this.system._logger,this.clock=(e==null?void 0:e.clock)??this.system._clock,this._parent=o,this._syncSnapshot=a,this.options=s,this.src=s.src??t,this.ref=this,this._actorScope={self:this,id:this.id,sessionId:this.sessionId,logger:this.logger,defer:d=>{this._deferred.push(d)},system:this.system,stopChild:d=>{if(d._parent!==this)throw new Error(`Cannot stop child actor ${d.id} of ${this.id} because it is not a child`);d._stop()},emit:d=>{let u=this.eventListeners.get(d.type),l=this.eventListeners.get("*");if(!u&&!l)return;let h=[...u?u.values():[],...l?l.values():[]];for(let y of h)try{y(d)}catch(_){T(_)}},actionExecutor:d=>{let u=()=>{if(this._actorScope.system._sendInspectionEvent({type:"@xstate.action",actorRef:this,action:{type:d.type,params:d.params}}),!d.exec)return;let l=lt;try{lt=!0,d.exec(d.info,d.params)}finally{lt=l}};this._processingStatus===m.Running?u():this._deferred.push(u)}},this.send=this.send.bind(this),this.system._sendInspectionEvent({type:"@xstate.actor",actorRef:this}),f&&(this.systemId=f,this.system._set(f,this)),this._initState((e==null?void 0:e.snapshot)??(e==null?void 0:e.state)),f&&this._snapshot.status!=="active"&&this.system._unregister(this)}_initState(t){var e;try{this._snapshot=t?this.logic.restoreSnapshot?this.logic.restoreSnapshot(t,this._actorScope):t:this.logic.getInitialSnapshot(this._actorScope,(e=this.options)==null?void 0:e.input)}catch(s){this._snapshot={status:"error",output:void 0,error:s}}}update(t,e){var i,r;this._snapshot=t;let s;for(;s=this._deferred.shift();)try{s()}catch(o){this._deferred.length=0,this._snapshot={...t,status:"error",error:o}}switch(this._snapshot.status){case"active":for(let o of this.observers)try{(i=o.next)==null||i.call(o,t)}catch(a){T(a)}break;case"done":for(let o of this.observers)try{(r=o.next)==null||r.call(o,t)}catch(a){T(a)}this._stopProcedure(),this._complete(),this._doneEvent=be(this.id,this._snapshot.output),this._parent&&this.system._relay(this,this._parent,this._doneEvent);break;case"error":this._error(this._snapshot.error);break}this.system._sendInspectionEvent({type:"@xstate.snapshot",actorRef:this,event:e,snapshot:t})}subscribe(t,e,s){var r;let i=tt(t,e,s);if(this._processingStatus!==m.Stopped)this.observers.add(i);else switch(this._snapshot.status){case"done":try{(r=i.complete)==null||r.call(i)}catch(o){T(o)}break;case"error":{let o=this._snapshot.error;if(!i.error)T(o);else try{i.error(o)}catch(a){T(a)}break}}return{unsubscribe:()=>{this.observers.delete(i)}}}on(t,e){let s=this.eventListeners.get(t);s||(s=new Set,this.eventListeners.set(t,s));let i=e.bind(void 0);return s.add(i),{unsubscribe:()=>{s.delete(i)}}}start(){if(this._processingStatus===m.Running)return this;this._syncSnapshot&&this.subscribe({next:s=>{s.status==="active"&&this.system._relay(this,this._parent,{type:`xstate.snapshot.${this.id}`,snapshot:s})},error:()=>{}}),this.system._register(this.sessionId,this),this.systemId&&this.system._set(this.systemId,this),this._processingStatus=m.Running;let t=nt(this.options.input);switch(this.system._sendInspectionEvent({type:"@xstate.event",sourceRef:this._parent,actorRef:this,event:t}),this._snapshot.status){case"done":return this.update(this._snapshot,t),this;case"error":return this._error(this._snapshot.error),this}if(this._parent||this.system.start(),this.logic.start)try{this.logic.start(this._snapshot,this._actorScope)}catch(s){return this._snapshot={...this._snapshot,status:"error",error:s},this._error(s),this}return this.update(this._snapshot,t),this.options.devTools&&this.attachDevTools(),this.mailbox.start(),this}_process(t){let e,s;try{e=this.logic.transition(this._snapshot,t,this._actorScope)}catch(i){s={err:i}}if(s){let{err:i}=s;this._snapshot={...this._snapshot,status:"error",error:i},this._error(i);return}this.update(e,t),t.type===pt&&(this._stopProcedure(),this._complete())}_stop(){return this._processingStatus===m.Stopped?this:(this.mailbox.clear(),this._processingStatus===m.NotStarted?(this._processingStatus=m.Stopped,this):(this.mailbox.enqueue({type:pt}),this))}stop(){if(this._parent)throw new Error("A non-root actor cannot be stopped directly.");return this._stop()}_complete(){var t;for(let e of this.observers)try{(t=e.complete)==null||t.call(e)}catch(s){T(s)}this.observers.clear(),this.eventListeners.clear()}_reportError(t){if(!this.observers.size){this._parent||T(t),this.eventListeners.clear();return}let e=!1;for(let s of this.observers){let i=s.error;e||=!i;try{i==null||i(t)}catch(r){T(r)}}this.observers.clear(),this.eventListeners.clear(),e&&T(t)}_error(t){this._stopProcedure(),this._reportError(t),this._parent&&this.system._relay(this,this._parent,St(this.id,t))}_stopProcedure(){return this._processingStatus!==m.Running?this:(this.system.scheduler.cancelAll(this),this.mailbox.clear(),this.mailbox=new Z(this._process.bind(this)),this._processingStatus=m.Stopped,this.system._unregister(this),this)}_send(t){this._processingStatus!==m.Stopped&&this.mailbox.enqueue(t)}send(t){this.system._relay(void 0,this,t)}attachDevTools(){let{devTools:t}=this.options;t&&(typeof t=="function"?t:Pt)(this)}toJSON(){return{xstate$$type:it,id:this.id}}getPersistedSnapshot(t){return this.logic.getPersistedSnapshot(this._snapshot,t)}[Ae](){return this}getSnapshot(){return this._snapshot}};function v(n,...[t]){return new et(n,t)}function Pe(n,t,e,s,{sendId:i}){let r=typeof i=="function"?i(e,s):i;return[t,{sendId:r},void 0]}function Oe(n,t){n.defer(()=>{n.system.scheduler.cancel(n.self,t.sendId)})}function $(n){function t(e,s){}return t.type="xstate.cancel",t.sendId=n,t.resolve=Pe,t.execute=Oe,t}function Re(n,t,e,s,{id:i,systemId:r,src:o,input:a,syncSnapshot:c}){let f=typeof o=="string"?H(t.machine,o):o,p=typeof i=="function"?i(e):i,d,u;return f&&(u=typeof a=="function"?a({context:t.context,event:e.event,self:n.self}):a,d=v(f,{id:p,src:o,parent:n.self,syncSnapshot:c,systemId:r,input:u})),[b(t,{children:{...t.children,[p]:d}}),{id:i,systemId:r,actorRef:d,src:o,input:u},void 0]}function Le(n,{actorRef:t}){t&&n.defer(()=>{t._processingStatus!==m.Stopped&&t.start()})}function M(...[n,{id:t,systemId:e,input:s,syncSnapshot:i=!1}={}]){function r(o,a){}return r.type="xstate.spawnChild",r.id=t,r.systemId=e,r.src=n,r.input=s,r.syncSnapshot=i,r.resolve=Re,r.execute=Le,r}function Ce(n,t,e,s,{actorRef:i}){let r=typeof i=="function"?i(e,s):i,o=typeof r=="string"?t.children[r]:r,a=t.children;return o&&(a={...a},delete a[o.id]),[b(t,{children:a}),o,void 0]}function Ht(n,t){let e=t.getSnapshot();if(e&&"children"in e)for(let s of Object.values(e.children))Ht(n,s);n.system._unregister(t)}function $e(n,t){if(t){if(Ht(n,t),t._processingStatus!==m.Running){n.stopChild(t);return}n.defer(()=>{n.stopChild(t)})}}function w(n){function t(e,s){}return t.type="xstate.stopChild",t.actorRef=n,t.resolve=Ce,t.execute=$e,t}function N(n,t,e,s){let{machine:i}=s,r=typeof n=="function",o=r?n:i.implementations.guards[typeof n=="string"?n:n.type];if(!r&&!o)throw new Error(`Guard '${typeof n=="string"?n:n.type}' is not implemented.'.`);if(typeof o!="function")return N(o,t,e,s);let a={context:t,event:e},c=r||typeof n=="string"?void 0:"params"in n?typeof n.params=="function"?n.params({context:t,event:e}):n.params:void 0;return"check"in o?o.check(s,a,o):o(a,c)}function rt(n){return n.type==="atomic"||n.type==="final"}function L(n){return Object.values(n.states).filter(t=>t.type!=="history")}function U(n,t){let e=[];if(t===n)return e;let s=n.parent;for(;s&&s!==t;)e.push(s),s=s.parent;return e}function j(n){let t=new Set(n),e=Vt(t);for(let s of t)if(s.type==="compound"&&(!e.get(s)||!e.get(s).length))Lt(s).forEach(i=>t.add(i));else if(s.type==="parallel"){for(let i of L(s))if(i.type!=="history"&&!t.has(i)){let r=Lt(i);for(let o of r)t.add(o)}}for(let s of t){let i=s.parent;for(;i;)t.add(i),i=i.parent}return t}function jt(n,t){let e=t.get(n);if(!e)return{};if(n.type==="compound"){let i=e[0];if(i){if(rt(i))return i.key}else return{}}let s={};for(let i of e)s[i.key]=jt(i,t);return s}function Vt(n){let t=new Map;for(let e of n)t.has(e)||t.set(e,[]),e.parent&&(t.has(e.parent)||t.set(e.parent,[]),t.get(e.parent).push(e));return t}function Ft(n,t){let e=j(t);return jt(n,Vt(e))}function ot(n,t){return t.type==="compound"?L(t).some(e=>e.type==="final"&&n.has(e)):t.type==="parallel"?L(t).every(e=>ot(n,e)):t.type==="final"}var V=n=>n[0]===Se;function Kt(n,t){return n.transitions.get(t)||[...n.transitions.keys()].filter(s=>Wt(t,s)).sort((s,i)=>i.length-s.length).flatMap(s=>n.transitions.get(s))}function Yt(n){let t=n.config.after;if(!t)return[];let e=i=>{let r=ke(i,n.id),o=r.type;return n.entry.push(G(r,{id:o,delay:i})),n.exit.push($(o)),o};return Object.keys(t).flatMap(i=>{let r=t[i],o=typeof r=="string"?{target:r}:r,a=Number.isNaN(+i)?i:+i,c=e(a);return S(o).map(f=>({...f,event:c,delay:a}))}).map(i=>{let{delay:r}=i;return{...x(n,i.event,i),delay:r}})}function x(n,t,e){let s=qt(e.target),i=e.reenter??!1,r=Me(n,s),o={...e,actions:S(e.actions),guard:e.guard,target:r,source:n,reenter:i,eventType:t,toJSON:()=>({...o,source:`#${n.id}`,target:r?r.map(a=>`#${a.id}`):void 0})};return o}function Jt(n){let t=new Map;if(n.config.on)for(let e of Object.keys(n.config.on)){if(e===Tt)throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');let s=n.config.on[e];t.set(e,A(s).map(i=>x(n,e,i)))}if(n.config.onDone){let e=`xstate.done.state.${n.id}`;t.set(e,A(n.config.onDone).map(s=>x(n,e,s)))}for(let e of n.invoke){if(e.onDone){let s=`xstate.done.actor.${e.id}`;t.set(s,A(e.onDone).map(i=>x(n,s,i)))}if(e.onError){let s=`xstate.error.actor.${e.id}`;t.set(s,A(e.onError).map(i=>x(n,s,i)))}if(e.onSnapshot){let s=`xstate.snapshot.${e.id}`;t.set(s,A(e.onSnapshot).map(i=>x(n,s,i)))}}for(let e of n.after){let s=t.get(e.eventType);s||(s=[],t.set(e.eventType,s)),s.push(e)}return t}function Xt(n){let t=[],e=s=>{Object.values(s).forEach(i=>{if(i.config.route&&i.config.id){let r=i.config.id,o=i.config.route.guard,a=(f,p)=>f.event.to!==`#${r}`?!1:o&&typeof o=="function"?o(f,p):!0,c={...i.config.route,guard:a,target:`#${r}`};t.push(x(n,"xstate.route",c))}i.states&&e(i.states)})};e(n.states),t.length>0&&n.transitions.set("xstate.route",t)}function zt(n,t){let e=typeof t=="string"?n.states[t]:t?n.states[t.target]:void 0;if(!e&&t)throw new Error(`Initial state node "${t}" not found on parent state node #${n.id}`);let s={source:n,actions:!t||typeof t=="string"?[]:S(t.actions),eventType:null,reenter:!1,target:e?[e]:[],toJSON:()=>({...s,source:`#${n.id}`,target:e?[`#${e.id}`]:[]})};return s}function Me(n,t){if(t!==void 0)return t.map(e=>{if(typeof e!="string")return e;if(V(e))return n.machine.getStateNodeById(e);let s=e[0]===vt;if(s&&!n.parent)return W(n,e.slice(1));let i=s?n.key+e:e;if(n.parent)try{return W(n.parent,i)}catch(r){throw new Error(`Invalid transition definition for state node '${n.id}':
2
+ ${r.message}`)}else throw new Error(`Invalid target: "${e}" is not a valid target from the root node. Did you mean ".${e}"?`)})}function Qt(n){let t=qt(n.config.target);return t?{target:t.map(e=>typeof e=="string"?W(n.parent,e):e)}:n.parent.initial}function E(n){return n.type==="history"}function Lt(n){let t=Zt(n);for(let e of t)for(let s of U(e,n))t.add(s);return t}function Zt(n){let t=new Set;function e(s){if(!t.has(s)){if(t.add(s),s.type==="compound")e(s.initial.target[0]);else if(s.type==="parallel")for(let i of L(s))e(i)}}return e(n),t}function C(n,t){if(V(t))return n.machine.getStateNodeById(t);if(!n.states)throw new Error(`Unable to retrieve child state '${t}' from '${n.id}'; no child states exist.`);let e=n.states[t];if(!e)throw new Error(`Child state '${t}' does not exist on '${n.id}'`);return e}function W(n,t){if(typeof t=="string"&&V(t))try{return n.machine.getStateNodeById(t)}catch{}let e=st(t).slice(),s=n;for(;e.length;){let i=e.shift();if(!i.length)break;s=C(s,i)}return s}function B(n,t){if(typeof t=="string"){let i=n.states[t];if(!i)throw new Error(`State '${t}' does not exist on '${n.id}'`);return[n,i]}let e=Object.keys(t),s=e.map(i=>C(n,i)).filter(Boolean);return[n.machine.root,n].concat(s,e.reduce((i,r)=>{let o=C(n,r);if(!o)return i;let a=B(o,t[r]);return i.concat(a)},[]))}function Ne(n,t,e,s){let r=C(n,t).next(e,s);return!r||!r.length?n.next(e,s):r}function Ue(n,t,e,s){let i=Object.keys(t),r=C(n,i[0]),o=at(r,t[i[0]],e,s);return!o||!o.length?n.next(e,s):o}function Be(n,t,e,s){let i=[];for(let r of Object.keys(t)){let o=t[r];if(!o)continue;let a=C(n,r),c=at(a,o,e,s);c&&i.push(...c)}return i.length?i:n.next(e,s)}function at(n,t,e,s){return typeof t=="string"?Ne(n,t,e,s):Object.keys(t).length===1?Ue(n,t,e,s):Be(n,t,e,s)}function Ge(n){return Object.keys(n.states).map(t=>n.states[t]).filter(t=>t.type==="history")}function k(n,t){let e=n;for(;e.parent&&e.parent!==t;)e=e.parent;return e.parent===t}function qe(n,t){let e=new Set(n),s=new Set(t);for(let i of e)if(s.has(i))return!0;for(let i of s)if(e.has(i))return!0;return!1}function te(n,t,e){let s=new Set;for(let i of n){let r=!1,o=new Set;for(let a of s)if(qe(_t([i],t,e),_t([a],t,e)))if(k(i.source,a.source))o.add(a);else{r=!0;break}if(!r){for(let a of o)s.delete(a);s.add(i)}}return Array.from(s)}function We(n){let[t,...e]=n;for(let s of U(t,void 0))if(e.every(i=>k(i,s)))return s}function At(n,t){if(!n.target)return[];let e=new Set;for(let s of n.target)if(E(s))if(t[s.id])for(let i of t[s.id])e.add(i);else for(let i of At(Qt(s),t))e.add(i);else e.add(s);return[...e]}function ee(n,t){let e=At(n,t);if(!e)return;if(!n.reenter&&e.every(i=>i===n.source||k(i,n.source)))return n.source;let s=We(e.concat(n.source));if(s)return s;if(!n.reenter)return n.source.machine.root}function _t(n,t,e){var i;let s=new Set;for(let r of n)if((i=r.target)!=null&&i.length){let o=ee(r,e);r.reenter&&r.source===o&&s.add(o);for(let a of t)k(a,o)&&s.add(a)}return[...s]}function He(n,t){if(n.length!==t.size)return!1;for(let e of n)if(!t.has(e))return!1;return!0}function Et(n,t,e,s,i){return mt([{target:[...Zt(n)],source:n,reenter:!0,actions:[],eventType:null,toJSON:null}],t,e,s,!0,i)}function mt(n,t,e,s,i,r){let o=[];if(!n.length)return[t,o];let a=e.actionExecutor;e.actionExecutor=c=>{o.push(c),a(c)};try{let c=new Set(t._nodes),f=t.historyValue,p=te(n,c,f),d=t;i||([d,f]=Ke(d,s,e,p,c,f,r,e.actionExecutor)),d=I(d,s,e,p.flatMap(l=>l.actions),r,void 0),d=Ve(d,s,e,p,c,r,f,i);let u=[...c];d.status==="done"&&(d=I(d,s,e,u.sort((l,h)=>h.order-l.order).flatMap(l=>l.exit),r,void 0));try{return f===t.historyValue&&He(t._nodes,c)?[d,o]:[b(d,{_nodes:u,historyValue:f}),o]}catch(l){throw l}}finally{e.actionExecutor=a}}function je(n,t,e,s,i){if(s.output===void 0)return;let r=gt(i.id,i.output!==void 0&&i.parent?yt(i.output,n.context,t,e.self):void 0);return yt(s.output,n.context,r,e.self)}function Ve(n,t,e,s,i,r,o,a){let c=n,f=new Set,p=new Set;Fe(s,o,p,f),a&&p.add(n.machine.root);let d=new Set;for(let u of[...f].sort((l,h)=>l.order-h.order)){i.add(u);let l=[];l.push(...u.entry);for(let h of u.invoke)l.push(M(h.src,{...h,syncSnapshot:!!h.onSnapshot}));if(p.has(u)){let h=u.initial.actions;l.push(...h)}if(c=I(c,t,e,l,r,u.invoke.map(h=>h.id)),u.type==="final"){let h=u.parent,y=(h==null?void 0:h.type)==="parallel"?h:h==null?void 0:h.parent,_=y||u;for((h==null?void 0:h.type)==="compound"&&r.push(gt(h.id,u.output!==void 0?yt(u.output,c.context,t,e.self):void 0));(y==null?void 0:y.type)==="parallel"&&!d.has(y)&&ot(i,y);)d.add(y),r.push(gt(y.id)),_=y,y=y.parent;if(y)continue;c=b(c,{status:"done",output:je(c,t,e,c.machine.root,_)})}}return c}function Fe(n,t,e,s){for(let i of n){let r=ee(i,t);for(let a of i.target||[])!E(a)&&(i.source!==a||i.source!==r||i.reenter)&&(s.add(a),e.add(a)),R(a,t,e,s);let o=At(i,t);for(let a of o){let c=U(a,r);(r==null?void 0:r.type)==="parallel"&&c.push(r),ne(s,t,e,c,!i.source.parent&&i.reenter?void 0:r)}}}function R(n,t,e,s){var i;if(E(n))if(t[n.id]){let r=t[n.id];for(let o of r)s.add(o),R(o,t,e,s);for(let o of r)ft(o,n.parent,s,t,e)}else{let r=Qt(n);for(let o of r.target)s.add(o),r===((i=n.parent)==null?void 0:i.initial)&&e.add(n.parent),R(o,t,e,s);for(let o of r.target)ft(o,n.parent,s,t,e)}else if(n.type==="compound"){let[r]=n.initial.target;E(r)||(s.add(r),e.add(r)),R(r,t,e,s),ft(r,n,s,t,e)}else if(n.type==="parallel")for(let r of L(n).filter(o=>!E(o)))[...s].some(o=>k(o,r))||(E(r)||(s.add(r),e.add(r)),R(r,t,e,s))}function ne(n,t,e,s,i){for(let r of s)if((!i||k(r,i))&&n.add(r),r.type==="parallel")for(let o of L(r).filter(a=>!E(a)))[...n].some(a=>k(a,o))||(n.add(o),R(o,t,e,n))}function ft(n,t,e,s,i){ne(e,s,i,U(n,t))}function Ke(n,t,e,s,i,r,o,a){let c=n,f=_t(s,i,r);f.sort((d,u)=>u.order-d.order);let p;for(let d of f)for(let u of Ge(d)){let l;u.history==="deep"?l=h=>rt(h)&&k(h,d):l=h=>h.parent===d,p??={...r},p[u.id]=Array.from(i).filter(l)}for(let d of f)c=I(c,t,e,[...d.exit,...d.invoke.map(u=>w(u.id))],o,void 0),i.delete(d);return[c,p||r]}function Ye(n,t){return n.implementations.actions[t]}function se(n,t,e,s,i,r){let{machine:o}=n,a=n;for(let c of s){let f=typeof c=="function",p=f?c:Ye(o,typeof c=="string"?c:c.type),d={context:a.context,event:t,self:e.self,system:e.system},u=f||typeof c=="string"?void 0:"params"in c?typeof c.params=="function"?c.params({context:a.context,event:t}):c.params:void 0;if(!p||!("resolve"in p)){e.actionExecutor({type:typeof c=="string"?c:typeof c=="object"?c.type:c.name||"(anonymous)",info:d,params:u,exec:p});continue}let l=p,[h,y,_]=l.resolve(e,a,d,u,p,i);a=h,"retryResolve"in l&&(r==null||r.push([l,y])),"execute"in l&&e.actionExecutor({type:l.type,info:d,params:y,exec:l.execute.bind(null,e,y)}),_&&(a=se(a,t,e,_,i,r))}return a}function I(n,t,e,s,i,r){let o=r?[]:void 0,a=se(n,t,e,s,{internalQueue:i,deferredActorIds:r},o);return o==null||o.forEach(([c,f])=>{c.retryResolve(e,a,f)}),a}function F(n,t,e,s){let i=n,r=[];function o(f,p,d){e.system._sendInspectionEvent({type:"@xstate.microstep",actorRef:e.self,event:p,snapshot:f[0],_transitions:d}),r.push(f)}if(t.type===pt)return i=b(Ct(i,t,e),{status:"stopped"}),o([i,[]],t,[]),{snapshot:i,microsteps:r};let a=t;if(a.type!==Mt){let f=a,p=Ee(f),d=$t(f,i);if(p&&!d.length)return i=b(n,{status:"error",error:f.error}),o([i,[]],f,[]),{snapshot:i,microsteps:r};let u=mt(d,n,e,a,!1,s);i=u[0],o(u,f,d)}let c=!0;for(;i.status==="active";){let f=c?Je(i,a):[],p=f.length?i:void 0;if(!f.length){if(!s.length)break;a=s.shift(),f=$t(a,i)}let d=mt(f,i,e,a,!1,s);i=d[0],c=i!==p,o(d,a,f)}return i.status!=="active"&&Ct(i,a,e),{snapshot:i,microsteps:r}}function Ct(n,t,e){return I(n,t,e,Object.values(n.children).map(s=>w(s)),[],void 0)}function $t(n,t){return t.machine.getTransitionData(t,n)}function Je(n,t){let e=new Set,s=n._nodes.filter(rt);for(let i of s)t:for(let r of[i].concat(U(i,void 0)))if(r.always){for(let o of r.always)if(o.guard===void 0||N(o.guard,n.context,t,n)){e.add(o);break t}}return te(Array.from(e),new Set(n._nodes),n.historyValue)}function ie(n,t){let e=j(B(n,t));return Ft(n,[...e])}function re(n){return!!n&&typeof n=="object"&&"machine"in n&&"value"in n}var Xe=function(t){return xt(t,this.value)},ze=function(t){return this.tags.has(t)},Qe=function(t){let e=this.machine.getTransitionData(this,t);return!!(e!=null&&e.length)&&e.some(s=>s.target!==void 0||s.actions.length)},Ze=function(){let{_nodes:t,tags:e,machine:s,getMeta:i,toJSON:r,can:o,hasTag:a,matches:c,...f}=this;return{...f,tags:Array.from(e)}},tn=function(){return this._nodes.reduce((t,e)=>(e.meta!==void 0&&(t[e.id]=e.meta),t),{})};function K(n,t){return{status:n.status,output:n.output,error:n.error,machine:t,context:n.context,_nodes:n._nodes,value:Ft(t.root,n._nodes),tags:new Set(n._nodes.flatMap(e=>e.tags)),children:n.children,historyValue:n.historyValue||{},matches:Xe,hasTag:ze,can:Qe,getMeta:tn,toJSON:Ze}}function b(n,t={}){return K({...n,...t},n.machine)}function en(n){if(typeof n!="object"||n===null)return{};let t={};for(let e in n){let s=n[e];Array.isArray(s)&&(t[e]=s.map(i=>({id:i.id})))}return t}function oe(n,t){let{_nodes:e,tags:s,machine:i,children:r,context:o,can:a,hasTag:c,matches:f,getMeta:p,toJSON:d,...u}=n,l={};for(let y in r){let _=r[y];l[y]={snapshot:_.getPersistedSnapshot(t),src:_.src,systemId:_.systemId,syncSnapshot:_._syncSnapshot}}return{...u,context:ae(o),children:l,historyValue:en(u.historyValue)}}function ae(n){let t;for(let e in n){let s=n[e];if(s&&typeof s=="object")if("sessionId"in s&&"send"in s&&"ref"in s)t??=Array.isArray(n)?n.slice():{...n},t[e]={xstate$$type:it,id:s.id};else{let i=ae(s);i!==s&&(t??=Array.isArray(n)?n.slice():{...n},t[e]=i)}}return t??n}function nn(n,t,e,s,{event:i,id:r,delay:o},{internalQueue:a}){let c=t.machine.implementations.delays;if(typeof i=="string")throw new Error(`Only event objects may be used with raise; use raise({ type: "${i}" }) instead`);let f=typeof i=="function"?i(e,s):i,p;if(typeof o=="string"){let d=c&&c[o];p=typeof d=="function"?d(e,s):d}else p=typeof o=="function"?o(e,s):o;return typeof p!="number"&&a.push(f),[t,{event:f,id:r,delay:p},void 0]}function sn(n,t){let{event:e,delay:s,id:i}=t;if(typeof s=="number"){n.defer(()=>{let r=n.self;n.system.scheduler.schedule(r,r,e,s,i)});return}}function G(n,t){function e(s,i){}return e.type="xstate.raise",e.event=n,e.id=t==null?void 0:t.id,e.delay=t==null?void 0:t.delay,e.resolve=nn,e.execute=sn,e}function ce(n,t){return{config:n,transition:(e,s,i)=>({...e,context:n(e.context,s,i)}),getInitialSnapshot:(e,s)=>({status:"active",output:void 0,error:void 0,context:typeof t=="function"?t({input:s}):t}),getPersistedSnapshot:e=>e,restoreSnapshot:e=>e}}var In=ce(n=>{},void 0);function rn(n,{machine:t,context:e},s,i){let r=(o,a)=>{if(typeof o=="string"){let c=H(t,o);if(!c)throw new Error(`Actor logic '${o}' not implemented in machine '${t.id}'`);let f=v(c,{id:a==null?void 0:a.id,parent:n.self,syncSnapshot:a==null?void 0:a.syncSnapshot,input:typeof(a==null?void 0:a.input)=="function"?a.input({context:e,event:s,self:n.self}):a==null?void 0:a.input,src:o,systemId:a==null?void 0:a.systemId});return i[f.id]=f,f}else return v(o,{id:a==null?void 0:a.id,parent:n.self,syncSnapshot:a==null?void 0:a.syncSnapshot,input:a==null?void 0:a.input,src:o,systemId:a==null?void 0:a.systemId})};return(o,a)=>{let c=r(o,a);return i[c.id]=c,n.defer(()=>{c._processingStatus!==m.Stopped&&c.start()}),c}}function on(n,t,e,s,{assignment:i}){if(!t.context)throw new Error("Cannot assign to undefined `context`. Ensure that `context` is defined in the machine config.");let r={},o={context:t.context,event:e.event,spawn:rn(n,t,e.event,r),self:n.self,system:n.system},a={};if(typeof i=="function")a=i(o,s);else for(let f of Object.keys(i)){let p=i[f];a[f]=typeof p=="function"?p(o,s):p}let c=Object.assign({},t.context,a);return[b(t,{context:c,children:Object.keys(r).length?{...t.children,...r}:t.children}),void 0,void 0]}function g(n){function t(e,s){}return t.type="xstate.assign",t.assignment=n,t.resolve=on,t}var ue=new WeakMap;function q(n,t,e){let s=ue.get(n);return s?t in s||(s[t]=e()):(s={[t]:e()},ue.set(n,s)),s[t]}var an={},Y=n=>typeof n=="string"?{type:n}:typeof n=="function"?"resolve"in n?{type:n.type}:{type:n.name}:n,ct=class n{constructor(t,e){if(this.config=t,this.key=void 0,this.id=void 0,this.type=void 0,this.path=void 0,this.states=void 0,this.history=void 0,this.entry=void 0,this.exit=void 0,this.parent=void 0,this.machine=void 0,this.meta=void 0,this.output=void 0,this.order=-1,this.description=void 0,this.tags=[],this.transitions=void 0,this.always=void 0,this.parent=e._parent,this.key=e._key,this.machine=e._machine,this.path=this.parent?this.parent.path.concat(this.key):[],this.id=this.config.id||[this.machine.id,...this.path].join(vt),this.type=this.config.type||(this.config.states&&Object.keys(this.config.states).length?"compound":this.config.history?"history":"atomic"),this.description=this.config.description,this.order=this.machine.idMap.size,this.machine.idMap.set(this.id,this),this.states=this.config.states?kt(this.config.states,(s,i)=>new n(s,{_parent:this,_key:i,_machine:this.machine})):an,this.type==="compound"&&!this.config.initial)throw new Error(`No initial state specified for compound state node "#${this.id}". Try adding { initial: "${Object.keys(this.states)[0]}" } to the state config.`);this.history=this.config.history===!0?"shallow":this.config.history||!1,this.entry=S(this.config.entry).slice(),this.exit=S(this.config.exit).slice(),this.meta=this.config.meta,this.output=this.type==="final"||!this.parent?this.config.output:void 0,this.tags=S(t.tags).slice()}_initialize(){this.transitions=Jt(this),this.config.always&&(this.always=A(this.config.always).map(t=>x(this,Tt,t))),Object.keys(this.states).forEach(t=>{this.states[t]._initialize()})}get definition(){return{id:this.id,key:this.key,version:this.machine.version,type:this.type,initial:this.initial?{target:this.initial.target,source:this,actions:this.initial.actions.map(Y),eventType:null,reenter:!1,toJSON:()=>({target:this.initial.target.map(t=>`#${t.id}`),source:`#${this.id}`,actions:this.initial.actions.map(Y),eventType:null})}:void 0,history:this.history,states:kt(this.states,t=>t.definition),on:this.on,transitions:[...this.transitions.values()].flat().map(t=>({...t,actions:t.actions.map(Y)})),entry:this.entry.map(Y),exit:this.exit.map(Y),meta:this.meta,order:this.order||-1,output:this.output,invoke:this.invoke,description:this.description,tags:this.tags}}toJSON(){return this.definition}get invoke(){return q(this,"invoke",()=>S(this.config.invoke).map((t,e)=>{let{src:s,systemId:i}=t,r=t.id??bt(this.id,e),o=typeof s=="string"?s:`xstate.invoke.${bt(this.id,e)}`;return{...t,src:o,id:r,systemId:i,toJSON(){let{onDone:a,onError:c,...f}=t;return{...f,type:"xstate.invoke",src:o,id:r}}}}))}get on(){return q(this,"on",()=>[...this.transitions].flatMap(([e,s])=>s.map(i=>[e,i])).reduce((e,[s,i])=>(e[s]=e[s]||[],e[s].push(i),e),{}))}get after(){return q(this,"delayedTransitions",()=>Yt(this))}get initial(){return q(this,"initial",()=>zt(this,this.config.initial))}next(t,e){let s=e.type,i=[],r,o=q(this,`candidates-${s}`,()=>Kt(this,s));for(let a of o){let{guard:c}=a,f=t.context,p=!1;try{p=!c||N(c,f,e,t)}catch(d){let u=typeof c=="string"?c:typeof c=="object"?c.type:void 0;throw new Error(`Unable to evaluate guard ${u?`'${u}' `:""}in transition for event '${s}' in state node '${this.id}':
3
+ ${d.message}`)}if(p){i.push(...a.actions),r=a;break}}return r?[r]:void 0}get events(){return q(this,"events",()=>{let{states:t}=this,e=new Set(this.ownEvents);if(t)for(let s of Object.keys(t)){let i=t[s];if(i.states)for(let r of i.events)e.add(`${r}`)}return Array.from(e)})}get ownEvents(){let t=Object.keys(Object.fromEntries(this.transitions)),e=new Set(t.filter(s=>this.transitions.get(s).some(i=>!(!i.target&&!i.actions.length&&!i.reenter))));return Array.from(e)}},cn="#",ut=class n{constructor(t,e){this.config=t,this.version=void 0,this.schemas=void 0,this.implementations=void 0,this.__xstatenode=!0,this.idMap=new Map,this.root=void 0,this.id=void 0,this.states=void 0,this.events=void 0,this.id=t.id||"(machine)",this.implementations={actors:(e==null?void 0:e.actors)??{},actions:(e==null?void 0:e.actions)??{},delays:(e==null?void 0:e.delays)??{},guards:(e==null?void 0:e.guards)??{}},this.version=this.config.version,this.schemas=this.config.schemas,this.transition=this.transition.bind(this),this.getInitialSnapshot=this.getInitialSnapshot.bind(this),this.getPersistedSnapshot=this.getPersistedSnapshot.bind(this),this.restoreSnapshot=this.restoreSnapshot.bind(this),this.start=this.start.bind(this),this.root=new ct(t,{_key:this.id,_machine:this}),this.root._initialize(),Xt(this.root),this.states=this.root.states,this.events=this.root.events}provide(t){let{actions:e,guards:s,actors:i,delays:r}=this.implementations;return new n(this.config,{actions:{...e,...t.actions},guards:{...s,...t.guards},actors:{...i,...t.actors},delays:{...r,...t.delays}})}resolveState(t){let e=ie(this.root,t.value),s=j(B(this.root,e));return K({_nodes:[...s],context:t.context||{},children:{},status:ot(s,this.root)?"done":t.status||"active",output:t.output,error:t.error,historyValue:t.historyValue},this)}transition(t,e,s){return F(t,e,s,[]).snapshot}microstep(t,e,s){return F(t,e,s,[]).microsteps.map(([i])=>i)}getTransitionData(t,e){return at(this.root,t.value,t,e)||[]}_getPreInitialState(t,e,s){let{context:i}=this.config,r=K({context:typeof i!="function"&&i?i:{},_nodes:[this.root],children:{},status:"active"},this);return typeof i=="function"?I(r,e,t,[g(({spawn:a,event:c,self:f})=>i({spawn:a,input:c.input,self:f}))],s,void 0):r}getInitialSnapshot(t,e){let s=nt(e),i=[],r=this._getPreInitialState(t,s,i),[o]=Et(this.root,r,t,s,i),{snapshot:a}=F(o,s,t,i);return a}start(t){Object.values(t.children).forEach(e=>{e.getSnapshot().status==="active"&&e.start()})}getStateNodeById(t){let e=st(t),s=e.slice(1),i=V(e[0])?e[0].slice(cn.length):e[0],r=this.idMap.get(i);if(!r)throw new Error(`Child state node '#${i}' does not exist on machine '${this.id}'`);return W(r,s)}get definition(){return this.root.definition}toJSON(){return this.definition}getPersistedSnapshot(t,e){return oe(t,e)}restoreSnapshot(t,e){let s={},i=t.children;Object.keys(i).forEach(d=>{let u=i[d],l=u.snapshot,h=u.src,y=typeof h=="string"?H(this,h):h;if(!y)return;let _=v(y,{id:d,parent:e.self,syncSnapshot:u.syncSnapshot,snapshot:l,src:h,systemId:u.systemId});s[d]=_});function r(d,u){if(u instanceof ct)return u;try{return d.machine.getStateNodeById(u.id)}catch{}}function o(d,u){if(!u||typeof u!="object")return{};let l={};for(let h in u){let y=u[h];for(let _ of y){let P=r(d,_);P&&(l[h]??=[],l[h].push(P))}}return l}let a=o(this.root,t.historyValue),c=K({...t,children:s,_nodes:Array.from(j(B(this.root,t.value))),historyValue:a},this),f=new Set;function p(d,u){if(!f.has(d)){f.add(d);for(let l in d){let h=d[l];if(h&&typeof h=="object"){if("xstate$$type"in h&&h.xstate$$type===it){d[l]=u[h.id];continue}p(h,u)}}}}return p(c.context,s),c}};function un(n,t,e,s,{event:i}){let r=typeof i=="function"?i(e,s):i;return[t,{event:r},void 0]}function dn(n,{event:t}){n.defer(()=>n.emit(t))}function wt(n){function t(e,s){}return t.type="xstate.emit",t.event=n,t.resolve=un,t.execute=dn,t}var It=(function(n){return n.Parent="#_parent",n.Internal="#_internal",n})({});function hn(n,t,e,s,{to:i,event:r,id:o,delay:a},c){var h;let f=t.machine.implementations.delays;if(typeof r=="string")throw new Error(`Only event objects may be used with sendTo; use sendTo({ type: "${r}" }) instead`);let p=typeof r=="function"?r(e,s):r,d;if(typeof a=="string"){let y=f&&f[a];d=typeof y=="function"?y(e,s):y}else d=typeof a=="function"?a(e,s):a;let u=typeof i=="function"?i(e,s):i,l;if(typeof u=="string"){if(u===It.Parent?l=n.self._parent:u===It.Internal?l=n.self:u.startsWith("#_")?l=t.children[u.slice(2)]:l=(h=c.deferredActorIds)!=null&&h.includes(u)?u:t.children[u],!l)throw new Error(`Unable to send event to actor '${u}' from machine '${t.machine.id}'.`)}else l=u||n.self;return[t,{to:l,targetId:typeof u=="string"?u:void 0,event:p,id:o,delay:d},void 0]}function ln(n,t,e){typeof e.to=="string"&&(e.to=t.children[e.to])}function fn(n,t){n.defer(()=>{let{to:e,event:s,delay:i,id:r}=t;if(typeof i=="number"){n.system.scheduler.schedule(n.self,e,s,i,r);return}n.system._relay(n.self,e,s.type===Nt?St(n.self.id,s.data):s)})}function dt(n,t,e){function s(i,r){}return s.type="xstate.sendTo",s.to=n,s.event=t,s.id=e==null?void 0:e.id,s.delay=e==null?void 0:e.delay,s.resolve=hn,s.retryResolve=ln,s.execute=fn,s}function pn(n,t){return dt(It.Parent,n,t)}function gn(n,t,e,s,{collect:i}){let r=[],o=function(c){r.push(c)};return o.assign=(...a)=>{r.push(g(...a))},o.cancel=(...a)=>{r.push($(...a))},o.raise=(...a)=>{r.push(G(...a))},o.sendTo=(...a)=>{r.push(dt(...a))},o.sendParent=(...a)=>{r.push(pn(...a))},o.spawnChild=(...a)=>{r.push(M(...a))},o.stopChild=(...a)=>{r.push(w(...a))},o.emit=(...a)=>{r.push(wt(...a))},i({context:e.context,event:e.event,enqueue:o,check:a=>N(a,t.context,e.event,t),self:n.self,system:n.system},s),[t,void 0,r]}function de(n){function t(e,s){}return t.type="xstate.enqueueActions",t.collect=n,t.resolve=gn,t}function yn(n,t,e,s,{value:i,label:r}){return[t,{value:typeof i=="function"?i(e,s):i,label:r},void 0]}function _n({logger:n},{value:t,label:e}){e?n(e,t):n(t)}function he(n=({context:e,event:s})=>({context:e,event:s}),t){function e(s,i){}return e.type="xstate.log",e.value=n,e.label=t,e.resolve=yn,e.execute=_n,e}function mn(n,t){return new ut(n,t)}function J({schemas:n,actors:t,actions:e,guards:s,delays:i}){return{assign:g,sendTo:dt,raise:G,log:he,cancel:$,stopChild:w,enqueueActions:de,emit:wt,spawnChild:M,createStateConfig:r=>r,createAction:r=>r,createMachine:r=>mn({...r,schemas:n},{actors:t,actions:e,guards:s,delays:i}),extend:r=>J({schemas:n,actors:t,actions:{...e,...r.actions},guards:{...s,...r.guards},delays:{...i,...r.delays}})}}var vn=typeof window<"u",X;function Tn(){if(!vn)return null;let n=window.AudioContext??window.webkitAudioContext;return n?new n:null}function z(){return X===void 0?null:X}function le(){X===void 0&&(X=Tn());let n=X;return n&&n.state==="suspended"?n.resume():Promise.resolve()}var Dt=typeof navigator<"u"&&"mediaSession"in navigator;function fe(n){if(!Dt)return;let{mediaSession:t}=navigator;t.setActionHandler("play",n.onPlay),t.setActionHandler("pause",n.onPause),t.setActionHandler("nexttrack",n.onNext),t.setActionHandler("previoustrack",n.onPrevious),t.setActionHandler("seekto",e=>{e.seekTime!=null&&n.onSeek(e.seekTime)})}function D(n){if(Dt){if(!n){navigator.mediaSession.metadata=null;return}navigator.mediaSession.metadata=new MediaMetadata({title:n.title??"",artist:n.artist??"",album:n.album??"",artwork:n.artwork??[]})}}function pe(n){Dt&&(navigator.mediaSession.playbackState=n?"playing":"paused")}function ge(n){return J({types:{context:{},events:{}},guards:{hasNextTrack:({context:t})=>t.currentTrackIndex+1<t.trackCount,playImmediately:({event:t})=>!!t.playImmediately}}).createMachine({id:"queue",initial:"idle",context:n,on:{ADD_TRACK:{actions:g({trackCount:({context:t})=>t.trackCount+1})},REMOVE_TRACK:{actions:g({trackCount:({context:t})=>Math.max(0,t.trackCount-1),currentTrackIndex:({context:t,event:e})=>e.index<t.currentTrackIndex?Math.max(0,t.currentTrackIndex-1):t.currentTrackIndex})}},states:{idle:{on:{PLAY:{target:"playing"},GOTO:[{guard:"playImmediately",target:"playing",actions:g({currentTrackIndex:({event:t})=>t.index})},{target:"paused",actions:g({currentTrackIndex:({event:t})=>t.index})}]}},playing:{on:{PAUSE:{target:"paused"},TOGGLE:{target:"paused"},NEXT:{actions:g({currentTrackIndex:({context:t})=>{let e=t.currentTrackIndex+1;return e<t.trackCount?e:t.currentTrackIndex}})},PREVIOUS:{actions:g({currentTrackIndex:({context:t})=>Math.max(0,t.currentTrackIndex-1)})},GOTO:{actions:g({currentTrackIndex:({event:t})=>t.index})},SEEK:{},TRACK_ENDED:[{guard:"hasNextTrack",target:"playing",actions:g({currentTrackIndex:({context:t})=>t.currentTrackIndex+1})},{target:"ended"}],TRACK_LOADED:{}}},paused:{on:{PLAY:{target:"playing"},TOGGLE:{target:"playing"},NEXT:{actions:g({currentTrackIndex:({context:t})=>{let e=t.currentTrackIndex+1;return e<t.trackCount?e:t.currentTrackIndex}})},PREVIOUS:{actions:g({currentTrackIndex:({context:t})=>Math.max(0,t.currentTrackIndex-1)})},GOTO:[{guard:"playImmediately",target:"playing",actions:g({currentTrackIndex:({event:t})=>t.index})},{actions:g({currentTrackIndex:({event:t})=>t.index})}],SEEK:{},TRACK_ENDED:[{guard:"hasNextTrack",target:"paused",actions:g({currentTrackIndex:({context:t})=>t.currentTrackIndex+1})},{target:"ended"}]}},ended:{on:{PLAY:{target:"playing",actions:g({currentTrackIndex:()=>0})},GOTO:[{guard:"playImmediately",target:"playing",actions:g({currentTrackIndex:({event:t})=>t.index})},{target:"paused",actions:g({currentTrackIndex:({event:t})=>t.index})}]}}}})}function ye(n){return J({types:{context:{},events:{}}}).createMachine({id:"track",initial:"idle",context:n,states:{idle:{on:{HTML5_ENDED:{},PLAY:{target:"html5",actions:g({isPlaying:()=>!0})},PLAY_WEBAUDIO:{target:"webaudio",actions:g({isPlaying:()=>!0,webAudioLoadingState:()=>"LOADED",playbackType:()=>"WEBAUDIO"})},PRELOAD:{target:"loading"},BUFFER_LOADING:{actions:g({webAudioLoadingState:()=>"LOADING"})},URL_RESOLVED:{actions:g({resolvedUrl:({event:t})=>t.url})}}},html5:{on:{PAUSE:{actions:g({isPlaying:()=>!1})},PLAY:{actions:g({isPlaying:()=>!0})},BUFFER_LOADING:{actions:g({webAudioLoadingState:()=>"LOADING"})},PLAY_WEBAUDIO:{target:"webaudio",actions:g({isPlaying:()=>!0,webAudioLoadingState:()=>"LOADED",playbackType:()=>"WEBAUDIO"})},BUFFER_READY:{actions:g({webAudioLoadingState:()=>"LOADED"})},BUFFER_ERROR:{actions:g({webAudioLoadingState:()=>"ERROR"})},SEEK:{actions:g({pausedAtTrackTime:({event:t})=>t.time})},HTML5_ENDED:{target:"idle",actions:g({isPlaying:()=>!1})},URL_RESOLVED:{actions:g({resolvedUrl:({event:t})=>t.url})},DEACTIVATE:{target:"loading",actions:g({isPlaying:()=>!1})}}},loading:{on:{BUFFER_LOADING:{actions:g({webAudioLoadingState:()=>"LOADING"})},BUFFER_READY:{target:"idle",actions:g({webAudioLoadingState:()=>"LOADED"})},BUFFER_ERROR:{target:"idle",actions:g({webAudioLoadingState:()=>"ERROR"})},PLAY:{target:"html5",actions:g({isPlaying:()=>!0})},PLAY_WEBAUDIO:{target:"webaudio",actions:g({isPlaying:()=>!0,webAudioLoadingState:()=>"LOADED",playbackType:()=>"WEBAUDIO"})},URL_RESOLVED:{actions:g({resolvedUrl:({event:t})=>t.url})}}},webaudio:{on:{PAUSE:{actions:g({isPlaying:()=>!1})},PLAY:{actions:g({isPlaying:()=>!0})},PLAY_WEBAUDIO:{actions:g({isPlaying:()=>!0,playbackType:()=>"WEBAUDIO"})},SEEK:{actions:g({pausedAtTrackTime:({event:t})=>t.time})},SET_VOLUME:{},WEBAUDIO_ENDED:{target:"idle",actions:g({isPlaying:()=>!1})},DEACTIVATE:{target:"idle",actions:g({isPlaying:()=>!1})}}}}})}var Sn=5,Q=class{index;metadata;_trackUrl;_resolvedUrl;skipHEAD;loadedHEAD=!1;abortController=null;audio;_webAudioDisabled;get ctx(){if(this._webAudioDisabled)return null;let t=z();return t&&!this.gainNode&&(this.gainNode=t.createGain(),this.gainNode.gain.value=this.audio.volume),t}gainNode=null;sourceNode=null;audioBuffer=null;webAudioStartedAt=0;pausedAtTrackTime=0;scheduledStartContextTime=null;_actor;queueRef;rafId=null;_notifiedLookahead=!1;constructor(t){this.index=t.index,this._trackUrl=t.trackUrl,this._resolvedUrl=t.trackUrl,this.skipHEAD=t.skipHEAD??!1,this.metadata=t.metadata??{},this.queueRef=t.queue,this.audio=new Audio,this.audio.preload="none",this.audio.src=this._trackUrl,this.audio.volume=t.queue.volume,this.audio.controls=!1,this.audio.onerror=()=>{var r,o;let s=(r=this.audio.error)==null?void 0:r.code;if(s===1)return;let i=((o=this.audio.error)==null?void 0:o.message)??"unknown";this.queueRef.onError(new Error(`HTML5 audio error on track ${this.index} (code ${s}): ${i}`))},this.audio.onended=()=>{let s=this._actor.getSnapshot().value;this.queueRef.onDebug(`audio.onended track=${this.index} machineState=${s} queueIdx=${this.queueRef.currentTrackIndex}`),(s==="html5"||s==="idle")&&(this._actor.send({type:"HTML5_ENDED"}),this.queueRef.onTrackEnded(this))},this._webAudioDisabled=t.queue.webAudioIsDisabled;let e={trackUrl:this._trackUrl,resolvedUrl:this._trackUrl,skipHEAD:this.skipHEAD,playbackType:"HTML5",webAudioLoadingState:"NONE",webAudioStartedAt:0,pausedAtTrackTime:0,isPlaying:!1};this._actor=v(ye(e)),this._actor.start()}play(){let t=this._actor.getSnapshot().value,e=!1;this.queueRef.onDebug(`Track.play() track=${this.index} machineState=${t} hasBuffer=${!!this.audioBuffer} hasCtx=${!!this.ctx} audioPaused=${this.audio.paused}`),t==="webaudio"?e=this._playWebAudio():this.audioBuffer&&this.ctx&&(t==="loading"||t==="idle")&&(e=this._playWebAudio()),e||t==="html5"&&!this.audio.paused||this._playHtml5(),this._actor.send({type:e?"PLAY_WEBAUDIO":"PLAY"}),this.startProgressLoop()}pause(){this._actor.getSnapshot().value==="webaudio"?(this.pausedAtTrackTime=this.currentTime,this._stopSourceNode(),this._disconnectGain()):this.audio.pause(),this._actor.send({type:"PAUSE"}),this._stopProgressLoop(),this.queueRef.onProgress(this.toInfo())}seek(t){let e=Math.max(0,isNaN(this.duration)?t:Math.min(t,this.duration));if(this.pausedAtTrackTime=e,this._actor.getSnapshot().value==="webaudio"){let i=this._actor.getSnapshot().context.isPlaying;this._stopSourceNode(),this.scheduledStartContextTime=null,i&&this._startSourceNode(e)}else this.audio.preload!=="auto"&&(this.audio.preload="auto"),this.audio.readyState>=HTMLMediaElement.HAVE_METADATA?this.audio.currentTime=e:(this.audio.addEventListener("loadedmetadata",()=>{this.audio.currentTime=e},{once:!0}),this.audio.load());this._actor.send({type:"SEEK",time:e}),this.queueRef.onProgress(this.toInfo())}setVolume(t){let e=Math.min(1,Math.max(0,t));this.audio.volume=e,this.gainNode&&(this.gainNode.gain.value=e),this._actor.send({type:"SET_VOLUME",volume:e})}preload(){this.queueRef.onDebug(`preload() track=${this.index} state=${this._actor.getSnapshot().value} hasBuffer=${!!this.audioBuffer} hasCtx=${!!this.ctx}`),this._actor.getSnapshot().value==="idle"&&this._actor.send({type:"PRELOAD"}),!(this.audioBuffer||!this.ctx)&&this._startLoad()}seekToEnd(t=6){let e=this.duration;!isNaN(e)&&e>t&&this.seek(e-t)}activate(){this._actor.getSnapshot().value==="webaudio"&&(this._stopSourceNode(),this._disconnectGain(),this.scheduledStartContextTime=null,this._stopProgressLoop(),this._actor.send({type:"DEACTIVATE"})),this.webAudioStartedAt=0,this.pausedAtTrackTime=0,this._notifiedLookahead=!1,(this.audio.ended||this.audio.currentTime>0)&&(this.audio.currentTime=0)}deactivate(){this.queueRef.onDebug(`Track.deactivate() track=${this.index} machineState=${this._actor.getSnapshot().value} isPlaying=${this.isPlaying}`),this._stopSourceNode(),this._disconnectGain(),this.webAudioStartedAt=0,this.pausedAtTrackTime=0,this.scheduledStartContextTime=null,this.audio.pause(),this.audio.currentTime=0,this._stopProgressLoop(),this._actor.send({type:"DEACTIVATE"}),this.queueRef.onDebug(`Track.deactivate() done track=${this.index} machineState=${this._actor.getSnapshot().value}`)}destroy(){var t,e;this.deactivate(),(t=this.abortController)==null||t.abort(),this.audioBuffer=null,(e=this.gainNode)==null||e.disconnect(),this.gainNode=null,this._actor.stop()}cancelGaplessStart(){this.scheduledStartContextTime!==null&&(this._stopSourceNode(),this._disconnectGain(),this.scheduledStartContextTime=null,this.webAudioStartedAt=0,this.pausedAtTrackTime=0,this._stopProgressLoop(),this._actor.send({type:"DEACTIVATE"}))}scheduleGaplessStart(t){!this.ctx||!this.audioBuffer||!this.gainNode||(this.scheduledStartContextTime=t,this._stopSourceNode(),this.sourceNode=this.ctx.createBufferSource(),this.sourceNode.buffer=this.audioBuffer,this.sourceNode.connect(this.gainNode),this.gainNode.connect(this.ctx.destination),this.sourceNode.onended=this._handleWebAudioEnded,this.sourceNode.start(t,0),this.webAudioStartedAt=t,this._actor.send({type:"PLAY_WEBAUDIO"}),this.queueRef.onDebug(`scheduleGaplessStart track=${this.index} when=${t.toFixed(3)} ctxNow=${this.ctx.currentTime.toFixed(3)} delta=${(t-this.ctx.currentTime).toFixed(3)}s ctxState=${this.ctx.state}`))}get currentTime(){return this._isUsingWebAudio?this._actor.getSnapshot().context.isPlaying?this.ctx?Math.max(0,this.ctx.currentTime-this.webAudioStartedAt):0:this.pausedAtTrackTime:this.audio.currentTime}get duration(){return this.audioBuffer?this.audioBuffer.duration:this.audio.duration}get isPaused(){return this._isUsingWebAudio?!this._actor.getSnapshot().context.isPlaying:this.audio.paused}get isPlaying(){return this._actor.getSnapshot().context.isPlaying}get trackUrl(){return this._resolvedUrl}get playbackType(){return this._actor.getSnapshot().context.playbackType}get webAudioLoadingState(){return this._actor.getSnapshot().context.webAudioLoadingState}get hasSourceNode(){return this.sourceNode!==null}get machineState(){return this._actor.getSnapshot().value}get isBufferLoaded(){return this.audioBuffer!==null}toInfo(){var t;return{index:this.index,currentTime:this.currentTime,duration:this.duration,isPlaying:this.isPlaying,isPaused:this.isPaused,volume:((t=this.gainNode)==null?void 0:t.gain.value)??this.audio.volume,trackUrl:this.trackUrl,playbackType:this.playbackType,webAudioLoadingState:this.webAudioLoadingState,metadata:this.metadata,machineState:this.machineState}}_playHtml5(){this.audio.preload!=="auto"&&(this.audio.preload="auto");let t=this.audio.play();t&&t.catch(e=>{e instanceof Error&&e.name==="NotAllowedError"?this.queueRef.onPlayBlocked():e instanceof Error&&e.name==="AbortError"||this.queueRef.onError(e instanceof Error?e:new Error(String(e)))})}get _isUsingWebAudio(){return this._actor.getSnapshot().value==="webaudio"}_playWebAudio(){if(!this.ctx||!this.audioBuffer||!this.gainNode)return this.queueRef.onDebug(`_playWebAudio BAIL track=${this.index} ctx=${!!this.ctx} buf=${!!this.audioBuffer} gain=${!!this.gainNode}`),!1;let e=this._actor.getSnapshot().context.isPlaying?0:this.pausedAtTrackTime;return this._startSourceNode(e),!0}_startSourceNode(t){!this.ctx||!this.audioBuffer||!this.gainNode||(this._stopSourceNode(),this.ctx.state==="suspended"&&this.ctx.resume(),this.sourceNode=this.ctx.createBufferSource(),this.sourceNode.buffer=this.audioBuffer,this.sourceNode.connect(this.gainNode),this.gainNode.connect(this.ctx.destination),this.sourceNode.onended=this._handleWebAudioEnded,this.webAudioStartedAt=this.ctx.currentTime-t,this.sourceNode.start(0,t))}_stopSourceNode(){if(this.sourceNode){this.sourceNode.onended=null;try{this.sourceNode.stop()}catch{}try{this.sourceNode.disconnect()}catch{}this.sourceNode=null}}_disconnectGain(){if(!(!this.gainNode||!this.ctx))try{this.gainNode.disconnect(this.ctx.destination)}catch{}}_handleWebAudioEnded=()=>{this.queueRef.onDebug(`_handleWebAudioEnded track=${this.index} sourceNode=${!!this.sourceNode} queueIdx=${this.queueRef.currentTrackIndex}`),this.sourceNode&&(this._actor.send({type:"WEBAUDIO_ENDED"}),this._stopProgressLoop(),this.queueRef.onTrackEnded(this))};_startLoad(){let t=this._actor.getSnapshot();if(!this.ctx||this.audioBuffer||t.context.webAudioLoadingState!=="NONE"){this.queueRef.onDebug(`_startLoad() SKIPPED track=${this.index} hasCtx=${!!this.ctx} hasBuffer=${!!this.audioBuffer} loadingState=${t.context.webAudioLoadingState}`);return}this.queueRef.onDebug(`_startLoad() STARTING track=${this.index} url=${this._resolvedUrl.slice(0,60)}`),this._actor.send({type:"BUFFER_LOADING"}),this.abortController=new AbortController;let e=s=>{fetch(s,{signal:this.abortController.signal}).then(i=>{if(!i.ok)throw new Error(`HTTP ${i.status} for ${s}`);return i.arrayBuffer()}).then(i=>this.ctx.decodeAudioData(i)).then(i=>{this.audioBuffer=i,this._actor.send({type:"BUFFER_READY"}),this.queueRef.onTrackBufferReady(this)}).catch(i=>{i instanceof Error&&i.name==="AbortError"||(console.error(`gapless.js: decode failed for track ${this.index}`,i),this._actor.send({type:"BUFFER_ERROR"}))})};this.skipHEAD||this.loadedHEAD?e(this._resolvedUrl):fetch(this._trackUrl,{method:"HEAD",signal:this.abortController.signal}).then(s=>{s.redirected&&s.url&&(this._resolvedUrl=s.url,this.audio.src=s.url,this._actor.send({type:"URL_RESOLVED",url:s.url})),this.loadedHEAD=!0,e(this._resolvedUrl)}).catch(s=>{s instanceof Error&&s.name==="AbortError"||(this.loadedHEAD=!0,e(this._trackUrl))})}startProgressLoop(){if(this.rafId!==null)return;let t=()=>{if(this.isPaused||!this.isPlaying){this.rafId=null;return}this.queueRef.onProgress(this.toInfo());let e=this.duration-this.currentTime;!this._notifiedLookahead&&!isNaN(e)&&e<=Sn&&(this._notifiedLookahead=!0,this.queueRef.onTrackBufferReady(this)),this.rafId=requestAnimationFrame(t)};this.rafId=requestAnimationFrame(t)}_stopProgressLoop(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}};var xn=2,ht=class{_tracks=[];_actor;_onProgress;_onEnded;_onPlayNextTrack;_onPlayPreviousTrack;_onStartNewTrack;_onError;_onPlayBlocked;_onDebug;webAudioIsDisabled;_volume;_scheduledIndices=new Set;constructor(t={}){let{tracks:e=[],onProgress:s,onEnded:i,onPlayNextTrack:r,onPlayPreviousTrack:o,onStartNewTrack:a,onError:c,onPlayBlocked:f,onDebug:p,webAudioIsDisabled:d=!1,trackMetadata:u=[],volume:l=1}=t;this._volume=Math.min(1,Math.max(0,l)),this.webAudioIsDisabled=d,this._onProgress=s,this._onEnded=i,this._onPlayNextTrack=r,this._onPlayPreviousTrack=o,this._onStartNewTrack=a,this._onError=c,this._onPlayBlocked=f,this._onDebug=p,this._tracks=e.map((h,y)=>new Q({trackUrl:h,index:y,queue:this,metadata:u[y]})),this._actor=v(ge({currentTrackIndex:0,trackCount:this._tracks.length})),this._actor.subscribe(h=>{pe(h.value==="playing")}),this._actor.start(),fe({onPlay:()=>this.play(),onPause:()=>{this._actor.getSnapshot().value==="playing"&&this.pause()},onNext:()=>this.next(),onPrevious:()=>this.previous(),onSeek:h=>this.seek(h)})}play(){let t=this._currentTrack;t&&(t.play(),this._actor.send({type:"PLAY"}),D(t.metadata),this._preloadAhead(t.index),this._tryScheduleGapless(t))}pause(){var t;this._actor.send({type:"PAUSE"}),this._cancelScheduledGapless(),(t=this._currentTrack)==null||t.pause()}togglePlayPause(){this._actor.getSnapshot().value==="playing"?this.pause():this.play()}next(){var i,r;if(this._actor.getSnapshot().context.currentTrackIndex+1>=this._tracks.length)return;this._deactivateCurrent(),this._cancelAllScheduledGapless(),this._actor.send({type:"NEXT"}),this._activateCurrent(!0);let s=this._currentTrack;s&&((i=this._onStartNewTrack)==null||i.call(this,s.toInfo()),(r=this._onPlayNextTrack)==null||r.call(this,s.toInfo()),D(s.metadata)),this._preloadAhead(this._actor.getSnapshot().context.currentTrackIndex)}previous(){var s,i;let t=this._currentTrack;if(t&&t.currentTime>8){t.seek(0),t.play();return}this._deactivateCurrent(),this._cancelAllScheduledGapless(),this._actor.send({type:"PREVIOUS"}),this._activateCurrent(!0);let e=this._currentTrack;e&&((s=this._onStartNewTrack)==null||s.call(this,e.toInfo()),(i=this._onPlayPreviousTrack)==null||i.call(this,e.toInfo()),D(e.metadata))}gotoTrack(t,e=!1){var r,o;if(t<0||t>=this._tracks.length)return;let s=this._actor.getSnapshot();this.onDebug(`gotoTrack(${t}, playImmediately=${e}) queueState=${s.value} curIdx=${s.context.currentTrackIndex}`),this._deactivateCurrent(),this._cancelAllScheduledGapless(),this._actor.send({type:"GOTO",index:t,playImmediately:e});let i=this._actor.getSnapshot();if(this.onDebug(`gotoTrack after GOTO \u2192 queueState=${i.value} curIdx=${i.context.currentTrackIndex}`),e){this._activateCurrent(!0);let a=this._currentTrack;a&&(this.onDebug(`gotoTrack activateCurrent done, track=${a.index} trackState=${a.playbackType} isPlaying=${a.isPlaying}`),(r=this._onStartNewTrack)==null||r.call(this,a.toInfo()),D(a.metadata)),this._preloadAhead(t)}else(o=this._currentTrack)==null||o.seek(0)}seek(t){var e;(e=this._currentTrack)==null||e.seek(t),this._cancelAndRescheduleGapless()}setVolume(t){let e=Math.min(1,Math.max(0,t));this._volume=e;for(let s of this._tracks)s.setVolume(e)}addTrack(t,e={}){let s=this._tracks.length,i=e.metadata??{};this._tracks.push(new Q({trackUrl:t,index:s,queue:this,skipHEAD:e.skipHEAD,metadata:i})),this._actor.send({type:"ADD_TRACK"})}removeTrack(t){if(!(t<0||t>=this._tracks.length)){this._tracks[t].destroy(),this._tracks.splice(t,1);for(let e=t;e<this._tracks.length;e++)this._tracks[e].index=e;this._scheduledIndices.delete(t),this._actor.send({type:"REMOVE_TRACK",index:t})}}resumeAudioContext(){return le()}destroy(){for(let t of this._tracks)t.destroy();this._tracks=[],this._actor.stop()}get currentTrack(){var t;return(t=this._currentTrack)==null?void 0:t.toInfo()}get currentTrackIndex(){return this._actor.getSnapshot().context.currentTrackIndex}get tracks(){return this._tracks.map(t=>t.toInfo())}get isPlaying(){return this._actor.getSnapshot().value==="playing"}get isPaused(){return this._actor.getSnapshot().value==="paused"}get volume(){return this._volume}get queueSnapshot(){let t=this._actor.getSnapshot();return{state:t.value,context:t.context}}onTrackEnded(t){var i,r,o,a;let e=this._actor.getSnapshot();if(this.onDebug(`onTrackEnded track=${t.index} queueState=${e.value} curIdx=${e.context.currentTrackIndex}`),t.index!==e.context.currentTrackIndex)return;t.deactivate(),this._actor.send({type:"TRACK_ENDED"});let s=this._actor.getSnapshot();if(this.onDebug(`onTrackEnded after TRACK_ENDED \u2192 queueState=${s.value} curIdx=${s.context.currentTrackIndex}`),s.value==="ended"){(i=this._onEnded)==null||i.call(this);return}if(s.value==="playing"){let c=this._currentTrack;c&&(this._scheduledIndices.has(c.index)?(this.onDebug(`onTrackEnded: gapless track ${c.index} \u2014 sourceNode=${c.hasSourceNode} isPlaying=${c.isPlaying} machineState=${c.machineState}`),c.startProgressLoop()):c.play(),(r=this._onStartNewTrack)==null||r.call(this,c.toInfo()),(o=this._onPlayNextTrack)==null||o.call(this,c.toInfo()),D(c.metadata),this._preloadAhead(c.index))}if(s.value==="paused"){let c=this._currentTrack;c&&((a=this._onStartNewTrack)==null||a.call(this,c.toInfo()),D(c.metadata))}}onTrackBufferReady(t){this._actor.send({type:"TRACK_LOADED",index:t.index}),this._tryScheduleGapless(t),this._preloadAhead(this._actor.getSnapshot().context.currentTrackIndex)}onProgress(t){var e;t.index===this._actor.getSnapshot().context.currentTrackIndex&&((e=this._onProgress)==null||e.call(this,t))}onError(t){var e;(e=this._onError)==null||e.call(this,t)}onPlayBlocked(){var t;(t=this._onPlayBlocked)==null||t.call(this)}onDebug(t){var e;(e=this._onDebug)==null||e.call(this,t)}get _currentTrack(){return this._tracks[this._actor.getSnapshot().context.currentTrackIndex]}_deactivateCurrent(){var t;(t=this._currentTrack)==null||t.deactivate()}_activateCurrent(t){let e=this._currentTrack;e&&(e.activate(),t&&!this._scheduledIndices.has(e.index)&&e.play())}_preloadAhead(t){let e=t+xn+1;this.onDebug(`_preloadAhead(${t}) limit=${e} trackCount=${this._tracks.length}`);for(let s=t+1;s<this._tracks.length&&s<e;s++){let i=this._tracks[s];if(i.isBufferLoaded)this.onDebug(`_preloadAhead: track ${s} already loaded`);else{this.onDebug(`_preloadAhead: starting preload for track ${s}`),i.preload();break}}}_cancelScheduledGapless(){let e=this._actor.getSnapshot().context.currentTrackIndex+1;e<this._tracks.length&&this._scheduledIndices.has(e)&&(this._tracks[e].cancelGaplessStart(),this._scheduledIndices.delete(e),this.onDebug(`_cancelScheduledGapless: cancelled track ${e}`))}_cancelAllScheduledGapless(){var t;for(let e of this._scheduledIndices)(t=this._tracks[e])==null||t.cancelGaplessStart();this._scheduledIndices.clear()}_cancelAndRescheduleGapless(){this._cancelScheduledGapless();let t=this._currentTrack;t&&this._tryScheduleGapless(t)}_tryScheduleGapless(t){let e=z();if(!e||this.webAudioIsDisabled)return;let i=this._actor.getSnapshot().context.currentTrackIndex,r=i+1;if(r>=this._tracks.length)return;let o=this._tracks[i],a=this._tracks[r];if(!o.isBufferLoaded||!a.isBufferLoaded||this._scheduledIndices.has(r)||!o.isPlaying)return;let c=this._computeTrackEndTime(o);c!==null&&(c<e.currentTime+.01||(a.scheduleGaplessStart(c),this._scheduledIndices.add(r)))}_computeTrackEndTime(t){let e=z();if(!e||!t.isBufferLoaded)return null;let s=t.duration;if(isNaN(s))return null;if(t.scheduledStartContextTime!==null)return t.scheduledStartContextTime+s;let i=s-t.currentTime;return i<=0?null:e.currentTime+i}};export{ht as Queue,ht as default};
4
+ //# sourceMappingURL=index.mjs.map