wavesurf 1.1.0 → 1.2.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/README.md +93 -0
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +103 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +103 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -300,12 +300,36 @@ Displays a track with waveform visualization:
|
|
|
300
300
|
}}
|
|
301
301
|
lazyLoad={true}
|
|
302
302
|
showTime={true}
|
|
303
|
+
standalone={false} // Use local audio instead of global context
|
|
303
304
|
className=""
|
|
304
305
|
renderHeader={(song, isPlaying) => <CustomHeader />}
|
|
305
306
|
renderControls={(song, isPlaying) => <CustomControls />}
|
|
306
307
|
/>
|
|
307
308
|
```
|
|
308
309
|
|
|
310
|
+
#### Standalone Mode
|
|
311
|
+
|
|
312
|
+
By default, `WaveformPlayer` uses the global `AudioPlayerProvider` context and works with the `MiniPlayer`. If you want a simpler setup—individual players that don't share state and don't show the mini player bar—use standalone mode:
|
|
313
|
+
|
|
314
|
+
```tsx
|
|
315
|
+
// No AudioPlayerProvider needed
|
|
316
|
+
<WaveformPlayer
|
|
317
|
+
song={song}
|
|
318
|
+
standalone={true}
|
|
319
|
+
/>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**When to use standalone mode:**
|
|
323
|
+
- Simple pages with just one or two tracks
|
|
324
|
+
- Embedded players that shouldn't affect the rest of your site
|
|
325
|
+
- When you don't want the persistent mini player bar
|
|
326
|
+
|
|
327
|
+
**Standalone mode behavior:**
|
|
328
|
+
- Each player manages its own audio element
|
|
329
|
+
- Clicking play on one song automatically pauses others (even in standalone mode)
|
|
330
|
+
- No MiniPlayer appears
|
|
331
|
+
- Volume fade-in and persistence are not applied
|
|
332
|
+
|
|
309
333
|
### MiniPlayer
|
|
310
334
|
|
|
311
335
|
Persistent playback bar:
|
|
@@ -321,6 +345,75 @@ Persistent playback bar:
|
|
|
321
345
|
/>
|
|
322
346
|
```
|
|
323
347
|
|
|
348
|
+
#### Persisting Across Route Changes
|
|
349
|
+
|
|
350
|
+
To keep the MiniPlayer visible and audio playing while users navigate between pages, place both `AudioPlayerProvider` and `MiniPlayer` in your **root layout**—not in individual pages.
|
|
351
|
+
|
|
352
|
+
**Next.js App Router:**
|
|
353
|
+
|
|
354
|
+
```tsx
|
|
355
|
+
// app/layout.tsx
|
|
356
|
+
import { AudioPlayerProvider, MiniPlayer } from 'wavesurf';
|
|
357
|
+
import 'wavesurf/styles.css';
|
|
358
|
+
|
|
359
|
+
export default function RootLayout({ children }) {
|
|
360
|
+
return (
|
|
361
|
+
<html>
|
|
362
|
+
<body>
|
|
363
|
+
<AudioPlayerProvider>
|
|
364
|
+
<Header />
|
|
365
|
+
<main>{children}</main>
|
|
366
|
+
<Footer />
|
|
367
|
+
<MiniPlayer />
|
|
368
|
+
</AudioPlayerProvider>
|
|
369
|
+
</body>
|
|
370
|
+
</html>
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
**Next.js Pages Router:**
|
|
376
|
+
|
|
377
|
+
```tsx
|
|
378
|
+
// pages/_app.tsx
|
|
379
|
+
import { AudioPlayerProvider, MiniPlayer } from 'wavesurf';
|
|
380
|
+
import 'wavesurf/styles.css';
|
|
381
|
+
|
|
382
|
+
export default function MyApp({ Component, pageProps }) {
|
|
383
|
+
return (
|
|
384
|
+
<AudioPlayerProvider>
|
|
385
|
+
<Component {...pageProps} />
|
|
386
|
+
<MiniPlayer />
|
|
387
|
+
</AudioPlayerProvider>
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
**React Router:**
|
|
393
|
+
|
|
394
|
+
```tsx
|
|
395
|
+
// App.tsx
|
|
396
|
+
import { AudioPlayerProvider, MiniPlayer } from 'wavesurf';
|
|
397
|
+
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
398
|
+
import 'wavesurf/styles.css';
|
|
399
|
+
|
|
400
|
+
function App() {
|
|
401
|
+
return (
|
|
402
|
+
<AudioPlayerProvider>
|
|
403
|
+
<BrowserRouter>
|
|
404
|
+
<Routes>
|
|
405
|
+
<Route path="/" element={<Home />} />
|
|
406
|
+
<Route path="/album/:id" element={<Album />} />
|
|
407
|
+
</Routes>
|
|
408
|
+
</BrowserRouter>
|
|
409
|
+
<MiniPlayer />
|
|
410
|
+
</AudioPlayerProvider>
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
**Why this works:** React Context state persists as long as the provider component stays mounted. By placing it in the root layout, the audio state survives page transitions. If you put the provider inside a page component, it unmounts on navigation and loses the current song.
|
|
416
|
+
|
|
324
417
|
### ShareButtons
|
|
325
418
|
|
|
326
419
|
Social sharing for tracks:
|
package/dist/index.d.mts
CHANGED
|
@@ -123,6 +123,12 @@ interface WaveformPlayerProps {
|
|
|
123
123
|
renderHeader?: (song: Song, isPlaying: boolean) => React.ReactNode;
|
|
124
124
|
/** Custom render function for additional controls */
|
|
125
125
|
renderControls?: (song: Song, isPlaying: boolean) => React.ReactNode;
|
|
126
|
+
/**
|
|
127
|
+
* Standalone mode - play audio locally without global context/MiniPlayer.
|
|
128
|
+
* Use this when you want a simple player without the persistent mini player bar.
|
|
129
|
+
* (default: false)
|
|
130
|
+
*/
|
|
131
|
+
standalone?: boolean;
|
|
126
132
|
}
|
|
127
133
|
/**
|
|
128
134
|
* Position of the mini player.
|
|
@@ -195,7 +201,7 @@ interface AudioPlayerProviderProps {
|
|
|
195
201
|
declare function AudioPlayerProvider({ children, config: userConfig, }: AudioPlayerProviderProps): react_jsx_runtime.JSX.Element;
|
|
196
202
|
declare function useAudioPlayer(): AudioPlayerContextValue;
|
|
197
203
|
|
|
198
|
-
declare function WaveformPlayer({ song, waveformConfig: userWaveformConfig, lazyLoad, showTime, className, renderHeader, renderControls, }: WaveformPlayerProps): react_jsx_runtime.JSX.Element;
|
|
204
|
+
declare function WaveformPlayer({ song, waveformConfig: userWaveformConfig, lazyLoad, showTime, className, renderHeader, renderControls, standalone, }: WaveformPlayerProps): react_jsx_runtime.JSX.Element;
|
|
199
205
|
|
|
200
206
|
declare function MiniPlayer({ position, showVolume, showClose, onClose, className, waveformConfig: userWaveformConfig, }: MiniPlayerProps): react_jsx_runtime.JSX.Element | null;
|
|
201
207
|
|
package/dist/index.d.ts
CHANGED
|
@@ -123,6 +123,12 @@ interface WaveformPlayerProps {
|
|
|
123
123
|
renderHeader?: (song: Song, isPlaying: boolean) => React.ReactNode;
|
|
124
124
|
/** Custom render function for additional controls */
|
|
125
125
|
renderControls?: (song: Song, isPlaying: boolean) => React.ReactNode;
|
|
126
|
+
/**
|
|
127
|
+
* Standalone mode - play audio locally without global context/MiniPlayer.
|
|
128
|
+
* Use this when you want a simple player without the persistent mini player bar.
|
|
129
|
+
* (default: false)
|
|
130
|
+
*/
|
|
131
|
+
standalone?: boolean;
|
|
126
132
|
}
|
|
127
133
|
/**
|
|
128
134
|
* Position of the mini player.
|
|
@@ -195,7 +201,7 @@ interface AudioPlayerProviderProps {
|
|
|
195
201
|
declare function AudioPlayerProvider({ children, config: userConfig, }: AudioPlayerProviderProps): react_jsx_runtime.JSX.Element;
|
|
196
202
|
declare function useAudioPlayer(): AudioPlayerContextValue;
|
|
197
203
|
|
|
198
|
-
declare function WaveformPlayer({ song, waveformConfig: userWaveformConfig, lazyLoad, showTime, className, renderHeader, renderControls, }: WaveformPlayerProps): react_jsx_runtime.JSX.Element;
|
|
204
|
+
declare function WaveformPlayer({ song, waveformConfig: userWaveformConfig, lazyLoad, showTime, className, renderHeader, renderControls, standalone, }: WaveformPlayerProps): react_jsx_runtime.JSX.Element;
|
|
199
205
|
|
|
200
206
|
declare function MiniPlayer({ position, showVolume, showClose, onClose, className, waveformConfig: userWaveformConfig, }: MiniPlayerProps): react_jsx_runtime.JSX.Element | null;
|
|
201
207
|
|
package/dist/index.js
CHANGED
|
@@ -304,6 +304,7 @@ var DEFAULT_WAVEFORM_CONFIG = {
|
|
|
304
304
|
height: 60,
|
|
305
305
|
normalize: true
|
|
306
306
|
};
|
|
307
|
+
react.createContext(null);
|
|
307
308
|
function WaveformPlayer({
|
|
308
309
|
song,
|
|
309
310
|
waveformConfig: userWaveformConfig,
|
|
@@ -311,35 +312,87 @@ function WaveformPlayer({
|
|
|
311
312
|
showTime = true,
|
|
312
313
|
className = "",
|
|
313
314
|
renderHeader,
|
|
314
|
-
renderControls
|
|
315
|
+
renderControls,
|
|
316
|
+
standalone = false
|
|
315
317
|
}) {
|
|
316
318
|
const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };
|
|
317
319
|
const containerRef = react.useRef(null);
|
|
318
320
|
const wavesurferRef = react.useRef(null);
|
|
321
|
+
const localAudioRef = react.useRef(null);
|
|
319
322
|
const [isReady, setIsReady] = react.useState(false);
|
|
320
323
|
const [totalDuration, setTotalDuration] = react.useState(song.duration || 0);
|
|
324
|
+
const [localIsPlaying, setLocalIsPlaying] = react.useState(false);
|
|
325
|
+
const [localCurrentTime, setLocalCurrentTime] = react.useState(0);
|
|
321
326
|
const { ref: wrapperRef, isVisible } = useLazyLoad({
|
|
322
327
|
forceVisible: !lazyLoad
|
|
323
328
|
});
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
const
|
|
333
|
-
const
|
|
334
|
-
const
|
|
329
|
+
let contextValue = null;
|
|
330
|
+
try {
|
|
331
|
+
if (!standalone) {
|
|
332
|
+
contextValue = useAudioPlayer();
|
|
333
|
+
}
|
|
334
|
+
} catch {
|
|
335
|
+
}
|
|
336
|
+
const useStandaloneMode = standalone || !contextValue;
|
|
337
|
+
const contextPlay = contextValue?.play;
|
|
338
|
+
const contextTogglePlay = contextValue?.togglePlay;
|
|
339
|
+
const contextSeek = contextValue?.seek;
|
|
340
|
+
const contextCurrentSong = contextValue?.currentSong;
|
|
341
|
+
const contextIsPlaying = contextValue?.isPlaying ?? false;
|
|
342
|
+
const contextCurrentTime = contextValue?.currentTime ?? 0;
|
|
343
|
+
const isThisSongPlayingInContext = !useStandaloneMode && contextCurrentSong?.id === song.id;
|
|
344
|
+
const isPlaying = useStandaloneMode ? localIsPlaying : isThisSongPlayingInContext && contextIsPlaying;
|
|
345
|
+
const currentTime = useStandaloneMode ? localCurrentTime : isThisSongPlayingInContext ? contextCurrentTime : 0;
|
|
346
|
+
react.useEffect(() => {
|
|
347
|
+
if (!useStandaloneMode) return;
|
|
348
|
+
const audio = new Audio();
|
|
349
|
+
audio.preload = "metadata";
|
|
350
|
+
localAudioRef.current = audio;
|
|
351
|
+
const handleTimeUpdate = () => {
|
|
352
|
+
setLocalCurrentTime(audio.currentTime);
|
|
353
|
+
};
|
|
354
|
+
const handleEnded = () => {
|
|
355
|
+
setLocalIsPlaying(false);
|
|
356
|
+
setLocalCurrentTime(0);
|
|
357
|
+
};
|
|
358
|
+
const handleLoadedMetadata = () => {
|
|
359
|
+
setTotalDuration(audio.duration);
|
|
360
|
+
};
|
|
361
|
+
audio.addEventListener("timeupdate", handleTimeUpdate);
|
|
362
|
+
audio.addEventListener("ended", handleEnded);
|
|
363
|
+
audio.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
364
|
+
return () => {
|
|
365
|
+
audio.removeEventListener("timeupdate", handleTimeUpdate);
|
|
366
|
+
audio.removeEventListener("ended", handleEnded);
|
|
367
|
+
audio.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
368
|
+
audio.pause();
|
|
369
|
+
audio.src = "";
|
|
370
|
+
};
|
|
371
|
+
}, [useStandaloneMode]);
|
|
372
|
+
react.useEffect(() => {
|
|
373
|
+
if (!useStandaloneMode) return;
|
|
374
|
+
const handleOtherPlayerPlay = (event) => {
|
|
375
|
+
if (event.detail !== song.id && localAudioRef.current) {
|
|
376
|
+
localAudioRef.current.pause();
|
|
377
|
+
setLocalIsPlaying(false);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
window.addEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay);
|
|
381
|
+
return () => {
|
|
382
|
+
window.removeEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay);
|
|
383
|
+
};
|
|
384
|
+
}, [useStandaloneMode, song.id]);
|
|
335
385
|
react.useEffect(() => {
|
|
336
|
-
if (!wavesurferRef.current
|
|
386
|
+
if (!wavesurferRef.current) return;
|
|
387
|
+
const relevantCurrentTime = useStandaloneMode ? localCurrentTime : contextCurrentTime;
|
|
388
|
+
const shouldSync = useStandaloneMode ? localIsPlaying : isThisSongPlayingInContext;
|
|
389
|
+
if (!shouldSync) return;
|
|
337
390
|
const waveDuration = wavesurferRef.current.getDuration();
|
|
338
|
-
if (waveDuration > 0 &&
|
|
339
|
-
const progress =
|
|
391
|
+
if (waveDuration > 0 && relevantCurrentTime >= 0) {
|
|
392
|
+
const progress = relevantCurrentTime / waveDuration;
|
|
340
393
|
wavesurferRef.current.seekTo(Math.min(progress, 1));
|
|
341
394
|
}
|
|
342
|
-
}, [contextCurrentTime,
|
|
395
|
+
}, [localCurrentTime, contextCurrentTime, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext]);
|
|
343
396
|
react.useEffect(() => {
|
|
344
397
|
if (!containerRef.current || !isVisible) return;
|
|
345
398
|
const hasPeaks = song.peaks && song.peaks.length > 0;
|
|
@@ -354,18 +407,24 @@ function WaveformPlayer({
|
|
|
354
407
|
height: waveformConfig.height,
|
|
355
408
|
normalize: waveformConfig.normalize,
|
|
356
409
|
interact: true,
|
|
357
|
-
// Allow clicking on waveform to seek
|
|
358
410
|
// Only load audio URL if we don't have peaks (needed to generate waveform)
|
|
359
411
|
url: hasPeaks ? void 0 : song.audioUrl,
|
|
360
412
|
peaks: hasPeaks ? [song.peaks] : void 0,
|
|
361
413
|
duration: hasPeaks ? song.duration || 0 : void 0
|
|
362
414
|
});
|
|
415
|
+
wavesurfer.setMuted(true);
|
|
363
416
|
wavesurfer.on("ready", () => {
|
|
364
417
|
setIsReady(true);
|
|
365
418
|
setTotalDuration(wavesurfer.getDuration() || song.duration || 0);
|
|
419
|
+
wavesurfer.setMuted(true);
|
|
366
420
|
});
|
|
367
421
|
wavesurfer.on("interaction", (newTime) => {
|
|
368
|
-
if (
|
|
422
|
+
if (useStandaloneMode) {
|
|
423
|
+
if (localAudioRef.current) {
|
|
424
|
+
localAudioRef.current.currentTime = newTime;
|
|
425
|
+
setLocalCurrentTime(newTime);
|
|
426
|
+
}
|
|
427
|
+
} else if (isThisSongPlayingInContext && contextSeek) {
|
|
369
428
|
contextSeek(newTime);
|
|
370
429
|
}
|
|
371
430
|
});
|
|
@@ -387,7 +446,8 @@ function WaveformPlayer({
|
|
|
387
446
|
song.peaks,
|
|
388
447
|
song.duration,
|
|
389
448
|
isVisible,
|
|
390
|
-
|
|
449
|
+
useStandaloneMode,
|
|
450
|
+
isThisSongPlayingInContext,
|
|
391
451
|
contextSeek,
|
|
392
452
|
waveformConfig.waveColor,
|
|
393
453
|
waveformConfig.progressColor,
|
|
@@ -400,12 +460,32 @@ function WaveformPlayer({
|
|
|
400
460
|
]);
|
|
401
461
|
const handlePlayClick = react.useCallback(() => {
|
|
402
462
|
if (!song.id || !song.audioUrl) return;
|
|
403
|
-
if (
|
|
404
|
-
|
|
463
|
+
if (useStandaloneMode) {
|
|
464
|
+
if (!localAudioRef.current) return;
|
|
465
|
+
if (localIsPlaying) {
|
|
466
|
+
localAudioRef.current.pause();
|
|
467
|
+
setLocalIsPlaying(false);
|
|
468
|
+
} else {
|
|
469
|
+
if (typeof window !== "undefined") {
|
|
470
|
+
window.dispatchEvent(
|
|
471
|
+
new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
if (localAudioRef.current.src !== song.audioUrl) {
|
|
475
|
+
localAudioRef.current.src = song.audioUrl;
|
|
476
|
+
}
|
|
477
|
+
localAudioRef.current.play().catch(() => {
|
|
478
|
+
});
|
|
479
|
+
setLocalIsPlaying(true);
|
|
480
|
+
}
|
|
405
481
|
} else {
|
|
406
|
-
|
|
482
|
+
if (isThisSongPlayingInContext) {
|
|
483
|
+
contextTogglePlay?.();
|
|
484
|
+
} else {
|
|
485
|
+
contextPlay?.(song);
|
|
486
|
+
}
|
|
407
487
|
}
|
|
408
|
-
}, [song,
|
|
488
|
+
}, [song, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext, contextPlay, contextTogglePlay]);
|
|
409
489
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
410
490
|
"div",
|
|
411
491
|
{
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context/AudioPlayerContext.tsx","../src/hooks/useLazyLoad.ts","../src/utils/formatTime.ts","../src/components/WaveformPlayer.tsx","../src/components/MiniPlayer.tsx","../src/components/ShareButtons.tsx"],"names":["createContext","useRef","useEffect","useState","useCallback","jsx","useContext","WaveSurfer","jsxs","DEFAULT_WAVEFORM_CONFIG"],"mappings":";;;;;;;;;;;AAmBO,IAAM,sBAAA,GAAyB;AAEtC,IAAM,kBAAA,GAAqBA,oBAA8C,IAAI,CAAA;AAE7E,IAAM,cAAA,GAA8C;AAAA,EAClD,aAAA,EAAe,IAAA;AAAA,EACf,cAAA,EAAgB,GAAA;AAAA,EAChB,aAAA,EAAe,IAAA;AAAA,EACf,UAAA,EAAY,mBAAA;AAAA,EACZ,aAAA,EAAe,CAAA;AAAA,EACf,QAAQ,MAAM;AAAA,EAAC,CAAA;AAAA,EACf,SAAS,MAAM;AAAA,EAAC,CAAA;AAAA,EAChB,OAAO,MAAM;AAAA,EAAC,CAAA;AAAA,EACd,cAAc,MAAM;AAAA,EAAC;AACvB,CAAA;AAEA,IAAM,UAAA,GAAa,EAAA;AACnB,IAAM,kBAAA,GAAqB,GAAA;AAOpB,SAAS,mBAAA,CAAoB;AAAA,EAClC,QAAA;AAAA,EACA,MAAA,EAAQ;AACV,CAAA,EAA6B;AAC3B,EAAA,MAAM,MAAA,GAAS,EAAE,GAAG,cAAA,EAAgB,GAAG,UAAA,EAAW;AAClD,EAAA,MAAM,QAAA,GAAWC,aAAgC,IAAI,CAAA;AACrD,EAAA,MAAM,eAAA,GAAkBA,aAA8C,IAAI,CAAA;AAC1E,EAAA,MAAM,SAAA,GAAYA,aAAO,MAAM,CAAA;AAG/B,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,SAAA,CAAU,OAAA,GAAU,MAAA;AAAA,EACtB,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,cAAA,CAA2B;AAAA,IACnD,WAAA,EAAa,IAAA;AAAA,IACb,SAAA,EAAW,KAAA;AAAA,IACX,WAAA,EAAa,CAAA;AAAA,IACb,QAAA,EAAU,CAAA;AAAA,IACV,QAAQ,MAAA,CAAO,aAAA;AAAA,IACf,eAAe,MAAA,CAAO,aAAA;AAAA,IACtB,UAAA,EAAY;AAAA,GACb,CAAA;AAGD,EAAAD,eAAA,CAAU,MAAM;AAEd,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,IAAA,KAAA,CAAM,OAAA,GAAU,UAAA;AAChB,IAAA,QAAA,CAAS,OAAA,GAAU,KAAA;AAGnB,IAAA,IAAI,MAAA,CAAO,aAAA,IAAiB,OAAO,MAAA,KAAW,WAAA,EAAa;AACzD,MAAA,MAAM,WAAA,GAAc,YAAA,CAAa,OAAA,CAAQ,MAAA,CAAO,UAAU,CAAA;AAC1D,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,MAAM,GAAA,GAAM,WAAW,WAAW,CAAA;AAClC,QAAA,IAAI,CAAC,KAAA,CAAM,GAAG,KAAK,GAAA,IAAO,CAAA,IAAK,OAAO,CAAA,EAAG;AACvC,UAAA,QAAA,CAAS,CAAC,OAAO,EAAE,GAAG,GAAG,MAAA,EAAQ,GAAA,EAAK,aAAA,EAAe,GAAA,EAAI,CAAE,CAAA;AAC3D,UAAA,KAAA,CAAM,MAAA,GAAS,GAAA;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAGA,IAAA,MAAM,mBAAmB,MAAM;AAC7B,MAAA,QAAA,CAAS,CAAC,OAAO,EAAE,GAAG,GAAG,WAAA,EAAa,KAAA,CAAM,aAAY,CAAE,CAAA;AAC1D,MAAA,SAAA,CAAU,OAAA,CAAQ,YAAA,GAAe,KAAA,CAAM,WAAW,CAAA;AAAA,IACpD,CAAA;AAEA,IAAA,MAAM,uBAAuB,MAAM;AACjC,MAAA,QAAA,CAAS,CAAC,OAAO,EAAE,GAAG,GAAG,QAAA,EAAU,KAAA,CAAM,UAAS,CAAE,CAAA;AAAA,IACtD,CAAA;AAEA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,QAAA,CAAS,CAAC,OAAO,EAAE,GAAG,GAAG,SAAA,EAAW,KAAA,EAAO,WAAA,EAAa,CAAA,EAAE,CAAE,CAAA;AAC5D,MAAA,SAAA,CAAU,QAAQ,KAAA,IAAQ;AAAA,IAC5B,CAAA;AAEA,IAAA,MAAM,aAAa,MAAM;AACvB,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,SAAA,EAAW,MAAK,CAAE,CAAA;AAAA,IAC7C,CAAA;AAEA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,SAAA,EAAW,OAAM,CAAE,CAAA;AAAA,IAC9C,CAAA;AAEA,IAAA,KAAA,CAAM,gBAAA,CAAiB,cAAc,gBAAgB,CAAA;AACrD,IAAA,KAAA,CAAM,gBAAA,CAAiB,kBAAkB,oBAAoB,CAAA;AAC7D,IAAA,KAAA,CAAM,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC3C,IAAA,KAAA,CAAM,gBAAA,CAAiB,QAAQ,UAAU,CAAA;AACzC,IAAA,KAAA,CAAM,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAE3C,IAAA,OAAO,MAAM;AAEX,MAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,QAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AAAA,MACvC;AACA,MAAA,KAAA,CAAM,mBAAA,CAAoB,cAAc,gBAAgB,CAAA;AACxD,MAAA,KAAA,CAAM,mBAAA,CAAoB,kBAAkB,oBAAoB,CAAA;AAChE,MAAA,KAAA,CAAM,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC9C,MAAA,KAAA,CAAM,mBAAA,CAAoB,QAAQ,UAAU,CAAA;AAC5C,MAAA,KAAA,CAAM,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC9C,MAAA,KAAA,CAAM,KAAA,EAAM;AACZ,MAAA,KAAA,CAAM,GAAA,GAAM,EAAA;AAAA,IACd,CAAA;AAAA,EAEF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,SAAA,GAAYE,kBAAY,MAAM;AAClC,IAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,MAAA,aAAA,CAAc,gBAAgB,OAAO,CAAA;AACrC,MAAA,eAAA,CAAgB,OAAA,GAAU,IAAA;AAAA,IAC5B;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,YAAA,GAAeA,iBAAA;AAAA,IACnB,CAAC,YAAA,KAAyB;AACxB,MAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AAEvB,MAAA,SAAA,EAAU;AACV,MAAA,QAAA,CAAS,CAAC,OAAO,EAAE,GAAG,GAAG,UAAA,EAAY,IAAA,EAAM,aAAA,EAAe,CAAA,EAAE,CAAE,CAAA;AAE9D,MAAA,MAAM,gBAAA,GAAmB,SAAA,CAAU,OAAA,CAAQ,cAAA,GAAiB,UAAA;AAC5D,MAAA,MAAM,aAAa,YAAA,GAAe,UAAA;AAClC,MAAA,IAAI,WAAA,GAAc,CAAA;AAElB,MAAA,eAAA,CAAgB,OAAA,GAAU,YAAY,MAAM;AAC1C,QAAA,WAAA,EAAA;AACA,QAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,UAAA,GAAa,aAAa,YAAY,CAAA;AACjE,QAAA,IAAI,SAAS,OAAA,EAAS;AACpB,UAAA,QAAA,CAAS,QAAQ,MAAA,GAAS,SAAA;AAAA,QAC5B;AAEA,QAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,aAAA,EAAe,WAAU,CAAE,CAAA;AAEpD,QAAA,IAAI,eAAe,UAAA,EAAY;AAC7B,UAAA,SAAA,EAAU;AACV,UAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,YACf,GAAG,CAAA;AAAA,YACH,UAAA,EAAY,KAAA;AAAA,YACZ,aAAA,EAAe;AAAA,WACjB,CAAE,CAAA;AAAA,QACJ;AAAA,MACF,GAAG,gBAAgB,CAAA;AAAA,IACrB,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAGA,EAAA,MAAM,IAAA,GAAOA,iBAAA;AAAA,IACX,OAAO,IAAA,KAAe;AACpB,MAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AAGvB,MAAA,SAAA,EAAU;AAGV,MAAA,IAAI,KAAA,CAAM,WAAA,EAAa,EAAA,KAAO,IAAA,CAAK,EAAA,EAAI;AACrC,QAAA,QAAA,CAAS,OAAA,CAAQ,MAAM,IAAA,CAAK,QAAA;AAC5B,QAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,UACf,GAAG,CAAA;AAAA,UACH,WAAA,EAAa,IAAA;AAAA,UACb,WAAA,EAAa,CAAA;AAAA,UACb,QAAA,EAAU,KAAK,QAAA,IAAY;AAAA,SAC7B,CAAE,CAAA;AAAA,MACJ;AAGA,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,QAAQ,kBAAkB,CAAA;AAG9D,MAAA,IAAI,SAAA,CAAU,QAAQ,aAAA,EAAe;AACnC,QAAA,QAAA,CAAS,QAAQ,MAAA,GAAS,CAAA;AAAA,MAC5B,CAAA,MAAO;AACL,QAAA,QAAA,CAAS,QAAQ,MAAA,GAAS,YAAA;AAAA,MAC5B;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,CAAS,QAAQ,IAAA,EAAK;AAE5B,QAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,UAAA,MAAA,CAAO,aAAA;AAAA,YACL,IAAI,WAAA,CAAY,sBAAA,EAAwB,EAAE,MAAA,EAAQ,IAAA,CAAK,IAAI;AAAA,WAC7D;AAAA,QACF;AAEA,QAAA,IAAI,SAAA,CAAU,QAAQ,aAAA,EAAe;AACnC,UAAA,YAAA,CAAa,YAAY,CAAA;AAAA,QAC3B;AAEA,QAAA,SAAA,CAAU,OAAA,CAAQ,SAAS,IAAI,CAAA;AAAA,MACjC,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA;AAAA,IACA,CAAC,KAAA,CAAM,WAAA,EAAa,IAAI,KAAA,CAAM,MAAA,EAAQ,WAAW,YAAY;AAAA,GAC/D;AAGA,EAAA,MAAM,KAAA,GAAQA,kBAAY,MAAM;AAC9B,IAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACvB,IAAA,SAAA,EAAU;AACV,IAAA,QAAA,CAAS,QAAQ,KAAA,EAAM;AACvB,IAAA,SAAA,CAAU,QAAQ,OAAA,IAAU;AAAA,EAC9B,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAGd,EAAA,MAAM,UAAA,GAAaA,kBAAY,MAAM;AACnC,IAAA,IAAI,CAAC,QAAA,CAAS,OAAA,IAAW,CAAC,MAAM,WAAA,EAAa;AAE7C,IAAA,IAAI,MAAM,SAAA,EAAW;AACnB,MAAA,KAAA,EAAM;AAAA,IACR,CAAA,MAAO;AAEL,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,GAAA,CAAI,KAAA,CAAM,QAAQ,kBAAkB,CAAA;AAE9D,MAAA,IAAI,SAAA,CAAU,QAAQ,aAAA,EAAe;AACnC,QAAA,QAAA,CAAS,QAAQ,MAAA,GAAS,CAAA;AAAA,MAC5B;AAEA,MAAA,QAAA,CAAS,OAAA,CACN,IAAA,EAAK,CACL,IAAA,CAAK,MAAM;AACV,QAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,UAAA,MAAA,CAAO,aAAA;AAAA,YACL,IAAI,YAAY,sBAAA,EAAwB;AAAA,cACtC,MAAA,EAAQ,MAAM,WAAA,EAAa;AAAA,aAC5B;AAAA,WACH;AAAA,QACF;AACA,QAAA,IAAI,SAAA,CAAU,QAAQ,aAAA,EAAe;AACnC,UAAA,YAAA,CAAa,YAAY,CAAA;AAAA,QAC3B;AAAA,MACF,CAAC,CAAA,CACA,KAAA,CAAM,MAAM;AAAA,MAEb,CAAC,CAAA;AAAA,IACL;AAAA,EACF,CAAA,EAAG,CAAC,KAAA,CAAM,SAAA,EAAW,KAAA,CAAM,aAAa,KAAA,CAAM,MAAA,EAAQ,KAAA,EAAO,YAAY,CAAC,CAAA;AAG1E,EAAA,MAAM,IAAA,GAAOA,iBAAA,CAAY,CAAC,IAAA,KAAiB;AACzC,IAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACvB,IAAA,QAAA,CAAS,QAAQ,WAAA,GAAc,IAAA;AAC/B,IAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,WAAA,EAAa,MAAK,CAAE,CAAA;AAAA,EAC/C,CAAA,EAAG,EAAE,CAAA;AAGL,EAAA,MAAM,SAAA,GAAYA,iBAAA;AAAA,IAChB,CAAC,MAAA,KAAmB;AAClB,MAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AAEvB,MAAA,MAAM,aAAA,GAAgB,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,MAAM,CAAC,CAAA;AAGrD,MAAA,IAAI,gBAAgB,OAAA,EAAS;AAC3B,QAAA,SAAA,EAAU;AACV,QAAA,QAAA,CAAS,CAAC,CAAA,MAAO,EAAE,GAAG,CAAA,EAAG,UAAA,EAAY,OAAM,CAAE,CAAA;AAAA,MAC/C;AAEA,MAAA,QAAA,CAAS,QAAQ,MAAA,GAAS,aAAA;AAG1B,MAAA,IAAI,SAAA,CAAU,OAAA,CAAQ,aAAA,IAAiB,OAAO,WAAW,WAAA,EAAa;AACpE,QAAA,YAAA,CAAa,OAAA;AAAA,UACX,UAAU,OAAA,CAAQ,UAAA;AAAA,UAClB,cAAc,QAAA;AAAS,SACzB;AAAA,MACF;AAEA,MAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,QACf,GAAG,CAAA;AAAA,QACH,MAAA,EAAQ,aAAA;AAAA,QACR,aAAA,EAAe;AAAA,OACjB,CAAE,CAAA;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAGA,EAAA,MAAM,IAAA,GAAOA,kBAAY,MAAM;AAC7B,IAAA,IAAI,CAAC,SAAS,OAAA,EAAS;AACvB,IAAA,SAAA,EAAU;AACV,IAAA,QAAA,CAAS,QAAQ,KAAA,EAAM;AACvB,IAAA,QAAA,CAAS,QAAQ,WAAA,GAAc,CAAA;AAC/B,IAAA,QAAA,CAAS,QAAQ,GAAA,GAAM,EAAA;AACvB,IAAA,QAAA,CAAS,CAAC,CAAA,MAAO;AAAA,MACf,GAAG,CAAA;AAAA,MACH,WAAA,EAAa,IAAA;AAAA,MACb,SAAA,EAAW,KAAA;AAAA,MACX,WAAA,EAAa,CAAA;AAAA,MACb,QAAA,EAAU,CAAA;AAAA,MACV,UAAA,EAAY;AAAA,KACd,CAAE,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,KAAA,GAAiC;AAAA,IACrC,GAAG,KAAA;AAAA,IACH,IAAA;AAAA,IACA,KAAA;AAAA,IACA,UAAA;AAAA,IACA,IAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,uBACEC,cAAA,CAAC,kBAAA,CAAmB,QAAA,EAAnB,EAA4B,OAC1B,QAAA,EACH,CAAA;AAEJ;AAEO,SAAS,cAAA,GAA0C;AACxD,EAAA,MAAM,OAAA,GAAUC,iBAAW,kBAAkB,CAAA;AAC7C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;ACrUO,SAAS,YAAY,OAAA,EAAiD;AAC3E,EAAA,MAAM;AAAA,IACJ,UAAA,GAAa,OAAA;AAAA,IACb,SAAA,GAAY,CAAA;AAAA,IACZ,YAAA,GAAe;AAAA,GACjB,GAAI,WAAW,EAAC;AAEhB,EAAA,MAAM,GAAA,GAAML,aAAuB,IAAI,CAAA;AACvC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIE,eAAS,YAAY,CAAA;AAEvD,EAAAD,gBAAU,MAAM;AACd,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,IAAI,OAAA,EAAS;AAElB,IAAA,MAAM,WAAW,IAAI,oBAAA;AAAA,MACnB,CAAC,CAAC,KAAK,CAAA,KAAM;AACX,QAAA,IAAI,MAAM,cAAA,EAAgB;AACxB,UAAA,YAAA,CAAa,IAAI,CAAA;AACjB,UAAA,QAAA,CAAS,UAAA,EAAW;AAAA,QACtB;AAAA,MACF,CAAA;AAAA,MACA,EAAE,YAAY,SAAA;AAAU,KAC1B;AAEA,IAAA,QAAA,CAAS,OAAA,CAAQ,IAAI,OAAO,CAAA;AAE5B,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,CAAC,UAAA,EAAY,SAAA,EAAW,YAAY,CAAC,CAAA;AAExC,EAAA,OAAO,EAAE,KAAK,SAAA,EAAU;AAC1B;;;AC5CO,SAAS,WAAW,OAAA,EAAyB;AAClD,EAAA,IAAI,CAAC,OAAA,IAAW,KAAA,CAAM,OAAO,CAAA,IAAK,OAAA,GAAU,GAAG,OAAO,MAAA;AAEtD,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,EAAE,CAAA;AACpC,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,OAAA,GAAU,EAAE,CAAA;AACpC,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,IAAA,CAAK,UAAS,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AACpD;ACRA,IAAM,uBAAA,GAAoD;AAAA,EACxD,SAAA,EAAW,SAAA;AAAA,EACX,aAAA,EAAe,SAAA;AAAA,EACf,WAAA,EAAa,SAAA;AAAA,EACb,QAAA,EAAU,CAAA;AAAA,EACV,MAAA,EAAQ,CAAA;AAAA,EACR,SAAA,EAAW,CAAA;AAAA,EACX,MAAA,EAAQ,EAAA;AAAA,EACR,SAAA,EAAW;AACb,CAAA;AAEO,SAAS,cAAA,CAAe;AAAA,EAC7B,IAAA;AAAA,EACA,cAAA,EAAgB,kBAAA;AAAA,EAChB,QAAA,GAAW,IAAA;AAAA,EACX,QAAA,GAAW,IAAA;AAAA,EACX,SAAA,GAAY,EAAA;AAAA,EACZ,YAAA;AAAA,EACA;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,cAAA,GAAiB,EAAE,GAAG,uBAAA,EAAyB,GAAG,kBAAA,EAAmB;AAC3E,EAAA,MAAM,YAAA,GAAeD,aAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,aAAA,GAAgBA,aAA0B,IAAI,CAAA;AACpD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIE,eAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,IAAIA,cAAAA,CAAS,IAAA,CAAK,YAAY,CAAC,CAAA;AAGrE,EAAA,MAAM,EAAE,GAAA,EAAK,UAAA,EAAY,SAAA,KAAc,WAAA,CAAY;AAAA,IACjD,cAAc,CAAC;AAAA,GAChB,CAAA;AAGD,EAAA,MAAM;AAAA,IACJ,IAAA,EAAM,WAAA;AAAA,IACN,UAAA,EAAY,iBAAA;AAAA,IACZ,IAAA,EAAM,WAAA;AAAA,IACN,WAAA;AAAA,IACA,SAAA,EAAW,gBAAA;AAAA,IACX,WAAA,EAAa;AAAA,MACX,cAAA,EAAe;AAGnB,EAAA,MAAM,iBAAA,GAAoB,WAAA,EAAa,EAAA,KAAO,IAAA,CAAK,EAAA;AACnD,EAAA,MAAM,YAAY,iBAAA,IAAqB,gBAAA;AACvC,EAAA,MAAM,WAAA,GAAc,oBAAoB,kBAAA,GAAqB,CAAA;AAG7D,EAAAD,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,aAAA,CAAc,OAAA,IAAW,CAAC,iBAAA,EAAmB;AAGlD,IAAA,MAAM,YAAA,GAAe,aAAA,CAAc,OAAA,CAAQ,WAAA,EAAY;AACvD,IAAA,IAAI,YAAA,GAAe,CAAA,IAAK,kBAAA,IAAsB,CAAA,EAAG;AAC/C,MAAA,MAAM,WAAW,kBAAA,GAAqB,YAAA;AACtC,MAAA,aAAA,CAAc,QAAQ,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,CAAC,CAAC,CAAA;AAAA,IACpD;AAAA,EACF,CAAA,EAAG,CAAC,kBAAA,EAAoB,iBAAiB,CAAC,CAAA;AAG1C,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,YAAA,CAAa,OAAA,IAAW,CAAC,SAAA,EAAW;AAEzC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,MAAM,MAAA,GAAS,CAAA;AAGnD,IAAA,MAAM,UAAA,GAAaK,4BAAW,MAAA,CAAO;AAAA,MACnC,WAAW,YAAA,CAAa,OAAA;AAAA,MACxB,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,eAAe,cAAA,CAAe,aAAA;AAAA,MAC9B,aAAa,cAAA,CAAe,WAAA;AAAA,MAC5B,UAAU,cAAA,CAAe,QAAA;AAAA,MACzB,QAAQ,cAAA,CAAe,MAAA;AAAA,MACvB,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,QAAQ,cAAA,CAAe,MAAA;AAAA,MACvB,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,QAAA,EAAU,IAAA;AAAA;AAAA;AAAA,MAEV,GAAA,EAAK,QAAA,GAAW,MAAA,GAAY,IAAA,CAAK,QAAA;AAAA,MACjC,KAAA,EAAO,QAAA,GAAW,CAAC,IAAA,CAAK,KAAM,CAAA,GAAI,MAAA;AAAA,MAClC,QAAA,EAAU,QAAA,GAAY,IAAA,CAAK,QAAA,IAAY,CAAA,GAAK;AAAA,KAC7C,CAAA;AAED,IAAA,UAAA,CAAW,EAAA,CAAG,SAAS,MAAM;AAC3B,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,gBAAA,CAAiB,UAAA,CAAW,WAAA,EAAY,IAAK,IAAA,CAAK,YAAY,CAAC,CAAA;AAAA,IACjE,CAAC,CAAA;AAGD,IAAA,UAAA,CAAW,EAAA,CAAG,aAAA,EAAe,CAAC,OAAA,KAAoB;AAEhD,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,WAAA,CAAY,OAAO,CAAA;AAAA,MACrB;AAAA,IACF,CAAC,CAAA;AAED,IAAA,UAAA,CAAW,EAAA,CAAG,SAAS,MAAM;AAAA,IAE7B,CAAC,CAAA;AAED,IAAA,aAAA,CAAc,OAAA,GAAU,UAAA;AAGxB,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,UAAA,CAAW,IAAI,CAAA;AACf,MAAA,gBAAA,CAAiB,IAAA,CAAK,YAAY,CAAC,CAAA;AAAA,IACrC;AAEA,IAAA,OAAO,MAAM;AACX,MAAA,IAAI;AACF,QAAA,UAAA,CAAW,OAAA,EAAQ;AAAA,MACrB,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,IAAA,CAAK,QAAA;AAAA,IACL,IAAA,CAAK,KAAA;AAAA,IACL,IAAA,CAAK,QAAA;AAAA,IACL,SAAA;AAAA,IACA,iBAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA,CAAe,SAAA;AAAA,IACf,cAAA,CAAe,aAAA;AAAA,IACf,cAAA,CAAe,WAAA;AAAA,IACf,cAAA,CAAe,QAAA;AAAA,IACf,cAAA,CAAe,MAAA;AAAA,IACf,cAAA,CAAe,SAAA;AAAA,IACf,cAAA,CAAe,MAAA;AAAA,IACf,cAAA,CAAe;AAAA,GAChB,CAAA;AAGD,EAAA,MAAM,eAAA,GAAkBH,kBAAY,MAAM;AACxC,IAAA,IAAI,CAAC,IAAA,CAAK,EAAA,IAAM,CAAC,KAAK,QAAA,EAAU;AAEhC,IAAA,IAAI,iBAAA,EAAmB;AAErB,MAAA,iBAAA,EAAkB;AAAA,IACpB,CAAA,MAAO;AAEL,MAAA,WAAA,CAAY,IAAI,CAAA;AAAA,IAClB;AAAA,EACF,GAAG,CAAC,IAAA,EAAM,iBAAA,EAAmB,WAAA,EAAa,iBAAiB,CAAC,CAAA;AAE5D,EAAA,uBACEI,eAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA,EAAK,UAAA;AAAA,MACL,SAAA,EAAW,cAAc,SAAS,CAAA,CAAA;AAAA,MAClC,gBAAc,IAAA,CAAK,EAAA;AAAA,MAGlB,QAAA,EAAA;AAAA,QAAA,YAAA,GACC,aAAa,IAAA,EAAM,SAAS,oBAE5BA,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mBAAA,EACb,QAAA,EAAA;AAAA,0BAAAH,cAAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kBAAA,EAAoB,eAAK,KAAA,EAAM,CAAA;AAAA,UAC5C,IAAA,CAAK,0BACJA,cAAAA,CAAC,UAAK,SAAA,EAAU,mBAAA,EAAqB,eAAK,MAAA,EAAO;AAAA,SAAA,EAErD,CAAA;AAAA,wBAIFG,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAEb,QAAA,EAAA;AAAA,0BAAAH,cAAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAS,eAAA;AAAA,cACT,UAAU,CAAC,OAAA;AAAA,cACX,SAAA,EAAW,CAAA,gBAAA,EAAmB,OAAA,GAAU,wBAAA,GAA2B,EAAE,CAAA,CAAA;AAAA,cACrE,YAAA,EAAY,YAAY,OAAA,GAAU,MAAA;AAAA,cAEjC,QAAA,EAAA,CAAC,0BACAG,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,4BAAA,EAA6B,IAAA,EAAK,MAAA,EAAO,OAAA,EAAQ,WAAA,EAC9D,QAAA,EAAA;AAAA,gCAAAH,cAAAA;AAAA,kBAAC,QAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,mBAAA;AAAA,oBACV,EAAA,EAAG,IAAA;AAAA,oBACH,EAAA,EAAG,IAAA;AAAA,oBACH,CAAA,EAAE,IAAA;AAAA,oBACF,MAAA,EAAO,cAAA;AAAA,oBACP,WAAA,EAAY;AAAA;AAAA,iBACd;AAAA,gCACAA,cAAAA;AAAA,kBAAC,MAAA;AAAA,kBAAA;AAAA,oBACC,SAAA,EAAU,kBAAA;AAAA,oBACV,IAAA,EAAK,cAAA;AAAA,oBACL,CAAA,EAAE;AAAA;AAAA;AACJ,eAAA,EACF,CAAA,GACE,4BACFG,eAAA,CAAC,KAAA,EAAA,EAAI,WAAU,UAAA,EAAW,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,WAAA,EACpD,QAAA,EAAA;AAAA,gCAAAH,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,gCAC/CA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,IAAA,EAAK,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI;AAAA,eAAA,EAClD,CAAA,mBAEAA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,yBAAA,EAA0B,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aACnE,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,iBAAgB,CAAA,EAC1B;AAAA;AAAA,WAEJ;AAAA,0BAGAG,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EACb,QAAA,EAAA;AAAA,4BAAAH,cAAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,YAAA,EAAc,WAAU,cAAA,EAAe,CAAA;AAAA,YAGhD,QAAA,oBACCG,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EACb,QAAA,EAAA;AAAA,8BAAAH,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,UAAA,EAAY,QAAA,EAAA,UAAA,CAAW,WAAW,CAAA,EAAE,CAAA;AAAA,8BACpDA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,UAAA,EAAY,QAAA,EAAA,UAAA,CAAW,aAAa,CAAA,EAAE;AAAA,aAAA,EACxD;AAAA,WAAA,EAEJ,CAAA;AAAA,UAGC,cAAA,IAAkB,cAAA,CAAe,IAAA,EAAM,SAAS;AAAA,SAAA,EACnD;AAAA;AAAA;AAAA,GACF;AAEJ;AC1NA,IAAMI,wBAAAA,GAAoD;AAAA,EACxD,SAAA,EAAW,SAAA;AAAA,EACX,aAAA,EAAe,SAAA;AAAA,EACf,WAAA,EAAa,aAAA;AAAA,EACb,QAAA,EAAU,CAAA;AAAA,EACV,MAAA,EAAQ,CAAA;AAAA,EACR,SAAA,EAAW,CAAA;AAAA,EACX,MAAA,EAAQ,EAAA;AAAA,EACR,SAAA,EAAW;AACb,CAAA;AAEO,SAAS,UAAA,CAAW;AAAA,EACzB,QAAA,GAAW,QAAA;AAAA,EACX,UAAA,GAAa,IAAA;AAAA,EACb,SAAA,GAAY,IAAA;AAAA,EACZ,OAAA;AAAA,EACA,SAAA,GAAY,EAAA;AAAA,EACZ,cAAA,EAAgB;AAClB,CAAA,EAAoB;AAClB,EAAA,MAAM,cAAA,GAAiB,EAAE,GAAGA,wBAAAA,EAAyB,GAAG,kBAAA,EAAmB;AAE3E,EAAA,MAAM;AAAA,IACJ,WAAA;AAAA,IACA,SAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,aAAA;AAAA,IACA,UAAA;AAAA,IACA,IAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,MACE,cAAA,EAAe;AAEnB,EAAA,MAAM,WAAA,GAAcR,aAAuB,IAAI,CAAA;AAC/C,EAAA,MAAM,aAAA,GAAgBA,aAA0B,IAAI,CAAA;AACpD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIE,eAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIA,eAAS,KAAK,CAAA;AACxD,EAAA,MAAM,aAAA,GAAgBF,aAAsB,IAAI,CAAA;AAGhD,EAAAC,gBAAU,MAAM;AACd,IAAA,MAAM,WAAA,GAAc,MAAM,WAAA,CAAY,MAAA,CAAO,aAAa,GAAG,CAAA;AAC7D,IAAA,WAAA,EAAY;AACZ,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,WAAW,CAAA;AAC7C,IAAA,OAAO,MAAM,MAAA,CAAO,mBAAA,CAAoB,QAAA,EAAU,WAAW,CAAA;AAAA,EAC/D,CAAA,EAAG,EAAE,CAAA;AAGL,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,WAAA,CAAY,OAAA,IAAW,CAAC,WAAA,EAAa;AAG1C,IAAA,IAAI,aAAA,CAAc,OAAA,KAAY,WAAA,CAAY,EAAA,IAAM,cAAc,OAAA,EAAS;AACrE,MAAA;AAAA,IACF;AAGA,IAAA,IAAI,cAAc,OAAA,EAAS;AACzB,MAAA,aAAA,CAAc,QAAQ,OAAA,EAAQ;AAC9B,MAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,IAC1B;AAEA,IAAA,gBAAA,CAAiB,KAAK,CAAA;AACtB,IAAA,aAAA,CAAc,UAAU,WAAA,CAAY,EAAA;AAEpC,IAAA,MAAM,QAAA,GAAW,WAAA,CAAY,KAAA,IAAS,WAAA,CAAY,MAAM,MAAA,GAAS,CAAA;AAGjE,IAAA,MAAM,UAAA,GAAaK,4BAAW,MAAA,CAAO;AAAA,MACnC,WAAW,WAAA,CAAY,OAAA;AAAA,MACvB,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,eAAe,cAAA,CAAe,aAAA;AAAA,MAC9B,aAAa,cAAA,CAAe,WAAA;AAAA,MAC5B,UAAU,cAAA,CAAe,QAAA;AAAA,MACzB,QAAQ,cAAA,CAAe,MAAA;AAAA,MACvB,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,QAAQ,cAAA,CAAe,MAAA;AAAA,MACvB,WAAW,cAAA,CAAe,SAAA;AAAA,MAC1B,QAAA,EAAU,IAAA;AAAA;AAAA,MAEV,GAAA,EAAK,QAAA,GAAW,MAAA,GAAY,WAAA,CAAY,QAAA;AAAA,MACxC,OAAO,QAAA,IAAY,WAAA,CAAY,QAAQ,CAAC,WAAA,CAAY,KAAK,CAAA,GAAI,MAAA;AAAA,MAC7D,QAAA,EAAU,QAAA,GAAY,WAAA,CAAY,QAAA,IAAY,YAAY,CAAA,GAAK;AAAA,KAChE,CAAA;AAED,IAAA,UAAA,CAAW,EAAA,CAAG,SAAS,MAAM;AAC3B,MAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA,IACvB,CAAC,CAAA;AAGD,IAAA,UAAA,CAAW,EAAA,CAAG,aAAA,EAAe,CAAC,OAAA,KAAoB;AAChD,MAAA,IAAA,CAAK,OAAO,CAAA;AAAA,IACd,CAAC,CAAA;AAED,IAAA,aAAA,CAAc,OAAA,GAAU,UAAA;AAGxB,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,gBAAA,CAAiB,IAAI,CAAA;AAAA,IACvB;AAEA,IAAA,OAAO,MAAM;AAAA,IAEb,CAAA;AAAA,EACF,CAAA,EAAG;AAAA,IACD,WAAA,EAAa,EAAA;AAAA,IACb,WAAA,EAAa,QAAA;AAAA,IACb,WAAA,EAAa,KAAA;AAAA,IACb,WAAA,EAAa,QAAA;AAAA,IACb,QAAA;AAAA,IACA,IAAA;AAAA,IACA,cAAA,CAAe,SAAA;AAAA,IACf,cAAA,CAAe,aAAA;AAAA,IACf,cAAA,CAAe,WAAA;AAAA,IACf,cAAA,CAAe,QAAA;AAAA,IACf,cAAA,CAAe,MAAA;AAAA,IACf,cAAA,CAAe,SAAA;AAAA,IACf,cAAA,CAAe,MAAA;AAAA,IACf,cAAA,CAAe;AAAA,GAChB,CAAA;AAGD,EAAAL,gBAAU,MAAM;AACd,IAAA,OAAO,MAAM;AACX,MAAA,IAAI,cAAc,OAAA,EAAS;AACzB,QAAA,aAAA,CAAc,QAAQ,OAAA,EAAQ;AAC9B,QAAA,aAAA,CAAc,OAAA,GAAU,IAAA;AAAA,MAC1B;AAAA,IACF,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAGL,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,aAAA,CAAc,OAAA,IAAW,CAAC,aAAA,EAAe;AAE9C,IAAA,MAAM,YAAA,GAAe,aAAA,CAAc,OAAA,CAAQ,WAAA,EAAY;AACvD,IAAA,IAAI,YAAA,GAAe,CAAA,IAAK,WAAA,IAAe,CAAA,EAAG;AACxC,MAAA,MAAM,WAAW,WAAA,GAAc,YAAA;AAC/B,MAAA,aAAA,CAAc,QAAQ,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,CAAC,CAAC,CAAA;AAAA,IACpD;AAAA,EACF,CAAA,EAAG,CAAC,WAAA,EAAa,aAAa,CAAC,CAAA;AAG/B,EAAA,MAAM,kBAAA,GAAqBE,iBAAAA;AAAA,IACzB,CAAC,CAAA,KAA2C;AAC1C,MAAA,SAAA,CAAU,UAAA,CAAW,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,IACtC,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACZ;AAGA,EAAA,MAAM,WAAA,GAAcA,kBAAY,MAAM;AACpC,IAAA,IAAA,EAAK;AACL,IAAA,OAAA,IAAU;AAAA,EACZ,CAAA,EAAG,CAAC,IAAA,EAAM,OAAO,CAAC,CAAA;AAGlB,EAAA,IAAI,CAAC,aAAa,OAAO,IAAA;AAGzB,EAAA,MAAM,gBAAA,GAAmB,cAAc,CAAC,QAAA;AAExC,EAAA,MAAM,aAAA,GAAgB,QAAA,KAAa,KAAA,GAAQ,sBAAA,GAAyB,yBAAA;AAEpE,EAAA,uBACEC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,CAAA,gBAAA,EAAmB,aAAa,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA,EAE3D,QAAA,kBAAAG,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,uBAAA,EAEb,QAAA,EAAA;AAAA,oBAAAH,cAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,UAAA;AAAA,QACT,SAAA,EAAU,sBAAA;AAAA,QACV,YAAA,EAAY,YAAY,OAAA,GAAU,MAAA;AAAA,QAEjC,QAAA,EAAA,SAAA,mBACCG,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,eAAA,EAAgB,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,WAAA,EACzD,QAAA,EAAA;AAAA,0BAAAH,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,GAAA,EAAI,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,CAAA;AAAA,0BAC/CA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,IAAA,EAAK,CAAA,EAAE,GAAA,EAAI,KAAA,EAAM,GAAA,EAAI,MAAA,EAAO,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI;AAAA,SAAA,EAClD,CAAA,mBAEAA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,mCAAA,EAAoC,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAC7E,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,iBAAgB,CAAA,EAC1B;AAAA;AAAA,KAEJ;AAAA,oBAGAG,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,kBAAA,EAEb,QAAA,EAAA;AAAA,sBAAAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EACb,QAAA,EAAA;AAAA,wBAAAH,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EAAkB,sBAAY,KAAA,EAAM,CAAA;AAAA,QAClD,YAAY,KAAA,oBACXG,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EAAiB,QAAA,EAAA;AAAA,UAAA,SAAA;AAAA,UAAG,WAAA,CAAY;AAAA,SAAA,EAAM;AAAA,OAAA,EAEzD,CAAA;AAAA,sBAGAA,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,6BAAA,EACb,QAAA,EAAA;AAAA,wBAAAH,eAAC,MAAA,EAAA,EAAK,SAAA,EAAU,eAAA,EAAiB,QAAA,EAAA,UAAA,CAAW,WAAW,CAAA,EAAE,CAAA;AAAA,wBACzDA,cAAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,WAAA,EAAa,WAAU,mBAAA,EAAoB,CAAA;AAAA,wBACrDA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,eAAA,EAAiB,QAAA,EAAA,UAAA,CAAW,QAAQ,CAAA,EAAE;AAAA,OAAA,EACxD;AAAA,KAAA,EACF,CAAA;AAAA,IAGC,gBAAA,oBACCG,eAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,iBAAA,EACb,QAAA,EAAA;AAAA,sBAAAH,cAAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,SAAS,MAAM,SAAA,CAAU,aAAA,GAAgB,CAAA,GAAI,IAAI,CAAC,CAAA;AAAA,UAClD,SAAA,EAAU,wBAAA;AAAA,UACV,YAAA,EAAY,aAAA,GAAgB,CAAA,GAAI,MAAA,GAAS,QAAA;AAAA,UAExC,QAAA,EAAA,aAAA,KAAkB,CAAA,mBACjBG,eAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EAAuB,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,OAAA,EAAQ,WAAA,EAC9E,QAAA,EAAA;AAAA,4BAAAH,cAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAc,OAAA;AAAA,gBACd,cAAA,EAAe,OAAA;AAAA,gBACf,WAAA,EAAa,CAAA;AAAA,gBACb,CAAA,EAAE;AAAA;AAAA,aACJ;AAAA,4BACAA,cAAAA;AAAA,cAAC,MAAA;AAAA,cAAA;AAAA,gBACC,aAAA,EAAc,OAAA;AAAA,gBACd,cAAA,EAAe,OAAA;AAAA,gBACf,WAAA,EAAa,CAAA;AAAA,gBACb,CAAA,EAAE;AAAA;AAAA;AACJ,WAAA,EACF,CAAA,GACE,aAAA,GAAgB,GAAA,mBAClBA,eAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EAAuB,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,OAAA,EAAQ,aAC9E,QAAA,kBAAAA,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,aAAA,EAAc,OAAA;AAAA,cACd,cAAA,EAAe,OAAA;AAAA,cACf,WAAA,EAAa,CAAA;AAAA,cACb,CAAA,EAAE;AAAA;AAAA,WACJ,EACF,CAAA,mBAEAA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sBAAA,EAAuB,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,OAAA,EAAQ,aAC9E,QAAA,kBAAAA,cAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,aAAA,EAAc,OAAA;AAAA,cACd,cAAA,EAAe,OAAA;AAAA,cACf,WAAA,EAAa,CAAA;AAAA,cACb,CAAA,EAAE;AAAA;AAAA,WACJ,EACF;AAAA;AAAA,OAEJ;AAAA,sBACAA,cAAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,OAAA;AAAA,UACL,GAAA,EAAI,GAAA;AAAA,UACJ,GAAA,EAAI,GAAA;AAAA,UACJ,IAAA,EAAK,MAAA;AAAA,UACL,KAAA,EAAO,aAAA;AAAA,UACP,QAAA,EAAU,kBAAA;AAAA,UACV,SAAA,EAAU,wBAAA;AAAA,UACV,YAAA,EAAW;AAAA;AAAA;AACb,KAAA,EACF,CAAA;AAAA,IAID,6BACCA,cAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,WAAA;AAAA,QACT,SAAA,EAAU,uBAAA;AAAA,QACV,YAAA,EAAW,cAAA;AAAA,QAEX,QAAA,kBAAAA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EAAsB,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,OAAA,EAAQ,WAAA,EAC7E,QAAA,kBAAAA,cAAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAc,OAAA;AAAA,YACd,cAAA,EAAe,OAAA;AAAA,YACf,WAAA,EAAa,CAAA;AAAA,YACb,CAAA,EAAE;AAAA;AAAA,SACJ,EACF;AAAA;AAAA;AACF,GAAA,EAEJ,CAAA,EACF,CAAA;AAEJ;AC3RA,IAAM,eAAA,GAQF;AAAA,EACF,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAA,EAAK,IAAA,KACZ,CAAA,6CAAA,EAAgD,kBAAA,CAAmB,GAAG,CAAC,CAAA,OAAA,EAAU,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA;AAAA,IAC3G,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EAAiB,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAC1D,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,kSAAiS,CAAA,EAC3S;AAAA,GAEJ;AAAA,EACA,OAAA,EAAS;AAAA,IACP,IAAA,EAAM,WAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAA,EAAK,IAAA,KACZ,CAAA,sCAAA,EAAyC,kBAAA,CAAmB,IAAI,CAAC,CAAA,KAAA,EAAQ,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AAAA,IAClG,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EAAiB,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAC1D,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,+JAA8J,CAAA,EACxK;AAAA,GAEJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAA,EAAK,IAAA,KACZ,CAAA,oBAAA,EAAuB,kBAAA,CAAmB,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC,CAAA,CAAA;AAAA,IAC7D,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EAAiB,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAC1D,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,olCAAmlC,CAAA,EAC7lC;AAAA,GAEJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,QAAQ,CAAC,GAAA,EAAK,SACZ,CAAA,oDAAA,EAAuD,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AAAA,IAChF,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EAAiB,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAC1D,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,sfAAqf,CAAA,EAC/f;AAAA,GAEJ;AAAA,EACA,MAAA,EAAQ;AAAA,IACN,IAAA,EAAM,QAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAA,EAAK,IAAA,KACZ,CAAA,kCAAA,EAAqC,kBAAA,CAAmB,GAAG,CAAC,CAAA,OAAA,EAAU,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA;AAAA,IAChG,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EAAiB,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAC1D,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6jCAA4jC,CAAA,EACtkC;AAAA,GAEJ;AAAA,EACA,QAAA,EAAU;AAAA,IACR,IAAA,EAAM,UAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAA,EAAK,IAAA,KACZ,CAAA,2BAAA,EAA8B,kBAAA,CAAmB,GAAG,CAAC,CAAA,MAAA,EAAS,kBAAA,CAAmB,IAAI,CAAC,CAAA,CAAA;AAAA,IACxF,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,gBAAA,EAAiB,IAAA,EAAK,cAAA,EAAe,OAAA,EAAQ,aAC1D,QAAA,kBAAAA,cAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,0nBAAynB,CAAA,EACnoB;AAAA,GAEJ;AAAA,EACA,KAAA,EAAO;AAAA,IACL,IAAA,EAAM,OAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,CAAC,GAAA,EAAK,IAAA,KACZ,CAAA,gBAAA,EAAmB,kBAAA,CAAmB,IAAI,CAAC,CAAA,MAAA,EAAS,kBAAA,CAAmB,CAAA,EAAG,IAAI;;AAAA,EAAO,GAAG,EAAE,CAAC,CAAA,CAAA;AAAA,IAC7F,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EAAiB,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,OAAA,EAAQ,WAAA,EACxE,QAAA,kBAAAA,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,aAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAe,OAAA;AAAA,QACf,WAAA,EAAa,CAAA;AAAA,QACb,CAAA,EAAE;AAAA;AAAA,KACJ,EACF;AAAA,GAEJ;AAAA,EACA,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM,WAAA;AAAA,IACN,KAAA,EAAO,SAAA;AAAA,IACP,QAAQ,MAAM,EAAA;AAAA;AAAA,IACd,IAAA,kBACEA,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gBAAA,EAAiB,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,cAAA,EAAe,OAAA,EAAQ,WAAA,EACxE,QAAA,kBAAAA,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,aAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAe,OAAA;AAAA,QACf,WAAA,EAAa,CAAA;AAAA,QACb,CAAA,EAAE;AAAA;AAAA,KACJ,EACF;AAAA;AAGN,CAAA;AAEA,IAAM,iBAAA,GAAqC;AAAA,EACzC,UAAA;AAAA,EACA,SAAA;AAAA,EACA,UAAA;AAAA,EACA;AACF,CAAA;AAEA,IAAM,SAAA,GAAY,sBAChBA,cAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,SAAA,EAAU,wCAAA;AAAA,IACV,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,OAAA,EAAQ,WAAA;AAAA,IAER,QAAA,kBAAAA,cAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,aAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAe,OAAA;AAAA,QACf,WAAA,EAAa,CAAA;AAAA,QACb,CAAA,EAAE;AAAA;AAAA;AACJ;AACF,CAAA;AAGK,SAAS,YAAA,CAAa;AAAA,EAC3B,GAAA;AAAA,EACA,IAAA,GAAO,EAAA;AAAA,EACP,SAAA,GAAY,iBAAA;AAAA,EACZ,OAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb,SAAA,GAAY;AACd,CAAA,EAAsB;AACpB,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAIF,eAAS,KAAK,CAAA;AAC1C,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA;AAE5C,EAAA,MAAM,WAAA,GAAcC,iBAAAA;AAAA,IAClB,OAAO,QAAA,KAA4B;AACjC,MAAA,UAAA,CAAW,IAAI,CAAA;AAEf,MAAA,IAAI,aAAa,MAAA,EAAQ;AACvB,QAAA,IAAI;AACF,UAAA,MAAM,SAAA,CAAU,SAAA,CAAU,SAAA,CAAU,GAAG,CAAA;AACvC,UAAA,SAAA,CAAU,IAAI,CAAA;AACd,UAAA,UAAA,CAAW,MAAM,SAAA,CAAU,KAAK,CAAA,EAAG,GAAI,CAAA;AACvC,UAAA,OAAA,GAAU,UAAU,GAAG,CAAA;AAAA,QACzB,CAAA,CAAA,MAAQ;AAAA,QAER;AAAA,MACF,CAAA,MAAO;AACL,QAAA,MAAM,MAAA,GAAS,gBAAgB,QAAQ,CAAA;AACvC,QAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,GAAA,EAAK,IAAI,CAAA;AAGxC,QAAA,IAAI,aAAa,OAAA,EAAS;AACxB,UAAA,MAAA,CAAO,SAAS,IAAA,GAAO,QAAA;AAAA,QACzB,CAAA,MAAO;AACL,UAAA,MAAA,CAAO,IAAA,CAAK,QAAA,EAAU,QAAA,EAAU,sBAAsB,CAAA;AAAA,QACxD;AAEA,QAAA,OAAA,GAAU,UAAU,GAAG,CAAA;AAAA,MACzB;AAEA,MAAA,UAAA,CAAW,KAAK,CAAA;AAAA,IAClB,CAAA;AAAA,IACA,CAAC,GAAA,EAAK,IAAA,EAAM,OAAO;AAAA,GACrB;AAEA,EAAA,uBACEC,cAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,CAAA,kBAAA,EAAqB,SAAS,CAAA,CAAA,EAC3C,QAAA,EAAA,SAAA,CAAU,GAAA,CAAI,CAAC,QAAA,KAAa;AAC3B,IAAA,MAAM,MAAA,GAAS,gBAAgB,QAAQ,CAAA;AACvC,IAAA,IAAI,CAAC,QAAQ,OAAO,IAAA;AAEpB,IAAA,MAAM,eAAe,QAAA,KAAa,MAAA;AAClC,IAAA,MAAM,YAAY,YAAA,IAAgB,MAAA;AAElC,IAAA,uBACEG,eAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QAEC,OAAA,EAAS,MAAM,WAAA,CAAY,QAAQ,CAAA;AAAA,QACnC,QAAA,EAAU,OAAA;AAAA,QACV,SAAA,EAAU,kBAAA;AAAA,QACV,KAAA,EAAO,EAAE,yBAAA,EAA2B,MAAA,CAAO,KAAA,EAAM;AAAA,QACjD,KAAA,EAAO,SAAA,GAAY,SAAA,GAAY,MAAA,CAAO,IAAA;AAAA,QACtC,YAAA,EAAY,CAAA,UAAA,EAAa,MAAA,CAAO,IAAI,CAAA,CAAA;AAAA,QAEnC,QAAA,EAAA;AAAA,UAAA,SAAA,mBAAYH,cAAAA,CAAC,SAAA,EAAA,EAAU,CAAA,GAAK,MAAA,CAAO,IAAA;AAAA,UACnC,UAAA,oBACCA,cAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,iBAAA,EACb,QAAA,EAAA,SAAA,GAAY,SAAA,GAAY,MAAA,CAAO,IAAA,EAClC;AAAA;AAAA,OAAA;AAAA,MAZG;AAAA,KAcP;AAAA,EAEJ,CAAC,CAAA,EACH,CAAA;AAEJ","file":"index.js","sourcesContent":["'use client';\n\nimport {\n createContext,\n useContext,\n useRef,\n useState,\n useCallback,\n useEffect,\n ReactNode,\n} from 'react';\nimport type {\n Song,\n AudioPlayerState,\n AudioPlayerContextValue,\n AudioPlayerConfig,\n} from '../types';\n\n// Custom event for notifying WaveformPlayers when mini-player starts playing\nexport const MINI_PLAYER_PLAY_EVENT = 'wavesurfer-player-mini-play';\n\nconst AudioPlayerContext = createContext<AudioPlayerContextValue | null>(null);\n\nconst DEFAULT_CONFIG: Required<AudioPlayerConfig> = {\n fadeInEnabled: true,\n fadeInDuration: 3000,\n persistVolume: true,\n storageKey: 'audioPlayerVolume',\n defaultVolume: 1,\n onPlay: () => {},\n onPause: () => {},\n onEnd: () => {},\n onTimeUpdate: () => {},\n};\n\nconst FADE_STEPS = 30; // 30 steps for smooth fade\nconst MIN_FADE_IN_VOLUME = 0.1; // Minimum 10% volume on fade-in so users hear something\n\ninterface AudioPlayerProviderProps {\n children: ReactNode;\n config?: AudioPlayerConfig;\n}\n\nexport function AudioPlayerProvider({\n children,\n config: userConfig,\n}: AudioPlayerProviderProps) {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const fadeIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const configRef = useRef(config);\n\n // Keep config ref up to date\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n const [state, setState] = useState<AudioPlayerState>({\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: config.defaultVolume,\n displayVolume: config.defaultVolume,\n isFadingIn: false,\n });\n\n // Initialize audio element and load saved volume\n useEffect(() => {\n // Create audio element\n const audio = new Audio();\n audio.preload = 'metadata';\n audioRef.current = audio;\n\n // Load saved volume from localStorage if persistence is enabled\n if (config.persistVolume && typeof window !== 'undefined') {\n const savedVolume = localStorage.getItem(config.storageKey);\n if (savedVolume) {\n const vol = parseFloat(savedVolume);\n if (!isNaN(vol) && vol >= 0 && vol <= 1) {\n setState((s) => ({ ...s, volume: vol, displayVolume: vol }));\n audio.volume = vol;\n }\n }\n }\n\n // Audio event listeners\n const handleTimeUpdate = () => {\n setState((s) => ({ ...s, currentTime: audio.currentTime }));\n configRef.current.onTimeUpdate?.(audio.currentTime);\n };\n\n const handleLoadedMetadata = () => {\n setState((s) => ({ ...s, duration: audio.duration }));\n };\n\n const handleEnded = () => {\n setState((s) => ({ ...s, isPlaying: false, currentTime: 0 }));\n configRef.current.onEnd?.();\n };\n\n const handlePlay = () => {\n setState((s) => ({ ...s, isPlaying: true }));\n };\n\n const handlePause = () => {\n setState((s) => ({ ...s, isPlaying: false }));\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('loadedmetadata', handleLoadedMetadata);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n\n return () => {\n // Cleanup\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n }\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('loadedmetadata', handleLoadedMetadata);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.pause();\n audio.src = '';\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Clear any existing fade interval\n const clearFade = useCallback(() => {\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n fadeIntervalRef.current = null;\n }\n }, []);\n\n // Fade in volume\n const fadeInVolume = useCallback(\n (targetVolume: number) => {\n if (!audioRef.current) return;\n\n clearFade();\n setState((s) => ({ ...s, isFadingIn: true, displayVolume: 0 }));\n\n const fadeStepDuration = configRef.current.fadeInDuration / FADE_STEPS;\n const volumeStep = targetVolume / FADE_STEPS;\n let currentStep = 0;\n\n fadeIntervalRef.current = setInterval(() => {\n currentStep++;\n const newVolume = Math.min(volumeStep * currentStep, targetVolume);\n if (audioRef.current) {\n audioRef.current.volume = newVolume;\n }\n // Update displayVolume so the slider follows the fade\n setState((s) => ({ ...s, displayVolume: newVolume }));\n\n if (currentStep >= FADE_STEPS) {\n clearFade();\n setState((s) => ({\n ...s,\n isFadingIn: false,\n displayVolume: targetVolume,\n }));\n }\n }, fadeStepDuration);\n },\n [clearFade]\n );\n\n // Play a song with optional fade-in\n const play = useCallback(\n async (song: Song) => {\n if (!audioRef.current) return;\n\n // Stop any current fade-in\n clearFade();\n\n // If it's a different song, load it\n if (state.currentSong?.id !== song.id) {\n audioRef.current.src = song.audioUrl;\n setState((s) => ({\n ...s,\n currentSong: song,\n currentTime: 0,\n duration: song.duration || 0,\n }));\n }\n\n // Determine target volume\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n // Set initial volume based on fade setting\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n } else {\n audioRef.current.volume = targetVolume;\n }\n\n try {\n await audioRef.current.play();\n // Dispatch event to pause other players\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })\n );\n }\n // Start fade-in if enabled\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n // Call onPlay callback\n configRef.current.onPlay?.(song);\n } catch {\n // Handle autoplay restrictions silently\n }\n },\n [state.currentSong?.id, state.volume, clearFade, fadeInVolume]\n );\n\n // Pause playback\n const pause = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n configRef.current.onPause?.();\n }, [clearFade]);\n\n // Toggle play/pause\n const togglePlay = useCallback(() => {\n if (!audioRef.current || !state.currentSong) return;\n\n if (state.isPlaying) {\n pause();\n } else {\n // Resume with fade-in if enabled\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n }\n\n audioRef.current\n .play()\n .then(() => {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, {\n detail: state.currentSong?.id,\n })\n );\n }\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n })\n .catch(() => {\n // Handle autoplay restrictions silently\n });\n }\n }, [state.isPlaying, state.currentSong, state.volume, pause, fadeInVolume]);\n\n // Seek to position\n const seek = useCallback((time: number) => {\n if (!audioRef.current) return;\n audioRef.current.currentTime = time;\n setState((s) => ({ ...s, currentTime: time }));\n }, []);\n\n // Set volume and persist to localStorage\n const setVolume = useCallback(\n (volume: number) => {\n if (!audioRef.current) return;\n\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n // If user manually changes volume during fade, stop the fade\n if (fadeIntervalRef.current) {\n clearFade();\n setState((s) => ({ ...s, isFadingIn: false }));\n }\n\n audioRef.current.volume = clampedVolume;\n\n // Persist to localStorage if enabled\n if (configRef.current.persistVolume && typeof window !== 'undefined') {\n localStorage.setItem(\n configRef.current.storageKey,\n clampedVolume.toString()\n );\n }\n\n setState((s) => ({\n ...s,\n volume: clampedVolume,\n displayVolume: clampedVolume,\n }));\n },\n [clearFade]\n );\n\n // Stop playback and clear song\n const stop = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n audioRef.current.currentTime = 0;\n audioRef.current.src = '';\n setState((s) => ({\n ...s,\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n isFadingIn: false,\n }));\n }, [clearFade]);\n\n const value: AudioPlayerContextValue = {\n ...state,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n stop,\n };\n\n return (\n <AudioPlayerContext.Provider value={value}>\n {children}\n </AudioPlayerContext.Provider>\n );\n}\n\nexport function useAudioPlayer(): AudioPlayerContextValue {\n const context = useContext(AudioPlayerContext);\n if (!context) {\n throw new Error(\n 'useAudioPlayer must be used within an AudioPlayerProvider'\n );\n }\n return context;\n}\n","'use client';\n\nimport { useRef, useState, useEffect } from 'react';\nimport type { UseLazyLoadResult, UseLazyLoadOptions } from '../types';\n\n/**\n * Hook for lazy loading elements using IntersectionObserver.\n * Returns a ref to attach to the target element and a boolean indicating visibility.\n *\n * @param options - Configuration options for the IntersectionObserver\n * @returns Object containing ref and isVisible state\n *\n * @example\n * const { ref, isVisible } = useLazyLoad();\n *\n * return (\n * <div ref={ref}>\n * {isVisible && <ExpensiveComponent />}\n * </div>\n * );\n */\nexport function useLazyLoad(options?: UseLazyLoadOptions): UseLazyLoadResult {\n const {\n rootMargin = '100px',\n threshold = 0,\n forceVisible = false,\n } = options || {};\n\n const ref = useRef<HTMLDivElement>(null);\n const [isVisible, setIsVisible] = useState(forceVisible);\n\n useEffect(() => {\n if (forceVisible) {\n setIsVisible(true);\n return;\n }\n\n if (!ref.current) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsVisible(true);\n observer.disconnect(); // Only need to detect once\n }\n },\n { rootMargin, threshold }\n );\n\n observer.observe(ref.current);\n\n return () => observer.disconnect();\n }, [rootMargin, threshold, forceVisible]);\n\n return { ref, isVisible };\n}\n","/**\n * Formats seconds into a human-readable time string (M:SS or MM:SS).\n *\n * @param seconds - The number of seconds to format\n * @returns Formatted time string (e.g., \"3:45\" or \"12:05\")\n *\n * @example\n * formatTime(125) // \"2:05\"\n * formatTime(0) // \"0:00\"\n * formatTime(3600) // \"60:00\"\n */\nexport function formatTime(seconds: number): string {\n if (!seconds || isNaN(seconds) || seconds < 0) return '0:00';\n\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","'use client';\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer, MINI_PLAYER_PLAY_EVENT } from '../context/AudioPlayerContext';\nimport { useLazyLoad } from '../hooks/useLazyLoad';\nimport { formatTime } from '../utils/formatTime';\nimport type { WaveformPlayerProps, WaveformConfig } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: '#D4AF37',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 60,\n normalize: true,\n};\n\nexport function WaveformPlayer({\n song,\n waveformConfig: userWaveformConfig,\n lazyLoad = true,\n showTime = true,\n className = '',\n renderHeader,\n renderControls,\n}: WaveformPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n const containerRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [totalDuration, setTotalDuration] = useState(song.duration || 0);\n\n // Lazy loading\n const { ref: wrapperRef, isVisible } = useLazyLoad({\n forceVisible: !lazyLoad,\n });\n\n // Get audio player context for global playback control\n const {\n play: contextPlay,\n togglePlay: contextTogglePlay,\n seek: contextSeek,\n currentSong,\n isPlaying: contextIsPlaying,\n currentTime: contextCurrentTime,\n } = useAudioPlayer();\n\n // Check if this song is the currently playing song\n const isThisSongPlaying = currentSong?.id === song.id;\n const isPlaying = isThisSongPlaying && contextIsPlaying;\n const currentTime = isThisSongPlaying ? contextCurrentTime : 0;\n\n // Sync waveform progress with context when this song is playing\n useEffect(() => {\n if (!wavesurferRef.current || !isThisSongPlaying) return;\n\n // Update waveform progress to match context time\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && contextCurrentTime >= 0) {\n const progress = contextCurrentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [contextCurrentTime, isThisSongPlaying]);\n\n // Initialize WaveSurfer - waveform display only (audio plays through context)\n useEffect(() => {\n if (!containerRef.current || !isVisible) return;\n\n const hasPeaks = song.peaks && song.peaks.length > 0;\n\n // Create WaveSurfer for waveform display only (no audio playback)\n const wavesurfer = WaveSurfer.create({\n container: containerRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true, // Allow clicking on waveform to seek\n // Only load audio URL if we don't have peaks (needed to generate waveform)\n url: hasPeaks ? undefined : song.audioUrl,\n peaks: hasPeaks ? [song.peaks!] : undefined,\n duration: hasPeaks ? (song.duration || 0) : undefined,\n });\n\n wavesurfer.on('ready', () => {\n setIsReady(true);\n setTotalDuration(wavesurfer.getDuration() || song.duration || 0);\n });\n\n // Handle waveform click for seeking\n wavesurfer.on('interaction', (newTime: number) => {\n // Only seek if this song is currently playing in the context\n if (isThisSongPlaying) {\n contextSeek(newTime);\n }\n });\n\n wavesurfer.on('error', () => {\n // Silently handle errors\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark as ready immediately\n if (hasPeaks) {\n setIsReady(true);\n setTotalDuration(song.duration || 0);\n }\n\n return () => {\n try {\n wavesurfer.destroy();\n } catch {\n // Ignore errors when component unmounts\n }\n };\n }, [\n song.audioUrl,\n song.peaks,\n song.duration,\n isVisible,\n isThisSongPlaying,\n contextSeek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Handle play button click - plays through global context\n const handlePlayClick = useCallback(() => {\n if (!song.id || !song.audioUrl) return;\n\n if (isThisSongPlaying) {\n // This song is already loaded - toggle play/pause\n contextTogglePlay();\n } else {\n // Play this song through the global context\n contextPlay(song);\n }\n }, [song, isThisSongPlaying, contextPlay, contextTogglePlay]);\n\n return (\n <div\n ref={wrapperRef}\n className={`wsp-player ${className}`}\n data-song-id={song.id}\n >\n {/* Custom header or default */}\n {renderHeader ? (\n renderHeader(song, isPlaying)\n ) : (\n <div className=\"wsp-player-header\">\n <h3 className=\"wsp-player-title\">{song.title}</h3>\n {song.artist && (\n <span className=\"wsp-player-artist\">{song.artist}</span>\n )}\n </div>\n )}\n\n {/* Player controls and waveform */}\n <div className=\"wsp-player-controls\">\n {/* Play/Pause button */}\n <button\n onClick={handlePlayClick}\n disabled={!isReady}\n className={`wsp-play-button ${isReady ? 'wsp-play-button--ready' : ''}`}\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {!isReady ? (\n <svg className=\"wsp-icon wsp-icon--spinner\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle\n className=\"wsp-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"wsp-spinner-head\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n ) : isPlaying ? (\n <svg className=\"wsp-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-icon wsp-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Waveform container */}\n <div className=\"wsp-waveform-wrapper\">\n <div ref={containerRef} className=\"wsp-waveform\" />\n\n {/* Time display */}\n {showTime && (\n <div className=\"wsp-time-display\">\n <span className=\"wsp-time\">{formatTime(currentTime)}</span>\n <span className=\"wsp-time\">{formatTime(totalDuration)}</span>\n </div>\n )}\n </div>\n\n {/* Custom controls slot */}\n {renderControls && renderControls(song, isPlaying)}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useRef, useEffect, useState } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer } from '../context/AudioPlayerContext';\nimport { formatTime } from '../utils/formatTime';\nimport type { MiniPlayerProps, WaveformConfig } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: 'transparent',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 40,\n normalize: true,\n};\n\nexport function MiniPlayer({\n position = 'bottom',\n showVolume = true,\n showClose = true,\n onClose,\n className = '',\n waveformConfig: userWaveformConfig,\n}: MiniPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n\n const {\n currentSong,\n isPlaying,\n currentTime,\n duration,\n displayVolume,\n togglePlay,\n seek,\n setVolume,\n stop,\n } = useAudioPlayer();\n\n const waveformRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const [isMobile, setIsMobile] = useState(false);\n const [waveformReady, setWaveformReady] = useState(false);\n const lastSongIdRef = useRef<string | null>(null);\n\n // Detect mobile viewport\n useEffect(() => {\n const checkMobile = () => setIsMobile(window.innerWidth < 640);\n checkMobile();\n window.addEventListener('resize', checkMobile);\n return () => window.removeEventListener('resize', checkMobile);\n }, []);\n\n // Initialize/update WaveSurfer when song changes\n useEffect(() => {\n if (!waveformRef.current || !currentSong) return;\n\n // If same song, don't recreate\n if (lastSongIdRef.current === currentSong.id && wavesurferRef.current) {\n return;\n }\n\n // Destroy previous instance\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n\n setWaveformReady(false);\n lastSongIdRef.current = currentSong.id;\n\n const hasPeaks = currentSong.peaks && currentSong.peaks.length > 0;\n\n // Create WaveSurfer - waveform only, no audio (audio plays through context)\n const wavesurfer = WaveSurfer.create({\n container: waveformRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true,\n // Use peaks if available, otherwise need audio URL to generate waveform\n url: hasPeaks ? undefined : currentSong.audioUrl,\n peaks: hasPeaks && currentSong.peaks ? [currentSong.peaks] : undefined,\n duration: hasPeaks ? (currentSong.duration || duration || 0) : undefined,\n });\n\n wavesurfer.on('ready', () => {\n setWaveformReady(true);\n });\n\n // Handle click on waveform to seek\n wavesurfer.on('interaction', (newTime: number) => {\n seek(newTime);\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark ready immediately\n if (hasPeaks) {\n setWaveformReady(true);\n }\n\n return () => {\n // Don't destroy on every render, only when song actually changes\n };\n }, [\n currentSong?.id,\n currentSong?.audioUrl,\n currentSong?.peaks,\n currentSong?.duration,\n duration,\n seek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n };\n }, []);\n\n // Sync waveform progress with audio context\n useEffect(() => {\n if (!wavesurferRef.current || !waveformReady) return;\n\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && currentTime >= 0) {\n const progress = currentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [currentTime, waveformReady]);\n\n // Handle volume change\n const handleVolumeChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setVolume(parseFloat(e.target.value));\n },\n [setVolume]\n );\n\n // Handle close button\n const handleClose = useCallback(() => {\n stop();\n onClose?.();\n }, [stop, onClose]);\n\n // Don't render if no song is loaded\n if (!currentSong) return null;\n\n // Determine if volume should be shown (respects both prop and mobile detection)\n const shouldShowVolume = showVolume && !isMobile;\n\n const positionClass = position === 'top' ? 'wsp-mini-player--top' : 'wsp-mini-player--bottom';\n\n return (\n <div className={`wsp-mini-player ${positionClass} ${className}`}>\n {/* Main controls */}\n <div className=\"wsp-mini-player-inner\">\n {/* Play/pause button - left */}\n <button\n onClick={togglePlay}\n className=\"wsp-mini-play-button\"\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {isPlaying ? (\n <svg className=\"wsp-mini-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-mini-icon wsp-mini-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Song info and waveform - center */}\n <div className=\"wsp-mini-content\">\n {/* Song title */}\n <div className=\"wsp-mini-info\">\n <div className=\"wsp-mini-title\">{currentSong.title}</div>\n {currentSong.album && (\n <div className=\"wsp-mini-album\">• {currentSong.album}</div>\n )}\n </div>\n\n {/* Waveform */}\n <div className=\"wsp-mini-waveform-container\">\n <span className=\"wsp-mini-time\">{formatTime(currentTime)}</span>\n <div ref={waveformRef} className=\"wsp-mini-waveform\" />\n <span className=\"wsp-mini-time\">{formatTime(duration)}</span>\n </div>\n </div>\n\n {/* Volume slider - hidden on mobile */}\n {shouldShowVolume && (\n <div className=\"wsp-mini-volume\">\n <button\n onClick={() => setVolume(displayVolume > 0 ? 0 : 1)}\n className=\"wsp-mini-volume-button\"\n aria-label={displayVolume > 0 ? 'Mute' : 'Unmute'}\n >\n {displayVolume === 0 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2\"\n />\n </svg>\n ) : displayVolume < 0.5 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n ) : (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n value={displayVolume}\n onChange={handleVolumeChange}\n className=\"wsp-mini-volume-slider\"\n aria-label=\"Volume\"\n />\n </div>\n )}\n\n {/* Close button */}\n {showClose && (\n <button\n onClick={handleClose}\n className=\"wsp-mini-close-button\"\n aria-label=\"Close player\"\n >\n <svg className=\"wsp-mini-close-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport type { ShareButtonsProps, SharePlatform } from '../types';\n\nconst PLATFORM_CONFIG: Record<\n SharePlatform,\n {\n name: string;\n color: string;\n getUrl: (url: string, text: string) => string;\n icon: JSX.Element;\n }\n> = {\n facebook: {\n name: 'Facebook',\n color: '#1877F2',\n getUrl: (url, text) =>\n `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}"e=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\" />\n </svg>\n ),\n },\n twitter: {\n name: 'Twitter/X',\n color: '#1DA1F2',\n getUrl: (url, text) =>\n `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\n </svg>\n ),\n },\n whatsapp: {\n name: 'WhatsApp',\n color: '#25D366',\n getUrl: (url, text) =>\n `https://wa.me/?text=${encodeURIComponent(`${text} ${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z\" />\n </svg>\n ),\n },\n linkedin: {\n name: 'LinkedIn',\n color: '#0A66C2',\n getUrl: (url, text) =>\n `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n ),\n },\n reddit: {\n name: 'Reddit',\n color: '#FF4500',\n getUrl: (url, text) =>\n `https://www.reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z\" />\n </svg>\n ),\n },\n telegram: {\n name: 'Telegram',\n color: '#0088CC',\n getUrl: (url, text) =>\n `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\" />\n </svg>\n ),\n },\n email: {\n name: 'Email',\n color: '#666666',\n getUrl: (url, text) =>\n `mailto:?subject=${encodeURIComponent(text)}&body=${encodeURIComponent(`${text}\\n\\n${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n copy: {\n name: 'Copy Link',\n color: '#666666',\n getUrl: () => '', // Not used for copy\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n};\n\nconst DEFAULT_PLATFORMS: SharePlatform[] = [\n 'facebook',\n 'twitter',\n 'whatsapp',\n 'copy',\n];\n\nconst CheckIcon = () => (\n <svg\n className=\"wsp-share-icon wsp-share-icon--success\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n);\n\nexport function ShareButtons({\n url,\n text = '',\n platforms = DEFAULT_PLATFORMS,\n onShare,\n showLabels = false,\n className = '',\n}: ShareButtonsProps) {\n const [copied, setCopied] = useState(false);\n const [sharing, setSharing] = useState(false);\n\n const handleShare = useCallback(\n async (platform: SharePlatform) => {\n setSharing(true);\n\n if (platform === 'copy') {\n try {\n await navigator.clipboard.writeText(url);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n onShare?.(platform, url);\n } catch {\n // Clipboard may not be available\n }\n } else {\n const config = PLATFORM_CONFIG[platform];\n const shareUrl = config.getUrl(url, text);\n\n // Open share dialog\n if (platform === 'email') {\n window.location.href = shareUrl;\n } else {\n window.open(shareUrl, '_blank', 'width=600,height=400');\n }\n\n onShare?.(platform, url);\n }\n\n setSharing(false);\n },\n [url, text, onShare]\n );\n\n return (\n <div className={`wsp-share-buttons ${className}`}>\n {platforms.map((platform) => {\n const config = PLATFORM_CONFIG[platform];\n if (!config) return null;\n\n const isCopyButton = platform === 'copy';\n const showCheck = isCopyButton && copied;\n\n return (\n <button\n key={platform}\n onClick={() => handleShare(platform)}\n disabled={sharing}\n className=\"wsp-share-button\"\n style={{ '--wsp-share-hover-color': config.color } as React.CSSProperties}\n title={showCheck ? 'Copied!' : config.name}\n aria-label={`Share via ${config.name}`}\n >\n {showCheck ? <CheckIcon /> : config.icon}\n {showLabels && (\n <span className=\"wsp-share-label\">\n {showCheck ? 'Copied!' : config.name}\n </span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context/AudioPlayerContext.tsx","../src/hooks/useLazyLoad.ts","../src/utils/formatTime.ts","../src/components/WaveformPlayer.tsx","../src/components/MiniPlayer.tsx","../src/components/ShareButtons.tsx"],"names":["createContext","useRef","useEffect","useState","useCallback","jsx","useContext","WaveSurfer","jsxs","DEFAULT_WAVEFORM_CONFIG"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport {\n createContext,\n useContext,\n useRef,\n useState,\n useCallback,\n useEffect,\n ReactNode,\n} from 'react';\nimport type {\n Song,\n AudioPlayerState,\n AudioPlayerContextValue,\n AudioPlayerConfig,\n} from '../types';\n\n// Custom event for notifying WaveformPlayers when mini-player starts playing\nexport const MINI_PLAYER_PLAY_EVENT = 'wavesurfer-player-mini-play';\n\nconst AudioPlayerContext = createContext<AudioPlayerContextValue | null>(null);\n\nconst DEFAULT_CONFIG: Required<AudioPlayerConfig> = {\n fadeInEnabled: true,\n fadeInDuration: 3000,\n persistVolume: true,\n storageKey: 'audioPlayerVolume',\n defaultVolume: 1,\n onPlay: () => {},\n onPause: () => {},\n onEnd: () => {},\n onTimeUpdate: () => {},\n};\n\nconst FADE_STEPS = 30; // 30 steps for smooth fade\nconst MIN_FADE_IN_VOLUME = 0.1; // Minimum 10% volume on fade-in so users hear something\n\ninterface AudioPlayerProviderProps {\n children: ReactNode;\n config?: AudioPlayerConfig;\n}\n\nexport function AudioPlayerProvider({\n children,\n config: userConfig,\n}: AudioPlayerProviderProps) {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const fadeIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const configRef = useRef(config);\n\n // Keep config ref up to date\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n const [state, setState] = useState<AudioPlayerState>({\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: config.defaultVolume,\n displayVolume: config.defaultVolume,\n isFadingIn: false,\n });\n\n // Initialize audio element and load saved volume\n useEffect(() => {\n // Create audio element\n const audio = new Audio();\n audio.preload = 'metadata';\n audioRef.current = audio;\n\n // Load saved volume from localStorage if persistence is enabled\n if (config.persistVolume && typeof window !== 'undefined') {\n const savedVolume = localStorage.getItem(config.storageKey);\n if (savedVolume) {\n const vol = parseFloat(savedVolume);\n if (!isNaN(vol) && vol >= 0 && vol <= 1) {\n setState((s) => ({ ...s, volume: vol, displayVolume: vol }));\n audio.volume = vol;\n }\n }\n }\n\n // Audio event listeners\n const handleTimeUpdate = () => {\n setState((s) => ({ ...s, currentTime: audio.currentTime }));\n configRef.current.onTimeUpdate?.(audio.currentTime);\n };\n\n const handleLoadedMetadata = () => {\n setState((s) => ({ ...s, duration: audio.duration }));\n };\n\n const handleEnded = () => {\n setState((s) => ({ ...s, isPlaying: false, currentTime: 0 }));\n configRef.current.onEnd?.();\n };\n\n const handlePlay = () => {\n setState((s) => ({ ...s, isPlaying: true }));\n };\n\n const handlePause = () => {\n setState((s) => ({ ...s, isPlaying: false }));\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('loadedmetadata', handleLoadedMetadata);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n\n return () => {\n // Cleanup\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n }\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('loadedmetadata', handleLoadedMetadata);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.pause();\n audio.src = '';\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Clear any existing fade interval\n const clearFade = useCallback(() => {\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n fadeIntervalRef.current = null;\n }\n }, []);\n\n // Fade in volume\n const fadeInVolume = useCallback(\n (targetVolume: number) => {\n if (!audioRef.current) return;\n\n clearFade();\n setState((s) => ({ ...s, isFadingIn: true, displayVolume: 0 }));\n\n const fadeStepDuration = configRef.current.fadeInDuration / FADE_STEPS;\n const volumeStep = targetVolume / FADE_STEPS;\n let currentStep = 0;\n\n fadeIntervalRef.current = setInterval(() => {\n currentStep++;\n const newVolume = Math.min(volumeStep * currentStep, targetVolume);\n if (audioRef.current) {\n audioRef.current.volume = newVolume;\n }\n // Update displayVolume so the slider follows the fade\n setState((s) => ({ ...s, displayVolume: newVolume }));\n\n if (currentStep >= FADE_STEPS) {\n clearFade();\n setState((s) => ({\n ...s,\n isFadingIn: false,\n displayVolume: targetVolume,\n }));\n }\n }, fadeStepDuration);\n },\n [clearFade]\n );\n\n // Play a song with optional fade-in\n const play = useCallback(\n async (song: Song) => {\n if (!audioRef.current) return;\n\n // Stop any current fade-in\n clearFade();\n\n // If it's a different song, load it\n if (state.currentSong?.id !== song.id) {\n audioRef.current.src = song.audioUrl;\n setState((s) => ({\n ...s,\n currentSong: song,\n currentTime: 0,\n duration: song.duration || 0,\n }));\n }\n\n // Determine target volume\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n // Set initial volume based on fade setting\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n } else {\n audioRef.current.volume = targetVolume;\n }\n\n try {\n await audioRef.current.play();\n // Dispatch event to pause other players\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })\n );\n }\n // Start fade-in if enabled\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n // Call onPlay callback\n configRef.current.onPlay?.(song);\n } catch {\n // Handle autoplay restrictions silently\n }\n },\n [state.currentSong?.id, state.volume, clearFade, fadeInVolume]\n );\n\n // Pause playback\n const pause = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n configRef.current.onPause?.();\n }, [clearFade]);\n\n // Toggle play/pause\n const togglePlay = useCallback(() => {\n if (!audioRef.current || !state.currentSong) return;\n\n if (state.isPlaying) {\n pause();\n } else {\n // Resume with fade-in if enabled\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n }\n\n audioRef.current\n .play()\n .then(() => {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, {\n detail: state.currentSong?.id,\n })\n );\n }\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n })\n .catch(() => {\n // Handle autoplay restrictions silently\n });\n }\n }, [state.isPlaying, state.currentSong, state.volume, pause, fadeInVolume]);\n\n // Seek to position\n const seek = useCallback((time: number) => {\n if (!audioRef.current) return;\n audioRef.current.currentTime = time;\n setState((s) => ({ ...s, currentTime: time }));\n }, []);\n\n // Set volume and persist to localStorage\n const setVolume = useCallback(\n (volume: number) => {\n if (!audioRef.current) return;\n\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n // If user manually changes volume during fade, stop the fade\n if (fadeIntervalRef.current) {\n clearFade();\n setState((s) => ({ ...s, isFadingIn: false }));\n }\n\n audioRef.current.volume = clampedVolume;\n\n // Persist to localStorage if enabled\n if (configRef.current.persistVolume && typeof window !== 'undefined') {\n localStorage.setItem(\n configRef.current.storageKey,\n clampedVolume.toString()\n );\n }\n\n setState((s) => ({\n ...s,\n volume: clampedVolume,\n displayVolume: clampedVolume,\n }));\n },\n [clearFade]\n );\n\n // Stop playback and clear song\n const stop = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n audioRef.current.currentTime = 0;\n audioRef.current.src = '';\n setState((s) => ({\n ...s,\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n isFadingIn: false,\n }));\n }, [clearFade]);\n\n const value: AudioPlayerContextValue = {\n ...state,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n stop,\n };\n\n return (\n <AudioPlayerContext.Provider value={value}>\n {children}\n </AudioPlayerContext.Provider>\n );\n}\n\nexport function useAudioPlayer(): AudioPlayerContextValue {\n const context = useContext(AudioPlayerContext);\n if (!context) {\n throw new Error(\n 'useAudioPlayer must be used within an AudioPlayerProvider'\n );\n }\n return context;\n}\n","'use client';\n\nimport { useRef, useState, useEffect } from 'react';\nimport type { UseLazyLoadResult, UseLazyLoadOptions } from '../types';\n\n/**\n * Hook for lazy loading elements using IntersectionObserver.\n * Returns a ref to attach to the target element and a boolean indicating visibility.\n *\n * @param options - Configuration options for the IntersectionObserver\n * @returns Object containing ref and isVisible state\n *\n * @example\n * const { ref, isVisible } = useLazyLoad();\n *\n * return (\n * <div ref={ref}>\n * {isVisible && <ExpensiveComponent />}\n * </div>\n * );\n */\nexport function useLazyLoad(options?: UseLazyLoadOptions): UseLazyLoadResult {\n const {\n rootMargin = '100px',\n threshold = 0,\n forceVisible = false,\n } = options || {};\n\n const ref = useRef<HTMLDivElement>(null);\n const [isVisible, setIsVisible] = useState(forceVisible);\n\n useEffect(() => {\n if (forceVisible) {\n setIsVisible(true);\n return;\n }\n\n if (!ref.current) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsVisible(true);\n observer.disconnect(); // Only need to detect once\n }\n },\n { rootMargin, threshold }\n );\n\n observer.observe(ref.current);\n\n return () => observer.disconnect();\n }, [rootMargin, threshold, forceVisible]);\n\n return { ref, isVisible };\n}\n","/**\n * Formats seconds into a human-readable time string (M:SS or MM:SS).\n *\n * @param seconds - The number of seconds to format\n * @returns Formatted time string (e.g., \"3:45\" or \"12:05\")\n *\n * @example\n * formatTime(125) // \"2:05\"\n * formatTime(0) // \"0:00\"\n * formatTime(3600) // \"60:00\"\n */\nexport function formatTime(seconds: number): string {\n if (!seconds || isNaN(seconds) || seconds < 0) return '0:00';\n\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","'use client';\n\nimport { useEffect, useRef, useState, useCallback, useContext, createContext } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer, MINI_PLAYER_PLAY_EVENT } from '../context/AudioPlayerContext';\nimport { useLazyLoad } from '../hooks/useLazyLoad';\nimport { formatTime } from '../utils/formatTime';\nimport type { WaveformPlayerProps, WaveformConfig, Song } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: '#D4AF37',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 60,\n normalize: true,\n};\n\n// Check if we're inside an AudioPlayerProvider\nconst AudioPlayerContext = createContext<unknown>(null);\n\nexport function WaveformPlayer({\n song,\n waveformConfig: userWaveformConfig,\n lazyLoad = true,\n showTime = true,\n className = '',\n renderHeader,\n renderControls,\n standalone = false,\n}: WaveformPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n const containerRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const localAudioRef = useRef<HTMLAudioElement | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [totalDuration, setTotalDuration] = useState(song.duration || 0);\n\n // Standalone mode state\n const [localIsPlaying, setLocalIsPlaying] = useState(false);\n const [localCurrentTime, setLocalCurrentTime] = useState(0);\n\n // Lazy loading\n const { ref: wrapperRef, isVisible } = useLazyLoad({\n forceVisible: !lazyLoad,\n });\n\n // Try to get audio player context (may not exist in standalone mode)\n let contextValue: ReturnType<typeof useAudioPlayer> | null = null;\n try {\n if (!standalone) {\n contextValue = useAudioPlayer();\n }\n } catch {\n // Context not available, use standalone mode\n }\n\n const useStandaloneMode = standalone || !contextValue;\n\n // Context values (only used when not in standalone mode)\n const contextPlay = contextValue?.play;\n const contextTogglePlay = contextValue?.togglePlay;\n const contextSeek = contextValue?.seek;\n const contextCurrentSong = contextValue?.currentSong;\n const contextIsPlaying = contextValue?.isPlaying ?? false;\n const contextCurrentTime = contextValue?.currentTime ?? 0;\n\n // Check if this song is the currently playing song (context mode)\n const isThisSongPlayingInContext = !useStandaloneMode && contextCurrentSong?.id === song.id;\n\n // Determine actual playing state and current time\n const isPlaying = useStandaloneMode ? localIsPlaying : (isThisSongPlayingInContext && contextIsPlaying);\n const currentTime = useStandaloneMode ? localCurrentTime : (isThisSongPlayingInContext ? contextCurrentTime : 0);\n\n // Initialize local audio element for standalone mode\n useEffect(() => {\n if (!useStandaloneMode) return;\n\n const audio = new Audio();\n audio.preload = 'metadata';\n localAudioRef.current = audio;\n\n const handleTimeUpdate = () => {\n setLocalCurrentTime(audio.currentTime);\n };\n\n const handleEnded = () => {\n setLocalIsPlaying(false);\n setLocalCurrentTime(0);\n };\n\n const handleLoadedMetadata = () => {\n setTotalDuration(audio.duration);\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('loadedmetadata', handleLoadedMetadata);\n\n return () => {\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('loadedmetadata', handleLoadedMetadata);\n audio.pause();\n audio.src = '';\n };\n }, [useStandaloneMode]);\n\n // Listen for other players starting (to pause this one in standalone mode)\n useEffect(() => {\n if (!useStandaloneMode) return;\n\n const handleOtherPlayerPlay = (event: CustomEvent<string>) => {\n // Another player started, pause this one\n if (event.detail !== song.id && localAudioRef.current) {\n localAudioRef.current.pause();\n setLocalIsPlaying(false);\n }\n };\n\n window.addEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay as EventListener);\n return () => {\n window.removeEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay as EventListener);\n };\n }, [useStandaloneMode, song.id]);\n\n // Sync waveform progress with playback\n useEffect(() => {\n if (!wavesurferRef.current) return;\n\n const relevantCurrentTime = useStandaloneMode ? localCurrentTime : contextCurrentTime;\n const shouldSync = useStandaloneMode ? localIsPlaying : isThisSongPlayingInContext;\n\n if (!shouldSync) return;\n\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && relevantCurrentTime >= 0) {\n const progress = relevantCurrentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [localCurrentTime, contextCurrentTime, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext]);\n\n // Initialize WaveSurfer - waveform display only (audio plays through context or local audio)\n useEffect(() => {\n if (!containerRef.current || !isVisible) return;\n\n const hasPeaks = song.peaks && song.peaks.length > 0;\n\n // Create WaveSurfer for waveform display only (no audio playback)\n const wavesurfer = WaveSurfer.create({\n container: containerRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true,\n // Only load audio URL if we don't have peaks (needed to generate waveform)\n url: hasPeaks ? undefined : song.audioUrl,\n peaks: hasPeaks ? [song.peaks!] : undefined,\n duration: hasPeaks ? (song.duration || 0) : undefined,\n });\n\n // IMPORTANT: Mute WaveSurfer so it doesn't play audio (only visualizes)\n // Audio playback is handled separately through context or local audio element\n wavesurfer.setMuted(true);\n\n wavesurfer.on('ready', () => {\n setIsReady(true);\n setTotalDuration(wavesurfer.getDuration() || song.duration || 0);\n // Ensure it stays muted\n wavesurfer.setMuted(true);\n });\n\n // Handle waveform click for seeking\n wavesurfer.on('interaction', (newTime: number) => {\n if (useStandaloneMode) {\n if (localAudioRef.current) {\n localAudioRef.current.currentTime = newTime;\n setLocalCurrentTime(newTime);\n }\n } else if (isThisSongPlayingInContext && contextSeek) {\n contextSeek(newTime);\n }\n });\n\n wavesurfer.on('error', () => {\n // Silently handle errors\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark as ready immediately\n if (hasPeaks) {\n setIsReady(true);\n setTotalDuration(song.duration || 0);\n }\n\n return () => {\n try {\n wavesurfer.destroy();\n } catch {\n // Ignore errors when component unmounts\n }\n };\n }, [\n song.audioUrl,\n song.peaks,\n song.duration,\n isVisible,\n useStandaloneMode,\n isThisSongPlayingInContext,\n contextSeek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Handle play button click\n const handlePlayClick = useCallback(() => {\n if (!song.id || !song.audioUrl) return;\n\n if (useStandaloneMode) {\n // Standalone mode - use local audio element\n if (!localAudioRef.current) return;\n\n if (localIsPlaying) {\n localAudioRef.current.pause();\n setLocalIsPlaying(false);\n } else {\n // Dispatch event so other standalone players pause\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })\n );\n }\n\n // Load and play\n if (localAudioRef.current.src !== song.audioUrl) {\n localAudioRef.current.src = song.audioUrl;\n }\n localAudioRef.current.play().catch(() => {\n // Handle autoplay restrictions\n });\n setLocalIsPlaying(true);\n }\n } else {\n // Context mode - use global player\n if (isThisSongPlayingInContext) {\n contextTogglePlay?.();\n } else {\n contextPlay?.(song);\n }\n }\n }, [song, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext, contextPlay, contextTogglePlay]);\n\n return (\n <div\n ref={wrapperRef}\n className={`wsp-player ${className}`}\n data-song-id={song.id}\n >\n {/* Custom header or default */}\n {renderHeader ? (\n renderHeader(song, isPlaying)\n ) : (\n <div className=\"wsp-player-header\">\n <h3 className=\"wsp-player-title\">{song.title}</h3>\n {song.artist && (\n <span className=\"wsp-player-artist\">{song.artist}</span>\n )}\n </div>\n )}\n\n {/* Player controls and waveform */}\n <div className=\"wsp-player-controls\">\n {/* Play/Pause button */}\n <button\n onClick={handlePlayClick}\n disabled={!isReady}\n className={`wsp-play-button ${isReady ? 'wsp-play-button--ready' : ''}`}\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {!isReady ? (\n <svg className=\"wsp-icon wsp-icon--spinner\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle\n className=\"wsp-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"wsp-spinner-head\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n ) : isPlaying ? (\n <svg className=\"wsp-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-icon wsp-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Waveform container */}\n <div className=\"wsp-waveform-wrapper\">\n <div ref={containerRef} className=\"wsp-waveform\" />\n\n {/* Time display */}\n {showTime && (\n <div className=\"wsp-time-display\">\n <span className=\"wsp-time\">{formatTime(currentTime)}</span>\n <span className=\"wsp-time\">{formatTime(totalDuration)}</span>\n </div>\n )}\n </div>\n\n {/* Custom controls slot */}\n {renderControls && renderControls(song, isPlaying)}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useRef, useEffect, useState } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer } from '../context/AudioPlayerContext';\nimport { formatTime } from '../utils/formatTime';\nimport type { MiniPlayerProps, WaveformConfig } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: 'transparent',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 40,\n normalize: true,\n};\n\nexport function MiniPlayer({\n position = 'bottom',\n showVolume = true,\n showClose = true,\n onClose,\n className = '',\n waveformConfig: userWaveformConfig,\n}: MiniPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n\n const {\n currentSong,\n isPlaying,\n currentTime,\n duration,\n displayVolume,\n togglePlay,\n seek,\n setVolume,\n stop,\n } = useAudioPlayer();\n\n const waveformRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const [isMobile, setIsMobile] = useState(false);\n const [waveformReady, setWaveformReady] = useState(false);\n const lastSongIdRef = useRef<string | null>(null);\n\n // Detect mobile viewport\n useEffect(() => {\n const checkMobile = () => setIsMobile(window.innerWidth < 640);\n checkMobile();\n window.addEventListener('resize', checkMobile);\n return () => window.removeEventListener('resize', checkMobile);\n }, []);\n\n // Initialize/update WaveSurfer when song changes\n useEffect(() => {\n if (!waveformRef.current || !currentSong) return;\n\n // If same song, don't recreate\n if (lastSongIdRef.current === currentSong.id && wavesurferRef.current) {\n return;\n }\n\n // Destroy previous instance\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n\n setWaveformReady(false);\n lastSongIdRef.current = currentSong.id;\n\n const hasPeaks = currentSong.peaks && currentSong.peaks.length > 0;\n\n // Create WaveSurfer - waveform only, no audio (audio plays through context)\n const wavesurfer = WaveSurfer.create({\n container: waveformRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true,\n // Use peaks if available, otherwise need audio URL to generate waveform\n url: hasPeaks ? undefined : currentSong.audioUrl,\n peaks: hasPeaks && currentSong.peaks ? [currentSong.peaks] : undefined,\n duration: hasPeaks ? (currentSong.duration || duration || 0) : undefined,\n });\n\n wavesurfer.on('ready', () => {\n setWaveformReady(true);\n });\n\n // Handle click on waveform to seek\n wavesurfer.on('interaction', (newTime: number) => {\n seek(newTime);\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark ready immediately\n if (hasPeaks) {\n setWaveformReady(true);\n }\n\n return () => {\n // Don't destroy on every render, only when song actually changes\n };\n }, [\n currentSong?.id,\n currentSong?.audioUrl,\n currentSong?.peaks,\n currentSong?.duration,\n duration,\n seek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n };\n }, []);\n\n // Sync waveform progress with audio context\n useEffect(() => {\n if (!wavesurferRef.current || !waveformReady) return;\n\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && currentTime >= 0) {\n const progress = currentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [currentTime, waveformReady]);\n\n // Handle volume change\n const handleVolumeChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setVolume(parseFloat(e.target.value));\n },\n [setVolume]\n );\n\n // Handle close button\n const handleClose = useCallback(() => {\n stop();\n onClose?.();\n }, [stop, onClose]);\n\n // Don't render if no song is loaded\n if (!currentSong) return null;\n\n // Determine if volume should be shown (respects both prop and mobile detection)\n const shouldShowVolume = showVolume && !isMobile;\n\n const positionClass = position === 'top' ? 'wsp-mini-player--top' : 'wsp-mini-player--bottom';\n\n return (\n <div className={`wsp-mini-player ${positionClass} ${className}`}>\n {/* Main controls */}\n <div className=\"wsp-mini-player-inner\">\n {/* Play/pause button - left */}\n <button\n onClick={togglePlay}\n className=\"wsp-mini-play-button\"\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {isPlaying ? (\n <svg className=\"wsp-mini-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-mini-icon wsp-mini-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Song info and waveform - center */}\n <div className=\"wsp-mini-content\">\n {/* Song title */}\n <div className=\"wsp-mini-info\">\n <div className=\"wsp-mini-title\">{currentSong.title}</div>\n {currentSong.album && (\n <div className=\"wsp-mini-album\">• {currentSong.album}</div>\n )}\n </div>\n\n {/* Waveform */}\n <div className=\"wsp-mini-waveform-container\">\n <span className=\"wsp-mini-time\">{formatTime(currentTime)}</span>\n <div ref={waveformRef} className=\"wsp-mini-waveform\" />\n <span className=\"wsp-mini-time\">{formatTime(duration)}</span>\n </div>\n </div>\n\n {/* Volume slider - hidden on mobile */}\n {shouldShowVolume && (\n <div className=\"wsp-mini-volume\">\n <button\n onClick={() => setVolume(displayVolume > 0 ? 0 : 1)}\n className=\"wsp-mini-volume-button\"\n aria-label={displayVolume > 0 ? 'Mute' : 'Unmute'}\n >\n {displayVolume === 0 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2\"\n />\n </svg>\n ) : displayVolume < 0.5 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n ) : (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n value={displayVolume}\n onChange={handleVolumeChange}\n className=\"wsp-mini-volume-slider\"\n aria-label=\"Volume\"\n />\n </div>\n )}\n\n {/* Close button */}\n {showClose && (\n <button\n onClick={handleClose}\n className=\"wsp-mini-close-button\"\n aria-label=\"Close player\"\n >\n <svg className=\"wsp-mini-close-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport type { ShareButtonsProps, SharePlatform } from '../types';\n\nconst PLATFORM_CONFIG: Record<\n SharePlatform,\n {\n name: string;\n color: string;\n getUrl: (url: string, text: string) => string;\n icon: JSX.Element;\n }\n> = {\n facebook: {\n name: 'Facebook',\n color: '#1877F2',\n getUrl: (url, text) =>\n `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}"e=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\" />\n </svg>\n ),\n },\n twitter: {\n name: 'Twitter/X',\n color: '#1DA1F2',\n getUrl: (url, text) =>\n `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\n </svg>\n ),\n },\n whatsapp: {\n name: 'WhatsApp',\n color: '#25D366',\n getUrl: (url, text) =>\n `https://wa.me/?text=${encodeURIComponent(`${text} ${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z\" />\n </svg>\n ),\n },\n linkedin: {\n name: 'LinkedIn',\n color: '#0A66C2',\n getUrl: (url, text) =>\n `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n ),\n },\n reddit: {\n name: 'Reddit',\n color: '#FF4500',\n getUrl: (url, text) =>\n `https://www.reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z\" />\n </svg>\n ),\n },\n telegram: {\n name: 'Telegram',\n color: '#0088CC',\n getUrl: (url, text) =>\n `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\" />\n </svg>\n ),\n },\n email: {\n name: 'Email',\n color: '#666666',\n getUrl: (url, text) =>\n `mailto:?subject=${encodeURIComponent(text)}&body=${encodeURIComponent(`${text}\\n\\n${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n copy: {\n name: 'Copy Link',\n color: '#666666',\n getUrl: () => '', // Not used for copy\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n};\n\nconst DEFAULT_PLATFORMS: SharePlatform[] = [\n 'facebook',\n 'twitter',\n 'whatsapp',\n 'copy',\n];\n\nconst CheckIcon = () => (\n <svg\n className=\"wsp-share-icon wsp-share-icon--success\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n);\n\nexport function ShareButtons({\n url,\n text = '',\n platforms = DEFAULT_PLATFORMS,\n onShare,\n showLabels = false,\n className = '',\n}: ShareButtonsProps) {\n const [copied, setCopied] = useState(false);\n const [sharing, setSharing] = useState(false);\n\n const handleShare = useCallback(\n async (platform: SharePlatform) => {\n setSharing(true);\n\n if (platform === 'copy') {\n try {\n await navigator.clipboard.writeText(url);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n onShare?.(platform, url);\n } catch {\n // Clipboard may not be available\n }\n } else {\n const config = PLATFORM_CONFIG[platform];\n const shareUrl = config.getUrl(url, text);\n\n // Open share dialog\n if (platform === 'email') {\n window.location.href = shareUrl;\n } else {\n window.open(shareUrl, '_blank', 'width=600,height=400');\n }\n\n onShare?.(platform, url);\n }\n\n setSharing(false);\n },\n [url, text, onShare]\n );\n\n return (\n <div className={`wsp-share-buttons ${className}`}>\n {platforms.map((platform) => {\n const config = PLATFORM_CONFIG[platform];\n if (!config) return null;\n\n const isCopyButton = platform === 'copy';\n const showCheck = isCopyButton && copied;\n\n return (\n <button\n key={platform}\n onClick={() => handleShare(platform)}\n disabled={sharing}\n className=\"wsp-share-button\"\n style={{ '--wsp-share-hover-color': config.color } as React.CSSProperties}\n title={showCheck ? 'Copied!' : config.name}\n aria-label={`Share via ${config.name}`}\n >\n {showCheck ? <CheckIcon /> : config.icon}\n {showLabels && (\n <span className=\"wsp-share-label\">\n {showCheck ? 'Copied!' : config.name}\n </span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -298,6 +298,7 @@ var DEFAULT_WAVEFORM_CONFIG = {
|
|
|
298
298
|
height: 60,
|
|
299
299
|
normalize: true
|
|
300
300
|
};
|
|
301
|
+
createContext(null);
|
|
301
302
|
function WaveformPlayer({
|
|
302
303
|
song,
|
|
303
304
|
waveformConfig: userWaveformConfig,
|
|
@@ -305,35 +306,87 @@ function WaveformPlayer({
|
|
|
305
306
|
showTime = true,
|
|
306
307
|
className = "",
|
|
307
308
|
renderHeader,
|
|
308
|
-
renderControls
|
|
309
|
+
renderControls,
|
|
310
|
+
standalone = false
|
|
309
311
|
}) {
|
|
310
312
|
const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };
|
|
311
313
|
const containerRef = useRef(null);
|
|
312
314
|
const wavesurferRef = useRef(null);
|
|
315
|
+
const localAudioRef = useRef(null);
|
|
313
316
|
const [isReady, setIsReady] = useState(false);
|
|
314
317
|
const [totalDuration, setTotalDuration] = useState(song.duration || 0);
|
|
318
|
+
const [localIsPlaying, setLocalIsPlaying] = useState(false);
|
|
319
|
+
const [localCurrentTime, setLocalCurrentTime] = useState(0);
|
|
315
320
|
const { ref: wrapperRef, isVisible } = useLazyLoad({
|
|
316
321
|
forceVisible: !lazyLoad
|
|
317
322
|
});
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
const
|
|
327
|
-
const
|
|
328
|
-
const
|
|
323
|
+
let contextValue = null;
|
|
324
|
+
try {
|
|
325
|
+
if (!standalone) {
|
|
326
|
+
contextValue = useAudioPlayer();
|
|
327
|
+
}
|
|
328
|
+
} catch {
|
|
329
|
+
}
|
|
330
|
+
const useStandaloneMode = standalone || !contextValue;
|
|
331
|
+
const contextPlay = contextValue?.play;
|
|
332
|
+
const contextTogglePlay = contextValue?.togglePlay;
|
|
333
|
+
const contextSeek = contextValue?.seek;
|
|
334
|
+
const contextCurrentSong = contextValue?.currentSong;
|
|
335
|
+
const contextIsPlaying = contextValue?.isPlaying ?? false;
|
|
336
|
+
const contextCurrentTime = contextValue?.currentTime ?? 0;
|
|
337
|
+
const isThisSongPlayingInContext = !useStandaloneMode && contextCurrentSong?.id === song.id;
|
|
338
|
+
const isPlaying = useStandaloneMode ? localIsPlaying : isThisSongPlayingInContext && contextIsPlaying;
|
|
339
|
+
const currentTime = useStandaloneMode ? localCurrentTime : isThisSongPlayingInContext ? contextCurrentTime : 0;
|
|
340
|
+
useEffect(() => {
|
|
341
|
+
if (!useStandaloneMode) return;
|
|
342
|
+
const audio = new Audio();
|
|
343
|
+
audio.preload = "metadata";
|
|
344
|
+
localAudioRef.current = audio;
|
|
345
|
+
const handleTimeUpdate = () => {
|
|
346
|
+
setLocalCurrentTime(audio.currentTime);
|
|
347
|
+
};
|
|
348
|
+
const handleEnded = () => {
|
|
349
|
+
setLocalIsPlaying(false);
|
|
350
|
+
setLocalCurrentTime(0);
|
|
351
|
+
};
|
|
352
|
+
const handleLoadedMetadata = () => {
|
|
353
|
+
setTotalDuration(audio.duration);
|
|
354
|
+
};
|
|
355
|
+
audio.addEventListener("timeupdate", handleTimeUpdate);
|
|
356
|
+
audio.addEventListener("ended", handleEnded);
|
|
357
|
+
audio.addEventListener("loadedmetadata", handleLoadedMetadata);
|
|
358
|
+
return () => {
|
|
359
|
+
audio.removeEventListener("timeupdate", handleTimeUpdate);
|
|
360
|
+
audio.removeEventListener("ended", handleEnded);
|
|
361
|
+
audio.removeEventListener("loadedmetadata", handleLoadedMetadata);
|
|
362
|
+
audio.pause();
|
|
363
|
+
audio.src = "";
|
|
364
|
+
};
|
|
365
|
+
}, [useStandaloneMode]);
|
|
366
|
+
useEffect(() => {
|
|
367
|
+
if (!useStandaloneMode) return;
|
|
368
|
+
const handleOtherPlayerPlay = (event) => {
|
|
369
|
+
if (event.detail !== song.id && localAudioRef.current) {
|
|
370
|
+
localAudioRef.current.pause();
|
|
371
|
+
setLocalIsPlaying(false);
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
window.addEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay);
|
|
375
|
+
return () => {
|
|
376
|
+
window.removeEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay);
|
|
377
|
+
};
|
|
378
|
+
}, [useStandaloneMode, song.id]);
|
|
329
379
|
useEffect(() => {
|
|
330
|
-
if (!wavesurferRef.current
|
|
380
|
+
if (!wavesurferRef.current) return;
|
|
381
|
+
const relevantCurrentTime = useStandaloneMode ? localCurrentTime : contextCurrentTime;
|
|
382
|
+
const shouldSync = useStandaloneMode ? localIsPlaying : isThisSongPlayingInContext;
|
|
383
|
+
if (!shouldSync) return;
|
|
331
384
|
const waveDuration = wavesurferRef.current.getDuration();
|
|
332
|
-
if (waveDuration > 0 &&
|
|
333
|
-
const progress =
|
|
385
|
+
if (waveDuration > 0 && relevantCurrentTime >= 0) {
|
|
386
|
+
const progress = relevantCurrentTime / waveDuration;
|
|
334
387
|
wavesurferRef.current.seekTo(Math.min(progress, 1));
|
|
335
388
|
}
|
|
336
|
-
}, [contextCurrentTime,
|
|
389
|
+
}, [localCurrentTime, contextCurrentTime, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext]);
|
|
337
390
|
useEffect(() => {
|
|
338
391
|
if (!containerRef.current || !isVisible) return;
|
|
339
392
|
const hasPeaks = song.peaks && song.peaks.length > 0;
|
|
@@ -348,18 +401,24 @@ function WaveformPlayer({
|
|
|
348
401
|
height: waveformConfig.height,
|
|
349
402
|
normalize: waveformConfig.normalize,
|
|
350
403
|
interact: true,
|
|
351
|
-
// Allow clicking on waveform to seek
|
|
352
404
|
// Only load audio URL if we don't have peaks (needed to generate waveform)
|
|
353
405
|
url: hasPeaks ? void 0 : song.audioUrl,
|
|
354
406
|
peaks: hasPeaks ? [song.peaks] : void 0,
|
|
355
407
|
duration: hasPeaks ? song.duration || 0 : void 0
|
|
356
408
|
});
|
|
409
|
+
wavesurfer.setMuted(true);
|
|
357
410
|
wavesurfer.on("ready", () => {
|
|
358
411
|
setIsReady(true);
|
|
359
412
|
setTotalDuration(wavesurfer.getDuration() || song.duration || 0);
|
|
413
|
+
wavesurfer.setMuted(true);
|
|
360
414
|
});
|
|
361
415
|
wavesurfer.on("interaction", (newTime) => {
|
|
362
|
-
if (
|
|
416
|
+
if (useStandaloneMode) {
|
|
417
|
+
if (localAudioRef.current) {
|
|
418
|
+
localAudioRef.current.currentTime = newTime;
|
|
419
|
+
setLocalCurrentTime(newTime);
|
|
420
|
+
}
|
|
421
|
+
} else if (isThisSongPlayingInContext && contextSeek) {
|
|
363
422
|
contextSeek(newTime);
|
|
364
423
|
}
|
|
365
424
|
});
|
|
@@ -381,7 +440,8 @@ function WaveformPlayer({
|
|
|
381
440
|
song.peaks,
|
|
382
441
|
song.duration,
|
|
383
442
|
isVisible,
|
|
384
|
-
|
|
443
|
+
useStandaloneMode,
|
|
444
|
+
isThisSongPlayingInContext,
|
|
385
445
|
contextSeek,
|
|
386
446
|
waveformConfig.waveColor,
|
|
387
447
|
waveformConfig.progressColor,
|
|
@@ -394,12 +454,32 @@ function WaveformPlayer({
|
|
|
394
454
|
]);
|
|
395
455
|
const handlePlayClick = useCallback(() => {
|
|
396
456
|
if (!song.id || !song.audioUrl) return;
|
|
397
|
-
if (
|
|
398
|
-
|
|
457
|
+
if (useStandaloneMode) {
|
|
458
|
+
if (!localAudioRef.current) return;
|
|
459
|
+
if (localIsPlaying) {
|
|
460
|
+
localAudioRef.current.pause();
|
|
461
|
+
setLocalIsPlaying(false);
|
|
462
|
+
} else {
|
|
463
|
+
if (typeof window !== "undefined") {
|
|
464
|
+
window.dispatchEvent(
|
|
465
|
+
new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
if (localAudioRef.current.src !== song.audioUrl) {
|
|
469
|
+
localAudioRef.current.src = song.audioUrl;
|
|
470
|
+
}
|
|
471
|
+
localAudioRef.current.play().catch(() => {
|
|
472
|
+
});
|
|
473
|
+
setLocalIsPlaying(true);
|
|
474
|
+
}
|
|
399
475
|
} else {
|
|
400
|
-
|
|
476
|
+
if (isThisSongPlayingInContext) {
|
|
477
|
+
contextTogglePlay?.();
|
|
478
|
+
} else {
|
|
479
|
+
contextPlay?.(song);
|
|
480
|
+
}
|
|
401
481
|
}
|
|
402
|
-
}, [song,
|
|
482
|
+
}, [song, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext, contextPlay, contextTogglePlay]);
|
|
403
483
|
return /* @__PURE__ */ jsxs(
|
|
404
484
|
"div",
|
|
405
485
|
{
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/context/AudioPlayerContext.tsx","../src/hooks/useLazyLoad.ts","../src/utils/formatTime.ts","../src/components/WaveformPlayer.tsx","../src/components/MiniPlayer.tsx","../src/components/ShareButtons.tsx"],"names":["useRef","useState","useEffect","useCallback","jsx","DEFAULT_WAVEFORM_CONFIG","WaveSurfer","jsxs"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\n\nimport {\n createContext,\n useContext,\n useRef,\n useState,\n useCallback,\n useEffect,\n ReactNode,\n} from 'react';\nimport type {\n Song,\n AudioPlayerState,\n AudioPlayerContextValue,\n AudioPlayerConfig,\n} from '../types';\n\n// Custom event for notifying WaveformPlayers when mini-player starts playing\nexport const MINI_PLAYER_PLAY_EVENT = 'wavesurfer-player-mini-play';\n\nconst AudioPlayerContext = createContext<AudioPlayerContextValue | null>(null);\n\nconst DEFAULT_CONFIG: Required<AudioPlayerConfig> = {\n fadeInEnabled: true,\n fadeInDuration: 3000,\n persistVolume: true,\n storageKey: 'audioPlayerVolume',\n defaultVolume: 1,\n onPlay: () => {},\n onPause: () => {},\n onEnd: () => {},\n onTimeUpdate: () => {},\n};\n\nconst FADE_STEPS = 30; // 30 steps for smooth fade\nconst MIN_FADE_IN_VOLUME = 0.1; // Minimum 10% volume on fade-in so users hear something\n\ninterface AudioPlayerProviderProps {\n children: ReactNode;\n config?: AudioPlayerConfig;\n}\n\nexport function AudioPlayerProvider({\n children,\n config: userConfig,\n}: AudioPlayerProviderProps) {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const fadeIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const configRef = useRef(config);\n\n // Keep config ref up to date\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n const [state, setState] = useState<AudioPlayerState>({\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: config.defaultVolume,\n displayVolume: config.defaultVolume,\n isFadingIn: false,\n });\n\n // Initialize audio element and load saved volume\n useEffect(() => {\n // Create audio element\n const audio = new Audio();\n audio.preload = 'metadata';\n audioRef.current = audio;\n\n // Load saved volume from localStorage if persistence is enabled\n if (config.persistVolume && typeof window !== 'undefined') {\n const savedVolume = localStorage.getItem(config.storageKey);\n if (savedVolume) {\n const vol = parseFloat(savedVolume);\n if (!isNaN(vol) && vol >= 0 && vol <= 1) {\n setState((s) => ({ ...s, volume: vol, displayVolume: vol }));\n audio.volume = vol;\n }\n }\n }\n\n // Audio event listeners\n const handleTimeUpdate = () => {\n setState((s) => ({ ...s, currentTime: audio.currentTime }));\n configRef.current.onTimeUpdate?.(audio.currentTime);\n };\n\n const handleLoadedMetadata = () => {\n setState((s) => ({ ...s, duration: audio.duration }));\n };\n\n const handleEnded = () => {\n setState((s) => ({ ...s, isPlaying: false, currentTime: 0 }));\n configRef.current.onEnd?.();\n };\n\n const handlePlay = () => {\n setState((s) => ({ ...s, isPlaying: true }));\n };\n\n const handlePause = () => {\n setState((s) => ({ ...s, isPlaying: false }));\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('loadedmetadata', handleLoadedMetadata);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n\n return () => {\n // Cleanup\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n }\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('loadedmetadata', handleLoadedMetadata);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.pause();\n audio.src = '';\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Clear any existing fade interval\n const clearFade = useCallback(() => {\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n fadeIntervalRef.current = null;\n }\n }, []);\n\n // Fade in volume\n const fadeInVolume = useCallback(\n (targetVolume: number) => {\n if (!audioRef.current) return;\n\n clearFade();\n setState((s) => ({ ...s, isFadingIn: true, displayVolume: 0 }));\n\n const fadeStepDuration = configRef.current.fadeInDuration / FADE_STEPS;\n const volumeStep = targetVolume / FADE_STEPS;\n let currentStep = 0;\n\n fadeIntervalRef.current = setInterval(() => {\n currentStep++;\n const newVolume = Math.min(volumeStep * currentStep, targetVolume);\n if (audioRef.current) {\n audioRef.current.volume = newVolume;\n }\n // Update displayVolume so the slider follows the fade\n setState((s) => ({ ...s, displayVolume: newVolume }));\n\n if (currentStep >= FADE_STEPS) {\n clearFade();\n setState((s) => ({\n ...s,\n isFadingIn: false,\n displayVolume: targetVolume,\n }));\n }\n }, fadeStepDuration);\n },\n [clearFade]\n );\n\n // Play a song with optional fade-in\n const play = useCallback(\n async (song: Song) => {\n if (!audioRef.current) return;\n\n // Stop any current fade-in\n clearFade();\n\n // If it's a different song, load it\n if (state.currentSong?.id !== song.id) {\n audioRef.current.src = song.audioUrl;\n setState((s) => ({\n ...s,\n currentSong: song,\n currentTime: 0,\n duration: song.duration || 0,\n }));\n }\n\n // Determine target volume\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n // Set initial volume based on fade setting\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n } else {\n audioRef.current.volume = targetVolume;\n }\n\n try {\n await audioRef.current.play();\n // Dispatch event to pause other players\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })\n );\n }\n // Start fade-in if enabled\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n // Call onPlay callback\n configRef.current.onPlay?.(song);\n } catch {\n // Handle autoplay restrictions silently\n }\n },\n [state.currentSong?.id, state.volume, clearFade, fadeInVolume]\n );\n\n // Pause playback\n const pause = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n configRef.current.onPause?.();\n }, [clearFade]);\n\n // Toggle play/pause\n const togglePlay = useCallback(() => {\n if (!audioRef.current || !state.currentSong) return;\n\n if (state.isPlaying) {\n pause();\n } else {\n // Resume with fade-in if enabled\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n }\n\n audioRef.current\n .play()\n .then(() => {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, {\n detail: state.currentSong?.id,\n })\n );\n }\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n })\n .catch(() => {\n // Handle autoplay restrictions silently\n });\n }\n }, [state.isPlaying, state.currentSong, state.volume, pause, fadeInVolume]);\n\n // Seek to position\n const seek = useCallback((time: number) => {\n if (!audioRef.current) return;\n audioRef.current.currentTime = time;\n setState((s) => ({ ...s, currentTime: time }));\n }, []);\n\n // Set volume and persist to localStorage\n const setVolume = useCallback(\n (volume: number) => {\n if (!audioRef.current) return;\n\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n // If user manually changes volume during fade, stop the fade\n if (fadeIntervalRef.current) {\n clearFade();\n setState((s) => ({ ...s, isFadingIn: false }));\n }\n\n audioRef.current.volume = clampedVolume;\n\n // Persist to localStorage if enabled\n if (configRef.current.persistVolume && typeof window !== 'undefined') {\n localStorage.setItem(\n configRef.current.storageKey,\n clampedVolume.toString()\n );\n }\n\n setState((s) => ({\n ...s,\n volume: clampedVolume,\n displayVolume: clampedVolume,\n }));\n },\n [clearFade]\n );\n\n // Stop playback and clear song\n const stop = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n audioRef.current.currentTime = 0;\n audioRef.current.src = '';\n setState((s) => ({\n ...s,\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n isFadingIn: false,\n }));\n }, [clearFade]);\n\n const value: AudioPlayerContextValue = {\n ...state,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n stop,\n };\n\n return (\n <AudioPlayerContext.Provider value={value}>\n {children}\n </AudioPlayerContext.Provider>\n );\n}\n\nexport function useAudioPlayer(): AudioPlayerContextValue {\n const context = useContext(AudioPlayerContext);\n if (!context) {\n throw new Error(\n 'useAudioPlayer must be used within an AudioPlayerProvider'\n );\n }\n return context;\n}\n","'use client';\n\nimport { useRef, useState, useEffect } from 'react';\nimport type { UseLazyLoadResult, UseLazyLoadOptions } from '../types';\n\n/**\n * Hook for lazy loading elements using IntersectionObserver.\n * Returns a ref to attach to the target element and a boolean indicating visibility.\n *\n * @param options - Configuration options for the IntersectionObserver\n * @returns Object containing ref and isVisible state\n *\n * @example\n * const { ref, isVisible } = useLazyLoad();\n *\n * return (\n * <div ref={ref}>\n * {isVisible && <ExpensiveComponent />}\n * </div>\n * );\n */\nexport function useLazyLoad(options?: UseLazyLoadOptions): UseLazyLoadResult {\n const {\n rootMargin = '100px',\n threshold = 0,\n forceVisible = false,\n } = options || {};\n\n const ref = useRef<HTMLDivElement>(null);\n const [isVisible, setIsVisible] = useState(forceVisible);\n\n useEffect(() => {\n if (forceVisible) {\n setIsVisible(true);\n return;\n }\n\n if (!ref.current) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsVisible(true);\n observer.disconnect(); // Only need to detect once\n }\n },\n { rootMargin, threshold }\n );\n\n observer.observe(ref.current);\n\n return () => observer.disconnect();\n }, [rootMargin, threshold, forceVisible]);\n\n return { ref, isVisible };\n}\n","/**\n * Formats seconds into a human-readable time string (M:SS or MM:SS).\n *\n * @param seconds - The number of seconds to format\n * @returns Formatted time string (e.g., \"3:45\" or \"12:05\")\n *\n * @example\n * formatTime(125) // \"2:05\"\n * formatTime(0) // \"0:00\"\n * formatTime(3600) // \"60:00\"\n */\nexport function formatTime(seconds: number): string {\n if (!seconds || isNaN(seconds) || seconds < 0) return '0:00';\n\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","'use client';\n\nimport { useEffect, useRef, useState, useCallback } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer, MINI_PLAYER_PLAY_EVENT } from '../context/AudioPlayerContext';\nimport { useLazyLoad } from '../hooks/useLazyLoad';\nimport { formatTime } from '../utils/formatTime';\nimport type { WaveformPlayerProps, WaveformConfig } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: '#D4AF37',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 60,\n normalize: true,\n};\n\nexport function WaveformPlayer({\n song,\n waveformConfig: userWaveformConfig,\n lazyLoad = true,\n showTime = true,\n className = '',\n renderHeader,\n renderControls,\n}: WaveformPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n const containerRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [totalDuration, setTotalDuration] = useState(song.duration || 0);\n\n // Lazy loading\n const { ref: wrapperRef, isVisible } = useLazyLoad({\n forceVisible: !lazyLoad,\n });\n\n // Get audio player context for global playback control\n const {\n play: contextPlay,\n togglePlay: contextTogglePlay,\n seek: contextSeek,\n currentSong,\n isPlaying: contextIsPlaying,\n currentTime: contextCurrentTime,\n } = useAudioPlayer();\n\n // Check if this song is the currently playing song\n const isThisSongPlaying = currentSong?.id === song.id;\n const isPlaying = isThisSongPlaying && contextIsPlaying;\n const currentTime = isThisSongPlaying ? contextCurrentTime : 0;\n\n // Sync waveform progress with context when this song is playing\n useEffect(() => {\n if (!wavesurferRef.current || !isThisSongPlaying) return;\n\n // Update waveform progress to match context time\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && contextCurrentTime >= 0) {\n const progress = contextCurrentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [contextCurrentTime, isThisSongPlaying]);\n\n // Initialize WaveSurfer - waveform display only (audio plays through context)\n useEffect(() => {\n if (!containerRef.current || !isVisible) return;\n\n const hasPeaks = song.peaks && song.peaks.length > 0;\n\n // Create WaveSurfer for waveform display only (no audio playback)\n const wavesurfer = WaveSurfer.create({\n container: containerRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true, // Allow clicking on waveform to seek\n // Only load audio URL if we don't have peaks (needed to generate waveform)\n url: hasPeaks ? undefined : song.audioUrl,\n peaks: hasPeaks ? [song.peaks!] : undefined,\n duration: hasPeaks ? (song.duration || 0) : undefined,\n });\n\n wavesurfer.on('ready', () => {\n setIsReady(true);\n setTotalDuration(wavesurfer.getDuration() || song.duration || 0);\n });\n\n // Handle waveform click for seeking\n wavesurfer.on('interaction', (newTime: number) => {\n // Only seek if this song is currently playing in the context\n if (isThisSongPlaying) {\n contextSeek(newTime);\n }\n });\n\n wavesurfer.on('error', () => {\n // Silently handle errors\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark as ready immediately\n if (hasPeaks) {\n setIsReady(true);\n setTotalDuration(song.duration || 0);\n }\n\n return () => {\n try {\n wavesurfer.destroy();\n } catch {\n // Ignore errors when component unmounts\n }\n };\n }, [\n song.audioUrl,\n song.peaks,\n song.duration,\n isVisible,\n isThisSongPlaying,\n contextSeek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Handle play button click - plays through global context\n const handlePlayClick = useCallback(() => {\n if (!song.id || !song.audioUrl) return;\n\n if (isThisSongPlaying) {\n // This song is already loaded - toggle play/pause\n contextTogglePlay();\n } else {\n // Play this song through the global context\n contextPlay(song);\n }\n }, [song, isThisSongPlaying, contextPlay, contextTogglePlay]);\n\n return (\n <div\n ref={wrapperRef}\n className={`wsp-player ${className}`}\n data-song-id={song.id}\n >\n {/* Custom header or default */}\n {renderHeader ? (\n renderHeader(song, isPlaying)\n ) : (\n <div className=\"wsp-player-header\">\n <h3 className=\"wsp-player-title\">{song.title}</h3>\n {song.artist && (\n <span className=\"wsp-player-artist\">{song.artist}</span>\n )}\n </div>\n )}\n\n {/* Player controls and waveform */}\n <div className=\"wsp-player-controls\">\n {/* Play/Pause button */}\n <button\n onClick={handlePlayClick}\n disabled={!isReady}\n className={`wsp-play-button ${isReady ? 'wsp-play-button--ready' : ''}`}\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {!isReady ? (\n <svg className=\"wsp-icon wsp-icon--spinner\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle\n className=\"wsp-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"wsp-spinner-head\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n ) : isPlaying ? (\n <svg className=\"wsp-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-icon wsp-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Waveform container */}\n <div className=\"wsp-waveform-wrapper\">\n <div ref={containerRef} className=\"wsp-waveform\" />\n\n {/* Time display */}\n {showTime && (\n <div className=\"wsp-time-display\">\n <span className=\"wsp-time\">{formatTime(currentTime)}</span>\n <span className=\"wsp-time\">{formatTime(totalDuration)}</span>\n </div>\n )}\n </div>\n\n {/* Custom controls slot */}\n {renderControls && renderControls(song, isPlaying)}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useRef, useEffect, useState } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer } from '../context/AudioPlayerContext';\nimport { formatTime } from '../utils/formatTime';\nimport type { MiniPlayerProps, WaveformConfig } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: 'transparent',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 40,\n normalize: true,\n};\n\nexport function MiniPlayer({\n position = 'bottom',\n showVolume = true,\n showClose = true,\n onClose,\n className = '',\n waveformConfig: userWaveformConfig,\n}: MiniPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n\n const {\n currentSong,\n isPlaying,\n currentTime,\n duration,\n displayVolume,\n togglePlay,\n seek,\n setVolume,\n stop,\n } = useAudioPlayer();\n\n const waveformRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const [isMobile, setIsMobile] = useState(false);\n const [waveformReady, setWaveformReady] = useState(false);\n const lastSongIdRef = useRef<string | null>(null);\n\n // Detect mobile viewport\n useEffect(() => {\n const checkMobile = () => setIsMobile(window.innerWidth < 640);\n checkMobile();\n window.addEventListener('resize', checkMobile);\n return () => window.removeEventListener('resize', checkMobile);\n }, []);\n\n // Initialize/update WaveSurfer when song changes\n useEffect(() => {\n if (!waveformRef.current || !currentSong) return;\n\n // If same song, don't recreate\n if (lastSongIdRef.current === currentSong.id && wavesurferRef.current) {\n return;\n }\n\n // Destroy previous instance\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n\n setWaveformReady(false);\n lastSongIdRef.current = currentSong.id;\n\n const hasPeaks = currentSong.peaks && currentSong.peaks.length > 0;\n\n // Create WaveSurfer - waveform only, no audio (audio plays through context)\n const wavesurfer = WaveSurfer.create({\n container: waveformRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true,\n // Use peaks if available, otherwise need audio URL to generate waveform\n url: hasPeaks ? undefined : currentSong.audioUrl,\n peaks: hasPeaks && currentSong.peaks ? [currentSong.peaks] : undefined,\n duration: hasPeaks ? (currentSong.duration || duration || 0) : undefined,\n });\n\n wavesurfer.on('ready', () => {\n setWaveformReady(true);\n });\n\n // Handle click on waveform to seek\n wavesurfer.on('interaction', (newTime: number) => {\n seek(newTime);\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark ready immediately\n if (hasPeaks) {\n setWaveformReady(true);\n }\n\n return () => {\n // Don't destroy on every render, only when song actually changes\n };\n }, [\n currentSong?.id,\n currentSong?.audioUrl,\n currentSong?.peaks,\n currentSong?.duration,\n duration,\n seek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n };\n }, []);\n\n // Sync waveform progress with audio context\n useEffect(() => {\n if (!wavesurferRef.current || !waveformReady) return;\n\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && currentTime >= 0) {\n const progress = currentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [currentTime, waveformReady]);\n\n // Handle volume change\n const handleVolumeChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setVolume(parseFloat(e.target.value));\n },\n [setVolume]\n );\n\n // Handle close button\n const handleClose = useCallback(() => {\n stop();\n onClose?.();\n }, [stop, onClose]);\n\n // Don't render if no song is loaded\n if (!currentSong) return null;\n\n // Determine if volume should be shown (respects both prop and mobile detection)\n const shouldShowVolume = showVolume && !isMobile;\n\n const positionClass = position === 'top' ? 'wsp-mini-player--top' : 'wsp-mini-player--bottom';\n\n return (\n <div className={`wsp-mini-player ${positionClass} ${className}`}>\n {/* Main controls */}\n <div className=\"wsp-mini-player-inner\">\n {/* Play/pause button - left */}\n <button\n onClick={togglePlay}\n className=\"wsp-mini-play-button\"\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {isPlaying ? (\n <svg className=\"wsp-mini-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-mini-icon wsp-mini-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Song info and waveform - center */}\n <div className=\"wsp-mini-content\">\n {/* Song title */}\n <div className=\"wsp-mini-info\">\n <div className=\"wsp-mini-title\">{currentSong.title}</div>\n {currentSong.album && (\n <div className=\"wsp-mini-album\">• {currentSong.album}</div>\n )}\n </div>\n\n {/* Waveform */}\n <div className=\"wsp-mini-waveform-container\">\n <span className=\"wsp-mini-time\">{formatTime(currentTime)}</span>\n <div ref={waveformRef} className=\"wsp-mini-waveform\" />\n <span className=\"wsp-mini-time\">{formatTime(duration)}</span>\n </div>\n </div>\n\n {/* Volume slider - hidden on mobile */}\n {shouldShowVolume && (\n <div className=\"wsp-mini-volume\">\n <button\n onClick={() => setVolume(displayVolume > 0 ? 0 : 1)}\n className=\"wsp-mini-volume-button\"\n aria-label={displayVolume > 0 ? 'Mute' : 'Unmute'}\n >\n {displayVolume === 0 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2\"\n />\n </svg>\n ) : displayVolume < 0.5 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n ) : (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n value={displayVolume}\n onChange={handleVolumeChange}\n className=\"wsp-mini-volume-slider\"\n aria-label=\"Volume\"\n />\n </div>\n )}\n\n {/* Close button */}\n {showClose && (\n <button\n onClick={handleClose}\n className=\"wsp-mini-close-button\"\n aria-label=\"Close player\"\n >\n <svg className=\"wsp-mini-close-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport type { ShareButtonsProps, SharePlatform } from '../types';\n\nconst PLATFORM_CONFIG: Record<\n SharePlatform,\n {\n name: string;\n color: string;\n getUrl: (url: string, text: string) => string;\n icon: JSX.Element;\n }\n> = {\n facebook: {\n name: 'Facebook',\n color: '#1877F2',\n getUrl: (url, text) =>\n `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}"e=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\" />\n </svg>\n ),\n },\n twitter: {\n name: 'Twitter/X',\n color: '#1DA1F2',\n getUrl: (url, text) =>\n `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\n </svg>\n ),\n },\n whatsapp: {\n name: 'WhatsApp',\n color: '#25D366',\n getUrl: (url, text) =>\n `https://wa.me/?text=${encodeURIComponent(`${text} ${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z\" />\n </svg>\n ),\n },\n linkedin: {\n name: 'LinkedIn',\n color: '#0A66C2',\n getUrl: (url, text) =>\n `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n ),\n },\n reddit: {\n name: 'Reddit',\n color: '#FF4500',\n getUrl: (url, text) =>\n `https://www.reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z\" />\n </svg>\n ),\n },\n telegram: {\n name: 'Telegram',\n color: '#0088CC',\n getUrl: (url, text) =>\n `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\" />\n </svg>\n ),\n },\n email: {\n name: 'Email',\n color: '#666666',\n getUrl: (url, text) =>\n `mailto:?subject=${encodeURIComponent(text)}&body=${encodeURIComponent(`${text}\\n\\n${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n copy: {\n name: 'Copy Link',\n color: '#666666',\n getUrl: () => '', // Not used for copy\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n};\n\nconst DEFAULT_PLATFORMS: SharePlatform[] = [\n 'facebook',\n 'twitter',\n 'whatsapp',\n 'copy',\n];\n\nconst CheckIcon = () => (\n <svg\n className=\"wsp-share-icon wsp-share-icon--success\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n);\n\nexport function ShareButtons({\n url,\n text = '',\n platforms = DEFAULT_PLATFORMS,\n onShare,\n showLabels = false,\n className = '',\n}: ShareButtonsProps) {\n const [copied, setCopied] = useState(false);\n const [sharing, setSharing] = useState(false);\n\n const handleShare = useCallback(\n async (platform: SharePlatform) => {\n setSharing(true);\n\n if (platform === 'copy') {\n try {\n await navigator.clipboard.writeText(url);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n onShare?.(platform, url);\n } catch {\n // Clipboard may not be available\n }\n } else {\n const config = PLATFORM_CONFIG[platform];\n const shareUrl = config.getUrl(url, text);\n\n // Open share dialog\n if (platform === 'email') {\n window.location.href = shareUrl;\n } else {\n window.open(shareUrl, '_blank', 'width=600,height=400');\n }\n\n onShare?.(platform, url);\n }\n\n setSharing(false);\n },\n [url, text, onShare]\n );\n\n return (\n <div className={`wsp-share-buttons ${className}`}>\n {platforms.map((platform) => {\n const config = PLATFORM_CONFIG[platform];\n if (!config) return null;\n\n const isCopyButton = platform === 'copy';\n const showCheck = isCopyButton && copied;\n\n return (\n <button\n key={platform}\n onClick={() => handleShare(platform)}\n disabled={sharing}\n className=\"wsp-share-button\"\n style={{ '--wsp-share-hover-color': config.color } as React.CSSProperties}\n title={showCheck ? 'Copied!' : config.name}\n aria-label={`Share via ${config.name}`}\n >\n {showCheck ? <CheckIcon /> : config.icon}\n {showLabels && (\n <span className=\"wsp-share-label\">\n {showCheck ? 'Copied!' : config.name}\n </span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/context/AudioPlayerContext.tsx","../src/hooks/useLazyLoad.ts","../src/utils/formatTime.ts","../src/components/WaveformPlayer.tsx","../src/components/MiniPlayer.tsx","../src/components/ShareButtons.tsx"],"names":["useRef","useState","useEffect","createContext","useCallback","jsx","DEFAULT_WAVEFORM_CONFIG","WaveSurfer","jsxs"],"mappings":"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","file":"index.mjs","sourcesContent":["'use client';\n\nimport {\n createContext,\n useContext,\n useRef,\n useState,\n useCallback,\n useEffect,\n ReactNode,\n} from 'react';\nimport type {\n Song,\n AudioPlayerState,\n AudioPlayerContextValue,\n AudioPlayerConfig,\n} from '../types';\n\n// Custom event for notifying WaveformPlayers when mini-player starts playing\nexport const MINI_PLAYER_PLAY_EVENT = 'wavesurfer-player-mini-play';\n\nconst AudioPlayerContext = createContext<AudioPlayerContextValue | null>(null);\n\nconst DEFAULT_CONFIG: Required<AudioPlayerConfig> = {\n fadeInEnabled: true,\n fadeInDuration: 3000,\n persistVolume: true,\n storageKey: 'audioPlayerVolume',\n defaultVolume: 1,\n onPlay: () => {},\n onPause: () => {},\n onEnd: () => {},\n onTimeUpdate: () => {},\n};\n\nconst FADE_STEPS = 30; // 30 steps for smooth fade\nconst MIN_FADE_IN_VOLUME = 0.1; // Minimum 10% volume on fade-in so users hear something\n\ninterface AudioPlayerProviderProps {\n children: ReactNode;\n config?: AudioPlayerConfig;\n}\n\nexport function AudioPlayerProvider({\n children,\n config: userConfig,\n}: AudioPlayerProviderProps) {\n const config = { ...DEFAULT_CONFIG, ...userConfig };\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const fadeIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const configRef = useRef(config);\n\n // Keep config ref up to date\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n const [state, setState] = useState<AudioPlayerState>({\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n volume: config.defaultVolume,\n displayVolume: config.defaultVolume,\n isFadingIn: false,\n });\n\n // Initialize audio element and load saved volume\n useEffect(() => {\n // Create audio element\n const audio = new Audio();\n audio.preload = 'metadata';\n audioRef.current = audio;\n\n // Load saved volume from localStorage if persistence is enabled\n if (config.persistVolume && typeof window !== 'undefined') {\n const savedVolume = localStorage.getItem(config.storageKey);\n if (savedVolume) {\n const vol = parseFloat(savedVolume);\n if (!isNaN(vol) && vol >= 0 && vol <= 1) {\n setState((s) => ({ ...s, volume: vol, displayVolume: vol }));\n audio.volume = vol;\n }\n }\n }\n\n // Audio event listeners\n const handleTimeUpdate = () => {\n setState((s) => ({ ...s, currentTime: audio.currentTime }));\n configRef.current.onTimeUpdate?.(audio.currentTime);\n };\n\n const handleLoadedMetadata = () => {\n setState((s) => ({ ...s, duration: audio.duration }));\n };\n\n const handleEnded = () => {\n setState((s) => ({ ...s, isPlaying: false, currentTime: 0 }));\n configRef.current.onEnd?.();\n };\n\n const handlePlay = () => {\n setState((s) => ({ ...s, isPlaying: true }));\n };\n\n const handlePause = () => {\n setState((s) => ({ ...s, isPlaying: false }));\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('loadedmetadata', handleLoadedMetadata);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('play', handlePlay);\n audio.addEventListener('pause', handlePause);\n\n return () => {\n // Cleanup\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n }\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('loadedmetadata', handleLoadedMetadata);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('play', handlePlay);\n audio.removeEventListener('pause', handlePause);\n audio.pause();\n audio.src = '';\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Clear any existing fade interval\n const clearFade = useCallback(() => {\n if (fadeIntervalRef.current) {\n clearInterval(fadeIntervalRef.current);\n fadeIntervalRef.current = null;\n }\n }, []);\n\n // Fade in volume\n const fadeInVolume = useCallback(\n (targetVolume: number) => {\n if (!audioRef.current) return;\n\n clearFade();\n setState((s) => ({ ...s, isFadingIn: true, displayVolume: 0 }));\n\n const fadeStepDuration = configRef.current.fadeInDuration / FADE_STEPS;\n const volumeStep = targetVolume / FADE_STEPS;\n let currentStep = 0;\n\n fadeIntervalRef.current = setInterval(() => {\n currentStep++;\n const newVolume = Math.min(volumeStep * currentStep, targetVolume);\n if (audioRef.current) {\n audioRef.current.volume = newVolume;\n }\n // Update displayVolume so the slider follows the fade\n setState((s) => ({ ...s, displayVolume: newVolume }));\n\n if (currentStep >= FADE_STEPS) {\n clearFade();\n setState((s) => ({\n ...s,\n isFadingIn: false,\n displayVolume: targetVolume,\n }));\n }\n }, fadeStepDuration);\n },\n [clearFade]\n );\n\n // Play a song with optional fade-in\n const play = useCallback(\n async (song: Song) => {\n if (!audioRef.current) return;\n\n // Stop any current fade-in\n clearFade();\n\n // If it's a different song, load it\n if (state.currentSong?.id !== song.id) {\n audioRef.current.src = song.audioUrl;\n setState((s) => ({\n ...s,\n currentSong: song,\n currentTime: 0,\n duration: song.duration || 0,\n }));\n }\n\n // Determine target volume\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n // Set initial volume based on fade setting\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n } else {\n audioRef.current.volume = targetVolume;\n }\n\n try {\n await audioRef.current.play();\n // Dispatch event to pause other players\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })\n );\n }\n // Start fade-in if enabled\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n // Call onPlay callback\n configRef.current.onPlay?.(song);\n } catch {\n // Handle autoplay restrictions silently\n }\n },\n [state.currentSong?.id, state.volume, clearFade, fadeInVolume]\n );\n\n // Pause playback\n const pause = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n configRef.current.onPause?.();\n }, [clearFade]);\n\n // Toggle play/pause\n const togglePlay = useCallback(() => {\n if (!audioRef.current || !state.currentSong) return;\n\n if (state.isPlaying) {\n pause();\n } else {\n // Resume with fade-in if enabled\n const targetVolume = Math.max(state.volume, MIN_FADE_IN_VOLUME);\n\n if (configRef.current.fadeInEnabled) {\n audioRef.current.volume = 0;\n }\n\n audioRef.current\n .play()\n .then(() => {\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, {\n detail: state.currentSong?.id,\n })\n );\n }\n if (configRef.current.fadeInEnabled) {\n fadeInVolume(targetVolume);\n }\n })\n .catch(() => {\n // Handle autoplay restrictions silently\n });\n }\n }, [state.isPlaying, state.currentSong, state.volume, pause, fadeInVolume]);\n\n // Seek to position\n const seek = useCallback((time: number) => {\n if (!audioRef.current) return;\n audioRef.current.currentTime = time;\n setState((s) => ({ ...s, currentTime: time }));\n }, []);\n\n // Set volume and persist to localStorage\n const setVolume = useCallback(\n (volume: number) => {\n if (!audioRef.current) return;\n\n const clampedVolume = Math.max(0, Math.min(1, volume));\n\n // If user manually changes volume during fade, stop the fade\n if (fadeIntervalRef.current) {\n clearFade();\n setState((s) => ({ ...s, isFadingIn: false }));\n }\n\n audioRef.current.volume = clampedVolume;\n\n // Persist to localStorage if enabled\n if (configRef.current.persistVolume && typeof window !== 'undefined') {\n localStorage.setItem(\n configRef.current.storageKey,\n clampedVolume.toString()\n );\n }\n\n setState((s) => ({\n ...s,\n volume: clampedVolume,\n displayVolume: clampedVolume,\n }));\n },\n [clearFade]\n );\n\n // Stop playback and clear song\n const stop = useCallback(() => {\n if (!audioRef.current) return;\n clearFade();\n audioRef.current.pause();\n audioRef.current.currentTime = 0;\n audioRef.current.src = '';\n setState((s) => ({\n ...s,\n currentSong: null,\n isPlaying: false,\n currentTime: 0,\n duration: 0,\n isFadingIn: false,\n }));\n }, [clearFade]);\n\n const value: AudioPlayerContextValue = {\n ...state,\n play,\n pause,\n togglePlay,\n seek,\n setVolume,\n stop,\n };\n\n return (\n <AudioPlayerContext.Provider value={value}>\n {children}\n </AudioPlayerContext.Provider>\n );\n}\n\nexport function useAudioPlayer(): AudioPlayerContextValue {\n const context = useContext(AudioPlayerContext);\n if (!context) {\n throw new Error(\n 'useAudioPlayer must be used within an AudioPlayerProvider'\n );\n }\n return context;\n}\n","'use client';\n\nimport { useRef, useState, useEffect } from 'react';\nimport type { UseLazyLoadResult, UseLazyLoadOptions } from '../types';\n\n/**\n * Hook for lazy loading elements using IntersectionObserver.\n * Returns a ref to attach to the target element and a boolean indicating visibility.\n *\n * @param options - Configuration options for the IntersectionObserver\n * @returns Object containing ref and isVisible state\n *\n * @example\n * const { ref, isVisible } = useLazyLoad();\n *\n * return (\n * <div ref={ref}>\n * {isVisible && <ExpensiveComponent />}\n * </div>\n * );\n */\nexport function useLazyLoad(options?: UseLazyLoadOptions): UseLazyLoadResult {\n const {\n rootMargin = '100px',\n threshold = 0,\n forceVisible = false,\n } = options || {};\n\n const ref = useRef<HTMLDivElement>(null);\n const [isVisible, setIsVisible] = useState(forceVisible);\n\n useEffect(() => {\n if (forceVisible) {\n setIsVisible(true);\n return;\n }\n\n if (!ref.current) return;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsVisible(true);\n observer.disconnect(); // Only need to detect once\n }\n },\n { rootMargin, threshold }\n );\n\n observer.observe(ref.current);\n\n return () => observer.disconnect();\n }, [rootMargin, threshold, forceVisible]);\n\n return { ref, isVisible };\n}\n","/**\n * Formats seconds into a human-readable time string (M:SS or MM:SS).\n *\n * @param seconds - The number of seconds to format\n * @returns Formatted time string (e.g., \"3:45\" or \"12:05\")\n *\n * @example\n * formatTime(125) // \"2:05\"\n * formatTime(0) // \"0:00\"\n * formatTime(3600) // \"60:00\"\n */\nexport function formatTime(seconds: number): string {\n if (!seconds || isNaN(seconds) || seconds < 0) return '0:00';\n\n const mins = Math.floor(seconds / 60);\n const secs = Math.floor(seconds % 60);\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n","'use client';\n\nimport { useEffect, useRef, useState, useCallback, useContext, createContext } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer, MINI_PLAYER_PLAY_EVENT } from '../context/AudioPlayerContext';\nimport { useLazyLoad } from '../hooks/useLazyLoad';\nimport { formatTime } from '../utils/formatTime';\nimport type { WaveformPlayerProps, WaveformConfig, Song } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: '#D4AF37',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 60,\n normalize: true,\n};\n\n// Check if we're inside an AudioPlayerProvider\nconst AudioPlayerContext = createContext<unknown>(null);\n\nexport function WaveformPlayer({\n song,\n waveformConfig: userWaveformConfig,\n lazyLoad = true,\n showTime = true,\n className = '',\n renderHeader,\n renderControls,\n standalone = false,\n}: WaveformPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n const containerRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const localAudioRef = useRef<HTMLAudioElement | null>(null);\n const [isReady, setIsReady] = useState(false);\n const [totalDuration, setTotalDuration] = useState(song.duration || 0);\n\n // Standalone mode state\n const [localIsPlaying, setLocalIsPlaying] = useState(false);\n const [localCurrentTime, setLocalCurrentTime] = useState(0);\n\n // Lazy loading\n const { ref: wrapperRef, isVisible } = useLazyLoad({\n forceVisible: !lazyLoad,\n });\n\n // Try to get audio player context (may not exist in standalone mode)\n let contextValue: ReturnType<typeof useAudioPlayer> | null = null;\n try {\n if (!standalone) {\n contextValue = useAudioPlayer();\n }\n } catch {\n // Context not available, use standalone mode\n }\n\n const useStandaloneMode = standalone || !contextValue;\n\n // Context values (only used when not in standalone mode)\n const contextPlay = contextValue?.play;\n const contextTogglePlay = contextValue?.togglePlay;\n const contextSeek = contextValue?.seek;\n const contextCurrentSong = contextValue?.currentSong;\n const contextIsPlaying = contextValue?.isPlaying ?? false;\n const contextCurrentTime = contextValue?.currentTime ?? 0;\n\n // Check if this song is the currently playing song (context mode)\n const isThisSongPlayingInContext = !useStandaloneMode && contextCurrentSong?.id === song.id;\n\n // Determine actual playing state and current time\n const isPlaying = useStandaloneMode ? localIsPlaying : (isThisSongPlayingInContext && contextIsPlaying);\n const currentTime = useStandaloneMode ? localCurrentTime : (isThisSongPlayingInContext ? contextCurrentTime : 0);\n\n // Initialize local audio element for standalone mode\n useEffect(() => {\n if (!useStandaloneMode) return;\n\n const audio = new Audio();\n audio.preload = 'metadata';\n localAudioRef.current = audio;\n\n const handleTimeUpdate = () => {\n setLocalCurrentTime(audio.currentTime);\n };\n\n const handleEnded = () => {\n setLocalIsPlaying(false);\n setLocalCurrentTime(0);\n };\n\n const handleLoadedMetadata = () => {\n setTotalDuration(audio.duration);\n };\n\n audio.addEventListener('timeupdate', handleTimeUpdate);\n audio.addEventListener('ended', handleEnded);\n audio.addEventListener('loadedmetadata', handleLoadedMetadata);\n\n return () => {\n audio.removeEventListener('timeupdate', handleTimeUpdate);\n audio.removeEventListener('ended', handleEnded);\n audio.removeEventListener('loadedmetadata', handleLoadedMetadata);\n audio.pause();\n audio.src = '';\n };\n }, [useStandaloneMode]);\n\n // Listen for other players starting (to pause this one in standalone mode)\n useEffect(() => {\n if (!useStandaloneMode) return;\n\n const handleOtherPlayerPlay = (event: CustomEvent<string>) => {\n // Another player started, pause this one\n if (event.detail !== song.id && localAudioRef.current) {\n localAudioRef.current.pause();\n setLocalIsPlaying(false);\n }\n };\n\n window.addEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay as EventListener);\n return () => {\n window.removeEventListener(MINI_PLAYER_PLAY_EVENT, handleOtherPlayerPlay as EventListener);\n };\n }, [useStandaloneMode, song.id]);\n\n // Sync waveform progress with playback\n useEffect(() => {\n if (!wavesurferRef.current) return;\n\n const relevantCurrentTime = useStandaloneMode ? localCurrentTime : contextCurrentTime;\n const shouldSync = useStandaloneMode ? localIsPlaying : isThisSongPlayingInContext;\n\n if (!shouldSync) return;\n\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && relevantCurrentTime >= 0) {\n const progress = relevantCurrentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [localCurrentTime, contextCurrentTime, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext]);\n\n // Initialize WaveSurfer - waveform display only (audio plays through context or local audio)\n useEffect(() => {\n if (!containerRef.current || !isVisible) return;\n\n const hasPeaks = song.peaks && song.peaks.length > 0;\n\n // Create WaveSurfer for waveform display only (no audio playback)\n const wavesurfer = WaveSurfer.create({\n container: containerRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true,\n // Only load audio URL if we don't have peaks (needed to generate waveform)\n url: hasPeaks ? undefined : song.audioUrl,\n peaks: hasPeaks ? [song.peaks!] : undefined,\n duration: hasPeaks ? (song.duration || 0) : undefined,\n });\n\n // IMPORTANT: Mute WaveSurfer so it doesn't play audio (only visualizes)\n // Audio playback is handled separately through context or local audio element\n wavesurfer.setMuted(true);\n\n wavesurfer.on('ready', () => {\n setIsReady(true);\n setTotalDuration(wavesurfer.getDuration() || song.duration || 0);\n // Ensure it stays muted\n wavesurfer.setMuted(true);\n });\n\n // Handle waveform click for seeking\n wavesurfer.on('interaction', (newTime: number) => {\n if (useStandaloneMode) {\n if (localAudioRef.current) {\n localAudioRef.current.currentTime = newTime;\n setLocalCurrentTime(newTime);\n }\n } else if (isThisSongPlayingInContext && contextSeek) {\n contextSeek(newTime);\n }\n });\n\n wavesurfer.on('error', () => {\n // Silently handle errors\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark as ready immediately\n if (hasPeaks) {\n setIsReady(true);\n setTotalDuration(song.duration || 0);\n }\n\n return () => {\n try {\n wavesurfer.destroy();\n } catch {\n // Ignore errors when component unmounts\n }\n };\n }, [\n song.audioUrl,\n song.peaks,\n song.duration,\n isVisible,\n useStandaloneMode,\n isThisSongPlayingInContext,\n contextSeek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Handle play button click\n const handlePlayClick = useCallback(() => {\n if (!song.id || !song.audioUrl) return;\n\n if (useStandaloneMode) {\n // Standalone mode - use local audio element\n if (!localAudioRef.current) return;\n\n if (localIsPlaying) {\n localAudioRef.current.pause();\n setLocalIsPlaying(false);\n } else {\n // Dispatch event so other standalone players pause\n if (typeof window !== 'undefined') {\n window.dispatchEvent(\n new CustomEvent(MINI_PLAYER_PLAY_EVENT, { detail: song.id })\n );\n }\n\n // Load and play\n if (localAudioRef.current.src !== song.audioUrl) {\n localAudioRef.current.src = song.audioUrl;\n }\n localAudioRef.current.play().catch(() => {\n // Handle autoplay restrictions\n });\n setLocalIsPlaying(true);\n }\n } else {\n // Context mode - use global player\n if (isThisSongPlayingInContext) {\n contextTogglePlay?.();\n } else {\n contextPlay?.(song);\n }\n }\n }, [song, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext, contextPlay, contextTogglePlay]);\n\n return (\n <div\n ref={wrapperRef}\n className={`wsp-player ${className}`}\n data-song-id={song.id}\n >\n {/* Custom header or default */}\n {renderHeader ? (\n renderHeader(song, isPlaying)\n ) : (\n <div className=\"wsp-player-header\">\n <h3 className=\"wsp-player-title\">{song.title}</h3>\n {song.artist && (\n <span className=\"wsp-player-artist\">{song.artist}</span>\n )}\n </div>\n )}\n\n {/* Player controls and waveform */}\n <div className=\"wsp-player-controls\">\n {/* Play/Pause button */}\n <button\n onClick={handlePlayClick}\n disabled={!isReady}\n className={`wsp-play-button ${isReady ? 'wsp-play-button--ready' : ''}`}\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {!isReady ? (\n <svg className=\"wsp-icon wsp-icon--spinner\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle\n className=\"wsp-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"4\"\n />\n <path\n className=\"wsp-spinner-head\"\n fill=\"currentColor\"\n d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"\n />\n </svg>\n ) : isPlaying ? (\n <svg className=\"wsp-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-icon wsp-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Waveform container */}\n <div className=\"wsp-waveform-wrapper\">\n <div ref={containerRef} className=\"wsp-waveform\" />\n\n {/* Time display */}\n {showTime && (\n <div className=\"wsp-time-display\">\n <span className=\"wsp-time\">{formatTime(currentTime)}</span>\n <span className=\"wsp-time\">{formatTime(totalDuration)}</span>\n </div>\n )}\n </div>\n\n {/* Custom controls slot */}\n {renderControls && renderControls(song, isPlaying)}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useCallback, useRef, useEffect, useState } from 'react';\nimport WaveSurfer from 'wavesurfer.js';\nimport { useAudioPlayer } from '../context/AudioPlayerContext';\nimport { formatTime } from '../utils/formatTime';\nimport type { MiniPlayerProps, WaveformConfig } from '../types';\n\nconst DEFAULT_WAVEFORM_CONFIG: Required<WaveformConfig> = {\n waveColor: '#666666',\n progressColor: '#D4AF37',\n cursorColor: 'transparent',\n barWidth: 2,\n barGap: 1,\n barRadius: 2,\n height: 40,\n normalize: true,\n};\n\nexport function MiniPlayer({\n position = 'bottom',\n showVolume = true,\n showClose = true,\n onClose,\n className = '',\n waveformConfig: userWaveformConfig,\n}: MiniPlayerProps) {\n const waveformConfig = { ...DEFAULT_WAVEFORM_CONFIG, ...userWaveformConfig };\n\n const {\n currentSong,\n isPlaying,\n currentTime,\n duration,\n displayVolume,\n togglePlay,\n seek,\n setVolume,\n stop,\n } = useAudioPlayer();\n\n const waveformRef = useRef<HTMLDivElement>(null);\n const wavesurferRef = useRef<WaveSurfer | null>(null);\n const [isMobile, setIsMobile] = useState(false);\n const [waveformReady, setWaveformReady] = useState(false);\n const lastSongIdRef = useRef<string | null>(null);\n\n // Detect mobile viewport\n useEffect(() => {\n const checkMobile = () => setIsMobile(window.innerWidth < 640);\n checkMobile();\n window.addEventListener('resize', checkMobile);\n return () => window.removeEventListener('resize', checkMobile);\n }, []);\n\n // Initialize/update WaveSurfer when song changes\n useEffect(() => {\n if (!waveformRef.current || !currentSong) return;\n\n // If same song, don't recreate\n if (lastSongIdRef.current === currentSong.id && wavesurferRef.current) {\n return;\n }\n\n // Destroy previous instance\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n\n setWaveformReady(false);\n lastSongIdRef.current = currentSong.id;\n\n const hasPeaks = currentSong.peaks && currentSong.peaks.length > 0;\n\n // Create WaveSurfer - waveform only, no audio (audio plays through context)\n const wavesurfer = WaveSurfer.create({\n container: waveformRef.current,\n waveColor: waveformConfig.waveColor,\n progressColor: waveformConfig.progressColor,\n cursorColor: waveformConfig.cursorColor,\n barWidth: waveformConfig.barWidth,\n barGap: waveformConfig.barGap,\n barRadius: waveformConfig.barRadius,\n height: waveformConfig.height,\n normalize: waveformConfig.normalize,\n interact: true,\n // Use peaks if available, otherwise need audio URL to generate waveform\n url: hasPeaks ? undefined : currentSong.audioUrl,\n peaks: hasPeaks && currentSong.peaks ? [currentSong.peaks] : undefined,\n duration: hasPeaks ? (currentSong.duration || duration || 0) : undefined,\n });\n\n wavesurfer.on('ready', () => {\n setWaveformReady(true);\n });\n\n // Handle click on waveform to seek\n wavesurfer.on('interaction', (newTime: number) => {\n seek(newTime);\n });\n\n wavesurferRef.current = wavesurfer;\n\n // If we have peaks, mark ready immediately\n if (hasPeaks) {\n setWaveformReady(true);\n }\n\n return () => {\n // Don't destroy on every render, only when song actually changes\n };\n }, [\n currentSong?.id,\n currentSong?.audioUrl,\n currentSong?.peaks,\n currentSong?.duration,\n duration,\n seek,\n waveformConfig.waveColor,\n waveformConfig.progressColor,\n waveformConfig.cursorColor,\n waveformConfig.barWidth,\n waveformConfig.barGap,\n waveformConfig.barRadius,\n waveformConfig.height,\n waveformConfig.normalize,\n ]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (wavesurferRef.current) {\n wavesurferRef.current.destroy();\n wavesurferRef.current = null;\n }\n };\n }, []);\n\n // Sync waveform progress with audio context\n useEffect(() => {\n if (!wavesurferRef.current || !waveformReady) return;\n\n const waveDuration = wavesurferRef.current.getDuration();\n if (waveDuration > 0 && currentTime >= 0) {\n const progress = currentTime / waveDuration;\n wavesurferRef.current.seekTo(Math.min(progress, 1));\n }\n }, [currentTime, waveformReady]);\n\n // Handle volume change\n const handleVolumeChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n setVolume(parseFloat(e.target.value));\n },\n [setVolume]\n );\n\n // Handle close button\n const handleClose = useCallback(() => {\n stop();\n onClose?.();\n }, [stop, onClose]);\n\n // Don't render if no song is loaded\n if (!currentSong) return null;\n\n // Determine if volume should be shown (respects both prop and mobile detection)\n const shouldShowVolume = showVolume && !isMobile;\n\n const positionClass = position === 'top' ? 'wsp-mini-player--top' : 'wsp-mini-player--bottom';\n\n return (\n <div className={`wsp-mini-player ${positionClass} ${className}`}>\n {/* Main controls */}\n <div className=\"wsp-mini-player-inner\">\n {/* Play/pause button - left */}\n <button\n onClick={togglePlay}\n className=\"wsp-mini-play-button\"\n aria-label={isPlaying ? 'Pause' : 'Play'}\n >\n {isPlaying ? (\n <svg className=\"wsp-mini-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <rect x=\"6\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n <rect x=\"14\" y=\"4\" width=\"4\" height=\"16\" rx=\"1\" />\n </svg>\n ) : (\n <svg className=\"wsp-mini-icon wsp-mini-icon--play\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M8 5v14l11-7z\" />\n </svg>\n )}\n </button>\n\n {/* Song info and waveform - center */}\n <div className=\"wsp-mini-content\">\n {/* Song title */}\n <div className=\"wsp-mini-info\">\n <div className=\"wsp-mini-title\">{currentSong.title}</div>\n {currentSong.album && (\n <div className=\"wsp-mini-album\">• {currentSong.album}</div>\n )}\n </div>\n\n {/* Waveform */}\n <div className=\"wsp-mini-waveform-container\">\n <span className=\"wsp-mini-time\">{formatTime(currentTime)}</span>\n <div ref={waveformRef} className=\"wsp-mini-waveform\" />\n <span className=\"wsp-mini-time\">{formatTime(duration)}</span>\n </div>\n </div>\n\n {/* Volume slider - hidden on mobile */}\n {shouldShowVolume && (\n <div className=\"wsp-mini-volume\">\n <button\n onClick={() => setVolume(displayVolume > 0 ? 0 : 1)}\n className=\"wsp-mini-volume-button\"\n aria-label={displayVolume > 0 ? 'Mute' : 'Unmute'}\n >\n {displayVolume === 0 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M17 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2\"\n />\n </svg>\n ) : displayVolume < 0.5 ? (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n ) : (\n <svg className=\"wsp-mini-volume-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M15.536 8.464a5 5 0 010 7.072m2.828-9.9a9 9 0 010 12.728M5.586 15H4a1 1 0 01-1-1v-4a1 1 0 011-1h1.586l4.707-4.707C10.923 3.663 12 4.109 12 5v14c0 .891-1.077 1.337-1.707.707L5.586 15z\"\n />\n </svg>\n )}\n </button>\n <input\n type=\"range\"\n min=\"0\"\n max=\"1\"\n step=\"0.01\"\n value={displayVolume}\n onChange={handleVolumeChange}\n className=\"wsp-mini-volume-slider\"\n aria-label=\"Volume\"\n />\n </div>\n )}\n\n {/* Close button */}\n {showClose && (\n <button\n onClick={handleClose}\n className=\"wsp-mini-close-button\"\n aria-label=\"Close player\"\n >\n <svg className=\"wsp-mini-close-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M6 18L18 6M6 6l12 12\"\n />\n </svg>\n </button>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport type { ShareButtonsProps, SharePlatform } from '../types';\n\nconst PLATFORM_CONFIG: Record<\n SharePlatform,\n {\n name: string;\n color: string;\n getUrl: (url: string, text: string) => string;\n icon: JSX.Element;\n }\n> = {\n facebook: {\n name: 'Facebook',\n color: '#1877F2',\n getUrl: (url, text) =>\n `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}"e=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z\" />\n </svg>\n ),\n },\n twitter: {\n name: 'Twitter/X',\n color: '#1DA1F2',\n getUrl: (url, text) =>\n `https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z\" />\n </svg>\n ),\n },\n whatsapp: {\n name: 'WhatsApp',\n color: '#25D366',\n getUrl: (url, text) =>\n `https://wa.me/?text=${encodeURIComponent(`${text} ${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z\" />\n </svg>\n ),\n },\n linkedin: {\n name: 'LinkedIn',\n color: '#0A66C2',\n getUrl: (url, text) =>\n `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURIComponent(url)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z\" />\n </svg>\n ),\n },\n reddit: {\n name: 'Reddit',\n color: '#FF4500',\n getUrl: (url, text) =>\n `https://www.reddit.com/submit?url=${encodeURIComponent(url)}&title=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M12 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0zm5.01 4.744c.688 0 1.25.561 1.25 1.249a1.25 1.25 0 0 1-2.498.056l-2.597-.547-.8 3.747c1.824.07 3.48.632 4.674 1.488.308-.309.73-.491 1.207-.491.968 0 1.754.786 1.754 1.754 0 .716-.435 1.333-1.01 1.614a3.111 3.111 0 0 1 .042.52c0 2.694-3.13 4.87-7.004 4.87-3.874 0-7.004-2.176-7.004-4.87 0-.183.015-.366.043-.534A1.748 1.748 0 0 1 4.028 12c0-.968.786-1.754 1.754-1.754.463 0 .898.196 1.207.49 1.207-.883 2.878-1.43 4.744-1.487l.885-4.182a.342.342 0 0 1 .14-.197.35.35 0 0 1 .238-.042l2.906.617a1.214 1.214 0 0 1 1.108-.701zM9.25 12C8.561 12 8 12.562 8 13.25c0 .687.561 1.248 1.25 1.248.687 0 1.248-.561 1.248-1.249 0-.688-.561-1.249-1.249-1.249zm5.5 0c-.687 0-1.248.561-1.248 1.25 0 .687.561 1.248 1.249 1.248.688 0 1.249-.561 1.249-1.249 0-.687-.562-1.249-1.25-1.249zm-5.466 3.99a.327.327 0 0 0-.231.094.33.33 0 0 0 0 .463c.842.842 2.484.913 2.961.913.477 0 2.105-.056 2.961-.913a.361.361 0 0 0 .029-.463.33.33 0 0 0-.464 0c-.547.533-1.684.73-2.512.73-.828 0-1.979-.196-2.512-.73a.326.326 0 0 0-.232-.095z\" />\n </svg>\n ),\n },\n telegram: {\n name: 'Telegram',\n color: '#0088CC',\n getUrl: (url, text) =>\n `https://t.me/share/url?url=${encodeURIComponent(url)}&text=${encodeURIComponent(text)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"currentColor\" viewBox=\"0 0 24 24\">\n <path d=\"M11.944 0A12 12 0 0 0 0 12a12 12 0 0 0 12 12 12 12 0 0 0 12-12A12 12 0 0 0 12 0a12 12 0 0 0-.056 0zm4.962 7.224c.1-.002.321.023.465.14a.506.506 0 0 1 .171.325c.016.093.036.306.02.472-.18 1.898-.962 6.502-1.36 8.627-.168.9-.499 1.201-.82 1.23-.696.065-1.225-.46-1.9-.902-1.056-.693-1.653-1.124-2.678-1.8-1.185-.78-.417-1.21.258-1.91.177-.184 3.247-2.977 3.307-3.23.007-.032.014-.15-.056-.212s-.174-.041-.249-.024c-.106.024-1.793 1.14-5.061 3.345-.48.33-.913.49-1.302.48-.428-.008-1.252-.241-1.865-.44-.752-.245-1.349-.374-1.297-.789.027-.216.325-.437.893-.663 3.498-1.524 5.83-2.529 6.998-3.014 3.332-1.386 4.025-1.627 4.476-1.635z\" />\n </svg>\n ),\n },\n email: {\n name: 'Email',\n color: '#666666',\n getUrl: (url, text) =>\n `mailto:?subject=${encodeURIComponent(text)}&body=${encodeURIComponent(`${text}\\n\\n${url}`)}`,\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n copy: {\n name: 'Copy Link',\n color: '#666666',\n getUrl: () => '', // Not used for copy\n icon: (\n <svg className=\"wsp-share-icon\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\"\n />\n </svg>\n ),\n },\n};\n\nconst DEFAULT_PLATFORMS: SharePlatform[] = [\n 'facebook',\n 'twitter',\n 'whatsapp',\n 'copy',\n];\n\nconst CheckIcon = () => (\n <svg\n className=\"wsp-share-icon wsp-share-icon--success\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M5 13l4 4L19 7\"\n />\n </svg>\n);\n\nexport function ShareButtons({\n url,\n text = '',\n platforms = DEFAULT_PLATFORMS,\n onShare,\n showLabels = false,\n className = '',\n}: ShareButtonsProps) {\n const [copied, setCopied] = useState(false);\n const [sharing, setSharing] = useState(false);\n\n const handleShare = useCallback(\n async (platform: SharePlatform) => {\n setSharing(true);\n\n if (platform === 'copy') {\n try {\n await navigator.clipboard.writeText(url);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n onShare?.(platform, url);\n } catch {\n // Clipboard may not be available\n }\n } else {\n const config = PLATFORM_CONFIG[platform];\n const shareUrl = config.getUrl(url, text);\n\n // Open share dialog\n if (platform === 'email') {\n window.location.href = shareUrl;\n } else {\n window.open(shareUrl, '_blank', 'width=600,height=400');\n }\n\n onShare?.(platform, url);\n }\n\n setSharing(false);\n },\n [url, text, onShare]\n );\n\n return (\n <div className={`wsp-share-buttons ${className}`}>\n {platforms.map((platform) => {\n const config = PLATFORM_CONFIG[platform];\n if (!config) return null;\n\n const isCopyButton = platform === 'copy';\n const showCheck = isCopyButton && copied;\n\n return (\n <button\n key={platform}\n onClick={() => handleShare(platform)}\n disabled={sharing}\n className=\"wsp-share-button\"\n style={{ '--wsp-share-hover-color': config.color } as React.CSSProperties}\n title={showCheck ? 'Copied!' : config.name}\n aria-label={`Share via ${config.name}`}\n >\n {showCheck ? <CheckIcon /> : config.icon}\n {showLabels && (\n <span className=\"wsp-share-label\">\n {showCheck ? 'Copied!' : config.name}\n </span>\n )}\n </button>\n );\n })}\n </div>\n );\n}\n"]}
|
package/package.json
CHANGED