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 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
- const {
325
- play: contextPlay,
326
- togglePlay: contextTogglePlay,
327
- seek: contextSeek,
328
- currentSong,
329
- isPlaying: contextIsPlaying,
330
- currentTime: contextCurrentTime
331
- } = useAudioPlayer();
332
- const isThisSongPlaying = currentSong?.id === song.id;
333
- const isPlaying = isThisSongPlaying && contextIsPlaying;
334
- const currentTime = isThisSongPlaying ? contextCurrentTime : 0;
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 || !isThisSongPlaying) return;
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 && contextCurrentTime >= 0) {
339
- const progress = contextCurrentTime / waveDuration;
391
+ if (waveDuration > 0 && relevantCurrentTime >= 0) {
392
+ const progress = relevantCurrentTime / waveDuration;
340
393
  wavesurferRef.current.seekTo(Math.min(progress, 1));
341
394
  }
342
- }, [contextCurrentTime, isThisSongPlaying]);
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 (isThisSongPlaying) {
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
- isThisSongPlaying,
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 (isThisSongPlaying) {
404
- contextTogglePlay();
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
- contextPlay(song);
482
+ if (isThisSongPlayingInContext) {
483
+ contextTogglePlay?.();
484
+ } else {
485
+ contextPlay?.(song);
486
+ }
407
487
  }
408
- }, [song, isThisSongPlaying, contextPlay, contextTogglePlay]);
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":"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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 } 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)}&quote=${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":";;;;;;;;;;;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;AAG2BF,oBAAuB,IAAI;AAE/C,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,cAAA;AAAA,EACA,UAAA,GAAa;AACf,CAAA,EAAwB;AACtB,EAAA,MAAM,cAAA,GAAiB,EAAE,GAAG,uBAAA,EAAyB,GAAG,kBAAA,EAAmB;AAC3E,EAAA,MAAM,YAAA,GAAeC,aAAuB,IAAI,CAAA;AAChD,EAAA,MAAM,aAAA,GAAgBA,aAA0B,IAAI,CAAA;AACpD,EAAA,MAAM,aAAA,GAAgBA,aAAgC,IAAI,CAAA;AAC1D,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,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAIA,eAAS,CAAC,CAAA;AAG1D,EAAA,MAAM,EAAE,GAAA,EAAK,UAAA,EAAY,SAAA,KAAc,WAAA,CAAY;AAAA,IACjD,cAAc,CAAC;AAAA,GAChB,CAAA;AAGD,EAAA,IAAI,YAAA,GAAyD,IAAA;AAC7D,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,UAAA,EAAY;AACf,MAAA,YAAA,GAAe,cAAA,EAAe;AAAA,IAChC;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,MAAM,iBAAA,GAAoB,cAAc,CAAC,YAAA;AAGzC,EAAA,MAAM,cAAc,YAAA,EAAc,IAAA;AAClC,EAAA,MAAM,oBAAoB,YAAA,EAAc,UAAA;AACxC,EAAA,MAAM,cAAc,YAAA,EAAc,IAAA;AAClC,EAAA,MAAM,qBAAqB,YAAA,EAAc,WAAA;AACzC,EAAA,MAAM,gBAAA,GAAmB,cAAc,SAAA,IAAa,KAAA;AACpD,EAAA,MAAM,kBAAA,GAAqB,cAAc,WAAA,IAAe,CAAA;AAGxD,EAAA,MAAM,0BAAA,GAA6B,CAAC,iBAAA,IAAqB,kBAAA,EAAoB,OAAO,IAAA,CAAK,EAAA;AAGzF,EAAA,MAAM,SAAA,GAAY,iBAAA,GAAoB,cAAA,GAAkB,0BAAA,IAA8B,gBAAA;AACtF,EAAA,MAAM,WAAA,GAAc,iBAAA,GAAoB,gBAAA,GAAoB,0BAAA,GAA6B,kBAAA,GAAqB,CAAA;AAG9G,EAAAD,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,iBAAA,EAAmB;AAExB,IAAA,MAAM,KAAA,GAAQ,IAAI,KAAA,EAAM;AACxB,IAAA,KAAA,CAAM,OAAA,GAAU,UAAA;AAChB,IAAA,aAAA,CAAc,OAAA,GAAU,KAAA;AAExB,IAAA,MAAM,mBAAmB,MAAM;AAC7B,MAAA,mBAAA,CAAoB,MAAM,WAAW,CAAA;AAAA,IACvC,CAAA;AAEA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,iBAAA,CAAkB,KAAK,CAAA;AACvB,MAAA,mBAAA,CAAoB,CAAC,CAAA;AAAA,IACvB,CAAA;AAEA,IAAA,MAAM,uBAAuB,MAAM;AACjC,MAAA,gBAAA,CAAiB,MAAM,QAAQ,CAAA;AAAA,IACjC,CAAA;AAEA,IAAA,KAAA,CAAM,gBAAA,CAAiB,cAAc,gBAAgB,CAAA;AACrD,IAAA,KAAA,CAAM,gBAAA,CAAiB,SAAS,WAAW,CAAA;AAC3C,IAAA,KAAA,CAAM,gBAAA,CAAiB,kBAAkB,oBAAoB,CAAA;AAE7D,IAAA,OAAO,MAAM;AACX,MAAA,KAAA,CAAM,mBAAA,CAAoB,cAAc,gBAAgB,CAAA;AACxD,MAAA,KAAA,CAAM,mBAAA,CAAoB,SAAS,WAAW,CAAA;AAC9C,MAAA,KAAA,CAAM,mBAAA,CAAoB,kBAAkB,oBAAoB,CAAA;AAChE,MAAA,KAAA,CAAM,KAAA,EAAM;AACZ,MAAA,KAAA,CAAM,GAAA,GAAM,EAAA;AAAA,IACd,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,iBAAiB,CAAC,CAAA;AAGtB,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,iBAAA,EAAmB;AAExB,IAAA,MAAM,qBAAA,GAAwB,CAAC,KAAA,KAA+B;AAE5D,MAAA,IAAI,KAAA,CAAM,MAAA,KAAW,IAAA,CAAK,EAAA,IAAM,cAAc,OAAA,EAAS;AACrD,QAAA,aAAA,CAAc,QAAQ,KAAA,EAAM;AAC5B,QAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,MACzB;AAAA,IACF,CAAA;AAEA,IAAA,MAAA,CAAO,gBAAA,CAAiB,wBAAwB,qBAAsC,CAAA;AACtF,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,wBAAwB,qBAAsC,CAAA;AAAA,IAC3F,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,iBAAA,EAAmB,IAAA,CAAK,EAAE,CAAC,CAAA;AAG/B,EAAAA,gBAAU,MAAM;AACd,IAAA,IAAI,CAAC,cAAc,OAAA,EAAS;AAE5B,IAAA,MAAM,mBAAA,GAAsB,oBAAoB,gBAAA,GAAmB,kBAAA;AACnE,IAAA,MAAM,UAAA,GAAa,oBAAoB,cAAA,GAAiB,0BAAA;AAExD,IAAA,IAAI,CAAC,UAAA,EAAY;AAEjB,IAAA,MAAM,YAAA,GAAe,aAAA,CAAc,OAAA,CAAQ,WAAA,EAAY;AACvD,IAAA,IAAI,YAAA,GAAe,CAAA,IAAK,mBAAA,IAAuB,CAAA,EAAG;AAChD,MAAA,MAAM,WAAW,mBAAA,GAAsB,YAAA;AACvC,MAAA,aAAA,CAAc,QAAQ,MAAA,CAAO,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,CAAC,CAAC,CAAA;AAAA,IACpD;AAAA,EACF,GAAG,CAAC,gBAAA,EAAkB,oBAAoB,iBAAA,EAAmB,cAAA,EAAgB,0BAA0B,CAAC,CAAA;AAGxG,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,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;AAID,IAAA,UAAA,CAAW,SAAS,IAAI,CAAA;AAExB,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;AAE/D,MAAA,UAAA,CAAW,SAAS,IAAI,CAAA;AAAA,IAC1B,CAAC,CAAA;AAGD,IAAA,UAAA,CAAW,EAAA,CAAG,aAAA,EAAe,CAAC,OAAA,KAAoB;AAChD,MAAA,IAAI,iBAAA,EAAmB;AACrB,QAAA,IAAI,cAAc,OAAA,EAAS;AACzB,UAAA,aAAA,CAAc,QAAQ,WAAA,GAAc,OAAA;AACpC,UAAA,mBAAA,CAAoB,OAAO,CAAA;AAAA,QAC7B;AAAA,MACF,CAAA,MAAA,IAAW,8BAA8B,WAAA,EAAa;AACpD,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,0BAAA;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,IAAI,CAAC,cAAc,OAAA,EAAS;AAE5B,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,aAAA,CAAc,QAAQ,KAAA,EAAM;AAC5B,QAAA,iBAAA,CAAkB,KAAK,CAAA;AAAA,MACzB,CAAA,MAAO;AAEL,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;AAGA,QAAA,IAAI,aAAA,CAAc,OAAA,CAAQ,GAAA,KAAQ,IAAA,CAAK,QAAA,EAAU;AAC/C,UAAA,aAAA,CAAc,OAAA,CAAQ,MAAM,IAAA,CAAK,QAAA;AAAA,QACnC;AACA,QAAA,aAAA,CAAc,OAAA,CAAQ,IAAA,EAAK,CAAE,KAAA,CAAM,MAAM;AAAA,QAEzC,CAAC,CAAA;AACD,QAAA,iBAAA,CAAkB,IAAI,CAAA;AAAA,MACxB;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,IAAI,0BAAA,EAA4B;AAC9B,QAAA,iBAAA,IAAoB;AAAA,MACtB,CAAA,MAAO;AACL,QAAA,WAAA,GAAc,IAAI,CAAA;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,iBAAA,EAAmB,gBAAgB,0BAAA,EAA4B,WAAA,EAAa,iBAAiB,CAAC,CAAA;AAExG,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;AC3UA,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, 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)}&quote=${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
- const {
319
- play: contextPlay,
320
- togglePlay: contextTogglePlay,
321
- seek: contextSeek,
322
- currentSong,
323
- isPlaying: contextIsPlaying,
324
- currentTime: contextCurrentTime
325
- } = useAudioPlayer();
326
- const isThisSongPlaying = currentSong?.id === song.id;
327
- const isPlaying = isThisSongPlaying && contextIsPlaying;
328
- const currentTime = isThisSongPlaying ? contextCurrentTime : 0;
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 || !isThisSongPlaying) return;
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 && contextCurrentTime >= 0) {
333
- const progress = contextCurrentTime / waveDuration;
385
+ if (waveDuration > 0 && relevantCurrentTime >= 0) {
386
+ const progress = relevantCurrentTime / waveDuration;
334
387
  wavesurferRef.current.seekTo(Math.min(progress, 1));
335
388
  }
336
- }, [contextCurrentTime, isThisSongPlaying]);
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 (isThisSongPlaying) {
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
- isThisSongPlaying,
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 (isThisSongPlaying) {
398
- contextTogglePlay();
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
- contextPlay(song);
476
+ if (isThisSongPlayingInContext) {
477
+ contextTogglePlay?.();
478
+ } else {
479
+ contextPlay?.(song);
480
+ }
401
481
  }
402
- }, [song, isThisSongPlaying, contextPlay, contextTogglePlay]);
482
+ }, [song, useStandaloneMode, localIsPlaying, isThisSongPlayingInContext, contextPlay, contextTogglePlay]);
403
483
  return /* @__PURE__ */ jsxs(
404
484
  "div",
405
485
  {
@@ -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)}&quote=${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)}&quote=${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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wavesurf",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "A React audio player with WaveSurfer.js waveform visualization, global state management, and mini-player support",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",