@lucaismyname/ginger 0.0.3 → 0.0.8
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 +745 -0
- package/dist/audio/GingerPlayer.d.ts.map +1 -1
- package/dist/components/controls/Controls.d.ts +7 -3
- package/dist/components/controls/Controls.d.ts.map +1 -1
- package/dist/components/current/Artwork.d.ts.map +1 -1
- package/dist/components/current/Time.d.ts +11 -1
- package/dist/components/current/Time.d.ts.map +1 -1
- package/dist/components/current/index.d.ts +1 -1
- package/dist/components/current/index.d.ts.map +1 -1
- package/dist/components/playlist/GingerPlaylist.d.ts.map +1 -1
- package/dist/context/GingerContext.d.ts +3 -1
- package/dist/context/GingerContext.d.ts.map +1 -1
- package/dist/context/GingerLocaleContext.d.ts +9 -0
- package/dist/context/GingerLocaleContext.d.ts.map +1 -0
- package/dist/context/GingerProvider.d.ts +1 -1
- package/dist/context/GingerProvider.d.ts.map +1 -1
- package/dist/context/GingerSplitContexts.d.ts +42 -0
- package/dist/context/GingerSplitContexts.d.ts.map +1 -0
- package/dist/core/playbackReducer.d.ts.map +1 -1
- package/dist/core/playbackReducer.test.d.ts +2 -0
- package/dist/core/playbackReducer.test.d.ts.map +1 -0
- package/dist/core/queue.d.ts +2 -1
- package/dist/core/queue.d.ts.map +1 -1
- package/dist/core/transitions.test.d.ts +2 -0
- package/dist/core/transitions.test.d.ts.map +1 -0
- package/dist/ginger.d.ts +1 -0
- package/dist/ginger.d.ts.map +1 -1
- package/dist/hooks/useControlBindings.d.ts +40 -0
- package/dist/hooks/useControlBindings.d.ts.map +1 -0
- package/dist/hooks/useGinger.d.ts +3 -1
- package/dist/hooks/useGinger.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +999 -647
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +33 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -5
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/context/GingerContext.tsx","../src/audio/GingerPlayer.tsx","../src/core/queue.ts","../src/core/transitions.ts","../src/internal/selectors.ts","../src/components/current/createTextDisplay.tsx","../src/components/current/texts.ts","../src/components/current/Year.tsx","../src/components/current/Lyrics.tsx","../src/components/current/FileUrl.tsx","../src/components/current/Artwork.tsx","../src/components/current/QueueMeta.tsx","../src/internal/formatTime.ts","../src/components/current/Time.tsx","../src/components/current/Playback.tsx","../src/components/controls/Controls.tsx","../src/components/playlist/GingerPlaylist.tsx","../src/components/queue/QueueDisplay.tsx","../src/core/playbackReducer.ts","../src/context/GingerProvider.tsx","../src/ginger.ts","../src/hooks/useGinger.ts"],"sourcesContent":["import { createContext, useContext, type Dispatch, type MutableRefObject } from \"react\";\nimport type { GingerAction, GingerState, PlaylistMeta, RepeatMode, Track } from \"../types\";\n\nexport type GingerContextValue = {\n state: GingerState;\n dispatch: Dispatch<GingerAction>;\n audioRef: MutableRefObject<HTMLAudioElement | null>;\n notifyEnded: () => void;\n play: () => void;\n pause: () => void;\n togglePlayPause: () => void;\n seek: (timeSeconds: number) => void;\n setVolume: (volume: number) => void;\n setMuted: (muted: boolean) => void;\n toggleMute: () => void;\n setPlaybackRate: (rate: number) => void;\n next: () => void;\n prev: () => void;\n setRepeatMode: (mode: RepeatMode) => void;\n cycleRepeat: () => void;\n toggleShuffle: () => void;\n setQueue: (tracks: Track[], currentIndex?: number) => void;\n playTrackAt: (index: number) => void;\n selectTrackAt: (index: number) => void;\n setPlaylistMeta: (meta: PlaylistMeta | null) => void;\n};\n\nconst GingerContext = createContext<GingerContextValue | null>(null);\n\nexport function useGingerContext(): GingerContextValue {\n const ctx = useContext(GingerContext);\n if (!ctx) throw new Error(\"Ginger components must be used within <Ginger.Provider>\");\n return ctx;\n}\n\nexport { GingerContext };\n","import { useEffect, type AudioHTMLAttributes, type CSSProperties } from \"react\";\nimport { useGingerContext } from \"../context/GingerContext\";\n\nexport type GingerPlayerProps = {\n className?: string;\n style?: CSSProperties;\n preload?: AudioHTMLAttributes<HTMLAudioElement>[\"preload\"];\n crossOrigin?: AudioHTMLAttributes<HTMLAudioElement>[\"crossOrigin\"];\n};\n\nfunction readBufferedFraction(el: HTMLAudioElement): number {\n const { buffered, duration } = el;\n if (!(duration > 0) || buffered.length === 0) return 0;\n return Math.min(1, buffered.end(buffered.length - 1) / duration);\n}\n\nexport function GingerPlayer({ className, style, preload = \"metadata\", crossOrigin }: GingerPlayerProps) {\n const { audioRef, dispatch, state, notifyEnded } = useGingerContext();\n const url = state.tracks[state.currentIndex]?.fileUrl ?? \"\";\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n el.volume = state.volume;\n el.muted = state.muted;\n el.playbackRate = state.playbackRate;\n }, [audioRef, state.volume, state.muted, state.playbackRate]);\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n if (!url) {\n el.removeAttribute(\"src\");\n return;\n }\n if (el.getAttribute(\"src\") !== url) {\n el.src = url;\n el.load();\n }\n }, [audioRef, state.currentIndex, state.tracks, url]);\n\n return (\n <audio\n ref={audioRef}\n className={className}\n style={style}\n preload={preload}\n crossOrigin={crossOrigin}\n controls={false}\n onTimeUpdate={(e) => {\n const el = e.currentTarget;\n dispatch({\n type: \"MEDIA_TIME_UPDATE\",\n payload: {\n currentTime: el.currentTime,\n duration: el.duration,\n bufferedFraction: readBufferedFraction(el),\n },\n });\n }}\n onLoadedMetadata={(e) => {\n const el = e.currentTarget;\n dispatch({\n type: \"MEDIA_LOADED_METADATA\",\n payload: {\n duration: el.duration,\n bufferedFraction: readBufferedFraction(el),\n },\n });\n }}\n onEnded={() => notifyEnded()}\n onPlay={() => dispatch({ type: \"MEDIA_PLAY\" })}\n onPause={() => dispatch({ type: \"MEDIA_PAUSE\" })}\n onWaiting={() => dispatch({ type: \"MEDIA_WAITING\" })}\n onCanPlay={() => dispatch({ type: \"MEDIA_CANPLAY\" })}\n onVolumeChange={(e) => {\n const el = e.currentTarget;\n dispatch({\n type: \"MEDIA_VOLUME_SYNC\",\n payload: { volume: el.volume, muted: el.muted },\n });\n }}\n onError={() => {\n const el = audioRef.current;\n const code = el?.error?.code;\n const message =\n code === 1\n ? \"MEDIA_ERR_ABORTED\"\n : code === 2\n ? \"MEDIA_ERR_NETWORK\"\n : code === 3\n ? \"MEDIA_ERR_DECODE\"\n : code === 4\n ? \"MEDIA_ERR_SRC_NOT_SUPPORTED\"\n : \"MEDIA_ERR_UNKNOWN\";\n dispatch({ type: \"MEDIA_ERROR\", payload: { message } });\n }}\n />\n );\n}\n","import type { Track } from \"../types\";\n\nexport function clampIndex(index: number, length: number): number {\n if (length <= 0) return 0;\n return Math.max(0, Math.min(length - 1, index));\n}\n\nexport function shuffleWithAnchor(tracks: Track[], anchorIndex: number): Track[] {\n if (tracks.length <= 1) return [...tracks];\n const anchor = tracks[anchorIndex];\n if (!anchor) return [...tracks];\n const rest = tracks.filter((_, i) => i !== anchorIndex);\n for (let i = rest.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [rest[i], rest[j]] = [rest[j]!, rest[i]!];\n }\n return [anchor, ...rest];\n}\n\nexport function findIndexByFileUrl(tracks: Track[], fileUrl: string): number {\n const i = tracks.findIndex((t) => t.fileUrl === fileUrl);\n return i === -1 ? 0 : i;\n}\n","import type { GingerState, RepeatMode, Track } from \"../types\";\nimport { clampIndex } from \"./queue\";\n\nexport type EndedTransition =\n | { kind: \"replay_same\" }\n | { kind: \"advance\"; nextIndex: number }\n | { kind: \"wrap\"; nextIndex: number }\n | { kind: \"stop\"; nextIndex: number };\n\nexport function computeEndedTransition(state: GingerState): EndedTransition {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return { kind: \"stop\", nextIndex: 0 };\n if (repeatMode === \"one\") return { kind: \"replay_same\" };\n if (currentIndex < len - 1) return { kind: \"advance\", nextIndex: currentIndex + 1 };\n if (repeatMode === \"all\") return { kind: \"wrap\", nextIndex: 0 };\n return { kind: \"stop\", nextIndex: clampIndex(currentIndex, len) };\n}\n\nexport function computeNextIndex(state: GingerState): number {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return 0;\n if (currentIndex < len - 1) return currentIndex + 1;\n if (repeatMode === \"all\") return 0;\n return clampIndex(currentIndex, len);\n}\n\nexport function computePrevIndex(state: GingerState): number {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return 0;\n if (currentIndex > 0) return currentIndex - 1;\n if (repeatMode === \"all\") return len - 1;\n return 0;\n}\n\nexport function cycleRepeatMode(mode: RepeatMode): RepeatMode {\n if (mode === \"off\") return \"all\";\n if (mode === \"all\") return \"one\";\n return \"off\";\n}\n\nexport function resolveArtworkUrl(track: Track | null, playlistArtwork?: string | null): string | undefined {\n return track?.artworkUrl ?? playlistArtwork ?? undefined;\n}\n\nexport function resolveAlbumLine(track: Track | null, playlistSubtitle?: string | null): string | undefined {\n return track?.album ?? playlistSubtitle ?? undefined;\n}\n","import type { GingerState, PlaybackUiState, Track } from \"../types\";\nimport { resolveAlbumLine, resolveArtworkUrl } from \"../core/transitions\";\n\nexport function getCurrentTrack(state: GingerState): Track | null {\n const t = state.tracks[state.currentIndex];\n return t ?? null;\n}\n\nexport function derivePlaybackUiState(state: GingerState): PlaybackUiState {\n if (state.errorMessage) return \"error\";\n if (state.tracks.length === 0) return \"idle\";\n if (state.isBuffering) return \"loading\";\n if (!state.isPaused) return \"playing\";\n if (\n Number.isFinite(state.duration) &&\n state.duration > 0 &&\n state.currentTime >= state.duration - 0.05\n ) {\n return \"ended\";\n }\n return \"paused\";\n}\n\nexport function effectiveDuration(state: GingerState): number {\n const d = state.duration;\n if (Number.isFinite(d) && d > 0) return d;\n const hint = state.tracks[state.currentIndex]?.durationSeconds;\n if (typeof hint === \"number\" && Number.isFinite(hint) && hint > 0) return hint;\n return 0;\n}\n\nexport function effectiveRemaining(state: GingerState): number {\n const dur = effectiveDuration(state);\n const rem = dur - state.currentTime;\n return Number.isFinite(rem) ? Math.max(0, rem) : 0;\n}\n\nexport function progressFraction(state: GingerState): number {\n const dur = effectiveDuration(state);\n if (!(dur > 0)) return 0;\n return Math.min(1, Math.max(0, state.currentTime / dur));\n}\n\nexport function resolvedArtwork(state: GingerState): string | undefined {\n const track = getCurrentTrack(state);\n return resolveArtworkUrl(track, state.playlistMeta?.artworkUrl);\n}\n\nexport function resolvedAlbumLine(state: GingerState): string | undefined {\n const track = getCurrentTrack(state);\n return resolveAlbumLine(track, state.playlistMeta?.subtitle);\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState, Track } from \"../../types\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\nimport { useGingerContext } from \"../../context/GingerContext\";\n\nexport type TextDisplayProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function createTextDisplay(\n displayName: string,\n select: (state: GingerState) => string | undefined,\n): (props: TextDisplayProps) => ReactElement | null {\n function Comp(props: TextDisplayProps) {\n const { state } = useGingerContext();\n const raw = select(state) ?? \"\";\n const value = raw.trim();\n const { className, style, fallback, empty, children } = props;\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n }\n Comp.displayName = displayName;\n return Comp;\n}\n\nexport function createTrackFieldDisplay(\n displayName: string,\n select: (track: Track | null) => string | undefined,\n): (props: TextDisplayProps) => ReactElement | null {\n return createTextDisplay(displayName, (state) => select(getCurrentTrack(state)));\n}\n","import { createTextDisplay, createTrackFieldDisplay } from \"./createTextDisplay\";\nimport { getCurrentTrack, resolvedAlbumLine } from \"../../internal/selectors\";\n\nexport const Title = createTrackFieldDisplay(\"Ginger.Current.Title\", (t) => t?.title);\nexport const Artist = createTrackFieldDisplay(\"Ginger.Current.Artist\", (t) => t?.artist);\nexport const Album = createTextDisplay(\"Ginger.Current.Album\", (s) => resolvedAlbumLine(s));\nexport const Description = createTrackFieldDisplay(\"Ginger.Current.Description\", (t) => t?.description);\nexport const Copyright = createTextDisplay(\"Ginger.Current.Copyright\", (s) => {\n const t = getCurrentTrack(s);\n return t?.copyright ?? s.playlistMeta?.copyright;\n});\nexport const Genre = createTrackFieldDisplay(\"Ginger.Current.Genre\", (t) => t?.genre);\nexport const Label = createTrackFieldDisplay(\"Ginger.Current.Label\", (t) => t?.label);\nexport const Isrc = createTrackFieldDisplay(\"Ginger.Current.Isrc\", (t) => t?.isrc);\nexport const TrackNumber = createTrackFieldDisplay(\"Ginger.Current.TrackNumber\", (t) =>\n t?.trackNumber != null ? String(t.trackNumber) : undefined,\n);\n","import type { TextDisplayProps } from \"./createTextDisplay\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type YearProps = TextDisplayProps & {\n format?: (year: number) => string;\n};\n\nexport function Year({ className, style, fallback, empty, children, format }: YearProps) {\n const { state } = useGingerContext();\n const y = getCurrentTrack(state)?.year;\n if (typeof y !== \"number\" || !Number.isFinite(y)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const text = format ? format(y) : String(y);\n if (children) return <span className={className} style={style}>{children(text, state)}</span>;\n return (\n <span className={className} style={style}>\n {text}\n </span>\n );\n}\n\nYear.displayName = \"Ginger.Current.Year\";\n","import type { CSSProperties, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type LyricsProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n /** When true, preserves internal newlines; trims only leading/trailing whitespace */\n preserveWhitespace?: boolean;\n};\n\nexport function Lyrics({ className, style, fallback, empty, children, preserveWhitespace = true }: LyricsProps) {\n const { state } = useGingerContext();\n const raw = getCurrentTrack(state)?.lyrics ?? \"\";\n const value = preserveWhitespace ? raw.replace(/^\\s+|\\s+$/g, \"\") : raw.trim();\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const whiteStyle: CSSProperties | undefined = preserveWhitespace ? { whiteSpace: \"pre-wrap\" } : undefined;\n if (children) return <span className={className} style={{ ...whiteStyle, ...style }}>{children(value, state)}</span>;\n return (\n <span className={className} style={{ ...whiteStyle, ...style }}>\n {value}\n </span>\n );\n}\n\nLyrics.displayName = \"Ginger.Current.Lyrics\";\n","import type { TextDisplayProps } from \"./createTextDisplay\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type FileUrlProps = TextDisplayProps & {\n /** When false (default), renders nothing unless you explicitly opt in */\n visible?: boolean;\n};\n\nexport function FileUrl({ visible = false, className, style, fallback, empty, children }: FileUrlProps) {\n const { state } = useGingerContext();\n if (!visible) return null;\n const value = getCurrentTrack(state)?.fileUrl ?? \"\";\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nFileUrl.displayName = \"Ginger.Current.FileUrl\";\n","import type { CSSProperties, ImgHTMLAttributes } from \"react\";\nimport type { DisplayBaseProps } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { getCurrentTrack, resolvedArtwork } from \"../../internal/selectors\";\n\nexport type ArtworkProps = DisplayBaseProps &\n Pick<ImgHTMLAttributes<HTMLImageElement>, \"sizes\" | \"loading\" | \"onError\" | \"decoding\"> & {\n imgStyle?: CSSProperties;\n };\n\nexport function Artwork({ className, style, fallback, empty, sizes, loading, onError, decoding, imgStyle }: ArtworkProps) {\n const { state } = useGingerContext();\n const track = getCurrentTrack(state);\n const src = resolvedArtwork(state);\n if (!src) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const alt = [track?.title, track?.artist].filter(Boolean).join(\" — \") || \"Artwork\";\n return (\n <span\n className={className}\n style={{\n display: \"inline-block\",\n background: \"var(--ginger-artwork-bg, #f3f4f6)\",\n borderRadius: \"var(--ginger-artwork-radius, 6px)\",\n overflow: \"hidden\",\n ...style,\n }}\n >\n <img\n src={src}\n alt={alt}\n sizes={sizes}\n loading={loading}\n decoding={decoding}\n onError={onError}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n ...imgStyle,\n }}\n />\n </span>\n );\n}\n\nArtwork.displayName = \"Ginger.Current.Artwork\";\n","import type { ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\n\nexport type QueueIndexProps = DisplayBaseProps & {\n base?: 0 | 1;\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function QueueIndex({ base = 0, className, style, fallback, empty, children }: QueueIndexProps) {\n const { state } = useGingerContext();\n const len = state.tracks.length;\n if (len === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const value = String(state.currentIndex + base);\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nQueueIndex.displayName = \"Ginger.Current.QueueIndex\";\n\nexport type QueueLengthProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function QueueLength({ className, style, fallback, empty, children }: QueueLengthProps) {\n const { state } = useGingerContext();\n const value = String(state.tracks.length);\n if (state.tracks.length === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nQueueLength.displayName = \"Ginger.Current.QueueLength\";\n\nexport type QueuePositionProps = DisplayBaseProps & {\n base?: 0 | 1;\n separator?: string;\n children?: (value: { index: string; length: string; label: string }, state: GingerState) => ReactNode;\n};\n\nexport function QueuePosition({\n base = 0,\n separator = \" / \",\n className,\n style,\n fallback,\n empty,\n children,\n}: QueuePositionProps) {\n const { state } = useGingerContext();\n const len = state.tracks.length;\n if (len === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const index = String(state.currentIndex + base);\n const length = String(len);\n const label = `${index}${separator}${length}`;\n if (children)\n return (\n <span className={className} style={style}>\n {children({ index, length, label }, state)}\n </span>\n );\n return (\n <span className={className} style={style}>\n {label}\n </span>\n );\n}\n\nQueuePosition.displayName = \"Ginger.Current.QueuePosition\";\n","export function formatMmSs(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"0:00\";\n const s = Math.floor(seconds % 60);\n const m = Math.floor(seconds / 60);\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { effectiveDuration, effectiveRemaining, progressFraction } from \"../../internal/selectors\";\nimport { formatMmSs } from \"../../internal/formatTime\";\n\nexport type TimeTextProps = DisplayBaseProps & {\n format?: (seconds: number) => string;\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nfunction renderTime(\n valueSeconds: number,\n state: GingerState,\n props: TimeTextProps,\n): ReactElement | null {\n const { className, style, fallback, empty, children, format = formatMmSs } = props;\n if (!(valueSeconds >= 0) || !Number.isFinite(valueSeconds)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const text = format(valueSeconds);\n if (children) return <span className={className} style={style}>{children(text, state)}</span>;\n return (\n <span className={className} style={style}>\n {text}\n </span>\n );\n}\n\nexport function Elapsed(props: TimeTextProps) {\n const { state } = useGingerContext();\n return renderTime(state.currentTime, state, props);\n}\n\nElapsed.displayName = \"Ginger.Current.Elapsed\";\n\nexport function Duration(props: TimeTextProps) {\n const { state } = useGingerContext();\n return renderTime(effectiveDuration(state), state, props);\n}\n\nDuration.displayName = \"Ginger.Current.Duration\";\n\nexport function Remaining(props: TimeTextProps) {\n const { state } = useGingerContext();\n return renderTime(effectiveRemaining(state), state, props);\n}\n\nRemaining.displayName = \"Ginger.Current.Remaining\";\n\nexport type ProgressProps = DisplayBaseProps & {\n children?: (value: { fraction: number; currentTime: number; duration: number }, state: GingerState) => ReactNode;\n};\n\nexport function Progress({ className, style, fallback, empty, children }: ProgressProps) {\n const { state } = useGingerContext();\n const duration = effectiveDuration(state);\n const fraction = progressFraction(state);\n if (!(duration > 0)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children)\n return (\n <span className={className} style={style}>\n {children({ fraction, currentTime: state.currentTime, duration }, state)}\n </span>\n );\n return (\n <span className={className} style={style}>\n {`${Math.round(fraction * 100)}%`}\n </span>\n );\n}\n\nProgress.displayName = \"Ginger.Current.Progress\";\n\nexport type TimeRailProps = DisplayBaseProps & {\n /** 0-1 height in px for the rail */\n height?: number;\n};\n\nexport function TimeRail({ className, style, height = 4 }: TimeRailProps) {\n const { state } = useGingerContext();\n const pct = `${Math.round(progressFraction(state) * 100)}%`;\n return (\n <div\n className={className}\n style={{\n width: \"100%\",\n height,\n background: \"var(--ginger-muted-color, #e5e7eb)\",\n borderRadius: 999,\n overflow: \"hidden\",\n ...style,\n }}\n aria-hidden\n >\n <div style={{ width: pct, height: \"100%\", background: \"var(--ginger-primary-color, #111827)\" }} />\n </div>\n );\n}\n\nTimeRail.displayName = \"Ginger.Current.TimeRail\";\n","import type { ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState, PlaybackUiState } from \"../../types\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport { derivePlaybackUiState } from \"../../internal/selectors\";\n\nexport type PlaybackStateProps = DisplayBaseProps & {\n children?: (value: PlaybackUiState, state: GingerState) => ReactNode;\n};\n\nexport function PlaybackState({ className, style, fallback, empty, children }: PlaybackStateProps) {\n const { state } = useGingerContext();\n const value = derivePlaybackUiState(state);\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nPlaybackState.displayName = \"Ginger.Current.PlaybackState\";\n\nexport type ErrorMessageProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function ErrorMessage({ className, style, fallback, empty, children }: ErrorMessageProps) {\n const { state } = useGingerContext();\n const value = state.errorMessage ?? \"\";\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nErrorMessage.displayName = \"Ginger.Current.ErrorMessage\";\n","import { useMemo } from \"react\";\nimport type {\n ButtonHTMLAttributes,\n CSSProperties,\n InputHTMLAttributes,\n ReactNode,\n SelectHTMLAttributes,\n} from \"react\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport type { RepeatMode } from \"../../types\";\n\nexport type PlayPauseProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Optional labels; still headless—defaults are text for a11y */\n playLabel?: ReactNode;\n pauseLabel?: ReactNode;\n};\n\nexport function PlayPause({ playLabel = \"Play\", pauseLabel = \"Pause\", type = \"button\", ...rest }: PlayPauseProps) {\n const { state, togglePlayPause } = useGingerContext();\n return (\n <button type={type} aria-label={state.isPaused ? \"Play\" : \"Pause\"} onClick={togglePlayPause} {...rest}>\n {state.isPaused ? playLabel : pauseLabel}\n </button>\n );\n}\n\nPlayPause.displayName = \"Ginger.Control.PlayPause\";\n\nconst repeatLabels: Record<RepeatMode, string> = {\n off: \"Repeat off\",\n all: \"Repeat all\",\n one: \"Repeat one\",\n};\n\nexport type RepeatProps = ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport function Repeat({ type = \"button\", ...rest }: RepeatProps) {\n const { state, cycleRepeat } = useGingerContext();\n return (\n <button type={type} aria-label={repeatLabels[state.repeatMode]} onClick={cycleRepeat} {...rest}>\n {repeatLabels[state.repeatMode]}\n </button>\n );\n}\n\nRepeat.displayName = \"Ginger.Control.Repeat\";\n\nexport type NextProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Next({ type = \"button\", children = \"Next\", ...rest }: NextProps) {\n const { next } = useGingerContext();\n return (\n <button type={type} aria-label=\"Next track\" onClick={next} {...rest}>\n {children}\n </button>\n );\n}\nNext.displayName = \"Ginger.Control.Next\";\n\nexport type PreviousProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Previous({ type = \"button\", children = \"Previous\", ...rest }: PreviousProps) {\n const { prev } = useGingerContext();\n return (\n <button type={type} aria-label=\"Previous track\" onClick={prev} {...rest}>\n {children}\n </button>\n );\n}\nPrevious.displayName = \"Ginger.Control.Previous\";\n\nexport type ShuffleProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Shuffle({ type = \"button\", children = \"Shuffle\", ...rest }: ShuffleProps) {\n const { state, toggleShuffle } = useGingerContext();\n return (\n <button type={type} aria-pressed={state.isShuffled} aria-label=\"Shuffle\" onClick={toggleShuffle} {...rest}>\n {children}\n </button>\n );\n}\nShuffle.displayName = \"Ginger.Control.Shuffle\";\n\nexport type SeekBarProps = Omit<InputHTMLAttributes<HTMLInputElement>, \"type\" | \"value\" | \"onChange\"> & {\n inputStyle?: CSSProperties;\n};\n\nexport function SeekBar({ inputStyle, style, ...rest }: SeekBarProps) {\n const { state, seek } = useGingerContext();\n const duration = Number.isFinite(state.duration) && state.duration > 0 ? state.duration : 0;\n const value = duration > 0 ? state.currentTime : 0;\n return (\n <input\n type=\"range\"\n min={0}\n max={duration > 0 ? duration : 1}\n step=\"any\"\n value={Number.isFinite(value) ? value : 0}\n aria-label=\"Seek\"\n onChange={(e) => seek(Number(e.currentTarget.value))}\n style={{ width: \"100%\", ...style, ...inputStyle }}\n {...rest}\n />\n );\n}\n\nSeekBar.displayName = \"Ginger.Control.SeekBar\";\n\nexport type VolumeProps = Omit<InputHTMLAttributes<HTMLInputElement>, \"type\" | \"value\" | \"onChange\"> & {\n inputStyle?: CSSProperties;\n};\n\nexport function Volume({ inputStyle, style, ...rest }: VolumeProps) {\n const { state, setVolume } = useGingerContext();\n return (\n <input\n type=\"range\"\n min={0}\n max={1}\n step=\"any\"\n value={state.volume}\n aria-label=\"Volume\"\n onChange={(e) => setVolume(Number(e.currentTarget.value))}\n style={{ width: \"100%\", ...style, ...inputStyle }}\n {...rest}\n />\n );\n}\n\nVolume.displayName = \"Ginger.Control.Volume\";\n\nexport type MuteProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n muteLabel?: ReactNode;\n unmuteLabel?: ReactNode;\n};\n\nexport function Mute({\n muteLabel = \"Mute\",\n unmuteLabel = \"Unmute\",\n type = \"button\",\n ...rest\n}: MuteProps) {\n const { state, toggleMute } = useGingerContext();\n return (\n <button\n type={type}\n aria-pressed={state.muted}\n aria-label={state.muted ? \"Unmute\" : \"Mute\"}\n onClick={toggleMute}\n {...rest}\n >\n {state.muted ? unmuteLabel : muteLabel}\n </button>\n );\n}\n\nMute.displayName = \"Ginger.Control.Mute\";\n\nconst defaultRates = [0.5, 0.75, 1, 1.25, 1.5, 2] as const;\n\nexport type PlaybackRateProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, \"value\" | \"onChange\"> & {\n /** Playback speed options (default: 0.5 … 2) */\n rates?: readonly number[];\n};\n\nexport function PlaybackRate({ rates = defaultRates, style, ...rest }: PlaybackRateProps) {\n const { state, setPlaybackRate } = useGingerContext();\n const options = useMemo(\n () => Array.from(new Set([...rates, state.playbackRate])).sort((a, b) => a - b),\n [rates, state.playbackRate],\n );\n return (\n <select\n aria-label=\"Playback speed\"\n value={String(state.playbackRate)}\n style={style}\n onChange={(e) => setPlaybackRate(Number(e.currentTarget.value))}\n {...rest}\n >\n {options.map((r) => (\n <option key={r} value={String(r)}>\n {r === 1 ? \"1× normal\" : `${r}×`}\n </option>\n ))}\n </select>\n );\n}\n\nPlaybackRate.displayName = \"Ginger.Control.PlaybackRate\";\n","import {\n createContext,\n useContext,\n type ButtonHTMLAttributes,\n type CSSProperties,\n type HTMLAttributes,\n type LiHTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { useGingerContext } from \"../../context/GingerContext\";\nimport type { Track } from \"../../types\";\n\nexport type GingerPlaylistConfig = {\n playOnSelect: boolean;\n};\n\nconst GingerPlaylistConfigContext = createContext<GingerPlaylistConfig | null>(null);\n\nfunction usePlaylistConfig(): GingerPlaylistConfig {\n const ctx = useContext(GingerPlaylistConfigContext);\n if (!ctx) {\n throw new Error(\"Ginger.Playlist.Track must be used inside <Ginger.Playlist>\");\n }\n return ctx;\n}\n\nexport type GingerPlaylistProps = Omit<HTMLAttributes<HTMLUListElement>, \"children\"> & {\n children?: ReactNode;\n rowStyle?: CSSProperties;\n /**\n * Used only in **auto** mode (no custom `children`). Ignored when you pass custom `children`\n * (manual mode); use `Ginger.Playlist.Track` for each row instead.\n */\n renderTrack?: (track: Track, index: number, isActive: boolean) => ReactNode;\n /** When true (default), clicking a row selects that index and starts playback */\n playOnSelect?: boolean;\n};\n\n/**\n * - **Auto mode** (no `children`): maps `state.tracks` to rows (optional `renderTrack`).\n * - **Manual mode** (`children` defined): renders `<ul>{children}</ul>`; map `state.tracks` yourself\n * with `Ginger.Playlist.Track` for each index.\n */\nexport function GingerPlaylist({\n children,\n rowStyle,\n renderTrack,\n playOnSelect = true,\n style,\n ...rest\n}: GingerPlaylistProps) {\n const { state, playTrackAt, selectTrackAt } = useGingerContext();\n\n const listStyle: CSSProperties = {\n listStyle: \"none\",\n margin: 0,\n padding: 0,\n fontFamily: \"var(--ginger-font-family, system-ui, sans-serif)\",\n fontSize: \"var(--ginger-font-size, 14px)\",\n color: \"var(--ginger-primary-color, #111827)\",\n ...style,\n };\n\n const manual = children !== undefined;\n\n if (manual) {\n return (\n <GingerPlaylistConfigContext.Provider value={{ playOnSelect }}>\n <ul style={listStyle} {...rest}>\n {children}\n </ul>\n </GingerPlaylistConfigContext.Provider>\n );\n }\n\n return (\n <GingerPlaylistConfigContext.Provider value={{ playOnSelect }}>\n <ul style={listStyle} {...rest}>\n {state.tracks.map((track, index) => {\n const active = index === state.currentIndex;\n return (\n <li key={`${track.fileUrl}-${index}`}>\n <button\n type=\"button\"\n onClick={() => {\n if (playOnSelect) playTrackAt(index);\n else selectTrackAt(index);\n }}\n style={{\n width: \"100%\",\n textAlign: \"left\",\n border: \"none\",\n background: active ? \"rgba(17, 24, 39, 0.06)\" : \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n cursor: \"pointer\",\n padding: \"var(--ginger-playlist-row-padding, 6px 8px)\",\n ...rowStyle,\n }}\n >\n {renderTrack ? (\n renderTrack(track, index, active)\n ) : (\n <span>\n {track.title}\n {track.artist ? ` — ${track.artist}` : \"\"}\n </span>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n </GingerPlaylistConfigContext.Provider>\n );\n}\n\nGingerPlaylist.displayName = \"Ginger.Playlist\";\n\nexport type GingerPlaylistTrackProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> & {\n index: number;\n /** Optional wrapper for the row; defaults to a plain `<li>` */\n liProps?: LiHTMLAttributes<HTMLLIElement>;\n};\n\nexport function GingerPlaylistTrack({\n index,\n className,\n style,\n children,\n liProps,\n onClick,\n ...buttonRest\n}: GingerPlaylistTrackProps) {\n const { playOnSelect } = usePlaylistConfig();\n const { state, playTrackAt, selectTrackAt } = useGingerContext();\n const active = index === state.currentIndex;\n const track = state.tracks[index];\n const defaultLabel =\n track != null ? (\n <span>\n {track.title}\n {track.artist ? ` — ${track.artist}` : \"\"}\n </span>\n ) : null;\n\n return (\n <li {...liProps}>\n <button\n type=\"button\"\n aria-current={active ? \"true\" : undefined}\n data-ginger-active={active || undefined}\n className={className}\n style={{\n width: \"100%\",\n textAlign: \"left\",\n border: \"none\",\n background: active ? \"rgba(17, 24, 39, 0.06)\" : \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n cursor: \"pointer\",\n padding: \"var(--ginger-playlist-row-padding, 6px 8px)\",\n ...style,\n }}\n {...buttonRest}\n onClick={(e) => {\n onClick?.(e);\n if (e.defaultPrevented) return;\n if (playOnSelect) playTrackAt(index);\n else selectTrackAt(index);\n }}\n >\n {children ?? defaultLabel}\n </button>\n </li>\n );\n}\n\nGingerPlaylistTrack.displayName = \"Ginger.Playlist.Track\";\n\nexport const GingerPlaylistCompound = Object.assign(GingerPlaylist, {\n Track: GingerPlaylistTrack,\n});\n","import type { CSSProperties } from \"react\";\nimport type { DisplayBaseProps } from \"../../types\";\nimport { createTextDisplay } from \"../current/createTextDisplay\";\nimport { useGingerContext } from \"../../context/GingerContext\";\n\nexport const Title = createTextDisplay(\"Ginger.Queue.Title\", (s) => s.playlistMeta?.title);\nexport const Subtitle = createTextDisplay(\"Ginger.Queue.Subtitle\", (s) => s.playlistMeta?.subtitle);\nexport const Description = createTextDisplay(\"Ginger.Queue.Description\", (s) => s.playlistMeta?.description);\nexport const Copyright = createTextDisplay(\"Ginger.Queue.Copyright\", (s) => s.playlistMeta?.copyright);\n\nexport type QueueArtworkProps = DisplayBaseProps & {\n imgStyle?: CSSProperties;\n};\n\nexport function Artwork({ className, style, fallback, empty, imgStyle }: QueueArtworkProps) {\n const { state } = useGingerContext();\n const src = state.playlistMeta?.artworkUrl;\n if (!src) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const alt = state.playlistMeta?.title ?? \"Playlist artwork\";\n return (\n <span\n className={className}\n style={{\n display: \"inline-block\",\n background: \"var(--ginger-artwork-bg, #f3f4f6)\",\n borderRadius: \"var(--ginger-artwork-radius, 6px)\",\n overflow: \"hidden\",\n ...style,\n }}\n >\n <img\n src={src}\n alt={alt}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n ...imgStyle,\n }}\n />\n </span>\n );\n}\n\nArtwork.displayName = \"Ginger.Queue.Artwork\";\n","import type { GingerAction, GingerState, RepeatMode, Track } from \"../types\";\nimport { clampIndex, findIndexByFileUrl, shuffleWithAnchor } from \"./queue\";\nimport { computeNextIndex, computePrevIndex, cycleRepeatMode } from \"./transitions\";\n\nexport function clampVolume(v: number): number {\n if (!Number.isFinite(v)) return 1;\n return Math.min(1, Math.max(0, v));\n}\n\nexport function clampPlaybackRate(r: number): number {\n if (!Number.isFinite(r)) return 1;\n return Math.min(4, Math.max(0.25, r));\n}\n\n/** Reset when the active track / position changes; keeps volume / mute / speed */\nconst resetTimingOnly = {\n currentTime: 0,\n duration: 0,\n bufferedFraction: 0,\n isBuffering: false,\n errorMessage: null as string | null,\n};\n\nconst defaultMedia = {\n ...resetTimingOnly,\n volume: 1,\n muted: false,\n playbackRate: 1,\n};\n\nexport function createInitialState(params: {\n tracks: Track[];\n currentIndex?: number;\n playlistMeta?: GingerState[\"playlistMeta\"];\n isPaused?: boolean;\n isShuffled?: boolean;\n repeatMode?: RepeatMode;\n volume?: number;\n muted?: boolean;\n playbackRate?: number;\n}): GingerState {\n const tracks = [...params.tracks];\n let currentIndex = clampIndex(params.currentIndex ?? 0, tracks.length);\n let originalTracks: Track[] | null = null;\n let ordered = tracks;\n\n if (params.isShuffled && tracks.length > 1) {\n originalTracks = [...tracks];\n ordered = shuffleWithAnchor(tracks, currentIndex);\n currentIndex = 0;\n }\n\n return {\n tracks: ordered,\n currentIndex,\n isPaused: params.isPaused ?? true,\n isShuffled: Boolean(params.isShuffled && ordered.length > 1),\n repeatMode: params.repeatMode ?? \"off\",\n originalTracks,\n playlistMeta: params.playlistMeta ?? null,\n ...defaultMedia,\n volume: clampVolume(params.volume ?? 1),\n muted: params.muted ?? false,\n playbackRate: clampPlaybackRate(params.playbackRate ?? 1),\n };\n}\n\nexport function gingerReducer(state: GingerState, action: GingerAction): GingerState {\n switch (action.type) {\n case \"INIT\": {\n const {\n tracks,\n currentIndex,\n playlistMeta,\n isPaused,\n isShuffled,\n repeatMode,\n volume,\n muted,\n playbackRate,\n } = action.payload;\n return createInitialState({\n tracks,\n currentIndex,\n playlistMeta: playlistMeta ?? null,\n isPaused: isPaused ?? true,\n isShuffled: isShuffled ?? false,\n repeatMode: repeatMode ?? \"off\",\n volume,\n muted,\n playbackRate,\n });\n }\n case \"SET_QUEUE\": {\n const { tracks, currentIndex } = action.payload;\n const next = [...tracks];\n const idx = clampIndex(currentIndex ?? state.currentIndex, next.length);\n return {\n ...state,\n tracks: next,\n currentIndex: idx,\n ...resetTimingOnly,\n };\n }\n case \"SET_INDEX\": {\n const idx = clampIndex(action.payload.index, state.tracks.length);\n const ap = action.payload.autoPlay;\n const isPaused =\n ap === true ? false : ap === false ? true : state.isPaused;\n return {\n ...state,\n currentIndex: idx,\n ...resetTimingOnly,\n isPaused,\n };\n }\n case \"PLAY\":\n return { ...state, isPaused: false };\n case \"PAUSE\":\n return { ...state, isPaused: true };\n case \"TOGGLE_PAUSE\":\n return { ...state, isPaused: !state.isPaused };\n case \"SET_REPEAT\":\n return { ...state, repeatMode: action.payload };\n case \"CYCLE_REPEAT\":\n return { ...state, repeatMode: cycleRepeatMode(state.repeatMode) };\n case \"TOGGLE_SHUFFLE\": {\n if (state.tracks.length <= 1) return { ...state, isShuffled: false, originalTracks: null };\n if (!state.isShuffled) {\n const snapshot = [...state.tracks];\n const shuffled = shuffleWithAnchor(snapshot, state.currentIndex);\n return {\n ...state,\n isShuffled: true,\n originalTracks: snapshot,\n tracks: shuffled,\n currentIndex: 0,\n };\n }\n const restored = state.originalTracks ? [...state.originalTracks] : [...state.tracks];\n const current = state.tracks[state.currentIndex];\n const fileUrl = current?.fileUrl ?? \"\";\n const newIndex = findIndexByFileUrl(restored, fileUrl);\n return {\n ...state,\n isShuffled: false,\n originalTracks: null,\n tracks: restored,\n currentIndex: clampIndex(newIndex, restored.length),\n };\n }\n case \"NEXT\": {\n const nextIndex = computeNextIndex(state);\n const same = nextIndex === state.currentIndex;\n return {\n ...state,\n currentIndex: nextIndex,\n ...(same ? {} : resetTimingOnly),\n isPaused: same ? state.isPaused : false,\n };\n }\n case \"PREV\": {\n const prevIndex = computePrevIndex(state);\n const same = prevIndex === state.currentIndex;\n return {\n ...state,\n currentIndex: prevIndex,\n ...(same ? {} : resetTimingOnly),\n isPaused: same ? state.isPaused : false,\n };\n }\n case \"MEDIA_TIME_UPDATE\":\n return {\n ...state,\n currentTime: action.payload.currentTime,\n duration: Number.isFinite(action.payload.duration) ? action.payload.duration : state.duration,\n bufferedFraction: action.payload.bufferedFraction,\n isBuffering: false,\n };\n case \"MEDIA_LOADED_METADATA\":\n return {\n ...state,\n duration: Number.isFinite(action.payload.duration) ? action.payload.duration : state.duration,\n bufferedFraction: action.payload.bufferedFraction,\n errorMessage: null,\n };\n case \"SET_PLAYLIST_META\":\n return { ...state, playlistMeta: action.payload };\n case \"MEDIA_ERROR\":\n return {\n ...state,\n errorMessage: action.payload.message,\n isPaused: true,\n isBuffering: false,\n };\n case \"MEDIA_WAITING\":\n return { ...state, isBuffering: true };\n case \"MEDIA_CANPLAY\":\n return { ...state, isBuffering: false, errorMessage: null };\n case \"MEDIA_PLAY\":\n return { ...state, isPaused: false, isBuffering: false };\n case \"MEDIA_PAUSE\":\n return { ...state, isPaused: true };\n case \"RESET_MEDIA_TIMES\":\n return { ...state, currentTime: 0, duration: 0, bufferedFraction: 0 };\n case \"SET_VOLUME\":\n return { ...state, volume: clampVolume(action.payload) };\n case \"SET_MUTED\":\n return { ...state, muted: action.payload };\n case \"TOGGLE_MUTE\":\n return { ...state, muted: !state.muted };\n case \"SET_PLAYBACK_RATE\":\n return { ...state, playbackRate: clampPlaybackRate(action.payload) };\n case \"MEDIA_VOLUME_SYNC\": {\n const { volume, muted } = action.payload;\n const v = clampVolume(volume);\n if (v === state.volume && muted === state.muted) return state;\n return { ...state, volume: v, muted };\n }\n default:\n return state;\n }\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n type CSSProperties,\n} from \"react\";\nimport { computeEndedTransition } from \"../core/transitions\";\nimport { clampPlaybackRate, clampVolume, gingerReducer, createInitialState } from \"../core/playbackReducer\";\nimport type { GingerProviderProps, PlaylistMeta, RepeatMode, Track } from \"../types\";\nimport { GingerContext, type GingerContextValue } from \"./GingerContext\";\n\nconst defaultProviderStyle: CSSProperties = {\n [\"--ginger-primary-color\" as string]: \"#111827\",\n [\"--ginger-muted-color\" as string]: \"#6b7280\",\n [\"--ginger-font-size\" as string]: \"14px\",\n [\"--ginger-font-family\" as string]: \"system-ui, sans-serif\",\n [\"--ginger-playlist-row-padding\" as string]: \"6px 8px\",\n [\"--ginger-artwork-radius\" as string]: \"6px\",\n [\"--ginger-artwork-bg\" as string]: \"#f3f4f6\",\n};\n\nexport function GingerProvider({\n children,\n initialTracks = [],\n initialIndex = 0,\n initialPlaylistMeta = null,\n initialShuffle = false,\n initialRepeatMode = \"off\",\n initialPaused = true,\n initialVolume = 1,\n initialMuted = false,\n initialPlaybackRate = 1,\n className,\n style,\n onTrackChange,\n onPlay,\n onPause,\n onQueueEnd,\n onError,\n}: GingerProviderProps) {\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const [state, dispatch] = useReducer(\n gingerReducer,\n undefined,\n () =>\n createInitialState({\n tracks: initialTracks,\n currentIndex: initialIndex,\n playlistMeta: initialPlaylistMeta,\n isPaused: initialPaused,\n isShuffled: initialShuffle,\n repeatMode: initialRepeatMode,\n volume: initialVolume,\n muted: initialMuted,\n playbackRate: initialPlaybackRate,\n }),\n );\n\n const currentTrack = state.tracks[state.currentIndex] ?? null;\n\n useEffect(() => {\n onTrackChange?.(currentTrack, state.currentIndex);\n }, [currentTrack, state.currentIndex, onTrackChange]);\n\n useEffect(() => {\n if (state.errorMessage) onError?.(state.errorMessage);\n }, [state.errorMessage, onError]);\n\n const prevPausedRef = useRef<boolean | undefined>(undefined);\n useEffect(() => {\n if (prevPausedRef.current === undefined) {\n prevPausedRef.current = state.isPaused;\n return;\n }\n if (prevPausedRef.current !== state.isPaused) {\n if (state.isPaused) onPause?.();\n else onPlay?.();\n }\n prevPausedRef.current = state.isPaused;\n }, [state.isPaused, onPause, onPlay]);\n\n const play = useCallback(() => {\n dispatch({ type: \"PLAY\" });\n void audioRef.current?.play().catch((e: unknown) => {\n dispatch({ type: \"PAUSE\" });\n const msg = e instanceof Error ? e.message : \"Playback failed\";\n onError?.(msg);\n });\n }, [onError]);\n\n const pause = useCallback(() => {\n dispatch({ type: \"PAUSE\" });\n audioRef.current?.pause();\n }, []);\n\n const togglePlayPause = useCallback(() => {\n if (state.isPaused) play();\n else pause();\n }, [pause, play, state.isPaused]);\n\n const seek = useCallback((timeSeconds: number) => {\n const el = audioRef.current;\n if (!el) return;\n if (!Number.isFinite(timeSeconds)) return;\n el.currentTime = Math.max(0, timeSeconds);\n }, []);\n\n const setVolume = useCallback((volume: number) => {\n dispatch({ type: \"SET_VOLUME\", payload: clampVolume(volume) });\n }, []);\n\n const setMuted = useCallback((muted: boolean) => {\n dispatch({ type: \"SET_MUTED\", payload: muted });\n }, []);\n\n const toggleMute = useCallback(() => {\n dispatch({ type: \"TOGGLE_MUTE\" });\n }, []);\n\n const setPlaybackRate = useCallback((rate: number) => {\n dispatch({ type: \"SET_PLAYBACK_RATE\", payload: clampPlaybackRate(rate) });\n }, []);\n\n const next = useCallback(() => {\n dispatch({ type: \"NEXT\" });\n }, []);\n\n const prev = useCallback(() => {\n dispatch({ type: \"PREV\" });\n }, []);\n\n const setRepeatMode = useCallback((mode: RepeatMode) => {\n dispatch({ type: \"SET_REPEAT\", payload: mode });\n }, []);\n\n const cycleRepeat = useCallback(() => {\n dispatch({ type: \"CYCLE_REPEAT\" });\n }, []);\n\n const toggleShuffle = useCallback(() => {\n dispatch({ type: \"TOGGLE_SHUFFLE\" });\n }, []);\n\n const setQueue = useCallback((tracks: Track[], currentIndex?: number) => {\n dispatch({ type: \"SET_QUEUE\", payload: { tracks, currentIndex } });\n }, []);\n\n const playTrackAt = useCallback((index: number) => {\n dispatch({ type: \"SET_INDEX\", payload: { index, autoPlay: true } });\n queueMicrotask(() => {\n void audioRef.current?.play().catch(() => {});\n });\n }, []);\n\n const selectTrackAt = useCallback((index: number) => {\n dispatch({ type: \"SET_INDEX\", payload: { index, autoPlay: false } });\n }, []);\n\n const setPlaylistMeta = useCallback((meta: PlaylistMeta | null) => {\n dispatch({ type: \"SET_PLAYLIST_META\", payload: meta });\n }, []);\n\n const currentUrl = state.tracks[state.currentIndex]?.fileUrl;\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n if (state.isPaused) el.pause();\n else\n void el.play().catch((e: unknown) => {\n dispatch({ type: \"PAUSE\" });\n const msg = e instanceof Error ? e.message : \"Playback failed\";\n onError?.(msg);\n });\n }, [state.isPaused, currentUrl, onError]);\n\n const notifyEnded = useCallback(() => {\n const transition = computeEndedTransition(state);\n if (transition.kind === \"replay_same\") {\n const el = audioRef.current;\n if (el) {\n el.currentTime = 0;\n void el.play().catch(() => {});\n }\n dispatch({ type: \"PLAY\" });\n return;\n }\n if (transition.kind === \"stop\") {\n dispatch({ type: \"PAUSE\" });\n onQueueEnd?.();\n return;\n }\n const nextIndex = transition.nextIndex;\n dispatch({ type: \"SET_INDEX\", payload: { index: nextIndex, autoPlay: true } });\n queueMicrotask(() => {\n void audioRef.current?.play().catch(() => {});\n });\n }, [onQueueEnd, state]);\n\n const value = useMemo<GingerContextValue>(\n () => ({\n state,\n dispatch,\n audioRef,\n notifyEnded,\n play,\n pause,\n togglePlayPause,\n seek,\n setVolume,\n setMuted,\n toggleMute,\n setPlaybackRate,\n next,\n prev,\n setRepeatMode,\n cycleRepeat,\n toggleShuffle,\n setQueue,\n playTrackAt,\n selectTrackAt,\n setPlaylistMeta,\n }),\n [\n cycleRepeat,\n dispatch,\n next,\n notifyEnded,\n pause,\n play,\n playTrackAt,\n selectTrackAt,\n prev,\n seek,\n setMuted,\n setPlaybackRate,\n setQueue,\n setRepeatMode,\n setPlaylistMeta,\n setVolume,\n state,\n toggleMute,\n togglePlayPause,\n toggleShuffle,\n ],\n );\n\n const mergedStyle = useMemo(() => ({ ...defaultProviderStyle, ...style }), [style]);\n\n return (\n <GingerContext.Provider value={value}>\n <div className={className} style={mergedStyle}>\n {children}\n </div>\n </GingerContext.Provider>\n );\n}\n","import { GingerPlayer } from \"./audio/GingerPlayer\";\nimport * as Current from \"./components/current\";\nimport * as Control from \"./components/controls/Controls\";\nimport { GingerPlaylistCompound } from \"./components/playlist/GingerPlaylist\";\nimport * as Queue from \"./components/queue/QueueDisplay\";\nimport { GingerProvider } from \"./context/GingerProvider\";\n\nexport const Ginger = {\n Provider: GingerProvider,\n Player: GingerPlayer,\n Current: {\n Title: Current.Title,\n Artist: Current.Artist,\n Album: Current.Album,\n Description: Current.Description,\n Copyright: Current.Copyright,\n Genre: Current.Genre,\n Label: Current.Label,\n Isrc: Current.Isrc,\n TrackNumber: Current.TrackNumber,\n Year: Current.Year,\n Lyrics: Current.Lyrics,\n FileUrl: Current.FileUrl,\n Artwork: Current.Artwork,\n QueueIndex: Current.QueueIndex,\n QueueLength: Current.QueueLength,\n QueuePosition: Current.QueuePosition,\n Elapsed: Current.Elapsed,\n Duration: Current.Duration,\n Remaining: Current.Remaining,\n Progress: Current.Progress,\n TimeRail: Current.TimeRail,\n PlaybackState: Current.PlaybackState,\n ErrorMessage: Current.ErrorMessage,\n },\n Queue: {\n Title: Queue.Title,\n Subtitle: Queue.Subtitle,\n Description: Queue.Description,\n Copyright: Queue.Copyright,\n Artwork: Queue.Artwork,\n },\n Control: {\n PlayPause: Control.PlayPause,\n Repeat: Control.Repeat,\n Next: Control.Next,\n Previous: Control.Previous,\n Shuffle: Control.Shuffle,\n SeekBar: Control.SeekBar,\n Volume: Control.Volume,\n Mute: Control.Mute,\n PlaybackRate: Control.PlaybackRate,\n },\n Playlist: GingerPlaylistCompound,\n};\n","import { useMemo } from \"react\";\nimport { useGingerContext } from \"../context/GingerContext\";\nimport {\n derivePlaybackUiState,\n effectiveDuration,\n effectiveRemaining,\n getCurrentTrack,\n progressFraction,\n resolvedAlbumLine,\n resolvedArtwork,\n} from \"../internal/selectors\";\n\nexport function useGinger() {\n const ctx = useGingerContext();\n const { state } = ctx;\n\n return useMemo(\n () => ({\n state,\n currentTrack: getCurrentTrack(state),\n playbackUi: derivePlaybackUiState(state),\n duration: effectiveDuration(state),\n remaining: effectiveRemaining(state),\n progress: progressFraction(state),\n artworkUrl: resolvedArtwork(state),\n albumLine: resolvedAlbumLine(state),\n play: ctx.play,\n pause: ctx.pause,\n togglePlayPause: ctx.togglePlayPause,\n seek: ctx.seek,\n setVolume: ctx.setVolume,\n setMuted: ctx.setMuted,\n toggleMute: ctx.toggleMute,\n setPlaybackRate: ctx.setPlaybackRate,\n next: ctx.next,\n prev: ctx.prev,\n setRepeatMode: ctx.setRepeatMode,\n cycleRepeat: ctx.cycleRepeat,\n toggleShuffle: ctx.toggleShuffle,\n setQueue: ctx.setQueue,\n playTrackAt: ctx.playTrackAt,\n selectTrackAt: ctx.selectTrackAt,\n setPlaylistMeta: ctx.setPlaylistMeta,\n dispatch: ctx.dispatch,\n }),\n [\n ctx.cycleRepeat,\n ctx.dispatch,\n ctx.next,\n ctx.pause,\n ctx.play,\n ctx.playTrackAt,\n ctx.selectTrackAt,\n ctx.prev,\n ctx.seek,\n ctx.setMuted,\n ctx.setPlaybackRate,\n ctx.setPlaylistMeta,\n ctx.setQueue,\n ctx.setRepeatMode,\n ctx.setVolume,\n ctx.toggleMute,\n ctx.togglePlayPause,\n ctx.toggleShuffle,\n state,\n ],\n );\n}\n"],"names":["GingerContext","createContext","useGingerContext","ctx","useContext","readBufferedFraction","el","buffered","duration","GingerPlayer","className","style","preload","crossOrigin","audioRef","dispatch","state","notifyEnded","url","_a","useEffect","jsx","e","code","clampIndex","index","length","shuffleWithAnchor","tracks","anchorIndex","anchor","rest","_","i","j","findIndexByFileUrl","fileUrl","t","computeEndedTransition","currentIndex","repeatMode","len","computeNextIndex","computePrevIndex","cycleRepeatMode","mode","resolveArtworkUrl","track","playlistArtwork","resolveAlbumLine","playlistSubtitle","getCurrentTrack","derivePlaybackUiState","effectiveDuration","d","hint","effectiveRemaining","rem","progressFraction","dur","resolvedArtwork","resolvedAlbumLine","createTextDisplay","displayName","select","Comp","props","value","fallback","empty","children","node","createTrackFieldDisplay","Title","Artist","Album","s","Description","Copyright","Genre","Label","Isrc","TrackNumber","Year","format","y","text","Lyrics","preserveWhitespace","raw","whiteStyle","FileUrl","visible","Artwork","sizes","loading","onError","decoding","imgStyle","src","alt","QueueIndex","base","QueueLength","QueuePosition","separator","label","formatMmSs","seconds","renderTime","valueSeconds","Elapsed","Duration","Remaining","Progress","fraction","TimeRail","height","pct","PlaybackState","ErrorMessage","PlayPause","playLabel","pauseLabel","type","togglePlayPause","repeatLabels","Repeat","cycleRepeat","Next","next","Previous","prev","Shuffle","toggleShuffle","SeekBar","inputStyle","seek","Volume","setVolume","Mute","muteLabel","unmuteLabel","toggleMute","defaultRates","PlaybackRate","rates","setPlaybackRate","options","useMemo","a","b","r","GingerPlaylistConfigContext","usePlaylistConfig","GingerPlaylist","rowStyle","renderTrack","playOnSelect","playTrackAt","selectTrackAt","listStyle","active","GingerPlaylistTrack","liProps","onClick","buttonRest","defaultLabel","jsxs","GingerPlaylistCompound","Subtitle","_b","clampVolume","v","clampPlaybackRate","resetTimingOnly","defaultMedia","createInitialState","params","originalTracks","ordered","gingerReducer","action","playlistMeta","isPaused","isShuffled","volume","muted","playbackRate","idx","ap","snapshot","shuffled","restored","current","newIndex","nextIndex","same","prevIndex","defaultProviderStyle","GingerProvider","initialTracks","initialIndex","initialPlaylistMeta","initialShuffle","initialRepeatMode","initialPaused","initialVolume","initialMuted","initialPlaybackRate","onTrackChange","onPlay","onPause","onQueueEnd","useRef","useReducer","currentTrack","prevPausedRef","play","useCallback","msg","pause","timeSeconds","setMuted","rate","setRepeatMode","setQueue","setPlaylistMeta","meta","currentUrl","transition","mergedStyle","Ginger","Current.Title","Current.Artist","Current.Album","Current.Description","Current.Copyright","Current.Genre","Current.Label","Current.Isrc","Current.TrackNumber","Current.Year","Current.Lyrics","Current.FileUrl","Current.Artwork","Current.QueueIndex","Current.QueueLength","Current.QueuePosition","Current.Elapsed","Current.Duration","Current.Remaining","Current.Progress","Current.TimeRail","Current.PlaybackState","Current.ErrorMessage","Queue.Title","Queue.Subtitle","Queue.Description","Queue.Copyright","Queue.Artwork","Control.PlayPause","Control.Repeat","Control.Next","Control.Previous","Control.Shuffle","Control.SeekBar","Control.Volume","Control.Mute","Control.PlaybackRate","useGinger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/context/GingerContext.tsx","../src/audio/GingerPlayer.tsx","../src/core/queue.ts","../src/core/transitions.ts","../src/internal/selectors.ts","../src/context/GingerSplitContexts.tsx","../src/components/current/createTextDisplay.tsx","../src/components/current/texts.ts","../src/components/current/Year.tsx","../src/components/current/Lyrics.tsx","../src/components/current/FileUrl.tsx","../src/components/current/Artwork.tsx","../src/components/current/QueueMeta.tsx","../src/internal/formatTime.ts","../src/components/current/Time.tsx","../src/components/current/Playback.tsx","../src/context/GingerLocaleContext.tsx","../src/hooks/useControlBindings.ts","../src/components/controls/Controls.tsx","../src/components/playlist/GingerPlaylist.tsx","../src/components/queue/QueueDisplay.tsx","../src/core/playbackReducer.ts","../src/context/GingerProvider.tsx","../src/ginger.ts","../src/hooks/useGinger.ts"],"sourcesContent":["import { createContext, useContext, type Dispatch, type MutableRefObject } from \"react\";\nimport type { GingerAction, GingerInitPayload, GingerState, PlaylistMeta, RepeatMode, Track } from \"../types\";\n\nexport type GingerContextValue = {\n state: GingerState;\n dispatch: Dispatch<GingerAction>;\n audioRef: MutableRefObject<HTMLAudioElement | null>;\n notifyEnded: () => void;\n /** Full reset to match `createInitialState` / provider `initial*` props. */\n init: (payload: GingerInitPayload) => void;\n play: () => void;\n pause: () => void;\n togglePlayPause: () => void;\n seek: (timeSeconds: number) => void;\n setVolume: (volume: number) => void;\n setMuted: (muted: boolean) => void;\n toggleMute: () => void;\n setPlaybackRate: (rate: number) => void;\n next: () => void;\n prev: () => void;\n setRepeatMode: (mode: RepeatMode) => void;\n cycleRepeat: () => void;\n toggleShuffle: () => void;\n setQueue: (tracks: Track[], currentIndex?: number) => void;\n playTrackAt: (index: number) => void;\n selectTrackAt: (index: number) => void;\n setPlaylistMeta: (meta: PlaylistMeta | null) => void;\n};\n\nconst GingerContext = createContext<GingerContextValue | null>(null);\n\nexport function useGingerContext(): GingerContextValue {\n const ctx = useContext(GingerContext);\n if (!ctx) throw new Error(\"Ginger components must be used within <Ginger.Provider>\");\n return ctx;\n}\n\nexport { GingerContext };\n","import { useEffect, useRef, type AudioHTMLAttributes, type CSSProperties } from \"react\";\nimport { useGingerContext } from \"../context/GingerContext\";\n\nexport type GingerPlayerProps = {\n className?: string;\n style?: CSSProperties;\n preload?: AudioHTMLAttributes<HTMLAudioElement>[\"preload\"];\n crossOrigin?: AudioHTMLAttributes<HTMLAudioElement>[\"crossOrigin\"];\n};\n\nfunction readBufferedFraction(el: HTMLAudioElement): number {\n const { buffered, duration } = el;\n if (!(duration > 0) || buffered.length === 0) return 0;\n return Math.min(1, buffered.end(buffered.length - 1) / duration);\n}\n\nexport function GingerPlayer({ className, style, preload = \"metadata\", crossOrigin }: GingerPlayerProps) {\n const { audioRef, dispatch, state, notifyEnded } = useGingerContext();\n const url = state.tracks[state.currentIndex]?.fileUrl ?? \"\";\n const lastTimeSnapshotRef = useRef({\n currentTime: -1,\n duration: -1,\n bufferedFraction: -1,\n });\n\n const syncTime = (el: HTMLAudioElement, force = false) => {\n const next = {\n currentTime: el.currentTime,\n duration: el.duration,\n bufferedFraction: readBufferedFraction(el),\n };\n const prev = lastTimeSnapshotRef.current;\n const changedEnough =\n Math.abs(next.currentTime - prev.currentTime) >= 0.25 ||\n Math.abs(next.duration - prev.duration) >= 0.01 ||\n Math.abs(next.bufferedFraction - prev.bufferedFraction) >= 0.01;\n if (!force && !changedEnough) return;\n lastTimeSnapshotRef.current = next;\n dispatch({\n type: \"MEDIA_TIME_UPDATE\",\n payload: next,\n });\n };\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n el.volume = state.volume;\n el.muted = state.muted;\n el.playbackRate = state.playbackRate;\n }, [audioRef, state.volume, state.muted, state.playbackRate]);\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n if (!url) {\n el.removeAttribute(\"src\");\n lastTimeSnapshotRef.current = { currentTime: -1, duration: -1, bufferedFraction: -1 };\n return;\n }\n if (el.getAttribute(\"src\") !== url) {\n el.src = url;\n el.load();\n lastTimeSnapshotRef.current = { currentTime: -1, duration: -1, bufferedFraction: -1 };\n }\n }, [audioRef, state.currentIndex, state.tracks, url]);\n\n return (\n <audio\n ref={audioRef}\n className={className}\n style={style}\n preload={preload}\n crossOrigin={crossOrigin}\n controls={false}\n playsInline\n onTimeUpdate={(e) => {\n syncTime(e.currentTarget);\n }}\n onLoadedMetadata={(e) => {\n const el = e.currentTarget;\n lastTimeSnapshotRef.current = { currentTime: -1, duration: -1, bufferedFraction: -1 };\n dispatch({\n type: \"MEDIA_LOADED_METADATA\",\n payload: {\n duration: el.duration,\n bufferedFraction: readBufferedFraction(el),\n },\n });\n }}\n onSeeking={(e) => syncTime(e.currentTarget, true)}\n onSeeked={(e) => syncTime(e.currentTarget, true)}\n onEnded={() => notifyEnded()}\n onPlay={() => dispatch({ type: \"MEDIA_PLAY\" })}\n onPause={() => dispatch({ type: \"MEDIA_PAUSE\" })}\n onWaiting={() => dispatch({ type: \"MEDIA_WAITING\" })}\n onCanPlay={() => dispatch({ type: \"MEDIA_CANPLAY\" })}\n onProgress={(e) => syncTime(e.currentTarget, true)}\n onVolumeChange={(e) => {\n const el = e.currentTarget;\n dispatch({\n type: \"MEDIA_VOLUME_SYNC\",\n payload: { volume: el.volume, muted: el.muted },\n });\n }}\n onError={() => {\n const el = audioRef.current;\n const code = el?.error?.code;\n const message =\n code === 1\n ? \"MEDIA_ERR_ABORTED\"\n : code === 2\n ? \"MEDIA_ERR_NETWORK\"\n : code === 3\n ? \"MEDIA_ERR_DECODE\"\n : code === 4\n ? \"MEDIA_ERR_SRC_NOT_SUPPORTED\"\n : \"MEDIA_ERR_UNKNOWN\";\n dispatch({ type: \"MEDIA_ERROR\", payload: { message } });\n }}\n />\n );\n}\n","import type { Track } from \"../types\";\n\nexport function clampIndex(index: number, length: number): number {\n if (length <= 0) return 0;\n return Math.max(0, Math.min(length - 1, index));\n}\n\nexport function shuffleWithAnchor(tracks: Track[], anchorIndex: number): Track[] {\n if (tracks.length <= 1) return [...tracks];\n const anchor = tracks[anchorIndex];\n if (!anchor) return [...tracks];\n const rest = tracks.filter((_, i) => i !== anchorIndex);\n for (let i = rest.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [rest[i], rest[j]] = [rest[j]!, rest[i]!];\n }\n return [anchor, ...rest];\n}\n\nexport function trackIdentity(track: Track | null | undefined): string {\n if (!track) return \"\";\n return track.id != null && track.id !== \"\" ? `id:${track.id}` : `file:${track.fileUrl}`;\n}\n\nexport function findIndexByTrackIdentity(tracks: Track[], target: Track | null | undefined): number {\n const identity = trackIdentity(target);\n if (!identity) return 0;\n const i = tracks.findIndex((track) => trackIdentity(track) === identity);\n return i === -1 ? 0 : i;\n}\n","import type { GingerState, RepeatMode, Track } from \"../types\";\nimport { clampIndex } from \"./queue\";\n\nexport type EndedTransition =\n | { kind: \"replay_same\" }\n | { kind: \"advance\"; nextIndex: number }\n | { kind: \"wrap\"; nextIndex: number }\n | { kind: \"stop\"; nextIndex: number };\n\nexport function computeEndedTransition(state: GingerState): EndedTransition {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return { kind: \"stop\", nextIndex: 0 };\n if (repeatMode === \"one\") return { kind: \"replay_same\" };\n if (currentIndex < len - 1) return { kind: \"advance\", nextIndex: currentIndex + 1 };\n if (repeatMode === \"all\") return { kind: \"wrap\", nextIndex: 0 };\n return { kind: \"stop\", nextIndex: clampIndex(currentIndex, len) };\n}\n\nexport function computeNextIndex(state: GingerState): number {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return 0;\n if (currentIndex < len - 1) return currentIndex + 1;\n if (repeatMode === \"all\") return 0;\n return clampIndex(currentIndex, len);\n}\n\nexport function computePrevIndex(state: GingerState): number {\n const { tracks, currentIndex, repeatMode } = state;\n const len = tracks.length;\n if (len === 0) return 0;\n if (currentIndex > 0) return currentIndex - 1;\n if (repeatMode === \"all\") return len - 1;\n return 0;\n}\n\nexport function cycleRepeatMode(mode: RepeatMode): RepeatMode {\n if (mode === \"off\") return \"all\";\n if (mode === \"all\") return \"one\";\n return \"off\";\n}\n\nexport function resolveArtworkUrl(track: Track | null, playlistArtwork?: string | null): string | undefined {\n return track?.artworkUrl ?? playlistArtwork ?? undefined;\n}\n\nexport function resolveAlbumLine(track: Track | null, playlistSubtitle?: string | null): string | undefined {\n return track?.album ?? playlistSubtitle ?? undefined;\n}\n","import type { GingerState, PlaybackUiState, Track } from \"../types\";\nimport { resolveAlbumLine, resolveArtworkUrl } from \"../core/transitions\";\n\nexport function getCurrentTrack(state: GingerState): Track | null {\n const t = state.tracks[state.currentIndex];\n return t ?? null;\n}\n\nexport function derivePlaybackUiState(state: GingerState): PlaybackUiState {\n if (state.errorMessage) return \"error\";\n if (state.tracks.length === 0) return \"idle\";\n if (state.isBuffering) return \"loading\";\n if (!state.isPaused) return \"playing\";\n if (\n Number.isFinite(state.duration) &&\n state.duration > 0 &&\n state.currentTime >= state.duration - 0.05\n ) {\n return \"ended\";\n }\n return \"paused\";\n}\n\nexport function effectiveDuration(state: GingerState): number {\n const d = state.duration;\n if (Number.isFinite(d) && d > 0) return d;\n const hint = state.tracks[state.currentIndex]?.durationSeconds;\n if (typeof hint === \"number\" && Number.isFinite(hint) && hint > 0) return hint;\n return 0;\n}\n\nexport function effectiveRemaining(state: GingerState): number {\n const dur = effectiveDuration(state);\n const rem = dur - state.currentTime;\n return Number.isFinite(rem) ? Math.max(0, rem) : 0;\n}\n\nexport function progressFraction(state: GingerState): number {\n const dur = effectiveDuration(state);\n if (!(dur > 0)) return 0;\n return Math.min(1, Math.max(0, state.currentTime / dur));\n}\n\nexport function resolvedArtwork(state: GingerState): string | undefined {\n const track = getCurrentTrack(state);\n return resolveArtworkUrl(track, state.playlistMeta?.artworkUrl);\n}\n\nexport function resolvedAlbumLine(state: GingerState): string | undefined {\n const track = getCurrentTrack(state);\n return resolveAlbumLine(track, state.playlistMeta?.subtitle);\n}\n","import { createContext, useContext, useMemo, type Dispatch, type MutableRefObject } from \"react\";\nimport type {\n GingerAction,\n GingerInitPayload,\n GingerMediaSlice,\n GingerPlaybackSlice,\n GingerState,\n PlaylistMeta,\n RepeatMode,\n Track,\n} from \"../types\";\n\nexport type GingerPlaybackActions = {\n init: (payload: GingerInitPayload) => void;\n play: () => void;\n pause: () => void;\n togglePlayPause: () => void;\n next: () => void;\n prev: () => void;\n setRepeatMode: (mode: RepeatMode) => void;\n cycleRepeat: () => void;\n toggleShuffle: () => void;\n setQueue: (tracks: Track[], currentIndex?: number) => void;\n playTrackAt: (index: number) => void;\n selectTrackAt: (index: number) => void;\n setPlaylistMeta: (meta: PlaylistMeta | null) => void;\n dispatch: Dispatch<GingerAction>;\n};\n\nexport type GingerPlaybackContextValue = GingerPlaybackSlice & GingerPlaybackActions;\n\nexport type GingerMediaActions = {\n seek: (timeSeconds: number) => void;\n setVolume: (volume: number) => void;\n setMuted: (muted: boolean) => void;\n toggleMute: () => void;\n setPlaybackRate: (rate: number) => void;\n audioRef: MutableRefObject<HTMLAudioElement | null>;\n notifyEnded: () => void;\n dispatch: Dispatch<GingerAction>;\n};\n\nexport type GingerMediaContextValue = GingerMediaSlice & GingerMediaActions;\n\nconst GingerPlaybackContext = createContext<GingerPlaybackContextValue | null>(null);\nconst GingerMediaContext = createContext<GingerMediaContextValue | null>(null);\n\nexport function useGingerPlayback(): GingerPlaybackContextValue {\n const ctx = useContext(GingerPlaybackContext);\n if (!ctx) throw new Error(\"Ginger hooks must be used within <Ginger.Provider>\");\n return ctx;\n}\n\nexport function useGingerMedia(): GingerMediaContextValue {\n const ctx = useContext(GingerMediaContext);\n if (!ctx) throw new Error(\"Ginger hooks must be used within <Ginger.Provider>\");\n return ctx;\n}\n\n/** Full merged state; prefer over `useGingerContext().state` so updates follow playback vs media splits. */\nexport function useGingerState(): GingerState {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n return useMemo(() => gingerStateFromContextValues(pb, md), [pb, md]);\n}\n\n/** Merge playback + media slices (for selectors and `useGinger`). */\nexport function gingerStateFromContexts(\n playback: GingerPlaybackSlice,\n media: GingerMediaSlice,\n): GingerState {\n return { ...playback, ...media };\n}\n\n/** Merge full context values into `GingerState` (strips action fields). */\nexport function gingerStateFromContextValues(\n pb: GingerPlaybackContextValue,\n md: GingerMediaContextValue,\n): GingerState {\n const {\n init: _i,\n play: _p,\n pause: _pa,\n togglePlayPause: _t,\n next: _n,\n prev: _pr,\n setRepeatMode: _sr,\n cycleRepeat: _cr,\n toggleShuffle: _ts,\n setQueue: _sq,\n playTrackAt: _pta,\n selectTrackAt: _sta,\n setPlaylistMeta: _spm,\n dispatch: _d1,\n ...playbackRest\n } = pb;\n const {\n seek: _sk,\n setVolume: _sv,\n setMuted: _sm,\n toggleMute: _tm,\n setPlaybackRate: _spr,\n audioRef: _ar,\n notifyEnded: _ne,\n dispatch: _d2,\n ...mediaRest\n } = md;\n return { ...playbackRest, ...mediaRest };\n}\n\nexport { GingerPlaybackContext, GingerMediaContext };\n","import type { ReactElement, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState, Track } from \"../../types\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\n\nexport type TextDisplayProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function createTextDisplay(\n displayName: string,\n select: (state: GingerState) => string | undefined,\n): (props: TextDisplayProps) => ReactElement | null {\n function Comp(props: TextDisplayProps) {\n const state = useGingerState();\n const raw = select(state) ?? \"\";\n const value = raw.trim();\n const { className, style, fallback, empty, children } = props;\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n }\n Comp.displayName = displayName;\n return Comp;\n}\n\nexport function createTrackFieldDisplay(\n displayName: string,\n select: (track: Track | null) => string | undefined,\n): (props: TextDisplayProps) => ReactElement | null {\n return createTextDisplay(displayName, (state) => select(getCurrentTrack(state)));\n}\n","import { createTextDisplay, createTrackFieldDisplay } from \"./createTextDisplay\";\nimport { getCurrentTrack, resolvedAlbumLine } from \"../../internal/selectors\";\n\nexport const Title = createTrackFieldDisplay(\"Ginger.Current.Title\", (t) => t?.title);\nexport const Artist = createTrackFieldDisplay(\"Ginger.Current.Artist\", (t) => t?.artist);\nexport const Album = createTextDisplay(\"Ginger.Current.Album\", (s) => resolvedAlbumLine(s));\nexport const Description = createTrackFieldDisplay(\"Ginger.Current.Description\", (t) => t?.description);\nexport const Copyright = createTextDisplay(\"Ginger.Current.Copyright\", (s) => {\n const t = getCurrentTrack(s);\n return t?.copyright ?? s.playlistMeta?.copyright;\n});\nexport const Genre = createTrackFieldDisplay(\"Ginger.Current.Genre\", (t) => t?.genre);\nexport const Label = createTrackFieldDisplay(\"Ginger.Current.Label\", (t) => t?.label);\nexport const Isrc = createTrackFieldDisplay(\"Ginger.Current.Isrc\", (t) => t?.isrc);\nexport const TrackNumber = createTrackFieldDisplay(\"Ginger.Current.TrackNumber\", (t) =>\n t?.trackNumber != null ? String(t.trackNumber) : undefined,\n);\n","import type { TextDisplayProps } from \"./createTextDisplay\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type YearProps = TextDisplayProps & {\n format?: (year: number) => string;\n};\n\nexport function Year({ className, style, fallback, empty, children, format }: YearProps) {\n const state = useGingerState();\n const y = getCurrentTrack(state)?.year;\n if (typeof y !== \"number\" || !Number.isFinite(y)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const text = format ? format(y) : String(y);\n if (children) return <span className={className} style={style}>{children(text, state)}</span>;\n return (\n <span className={className} style={style}>\n {text}\n </span>\n );\n}\n\nYear.displayName = \"Ginger.Current.Year\";\n","import type { CSSProperties, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type LyricsProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n /** When true, preserves internal newlines; trims only leading/trailing whitespace */\n preserveWhitespace?: boolean;\n};\n\nexport function Lyrics({ className, style, fallback, empty, children, preserveWhitespace = true }: LyricsProps) {\n const state = useGingerState();\n const raw = getCurrentTrack(state)?.lyrics ?? \"\";\n const value = preserveWhitespace ? raw.replace(/^\\s+|\\s+$/g, \"\") : raw.trim();\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const whiteStyle: CSSProperties | undefined = preserveWhitespace ? { whiteSpace: \"pre-wrap\" } : undefined;\n if (children) return <span className={className} style={{ ...whiteStyle, ...style }}>{children(value, state)}</span>;\n return (\n <span className={className} style={{ ...whiteStyle, ...style }}>\n {value}\n </span>\n );\n}\n\nLyrics.displayName = \"Ginger.Current.Lyrics\";\n","import type { TextDisplayProps } from \"./createTextDisplay\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\nimport { getCurrentTrack } from \"../../internal/selectors\";\n\nexport type FileUrlProps = TextDisplayProps & {\n /** When false (default), renders nothing unless you explicitly opt in */\n visible?: boolean;\n};\n\nexport function FileUrl({ visible = false, className, style, fallback, empty, children }: FileUrlProps) {\n const state = useGingerState();\n if (!visible) return null;\n const value = getCurrentTrack(state)?.fileUrl ?? \"\";\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nFileUrl.displayName = \"Ginger.Current.FileUrl\";\n","import type { CSSProperties, ImgHTMLAttributes } from \"react\";\nimport type { DisplayBaseProps } from \"../../types\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\nimport { getCurrentTrack, resolvedArtwork } from \"../../internal/selectors\";\n\nexport type ArtworkProps = DisplayBaseProps &\n Pick<ImgHTMLAttributes<HTMLImageElement>, \"sizes\" | \"loading\" | \"onError\" | \"decoding\"> & {\n imgStyle?: CSSProperties;\n };\n\nexport function Artwork({ className, style, fallback, empty, sizes, loading, onError, decoding, imgStyle }: ArtworkProps) {\n const state = useGingerState();\n const track = getCurrentTrack(state);\n const src = resolvedArtwork(state);\n if (!src) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const alt = [track?.title, track?.artist].filter(Boolean).join(\" — \") || \"Artwork\";\n return (\n <div\n className={className}\n style={{\n background: \"var(--ginger-artwork-bg, transparent)\",\n borderRadius: \"var(--ginger-artwork-radius, 0)\",\n overflow: \"hidden\",\n ...style,\n }}\n >\n <img\n src={src}\n alt={alt}\n sizes={sizes}\n loading={loading}\n decoding={decoding}\n onError={onError}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n ...imgStyle,\n }}\n />\n </div>\n );\n}\n\nArtwork.displayName = \"Ginger.Current.Artwork\";\n","import type { ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\n\nexport type QueueIndexProps = DisplayBaseProps & {\n base?: 0 | 1;\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function QueueIndex({ base = 0, className, style, fallback, empty, children }: QueueIndexProps) {\n const state = useGingerState();\n const len = state.tracks.length;\n if (len === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const value = String(state.currentIndex + base);\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nQueueIndex.displayName = \"Ginger.Current.QueueIndex\";\n\nexport type QueueLengthProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function QueueLength({ className, style, fallback, empty, children }: QueueLengthProps) {\n const state = useGingerState();\n const value = String(state.tracks.length);\n if (state.tracks.length === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nQueueLength.displayName = \"Ginger.Current.QueueLength\";\n\nexport type QueuePositionProps = DisplayBaseProps & {\n base?: 0 | 1;\n separator?: string;\n children?: (value: { index: string; length: string; label: string }, state: GingerState) => ReactNode;\n};\n\nexport function QueuePosition({\n base = 0,\n separator = \" / \",\n className,\n style,\n fallback,\n empty,\n children,\n}: QueuePositionProps) {\n const state = useGingerState();\n const len = state.tracks.length;\n if (len === 0) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const index = String(state.currentIndex + base);\n const length = String(len);\n const label = `${index}${separator}${length}`;\n if (children)\n return (\n <span className={className} style={style}>\n {children({ index, length, label }, state)}\n </span>\n );\n return (\n <span className={className} style={style}>\n {label}\n </span>\n );\n}\n\nQueuePosition.displayName = \"Ginger.Current.QueuePosition\";\n","export function formatMmSs(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"0:00\";\n const s = Math.floor(seconds % 60);\n const m = Math.floor(seconds / 60);\n return `${m}:${s.toString().padStart(2, \"0\")}`;\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState } from \"../../types\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\nimport { effectiveDuration, effectiveRemaining, progressFraction } from \"../../internal/selectors\";\nimport { formatMmSs } from \"../../internal/formatTime\";\n\nexport type TimeTextProps = DisplayBaseProps & {\n format?: (seconds: number) => string;\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nfunction renderTime(\n valueSeconds: number,\n state: GingerState,\n props: TimeTextProps,\n): ReactElement | null {\n const { className, style, fallback, empty, children, format = formatMmSs } = props;\n if (!(valueSeconds >= 0) || !Number.isFinite(valueSeconds)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const text = format(valueSeconds);\n if (children) return <span className={className} style={style}>{children(text, state)}</span>;\n return (\n <span className={className} style={style}>\n {text}\n </span>\n );\n}\n\nexport function Elapsed(props: TimeTextProps) {\n const state = useGingerState();\n return renderTime(state.currentTime, state, props);\n}\n\nElapsed.displayName = \"Ginger.Current.Elapsed\";\n\nexport function Duration(props: TimeTextProps) {\n const state = useGingerState();\n return renderTime(effectiveDuration(state), state, props);\n}\n\nDuration.displayName = \"Ginger.Current.Duration\";\n\nexport function Remaining(props: TimeTextProps) {\n const state = useGingerState();\n return renderTime(effectiveRemaining(state), state, props);\n}\n\nRemaining.displayName = \"Ginger.Current.Remaining\";\n\nexport type ProgressProps = DisplayBaseProps & {\n children?: (value: { fraction: number; currentTime: number; duration: number }, state: GingerState) => ReactNode;\n};\n\nexport function Progress({ className, style, fallback, empty, children }: ProgressProps) {\n const state = useGingerState();\n const duration = effectiveDuration(state);\n const fraction = progressFraction(state);\n if (!(duration > 0)) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children)\n return (\n <span className={className} style={style}>\n {children({ fraction, currentTime: state.currentTime, duration }, state)}\n </span>\n );\n return (\n <span className={className} style={style}>\n {`${Math.round(fraction * 100)}%`}\n </span>\n );\n}\n\nProgress.displayName = \"Ginger.Current.Progress\";\n\nexport type TimeRailProps = DisplayBaseProps & {\n /** 0-1 height in px for the rail */\n height?: number;\n /** When true, shows a buffered range behind the progress fill (uses `bufferedFraction`). */\n showBuffered?: boolean;\n};\n\nexport function TimeRail({ className, style, height = 4, showBuffered = false }: TimeRailProps) {\n const state = useGingerState();\n const progressPct = `${Math.round(progressFraction(state) * 100)}%`;\n const bufPct = `${Math.round(Math.min(1, Math.max(0, state.bufferedFraction)) * 100)}%`;\n return (\n <div\n className={className}\n style={{\n width: \"100%\",\n height,\n background: \"var(--ginger-muted-color, #e5e7eb)\",\n borderRadius: 999,\n overflow: \"hidden\",\n position: \"relative\",\n ...style,\n }}\n aria-hidden\n >\n {showBuffered ? (\n <div\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n height: \"100%\",\n width: bufPct,\n background: \"var(--ginger-buffer-color, rgba(107, 114, 128, 0.35))\",\n }}\n />\n ) : null}\n <div\n style={{\n position: \"relative\",\n width: progressPct,\n height: \"100%\",\n background: \"var(--ginger-primary-color, #111827)\",\n }}\n />\n </div>\n );\n}\n\nTimeRail.displayName = \"Ginger.Current.TimeRail\";\n\nexport type BufferRailProps = DisplayBaseProps & {\n height?: number;\n};\n\n/** Buffered portion of the timeline (0…`bufferedFraction`); pair with `TimeRail` or use alone. */\nexport function BufferRail({ className, style, height = 4 }: BufferRailProps) {\n const state = useGingerState();\n const bufPct = `${Math.round(Math.min(1, Math.max(0, state.bufferedFraction)) * 100)}%`;\n return (\n <div\n className={className}\n style={{\n width: \"100%\",\n height,\n background: \"var(--ginger-muted-color, #e5e7eb)\",\n borderRadius: 999,\n overflow: \"hidden\",\n ...style,\n }}\n aria-hidden\n >\n <div\n style={{\n width: bufPct,\n height: \"100%\",\n background: \"var(--ginger-buffer-color, rgba(107, 114, 128, 0.35))\",\n }}\n />\n </div>\n );\n}\n\nBufferRail.displayName = \"Ginger.Current.BufferRail\";\n","import type { ReactNode } from \"react\";\nimport type { DisplayBaseProps, GingerState, PlaybackUiState } from \"../../types\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\nimport { derivePlaybackUiState } from \"../../internal/selectors\";\n\nexport type PlaybackStateProps = DisplayBaseProps & {\n children?: (value: PlaybackUiState, state: GingerState) => ReactNode;\n};\n\nexport function PlaybackState({ className, style, fallback, empty, children }: PlaybackStateProps) {\n const state = useGingerState();\n const value = derivePlaybackUiState(state);\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nPlaybackState.displayName = \"Ginger.Current.PlaybackState\";\n\nexport type ErrorMessageProps = DisplayBaseProps & {\n children?: (value: string, state: GingerState) => ReactNode;\n};\n\nexport function ErrorMessage({ className, style, fallback, empty, children }: ErrorMessageProps) {\n const state = useGingerState();\n const value = state.errorMessage ?? \"\";\n if (!value) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n if (children) return <span className={className} style={style}>{children(value, state)}</span>;\n return (\n <span className={className} style={style}>\n {value}\n </span>\n );\n}\n\nErrorMessage.displayName = \"Ginger.Current.ErrorMessage\";\n","import { createContext, useContext, type ReactNode } from \"react\";\nimport type { GingerLocaleMessages } from \"../types\";\n\nexport const defaultGingerLocale: GingerLocaleMessages = {\n seek: \"Seek\",\n volume: \"Volume\",\n playbackSpeed: \"Playback speed\",\n nextTrack: \"Next track\",\n previousTrack: \"Previous track\",\n shuffle: \"Shuffle\",\n mute: \"Mute\",\n unmute: \"Unmute\",\n play: \"Play\",\n pause: \"Pause\",\n repeat: {\n off: \"Repeat off\",\n all: \"Repeat all\",\n one: \"Repeat one\",\n },\n playbackRateNormal: \"1× normal\",\n playbackRateTimes: (rate) => `${rate}×`,\n};\n\nfunction mergeLocale(partial?: Partial<GingerLocaleMessages>): GingerLocaleMessages {\n if (!partial) return defaultGingerLocale;\n return {\n ...defaultGingerLocale,\n ...partial,\n repeat: { ...defaultGingerLocale.repeat, ...partial.repeat },\n };\n}\n\nconst GingerLocaleContext = createContext<GingerLocaleMessages>(defaultGingerLocale);\n\nexport function GingerLocaleProvider({\n locale,\n children,\n}: {\n locale?: Partial<GingerLocaleMessages>;\n children: ReactNode;\n}) {\n const value = mergeLocale(locale);\n return <GingerLocaleContext.Provider value={value}>{children}</GingerLocaleContext.Provider>;\n}\n\nexport function useGingerLocale(): GingerLocaleMessages {\n return useContext(GingerLocaleContext);\n}\n","import { useMemo } from \"react\";\nimport type { FormEvent } from \"react\";\nimport type { GingerState } from \"../types\";\nimport { gingerStateFromContextValues, useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport { effectiveDuration } from \"../internal/selectors\";\nimport { formatMmSs } from \"../internal/formatTime\";\nimport { useGingerLocale } from \"../context/GingerLocaleContext\";\n\nexport type SeekBarBinding = {\n state: GingerState;\n value: number;\n min: number;\n max: number;\n step: \"any\";\n ariaValueText: string;\n ariaLabel: string;\n onSeekInput: (e: FormEvent<HTMLInputElement>) => void;\n onSeekChange: (e: FormEvent<HTMLInputElement>) => void;\n};\n\n/** Headless seek slider: bind return value to `<input type=\"range\" />` or your own component. */\nexport function useSeekBarBinding(): SeekBarBinding {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n const locale = useGingerLocale();\n const state = useMemo(() => gingerStateFromContextValues(pb, md), [pb, md]);\n const duration = effectiveDuration(state);\n const value = duration > 0 ? state.currentTime : 0;\n const numericValue = Number.isFinite(value) ? value : 0;\n const ariaValueText =\n duration > 0\n ? `${formatMmSs(numericValue)} of ${formatMmSs(duration)}`\n : formatMmSs(numericValue);\n\n const onSeekInput = (e: FormEvent<HTMLInputElement>) => {\n md.seek(Number(e.currentTarget.value));\n };\n\n return {\n state,\n value: numericValue,\n min: 0,\n max: duration > 0 ? duration : 1,\n step: \"any\",\n ariaValueText,\n ariaLabel: locale.seek,\n onSeekInput,\n onSeekChange: onSeekInput,\n };\n}\n\nexport type VolumeBinding = {\n state: GingerState;\n value: number;\n min: number;\n max: number;\n step: \"any\";\n ariaValueText: string;\n ariaLabel: string;\n onVolumeInput: (e: FormEvent<HTMLInputElement>) => void;\n onVolumeChange: (e: FormEvent<HTMLInputElement>) => void;\n};\n\n/** Headless volume slider. */\nexport function useVolumeSlider(): VolumeBinding {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n const locale = useGingerLocale();\n const state = useMemo(() => gingerStateFromContextValues(pb, md), [pb, md]);\n\n const onVolumeInput = (e: FormEvent<HTMLInputElement>) => {\n md.setVolume(Number(e.currentTarget.value));\n };\n\n return {\n state,\n value: state.volume,\n min: 0,\n max: 1,\n step: \"any\",\n ariaValueText: `${Math.round(state.volume * 100)}%`,\n ariaLabel: locale.volume,\n onVolumeInput,\n onVolumeChange: onVolumeInput,\n };\n}\n\nexport type PlayPauseBinding = {\n isPaused: boolean;\n toggle: () => void;\n /** Resolved aria label for the button’s *next* action (play vs pause). */\n ariaLabel: string;\n};\n\n/** Headless play/pause control; use with `playAriaLabel` / `pauseAriaLabel` from locale or custom strings. */\nexport function usePlayPauseBinding(options?: {\n playAriaLabel?: string;\n pauseAriaLabel?: string;\n}): PlayPauseBinding {\n const pb = useGingerPlayback();\n const locale = useGingerLocale();\n const playL = options?.playAriaLabel ?? locale.play;\n const pauseL = options?.pauseAriaLabel ?? locale.pause;\n return {\n isPaused: pb.isPaused,\n toggle: pb.togglePlayPause,\n ariaLabel: pb.isPaused ? playL : pauseL,\n };\n}\n","import { useMemo } from \"react\";\nimport type {\n ButtonHTMLAttributes,\n CSSProperties,\n InputHTMLAttributes,\n ReactNode,\n SelectHTMLAttributes,\n} from \"react\";\nimport { useGingerLocale } from \"../../context/GingerLocaleContext\";\nimport { useGingerMedia, useGingerPlayback } from \"../../context/GingerSplitContexts\";\nimport { usePlayPauseBinding, useSeekBarBinding, useVolumeSlider } from \"../../hooks/useControlBindings\";\n\nexport type PlayPauseProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Optional labels; still headless—defaults are text for a11y */\n playLabel?: ReactNode;\n pauseLabel?: ReactNode;\n /** Screen-reader label when paused (playing would start); defaults to match `playLabel` when it is a string */\n playAriaLabel?: string;\n /** Screen-reader label when playing (action would pause); defaults to match `pauseLabel` when it is a string */\n pauseAriaLabel?: string;\n};\n\nexport function PlayPause({\n playLabel = \"Play\",\n pauseLabel = \"Pause\",\n playAriaLabel,\n pauseAriaLabel,\n type = \"button\",\n ...rest\n}: PlayPauseProps) {\n const locale = useGingerLocale();\n const defaultPlayAria = typeof playLabel === \"string\" ? playLabel : locale.play;\n const defaultPauseAria = typeof pauseLabel === \"string\" ? pauseLabel : locale.pause;\n const b = usePlayPauseBinding({\n playAriaLabel: playAriaLabel ?? defaultPlayAria,\n pauseAriaLabel: pauseAriaLabel ?? defaultPauseAria,\n });\n return (\n <button type={type} aria-label={b.ariaLabel} onClick={b.toggle} {...rest}>\n {b.isPaused ? playLabel : pauseLabel}\n </button>\n );\n}\n\nPlayPause.displayName = \"Ginger.Control.PlayPause\";\n\nexport type RepeatProps = ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport function Repeat({ type = \"button\", ...rest }: RepeatProps) {\n const { repeatMode, cycleRepeat } = useGingerPlayback();\n const locale = useGingerLocale();\n const label = locale.repeat[repeatMode];\n return (\n <button type={type} aria-label={label} onClick={cycleRepeat} {...rest}>\n {label}\n </button>\n );\n}\n\nRepeat.displayName = \"Ginger.Control.Repeat\";\n\nexport type NextProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Next({ type = \"button\", children = \"Next\", ...rest }: NextProps) {\n const { next } = useGingerPlayback();\n const locale = useGingerLocale();\n return (\n <button type={type} aria-label={locale.nextTrack} onClick={next} {...rest}>\n {children}\n </button>\n );\n}\nNext.displayName = \"Ginger.Control.Next\";\n\nexport type PreviousProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Previous({ type = \"button\", children = \"Previous\", ...rest }: PreviousProps) {\n const { prev } = useGingerPlayback();\n const locale = useGingerLocale();\n return (\n <button type={type} aria-label={locale.previousTrack} onClick={prev} {...rest}>\n {children}\n </button>\n );\n}\nPrevious.displayName = \"Ginger.Control.Previous\";\n\nexport type ShuffleProps = ButtonHTMLAttributes<HTMLButtonElement>;\nexport function Shuffle({ type = \"button\", children = \"Shuffle\", ...rest }: ShuffleProps) {\n const { isShuffled, toggleShuffle } = useGingerPlayback();\n const locale = useGingerLocale();\n return (\n <button\n type={type}\n aria-pressed={isShuffled}\n aria-label={locale.shuffle}\n onClick={toggleShuffle}\n {...rest}\n >\n {children}\n </button>\n );\n}\nShuffle.displayName = \"Ginger.Control.Shuffle\";\n\nexport type SeekBarProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"type\" | \"value\" | \"onChange\" | \"onInput\" | \"min\" | \"max\" | \"step\"\n> & {\n inputStyle?: CSSProperties;\n};\n\nexport function SeekBar({ inputStyle, style, ...rest }: SeekBarProps) {\n const b = useSeekBarBinding();\n return (\n <input\n {...rest}\n type=\"range\"\n min={b.min}\n max={b.max}\n step={b.step}\n value={b.value}\n aria-label={b.ariaLabel}\n aria-valuetext={b.ariaValueText}\n onInput={b.onSeekInput}\n onChange={b.onSeekChange}\n style={{ width: \"100%\", ...style, ...inputStyle }}\n />\n );\n}\n\nSeekBar.displayName = \"Ginger.Control.SeekBar\";\n\nexport type VolumeProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n \"type\" | \"value\" | \"onChange\" | \"onInput\" | \"min\" | \"max\" | \"step\"\n> & {\n inputStyle?: CSSProperties;\n};\n\nexport function Volume({ inputStyle, style, ...rest }: VolumeProps) {\n const b = useVolumeSlider();\n return (\n <input\n {...rest}\n type=\"range\"\n min={b.min}\n max={b.max}\n step={b.step}\n value={b.value}\n aria-label={b.ariaLabel}\n aria-valuetext={b.ariaValueText}\n onInput={b.onVolumeInput}\n onChange={b.onVolumeChange}\n style={{ width: \"100%\", ...style, ...inputStyle }}\n />\n );\n}\n\nVolume.displayName = \"Ginger.Control.Volume\";\n\nexport type MuteProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n muteLabel?: ReactNode;\n unmuteLabel?: ReactNode;\n};\n\nexport function Mute({\n muteLabel,\n unmuteLabel,\n type = \"button\",\n ...rest\n}: MuteProps) {\n const { muted, toggleMute } = useGingerMedia();\n const locale = useGingerLocale();\n const m = muteLabel ?? locale.mute;\n const u = unmuteLabel ?? locale.unmute;\n return (\n <button\n type={type}\n aria-pressed={muted}\n aria-label={muted ? locale.unmute : locale.mute}\n onClick={toggleMute}\n {...rest}\n >\n {muted ? u : m}\n </button>\n );\n}\n\nMute.displayName = \"Ginger.Control.Mute\";\n\nconst defaultRates = [0.5, 0.75, 1, 1.25, 1.5, 2] as const;\n\nexport type PlaybackRateProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, \"value\" | \"onChange\"> & {\n /** Playback speed options (default: 0.5 … 2) */\n rates?: readonly number[];\n};\n\nexport function PlaybackRate({ rates = defaultRates, style, ...rest }: PlaybackRateProps) {\n const { playbackRate, setPlaybackRate } = useGingerMedia();\n const locale = useGingerLocale();\n const options = useMemo(\n () => Array.from(new Set([...rates, playbackRate])).sort((a, b) => a - b),\n [rates, playbackRate],\n );\n return (\n <select\n {...rest}\n aria-label={locale.playbackSpeed}\n value={String(playbackRate)}\n style={style}\n onChange={(e) => setPlaybackRate(Number(e.currentTarget.value))}\n >\n {options.map((r) => (\n <option key={r} value={String(r)}>\n {r === 1 ? locale.playbackRateNormal : locale.playbackRateTimes(r)}\n </option>\n ))}\n </select>\n );\n}\n\nPlaybackRate.displayName = \"Ginger.Control.PlaybackRate\";\n","import {\n createContext,\n useContext,\n type ButtonHTMLAttributes,\n type CSSProperties,\n type HTMLAttributes,\n type LiHTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { useGingerPlayback } from \"../../context/GingerSplitContexts\";\nimport { trackIdentity } from \"../../core/queue\";\nimport type { Track } from \"../../types\";\n\nexport type GingerPlaylistConfig = {\n playOnSelect: boolean;\n};\n\nconst GingerPlaylistConfigContext = createContext<GingerPlaylistConfig | null>(null);\n\nfunction usePlaylistConfig(): GingerPlaylistConfig {\n const ctx = useContext(GingerPlaylistConfigContext);\n if (!ctx) {\n throw new Error(\"Ginger.Playlist.Track must be used inside <Ginger.Playlist>\");\n }\n return ctx;\n}\n\nexport type GingerPlaylistProps = Omit<HTMLAttributes<HTMLUListElement>, \"children\"> & {\n children?: ReactNode;\n rowStyle?: CSSProperties;\n /**\n * Used only in **auto** mode (no custom `children`). Ignored when you pass custom `children`\n * (manual mode); use `Ginger.Playlist.Track` for each row instead.\n */\n renderTrack?: (track: Track, index: number, isActive: boolean) => ReactNode;\n /** When true (default), clicking a row selects that index and starts playback */\n playOnSelect?: boolean;\n};\n\n/**\n * - **Auto mode** (no `children`): maps `state.tracks` to rows (optional `renderTrack`).\n * - **Manual mode** (`children` defined): renders `<ul>{children}</ul>`; map `state.tracks` yourself\n * with `Ginger.Playlist.Track` for each index.\n */\nexport function GingerPlaylist({\n children,\n rowStyle,\n renderTrack,\n playOnSelect = true,\n style,\n ...rest\n}: GingerPlaylistProps) {\n const { tracks, currentIndex, playTrackAt, selectTrackAt } = useGingerPlayback();\n\n const listStyle: CSSProperties = {\n listStyle: \"none\",\n margin: 0,\n padding: 0,\n fontFamily: \"var(--ginger-font-family, system-ui, sans-serif)\",\n fontSize: \"var(--ginger-font-size, 14px)\",\n color: \"var(--ginger-primary-color, #111827)\",\n ...style,\n };\n\n const manual = children !== undefined;\n\n if (manual) {\n return (\n <GingerPlaylistConfigContext.Provider value={{ playOnSelect }}>\n <ul style={listStyle} {...rest}>\n {children}\n </ul>\n </GingerPlaylistConfigContext.Provider>\n );\n }\n\n return (\n <GingerPlaylistConfigContext.Provider value={{ playOnSelect }}>\n <ul style={listStyle} {...rest}>\n {tracks.map((track, index) => {\n const active = index === currentIndex;\n return (\n <li key={`${index}-${trackIdentity(track)}`}>\n <button\n type=\"button\"\n onClick={() => {\n if (playOnSelect) playTrackAt(index);\n else selectTrackAt(index);\n }}\n style={{\n width: \"100%\",\n textAlign: \"left\",\n border: \"none\",\n background: active ? \"var(--ginger-playlist-active-bg, rgba(17, 24, 39, 0.06))\" : \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n cursor: \"pointer\",\n padding: \"var(--ginger-playlist-row-padding, 6px 8px)\",\n ...rowStyle,\n }}\n >\n {renderTrack ? (\n renderTrack(track, index, active)\n ) : (\n <span>\n {track.title}\n {track.artist ? ` — ${track.artist}` : \"\"}\n </span>\n )}\n </button>\n </li>\n );\n })}\n </ul>\n </GingerPlaylistConfigContext.Provider>\n );\n}\n\nGingerPlaylist.displayName = \"Ginger.Playlist\";\n\nexport type GingerPlaylistTrackProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\"> & {\n index: number;\n /** Optional wrapper for the row; defaults to a plain `<li>` */\n liProps?: LiHTMLAttributes<HTMLLIElement>;\n};\n\nexport function GingerPlaylistTrack({\n index,\n className,\n style,\n children,\n liProps,\n onClick,\n ...buttonRest\n}: GingerPlaylistTrackProps) {\n const { playOnSelect } = usePlaylistConfig();\n const { tracks, currentIndex, playTrackAt, selectTrackAt } = useGingerPlayback();\n const active = index === currentIndex;\n const track = tracks[index];\n const defaultLabel =\n track != null ? (\n <span>\n {track.title}\n {track.artist ? ` — ${track.artist}` : \"\"}\n </span>\n ) : null;\n\n return (\n <li {...liProps}>\n <button\n type=\"button\"\n aria-current={active ? \"true\" : undefined}\n data-ginger-active={active || undefined}\n className={className}\n style={{\n width: \"100%\",\n textAlign: \"left\",\n border: \"none\",\n background: active ? \"var(--ginger-playlist-active-bg, rgba(17, 24, 39, 0.06))\" : \"transparent\",\n color: \"inherit\",\n font: \"inherit\",\n cursor: \"pointer\",\n padding: \"var(--ginger-playlist-row-padding, 6px 8px)\",\n ...style,\n }}\n {...buttonRest}\n onClick={(e) => {\n onClick?.(e);\n if (e.defaultPrevented) return;\n if (playOnSelect) playTrackAt(index);\n else selectTrackAt(index);\n }}\n >\n {children ?? defaultLabel}\n </button>\n </li>\n );\n}\n\nGingerPlaylistTrack.displayName = \"Ginger.Playlist.Track\";\n\nexport const GingerPlaylistCompound = Object.assign(GingerPlaylist, {\n Track: GingerPlaylistTrack,\n});\n","import type { CSSProperties } from \"react\";\nimport type { DisplayBaseProps } from \"../../types\";\nimport { createTextDisplay } from \"../current/createTextDisplay\";\nimport { useGingerState } from \"../../context/GingerSplitContexts\";\n\nexport const Title = createTextDisplay(\"Ginger.Queue.Title\", (s) => s.playlistMeta?.title);\nexport const Subtitle = createTextDisplay(\"Ginger.Queue.Subtitle\", (s) => s.playlistMeta?.subtitle);\nexport const Description = createTextDisplay(\"Ginger.Queue.Description\", (s) => s.playlistMeta?.description);\nexport const Copyright = createTextDisplay(\"Ginger.Queue.Copyright\", (s) => s.playlistMeta?.copyright);\n\nexport type QueueArtworkProps = DisplayBaseProps & {\n imgStyle?: CSSProperties;\n};\n\nexport function Artwork({ className, style, fallback, empty, imgStyle }: QueueArtworkProps) {\n const state = useGingerState();\n const src = state.playlistMeta?.artworkUrl;\n if (!src) {\n const node = empty ?? fallback ?? null;\n return node ? <span className={className} style={style}>{node}</span> : null;\n }\n const alt = state.playlistMeta?.title ?? \"Playlist artwork\";\n return (\n <span\n className={className}\n style={{\n display: \"inline-block\",\n background: \"var(--ginger-artwork-bg, #f3f4f6)\",\n borderRadius: \"var(--ginger-artwork-radius, 6px)\",\n overflow: \"hidden\",\n ...style,\n }}\n >\n <img\n src={src}\n alt={alt}\n style={{\n display: \"block\",\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n ...imgStyle,\n }}\n />\n </span>\n );\n}\n\nArtwork.displayName = \"Ginger.Queue.Artwork\";\n","import type { GingerAction, GingerState, RepeatMode, Track } from \"../types\";\nimport { clampIndex, findIndexByTrackIdentity, shuffleWithAnchor } from \"./queue\";\nimport { computeNextIndex, computePrevIndex, cycleRepeatMode } from \"./transitions\";\n\nexport function clampVolume(v: number): number {\n if (!Number.isFinite(v)) return 1;\n return Math.min(1, Math.max(0, v));\n}\n\nexport function clampPlaybackRate(r: number): number {\n if (!Number.isFinite(r)) return 1;\n return Math.min(4, Math.max(0.25, r));\n}\n\n/** Reset when the active track / position changes; keeps volume / mute / speed */\nconst resetTimingOnly = {\n currentTime: 0,\n duration: 0,\n bufferedFraction: 0,\n isBuffering: false,\n errorMessage: null as string | null,\n};\n\nconst defaultMedia = {\n ...resetTimingOnly,\n volume: 1,\n muted: false,\n playbackRate: 1,\n};\n\nexport function createInitialState(params: {\n tracks: Track[];\n currentIndex?: number;\n playlistMeta?: GingerState[\"playlistMeta\"];\n isPaused?: boolean;\n isShuffled?: boolean;\n repeatMode?: RepeatMode;\n volume?: number;\n muted?: boolean;\n playbackRate?: number;\n}): GingerState {\n const tracks = [...params.tracks];\n let currentIndex = clampIndex(params.currentIndex ?? 0, tracks.length);\n let originalTracks: Track[] | null = null;\n let ordered = tracks;\n\n if (params.isShuffled && tracks.length > 1) {\n originalTracks = [...tracks];\n ordered = shuffleWithAnchor(tracks, currentIndex);\n currentIndex = 0;\n }\n\n return {\n tracks: ordered,\n currentIndex,\n isPaused: params.isPaused ?? true,\n isShuffled: Boolean(params.isShuffled && ordered.length > 1),\n repeatMode: params.repeatMode ?? \"off\",\n originalTracks,\n playlistMeta: params.playlistMeta ?? null,\n ...defaultMedia,\n volume: clampVolume(params.volume ?? 1),\n muted: params.muted ?? false,\n playbackRate: clampPlaybackRate(params.playbackRate ?? 1),\n };\n}\n\nexport function gingerReducer(state: GingerState, action: GingerAction): GingerState {\n switch (action.type) {\n case \"INIT\": {\n const {\n tracks,\n currentIndex,\n playlistMeta,\n isPaused,\n isShuffled,\n repeatMode,\n volume,\n muted,\n playbackRate,\n } = action.payload;\n return createInitialState({\n tracks,\n currentIndex,\n playlistMeta: playlistMeta ?? null,\n isPaused: isPaused ?? true,\n isShuffled: isShuffled ?? false,\n repeatMode: repeatMode ?? \"off\",\n volume,\n muted,\n playbackRate,\n });\n }\n case \"SET_QUEUE\": {\n const { tracks, currentIndex } = action.payload;\n const next = [...tracks];\n const idx = clampIndex(currentIndex ?? state.currentIndex, next.length);\n return {\n ...state,\n tracks: next,\n currentIndex: idx,\n isShuffled: false,\n originalTracks: null,\n ...resetTimingOnly,\n };\n }\n case \"SET_INDEX\": {\n const idx = clampIndex(action.payload.index, state.tracks.length);\n const ap = action.payload.autoPlay;\n const isPaused =\n ap === true ? false : ap === false ? true : state.isPaused;\n return {\n ...state,\n currentIndex: idx,\n ...resetTimingOnly,\n isPaused,\n };\n }\n case \"PLAY\":\n return { ...state, isPaused: false };\n case \"PAUSE\":\n return { ...state, isPaused: true };\n case \"TOGGLE_PAUSE\":\n return { ...state, isPaused: !state.isPaused };\n case \"SET_REPEAT\":\n return { ...state, repeatMode: action.payload };\n case \"CYCLE_REPEAT\":\n return { ...state, repeatMode: cycleRepeatMode(state.repeatMode) };\n case \"TOGGLE_SHUFFLE\": {\n if (state.tracks.length <= 1) return { ...state, isShuffled: false, originalTracks: null };\n if (!state.isShuffled) {\n const snapshot = [...state.tracks];\n const shuffled = shuffleWithAnchor(snapshot, state.currentIndex);\n return {\n ...state,\n isShuffled: true,\n originalTracks: snapshot,\n tracks: shuffled,\n currentIndex: 0,\n };\n }\n const restored = state.originalTracks ? [...state.originalTracks] : [...state.tracks];\n const current = state.tracks[state.currentIndex];\n const newIndex = findIndexByTrackIdentity(restored, current);\n return {\n ...state,\n isShuffled: false,\n originalTracks: null,\n tracks: restored,\n currentIndex: clampIndex(newIndex, restored.length),\n };\n }\n case \"NEXT\": {\n const nextIndex = computeNextIndex(state);\n const same = nextIndex === state.currentIndex;\n return {\n ...state,\n currentIndex: nextIndex,\n ...(same ? {} : resetTimingOnly),\n isPaused: same ? state.isPaused : false,\n };\n }\n case \"PREV\": {\n const prevIndex = computePrevIndex(state);\n const same = prevIndex === state.currentIndex;\n return {\n ...state,\n currentIndex: prevIndex,\n ...(same ? {} : resetTimingOnly),\n isPaused: same ? state.isPaused : false,\n };\n }\n case \"MEDIA_TIME_UPDATE\":\n return {\n ...state,\n currentTime: action.payload.currentTime,\n duration: Number.isFinite(action.payload.duration) ? action.payload.duration : state.duration,\n bufferedFraction: action.payload.bufferedFraction,\n isBuffering: false,\n };\n case \"MEDIA_LOADED_METADATA\":\n return {\n ...state,\n duration: Number.isFinite(action.payload.duration) ? action.payload.duration : state.duration,\n bufferedFraction: action.payload.bufferedFraction,\n errorMessage: null,\n };\n case \"SET_PLAYLIST_META\":\n return { ...state, playlistMeta: action.payload };\n case \"MEDIA_ERROR\":\n return {\n ...state,\n errorMessage: action.payload.message,\n isPaused: true,\n isBuffering: false,\n };\n case \"MEDIA_WAITING\":\n return { ...state, isBuffering: true };\n case \"MEDIA_CANPLAY\":\n return { ...state, isBuffering: false, errorMessage: null };\n case \"MEDIA_PLAY\":\n return { ...state, isPaused: false, isBuffering: false };\n case \"MEDIA_PAUSE\":\n return { ...state, isPaused: true };\n case \"RESET_MEDIA_TIMES\":\n return { ...state, currentTime: 0, duration: 0, bufferedFraction: 0 };\n case \"SET_VOLUME\":\n return { ...state, volume: clampVolume(action.payload) };\n case \"SET_MUTED\":\n return { ...state, muted: action.payload };\n case \"TOGGLE_MUTE\":\n return { ...state, muted: !state.muted };\n case \"SET_PLAYBACK_RATE\":\n return { ...state, playbackRate: clampPlaybackRate(action.payload) };\n case \"MEDIA_VOLUME_SYNC\": {\n const { volume, muted } = action.payload;\n const v = clampVolume(volume);\n if (v === state.volume && muted === state.muted) return state;\n return { ...state, volume: v, muted };\n }\n default:\n return state;\n }\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useReducer,\n useRef,\n type CSSProperties,\n} from \"react\";\nimport { computeEndedTransition } from \"../core/transitions\";\nimport { clampPlaybackRate, clampVolume, gingerReducer, createInitialState } from \"../core/playbackReducer\";\nimport { derivePlaybackUiState } from \"../internal/selectors\";\nimport type { GingerInitPayload, GingerProviderProps, PlaylistMeta, RepeatMode, Track } from \"../types\";\nimport { GingerContext, type GingerContextValue } from \"./GingerContext\";\nimport { GingerLocaleProvider } from \"./GingerLocaleContext\";\nimport { GingerMediaContext, GingerPlaybackContext, type GingerMediaContextValue, type GingerPlaybackContextValue } from \"./GingerSplitContexts\";\n\nconst defaultProviderStyle: CSSProperties = {\n [\"--ginger-primary-color\" as string]: \"#111827\",\n [\"--ginger-muted-color\" as string]: \"#6b7280\",\n [\"--ginger-font-size\" as string]: \"14px\",\n [\"--ginger-font-family\" as string]: \"system-ui, sans-serif\",\n [\"--ginger-playlist-row-padding\" as string]: \"6px 8px\",\n [\"--ginger-artwork-radius\" as string]: \"6px\",\n [\"--ginger-artwork-bg\" as string]: \"#f3f4f6\",\n [\"--ginger-playlist-active-bg\" as string]: \"rgba(17, 24, 39, 0.06)\",\n [\"--ginger-buffer-color\" as string]: \"rgba(107, 114, 128, 0.35)\",\n [\"--ginger-focus-ring\" as string]: \"0 0 0 2px rgba(59, 130, 246, 0.45)\",\n};\n\nexport function GingerProvider({\n children,\n initialTracks = [],\n initialIndex = 0,\n initialPlaylistMeta = null,\n initialShuffle = false,\n initialRepeatMode = \"off\",\n initialPaused = true,\n initialVolume = 1,\n initialMuted = false,\n initialPlaybackRate = 1,\n initialStateKey,\n locale,\n className,\n style,\n onTrackChange,\n onPlay,\n onPause,\n onQueueEnd,\n onError,\n}: GingerProviderProps) {\n const audioRef = useRef<HTMLAudioElement | null>(null);\n const [state, dispatch] = useReducer(\n gingerReducer,\n undefined,\n () =>\n createInitialState({\n tracks: initialTracks,\n currentIndex: initialIndex,\n playlistMeta: initialPlaylistMeta,\n isPaused: initialPaused,\n isShuffled: initialShuffle,\n repeatMode: initialRepeatMode,\n volume: initialVolume,\n muted: initialMuted,\n playbackRate: initialPlaybackRate,\n }),\n );\n const stateRef = useRef(state);\n\n const latestInitRef = useRef({\n tracks: initialTracks,\n currentIndex: initialIndex,\n playlistMeta: initialPlaylistMeta,\n isPaused: initialPaused,\n isShuffled: initialShuffle,\n repeatMode: initialRepeatMode,\n volume: initialVolume,\n muted: initialMuted,\n playbackRate: initialPlaybackRate,\n });\n latestInitRef.current = {\n tracks: initialTracks,\n currentIndex: initialIndex,\n playlistMeta: initialPlaylistMeta,\n isPaused: initialPaused,\n isShuffled: initialShuffle,\n repeatMode: initialRepeatMode,\n volume: initialVolume,\n muted: initialMuted,\n playbackRate: initialPlaybackRate,\n };\n\n const prevInitialStateKeyRef = useRef<typeof initialStateKey>(undefined);\n\n useEffect(() => {\n if (initialStateKey === undefined) {\n prevInitialStateKeyRef.current = undefined;\n return;\n }\n if (prevInitialStateKeyRef.current === undefined) {\n prevInitialStateKeyRef.current = initialStateKey;\n return;\n }\n if (prevInitialStateKeyRef.current === initialStateKey) return;\n prevInitialStateKeyRef.current = initialStateKey;\n const p = latestInitRef.current;\n dispatch({\n type: \"INIT\",\n payload: {\n tracks: p.tracks,\n currentIndex: p.currentIndex,\n playlistMeta: p.playlistMeta,\n isPaused: p.isPaused,\n isShuffled: p.isShuffled,\n repeatMode: p.repeatMode,\n volume: p.volume,\n muted: p.muted,\n playbackRate: p.playbackRate,\n },\n });\n }, [initialStateKey]);\n\n useEffect(() => {\n stateRef.current = state;\n }, [state]);\n\n const currentTrack = state.tracks[state.currentIndex] ?? null;\n\n useEffect(() => {\n onTrackChange?.(currentTrack, state.currentIndex);\n }, [currentTrack, state.currentIndex, onTrackChange]);\n\n useEffect(() => {\n if (state.errorMessage) onError?.(state.errorMessage);\n }, [state.errorMessage, onError]);\n\n const prevPausedRef = useRef<boolean | undefined>(undefined);\n useEffect(() => {\n if (prevPausedRef.current === undefined) {\n prevPausedRef.current = state.isPaused;\n return;\n }\n if (prevPausedRef.current !== state.isPaused) {\n if (state.isPaused) onPause?.();\n else onPlay?.();\n }\n prevPausedRef.current = state.isPaused;\n }, [state.isPaused, onPause, onPlay]);\n\n const play = useCallback(() => {\n dispatch({ type: \"PLAY\" });\n }, []);\n\n const pause = useCallback(() => {\n dispatch({ type: \"PAUSE\" });\n audioRef.current?.pause();\n }, []);\n\n const togglePlayPause = useCallback(() => {\n if (state.isPaused) play();\n else pause();\n }, [pause, play, state.isPaused]);\n\n const seek = useCallback((timeSeconds: number) => {\n const el = audioRef.current;\n if (!el) return;\n if (!Number.isFinite(timeSeconds)) return;\n el.currentTime = Math.max(0, timeSeconds);\n }, []);\n\n const setVolume = useCallback((volume: number) => {\n dispatch({ type: \"SET_VOLUME\", payload: clampVolume(volume) });\n }, []);\n\n const setMuted = useCallback((muted: boolean) => {\n dispatch({ type: \"SET_MUTED\", payload: muted });\n }, []);\n\n const toggleMute = useCallback(() => {\n dispatch({ type: \"TOGGLE_MUTE\" });\n }, []);\n\n const setPlaybackRate = useCallback((rate: number) => {\n dispatch({ type: \"SET_PLAYBACK_RATE\", payload: clampPlaybackRate(rate) });\n }, []);\n\n const next = useCallback(() => {\n dispatch({ type: \"NEXT\" });\n }, []);\n\n const prev = useCallback(() => {\n dispatch({ type: \"PREV\" });\n }, []);\n\n const setRepeatMode = useCallback((mode: RepeatMode) => {\n dispatch({ type: \"SET_REPEAT\", payload: mode });\n }, []);\n\n const cycleRepeat = useCallback(() => {\n dispatch({ type: \"CYCLE_REPEAT\" });\n }, []);\n\n const toggleShuffle = useCallback(() => {\n dispatch({ type: \"TOGGLE_SHUFFLE\" });\n }, []);\n\n const setQueue = useCallback((tracks: Track[], currentIndex?: number) => {\n dispatch({ type: \"SET_QUEUE\", payload: { tracks, currentIndex } });\n }, []);\n\n const playTrackAt = useCallback((index: number) => {\n dispatch({ type: \"SET_INDEX\", payload: { index, autoPlay: true } });\n }, []);\n\n const selectTrackAt = useCallback((index: number) => {\n dispatch({ type: \"SET_INDEX\", payload: { index, autoPlay: false } });\n }, []);\n\n const setPlaylistMeta = useCallback((meta: PlaylistMeta | null) => {\n dispatch({ type: \"SET_PLAYLIST_META\", payload: meta });\n }, []);\n\n const init = useCallback((payload: GingerInitPayload) => {\n dispatch({ type: \"INIT\", payload });\n }, []);\n\n const currentUrl = state.tracks[state.currentIndex]?.fileUrl;\n\n useEffect(() => {\n const el = audioRef.current;\n if (!el) return;\n if (state.isPaused) el.pause();\n else\n void el.play().catch((e: unknown) => {\n const msg =\n e instanceof Error\n ? e.message\n : typeof e === \"string\"\n ? e\n : \"Playback failed (e.g. autoplay blocked or unavailable source)\";\n dispatch({ type: \"MEDIA_ERROR\", payload: { message: msg } });\n });\n }, [state.isPaused, currentUrl]);\n\n const notifyEnded = useCallback(() => {\n const transition = computeEndedTransition(stateRef.current);\n if (transition.kind === \"replay_same\") {\n const el = audioRef.current;\n if (el) {\n el.currentTime = 0;\n }\n dispatch({ type: \"PLAY\" });\n return;\n }\n if (transition.kind === \"stop\") {\n dispatch({ type: \"PAUSE\" });\n onQueueEnd?.();\n return;\n }\n const nextIndex = transition.nextIndex;\n dispatch({ type: \"SET_INDEX\", payload: { index: nextIndex, autoPlay: true } });\n }, [onQueueEnd]);\n\n const value = useMemo<GingerContextValue>(\n () => ({\n state,\n dispatch,\n audioRef,\n notifyEnded,\n init,\n play,\n pause,\n togglePlayPause,\n seek,\n setVolume,\n setMuted,\n toggleMute,\n setPlaybackRate,\n next,\n prev,\n setRepeatMode,\n cycleRepeat,\n toggleShuffle,\n setQueue,\n playTrackAt,\n selectTrackAt,\n setPlaylistMeta,\n }),\n [\n cycleRepeat,\n dispatch,\n init,\n next,\n notifyEnded,\n pause,\n play,\n playTrackAt,\n selectTrackAt,\n prev,\n seek,\n setMuted,\n setPlaybackRate,\n setQueue,\n setRepeatMode,\n setPlaylistMeta,\n setVolume,\n state,\n toggleMute,\n togglePlayPause,\n toggleShuffle,\n ],\n );\n\n const playbackValue = useMemo<GingerPlaybackContextValue>(\n () => ({\n tracks: state.tracks,\n currentIndex: state.currentIndex,\n isPaused: state.isPaused,\n isShuffled: state.isShuffled,\n repeatMode: state.repeatMode,\n originalTracks: state.originalTracks,\n playlistMeta: state.playlistMeta,\n init,\n play,\n pause,\n togglePlayPause,\n next,\n prev,\n setRepeatMode,\n cycleRepeat,\n toggleShuffle,\n setQueue,\n playTrackAt,\n selectTrackAt,\n setPlaylistMeta,\n dispatch,\n }),\n [\n state.tracks,\n state.currentIndex,\n state.isPaused,\n state.isShuffled,\n state.repeatMode,\n state.originalTracks,\n state.playlistMeta,\n init,\n play,\n pause,\n togglePlayPause,\n next,\n prev,\n setRepeatMode,\n cycleRepeat,\n toggleShuffle,\n setQueue,\n playTrackAt,\n selectTrackAt,\n setPlaylistMeta,\n dispatch,\n ],\n );\n\n const mediaValue = useMemo<GingerMediaContextValue>(\n () => ({\n currentTime: state.currentTime,\n duration: state.duration,\n bufferedFraction: state.bufferedFraction,\n isBuffering: state.isBuffering,\n errorMessage: state.errorMessage,\n volume: state.volume,\n muted: state.muted,\n playbackRate: state.playbackRate,\n seek,\n setVolume,\n setMuted,\n toggleMute,\n setPlaybackRate,\n audioRef,\n notifyEnded,\n dispatch,\n }),\n [\n state.currentTime,\n state.duration,\n state.bufferedFraction,\n state.isBuffering,\n state.errorMessage,\n state.volume,\n state.muted,\n state.playbackRate,\n seek,\n setVolume,\n setMuted,\n toggleMute,\n setPlaybackRate,\n audioRef,\n notifyEnded,\n dispatch,\n ],\n );\n\n const playbackUi = derivePlaybackUiState(state);\n\n const mergedStyle = useMemo(() => ({ ...defaultProviderStyle, ...style }), [style]);\n\n return (\n <GingerLocaleProvider locale={locale}>\n <GingerPlaybackContext.Provider value={playbackValue}>\n <GingerMediaContext.Provider value={mediaValue}>\n <GingerContext.Provider value={value}>\n <div\n className={className}\n style={mergedStyle}\n data-ginger-playback={playbackUi}\n >\n {children}\n </div>\n </GingerContext.Provider>\n </GingerMediaContext.Provider>\n </GingerPlaybackContext.Provider>\n </GingerLocaleProvider>\n );\n}\n","import { GingerPlayer } from \"./audio/GingerPlayer\";\nimport * as Current from \"./components/current\";\nimport * as Control from \"./components/controls/Controls\";\nimport { GingerPlaylistCompound } from \"./components/playlist/GingerPlaylist\";\nimport * as Queue from \"./components/queue/QueueDisplay\";\nimport { GingerProvider } from \"./context/GingerProvider\";\n\nexport const Ginger = {\n Provider: GingerProvider,\n Player: GingerPlayer,\n Current: {\n Title: Current.Title,\n Artist: Current.Artist,\n Album: Current.Album,\n Description: Current.Description,\n Copyright: Current.Copyright,\n Genre: Current.Genre,\n Label: Current.Label,\n Isrc: Current.Isrc,\n TrackNumber: Current.TrackNumber,\n Year: Current.Year,\n Lyrics: Current.Lyrics,\n FileUrl: Current.FileUrl,\n Artwork: Current.Artwork,\n QueueIndex: Current.QueueIndex,\n QueueLength: Current.QueueLength,\n QueuePosition: Current.QueuePosition,\n Elapsed: Current.Elapsed,\n Duration: Current.Duration,\n Remaining: Current.Remaining,\n Progress: Current.Progress,\n TimeRail: Current.TimeRail,\n BufferRail: Current.BufferRail,\n PlaybackState: Current.PlaybackState,\n ErrorMessage: Current.ErrorMessage,\n },\n Queue: {\n Title: Queue.Title,\n Subtitle: Queue.Subtitle,\n Description: Queue.Description,\n Copyright: Queue.Copyright,\n Artwork: Queue.Artwork,\n },\n Control: {\n PlayPause: Control.PlayPause,\n Repeat: Control.Repeat,\n Next: Control.Next,\n Previous: Control.Previous,\n Shuffle: Control.Shuffle,\n SeekBar: Control.SeekBar,\n Volume: Control.Volume,\n Mute: Control.Mute,\n PlaybackRate: Control.PlaybackRate,\n },\n Playlist: GingerPlaylistCompound,\n};\n","import { useMemo } from \"react\";\nimport { gingerStateFromContextValues, useGingerMedia, useGingerPlayback } from \"../context/GingerSplitContexts\";\nimport {\n derivePlaybackUiState,\n effectiveDuration,\n effectiveRemaining,\n getCurrentTrack,\n progressFraction,\n resolvedAlbumLine,\n resolvedArtwork,\n} from \"../internal/selectors\";\n\nexport function useGinger() {\n const pb = useGingerPlayback();\n const md = useGingerMedia();\n\n return useMemo(\n () => {\n const state = gingerStateFromContextValues(pb, md);\n return {\n state,\n currentTrack: getCurrentTrack(state),\n playbackUi: derivePlaybackUiState(state),\n duration: effectiveDuration(state),\n remaining: effectiveRemaining(state),\n progress: progressFraction(state),\n artworkUrl: resolvedArtwork(state),\n albumLine: resolvedAlbumLine(state),\n play: pb.play,\n pause: pb.pause,\n togglePlayPause: pb.togglePlayPause,\n seek: md.seek,\n setVolume: md.setVolume,\n setMuted: md.setMuted,\n toggleMute: md.toggleMute,\n setPlaybackRate: md.setPlaybackRate,\n next: pb.next,\n prev: pb.prev,\n setRepeatMode: pb.setRepeatMode,\n cycleRepeat: pb.cycleRepeat,\n toggleShuffle: pb.toggleShuffle,\n setQueue: pb.setQueue,\n playTrackAt: pb.playTrackAt,\n selectTrackAt: pb.selectTrackAt,\n setPlaylistMeta: pb.setPlaylistMeta,\n init: pb.init,\n audioRef: md.audioRef,\n dispatch: pb.dispatch,\n };\n },\n [pb, md],\n );\n}\n"],"names":["GingerContext","createContext","useGingerContext","ctx","useContext","readBufferedFraction","el","buffered","duration","GingerPlayer","className","style","preload","crossOrigin","audioRef","dispatch","state","notifyEnded","url","_a","lastTimeSnapshotRef","useRef","syncTime","force","next","prev","changedEnough","useEffect","jsx","e","code","clampIndex","index","length","shuffleWithAnchor","tracks","anchorIndex","anchor","rest","_","i","j","trackIdentity","track","findIndexByTrackIdentity","target","identity","computeEndedTransition","currentIndex","repeatMode","len","computeNextIndex","computePrevIndex","cycleRepeatMode","mode","resolveArtworkUrl","playlistArtwork","resolveAlbumLine","playlistSubtitle","getCurrentTrack","derivePlaybackUiState","effectiveDuration","d","hint","effectiveRemaining","rem","progressFraction","dur","resolvedArtwork","resolvedAlbumLine","GingerPlaybackContext","GingerMediaContext","useGingerPlayback","useGingerMedia","useGingerState","pb","md","useMemo","gingerStateFromContextValues","gingerStateFromContexts","playback","media","_i","_p","_pa","_t","_n","_pr","_sr","_cr","_ts","_sq","_pta","_sta","_spm","_d1","playbackRest","_sk","_sv","_sm","_tm","_spr","_ar","_ne","_d2","mediaRest","createTextDisplay","displayName","select","Comp","props","value","fallback","empty","children","node","createTrackFieldDisplay","Title","t","Artist","Album","s","Description","Copyright","Genre","Label","Isrc","TrackNumber","Year","format","y","text","Lyrics","preserveWhitespace","raw","whiteStyle","FileUrl","visible","Artwork","sizes","loading","onError","decoding","imgStyle","src","alt","QueueIndex","base","QueueLength","QueuePosition","separator","label","formatMmSs","seconds","renderTime","valueSeconds","Elapsed","Duration","Remaining","Progress","fraction","TimeRail","height","showBuffered","progressPct","bufPct","jsxs","BufferRail","PlaybackState","ErrorMessage","defaultGingerLocale","rate","mergeLocale","partial","GingerLocaleContext","GingerLocaleProvider","locale","useGingerLocale","useSeekBarBinding","numericValue","ariaValueText","onSeekInput","useVolumeSlider","onVolumeInput","usePlayPauseBinding","options","playL","pauseL","PlayPause","playLabel","pauseLabel","playAriaLabel","pauseAriaLabel","type","defaultPlayAria","defaultPauseAria","b","Repeat","cycleRepeat","Next","Previous","Shuffle","isShuffled","toggleShuffle","SeekBar","inputStyle","Volume","Mute","muteLabel","unmuteLabel","muted","toggleMute","m","u","defaultRates","PlaybackRate","rates","playbackRate","setPlaybackRate","a","r","GingerPlaylistConfigContext","usePlaylistConfig","GingerPlaylist","rowStyle","renderTrack","playOnSelect","playTrackAt","selectTrackAt","listStyle","active","GingerPlaylistTrack","liProps","onClick","buttonRest","defaultLabel","GingerPlaylistCompound","Subtitle","_b","clampVolume","v","clampPlaybackRate","resetTimingOnly","defaultMedia","createInitialState","params","originalTracks","ordered","gingerReducer","action","playlistMeta","isPaused","volume","idx","ap","snapshot","shuffled","restored","current","newIndex","nextIndex","same","prevIndex","defaultProviderStyle","GingerProvider","initialTracks","initialIndex","initialPlaylistMeta","initialShuffle","initialRepeatMode","initialPaused","initialVolume","initialMuted","initialPlaybackRate","initialStateKey","onTrackChange","onPlay","onPause","onQueueEnd","useReducer","stateRef","latestInitRef","prevInitialStateKeyRef","p","currentTrack","prevPausedRef","play","useCallback","pause","togglePlayPause","seek","timeSeconds","setVolume","setMuted","setRepeatMode","setQueue","setPlaylistMeta","meta","init","payload","currentUrl","msg","transition","playbackValue","mediaValue","playbackUi","mergedStyle","Ginger","Current.Title","Current.Artist","Current.Album","Current.Description","Current.Copyright","Current.Genre","Current.Label","Current.Isrc","Current.TrackNumber","Current.Year","Current.Lyrics","Current.FileUrl","Current.Artwork","Current.QueueIndex","Current.QueueLength","Current.QueuePosition","Current.Elapsed","Current.Duration","Current.Remaining","Current.Progress","Current.TimeRail","Current.BufferRail","Current.PlaybackState","Current.ErrorMessage","Queue.Title","Queue.Subtitle","Queue.Description","Queue.Copyright","Queue.Artwork","Control.PlayPause","Control.Repeat","Control.Next","Control.Previous","Control.Shuffle","Control.SeekBar","Control.Volume","Control.Mute","Control.PlaybackRate","useGinger"],"mappings":";;AA6BA,MAAMA,KAAgBC,EAAyC,IAAI;AAE5D,SAASC,KAAuC;AACrD,QAAMC,IAAMC,EAAWJ,EAAa;AACpC,MAAI,CAACG,EAAK,OAAM,IAAI,MAAM,yDAAyD;AACnF,SAAOA;AACT;ACzBA,SAASE,GAAqBC,GAA8B;AAC1D,QAAM,EAAE,UAAAC,GAAU,UAAAC,EAAA,IAAaF;AAC/B,SAAI,EAAEE,IAAW,MAAMD,EAAS,WAAW,IAAU,IAC9C,KAAK,IAAI,GAAGA,EAAS,IAAIA,EAAS,SAAS,CAAC,IAAIC,CAAQ;AACjE;AAEO,SAASC,GAAa,EAAE,WAAAC,GAAW,OAAAC,GAAO,SAAAC,IAAU,YAAY,aAAAC,KAAkC;;AACvG,QAAM,EAAE,UAAAC,GAAU,UAAAC,GAAU,OAAAC,GAAO,aAAAC,EAAA,IAAgBf,GAAA,GAC7CgB,MAAMC,IAAAH,EAAM,OAAOA,EAAM,YAAY,MAA/B,gBAAAG,EAAkC,YAAW,IACnDC,IAAsBC,EAAO;AAAA,IACjC,aAAa;AAAA,IACb,UAAU;AAAA,IACV,kBAAkB;AAAA,EAAA,CACnB,GAEKC,IAAW,CAAChB,GAAsBiB,IAAQ,OAAU;AACxD,UAAMC,IAAO;AAAA,MACX,aAAalB,EAAG;AAAA,MAChB,UAAUA,EAAG;AAAA,MACb,kBAAkBD,GAAqBC,CAAE;AAAA,IAAA,GAErCmB,IAAOL,EAAoB,SAC3BM,IACJ,KAAK,IAAIF,EAAK,cAAcC,EAAK,WAAW,KAAK,QACjD,KAAK,IAAID,EAAK,WAAWC,EAAK,QAAQ,KAAK,QAC3C,KAAK,IAAID,EAAK,mBAAmBC,EAAK,gBAAgB,KAAK;AAC7D,IAAI,CAACF,KAAS,CAACG,MACfN,EAAoB,UAAUI,GAC9BT,EAAS;AAAA,MACP,MAAM;AAAA,MACN,SAASS;AAAA,IAAA,CACV;AAAA,EACH;AAEA,SAAAG,EAAU,MAAM;AACd,UAAMrB,IAAKQ,EAAS;AACpB,IAAKR,MACLA,EAAG,SAASU,EAAM,QAClBV,EAAG,QAAQU,EAAM,OACjBV,EAAG,eAAeU,EAAM;AAAA,EAC1B,GAAG,CAACF,GAAUE,EAAM,QAAQA,EAAM,OAAOA,EAAM,YAAY,CAAC,GAE5DW,EAAU,MAAM;AACd,UAAMrB,IAAKQ,EAAS;AACpB,QAAKR,GACL;AAAA,UAAI,CAACY,GAAK;AACR,QAAAZ,EAAG,gBAAgB,KAAK,GACxBc,EAAoB,UAAU,EAAE,aAAa,IAAI,UAAU,IAAI,kBAAkB,GAAA;AACjF;AAAA,MACF;AACA,MAAId,EAAG,aAAa,KAAK,MAAMY,MAC7BZ,EAAG,MAAMY,GACTZ,EAAG,KAAA,GACHc,EAAoB,UAAU,EAAE,aAAa,IAAI,UAAU,IAAI,kBAAkB,GAAA;AAAA;AAAA,EAErF,GAAG,CAACN,GAAUE,EAAM,cAAcA,EAAM,QAAQE,CAAG,CAAC,GAGlD,gBAAAU;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAKd;AAAA,MACL,WAAAJ;AAAA,MACA,OAAAC;AAAA,MACA,SAAAC;AAAA,MACA,aAAAC;AAAA,MACA,UAAU;AAAA,MACV,aAAW;AAAA,MACX,cAAc,CAACgB,MAAM;AACnB,QAAAP,EAASO,EAAE,aAAa;AAAA,MAC1B;AAAA,MACA,kBAAkB,CAACA,MAAM;AACvB,cAAMvB,IAAKuB,EAAE;AACb,QAAAT,EAAoB,UAAU,EAAE,aAAa,IAAI,UAAU,IAAI,kBAAkB,GAAA,GACjFL,EAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,YACP,UAAUT,EAAG;AAAA,YACb,kBAAkBD,GAAqBC,CAAE;AAAA,UAAA;AAAA,QAC3C,CACD;AAAA,MACH;AAAA,MACA,WAAW,CAACuB,MAAMP,EAASO,EAAE,eAAe,EAAI;AAAA,MAChD,UAAU,CAACA,MAAMP,EAASO,EAAE,eAAe,EAAI;AAAA,MAC/C,SAAS,MAAMZ,EAAA;AAAA,MACf,QAAQ,MAAMF,EAAS,EAAE,MAAM,cAAc;AAAA,MAC7C,SAAS,MAAMA,EAAS,EAAE,MAAM,eAAe;AAAA,MAC/C,WAAW,MAAMA,EAAS,EAAE,MAAM,iBAAiB;AAAA,MACnD,WAAW,MAAMA,EAAS,EAAE,MAAM,iBAAiB;AAAA,MACnD,YAAY,CAACc,MAAMP,EAASO,EAAE,eAAe,EAAI;AAAA,MACjD,gBAAgB,CAACA,MAAM;AACrB,cAAMvB,IAAKuB,EAAE;AACb,QAAAd,EAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS,EAAE,QAAQT,EAAG,QAAQ,OAAOA,EAAG,MAAA;AAAA,QAAM,CAC/C;AAAA,MACH;AAAA,MACA,SAAS,MAAM;;AACb,cAAMA,IAAKQ,EAAS,SACdgB,KAAOX,IAAAb,KAAA,gBAAAA,EAAI,UAAJ,gBAAAa,EAAW;AAWxB,QAAAJ,EAAS,EAAE,MAAM,eAAe,SAAS,EAAE,SATzCe,MAAS,IACL,sBACAA,MAAS,IACP,sBACAA,MAAS,IACP,qBACAA,MAAS,IACP,gCACA,oBAC+B,GAAW;AAAA,MACxD;AAAA,IAAA;AAAA,EAAA;AAGN;ACxHO,SAASC,EAAWC,GAAeC,GAAwB;AAChE,SAAIA,KAAU,IAAU,IACjB,KAAK,IAAI,GAAG,KAAK,IAAIA,IAAS,GAAGD,CAAK,CAAC;AAChD;AAEO,SAASE,GAAkBC,GAAiBC,GAA8B;AAC/E,MAAID,EAAO,UAAU,EAAG,QAAO,CAAC,GAAGA,CAAM;AACzC,QAAME,IAASF,EAAOC,CAAW;AACjC,MAAI,CAACC,EAAQ,QAAO,CAAC,GAAGF,CAAM;AAC9B,QAAMG,IAAOH,EAAO,OAAO,CAACI,GAAGC,MAAMA,MAAMJ,CAAW;AACtD,WAASI,IAAIF,EAAK,SAAS,GAAGE,IAAI,GAAGA,KAAK;AACxC,UAAMC,IAAI,KAAK,MAAM,KAAK,YAAYD,IAAI,EAAE;AAC5C,KAACF,EAAKE,CAAC,GAAGF,EAAKG,CAAC,CAAC,IAAI,CAACH,EAAKG,CAAC,GAAIH,EAAKE,CAAC,CAAE;AAAA,EAC1C;AACA,SAAO,CAACH,GAAQ,GAAGC,CAAI;AACzB;AAEO,SAASI,GAAcC,GAAyC;AACrE,SAAKA,IACEA,EAAM,MAAM,QAAQA,EAAM,OAAO,KAAK,MAAMA,EAAM,EAAE,KAAK,QAAQA,EAAM,OAAO,KADlE;AAErB;AAEO,SAASC,GAAyBT,GAAiBU,GAA0C;AAClG,QAAMC,IAAWJ,GAAcG,CAAM;AACrC,MAAI,CAACC,EAAU,QAAO;AACtB,QAAMN,IAAIL,EAAO,UAAU,CAACQ,MAAUD,GAAcC,CAAK,MAAMG,CAAQ;AACvE,SAAON,MAAM,KAAK,IAAIA;AACxB;ACpBO,SAASO,GAAuB/B,GAAqC;AAC1E,QAAM,EAAE,QAAAmB,GAAQ,cAAAa,GAAc,YAAAC,EAAA,IAAejC,GACvCkC,IAAMf,EAAO;AACnB,SAAIe,MAAQ,IAAU,EAAE,MAAM,QAAQ,WAAW,EAAA,IAC7CD,MAAe,QAAc,EAAE,MAAM,cAAA,IACrCD,IAAeE,IAAM,IAAU,EAAE,MAAM,WAAW,WAAWF,IAAe,EAAA,IAC5EC,MAAe,QAAc,EAAE,MAAM,QAAQ,WAAW,EAAA,IACrD,EAAE,MAAM,QAAQ,WAAWlB,EAAWiB,GAAcE,CAAG,EAAA;AAChE;AAEO,SAASC,GAAiBnC,GAA4B;AAC3D,QAAM,EAAE,QAAAmB,GAAQ,cAAAa,GAAc,YAAAC,EAAA,IAAejC,GACvCkC,IAAMf,EAAO;AACnB,SAAIe,MAAQ,IAAU,IAClBF,IAAeE,IAAM,IAAUF,IAAe,IAC9CC,MAAe,QAAc,IAC1BlB,EAAWiB,GAAcE,CAAG;AACrC;AAEO,SAASE,GAAiBpC,GAA4B;AAC3D,QAAM,EAAE,QAAAmB,GAAQ,cAAAa,GAAc,YAAAC,EAAA,IAAejC,GACvCkC,IAAMf,EAAO;AACnB,SAAIe,MAAQ,IAAU,IAClBF,IAAe,IAAUA,IAAe,IACxCC,MAAe,QAAcC,IAAM,IAChC;AACT;AAEO,SAASG,GAAgBC,GAA8B;AAC5D,SAAIA,MAAS,QAAc,QACvBA,MAAS,QAAc,QACpB;AACT;AAEO,SAASC,GAAkBZ,GAAqBa,GAAqD;AAC1G,UAAOb,KAAA,gBAAAA,EAAO,eAAca,KAAmB;AACjD;AAEO,SAASC,GAAiBd,GAAqBe,GAAsD;AAC1G,UAAOf,KAAA,gBAAAA,EAAO,UAASe,KAAoB;AAC7C;AC9CO,SAASC,EAAgB3C,GAAkC;AAEhE,SADUA,EAAM,OAAOA,EAAM,YAAY,KAC7B;AACd;AAEO,SAAS4C,GAAsB5C,GAAqC;AACzE,SAAIA,EAAM,eAAqB,UAC3BA,EAAM,OAAO,WAAW,IAAU,SAClCA,EAAM,cAAoB,YACzBA,EAAM,WAET,OAAO,SAASA,EAAM,QAAQ,KAC9BA,EAAM,WAAW,KACjBA,EAAM,eAAeA,EAAM,WAAW,OAE/B,UAEF,WARqB;AAS9B;AAEO,SAAS6C,EAAkB7C,GAA4B;;AAC5D,QAAM8C,IAAI9C,EAAM;AAChB,MAAI,OAAO,SAAS8C,CAAC,KAAKA,IAAI,EAAG,QAAOA;AACxC,QAAMC,KAAO5C,IAAAH,EAAM,OAAOA,EAAM,YAAY,MAA/B,gBAAAG,EAAkC;AAC/C,SAAI,OAAO4C,KAAS,YAAY,OAAO,SAASA,CAAI,KAAKA,IAAO,IAAUA,IACnE;AACT;AAEO,SAASC,GAAmBhD,GAA4B;AAE7D,QAAMiD,IADMJ,EAAkB7C,CAAK,IACjBA,EAAM;AACxB,SAAO,OAAO,SAASiD,CAAG,IAAI,KAAK,IAAI,GAAGA,CAAG,IAAI;AACnD;AAEO,SAASC,GAAiBlD,GAA4B;AAC3D,QAAMmD,IAAMN,EAAkB7C,CAAK;AACnC,SAAMmD,IAAM,IACL,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGnD,EAAM,cAAcmD,CAAG,CAAC,IADhC;AAEzB;AAEO,SAASC,GAAgBpD,GAAwC;;AACtE,QAAM2B,IAAQgB,EAAgB3C,CAAK;AACnC,SAAOuC,GAAkBZ,IAAOxB,IAAAH,EAAM,iBAAN,gBAAAG,EAAoB,UAAU;AAChE;AAEO,SAASkD,GAAkBrD,GAAwC;;AACxE,QAAM2B,IAAQgB,EAAgB3C,CAAK;AACnC,SAAOyC,GAAiBd,IAAOxB,IAAAH,EAAM,iBAAN,gBAAAG,EAAoB,QAAQ;AAC7D;ACPA,MAAMmD,KAAwBrE,EAAiD,IAAI,GAC7EsE,KAAqBtE,EAA8C,IAAI;AAEtE,SAASuE,IAAgD;AAC9D,QAAMrE,IAAMC,EAAWkE,EAAqB;AAC5C,MAAI,CAACnE,EAAK,OAAM,IAAI,MAAM,oDAAoD;AAC9E,SAAOA;AACT;AAEO,SAASsE,IAA0C;AACxD,QAAMtE,IAAMC,EAAWmE,EAAkB;AACzC,MAAI,CAACpE,EAAK,OAAM,IAAI,MAAM,oDAAoD;AAC9E,SAAOA;AACT;AAGO,SAASuE,IAA8B;AAC5C,QAAMC,IAAKH,EAAA,GACLI,IAAKH,EAAA;AACX,SAAOI,EAAQ,MAAMC,GAA6BH,GAAIC,CAAE,GAAG,CAACD,GAAIC,CAAE,CAAC;AACrE;AAGO,SAASG,GACdC,GACAC,GACa;AACb,SAAO,EAAE,GAAGD,GAAU,GAAGC,EAAA;AAC3B;AAGO,SAASH,GACdH,GACAC,GACa;AACb,QAAM;AAAA,IACJ,MAAMM;AAAA,IACN,MAAMC;AAAA,IACN,OAAOC;AAAA,IACP,iBAAiBC;AAAA,IACjB,MAAMC;AAAA,IACN,MAAMC;AAAA,IACN,eAAeC;AAAA,IACf,aAAaC;AAAA,IACb,eAAeC;AAAA,IACf,UAAUC;AAAA,IACV,aAAaC;AAAA,IACb,eAAeC;AAAA,IACf,iBAAiBC;AAAA,IACjB,UAAUC;AAAA,IACV,GAAGC;AAAA,EAAA,IACDrB,GACE;AAAA,IACJ,MAAMsB;AAAA,IACN,WAAWC;AAAA,IACX,UAAUC;AAAA,IACV,YAAYC;AAAA,IACZ,iBAAiBC;AAAA,IACjB,UAAUC;AAAA,IACV,aAAaC;AAAA,IACb,UAAUC;AAAA,IACV,GAAGC;AAAA,EAAA,IACD7B;AACJ,SAAO,EAAE,GAAGoB,GAAc,GAAGS,EAAA;AAC/B;ACnGO,SAASC,EACdC,GACAC,GACkD;AAClD,WAASC,EAAKC,GAAyB;AACrC,UAAM9F,IAAQ0D,EAAA,GAERqC,KADMH,EAAO5F,CAAK,KAAK,IACX,KAAA,GACZ,EAAE,WAAAN,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,MAAaJ;AACxD,QAAI,CAACC,GAAO;AACV,YAAMI,IAAOF,KAASD,KAAY;AAClC,aAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,IAC1E;AACA,WAAIuG,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASH,GAAO/F,CAAK,EAAA,CAAE,IAErF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAoG,GACH;AAAA,EAEJ;AACA,SAAAF,EAAK,cAAcF,GACZE;AACT;AAEO,SAASO,EACdT,GACAC,GACkD;AAClD,SAAOF,EAAkBC,GAAa,CAAC3F,MAAU4F,EAAOjD,EAAgB3C,CAAK,CAAC,CAAC;AACjF;ACnCO,MAAMqG,KAAQD,EAAwB,wBAAwB,CAACE,MAAMA,KAAA,gBAAAA,EAAG,KAAK,GACvEC,KAASH,EAAwB,yBAAyB,CAACE,MAAMA,KAAA,gBAAAA,EAAG,MAAM,GAC1EE,KAAQd,EAAkB,wBAAwB,CAACe,MAAMpD,GAAkBoD,CAAC,CAAC,GAC7EC,KAAcN,EAAwB,8BAA8B,CAACE,MAAMA,KAAA,gBAAAA,EAAG,WAAW,GACzFK,KAAYjB,EAAkB,4BAA4B,CAACe,MAAM;;AAC5E,QAAMH,IAAI3D,EAAgB8D,CAAC;AAC3B,UAAOH,KAAA,gBAAAA,EAAG,gBAAanG,IAAAsG,EAAE,iBAAF,gBAAAtG,EAAgB;AACzC,CAAC,GACYyG,KAAQR,EAAwB,wBAAwB,CAACE,MAAMA,KAAA,gBAAAA,EAAG,KAAK,GACvEO,KAAQT,EAAwB,wBAAwB,CAACE,MAAMA,KAAA,gBAAAA,EAAG,KAAK,GACvEQ,KAAOV,EAAwB,uBAAuB,CAACE,MAAMA,KAAA,gBAAAA,EAAG,IAAI,GACpES,KAAcX;AAAA,EAAwB;AAAA,EAA8B,CAACE,OAChFA,KAAA,gBAAAA,EAAG,gBAAe,OAAO,OAAOA,EAAE,WAAW,IAAI;AACnD;ACRO,SAASU,GAAK,EAAE,WAAAtH,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,GAAU,QAAAe,KAAqB;;AACvF,QAAMjH,IAAQ0D,EAAA,GACRwD,KAAI/G,IAAAwC,EAAgB3C,CAAK,MAArB,gBAAAG,EAAwB;AAClC,MAAI,OAAO+G,KAAM,YAAY,CAAC,OAAO,SAASA,CAAC,GAAG;AAChD,UAAMf,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,QAAMwH,IAAOF,IAASA,EAAOC,CAAC,IAAI,OAAOA,CAAC;AAC1C,SAAIhB,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASiB,GAAMnH,CAAK,EAAA,CAAE,IAEpF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAwH,GACH;AAEJ;AAEAH,GAAK,cAAc;ACbZ,SAASI,GAAO,EAAE,WAAA1H,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,GAAU,oBAAAmB,IAAqB,MAAqB;;AAC9G,QAAMrH,IAAQ0D,EAAA,GACR4D,MAAMnH,IAAAwC,EAAgB3C,CAAK,MAArB,gBAAAG,EAAwB,WAAU,IACxC4F,IAAQsB,IAAqBC,EAAI,QAAQ,cAAc,EAAE,IAAIA,EAAI,KAAA;AACvE,MAAI,CAACvB,GAAO;AACV,UAAMI,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,QAAM4H,IAAwCF,IAAqB,EAAE,YAAY,eAAe;AAChG,SAAInB,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAO,EAAE,GAAG6H,GAAY,GAAG5H,EAAA,GAAU,UAAAuG,EAASH,GAAO/F,CAAK,GAAE,IAE3G,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAO,EAAE,GAAG6H,GAAY,GAAG5H,EAAA,GACpD,UAAAoG,EAAA,CACH;AAEJ;AAEAqB,GAAO,cAAc;ACnBd,SAASI,GAAQ,EAAE,SAAAC,IAAU,IAAO,WAAA/H,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,KAA0B;;AACtG,QAAMlG,IAAQ0D,EAAA;AACd,MAAI,CAAC+D,EAAS,QAAO;AACrB,QAAM1B,MAAQ5F,IAAAwC,EAAgB3C,CAAK,MAArB,gBAAAG,EAAwB,YAAW;AACjD,MAAI,CAAC4F,GAAO;AACV,UAAMI,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,SAAIuG,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASH,GAAO/F,CAAK,EAAA,CAAE,IAErF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAoG,GACH;AAEJ;AAEAyB,GAAQ,cAAc;ACff,SAASE,GAAQ,EAAE,WAAAhI,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,OAAA0B,GAAO,SAAAC,GAAS,SAAAC,GAAS,UAAAC,GAAU,UAAAC,EAAA,GAA0B;AACxH,QAAM/H,IAAQ0D,EAAA,GACR/B,IAAQgB,EAAgB3C,CAAK,GAC7BgI,IAAM5E,GAAgBpD,CAAK;AACjC,MAAI,CAACgI,GAAK;AACR,UAAM7B,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,QAAMsI,IAAM,CAACtG,KAAA,gBAAAA,EAAO,OAAOA,KAAA,gBAAAA,EAAO,MAAM,EAAE,OAAO,OAAO,EAAE,KAAK,KAAK,KAAK;AACzE,SACE,gBAAAf;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAAlB;AAAA,MACA,OAAO;AAAA,QACL,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,GAAGC;AAAA,MAAA;AAAA,MAGL,UAAA,gBAAAiB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAAoH;AAAA,UACA,KAAAC;AAAA,UACA,OAAAN;AAAA,UACA,SAAAC;AAAA,UACA,UAAAE;AAAA,UACA,SAAAD;AAAA,UACA,OAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,WAAW;AAAA,YACX,GAAGE;AAAA,UAAA;AAAA,QACL;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;AAEAL,GAAQ,cAAc;ACvCf,SAASQ,GAAW,EAAE,MAAAC,IAAO,GAAG,WAAAzI,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,KAA6B;AACrG,QAAMlG,IAAQ0D,EAAA;AAEd,MADY1D,EAAM,OAAO,WACb,GAAG;AACb,UAAMmG,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,QAAMoG,IAAQ,OAAO/F,EAAM,eAAemI,CAAI;AAC9C,SAAIjC,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASH,GAAO/F,CAAK,EAAA,CAAE,IAErF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAoG,GACH;AAEJ;AAEAmC,GAAW,cAAc;AAMlB,SAASE,GAAY,EAAE,WAAA1I,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,KAA8B;AAC7F,QAAMlG,IAAQ0D,EAAA,GACRqC,IAAQ,OAAO/F,EAAM,OAAO,MAAM;AACxC,MAAIA,EAAM,OAAO,WAAW,GAAG;AAC7B,UAAMmG,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,SAAIuG,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASH,GAAO/F,CAAK,EAAA,CAAE,IAErF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAoG,GACH;AAEJ;AAEAqC,GAAY,cAAc;AAQnB,SAASC,GAAc;AAAA,EAC5B,MAAAF,IAAO;AAAA,EACP,WAAAG,IAAY;AAAA,EACZ,WAAA5I;AAAA,EACA,OAAAC;AAAA,EACA,UAAAqG;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AACF,GAAuB;AACrB,QAAMlG,IAAQ0D,EAAA,GACRxB,IAAMlC,EAAM,OAAO;AACzB,MAAIkC,MAAQ,GAAG;AACb,UAAMiE,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,QAAMqB,IAAQ,OAAOhB,EAAM,eAAemI,CAAI,GACxClH,IAAS,OAAOiB,CAAG,GACnBqG,IAAQ,GAAGvH,CAAK,GAAGsH,CAAS,GAAGrH,CAAM;AAC3C,SAAIiF,IAEA,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAuG,EAAS,EAAE,OAAAlF,GAAO,QAAAC,GAAQ,OAAAsH,EAAA,GAASvI,CAAK,EAAA,CAC3C,IAGF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAA4I,GACH;AAEJ;AAEAF,GAAc,cAAc;ACrFrB,SAASG,GAAWC,GAAyB;AAClD,MAAI,CAAC,OAAO,SAASA,CAAO,KAAKA,IAAU,EAAG,QAAO;AACrD,QAAMhC,IAAI,KAAK,MAAMgC,IAAU,EAAE;AAEjC,SAAO,GADG,KAAK,MAAMA,IAAU,EAAE,CACtB,IAAIhC,EAAE,WAAW,SAAS,GAAG,GAAG,CAAC;AAC9C;ACMA,SAASiC,GACPC,GACA3I,GACA8F,GACqB;AACrB,QAAM,EAAE,WAAApG,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,GAAU,QAAAe,IAASuB,OAAe1C;AAC7E,MAAI,EAAE6C,KAAgB,MAAM,CAAC,OAAO,SAASA,CAAY,GAAG;AAC1D,UAAMxC,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,QAAMwH,IAAOF,EAAO0B,CAAY;AAChC,SAAIzC,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASiB,GAAMnH,CAAK,EAAA,CAAE,IAEpF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAwH,GACH;AAEJ;AAEO,SAASyB,GAAQ9C,GAAsB;AAC5C,QAAM9F,IAAQ0D,EAAA;AACd,SAAOgF,GAAW1I,EAAM,aAAaA,GAAO8F,CAAK;AACnD;AAEA8C,GAAQ,cAAc;AAEf,SAASC,GAAS/C,GAAsB;AAC7C,QAAM9F,IAAQ0D,EAAA;AACd,SAAOgF,GAAW7F,EAAkB7C,CAAK,GAAGA,GAAO8F,CAAK;AAC1D;AAEA+C,GAAS,cAAc;AAEhB,SAASC,GAAUhD,GAAsB;AAC9C,QAAM9F,IAAQ0D,EAAA;AACd,SAAOgF,GAAW1F,GAAmBhD,CAAK,GAAGA,GAAO8F,CAAK;AAC3D;AAEAgD,GAAU,cAAc;AAMjB,SAASC,GAAS,EAAE,WAAArJ,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,KAA2B;AACvF,QAAMlG,IAAQ0D,EAAA,GACRlE,IAAWqD,EAAkB7C,CAAK,GAClCgJ,IAAW9F,GAAiBlD,CAAK;AACvC,MAAI,EAAER,IAAW,IAAI;AACnB,UAAM2G,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,SAAIuG,IAEA,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAuG,EAAS,EAAE,UAAA8C,GAAU,aAAahJ,EAAM,aAAa,UAAAR,EAAA,GAAYQ,CAAK,GACzE,IAGF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAA,GAAG,KAAK,MAAMqJ,IAAW,GAAG,CAAC,IAAA,CAChC;AAEJ;AAEAD,GAAS,cAAc;AAShB,SAASE,GAAS,EAAE,WAAAvJ,GAAW,OAAAC,GAAO,QAAAuJ,IAAS,GAAG,cAAAC,IAAe,MAAwB;AAC9F,QAAMnJ,IAAQ0D,EAAA,GACR0F,IAAc,GAAG,KAAK,MAAMlG,GAAiBlD,CAAK,IAAI,GAAG,CAAC,KAC1DqJ,IAAS,GAAG,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGrJ,EAAM,gBAAgB,CAAC,IAAI,GAAG,CAAC;AACpF,SACE,gBAAAsJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAA5J;AAAA,MACA,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAAwJ;AAAA,QACA,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,UAAU;AAAA,QACV,GAAGvJ;AAAA,MAAA;AAAA,MAEL,eAAW;AAAA,MAEV,UAAA;AAAA,QAAAwJ,IACC,gBAAAvI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,MAAM;AAAA,cACN,KAAK;AAAA,cACL,QAAQ;AAAA,cACR,OAAOyI;AAAA,cACP,YAAY;AAAA,YAAA;AAAA,UACd;AAAA,QAAA,IAEA;AAAA,QACJ,gBAAAzI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAOwI;AAAA,cACP,QAAQ;AAAA,cACR,YAAY;AAAA,YAAA;AAAA,UACd;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAGN;AAEAH,GAAS,cAAc;AAOhB,SAASM,GAAW,EAAE,WAAA7J,GAAW,OAAAC,GAAO,QAAAuJ,IAAS,KAAsB;AAC5E,QAAMlJ,IAAQ0D,EAAA,GACR2F,IAAS,GAAG,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGrJ,EAAM,gBAAgB,CAAC,IAAI,GAAG,CAAC;AACpF,SACE,gBAAAY;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAAlB;AAAA,MACA,OAAO;AAAA,QACL,OAAO;AAAA,QACP,QAAAwJ;AAAA,QACA,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,GAAGvJ;AAAA,MAAA;AAAA,MAEL,eAAW;AAAA,MAEX,UAAA,gBAAAiB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,YACL,OAAOyI;AAAA,YACP,QAAQ;AAAA,YACR,YAAY;AAAA,UAAA;AAAA,QACd;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;AAEAE,GAAW,cAAc;ACxJlB,SAASC,GAAc,EAAE,WAAA9J,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,KAAgC;AACjG,QAAMlG,IAAQ0D,EAAA,GACRqC,IAAQnD,GAAsB5C,CAAK;AACzC,SAAIkG,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASH,GAAO/F,CAAK,EAAA,CAAE,IAErF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAoG,GACH;AAEJ;AAEAyD,GAAc,cAAc;AAMrB,SAASC,GAAa,EAAE,WAAA/J,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAAC,KAA+B;AAC/F,QAAMlG,IAAQ0D,EAAA,GACRqC,IAAQ/F,EAAM,gBAAgB;AACpC,MAAI,CAAC+F,GAAO;AACV,UAAMI,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,SAAIuG,IAAiB,gBAAAtF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,UAAAuG,EAASH,GAAO/F,CAAK,EAAA,CAAE,IAErF,gBAAAY,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GACzB,UAAAoG,GACH;AAEJ;AAEA0D,GAAa,cAAc;ACtCpB,MAAMC,KAA4C;AAAA,EACvD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,WAAW;AAAA,EACX,eAAe;AAAA,EACf,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EAAA;AAAA,EAEP,oBAAoB;AAAA,EACpB,mBAAmB,CAACC,MAAS,GAAGA,CAAI;AACtC;AAEA,SAASC,GAAYC,GAA+D;AAClF,SAAKA,IACE;AAAA,IACL,GAAGH;AAAA,IACH,GAAGG;AAAA,IACH,QAAQ,EAAE,GAAGH,GAAoB,QAAQ,GAAGG,EAAQ,OAAA;AAAA,EAAO,IAJxCH;AAMvB;AAEA,MAAMI,KAAsB7K,EAAoCyK,EAAmB;AAE5E,SAASK,GAAqB;AAAA,EACnC,QAAAC;AAAA,EACA,UAAA9D;AACF,GAGG;AACD,QAAMH,IAAQ6D,GAAYI,CAAM;AAChC,SAAO,gBAAApJ,EAACkJ,GAAoB,UAApB,EAA6B,OAAA/D,GAAe,UAAAG,EAAA,CAAS;AAC/D;AAEO,SAAS+D,IAAwC;AACtD,SAAO7K,EAAW0K,EAAmB;AACvC;AC1BO,SAASI,KAAoC;AAClD,QAAMvG,IAAKH,EAAA,GACLI,IAAKH,EAAA,GACLuG,IAASC,EAAA,GACTjK,IAAQ6D,EAAQ,MAAMC,GAA6BH,GAAIC,CAAE,GAAG,CAACD,GAAIC,CAAE,CAAC,GACpEpE,IAAWqD,EAAkB7C,CAAK,GAClC+F,IAAQvG,IAAW,IAAIQ,EAAM,cAAc,GAC3CmK,IAAe,OAAO,SAASpE,CAAK,IAAIA,IAAQ,GAChDqE,IACJ5K,IAAW,IACP,GAAGgJ,GAAW2B,CAAY,CAAC,OAAO3B,GAAWhJ,CAAQ,CAAC,KACtDgJ,GAAW2B,CAAY,GAEvBE,IAAc,CAACxJ,MAAmC;AACtD,IAAA+C,EAAG,KAAK,OAAO/C,EAAE,cAAc,KAAK,CAAC;AAAA,EACvC;AAEA,SAAO;AAAA,IACL,OAAAb;AAAA,IACA,OAAOmK;AAAA,IACP,KAAK;AAAA,IACL,KAAK3K,IAAW,IAAIA,IAAW;AAAA,IAC/B,MAAM;AAAA,IACN,eAAA4K;AAAA,IACA,WAAWJ,EAAO;AAAA,IAClB,aAAAK;AAAA,IACA,cAAcA;AAAA,EAAA;AAElB;AAeO,SAASC,KAAiC;AAC/C,QAAM3G,IAAKH,EAAA,GACLI,IAAKH,EAAA,GACLuG,IAASC,EAAA,GACTjK,IAAQ6D,EAAQ,MAAMC,GAA6BH,GAAIC,CAAE,GAAG,CAACD,GAAIC,CAAE,CAAC,GAEpE2G,IAAgB,CAAC1J,MAAmC;AACxD,IAAA+C,EAAG,UAAU,OAAO/C,EAAE,cAAc,KAAK,CAAC;AAAA,EAC5C;AAEA,SAAO;AAAA,IACL,OAAAb;AAAA,IACA,OAAOA,EAAM;AAAA,IACb,KAAK;AAAA,IACL,KAAK;AAAA,IACL,MAAM;AAAA,IACN,eAAe,GAAG,KAAK,MAAMA,EAAM,SAAS,GAAG,CAAC;AAAA,IAChD,WAAWgK,EAAO;AAAA,IAClB,eAAAO;AAAA,IACA,gBAAgBA;AAAA,EAAA;AAEpB;AAUO,SAASC,GAAoBC,GAGf;AACnB,QAAM9G,IAAKH,EAAA,GACLwG,IAASC,EAAA,GACTS,KAAQD,KAAA,gBAAAA,EAAS,kBAAiBT,EAAO,MACzCW,KAASF,KAAA,gBAAAA,EAAS,mBAAkBT,EAAO;AACjD,SAAO;AAAA,IACL,UAAUrG,EAAG;AAAA,IACb,QAAQA,EAAG;AAAA,IACX,WAAWA,EAAG,WAAW+G,IAAQC;AAAA,EAAA;AAErC;ACtFO,SAASC,GAAU;AAAA,EACxB,WAAAC,IAAY;AAAA,EACZ,YAAAC,IAAa;AAAA,EACb,eAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,GAAG3J;AACL,GAAmB;AACjB,QAAM0I,IAASC,EAAA,GACTiB,IAAkB,OAAOL,KAAc,WAAWA,IAAYb,EAAO,MACrEmB,IAAmB,OAAOL,KAAe,WAAWA,IAAad,EAAO,OACxEoB,IAAIZ,GAAoB;AAAA,IAC5B,eAAeO,KAAiBG;AAAA,IAChC,gBAAgBF,KAAkBG;AAAA,EAAA,CACnC;AACD,SACE,gBAAAvK,EAAC,UAAA,EAAO,MAAAqK,GAAY,cAAYG,EAAE,WAAW,SAASA,EAAE,QAAS,GAAG9J,GACjE,UAAA8J,EAAE,WAAWP,IAAYC,GAC5B;AAEJ;AAEAF,GAAU,cAAc;AAIjB,SAASS,GAAO,EAAE,MAAAJ,IAAO,UAAU,GAAG3J,KAAqB;AAChE,QAAM,EAAE,YAAAW,GAAY,aAAAqJ,EAAA,IAAgB9H,EAAA,GAE9B+E,IADS0B,EAAA,EACM,OAAOhI,CAAU;AACtC,SACE,gBAAArB,EAAC,YAAO,MAAAqK,GAAY,cAAY1C,GAAO,SAAS+C,GAAc,GAAGhK,GAC9D,UAAAiH,EAAA,CACH;AAEJ;AAEA8C,GAAO,cAAc;AAGd,SAASE,GAAK,EAAE,MAAAN,IAAO,UAAU,UAAA/E,IAAW,QAAQ,GAAG5E,KAAmB;AAC/E,QAAM,EAAE,MAAAd,EAAA,IAASgD,EAAA,GACXwG,IAASC,EAAA;AACf,SACE,gBAAArJ,EAAC,UAAA,EAAO,MAAAqK,GAAY,cAAYjB,EAAO,WAAW,SAASxJ,GAAO,GAAGc,GAClE,UAAA4E,EAAA,CACH;AAEJ;AACAqF,GAAK,cAAc;AAGZ,SAASC,GAAS,EAAE,MAAAP,IAAO,UAAU,UAAA/E,IAAW,YAAY,GAAG5E,KAAuB;AAC3F,QAAM,EAAE,MAAAb,EAAA,IAAS+C,EAAA,GACXwG,IAASC,EAAA;AACf,SACE,gBAAArJ,EAAC,UAAA,EAAO,MAAAqK,GAAY,cAAYjB,EAAO,eAAe,SAASvJ,GAAO,GAAGa,GACtE,UAAA4E,EAAA,CACH;AAEJ;AACAsF,GAAS,cAAc;AAGhB,SAASC,GAAQ,EAAE,MAAAR,IAAO,UAAU,UAAA/E,IAAW,WAAW,GAAG5E,KAAsB;AACxF,QAAM,EAAE,YAAAoK,GAAY,eAAAC,EAAA,IAAkBnI,EAAA,GAChCwG,IAASC,EAAA;AACf,SACE,gBAAArJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAAqK;AAAA,MACA,gBAAcS;AAAA,MACd,cAAY1B,EAAO;AAAA,MACnB,SAAS2B;AAAA,MACR,GAAGrK;AAAA,MAEH,UAAA4E;AAAA,IAAA;AAAA,EAAA;AAGP;AACAuF,GAAQ,cAAc;AASf,SAASG,GAAQ,EAAE,YAAAC,GAAY,OAAAlM,GAAO,GAAG2B,KAAsB;AACpE,QAAM8J,IAAIlB,GAAA;AACV,SACE,gBAAAtJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAGU;AAAA,MACJ,MAAK;AAAA,MACL,KAAK8J,EAAE;AAAA,MACP,KAAKA,EAAE;AAAA,MACP,MAAMA,EAAE;AAAA,MACR,OAAOA,EAAE;AAAA,MACT,cAAYA,EAAE;AAAA,MACd,kBAAgBA,EAAE;AAAA,MAClB,SAASA,EAAE;AAAA,MACX,UAAUA,EAAE;AAAA,MACZ,OAAO,EAAE,OAAO,QAAQ,GAAGzL,GAAO,GAAGkM,EAAA;AAAA,IAAW;AAAA,EAAA;AAGtD;AAEAD,GAAQ,cAAc;AASf,SAASE,GAAO,EAAE,YAAAD,GAAY,OAAAlM,GAAO,GAAG2B,KAAqB;AAClE,QAAM8J,IAAId,GAAA;AACV,SACE,gBAAA1J;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAGU;AAAA,MACJ,MAAK;AAAA,MACL,KAAK8J,EAAE;AAAA,MACP,KAAKA,EAAE;AAAA,MACP,MAAMA,EAAE;AAAA,MACR,OAAOA,EAAE;AAAA,MACT,cAAYA,EAAE;AAAA,MACd,kBAAgBA,EAAE;AAAA,MAClB,SAASA,EAAE;AAAA,MACX,UAAUA,EAAE;AAAA,MACZ,OAAO,EAAE,OAAO,QAAQ,GAAGzL,GAAO,GAAGkM,EAAA;AAAA,IAAW;AAAA,EAAA;AAGtD;AAEAC,GAAO,cAAc;AAOd,SAASC,GAAK;AAAA,EACnB,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,MAAAhB,IAAO;AAAA,EACP,GAAG3J;AACL,GAAc;AACZ,QAAM,EAAE,OAAA4K,GAAO,YAAAC,EAAA,IAAe1I,EAAA,GACxBuG,IAASC,EAAA,GACTmC,IAAIJ,KAAahC,EAAO,MACxBqC,IAAIJ,KAAejC,EAAO;AAChC,SACE,gBAAApJ;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAAqK;AAAA,MACA,gBAAciB;AAAA,MACd,cAAYA,IAAQlC,EAAO,SAASA,EAAO;AAAA,MAC3C,SAASmC;AAAA,MACR,GAAG7K;AAAA,MAEH,cAAQ+K,IAAID;AAAA,IAAA;AAAA,EAAA;AAGnB;AAEAL,GAAK,cAAc;AAEnB,MAAMO,KAAe,CAAC,KAAK,MAAM,GAAG,MAAM,KAAK,CAAC;AAOzC,SAASC,GAAa,EAAE,OAAAC,IAAQF,IAAc,OAAA3M,GAAO,GAAG2B,KAA2B;AACxF,QAAM,EAAE,cAAAmL,GAAc,iBAAAC,EAAA,IAAoBjJ,EAAA,GACpCuG,IAASC,EAAA,GACTQ,IAAU5G;AAAA,IACd,MAAM,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG2I,GAAOC,CAAY,CAAC,CAAC,EAAE,KAAK,CAACE,GAAGvB,MAAMuB,IAAIvB,CAAC;AAAA,IACxE,CAACoB,GAAOC,CAAY;AAAA,EAAA;AAEtB,SACE,gBAAA7L;AAAA,IAAC;AAAA,IAAA;AAAA,MACE,GAAGU;AAAA,MACJ,cAAY0I,EAAO;AAAA,MACnB,OAAO,OAAOyC,CAAY;AAAA,MAC1B,OAAA9M;AAAA,MACA,UAAU,CAACkB,MAAM6L,EAAgB,OAAO7L,EAAE,cAAc,KAAK,CAAC;AAAA,MAE7D,YAAQ,IAAI,CAAC+L,MACZ,gBAAAhM,EAAC,UAAA,EAAe,OAAO,OAAOgM,CAAC,GAC5B,UAAAA,MAAM,IAAI5C,EAAO,qBAAqBA,EAAO,kBAAkB4C,CAAC,EAAA,GADtDA,CAEb,CACD;AAAA,IAAA;AAAA,EAAA;AAGP;AAEAL,GAAa,cAAc;AC3M3B,MAAMM,KAA8B5N,EAA2C,IAAI;AAEnF,SAAS6N,KAA0C;AACjD,QAAM3N,IAAMC,EAAWyN,EAA2B;AAClD,MAAI,CAAC1N;AACH,UAAM,IAAI,MAAM,6DAA6D;AAE/E,SAAOA;AACT;AAmBO,SAAS4N,GAAe;AAAA,EAC7B,UAAA7G;AAAA,EACA,UAAA8G;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC,IAAe;AAAA,EACf,OAAAvN;AAAA,EACA,GAAG2B;AACL,GAAwB;AACtB,QAAM,EAAE,QAAAH,GAAQ,cAAAa,GAAc,aAAAmL,GAAa,eAAAC,EAAA,IAAkB5J,EAAA,GAEvD6J,IAA2B;AAAA,IAC/B,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,OAAO;AAAA,IACP,GAAG1N;AAAA,EAAA;AAKL,SAFeuG,MAAa,SAIxB,gBAAAtF,EAACiM,GAA4B,UAA5B,EAAqC,OAAO,EAAE,cAAAK,EAAA,GAC7C,UAAA,gBAAAtM,EAAC,QAAG,OAAOyM,GAAY,GAAG/L,GACvB,UAAA4E,GACH,GACF,sBAKD2G,GAA4B,UAA5B,EAAqC,OAAO,EAAE,cAAAK,KAC7C,UAAA,gBAAAtM,EAAC,MAAA,EAAG,OAAOyM,GAAY,GAAG/L,GACvB,YAAO,IAAI,CAACK,GAAOX,MAAU;AAC5B,UAAMsM,IAAStM,MAAUgB;AACzB,6BACG,MAAA,EACC,UAAA,gBAAApB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAS,MAAM;AACb,UAAIsM,MAA0BlM,CAAK,MAChBA,CAAK;AAAA,QAC1B;AAAA,QACA,OAAO;AAAA,UACL,OAAO;AAAA,UACP,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,YAAYsM,IAAS,6DAA6D;AAAA,UAClF,OAAO;AAAA,UACP,MAAM;AAAA,UACN,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,GAAGN;AAAA,QAAA;AAAA,QAGJ,cACCC,EAAYtL,GAAOX,GAAOsM,CAAM,uBAE/B,QAAA,EACE,UAAA;AAAA,UAAA3L,EAAM;AAAA,UACNA,EAAM,SAAS,MAAMA,EAAM,MAAM,KAAK;AAAA,QAAA,EAAA,CACzC;AAAA,MAAA;AAAA,IAAA,KAzBG,GAAGX,CAAK,IAAIU,GAAcC,CAAK,CAAC,EA4BzC;AAAA,EAEJ,CAAC,GACH,GACF;AAEJ;AAEAoL,GAAe,cAAc;AAQtB,SAASQ,GAAoB;AAAA,EAClC,OAAAvM;AAAA,EACA,WAAAtB;AAAA,EACA,OAAAC;AAAA,EACA,UAAAuG;AAAA,EACA,SAAAsH;AAAA,EACA,SAAAC;AAAA,EACA,GAAGC;AACL,GAA6B;AAC3B,QAAM,EAAE,cAAAR,EAAA,IAAiBJ,GAAA,GACnB,EAAE,QAAA3L,GAAQ,cAAAa,GAAc,aAAAmL,GAAa,eAAAC,EAAA,IAAkB5J,EAAA,GACvD8J,IAAStM,MAAUgB,GACnBL,IAAQR,EAAOH,CAAK,GACpB2M,IACJhM,KAAS,OACP,gBAAA2H,GAAC,QAAA,EACE,UAAA;AAAA,IAAA3H,EAAM;AAAA,IACNA,EAAM,SAAS,MAAMA,EAAM,MAAM,KAAK;AAAA,EAAA,EAAA,CACzC,IACE;AAEN,SACE,gBAAAf,EAAC,MAAA,EAAI,GAAG4M,GACN,UAAA,gBAAA5M;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,gBAAc0M,IAAS,SAAS;AAAA,MAChC,sBAAoBA,KAAU;AAAA,MAC9B,WAAA5N;AAAA,MACA,OAAO;AAAA,QACL,OAAO;AAAA,QACP,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,YAAY4N,IAAS,6DAA6D;AAAA,QAClF,OAAO;AAAA,QACP,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,GAAG3N;AAAA,MAAA;AAAA,MAEJ,GAAG+N;AAAA,MACJ,SAAS,CAAC7M,MAAM;AAEd,QADA4M,KAAA,QAAAA,EAAU5M,IACN,CAAAA,EAAE,qBACFqM,MAA0BlM,CAAK,MAChBA,CAAK;AAAA,MAC1B;AAAA,MAEC,UAAAkF,KAAYyH;AAAA,IAAA;AAAA,EAAA,GAEjB;AAEJ;AAEAJ,GAAoB,cAAc;AAE3B,MAAMK,KAAyB,OAAO,OAAOb,IAAgB;AAAA,EAClE,OAAOQ;AACT,CAAC,GClLYlH,KAAQX,EAAkB,sBAAsB,CAACe,MAAA;;AAAM,UAAAtG,IAAAsG,EAAE,iBAAF,gBAAAtG,EAAgB;AAAA,CAAK,GAC5E0N,KAAWnI,EAAkB,yBAAyB,CAACe,MAAA;;AAAM,UAAAtG,IAAAsG,EAAE,iBAAF,gBAAAtG,EAAgB;AAAA,CAAQ,GACrFuG,KAAchB,EAAkB,4BAA4B,CAACe,MAAA;;AAAM,UAAAtG,IAAAsG,EAAE,iBAAF,gBAAAtG,EAAgB;AAAA,CAAW,GAC9FwG,KAAYjB,EAAkB,0BAA0B,CAACe,MAAA;;AAAM,UAAAtG,IAAAsG,EAAE,iBAAF,gBAAAtG,EAAgB;AAAA,CAAS;AAM9F,SAASuH,GAAQ,EAAE,WAAAhI,GAAW,OAAAC,GAAO,UAAAqG,GAAU,OAAAC,GAAO,UAAA8B,KAA+B;;AAC1F,QAAM/H,IAAQ0D,EAAA,GACRsE,KAAM7H,IAAAH,EAAM,iBAAN,gBAAAG,EAAoB;AAChC,MAAI,CAAC6H,GAAK;AACR,UAAM7B,IAAOF,KAASD,KAAY;AAClC,WAAOG,IAAO,gBAAAvF,EAAC,QAAA,EAAK,WAAAlB,GAAsB,OAAAC,GAAe,aAAK,IAAU;AAAA,EAC1E;AACA,QAAMsI,MAAM6F,IAAA9N,EAAM,iBAAN,gBAAA8N,EAAoB,UAAS;AACzC,SACE,gBAAAlN;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAAlB;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,QACV,GAAGC;AAAA,MAAA;AAAA,MAGL,UAAA,gBAAAiB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAAoH;AAAA,UACA,KAAAC;AAAA,UACA,OAAO;AAAA,YACL,SAAS;AAAA,YACT,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,WAAW;AAAA,YACX,GAAGF;AAAA,UAAA;AAAA,QACL;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN;AAEAL,GAAQ,cAAc;AC5Cf,SAASqG,GAAYC,GAAmB;AAC7C,SAAK,OAAO,SAASA,CAAC,IACf,KAAK,IAAI,GAAG,KAAK,IAAI,GAAGA,CAAC,CAAC,IADD;AAElC;AAEO,SAASC,GAAkBrB,GAAmB;AACnD,SAAK,OAAO,SAASA,CAAC,IACf,KAAK,IAAI,GAAG,KAAK,IAAI,MAAMA,CAAC,CAAC,IADJ;AAElC;AAGA,MAAMsB,IAAkB;AAAA,EACtB,aAAa;AAAA,EACb,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,aAAa;AAAA,EACb,cAAc;AAChB,GAEMC,KAAe;AAAA,EACnB,GAAGD;AAAA,EACH,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,cAAc;AAChB;AAEO,SAASE,GAAmBC,GAUnB;AACd,QAAMlN,IAAS,CAAC,GAAGkN,EAAO,MAAM;AAChC,MAAIrM,IAAejB,EAAWsN,EAAO,gBAAgB,GAAGlN,EAAO,MAAM,GACjEmN,IAAiC,MACjCC,IAAUpN;AAEd,SAAIkN,EAAO,cAAclN,EAAO,SAAS,MACvCmN,IAAiB,CAAC,GAAGnN,CAAM,GAC3BoN,IAAUrN,GAAkBC,GAAQa,CAAY,GAChDA,IAAe,IAGV;AAAA,IACL,QAAQuM;AAAA,IACR,cAAAvM;AAAA,IACA,UAAUqM,EAAO,YAAY;AAAA,IAC7B,YAAY,GAAQA,EAAO,cAAcE,EAAQ,SAAS;AAAA,IAC1D,YAAYF,EAAO,cAAc;AAAA,IACjC,gBAAAC;AAAA,IACA,cAAcD,EAAO,gBAAgB;AAAA,IACrC,GAAGF;AAAA,IACH,QAAQJ,GAAYM,EAAO,UAAU,CAAC;AAAA,IACtC,OAAOA,EAAO,SAAS;AAAA,IACvB,cAAcJ,GAAkBI,EAAO,gBAAgB,CAAC;AAAA,EAAA;AAE5D;AAEO,SAASG,GAAcxO,GAAoByO,GAAmC;AACnF,UAAQA,EAAO,MAAA;AAAA,IACb,KAAK,QAAQ;AACX,YAAM;AAAA,QACJ,QAAAtN;AAAA,QACA,cAAAa;AAAA,QACA,cAAA0M;AAAA,QACA,UAAAC;AAAA,QACA,YAAAjD;AAAA,QACA,YAAAzJ;AAAA,QACA,QAAA2M;AAAA,QACA,OAAA1C;AAAA,QACA,cAAAO;AAAA,MAAA,IACEgC,EAAO;AACX,aAAOL,GAAmB;AAAA,QACxB,QAAAjN;AAAA,QACA,cAAAa;AAAA,QACA,cAAc0M,KAAgB;AAAA,QAC9B,UAAUC,KAAY;AAAA,QACtB,YAAYjD,KAAc;AAAA,QAC1B,YAAYzJ,KAAc;AAAA,QAC1B,QAAA2M;AAAA,QACA,OAAA1C;AAAA,QACA,cAAAO;AAAA,MAAA,CACD;AAAA,IACH;AAAA,IACA,KAAK,aAAa;AAChB,YAAM,EAAE,QAAAtL,GAAQ,cAAAa,EAAA,IAAiByM,EAAO,SAClCjO,IAAO,CAAC,GAAGW,CAAM,GACjB0N,IAAM9N,EAAWiB,KAAgBhC,EAAM,cAAcQ,EAAK,MAAM;AACtE,aAAO;AAAA,QACL,GAAGR;AAAA,QACH,QAAQQ;AAAA,QACR,cAAcqO;AAAA,QACd,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,GAAGX;AAAA,MAAA;AAAA,IAEP;AAAA,IACA,KAAK,aAAa;AAChB,YAAMW,IAAM9N,EAAW0N,EAAO,QAAQ,OAAOzO,EAAM,OAAO,MAAM,GAC1D8O,IAAKL,EAAO,QAAQ,UACpBE,IACJG,MAAO,KAAO,KAAQA,MAAO,KAAQ,KAAO9O,EAAM;AACpD,aAAO;AAAA,QACL,GAAGA;AAAA,QACH,cAAc6O;AAAA,QACd,GAAGX;AAAA,QACH,UAAAS;AAAA,MAAA;AAAA,IAEJ;AAAA,IACA,KAAK;AACH,aAAO,EAAE,GAAG3O,GAAO,UAAU,GAAA;AAAA,IAC/B,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,UAAU,GAAA;AAAA,IAC/B,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,UAAU,CAACA,EAAM,SAAA;AAAA,IACtC,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,YAAYyO,EAAO,QAAA;AAAA,IACxC,KAAK;AACH,aAAO,EAAE,GAAGzO,GAAO,YAAYqC,GAAgBrC,EAAM,UAAU,EAAA;AAAA,IACjE,KAAK,kBAAkB;AACrB,UAAIA,EAAM,OAAO,UAAU,EAAG,QAAO,EAAE,GAAGA,GAAO,YAAY,IAAO,gBAAgB,KAAA;AACpF,UAAI,CAACA,EAAM,YAAY;AACrB,cAAM+O,IAAW,CAAC,GAAG/O,EAAM,MAAM,GAC3BgP,IAAW9N,GAAkB6N,GAAU/O,EAAM,YAAY;AAC/D,eAAO;AAAA,UACL,GAAGA;AAAA,UACH,YAAY;AAAA,UACZ,gBAAgB+O;AAAA,UAChB,QAAQC;AAAA,UACR,cAAc;AAAA,QAAA;AAAA,MAElB;AACA,YAAMC,IAAWjP,EAAM,iBAAiB,CAAC,GAAGA,EAAM,cAAc,IAAI,CAAC,GAAGA,EAAM,MAAM,GAC9EkP,IAAUlP,EAAM,OAAOA,EAAM,YAAY,GACzCmP,IAAWvN,GAAyBqN,GAAUC,CAAO;AAC3D,aAAO;AAAA,QACL,GAAGlP;AAAA,QACH,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,QAAQiP;AAAA,QACR,cAAclO,EAAWoO,GAAUF,EAAS,MAAM;AAAA,MAAA;AAAA,IAEtD;AAAA,IACA,KAAK,QAAQ;AACX,YAAMG,IAAYjN,GAAiBnC,CAAK,GAClCqP,IAAOD,MAAcpP,EAAM;AACjC,aAAO;AAAA,QACL,GAAGA;AAAA,QACH,cAAcoP;AAAA,QACd,GAAIC,IAAO,CAAA,IAAKnB;AAAA,QAChB,UAAUmB,IAAOrP,EAAM,WAAW;AAAA,MAAA;AAAA,IAEtC;AAAA,IACA,KAAK,QAAQ;AACX,YAAMsP,IAAYlN,GAAiBpC,CAAK,GAClCqP,IAAOC,MAActP,EAAM;AACjC,aAAO;AAAA,QACL,GAAGA;AAAA,QACH,cAAcsP;AAAA,QACd,GAAID,IAAO,CAAA,IAAKnB;AAAA,QAChB,UAAUmB,IAAOrP,EAAM,WAAW;AAAA,MAAA;AAAA,IAEtC;AAAA,IACA,KAAK;AACH,aAAO;AAAA,QACL,GAAGA;AAAA,QACH,aAAayO,EAAO,QAAQ;AAAA,QAC5B,UAAU,OAAO,SAASA,EAAO,QAAQ,QAAQ,IAAIA,EAAO,QAAQ,WAAWzO,EAAM;AAAA,QACrF,kBAAkByO,EAAO,QAAQ;AAAA,QACjC,aAAa;AAAA,MAAA;AAAA,IAEjB,KAAK;AACH,aAAO;AAAA,QACL,GAAGzO;AAAA,QACH,UAAU,OAAO,SAASyO,EAAO,QAAQ,QAAQ,IAAIA,EAAO,QAAQ,WAAWzO,EAAM;AAAA,QACrF,kBAAkByO,EAAO,QAAQ;AAAA,QACjC,cAAc;AAAA,MAAA;AAAA,IAElB,KAAK;AACH,aAAO,EAAE,GAAGzO,GAAO,cAAcyO,EAAO,QAAA;AAAA,IAC1C,KAAK;AACH,aAAO;AAAA,QACL,GAAGzO;AAAA,QACH,cAAcyO,EAAO,QAAQ;AAAA,QAC7B,UAAU;AAAA,QACV,aAAa;AAAA,MAAA;AAAA,IAEjB,KAAK;AACH,aAAO,EAAE,GAAGzO,GAAO,aAAa,GAAA;AAAA,IAClC,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,aAAa,IAAO,cAAc,KAAA;AAAA,IACvD,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,UAAU,IAAO,aAAa,GAAA;AAAA,IACnD,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,UAAU,GAAA;AAAA,IAC/B,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,aAAa,GAAG,UAAU,GAAG,kBAAkB,EAAA;AAAA,IACpE,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,QAAQ+N,GAAYU,EAAO,OAAO,EAAA;AAAA,IACvD,KAAK;AACH,aAAO,EAAE,GAAGzO,GAAO,OAAOyO,EAAO,QAAA;AAAA,IACnC,KAAK;AACH,aAAO,EAAE,GAAGzO,GAAO,OAAO,CAACA,EAAM,MAAA;AAAA,IACnC,KAAK;AACH,aAAO,EAAE,GAAGA,GAAO,cAAciO,GAAkBQ,EAAO,OAAO,EAAA;AAAA,IACnE,KAAK,qBAAqB;AACxB,YAAM,EAAE,QAAAG,GAAQ,OAAA1C,EAAA,IAAUuC,EAAO,SAC3BT,IAAID,GAAYa,CAAM;AAC5B,aAAIZ,MAAMhO,EAAM,UAAUkM,MAAUlM,EAAM,QAAcA,IACjD,EAAE,GAAGA,GAAO,QAAQgO,GAAG,OAAA9B,EAAA;AAAA,IAChC;AAAA,IACA;AACE,aAAOlM;AAAA,EAAA;AAEb;AC/MA,MAAMuP,KAAsC;AAAA,EACzC,0BAAqC;AAAA,EACrC,wBAAmC;AAAA,EACnC,sBAAiC;AAAA,EACjC,wBAAmC;AAAA,EACnC,iCAA4C;AAAA,EAC5C,2BAAsC;AAAA,EACtC,uBAAkC;AAAA,EAClC,+BAA0C;AAAA,EAC1C,yBAAoC;AAAA,EACpC,uBAAkC;AACrC;AAEO,SAASC,GAAe;AAAA,EAC7B,UAAAtJ;AAAA,EACA,eAAAuJ,IAAgB,CAAA;AAAA,EAChB,cAAAC,IAAe;AAAA,EACf,qBAAAC,IAAsB;AAAA,EACtB,gBAAAC,IAAiB;AAAA,EACjB,mBAAAC,IAAoB;AAAA,EACpB,eAAAC,IAAgB;AAAA,EAChB,eAAAC,IAAgB;AAAA,EAChB,cAAAC,IAAe;AAAA,EACf,qBAAAC,IAAsB;AAAA,EACtB,iBAAAC;AAAA,EACA,QAAAlG;AAAA,EACA,WAAAtK;AAAA,EACA,OAAAC;AAAA,EACA,eAAAwQ;AAAA,EACA,QAAAC;AAAA,EACA,SAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAzI;AACF,GAAwB;;AACtB,QAAM/H,IAAWO,EAAgC,IAAI,GAC/C,CAACL,GAAOD,CAAQ,IAAIwQ;AAAA,IACxB/B;AAAA,IACA;AAAA,IACA,MACEJ,GAAmB;AAAA,MACjB,QAAQqB;AAAA,MACR,cAAcC;AAAA,MACd,cAAcC;AAAA,MACd,UAAUG;AAAA,MACV,YAAYF;AAAA,MACZ,YAAYC;AAAA,MACZ,QAAQE;AAAA,MACR,OAAOC;AAAA,MACP,cAAcC;AAAA,IAAA,CACf;AAAA,EAAA,GAECO,KAAWnQ,EAAOL,CAAK,GAEvByQ,KAAgBpQ,EAAO;AAAA,IAC3B,QAAQoP;AAAA,IACR,cAAcC;AAAA,IACd,cAAcC;AAAA,IACd,UAAUG;AAAA,IACV,YAAYF;AAAA,IACZ,YAAYC;AAAA,IACZ,QAAQE;AAAA,IACR,OAAOC;AAAA,IACP,cAAcC;AAAA,EAAA,CACf;AACD,EAAAQ,GAAc,UAAU;AAAA,IACtB,QAAQhB;AAAA,IACR,cAAcC;AAAA,IACd,cAAcC;AAAA,IACd,UAAUG;AAAA,IACV,YAAYF;AAAA,IACZ,YAAYC;AAAA,IACZ,QAAQE;AAAA,IACR,OAAOC;AAAA,IACP,cAAcC;AAAA,EAAA;AAGhB,QAAMS,IAAyBrQ,EAA+B,MAAS;AAEvE,EAAAM,EAAU,MAAM;AACd,QAAIuP,MAAoB,QAAW;AACjC,MAAAQ,EAAuB,UAAU;AACjC;AAAA,IACF;AACA,QAAIA,EAAuB,YAAY,QAAW;AAChD,MAAAA,EAAuB,UAAUR;AACjC;AAAA,IACF;AACA,QAAIQ,EAAuB,YAAYR,EAAiB;AACxD,IAAAQ,EAAuB,UAAUR;AACjC,UAAMS,IAAIF,GAAc;AACxB,IAAA1Q,EAAS;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,QACP,QAAQ4Q,EAAE;AAAA,QACV,cAAcA,EAAE;AAAA,QAChB,cAAcA,EAAE;AAAA,QAChB,UAAUA,EAAE;AAAA,QACZ,YAAYA,EAAE;AAAA,QACd,YAAYA,EAAE;AAAA,QACd,QAAQA,EAAE;AAAA,QACV,OAAOA,EAAE;AAAA,QACT,cAAcA,EAAE;AAAA,MAAA;AAAA,IAClB,CACD;AAAA,EACH,GAAG,CAACT,CAAe,CAAC,GAEpBvP,EAAU,MAAM;AACd,IAAA6P,GAAS,UAAUxQ;AAAA,EACrB,GAAG,CAACA,CAAK,CAAC;AAEV,QAAM4Q,IAAe5Q,EAAM,OAAOA,EAAM,YAAY,KAAK;AAEzD,EAAAW,EAAU,MAAM;AACd,IAAAwP,KAAA,QAAAA,EAAgBS,GAAc5Q,EAAM;AAAA,EACtC,GAAG,CAAC4Q,GAAc5Q,EAAM,cAAcmQ,CAAa,CAAC,GAEpDxP,EAAU,MAAM;AACd,IAAIX,EAAM,iBAAc6H,KAAA,QAAAA,EAAU7H,EAAM;AAAA,EAC1C,GAAG,CAACA,EAAM,cAAc6H,CAAO,CAAC;AAEhC,QAAMgJ,IAAgBxQ,EAA4B,MAAS;AAC3D,EAAAM,EAAU,MAAM;AACd,QAAIkQ,EAAc,YAAY,QAAW;AACvC,MAAAA,EAAc,UAAU7Q,EAAM;AAC9B;AAAA,IACF;AACA,IAAI6Q,EAAc,YAAY7Q,EAAM,aAC9BA,EAAM,WAAUqQ,KAAA,QAAAA,MACfD,KAAA,QAAAA,MAEPS,EAAc,UAAU7Q,EAAM;AAAA,EAChC,GAAG,CAACA,EAAM,UAAUqQ,GAASD,CAAM,CAAC;AAEpC,QAAMU,IAAOC,EAAY,MAAM;AAC7B,IAAAhR,EAAS,EAAE,MAAM,QAAQ;AAAA,EAC3B,GAAG,CAAA,CAAE,GAECiR,IAAQD,EAAY,MAAM;;AAC9B,IAAAhR,EAAS,EAAE,MAAM,SAAS,IAC1BI,IAAAL,EAAS,YAAT,QAAAK,EAAkB;AAAA,EACpB,GAAG,CAAA,CAAE,GAEC8Q,IAAkBF,EAAY,MAAM;AACxC,IAAI/Q,EAAM,WAAU8Q,EAAA,IACfE,EAAA;AAAA,EACP,GAAG,CAACA,GAAOF,GAAM9Q,EAAM,QAAQ,CAAC,GAE1BkR,IAAOH,EAAY,CAACI,MAAwB;AAChD,UAAM7R,IAAKQ,EAAS;AACpB,IAAKR,KACA,OAAO,SAAS6R,CAAW,MAChC7R,EAAG,cAAc,KAAK,IAAI,GAAG6R,CAAW;AAAA,EAC1C,GAAG,CAAA,CAAE,GAECC,IAAYL,EAAY,CAACnC,MAAmB;AAChD,IAAA7O,EAAS,EAAE,MAAM,cAAc,SAASgO,GAAYa,CAAM,GAAG;AAAA,EAC/D,GAAG,CAAA,CAAE,GAECyC,IAAWN,EAAY,CAAC7E,MAAmB;AAC/C,IAAAnM,EAAS,EAAE,MAAM,aAAa,SAASmM,GAAO;AAAA,EAChD,GAAG,CAAA,CAAE,GAECC,IAAa4E,EAAY,MAAM;AACnC,IAAAhR,EAAS,EAAE,MAAM,eAAe;AAAA,EAClC,GAAG,CAAA,CAAE,GAEC2M,IAAkBqE,EAAY,CAACpH,MAAiB;AACpD,IAAA5J,EAAS,EAAE,MAAM,qBAAqB,SAASkO,GAAkBtE,CAAI,GAAG;AAAA,EAC1E,GAAG,CAAA,CAAE,GAECnJ,IAAOuQ,EAAY,MAAM;AAC7B,IAAAhR,EAAS,EAAE,MAAM,QAAQ;AAAA,EAC3B,GAAG,CAAA,CAAE,GAECU,IAAOsQ,EAAY,MAAM;AAC7B,IAAAhR,EAAS,EAAE,MAAM,QAAQ;AAAA,EAC3B,GAAG,CAAA,CAAE,GAECuR,KAAgBP,EAAY,CAACzO,MAAqB;AACtD,IAAAvC,EAAS,EAAE,MAAM,cAAc,SAASuC,GAAM;AAAA,EAChD,GAAG,CAAA,CAAE,GAECgJ,KAAcyF,EAAY,MAAM;AACpC,IAAAhR,EAAS,EAAE,MAAM,gBAAgB;AAAA,EACnC,GAAG,CAAA,CAAE,GAEC4L,KAAgBoF,EAAY,MAAM;AACtC,IAAAhR,EAAS,EAAE,MAAM,kBAAkB;AAAA,EACrC,GAAG,CAAA,CAAE,GAECwR,KAAWR,EAAY,CAAC5P,GAAiBa,MAA0B;AACvE,IAAAjC,EAAS,EAAE,MAAM,aAAa,SAAS,EAAE,QAAAoB,GAAQ,cAAAa,EAAA,GAAgB;AAAA,EACnE,GAAG,CAAA,CAAE,GAECmL,KAAc4D,EAAY,CAAC/P,MAAkB;AACjD,IAAAjB,EAAS,EAAE,MAAM,aAAa,SAAS,EAAE,OAAAiB,GAAO,UAAU,GAAA,GAAQ;AAAA,EACpE,GAAG,CAAA,CAAE,GAECoM,KAAgB2D,EAAY,CAAC/P,MAAkB;AACnD,IAAAjB,EAAS,EAAE,MAAM,aAAa,SAAS,EAAE,OAAAiB,GAAO,UAAU,GAAA,GAAS;AAAA,EACrE,GAAG,CAAA,CAAE,GAECwQ,KAAkBT,EAAY,CAACU,MAA8B;AACjE,IAAA1R,EAAS,EAAE,MAAM,qBAAqB,SAAS0R,GAAM;AAAA,EACvD,GAAG,CAAA,CAAE,GAECC,KAAOX,EAAY,CAACY,MAA+B;AACvD,IAAA5R,EAAS,EAAE,MAAM,QAAQ,SAAA4R,EAAA,CAAS;AAAA,EACpC,GAAG,CAAA,CAAE,GAECC,MAAazR,KAAAH,EAAM,OAAOA,EAAM,YAAY,MAA/B,gBAAAG,GAAkC;AAErD,EAAAQ,EAAU,MAAM;AACd,UAAMrB,IAAKQ,EAAS;AACpB,IAAKR,MACDU,EAAM,WAAUV,EAAG,MAAA,IAEhBA,EAAG,KAAA,EAAO,MAAM,CAACuB,MAAe;AACnC,YAAMgR,KACJhR,aAAa,QACTA,EAAE,UACF,OAAOA,KAAM,WACXA,IACA;AACR,MAAAd,EAAS,EAAE,MAAM,eAAe,SAAS,EAAE,SAAS8R,GAAA,GAAO;AAAA,IAC7D,CAAC;AAAA,EACL,GAAG,CAAC7R,EAAM,UAAU4R,EAAU,CAAC;AAE/B,QAAM3R,KAAc8Q,EAAY,MAAM;AACpC,UAAMe,IAAa/P,GAAuByO,GAAS,OAAO;AAC1D,QAAIsB,EAAW,SAAS,eAAe;AACrC,YAAMxS,KAAKQ,EAAS;AACpB,MAAIR,OACFA,GAAG,cAAc,IAEnBS,EAAS,EAAE,MAAM,QAAQ;AACzB;AAAA,IACF;AACA,QAAI+R,EAAW,SAAS,QAAQ;AAC9B,MAAA/R,EAAS,EAAE,MAAM,SAAS,GAC1BuQ,KAAA,QAAAA;AACA;AAAA,IACF;AACA,UAAMlB,IAAY0C,EAAW;AAC7B,IAAA/R,EAAS,EAAE,MAAM,aAAa,SAAS,EAAE,OAAOqP,GAAW,UAAU,GAAA,GAAQ;AAAA,EAC/E,GAAG,CAACkB,CAAU,CAAC,GAETvK,KAAQlC;AAAA,IACZ,OAAO;AAAA,MACL,OAAA7D;AAAA,MACA,UAAAD;AAAA,MACA,UAAAD;AAAA,MACA,aAAAG;AAAA,MACA,MAAAyR;AAAA,MACA,MAAAZ;AAAA,MACA,OAAAE;AAAA,MACA,iBAAAC;AAAA,MACA,MAAAC;AAAA,MACA,WAAAE;AAAA,MACA,UAAAC;AAAA,MACA,YAAAlF;AAAA,MACA,iBAAAO;AAAA,MACA,MAAAlM;AAAA,MACA,MAAAC;AAAA,MACA,eAAA6Q;AAAA,MACA,aAAAhG;AAAA,MACA,eAAAK;AAAA,MACA,UAAA4F;AAAA,MACA,aAAApE;AAAA,MACA,eAAAC;AAAA,MACA,iBAAAoE;AAAA,IAAA;AAAA,IAEF;AAAA,MACElG;AAAA,MACAvL;AAAA,MACA2R;AAAA,MACAlR;AAAA,MACAP;AAAA,MACA+Q;AAAA,MACAF;AAAA,MACA3D;AAAA,MACAC;AAAA,MACA3M;AAAA,MACAyQ;AAAA,MACAG;AAAA,MACA3E;AAAA,MACA6E;AAAA,MACAD;AAAA,MACAE;AAAA,MACAJ;AAAA,MACApR;AAAA,MACAmM;AAAA,MACA8E;AAAA,MACAtF;AAAA,IAAA;AAAA,EACF,GAGIoG,KAAgBlO;AAAA,IACpB,OAAO;AAAA,MACL,QAAQ7D,EAAM;AAAA,MACd,cAAcA,EAAM;AAAA,MACpB,UAAUA,EAAM;AAAA,MAChB,YAAYA,EAAM;AAAA,MAClB,YAAYA,EAAM;AAAA,MAClB,gBAAgBA,EAAM;AAAA,MACtB,cAAcA,EAAM;AAAA,MACpB,MAAA0R;AAAA,MACA,MAAAZ;AAAA,MACA,OAAAE;AAAA,MACA,iBAAAC;AAAA,MACA,MAAAzQ;AAAA,MACA,MAAAC;AAAA,MACA,eAAA6Q;AAAA,MACA,aAAAhG;AAAA,MACA,eAAAK;AAAA,MACA,UAAA4F;AAAA,MACA,aAAApE;AAAA,MACA,eAAAC;AAAA,MACA,iBAAAoE;AAAA,MACA,UAAAzR;AAAA,IAAA;AAAA,IAEF;AAAA,MACEC,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACN0R;AAAA,MACAZ;AAAA,MACAE;AAAA,MACAC;AAAA,MACAzQ;AAAA,MACAC;AAAA,MACA6Q;AAAA,MACAhG;AAAA,MACAK;AAAA,MACA4F;AAAA,MACApE;AAAA,MACAC;AAAA,MACAoE;AAAA,MACAzR;AAAA,IAAA;AAAA,EACF,GAGIiS,KAAanO;AAAA,IACjB,OAAO;AAAA,MACL,aAAa7D,EAAM;AAAA,MACnB,UAAUA,EAAM;AAAA,MAChB,kBAAkBA,EAAM;AAAA,MACxB,aAAaA,EAAM;AAAA,MACnB,cAAcA,EAAM;AAAA,MACpB,QAAQA,EAAM;AAAA,MACd,OAAOA,EAAM;AAAA,MACb,cAAcA,EAAM;AAAA,MACpB,MAAAkR;AAAA,MACA,WAAAE;AAAA,MACA,UAAAC;AAAA,MACA,YAAAlF;AAAA,MACA,iBAAAO;AAAA,MACA,UAAA5M;AAAA,MACA,aAAAG;AAAA,MACA,UAAAF;AAAA,IAAA;AAAA,IAEF;AAAA,MACEC,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNA,EAAM;AAAA,MACNkR;AAAA,MACAE;AAAA,MACAC;AAAA,MACAlF;AAAA,MACAO;AAAA,MACA5M;AAAA,MACAG;AAAA,MACAF;AAAA,IAAA;AAAA,EACF,GAGIkS,KAAarP,GAAsB5C,CAAK,GAExCkS,KAAcrO,EAAQ,OAAO,EAAE,GAAG0L,IAAsB,GAAG5P,EAAA,IAAU,CAACA,CAAK,CAAC;AAElF,2BACGoK,IAAA,EAAqB,QAAAC,GACpB,4BAAC1G,GAAsB,UAAtB,EAA+B,OAAOyO,IACrC,4BAACxO,GAAmB,UAAnB,EAA4B,OAAOyO,IAClC,4BAAChT,GAAc,UAAd,EAAuB,OAAA+G,IACtB,UAAA,gBAAAnF;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAAlB;AAAA,MACA,OAAOwS;AAAA,MACP,wBAAsBD;AAAA,MAErB,UAAA/L;AAAA,IAAA;AAAA,EAAA,GAEL,EAAA,CACF,EAAA,CACF,GACF;AAEJ;AC/ZO,MAAMiM,KAAS;AAAA,EACpB,UAAU3C;AAAA,EACV,QAAQ/P;AAAA,EACR,SAAS;AAAA,IACP,OAAO2S;AAAAA,IACP,QAAQC;AAAAA,IACR,OAAOC;AAAAA,IACP,aAAaC;AAAAA,IACb,WAAWC;AAAAA,IACX,OAAOC;AAAAA,IACP,OAAOC;AAAAA,IACP,MAAMC;AAAAA,IACN,aAAaC;AAAAA,IACb,MAAMC;AAAAA,IACN,QAAQC;AAAAA,IACR,SAASC;AAAAA,IACT,SAASC;AAAAA,IACT,YAAYC;AAAAA,IACZ,aAAaC;AAAAA,IACb,eAAeC;AAAAA,IACf,SAASC;AAAAA,IACT,UAAUC;AAAAA,IACV,WAAWC;AAAAA,IACX,UAAUC;AAAAA,IACV,UAAUC;AAAAA,IACV,YAAYC;AAAAA,IACZ,eAAeC;AAAAA,IACf,cAAcC;AAAAA,EAAQ;AAAA,EAExB,OAAO;AAAA,IACL,OAAOC;AAAAA,IACP,UAAUC;AAAAA,IACV,aAAaC;AAAAA,IACb,WAAWC;AAAAA,IACX,SAASC;AAAAA,EAAM;AAAA,EAEjB,SAAS;AAAA,IACP,WAAWC;AAAAA,IACX,QAAQC;AAAAA,IACR,MAAMC;AAAAA,IACN,UAAUC;AAAAA,IACV,SAASC;AAAAA,IACT,SAASC;AAAAA,IACT,QAAQC;AAAAA,IACR,MAAMC;AAAAA,IACN,cAAcC;AAAAA,EAAQ;AAAA,EAExB,UAAU7G;AACZ;AC3CO,SAAS8G,KAAY;AAC1B,QAAM/Q,IAAKH,EAAA,GACLI,IAAKH,EAAA;AAEX,SAAOI;AAAA,IACL,MAAM;AACJ,YAAM7D,IAAQ8D,GAA6BH,GAAIC,CAAE;AACjD,aAAO;AAAA,QACL,OAAA5D;AAAA,QACA,cAAc2C,EAAgB3C,CAAK;AAAA,QACnC,YAAY4C,GAAsB5C,CAAK;AAAA,QACvC,UAAU6C,EAAkB7C,CAAK;AAAA,QACjC,WAAWgD,GAAmBhD,CAAK;AAAA,QACnC,UAAUkD,GAAiBlD,CAAK;AAAA,QAChC,YAAYoD,GAAgBpD,CAAK;AAAA,QACjC,WAAWqD,GAAkBrD,CAAK;AAAA,QAClC,MAAM2D,EAAG;AAAA,QACT,OAAOA,EAAG;AAAA,QACV,iBAAiBA,EAAG;AAAA,QACpB,MAAMC,EAAG;AAAA,QACT,WAAWA,EAAG;AAAA,QACd,UAAUA,EAAG;AAAA,QACb,YAAYA,EAAG;AAAA,QACf,iBAAiBA,EAAG;AAAA,QACpB,MAAMD,EAAG;AAAA,QACT,MAAMA,EAAG;AAAA,QACT,eAAeA,EAAG;AAAA,QAClB,aAAaA,EAAG;AAAA,QAChB,eAAeA,EAAG;AAAA,QAClB,UAAUA,EAAG;AAAA,QACb,aAAaA,EAAG;AAAA,QAChB,eAAeA,EAAG;AAAA,QAClB,iBAAiBA,EAAG;AAAA,QACpB,MAAMA,EAAG;AAAA,QACT,UAAUC,EAAG;AAAA,QACb,UAAUD,EAAG;AAAA,MAAA;AAAA,IAEjB;AAAA,IACA,CAACA,GAAIC,CAAE;AAAA,EAAA;AAEX;"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
export type RepeatMode = "off" | "all" | "one";
|
|
3
|
+
/** Default control strings; override via `Ginger.Provider` `locale` prop. */
|
|
4
|
+
export type GingerLocaleMessages = {
|
|
5
|
+
seek: string;
|
|
6
|
+
volume: string;
|
|
7
|
+
playbackSpeed: string;
|
|
8
|
+
nextTrack: string;
|
|
9
|
+
previousTrack: string;
|
|
10
|
+
shuffle: string;
|
|
11
|
+
mute: string;
|
|
12
|
+
unmute: string;
|
|
13
|
+
play: string;
|
|
14
|
+
pause: string;
|
|
15
|
+
repeat: Record<RepeatMode, string>;
|
|
16
|
+
playbackRateNormal: string;
|
|
17
|
+
playbackRateTimes: (rate: number) => string;
|
|
18
|
+
};
|
|
3
19
|
export type Track = {
|
|
20
|
+
/** Optional stable identity for duplicate URLs / queue mutations */
|
|
21
|
+
id?: string;
|
|
4
22
|
title: string;
|
|
5
23
|
fileUrl: string;
|
|
6
24
|
artist?: string;
|
|
@@ -16,6 +34,8 @@ export type Track = {
|
|
|
16
34
|
lyrics?: string;
|
|
17
35
|
/** Hint before metadata loads; never overrides finite media duration */
|
|
18
36
|
durationSeconds?: number;
|
|
37
|
+
/** App-specific data for custom UI; not read by Ginger core */
|
|
38
|
+
metadata?: Record<string, unknown>;
|
|
19
39
|
};
|
|
20
40
|
export type PlaylistMeta = {
|
|
21
41
|
id?: string;
|
|
@@ -24,6 +44,8 @@ export type PlaylistMeta = {
|
|
|
24
44
|
artworkUrl?: string;
|
|
25
45
|
copyright?: string;
|
|
26
46
|
description?: string;
|
|
47
|
+
/** App-specific data for custom UI; not read by Ginger core */
|
|
48
|
+
metadata?: Record<string, unknown>;
|
|
27
49
|
};
|
|
28
50
|
export type PlaybackUiState = "idle" | "loading" | "playing" | "paused" | "ended" | "error";
|
|
29
51
|
export type GingerMediaSlice = {
|
|
@@ -141,6 +163,10 @@ export type GingerAction = {
|
|
|
141
163
|
muted: boolean;
|
|
142
164
|
};
|
|
143
165
|
};
|
|
166
|
+
/** Payload for `INIT` / `init()`; replaces queue and media timing like a fresh mount. */
|
|
167
|
+
export type GingerInitPayload = Extract<GingerAction, {
|
|
168
|
+
type: "INIT";
|
|
169
|
+
}>["payload"];
|
|
144
170
|
export type GingerProviderProps = {
|
|
145
171
|
children: ReactNode;
|
|
146
172
|
initialTracks?: Track[];
|
|
@@ -155,6 +181,13 @@ export type GingerProviderProps = {
|
|
|
155
181
|
initialMuted?: boolean;
|
|
156
182
|
/** Default 1; clamped ~0.25–4 on set */
|
|
157
183
|
initialPlaybackRate?: number;
|
|
184
|
+
/**
|
|
185
|
+
* When set, changing this value dispatches `INIT` with the **current** `initialTracks`, `initialIndex`,
|
|
186
|
+
* and other `initial*` props (same as calling `init()`). First paint still uses the reducer initializer only.
|
|
187
|
+
*/
|
|
188
|
+
initialStateKey?: string | number;
|
|
189
|
+
/** Override default English strings on built-in controls */
|
|
190
|
+
locale?: Partial<GingerLocaleMessages>;
|
|
158
191
|
className?: string;
|
|
159
192
|
style?: CSSProperties;
|
|
160
193
|
onTrackChange?: (track: Track | null, index: number) => void;
|