@lucaismyname/ginger 0.0.5 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +844 -0
  2. package/dist/GingerSplitContexts-4YZ-OJ9V.js +63 -0
  3. package/dist/GingerSplitContexts-4YZ-OJ9V.js.map +1 -0
  4. package/dist/GingerSplitContexts-Bze1Bqe2.cjs +2 -0
  5. package/dist/GingerSplitContexts-Bze1Bqe2.cjs.map +1 -0
  6. package/dist/audio/GingerPlayer.d.ts +2 -1
  7. package/dist/audio/GingerPlayer.d.ts.map +1 -1
  8. package/dist/client.cjs +2 -0
  9. package/dist/client.cjs.map +1 -0
  10. package/dist/client.d.ts +2 -0
  11. package/dist/client.d.ts.map +1 -0
  12. package/dist/client.js +28 -0
  13. package/dist/client.js.map +1 -0
  14. package/dist/components/controls/Controls.d.ts +7 -3
  15. package/dist/components/controls/Controls.d.ts.map +1 -1
  16. package/dist/components/current/Artwork.d.ts.map +1 -1
  17. package/dist/components/current/Playback.d.ts +2 -1
  18. package/dist/components/current/Playback.d.ts.map +1 -1
  19. package/dist/components/current/Time.d.ts +11 -1
  20. package/dist/components/current/Time.d.ts.map +1 -1
  21. package/dist/components/current/index.d.ts +1 -1
  22. package/dist/components/current/index.d.ts.map +1 -1
  23. package/dist/components/playlist/GingerPlaylist.d.ts.map +1 -1
  24. package/dist/context/GingerContext.d.ts +7 -1
  25. package/dist/context/GingerContext.d.ts.map +1 -1
  26. package/dist/context/GingerLocaleContext.d.ts +9 -0
  27. package/dist/context/GingerLocaleContext.d.ts.map +1 -0
  28. package/dist/context/GingerProvider.d.ts +1 -1
  29. package/dist/context/GingerProvider.d.ts.map +1 -1
  30. package/dist/context/GingerSplitContexts.d.ts +46 -0
  31. package/dist/context/GingerSplitContexts.d.ts.map +1 -0
  32. package/dist/core/playbackReducer.d.ts +1 -0
  33. package/dist/core/playbackReducer.d.ts.map +1 -1
  34. package/dist/core/queue.d.ts +4 -0
  35. package/dist/core/queue.d.ts.map +1 -1
  36. package/dist/core/transitions.d.ts.map +1 -1
  37. package/dist/core/transitions.test.d.ts +2 -0
  38. package/dist/core/transitions.test.d.ts.map +1 -0
  39. package/dist/experimental-gapless/index.cjs +2 -0
  40. package/dist/experimental-gapless/index.cjs.map +1 -0
  41. package/dist/experimental-gapless/index.d.ts +11 -0
  42. package/dist/experimental-gapless/index.d.ts.map +1 -0
  43. package/dist/experimental-gapless/index.js +17 -0
  44. package/dist/experimental-gapless/index.js.map +1 -0
  45. package/dist/ginger-C1fV612c.cjs +2 -0
  46. package/dist/ginger-C1fV612c.cjs.map +1 -0
  47. package/dist/ginger-gb6OJ3eQ.js +1547 -0
  48. package/dist/ginger-gb6OJ3eQ.js.map +1 -0
  49. package/dist/ginger.d.ts +1 -0
  50. package/dist/ginger.d.ts.map +1 -1
  51. package/dist/hooks/useControlBindings.d.ts +40 -0
  52. package/dist/hooks/useControlBindings.d.ts.map +1 -0
  53. package/dist/hooks/useGinger.d.ts +5 -0
  54. package/dist/hooks/useGinger.d.ts.map +1 -1
  55. package/dist/hooks/useGingerChapters.d.ts +12 -0
  56. package/dist/hooks/useGingerChapters.d.ts.map +1 -0
  57. package/dist/hooks/useGingerDebugLog.d.ts +2 -0
  58. package/dist/hooks/useGingerDebugLog.d.ts.map +1 -0
  59. package/dist/hooks/useGingerKeyboardShortcuts.d.ts +8 -0
  60. package/dist/hooks/useGingerKeyboardShortcuts.d.ts.map +1 -0
  61. package/dist/hooks/useGingerLyricsSync.d.ts +8 -0
  62. package/dist/hooks/useGingerLyricsSync.d.ts.map +1 -0
  63. package/dist/hooks/useGingerSleepTimer.d.ts +9 -0
  64. package/dist/hooks/useGingerSleepTimer.d.ts.map +1 -0
  65. package/dist/hooks/useSeekDrag.d.ts +8 -0
  66. package/dist/hooks/useSeekDrag.d.ts.map +1 -0
  67. package/dist/index.cjs +1 -1
  68. package/dist/index.cjs.map +1 -1
  69. package/dist/index.d.ts +21 -2
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +25 -1071
  72. package/dist/index.js.map +1 -1
  73. package/dist/internal/lyrics.d.ts +6 -0
  74. package/dist/internal/lyrics.d.ts.map +1 -0
  75. package/dist/internal/lyrics.test.d.ts +2 -0
  76. package/dist/internal/lyrics.test.d.ts.map +1 -0
  77. package/dist/media/useMediaSession.d.ts +10 -0
  78. package/dist/media/useMediaSession.d.ts.map +1 -0
  79. package/dist/testing/index.cjs +91 -0
  80. package/dist/testing/index.cjs.map +1 -0
  81. package/dist/testing/index.d.ts +8 -0
  82. package/dist/testing/index.d.ts.map +1 -0
  83. package/dist/testing/index.js +11076 -0
  84. package/dist/testing/index.js.map +1 -0
  85. package/dist/types.d.ts +77 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/dist/useSeekDrag-CU-8Mi3A.cjs +2 -0
  88. package/dist/useSeekDrag-CU-8Mi3A.cjs.map +1 -0
  89. package/dist/useSeekDrag-DdlE-Qej.js +174 -0
  90. package/dist/useSeekDrag-DdlE-Qej.js.map +1 -0
  91. package/dist/waveform/index.cjs +2 -0
  92. package/dist/waveform/index.cjs.map +1 -0
  93. package/dist/waveform/index.d.ts +3 -0
  94. package/dist/waveform/index.d.ts.map +1 -0
  95. package/dist/waveform/index.js +40 -0
  96. package/dist/waveform/index.js.map +1 -0
  97. package/dist/waveform/useAudioPeaks.d.ts +7 -0
  98. package/dist/waveform/useAudioPeaks.d.ts.map +1 -0
  99. package/package.json +25 -3
@@ -0,0 +1,1547 @@
1
+ import { jsx as c, jsxs as Ae } from "react/jsx-runtime";
2
+ import { useContext as Se, createContext as Re, useRef as Q, useState as Er, useEffect as I, useMemo as L, useReducer as Pr, useCallback as k } from "react";
3
+ import { c as v, b as _, u as ve, g as Le, G as Ar, d as Sr } from "./GingerSplitContexts-4YZ-OJ9V.js";
4
+ const Fe = Re(null);
5
+ function Rr() {
6
+ const e = Se(Fe);
7
+ if (!e) throw new Error("Ginger components must be used within <Ginger.Provider>");
8
+ return e;
9
+ }
10
+ function De(e) {
11
+ const { buffered: r, duration: n } = e;
12
+ return !(n > 0) || r.length === 0 ? 0 : Math.min(1, r.end(r.length - 1) / n);
13
+ }
14
+ function Cr({
15
+ className: e,
16
+ style: r,
17
+ preload: n = "metadata",
18
+ crossOrigin: t,
19
+ respectReducedMotion: a = !1
20
+ }) {
21
+ var P;
22
+ const { audioRef: u, dispatch: o, state: l, notifyEnded: d } = Rr(), f = ((P = l.tracks[l.currentIndex]) == null ? void 0 : P.fileUrl) ?? "", g = Q({
23
+ currentTime: -1,
24
+ duration: -1,
25
+ bufferedFraction: -1
26
+ }), [h, b] = Er(!1);
27
+ I(() => {
28
+ if (!a || typeof window > "u") return;
29
+ const p = window.matchMedia("(prefers-reduced-motion: reduce)"), y = () => b(p.matches);
30
+ return y(), p.addEventListener("change", y), () => p.removeEventListener("change", y);
31
+ }, [a]);
32
+ const T = (p, y = !1) => {
33
+ const C = {
34
+ currentTime: p.currentTime,
35
+ duration: p.duration,
36
+ bufferedFraction: De(p)
37
+ }, A = g.current, Ie = h ? 0.5 : 0.25, K = Math.abs(C.currentTime - A.currentTime) >= Ie || Math.abs(C.duration - A.duration) >= 0.01 || Math.abs(C.bufferedFraction - A.bufferedFraction) >= 0.01;
38
+ !y && !K || (g.current = C, o({
39
+ type: "MEDIA_TIME_UPDATE",
40
+ payload: C
41
+ }));
42
+ };
43
+ return I(() => {
44
+ const p = u.current;
45
+ p && (p.volume = l.volume, p.muted = l.muted, p.playbackRate = l.playbackRate);
46
+ }, [u, l.volume, l.muted, l.playbackRate]), I(() => {
47
+ const p = u.current;
48
+ if (p) {
49
+ if (!f) {
50
+ p.removeAttribute("src"), g.current = { currentTime: -1, duration: -1, bufferedFraction: -1 };
51
+ return;
52
+ }
53
+ p.getAttribute("src") !== f && (p.src = f, p.load(), g.current = { currentTime: -1, duration: -1, bufferedFraction: -1 });
54
+ }
55
+ }, [u, l.currentIndex, l.tracks, f]), /* @__PURE__ */ c(
56
+ "audio",
57
+ {
58
+ ref: u,
59
+ className: e,
60
+ style: r,
61
+ preload: n,
62
+ crossOrigin: t,
63
+ controls: !1,
64
+ playsInline: !0,
65
+ onTimeUpdate: (p) => {
66
+ T(p.currentTarget);
67
+ },
68
+ onLoadedMetadata: (p) => {
69
+ const y = p.currentTarget;
70
+ g.current = { currentTime: -1, duration: -1, bufferedFraction: -1 }, o({
71
+ type: "MEDIA_LOADED_METADATA",
72
+ payload: {
73
+ duration: y.duration,
74
+ bufferedFraction: De(y)
75
+ }
76
+ });
77
+ },
78
+ onSeeking: (p) => T(p.currentTarget, !0),
79
+ onSeeked: (p) => T(p.currentTarget, !0),
80
+ onEnded: () => d(),
81
+ onPlay: () => o({ type: "MEDIA_PLAY" }),
82
+ onPause: () => o({ type: "MEDIA_PAUSE" }),
83
+ onWaiting: () => o({ type: "MEDIA_WAITING" }),
84
+ onCanPlay: () => o({ type: "MEDIA_CANPLAY" }),
85
+ onProgress: (p) => T(p.currentTarget, !0),
86
+ onVolumeChange: (p) => {
87
+ const y = p.currentTarget;
88
+ o({
89
+ type: "MEDIA_VOLUME_SYNC",
90
+ payload: { volume: y.volume, muted: y.muted }
91
+ });
92
+ },
93
+ onError: () => {
94
+ var A;
95
+ const p = u.current, y = (A = p == null ? void 0 : p.error) == null ? void 0 : A.code;
96
+ o({ type: "MEDIA_ERROR", payload: { message: y === 1 ? "MEDIA_ERR_ABORTED" : y === 2 ? "MEDIA_ERR_NETWORK" : y === 3 ? "MEDIA_ERR_DECODE" : y === 4 ? "MEDIA_ERR_SRC_NOT_SUPPORTED" : "MEDIA_ERR_UNKNOWN" } });
97
+ }
98
+ }
99
+ );
100
+ }
101
+ function E(e, r) {
102
+ return r <= 0 ? 0 : Math.max(0, Math.min(r - 1, e));
103
+ }
104
+ function Ue(e, r) {
105
+ if (e.length <= 1) return [...e];
106
+ const n = e[r];
107
+ if (!n) return [...e];
108
+ const t = e.filter((a, u) => u !== r);
109
+ for (let a = t.length - 1; a > 0; a--) {
110
+ const u = Math.floor(Math.random() * (a + 1));
111
+ [t[a], t[u]] = [t[u], t[a]];
112
+ }
113
+ return [n, ...t];
114
+ }
115
+ function j(e) {
116
+ return e ? e.id != null && e.id !== "" ? `id:${e.id}` : `file:${e.fileUrl}` : "";
117
+ }
118
+ function Gr(e, r) {
119
+ const n = j(r);
120
+ if (!n) return 0;
121
+ const t = e.findIndex((a) => j(a) === n);
122
+ return t === -1 ? 0 : t;
123
+ }
124
+ function Ve(e, r, n) {
125
+ const t = [...e], a = Math.max(0, Math.min(t.length, n ?? t.length));
126
+ return t.splice(a, 0, r), t;
127
+ }
128
+ function _r(e, r) {
129
+ if (r < 0 || r >= e.length) return [...e];
130
+ const n = [...e];
131
+ return n.splice(r, 1), n;
132
+ }
133
+ function Nr(e, r, n) {
134
+ if (r === n || r < 0 || r >= e.length || n < 0 || n >= e.length)
135
+ return [...e];
136
+ const t = [...e], [a] = t.splice(r, 1);
137
+ return a ? (t.splice(n, 0, a), t) : [...e];
138
+ }
139
+ function wr(e, r, n) {
140
+ return Ve(e, n, Math.max(0, Math.min(e.length, r + 1)));
141
+ }
142
+ function Dr(e) {
143
+ const { tracks: r, currentIndex: n, repeatMode: t, playbackMode: a } = e, u = r.length;
144
+ return u === 0 ? { kind: "stop", nextIndex: 0 } : t === "one" ? { kind: "replay_same" } : a === "single" ? { kind: "stop", nextIndex: E(n, u) } : n < u - 1 ? { kind: "advance", nextIndex: n + 1 } : t === "all" ? { kind: "wrap", nextIndex: 0 } : { kind: "stop", nextIndex: E(n, u) };
145
+ }
146
+ function Lr(e) {
147
+ const { tracks: r, currentIndex: n, repeatMode: t, playbackMode: a } = e, u = r.length;
148
+ return u === 0 ? 0 : a === "single" ? E(n, u) : n < u - 1 ? n + 1 : t === "all" ? 0 : E(n, u);
149
+ }
150
+ function Fr(e) {
151
+ const { tracks: r, currentIndex: n, repeatMode: t, playbackMode: a } = e, u = r.length;
152
+ return u === 0 ? 0 : a === "single" ? E(n, u) : n > 0 ? n - 1 : t === "all" ? u - 1 : 0;
153
+ }
154
+ function Ur(e) {
155
+ return e === "off" ? "all" : e === "all" ? "one" : "off";
156
+ }
157
+ function Vr(e, r) {
158
+ return (e == null ? void 0 : e.artworkUrl) ?? r ?? void 0;
159
+ }
160
+ function $r(e, r) {
161
+ return (e == null ? void 0 : e.album) ?? r ?? void 0;
162
+ }
163
+ function F(e) {
164
+ return e.tracks[e.currentIndex] ?? null;
165
+ }
166
+ function $e(e) {
167
+ return e.errorMessage ? "error" : e.tracks.length === 0 ? "idle" : e.isBuffering ? "loading" : e.isPaused ? Number.isFinite(e.duration) && e.duration > 0 && e.currentTime >= e.duration - 0.05 ? "ended" : "paused" : "playing";
168
+ }
169
+ function X(e) {
170
+ var t;
171
+ const r = e.duration;
172
+ if (Number.isFinite(r) && r > 0) return r;
173
+ const n = (t = e.tracks[e.currentIndex]) == null ? void 0 : t.durationSeconds;
174
+ return typeof n == "number" && Number.isFinite(n) && n > 0 ? n : 0;
175
+ }
176
+ function Br(e) {
177
+ const n = X(e) - e.currentTime;
178
+ return Number.isFinite(n) ? Math.max(0, n) : 0;
179
+ }
180
+ function Be(e) {
181
+ const r = X(e);
182
+ return r > 0 ? Math.min(1, Math.max(0, e.currentTime / r)) : 0;
183
+ }
184
+ function Or(e) {
185
+ var n;
186
+ const r = F(e);
187
+ return Vr(r, (n = e.playlistMeta) == null ? void 0 : n.artworkUrl);
188
+ }
189
+ function Yr(e) {
190
+ var n;
191
+ const r = F(e);
192
+ return $r(r, (n = e.playlistMeta) == null ? void 0 : n.subtitle);
193
+ }
194
+ function $(e, r) {
195
+ function n(t) {
196
+ const a = v(), o = (r(a) ?? "").trim(), { className: l, style: d, fallback: f, empty: g, children: h } = t;
197
+ if (!o) {
198
+ const b = g ?? f ?? null;
199
+ return b ? /* @__PURE__ */ c("span", { className: l, style: d, children: b }) : null;
200
+ }
201
+ return h ? /* @__PURE__ */ c("span", { className: l, style: d, children: h(o, a) }) : /* @__PURE__ */ c("span", { className: l, style: d, children: o });
202
+ }
203
+ return n.displayName = e, n;
204
+ }
205
+ function B(e, r) {
206
+ return $(e, (n) => r(F(n)));
207
+ }
208
+ const Qr = B("Ginger.Current.Title", (e) => e == null ? void 0 : e.title), Hr = B("Ginger.Current.Artist", (e) => e == null ? void 0 : e.artist), jr = $("Ginger.Current.Album", (e) => Yr(e)), Xr = B("Ginger.Current.Description", (e) => e == null ? void 0 : e.description), Kr = $("Ginger.Current.Copyright", (e) => {
209
+ var n;
210
+ const r = F(e);
211
+ return (r == null ? void 0 : r.copyright) ?? ((n = e.playlistMeta) == null ? void 0 : n.copyright);
212
+ }), Wr = B("Ginger.Current.Genre", (e) => e == null ? void 0 : e.genre), zr = B("Ginger.Current.Label", (e) => e == null ? void 0 : e.label), qr = B("Ginger.Current.Isrc", (e) => e == null ? void 0 : e.isrc), Jr = B(
213
+ "Ginger.Current.TrackNumber",
214
+ (e) => (e == null ? void 0 : e.trackNumber) != null ? String(e.trackNumber) : void 0
215
+ );
216
+ function Oe({ className: e, style: r, fallback: n, empty: t, children: a, format: u }) {
217
+ var f;
218
+ const o = v(), l = (f = F(o)) == null ? void 0 : f.year;
219
+ if (typeof l != "number" || !Number.isFinite(l)) {
220
+ const g = t ?? n ?? null;
221
+ return g ? /* @__PURE__ */ c("span", { className: e, style: r, children: g }) : null;
222
+ }
223
+ const d = u ? u(l) : String(l);
224
+ return a ? /* @__PURE__ */ c("span", { className: e, style: r, children: a(d, o) }) : /* @__PURE__ */ c("span", { className: e, style: r, children: d });
225
+ }
226
+ Oe.displayName = "Ginger.Current.Year";
227
+ function Ye({ className: e, style: r, fallback: n, empty: t, children: a, preserveWhitespace: u = !0 }) {
228
+ var g;
229
+ const o = v(), l = ((g = F(o)) == null ? void 0 : g.lyrics) ?? "", d = u ? l.replace(/^\s+|\s+$/g, "") : l.trim();
230
+ if (!d) {
231
+ const h = t ?? n ?? null;
232
+ return h ? /* @__PURE__ */ c("span", { className: e, style: r, children: h }) : null;
233
+ }
234
+ const f = u ? { whiteSpace: "pre-wrap" } : void 0;
235
+ return a ? /* @__PURE__ */ c("span", { className: e, style: { ...f, ...r }, children: a(d, o) }) : /* @__PURE__ */ c("span", { className: e, style: { ...f, ...r }, children: d });
236
+ }
237
+ Ye.displayName = "Ginger.Current.Lyrics";
238
+ function Qe({ visible: e = !1, className: r, style: n, fallback: t, empty: a, children: u }) {
239
+ var d;
240
+ const o = v();
241
+ if (!e) return null;
242
+ const l = ((d = F(o)) == null ? void 0 : d.fileUrl) ?? "";
243
+ if (!l) {
244
+ const f = a ?? t ?? null;
245
+ return f ? /* @__PURE__ */ c("span", { className: r, style: n, children: f }) : null;
246
+ }
247
+ return u ? /* @__PURE__ */ c("span", { className: r, style: n, children: u(l, o) }) : /* @__PURE__ */ c("span", { className: r, style: n, children: l });
248
+ }
249
+ Qe.displayName = "Ginger.Current.FileUrl";
250
+ function He({ className: e, style: r, fallback: n, empty: t, sizes: a, loading: u, onError: o, decoding: l, imgStyle: d }) {
251
+ const f = v(), g = F(f), h = Or(f);
252
+ if (!h) {
253
+ const T = t ?? n ?? null;
254
+ return T ? /* @__PURE__ */ c("span", { className: e, style: r, children: T }) : null;
255
+ }
256
+ const b = [g == null ? void 0 : g.title, g == null ? void 0 : g.artist].filter(Boolean).join(" — ") || "Artwork";
257
+ return /* @__PURE__ */ c(
258
+ "div",
259
+ {
260
+ className: e,
261
+ style: {
262
+ background: "var(--ginger-artwork-bg, transparent)",
263
+ borderRadius: "var(--ginger-artwork-radius, 0)",
264
+ overflow: "hidden",
265
+ ...r
266
+ },
267
+ children: /* @__PURE__ */ c(
268
+ "img",
269
+ {
270
+ src: h,
271
+ alt: b,
272
+ sizes: a,
273
+ loading: u,
274
+ decoding: l,
275
+ onError: o,
276
+ style: {
277
+ display: "block",
278
+ width: "100%",
279
+ height: "100%",
280
+ objectFit: "cover",
281
+ ...d
282
+ }
283
+ }
284
+ )
285
+ }
286
+ );
287
+ }
288
+ He.displayName = "Ginger.Current.Artwork";
289
+ function je({ base: e = 0, className: r, style: n, fallback: t, empty: a, children: u }) {
290
+ const o = v();
291
+ if (o.tracks.length === 0) {
292
+ const f = a ?? t ?? null;
293
+ return f ? /* @__PURE__ */ c("span", { className: r, style: n, children: f }) : null;
294
+ }
295
+ const d = String(o.currentIndex + e);
296
+ return u ? /* @__PURE__ */ c("span", { className: r, style: n, children: u(d, o) }) : /* @__PURE__ */ c("span", { className: r, style: n, children: d });
297
+ }
298
+ je.displayName = "Ginger.Current.QueueIndex";
299
+ function Xe({ className: e, style: r, fallback: n, empty: t, children: a }) {
300
+ const u = v(), o = String(u.tracks.length);
301
+ if (u.tracks.length === 0) {
302
+ const l = t ?? n ?? null;
303
+ return l ? /* @__PURE__ */ c("span", { className: e, style: r, children: l }) : null;
304
+ }
305
+ return a ? /* @__PURE__ */ c("span", { className: e, style: r, children: a(o, u) }) : /* @__PURE__ */ c("span", { className: e, style: r, children: o });
306
+ }
307
+ Xe.displayName = "Ginger.Current.QueueLength";
308
+ function Ke({
309
+ base: e = 0,
310
+ separator: r = " / ",
311
+ className: n,
312
+ style: t,
313
+ fallback: a,
314
+ empty: u,
315
+ children: o
316
+ }) {
317
+ const l = v(), d = l.tracks.length;
318
+ if (d === 0) {
319
+ const b = u ?? a ?? null;
320
+ return b ? /* @__PURE__ */ c("span", { className: n, style: t, children: b }) : null;
321
+ }
322
+ const f = String(l.currentIndex + e), g = String(d), h = `${f}${r}${g}`;
323
+ return o ? /* @__PURE__ */ c("span", { className: n, style: t, children: o({ index: f, length: g, label: h }, l) }) : /* @__PURE__ */ c("span", { className: n, style: t, children: h });
324
+ }
325
+ Ke.displayName = "Ginger.Current.QueuePosition";
326
+ function Me(e) {
327
+ if (!Number.isFinite(e) || e < 0) return "0:00";
328
+ const r = Math.floor(e % 60);
329
+ return `${Math.floor(e / 60)}:${r.toString().padStart(2, "0")}`;
330
+ }
331
+ function Ce(e, r, n) {
332
+ const { className: t, style: a, fallback: u, empty: o, children: l, format: d = Me } = n;
333
+ if (!(e >= 0) || !Number.isFinite(e)) {
334
+ const g = o ?? u ?? null;
335
+ return g ? /* @__PURE__ */ c("span", { className: t, style: a, children: g }) : null;
336
+ }
337
+ const f = d(e);
338
+ return l ? /* @__PURE__ */ c("span", { className: t, style: a, children: l(f, r) }) : /* @__PURE__ */ c("span", { className: t, style: a, children: f });
339
+ }
340
+ function We(e) {
341
+ const r = v();
342
+ return Ce(r.currentTime, r, e);
343
+ }
344
+ We.displayName = "Ginger.Current.Elapsed";
345
+ function ze(e) {
346
+ const r = v();
347
+ return Ce(X(r), r, e);
348
+ }
349
+ ze.displayName = "Ginger.Current.Duration";
350
+ function qe(e) {
351
+ const r = v();
352
+ return Ce(Br(r), r, e);
353
+ }
354
+ qe.displayName = "Ginger.Current.Remaining";
355
+ function Je({ className: e, style: r, fallback: n, empty: t, children: a }) {
356
+ const u = v(), o = X(u), l = Be(u);
357
+ if (!(o > 0)) {
358
+ const d = t ?? n ?? null;
359
+ return d ? /* @__PURE__ */ c("span", { className: e, style: r, children: d }) : null;
360
+ }
361
+ return a ? /* @__PURE__ */ c("span", { className: e, style: r, children: a({ fraction: l, currentTime: u.currentTime, duration: o }, u) }) : /* @__PURE__ */ c("span", { className: e, style: r, children: `${Math.round(l * 100)}%` });
362
+ }
363
+ Je.displayName = "Ginger.Current.Progress";
364
+ function Ze({ className: e, style: r, height: n = 4, showBuffered: t = !1 }) {
365
+ const a = v(), u = `${Math.round(Be(a) * 100)}%`, o = `${Math.round(Math.min(1, Math.max(0, a.bufferedFraction)) * 100)}%`;
366
+ return /* @__PURE__ */ Ae(
367
+ "div",
368
+ {
369
+ className: e,
370
+ style: {
371
+ width: "100%",
372
+ height: n,
373
+ background: "var(--ginger-muted-color, #e5e7eb)",
374
+ borderRadius: 999,
375
+ overflow: "hidden",
376
+ position: "relative",
377
+ ...r
378
+ },
379
+ "aria-hidden": !0,
380
+ children: [
381
+ t ? /* @__PURE__ */ c(
382
+ "div",
383
+ {
384
+ style: {
385
+ position: "absolute",
386
+ left: 0,
387
+ top: 0,
388
+ height: "100%",
389
+ width: o,
390
+ background: "var(--ginger-buffer-color, rgba(107, 114, 128, 0.35))"
391
+ }
392
+ }
393
+ ) : null,
394
+ /* @__PURE__ */ c(
395
+ "div",
396
+ {
397
+ style: {
398
+ position: "relative",
399
+ width: u,
400
+ height: "100%",
401
+ background: "var(--ginger-primary-color, #111827)"
402
+ }
403
+ }
404
+ )
405
+ ]
406
+ }
407
+ );
408
+ }
409
+ Ze.displayName = "Ginger.Current.TimeRail";
410
+ function er({ className: e, style: r, height: n = 4 }) {
411
+ const t = v(), a = `${Math.round(Math.min(1, Math.max(0, t.bufferedFraction)) * 100)}%`;
412
+ return /* @__PURE__ */ c(
413
+ "div",
414
+ {
415
+ className: e,
416
+ style: {
417
+ width: "100%",
418
+ height: n,
419
+ background: "var(--ginger-muted-color, #e5e7eb)",
420
+ borderRadius: 999,
421
+ overflow: "hidden",
422
+ ...r
423
+ },
424
+ "aria-hidden": !0,
425
+ children: /* @__PURE__ */ c(
426
+ "div",
427
+ {
428
+ style: {
429
+ width: a,
430
+ height: "100%",
431
+ background: "var(--ginger-buffer-color, rgba(107, 114, 128, 0.35))"
432
+ }
433
+ }
434
+ )
435
+ }
436
+ );
437
+ }
438
+ er.displayName = "Ginger.Current.BufferRail";
439
+ function rr({ className: e, style: r, fallback: n, empty: t, children: a }) {
440
+ const u = v(), o = $e(u);
441
+ return a ? /* @__PURE__ */ c("span", { className: e, style: r, children: a(o, u) }) : /* @__PURE__ */ c("span", { className: e, style: r, children: o });
442
+ }
443
+ rr.displayName = "Ginger.Current.PlaybackState";
444
+ function nr({ className: e, style: r, fallback: n, empty: t, live: a = "polite", children: u }) {
445
+ const o = v(), l = o.errorMessage ?? "";
446
+ if (!l) {
447
+ const d = t ?? n ?? null;
448
+ return d ? /* @__PURE__ */ c("span", { className: e, style: r, children: d }) : null;
449
+ }
450
+ return u ? /* @__PURE__ */ c("span", { className: e, style: r, "aria-live": a, children: u(l, o) }) : /* @__PURE__ */ c("span", { className: e, style: r, "aria-live": a, children: l });
451
+ }
452
+ nr.displayName = "Ginger.Current.ErrorMessage";
453
+ const xe = {
454
+ seek: "Seek",
455
+ volume: "Volume",
456
+ playbackSpeed: "Playback speed",
457
+ nextTrack: "Next track",
458
+ previousTrack: "Previous track",
459
+ shuffle: "Shuffle",
460
+ mute: "Mute",
461
+ unmute: "Unmute",
462
+ play: "Play",
463
+ pause: "Pause",
464
+ repeat: {
465
+ off: "Repeat off",
466
+ all: "Repeat all",
467
+ one: "Repeat one"
468
+ },
469
+ playbackRateNormal: "1× normal",
470
+ playbackRateTimes: (e) => `${e}×`
471
+ };
472
+ function Zr(e) {
473
+ return e ? {
474
+ ...xe,
475
+ ...e,
476
+ repeat: { ...xe.repeat, ...e.repeat }
477
+ } : xe;
478
+ }
479
+ const tr = Re(xe);
480
+ function en({
481
+ locale: e,
482
+ children: r
483
+ }) {
484
+ const n = Zr(e);
485
+ return /* @__PURE__ */ c(tr.Provider, { value: n, children: r });
486
+ }
487
+ function R() {
488
+ return Se(tr);
489
+ }
490
+ function rn() {
491
+ const e = _(), r = ve(), n = R(), t = L(() => Le(e, r), [e, r]), a = X(t), u = a > 0 ? t.currentTime : 0, o = Number.isFinite(u) ? u : 0, l = a > 0 ? `${Me(o)} of ${Me(a)}` : Me(o), d = (f) => {
492
+ r.seek(Number(f.currentTarget.value));
493
+ };
494
+ return {
495
+ state: t,
496
+ value: o,
497
+ min: 0,
498
+ max: a > 0 ? a : 1,
499
+ step: "any",
500
+ ariaValueText: l,
501
+ ariaLabel: n.seek,
502
+ onSeekInput: d,
503
+ onSeekChange: d
504
+ };
505
+ }
506
+ function nn() {
507
+ const e = _(), r = ve(), n = R(), t = L(() => Le(e, r), [e, r]), a = (u) => {
508
+ r.setVolume(Number(u.currentTarget.value));
509
+ };
510
+ return {
511
+ state: t,
512
+ value: t.volume,
513
+ min: 0,
514
+ max: 1,
515
+ step: "any",
516
+ ariaValueText: `${Math.round(t.volume * 100)}%`,
517
+ ariaLabel: n.volume,
518
+ onVolumeInput: a,
519
+ onVolumeChange: a
520
+ };
521
+ }
522
+ function tn(e) {
523
+ const r = _(), n = R(), t = (e == null ? void 0 : e.playAriaLabel) ?? n.play, a = (e == null ? void 0 : e.pauseAriaLabel) ?? n.pause;
524
+ return {
525
+ isPaused: r.isPaused,
526
+ toggle: r.togglePlayPause,
527
+ ariaLabel: r.isPaused ? t : a
528
+ };
529
+ }
530
+ function ar({
531
+ playLabel: e = "Play",
532
+ pauseLabel: r = "Pause",
533
+ playAriaLabel: n,
534
+ pauseAriaLabel: t,
535
+ type: a = "button",
536
+ ...u
537
+ }) {
538
+ const o = R(), l = typeof e == "string" ? e : o.play, d = typeof r == "string" ? r : o.pause, f = tn({
539
+ playAriaLabel: n ?? l,
540
+ pauseAriaLabel: t ?? d
541
+ });
542
+ return /* @__PURE__ */ c("button", { type: a, "aria-label": f.ariaLabel, onClick: f.toggle, ...u, children: f.isPaused ? e : r });
543
+ }
544
+ ar.displayName = "Ginger.Control.PlayPause";
545
+ function ur({ type: e = "button", ...r }) {
546
+ const { repeatMode: n, cycleRepeat: t } = _(), u = R().repeat[n];
547
+ return /* @__PURE__ */ c("button", { type: e, "aria-label": u, onClick: t, ...r, children: u });
548
+ }
549
+ ur.displayName = "Ginger.Control.Repeat";
550
+ function ir({ type: e = "button", children: r = "Next", ...n }) {
551
+ const { next: t } = _(), a = R();
552
+ return /* @__PURE__ */ c("button", { type: e, "aria-label": a.nextTrack, onClick: t, ...n, children: r });
553
+ }
554
+ ir.displayName = "Ginger.Control.Next";
555
+ function or({ type: e = "button", children: r = "Previous", ...n }) {
556
+ const { prev: t } = _(), a = R();
557
+ return /* @__PURE__ */ c("button", { type: e, "aria-label": a.previousTrack, onClick: t, ...n, children: r });
558
+ }
559
+ or.displayName = "Ginger.Control.Previous";
560
+ function lr({ type: e = "button", children: r = "Shuffle", ...n }) {
561
+ const { isShuffled: t, toggleShuffle: a } = _(), u = R();
562
+ return /* @__PURE__ */ c(
563
+ "button",
564
+ {
565
+ type: e,
566
+ "aria-pressed": t,
567
+ "aria-label": u.shuffle,
568
+ onClick: a,
569
+ ...n,
570
+ children: r
571
+ }
572
+ );
573
+ }
574
+ lr.displayName = "Ginger.Control.Shuffle";
575
+ function cr({ inputStyle: e, style: r, ...n }) {
576
+ const t = rn();
577
+ return /* @__PURE__ */ c(
578
+ "input",
579
+ {
580
+ ...n,
581
+ type: "range",
582
+ min: t.min,
583
+ max: t.max,
584
+ step: t.step,
585
+ value: t.value,
586
+ "aria-label": t.ariaLabel,
587
+ "aria-valuetext": t.ariaValueText,
588
+ onInput: t.onSeekInput,
589
+ onChange: t.onSeekChange,
590
+ style: { width: "100%", ...r, ...e }
591
+ }
592
+ );
593
+ }
594
+ cr.displayName = "Ginger.Control.SeekBar";
595
+ function sr({ inputStyle: e, style: r, ...n }) {
596
+ const t = nn();
597
+ return /* @__PURE__ */ c(
598
+ "input",
599
+ {
600
+ ...n,
601
+ type: "range",
602
+ min: t.min,
603
+ max: t.max,
604
+ step: t.step,
605
+ value: t.value,
606
+ "aria-label": t.ariaLabel,
607
+ "aria-valuetext": t.ariaValueText,
608
+ onInput: t.onVolumeInput,
609
+ onChange: t.onVolumeChange,
610
+ style: { width: "100%", ...r, ...e }
611
+ }
612
+ );
613
+ }
614
+ sr.displayName = "Ginger.Control.Volume";
615
+ function dr({
616
+ muteLabel: e,
617
+ unmuteLabel: r,
618
+ type: n = "button",
619
+ ...t
620
+ }) {
621
+ const { muted: a, toggleMute: u } = ve(), o = R(), l = e ?? o.mute, d = r ?? o.unmute;
622
+ return /* @__PURE__ */ c(
623
+ "button",
624
+ {
625
+ type: n,
626
+ "aria-pressed": a,
627
+ "aria-label": a ? o.unmute : o.mute,
628
+ onClick: u,
629
+ ...t,
630
+ children: a ? d : l
631
+ }
632
+ );
633
+ }
634
+ dr.displayName = "Ginger.Control.Mute";
635
+ const an = [0.5, 0.75, 1, 1.25, 1.5, 2];
636
+ function fr({ rates: e = an, style: r, ...n }) {
637
+ const { playbackRate: t, setPlaybackRate: a } = ve(), u = R(), o = L(
638
+ () => Array.from(/* @__PURE__ */ new Set([...e, t])).sort((l, d) => l - d),
639
+ [e, t]
640
+ );
641
+ return /* @__PURE__ */ c(
642
+ "select",
643
+ {
644
+ ...n,
645
+ "aria-label": u.playbackSpeed,
646
+ value: String(t),
647
+ style: r,
648
+ onChange: (l) => a(Number(l.currentTarget.value)),
649
+ children: o.map((l) => /* @__PURE__ */ c("option", { value: String(l), children: l === 1 ? u.playbackRateNormal : u.playbackRateTimes(l) }, l))
650
+ }
651
+ );
652
+ }
653
+ fr.displayName = "Ginger.Control.PlaybackRate";
654
+ const Pe = Re(null);
655
+ function un() {
656
+ const e = Se(Pe);
657
+ if (!e)
658
+ throw new Error("Ginger.Playlist.Track must be used inside <Ginger.Playlist>");
659
+ return e;
660
+ }
661
+ function pr({
662
+ children: e,
663
+ rowStyle: r,
664
+ renderTrack: n,
665
+ playOnSelect: t = !0,
666
+ style: a,
667
+ ...u
668
+ }) {
669
+ const { tracks: o, currentIndex: l, playTrackAt: d, selectTrackAt: f } = _(), g = {
670
+ listStyle: "none",
671
+ margin: 0,
672
+ padding: 0,
673
+ fontFamily: "var(--ginger-font-family, system-ui, sans-serif)",
674
+ fontSize: "var(--ginger-font-size, 14px)",
675
+ color: "var(--ginger-primary-color, #111827)",
676
+ ...a
677
+ };
678
+ return e !== void 0 ? /* @__PURE__ */ c(Pe.Provider, { value: { playOnSelect: t }, children: /* @__PURE__ */ c("ul", { style: g, ...u, children: e }) }) : /* @__PURE__ */ c(Pe.Provider, { value: { playOnSelect: t }, children: /* @__PURE__ */ c("ul", { style: g, ...u, children: o.map((b, T) => {
679
+ const P = T === l;
680
+ return /* @__PURE__ */ c("li", { children: /* @__PURE__ */ c(
681
+ "button",
682
+ {
683
+ type: "button",
684
+ onClick: () => {
685
+ t ? d(T) : f(T);
686
+ },
687
+ style: {
688
+ width: "100%",
689
+ textAlign: "left",
690
+ border: "none",
691
+ background: P ? "var(--ginger-playlist-active-bg, rgba(17, 24, 39, 0.06))" : "transparent",
692
+ color: "inherit",
693
+ font: "inherit",
694
+ cursor: "pointer",
695
+ padding: "var(--ginger-playlist-row-padding, 6px 8px)",
696
+ ...r
697
+ },
698
+ children: n ? n(b, T, P) : /* @__PURE__ */ Ae("span", { children: [
699
+ b.title,
700
+ b.artist ? ` — ${b.artist}` : ""
701
+ ] })
702
+ }
703
+ ) }, `${T}-${j(b)}`);
704
+ }) }) });
705
+ }
706
+ pr.displayName = "Ginger.Playlist";
707
+ function gr({
708
+ index: e,
709
+ className: r,
710
+ style: n,
711
+ children: t,
712
+ liProps: a,
713
+ onClick: u,
714
+ ...o
715
+ }) {
716
+ const { playOnSelect: l } = un(), { tracks: d, currentIndex: f, playTrackAt: g, selectTrackAt: h } = _(), b = e === f, T = d[e], P = T != null ? /* @__PURE__ */ Ae("span", { children: [
717
+ T.title,
718
+ T.artist ? ` — ${T.artist}` : ""
719
+ ] }) : null;
720
+ return /* @__PURE__ */ c("li", { ...a, children: /* @__PURE__ */ c(
721
+ "button",
722
+ {
723
+ type: "button",
724
+ "aria-current": b ? "true" : void 0,
725
+ "data-ginger-active": b || void 0,
726
+ className: r,
727
+ style: {
728
+ width: "100%",
729
+ textAlign: "left",
730
+ border: "none",
731
+ background: b ? "var(--ginger-playlist-active-bg, rgba(17, 24, 39, 0.06))" : "transparent",
732
+ color: "inherit",
733
+ font: "inherit",
734
+ cursor: "pointer",
735
+ padding: "var(--ginger-playlist-row-padding, 6px 8px)",
736
+ ...n
737
+ },
738
+ ...o,
739
+ onClick: (p) => {
740
+ u == null || u(p), !p.defaultPrevented && (l ? g(e) : h(e));
741
+ },
742
+ children: t ?? P
743
+ }
744
+ ) });
745
+ }
746
+ gr.displayName = "Ginger.Playlist.Track";
747
+ const on = Object.assign(pr, {
748
+ Track: gr
749
+ }), ln = $("Ginger.Queue.Title", (e) => {
750
+ var r;
751
+ return (r = e.playlistMeta) == null ? void 0 : r.title;
752
+ }), cn = $("Ginger.Queue.Subtitle", (e) => {
753
+ var r;
754
+ return (r = e.playlistMeta) == null ? void 0 : r.subtitle;
755
+ }), sn = $("Ginger.Queue.Description", (e) => {
756
+ var r;
757
+ return (r = e.playlistMeta) == null ? void 0 : r.description;
758
+ }), dn = $("Ginger.Queue.Copyright", (e) => {
759
+ var r;
760
+ return (r = e.playlistMeta) == null ? void 0 : r.copyright;
761
+ });
762
+ function yr({ className: e, style: r, fallback: n, empty: t, imgStyle: a }) {
763
+ var d, f;
764
+ const u = v(), o = (d = u.playlistMeta) == null ? void 0 : d.artworkUrl;
765
+ if (!o) {
766
+ const g = t ?? n ?? null;
767
+ return g ? /* @__PURE__ */ c("span", { className: e, style: r, children: g }) : null;
768
+ }
769
+ const l = ((f = u.playlistMeta) == null ? void 0 : f.title) ?? "Playlist artwork";
770
+ return /* @__PURE__ */ c(
771
+ "span",
772
+ {
773
+ className: e,
774
+ style: {
775
+ display: "inline-block",
776
+ background: "var(--ginger-artwork-bg, #f3f4f6)",
777
+ borderRadius: "var(--ginger-artwork-radius, 6px)",
778
+ overflow: "hidden",
779
+ ...r
780
+ },
781
+ children: /* @__PURE__ */ c(
782
+ "img",
783
+ {
784
+ src: o,
785
+ alt: l,
786
+ style: {
787
+ display: "block",
788
+ width: "100%",
789
+ height: "100%",
790
+ objectFit: "cover",
791
+ ...a
792
+ }
793
+ }
794
+ )
795
+ }
796
+ );
797
+ }
798
+ yr.displayName = "Ginger.Queue.Artwork";
799
+ function Te(e) {
800
+ return Number.isFinite(e) ? Math.min(1, Math.max(0, e)) : 1;
801
+ }
802
+ function Ge(e) {
803
+ return Number.isFinite(e) ? Math.min(4, Math.max(0.25, e)) : 1;
804
+ }
805
+ const V = {
806
+ currentTime: 0,
807
+ duration: 0,
808
+ bufferedFraction: 0,
809
+ isBuffering: !1,
810
+ errorMessage: null
811
+ }, fn = {
812
+ ...V,
813
+ volume: 1,
814
+ muted: !1,
815
+ playbackRate: 1
816
+ };
817
+ function mr(e) {
818
+ const r = [...e.tracks];
819
+ let n = E(e.currentIndex ?? 0, r.length), t = null, a = r;
820
+ return e.isShuffled && r.length > 1 && (t = [...r], a = Ue(r, n), n = 0), {
821
+ tracks: a,
822
+ currentIndex: n,
823
+ playbackMode: e.playbackMode ?? "playlist",
824
+ isPaused: e.isPaused ?? !0,
825
+ isShuffled: !!(e.isShuffled && a.length > 1),
826
+ repeatMode: e.repeatMode ?? "off",
827
+ originalTracks: t,
828
+ playlistMeta: e.playlistMeta ?? null,
829
+ ...fn,
830
+ volume: Te(e.volume ?? 1),
831
+ muted: e.muted ?? !1,
832
+ playbackRate: Ge(e.playbackRate ?? 1)
833
+ };
834
+ }
835
+ function pn(e, r) {
836
+ switch (r.type) {
837
+ case "INIT": {
838
+ const {
839
+ tracks: n,
840
+ currentIndex: t,
841
+ playlistMeta: a,
842
+ isPaused: u,
843
+ isShuffled: o,
844
+ repeatMode: l,
845
+ playbackMode: d,
846
+ volume: f,
847
+ muted: g,
848
+ playbackRate: h
849
+ } = r.payload;
850
+ return mr({
851
+ tracks: n,
852
+ currentIndex: t,
853
+ playlistMeta: a ?? null,
854
+ isPaused: u ?? !0,
855
+ isShuffled: o ?? !1,
856
+ repeatMode: l ?? "off",
857
+ playbackMode: d ?? "playlist",
858
+ volume: f,
859
+ muted: g,
860
+ playbackRate: h
861
+ });
862
+ }
863
+ case "SET_QUEUE": {
864
+ const { tracks: n, currentIndex: t } = r.payload, a = [...n], u = E(t ?? e.currentIndex, a.length);
865
+ return {
866
+ ...e,
867
+ tracks: a,
868
+ currentIndex: u,
869
+ isShuffled: !1,
870
+ originalTracks: null,
871
+ ...V
872
+ };
873
+ }
874
+ case "INSERT_TRACK": {
875
+ const n = r.payload.index ?? e.tracks.length, t = Ve(e.tracks, r.payload.track, n);
876
+ if (r.payload.autoPlay) {
877
+ const u = E(n, t.length);
878
+ return {
879
+ ...e,
880
+ tracks: t,
881
+ currentIndex: u,
882
+ isShuffled: !1,
883
+ originalTracks: null,
884
+ isPaused: !1,
885
+ ...V
886
+ };
887
+ }
888
+ const a = n <= e.currentIndex ? e.currentIndex + 1 : e.currentIndex;
889
+ return {
890
+ ...e,
891
+ tracks: t,
892
+ isShuffled: !1,
893
+ originalTracks: null,
894
+ currentIndex: E(a, t.length)
895
+ };
896
+ }
897
+ case "REMOVE_TRACK": {
898
+ const n = r.payload.index, t = _r(e.tracks, n), a = n < e.currentIndex ? e.currentIndex - 1 : n === e.currentIndex ? Math.min(e.currentIndex, Math.max(0, t.length - 1)) : e.currentIndex;
899
+ return {
900
+ ...e,
901
+ tracks: t,
902
+ isShuffled: !1,
903
+ originalTracks: null,
904
+ currentIndex: E(a, t.length),
905
+ ...n === e.currentIndex ? V : {}
906
+ };
907
+ }
908
+ case "MOVE_TRACK": {
909
+ const { fromIndex: n, toIndex: t } = r.payload, a = Nr(e.tracks, n, t);
910
+ let u = e.currentIndex;
911
+ return e.currentIndex === n ? u = t : n < e.currentIndex && t >= e.currentIndex ? u -= 1 : n > e.currentIndex && t <= e.currentIndex && (u += 1), {
912
+ ...e,
913
+ tracks: a,
914
+ isShuffled: !1,
915
+ originalTracks: null,
916
+ currentIndex: E(u, a.length)
917
+ };
918
+ }
919
+ case "ADD_NEXT": {
920
+ const n = wr(e.tracks, e.currentIndex, r.payload.track);
921
+ return {
922
+ ...e,
923
+ tracks: n,
924
+ isShuffled: !1,
925
+ originalTracks: null
926
+ };
927
+ }
928
+ case "SET_INDEX": {
929
+ const n = E(r.payload.index, e.tracks.length), t = r.payload.autoPlay, a = t === !0 ? !1 : t === !1 ? !0 : e.isPaused;
930
+ return {
931
+ ...e,
932
+ currentIndex: n,
933
+ ...V,
934
+ isPaused: a
935
+ };
936
+ }
937
+ case "PLAY":
938
+ return { ...e, isPaused: !1 };
939
+ case "PAUSE":
940
+ return { ...e, isPaused: !0 };
941
+ case "TOGGLE_PAUSE":
942
+ return { ...e, isPaused: !e.isPaused };
943
+ case "SET_REPEAT":
944
+ return { ...e, repeatMode: r.payload };
945
+ case "CYCLE_REPEAT":
946
+ return { ...e, repeatMode: Ur(e.repeatMode) };
947
+ case "TOGGLE_SHUFFLE": {
948
+ if (e.tracks.length <= 1) return { ...e, isShuffled: !1, originalTracks: null };
949
+ if (!e.isShuffled) {
950
+ const u = [...e.tracks], o = Ue(u, e.currentIndex);
951
+ return {
952
+ ...e,
953
+ isShuffled: !0,
954
+ originalTracks: u,
955
+ tracks: o,
956
+ currentIndex: 0
957
+ };
958
+ }
959
+ const n = e.originalTracks ? [...e.originalTracks] : [...e.tracks], t = e.tracks[e.currentIndex], a = Gr(n, t);
960
+ return {
961
+ ...e,
962
+ isShuffled: !1,
963
+ originalTracks: null,
964
+ tracks: n,
965
+ currentIndex: E(a, n.length)
966
+ };
967
+ }
968
+ case "NEXT": {
969
+ const n = Lr(e), t = n === e.currentIndex;
970
+ return {
971
+ ...e,
972
+ currentIndex: n,
973
+ ...t ? {} : V,
974
+ isPaused: t ? e.isPaused : !1
975
+ };
976
+ }
977
+ case "PREV": {
978
+ const n = Fr(e), t = n === e.currentIndex;
979
+ return {
980
+ ...e,
981
+ currentIndex: n,
982
+ ...t ? {} : V,
983
+ isPaused: t ? e.isPaused : !1
984
+ };
985
+ }
986
+ case "MEDIA_TIME_UPDATE":
987
+ return {
988
+ ...e,
989
+ currentTime: r.payload.currentTime,
990
+ duration: Number.isFinite(r.payload.duration) ? r.payload.duration : e.duration,
991
+ bufferedFraction: r.payload.bufferedFraction,
992
+ isBuffering: !1
993
+ };
994
+ case "MEDIA_LOADED_METADATA":
995
+ return {
996
+ ...e,
997
+ duration: Number.isFinite(r.payload.duration) ? r.payload.duration : e.duration,
998
+ bufferedFraction: r.payload.bufferedFraction,
999
+ errorMessage: null
1000
+ };
1001
+ case "SET_PLAYLIST_META":
1002
+ return { ...e, playlistMeta: r.payload };
1003
+ case "MEDIA_ERROR":
1004
+ return {
1005
+ ...e,
1006
+ errorMessage: r.payload.message,
1007
+ isPaused: !0,
1008
+ isBuffering: !1
1009
+ };
1010
+ case "MEDIA_WAITING":
1011
+ return { ...e, isBuffering: !0 };
1012
+ case "MEDIA_CANPLAY":
1013
+ return { ...e, isBuffering: !1, errorMessage: null };
1014
+ case "MEDIA_PLAY":
1015
+ return { ...e, isPaused: !1, isBuffering: !1 };
1016
+ case "MEDIA_PAUSE":
1017
+ return { ...e, isPaused: !0 };
1018
+ case "RESET_MEDIA_TIMES":
1019
+ return { ...e, currentTime: 0, duration: 0, bufferedFraction: 0 };
1020
+ case "SET_VOLUME":
1021
+ return { ...e, volume: Te(r.payload) };
1022
+ case "SET_MUTED":
1023
+ return { ...e, muted: r.payload };
1024
+ case "TOGGLE_MUTE":
1025
+ return { ...e, muted: !e.muted };
1026
+ case "SET_PLAYBACK_RATE":
1027
+ return { ...e, playbackRate: Ge(r.payload) };
1028
+ case "MEDIA_VOLUME_SYNC": {
1029
+ const { volume: n, muted: t } = r.payload, a = Te(n);
1030
+ return a === e.volume && t === e.muted ? e : { ...e, volume: a, muted: t };
1031
+ }
1032
+ default:
1033
+ return e;
1034
+ }
1035
+ }
1036
+ function gn(e) {
1037
+ const r = e.tracks[e.currentIndex];
1038
+ return r ? {
1039
+ title: r.title,
1040
+ artist: r.artist,
1041
+ album: r.album,
1042
+ artwork: r.artworkUrl ? [{ src: r.artworkUrl }] : void 0
1043
+ } : { title: "Unknown track" };
1044
+ }
1045
+ function yn(e, r, n) {
1046
+ I(() => {
1047
+ if (!e || typeof navigator > "u" || !("mediaSession" in navigator)) return;
1048
+ const t = navigator.mediaSession;
1049
+ t.metadata = new MediaMetadata(gn(r)), t.playbackState = r.isPaused ? "paused" : "playing";
1050
+ try {
1051
+ t.setActionHandler("play", n.play), t.setActionHandler("pause", n.pause), t.setActionHandler("nexttrack", n.next), t.setActionHandler("previoustrack", n.prev), t.setActionHandler("seekto", (a) => {
1052
+ typeof a.seekTime == "number" && Number.isFinite(a.seekTime) && n.seek(a.seekTime);
1053
+ });
1054
+ } catch {
1055
+ }
1056
+ return () => {
1057
+ try {
1058
+ t.setActionHandler("play", null), t.setActionHandler("pause", null), t.setActionHandler("nexttrack", null), t.setActionHandler("previoustrack", null), t.setActionHandler("seekto", null);
1059
+ } catch {
1060
+ }
1061
+ };
1062
+ }, [e, r, n]);
1063
+ }
1064
+ const mn = {
1065
+ "--ginger-primary-color": "#111827",
1066
+ "--ginger-muted-color": "#6b7280",
1067
+ "--ginger-font-size": "14px",
1068
+ "--ginger-font-family": "system-ui, sans-serif",
1069
+ "--ginger-playlist-row-padding": "6px 8px",
1070
+ "--ginger-artwork-radius": "6px",
1071
+ "--ginger-artwork-bg": "#f3f4f6",
1072
+ "--ginger-playlist-active-bg": "rgba(17, 24, 39, 0.06)",
1073
+ "--ginger-buffer-color": "rgba(107, 114, 128, 0.35)",
1074
+ "--ginger-focus-ring": "0 0 0 2px rgba(59, 130, 246, 0.45)"
1075
+ };
1076
+ function bn({
1077
+ children: e,
1078
+ initialTracks: r = [],
1079
+ initialIndex: n = 0,
1080
+ initialPlaylistMeta: t = null,
1081
+ initialShuffle: a = !1,
1082
+ initialRepeatMode: u = "off",
1083
+ initialPlaybackMode: o = "playlist",
1084
+ initialPaused: l = !0,
1085
+ initialVolume: d = 1,
1086
+ initialMuted: f = !1,
1087
+ initialPlaybackRate: g = 1,
1088
+ initialStateKey: h,
1089
+ locale: b,
1090
+ mediaSession: T = !1,
1091
+ beforePlay: P,
1092
+ onPlayBlocked: p,
1093
+ persistence: y,
1094
+ hydrateOnMount: C = !1,
1095
+ resumeOnTrackChange: A = !1,
1096
+ className: Ie,
1097
+ style: K,
1098
+ onTrackChange: W,
1099
+ onPlay: z,
1100
+ onPause: q,
1101
+ onQueueEnd: J,
1102
+ onError: Z
1103
+ }) {
1104
+ var we;
1105
+ const U = Q(null), [i, m] = Pr(
1106
+ pn,
1107
+ void 0,
1108
+ () => mr({
1109
+ tracks: r,
1110
+ currentIndex: n,
1111
+ playlistMeta: t,
1112
+ isPaused: l,
1113
+ isShuffled: a,
1114
+ repeatMode: u,
1115
+ playbackMode: o,
1116
+ volume: d,
1117
+ muted: f,
1118
+ playbackRate: g
1119
+ })
1120
+ ), _e = Q(i), Ee = Q({
1121
+ tracks: r,
1122
+ currentIndex: n,
1123
+ playlistMeta: t,
1124
+ isPaused: l,
1125
+ isShuffled: a,
1126
+ repeatMode: u,
1127
+ playbackMode: o,
1128
+ volume: d,
1129
+ muted: f,
1130
+ playbackRate: g
1131
+ });
1132
+ Ee.current = {
1133
+ tracks: r,
1134
+ currentIndex: n,
1135
+ playlistMeta: t,
1136
+ isPaused: l,
1137
+ isShuffled: a,
1138
+ repeatMode: u,
1139
+ playbackMode: o,
1140
+ volume: d,
1141
+ muted: f,
1142
+ playbackRate: g
1143
+ };
1144
+ const H = Q(void 0);
1145
+ I(() => {
1146
+ if (h === void 0) {
1147
+ H.current = void 0;
1148
+ return;
1149
+ }
1150
+ if (H.current === void 0) {
1151
+ H.current = h;
1152
+ return;
1153
+ }
1154
+ if (H.current === h) return;
1155
+ H.current = h;
1156
+ const s = Ee.current;
1157
+ m({
1158
+ type: "INIT",
1159
+ payload: {
1160
+ tracks: s.tracks,
1161
+ currentIndex: s.currentIndex,
1162
+ playlistMeta: s.playlistMeta,
1163
+ isPaused: s.isPaused,
1164
+ isShuffled: s.isShuffled,
1165
+ repeatMode: s.repeatMode,
1166
+ playbackMode: s.playbackMode,
1167
+ volume: s.volume,
1168
+ muted: s.muted,
1169
+ playbackRate: s.playbackRate
1170
+ }
1171
+ });
1172
+ }, [h]), I(() => {
1173
+ _e.current = i;
1174
+ }, [i]);
1175
+ const Ne = i.tracks[i.currentIndex] ?? null;
1176
+ I(() => {
1177
+ W == null || W(Ne, i.currentIndex);
1178
+ }, [Ne, i.currentIndex, W]), I(() => {
1179
+ i.errorMessage && (Z == null || Z(i.errorMessage));
1180
+ }, [i.errorMessage, Z]);
1181
+ const ee = Q(void 0);
1182
+ I(() => {
1183
+ if (ee.current === void 0) {
1184
+ ee.current = i.isPaused;
1185
+ return;
1186
+ }
1187
+ ee.current !== i.isPaused && (i.isPaused ? q == null || q() : z == null || z()), ee.current = i.isPaused;
1188
+ }, [i.isPaused, q, z]);
1189
+ const N = k(() => {
1190
+ m({ type: "PLAY" });
1191
+ }, []), w = k(() => {
1192
+ var s;
1193
+ m({ type: "PAUSE" }), (s = U.current) == null || s.pause();
1194
+ }, []), re = k(() => {
1195
+ i.isPaused ? N() : w();
1196
+ }, [w, N, i.isPaused]), D = k((s) => {
1197
+ const M = U.current;
1198
+ M && Number.isFinite(s) && (M.currentTime = Math.max(0, s));
1199
+ }, []), ne = k((s) => {
1200
+ m({ type: "SET_VOLUME", payload: Te(s) });
1201
+ }, []), te = k((s) => {
1202
+ m({ type: "SET_MUTED", payload: s });
1203
+ }, []), ae = k(() => {
1204
+ m({ type: "TOGGLE_MUTE" });
1205
+ }, []), ue = k((s) => {
1206
+ m({ type: "SET_PLAYBACK_RATE", payload: Ge(s) });
1207
+ }, []), O = k(() => {
1208
+ m({ type: "NEXT" });
1209
+ }, []), Y = k(() => {
1210
+ m({ type: "PREV" });
1211
+ }, []), ie = k((s) => {
1212
+ m({ type: "SET_REPEAT", payload: s });
1213
+ }, []), oe = k(() => {
1214
+ m({ type: "CYCLE_REPEAT" });
1215
+ }, []), le = k(() => {
1216
+ m({ type: "TOGGLE_SHUFFLE" });
1217
+ }, []), ce = k((s, M) => {
1218
+ m({ type: "SET_QUEUE", payload: { tracks: s, currentIndex: M } });
1219
+ }, []), se = k((s, M, x) => {
1220
+ m({ type: "INSERT_TRACK", payload: { track: s, index: M, autoPlay: x } });
1221
+ }, []), de = k((s) => {
1222
+ m({ type: "REMOVE_TRACK", payload: { index: s } });
1223
+ }, []), fe = k((s, M) => {
1224
+ m({ type: "MOVE_TRACK", payload: { fromIndex: s, toIndex: M } });
1225
+ }, []), pe = k((s) => {
1226
+ m({ type: "ADD_NEXT", payload: { track: s } });
1227
+ }, []), ge = k((s) => {
1228
+ m({ type: "SET_INDEX", payload: { index: s, autoPlay: !0 } });
1229
+ }, []), ye = k((s) => {
1230
+ m({ type: "SET_INDEX", payload: { index: s, autoPlay: !1 } });
1231
+ }, []), me = k((s) => {
1232
+ m({ type: "SET_PLAYLIST_META", payload: s });
1233
+ }, []), be = k((s) => {
1234
+ m({ type: "INIT", payload: s });
1235
+ }, []);
1236
+ I(() => {
1237
+ if (!y || !C) return;
1238
+ const s = y.get("ginger:volume"), M = y.get("ginger:muted"), x = y.get("ginger:playbackRate"), G = y.get("ginger:repeatMode"), ke = y.get("ginger:currentIndex"), S = Ee.current;
1239
+ m({
1240
+ type: "INIT",
1241
+ payload: {
1242
+ tracks: S.tracks,
1243
+ playlistMeta: S.playlistMeta,
1244
+ isPaused: S.isPaused,
1245
+ isShuffled: S.isShuffled,
1246
+ playbackMode: S.playbackMode,
1247
+ currentIndex: typeof ke == "number" ? ke : S.currentIndex,
1248
+ repeatMode: G === "off" || G === "all" || G === "one" ? G : S.repeatMode,
1249
+ volume: typeof s == "number" ? s : S.volume,
1250
+ muted: typeof M == "boolean" ? M : S.muted,
1251
+ playbackRate: typeof x == "number" ? x : S.playbackRate
1252
+ }
1253
+ });
1254
+ }, [C, y]), I(() => {
1255
+ y && (y.set("ginger:volume", i.volume), y.set("ginger:muted", i.muted), y.set("ginger:playbackRate", i.playbackRate), y.set("ginger:repeatMode", i.repeatMode), y.set("ginger:currentIndex", i.currentIndex));
1256
+ }, [y, i.volume, i.muted, i.playbackRate, i.repeatMode, i.currentIndex]), I(() => {
1257
+ if (!y || !A) return;
1258
+ const s = i.tracks[i.currentIndex];
1259
+ if (!s) return;
1260
+ const M = `ginger:resume:${j(s)}`, x = y.get(M);
1261
+ typeof x == "number" && Number.isFinite(x) && D(x);
1262
+ }, [y, A, i.currentIndex, i.tracks, D]), I(() => {
1263
+ if (!y || !A) return;
1264
+ const s = i.tracks[i.currentIndex];
1265
+ if (!s || !(i.currentTime >= 0)) return;
1266
+ const M = `ginger:resume:${j(s)}`, x = setTimeout(() => y.set(M, i.currentTime), 250);
1267
+ return () => clearTimeout(x);
1268
+ }, [y, A, i.currentIndex, i.tracks, i.currentTime]);
1269
+ const br = (we = i.tracks[i.currentIndex]) == null ? void 0 : we.fileUrl;
1270
+ I(() => {
1271
+ const s = U.current;
1272
+ if (!s) return;
1273
+ if (i.isPaused) {
1274
+ s.pause();
1275
+ return;
1276
+ }
1277
+ let M = !1;
1278
+ return (async () => {
1279
+ if (P) {
1280
+ let x = !1;
1281
+ try {
1282
+ x = await P();
1283
+ } catch (G) {
1284
+ const ke = G instanceof Error ? G.message : "beforePlay rejected";
1285
+ m({ type: "MEDIA_ERROR", payload: { message: ke } });
1286
+ return;
1287
+ }
1288
+ if (!x) {
1289
+ M || (m({ type: "PAUSE" }), p == null || p());
1290
+ return;
1291
+ }
1292
+ }
1293
+ M || s.play().catch((x) => {
1294
+ const G = x instanceof Error ? x.message : typeof x == "string" ? x : "Playback failed (e.g. autoplay blocked or unavailable source)";
1295
+ m({ type: "MEDIA_ERROR", payload: { message: G } });
1296
+ });
1297
+ })(), () => {
1298
+ M = !0;
1299
+ };
1300
+ }, [P, br, p, i.isPaused]);
1301
+ const he = k(() => {
1302
+ const s = Dr(_e.current);
1303
+ if (s.kind === "replay_same") {
1304
+ const x = U.current;
1305
+ x && (x.currentTime = 0), m({ type: "PLAY" });
1306
+ return;
1307
+ }
1308
+ if (s.kind === "stop") {
1309
+ m({ type: "PAUSE" }), J == null || J();
1310
+ return;
1311
+ }
1312
+ const M = s.nextIndex;
1313
+ m({ type: "SET_INDEX", payload: { index: M, autoPlay: !0 } });
1314
+ }, [J]), hr = L(
1315
+ () => ({ play: N, pause: w, next: O, prev: Y, seek: D }),
1316
+ [N, w, O, Y, D]
1317
+ );
1318
+ yn(!!T, i, hr);
1319
+ const kr = b != null && b.seek && /[\u0590-\u08FF]/.test(b.seek) ? "rtl" : "ltr", Mr = L(
1320
+ () => ({
1321
+ state: i,
1322
+ dispatch: m,
1323
+ audioRef: U,
1324
+ notifyEnded: he,
1325
+ init: be,
1326
+ play: N,
1327
+ pause: w,
1328
+ togglePlayPause: re,
1329
+ seek: D,
1330
+ setVolume: ne,
1331
+ setMuted: te,
1332
+ toggleMute: ae,
1333
+ setPlaybackRate: ue,
1334
+ next: O,
1335
+ prev: Y,
1336
+ setRepeatMode: ie,
1337
+ cycleRepeat: oe,
1338
+ toggleShuffle: le,
1339
+ setQueue: ce,
1340
+ insertTrackAt: se,
1341
+ removeTrackAt: de,
1342
+ moveTrack: fe,
1343
+ enqueueNext: pe,
1344
+ playTrackAt: ge,
1345
+ selectTrackAt: ye,
1346
+ setPlaylistMeta: me
1347
+ }),
1348
+ [
1349
+ oe,
1350
+ m,
1351
+ be,
1352
+ O,
1353
+ he,
1354
+ w,
1355
+ N,
1356
+ ge,
1357
+ se,
1358
+ de,
1359
+ fe,
1360
+ pe,
1361
+ ye,
1362
+ Y,
1363
+ D,
1364
+ te,
1365
+ ue,
1366
+ ce,
1367
+ ie,
1368
+ me,
1369
+ ne,
1370
+ i,
1371
+ ae,
1372
+ re,
1373
+ le
1374
+ ]
1375
+ ), xr = L(
1376
+ () => ({
1377
+ tracks: i.tracks,
1378
+ currentIndex: i.currentIndex,
1379
+ isPaused: i.isPaused,
1380
+ isShuffled: i.isShuffled,
1381
+ repeatMode: i.repeatMode,
1382
+ originalTracks: i.originalTracks,
1383
+ playlistMeta: i.playlistMeta,
1384
+ init: be,
1385
+ play: N,
1386
+ pause: w,
1387
+ togglePlayPause: re,
1388
+ next: O,
1389
+ prev: Y,
1390
+ setRepeatMode: ie,
1391
+ cycleRepeat: oe,
1392
+ toggleShuffle: le,
1393
+ playbackMode: i.playbackMode,
1394
+ setQueue: ce,
1395
+ insertTrackAt: se,
1396
+ removeTrackAt: de,
1397
+ moveTrack: fe,
1398
+ enqueueNext: pe,
1399
+ playTrackAt: ge,
1400
+ selectTrackAt: ye,
1401
+ setPlaylistMeta: me,
1402
+ dispatch: m
1403
+ }),
1404
+ [
1405
+ i.tracks,
1406
+ i.currentIndex,
1407
+ i.isPaused,
1408
+ i.isShuffled,
1409
+ i.repeatMode,
1410
+ i.playbackMode,
1411
+ i.originalTracks,
1412
+ i.playlistMeta,
1413
+ be,
1414
+ N,
1415
+ w,
1416
+ re,
1417
+ O,
1418
+ Y,
1419
+ ie,
1420
+ oe,
1421
+ le,
1422
+ ce,
1423
+ se,
1424
+ de,
1425
+ fe,
1426
+ pe,
1427
+ ge,
1428
+ ye,
1429
+ me,
1430
+ m
1431
+ ]
1432
+ ), Tr = L(
1433
+ () => ({
1434
+ currentTime: i.currentTime,
1435
+ duration: i.duration,
1436
+ bufferedFraction: i.bufferedFraction,
1437
+ isBuffering: i.isBuffering,
1438
+ errorMessage: i.errorMessage,
1439
+ volume: i.volume,
1440
+ muted: i.muted,
1441
+ playbackRate: i.playbackRate,
1442
+ seek: D,
1443
+ setVolume: ne,
1444
+ setMuted: te,
1445
+ toggleMute: ae,
1446
+ setPlaybackRate: ue,
1447
+ audioRef: U,
1448
+ notifyEnded: he,
1449
+ dispatch: m
1450
+ }),
1451
+ [
1452
+ i.currentTime,
1453
+ i.duration,
1454
+ i.bufferedFraction,
1455
+ i.isBuffering,
1456
+ i.errorMessage,
1457
+ i.volume,
1458
+ i.muted,
1459
+ i.playbackRate,
1460
+ D,
1461
+ ne,
1462
+ te,
1463
+ ae,
1464
+ ue,
1465
+ U,
1466
+ he,
1467
+ m
1468
+ ]
1469
+ ), vr = $e(i), Ir = L(() => ({ ...mn, ...K }), [K]);
1470
+ return /* @__PURE__ */ c(en, { locale: b, children: /* @__PURE__ */ c(Ar.Provider, { value: xr, children: /* @__PURE__ */ c(Sr.Provider, { value: Tr, children: /* @__PURE__ */ c(Fe.Provider, { value: Mr, children: /* @__PURE__ */ c(
1471
+ "div",
1472
+ {
1473
+ className: Ie,
1474
+ style: Ir,
1475
+ "data-ginger-playback": vr,
1476
+ dir: kr,
1477
+ children: e
1478
+ }
1479
+ ) }) }) }) });
1480
+ }
1481
+ const xn = {
1482
+ Provider: bn,
1483
+ Player: Cr,
1484
+ Current: {
1485
+ Title: Qr,
1486
+ Artist: Hr,
1487
+ Album: jr,
1488
+ Description: Xr,
1489
+ Copyright: Kr,
1490
+ Genre: Wr,
1491
+ Label: zr,
1492
+ Isrc: qr,
1493
+ TrackNumber: Jr,
1494
+ Year: Oe,
1495
+ Lyrics: Ye,
1496
+ FileUrl: Qe,
1497
+ Artwork: He,
1498
+ QueueIndex: je,
1499
+ QueueLength: Xe,
1500
+ QueuePosition: Ke,
1501
+ Elapsed: We,
1502
+ Duration: ze,
1503
+ Remaining: qe,
1504
+ Progress: Je,
1505
+ TimeRail: Ze,
1506
+ BufferRail: er,
1507
+ PlaybackState: rr,
1508
+ ErrorMessage: nr
1509
+ },
1510
+ Queue: {
1511
+ Title: ln,
1512
+ Subtitle: cn,
1513
+ Description: sn,
1514
+ Copyright: dn,
1515
+ Artwork: yr
1516
+ },
1517
+ Control: {
1518
+ PlayPause: ar,
1519
+ Repeat: ur,
1520
+ Next: ir,
1521
+ Previous: or,
1522
+ Shuffle: lr,
1523
+ SeekBar: cr,
1524
+ Volume: sr,
1525
+ Mute: dr,
1526
+ PlaybackRate: fr
1527
+ },
1528
+ Playlist: on
1529
+ };
1530
+ export {
1531
+ xn as G,
1532
+ Te as a,
1533
+ $e as b,
1534
+ Ge as c,
1535
+ xe as d,
1536
+ tn as e,
1537
+ rn as f,
1538
+ nn as g,
1539
+ Or as h,
1540
+ Br as i,
1541
+ X as j,
1542
+ F as k,
1543
+ Be as p,
1544
+ Yr as r,
1545
+ R as u
1546
+ };
1547
+ //# sourceMappingURL=ginger-gb6OJ3eQ.js.map