@ngxsp/core 0.0.1-next.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/default-config.ts","../src/engine/engine-factory.ts","../src/engine/native.engine.ts","../src/engine/native.factory.ts","../src/engine/engine-profile.ts","../src/engine/playback-capabilities.ts","../src/engine/capability-report.ts","../src/remote-config/remote-config.ts","../src/ports/storage.port.ts","../src/ports/telemetry.port.ts","../src/ports/log.port.ts","../src/ports/ports.ts","../src/facade/player-facade.ts","../src/plugins/metadata/providers/local-metadata.provider.ts","../src/plugins/subtitles/providers/local-subtitle.provider.ts","../src/utils/cache-store.ts","../src/commands.ts","../src/events/event-bus.ts","../src/plugins/progress/progress.plugin.ts","../src/plugins/resilience/resilience.plugin.ts","../src/plugins/ads/ssai.plugin.ts"],"names":["patch","merged","fetch","BehaviorSubject","Subject"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n AdsConfig,\n MetadataConfig,\n PlayerConfig,\n PlayerSource,\n ProgressConfig,\n ResilienceConfig,\n SubtitlesConfig,\n UiConfig,\n} from '../types';\n\n/**\n * Sensible, framework-agnostic defaults for the mandatory sub-configs of\n * {@link PlayerConfig}. They mirror the values used by the existing\n * consumers (local audio/video players) so a brand new integration can get a\n * valid config without restating every field.\n */\nexport const DEFAULT_PROGRESS_CONFIG: ProgressConfig = {\n mode: 'local',\n intervalSec: 5,\n};\n\nexport const DEFAULT_UI_CONFIG: UiConfig = {\n ratios: ['16:9'],\n defaultRatio: '16:9',\n keyboardShortcuts: true,\n};\n\nexport const DEFAULT_RESILIENCE_CONFIG: ResilienceConfig = {\n retries: 2,\n backoffMs: { min: 300, max: 1500 },\n};\n\nexport const DEFAULT_SUBTITLES_CONFIG: SubtitlesConfig = {\n enabled: false,\n providers: ['local'],\n};\n\nexport const DEFAULT_METADATA_CONFIG: MetadataConfig = {\n enabled: false,\n providers: ['local'],\n localSidecar: false,\n};\n\nexport const DEFAULT_ADS_CONFIG: AdsConfig = {\n enabled: false,\n mode: 'csai',\n};\n\n/**\n * Build a complete, type-safe {@link PlayerConfig} from a minimal set of\n * overrides. Only `source` is required; the mandatory sub-configs\n * (`progress`, `ui`, `resilience`, `subtitles`, `metadata`, `ads`) are filled\n * with the defaults above and shallow-merged with any override provided.\n *\n * Optional top-level fields (`profile`, `drm`, `series`, `playlist`,\n * `offline`, `remoteConfig`, ...) are passed through untouched when present.\n *\n * @example\n * ```ts\n * const config = createDefaultConfig({\n * source: { type: 'hls', url: 'https://cdn.example.com/movie.m3u8' },\n * drm: { keySystems: { 'com.widevine.alpha': { licenseServerUrl: 'https://drm/widevine' } } },\n * subtitles: { enabled: true, providers: ['local'], preferredLang: 'fr' },\n * });\n * ```\n */\nexport function createDefaultConfig(\n overrides: Partial<PlayerConfig> & { source: PlayerSource },\n): PlayerConfig {\n const {\n source,\n progress,\n ui,\n resilience,\n subtitles,\n metadata,\n ads,\n ...rest\n } = overrides;\n\n return {\n // Pass through every other (mostly optional) top-level field as provided:\n // profile, drm, series, playlist, playlistStartIndex, autoNext, offline,\n // remoteConfig, ...\n ...rest,\n source,\n progress: { ...DEFAULT_PROGRESS_CONFIG, ...progress },\n ui: { ...DEFAULT_UI_CONFIG, ...ui },\n resilience: {\n ...DEFAULT_RESILIENCE_CONFIG,\n ...resilience,\n backoffMs: {\n ...DEFAULT_RESILIENCE_CONFIG.backoffMs,\n ...resilience?.backoffMs,\n },\n },\n subtitles: { ...DEFAULT_SUBTITLES_CONFIG, ...subtitles },\n metadata: { ...DEFAULT_METADATA_CONFIG, ...metadata },\n ads: { ...DEFAULT_ADS_CONFIG, ...ads },\n };\n}\n","import type { PlayerConfig } from '../types';\nimport type { PlaybackEngine } from './playback-engine';\nimport type { PlaybackCapabilities } from './playback-capabilities';\n\nexport interface EngineFactory {\n /** Unique id (ex: 'native', 'shaka') */\n id: string;\n /** Higher priority wins when multiple support the same source. Default 0. */\n priority?: number;\n /** Whether this engine supports this config/source. */\n supports(config: PlayerConfig): boolean;\n /**\n * Optional, capability-aware selector.\n * If present, it is preferred over supports().\n */\n supportsWithCaps?: (config: PlayerConfig, caps: PlaybackCapabilities) => boolean;\n /** Create a new engine instance. */\n create(): PlaybackEngine;\n}\n\nexport function selectEngine(\n config: PlayerConfig,\n factories: EngineFactory[],\n caps?: PlaybackCapabilities\n): EngineFactory | null {\n const candidates = (factories ?? []).filter(f => {\n try {\n if (caps && typeof f.supportsWithCaps === 'function') return !!f.supportsWithCaps(config, caps);\n return !!f.supports(config);\n } catch {\n return false;\n }\n });\n if (candidates.length === 0) return null;\n candidates.sort((a,b) => (b.priority ?? 0) - (a.priority ?? 0));\n return candidates[0];\n}\n","import { PlaybackEngine, EngineEvent } from './playback-engine';\nimport { MediaTrack, PlayerSource } from '../types';\n\n\nfunction mimeFromUrl(url: string): string {\n try {\n const clean = url.split('?')[0].split('#')[0];\n const parts = clean.split('.');\n const ext = (parts.length > 1 ? parts.pop() : '')?.toLowerCase() || '';\n switch (ext) {\n case 'mp4': return 'video/mp4';\n case 'm4v': return 'video/x-m4v';\n case 'mov': return 'video/quicktime';\n case 'webm': return 'video/webm';\n case 'mkv': return 'video/x-matroska';\n case 'avi': return 'video/x-msvideo';\n case 'mpg':\n case 'mpeg': return 'video/mpeg';\n case 'ts': return 'video/mp2t';\n case 'ogv': return 'video/ogg';\n default: return '';\n }\n } catch {\n return '';\n }\n}\n\nexport class NativeEngine implements PlaybackEngine {\n public readonly id = 'native';\n private video?: HTMLVideoElement;\n private listeners: Array<(e: EngineEvent) => void> = [];\n\n async attach(videoEl: HTMLVideoElement): Promise<void> {\n this.video = videoEl;\n const v = videoEl;\n\n const emit = (e: EngineEvent) => this.listeners.forEach(l => l(e));\n\n v.addEventListener('timeupdate', () => emit({ type: 'timeupdate', currentTime: v.currentTime, duration: v.duration || 0 }));\n v.addEventListener('playing', () => emit({ type: 'state', state: 'playing' }));\n v.addEventListener('pause', () => emit({ type: 'state', state: 'paused' }));\n v.addEventListener('waiting', () => emit({ type: 'state', state: 'buffering' }));\n v.addEventListener('ended', () => emit({ type: 'state', state: 'ended' }));\n v.addEventListener('error', () => {\n const err = v.error;\n emit({\n type: 'error',\n error: { code: `HTML5_${err?.code ?? 'UNKNOWN'}`, message: err?.message ?? 'HTML5 video error', fatal: true, details: err }\n });\n });\n }\n\n async load(source: PlayerSource, opts?: { startTimeSec?: number }): Promise<void> {\n if (!this.video) throw new Error('NativeEngine not attached');\n const v = this.video;\n\n if (source.type === 'local-file') {\n if (!source.file) throw new Error('source.file is required');\n v.src = URL.createObjectURL(source.file);\n } else {\n if (!source.url) throw new Error('source.url is required');\n\n // For custom protocols (e.g. ngxsp-file://) Chromium sometimes refuses to infer\n // a playable type from the URL alone. Using a <source type=\"...\"> helps it pick\n // the right pipeline and avoids \"The element has no supported sources.\"\n const type = mimeFromUrl(source.url);\n while (v.firstChild) v.removeChild(v.firstChild);\n if (type) {\n const s = document.createElement('source');\n s.src = source.url;\n s.type = type;\n v.appendChild(s);\n v.removeAttribute('src');\n } else {\n v.src = source.url;\n }\n}\n\n await v.load();\n if (opts?.startTimeSec != null && isFinite(opts.startTimeSec)) {\n v.currentTime = Math.max(0, opts.startTimeSec);\n }\n }\n\n async destroy(): Promise<void> {\n if (!this.video) return;\n this.video.removeAttribute('src');\n this.video.load();\n this.video = undefined;\n this.listeners = [];\n }\n\n async play(): Promise<void> { await this.video?.play(); }\n async pause(): Promise<void> { this.video?.pause(); }\n async seekTo(timeSec: number): Promise<void> { if (this.video) this.video.currentTime = Math.max(0, timeSec); }\n async setPlaybackRate(rate: number): Promise<void> { if (this.video) this.video.playbackRate = rate; }\n async setVolume(volume: number): Promise<void> { if (this.video) this.video.volume = Math.min(1, Math.max(0, volume)); }\n\n async setTextTrack(_trackId: string | null): Promise<void> { /* native text tracks not managed here */ }\n async setAudioTrack(_trackId: string | null): Promise<void> { /* not supported in basic native impl */ }\n async setVideoTrack(_trackId: string | null): Promise<void> { /* not supported in basic native impl */ }\n\n async getTracks(): Promise<MediaTrack[]> { return []; }\n\n onEvent(cb: (ev: EngineEvent) => void): () => void {\n this.listeners.push(cb);\n return () => { this.listeners = this.listeners.filter(x => x !== cb); };\n }\n}\n","import type { EngineFactory } from './engine-factory';\nimport { NativeEngine } from './native.engine';\nimport type { PlayerConfig } from '../types';\n\nexport function createNativeEngineFactory(): EngineFactory {\n return {\n id: 'native',\n priority: 0,\n supports: (cfg: PlayerConfig) => {\n const drm = (cfg as any).drm ?? (cfg as any).source?.drm;\n if (drm?.required) return false;\n // Native engine for progressive/local urls\n const t = cfg.source.type;\n if (t === 'url' || t === 'local-file') return true;\n // also allow unknown as fallback, but avoid claiming HLS/DASH/DRM explicitly\n return false;\n },\n create: () => new NativeEngine()\n };\n}\n","import type { EngineProfileId, PlayerSource } from '../types';\n\n/**\n * High-level playback profiles.\n *\n * Goal: provide good defaults with *minimal configuration*.\n * Users can still override per-source hints via `source.abr`.\n */\nexport interface EngineProfileHints {\n /** Defaults applied only when the user did not specify `source.abr.*` */\n abr?: {\n maxHeight?: number;\n maxBandwidth?: number;\n };\n\n /** Shaka-specific streaming knobs (best-effort, ignored by non-shaka engines). */\n shakaStreaming?: {\n lowLatencyMode?: boolean;\n bufferingGoalSec?: number;\n rebufferingGoalSec?: number;\n };\n}\n\nexport function getEngineProfileHints(profile?: EngineProfileId): EngineProfileHints {\n switch (profile) {\n case 'tv':\n return {\n abr: {\n // Prefer higher quality by default.\n maxHeight: 2160\n },\n shakaStreaming: {\n bufferingGoalSec: 30,\n rebufferingGoalSec: 2\n }\n };\n case 'mobile':\n return {\n abr: {\n // Reasonable default for mobile data/CPU.\n maxHeight: 720\n },\n shakaStreaming: {\n bufferingGoalSec: 15,\n rebufferingGoalSec: 2\n }\n };\n case 'low-latency':\n return {\n abr: {\n // Avoid very high res by default (keeps latency predictable).\n maxHeight: 1080\n },\n shakaStreaming: {\n lowLatencyMode: true,\n bufferingGoalSec: 6,\n rebufferingGoalSec: 1\n }\n };\n case 'default':\n default:\n return {\n shakaStreaming: {\n bufferingGoalSec: 20,\n rebufferingGoalSec: 2\n }\n };\n }\n}\n\n/**\n * Apply profile defaults to a `PlayerSource` without overriding user-provided hints.\n *\n * This function is intentionally conservative: it only fills missing fields.\n */\nexport function applyEngineProfileToSource(source: PlayerSource, profile?: EngineProfileId): PlayerSource {\n const p: EngineProfileId = profile ?? 'default';\n const hints = getEngineProfileHints(p);\n\n const anySrc: any = source as any;\n const abrIn = (anySrc.abr ?? {}) as any;\n\n const abrOut: any = { ...abrIn };\n if (abrOut.maxHeight == null && hints.abr?.maxHeight != null) abrOut.maxHeight = hints.abr.maxHeight;\n if (abrOut.maxBandwidth == null && hints.abr?.maxBandwidth != null) abrOut.maxBandwidth = hints.abr.maxBandwidth;\n\n const out: any = {\n ...anySrc,\n // Expose profile to engines (optional).\n profile: p\n };\n\n if (Object.keys(abrOut).length) out.abr = abrOut;\n\n // Shaka streaming hints are carried on the source (optional).\n if (hints.shakaStreaming) {\n out._shakaStreaming = {\n ...(anySrc._shakaStreaming ?? {}),\n ...hints.shakaStreaming\n };\n }\n\n return out as PlayerSource;\n}\n","export interface PlaybackCapabilities {\n /** Browser has MediaSource (MSE). */\n mse: boolean;\n /** Browser has Encrypted Media Extensions (EME) API. */\n eme: boolean;\n /** True if navigator.mediaCapabilities is available. */\n mediaCapabilities: boolean;\n /** Whether basic HLS playback is possible via MSE/native. */\n hls: boolean;\n /** Whether basic DASH playback is possible via MSE. */\n dash: boolean;\n /** Progressive mp4/webm playback via <video src>. */\n progressive: boolean;\n /** Heuristic: support for at least one of common video codecs. */\n codecs: {\n mp4_h264: boolean;\n mp4_hevc: boolean;\n webm_vp9: boolean;\n webm_av1: boolean;\n };\n /** Known DRM key systems availability (best-effort). */\n drm: {\n widevine: boolean;\n playready: boolean;\n fairplay: boolean;\n };\n}\n\nexport function createDefaultCapabilities(): PlaybackCapabilities {\n return {\n mse: false,\n eme: false,\n mediaCapabilities: false,\n hls: false,\n dash: false,\n progressive: true,\n codecs: { mp4_h264: false, mp4_hevc: false, webm_vp9: false, webm_av1: false },\n drm: { widevine: false, playready: false, fairplay: false }\n };\n}\n\nexport async function detectPlaybackCapabilities(videoEl?: HTMLVideoElement): Promise<PlaybackCapabilities> {\n const caps = createDefaultCapabilities();\n\n const w = globalThis as any;\n caps.mse = !!w.MediaSource && typeof w.MediaSource.isTypeSupported === 'function';\n caps.eme = !!(w.navigator && w.navigator.requestMediaKeySystemAccess);\n caps.mediaCapabilities = !!(w.navigator && (w.navigator as any).mediaCapabilities);\n\n // Codec support (quick heuristic). Prefer MediaSource.isTypeSupported when available.\n const v = videoEl ?? (typeof document !== 'undefined' ? document.createElement('video') : undefined);\n const canPlay = (mime: string) => {\n try {\n if (caps.mse && w.MediaSource?.isTypeSupported) return !!w.MediaSource.isTypeSupported(mime);\n if (v && typeof v.canPlayType === 'function') return v.canPlayType(mime) !== '';\n return false;\n } catch {\n return false;\n }\n };\n\n caps.codecs.mp4_h264 = canPlay('video/mp4; codecs=\"avc1.42E01E\"');\n caps.codecs.mp4_hevc = canPlay('video/mp4; codecs=\"hvc1.1.6.L93.B0\"');\n caps.codecs.webm_vp9 = canPlay('video/webm; codecs=\"vp09.00.10.08\"');\n caps.codecs.webm_av1 = canPlay('video/webm; codecs=\"av01.0.05M.08\"');\n\n // HLS/DASH heuristics:\n // - DASH typically requires MSE.\n // - HLS can be native on Safari, otherwise usually requires MSE + JS player (Shaka/hls.js).\n caps.dash = caps.mse;\n caps.hls = canPlay('application/vnd.apple.mpegurl') || canPlay('application/x-mpegURL') || caps.mse;\n caps.progressive = caps.codecs.mp4_h264 || caps.codecs.webm_vp9 || caps.codecs.webm_av1 || true;\n\n // DRM availability (best-effort probes)\n if (caps.eme && w.navigator?.requestMediaKeySystemAccess) {\n const probe = async (ks: string) => {\n try {\n // minimal config; browsers may still reject.\n const cfg = [{\n initDataTypes: ['cenc'],\n audioCapabilities: [{ contentType: 'audio/mp4; codecs=\"mp4a.40.2\"' }],\n videoCapabilities: [{ contentType: 'video/mp4; codecs=\"avc1.42E01E\"' }]\n }];\n await w.navigator.requestMediaKeySystemAccess(ks, cfg);\n return true;\n } catch {\n return false;\n }\n };\n\n // Widevine\n caps.drm.widevine = await probe('com.widevine.alpha');\n // PlayReady\n caps.drm.playready = await probe('com.microsoft.playready');\n // FairPlay (Safari)\n caps.drm.fairplay = await probe('com.apple.fps.1_0');\n }\n\n return caps;\n}\n","import type { PlayerConfig } from '../types';\n\nexport interface CapabilityReport {\n timestamp: number;\n userAgent?: string;\n source?: {\n type?: string;\n live?: boolean;\n drm?: boolean;\n url?: string;\n contentId?: string;\n };\n platform: {\n isSecureContext: boolean;\n };\n features: {\n mse: boolean;\n eme: boolean;\n mediaCapabilities: boolean;\n };\n canPlay: Record<string, boolean>;\n /**\n * Optional, best-effort decoding probes via the MediaCapabilities API.\n *\n * Keys are stable labels (e.g. \"h264_1080p\").\n */\n mediaDecoding?: Record<string, { supported: boolean; smooth?: boolean; powerEfficient?: boolean }>;\n notes: string[];\n}\n\n/** Best-effort decoding probes used for diagnostics and ABR tuning hints. */\nexport async function createMediaDecodingReport(): Promise<CapabilityReport['mediaDecoding']> {\n const mc: any = (globalThis as any).navigator?.mediaCapabilities;\n if (!mc?.decodingInfo) return undefined;\n\n const mk = (contentType: string, width: number, height: number, bitrate: number) => ({\n type: 'media-source',\n video: { contentType, width, height, bitrate, framerate: 30 },\n audio: { contentType: 'audio/mp4; codecs=\"mp4a.40.2\"', channels: 2, bitrate: 128000, samplerate: 48000 }\n });\n\n const probes: Array<[string, any]> = [\n ['h264_720p', mk('video/mp4; codecs=\"avc1.64001f\"', 1280, 720, 2500000)],\n ['h264_1080p', mk('video/mp4; codecs=\"avc1.640028\"', 1920, 1080, 5000000)],\n ['vp9_1080p', mk('video/webm; codecs=\"vp09.00.51.08\"', 1920, 1080, 5000000)]\n ];\n\n const out: NonNullable<CapabilityReport['mediaDecoding']> = {};\n for (const [key, cfg] of probes) {\n try {\n const info = await mc.decodingInfo(cfg);\n out[key] = {\n supported: !!info?.supported,\n smooth: info?.smooth,\n powerEfficient: info?.powerEfficient\n };\n } catch {\n // ignore\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n\nfunction safeUa(): string | undefined {\n try { return (globalThis as any).navigator?.userAgent; } catch { return undefined; }\n}\n\nfunction canPlayType(videoEl: HTMLVideoElement | undefined, mime: string): boolean {\n try {\n const v = videoEl ?? (typeof document !== 'undefined' ? document.createElement('video') : undefined);\n if (!v || typeof v.canPlayType !== 'function') return false;\n return v.canPlayType(mime) !== '';\n } catch {\n return false;\n }\n}\n\nexport function createCapabilityReport(\n videoEl?: HTMLVideoElement,\n cfg?: PlayerConfig,\n mediaDecoding?: CapabilityReport['mediaDecoding']\n): CapabilityReport {\n const w = globalThis as any;\n const notes: string[] = [];\n\n const mse = !!w.MediaSource && typeof w.MediaSource.isTypeSupported === 'function';\n const eme = !!(w.navigator && w.navigator.requestMediaKeySystemAccess);\n const mediaCapabilities = !!(w.navigator && (w.navigator as any).mediaCapabilities);\n\n if (!mse) notes.push('MediaSource (MSE) not available');\n if (!eme) notes.push('Encrypted Media Extensions (EME) not available');\n\n const canPlay: Record<string, boolean> = {\n 'video/mp4; codecs=\"avc1.42E01E\"': canPlayType(videoEl, 'video/mp4; codecs=\"avc1.42E01E\"'),\n 'video/mp4; codecs=\"hvc1.1.6.L93.B0\"': canPlayType(videoEl, 'video/mp4; codecs=\"hvc1.1.6.L93.B0\"'),\n 'video/webm; codecs=\"vp09.00.10.08\"': canPlayType(videoEl, 'video/webm; codecs=\"vp09.00.10.08\"'),\n 'video/webm; codecs=\"av01.0.05M.08\"': canPlayType(videoEl, 'video/webm; codecs=\"av01.0.05M.08\"'),\n 'application/vnd.apple.mpegurl': canPlayType(videoEl, 'application/vnd.apple.mpegurl'),\n 'application/dash+xml': canPlayType(videoEl, 'application/dash+xml')\n };\n\n const secure = (() => {\n try { return !!(globalThis as any).isSecureContext; } catch { return false; }\n })();\n if (!secure) notes.push('Not running in a secure context (HTTPS). DRM and some APIs may fail.');\n\n const src = cfg?.source;\n const drmCfg = cfg ? ((cfg as any).drm ?? (src as any)?.drm) : undefined;\n const drmFlag = !!drmCfg;\n\n return {\n timestamp: Date.now(),\n userAgent: safeUa(),\n source: src ? {\n type: (src as any).type,\n live: (src as any).live,\n drm: drmFlag,\n url: (src as any).url,\n contentId: (src as any).contentId\n } : undefined,\n platform: { isSecureContext: secure },\n features: { mse, eme, mediaCapabilities },\n canPlay,\n mediaDecoding,\n notes\n };\n}\n","import type { PlayerPorts } from '../ports/ports';\nimport type { PlayerConfig, RemoteConfigConfig, RemoteConfigPayload } from '../types';\n\ntype CacheEntry = { ts: number; data: RemoteConfigPayload };\n\nconst DEFAULT_ALLOW = [\n 'profile',\n 'abr',\n 'resilience',\n 'drm',\n 'ads',\n 'ui',\n 'subtitles',\n 'metadata',\n 'progress',\n 'chapters',\n 'offline'\n];\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction deepMerge<T extends Record<string, any>>(base: T, patch: Record<string, any>): T {\n const out: any = { ...base };\n for (const [k, v] of Object.entries(patch)) {\n if (isPlainObject(v) && isPlainObject(out[k])) out[k] = deepMerge(out[k], v);\n else out[k] = v;\n }\n return out;\n}\n\nfunction shallowMerge<T extends Record<string, any>>(base: T, patch: Record<string, any>): T {\n return { ...(base as any), ...(patch as any) };\n}\n\nfunction hashKey(url: string): string {\n // Small deterministic key (no crypto dependency).\n let h = 0;\n for (let i = 0; i < url.length; i++) h = (h * 31 + url.charCodeAt(i)) >>> 0;\n return h.toString(16);\n}\n\nasync function readCache(storage: PlayerPorts['storage'] | undefined, key: string): Promise<CacheEntry | null> {\n if (!storage?.get) return null;\n const raw = await storage.get(key);\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as CacheEntry;\n if (!parsed || typeof parsed.ts !== 'number' || !isPlainObject(parsed.data)) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function writeCache(storage: PlayerPorts['storage'] | undefined, key: string, entry: CacheEntry): Promise<void> {\n if (!storage?.set) return;\n await storage.set(key, JSON.stringify(entry));\n}\n\nexport async function applyRemoteConfig(\n cfg: PlayerConfig,\n ports: Partial<PlayerPorts>\n): Promise<{ config: PlayerConfig; applied: boolean; payload?: RemoteConfigPayload; source: 'cache' | 'network' | 'none' }>\n{\n const rc = cfg.remoteConfig;\n if (!rc?.enabled) return { config: cfg, applied: false, source: 'none' };\n\n const url = rc.url;\n const ttlMs = Math.max(1, (rc.ttlSec ?? 300)) * 1000;\n const mode = rc.mode ?? 'deep';\n const allow = (rc.allow?.length ? rc.allow : DEFAULT_ALLOW) as string[];\n const cacheKey = `remoteConfig:${hashKey(url)}`;\n\n const now = Date.now();\n\n try {\n const cached = await readCache(ports.storage, cacheKey);\n if (cached && now - cached.ts < ttlMs) {\n const patch = filterAllowList(cached.data, allow);\n const merged = mode === 'shallow' ? shallowMerge(cfg as any, patch as any) : deepMerge(cfg as any, patch as any);\n return { config: merged, applied: true, payload: cached.data, source: 'cache' };\n }\n\n const fetch = ports.http?.fetch;\n if (!fetch) throw new Error('Remote config enabled but no ports.http.fetch provided');\n\n const res = await fetch(url, { method: 'GET', headers: { 'accept': 'application/json' } });\n if (!res.ok) throw new Error(`Remote config HTTP ${res.status}`);\n const json = (await res.json()) as unknown;\n if (!isPlainObject(json)) throw new Error('Remote config payload must be a JSON object');\n\n const payload = json as RemoteConfigPayload;\n await writeCache(ports.storage, cacheKey, { ts: now, data: payload });\n\n const patch = filterAllowList(payload, allow);\n const merged = mode === 'shallow' ? shallowMerge(cfg as any, patch as any) : deepMerge(cfg as any, patch as any);\n return { config: merged, applied: true, payload, source: 'network' };\n } catch (err) {\n ports.log?.warn?.('[ngxsp] remoteConfig failed', err);\n return { config: cfg, applied: false, source: 'none' };\n }\n}\n\nfunction filterAllowList(payload: RemoteConfigPayload, allow: string[]): RemoteConfigPayload {\n const out: RemoteConfigPayload = {};\n for (const k of allow) {\n if (Object.prototype.hasOwnProperty.call(payload, k)) out[k] = payload[k];\n }\n return out;\n}\n","export interface StoragePort {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n remove?(key: string): Promise<void>;\n}\n\nexport class MemoryStoragePort implements StoragePort {\n private map = new Map<string, string>();\n async get(key: string): Promise<string | null> { return this.map.get(key) ?? null; }\n async set(key: string, value: string): Promise<void> { this.map.set(key, value); }\n async remove(key: string): Promise<void> { this.map.delete(key); }\n}\n","export interface TelemetryPort {\n add(sample: Record<string, unknown>): void;\n export?(): unknown;\n}\n\nexport class NoopTelemetryPort implements TelemetryPort {\n add(_sample: Record<string, unknown>): void { /* noop */ }\n}\n","export interface LogPort {\n debug(...args: unknown[]): void;\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport class ConsoleLogPort implements LogPort {\n debug(...args: unknown[]): void { console.debug(...args); }\n info(...args: unknown[]): void { console.info(...args); }\n warn(...args: unknown[]): void { console.warn(...args); }\n error(...args: unknown[]): void { console.error(...args); }\n}\n","import type { HttpPort } from './http.port';\nimport type { StoragePort } from './storage.port';\nimport type { TelemetryPort } from './telemetry.port';\nimport type { LogPort } from './log.port';\nimport { MemoryStoragePort } from './storage.port';\nimport { NoopTelemetryPort } from './telemetry.port';\nimport { ConsoleLogPort } from './log.port';\n\nexport interface PlayerPorts {\n http: HttpPort;\n storage: StoragePort;\n telemetry: TelemetryPort;\n log: LogPort;\n}\n\nexport function createDefaultPorts(): PlayerPorts {\n const http: HttpPort = { fetch: (input, init) => fetch(input, init) };\n return {\n http,\n storage: new MemoryStoragePort(),\n telemetry: new NoopTelemetryPort(),\n log: new ConsoleLogPort()\n };\n}\n\nexport { MemoryStoragePort } from './storage.port';\nexport { NoopTelemetryPort } from './telemetry.port';\nexport { ConsoleLogPort } from './log.port';\n","import { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport {\n AspectRatioMode,\n MediaTrack,\n PlayerConfig,\n PlayerError,\n PlayerErrorCode,\n PlayerState,\n type DiagnosticsSnapshot,\n type DiagnosticsEngineInfo,\n type PlayerTime,\n type PlayerSource\n} from '../types';\nimport type { TelemetrySample, TelemetryEvent, TelemetryLevel } from '../telemetry/telemetry.types';\nimport { PlaybackEngine, EngineEvent, LoadOptions } from '../engine/playback-engine';\nimport type { EngineFactory } from '../engine/engine-factory';\nimport { selectEngine } from '../engine/engine-factory';\nimport { createNativeEngineFactory } from '../engine/native.factory';\nimport { applyEngineProfileToSource } from '../engine/engine-profile';\nimport { detectPlaybackCapabilities, type PlaybackCapabilities } from '../engine/playback-capabilities';\nimport { createCapabilityReport, createMediaDecodingReport, type CapabilityReport } from '../engine/capability-report';\nimport { applyRemoteConfig } from '../remote-config/remote-config';\nimport { PlayerPlugin, PlayerContext } from '../plugins/plugin';\nimport type { PlayerPorts } from '../ports/ports';\nimport { createDefaultPorts } from '../ports/ports';\nimport { VideoMetadata } from '../plugins/metadata/metadata.types';\n\nexport interface PlayerSnapshot {\n currentTime: number;\n duration: number;\n state: PlayerState;\n bufferedAheadSec: number;\n}\n\n/**\n * Public diagnostics payload.\n *\n * NOTE: This is intentionally an alias of `DiagnosticsSnapshot` to keep one\n * canonical shape exported by `@ngxsp/core`.\n */\nexport type PlayerDiagnostics = DiagnosticsSnapshot;\n\nexport class PlayerFacade {\n private engineFactories: EngineFactory[] = [createNativeEngineFactory()];\n private engineId = 'native';\n private lastNonFatal: PlayerError | null = null;\n\n // Optional MediaCapabilities decoding probes (async, best-effort)\n private mediaDecodingSub = new BehaviorSubject<CapabilityReport['mediaDecoding'] | null>(null);\n private video?: HTMLVideoElement;\n private engine?: PlaybackEngine;\n private plugins: PlayerPlugin[] = [];\n private ctx?: PlayerContext;\n\n private stateSub = new BehaviorSubject<PlayerState>({ kind: 'idle' });\n private timeSub = new BehaviorSubject<{ currentTime: number; duration: number }>({ currentTime: 0, duration: 0 });\n private bufferSub = new BehaviorSubject<number>(0);\n private tracksSub = new BehaviorSubject<MediaTrack[]>([]);\n private errorSub = new Subject<PlayerError>();\n private metadataSub = new BehaviorSubject<VideoMetadata | null>(null);\n\n private capsSub = new BehaviorSubject<PlaybackCapabilities | null>(null);\n readonly capabilities$ = this.capsSub.asObservable();\n\n readonly state$ = this.stateSub.asObservable();\n readonly time$ = this.timeSub.asObservable();\n readonly bufferAheadSec$ = this.bufferSub.asObservable();\n readonly tracks$ = this.tracksSub.asObservable();\n readonly error$ = this.errorSub.asObservable();\n readonly metadata$ = this.metadataSub.asObservable();\n\n private seriesIndexSub = new BehaviorSubject<number | null>(null);\n readonly seriesIndex$ = this.seriesIndexSub.asObservable();\n\n private playlistIndexSub = new BehaviorSubject<number | null>(null);\n readonly playlistIndex$ = this.playlistIndexSub.asObservable();\n private playlist: import('../types').PlayerSource[] = [];\n private playlistKey = '';\n\n private externalVttUrl?: string;\n\n constructor(private ports: PlayerPorts = createDefaultPorts()) {}\n\n\nattach(videoEl: HTMLVideoElement, plugins: PlayerPlugin[] = [], config: PlayerConfig, ports?: Partial<PlayerPorts>, engines?: EngineFactory[]): void {\n // merge ports\n if (ports) {\n this.ports = { ...this.ports, ...ports } as any;\n }\n // Engines registry: always keep native engine as fallback to avoid breaking progressive/local playback.\n if (engines && engines.length) {\n this.engineFactories = [createNativeEngineFactory(), ...engines];\n } else {\n this.engineFactories = [createNativeEngineFactory()];\n }\n this.video = videoEl;\n this.plugins = plugins ?? [];\n this.ctx = { config, facade: this, ports: this.ports, contentId: config.source.contentId };\n\n // Capability probe (async; used for engine selection + better diagnostics).\n void detectPlaybackCapabilities(videoEl)\n .then(c => this.capsSub.next(c))\n .catch(() => this.capsSub.next(null));\n\n // MediaCapabilities decoding probes (async; best-effort; used for diagnostics/ABR hints).\n void createMediaDecodingReport()\n .then(r => this.mediaDecodingSub.next(r ?? null))\n .catch(() => this.mediaDecodingSub.next(null));\n this.emitTelemetry('player:attach','info');\n this.emitTelemetry('player:source_set','info',{ type: config.source.type, live: config.source.live });\n\n this.installVideoEventListeners();\n\n // init plugins\n for (const p of this.plugins) {\n try { void p.onInit?.(this.ctx); } catch { /* noop */ }\n }\n}\n\nasync load(config: PlayerConfig, opts?: LoadOptions): Promise<void> {\n if (!this.video) throw new Error('PlayerFacade not attached');\n if (!this.ctx) throw new Error('PlayerFacade context missing');\n\n // Remote control-plane (feature flags / tuning / profiles) – applied before engine/plugin decisions.\n const rc = await applyRemoteConfig(config, this.ports);\n if (rc.applied) {\n this.ports.telemetry?.add?.({\n event: 'remote_config:applied' as any,\n level: 'info',\n ts: Date.now(),\n data: { source: rc.source, url: config.remoteConfig?.url }\n } as any);\n config = rc.config;\n }\n\n // Normalize playlist (v1.7.1)\n const list = config.playlist ?? [];\n if (list.length > 0) {\n const key = list.map(s => (s.contentId ?? s.url ?? (s as any).filePath ?? '')).join('|');\n if (key !== this.playlistKey) {\n this.playlistKey = key;\n this.playlist = list;\n const startIdx = config.playlistStartIndex ?? 0;\n this.playlistIndexSub.next(Math.max(0, Math.min(startIdx, list.length - 1)));\n }\n if (opts?.playlistIndex != null) {\n this.playlistIndexSub.next(Math.max(0, Math.min(opts.playlistIndex, list.length - 1)));\n }\n const idx = this.playlistIndexSub.value ?? 0;\n const src = list[idx] ?? config.source;\n config = { ...config, source: src, autoNext: config.autoNext ?? true };\n this.emitTelemetry('player:playlist_index', 'info', { index: idx, total: list.length });\n }\n\n this.ctx.config = config;\n this.ctx.contentId = config.source.contentId;\n this.emitTelemetry('player:load_start','info');\n try {\n const now = (globalThis.performance?.now?.() ?? Date.now());\n this.qoe.loadStartMs = now;\n this.qoe.firstFrameMs = 0;\n this.qoe.startupMs = 0;\n this.qoe.rebufferCount = 0;\n this.qoe.rebufferMs = 0;\n this.qoe.rebufferStartMs = 0;\n this.qoe.firstFrameEmitted = false;\n } catch {}\n\n for (const p of this.plugins) {\n try { await p.onLoadStart?.(this.ctx); } catch { /* noop */ }\n }\n\n // (re)create engine\n if (this.engine) {\n try { await this.engine.destroy(); } catch {}\n this.engine = undefined;\n }\n\n const caps = this.capsSub.value ?? undefined;\n const chosen = selectEngine(config, this.engineFactories, caps);\n if (!chosen) {\n const detail = { source: config.source, caps };\n this.emitFatal(new Error(`No engine registered for this source: ${JSON.stringify(detail)}`), 'ENGINE_MISSING');\n throw new Error('ENGINE_MISSING');\n }\n const engine = chosen.create();\n\n this.engine = engine;\n this.engineId = (engine as any).id ?? (engine.constructor?.name ?? 'engine');\n this.emitTelemetry('player:engine_selected','info',{ engineId: this.engineId });\n\n await engine.attach(this.video);\n\n const off = engine.onEvent(ev => this.handleEngineEvent(ev));\n (this as any)._offEngine = off;\n\n const startTime = opts?.startTimeSec;\n // Merge DRM from config onto the source so engines can stay \"source-only\".\n const sourceWithDrm = applyEngineProfileToSource(\n {\n ...config.source,\n drm: (config as any).drm ?? (config.source as any).drm,\n profile: (config as any).profile ?? (config.source as any).profile\n } as any,\n (config as any).profile ?? (config.source as any).profile\n ) as any;\n try {\n await engine.load(sourceWithDrm, { startTimeSec: startTime ?? undefined });\n this.stateSub.next({ kind: 'paused' });\n this.emitTelemetry('player:load_ok','info');\n } catch (err) {\n this.emitTelemetry('player:load_fail','error',{}, (err as any)?.message);\n this.emitFatal(err, 'UNKNOWN');\n throw err;\n }\n\n // notify plugins loaded\n for (const p of this.plugins) {\n try { await p.onLoaded?.(this.ctx); } catch { /* noop */ }\n }\n}\n\nasync reload(opts?: LoadOptions): Promise<void> {\n if (!this.ctx) throw new Error('PlayerFacade context missing');\n const snap = this.snapshot();\n const start = opts?.startTimeSec ?? snap.currentTime ?? 0;\n await this.load(this.ctx.config, { startTimeSec: start });\n}\n\nasync next(): Promise<void> {\n if (!this.ctx) return;\n const cfg = this.ctx.config;\n const list = cfg.playlist ?? this.playlist;\n if (!list || list.length === 0) return;\n const idx = (this.playlistIndexSub.value ?? 0) + 1;\n if (idx >= list.length) return;\n await this.load(cfg, { playlistIndex: idx, startTimeSec: 0 });\n}\n\nasync previous(): Promise<void> {\n if (!this.ctx) return;\n const cfg = this.ctx.config;\n const list = cfg.playlist ?? this.playlist;\n if (!list || list.length === 0) return;\n const idx = (this.playlistIndexSub.value ?? 0) - 1;\n if (idx < 0) return;\n await this.load(cfg, { playlistIndex: idx, startTimeSec: 0 });\n}\n\n\nasync destroy(): Promise<void> {\n try {\n for (const p of this.plugins) {\n try { await p.onDestroy?.(this.ctx!); } catch { /* noop */ }\n }\n } finally {\n try { (this as any)._offEngine?.(); } catch {}\n try { await this.engine?.destroy(); } catch {}\n this.engine = undefined;\n this.video = undefined;\n this.ctx = undefined;\n this.plugins = [];\n this.emitTelemetry('player:init','debug',{ destroyed: true });\n }\n}\n\n/** Emit a non-fatal error (does not transition to fatal error state). */\npublic emitNonFatal(err: unknown, code: PlayerErrorCode | string = 'UNKNOWN'): void {\n const pe = this.toPlayerError(err, false, code);\n this.lastNonFatal = pe;\n this.emitTelemetry('player:error_nonfatal', 'warn', { code: pe.code }, pe.message);\n // let plugins observe if they subscribe to error$ externally\n this.errorSub.next(pe);\n}\n\n/** Emit a fatal error (transitions to error state). */\nprivate emitFatal(err: unknown, code: PlayerErrorCode | string = 'UNKNOWN'): void {\n const pe = this.toPlayerError(err, true, code);\n this.emitTelemetry('player:error_fatal', 'error', { code: pe.code }, pe.message);\n this.stateSub.next({ kind: 'error', error: pe });\n this.errorSub.next(pe);\n // notify plugins\n if (this.ctx) {\n for (const p of this.plugins) {\n try { void p.onError?.(this.ctx, pe); } catch { /* noop */ }\n }\n }\n}\n\nprivate async tryAutoNext(): Promise<void> {\n if (!this.ctx) return;\n const cfg = this.ctx.config;\n const list = cfg.playlist ?? this.playlist;\n if (!list || list.length === 0) return;\n const auto = cfg.autoNext ?? true;\n if (!auto) return;\n const idx = this.playlistIndexSub.value ?? 0;\n if (idx >= list.length - 1) return;\n\n const nextIdx = idx + 1;\n this.emitTelemetry('player:auto_next','info',{ from: idx, to: nextIdx, total: list.length });\n try {\n await this.load(cfg, { playlistIndex: nextIdx, startTimeSec: 0 });\n } catch {\n // handled by load\n }\n}\n\n\nprivate installed = false;\n\n // QoE metrics (v1.7)\n private qoe = {\n loadStartMs: 0,\n firstFrameMs: 0,\n startupMs: 0,\n rebufferCount: 0,\n rebufferMs: 0,\n rebufferStartMs: 0 as number | 0,\n firstFrameEmitted: false\n };\nprivate installVideoEventListeners(): void {\n const v = this.video;\n if (!v || this.installed) return;\n this.installed = true;\n\n const nowMs = () => (globalThis.performance?.now?.() ?? Date.now());\n\n const maybeFirstFrame = () => {\n if (this.qoe.firstFrameEmitted) return;\n const t = nowMs();\n this.qoe.firstFrameMs = t;\n if (this.qoe.loadStartMs) this.qoe.startupMs = Math.max(0, t - this.qoe.loadStartMs);\n this.qoe.firstFrameEmitted = true;\n this.emitTelemetry('qoe:first_frame','info', { firstFrameMs: this.qoe.startupMs });\n };\n\n const maybeEndRebuffer = () => {\n if (!this.qoe.rebufferStartMs) return;\n const t = nowMs();\n const delta = Math.max(0, t - this.qoe.rebufferStartMs);\n this.qoe.rebufferMs += delta;\n this.qoe.rebufferStartMs = 0;\n this.emitTelemetry('qoe:rebuffer_end','debug', { deltaMs: delta, totalMs: this.qoe.rebufferMs, count: this.qoe.rebufferCount });\n };\n\n v.addEventListener('timeupdate', () => {\n this.emitTelemetry('player:timeupdate', 'debug', { t: v.currentTime, d: v.duration });\n });\n\nv.addEventListener('loadeddata', () => {\n // First frame decoded (often the best proxy)\n maybeFirstFrame();\n});\n\nv.addEventListener('playing', () => {\n // Playback actually started\n maybeFirstFrame();\n maybeEndRebuffer();\n this.emitTelemetry('player:playing', 'info');\n});\n\nv.addEventListener('waiting', () => {\n // Rebuffering\n if (!this.qoe.rebufferStartMs) {\n this.qoe.rebufferCount += 1;\n this.qoe.rebufferStartMs = nowMs();\n this.emitTelemetry('qoe:rebuffer_start','debug', { count: this.qoe.rebufferCount });\n }\n});\n\nv.addEventListener('stalled', () => {\n if (!this.qoe.rebufferStartMs) {\n this.qoe.rebufferCount += 1;\n this.qoe.rebufferStartMs = nowMs();\n this.emitTelemetry('qoe:rebuffer_start','debug', { count: this.qoe.rebufferCount, reason: 'stalled' });\n }\n});\n\n\n v.addEventListener('ended', () => {\n maybeEndRebuffer();\n this.emitTelemetry('player:ended', 'info');\n this.emitTelemetry('qoe:summary','info', { startupMs: this.qoe.startupMs, rebufferCount: this.qoe.rebufferCount, rebufferMs: this.qoe.rebufferMs });\n void this.tryAutoNext();\n });\n\n v.addEventListener('pause', () => {\n this.emitTelemetry('player:pause', 'info');\n });\n\n v.addEventListener('error', () => {\n const me = v.error;\n if (!me) return;\n const codeMap: Record<number, PlayerErrorCode> = {\n 1: 'UNKNOWN',\n 2: 'NETWORK_HTTP',\n 3: 'DECODE_ERROR',\n 4: 'SRC_NOT_SUPPORTED'\n };\n const c = codeMap[me.code] ?? 'UNKNOWN';\n this.emitFatal(me, c);\n });\n}\n\nprivate emitTelemetry(event: TelemetryEvent, level: TelemetryLevel = 'info', data?: Record<string, unknown>, message?: string): void {\n try {\n const cfg = this.ctx?.config;\n const contentId = cfg?.source?.contentId;\n const sample: TelemetrySample = {\n ts: Date.now(),\n level,\n event,\n contentId,\n engineId: this.engineId,\n message,\n data\n };\n this.ports.telemetry.add(sample as any);\n } catch { /* noop */ }\n}\n\nprivate toPlayerError(err: unknown, fatal: boolean, code: PlayerErrorCode | string = 'UNKNOWN'): PlayerError {\n const e: any = err as any;\n const msg = e?.message ? String(e.message) : String(err ?? 'Unknown error');\n return { code, message: msg, fatal, details: e };\n}\n async play(): Promise<void> {\n this.emitTelemetry('player:play_request','info');\n try {\n await this.engine?.play();\n this.emitTelemetry('player:play_ok','info');\n } catch (err) {\n const name = (err as any)?.name;\n if (name === 'NotAllowedError') {\n this.emitNonFatal(err, 'AUTOPLAY_BLOCKED');\n this.emitTelemetry('player:play_fail','warn',{ code: 'AUTOPLAY_BLOCKED' }, (err as any)?.message);\n } else {\n this.emitFatal(err, 'UNKNOWN');\n this.emitTelemetry('player:play_fail','error',{ code: 'UNKNOWN' }, (err as any)?.message);\n }\n throw err;\n }\n }\n async pause(): Promise<void> { await this.engine?.pause(); }\n async seekTo(timeSec: number): Promise<void> { await this.engine?.seekTo(timeSec); }\n async setRate(rate: number): Promise<void> { await this.engine?.setPlaybackRate(rate); }\n async setVolume(volume: number): Promise<void> { await this.engine?.setVolume(volume); }\n\n async setTextTrack(trackId: string | null): Promise<void> {\n if (trackId === 'external') {\n // handled by external VTT injection\n if (this.video && this.externalVttUrl) {\n this.ensureExternalTrack(this.externalVttUrl);\n }\n return;\n }\n await this.engine?.setTextTrack(trackId);\n }\n async setAudioTrack(trackId: string | null): Promise<void> { await this.engine?.setAudioTrack(trackId); }\n async setVideoTrack(trackId: string | null): Promise<void> { await this.engine?.setVideoTrack(trackId); }\n\n // UI helpers\n setAspectRatio(_mode: AspectRatioMode): void {\n // UI component controls CSS class; facade keeps it as state if needed in your app.\n }\n\n snapshot(): PlayerSnapshot {\n const time = this.timeSub.value;\n return {\n currentTime: time.currentTime,\n duration: time.duration,\n state: this.stateSub.value,\n bufferedAheadSec: this.bufferSub.value\n };\n }\n\n /**\n * Diagnostics helper for UI / support logs.\n * Safe to call anytime after attach().\n */\n diagnostics(): PlayerDiagnostics {\n const snap = this.snapshot();\n const bufferedEnd = (snap.currentTime ?? 0) + (snap.bufferedAheadSec ?? 0);\n const time: PlayerTime = {\n currentTime: snap.currentTime,\n duration: snap.duration,\n bufferedEnd\n };\n const engine: DiagnosticsEngineInfo = {\n id: this.engine?.id ?? 'none',\n selectedBy: 'supports',\n reasons: []\n };\n const source = (this.ctx?.config as any)?.source as PlayerSource | undefined;\n return {\n ts: Date.now(),\n engine,\n capabilities: createCapabilityReport(\n this.video ?? undefined,\n this.ctx?.config,\n this.mediaDecodingSub.value ?? undefined\n ),\n source,\n state: snap.state,\n time,\n lastNonFatal: this.lastNonFatal,\n\n // backward compat\n selectedEngineId: engine.id,\n snapshot: {\n currentTime: snap.currentTime,\n duration: snap.duration,\n state: snap.state,\n bufferedAheadSec: snap.bufferedAheadSec\n }\n };\n }\n\n // External tracks (for provider-based subtitles)\n async setExternalVttTrack(lang: string, vtt: string): Promise<void> {\n if (!this.video) return;\n const blob = new Blob([vtt], { type: 'text/vtt' });\n this.externalVttUrl = URL.createObjectURL(blob);\n this.ensureExternalTrack(this.externalVttUrl, lang);\n }\n\n setMetadata(meta: VideoMetadata): void { this.metadataSub.next(meta); }\n\n private ensureExternalTrack(url: string, lang: string = 'und'): void {\n if (!this.video) return;\n // Remove prior external track\n const prev = this.video.querySelector('track[data-external=\"true\"]');\n if (prev) prev.remove();\n\n const track = document.createElement('track');\n track.kind = 'subtitles';\n track.label = `External (${lang})`;\n track.srclang = lang;\n track.src = url;\n track.default = true;\n track.setAttribute('data-external', 'true');\n\n this.video.appendChild(track);\n }\n\n private handleEngineEvent(ev: EngineEvent): void {\n if (ev.type === 'timeupdate') {\n this.timeSub.next({ currentTime: ev.currentTime, duration: ev.duration });\n return;\n }\n if (ev.type === 'bufferupdate') {\n this.bufferSub.next(ev.bufferedAheadSec);\n return;\n }\n if (ev.type === 'tracks') {\n this.tracksSub.next(ev.tracks);\n return;\n }\n if (ev.type === 'state') {\n const map: Record<string, PlayerState> = {\n loading: { kind: 'loading' },\n buffering: { kind: 'buffering' },\n playing: { kind: 'playing' },\n paused: { kind: 'paused' },\n ended: { kind: 'ended' }\n };\n this.stateSub.next(map[ev.state] ?? { kind: 'idle' });\n try { this.ctx?.ports.telemetry.add({ t: Date.now(), kind: 'state', state: ev.state }); } catch { /* ignore */ }\n if (ev.state === 'ended') void this.tryAutoNext();\n return;\n }\n if (ev.type === 'error') {\n const pe: PlayerError = { code: ev.error.code, message: ev.error.message, fatal: ev.error.fatal, details: ev.error.details };\n this.stateSub.next({ kind: 'error', error: pe });\n this.errorSub.next(pe);\n try { this.ctx?.ports.telemetry.add({ t: Date.now(), kind: 'error', code: pe.code, fatal: !!pe.fatal }); } catch { /* ignore */ }\n if (this.ctx) for (const p of this.plugins) void p.onError?.(this.ctx, pe);\n return;\n }\n }\n\n private async tryRestoreStartTime(_config: PlayerConfig): Promise<number | null> {\n // Start time can be injected by ProgressPlugin through ctx.facade.seekTo after load.\n // Here we keep it null; the plugin may seek during onLoaded().\n return null;\n }\n}\n","import { MetadataProvider, MetadataHint, MetadataMatch, VideoMetadata } from '../metadata.types';\n\n/**\n * Local provider: loads sidecar metadata from a URL (json or txt).\n * - JSON: parsed into `VideoMetadata` where possible\n * - TXT: stored as description\n */\nexport class LocalMetadataProvider implements MetadataProvider {\n id = 'local';\n\n async match(_hint: MetadataHint): Promise<MetadataMatch[]> {\n // Match is resolved by the plugin using sidecar URL; nothing to match here.\n return [];\n }\n\n async fetch(id: string): Promise<VideoMetadata> {\n // Here `id` is expected to be a URL in the local provider.\n const res = await fetch(id);\n if (!res.ok) throw new Error(`Metadata fetch failed: ${res.status}`);\n const ct = res.headers.get('content-type') ?? '';\n const text = await res.text();\n\n if (ct.includes('application/json') || looksLikeJson(text)) {\n try { return JSON.parse(text) as VideoMetadata; } catch { /* fallthrough */ }\n }\n return { description: text };\n }\n}\n\nfunction looksLikeJson(t: string): boolean {\n const s = t.trim();\n return (s.startsWith('{') && s.endsWith('}')) || (s.startsWith('[') && s.endsWith(']'));\n}\n","import { SubtitleProvider, SubtitleCandidate, SubtitleQuery } from '../subtitles.types';\n\n/**\n * Local provider: uses `config.source.sidecar.subtitles` entries as candidates.\n */\nexport class LocalSubtitleProvider implements SubtitleProvider {\n id = 'local';\n\n async search(query: SubtitleQuery): Promise<SubtitleCandidate[]> {\n // This provider doesn't search globally. The plugin will pass sidecar items directly.\n return [];\n }\n\n async fetch(candidate: SubtitleCandidate): Promise<string | ArrayBuffer> {\n if (!candidate.url) throw new Error('LocalSubtitleProvider: candidate.url is required');\n const res = await fetch(candidate.url);\n if (!res.ok) throw new Error(`Subtitle fetch failed: ${res.status}`);\n return await res.text();\n }\n}\n","export interface CacheStore {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T, ttlMs: number): Promise<void>;\n del(key: string): Promise<void>;\n}\n\nexport class DefaultCacheStore implements CacheStore {\n private dbp: Promise<IDBDatabase | null> | null = null;\n\n async get<T>(key: string): Promise<T | null> {\n const db = await this.db();\n if (db) return idbGet<T>(db, key);\n return lsGet<T>(key);\n }\n\n async set<T>(key: string, value: T, ttlMs: number): Promise<void> {\n const payload = { value, exp: Date.now() + ttlMs };\n const db = await this.db();\n if (db) return idbSet(db, key, payload);\n lsSet(key, payload);\n }\n\n async del(key: string): Promise<void> {\n const db = await this.db();\n if (db) return idbDel(db, key);\n localStorage.removeItem(key);\n }\n\n private db(): Promise<IDBDatabase | null> {\n if (typeof indexedDB === 'undefined') return Promise.resolve(null);\n if (!this.dbp) this.dbp = openDb();\n return this.dbp;\n }\n}\n\nconst DB_NAME = 'ngx-smart-player-cache';\nconst STORE = 'kv';\n\nfunction openDb(): Promise<IDBDatabase | null> {\n return new Promise((resolve) => {\n const req = indexedDB.open(DB_NAME, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE);\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => resolve(null);\n });\n}\n\nasync function idbGet<T>(db: IDBDatabase, key: string): Promise<T | null> {\n return new Promise((resolve) => {\n const tx = db.transaction(STORE, 'readonly');\n const st = tx.objectStore(STORE);\n const req = st.get(key);\n req.onsuccess = () => {\n const v = req.result;\n if (!v) return resolve(null);\n if (v.exp && Date.now() > v.exp) return resolve(null);\n resolve(v.value as T);\n };\n req.onerror = () => resolve(null);\n });\n}\n\nasync function idbSet(db: IDBDatabase, key: string, val: any): Promise<void> {\n return new Promise((resolve) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).put(val, key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n });\n}\n\nasync function idbDel(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).delete(key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n });\n}\n\nfunction lsGet<T>(key: string): T | null {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n try {\n const v = JSON.parse(raw);\n if (v?.exp && Date.now() > v.exp) return null;\n return (v?.value as T) ?? null;\n } catch { return null; }\n}\n\nfunction lsSet(key: string, val: any): void {\n try { localStorage.setItem(key, JSON.stringify(val)); } catch {}\n}\n","export type PlayerCommand =\n | { type: 'play' }\n | { type: 'pause' }\n | { type: 'toggle' }\n | { type: 'seek'; to: number }\n | { type: 'setPlaybackRate'; rate: number }\n | { type: 'setVolume'; volume: number }\n | { type: 'setMuted'; muted: boolean }\n | { type: 'selectTextTrack'; id: string }\n | { type: 'disableTextTrack' }\n | { type: 'selectAudioTrack'; id: string }\n | { type: 'requestPiP' }\n | { type: 'exitPiP' }\n | { type: 'requestFullscreen' }\n | { type: 'exitFullscreen' }\n | { type: 'requestCast' }\n | { type: 'stopCast' };\n\nexport function isCategorizedEventType(type: string): boolean {\n return /^(playback|engine|network|drm|ads|subtitles|ui):/.test(type);\n}\n","import type { PlayerEvent } from '../types';\n\nexport type Unsubscribe = () => void;\n\nexport interface PlayerEventBus {\n emit(event: PlayerEvent): void;\n on<T extends PlayerEvent['type']>(\n type: T,\n handler: (e: Extract<PlayerEvent, { type: T }>) => void\n ): Unsubscribe;\n}\n\nexport class SimpleEventBus implements PlayerEventBus {\n private handlers = new Map<string, Set<(e: any) => void>>();\n\n emit(event: PlayerEvent): void {\n const set = this.handlers.get(event.type);\n if (!set) return;\n for (const h of Array.from(set)) h(event as any);\n }\n\n on<T extends PlayerEvent['type']>(type: T, handler: (e: Extract<PlayerEvent, { type: T }>) => void): Unsubscribe {\n const set = this.handlers.get(type) ?? new Set();\n set.add(handler as any);\n this.handlers.set(type, set);\n return () => set.delete(handler as any);\n }\n}\n","import type { PlayerPlugin, PlayerContext } from '../plugin';\n\ninterface ProgressRecord {\n contentId: string;\n positionSec: number;\n updatedAt: number;\n durationSec?: number;\n}\n\nfunction keyFor(contentId: string): string {\n return `progress:${contentId}`;\n}\n\nexport class ProgressPlugin implements PlayerPlugin {\n readonly id = 'progress';\n private timer: any = null;\n\n async onLoadStart(ctx: PlayerContext): Promise<void> {\n this.stop();\n // nothing else; restore happens onLoaded (engine ready)\n }\n\n async onLoaded(ctx: PlayerContext): Promise<void> {\n const contentId = ctx.contentId ?? ctx.config.source.contentId;\n if (!contentId) return;\n\n // Restore (local)\n try {\n if (ctx.config.progress.mode === 'local' || ctx.config.progress.mode === 'hybrid') {\n const raw = await ctx.ports.storage.get(keyFor(contentId));\n if (raw) {\n const rec = JSON.parse(raw) as ProgressRecord;\n if (Number.isFinite(rec.positionSec) && rec.positionSec > 0) {\n // seek after load\n await ctx.facade.seekTo(rec.positionSec);\n }\n }\n }\n } catch (e) {\n ctx.ports.log.warn('[ProgressPlugin] restore failed', e);\n }\n\n // Start periodic save\n const intervalMs = Math.max(3, ctx.config.progress.intervalSec ?? 10) * 1000;\n this.timer = setInterval(() => void this.save(ctx), intervalMs);\n }\n\n async onDestroy(ctx: PlayerContext): Promise<void> {\n this.stop();\n // final save\n await this.save(ctx);\n }\n\n private stop(): void {\n if (this.timer) { clearInterval(this.timer); this.timer = null; }\n }\n\n private async save(ctx: PlayerContext): Promise<void> {\n const contentId = ctx.contentId ?? ctx.config.source.contentId;\n if (!contentId) return;\n\n const snap = ctx.facade.snapshot();\n const positionSec = Math.max(0, snap.currentTime);\n const rec: ProgressRecord = {\n contentId,\n positionSec,\n durationSec: snap.duration || undefined,\n updatedAt: Date.now()\n };\n\n // Local storage\n try {\n if (ctx.config.progress.mode === 'local' || ctx.config.progress.mode === 'hybrid') {\n await ctx.ports.storage.set(keyFor(contentId), JSON.stringify(rec));\n }\n } catch (e) {\n ctx.ports.log.warn('[ProgressPlugin] local save failed', e);\n }\n\n // Server persistence (best-effort)\n try {\n if ((ctx.config.progress.mode === 'server' || ctx.config.progress.mode === 'hybrid') && ctx.config.progress.endpoint) {\n await ctx.ports.http.fetch(ctx.config.progress.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(rec)\n });\n }\n } catch (e) {\n ctx.ports.log.warn('[ProgressPlugin] server save failed', e);\n }\n }\n}\n","import type { PlayerPlugin, PlayerContext } from '../plugin';\nimport type { PlayerError } from '../../types';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nexport class ResiliencePlugin implements PlayerPlugin {\n readonly id = 'resilience';\n private attempts = 0;\n private recovering = false;\n\n async onLoadStart(ctx: PlayerContext): Promise<void> {\n this.attempts = 0;\n this.recovering = false;\n // optional health check at load\n if (ctx.config.resilience.healthEndpoint) {\n void this.health(ctx);\n }\n }\n\n async onError(ctx: PlayerContext, err: PlayerError): Promise<void> {\n if (this.recovering) return;\n if (err.fatal) return;\n\n const max = Math.max(0, ctx.config.resilience.retries ?? 0);\n if (this.attempts >= max) return;\n\n this.attempts++;\n this.recovering = true;\n\n const min = ctx.config.resilience.backoffMs?.min ?? 500;\n const maxMs = ctx.config.resilience.backoffMs?.max ?? 8000;\n const backoff = Math.min(maxMs, min * Math.pow(2, this.attempts - 1));\n\n ctx.ports.log.warn('[ResiliencePlugin] retry', { attempt: this.attempts, backoff, code: err.code });\n\n // optional health token refresh\n if (ctx.config.resilience.healthEndpoint) {\n await this.health(ctx);\n }\n\n await sleep(backoff);\n\n try {\n const snap = ctx.facade.snapshot();\n await ctx.facade.reload({ startTimeSec: snap.currentTime || undefined });\n } catch (e) {\n ctx.ports.log.error('[ResiliencePlugin] reload failed', e);\n } finally {\n this.recovering = false;\n }\n }\n\n private async health(ctx: PlayerContext): Promise<void> {\n try {\n await ctx.ports.http.fetch(ctx.config.resilience.healthEndpoint!, { method: 'GET' });\n } catch (e) {\n ctx.ports.log.warn('[ResiliencePlugin] health check failed', e);\n }\n }\n}\n","import type { PlayerContext, PlayerPlugin } from '../plugin';\n\n/**\n * SSAI helper (v1.11)\n *\n * Keeps the core decoupled from vendor SDKs.\n * This plugin rewrites the manifest URL before the engine loads it.\n */\n\nexport interface SsaiManifestRewriteConfig {\n /** If provided, used as the final playback URL (highest priority). */\n stitchedUrl?: string;\n /** Append query parameters to the source URL (e.g. session, device). */\n appendQuery?: Record<string, string | number | boolean | null | undefined>;\n}\n\nfunction appendQuery(url: string, q: Record<string, any>): string {\n try {\n const base = typeof window !== 'undefined' ? window.location.href : 'http://localhost';\n const u = new URL(url, base);\n for (const [k, v] of Object.entries(q)) {\n if (v === undefined || v === null) continue;\n u.searchParams.set(k, String(v));\n }\n return u.toString();\n } catch {\n return url;\n }\n}\n\nexport function createSsaiManifestRewritePlugin(): PlayerPlugin {\n return {\n id: 'ads:ssai-manifest-rewrite',\n\n async onLoadStart(ctx: PlayerContext): Promise<void> {\n const ads: any = (ctx.config as any)?.ads;\n if (!ads || ads.enabled !== true) return;\n if (ads.mode !== 'ssai') return;\n\n const provider: SsaiManifestRewriteConfig = (ads.providerConfig ?? {}) as any;\n const src: any = (ctx.config as any)?.source;\n if (!src || typeof src.url !== 'string' || !src.url) return;\n\n const before = src.url;\n let after = before;\n if (provider.stitchedUrl) after = provider.stitchedUrl;\n if (provider.appendQuery) after = appendQuery(after, provider.appendQuery);\n\n if (after !== before) {\n src.url = after;\n ctx.ports.telemetry?.add?.({\n event: 'ssai:manifest_rewrite',\n level: 'info',\n ts: Date.now(),\n payload: { before, after }\n } as any);\n }\n }\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/config/default-config.ts","../src/domain/remote-playback.ts","../src/engine/engine-factory.ts","../src/engine/native.engine.ts","../src/engine/native.factory.ts","../src/engine/engine-profile.ts","../src/engine/playback-capabilities.ts","../src/engine/capability-report.ts","../src/remote-config/remote-config.ts","../src/ports/storage.port.ts","../src/ports/telemetry.port.ts","../src/ports/log.port.ts","../src/ports/ports.ts","../src/facade/player-facade.ts","../src/plugins/metadata/providers/local-metadata.provider.ts","../src/plugins/subtitles/providers/local-subtitle.provider.ts","../src/plugins/subtitles/subtitle-file.ts","../src/utils/cache-store.ts","../src/commands.ts","../src/events/event-bus.ts","../src/plugins/progress/progress.plugin.ts","../src/plugins/resilience/resilience.plugin.ts","../src/plugins/ads/ssai.plugin.ts","../src/engine/remote-playback.engine.ts","../src/domain/audio-library.ts","../src/domain/audio-metadata-harmony.ts","../src/domain/audio-identification.ts","../src/domain/audio-identification-routine.ts","../src/domain/media-library-model.ts","../src/domain/media-source.ts","../src/domain/ringtone.ts","../src/domain/shake.ts","../src/domain/vault.ts","../src/domain/device-playback.ts","../src/online/online-http.ts","../src/online/media-cache.ts","../src/online/jellyfin.ts","../src/online/xml-text.ts","../src/online/upnp.ts","../src/online/dlna.ts","../src/online/dlna-renderer.ts","../src/online/mdns.ts","../src/online/cast-v2.ts","../src/online/playback-transfer.ts","../src/online/md5.ts","../src/online/subsonic.ts","../src/online/webdav.ts","../src/online/internet-archive.ts","../src/online/radio-browser.ts","../src/online/musicbrainz.ts","../src/online/lyrics.ts","../src/online/acoustid.ts"],"names":["canPlay","patch","merged","fetch","BehaviorSubject","Subject","text","recording","artistKey","tidy","parsed","request","body","positiveInteger","contentDirectory","LEADING_TRACK_NUMBER","PAGE_SIZE","document","response","shortHash","allTexts","fileStem","clampInteger","originOf","LUCENE_SPECIAL","durationGap"],"mappings":"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","file":"index.cjs","sourcesContent":["import type {\n AdsConfig,\n MetadataConfig,\n PlayerConfig,\n PlayerSource,\n ProgressConfig,\n ResilienceConfig,\n SubtitlesConfig,\n UiConfig,\n} from '../types';\n\n/**\n * Sensible, framework-agnostic defaults for the mandatory sub-configs of\n * {@link PlayerConfig}. They mirror the values used by the existing\n * consumers (local audio/video players) so a brand new integration can get a\n * valid config without restating every field.\n */\nexport const DEFAULT_PROGRESS_CONFIG: ProgressConfig = {\n mode: 'local',\n intervalSec: 5,\n};\n\nexport const DEFAULT_UI_CONFIG: UiConfig = {\n ratios: ['16:9'],\n defaultRatio: '16:9',\n keyboardShortcuts: true,\n};\n\nexport const DEFAULT_RESILIENCE_CONFIG: ResilienceConfig = {\n retries: 2,\n backoffMs: { min: 300, max: 1500 },\n};\n\nexport const DEFAULT_SUBTITLES_CONFIG: SubtitlesConfig = {\n enabled: false,\n providers: ['local'],\n};\n\nexport const DEFAULT_METADATA_CONFIG: MetadataConfig = {\n enabled: false,\n providers: ['local'],\n localSidecar: false,\n};\n\nexport const DEFAULT_ADS_CONFIG: AdsConfig = {\n enabled: false,\n mode: 'csai',\n};\n\n/**\n * Build a complete, type-safe {@link PlayerConfig} from a minimal set of\n * overrides. Only `source` is required; the mandatory sub-configs\n * (`progress`, `ui`, `resilience`, `subtitles`, `metadata`, `ads`) are filled\n * with the defaults above and shallow-merged with any override provided.\n *\n * Optional top-level fields (`profile`, `drm`, `series`, `playlist`,\n * `offline`, `remoteConfig`, ...) are passed through untouched when present.\n *\n * @example\n * ```ts\n * const config = createDefaultConfig({\n * source: { type: 'hls', url: 'https://cdn.example.com/movie.m3u8' },\n * drm: { keySystems: { 'com.widevine.alpha': { licenseServerUrl: 'https://drm/widevine' } } },\n * subtitles: { enabled: true, providers: ['local'], preferredLang: 'fr' },\n * });\n * ```\n */\nexport function createDefaultConfig(\n overrides: Partial<PlayerConfig> & { source: PlayerSource },\n): PlayerConfig {\n const {\n source,\n progress,\n ui,\n resilience,\n subtitles,\n metadata,\n ads,\n ...rest\n } = overrides;\n\n return {\n // Pass through every other (mostly optional) top-level field as provided:\n // profile, drm, series, playlist, playlistStartIndex, autoNext, offline,\n // remoteConfig, ...\n ...rest,\n source,\n progress: { ...DEFAULT_PROGRESS_CONFIG, ...progress },\n ui: { ...DEFAULT_UI_CONFIG, ...ui },\n resilience: {\n ...DEFAULT_RESILIENCE_CONFIG,\n ...resilience,\n backoffMs: {\n ...DEFAULT_RESILIENCE_CONFIG.backoffMs,\n ...resilience?.backoffMs,\n },\n },\n subtitles: { ...DEFAULT_SUBTITLES_CONFIG, ...subtitles },\n metadata: { ...DEFAULT_METADATA_CONFIG, ...metadata },\n ads: { ...DEFAULT_ADS_CONFIG, ...ads },\n };\n}\n","/**\n * Playing on another device of the local network: a DLNA renderer (TV, network speaker), a Chromecast, an AirPlay\n * receiver. Each protocol exposes the same session, so the apps drive a remote device like their own player.\n */\nexport type RemotePlaybackKind = 'dlna' | 'chromecast' | 'airplay';\n\n/** What is sent to the device. The address must be reachable from the device itself, not only from the app. */\nexport interface RemotePlaybackMedia {\n url: string;\n contentType: string;\n kind: 'audio' | 'video';\n title: string;\n artist?: string;\n album?: string;\n artworkUrl?: string;\n durationSec?: number;\n /** Position to start from, to continue what the app was playing. */\n startSec?: number;\n /** Radios and live streams: no duration, no seeking. */\n live?: boolean;\n /**\n * A stream the app converts on the fly into a format the device reads. It cannot seek: it starts where it is asked\n * to, at `at(position)`, and the device counts from there.\n */\n conversion?: { at(startSec: number): string };\n}\n\nexport type RemotePlayerState = 'idle' | 'loading' | 'buffering' | 'playing' | 'paused' | 'stopped';\n\n/**\n * Why a device did not play a media, for the apps to explain it in their own words:\n * - `unsupported-format`: the device does not read this format at all; nothing was sent (`format` names it);\n * - `load-failed`: the device tried and gave up (codec it cannot decode, address it cannot reach);\n * - `timeout`: the device did not answer.\n */\nexport type RemotePlaybackErrorCode = 'unsupported-format' | 'load-failed' | 'timeout';\n\nexport class RemotePlaybackError extends Error {\n constructor(readonly code: RemotePlaybackErrorCode, message: string, readonly format?: string) {\n super(message);\n this.name = 'RemotePlaybackError';\n }\n}\n\n/** The player error code a device failure is reported under: `REMOTE_UNSUPPORTED_FORMAT`, `REMOTE_LOAD_FAILED`… */\nexport function remotePlaybackErrorCode(code: RemotePlaybackErrorCode): string {\n return `REMOTE_${code.toUpperCase().replace(/-/g, '_')}`;\n}\n\n/**\n * The device failure behind a player error, if it is one: raised when the media was sent (a `RemotePlaybackError`),\n * or reported later by the device while playing (`REMOTE_PLAYBACK`, which means it gave up on the media).\n */\nexport function remotePlaybackFailure(error: { code?: string; details?: unknown } | null | undefined): { code: RemotePlaybackErrorCode; format?: string } | null {\n if (!error) return null;\n const details = error.details as { name?: string; code?: RemotePlaybackErrorCode; format?: string } | undefined;\n if (details?.name === 'RemotePlaybackError' && details.code) return { code: details.code, ...(details.format ? { format: details.format } : {}) };\n if (error.code === 'REMOTE_PLAYBACK') return { code: 'load-failed' };\n return null;\n}\n\nexport interface RemotePlaybackStatus {\n state: RemotePlayerState;\n positionSec?: number;\n durationSec?: number;\n /** 0 to 1. */\n volume?: number;\n /** Set when the device gave up on the media (unreachable address, unsupported format). */\n error?: string;\n /** The media played to its end (devices that tell it apart from a stop). */\n ended?: boolean;\n}\n\nexport interface RemotePlaybackSession {\n readonly kind: RemotePlaybackKind;\n load(media: RemotePlaybackMedia): Promise<void>;\n play(): Promise<void>;\n pause(): Promise<void>;\n seek(positionSec: number): Promise<void>;\n /** 0 to 1. */\n setVolume(level: number): Promise<void>;\n /** Ends playback on the device. */\n stop(): Promise<void>;\n status(): Promise<RemotePlaybackStatus>;\n /** Leaves the device; what it plays keeps playing unless `stop` was called. */\n close(): Promise<void>;\n}\n\n/** `H:MM:SS` as UPnP and most devices write positions. */\nexport function formatRemoteClock(seconds: number): string {\n const total = Math.max(0, Math.floor(seconds));\n const hours = Math.floor(total / 3600);\n const minutes = Math.floor((total % 3600) / 60);\n const rest = total % 60;\n return `${hours}:${String(minutes).padStart(2, '0')}:${String(rest).padStart(2, '0')}`;\n}\n\n/** `H+:MM:SS[.F+]` to seconds; undefined for \"NOT_IMPLEMENTED\" and other placeholders. */\nexport function parseRemoteClock(value: string | undefined): number | undefined {\n const match = /^(\\d+):(\\d{1,2}):(\\d{1,2})(?:\\.(\\d+))?$/.exec(value?.trim() ?? '');\n if (!match) return undefined;\n return Number(match[1]) * 3600 + Number(match[2]) * 60 + Number(match[3]) + (match[4] ? Number(`0.${match[4]}`) : 0);\n}\n","import type { PlayerConfig } from '../types';\nimport type { PlaybackEngine } from './playback-engine';\nimport type { PlaybackCapabilities } from './playback-capabilities';\n\nexport interface EngineFactory {\n /** Unique id (ex: 'native', 'shaka') */\n id: string;\n /** Higher priority wins when multiple support the same source. Default 0. */\n priority?: number;\n /** Whether this engine supports this config/source. */\n supports(config: PlayerConfig): boolean;\n /**\n * Optional, capability-aware selector.\n * If present, it is preferred over supports().\n */\n supportsWithCaps?: (config: PlayerConfig, caps: PlaybackCapabilities) => boolean;\n /** Create a new engine instance. */\n create(): PlaybackEngine;\n}\n\nexport function selectEngine(\n config: PlayerConfig,\n factories: EngineFactory[],\n caps?: PlaybackCapabilities\n): EngineFactory | null {\n const candidates = (factories ?? []).filter(f => {\n try {\n if (caps && typeof f.supportsWithCaps === 'function') return !!f.supportsWithCaps(config, caps);\n return !!f.supports(config);\n } catch {\n return false;\n }\n });\n if (candidates.length === 0) return null;\n candidates.sort((a,b) => (b.priority ?? 0) - (a.priority ?? 0));\n return candidates[0];\n}\n","import { PlaybackEngine, EngineEvent } from './playback-engine';\nimport { MediaTrack, PlayerSource } from '../types';\n\n\nfunction mimeFromUrl(url: string): string {\n try {\n const clean = url.split('?')[0].split('#')[0];\n const parts = clean.split('.');\n const ext = (parts.length > 1 ? parts.pop() : '')?.toLowerCase() || '';\n switch (ext) {\n case 'mp4': return 'video/mp4';\n case 'm4v': return 'video/x-m4v';\n case 'mov': return 'video/quicktime';\n case 'webm': return 'video/webm';\n case 'mkv': return 'video/x-matroska';\n case 'avi': return 'video/x-msvideo';\n case 'mpg':\n case 'mpeg': return 'video/mpeg';\n case 'ts': return 'video/mp2t';\n case 'ogv': return 'video/ogg';\n default: return '';\n }\n } catch {\n return '';\n }\n}\n\n/** HTMLMediaElement.NETWORK_NO_SOURCE: every candidate source was tried and none could be used. */\nconst NO_SOURCE = 3;\n\n/** Whether the engine would take that type at all; '' is its way of saying no. */\nfunction canPlay(v: HTMLVideoElement, type: string): boolean {\n return typeof v.canPlayType !== 'function' || v.canPlayType(type) !== '';\n}\n\nexport class NativeEngine implements PlaybackEngine {\n public readonly id = 'native';\n private video?: HTMLVideoElement;\n private listeners: Array<(e: EngineEvent) => void> = [];\n\n private emit(e: EngineEvent): void {\n this.listeners.forEach(l => l(e));\n }\n\n async attach(videoEl: HTMLVideoElement): Promise<void> {\n this.video = videoEl;\n const v = videoEl;\n\n const emit = (e: EngineEvent) => this.emit(e);\n\n v.addEventListener('timeupdate', () => emit({ type: 'timeupdate', currentTime: v.currentTime, duration: v.duration || 0 }));\n v.addEventListener('playing', () => emit({ type: 'state', state: 'playing' }));\n v.addEventListener('pause', () => emit({ type: 'state', state: 'paused' }));\n v.addEventListener('waiting', () => emit({ type: 'state', state: 'buffering' }));\n v.addEventListener('ended', () => emit({ type: 'state', state: 'ended' }));\n v.addEventListener('error', () => {\n const err = v.error;\n emit({\n type: 'error',\n error: { code: `HTML5_${err?.code ?? 'UNKNOWN'}`, message: err?.message ?? 'HTML5 video error', fatal: true, details: err }\n });\n });\n }\n\n async load(source: PlayerSource, opts?: { startTimeSec?: number }): Promise<void> {\n if (!this.video) throw new Error('NativeEngine not attached');\n const v = this.video;\n\n if (source.type === 'local-file') {\n if (!source.file) throw new Error('source.file is required');\n v.src = URL.createObjectURL(source.file);\n } else {\n if (!source.url) throw new Error('source.url is required');\n\n // For custom protocols (e.g. ngxsp-file://) Chromium sometimes refuses to infer\n // a playable type from the URL alone. Using a <source type=\"...\"> helps it pick\n // the right pipeline and avoids \"The element has no supported sources.\"\n //\n // Only ever name a type the engine accepts. The extension describes the file on disk, not\n // what arrives: a desktop host converts an AVI to fragmented MP4 as it serves it, at the\n // same URL. Declaring `video/x-msvideo` there makes `canPlayType` return '' and the source\n // is skipped before a single byte is fetched — a stream that plays, refused on its name.\n // Unnamed, the element reads the response's own content type and plays it.\n const declared = mimeFromUrl(source.url);\n const type = declared && canPlay(v, declared) ? declared : '';\n while (v.firstChild) v.removeChild(v.firstChild);\n if (type) {\n const s = document.createElement('source');\n s.src = source.url;\n s.type = type;\n // A <source> that cannot be read is the one failure the media element keeps to itself: the\n // spec fires the error on the child, leaves `video.error` null and never fires `error` on\n // the element. The listener in attach() therefore hears nothing, the last state to arrive\n // is the `waiting` that came before it, and the player sits on \"buffering\" for as long as\n // anyone cares to wait. Saying it here is the only way it gets said at all.\n s.addEventListener('error', () => {\n if (v.networkState !== NO_SOURCE) return;\n this.emit({\n type: 'error',\n error: {\n code: 'HTML5_4',\n message: `No source could be decoded (${type})`,\n fatal: true,\n details: { url: source.url, type }\n }\n });\n });\n v.appendChild(s);\n v.removeAttribute('src');\n } else {\n v.src = source.url;\n }\n}\n\n await v.load();\n if (opts?.startTimeSec != null && isFinite(opts.startTimeSec)) {\n v.currentTime = Math.max(0, opts.startTimeSec);\n } else if (!source.live) {\n // A position set before the previous media had its metadata stays pending on the element, and Chromium applies it\n // to the next media loaded there: a restored track at 1:04, then a one-minute file, and the file \"ends\" at once.\n // Asking for the start clears it. Live streams keep the edge the browser picks.\n v.currentTime = 0;\n }\n }\n\n async destroy(): Promise<void> {\n if (!this.video) return;\n this.video.removeAttribute('src');\n this.video.load();\n this.video = undefined;\n this.listeners = [];\n }\n\n async play(): Promise<void> { await this.video?.play(); }\n async pause(): Promise<void> { this.video?.pause(); }\n async seekTo(timeSec: number): Promise<void> { if (this.video) this.video.currentTime = Math.max(0, timeSec); }\n async setPlaybackRate(rate: number): Promise<void> { if (this.video) this.video.playbackRate = rate; }\n async setVolume(volume: number): Promise<void> {\n if (!this.video) return;\n const level = Math.min(1, Math.max(0, volume));\n this.video.volume = level;\n // iOS ignores volume writes on media elements: muting is the only way to silence playback there.\n this.video.muted = level <= 0;\n }\n\n async setTextTrack(_trackId: string | null): Promise<void> { /* native text tracks not managed here */ }\n async setAudioTrack(_trackId: string | null): Promise<void> { /* not supported in basic native impl */ }\n async setVideoTrack(_trackId: string | null): Promise<void> { /* not supported in basic native impl */ }\n\n async getTracks(): Promise<MediaTrack[]> { return []; }\n\n onEvent(cb: (ev: EngineEvent) => void): () => void {\n this.listeners.push(cb);\n return () => { this.listeners = this.listeners.filter(x => x !== cb); };\n }\n}\n","import type { EngineFactory } from './engine-factory';\nimport { NativeEngine } from './native.engine';\nimport type { PlayerConfig } from '../types';\n\nexport function createNativeEngineFactory(): EngineFactory {\n return {\n id: 'native',\n priority: 0,\n supports: (cfg: PlayerConfig) => {\n const drm = (cfg as any).drm ?? (cfg as any).source?.drm;\n if (drm?.required) return false;\n // Native engine for progressive/local urls\n const t = cfg.source.type;\n if (t === 'url' || t === 'local-file') return true;\n // also allow unknown as fallback, but avoid claiming HLS/DASH/DRM explicitly\n return false;\n },\n create: () => new NativeEngine()\n };\n}\n","import type { EngineProfileId, PlayerSource } from '../types';\n\n/**\n * High-level playback profiles.\n *\n * Goal: provide good defaults with *minimal configuration*.\n * Users can still override per-source hints via `source.abr`.\n */\nexport interface EngineProfileHints {\n /** Defaults applied only when the user did not specify `source.abr.*` */\n abr?: {\n maxHeight?: number;\n maxBandwidth?: number;\n };\n\n /** Shaka-specific streaming knobs (best-effort, ignored by non-shaka engines). */\n shakaStreaming?: {\n lowLatencyMode?: boolean;\n bufferingGoalSec?: number;\n rebufferingGoalSec?: number;\n };\n}\n\nexport function getEngineProfileHints(profile?: EngineProfileId): EngineProfileHints {\n switch (profile) {\n case 'tv':\n return {\n abr: {\n // Prefer higher quality by default.\n maxHeight: 2160\n },\n shakaStreaming: {\n bufferingGoalSec: 30,\n rebufferingGoalSec: 2\n }\n };\n case 'mobile':\n return {\n abr: {\n // Reasonable default for mobile data/CPU.\n maxHeight: 720\n },\n shakaStreaming: {\n bufferingGoalSec: 15,\n rebufferingGoalSec: 2\n }\n };\n case 'low-latency':\n return {\n abr: {\n // Avoid very high res by default (keeps latency predictable).\n maxHeight: 1080\n },\n shakaStreaming: {\n lowLatencyMode: true,\n bufferingGoalSec: 6,\n rebufferingGoalSec: 1\n }\n };\n case 'default':\n default:\n return {\n shakaStreaming: {\n bufferingGoalSec: 20,\n rebufferingGoalSec: 2\n }\n };\n }\n}\n\n/**\n * Apply profile defaults to a `PlayerSource` without overriding user-provided hints.\n *\n * This function is intentionally conservative: it only fills missing fields.\n */\nexport function applyEngineProfileToSource(source: PlayerSource, profile?: EngineProfileId): PlayerSource {\n const p: EngineProfileId = profile ?? 'default';\n const hints = getEngineProfileHints(p);\n\n const anySrc: any = source as any;\n const abrIn = (anySrc.abr ?? {}) as any;\n\n const abrOut: any = { ...abrIn };\n if (abrOut.maxHeight == null && hints.abr?.maxHeight != null) abrOut.maxHeight = hints.abr.maxHeight;\n if (abrOut.maxBandwidth == null && hints.abr?.maxBandwidth != null) abrOut.maxBandwidth = hints.abr.maxBandwidth;\n\n const out: any = {\n ...anySrc,\n // Expose profile to engines (optional).\n profile: p\n };\n\n if (Object.keys(abrOut).length) out.abr = abrOut;\n\n // Shaka streaming hints are carried on the source (optional).\n if (hints.shakaStreaming) {\n out._shakaStreaming = {\n ...(anySrc._shakaStreaming ?? {}),\n ...hints.shakaStreaming\n };\n }\n\n return out as PlayerSource;\n}\n","export interface PlaybackCapabilities {\n /** Browser has MediaSource (MSE). */\n mse: boolean;\n /** Browser has Encrypted Media Extensions (EME) API. */\n eme: boolean;\n /** True if navigator.mediaCapabilities is available. */\n mediaCapabilities: boolean;\n /** Whether basic HLS playback is possible via MSE/native. */\n hls: boolean;\n /** Whether basic DASH playback is possible via MSE. */\n dash: boolean;\n /** Progressive mp4/webm playback via <video src>. */\n progressive: boolean;\n /** Heuristic: support for at least one of common video codecs. */\n codecs: {\n mp4_h264: boolean;\n mp4_hevc: boolean;\n webm_vp9: boolean;\n webm_av1: boolean;\n };\n /** Known DRM key systems availability (best-effort). */\n drm: {\n widevine: boolean;\n playready: boolean;\n fairplay: boolean;\n };\n}\n\nexport function createDefaultCapabilities(): PlaybackCapabilities {\n return {\n mse: false,\n eme: false,\n mediaCapabilities: false,\n hls: false,\n dash: false,\n progressive: true,\n codecs: { mp4_h264: false, mp4_hevc: false, webm_vp9: false, webm_av1: false },\n drm: { widevine: false, playready: false, fairplay: false }\n };\n}\n\nexport async function detectPlaybackCapabilities(videoEl?: HTMLVideoElement): Promise<PlaybackCapabilities> {\n const caps = createDefaultCapabilities();\n\n const w = globalThis as any;\n caps.mse = !!w.MediaSource && typeof w.MediaSource.isTypeSupported === 'function';\n caps.eme = !!(w.navigator && w.navigator.requestMediaKeySystemAccess);\n caps.mediaCapabilities = !!(w.navigator && (w.navigator as any).mediaCapabilities);\n\n // Codec support (quick heuristic). Prefer MediaSource.isTypeSupported when available.\n const v = videoEl ?? (typeof document !== 'undefined' ? document.createElement('video') : undefined);\n const canPlay = (mime: string) => {\n try {\n if (caps.mse && w.MediaSource?.isTypeSupported) return !!w.MediaSource.isTypeSupported(mime);\n if (v && typeof v.canPlayType === 'function') return v.canPlayType(mime) !== '';\n return false;\n } catch {\n return false;\n }\n };\n\n caps.codecs.mp4_h264 = canPlay('video/mp4; codecs=\"avc1.42E01E\"');\n caps.codecs.mp4_hevc = canPlay('video/mp4; codecs=\"hvc1.1.6.L93.B0\"');\n caps.codecs.webm_vp9 = canPlay('video/webm; codecs=\"vp09.00.10.08\"');\n caps.codecs.webm_av1 = canPlay('video/webm; codecs=\"av01.0.05M.08\"');\n\n // HLS/DASH heuristics:\n // - DASH typically requires MSE.\n // - HLS can be native on Safari, otherwise usually requires MSE + JS player (Shaka/hls.js).\n caps.dash = caps.mse;\n caps.hls = canPlay('application/vnd.apple.mpegurl') || canPlay('application/x-mpegURL') || caps.mse;\n caps.progressive = caps.codecs.mp4_h264 || caps.codecs.webm_vp9 || caps.codecs.webm_av1 || true;\n\n // DRM availability (best-effort probes)\n if (caps.eme && w.navigator?.requestMediaKeySystemAccess) {\n const probe = async (ks: string) => {\n try {\n // minimal config; browsers may still reject.\n const cfg = [{\n initDataTypes: ['cenc'],\n audioCapabilities: [{ contentType: 'audio/mp4; codecs=\"mp4a.40.2\"' }],\n videoCapabilities: [{ contentType: 'video/mp4; codecs=\"avc1.42E01E\"' }]\n }];\n await w.navigator.requestMediaKeySystemAccess(ks, cfg);\n return true;\n } catch {\n return false;\n }\n };\n\n // Widevine\n caps.drm.widevine = await probe('com.widevine.alpha');\n // PlayReady\n caps.drm.playready = await probe('com.microsoft.playready');\n // FairPlay (Safari)\n caps.drm.fairplay = await probe('com.apple.fps.1_0');\n }\n\n return caps;\n}\n","import type { PlayerConfig } from '../types';\n\nexport interface CapabilityReport {\n timestamp: number;\n userAgent?: string;\n source?: {\n type?: string;\n live?: boolean;\n drm?: boolean;\n url?: string;\n contentId?: string;\n };\n platform: {\n isSecureContext: boolean;\n };\n features: {\n mse: boolean;\n eme: boolean;\n mediaCapabilities: boolean;\n };\n canPlay: Record<string, boolean>;\n /**\n * Optional, best-effort decoding probes via the MediaCapabilities API.\n *\n * Keys are stable labels (e.g. \"h264_1080p\").\n */\n mediaDecoding?: Record<string, { supported: boolean; smooth?: boolean; powerEfficient?: boolean }>;\n notes: string[];\n}\n\n/** Best-effort decoding probes used for diagnostics and ABR tuning hints. */\nexport async function createMediaDecodingReport(): Promise<CapabilityReport['mediaDecoding']> {\n const mc: any = (globalThis as any).navigator?.mediaCapabilities;\n if (!mc?.decodingInfo) return undefined;\n\n const mk = (contentType: string, width: number, height: number, bitrate: number) => ({\n type: 'media-source',\n video: { contentType, width, height, bitrate, framerate: 30 },\n audio: { contentType: 'audio/mp4; codecs=\"mp4a.40.2\"', channels: 2, bitrate: 128000, samplerate: 48000 }\n });\n\n const probes: Array<[string, any]> = [\n ['h264_720p', mk('video/mp4; codecs=\"avc1.64001f\"', 1280, 720, 2500000)],\n ['h264_1080p', mk('video/mp4; codecs=\"avc1.640028\"', 1920, 1080, 5000000)],\n ['vp9_1080p', mk('video/webm; codecs=\"vp09.00.51.08\"', 1920, 1080, 5000000)]\n ];\n\n const out: NonNullable<CapabilityReport['mediaDecoding']> = {};\n for (const [key, cfg] of probes) {\n try {\n const info = await mc.decodingInfo(cfg);\n out[key] = {\n supported: !!info?.supported,\n smooth: info?.smooth,\n powerEfficient: info?.powerEfficient\n };\n } catch {\n // ignore\n }\n }\n return Object.keys(out).length ? out : undefined;\n}\n\nfunction safeUa(): string | undefined {\n try { return (globalThis as any).navigator?.userAgent; } catch { return undefined; }\n}\n\nfunction canPlayType(videoEl: HTMLVideoElement | undefined, mime: string): boolean {\n try {\n const v = videoEl ?? (typeof document !== 'undefined' ? document.createElement('video') : undefined);\n if (!v || typeof v.canPlayType !== 'function') return false;\n return v.canPlayType(mime) !== '';\n } catch {\n return false;\n }\n}\n\nexport function createCapabilityReport(\n videoEl?: HTMLVideoElement,\n cfg?: PlayerConfig,\n mediaDecoding?: CapabilityReport['mediaDecoding']\n): CapabilityReport {\n const w = globalThis as any;\n const notes: string[] = [];\n\n const mse = !!w.MediaSource && typeof w.MediaSource.isTypeSupported === 'function';\n const eme = !!(w.navigator && w.navigator.requestMediaKeySystemAccess);\n const mediaCapabilities = !!(w.navigator && (w.navigator as any).mediaCapabilities);\n\n if (!mse) notes.push('MediaSource (MSE) not available');\n if (!eme) notes.push('Encrypted Media Extensions (EME) not available');\n\n const canPlay: Record<string, boolean> = {\n 'video/mp4; codecs=\"avc1.42E01E\"': canPlayType(videoEl, 'video/mp4; codecs=\"avc1.42E01E\"'),\n 'video/mp4; codecs=\"hvc1.1.6.L93.B0\"': canPlayType(videoEl, 'video/mp4; codecs=\"hvc1.1.6.L93.B0\"'),\n 'video/webm; codecs=\"vp09.00.10.08\"': canPlayType(videoEl, 'video/webm; codecs=\"vp09.00.10.08\"'),\n 'video/webm; codecs=\"av01.0.05M.08\"': canPlayType(videoEl, 'video/webm; codecs=\"av01.0.05M.08\"'),\n 'application/vnd.apple.mpegurl': canPlayType(videoEl, 'application/vnd.apple.mpegurl'),\n 'application/dash+xml': canPlayType(videoEl, 'application/dash+xml')\n };\n\n const secure = (() => {\n try { return !!(globalThis as any).isSecureContext; } catch { return false; }\n })();\n if (!secure) notes.push('Not running in a secure context (HTTPS). DRM and some APIs may fail.');\n\n const src = cfg?.source;\n const drmCfg = cfg ? ((cfg as any).drm ?? (src as any)?.drm) : undefined;\n const drmFlag = !!drmCfg;\n\n return {\n timestamp: Date.now(),\n userAgent: safeUa(),\n source: src ? {\n type: (src as any).type,\n live: (src as any).live,\n drm: drmFlag,\n url: (src as any).url,\n contentId: (src as any).contentId\n } : undefined,\n platform: { isSecureContext: secure },\n features: { mse, eme, mediaCapabilities },\n canPlay,\n mediaDecoding,\n notes\n };\n}\n","import type { PlayerPorts } from '../ports/ports';\nimport type { PlayerConfig, RemoteConfigConfig, RemoteConfigPayload } from '../types';\n\ntype CacheEntry = { ts: number; data: RemoteConfigPayload };\n\nconst DEFAULT_ALLOW = [\n 'profile',\n 'abr',\n 'resilience',\n 'drm',\n 'ads',\n 'ui',\n 'subtitles',\n 'metadata',\n 'progress',\n 'chapters',\n 'offline'\n];\n\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return !!v && typeof v === 'object' && !Array.isArray(v);\n}\n\nfunction deepMerge<T extends Record<string, any>>(base: T, patch: Record<string, any>): T {\n const out: any = { ...base };\n for (const [k, v] of Object.entries(patch)) {\n if (isPlainObject(v) && isPlainObject(out[k])) out[k] = deepMerge(out[k], v);\n else out[k] = v;\n }\n return out;\n}\n\nfunction shallowMerge<T extends Record<string, any>>(base: T, patch: Record<string, any>): T {\n return { ...(base as any), ...(patch as any) };\n}\n\nfunction hashKey(url: string): string {\n // Small deterministic key (no crypto dependency).\n let h = 0;\n for (let i = 0; i < url.length; i++) h = (h * 31 + url.charCodeAt(i)) >>> 0;\n return h.toString(16);\n}\n\nasync function readCache(storage: PlayerPorts['storage'] | undefined, key: string): Promise<CacheEntry | null> {\n if (!storage?.get) return null;\n const raw = await storage.get(key);\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw) as CacheEntry;\n if (!parsed || typeof parsed.ts !== 'number' || !isPlainObject(parsed.data)) return null;\n return parsed;\n } catch {\n return null;\n }\n}\n\nasync function writeCache(storage: PlayerPorts['storage'] | undefined, key: string, entry: CacheEntry): Promise<void> {\n if (!storage?.set) return;\n await storage.set(key, JSON.stringify(entry));\n}\n\nexport async function applyRemoteConfig(\n cfg: PlayerConfig,\n ports: Partial<PlayerPorts>\n): Promise<{ config: PlayerConfig; applied: boolean; payload?: RemoteConfigPayload; source: 'cache' | 'network' | 'none' }>\n{\n const rc = cfg.remoteConfig;\n if (!rc?.enabled) return { config: cfg, applied: false, source: 'none' };\n\n const url = rc.url;\n const ttlMs = Math.max(1, (rc.ttlSec ?? 300)) * 1000;\n const mode = rc.mode ?? 'deep';\n const allow = (rc.allow?.length ? rc.allow : DEFAULT_ALLOW) as string[];\n const cacheKey = `remoteConfig:${hashKey(url)}`;\n\n const now = Date.now();\n\n try {\n const cached = await readCache(ports.storage, cacheKey);\n if (cached && now - cached.ts < ttlMs) {\n const patch = filterAllowList(cached.data, allow);\n const merged = mode === 'shallow' ? shallowMerge(cfg as any, patch as any) : deepMerge(cfg as any, patch as any);\n return { config: merged, applied: true, payload: cached.data, source: 'cache' };\n }\n\n const fetch = ports.http?.fetch;\n if (!fetch) throw new Error('Remote config enabled but no ports.http.fetch provided');\n\n const res = await fetch(url, { method: 'GET', headers: { 'accept': 'application/json' } });\n if (!res.ok) throw new Error(`Remote config HTTP ${res.status}`);\n const json = (await res.json()) as unknown;\n if (!isPlainObject(json)) throw new Error('Remote config payload must be a JSON object');\n\n const payload = json as RemoteConfigPayload;\n await writeCache(ports.storage, cacheKey, { ts: now, data: payload });\n\n const patch = filterAllowList(payload, allow);\n const merged = mode === 'shallow' ? shallowMerge(cfg as any, patch as any) : deepMerge(cfg as any, patch as any);\n return { config: merged, applied: true, payload, source: 'network' };\n } catch (err) {\n ports.log?.warn?.('[ngxsp] remoteConfig failed', err);\n return { config: cfg, applied: false, source: 'none' };\n }\n}\n\nfunction filterAllowList(payload: RemoteConfigPayload, allow: string[]): RemoteConfigPayload {\n const out: RemoteConfigPayload = {};\n for (const k of allow) {\n if (Object.prototype.hasOwnProperty.call(payload, k)) out[k] = payload[k];\n }\n return out;\n}\n","export interface StoragePort {\n get(key: string): Promise<string | null>;\n set(key: string, value: string): Promise<void>;\n remove?(key: string): Promise<void>;\n}\n\nexport class MemoryStoragePort implements StoragePort {\n private map = new Map<string, string>();\n async get(key: string): Promise<string | null> { return this.map.get(key) ?? null; }\n async set(key: string, value: string): Promise<void> { this.map.set(key, value); }\n async remove(key: string): Promise<void> { this.map.delete(key); }\n}\n","export interface TelemetryPort {\n add(sample: Record<string, unknown>): void;\n export?(): unknown;\n}\n\nexport class NoopTelemetryPort implements TelemetryPort {\n add(_sample: Record<string, unknown>): void { /* noop */ }\n}\n","export interface LogPort {\n debug(...args: unknown[]): void;\n info(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n}\n\nexport class ConsoleLogPort implements LogPort {\n debug(...args: unknown[]): void { console.debug(...args); }\n info(...args: unknown[]): void { console.info(...args); }\n warn(...args: unknown[]): void { console.warn(...args); }\n error(...args: unknown[]): void { console.error(...args); }\n}\n","import type { HttpPort } from './http.port';\nimport type { StoragePort } from './storage.port';\nimport type { TelemetryPort } from './telemetry.port';\nimport type { LogPort } from './log.port';\nimport { MemoryStoragePort } from './storage.port';\nimport { NoopTelemetryPort } from './telemetry.port';\nimport { ConsoleLogPort } from './log.port';\n\nexport interface PlayerPorts {\n http: HttpPort;\n storage: StoragePort;\n telemetry: TelemetryPort;\n log: LogPort;\n}\n\nexport function createDefaultPorts(): PlayerPorts {\n const http: HttpPort = { fetch: (input, init) => fetch(input, init) };\n return {\n http,\n storage: new MemoryStoragePort(),\n telemetry: new NoopTelemetryPort(),\n log: new ConsoleLogPort()\n };\n}\n\nexport { MemoryStoragePort } from './storage.port';\nexport { NoopTelemetryPort } from './telemetry.port';\nexport { ConsoleLogPort } from './log.port';\n","import { BehaviorSubject, Observable, Subject } from 'rxjs';\nimport {\n AspectRatioMode,\n MediaTrack,\n PlayerConfig,\n PlayerError,\n PlayerErrorCode,\n PlayerState,\n type DiagnosticsSnapshot,\n type DiagnosticsEngineInfo,\n type PlayerTime,\n type PlayerSource\n} from '../types';\nimport type { TelemetrySample, TelemetryEvent, TelemetryLevel } from '../telemetry/telemetry.types';\nimport { PlaybackEngine, EngineEvent, LoadOptions } from '../engine/playback-engine';\nimport type { EngineFactory } from '../engine/engine-factory';\nimport { remotePlaybackErrorCode } from '../domain/remote-playback';\nimport { selectEngine } from '../engine/engine-factory';\nimport { createNativeEngineFactory } from '../engine/native.factory';\nimport { applyEngineProfileToSource } from '../engine/engine-profile';\nimport { detectPlaybackCapabilities, type PlaybackCapabilities } from '../engine/playback-capabilities';\nimport { createCapabilityReport, createMediaDecodingReport, type CapabilityReport } from '../engine/capability-report';\nimport { applyRemoteConfig } from '../remote-config/remote-config';\nimport { PlayerPlugin, PlayerContext } from '../plugins/plugin';\nimport type { PlayerPorts } from '../ports/ports';\nimport { createDefaultPorts } from '../ports/ports';\nimport { VideoMetadata } from '../plugins/metadata/metadata.types';\n\nexport interface PlayerSnapshot {\n currentTime: number;\n duration: number;\n state: PlayerState;\n bufferedAheadSec: number;\n}\n\n/**\n * Public diagnostics payload.\n *\n * NOTE: This is intentionally an alias of `DiagnosticsSnapshot` to keep one\n * canonical shape exported by `@ngxsp/core`.\n */\nexport type PlayerDiagnostics = DiagnosticsSnapshot;\n\nexport class PlayerFacade {\n private engineFactories: EngineFactory[] = [createNativeEngineFactory()];\n private engineId = 'native';\n private lastNonFatal: PlayerError | null = null;\n\n // Optional MediaCapabilities decoding probes (async, best-effort)\n private mediaDecodingSub = new BehaviorSubject<CapabilityReport['mediaDecoding'] | null>(null);\n private video?: HTMLVideoElement;\n private engine?: PlaybackEngine;\n private plugins: PlayerPlugin[] = [];\n private ctx?: PlayerContext;\n\n private stateSub = new BehaviorSubject<PlayerState>({ kind: 'idle' });\n private timeSub = new BehaviorSubject<{ currentTime: number; duration: number }>({ currentTime: 0, duration: 0 });\n private bufferSub = new BehaviorSubject<number>(0);\n private tracksSub = new BehaviorSubject<MediaTrack[]>([]);\n private errorSub = new Subject<PlayerError>();\n private metadataSub = new BehaviorSubject<VideoMetadata | null>(null);\n\n private capsSub = new BehaviorSubject<PlaybackCapabilities | null>(null);\n readonly capabilities$ = this.capsSub.asObservable();\n\n readonly state$ = this.stateSub.asObservable();\n readonly time$ = this.timeSub.asObservable();\n readonly bufferAheadSec$ = this.bufferSub.asObservable();\n readonly tracks$ = this.tracksSub.asObservable();\n readonly error$ = this.errorSub.asObservable();\n readonly metadata$ = this.metadataSub.asObservable();\n\n private seriesIndexSub = new BehaviorSubject<number | null>(null);\n readonly seriesIndex$ = this.seriesIndexSub.asObservable();\n\n private playlistIndexSub = new BehaviorSubject<number | null>(null);\n readonly playlistIndex$ = this.playlistIndexSub.asObservable();\n private playlist: import('../types').PlayerSource[] = [];\n private playlistKey = '';\n\n /** Subtitles loaded from files, shown by the host from `captionCues$` rather than by the browser. */\n private externalTexts: Array<{ id: string; label: string; language?: string; url: string; element: HTMLTrackElement }> = [];\n private externalTextCount = 0;\n /** The text track picked here; undefined while the engine's own choice stands. */\n private textSelection: string | null | undefined = undefined;\n private engineTracks: MediaTrack[] = [];\n private offCueChange?: () => void;\n private captionCuesSub = new BehaviorSubject<TextTrackCue[]>([]);\n /** The cues of the loaded subtitles to show now: the host draws them over the video. */\n readonly captionCues$ = this.captionCuesSub.asObservable();\n\n constructor(private ports: PlayerPorts = createDefaultPorts()) {}\n\n\nattach(videoEl: HTMLVideoElement, plugins: PlayerPlugin[] = [], config: PlayerConfig, ports?: Partial<PlayerPorts>, engines?: EngineFactory[]): void {\n // merge ports\n if (ports) {\n this.ports = { ...this.ports, ...ports } as any;\n }\n this.setEngines(engines);\n this.video = videoEl;\n this.plugins = plugins ?? [];\n this.ctx = { config, facade: this, ports: this.ports, contentId: config.source.contentId };\n\n // Capability probe (async; used for engine selection + better diagnostics).\n void detectPlaybackCapabilities(videoEl)\n .then(c => this.capsSub.next(c))\n .catch(() => this.capsSub.next(null));\n\n // MediaCapabilities decoding probes (async; best-effort; used for diagnostics/ABR hints).\n void createMediaDecodingReport()\n .then(r => this.mediaDecodingSub.next(r ?? null))\n .catch(() => this.mediaDecodingSub.next(null));\n this.emitTelemetry('player:attach','info');\n this.emitTelemetry('player:source_set','info',{ type: config.source.type, live: config.source.live });\n\n this.installVideoEventListeners();\n\n // init plugins\n for (const p of this.plugins) {\n try { void p.onInit?.(this.ctx); } catch { /* noop */ }\n }\n}\n\nasync load(config: PlayerConfig, opts?: LoadOptions): Promise<void> {\n if (!this.video) throw new Error('PlayerFacade not attached');\n if (!this.ctx) throw new Error('PlayerFacade context missing');\n\n // Remote control-plane (feature flags / tuning / profiles) – applied before engine/plugin decisions.\n const rc = await applyRemoteConfig(config, this.ports);\n if (rc.applied) {\n this.ports.telemetry?.add?.({\n event: 'remote_config:applied' as any,\n level: 'info',\n ts: Date.now(),\n data: { source: rc.source, url: config.remoteConfig?.url }\n } as any);\n config = rc.config;\n }\n\n // Normalize playlist (v1.7.1)\n const list = config.playlist ?? [];\n if (list.length > 0) {\n const key = list.map(s => (s.contentId ?? s.url ?? (s as any).filePath ?? '')).join('|');\n if (key !== this.playlistKey) {\n this.playlistKey = key;\n this.playlist = list;\n const startIdx = config.playlistStartIndex ?? 0;\n this.playlistIndexSub.next(Math.max(0, Math.min(startIdx, list.length - 1)));\n }\n if (opts?.playlistIndex != null) {\n this.playlistIndexSub.next(Math.max(0, Math.min(opts.playlistIndex, list.length - 1)));\n }\n const idx = this.playlistIndexSub.value ?? 0;\n const src = list[idx] ?? config.source;\n config = { ...config, source: src, autoNext: config.autoNext ?? true };\n this.emitTelemetry('player:playlist_index', 'info', { index: idx, total: list.length });\n }\n\n this.ctx.config = config;\n this.ctx.contentId = config.source.contentId;\n // The last known position is the previous media's until this one reports. Kept, a reload in between (a retry after an\n // early error) would send this media there — past its end for a short file, which then \"finishes\" at once.\n this.timeSub.next({ currentTime: Math.max(0, opts?.startTimeSec ?? 0), duration: 0 });\n this.emitTelemetry('player:load_start','info');\n try {\n const now = (globalThis.performance?.now?.() ?? Date.now());\n this.qoe.loadStartMs = now;\n this.qoe.firstFrameMs = 0;\n this.qoe.startupMs = 0;\n this.qoe.rebufferCount = 0;\n this.qoe.rebufferMs = 0;\n this.qoe.rebufferStartMs = 0;\n this.qoe.firstFrameEmitted = false;\n } catch {}\n\n for (const p of this.plugins) {\n try { await p.onLoadStart?.(this.ctx); } catch { /* noop */ }\n }\n\n // A new media: the subtitles loaded for the previous one go.\n this.clearExternalTextTracks();\n\n // (re)create engine\n if (this.engine) {\n try { await this.engine.destroy(); } catch {}\n this.engine = undefined;\n }\n\n const caps = this.capsSub.value ?? undefined;\n const chosen = selectEngine(config, this.engineFactories, caps);\n if (!chosen) {\n const detail = { source: config.source, caps };\n this.emitFatal(new Error(`No engine registered for this source: ${JSON.stringify(detail)}`), 'ENGINE_MISSING');\n throw new Error('ENGINE_MISSING');\n }\n const engine = chosen.create();\n\n this.engine = engine;\n this.engineId = (engine as any).id ?? (engine.constructor?.name ?? 'engine');\n this.emitTelemetry('player:engine_selected','info',{ engineId: this.engineId });\n\n await engine.attach(this.video);\n\n const off = engine.onEvent(ev => this.handleEngineEvent(ev));\n (this as any)._offEngine = off;\n\n const startTime = opts?.startTimeSec;\n // Merge DRM from config onto the source so engines can stay \"source-only\".\n const sourceWithDrm = applyEngineProfileToSource(\n {\n ...config.source,\n drm: (config as any).drm ?? (config.source as any).drm,\n profile: (config as any).profile ?? (config.source as any).profile\n } as any,\n (config as any).profile ?? (config.source as any).profile\n ) as any;\n try {\n await engine.load(sourceWithDrm, { startTimeSec: startTime ?? undefined });\n this.stateSub.next({ kind: 'paused' });\n this.emitTelemetry('player:load_ok','info');\n } catch (err) {\n this.emitTelemetry('player:load_fail','error',{}, (err as any)?.message);\n this.emitFatal(err, 'UNKNOWN');\n throw err;\n }\n\n // notify plugins loaded\n for (const p of this.plugins) {\n try { await p.onLoaded?.(this.ctx); } catch { /* noop */ }\n }\n}\n\n/**\n * Replaces the engines the next load chooses from (a remote device session starting or ending). The native engine is\n * always kept as fallback so progressive and local playback never breaks; call `load` or `reload` to switch now.\n */\nsetEngines(engines?: EngineFactory[]): void {\n this.engineFactories = engines && engines.length ? [createNativeEngineFactory(), ...engines] : [createNativeEngineFactory()];\n}\n\nasync reload(opts?: LoadOptions): Promise<void> {\n if (!this.ctx) throw new Error('PlayerFacade context missing');\n const snap = this.snapshot();\n const start = opts?.startTimeSec ?? snap.currentTime ?? 0;\n await this.load(this.ctx.config, { startTimeSec: start });\n}\n\nasync next(): Promise<void> {\n if (!this.ctx) return;\n const cfg = this.ctx.config;\n const list = cfg.playlist ?? this.playlist;\n if (!list || list.length === 0) return;\n const idx = (this.playlistIndexSub.value ?? 0) + 1;\n if (idx >= list.length) return;\n await this.load(cfg, { playlistIndex: idx, startTimeSec: 0 });\n}\n\nasync previous(): Promise<void> {\n if (!this.ctx) return;\n const cfg = this.ctx.config;\n const list = cfg.playlist ?? this.playlist;\n if (!list || list.length === 0) return;\n const idx = (this.playlistIndexSub.value ?? 0) - 1;\n if (idx < 0) return;\n await this.load(cfg, { playlistIndex: idx, startTimeSec: 0 });\n}\n\n\nasync destroy(): Promise<void> {\n try {\n for (const p of this.plugins) {\n try { await p.onDestroy?.(this.ctx!); } catch { /* noop */ }\n }\n } finally {\n try { (this as any)._offEngine?.(); } catch {}\n try { await this.engine?.destroy(); } catch {}\n this.clearExternalTextTracks();\n this.engine = undefined;\n this.video = undefined;\n this.ctx = undefined;\n this.plugins = [];\n this.emitTelemetry('player:init','debug',{ destroyed: true });\n }\n}\n\n/** Emit a non-fatal error (does not transition to fatal error state). */\npublic emitNonFatal(err: unknown, code: PlayerErrorCode | string = 'UNKNOWN'): void {\n const pe = this.toPlayerError(err, false, code);\n this.lastNonFatal = pe;\n this.emitTelemetry('player:error_nonfatal', 'warn', { code: pe.code }, pe.message);\n // let plugins observe if they subscribe to error$ externally\n this.errorSub.next(pe);\n}\n\n/** Emit a fatal error (transitions to error state). */\nprivate emitFatal(err: unknown, code: PlayerErrorCode | string = 'UNKNOWN'): void {\n const pe = this.toPlayerError(err, true, code);\n this.emitTelemetry('player:error_fatal', 'error', { code: pe.code }, pe.message);\n this.stateSub.next({ kind: 'error', error: pe });\n this.errorSub.next(pe);\n // notify plugins\n if (this.ctx) {\n for (const p of this.plugins) {\n try { void p.onError?.(this.ctx, pe); } catch { /* noop */ }\n }\n }\n}\n\nprivate async tryAutoNext(): Promise<void> {\n if (!this.ctx) return;\n const cfg = this.ctx.config;\n const list = cfg.playlist ?? this.playlist;\n if (!list || list.length === 0) return;\n const auto = cfg.autoNext ?? true;\n if (!auto) return;\n const idx = this.playlistIndexSub.value ?? 0;\n if (idx >= list.length - 1) return;\n\n const nextIdx = idx + 1;\n this.emitTelemetry('player:auto_next','info',{ from: idx, to: nextIdx, total: list.length });\n try {\n await this.load(cfg, { playlistIndex: nextIdx, startTimeSec: 0 });\n } catch {\n // handled by load\n }\n}\n\n\nprivate installed = false;\n\n // QoE metrics (v1.7)\n private qoe = {\n loadStartMs: 0,\n firstFrameMs: 0,\n startupMs: 0,\n rebufferCount: 0,\n rebufferMs: 0,\n rebufferStartMs: 0 as number | 0,\n firstFrameEmitted: false\n };\nprivate installVideoEventListeners(): void {\n const v = this.video;\n if (!v || this.installed) return;\n this.installed = true;\n\n const nowMs = () => (globalThis.performance?.now?.() ?? Date.now());\n\n const maybeFirstFrame = () => {\n if (this.qoe.firstFrameEmitted) return;\n const t = nowMs();\n this.qoe.firstFrameMs = t;\n if (this.qoe.loadStartMs) this.qoe.startupMs = Math.max(0, t - this.qoe.loadStartMs);\n this.qoe.firstFrameEmitted = true;\n this.emitTelemetry('qoe:first_frame','info', { firstFrameMs: this.qoe.startupMs });\n };\n\n const maybeEndRebuffer = () => {\n if (!this.qoe.rebufferStartMs) return;\n const t = nowMs();\n const delta = Math.max(0, t - this.qoe.rebufferStartMs);\n this.qoe.rebufferMs += delta;\n this.qoe.rebufferStartMs = 0;\n this.emitTelemetry('qoe:rebuffer_end','debug', { deltaMs: delta, totalMs: this.qoe.rebufferMs, count: this.qoe.rebufferCount });\n };\n\n v.addEventListener('timeupdate', () => {\n this.emitTelemetry('player:timeupdate', 'debug', { t: v.currentTime, d: v.duration });\n });\n\nv.addEventListener('loadeddata', () => {\n // First frame decoded (often the best proxy)\n maybeFirstFrame();\n});\n\nv.addEventListener('playing', () => {\n // Playback actually started\n maybeFirstFrame();\n maybeEndRebuffer();\n this.emitTelemetry('player:playing', 'info');\n});\n\nv.addEventListener('waiting', () => {\n // Rebuffering\n if (!this.qoe.rebufferStartMs) {\n this.qoe.rebufferCount += 1;\n this.qoe.rebufferStartMs = nowMs();\n this.emitTelemetry('qoe:rebuffer_start','debug', { count: this.qoe.rebufferCount });\n }\n});\n\nv.addEventListener('stalled', () => {\n if (!this.qoe.rebufferStartMs) {\n this.qoe.rebufferCount += 1;\n this.qoe.rebufferStartMs = nowMs();\n this.emitTelemetry('qoe:rebuffer_start','debug', { count: this.qoe.rebufferCount, reason: 'stalled' });\n }\n});\n\n\n v.addEventListener('ended', () => {\n maybeEndRebuffer();\n this.emitTelemetry('player:ended', 'info');\n this.emitTelemetry('qoe:summary','info', { startupMs: this.qoe.startupMs, rebufferCount: this.qoe.rebufferCount, rebufferMs: this.qoe.rebufferMs });\n void this.tryAutoNext();\n });\n\n v.addEventListener('pause', () => {\n this.emitTelemetry('player:pause', 'info');\n });\n\n v.addEventListener('error', () => {\n const me = v.error;\n if (!me) return;\n const codeMap: Record<number, PlayerErrorCode> = {\n 1: 'UNKNOWN',\n 2: 'NETWORK_HTTP',\n 3: 'DECODE_ERROR',\n 4: 'SRC_NOT_SUPPORTED'\n };\n const c = codeMap[me.code] ?? 'UNKNOWN';\n this.emitFatal(me, c);\n });\n}\n\nprivate emitTelemetry(event: TelemetryEvent, level: TelemetryLevel = 'info', data?: Record<string, unknown>, message?: string): void {\n try {\n const cfg = this.ctx?.config;\n const contentId = cfg?.source?.contentId;\n const sample: TelemetrySample = {\n ts: Date.now(),\n level,\n event,\n contentId,\n engineId: this.engineId,\n message,\n data\n };\n this.ports.telemetry.add(sample as any);\n } catch { /* noop */ }\n}\n\nprivate toPlayerError(err: unknown, fatal: boolean, code: PlayerErrorCode | string = 'UNKNOWN'): PlayerError {\n const e: any = err as any;\n const msg = e?.message ? String(e.message) : String(err ?? 'Unknown error');\n return { code, message: msg, fatal, details: e };\n}\n async play(): Promise<void> {\n this.emitTelemetry('player:play_request','info');\n try {\n await this.engine?.play();\n this.emitTelemetry('player:play_ok','info');\n } catch (err) {\n const name = (err as any)?.name;\n if (name === 'AbortError') {\n // A newer load() or pause() superseded this request: not a playback failure.\n this.emitTelemetry('player:play_aborted','info', {}, (err as any)?.message);\n return;\n }\n if (name === 'NotAllowedError') {\n this.emitNonFatal(err, 'AUTOPLAY_BLOCKED');\n this.emitTelemetry('player:play_fail','warn',{ code: 'AUTOPLAY_BLOCKED' }, (err as any)?.message);\n } else if (name === 'RemotePlaybackError') {\n // A device refused the media: its reason (format, codec, no answer) is what the host has to show.\n const code = remotePlaybackErrorCode((err as any).code);\n this.emitFatal(err, code);\n this.emitTelemetry('player:play_fail','error',{ code }, (err as any)?.message);\n } else {\n this.emitFatal(err, 'UNKNOWN');\n this.emitTelemetry('player:play_fail','error',{ code: 'UNKNOWN' }, (err as any)?.message);\n }\n throw err;\n }\n }\n async pause(): Promise<void> { await this.engine?.pause(); }\n /**\n * Seeks the attached engine. Resolves to false when no engine can take the request yet (a load is replacing it), so\n * callers keep the position and apply it once the media is ready instead of assuming it happened.\n */\n async seekTo(timeSec: number): Promise<boolean> {\n const engine = this.engine;\n if (!engine) return false;\n await engine.seekTo(timeSec);\n return true;\n }\n async setRate(rate: number): Promise<void> { await this.engine?.setPlaybackRate(rate); }\n async setVolume(volume: number): Promise<void> { await this.engine?.setVolume(volume); }\n\n /**\n * Shows a text track: one of the engine's, one loaded from a file (`addExternalTextTrack`), or none (null).\n * \"external\" still names the last file loaded.\n */\n async setTextTrack(trackId: string | null): Promise<void> {\n const id = trackId === 'external' ? this.externalTexts[this.externalTexts.length - 1]?.id ?? null : trackId;\n const external = this.externalTexts.find((text) => text.id === id);\n this.showExternalText(external);\n // The engine hides its own subtitles while a file's are shown.\n await this.engine?.setTextTrack(external ? null : id);\n this.textSelection = id;\n this.emitTracks();\n }\n\n /** Adds subtitles read from a file (WebVTT) to the media playing, and shows them; resolves to the new track's id. */\n async addExternalTextTrack(text: { label: string; language?: string; vtt: string }): Promise<string> {\n if (!this.video) throw new Error('PlayerFacade not attached');\n const id = `external:${++this.externalTextCount}`;\n const url = URL.createObjectURL(new Blob([text.vtt], { type: 'text/vtt' }));\n const element = document.createElement('track');\n element.kind = 'subtitles';\n element.label = text.label;\n if (text.language) element.srclang = text.language;\n element.src = url;\n element.setAttribute('data-external', 'true');\n this.video.appendChild(element);\n element.track.mode = 'disabled';\n this.externalTexts.push({ id, label: text.label, ...(text.language ? { language: text.language } : {}), url, element });\n await this.setTextTrack(id);\n return id;\n }\n async setAudioTrack(trackId: string | null): Promise<void> { await this.engine?.setAudioTrack(trackId); }\n async setVideoTrack(trackId: string | null): Promise<void> { await this.engine?.setVideoTrack(trackId); }\n\n // UI helpers\n setAspectRatio(_mode: AspectRatioMode): void {\n // UI component controls CSS class; facade keeps it as state if needed in your app.\n }\n\n snapshot(): PlayerSnapshot {\n const time = this.timeSub.value;\n return {\n currentTime: time.currentTime,\n duration: time.duration,\n state: this.stateSub.value,\n bufferedAheadSec: this.bufferSub.value\n };\n }\n\n /**\n * Diagnostics helper for UI / support logs.\n * Safe to call anytime after attach().\n */\n diagnostics(): PlayerDiagnostics {\n const snap = this.snapshot();\n const bufferedEnd = (snap.currentTime ?? 0) + (snap.bufferedAheadSec ?? 0);\n const time: PlayerTime = {\n currentTime: snap.currentTime,\n duration: snap.duration,\n bufferedEnd\n };\n const engine: DiagnosticsEngineInfo = {\n id: this.engine?.id ?? 'none',\n selectedBy: 'supports',\n reasons: []\n };\n const source = (this.ctx?.config as any)?.source as PlayerSource | undefined;\n return {\n ts: Date.now(),\n engine,\n capabilities: createCapabilityReport(\n this.video ?? undefined,\n this.ctx?.config,\n this.mediaDecodingSub.value ?? undefined\n ),\n source,\n state: snap.state,\n time,\n lastNonFatal: this.lastNonFatal,\n\n // backward compat\n selectedEngineId: engine.id,\n snapshot: {\n currentTime: snap.currentTime,\n duration: snap.duration,\n state: snap.state,\n bufferedAheadSec: snap.bufferedAheadSec\n }\n };\n }\n\n // External tracks (for provider-based subtitles)\n async setExternalVttTrack(lang: string, vtt: string): Promise<void> {\n if (!this.video) return;\n await this.addExternalTextTrack({ label: `External (${lang})`, language: lang, vtt });\n }\n\n setMetadata(meta: VideoMetadata): void { this.metadataSub.next(meta); }\n\n /** Shows `shown` (its cues go to `captionCues$`, the browser draws none) and turns the other files' subtitles off. */\n private showExternalText(shown: { element: HTMLTrackElement } | undefined): void {\n this.offCueChange?.();\n this.offCueChange = undefined;\n for (const text of this.externalTexts) {\n if (text !== shown) text.element.track.mode = 'disabled';\n }\n if (!shown) {\n this.captionCuesSub.next([]);\n return;\n }\n const track = shown.element.track;\n track.mode = 'hidden';\n const publish = () => this.captionCuesSub.next(Array.from(track.activeCues ?? []));\n track.addEventListener('cuechange', publish);\n this.offCueChange = () => track.removeEventListener('cuechange', publish);\n publish();\n }\n\n private clearExternalTextTracks(): void {\n const hadSelection = this.textSelection !== undefined || this.externalTexts.length > 0;\n this.showExternalText(undefined);\n for (const text of this.externalTexts) {\n text.element.remove();\n URL.revokeObjectURL(text.url);\n }\n this.externalTexts = [];\n this.textSelection = undefined;\n if (hadSelection) this.emitTracks();\n }\n\n /** The engine's tracks and the loaded subtitles, the text track picked here marked active. */\n private emitTracks(): void {\n const selection = this.textSelection;\n const engine = selection === undefined\n ? this.engineTracks\n : this.engineTracks.map((track) => track.kind === 'text' ? { ...track, active: track.id === selection } : track);\n const external: MediaTrack[] = this.externalTexts.map((text) => ({\n id: text.id,\n kind: 'text',\n label: text.label,\n ...(text.language ? { language: text.language } : {}),\n active: text.id === selection,\n }));\n this.tracksSub.next([...engine, ...external]);\n }\n\n private handleEngineEvent(ev: EngineEvent): void {\n if (ev.type === 'timeupdate') {\n this.timeSub.next({ currentTime: ev.currentTime, duration: ev.duration });\n return;\n }\n if (ev.type === 'bufferupdate') {\n this.bufferSub.next(ev.bufferedAheadSec);\n return;\n }\n if (ev.type === 'tracks') {\n this.engineTracks = ev.tracks;\n this.emitTracks();\n return;\n }\n if (ev.type === 'state') {\n const map: Record<string, PlayerState> = {\n loading: { kind: 'loading' },\n buffering: { kind: 'buffering' },\n playing: { kind: 'playing' },\n paused: { kind: 'paused' },\n ended: { kind: 'ended' }\n };\n this.stateSub.next(map[ev.state] ?? { kind: 'idle' });\n try { this.ctx?.ports.telemetry.add({ t: Date.now(), kind: 'state', state: ev.state }); } catch { /* ignore */ }\n if (ev.state === 'ended') void this.tryAutoNext();\n return;\n }\n if (ev.type === 'error') {\n const pe: PlayerError = { code: ev.error.code, message: ev.error.message, fatal: ev.error.fatal, details: ev.error.details };\n this.stateSub.next({ kind: 'error', error: pe });\n this.errorSub.next(pe);\n try { this.ctx?.ports.telemetry.add({ t: Date.now(), kind: 'error', code: pe.code, fatal: !!pe.fatal }); } catch { /* ignore */ }\n if (this.ctx) for (const p of this.plugins) void p.onError?.(this.ctx, pe);\n return;\n }\n }\n\n private async tryRestoreStartTime(_config: PlayerConfig): Promise<number | null> {\n // Start time can be injected by ProgressPlugin through ctx.facade.seekTo after load.\n // Here we keep it null; the plugin may seek during onLoaded().\n return null;\n }\n}\n","import { MetadataProvider, MetadataHint, MetadataMatch, VideoMetadata } from '../metadata.types';\n\n/**\n * Local provider: loads sidecar metadata from a URL (json or txt).\n * - JSON: parsed into `VideoMetadata` where possible\n * - TXT: stored as description\n */\nexport class LocalMetadataProvider implements MetadataProvider {\n id = 'local';\n\n async match(_hint: MetadataHint): Promise<MetadataMatch[]> {\n // Match is resolved by the plugin using sidecar URL; nothing to match here.\n return [];\n }\n\n async fetch(id: string): Promise<VideoMetadata> {\n // Here `id` is expected to be a URL in the local provider.\n const res = await fetch(id);\n if (!res.ok) throw new Error(`Metadata fetch failed: ${res.status}`);\n const ct = res.headers.get('content-type') ?? '';\n const text = await res.text();\n\n if (ct.includes('application/json') || looksLikeJson(text)) {\n try { return JSON.parse(text) as VideoMetadata; } catch { /* fallthrough */ }\n }\n return { description: text };\n }\n}\n\nfunction looksLikeJson(t: string): boolean {\n const s = t.trim();\n return (s.startsWith('{') && s.endsWith('}')) || (s.startsWith('[') && s.endsWith(']'));\n}\n","import { SubtitleProvider, SubtitleCandidate, SubtitleQuery } from '../subtitles.types';\n\n/**\n * Local provider: uses `config.source.sidecar.subtitles` entries as candidates.\n */\nexport class LocalSubtitleProvider implements SubtitleProvider {\n id = 'local';\n\n async search(query: SubtitleQuery): Promise<SubtitleCandidate[]> {\n // This provider doesn't search globally. The plugin will pass sidecar items directly.\n return [];\n }\n\n async fetch(candidate: SubtitleCandidate): Promise<string | ArrayBuffer> {\n if (!candidate.url) throw new Error('LocalSubtitleProvider: candidate.url is required');\n const res = await fetch(candidate.url);\n if (!res.ok) throw new Error(`Subtitle fetch failed: ${res.status}`);\n return await res.text();\n }\n}\n","/**\n * Subtitle files the viewer loads next to a video: SubRip (.srt) or WebVTT (.vtt), in whatever encoding they were\n * saved (UTF-8 today, Windows-1252 for many older French files). The player reads WebVTT only, so SubRip is turned\n * into it.\n */\n\n/** The text of a subtitle file: UTF-8 (with or without its byte order mark), else Windows-1252. */\nexport function decodeSubtitleBytes(bytes: Uint8Array): string {\n if (bytes[0] === 0xff && bytes[1] === 0xfe) return new TextDecoder('utf-16le').decode(bytes.subarray(2));\n if (bytes[0] === 0xfe && bytes[1] === 0xff) return new TextDecoder('utf-16be').decode(bytes.subarray(2));\n const body = bytes[0] === 0xef && bytes[1] === 0xbb && bytes[2] === 0xbf ? bytes.subarray(3) : bytes;\n try {\n return new TextDecoder('utf-8', { fatal: true }).decode(body);\n } catch {\n return new TextDecoder('windows-1252').decode(body);\n }\n}\n\n/** WebVTT from the text of a .vtt or .srt file. */\nexport function subtitleTextToVtt(text: string): string {\n const lines = text.replace(/^/, '').replace(/\\r\\n?/g, '\\n');\n if (/^WEBVTT/.test(lines)) return lines;\n const body = lines\n // SubRip times use a comma before the milliseconds, WebVTT a dot.\n .replace(/(\\d{1,2}:\\d{2}:\\d{2}),(\\d{3})/g, '$1.$2')\n // Positioning tags of SubStation files saved as SubRip ({\\an8}) would show as text.\n .replace(/\\{\\\\[^}]*\\}/g, '')\n .trim();\n return `WEBVTT\\n\\n${body}\\n`;\n}\n\nconst LANGUAGE_NAMES: Record<string, string> = {\n fr: 'fr', fre: 'fr', fra: 'fr', french: 'fr', francais: 'fr', vf: 'fr', vostfr: 'fr',\n en: 'en', eng: 'en', english: 'en', anglais: 'en',\n es: 'es', spa: 'es', spanish: 'es', espanol: 'es',\n de: 'de', ger: 'de', deu: 'de', german: 'de', deutsch: 'de',\n it: 'it', ita: 'it', italian: 'it', italiano: 'it',\n pt: 'pt', por: 'pt', portuguese: 'pt',\n nl: 'nl', dut: 'nl', nld: 'nl', dutch: 'nl',\n ja: 'ja', jpn: 'ja', japanese: 'ja',\n ar: 'ar', ara: 'ar', arabic: 'ar',\n};\n\n/** The subtitle's name and language, from its file name: \"Film.fr.srt\" is \"Film\", in French. */\nexport function describeSubtitleFile(fileName: string): { label: string; language?: string } {\n const base = fileName.replace(/\\.(srt|vtt)$/i, '');\n const parts = base.split('.');\n const tag = parts.length > 1 ? parts[parts.length - 1].normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase() : '';\n const language = LANGUAGE_NAMES[tag];\n return { label: base, ...(language ? { language } : {}) };\n}\n","export interface CacheStore {\n get<T>(key: string): Promise<T | null>;\n set<T>(key: string, value: T, ttlMs: number): Promise<void>;\n del(key: string): Promise<void>;\n}\n\nexport class DefaultCacheStore implements CacheStore {\n private dbp: Promise<IDBDatabase | null> | null = null;\n\n async get<T>(key: string): Promise<T | null> {\n const db = await this.db();\n if (db) return idbGet<T>(db, key);\n return lsGet<T>(key);\n }\n\n async set<T>(key: string, value: T, ttlMs: number): Promise<void> {\n const payload = { value, exp: Date.now() + ttlMs };\n const db = await this.db();\n if (db) return idbSet(db, key, payload);\n lsSet(key, payload);\n }\n\n async del(key: string): Promise<void> {\n const db = await this.db();\n if (db) return idbDel(db, key);\n localStorage.removeItem(key);\n }\n\n private db(): Promise<IDBDatabase | null> {\n if (typeof indexedDB === 'undefined') return Promise.resolve(null);\n if (!this.dbp) this.dbp = openDb();\n return this.dbp;\n }\n}\n\nconst DB_NAME = 'ngx-smart-player-cache';\nconst STORE = 'kv';\n\nfunction openDb(): Promise<IDBDatabase | null> {\n return new Promise((resolve) => {\n const req = indexedDB.open(DB_NAME, 1);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE);\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => resolve(null);\n });\n}\n\nasync function idbGet<T>(db: IDBDatabase, key: string): Promise<T | null> {\n return new Promise((resolve) => {\n const tx = db.transaction(STORE, 'readonly');\n const st = tx.objectStore(STORE);\n const req = st.get(key);\n req.onsuccess = () => {\n const v = req.result;\n if (!v) return resolve(null);\n if (v.exp && Date.now() > v.exp) return resolve(null);\n resolve(v.value as T);\n };\n req.onerror = () => resolve(null);\n });\n}\n\nasync function idbSet(db: IDBDatabase, key: string, val: any): Promise<void> {\n return new Promise((resolve) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).put(val, key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n });\n}\n\nasync function idbDel(db: IDBDatabase, key: string): Promise<void> {\n return new Promise((resolve) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).delete(key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => resolve();\n });\n}\n\nfunction lsGet<T>(key: string): T | null {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n try {\n const v = JSON.parse(raw);\n if (v?.exp && Date.now() > v.exp) return null;\n return (v?.value as T) ?? null;\n } catch { return null; }\n}\n\nfunction lsSet(key: string, val: any): void {\n try { localStorage.setItem(key, JSON.stringify(val)); } catch {}\n}\n","export type PlayerCommand =\n | { type: 'play' }\n | { type: 'pause' }\n | { type: 'toggle' }\n | { type: 'seek'; to: number }\n | { type: 'setPlaybackRate'; rate: number }\n | { type: 'setVolume'; volume: number }\n | { type: 'setMuted'; muted: boolean }\n | { type: 'selectTextTrack'; id: string }\n | { type: 'disableTextTrack' }\n | { type: 'selectAudioTrack'; id: string }\n | { type: 'requestPiP' }\n | { type: 'exitPiP' }\n | { type: 'requestFullscreen' }\n | { type: 'exitFullscreen' }\n | { type: 'requestCast' }\n | { type: 'stopCast' };\n\nexport function isCategorizedEventType(type: string): boolean {\n return /^(playback|engine|network|drm|ads|subtitles|ui):/.test(type);\n}\n","import type { PlayerEvent } from '../types';\n\nexport type Unsubscribe = () => void;\n\nexport interface PlayerEventBus {\n emit(event: PlayerEvent): void;\n on<T extends PlayerEvent['type']>(\n type: T,\n handler: (e: Extract<PlayerEvent, { type: T }>) => void\n ): Unsubscribe;\n}\n\nexport class SimpleEventBus implements PlayerEventBus {\n private handlers = new Map<string, Set<(e: any) => void>>();\n\n emit(event: PlayerEvent): void {\n const set = this.handlers.get(event.type);\n if (!set) return;\n for (const h of Array.from(set)) h(event as any);\n }\n\n on<T extends PlayerEvent['type']>(type: T, handler: (e: Extract<PlayerEvent, { type: T }>) => void): Unsubscribe {\n const set = this.handlers.get(type) ?? new Set();\n set.add(handler as any);\n this.handlers.set(type, set);\n return () => set.delete(handler as any);\n }\n}\n","import type { PlayerPlugin, PlayerContext } from '../plugin';\n\ninterface ProgressRecord {\n contentId: string;\n positionSec: number;\n updatedAt: number;\n durationSec?: number;\n}\n\nfunction keyFor(contentId: string): string {\n return `progress:${contentId}`;\n}\n\nexport class ProgressPlugin implements PlayerPlugin {\n readonly id = 'progress';\n private timer: any = null;\n\n async onLoadStart(ctx: PlayerContext): Promise<void> {\n this.stop();\n // nothing else; restore happens onLoaded (engine ready)\n }\n\n async onLoaded(ctx: PlayerContext): Promise<void> {\n const contentId = ctx.contentId ?? ctx.config.source.contentId;\n if (!contentId) return;\n\n // Restore (local)\n try {\n if (ctx.config.progress.mode === 'local' || ctx.config.progress.mode === 'hybrid') {\n const raw = await ctx.ports.storage.get(keyFor(contentId));\n if (raw) {\n const rec = JSON.parse(raw) as ProgressRecord;\n if (Number.isFinite(rec.positionSec) && rec.positionSec > 0) {\n // seek after load\n await ctx.facade.seekTo(rec.positionSec);\n }\n }\n }\n } catch (e) {\n ctx.ports.log.warn('[ProgressPlugin] restore failed', e);\n }\n\n // Start periodic save\n const intervalMs = Math.max(3, ctx.config.progress.intervalSec ?? 10) * 1000;\n this.timer = setInterval(() => void this.save(ctx), intervalMs);\n }\n\n async onDestroy(ctx: PlayerContext): Promise<void> {\n this.stop();\n // final save\n await this.save(ctx);\n }\n\n private stop(): void {\n if (this.timer) { clearInterval(this.timer); this.timer = null; }\n }\n\n private async save(ctx: PlayerContext): Promise<void> {\n const contentId = ctx.contentId ?? ctx.config.source.contentId;\n if (!contentId) return;\n\n const snap = ctx.facade.snapshot();\n const positionSec = Math.max(0, snap.currentTime);\n const rec: ProgressRecord = {\n contentId,\n positionSec,\n durationSec: snap.duration || undefined,\n updatedAt: Date.now()\n };\n\n // Local storage\n try {\n if (ctx.config.progress.mode === 'local' || ctx.config.progress.mode === 'hybrid') {\n await ctx.ports.storage.set(keyFor(contentId), JSON.stringify(rec));\n }\n } catch (e) {\n ctx.ports.log.warn('[ProgressPlugin] local save failed', e);\n }\n\n // Server persistence (best-effort)\n try {\n if ((ctx.config.progress.mode === 'server' || ctx.config.progress.mode === 'hybrid') && ctx.config.progress.endpoint) {\n await ctx.ports.http.fetch(ctx.config.progress.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(rec)\n });\n }\n } catch (e) {\n ctx.ports.log.warn('[ProgressPlugin] server save failed', e);\n }\n }\n}\n","import type { PlayerPlugin, PlayerContext } from '../plugin';\nimport type { PlayerError } from '../../types';\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nexport class ResiliencePlugin implements PlayerPlugin {\n readonly id = 'resilience';\n private attempts = 0;\n private recovering = false;\n /** Bumped by every load: a retry only reloads the media that failed, never one loaded since. */\n private loadGeneration = 0;\n\n async onLoadStart(ctx: PlayerContext): Promise<void> {\n this.loadGeneration++;\n this.attempts = 0;\n this.recovering = false;\n // optional health check at load\n if (ctx.config.resilience.healthEndpoint) {\n void this.health(ctx);\n }\n }\n\n async onError(ctx: PlayerContext, err: PlayerError): Promise<void> {\n if (this.recovering) return;\n if (err.fatal) return;\n\n const max = Math.max(0, ctx.config.resilience.retries ?? 0);\n if (this.attempts >= max) return;\n\n this.attempts++;\n this.recovering = true;\n const generation = this.loadGeneration;\n\n const min = ctx.config.resilience.backoffMs?.min ?? 500;\n const maxMs = ctx.config.resilience.backoffMs?.max ?? 8000;\n const backoff = Math.min(maxMs, min * Math.pow(2, this.attempts - 1));\n\n ctx.ports.log.warn('[ResiliencePlugin] retry', { attempt: this.attempts, backoff, code: err.code });\n\n // optional health token refresh\n if (ctx.config.resilience.healthEndpoint) {\n await this.health(ctx);\n }\n\n await sleep(backoff);\n\n // Another media was loaded while waiting (the listener moved on, often because this one was interrupted): reloading\n // now would load that one again, at the failed media's position. It owns playback; the retry is dropped.\n if (generation !== this.loadGeneration) return;\n\n try {\n const snap = ctx.facade.snapshot();\n await ctx.facade.reload({ startTimeSec: snap.currentTime || undefined });\n } catch (e) {\n ctx.ports.log.error('[ResiliencePlugin] reload failed', e);\n } finally {\n this.recovering = false;\n }\n }\n\n private async health(ctx: PlayerContext): Promise<void> {\n try {\n await ctx.ports.http.fetch(ctx.config.resilience.healthEndpoint!, { method: 'GET' });\n } catch (e) {\n ctx.ports.log.warn('[ResiliencePlugin] health check failed', e);\n }\n }\n}\n","import type { PlayerContext, PlayerPlugin } from '../plugin';\n\n/**\n * SSAI helper (v1.11)\n *\n * Keeps the core decoupled from vendor SDKs.\n * This plugin rewrites the manifest URL before the engine loads it.\n */\n\nexport interface SsaiManifestRewriteConfig {\n /** If provided, used as the final playback URL (highest priority). */\n stitchedUrl?: string;\n /** Append query parameters to the source URL (e.g. session, device). */\n appendQuery?: Record<string, string | number | boolean | null | undefined>;\n}\n\nfunction appendQuery(url: string, q: Record<string, any>): string {\n try {\n const base = typeof window !== 'undefined' ? window.location.href : 'http://localhost';\n const u = new URL(url, base);\n for (const [k, v] of Object.entries(q)) {\n if (v === undefined || v === null) continue;\n u.searchParams.set(k, String(v));\n }\n return u.toString();\n } catch {\n return url;\n }\n}\n\nexport function createSsaiManifestRewritePlugin(): PlayerPlugin {\n return {\n id: 'ads:ssai-manifest-rewrite',\n\n async onLoadStart(ctx: PlayerContext): Promise<void> {\n const ads: any = (ctx.config as any)?.ads;\n if (!ads || ads.enabled !== true) return;\n if (ads.mode !== 'ssai') return;\n\n const provider: SsaiManifestRewriteConfig = (ads.providerConfig ?? {}) as any;\n const src: any = (ctx.config as any)?.source;\n if (!src || typeof src.url !== 'string' || !src.url) return;\n\n const before = src.url;\n let after = before;\n if (provider.stitchedUrl) after = provider.stitchedUrl;\n if (provider.appendQuery) after = appendQuery(after, provider.appendQuery);\n\n if (after !== before) {\n src.url = after;\n ctx.ports.telemetry?.add?.({\n event: 'ssai:manifest_rewrite',\n level: 'info',\n ts: Date.now(),\n payload: { before, after }\n } as any);\n }\n }\n };\n}\n","import type { PlayerConfig, PlayerSource, MediaTrack } from '../types';\nimport { RemotePlaybackError, type RemotePlaybackMedia, type RemotePlaybackSession, type RemotePlaybackStatus } from '../domain/remote-playback';\nimport type { EngineFactory } from './engine-factory';\nimport type { EngineEvent, LoadOptions, PlaybackEngine } from './playback-engine';\n\nexport interface RemotePlaybackEngineOptions {\n /** The device session media goes to; the engine only claims sources while one is set. */\n session: () => RemotePlaybackSession | null;\n /** What to send for a source: an address the device can reach, its type and display metadata. */\n media: (source: PlayerSource, startSec: number) => RemotePlaybackMedia | Promise<RemotePlaybackMedia>;\n /**\n * The same media converted on the fly (`conversion`), for a device that refuses it as it is: a format or a codec\n * it does not read. Only where the app can convert; the device gets it once it has refused the original.\n */\n convertedMedia?: (source: PlayerSource, startSec: number) => Promise<RemotePlaybackMedia>;\n /** How often the device is asked where it is. */\n pollMs?: number;\n /** Above the native (0) and adaptive engines, so a session takes every source. */\n priority?: number;\n}\n\n/**\n * Plays through a remote device (DLNA renderer, Cast device) with the player's own controls. Like a media element,\n * loading prepares the media and playing starts it: the device receives it on the first `play`, from the position\n * reached until then. The device's position and state come back by polling. A device that refuses a media gets it\n * converted when the app can convert it; a converted stream seeks by starting again from the new position.\n */\nexport function createRemotePlaybackEngineFactory(options: RemotePlaybackEngineOptions): EngineFactory {\n return {\n id: 'remote',\n priority: options.priority ?? 100,\n supports: (config: PlayerConfig) => options.session() !== null && !!config.source.url,\n supportsWithCaps: (config: PlayerConfig) => options.session() !== null && !!config.source.url,\n create: () => new RemotePlaybackEngine(options),\n };\n}\n\nexport class RemotePlaybackEngine implements PlaybackEngine {\n readonly id = 'remote';\n private readonly listeners = new Set<(event: EngineEvent) => void>();\n private session: RemotePlaybackSession | null = null;\n private source: PlayerSource | null = null;\n /** What the device plays, as the app described it. */\n private media: RemotePlaybackMedia | null = null;\n private startSec = 0;\n private sent = false;\n /** The device played the media to its end: it closed it, and only takes it again sent anew. */\n private finished = false;\n private durationSec = 0;\n private positionSec = 0;\n /** Where a converted stream starts in the media: the device counts from there. */\n private offsetSec = 0;\n /** Furthest position the device reported since the media was sent: an end before any progress is a refusal. */\n private furthestSec = 0;\n private conversionTried = false;\n private lastState: RemotePlaybackStatus['state'] | null = null;\n private timer: ReturnType<typeof setInterval> | undefined;\n private polling = false;\n private failures = 0;\n private destroyed = false;\n\n constructor(private readonly options: RemotePlaybackEngineOptions) {}\n\n async attach(videoEl: HTMLVideoElement): Promise<void> {\n // Nothing plays on this device while another one does.\n try {\n videoEl.pause();\n while (videoEl.firstChild) videoEl.removeChild(videoEl.firstChild);\n videoEl.removeAttribute('src');\n videoEl.load();\n } catch {\n // Test environments without media support.\n }\n }\n\n async load(source: PlayerSource, opts?: LoadOptions): Promise<void> {\n this.session = this.options.session();\n if (!this.session) throw new Error('No remote device is selected');\n this.source = source;\n this.media = null;\n this.startSec = Math.max(0, opts?.startTimeSec ?? 0);\n this.positionSec = this.startSec;\n this.offsetSec = 0;\n this.sent = false;\n this.finished = false;\n this.furthestSec = 0;\n this.conversionTried = false;\n this.lastState = null;\n this.emit({ type: 'timeupdate', currentTime: this.positionSec, duration: this.durationSec });\n }\n\n async play(): Promise<void> {\n const session = this.requireSession();\n // Played again after its end (repeat, or play pressed on the ended media): from the start unless a seek said.\n if (this.finished) this.restartAt(0);\n if (!this.sent) {\n this.emit({ type: 'state', state: 'loading' });\n // The same media again (converted if it was): the device refused the original once already.\n const media = this.media ?? await this.options.media(this.source as PlayerSource, this.startSec);\n if (this.destroyed) return;\n try {\n await this.send(session, media, this.startSec);\n } catch (error) {\n if (!this.convertible(media) || !(error instanceof RemotePlaybackError)) throw error;\n // Refused as it is (Cast devices refuse some formats before loading anything): the device may read it converted.\n this.conversionTried = true;\n const converted = await this.options.convertedMedia!(this.source as PlayerSource, this.startSec).catch(() => {\n throw error;\n });\n if (this.destroyed) return;\n await this.send(session, converted, this.startSec);\n }\n this.sent = true;\n this.startPolling();\n } else {\n await session.play();\n }\n this.lastState = 'playing';\n this.emit({ type: 'state', state: 'playing' });\n }\n\n async pause(): Promise<void> {\n if (!this.sent) return;\n await this.requireSession().pause();\n this.lastState = 'paused';\n this.emit({ type: 'state', state: 'paused' });\n }\n\n async seekTo(timeSec: number): Promise<void> {\n const target = Math.max(0, timeSec);\n this.positionSec = target;\n if (!this.sent || this.finished) {\n // Not on the device (yet, or any more): the next play sends it from here.\n this.restartAt(target);\n } else if (this.media?.conversion) {\n // A converted stream cannot seek: it starts again from the new position, as it was (playing or paused).\n const session = this.requireSession();\n const paused = this.lastState === 'paused';\n await this.send(session, this.media, target);\n if (paused) await session.pause();\n } else {\n await this.requireSession().seek(target);\n }\n this.emit({ type: 'timeupdate', currentTime: target, duration: this.durationSec });\n }\n\n async setVolume(volume: number): Promise<void> {\n if (!this.session) return;\n await this.session.setVolume(Math.min(1, Math.max(0, volume))).catch(() => undefined);\n }\n\n async setPlaybackRate(_rate: number): Promise<void> { /* devices play at normal speed */ }\n async setTextTrack(_trackId: string | null): Promise<void> { /* not sent to devices */ }\n async setAudioTrack(_trackId: string | null): Promise<void> { /* not sent to devices */ }\n async setVideoTrack(_trackId: string | null): Promise<void> { /* not sent to devices */ }\n async getTracks(): Promise<MediaTrack[]> { return []; }\n\n onEvent(cb: (event: EngineEvent) => void): () => void {\n this.listeners.add(cb);\n return () => this.listeners.delete(cb);\n }\n\n /** Stops following the device; the session stays open for the next media. */\n async destroy(): Promise<void> {\n this.destroyed = true;\n if (this.timer) clearInterval(this.timer);\n this.timer = undefined;\n this.listeners.clear();\n }\n\n /** Reads the device once; exposed for hosts and tests that do not want to wait for the timer. */\n async poll(): Promise<void> {\n if (!this.session || !this.sent || this.polling || this.destroyed) return;\n this.polling = true;\n try {\n const status = await this.session.status();\n if (this.destroyed) return;\n this.failures = 0;\n // A converted stream has no length of its own for the device: the media's is the one to show.\n if (status.durationSec && !this.media?.conversion) this.durationSec = status.durationSec;\n if (status.positionSec !== undefined) this.positionSec = this.offsetSec + status.positionSec;\n this.furthestSec = Math.max(this.furthestSec, this.positionSec - this.offsetSec);\n const wasPlaying = this.lastState === 'playing' || this.lastState === 'buffering';\n // Devices that cannot play a media (a video on a speaker) often call it finished right away: that is not an\n // end to chain the queue from.\n const refused = (status.ended || status.state === 'stopped') && this.furthestSec < 1 && !this.source?.live && (status.ended || wasPlaying);\n if ((refused || status.error) && this.convertible(this.media)) {\n await this.convertAfterRefusal(status.error);\n return;\n }\n this.emit({ type: 'timeupdate', currentTime: this.positionSec, duration: this.durationSec });\n\n if (status.error) {\n this.emit({ type: 'error', error: { code: 'REMOTE_PLAYBACK', message: status.error, fatal: false } });\n }\n if (refused) {\n this.emit({ type: 'error', error: { code: 'REMOTE_PLAYBACK', message: status.error ?? 'The device could not play this media', fatal: false } });\n this.lastState = status.state;\n if (this.timer) clearInterval(this.timer);\n this.timer = undefined;\n return;\n }\n const nearEnd = this.durationSec > 0 && this.positionSec >= this.durationSec - 3;\n let state: EngineEvent & { type: 'state' } | null = null;\n if (status.state === 'playing') state = { type: 'state', state: 'playing' };\n else if (status.state === 'paused') state = { type: 'state', state: 'paused' };\n else if (status.state === 'buffering' || status.state === 'loading') state = { type: 'state', state: 'buffering' };\n else if (status.ended || (wasPlaying && nearEnd && !this.source?.live)) state = { type: 'state', state: 'ended' };\n else if (wasPlaying) state = { type: 'state', state: 'paused' };\n if (state?.state === 'ended') {\n // Before the end is told: the player answers it at once (repeat one plays again), and the device closed it.\n this.finished = true;\n if (this.timer) clearInterval(this.timer);\n this.timer = undefined;\n }\n if (state && status.state !== this.lastState) this.emit(state);\n this.lastState = status.state;\n } catch (error) {\n this.failures += 1;\n if (this.failures === 3) {\n this.emit({ type: 'error', error: { code: 'REMOTE_UNREACHABLE', message: error instanceof Error ? error.message : String(error), fatal: false } });\n }\n } finally {\n this.polling = false;\n }\n }\n\n private restartAt(positionSec: number): void {\n this.finished = false;\n this.sent = false;\n this.startSec = positionSec;\n }\n\n /** Sends a media to the device from a position of it; a converted stream starts there and counts from 0. */\n private async send(session: RemotePlaybackSession, media: RemotePlaybackMedia, startSec: number): Promise<void> {\n const conversion = media.conversion;\n this.durationSec = media.durationSec ?? 0;\n await session.load(conversion\n ? { ...media, url: conversion.at(startSec), startSec: 0, ...(media.durationSec ? { durationSec: Math.max(0, media.durationSec - startSec) } : {}) }\n : { ...media, startSec });\n this.media = media;\n this.offsetSec = conversion ? startSec : 0;\n this.positionSec = startSec;\n this.furthestSec = 0;\n }\n\n private convertible(media: RemotePlaybackMedia | null): boolean {\n return !!this.options.convertedMedia && !!media && !media.conversion && !media.live && !this.conversionTried;\n }\n\n /** The device gave up on the media as it is: it gets it converted, from where it was. */\n private async convertAfterRefusal(reason: string | undefined): Promise<void> {\n this.conversionTried = true;\n const position = this.positionSec;\n try {\n const converted = await this.options.convertedMedia!(this.source as PlayerSource, position);\n if (this.destroyed) return;\n await this.send(this.requireSession(), converted, position);\n this.lastState = 'playing';\n } catch {\n if (this.destroyed) return;\n this.emit({ type: 'error', error: { code: 'REMOTE_PLAYBACK', message: reason ?? 'The device could not play this media', fatal: false } });\n if (this.timer) clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n private startPolling(): void {\n if (this.timer || this.destroyed) return;\n this.timer = setInterval(() => void this.poll(), this.options.pollMs ?? 1000);\n }\n\n private requireSession(): RemotePlaybackSession {\n if (!this.session || this.destroyed) throw new Error('No remote device is selected');\n return this.session;\n }\n\n private emit(event: EngineEvent): void {\n for (const listener of this.listeners) listener(event);\n }\n}\n","import type { MediaItem } from './media-item';\n\nexport interface AudioTrack extends MediaItem {\n kind: 'audio';\n artist?: string;\n album?: string;\n albumArtist?: string;\n genre?: string;\n trackNo?: number;\n discNo?: number;\n year?: number;\n}\n\nexport interface AudioAlbum<TTrack extends AudioTrack = AudioTrack> {\n id: string;\n title: string;\n artist?: string;\n artwork?: string;\n year?: number;\n tracks: TTrack[];\n}\n\nexport interface AudioArtist<TTrack extends AudioTrack = AudioTrack> {\n id: string;\n name: string;\n artwork?: string;\n tracks: TTrack[];\n}\n\nexport interface AudioGenre<TTrack extends AudioTrack = AudioTrack> {\n id: string;\n name: string;\n tracks: TTrack[];\n}\n\nexport interface AudioPlaylist {\n id: string;\n name: string;\n description?: string;\n artwork?: string;\n trackIds: string[];\n}\n\nexport type AudioPlaylistRef = AudioPlaylist;\n\nexport interface AudioLibrarySnapshot<TTrack extends AudioTrack = AudioTrack> {\n tracks: TTrack[];\n albums: AudioAlbum<TTrack>[];\n artists: AudioArtist<TTrack>[];\n genres: AudioGenre<TTrack>[];\n playlists: AudioPlaylist[];\n}\n\nexport interface AudioLibrarySearchResult<TTrack extends AudioTrack = AudioTrack> extends AudioLibrarySnapshot<TTrack> {\n active: boolean;\n query: string;\n directTrackIds: string[];\n matchedTrackIds: string[];\n matchedAlbumIds: string[];\n matchedArtistIds: string[];\n matchedGenreIds: string[];\n matchedPlaylistIds: string[];\n}\n\nexport function createAudioLibrarySnapshot<TTrack extends AudioTrack>(\n tracks: readonly TTrack[],\n playlists: readonly AudioPlaylist[] = [],\n): AudioLibrarySnapshot<TTrack> {\n const trackCopies = tracks.map(cloneAudioTrack);\n\n return {\n tracks: trackCopies,\n albums: groupAudioAlbums(trackCopies),\n artists: groupAudioArtists(trackCopies),\n genres: groupAudioGenres(trackCopies),\n playlists: playlists.map((playlist) => ({ ...playlist, trackIds: [...playlist.trackIds] })),\n };\n}\n\nexport function searchAudioLibrarySnapshot<TTrack extends AudioTrack>(\n snapshot: AudioLibrarySnapshot<TTrack>,\n searchTerm: string,\n): AudioLibrarySearchResult<TTrack> {\n const query = normalizeAudioSearchText(searchTerm);\n\n if (!query) {\n return {\n ...cloneAudioLibrarySnapshot(snapshot),\n active: false,\n query,\n directTrackIds: [],\n matchedTrackIds: [],\n matchedAlbumIds: [],\n matchedArtistIds: [],\n matchedGenreIds: [],\n matchedPlaylistIds: [],\n };\n }\n\n const directTrackIds = ids(snapshot.tracks.filter((track) => metadataMatchesQuery(audioTrackSearchValues(track), query)));\n const matchedAlbumIds = ids(snapshot.albums.filter((album) => metadataMatchesQuery(audioAlbumSearchValues(album), query)));\n const matchedArtistIds = ids(snapshot.artists.filter((artist) => metadataMatchesQuery(audioArtistSearchValues(artist), query)));\n const matchedGenreIds = ids(snapshot.genres.filter((genre) => metadataMatchesQuery(audioGenreSearchValues(genre), query)));\n const matchedPlaylistIds = ids(snapshot.playlists.filter((playlist) => metadataMatchesQuery(audioPlaylistSearchValues(playlist), query)));\n const matchedTrackIds = new Set<string>(directTrackIds);\n\n for (const album of snapshot.albums) {\n if (matchedAlbumIds.includes(album.id)) addTrackIds(matchedTrackIds, album.tracks);\n }\n\n for (const artist of snapshot.artists) {\n if (matchedArtistIds.includes(artist.id)) addTrackIds(matchedTrackIds, artist.tracks);\n }\n\n for (const genre of snapshot.genres) {\n if (matchedGenreIds.includes(genre.id)) addTrackIds(matchedTrackIds, genre.tracks);\n }\n\n for (const playlist of snapshot.playlists) {\n if (matchedPlaylistIds.includes(playlist.id)) {\n playlist.trackIds.forEach((trackId) => matchedTrackIds.add(trackId));\n }\n }\n\n const matchedTracks = snapshot.tracks.filter((track) => matchedTrackIds.has(track.id));\n const matchedAlbums = snapshot.albums.filter((album) => (\n matchedAlbumIds.includes(album.id) || album.tracks.some((track) => matchedTrackIds.has(track.id))\n ));\n const matchedArtists = snapshot.artists.filter((artist) => (\n matchedArtistIds.includes(artist.id) || artist.tracks.some((track) => matchedTrackIds.has(track.id))\n ));\n const matchedGenres = snapshot.genres.filter((genre) => (\n matchedGenreIds.includes(genre.id) || genre.tracks.some((track) => matchedTrackIds.has(track.id))\n ));\n const matchedPlaylists = snapshot.playlists.filter((playlist) => (\n matchedPlaylistIds.includes(playlist.id)\n || (!matchedPlaylistIds.length && playlist.trackIds.some((trackId) => matchedTrackIds.has(trackId)))\n ));\n\n return {\n active: true,\n query,\n tracks: matchedTracks.map(cloneAudioTrack),\n albums: matchedAlbums.map(cloneAudioAlbum),\n artists: matchedArtists.map(cloneAudioArtist),\n genres: matchedGenres.map(cloneAudioGenre),\n playlists: matchedPlaylists.map(cloneAudioPlaylist),\n directTrackIds,\n matchedTrackIds: [...matchedTrackIds],\n matchedAlbumIds,\n matchedArtistIds,\n matchedGenreIds,\n matchedPlaylistIds,\n };\n}\n\nexport function normalizeAudioSearchText(value: string): string {\n return value.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '').toLowerCase().trim();\n}\n\nexport function audioTrackMatchesSearch(track: AudioTrack, searchTerm: string): boolean {\n const query = normalizeAudioSearchText(searchTerm);\n return !!query && metadataMatchesQuery(audioTrackSearchValues(track), query);\n}\n\n/** Albums share a title and, when tagged, an album artist; the most recent releases come first. */\nfunction groupAudioAlbums<TTrack extends AudioTrack>(tracks: readonly TTrack[]): AudioAlbum<TTrack>[] {\n const groups = groupByMetadata(\n tracks,\n (track) => track.album,\n (track) => track.albumArtist ? `${metadataGroupKey(track.albumArtist)}\\u0000` : '',\n );\n const titleCounts = new Map<string, number>();\n for (const [albumTitle] of groups) {\n const slug = slugifyAudioLibraryId(albumTitle);\n titleCounts.set(slug, (titleCounts.get(slug) ?? 0) + 1);\n }\n\n const albums = groups.map(([albumTitle, albumTracks]) => {\n const albumArtist = firstDefined(albumTracks.map((track) => track.albumArtist?.trim() || undefined));\n const slug = slugifyAudioLibraryId(albumTitle);\n return {\n // Same-title albums of different artists get the artist in their id to stay distinct.\n id: albumArtist && (titleCounts.get(slug) ?? 0) > 1\n ? `album:${slug}--${slugifyAudioLibraryId(albumArtist)}`\n : `album:${slug}`,\n title: albumTitle,\n artist: uniqueValues(albumTracks.map((track) => track.albumArtist ?? track.artist)).join(', ') || undefined,\n year: mostFrequentYear(albumTracks),\n artwork: firstDefined(albumTracks.map((track) => track.artwork?.[0]?.src)),\n tracks: albumTracks.map(cloneAudioTrack),\n };\n });\n\n return albums.sort((left, right) => (\n (right.year ?? Number.NEGATIVE_INFINITY) - (left.year ?? Number.NEGATIVE_INFINITY)\n || left.title.localeCompare(right.title, undefined, { sensitivity: 'base', numeric: true })\n ));\n}\n\nfunction groupAudioArtists<TTrack extends AudioTrack>(tracks: readonly TTrack[]): AudioArtist<TTrack>[] {\n return groupByMetadata(tracks, (track) => track.albumArtist ?? track.artist).map(([artistName, artistTracks]) => ({\n id: `artist:${slugifyAudioLibraryId(artistName)}`,\n name: artistName,\n artwork: firstDefined(artistTracks.map((track) => track.artwork?.[0]?.src)),\n tracks: artistTracks.map(cloneAudioTrack),\n }));\n}\n\nfunction groupAudioGenres<TTrack extends AudioTrack>(tracks: readonly TTrack[]): AudioGenre<TTrack>[] {\n return groupByMetadata(tracks, (track) => track.genre).map(([genreName, genreTracks]) => ({\n id: `genre:${slugifyAudioLibraryId(genreName)}`,\n name: genreName,\n tracks: genreTracks.map(cloneAudioTrack),\n }));\n}\n\nfunction cloneAudioLibrarySnapshot<TTrack extends AudioTrack>(\n snapshot: AudioLibrarySnapshot<TTrack>,\n): AudioLibrarySnapshot<TTrack> {\n return {\n tracks: snapshot.tracks.map(cloneAudioTrack),\n albums: snapshot.albums.map(cloneAudioAlbum),\n artists: snapshot.artists.map(cloneAudioArtist),\n genres: snapshot.genres.map(cloneAudioGenre),\n playlists: snapshot.playlists.map(cloneAudioPlaylist),\n };\n}\n\nfunction cloneAudioAlbum<TTrack extends AudioTrack>(album: AudioAlbum<TTrack>): AudioAlbum<TTrack> {\n return {\n ...album,\n tracks: album.tracks.map(cloneAudioTrack),\n };\n}\n\nfunction cloneAudioArtist<TTrack extends AudioTrack>(artist: AudioArtist<TTrack>): AudioArtist<TTrack> {\n return {\n ...artist,\n tracks: artist.tracks.map(cloneAudioTrack),\n };\n}\n\nfunction cloneAudioGenre<TTrack extends AudioTrack>(genre: AudioGenre<TTrack>): AudioGenre<TTrack> {\n return {\n ...genre,\n tracks: genre.tracks.map(cloneAudioTrack),\n };\n}\n\nfunction cloneAudioPlaylist(playlist: AudioPlaylist): AudioPlaylist {\n return {\n ...playlist,\n trackIds: [...playlist.trackIds],\n };\n}\n\nfunction cloneAudioTrack<TTrack extends AudioTrack>(track: TTrack): TTrack {\n return {\n ...track,\n artwork: track.artwork?.map((artwork) => ({ ...artwork })),\n } as TTrack;\n}\n\n/** Groups by a value regardless of case, accents or punctuation, named after its most frequent spelling. */\nfunction groupByMetadata<TTrack extends AudioTrack>(\n tracks: readonly TTrack[],\n pickValue: (track: TTrack) => string | undefined,\n scope: (track: TTrack) => string = () => '',\n): Array<[string, TTrack[]]> {\n const groups = new Map<string, { names: Map<string, number>; tracks: TTrack[] }>();\n for (const track of tracks) {\n const name = pickValue(track)?.trim();\n if (!name) continue;\n const key = scope(track) + (metadataGroupKey(name) || name);\n const group = groups.get(key) ?? { names: new Map<string, number>(), tracks: [] };\n group.names.set(name, (group.names.get(name) ?? 0) + 1);\n group.tracks.push(track);\n groups.set(key, group);\n }\n\n return [...groups.values()].map((group) => {\n const name = [...group.names].sort((left, right) => right[1] - left[1] || casingQuality(right[0]) - casingQuality(left[0]))[0][0];\n return [name, group.tracks];\n });\n}\n\nfunction casingQuality(value: string): number {\n return value !== value.toLowerCase() && value !== value.toUpperCase() ? 1 : 0;\n}\n\nfunction metadataGroupKey(value: string): string {\n return value\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/&/g, 'and')\n .replace(/[^\\p{L}\\p{N}]+/gu, '');\n}\n\nfunction mostFrequentYear(tracks: readonly AudioTrack[]): number | undefined {\n const counts = new Map<number, number>();\n for (const track of tracks) {\n if (track.year !== undefined) counts.set(track.year, (counts.get(track.year) ?? 0) + 1);\n }\n return [...counts].sort((left, right) => right[1] - left[1] || left[0] - right[0])[0]?.[0];\n}\n\nfunction uniqueValues(values: ReadonlyArray<string | undefined>): string[] {\n return [...new Set(values.flatMap((value) => {\n const cleanValue = value?.trim();\n return cleanValue ? [cleanValue] : [];\n }))];\n}\n\nfunction firstDefined<T>(values: ReadonlyArray<T | undefined>): T | undefined {\n return values.find((value): value is T => value !== undefined);\n}\n\nfunction addTrackIds(target: Set<string>, tracks: readonly AudioTrack[]): void {\n tracks.forEach((track) => target.add(track.id));\n}\n\nfunction ids(items: ReadonlyArray<{ id: string }>): string[] {\n return items.map((item) => item.id);\n}\n\nfunction audioTrackSearchValues(track: AudioTrack): SearchValue[] {\n return [\n track.title,\n track.artist,\n track.albumArtist,\n track.album,\n track.genre,\n track.subtitle,\n track.durationSec,\n track.trackNo,\n track.discNo,\n track.year,\n ];\n}\n\nfunction audioAlbumSearchValues(album: AudioAlbum): SearchValue[] {\n return [\n album.title,\n album.artist,\n album.year,\n ];\n}\n\nfunction audioArtistSearchValues(artist: AudioArtist): SearchValue[] {\n return [\n artist.name,\n ];\n}\n\nfunction audioGenreSearchValues(genre: AudioGenre): SearchValue[] {\n return [\n genre.name,\n ];\n}\n\nfunction audioPlaylistSearchValues(playlist: AudioPlaylist): SearchValue[] {\n return [\n playlist.name,\n playlist.description,\n ];\n}\n\ntype SearchValue = string | number | undefined;\n\nfunction metadataMatchesQuery(values: readonly SearchValue[], query: string): boolean {\n return values.some((value) => {\n if (value === undefined) return false;\n return normalizeAudioSearchText(String(value)).includes(query);\n });\n}\n\nfunction slugifyAudioLibraryId(value: string): string {\n return value\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '') || 'unknown';\n}\n","import type { AudioTrack } from './audio-library';\n\n/** Number of tracks whose metadata was changed, per kind of correction. */\nexport interface AudioMetadataCorrections {\n /** Artist or album artist spelled differently from the rest of the library, or prefixed by a track number. */\n artists: number;\n /** Album titles unified within the same album, disc suffixes moved to the disc number. */\n albums: number;\n /** Genres merged with their other spellings. */\n genres: number;\n /** Titles freed from a track number or artist prefix. */\n titles: number;\n /** Missing album artist, year, genre or track number filled from the rest of the same album. */\n filled: number;\n}\n\nexport interface AudioMetadataHarmony<TTrack extends AudioTrack> {\n tracks: TTrack[];\n corrections: AudioMetadataCorrections;\n /** Tracks with at least one correction. */\n correctedTracks: number;\n}\n\n/** Spellings that denote the same genre once case, accents and punctuation are ignored. */\nconst GENRE_KEY_ALIASES: Readonly<Record<string, string>> = {\n rb: 'rnb',\n randb: 'rnb',\n rhythmandblues: 'rnb',\n rhythmnblues: 'rnb',\n hiphoprap: 'hiphop',\n raphiphop: 'hiphop',\n rocknroll: 'rockandroll',\n rockroll: 'rockandroll',\n ost: 'soundtrack',\n originalsoundtrack: 'soundtrack',\n worldmusic: 'world',\n};\n\nconst TRACK_NUMBER_PREFIX = /^\\s*(\\d{1,3})\\s*(?:[.)_]|-(?!\\d))\\s*(?=[\\p{L}([\"'¿¡])/u;\nconst DISC_SUFFIX = /\\s*[([]?\\s*(?:cd|disc|disk|disque)\\s*(\\d{1,2})\\s*[)\\]]?\\s*$/iu;\n\n/**\n * Makes a library consistent without inventing information: spellings of the same artist, album or genre are\n * unified on their most frequent form, and gaps are only filled from other tracks of the same album.\n */\nexport function harmonizeAudioMetadata<TTrack extends AudioTrack>(tracks: readonly TTrack[]): AudioMetadataHarmony<TTrack> {\n const corrections: AudioMetadataCorrections = { artists: 0, albums: 0, genres: 0, titles: 0, filled: 0 };\n const corrected = new Set<string>();\n const note = (track: TTrack, kind: keyof AudioMetadataCorrections) => {\n corrections[kind] += 1;\n corrected.add(track.id);\n };\n\n // 1. Per-track cleanup of values that carry file-naming artefacts.\n const working = tracks.map((original) => {\n const track = { ...original };\n const artist = cleanAudioArtistName(track.artist);\n const albumArtist = cleanAudioArtistName(track.albumArtist);\n if (artist !== tidy(track.artist) || albumArtist !== tidy(track.albumArtist)) note(track, 'artists');\n track.artist = artist;\n track.albumArtist = albumArtist;\n\n const album = tidy(track.album);\n const disc = album ? DISC_SUFFIX.exec(album) : null;\n if (album && disc && album.slice(0, disc.index).trim()) {\n track.album = album.slice(0, disc.index).trim();\n if (track.discNo === undefined) track.discNo = Number(disc[1]);\n note(track, 'albums');\n } else {\n track.album = album;\n }\n\n const genre = tidy(track.genre);\n track.genre = genre;\n\n const title = tidy(track.title) ?? track.title;\n const numbered = TRACK_NUMBER_PREFIX.exec(title);\n if (numbered && title.slice(numbered[0].length).trim()) {\n track.title = title.slice(numbered[0].length).trim();\n if (track.trackNo === undefined) track.trackNo = Number(numbered[1]);\n note(track, 'titles');\n } else {\n track.title = title;\n }\n return track;\n });\n\n // 2. One spelling per artist across artists and album artists.\n const artistNames = preferredSpellings(working.flatMap((track) => [track.artist, track.albumArtist]), artistKey);\n for (const track of working) {\n const artist = track.artist && artistNames.get(artistKey(track.artist));\n const albumArtist = track.albumArtist && artistNames.get(artistKey(track.albumArtist));\n if ((artist && artist !== track.artist) || (albumArtist && albumArtist !== track.albumArtist)) note(track, 'artists');\n if (artist) track.artist = artist;\n if (albumArtist) track.albumArtist = albumArtist;\n }\n\n // 3. Titles repeating a known artist: \"Corneille - Parce qu'on vient de loin\".\n for (const track of working) {\n const separator = track.title.indexOf(' - ');\n if (separator <= 0) continue;\n const prefix = artistNames.get(artistKey(track.title.slice(0, separator)));\n const rest = track.title.slice(separator + 3).trim();\n if (!prefix || !rest) continue;\n if (track.artist && artistKey(track.artist) !== artistKey(prefix)) continue;\n track.title = rest;\n note(track, 'titles');\n if (!track.artist) track.artist = prefix;\n }\n\n // 4. One spelling per genre.\n const genreNames = preferredSpellings(working.map((track) => track.genre), genreKey, readableCase);\n for (const track of working) {\n const genre = track.genre && genreNames.get(genreKey(track.genre));\n if (genre && genre !== track.genre) {\n track.genre = genre;\n note(track, 'genres');\n }\n }\n\n // 5. Album-level consistency: title spelling, album artist, year, genre and missing track numbers.\n for (const albumTracks of albumGroups(working)) {\n const title = preferredSpellings(albumTracks.map((track) => track.album), metadataKey).get(metadataKey(albumTracks[0].album ?? ''));\n const albumArtist = mostFrequent(albumTracks.map((track) => track.albumArtist), artistKey);\n const year = mostFrequent(albumTracks.map((track) => track.year), String);\n const genre = mostFrequent(albumTracks.map((track) => track.genre), genreKey);\n\n for (const track of albumTracks) {\n if (title && track.album !== title) {\n track.album = title;\n note(track, 'albums');\n }\n if (albumArtist && !track.albumArtist) {\n track.albumArtist = albumArtist;\n note(track, 'filled');\n }\n if (year !== undefined && track.year === undefined) {\n track.year = year;\n note(track, 'filled');\n }\n if (genre && !track.genre) {\n track.genre = genre;\n note(track, 'filled');\n }\n }\n }\n\n return { tracks: working, corrections, correctedTracks: corrected.size };\n}\n\n/** Removes track-number prefixes (`01.Corneille`, `03 - Corneille`) and file-name underscores from a name. */\nexport function cleanAudioArtistName(value: string | undefined): string | undefined {\n let name = tidy(value);\n if (!name) return undefined;\n const numbered = TRACK_NUMBER_PREFIX.exec(name);\n if (numbered && name.slice(numbered[0].length).trim()) name = name.slice(numbered[0].length).trim();\n if (name.includes('_') && !name.includes(' ')) name = name.replace(/_+/g, ' ').trim();\n return name || undefined;\n}\n\n/** Case, accent and punctuation insensitive key: `Jay-Z`, `JAY Z` and `jay z` share one key. Works for any media name. */\nexport function mediaMetadataKey(value: string): string {\n return metadataKey(value);\n}\n\nfunction metadataKey(value: string): string {\n return value\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/&/g, 'and')\n .replace(/[^\\p{L}\\p{N}]+/gu, '');\n}\n\nfunction artistKey(value: string): string {\n const key = metadataKey(value.replace(/^\\s*the\\s+/i, ''));\n return key || metadataKey(value);\n}\n\nfunction genreKey(value: string): string {\n const key = metadataKey(value);\n return GENRE_KEY_ALIASES[key] ?? key;\n}\n\n/** Tracks of the same album: same title key, split by album artist when the album artists disagree. */\nfunction albumGroups<TTrack extends AudioTrack>(tracks: readonly TTrack[]): TTrack[][] {\n const byTitle = new Map<string, TTrack[]>();\n for (const track of tracks) {\n if (!track.album) continue;\n const key = metadataKey(track.album);\n if (!key) continue;\n byTitle.set(key, [...(byTitle.get(key) ?? []), track]);\n }\n\n return [...byTitle.values()].flatMap((titleTracks) => {\n const albumArtistKeys = new Set(titleTracks.flatMap((track) => track.albumArtist ? [artistKey(track.albumArtist)] : []));\n if (albumArtistKeys.size <= 1) return [titleTracks];\n\n // Different albums sharing a title (\"Greatest Hits\"): tracks without album artist follow their artist.\n const groups = new Map<string, TTrack[]>();\n for (const track of titleTracks) {\n const key = track.albumArtist ? artistKey(track.albumArtist) : track.artist ? artistKey(track.artist) : '';\n groups.set(key, [...(groups.get(key) ?? []), track]);\n }\n return [...groups.values()];\n });\n}\n\nfunction preferredSpellings(\n values: ReadonlyArray<string | undefined>,\n keyOf: (value: string) => string,\n finish: (value: string) => string = (value) => value,\n): Map<string, string> {\n const variants = new Map<string, Map<string, number>>();\n for (const value of values) {\n if (!value) continue;\n const key = keyOf(value);\n if (!key) continue;\n const counts = variants.get(key) ?? new Map<string, number>();\n counts.set(value, (counts.get(value) ?? 0) + 1);\n variants.set(key, counts);\n }\n\n return new Map([...variants].map(([key, counts]) => {\n const best = [...counts].sort(([left, leftCount], [right, rightCount]) => (\n rightCount - leftCount\n || spellingQuality(right) - spellingQuality(left)\n || left.localeCompare(right)\n ))[0][0];\n return [key, finish(best)];\n }));\n}\n\nfunction mostFrequent<T extends string | number>(values: ReadonlyArray<T | undefined>, keyOf: (value: T) => string): T | undefined {\n const counts = new Map<string, { value: T; count: number }>();\n for (const value of values) {\n if (value === undefined || value === '') continue;\n const key = keyOf(value);\n const entry = counts.get(key);\n counts.set(key, { value: entry?.value ?? value, count: (entry?.count ?? 0) + 1 });\n }\n return [...counts.values()].sort((left, right) => right.count - left.count)[0]?.value;\n}\n\n/** Ties go to the spelling that looks deliberate: mixed case or a short acronym (`R&B`, `IAM`), then accents. */\nfunction spellingQuality(value: string): number {\n const acronym = value === value.toUpperCase() && value.replace(/[^\\p{L}]/gu, '').length <= 4;\n const mixedCase = acronym || (value !== value.toLowerCase() && value !== value.toUpperCase()) ? 2 : 0;\n const accents = value.normalize('NFD').length !== value.length ? 1 : 0;\n return mixedCase + accents;\n}\n\n/** `hip hop` or `ZOUK` become `Hip Hop` and `Zouk`; short acronyms such as `R&B` or `EDM` are kept. */\nfunction readableCase(value: string): string {\n const letters = value.replace(/[^\\p{L}]/gu, '');\n if (letters.length <= 3) return value;\n if (value !== value.toLowerCase() && value !== value.toUpperCase()) return value;\n return value.toLowerCase().replace(/(^|[\\s\\-/&(])(\\p{L})/gu, (_, separator: string, letter: string) => separator + letter.toUpperCase());\n}\n\nfunction tidy(value: string | undefined): string | undefined {\n const text = value?.replace(/\\s+/g, ' ').trim().replace(/^[\"'](.*)[\"']$/, '$1').trim();\n return text || undefined;\n}\n","import type { AcoustIdResult } from '../online/acoustid';\nimport type { MusicBrainzRecording, MusicBrainzRelease } from '../online/musicbrainz';\nimport { mediaMetadataKey } from './audio-metadata-harmony';\n\n/** Bump when the matching rules change: tracks left unmatched by an older version are checked again once. */\nexport const AUDIO_IDENTIFICATION_VERSION = 1;\n\n/** Unmatched tracks are retried after 30 days, failed checks (offline, service down) after an hour. */\nexport const AUDIO_IDENTIFICATION_RETRY_MS = { unmatched: 30 * 24 * 3_600_000, error: 3_600_000 } as const;\n\nexport type AudioIdentifiableField = 'title' | 'artist' | 'albumArtist' | 'album' | 'year' | 'trackNo';\n\nexport interface AudioIdentificationInput {\n title: string;\n artist?: string;\n albumArtist?: string;\n album?: string;\n year?: number;\n trackNo?: number;\n durationSec?: number;\n /** Fields guessed from file and folder names instead of read from tags. */\n inferredFields?: readonly AudioIdentifiableField[];\n}\n\n/**\n * - `trusted`: tags were complete, nothing to look up.\n * - `matched`: an online source confirmed the track; its fields fill what the tags lacked.\n * - `unmatched`: no reliable answer; retried much later.\n * - `error`: the check could not run; retried soon.\n */\nexport type AudioIdentificationStatus = 'trusted' | 'matched' | 'unmatched' | 'error';\n\n/** `fingerprint`: Chromaprint + AcoustID recognise the sound itself; `text`: MusicBrainz search on title, artist and duration. */\nexport type AudioIdentificationMethod = 'fingerprint' | 'text';\n\nexport interface AudioIdentification {\n version: number;\n status: AudioIdentificationStatus;\n checkedAt: number;\n /** File size and modification time at check time: a changed file is checked again. */\n fileKey: string;\n source?: 'musicbrainz';\n /** Strongest method used for this check; a track left unmatched by text search is retried once fingerprints are available. */\n method?: AudioIdentificationMethod;\n recordingId?: string;\n releaseId?: string;\n confidence?: number;\n fields?: Partial<Pick<AudioIdentificationInput, AudioIdentifiableField>>;\n}\n\nexport interface AudioIdentificationMatch {\n status: 'matched' | 'unmatched';\n method?: AudioIdentificationMethod;\n recordingId?: string;\n releaseId?: string;\n confidence: number;\n fields: Partial<Pick<AudioIdentificationInput, AudioIdentifiableField>>;\n}\n\nconst MIN_SEARCH_SCORE = 90;\nconst DURATION_TOLERANCE_SEC = 4;\nconst MIN_FINGERPRINT_SCORE = 0.85;\nconst FINGERPRINT_DURATION_TOLERANCE_SEC = 7;\n\n/** Fields worth checking online: guessed from names or missing. Empty when tags are complete. */\nexport function audioIdentificationDoubts(input: AudioIdentificationInput): AudioIdentifiableField[] {\n const inferred = new Set(input.inferredFields ?? []);\n return (['title', 'artist', 'album'] as const).filter((field) => inferred.has(field) || !input[field]);\n}\n\n/**\n * Up-to-date tracks (trusted or matched) are never checked again while their file is unchanged. Unmatched tracks are\n * retried when a stronger method or newer rules become available, or after a long delay; failed checks soon.\n */\nexport function needsAudioIdentification(\n previous: AudioIdentification | undefined,\n fileKey: string,\n now: number,\n methods: readonly AudioIdentificationMethod[] = ['text'],\n): boolean {\n if (!previous || previous.fileKey !== fileKey) return true;\n if (previous.status === 'trusted' || previous.status === 'matched') return false;\n if (previous.status === 'error') return now - previous.checkedAt >= AUDIO_IDENTIFICATION_RETRY_MS.error;\n if (methods.includes('fingerprint') && previous.method !== 'fingerprint') return true;\n if (previous.version < AUDIO_IDENTIFICATION_VERSION) return true;\n return now - previous.checkedAt >= AUDIO_IDENTIFICATION_RETRY_MS.unmatched;\n}\n\n/**\n * Picks the MusicBrainz recording behind a fingerprint. The sound decides; names only break ties between the\n * recordings AcoustID links to the same fingerprint.\n */\nexport function pickAcoustIdRecording(\n input: AudioIdentificationInput,\n results: readonly AcoustIdResult[],\n): { recordingId: string; confidence: number } | null {\n const inferred = new Set(input.inferredFields ?? []);\n const titleKey = !inferred.has('title') ? mediaMetadataKey(input.title) : '';\n const best = [...results].filter((result) => result.score >= MIN_FINGERPRINT_SCORE && result.recordings.length)\n .sort((left, right) => right.score - left.score)[0];\n if (!best) return null;\n const recordings = best.recordings.filter((recording) => (\n !input.durationSec || !recording.durationSec || Math.abs(input.durationSec - recording.durationSec) <= FINGERPRINT_DURATION_TOLERANCE_SEC\n ));\n const recording = recordings.find((item) => titleKey && item.title && mediaMetadataKey(item.title) === titleKey) ?? recordings[0];\n return recording ? { recordingId: recording.id, confidence: Math.min(1, best.score) } : null;\n}\n\n/** Metadata of a recording recognised by its fingerprint; album rules are the same as for text matches. */\nexport function matchFingerprintedRecording(\n input: AudioIdentificationInput,\n recording: MusicBrainzRecording | null,\n confidence: number,\n): AudioIdentificationMatch {\n if (!recording) return { status: 'unmatched', method: 'fingerprint', confidence: 0, fields: {} };\n const inferred = new Set(input.inferredFields ?? []);\n // Tagged names that disagree with the recognised recording keep the album lookup on the tagged artist.\n const release = pickRelease({ ...input, artist: inferred.has('artist') || !input.artist ? recording.artist : input.artist }, recording, [recording]);\n const fields: AudioIdentificationMatch['fields'] = { title: recording.title };\n if (recording.artist) fields.artist = recording.artist;\n addReleaseFields(fields, release);\n return { status: 'matched', method: 'fingerprint', recordingId: recording.id, releaseId: release?.id, confidence, fields };\n}\n\n/**\n * Accepts a recording only when title, artist and duration agree with the file. Without an artist a name search is\n * never trusted (\"Track 07\" exists many times over): only a fingerprint can identify such files. Album data is taken from a release\n * with the same album title, or from the artist's own album when the file has no album at all, so folders stay\n * grouped the way the user organised them.\n */\nexport function matchMusicBrainzRecording(input: AudioIdentificationInput, recordings: readonly MusicBrainzRecording[]): AudioIdentificationMatch {\n const titleKey = mediaMetadataKey(input.title);\n const artistKey = input.artist ? mediaMetadataKey(input.artist) : '';\n const candidates = !artistKey ? [] : recordings.filter((recording) => {\n if (recording.score < MIN_SEARCH_SCORE || !titleKey || mediaMetadataKey(recording.title) !== titleKey) return false;\n if (input.durationSec && recording.durationSec && Math.abs(input.durationSec - recording.durationSec) > DURATION_TOLERANCE_SEC) return false;\n return sameArtist(artistKey, recording.artist);\n });\n if (!candidates.length) return { status: 'unmatched', method: 'text', confidence: 0, fields: {} };\n\n const best = [...candidates].sort((left, right) => (\n right.score - left.score\n || durationGap(input, left) - durationGap(input, right)\n ))[0];\n const release = pickRelease(input, best, candidates);\n const fields: AudioIdentificationMatch['fields'] = { title: best.title };\n if (best.artist) fields.artist = best.artist;\n addReleaseFields(fields, release);\n\n return {\n status: 'matched',\n method: 'text',\n recordingId: best.id,\n releaseId: release?.id,\n confidence: Math.min(1, best.score / 100),\n fields,\n };\n}\n\n/** Identification fills guessed or missing fields only: values read from tags are never overwritten. */\nexport function applyAudioIdentification<TItem extends AudioIdentificationInput>(item: TItem, identification: AudioIdentification | undefined): TItem {\n if (identification?.status !== 'matched' || !identification.fields) return item;\n const inferred = new Set(item.inferredFields ?? []);\n const next = { ...item };\n for (const [field, value] of Object.entries(identification.fields) as Array<[AudioIdentifiableField, string | number]>) {\n if (value === undefined || (item[field] !== undefined && item[field] !== '' && !inferred.has(field))) continue;\n (next as Record<AudioIdentifiableField, unknown>)[field] = value;\n }\n return next;\n}\n\nfunction addReleaseFields(fields: AudioIdentificationMatch['fields'], release: MusicBrainzRelease | undefined): void {\n if (!release) return;\n fields.album = release.title;\n if (release.artist) fields.albumArtist = release.artist;\n if (release.year) fields.year = release.year;\n if (release.trackNo) fields.trackNo = release.trackNo;\n}\n\nfunction pickRelease(\n input: AudioIdentificationInput,\n best: MusicBrainzRecording,\n candidates: readonly MusicBrainzRecording[],\n): MusicBrainzRelease | undefined {\n const releases = [best, ...candidates.filter((candidate) => candidate !== best)].flatMap((recording) => recording.releases);\n if (input.album) {\n const albumKey = mediaMetadataKey(input.album);\n return releases.find((release) => mediaMetadataKey(release.title) === albumKey);\n }\n const artistKey = mediaMetadataKey(input.artist ?? best.artist ?? '');\n return releases\n .filter((release) => release.status === 'Official' && release.primaryType === 'Album' && sameArtist(artistKey, release.artist))\n .sort((left, right) => (left.year ?? Number.MAX_SAFE_INTEGER) - (right.year ?? Number.MAX_SAFE_INTEGER))[0];\n}\n\nfunction sameArtist(artistKey: string, candidate: string | undefined): boolean {\n if (!artistKey || !candidate) return false;\n const candidateKey = mediaMetadataKey(candidate);\n // Tolerates featured artists on either side: \"Corneille\" matches \"Corneille feat. Wyclef Jean\".\n return candidateKey === artistKey || candidateKey.startsWith(artistKey) || artistKey.startsWith(candidateKey);\n}\n\nfunction durationGap(input: AudioIdentificationInput, recording: MusicBrainzRecording): number {\n return input.durationSec && recording.durationSec ? Math.abs(input.durationSec - recording.durationSec) : 0;\n}\n","import {\n AUDIO_IDENTIFICATION_VERSION,\n audioIdentificationDoubts,\n needsAudioIdentification,\n type AudioIdentification,\n type AudioIdentificationInput,\n type AudioIdentificationMatch,\n type AudioIdentificationMethod,\n} from './audio-identification';\n\n/**\n * Background metadata check, shared by the desktop shell and the mobile apps. Tracks whose title, artist or album\n * were guessed from file and folder names are looked up online once; tracks with complete tags or an accepted match\n * are never checked again. This only schedules and records: the matching rules and the lookup are injected.\n */\n\nconst RETRY_INTERVAL_MS = 60 * 60 * 1000;\n/** While a long run is matching tracks, the library is refreshed at this pace rather than on every track. */\nconst NOTIFY_INTERVAL_MS = 3000;\n\n/** A library item as the routine reads it: the identification state and what tells a changed file apart. */\nexport interface IdentifiableItem extends AudioIdentificationInput {\n id: string;\n identification?: AudioIdentification;\n size: number;\n /** Modification time in milliseconds; with the size it says whether the file changed. */\n mtimeMs: number;\n}\n\n/** What the routine needs from a library, on the desktop as on a phone. */\nexport interface IdentificationLibrary<TItem extends IdentifiableItem = IdentifiableItem> {\n identificationCandidates(): readonly TItem[];\n recordIdentification(id: string, identification: AudioIdentification): void;\n setIdentificationProgress(progress: { identifying: boolean; identified: number; identifyTotal: number }): void;\n notifyChanged(): void;\n /** Writes the index; the routine calls it once a run is over. */\n flush(): Promise<void> | void;\n}\n\nexport interface IdentificationRoutineOptions<TItem extends IdentifiableItem = IdentifiableItem> {\n library: IdentificationLibrary<TItem>;\n identify(item: TItem): Promise<AudioIdentificationMatch>;\n /** Methods available now; unmatched tracks are tried again when a stronger one appears (fingerprints). */\n methods?: readonly AudioIdentificationMethod[];\n source?: AudioIdentification['source'];\n now?: () => number;\n retryIntervalMs?: number;\n /** Offline or service down: a run stops after this many failures in a row. */\n maxConsecutiveErrors?: number;\n onError?: (error: unknown) => void;\n}\n\nexport interface IdentificationRoutine {\n /** Runs once now; a call during a run schedules another pass, so new files are never missed. */\n run(): Promise<void>;\n /** Runs now and then every `retryIntervalMs`. */\n start(): void;\n dispose(): void;\n}\n\n/** `size:mtime`, which changes when the file behind an item changes. */\nexport function fileKeyFor(item: { size: number; mtimeMs: number }): string {\n return `${item.size}:${Math.round(item.mtimeMs)}`;\n}\n\nexport function createIdentificationRoutine<TItem extends IdentifiableItem>(\n options: IdentificationRoutineOptions<TItem>,\n): IdentificationRoutine {\n const {\n library,\n identify,\n methods = ['text'],\n source = 'musicbrainz',\n now = Date.now,\n retryIntervalMs = RETRY_INTERVAL_MS,\n maxConsecutiveErrors = 3,\n onError = (error: unknown) => console.error('[identification] run failed', error),\n } = options;\n\n let running: Promise<void> | null = null;\n let rerun = false;\n let timer: ReturnType<typeof setInterval> | null = null;\n let disposed = false;\n\n async function runOnce(): Promise<{ checked: number; matched: number }> {\n const due = library\n .identificationCandidates()\n .filter((item) => needsAudioIdentification(item.identification, fileKeyFor(item), now(), methods));\n const lookups: TItem[] = [];\n for (const item of due) {\n if (audioIdentificationDoubts(item).length) {\n lookups.push(item);\n } else {\n // Complete tags: nothing to look up, and nothing to ask again later.\n library.recordIdentification(item.id, {\n version: AUDIO_IDENTIFICATION_VERSION,\n status: 'trusted',\n checkedAt: now(),\n fileKey: fileKeyFor(item),\n });\n }\n }\n if (!lookups.length) return { checked: 0, matched: 0 };\n\n let checked = 0;\n let matched = 0;\n let consecutiveErrors = 0;\n let lastNotifiedAt = now();\n library.setIdentificationProgress({ identifying: true, identified: 0, identifyTotal: lookups.length });\n\n for (const item of lookups) {\n if (disposed) break;\n const base = { version: AUDIO_IDENTIFICATION_VERSION, checkedAt: now(), fileKey: fileKeyFor(item), source };\n try {\n const match = await identify(item);\n consecutiveErrors = 0;\n library.recordIdentification(item.id, {\n ...base,\n status: match.status,\n method: match.method,\n recordingId: match.recordingId,\n releaseId: match.releaseId,\n confidence: match.confidence,\n fields: match.status === 'matched' ? match.fields : undefined,\n });\n if (match.status === 'matched') matched += 1;\n } catch {\n library.recordIdentification(item.id, { ...base, status: 'error' });\n consecutiveErrors += 1;\n }\n checked += 1;\n library.setIdentificationProgress({ identifying: true, identified: checked, identifyTotal: lookups.length });\n if (matched && now() - lastNotifiedAt >= NOTIFY_INTERVAL_MS) {\n lastNotifiedAt = now();\n library.notifyChanged();\n }\n // Offline or service down: stop here, the remaining tracks are picked up by the next run.\n if (consecutiveErrors >= maxConsecutiveErrors) break;\n }\n\n library.setIdentificationProgress({ identifying: false, identified: 0, identifyTotal: 0 });\n await library.flush();\n if (matched) library.notifyChanged();\n return { checked, matched };\n }\n\n function run(): Promise<void> {\n if (disposed) return Promise.resolve();\n if (running) {\n rerun = true;\n return running;\n }\n running = (async () => {\n do {\n rerun = false;\n await runOnce();\n } while (rerun && !disposed);\n })()\n .catch(onError)\n .finally(() => {\n running = null;\n });\n return running;\n }\n\n return {\n run,\n start() {\n void run();\n timer = setInterval(() => void run(), retryIntervalMs);\n // Node: an interval must not keep the process alive on its own.\n (timer as { unref?: () => void }).unref?.();\n },\n dispose() {\n disposed = true;\n if (timer) clearInterval(timer);\n },\n };\n}\n","/**\n * Media library model shared by the desktop and mobile shells: file filtering, title cleanup and audio/video\n * classification from tags, file names and folders. Paths are relative to the library folder and use \"/\".\n */\n\n/** Bump when classification changes: indexed files are read again once. */\nexport const MEDIA_LIBRARY_MODEL_VERSION = 3;\n\nexport type MediaLibraryKind = 'audio' | 'video';\nexport type AudioInferredField = 'title' | 'artist' | 'albumArtist' | 'album' | 'trackNo';\n\n/** The subset of music-metadata results the model reads. */\nexport interface MediaTags {\n title?: string;\n artist?: string;\n artists?: string[];\n albumartist?: string;\n album?: string;\n genre?: string | string[];\n track?: { no?: number | null };\n disk?: { no?: number | null };\n year?: number;\n stik?: number;\n tvShow?: string;\n tvSeason?: number;\n tvEpisode?: number;\n}\n\nexport interface MediaFormat {\n duration?: number;\n}\n\nexport interface MediaTagsInput {\n /** Path of the file inside the library folder, e.g. `Artist/Album/01 - Song.mp3`. */\n relativePath: string;\n common?: MediaTags;\n format?: MediaFormat;\n}\n\nexport interface AudioLibraryFields {\n title: string;\n artist?: string;\n albumArtist?: string;\n album?: string;\n genre?: string;\n trackNo?: number;\n discNo?: number;\n year?: number;\n durationSec?: number;\n /** Fields guessed from file and folder names: identification may correct them, never tagged values. */\n inferredFields?: AudioInferredField[];\n}\n\nexport interface VideoLibraryFields {\n category: 'movie' | 'episode' | 'other';\n title: string;\n series?: string;\n season?: number;\n episode?: number;\n year?: number;\n durationSec?: number;\n}\n\nconst MEDIA_EXTENSIONS: Readonly<Record<MediaLibraryKind, ReadonlySet<string>>> = {\n audio: new Set(['.aac', '.aif', '.aiff', '.flac', '.m4a', '.mp3', '.oga', '.ogg', '.opus', '.wav', '.weba', '.wma']),\n video: new Set(['.avi', '.m4v', '.mkv', '.mov', '.mp4', '.mpeg', '.mpg', '.ogv', '.webm', '.wmv']),\n};\n\nconst IMAGE_EXTENSIONS = new Set(['.jpg', '.jpeg', '.png', '.webp']);\nconst FOLDER_ARTWORK_NAMES = ['cover', 'folder', 'front', 'album', 'poster', 'artwork'];\nconst IGNORED_DIRECTORIES = new Set(['node_modules', '$recycle.bin', '@eadir', 'system volume information', '.trash', '.trashes']);\n\nconst CONTENT_TYPES: ReadonlyMap<string, string> = new Map([\n ['.aac', 'audio/aac'],\n ['.aif', 'audio/aiff'],\n ['.aiff', 'audio/aiff'],\n ['.avi', 'video/x-msvideo'],\n ['.flac', 'audio/flac'],\n ['.jpeg', 'image/jpeg'],\n ['.jpg', 'image/jpeg'],\n ['.m4a', 'audio/mp4'],\n ['.m4v', 'video/mp4'],\n ['.mkv', 'video/x-matroska'],\n ['.mov', 'video/quicktime'],\n ['.mp3', 'audio/mpeg'],\n ['.mp4', 'video/mp4'],\n ['.mpeg', 'video/mpeg'],\n ['.mpg', 'video/mpeg'],\n ['.oga', 'audio/ogg'],\n ['.ogg', 'audio/ogg'],\n ['.ogv', 'video/ogg'],\n ['.opus', 'audio/ogg'],\n ['.png', 'image/png'],\n ['.wav', 'audio/wav'],\n ['.weba', 'audio/webm'],\n ['.webm', 'video/webm'],\n ['.webp', 'image/webp'],\n ['.wma', 'audio/x-ms-wma'],\n ['.wmv', 'video/x-ms-wmv'],\n]);\n\nconst RELEASE_TOKEN = /[\\s._\\-([]+(?:2160p|1080p|720p|576p|480p|4k|uhd|hdr10?|dv|x264|x265|h\\.?264|h\\.?265|hevc|avc|bluray|blu-ray|brrip|bdrip|web[\\s._-]?dl|webrip|hdtv|dvdrip|remux|proper|repack|multi|vostfr|vf[fqi]?|truefrench|french|english|subfrench|aac|ac3|eac3|dts|ddp?5\\.1|5\\.1|7\\.1|10bit)\\b.*$/i;\nconst YEAR = /(?:^|[\\s._\\-([])((?:19|20)\\d{2})(?=$|[\\s._\\-)\\]])/;\nconst EPISODE_SXE = /^(.*?)[\\s._-]*\\bs(\\d{1,2})[\\s._-]*e(\\d{1,3})(?:[\\s._-]*e\\d{1,3})*\\b[\\s._-]*(.*)$/i;\nconst EPISODE_NXN = /^(.*?)[\\s._-]+(\\d{1,2})x(\\d{2,3})\\b[\\s._-]*(.*)$/i;\nconst SEASON_FOLDER = /^(?:season|saison|staffel|temporada|s)[\\s._-]*(\\d{1,2})$/i;\nconst EPISODE_ONLY = /^(?:e|ep|episode|épisode)?[\\s._-]*(\\d{1,3})\\b[\\s._-]*(.*)$/i;\nconst MOVIE_FOLDER = /^(?:movies?|films?|cin[ée]ma)$/i;\nconst SERIES_FOLDER = /^(?:series|s[ée]ries|tv|tv[\\s._-]?shows?|shows?)$/i;\nconst LEADING_TRACK_NUMBER = /^(\\d{1,3})(?:[\\s._-]+|\\s*-\\s*)(.+)$/;\n\nexport function mediaFileExtension(fileName: string): string {\n const name = fileName.split('/').pop() ?? fileName;\n const dot = name.lastIndexOf('.');\n return dot > 0 ? name.slice(dot).toLowerCase() : '';\n}\n\nexport function isMediaFileName(fileName: string, kind: MediaLibraryKind): boolean {\n return MEDIA_EXTENSIONS[kind].has(mediaFileExtension(fileName));\n}\n\nexport function isImageFileName(fileName: string): boolean {\n return IMAGE_EXTENSIONS.has(mediaFileExtension(fileName));\n}\n\nexport function isIgnoredDirectoryName(name: string): boolean {\n return name.startsWith('.') || IGNORED_DIRECTORIES.has(name.toLowerCase());\n}\n\nexport function mediaContentType(fileName: string): string {\n return CONTENT_TYPES.get(mediaFileExtension(fileName)) ?? 'application/octet-stream';\n}\n\n/** Rank of a folder image as album or poster art (0 is best), -1 when it is not one. */\nexport function folderArtworkRank(fileName: string): number {\n if (!isImageFileName(fileName)) return -1;\n return FOLDER_ARTWORK_NAMES.indexOf(fileStem(fileName).toLowerCase());\n}\n\nexport function cleanMediaTitle(fileStemValue: string): string {\n const withoutRelease = String(fileStemValue).replace(RELEASE_TOKEN, '');\n return tidy(withoutRelease.replace(/\\[[^\\]]*\\]/g, ''));\n}\n\nexport function parseEpisodeFileName(stem: string): { series?: string; season?: number; episode?: number; episodeTitle?: string } | null {\n const match = EPISODE_SXE.exec(stem) ?? EPISODE_NXN.exec(stem);\n if (!match) return null;\n return {\n series: nonEmpty(cleanMediaTitle(match[1])),\n season: positiveInteger(match[2]),\n episode: positiveInteger(match[3]),\n // The separator before the rest was consumed by the pattern: restore one so release tags (\"1080p\") are recognised.\n episodeTitle: nonEmpty(cleanMediaTitle(` ${match[4] ?? ''}`)),\n };\n}\n\nexport function audioFieldsFromTags({ relativePath, common = {}, format = {} }: MediaTagsInput): AudioLibraryFields {\n const stem = fileStem(relativePath);\n const numbered = LEADING_TRACK_NUMBER.exec(stem);\n const ancestors = ancestorNames(relativePath);\n const artists = Array.isArray(common.artists) ? common.artists.filter(Boolean) : [];\n const genre = Array.isArray(common.genre) ? common.genre.find(Boolean) : common.genre;\n const taggedArtist = nonEmpty(common.artist) ?? nonEmpty(artists.join(', ')) ?? nonEmpty(common.albumartist);\n const inferredFields = ([\n !nonEmpty(common.title) && 'title',\n !taggedArtist && 'artist',\n !nonEmpty(common.albumartist) && !nonEmpty(common.artist) && 'albumArtist',\n !nonEmpty(common.album) && 'album',\n !positiveInteger(common.track?.no) && numbered && 'trackNo',\n ] as const).filter((field): field is AudioInferredField => typeof field === 'string');\n\n return {\n title: nonEmpty(common.title) ?? cleanMediaTitle(numbered ? numbered[2] : stem),\n artist: taggedArtist ?? (ancestors[1] ? tidy(ancestors[1]) : undefined),\n albumArtist: nonEmpty(common.albumartist) ?? nonEmpty(common.artist) ?? (ancestors[1] ? tidy(ancestors[1]) : undefined),\n album: nonEmpty(common.album) ?? (ancestors[0] ? tidy(ancestors[0]) : undefined),\n genre: nonEmpty(genre),\n trackNo: positiveInteger(common.track?.no) ?? (numbered ? positiveInteger(numbered[1]) : undefined),\n discNo: positiveInteger(common.disk?.no),\n year: positiveInteger(common.year),\n durationSec: durationOf(format),\n inferredFields: inferredFields.length ? inferredFields : undefined,\n };\n}\n\nexport function videoFieldsFromTags({ relativePath, common = {}, format = {} }: MediaTagsInput): VideoLibraryFields {\n const stem = fileStem(relativePath);\n const ancestors = ancestorNames(relativePath);\n const durationSec = durationOf(format);\n const yearMatch = YEAR.exec(stem);\n const taggedTitle = nonEmpty(common.title);\n const base = { durationSec, year: positiveInteger(common.year) ?? (yearMatch ? positiveInteger(yearMatch[1]) : undefined) };\n\n // 1. Explicit TV tags (MP4 \"stik\" 10 = TV show, or tvShow/tvSeason/tvEpisode).\n if (common.stik === 10 || nonEmpty(common.tvShow)) {\n const parsed = parseEpisodeFileName(stem);\n return {\n ...base,\n category: 'episode',\n series: nonEmpty(common.tvShow) ?? parsed?.series ?? seriesFromFolders(ancestors) ?? cleanMediaTitle(stem),\n season: positiveInteger(common.tvSeason) ?? parsed?.season ?? seasonFromFolders(ancestors),\n episode: positiveInteger(common.tvEpisode) ?? parsed?.episode,\n title: taggedTitle ?? parsed?.episodeTitle ?? cleanMediaTitle(stem),\n };\n }\n\n // 2. Episode patterns in the file name: S01E02 or 1x02.\n const parsed = parseEpisodeFileName(stem);\n if (parsed?.season !== undefined && parsed.episode !== undefined) {\n return {\n ...base,\n category: 'episode',\n // The folder wins over the file name. A season folder says what the series is with far\n // more authority than a release name: the same series arrives with several spellings, or\n // with none at all when the name is obfuscated, and each spelling would be its own series\n // in the library. What the viewer named the folder is what they mean.\n series: seriesFromFolders(ancestors) ?? parsed.series ?? cleanMediaTitle(stem),\n season: parsed.season,\n episode: parsed.episode,\n title: taggedTitle ?? parsed.episodeTitle ?? cleanMediaTitle(stem),\n };\n }\n\n // 3. \"Series/Season 1/03 - Title.mkv\" folder layouts.\n const seasonFolderIndex = ancestors.findIndex((name) => SEASON_FOLDER.test(name));\n if (seasonFolderIndex === 0) {\n const episodeMatch = EPISODE_ONLY.exec(stem);\n const series = ancestors[1] && !SERIES_FOLDER.test(ancestors[1]) ? tidy(ancestors[1]) : undefined;\n if (series) {\n return {\n ...base,\n category: 'episode',\n series,\n season: positiveInteger(SEASON_FOLDER.exec(ancestors[0])?.[1]),\n episode: episodeMatch ? positiveInteger(episodeMatch[1]) : undefined,\n title: taggedTitle ?? nonEmpty(cleanMediaTitle(episodeMatch?.[2] ?? '')) ?? cleanMediaTitle(stem),\n };\n }\n }\n\n const underSeriesFolder = ancestors.findIndex((name) => SERIES_FOLDER.test(name));\n if (underSeriesFolder > 0) {\n const episodeMatch = EPISODE_ONLY.exec(stem);\n return {\n ...base,\n category: 'episode',\n series: tidy(ancestors[underSeriesFolder - 1]),\n season: seasonFromFolders(ancestors.slice(0, underSeriesFolder)),\n episode: episodeMatch ? positiveInteger(episodeMatch[1]) : undefined,\n title: taggedTitle ?? nonEmpty(cleanMediaTitle(episodeMatch?.[2] ?? '')) ?? cleanMediaTitle(stem),\n };\n }\n\n // 4. Movies: MP4 \"stik\" 9, a Movies/Films folder, a release year or a feature length.\n const movieTitle = taggedTitle ?? cleanMediaTitle(yearMatch ? stem.slice(0, yearMatch.index) : stem);\n const inMovieFolder = ancestors.some((name) => MOVIE_FOLDER.test(name));\n if (common.stik === 9 || inMovieFolder || yearMatch || (durationSec !== undefined && durationSec >= 40 * 60)) {\n return { ...base, category: 'movie', title: movieTitle || cleanMediaTitle(stem) };\n }\n\n return { ...base, category: 'other', title: taggedTitle ?? cleanMediaTitle(stem) };\n}\n\n/** Folder names between the library folder and the file, closest first. */\nfunction ancestorNames(relativePath: string): string[] {\n return relativePath.split('/').filter(Boolean).slice(0, -1).reverse();\n}\n\nfunction fileStem(path: string): string {\n const name = path.split('/').pop() ?? path;\n const dot = name.lastIndexOf('.');\n return dot > 0 ? name.slice(0, dot) : name;\n}\n\nfunction tidy(value: string | undefined): string {\n return String(value ?? '')\n .replace(/[._]+/g, ' ')\n .replace(/\\s*[-–]\\s*$/, '')\n .replace(/^\\s*[-–]\\s*/, '')\n .replace(/\\s{2,}/g, ' ')\n .trim();\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n const text = typeof value === 'string' ? value.trim() : '';\n return text || undefined;\n}\n\nfunction positiveInteger(value: unknown): number | undefined {\n const number = Number(value);\n return Number.isInteger(number) && number > 0 ? number : undefined;\n}\n\nfunction durationOf(format: MediaFormat): number | undefined {\n return typeof format.duration === 'number' && Number.isFinite(format.duration) && format.duration > 0 ? Math.round(format.duration) : undefined;\n}\n\nfunction seasonFromFolders(ancestors: readonly string[]): number | undefined {\n for (const name of ancestors) {\n const match = SEASON_FOLDER.exec(name);\n if (match) return positiveInteger(match[1]);\n }\n return undefined;\n}\n\nfunction seriesFromFolders(ancestors: readonly string[]): string | undefined {\n const seasonIndex = ancestors.findIndex((name) => SEASON_FOLDER.test(name));\n if (seasonIndex >= 0 && ancestors[seasonIndex + 1]) return tidy(ancestors[seasonIndex + 1]);\n return undefined;\n}\n","/**\n * Media servers the apps can browse and play from: a home server (Jellyfin), a UPnP/DLNA server, a Subsonic music\n * server or a plain WebDAV share. Connectors translate each protocol into the same containers and items, so the\n * library views and the queue treat every source alike.\n */\nexport type MediaSourceKind = 'jellyfin' | 'dlna' | 'subsonic' | 'webdav';\n\n/** What the listener fills in to connect a server. */\nexport interface MediaSourceInput {\n kind: MediaSourceKind;\n /** Address of the server, with or without scheme; connectors normalise it. */\n address: string;\n name?: string;\n username?: string;\n password?: string;\n}\n\n/**\n * A connected server. `secret` is the credential kept to reach it again (an access token when the server issues one,\n * the password otherwise); applications store it with their own preferences and never send it anywhere else.\n */\nexport interface MediaSourceAccount {\n id: string;\n kind: MediaSourceKind;\n name: string;\n baseUrl: string;\n username?: string;\n secret?: string;\n /** Account identifier on the server, when it has one. */\n userId?: string;\n}\n\n/** A browsable node: a library, a folder, an album, a series. */\nexport interface MediaSourceContainer {\n id: string;\n title: string;\n subtitle?: string;\n artworkUrl?: string;\n /** What it holds, when the server says so. */\n kind?: 'audio' | 'video' | 'mixed';\n childCount?: number;\n}\n\n/** A playable file, in the shape the libraries already use. */\nexport interface MediaSourceItem {\n id: string;\n kind: 'audio' | 'video';\n title: string;\n url: string;\n artworkUrl?: string;\n durationSec?: number;\n artist?: string;\n albumArtist?: string;\n album?: string;\n genre?: string;\n year?: number;\n trackNo?: number;\n discNo?: number;\n series?: string;\n season?: number;\n episode?: number;\n container?: string;\n}\n\nexport interface MediaSourcePage {\n containers: MediaSourceContainer[];\n items: MediaSourceItem[];\n /** Total number of items in the container, when the server reports it. */\n total?: number;\n}\n\nexport interface MediaSourceRequest {\n url: string;\n method?: 'GET' | 'POST' | 'PROPFIND';\n headers?: Record<string, string>;\n json?: unknown;\n body?: string;\n signal?: AbortSignal;\n /** For a request that waits on purpose (another device asking its user); transports keep their own otherwise. */\n timeoutMs?: number;\n}\n\nexport interface MediaSourceResponse {\n status: number;\n json(): Promise<unknown>;\n text(): Promise<string>;\n}\n\n/** Transport used by connectors; applications plug their HTTP client here. */\nexport interface MediaSourceHttp {\n send(request: MediaSourceRequest): Promise<MediaSourceResponse>;\n}\n\nexport interface MediaSourceBrowseOptions {\n containerId?: string;\n /** Filters what the container returns, for apps that only play one kind. */\n kind?: 'audio' | 'video';\n search?: string;\n startIndex?: number;\n limit?: number;\n signal?: AbortSignal;\n}\n\nexport interface MediaSourceConnector {\n kind: MediaSourceKind;\n /** Checks the address and credentials, and returns the account to keep. */\n connect(input: MediaSourceInput, http: MediaSourceHttp): Promise<MediaSourceAccount>;\n /** Libraries and folders at the root, then their contents. */\n browse(account: MediaSourceAccount, options: MediaSourceBrowseOptions, http: MediaSourceHttp): Promise<MediaSourcePage>;\n /**\n * Lyrics the server holds for a track, as LRC text or plain words, or null when it has none. Servers that keep\n * no lyrics leave this out.\n */\n lyrics?(account: MediaSourceAccount, item: MediaSourceItem, http: MediaSourceHttp): Promise<string | null>;\n}\n\n/** `https://host:port/path` without a trailing slash; plain http is kept for servers on a local network. */\nexport function normalizeMediaSourceAddress(address: string): string {\n const trimmed = address.trim();\n if (!trimmed) throw new Error('Server address is required');\n const withScheme = /^[a-z][a-z0-9+.-]*:\\/\\//i.test(trimmed) ? trimmed : `http://${trimmed}`;\n const url = new URL(withScheme);\n if (url.protocol !== 'http:' && url.protocol !== 'https:') throw new Error('Server address must be http or https');\n url.hash = '';\n url.search = '';\n return `${url.origin}${url.pathname.replace(/\\/+$/, '')}`;\n}\n\n/** Stable id of an item or container inside an account, so queues and playlists survive a restart. */\nexport function mediaSourceItemId(accountId: string, remoteId: string): string {\n return `src:${accountId}:${remoteId}`;\n}\n\nexport function parseMediaSourceItemId(id: string): { accountId: string; remoteId: string } | null {\n const match = /^src:([^:]+):(.+)$/.exec(id);\n return match ? { accountId: match[1], remoteId: match[2] } : null;\n}\n\n/** Ticks used by Jellyfin and Emby (100 ns units) to seconds. */\nexport function ticksToSeconds(ticks: unknown): number | undefined {\n const value = Number(ticks);\n return Number.isFinite(value) && value > 0 ? Math.round(value / 10_000_000) : undefined;\n}\n","/**\n * Cutting a piece of a track to use as a ringtone.\n *\n * The piece is taken from where the listener is: they were listening to the part they want, and\n * asking them to find it again in a waveform is asking them to do the work twice. So the start\n * is the playhead, the length is a choice between a few, and what comes out is a real file.\n *\n * Both edges are faded. A ringtone cut straight out of the middle of a track starts with a click\n * and ends with one, which is the difference between something made and something taken.\n */\n\n/** How long a ringtone may be. Android accepts more; a phone that rings for half a minute is enough. */\nexport const RINGTONE_MAX_SEC = 30;\n/** Long enough not to click, short enough not to be heard as a fade. */\nexport const RINGTONE_FADE_SEC = 0.05;\n\nexport interface RingtoneSegment {\n startSec: number;\n lengthSec: number;\n}\n\n/**\n * Where the piece starts and how long it runs, kept inside the track.\n *\n * A playhead near the end would give a piece that runs off it, so the start slides back to make\n * room; a track shorter than the length asked for simply gives all of itself.\n */\nexport function ringtoneSegment(options: {\n positionSec: number;\n trackDurationSec: number;\n lengthSec: number;\n}): RingtoneSegment {\n const duration = Math.max(0, finite(options.trackDurationSec));\n const wanted = Math.min(Math.max(1, finite(options.lengthSec)), RINGTONE_MAX_SEC);\n const lengthSec = duration > 0 ? Math.min(wanted, duration) : wanted;\n const position = Math.min(Math.max(0, finite(options.positionSec)), duration);\n // Slid back rather than cut short: a ringtone that stops early is not the piece that was asked for.\n const startSec = duration > 0 ? Math.min(position, Math.max(0, duration - lengthSec)) : 0;\n return { startSec, lengthSec };\n}\n\n/**\n * Fades both edges in place, so the piece does not begin or end on a click.\n *\n * A piece too short to hold two fades gets shorter ones rather than none: the click is what is\n * being removed, and half a fade removes it just as well.\n */\nexport function fadeEdges(channels: Float32Array[], sampleRate: number, fadeSec = RINGTONE_FADE_SEC): void {\n const frames = channels[0]?.length ?? 0;\n if (!frames || sampleRate <= 0) return;\n const fade = Math.max(1, Math.min(Math.round(fadeSec * sampleRate), Math.floor(frames / 2)));\n for (const channel of channels) {\n for (let index = 0; index < fade; index += 1) {\n const gain = index / fade;\n channel[index] *= gain;\n channel[frames - 1 - index] *= gain;\n }\n }\n}\n\n/**\n * Writes audio as a WAV file: 16-bit PCM, the one encoding a page can produce on its own.\n *\n * It is not small, and it is not meant to be kept — it is what is handed to the system, which\n * stores a ringtone however it likes. What matters is that no library has to be shipped to make\n * one, and that every platform reads it.\n */\nexport function encodeWav(channels: Float32Array[], sampleRate: number): ArrayBuffer {\n const channelCount = Math.max(1, channels.length);\n const frames = channels[0]?.length ?? 0;\n const bytesPerSample = 2;\n const blockAlign = channelCount * bytesPerSample;\n const dataBytes = frames * blockAlign;\n const buffer = new ArrayBuffer(44 + dataBytes);\n const view = new DataView(buffer);\n\n writeText(view, 0, 'RIFF');\n view.setUint32(4, 36 + dataBytes, true);\n writeText(view, 8, 'WAVE');\n writeText(view, 12, 'fmt ');\n view.setUint32(16, 16, true);\n view.setUint16(20, 1, true);\n view.setUint16(22, channelCount, true);\n view.setUint32(24, sampleRate, true);\n view.setUint32(28, sampleRate * blockAlign, true);\n view.setUint16(32, blockAlign, true);\n view.setUint16(34, 8 * bytesPerSample, true);\n writeText(view, 36, 'data');\n view.setUint32(40, dataBytes, true);\n\n let offset = 44;\n for (let frame = 0; frame < frames; frame += 1) {\n for (let channel = 0; channel < channelCount; channel += 1) {\n // Clipped before it is scaled: a sample past the rails would wrap round to the other one.\n const sample = Math.max(-1, Math.min(1, channels[channel]?.[frame] ?? 0));\n view.setInt16(offset, Math.round(sample * (sample < 0 ? 0x8000 : 0x7fff)), true);\n offset += bytesPerSample;\n }\n }\n return buffer;\n}\n\n/** A file name from a track's title: what a viewer will look for in their files. */\nexport function ringtoneFileName(title: string, extension = 'wav'): string {\n const safe = String(title ?? '')\n .replace(/[/\\\\:*?\"<>|\\u0000-\\u001f]+/g, ' ')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, 60);\n return `${safe || 'ringtone'}.${extension}`;\n}\n\nfunction finite(value: number): number {\n return Number.isFinite(value) ? value : 0;\n}\n\nfunction writeText(view: DataView, offset: number, text: string): void {\n for (let index = 0; index < text.length; index += 1) view.setUint8(offset + index, text.charCodeAt(index));\n}\n","/**\n * Shaking the device, read from its accelerometer.\n *\n * A shake is not one movement but several: the hand throws the device one way and pulls it back,\n * and does it again. So what is counted is not force but **reversals** — the number of times the\n * movement changed its mind inside a short window. That is what tells a shake apart from setting\n * the phone down hard, from a pocket, from a car going over a kerb.\n *\n * Direction is deliberately not read. A sideways shake does carry a first impulse one way or the\n * other, but which way that is depends on how the device is being held, and a control that works\n * most of the time is worse than one that works the same way every time. So a shake means one\n * thing, and two shakes in a row mean the other — the same bargain a double click makes.\n *\n * One thing follows from that and is worth saying rather than hiding: a shake that simply goes\n * on long enough crosses the rest and is heard as a second one. Someone still shaking after a\n * second and a half meant more than \"the next one\", so reading it as the other gesture is the\n * least surprising of the available wrong answers.\n */\n\n/** One reading of the accelerometer, in m/s², gravity included or not — only the changes are read. */\nexport interface ShakeSample {\n x: number;\n y: number;\n z: number;\n /** When it was taken, in milliseconds. */\n at: number;\n}\n\nexport type ShakeGesture = 'single' | 'double';\n\nexport interface ShakeOptions {\n /** How hard a movement has to be before it counts as one, in m/s² of change. */\n force?: number;\n /** How many changes of direction make a shake. */\n reversals?: number;\n /** How long those changes have to happen inside, in milliseconds. */\n window?: number;\n /** How long to ignore the accelerometer after a shake, so one shake is not read as three. */\n rest?: number;\n /**\n * How long a second shake has to arrive within to mean \"the other way\", counted from the first.\n * It has to leave room for the rest above, or a second shake would be swallowed before it could\n * be heard — so the two are set together, not one at a time.\n */\n pairWindow?: number;\n}\n\nconst DEFAULTS: Required<ShakeOptions> = {\n force: 12,\n reversals: 3,\n window: 700,\n rest: 600,\n pairWindow: 1800,\n};\n\n/**\n * Reads samples and says when a shake happened.\n *\n * A single shake is reported only once it is clear no second one is coming, so that a double\n * shake never arrives as a single one first and is then contradicted.\n */\nexport function createShakeDetector(options: ShakeOptions = {}) {\n const settings = { ...DEFAULTS, ...options };\n let last: ShakeSample | null = null;\n let direction = 0;\n let reversals: number[] = [];\n let restingUntil = 0;\n let firstShakeAt = 0;\n\n /** Feeds one reading. Returns the gesture it completes, or null. */\n function read(sample: ShakeSample): ShakeGesture | null {\n const previous = last;\n last = sample;\n if (!previous) return null;\n if (sample.at < restingUntil) return null;\n\n const elapsed = sample.at - previous.at;\n if (elapsed <= 0) return null;\n // Change over time, so a slow phone and a fast one read a shake the same way.\n const speed = (Math.abs(sample.x - previous.x) + Math.abs(sample.y - previous.y) + Math.abs(sample.z - previous.z)) / (elapsed / 1000);\n if (speed < settings.force) return null;\n\n const moving = Math.sign((sample.x - previous.x) + (sample.y - previous.y) + (sample.z - previous.z));\n if (moving !== 0 && moving !== direction) {\n direction = moving;\n reversals.push(sample.at);\n }\n reversals = reversals.filter((at) => sample.at - at <= settings.window);\n if (reversals.length < settings.reversals) return null;\n\n reversals = [];\n direction = 0;\n restingUntil = sample.at + settings.rest;\n if (firstShakeAt && sample.at - firstShakeAt <= settings.pairWindow) {\n firstShakeAt = 0;\n return 'double';\n }\n firstShakeAt = sample.at;\n return null;\n }\n\n /**\n * Whether a single shake, still waiting to see whether a second one follows, has waited long\n * enough to count on its own. Called on a timer by whoever owns the clock.\n */\n function settle(now: number): ShakeGesture | null {\n if (!firstShakeAt || now - firstShakeAt <= settings.pairWindow) return null;\n firstShakeAt = 0;\n return 'single';\n }\n\n /** How long there is left to wait before a lone shake counts, or 0 when nothing is pending. */\n function pendingFor(now: number): number {\n return firstShakeAt ? Math.max(0, settings.pairWindow - (now - firstShakeAt)) : 0;\n }\n\n function reset(): void {\n last = null;\n direction = 0;\n reversals = [];\n restingUntil = 0;\n firstShakeAt = 0;\n }\n\n return { read, settle, pendingFor, reset };\n}\n","/**\n * Media kept behind a lock.\n *\n * What is locked is not merely refused: it is **absent**. It is in no shelf, no search, no\n * history, no queue, until the vault is opened. Anything less tells whoever is holding the\n * device that there is something to look for, which is the thing a lock is meant to avoid.\n *\n * The code is never kept. What is kept is a salt and the result of stretching the code through\n * PBKDF2 with it, so the stored record cannot be read backwards, and the same code typed twice\n * on two devices does not produce the same record.\n */\n\n/** What is written down about the code. The code itself never is. */\nexport interface VaultPasscode {\n /** Random, per vault, so two vaults with the same code do not look alike. */\n salt: string;\n /** The stretched code, base64. */\n hash: string;\n /** How many rounds produced it, so a record made today still opens after the cost is raised. */\n rounds: number;\n}\n\n/** The parts of Web Crypto this needs, named so a test can stand in for them. */\nexport interface VaultCrypto {\n getRandomValues(array: Uint8Array): Uint8Array;\n subtle: Pick<SubtleCrypto, 'importKey' | 'deriveBits'>;\n}\n\nexport const VAULT_ROUNDS = 310_000;\n\n/**\n * Stretches a code into something that can be written down.\n *\n * The rounds are the cost of one guess. They are stored with the record rather than assumed, so\n * raising them later does not lock anyone out of a vault they already have.\n */\nexport async function hashPasscode(\n code: string,\n crypto: VaultCrypto,\n options: { salt?: string; rounds?: number } = {},\n): Promise<VaultPasscode> {\n const rounds = options.rounds ?? VAULT_ROUNDS;\n const salt = options.salt ?? toBase64(crypto.getRandomValues(new Uint8Array(16)));\n const key = await crypto.subtle.importKey('raw', encode(code), 'PBKDF2', false, ['deriveBits']);\n const bits = await crypto.subtle.deriveBits(\n { name: 'PBKDF2', salt: fromBase64(salt), iterations: rounds, hash: 'SHA-256' },\n key,\n 256,\n );\n return { salt, hash: toBase64(new Uint8Array(bits)), rounds };\n}\n\n/**\n * Whether a code opens a record. Compared in constant time, so the time an answer takes says\n * nothing about how much of the code was right.\n */\nexport async function verifyPasscode(code: string, record: VaultPasscode | null, crypto: VaultCrypto): Promise<boolean> {\n if (!record?.hash || !record.salt) return false;\n const candidate = await hashPasscode(code, crypto, { salt: record.salt, rounds: record.rounds });\n return equalInConstantTime(candidate.hash, record.hash);\n}\n\n/** A code short enough to guess is not a code. Four is the floor every phone uses. */\nexport function isUsablePasscode(code: string): boolean {\n return /^[0-9]{4,}$/.test(code) && new Set(code).size > 1;\n}\n\n/**\n * The ids that must not be shown.\n *\n * Nothing is hidden while the vault is open, and nothing is hidden when there is no code — a\n * vault nobody can open is a way of losing media, not of protecting it.\n */\nexport function hiddenIds(locked: Iterable<string>, state: { open: boolean; hasPasscode: boolean }): Set<string> {\n return state.open || !state.hasPasscode ? new Set() : new Set(locked);\n}\n\n/** Keeps only what may be seen, in the order it was given. */\nexport function withoutHidden<T>(items: readonly T[], idOf: (item: T) => string, hidden: ReadonlySet<string>): T[] {\n return hidden.size ? items.filter((item) => !hidden.has(idOf(item))) : [...items];\n}\n\n/** A view on a plain buffer, which is what the platform's own crypto types will take. */\nfunction encode(text: string): ArrayBuffer {\n const encoded = new TextEncoder().encode(text);\n const bytes = new Uint8Array(new ArrayBuffer(encoded.length));\n bytes.set(encoded);\n return bytes.buffer;\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nfunction fromBase64(text: string): ArrayBuffer {\n const binary = atob(text);\n const bytes = new Uint8Array(new ArrayBuffer(binary.length));\n for (let index = 0; index < binary.length; index += 1) bytes[index] = binary.charCodeAt(index);\n return bytes.buffer;\n}\n\n/** Every character is compared, whether or not the answer is already known. */\nfunction equalInConstantTime(left: string, right: string): boolean {\n if (left.length !== right.length) return false;\n let difference = 0;\n for (let index = 0; index < left.length; index += 1) {\n difference |= left.charCodeAt(index) ^ right.charCodeAt(index);\n }\n return difference === 0;\n}\n","import type { RemotePlaybackKind } from './remote-playback';\n\nexport type DevicePlaybackKind = RemotePlaybackKind;\nexport type DevicePlaybackStatus = 'idle' | 'connecting' | 'playing' | 'failed';\n\nexport interface PlaybackDevice {\n id: string;\n name: string;\n kind: DevicePlaybackKind;\n address: string;\n model?: string;\n connected?: boolean;\n}\n\nexport interface DevicePlaybackState {\n status: DevicePlaybackStatus;\n activeDeviceId: string | null;\n activeDeviceName: string | null;\n targetUrl?: string;\n message?: string;\n error?: string;\n}\n\nexport type DevicePlaybackEvent =\n | { type: 'connect'; device: PlaybackDevice; targetUrl: string; message?: string }\n | { type: 'playing'; deviceId: string; message?: string }\n | { type: 'fail'; deviceId: string; error: string; message?: string }\n | { type: 'stop'; deviceId?: string; message?: string };\n\nexport function createIdleDevicePlaybackState(message?: string): DevicePlaybackState {\n return {\n status: 'idle',\n activeDeviceId: null,\n activeDeviceName: null,\n ...(message ? { message } : {}),\n };\n}\n\nexport function reduceDevicePlaybackState(\n state: DevicePlaybackState,\n event: DevicePlaybackEvent,\n): DevicePlaybackState {\n switch (event.type) {\n case 'connect':\n return connectDevice(event.device, event.targetUrl, event.message);\n case 'playing':\n return transitionActiveDevice(state, event.deviceId, {\n status: 'playing',\n message: event.message ?? `Playing on ${state.activeDeviceName ?? 'device'}.`,\n });\n case 'fail':\n return transitionActiveDevice(state, event.deviceId, {\n status: 'failed',\n error: event.error,\n message: event.message ?? event.error,\n });\n case 'stop':\n if (event.deviceId && state.activeDeviceId !== event.deviceId) return state;\n return createIdleDevicePlaybackState(event.message);\n }\n}\n\nfunction connectDevice(\n device: PlaybackDevice,\n targetUrl: string,\n message?: string,\n): DevicePlaybackState {\n const activeDeviceId = device.id.trim();\n const activeDeviceName = device.name.trim();\n const cleanTargetUrl = targetUrl.trim();\n\n if (!activeDeviceId || !activeDeviceName) {\n return {\n status: 'failed',\n activeDeviceId: activeDeviceId || null,\n activeDeviceName: activeDeviceName || null,\n error: 'Playback device identity is incomplete.',\n message: 'Playback device identity is incomplete.',\n };\n }\n\n if (!cleanTargetUrl) {\n return {\n status: 'failed',\n activeDeviceId,\n activeDeviceName,\n error: 'Playback target URL is required.',\n message: 'Playback target URL is required.',\n };\n }\n\n return {\n status: 'connecting',\n activeDeviceId,\n activeDeviceName,\n targetUrl: cleanTargetUrl,\n message: message ?? `Connecting to ${activeDeviceName}.`,\n };\n}\n\nfunction transitionActiveDevice(\n state: DevicePlaybackState,\n deviceId: string,\n patch: Pick<DevicePlaybackState, 'status'> & Partial<DevicePlaybackState>,\n): DevicePlaybackState {\n if (state.activeDeviceId !== deviceId) return state;\n\n return {\n activeDeviceId: state.activeDeviceId,\n activeDeviceName: state.activeDeviceName,\n targetUrl: state.targetUrl,\n ...patch,\n };\n}\n","/**\n * Transport used by the online catalogs: resolves a JSON document or throws.\n * Applications plug their HTTP client here (cache, retries, telemetry); the default uses `fetch`.\n */\nexport interface OnlineJsonHttp {\n getJson(url: string, options?: { signal?: AbortSignal }): Promise<unknown>;\n}\n\nexport function createFetchOnlineJsonHttp(fetchFn: typeof fetch = (input, init) => fetch(input, init)): OnlineJsonHttp {\n return {\n async getJson(url, options = {}) {\n const response = await fetchFn(url, { signal: options.signal, headers: { Accept: 'application/json' } });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return response.json();\n },\n };\n}\n","/**\n * Local copies of online media (Internet Archive tracks): instant starts, seamless queue transitions and playback\n * through network drops. Downloads run one at a time in the background and the cache stays under a byte budget by\n * evicting the least recently used copies, never the ones the queue still needs.\n */\nexport interface MediaCacheEntry {\n key: string;\n url: string;\n size: number;\n contentType: string;\n storedAt: number;\n lastUsedAt: number;\n}\n\n/** Persistence of cached media; browsers implement it with IndexedDB. */\nexport interface MediaCacheStore {\n entries(): Promise<MediaCacheEntry[]>;\n read(key: string): Promise<Blob | null>;\n write(entry: MediaCacheEntry, data: Blob): Promise<void>;\n touch(key: string, lastUsedAt: number): Promise<void>;\n remove(keys: readonly string[]): Promise<void>;\n}\n\nexport interface MediaCacheRequest {\n key: string;\n url: string;\n /** Tried in order when `url` cannot be downloaded (network, HTTP or CORS failure). */\n alternateUrls?: readonly string[];\n}\n\nexport interface MediaCacheUsage {\n bytes: number;\n count: number;\n budgetBytes: number;\n}\n\nexport interface MediaCacheOptions {\n store: MediaCacheStore;\n budgetBytes: number;\n /** Larger media are streamed only. Defaults to a quarter of the budget. */\n maxEntryBytes?: number;\n fetch?: typeof fetch;\n now?: () => number;\n /** Background downloads wait while this returns false (data saver, slow connection). */\n canDownload?: () => boolean;\n}\n\nexport interface MediaCache {\n /** Resolves once the stored index is loaded; `has` answers false before. */\n readonly ready: Promise<void>;\n has(key: string): boolean;\n /** The local copy, marked as recently used; null when absent or unreadable. */\n open(key: string): Promise<Blob | null>;\n /**\n * Media the player needs next, most urgent first. Missing ones are downloaded in that order; a download no longer\n * requested is cancelled. Requested keys are protected from eviction until the next call.\n */\n keep(requests: readonly MediaCacheRequest[]): void;\n usage(): MediaCacheUsage;\n clear(): Promise<void>;\n /** Called after downloads, evictions and clears. */\n onChange(listener: () => void): () => void;\n}\n\n/** Keys to evict, least recently used first, so that `incomingBytes` fits in the budget; null when it cannot fit. */\nexport function planMediaCacheEviction(\n entries: readonly MediaCacheEntry[],\n budgetBytes: number,\n incomingBytes: number,\n protectedKeys: ReadonlySet<string> = new Set(),\n): string[] | null {\n let total = entries.reduce((sum, entry) => sum + entry.size, 0) + incomingBytes;\n if (total <= budgetBytes) return [];\n const evicted: string[] = [];\n const candidates = entries.filter((entry) => !protectedKeys.has(entry.key)).sort((left, right) => left.lastUsedAt - right.lastUsedAt);\n for (const entry of candidates) {\n evicted.push(entry.key);\n total -= entry.size;\n if (total <= budgetBytes) return evicted;\n }\n return null;\n}\n\nexport function createMediaCache(options: MediaCacheOptions): MediaCache {\n const { store, budgetBytes } = options;\n const maxEntryBytes = Math.min(options.maxEntryBytes ?? budgetBytes / 4, budgetBytes);\n const fetchFn = options.fetch ?? ((input: RequestInfo | URL, init?: RequestInit) => fetch(input, init));\n const now = options.now ?? Date.now;\n const canDownload = options.canDownload ?? (() => true);\n const index = new Map<string, MediaCacheEntry>();\n const listeners = new Set<() => void>();\n // Media that failed recently are not retried on every queue change.\n const failures = new Map<string, number>();\n const FAILURE_RETRY_MS = 10 * 60_000;\n let wanted: MediaCacheRequest[] = [];\n let current: { key: string; controller: AbortController } | null = null;\n let loaded = false;\n\n const emit = () => listeners.forEach((listener) => listener());\n\n const ready = store.entries().then(\n (entries) => {\n entries.forEach((entry) => index.set(entry.key, entry));\n loaded = true;\n pump();\n },\n () => {\n loaded = true;\n },\n );\n\n function pump(): void {\n if (!loaded || current) return;\n const next = wanted.find((request) => !index.has(request.key) && !isFailing(request.key));\n if (!next || !canDownload()) return;\n const controller = new AbortController();\n current = { key: next.key, controller };\n void download(next, controller.signal).finally(() => {\n current = null;\n pump();\n });\n }\n\n function isFailing(key: string): boolean {\n const failedAt = failures.get(key);\n return failedAt !== undefined && now() - failedAt < FAILURE_RETRY_MS;\n }\n\n async function fetchFirst(urls: readonly string[], signal: AbortSignal): Promise<{ response: Response; url: string }> {\n let failure: unknown = new Error('No URL to download');\n for (const url of urls) {\n try {\n const response = await fetchFn(url, { signal });\n if (response.ok) return { response, url };\n failure = new Error(`HTTP ${response.status}`);\n } catch (error) {\n if (signal.aborted) throw error;\n failure = error;\n }\n }\n throw failure;\n }\n\n async function download(request: MediaCacheRequest, signal: AbortSignal): Promise<void> {\n try {\n const { response, url } = await fetchFirst([request.url, ...(request.alternateUrls ?? [])], signal);\n const announced = Number(response.headers.get('content-length'));\n if (announced > maxEntryBytes) {\n failures.set(request.key, now());\n return;\n }\n const data = await response.blob();\n if (signal.aborted || data.size === 0 || data.size > maxEntryBytes) return;\n const protectedKeys = new Set(wanted.map((item) => item.key));\n const evicted = planMediaCacheEviction([...index.values()], budgetBytes, data.size, protectedKeys);\n if (!evicted) return;\n if (evicted.length) {\n await store.remove(evicted);\n evicted.forEach((key) => index.delete(key));\n }\n const time = now();\n const entry: MediaCacheEntry = {\n key: request.key,\n url,\n size: data.size,\n contentType: data.type || response.headers.get('content-type') || 'application/octet-stream',\n storedAt: time,\n lastUsedAt: time,\n };\n await store.write(entry, data);\n index.set(entry.key, entry);\n failures.delete(request.key);\n emit();\n } catch {\n if (!signal.aborted) failures.set(request.key, now());\n }\n }\n\n return {\n ready,\n has: (key) => index.has(key),\n async open(key) {\n const entry = index.get(key);\n if (!entry) return null;\n const data = await store.read(key).catch(() => null);\n if (!data) {\n index.delete(key);\n await store.remove([key]).catch(() => undefined);\n emit();\n return null;\n }\n entry.lastUsedAt = now();\n void store.touch(key, entry.lastUsedAt).catch(() => undefined);\n return data;\n },\n keep(requests) {\n const seen = new Set<string>();\n wanted = requests.filter((request) => request.key && request.url && !seen.has(request.key) && seen.add(request.key));\n if (current && !wanted.some((request) => request.key === current?.key)) current.controller.abort();\n pump();\n },\n usage() {\n const entries = [...index.values()];\n return { bytes: entries.reduce((sum, entry) => sum + entry.size, 0), count: entries.length, budgetBytes };\n },\n async clear() {\n // Nothing is downloaded again until the player asks for media anew.\n wanted = [];\n current?.controller.abort();\n const keys = [...index.keys()];\n index.clear();\n failures.clear();\n await store.remove(keys);\n emit();\n },\n onChange(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n","import {\n mediaSourceItemId,\n normalizeMediaSourceAddress,\n parseMediaSourceItemId,\n ticksToSeconds,\n type MediaSourceAccount,\n type MediaSourceBrowseOptions,\n type MediaSourceConnector,\n type MediaSourceContainer,\n type MediaSourceHttp,\n type MediaSourceInput,\n type MediaSourceItem,\n type MediaSourcePage,\n} from '../domain/media-source';\n\n/**\n * Jellyfin, the free software home media server (GPL). One account gives music and videos with their covers,\n * artists, series and seasons; files are played as they are stored, so seeking works through byte ranges.\n */\nexport const JELLYFIN_CLIENT = { name: 'NGXSP', version: '1.0.0' } as const;\n\nconst AUDIO_FIELDS = 'Genres,ProductionYear,RunTimeTicks,ParentIndexNumber,IndexNumber,AlbumArtist,Artists,MediaSources';\nconst VIDEO_FIELDS = 'Genres,ProductionYear,RunTimeTicks,ParentIndexNumber,IndexNumber,SeriesName,MediaSources';\nconst PAGE_SIZE = 200;\n\nexport function createJellyfinConnector(deviceId: string = 'ngxsp'): MediaSourceConnector {\n return {\n kind: 'jellyfin',\n connect: (input, http) => connectJellyfin(input, http, deviceId),\n browse: (account, options, http) => browseJellyfin(account, options, http),\n lyrics: (account, item, http) => readJellyfinLyrics(account, item, http),\n };\n}\n\n/** Signs in and keeps the access token the server issues; the password is not stored. */\nexport async function connectJellyfin(input: MediaSourceInput, http: MediaSourceHttp, deviceId = 'ngxsp'): Promise<MediaSourceAccount> {\n const baseUrl = normalizeMediaSourceAddress(input.address);\n const system = await readJson(http, { url: `${baseUrl}/System/Info/Public` });\n const serverName = text((system as Record<string, unknown> | null)?.['ServerName']);\n\n const response = await http.send({\n url: `${baseUrl}/Users/AuthenticateByName`,\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: jellyfinClientHeader(deviceId),\n },\n json: { Username: input.username ?? '', Pw: input.password ?? '' },\n });\n if (response.status === 401) throw new Error('Jellyfin refused this user name or password');\n if (response.status >= 400) throw new Error(`Jellyfin sign-in failed (HTTP ${response.status})`);\n const body = (await response.json()) as Record<string, unknown> | null;\n const token = text(body?.['AccessToken']);\n const user = (body?.['User'] ?? {}) as Record<string, unknown>;\n const userId = text(user['Id']);\n if (!token || !userId) throw new Error('Jellyfin did not return an access token');\n\n return {\n id: `jellyfin-${userId.slice(0, 8)}`,\n kind: 'jellyfin',\n name: input.name?.trim() || serverName || new URL(baseUrl).host,\n baseUrl,\n username: text(user['Name']) ?? input.username,\n secret: token,\n userId,\n };\n}\n\n/** Libraries at the root, then albums, series and seasons, then the files they hold. */\nexport async function browseJellyfin(account: MediaSourceAccount, options: MediaSourceBrowseOptions, http: MediaSourceHttp): Promise<MediaSourcePage> {\n const { userId } = account;\n if (!userId) throw new Error('Jellyfin account is not signed in');\n\n if (!options.containerId && !options.search) {\n const body = await readJson(http, request(account, `${account.baseUrl}/Users/${userId}/Views`, options.signal));\n const containers = itemsOf(body)\n .map((view) => libraryContainer(account, view))\n .filter((container): container is MediaSourceContainer => !!container && (!options.kind || container.kind === options.kind || container.kind === 'mixed'));\n return { containers, items: [] };\n }\n\n const parameters = new URLSearchParams({\n Recursive: 'true',\n Fields: options.kind === 'video' ? VIDEO_FIELDS : AUDIO_FIELDS,\n StartIndex: String(Math.max(0, options.startIndex ?? 0)),\n Limit: String(Math.min(PAGE_SIZE, Math.max(1, options.limit ?? PAGE_SIZE))),\n ImageTypeLimit: '1',\n EnableImageTypes: 'Primary',\n });\n if (options.containerId) parameters.set('ParentId', options.containerId);\n if (options.search) parameters.set('SearchTerm', options.search);\n if (options.kind === 'video') {\n parameters.set('IncludeItemTypes', 'Movie,Episode,Video');\n parameters.set('SortBy', 'SeriesSortName,ParentIndexNumber,IndexNumber,SortName');\n } else {\n parameters.set('IncludeItemTypes', 'Audio');\n parameters.set('SortBy', 'AlbumArtist,Album,ParentIndexNumber,IndexNumber,SortName');\n }\n parameters.set('SortOrder', 'Ascending');\n\n const body = await readJson(http, request(account, `${account.baseUrl}/Users/${userId}/Items?${parameters}`, options.signal));\n const items = itemsOf(body)\n .map((entry) => parseJellyfinItem(account, entry, options.kind ?? 'audio'))\n .filter((item): item is MediaSourceItem => !!item);\n const total = Number((body as Record<string, unknown> | null)?.['TotalRecordCount']);\n return { containers: [], items, ...(Number.isFinite(total) ? { total } : {}) };\n}\n\n/**\n * Lyrics stored next to the track on the server (Jellyfin 10.9 and later). Timed lines come back as ticks of a\n * hundred nanoseconds and are written as LRC, so the player reads them with its own parser.\n */\nexport async function readJellyfinLyrics(account: MediaSourceAccount, item: MediaSourceItem, http: MediaSourceHttp): Promise<string | null> {\n const remoteId = parseMediaSourceItemId(item.id)?.remoteId;\n if (!remoteId) return null;\n const response = await http.send(request(account, `${account.baseUrl}/Audio/${encodeURIComponent(remoteId)}/Lyrics`));\n // 404 is the usual answer for a track without lyrics.\n if (response.status >= 400) return null;\n const lines = ((await response.json()) as { Lyrics?: unknown } | null)?.['Lyrics'];\n if (!Array.isArray(lines) || !lines.length) return null;\n\n const written = lines\n .map((line) => {\n const entry = line as Record<string, unknown>;\n const words = text(entry['Text']) ?? '';\n // Not ticksToSeconds: that one rounds to whole seconds and drops zero, which a first line needs.\n const ticks = Number(entry['Start']);\n return Number.isFinite(ticks) && ticks >= 0 ? `${lrcStamp(ticks / 10_000_000)}${words}` : words;\n })\n .filter((line) => line.trim());\n return written.length ? written.join('\\n') : null;\n}\n\n/** `[mm:ss.xx]`, the timestamp of an LRC line. */\nfunction lrcStamp(seconds: number): string {\n const safe = Math.max(0, seconds);\n const minutes = Math.floor(safe / 60);\n return `[${String(minutes).padStart(2, '0')}:${(safe - minutes * 60).toFixed(2).padStart(5, '0')}]`;\n}\n\n/** Plays the file as stored on the server; the browser asks for the byte ranges it needs. */\nexport function jellyfinStreamUrl(account: MediaSourceAccount, itemId: string, kind: 'audio' | 'video'): string {\n const path = kind === 'audio' ? `Audio/${encodeURIComponent(itemId)}/stream` : `Videos/${encodeURIComponent(itemId)}/stream`;\n return `${account.baseUrl}/${path}?static=true&api_key=${encodeURIComponent(account.secret ?? '')}`;\n}\n\nexport function jellyfinImageUrl(account: MediaSourceAccount, itemId: string, tag?: string, maxHeight = 480): string {\n const parameters = new URLSearchParams({ maxHeight: String(maxHeight), quality: '90' });\n if (tag) parameters.set('tag', tag);\n return `${account.baseUrl}/Items/${encodeURIComponent(itemId)}/Images/Primary?${parameters}`;\n}\n\nexport function jellyfinClientHeader(deviceId: string, token?: string): string {\n const parts = [\n `Client=\"${JELLYFIN_CLIENT.name}\"`,\n `Device=\"${JELLYFIN_CLIENT.name}\"`,\n `DeviceId=\"${deviceId}\"`,\n `Version=\"${JELLYFIN_CLIENT.version}\"`,\n ];\n if (token) parts.push(`Token=\"${token}\"`);\n return `MediaBrowser ${parts.join(', ')}`;\n}\n\nexport function parseJellyfinItem(account: MediaSourceAccount, entry: unknown, kind: 'audio' | 'video'): MediaSourceItem | null {\n const record = (entry ?? {}) as Record<string, unknown>;\n const remoteId = text(record['Id']);\n const title = text(record['Name']);\n if (!remoteId || !title) return null;\n const type = text(record['Type']);\n const itemKind: 'audio' | 'video' = type === 'Audio' ? 'audio' : type ? 'video' : kind;\n const imageTag = text((record['ImageTags'] as Record<string, unknown> | undefined)?.['Primary']);\n const albumImageTag = text(record['AlbumPrimaryImageTag']);\n const albumId = text(record['AlbumId']);\n const artworkId = imageTag ? remoteId : albumImageTag && albumId ? albumId : undefined;\n\n const item: MediaSourceItem = {\n id: mediaSourceItemId(account.id, remoteId),\n kind: itemKind,\n title,\n url: jellyfinStreamUrl(account, remoteId, itemKind),\n };\n const duration = ticksToSeconds(record['RunTimeTicks']);\n if (duration) item.durationSec = duration;\n if (artworkId) item.artworkUrl = jellyfinImageUrl(account, artworkId, imageTag ?? albumImageTag);\n const year = Number(record['ProductionYear']);\n if (Number.isInteger(year) && year > 0) item.year = year;\n const genre = allTexts(record['Genres'])[0];\n if (genre) item.genre = genre;\n const container = text(record['Container']);\n if (container) item.container = container;\n\n if (itemKind === 'audio') {\n const artists = allTexts(record['Artists']);\n const albumArtist = text(record['AlbumArtist']);\n if (artists.length) item.artist = artists.join(', ');\n else if (albumArtist) item.artist = albumArtist;\n if (albumArtist) item.albumArtist = albumArtist;\n const album = text(record['Album']);\n if (album) item.album = album;\n const trackNo = positiveInteger(record['IndexNumber']);\n if (trackNo) item.trackNo = trackNo;\n const discNo = positiveInteger(record['ParentIndexNumber']);\n if (discNo) item.discNo = discNo;\n return item;\n }\n\n const series = text(record['SeriesName']);\n if (series) {\n item.series = series;\n const season = positiveInteger(record['ParentIndexNumber']);\n if (season) item.season = season;\n const episode = positiveInteger(record['IndexNumber']);\n if (episode) item.episode = episode;\n }\n return item;\n}\n\nfunction libraryContainer(account: MediaSourceAccount, view: unknown): MediaSourceContainer | null {\n const record = (view ?? {}) as Record<string, unknown>;\n const id = text(record['Id']);\n const title = text(record['Name']);\n if (!id || !title) return null;\n const collection = text(record['CollectionType']);\n // Libraries holding something else (books, photos, live TV) are not offered.\n const kind = collection === 'music' ? 'audio'\n : collection === 'movies' || collection === 'tvshows' || collection === 'homevideos' || collection === 'musicvideos' ? 'video'\n : collection ? null : 'mixed';\n if (!kind) return null;\n const imageTag = text((record['ImageTags'] as Record<string, unknown> | undefined)?.['Primary']);\n return {\n id,\n title,\n kind,\n ...(collection ? { subtitle: collection } : {}),\n ...(imageTag ? { artworkUrl: jellyfinImageUrl(account, id, imageTag) } : {}),\n };\n}\n\nfunction request(account: MediaSourceAccount, url: string, signal?: AbortSignal) {\n return {\n url,\n headers: { Authorization: jellyfinClientHeader(account.id, account.secret), Accept: 'application/json' },\n ...(signal ? { signal } : {}),\n };\n}\n\nasync function readJson(http: MediaSourceHttp, options: Parameters<MediaSourceHttp['send']>[0]): Promise<unknown> {\n const response = await http.send(options);\n if (response.status === 401 || response.status === 403) throw new Error('Jellyfin refused the connection; sign in again');\n if (response.status >= 400) throw new Error(`Jellyfin request failed (HTTP ${response.status})`);\n return response.json();\n}\n\nfunction itemsOf(body: unknown): unknown[] {\n const items = (body as { Items?: unknown } | null)?.['Items'];\n return Array.isArray(items) ? items : [];\n}\n\nfunction text(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction allTexts(value: unknown): string[] {\n return (Array.isArray(value) ? value : [value]).flatMap((entry) => {\n const item = text(entry);\n return item ? [item] : [];\n });\n}\n\nfunction positiveInteger(value: unknown): number | undefined {\n const number = Number(value);\n return Number.isInteger(number) && number > 0 ? number : undefined;\n}\n","/**\n * Small readers for the XML documents media servers answer (WebDAV multistatus, UPnP descriptions, DIDL-Lite).\n * Namespace prefixes vary between servers, so elements are matched by local name; documents are small and trusted to\n * be well formed enough for that.\n */\n\nexport interface XmlElement {\n attributes: Record<string, string>;\n /** Raw inner markup; undefined for self-closing elements. */\n content: string | undefined;\n}\n\n/** Inner markup of the first element with this local name. */\nexport function xmlTagContent(xml: string, name: string): string | undefined {\n const match = new RegExp(`<(?:[\\\\w.-]+:)?${name}\\\\b[^>]*?(?:/>|>([\\\\s\\\\S]*?)</(?:[\\\\w.-]+:)?${name}>)`, 'i').exec(xml);\n return match ? (match[1] ?? '') : undefined;\n}\n\n/** Decoded, trimmed text of the first element with this local name; undefined when absent or empty. */\nexport function xmlTagText(xml: string, name: string): string | undefined {\n return xmlText(xmlTagContent(xml, name));\n}\n\n/** Every element with this local name, with its decoded attributes. */\nexport function xmlElements(xml: string, name: string): XmlElement[] {\n const pattern = new RegExp(`<(?:[\\\\w.-]+:)?${name}\\\\b((?:[^>\"']|\"[^\"]*\"|'[^']*')*?)(?:/>|>([\\\\s\\\\S]*?)</(?:[\\\\w.-]+:)?${name}>)`, 'gi');\n return [...xml.matchAll(pattern)].map((match) => ({ attributes: xmlAttributes(match[1]), content: match[2] }));\n}\n\nexport function xmlText(content: string | undefined): string | undefined {\n const value = content === undefined ? undefined : decodeXmlEntities(content.replace(/<!\\[CDATA\\[([\\s\\S]*?)\\]\\]>/g, '$1')).trim();\n return value || undefined;\n}\n\nexport function decodeXmlEntities(value: string): string {\n return value\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&quot;/g, '\"')\n .replace(/&apos;/g, \"'\")\n .replace(/&#(\\d+);/g, (_, code: string) => String.fromCodePoint(Number(code)))\n .replace(/&#x([0-9a-f]+);/gi, (_, code: string) => String.fromCodePoint(parseInt(code, 16)))\n .replace(/&amp;/g, '&');\n}\n\nexport function escapeXmlText(value: string): string {\n return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;').replace(/'/g, '&apos;');\n}\n\nfunction xmlAttributes(source: string): Record<string, string> {\n const attributes: Record<string, string> = {};\n for (const match of source.matchAll(/([\\w.:-]+)\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/g)) {\n // Local names, like elements: `dlna:profileID` reads as `profileID`.\n attributes[match[1].replace(/^[\\w.-]+:/, '')] = decodeXmlEntities(match[3] ?? match[4] ?? '');\n }\n return attributes;\n}\n","import type { MediaSourceHttp } from '../domain/media-source';\nimport { escapeXmlText, xmlElements, xmlTagText } from './xml-text';\n\n/** A service of a UPnP device (ContentDirectory, AVTransport, RenderingControl…) and where to send its actions. */\nexport interface UpnpService {\n serviceType: string;\n controlUrl: string;\n}\n\nexport interface UpnpDeviceDescription {\n udn?: string;\n friendlyName: string;\n deviceType?: string;\n manufacturer?: string;\n modelName?: string;\n iconUrl?: string;\n /** Every service the device and its embedded devices offer. */\n services: UpnpService[];\n contentDirectory?: UpnpService;\n}\n\n/** A UPnP action the device refused; `code` is its UPnP error code when it gave one. */\nexport class UpnpActionError extends Error {\n constructor(readonly action: string, readonly code: string | undefined, readonly status: number) {\n super(`UPnP ${action} failed (${code ? `UPnP error ${code}` : `HTTP ${status}`})`);\n this.name = 'UpnpActionError';\n }\n}\n\nexport function parseUpnpDeviceDescription(xml: string, descriptionUrl: string): UpnpDeviceDescription {\n const base = xmlTagText(xml, 'URLBase') ?? descriptionUrl;\n const services = xmlElements(xml, 'service').flatMap((element): UpnpService[] => {\n const content = element.content ?? '';\n const serviceType = xmlTagText(content, 'serviceType');\n const controlUrl = resolveUpnpUrl(xmlTagText(content, 'controlURL'), base);\n return serviceType && controlUrl ? [{ serviceType, controlUrl }] : [];\n });\n const icon = xmlElements(xml, 'icon')\n .map((element) => ({\n url: resolveUpnpUrl(xmlTagText(element.content ?? '', 'url'), base),\n width: Number(xmlTagText(element.content ?? '', 'width')) || 0,\n type: xmlTagText(element.content ?? '', 'mimetype') ?? '',\n }))\n .filter((candidate) => candidate.url && /png|jpe?g/i.test(candidate.type))\n .sort((left, right) => right.width - left.width)[0];\n\n const udn = xmlTagText(xml, 'UDN');\n const deviceType = xmlTagText(xml, 'deviceType');\n const manufacturer = xmlTagText(xml, 'manufacturer');\n const modelName = xmlTagText(xml, 'modelName');\n const contentDirectory = findUpnpService(services, 'ContentDirectory');\n return {\n friendlyName: xmlTagText(xml, 'friendlyName') ?? modelName ?? new URL(descriptionUrl).host,\n ...(udn ? { udn } : {}),\n ...(deviceType ? { deviceType } : {}),\n ...(manufacturer ? { manufacturer } : {}),\n ...(modelName ? { modelName } : {}),\n ...(icon?.url ? { iconUrl: icon.url } : {}),\n services,\n ...(contentDirectory ? { contentDirectory } : {}),\n };\n}\n\n/** The first service of this kind (`AVTransport`, `RenderingControl`…), whatever its version. */\nexport function findUpnpService(services: readonly UpnpService[], name: string): UpnpService | undefined {\n return services.find((service) => service.serviceType.startsWith(`urn:schemas-upnp-org:service:${name}:`));\n}\n\n/** Sends a SOAP action and returns the answer; a refusal throws `UpnpActionError`. */\nexport async function upnpAction(\n http: MediaSourceHttp,\n service: UpnpService,\n action: string,\n soapArguments: Record<string, string>,\n signal?: AbortSignal,\n): Promise<string> {\n const body = '<?xml version=\"1.0\" encoding=\"utf-8\"?>'\n + '<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">'\n + `<s:Body><u:${action} xmlns:u=\"${service.serviceType}\">`\n + Object.entries(soapArguments).map(([name, value]) => `<${name}>${escapeXmlText(value)}</${name}>`).join('')\n + `</u:${action}></s:Body></s:Envelope>`;\n const response = await http.send({\n url: service.controlUrl,\n method: 'POST',\n headers: { 'Content-Type': 'text/xml; charset=\"utf-8\"', SOAPACTION: `\"${service.serviceType}#${action}\"` },\n body,\n ...(signal ? { signal } : {}),\n });\n const text = await response.text();\n if (response.status >= 400) throw new UpnpActionError(action, xmlTagText(text, 'errorCode'), response.status);\n return text;\n}\n\nexport function resolveUpnpUrl(value: string | undefined, base: string): string | undefined {\n if (!value) return undefined;\n try {\n const url = new URL(value, base);\n return url.protocol === 'http:' || url.protocol === 'https:' ? url.toString() : undefined;\n } catch {\n return undefined;\n }\n}\n","import {\n mediaSourceItemId,\n normalizeMediaSourceAddress,\n type MediaSourceAccount,\n type MediaSourceBrowseOptions,\n type MediaSourceConnector,\n type MediaSourceContainer,\n type MediaSourceHttp,\n type MediaSourceInput,\n type MediaSourceItem,\n type MediaSourcePage,\n} from '../domain/media-source';\nimport { cleanMediaTitle, parseEpisodeFileName } from '../domain/media-library-model';\nimport { parseUpnpDeviceDescription, resolveUpnpUrl, upnpAction, UpnpActionError, type UpnpService } from './upnp';\nimport { xmlElements, xmlTagContent, xmlTagText, xmlText, type XmlElement } from './xml-text';\n\n/**\n * UPnP AV / DLNA media servers (ReadyMedia/MiniDLNA, Gerbera, Kodi, Jellyfin's DLNA plugin, most NAS): the device\n * description names the server and its ContentDirectory service, which is browsed with SOAP `Browse` requests that\n * answer DIDL-Lite documents. Files are served over plain HTTP without credentials.\n *\n * Servers answer neither web pages (no CORS) nor discovery from a browser: applications find them with SSDP through\n * their native shell, using `DLNA_MEDIA_SERVER_SEARCH_TARGET`, or take the address of the description document.\n */\nexport const DLNA_MEDIA_SERVER_SEARCH_TARGET = 'urn:schemas-upnp-org:device:MediaServer:1';\n\n/** Where common servers publish their description when only a host and port are typed. */\nconst DESCRIPTION_PATHS = ['/rootDesc.xml', '/description.xml', '/DeviceDescription.xml'];\n/** Same leading track numbers as local file names (\"02 - Title\"). */\nconst LEADING_TRACK_NUMBER = /^(\\d{1,3})(?:[\\s._-]+|\\s*-\\s*)(.+)$/;\nconst PAGE_SIZE = 200;\nconst MAX_ENTRIES = 5000;\n\nexport interface DidlResource {\n url: string;\n mimeType?: string;\n durationSec?: number;\n size?: number;\n}\n\nexport interface DidlObject {\n id: string;\n parentId?: string;\n container: boolean;\n title: string;\n upnpClass: string;\n childCount?: number;\n artists: Array<{ name: string; role?: string }>;\n creator?: string;\n album?: string;\n genre?: string;\n date?: string;\n trackNo?: number;\n artworkUrl?: string;\n seriesTitle?: string;\n season?: number;\n episode?: number;\n resources: DidlResource[];\n}\n\nexport function createDlnaConnector(): MediaSourceConnector {\n return {\n kind: 'dlna',\n connect: (input, http) => connectDlna(input, http),\n browse: (account, options, http) => browseDlna(account, options, http),\n };\n}\n\n/** Reads the device description (typed, or found on the network) and checks the device serves media. */\nexport async function connectDlna(input: MediaSourceInput, http: MediaSourceHttp): Promise<MediaSourceAccount> {\n const address = normalizeMediaSourceAddress(input.address);\n const candidates = new URL(address).pathname === '/' ? DESCRIPTION_PATHS.map((path) => `${address}${path}`) : [address];\n\n for (const descriptionUrl of candidates) {\n const response = await http.send({ url: descriptionUrl });\n if (response.status >= 400) continue;\n const description = parseUpnpDeviceDescription(await response.text(), descriptionUrl);\n if (!description.contentDirectory) throw new Error('This device is not a media server');\n contentDirectories.set(descriptionUrl, Promise.resolve(description.contentDirectory));\n return {\n id: `dlna-${shortHash(description.udn ?? descriptionUrl)}`,\n kind: 'dlna',\n name: input.name?.trim() || description.friendlyName,\n baseUrl: descriptionUrl,\n };\n }\n throw new Error('No media server description at this address');\n}\n\n/**\n * Children of a container, the root when none is given. Folders come first, then the files the app plays; a search\n * asks the server for matching titles when it supports it.\n */\nexport async function browseDlna(account: MediaSourceAccount, options: MediaSourceBrowseOptions, http: MediaSourceHttp): Promise<MediaSourcePage> {\n const service = await contentDirectory(account, http, options.signal);\n const kind = options.kind ?? 'audio';\n const limit = Math.min(options.limit ?? MAX_ENTRIES, MAX_ENTRIES);\n const objects: DidlObject[] = [];\n let start = options.startIndex ?? 0;\n let total: number | undefined;\n\n try {\n while (objects.length < limit) {\n const count = Math.min(PAGE_SIZE, limit - objects.length);\n const soapArguments: Record<string, string> = options.search\n ? {\n ContainerID: '0',\n SearchCriteria: `upnp:class derivedfrom \"object.item.${kind}Item\" and dc:title contains \"${options.search.replace(/[\"\\\\]/g, '\\\\$&')}\"`,\n Filter: '*',\n StartingIndex: String(start),\n RequestedCount: String(count),\n SortCriteria: '',\n }\n : {\n ObjectID: options.containerId ?? '0',\n BrowseFlag: 'BrowseDirectChildren',\n Filter: '*',\n StartingIndex: String(start),\n RequestedCount: String(count),\n SortCriteria: '',\n };\n const answer = await soap(http, service, options.search ? 'Search' : 'Browse', soapArguments, options.signal, Boolean(options.search));\n if (!answer) return { containers: [], items: [] };\n const page = parseDidlLite(answer.result, service.controlUrl);\n objects.push(...page);\n total = answer.totalMatches;\n start += answer.numberReturned || page.length;\n if (!page.length || (total !== undefined && start >= total)) break;\n }\n } catch (error) {\n // The server may have moved or restarted with another layout: read its description again next time.\n contentDirectories.delete(account.baseUrl);\n throw error;\n }\n\n const containers = options.search ? [] : objects.filter((object) => object.container && showsContainer(object, kind)).map(containerFrom);\n const items = objects.filter((object) => !object.container).flatMap((object) => itemFrom(account, object, kind) ?? []);\n return { containers, items, total: items.length };\n}\n\n/** Containers and items of a DIDL-Lite document, with relative links resolved against `baseUrl`. */\nexport function parseDidlLite(xml: string, baseUrl: string): DidlObject[] {\n const document = /<(?:[\\w.-]+:)?DIDL-Lite\\b/i.test(xml) ? xml : '';\n const read = (element: XmlElement, container: boolean): DidlObject | null => {\n const content = element.content ?? '';\n const id = element.attributes['id'];\n if (!id) return null;\n const resources = xmlElements(content, 'res').flatMap((resource): DidlResource[] => {\n const url = resolveUpnpUrl(xmlText(resource.content), baseUrl);\n if (!url) return [];\n const mimeType = resource.attributes['protocolInfo']?.split(':')[2];\n const durationSec = parseDuration(resource.attributes['duration']);\n const size = Number(resource.attributes['size']);\n return [{\n url,\n ...(mimeType && mimeType !== '*' ? { mimeType: mimeType.toLowerCase() } : {}),\n ...(durationSec ? { durationSec } : {}),\n ...(Number.isFinite(size) && size > 0 ? { size } : {}),\n }];\n });\n const childCount = Number(element.attributes['childCount']);\n const object: DidlObject = {\n id,\n container,\n title: xmlTagText(content, 'title') ?? id,\n upnpClass: xmlTagText(content, 'class') ?? (container ? 'object.container' : 'object.item'),\n artists: xmlElements(content, 'artist').flatMap((artist) => {\n const name = xmlText(artist.content);\n return name ? [{ name, ...(artist.attributes['role'] ? { role: artist.attributes['role'] } : {}) }] : [];\n }),\n resources,\n };\n const optional: Partial<DidlObject> = {\n parentId: element.attributes['parentID'],\n childCount: Number.isFinite(childCount) && element.attributes['childCount'] !== undefined ? childCount : undefined,\n creator: xmlTagText(content, 'creator'),\n album: xmlTagText(content, 'album'),\n genre: xmlTagText(content, 'genre'),\n date: xmlTagText(content, 'date'),\n trackNo: positive(xmlTagText(content, 'originalTrackNumber')),\n artworkUrl: resolveUpnpUrl(xmlTagText(content, 'albumArtURI'), baseUrl),\n seriesTitle: xmlTagText(content, 'seriesTitle'),\n season: positive(xmlTagText(content, 'episodeSeason')),\n episode: positive(xmlTagText(content, 'episodeNumber')),\n };\n for (const [key, value] of Object.entries(optional)) {\n if (value !== undefined) (object as unknown as Record<string, unknown>)[key] = value;\n }\n return object;\n };\n return [\n ...xmlElements(document, 'container').flatMap((element) => read(element, true) ?? []),\n ...xmlElements(document, 'item').flatMap((element) => read(element, false) ?? []),\n ];\n}\n\n/** Service addresses by description URL: read once per session, and again after a failure. */\nconst contentDirectories = new Map<string, Promise<UpnpService>>();\n\nfunction contentDirectory(account: MediaSourceAccount, http: MediaSourceHttp, signal?: AbortSignal): Promise<UpnpService> {\n let pending = contentDirectories.get(account.baseUrl);\n if (!pending) {\n pending = (async () => {\n const response = await http.send({ url: account.baseUrl, ...(signal ? { signal } : {}) });\n if (response.status >= 400) throw new Error('The media server is not reachable at its last address');\n const service = parseUpnpDeviceDescription(await response.text(), account.baseUrl).contentDirectory;\n if (!service) throw new Error('This device is not a media server');\n return service;\n })();\n contentDirectories.set(account.baseUrl, pending);\n pending.catch(() => contentDirectories.delete(account.baseUrl));\n }\n return pending;\n}\n\nasync function soap(\n http: MediaSourceHttp,\n service: UpnpService,\n action: 'Browse' | 'Search',\n soapArguments: Record<string, string>,\n signal: AbortSignal | undefined,\n optional: boolean,\n): Promise<{ result: string; numberReturned: number; totalMatches?: number } | null> {\n let text: string;\n try {\n text = await upnpAction(http, service, action, soapArguments, signal);\n } catch (error) {\n if (!(error instanceof UpnpActionError)) throw error;\n // Search is optional in UPnP: servers without it answer \"invalid action\" (401) or \"unsupported\" (708).\n if (optional && (error.code === '401' || error.code === '708' || error.code === '710')) return null;\n if (error.code === '701' || error.code === '710') throw new Error('This folder is no longer on the media server');\n throw new Error(`Media server request failed (${error.code ? `UPnP error ${error.code}` : `HTTP ${error.status}`})`);\n }\n const totalMatches = Number(xmlTagText(text, 'TotalMatches'));\n return {\n result: xmlText(xmlTagContent(text, 'Result')) ?? '',\n numberReturned: Number(xmlTagText(text, 'NumberReturned')) || 0,\n ...(Number.isFinite(totalMatches) && xmlTagText(text, 'TotalMatches') !== undefined ? { totalMatches } : {}),\n };\n}\n\nfunction showsContainer(object: DidlObject, kind: 'audio' | 'video'): boolean {\n const upnpClass = object.upnpClass.toLowerCase();\n if (upnpClass.startsWith('object.container.album.photoalbum')) return false;\n if (kind === 'video') return !/^object\\.container\\.(album\\.musicalbum|person\\.musicartist|genre\\.musicgenre)/.test(upnpClass);\n return !/^object\\.container\\.(genre\\.moviegenre|storagefolder\\.video)/.test(upnpClass);\n}\n\nfunction containerFrom(object: DidlObject): MediaSourceContainer {\n const upnpClass = object.upnpClass.toLowerCase();\n const kind = /music|audio/.test(upnpClass) ? 'audio' : /video|movie/.test(upnpClass) ? 'video' : 'mixed';\n const artist = object.artists.find((entry) => !entry.role)?.name ?? object.creator;\n return {\n id: object.id,\n title: object.title,\n kind,\n ...(artist && upnpClass.startsWith('object.container.album') ? { subtitle: artist } : {}),\n ...(object.artworkUrl ? { artworkUrl: object.artworkUrl } : {}),\n ...(object.childCount !== undefined ? { childCount: object.childCount } : {}),\n };\n}\n\nfunction itemFrom(account: MediaSourceAccount, object: DidlObject, kind: 'audio' | 'video'): MediaSourceItem | null {\n const upnpClass = object.upnpClass.toLowerCase();\n const classKind = upnpClass.startsWith('object.item.audioitem') ? 'audio' : upnpClass.startsWith('object.item.videoitem') ? 'video' : undefined;\n if (classKind && classKind !== kind) return null;\n // Originals come first; generic items are recognised by the type of what they serve.\n const resource = object.resources.find((entry) => entry.mimeType?.startsWith(`${kind}/`))\n ?? (classKind ? object.resources.find((entry) => !entry.mimeType?.startsWith('image/')) : undefined);\n if (!resource) return null;\n\n const item: MediaSourceItem = {\n id: mediaSourceItemId(account.id, object.id),\n kind,\n title: object.title,\n url: resource.url,\n };\n if (resource.durationSec) item.durationSec = resource.durationSec;\n if (object.artworkUrl) item.artworkUrl = object.artworkUrl;\n if (object.genre) item.genre = object.genre;\n // A full timestamp is the file's date (Gerbera on untagged files), not the year of the work.\n const year = object.date && !object.date.includes('T') ? positive(object.date.slice(0, 4)) : undefined;\n if (year) item.year = year;\n\n if (kind === 'audio') {\n const albumArtist = object.artists.find((entry) => /^albumartist$/i.test(entry.role ?? ''))?.name;\n const artist = object.artists.find((entry) => !entry.role || /^performer$/i.test(entry.role))?.name ?? object.creator ?? albumArtist;\n if (artist) item.artist = artist;\n if (albumArtist) item.albumArtist = albumArtist;\n if (object.album) item.album = object.album;\n if (object.trackNo) item.trackNo = object.trackNo;\n const numbered = LEADING_TRACK_NUMBER.exec(object.title);\n if (numbered && !object.trackNo && !object.album && !artist) {\n // Untagged files are titled after their names by most servers: read them like local files.\n item.trackNo = Number(numbered[1]);\n item.title = cleanMediaTitle(numbered[2]) || object.title;\n }\n return item;\n }\n\n if (object.seriesTitle || (object.season && object.episode)) {\n if (object.seriesTitle) item.series = object.seriesTitle;\n if (object.season) item.season = object.season;\n if (object.episode) item.episode = object.episode;\n return item;\n }\n // Many servers title videos after their file names: read episodes and release names the way local folders do.\n const parsed = parseEpisodeFileName(object.title);\n if (parsed?.season !== undefined && parsed.episode !== undefined) {\n if (parsed.series) item.series = parsed.series;\n item.season = parsed.season;\n item.episode = parsed.episode;\n item.title = parsed.episodeTitle ?? parsed.series ?? object.title;\n } else if (!/\\s/.test(object.title) && /[._]/.test(object.title)) {\n item.title = cleanMediaTitle(object.title) || object.title;\n }\n return item;\n}\n\n/** `H+:MM:SS[.F+]` (DIDL-Lite `res@duration`) to whole seconds. */\nfunction parseDuration(value: string | undefined): number | undefined {\n const match = /^(\\d+):(\\d{1,2}):(\\d{1,2})(?:\\.(\\d+)(?:\\/(\\d+))?)?$/.exec(value?.trim() ?? '');\n if (!match) return undefined;\n const fraction = match[4] ? (match[5] ? Number(match[4]) / Number(match[5]) : Number(`0.${match[4]}`)) : 0;\n const seconds = Number(match[1]) * 3600 + Number(match[2]) * 60 + Number(match[3]) + fraction;\n return seconds > 0 ? Math.round(seconds) : undefined;\n}\n\nfunction positive(value: string | undefined): number | undefined {\n const number = Number(value);\n return Number.isInteger(number) && number > 0 ? number : undefined;\n}\n\nfunction shortHash(value: string): string {\n let hash = 0;\n for (let index = 0; index < value.length; index += 1) hash = (Math.imul(31, hash) + value.charCodeAt(index)) | 0;\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n","import type { MediaSourceHttp } from '../domain/media-source';\nimport {\n formatRemoteClock,\n parseRemoteClock,\n RemotePlaybackError,\n type RemotePlaybackMedia,\n type RemotePlaybackSession,\n type RemotePlaybackStatus,\n type RemotePlayerState,\n} from '../domain/remote-playback';\nimport { findUpnpService, parseUpnpDeviceDescription, upnpAction, UpnpActionError, type UpnpService } from './upnp';\nimport { escapeXmlText, xmlTagText } from './xml-text';\n\n/**\n * UPnP AV / DLNA renderers (smart TVs, network speakers, Kodi, gmrender): media is handed over with AVTransport\n * `SetAVTransportURI` and driven with `Play`, `Pause`, `Seek` and `Stop`; RenderingControl sets the volume. Renderers\n * fetch the media themselves, over plain HTTP.\n */\nexport const DLNA_MEDIA_RENDERER_SEARCH_TARGET = 'urn:schemas-upnp-org:device:MediaRenderer:1';\n\nexport interface DlnaRendererInfo {\n name: string;\n udn?: string;\n modelName?: string;\n avTransport: UpnpService;\n renderingControl?: UpnpService;\n}\n\n/** Reads a renderer's description; devices without AVTransport cannot play what they are sent. */\nexport async function readDlnaRenderer(descriptionUrl: string, http: MediaSourceHttp): Promise<DlnaRendererInfo> {\n const response = await http.send({ url: descriptionUrl });\n if (response.status >= 400) throw new Error('The renderer is not reachable');\n const description = parseUpnpDeviceDescription(await response.text(), descriptionUrl);\n const avTransport = findUpnpService(description.services, 'AVTransport');\n if (!avTransport) throw new Error('This device cannot play media sent to it');\n const renderingControl = findUpnpService(description.services, 'RenderingControl');\n return {\n name: description.friendlyName,\n ...(description.udn ? { udn: description.udn } : {}),\n ...(description.modelName ? { modelName: description.modelName } : {}),\n avTransport,\n ...(renderingControl ? { renderingControl } : {}),\n };\n}\n\nexport async function createDlnaRendererSession(descriptionUrl: string, http: MediaSourceHttp): Promise<RemotePlaybackSession> {\n const renderer = await readDlnaRenderer(descriptionUrl, http);\n const transport = (action: string, soapArguments: Record<string, string> = {}) =>\n upnpAction(http, renderer.avTransport, action, { InstanceID: '0', ...soapArguments });\n\n return {\n kind: 'dlna',\n async load(media) {\n const soapArguments = { CurrentURI: media.url, CurrentURIMetaData: didlMetadata(media) };\n try {\n await transport('SetAVTransportURI', soapArguments);\n } catch (error) {\n // Some renderers refuse a new address while they play (\"transition not available\", 701/705): stop first.\n if (!(error instanceof UpnpActionError)) throw error;\n await transport('Stop').catch(() => undefined);\n await transport('SetAVTransportURI', soapArguments).catch((retryError: unknown) => {\n // 714, \"illegal MIME-type\": the renderer does not read this format.\n if (retryError instanceof UpnpActionError && retryError.code === '714') {\n throw new RemotePlaybackError('load-failed', 'The renderer does not read this format');\n }\n throw retryError;\n });\n }\n await transport('Play', { Speed: '1' });\n if (media.startSec && media.startSec > 1 && !media.live) {\n // Renderers ignore a seek while they still open the media: some say TRANSITIONING, others already say\n // PLAYING, so wait until the position moves.\n for (let attempt = 0; attempt < 20; attempt++) {\n const state = xmlTagText(await transport('GetTransportInfo').catch(() => ''), 'CurrentTransportState');\n if (state === 'PAUSED_PLAYBACK') break;\n if (state === 'PLAYING' && (parseRemoteClock(xmlTagText(await transport('GetPositionInfo').catch(() => ''), 'RelTime')) ?? 0) > 0) break;\n await new Promise((resolve) => setTimeout(resolve, 250));\n }\n await transport('Seek', { Unit: 'REL_TIME', Target: formatRemoteClock(media.startSec) }).catch(() => undefined);\n }\n },\n play: async () => void (await transport('Play', { Speed: '1' })),\n pause: async () => void (await transport('Pause')),\n seek: async (positionSec) => void (await transport('Seek', { Unit: 'REL_TIME', Target: formatRemoteClock(positionSec) })),\n stop: async () => void (await transport('Stop')),\n async setVolume(level) {\n if (!renderer.renderingControl) return;\n const volume = String(Math.round(Math.min(Math.max(level, 0), 1) * 100));\n await upnpAction(http, renderer.renderingControl, 'SetVolume', { InstanceID: '0', Channel: 'Master', DesiredVolume: volume });\n },\n async status(): Promise<RemotePlaybackStatus> {\n const [transportInfo, positionInfo, volumeInfo] = await Promise.all([\n transport('GetTransportInfo'),\n transport('GetPositionInfo').catch(() => ''),\n renderer.renderingControl\n ? upnpAction(http, renderer.renderingControl, 'GetVolume', { InstanceID: '0', Channel: 'Master' }).catch(() => '')\n : Promise.resolve(''),\n ]);\n const positionSec = parseRemoteClock(xmlTagText(positionInfo, 'RelTime'));\n const durationSec = parseRemoteClock(xmlTagText(positionInfo, 'TrackDuration'));\n const volume = Number(xmlTagText(volumeInfo, 'CurrentVolume'));\n const transportStatus = xmlTagText(transportInfo, 'CurrentTransportStatus');\n return {\n state: playerState(xmlTagText(transportInfo, 'CurrentTransportState')),\n ...(positionSec !== undefined ? { positionSec } : {}),\n ...(durationSec ? { durationSec } : {}),\n ...(volumeInfo && Number.isFinite(volume) ? { volume: Math.min(Math.max(volume / 100, 0), 1) } : {}),\n ...(transportStatus && transportStatus !== 'OK' ? { error: transportStatus } : {}),\n };\n },\n // UPnP control is stateless: there is no connection to leave.\n close: async () => undefined,\n };\n}\n\nfunction playerState(value: string | undefined): RemotePlayerState {\n switch (value) {\n case 'PLAYING': return 'playing';\n case 'PAUSED_PLAYBACK':\n case 'PAUSED_RECORDING': return 'paused';\n case 'TRANSITIONING': return 'buffering';\n case 'STOPPED': return 'stopped';\n default: return 'idle';\n }\n}\n\n/** DIDL-Lite describing the media, so the renderer shows a title and picks a decoder before reading the file. */\nfunction didlMetadata(media: RemotePlaybackMedia): string {\n const upnpClass = media.kind === 'video' ? 'object.item.videoItem' : 'object.item.audioItem.musicTrack';\n const duration = media.durationSec && !media.live ? ` duration=\"${formatRemoteClock(media.durationSec)}.000\"` : '';\n return '<DIDL-Lite xmlns=\"urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\"'\n + ' xmlns:upnp=\"urn:schemas-upnp-org:metadata-1-0/upnp/\">'\n + '<item id=\"0\" parentID=\"-1\" restricted=\"1\">'\n + `<dc:title>${escapeXmlText(media.title)}</dc:title>`\n + (media.artist ? `<upnp:artist>${escapeXmlText(media.artist)}</upnp:artist>` : '')\n + (media.album ? `<upnp:album>${escapeXmlText(media.album)}</upnp:album>` : '')\n + (media.artworkUrl ? `<upnp:albumArtURI>${escapeXmlText(media.artworkUrl)}</upnp:albumArtURI>` : '')\n + `<upnp:class>${upnpClass}</upnp:class>`\n + `<res protocolInfo=\"http-get:*:${escapeXmlText(media.contentType)}:*\"${duration}>${escapeXmlText(media.url)}</res>`\n + '</item></DIDL-Lite>';\n}\n","/**\n * Just enough DNS for mDNS service discovery (RFC 6762/6763): a PTR question for a service type, and the PTR, SRV,\n * TXT and A records devices answer with. Apps send the question from an ordinary UDP port to 224.0.0.251:5353\n * (\"legacy unicast\" query), so devices answer that port directly and no process has to share port 5353. An app that\n * advertises a service of its own reads the questions (`parseMdnsQuestions`) and answers them (`encodeMdnsResponse`).\n */\nexport const MDNS_ADDRESS = '224.0.0.251';\nexport const MDNS_PORT = 5353;\n\nexport type MdnsRecord =\n | { type: 'PTR'; name: string; target: string }\n | { type: 'SRV'; name: string; target: string; port: number }\n | { type: 'TXT'; name: string; entries: Record<string, string> }\n | { type: 'A'; name: string; address: string };\n\n/** A service instance put together from the records of one or more answers. */\nexport interface MdnsService {\n /** Full instance name, e.g. `Kitchen._googlecast._tcp.local`. */\n instance: string;\n host?: string;\n address?: string;\n port?: number;\n txt: Record<string, string>;\n}\n\n/** A PTR question for a service type (`_googlecast._tcp.local`). */\nexport function encodeMdnsQuery(serviceType: string, id = 1 + Math.floor(Math.random() * 0xfffe)): Uint8Array {\n const bytes = [id >> 8, id & 0xff, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0];\n for (const label of serviceType.replace(/\\.$/, '').split('.')) {\n const encoded = new TextEncoder().encode(label);\n if (!encoded.length || encoded.length > 63) throw new Error('Invalid service type');\n bytes.push(encoded.length, ...encoded);\n }\n bytes.push(0, 0, 12, 0, 1);\n return new Uint8Array(bytes);\n}\n\n/** The questions of a DNS query (not of a response); malformed messages give none. */\nexport function parseMdnsQuestions(bytes: Uint8Array): Array<{ name: string; type: number }> {\n try {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n if (view.getUint16(2) & 0x8000) return [];\n const questions: Array<{ name: string; type: number }> = [];\n let offset = 12;\n for (let index = 0; index < Math.min(view.getUint16(4), 32); index++) {\n const { name, next } = readName(bytes, offset);\n questions.push({ name, type: view.getUint16(next) });\n offset = next + 4;\n }\n return questions;\n } catch {\n return [];\n }\n}\n\n/**\n * A response carrying `records`: what a service advertises (PTR to its instance, SRV, TXT, A). `ttl` 0 says goodbye.\n * `id` and `question` echo a legacy unicast query, which expects them back.\n */\nexport function encodeMdnsResponse(\n records: readonly MdnsRecord[],\n options: { id?: number; ttl?: number; question?: { name: string; type: number } } = {},\n): Uint8Array {\n const bytes: number[] = [];\n const u16 = (value: number) => bytes.push((value >> 8) & 0xff, value & 0xff);\n const u32 = (value: number) => bytes.push((value >>> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff);\n const name = (value: string, into: number[] = bytes) => {\n for (const label of value.replace(/\\.$/, '').split('.')) {\n const encoded = new TextEncoder().encode(label);\n if (!encoded.length || encoded.length > 63) throw new Error('Invalid DNS name');\n into.push(encoded.length, ...encoded);\n }\n into.push(0);\n };\n u16(options.id ?? 0);\n u16(0x8400);\n u16(options.question ? 1 : 0);\n u16(records.length);\n u16(0);\n u16(0);\n if (options.question) {\n name(options.question.name);\n u16(options.question.type);\n u16(1);\n }\n for (const record of records) {\n const data: number[] = [];\n if (record.type === 'PTR') name(record.target, data);\n if (record.type === 'SRV') {\n data.push(0, 0, 0, 0, (record.port >> 8) & 0xff, record.port & 0xff);\n name(record.target, data);\n }\n if (record.type === 'TXT') {\n for (const [key, value] of Object.entries(record.entries)) {\n const entry = new TextEncoder().encode(`${key}=${value}`).subarray(0, 255);\n data.push(entry.length, ...entry);\n }\n if (!data.length) data.push(0);\n }\n if (record.type === 'A') data.push(...record.address.split('.').map((part) => Number(part) & 0xff));\n name(record.name);\n u16({ PTR: 12, SRV: 33, TXT: 16, A: 1 }[record.type]);\n u16(1);\n // Addresses and ports change more often than a service's name and details.\n u32(options.ttl ?? (record.type === 'SRV' || record.type === 'A' ? 120 : 4500));\n u16(data.length);\n bytes.push(...data);\n }\n return new Uint8Array(bytes);\n}\n\n/** Answer and additional records of a DNS message; malformed messages give no records. */\nexport function parseMdnsMessage(bytes: Uint8Array): MdnsRecord[] {\n try {\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const questions = view.getUint16(4);\n const records = view.getUint16(6) + view.getUint16(8) + view.getUint16(10);\n let offset = 12;\n for (let index = 0; index < questions; index++) {\n offset = readName(bytes, offset).next + 4;\n }\n const result: MdnsRecord[] = [];\n for (let index = 0; index < records; index++) {\n const { name, next } = readName(bytes, offset);\n const type = view.getUint16(next);\n const length = view.getUint16(next + 8);\n const data = next + 10;\n if (data + length > bytes.length) break;\n if (type === 12) {\n result.push({ type: 'PTR', name, target: readName(bytes, data).name });\n } else if (type === 33) {\n result.push({ type: 'SRV', name, port: view.getUint16(data + 4), target: readName(bytes, data + 6).name });\n } else if (type === 16) {\n result.push({ type: 'TXT', name, entries: readTxt(bytes.subarray(data, data + length)) });\n } else if (type === 1 && length === 4) {\n result.push({ type: 'A', name, address: [...bytes.subarray(data, data + 4)].join('.') });\n }\n offset = data + length;\n }\n return result;\n } catch {\n return [];\n }\n}\n\n/** Instances of a service type found in a set of answers, with their port, TXT entries and IPv4 address. */\nexport function mdnsServices(serviceType: string, answers: ReadonlyArray<{ from?: string; bytes: Uint8Array }>): MdnsService[] {\n const type = normalize(serviceType);\n const services = new Map<string, MdnsService>();\n const addresses = new Map<string, string>();\n const pending: Array<{ records: MdnsRecord[]; from?: string }> = answers.map((answer) => ({ records: parseMdnsMessage(answer.bytes), ...(answer.from ? { from: answer.from } : {}) }));\n\n for (const { records } of pending) {\n for (const record of records) {\n if (record.type === 'A') addresses.set(normalize(record.name), record.address);\n if (record.type === 'PTR' && normalize(record.name) === type && !services.has(normalize(record.target))) {\n services.set(normalize(record.target), { instance: record.target.replace(/\\.$/, ''), txt: {} });\n }\n }\n }\n for (const { records, from } of pending) {\n for (const record of records) {\n const service = services.get(normalize(record.name));\n if (!service) continue;\n if (record.type === 'SRV') {\n service.host = record.target.replace(/\\.$/, '');\n service.port = record.port;\n // The device that answered is the device, when its address record is missing.\n if (!service.address && from) service.address = from;\n }\n if (record.type === 'TXT') service.txt = { ...service.txt, ...record.entries };\n }\n }\n for (const service of services.values()) {\n const address = service.host ? addresses.get(normalize(service.host)) : undefined;\n if (address) service.address = address;\n }\n return [...services.values()];\n}\n\nfunction readName(bytes: Uint8Array, start: number): { name: string; next: number } {\n const labels: string[] = [];\n let offset = start;\n let next = -1;\n for (let jumps = 0; jumps < 32; jumps++) {\n const length = bytes[offset];\n if (length === undefined) throw new Error('Truncated name');\n if (length === 0) {\n return { name: labels.join('.'), next: next >= 0 ? next : offset + 1 };\n }\n if ((length & 0xc0) === 0xc0) {\n if (next < 0) next = offset + 2;\n offset = ((length & 0x3f) << 8) | bytes[offset + 1];\n continue;\n }\n labels.push(new TextDecoder().decode(bytes.subarray(offset + 1, offset + 1 + length)));\n offset += 1 + length;\n }\n throw new Error('Name compression loop');\n}\n\nfunction readTxt(bytes: Uint8Array): Record<string, string> {\n const entries: Record<string, string> = {};\n let offset = 0;\n while (offset < bytes.length) {\n const length = bytes[offset];\n const entry = new TextDecoder().decode(bytes.subarray(offset + 1, offset + 1 + length));\n offset += 1 + length;\n const separator = entry.indexOf('=');\n if (separator > 0) entries[entry.slice(0, separator).toLowerCase()] = entry.slice(separator + 1);\n else if (entry) entries[entry.toLowerCase()] = '';\n }\n return entries;\n}\n\nfunction normalize(name: string): string {\n return name.replace(/\\.$/, '').toLowerCase();\n}\n","import { mdnsServices } from './mdns';\nimport { RemotePlaybackError } from '../domain/remote-playback';\nimport type {\n RemotePlaybackMedia,\n RemotePlaybackSession,\n RemotePlaybackStatus,\n RemotePlayerState,\n} from '../domain/remote-playback';\n\n/**\n * Chromecast and Cast-enabled speakers and TVs, spoken without Google's SDK: CASTV2 messages (protobuf `CastMessage`\n * frames carrying JSON) over a TLS connection to port 8009. Media plays in the Default Media Receiver, the player\n * every Cast device ships. The apps' native shells open the TLS connection and find devices with mDNS\n * (`CAST_MDNS_SERVICE`); everything else happens here.\n */\nexport const CAST_MDNS_SERVICE = '_googlecast._tcp';\nexport const CAST_PORT = 8009;\nexport const CAST_DEFAULT_MEDIA_RECEIVER = 'CC1AD845';\n\nconst NS_CONNECTION = 'urn:x-cast:com.google.cast.tp.connection';\nconst NS_HEARTBEAT = 'urn:x-cast:com.google.cast.tp.heartbeat';\nconst NS_RECEIVER = 'urn:x-cast:com.google.cast.receiver';\nconst NS_MEDIA = 'urn:x-cast:com.google.cast.media';\nconst RECEIVER_ID = 'receiver-0';\nconst FAILURES = new Set(['LOAD_FAILED', 'LOAD_CANCELLED', 'INVALID_REQUEST', 'INVALID_PLAYER_STATE', 'LAUNCH_ERROR']);\n\n/** Formats no Cast receiver reads (measured on a TV with Cast built in): sending them only ends in LOAD_FAILED. */\nconst CAST_UNSUPPORTED_TYPES: ReadonlyMap<string, string> = new Map([\n ['video/x-msvideo', 'AVI'],\n ['video/avi', 'AVI'],\n ['video/x-ms-wmv', 'WMV'],\n ['video/x-ms-asf', 'ASF'],\n ['audio/x-ms-wma', 'WMA'],\n ['video/x-flv', 'FLV'],\n]);\n\n/** Containers that Cast receivers read under the MP4 type, and may refuse under their own. */\nconst CAST_TYPE_ALIASES: ReadonlyMap<string, string> = new Map([\n ['video/x-matroska', 'video/mp4'],\n ['video/quicktime', 'video/mp4'],\n]);\n\n/** The type to send a media to a Cast receiver with, or the format it cannot read. */\nexport function castContentType(contentType: string): { contentType: string } | { unsupported: string } {\n const type = contentType.split(';')[0].trim().toLowerCase();\n const unsupported = CAST_UNSUPPORTED_TYPES.get(type);\n if (unsupported) return { unsupported };\n return { contentType: CAST_TYPE_ALIASES.get(type) ?? contentType };\n}\n\n/** A Cast device found on the network. */\nexport interface CastDeviceInfo {\n id: string;\n name: string;\n model?: string;\n address: string;\n port: number;\n /** Speakers and speaker groups have no screen. */\n video: boolean;\n}\n\n/** Cast devices in the answers to an mDNS question for `CAST_MDNS_SERVICE`, one per device id. */\nexport function castDevicesFromMdns(answers: ReadonlyArray<{ from?: string; bytes: Uint8Array }>): CastDeviceInfo[] {\n const devices = new Map<string, CastDeviceInfo>();\n for (const service of mdnsServices(`${CAST_MDNS_SERVICE}.local`, answers)) {\n if (!service.address) continue;\n const id = service.txt['id'] || service.instance;\n const capabilities = Number(service.txt['ca']);\n devices.set(id, {\n id,\n name: service.txt['fn'] || service.instance.split('._')[0],\n ...(service.txt['md'] ? { model: service.txt['md'] } : {}),\n address: service.address,\n port: service.port ?? CAST_PORT,\n // Capability bit 0 is video output; unknown capabilities are treated as a screen.\n video: Number.isFinite(capabilities) ? (capabilities & 1) === 1 : true,\n });\n }\n return [...devices.values()];\n}\n\n/** A TLS connection to a Cast device, opened by the native shell. */\nexport interface CastSocket {\n send(frame: Uint8Array): void | Promise<void>;\n onData(listener: (chunk: Uint8Array) => void): () => void;\n onClose(listener: (reason?: string) => void): () => void;\n close(): void;\n}\n\nexport interface CastMessage {\n sourceId: string;\n destinationId: string;\n namespace: string;\n payload: string;\n}\n\nexport interface CastSessionOptions {\n appId?: string;\n senderId?: string;\n requestTimeoutMs?: number;\n /** How long a LOAD may take: a receiver that has just started loads its player first (over 10 s on a TV). */\n loadTimeoutMs?: number;\n /** Interval of the keep-alive PING; 0 disables it (tests). */\n heartbeatMs?: number;\n}\n\ntype Payload = Record<string, unknown> & { type?: string; requestId?: number };\n\ninterface MediaStatus {\n mediaSessionId?: number;\n playerState?: string;\n idleReason?: string;\n currentTime?: number;\n media?: { duration?: number };\n}\n\n/** One length-prefixed protobuf `CastMessage` with a UTF-8 payload. */\nexport function encodeCastMessage(message: CastMessage): Uint8Array {\n const body: number[] = [];\n const text = new TextEncoder();\n const varint = (value: number) => {\n let rest = value >>> 0;\n while (rest > 0x7f) {\n body.push((rest & 0x7f) | 0x80);\n rest >>>= 7;\n }\n body.push(rest);\n };\n const string = (field: number, value: string) => {\n const bytes = text.encode(value);\n varint((field << 3) | 2);\n varint(bytes.length);\n body.push(...bytes);\n };\n varint(1 << 3); // protocol_version: CASTV2_1_0\n varint(0);\n string(2, message.sourceId);\n string(3, message.destinationId);\n string(4, message.namespace);\n varint(5 << 3); // payload_type: STRING\n varint(0);\n string(6, message.payload);\n\n const frame = new Uint8Array(4 + body.length);\n new DataView(frame.buffer).setUint32(0, body.length);\n frame.set(body, 4);\n return frame;\n}\n\n/** Splits received bytes into messages; returns the messages and the bytes of an incomplete frame. */\nexport function decodeCastFrames(buffer: Uint8Array): { messages: CastMessage[]; rest: Uint8Array } {\n const messages: CastMessage[] = [];\n let offset = 0;\n while (buffer.length - offset >= 4) {\n const length = new DataView(buffer.buffer, buffer.byteOffset + offset, 4).getUint32(0);\n if (buffer.length - offset - 4 < length) break;\n const message = decodeCastMessage(buffer.subarray(offset + 4, offset + 4 + length));\n if (message) messages.push(message);\n offset += 4 + length;\n }\n return { messages, rest: buffer.slice(offset) };\n}\n\nfunction decodeCastMessage(bytes: Uint8Array): CastMessage | null {\n const text = new TextDecoder();\n const message: Partial<CastMessage> = {};\n let offset = 0;\n const varint = () => {\n let value = 0;\n let shift = 0;\n while (offset < bytes.length) {\n const byte = bytes[offset++];\n value += (byte & 0x7f) * 2 ** shift;\n if (byte < 0x80) return value;\n shift += 7;\n }\n throw new Error('Truncated varint');\n };\n try {\n while (offset < bytes.length) {\n const key = varint();\n const field = Math.floor(key / 8);\n const wireType = key & 7;\n if (wireType === 0) {\n varint();\n } else if (wireType === 2) {\n const length = varint();\n const value = bytes.subarray(offset, offset + length);\n offset += length;\n if (field === 2) message.sourceId = text.decode(value);\n else if (field === 3) message.destinationId = text.decode(value);\n else if (field === 4) message.namespace = text.decode(value);\n else if (field === 6) message.payload = text.decode(value);\n } else if (wireType === 5) {\n offset += 4;\n } else if (wireType === 1) {\n offset += 8;\n } else {\n return null;\n }\n }\n } catch {\n return null;\n }\n return message.namespace && message.payload !== undefined\n ? { sourceId: message.sourceId ?? '', destinationId: message.destinationId ?? '', namespace: message.namespace, payload: message.payload }\n : null;\n}\n\n/** Connects to the device; media is sent with `load`, which starts the Default Media Receiver when needed. */\nexport function createCastSession(socket: CastSocket, options: CastSessionOptions = {}): RemotePlaybackSession {\n const appId = options.appId ?? CAST_DEFAULT_MEDIA_RECEIVER;\n const senderId = options.senderId ?? `sender-${Math.random().toString(36).slice(2, 10)}`;\n const requestTimeoutMs = options.requestTimeoutMs ?? 10_000;\n const loadTimeoutMs = options.loadTimeoutMs ?? Math.max(requestTimeoutMs, 30_000);\n const pending = new Map<number, { resolve: (payload: Payload) => void; reject: (error: Error) => void; timer: ReturnType<typeof setTimeout> }>();\n let buffer: Uint8Array = new Uint8Array(0);\n let nextRequestId = 1;\n let closed: string | null = null;\n let transportId: string | null = null;\n let appSessionId: string | null = null;\n let mediaSessionId: number | null = null;\n let lastMedia: MediaStatus | null = null;\n /** What was sent last and where it had got to: a device that closed its player is loaded again from there. */\n let loaded: { media: RemotePlaybackMedia; positionSec: number } | null = null;\n let volume: number | undefined;\n const connected = new Set<string>();\n let heartbeat: ReturnType<typeof setInterval> | undefined;\n\n const send = (destinationId: string, namespace: string, payload: Payload) => {\n if (closed) throw new Error(closed);\n return socket.send(encodeCastMessage({ sourceId: senderId, destinationId, namespace, payload: JSON.stringify(payload) }));\n };\n\n const connect = async (destinationId: string) => {\n if (connected.has(destinationId)) return;\n await send(destinationId, NS_CONNECTION, { type: 'CONNECT', origin: {} });\n connected.add(destinationId);\n };\n\n const request = async (destinationId: string, namespace: string, payload: Payload, timeoutMs = requestTimeoutMs): Promise<Payload> => {\n const requestId = nextRequestId++;\n const answer = new Promise<Payload>((resolve, reject) => {\n const timer = setTimeout(() => {\n pending.delete(requestId);\n reject(new RemotePlaybackError('timeout', 'The Cast device did not answer'));\n }, timeoutMs);\n pending.set(requestId, { resolve, reject, timer });\n });\n try {\n await send(destinationId, namespace, { ...payload, requestId });\n } catch (error) {\n clearTimeout(pending.get(requestId)?.timer);\n pending.delete(requestId);\n throw error;\n }\n return answer;\n };\n\n const shutdown = (reason: string) => {\n if (closed) return;\n closed = reason;\n if (heartbeat) clearInterval(heartbeat);\n for (const [requestId, entry] of pending) {\n clearTimeout(entry.timer);\n entry.reject(new Error(reason));\n pending.delete(requestId);\n }\n };\n\n const remember = (payload: Payload) => {\n if (payload.type === 'RECEIVER_STATUS') {\n const status = payload['status'] as { applications?: Array<{ appId?: string; sessionId?: string; transportId?: string }>; volume?: { level?: number } } | undefined;\n if (typeof status?.volume?.level === 'number') volume = status.volume.level;\n const application = status?.applications?.find((entry) => entry.appId === appId);\n if (!application) {\n transportId = null;\n appSessionId = null;\n mediaSessionId = null;\n } else if (application.transportId) {\n transportId = application.transportId;\n appSessionId = application.sessionId ?? null;\n }\n }\n if (payload.type === 'MEDIA_STATUS') {\n const statuses = (payload['status'] as MediaStatus[] | undefined) ?? [];\n const current = statuses.find((entry) => entry.mediaSessionId === mediaSessionId) ?? statuses[0];\n if (current?.mediaSessionId !== undefined) mediaSessionId = current.mediaSessionId;\n lastMedia = current ?? (lastMedia ? { ...lastMedia, playerState: 'IDLE', idleReason: lastMedia.idleReason ?? 'FINISHED' } : null);\n if (loaded && typeof current?.currentTime === 'number') loaded = { ...loaded, positionSec: current.currentTime };\n }\n };\n\n const unsubscribeData = socket.onData((chunk) => {\n const joined = new Uint8Array(buffer.length + chunk.length);\n joined.set(buffer);\n joined.set(chunk, buffer.length);\n const { messages, rest } = decodeCastFrames(joined);\n buffer = rest;\n for (const message of messages) {\n let payload: Payload;\n try {\n payload = JSON.parse(message.payload) as Payload;\n } catch {\n continue;\n }\n if (message.namespace === NS_HEARTBEAT && payload.type === 'PING') {\n void Promise.resolve(send(message.sourceId, NS_HEARTBEAT, { type: 'PONG' })).catch(() => undefined);\n continue;\n }\n if (message.namespace === NS_CONNECTION && payload.type === 'CLOSE') {\n connected.delete(message.sourceId);\n if (message.sourceId === transportId) {\n transportId = null;\n mediaSessionId = null;\n }\n continue;\n }\n remember(payload);\n const entry = payload.requestId ? pending.get(payload.requestId) : undefined;\n if (!entry) continue;\n pending.delete(payload.requestId as number);\n clearTimeout(entry.timer);\n if (payload.type && FAILURES.has(payload.type)) {\n entry.reject(payload.type === 'LOAD_FAILED'\n ? new RemotePlaybackError('load-failed', 'The Cast device could not play this media')\n : new Error(`The Cast device refused the request (${payload.type})`));\n } else {\n entry.resolve(payload);\n }\n }\n });\n const unsubscribeClose = socket.onClose((reason) => shutdown(reason ?? 'The Cast device closed the connection'));\n\n const heartbeatMs = options.heartbeatMs ?? 5000;\n if (heartbeatMs > 0) {\n // Devices drop senders that stay silent.\n heartbeat = setInterval(() => {\n if (!closed) void Promise.resolve(send(RECEIVER_ID, NS_HEARTBEAT, { type: 'PING' })).catch(() => undefined);\n }, heartbeatMs);\n }\n\n const ready = connect(RECEIVER_ID);\n\n const launch = async (): Promise<string> => {\n await ready;\n if (!transportId) remember(await request(RECEIVER_ID, NS_RECEIVER, { type: 'GET_STATUS' }));\n for (let attempt = 0; !transportId && attempt < 5; attempt++) {\n remember(attempt === 0\n ? await request(RECEIVER_ID, NS_RECEIVER, { type: 'LAUNCH', appId })\n : await request(RECEIVER_ID, NS_RECEIVER, { type: 'GET_STATUS' }));\n if (!transportId) await new Promise((resolve) => setTimeout(resolve, 500));\n }\n if (!transportId) throw new Error('The Cast device did not start its media player');\n await connect(transportId);\n return transportId;\n };\n\n /**\n * Sends media to the device, starting its player when needed. Pulled out of `load` because a device that closed\n * its player on its own has to be loaded again, from where it had got to, before it will do anything.\n */\n const sendMedia = async (media: RemotePlaybackMedia, positionSec: number) => {\n const type = castContentType(media.contentType);\n if ('unsupported' in type) {\n throw new RemotePlaybackError('unsupported-format', `Cast devices do not read ${type.unsupported} files`, type.unsupported);\n }\n const destination = await launch();\n const answer = await request(destination, NS_MEDIA, {\n type: 'LOAD',\n ...(appSessionId ? { sessionId: appSessionId } : {}),\n autoplay: true,\n currentTime: media.live ? 0 : Math.max(0, positionSec),\n media: {\n contentId: media.url,\n contentUrl: media.url,\n contentType: type.contentType,\n streamType: media.live ? 'LIVE' : 'BUFFERED',\n ...(media.durationSec && !media.live ? { duration: media.durationSec } : {}),\n metadata: {\n // 3: MusicTrackMediaMetadata, 0: GenericMediaMetadata.\n metadataType: media.kind === 'audio' ? 3 : 0,\n title: media.title,\n ...(media.artist ? { artist: media.artist, subtitle: media.artist } : {}),\n ...(media.album ? { albumName: media.album } : {}),\n ...(media.artworkUrl ? { images: [{ url: media.artworkUrl }] } : {}),\n },\n },\n }, loadTimeoutMs);\n loaded = { media, positionSec: media.live ? 0 : Math.max(0, positionSec) };\n remember(answer);\n };\n const mediaCommand = async (type: string, extra: Payload = {}) => {\n // A Cast device closes its player after a while paused, taking the session with it. What was playing is loaded\n // again from where it stopped, so the viewer presses play and it carries on rather than being told nothing plays.\n if ((!transportId || mediaSessionId === null) && loaded && type !== 'STOP') {\n await sendMedia(loaded.media, loaded.positionSec);\n if (type === 'PLAY') return;\n }\n if (!transportId || mediaSessionId === null) throw new Error('Nothing is playing on the Cast device');\n remember(await request(transportId, NS_MEDIA, { type, mediaSessionId, ...extra }));\n };\n\n return {\n kind: 'chromecast',\n load: (media: RemotePlaybackMedia) => sendMedia(media, media.live ? 0 : media.startSec ?? 0),\n play: () => mediaCommand('PLAY'),\n pause: () => mediaCommand('PAUSE'),\n seek: (positionSec) => mediaCommand('SEEK', { currentTime: Math.max(0, positionSec) }),\n async setVolume(level) {\n await ready;\n remember(await request(RECEIVER_ID, NS_RECEIVER, { type: 'SET_VOLUME', volume: { level: Math.min(Math.max(level, 0), 1) } }));\n },\n async stop() {\n if (transportId && mediaSessionId !== null) await mediaCommand('STOP').catch(() => undefined);\n if (appSessionId) remember(await request(RECEIVER_ID, NS_RECEIVER, { type: 'STOP', sessionId: appSessionId }).catch(() => ({})));\n mediaSessionId = null;\n lastMedia = null;\n loaded = null;\n },\n async status(): Promise<RemotePlaybackStatus> {\n if (transportId && mediaSessionId !== null) {\n remember(await request(transportId, NS_MEDIA, { type: 'GET_STATUS', mediaSessionId }));\n } else {\n // Nothing sent yet: the device still tells its volume and whether its media player is open.\n await ready;\n remember(await request(RECEIVER_ID, NS_RECEIVER, { type: 'GET_STATUS' }));\n }\n return castStatus(lastMedia, volume);\n },\n async close() {\n for (const destination of [...connected].reverse()) {\n await Promise.resolve(send(destination, NS_CONNECTION, { type: 'CLOSE' })).catch(() => undefined);\n }\n shutdown('The Cast session is closed');\n unsubscribeData();\n unsubscribeClose();\n socket.close();\n },\n };\n}\n\nfunction castStatus(media: MediaStatus | null, volume: number | undefined): RemotePlaybackStatus {\n const base = volume !== undefined ? { volume } : {};\n if (!media) return { state: 'idle', ...base };\n const states: Record<string, RemotePlayerState> = { PLAYING: 'playing', PAUSED: 'paused', BUFFERING: 'buffering', LOADING: 'loading' };\n const state = states[media.playerState ?? ''] ?? (media.idleReason ? 'stopped' : 'idle');\n return {\n state,\n ...base,\n ...(typeof media.currentTime === 'number' ? { positionSec: media.currentTime } : {}),\n ...(media.media?.duration ? { durationSec: media.media.duration } : {}),\n ...(media.idleReason === 'ERROR' ? { error: 'The Cast device could not play this media' } : {}),\n ...(media.idleReason === 'FINISHED' ? { ended: true } : {}),\n };\n}\n","import type { MediaSourceHttp } from '../domain/media-source';\nimport { mdnsServices, type MdnsRecord } from './mdns';\n\n/**\n * Playback transfer between NGXSP apps of a local network: an app hands what it plays (the queue, the item, the\n * position) to another app of the same kind, which carries on from there.\n *\n * - Apps advertise themselves over mDNS as `_ngxsp._tcp` services; TXT entries say which app they are.\n * - The sender POSTs a `PlaybackTransfer` to `/ngxsp/transfer` on the receiver. Its media addresses are ones the\n * receiver can fetch: web addresses as they are, the sender's own media shared on the network.\n * - The first transfer from an app asks on the receiving device (refuse or allow). Allowed, the sender gets a token\n * it presents from then on, and later transfers go through without asking (\"accept once\").\n */\nexport const NGXSP_SERVICE_TYPE = '_ngxsp._tcp.local';\nexport const PLAYBACK_TRANSFER_PATH = '/ngxsp/transfer';\nexport const PLAYBACK_TRANSFER_VERSION = 1;\n/** How long the receiving device waits for its user to answer. */\nexport const PLAYBACK_TRANSFER_PROMPT_MS = 60_000;\n\nexport type NgxspAppKind = 'audio' | 'video';\n\n/** An NGXSP app as the others know it. */\nexport interface NgxspAppIdentity {\n /** Random, kept by the app for good. */\n id: string;\n /** The device's name, as its user knows it. */\n name: string;\n app: NgxspAppKind;\n}\n\n/** Another NGXSP app of the network. */\nexport interface NgxspPeer extends NgxspAppIdentity {\n address: string;\n port: number;\n}\n\nexport interface PlaybackTransferItem {\n url: string;\n title: string;\n artist?: string;\n album?: string;\n artworkUrl?: string;\n durationSec?: number;\n /** Radios and live streams. */\n live?: boolean;\n}\n\nexport interface PlaybackTransfer {\n version: number;\n from: NgxspAppIdentity;\n items: PlaybackTransferItem[];\n /** The item playing, in `items`. */\n index: number;\n positionSec: number;\n playing: boolean;\n}\n\nexport interface TrustedSender {\n id: string;\n name: string;\n /** SHA-256 of the token the sender presents, in hex. */\n tokenHash: string;\n since: number;\n}\n\nexport type PlaybackTransferOutcome =\n | { accepted: true; token?: string }\n | { accepted: false; reason: 'refused' | 'busy' | 'timeout' | 'disabled' | 'other-app' | 'invalid' | 'unreachable' };\n\nconst MAX_ITEMS = 200;\nconst MAX_TEXT = 300;\n\n/** The TXT entries an app advertises. */\nexport function ngxspTxt(identity: NgxspAppIdentity): Record<string, string> {\n return { v: String(PLAYBACK_TRANSFER_VERSION), id: identity.id, app: identity.app, name: identity.name.slice(0, 120) };\n}\n\n/** The records an app answers `_ngxsp._tcp` questions with, for each of its addresses. */\nexport function ngxspServiceRecords(identity: NgxspAppIdentity, port: number, addresses: readonly string[]): MdnsRecord[] {\n // A DNS label cannot hold dots and stops at 63 bytes.\n const label = `${identity.name.replace(/[.\\s]+/g, ' ').trim().slice(0, 40) || 'NGXSP'} (NGXSP ${identity.app === 'audio' ? 'Audio' : 'Video'})`;\n const instance = `${label}.${NGXSP_SERVICE_TYPE}`;\n const host = `ngxsp-${identity.id.replace(/[^a-z0-9]/gi, '').slice(0, 12).toLowerCase() || 'app'}.local`;\n return [\n { type: 'PTR', name: NGXSP_SERVICE_TYPE, target: instance },\n { type: 'SRV', name: instance, target: host, port },\n { type: 'TXT', name: instance, entries: ngxspTxt(identity) },\n ...addresses.map((address): MdnsRecord => ({ type: 'A', name: host, address })),\n ];\n}\n\n/** NGXSP apps of kind `app` found in mDNS answers, this one aside. */\nexport function ngxspPeersFromMdns(answers: ReadonlyArray<{ from?: string; bytes: Uint8Array }>, self: Pick<NgxspAppIdentity, 'id' | 'app'>): NgxspPeer[] {\n const peers = new Map<string, NgxspPeer>();\n for (const service of mdnsServices(NGXSP_SERVICE_TYPE, answers)) {\n const { id, app, name } = service.txt;\n if (!id || id === self.id || app !== self.app || !service.address || !service.port) continue;\n peers.set(id, { id, app, name: name || service.instance.split('.')[0], address: service.address, port: service.port });\n }\n return [...peers.values()];\n}\n\n/** A transfer as received, checked and trimmed; null when it is not one. */\nexport function readPlaybackTransfer(value: unknown): PlaybackTransfer | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n const from = input['from'] as Record<string, unknown> | undefined;\n const app = from?.['app'];\n if (input['version'] !== PLAYBACK_TRANSFER_VERSION || !from || typeof from['id'] !== 'string' || !from['id'] || (app !== 'audio' && app !== 'video')) return null;\n const items = Array.isArray(input['items']) ? input['items'].slice(0, MAX_ITEMS).flatMap((item) => {\n const entry = readItem(item);\n return entry ? [entry] : [];\n }) : [];\n if (!items.length) return null;\n const index = Number(input['index']);\n const positionSec = Number(input['positionSec']);\n return {\n version: PLAYBACK_TRANSFER_VERSION,\n from: { id: text(from['id']).slice(0, 64), name: text(from['name']) || text(from['id']).slice(0, 8), app },\n items,\n index: Number.isInteger(index) && index >= 0 && index < items.length ? index : 0,\n positionSec: Number.isFinite(positionSec) && positionSec > 0 ? positionSec : 0,\n playing: input['playing'] !== false,\n };\n}\n\nfunction readItem(value: unknown): PlaybackTransferItem | null {\n if (!value || typeof value !== 'object') return null;\n const input = value as Record<string, unknown>;\n const url = text(input['url'], 4000);\n // Media go from one device to another over the network: nothing else is fetched.\n if (!/^https?:\\/\\//i.test(url)) return null;\n const artworkUrl = text(input['artworkUrl'], 4000);\n const durationSec = Number(input['durationSec']);\n return {\n url,\n title: text(input['title']) || url.split(/[?#]/)[0].split('/').pop() || url,\n ...(text(input['artist']) ? { artist: text(input['artist']) } : {}),\n ...(text(input['album']) ? { album: text(input['album']) } : {}),\n ...(/^https?:\\/\\//i.test(artworkUrl) ? { artworkUrl } : {}),\n ...(Number.isFinite(durationSec) && durationSec > 0 ? { durationSec } : {}),\n ...(input['live'] === true ? { live: true } : {}),\n };\n}\n\nfunction text(value: unknown, max = MAX_TEXT): string {\n return typeof value === 'string' ? value.replace(/[\\u0000-\\u001f]/g, ' ').trim().slice(0, max) : '';\n}\n\nexport interface PlaybackTransferReceiverOptions {\n app: NgxspAppKind;\n /** Off, the app refuses every transfer without asking. */\n enabled: () => boolean;\n trusted: () => readonly TrustedSender[];\n saveTrusted: (senders: TrustedSender[]) => void;\n /** Asks the user whether `from` may send its playback here: true to allow. */\n ask: (from: NgxspAppIdentity) => Promise<boolean>;\n /** Plays what was transferred. */\n apply: (transfer: PlaybackTransfer) => void;\n sha256Hex: (value: string) => Promise<string>;\n randomToken: () => string;\n promptMs?: number;\n}\n\n/** A transfer request as the app's HTTP endpoint hands it over, and what it answers. */\nexport interface PlaybackTransferRequest {\n method: string;\n body: string;\n /** The `Authorization` header: `NGXSP <token>` from a sender allowed before. */\n authorization?: string;\n}\n\nexport interface PlaybackTransferResponse {\n status: number;\n body: Record<string, unknown>;\n}\n\n/** Decides on the transfers an app receives, asking its user the first time an app sends one. */\nexport function createPlaybackTransferReceiver(options: PlaybackTransferReceiverOptions) {\n let asking = false;\n\n async function isTrusted(from: NgxspAppIdentity, authorization: string | undefined): Promise<boolean> {\n const token = /^NGXSP\\s+(\\S{16,200})$/.exec(authorization?.trim() ?? '')?.[1];\n const sender = options.trusted().find((entry) => entry.id === from.id);\n return !!token && !!sender && (await options.sha256Hex(token)) === sender.tokenHash;\n }\n\n async function handle(request: PlaybackTransferRequest): Promise<PlaybackTransferResponse> {\n if (request.method.toUpperCase() !== 'POST') return { status: 405, body: { accepted: false, reason: 'invalid' } };\n if (!options.enabled()) return { status: 403, body: { accepted: false, reason: 'disabled' } };\n let transfer: PlaybackTransfer | null = null;\n try {\n transfer = readPlaybackTransfer(JSON.parse(request.body));\n } catch {\n transfer = null;\n }\n if (!transfer) return { status: 400, body: { accepted: false, reason: 'invalid' } };\n if (transfer.from.app !== options.app) return { status: 422, body: { accepted: false, reason: 'other-app' } };\n\n if (await isTrusted(transfer.from, request.authorization)) {\n // The name may have changed since.\n const from = transfer.from;\n options.saveTrusted(options.trusted().map((entry) => (entry.id === from.id ? { ...entry, name: from.name } : entry)));\n options.apply(transfer);\n return { status: 200, body: { accepted: true } };\n }\n if (asking) return { status: 409, body: { accepted: false, reason: 'busy' } };\n\n asking = true;\n let allowed: boolean | 'timeout';\n try {\n allowed = await Promise.race([\n options.ask(transfer.from),\n new Promise<'timeout'>((resolve) => setTimeout(() => resolve('timeout'), options.promptMs ?? PLAYBACK_TRANSFER_PROMPT_MS)),\n ]);\n } finally {\n asking = false;\n }\n if (allowed === 'timeout') return { status: 408, body: { accepted: false, reason: 'timeout' } };\n if (!allowed) return { status: 403, body: { accepted: false, reason: 'refused' } };\n\n const token = options.randomToken();\n const sender: TrustedSender = { id: transfer.from.id, name: transfer.from.name, tokenHash: await options.sha256Hex(token), since: Date.now() };\n options.saveTrusted([...options.trusted().filter((entry) => entry.id !== sender.id), sender]);\n options.apply(transfer);\n return { status: 200, body: { accepted: true, token } };\n }\n\n return { handle };\n}\n\n/** Sends a transfer to a peer, with the token it gave the last time if there is one. */\nexport async function sendPlaybackTransfer(http: MediaSourceHttp, peer: Pick<NgxspPeer, 'address' | 'port'>, transfer: PlaybackTransfer, token?: string): Promise<PlaybackTransferOutcome> {\n let response;\n try {\n response = await http.send({\n url: `http://${peer.address}:${peer.port}${PLAYBACK_TRANSFER_PATH}`,\n method: 'POST',\n headers: { 'Content-Type': 'application/json', ...(token ? { Authorization: `NGXSP ${token}` } : {}) },\n body: JSON.stringify(transfer),\n // The other device may be waiting for its user.\n timeoutMs: PLAYBACK_TRANSFER_PROMPT_MS + 15_000,\n });\n } catch {\n return { accepted: false, reason: 'unreachable' };\n }\n let body: Record<string, unknown> = {};\n try {\n body = JSON.parse(await response.text()) as Record<string, unknown>;\n } catch {\n body = {};\n }\n if (response.status === 200 && body['accepted'] === true) {\n return { accepted: true, ...(typeof body['token'] === 'string' ? { token: body['token'] } : {}) };\n }\n const reasons = ['refused', 'busy', 'timeout', 'disabled', 'other-app', 'invalid'] as const;\n const reason = reasons.find((entry) => entry === body['reason']);\n return { accepted: false, reason: reason ?? 'unreachable' };\n}\n","/**\n * MD5 of a UTF-8 string, as lowercase hex (RFC 1321). Only for protocols that require it, such as Subsonic request\n * signing; never as a security primitive of its own. WebCrypto does not offer MD5, hence this implementation.\n */\nexport function md5Hex(input: string): string {\n const bytes = new TextEncoder().encode(input);\n const bitLength = bytes.length * 8;\n const paddedLength = (((bytes.length + 8) >>> 6) + 1) * 64;\n const buffer = new Uint8Array(paddedLength);\n buffer.set(bytes);\n buffer[bytes.length] = 0x80;\n const view = new DataView(buffer.buffer);\n view.setUint32(paddedLength - 8, bitLength >>> 0, true);\n view.setUint32(paddedLength - 4, Math.floor(bitLength / 0x1_0000_0000), true);\n\n let a0 = 0x67452301;\n let b0 = 0xefcdab89;\n let c0 = 0x98badcfe;\n let d0 = 0x10325476;\n\n for (let offset = 0; offset < paddedLength; offset += 64) {\n let a = a0;\n let b = b0;\n let c = c0;\n let d = d0;\n for (let index = 0; index < 64; index += 1) {\n let f: number;\n let g: number;\n if (index < 16) {\n f = (b & c) | (~b & d);\n g = index;\n } else if (index < 32) {\n f = (d & b) | (~d & c);\n g = (5 * index + 1) % 16;\n } else if (index < 48) {\n f = b ^ c ^ d;\n g = (3 * index + 5) % 16;\n } else {\n f = c ^ (b | ~d);\n g = (7 * index) % 16;\n }\n const rotated = (a + f + K[index] + view.getUint32(offset + g * 4, true)) | 0;\n a = d;\n d = c;\n c = b;\n b = (b + ((rotated << S[index]) | (rotated >>> (32 - S[index])))) | 0;\n }\n a0 = (a0 + a) | 0;\n b0 = (b0 + b) | 0;\n c0 = (c0 + c) | 0;\n d0 = (d0 + d) | 0;\n }\n\n const digest = new Uint8Array(16);\n const out = new DataView(digest.buffer);\n [a0, b0, c0, d0].forEach((word, index) => out.setUint32(index * 4, word >>> 0, true));\n return [...digest].map((byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\nconst S = [\n 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,\n 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,\n 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,\n 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21,\n];\n\nconst K = Array.from({ length: 64 }, (_, index) => Math.floor(Math.abs(Math.sin(index + 1)) * 0x1_0000_0000) | 0);\n","import {\n mediaSourceItemId,\n normalizeMediaSourceAddress,\n type MediaSourceAccount,\n type MediaSourceBrowseOptions,\n type MediaSourceConnector,\n type MediaSourceContainer,\n type MediaSourceHttp,\n type MediaSourceInput,\n type MediaSourceItem,\n type MediaSourcePage,\n} from '../domain/media-source';\nimport { md5Hex } from './md5';\n\n/**\n * Subsonic API, spoken by Navidrome, Airsonic-Advanced, Gonic and others (all open source): a music server with\n * albums, artists and covers. Every request is signed with md5(password + salt), so the account keeps that signature\n * and its salt instead of the password.\n */\nexport const SUBSONIC_API_VERSION = '1.16.1';\nexport const SUBSONIC_CLIENT = 'NGXSP';\n\nconst ALBUM_PREFIX = 'album:';\nconst PAGE_SIZE = 500;\n\nexport function createSubsonicConnector(salt: () => string = randomSalt): MediaSourceConnector {\n return {\n kind: 'subsonic',\n connect: (input, http) => connectSubsonic(input, http, salt),\n browse: (account, options, http) => browseSubsonic(account, options, http),\n };\n}\n\n/** Checks the credentials with `ping` and keeps the request signature, never the password. */\nexport async function connectSubsonic(input: MediaSourceInput, http: MediaSourceHttp, salt: () => string = randomSalt): Promise<MediaSourceAccount> {\n const baseUrl = normalizeMediaSourceAddress(input.address);\n const username = input.username?.trim() ?? '';\n if (!username) throw new Error('A Subsonic server needs a user name');\n const signatureSalt = salt();\n const account: MediaSourceAccount = {\n id: `subsonic-${md5Hex(`${baseUrl}|${username}`).slice(0, 8)}`,\n kind: 'subsonic',\n name: input.name?.trim() || new URL(baseUrl).host,\n baseUrl,\n username,\n secret: `${signatureSalt}:${md5Hex(`${input.password ?? ''}${signatureSalt}`)}`,\n };\n const response = await call(http, account, 'ping', {});\n const serverType = text(response['type']);\n return serverType && !input.name?.trim() ? { ...account, name: `${capitalize(serverType)} - ${new URL(baseUrl).host}` } : account;\n}\n\n/** Albums at the root (with their covers), then the tracks of an album; searches look up tracks directly. */\nexport async function browseSubsonic(account: MediaSourceAccount, options: MediaSourceBrowseOptions, http: MediaSourceHttp): Promise<MediaSourcePage> {\n // Subsonic servers hold music; video apps get nothing from them.\n if (options.kind === 'video') return { containers: [], items: [] };\n\n if (options.search) {\n const response = await call(http, account, 'search3', { query: options.search, songCount: '100', albumCount: '0', artistCount: '0' }, options.signal);\n const songs = asArray((response['searchResult3'] as Record<string, unknown> | undefined)?.['song']);\n return { containers: [], items: songs.flatMap((song) => itemOrEmpty(account, song)) };\n }\n\n if (options.containerId?.startsWith(ALBUM_PREFIX)) {\n const response = await call(http, account, 'getAlbum', { id: options.containerId.slice(ALBUM_PREFIX.length) }, options.signal);\n const songs = asArray((response['album'] as Record<string, unknown> | undefined)?.['song']);\n return { containers: [], items: songs.flatMap((song) => itemOrEmpty(account, song)), total: songs.length };\n }\n\n const response = await call(http, account, 'getAlbumList2', {\n type: 'alphabeticalByArtist',\n size: String(Math.min(PAGE_SIZE, Math.max(1, options.limit ?? PAGE_SIZE))),\n offset: String(Math.max(0, options.startIndex ?? 0)),\n }, options.signal);\n const albums = asArray((response['albumList2'] as Record<string, unknown> | undefined)?.['album']);\n return {\n containers: albums.flatMap((album): MediaSourceContainer[] => {\n const record = (album ?? {}) as Record<string, unknown>;\n const id = text(record['id']);\n const title = text(record['name']) ?? text(record['album']);\n if (!id || !title) return [];\n const coverArt = text(record['coverArt']);\n const songCount = positiveInteger(record['songCount']);\n return [{\n id: `${ALBUM_PREFIX}${id}`,\n title,\n kind: 'audio',\n ...(text(record['artist']) ? { subtitle: text(record['artist']) } : {}),\n ...(coverArt ? { artworkUrl: subsonicCoverUrl(account, coverArt) } : {}),\n ...(songCount ? { childCount: songCount } : {}),\n }];\n }),\n items: [],\n };\n}\n\nexport function subsonicStreamUrl(account: MediaSourceAccount, songId: string): string {\n return subsonicUrl(account, 'stream', { id: songId }, false);\n}\n\nexport function subsonicCoverUrl(account: MediaSourceAccount, coverArtId: string, size = 480): string {\n return subsonicUrl(account, 'getCoverArt', { id: coverArtId, size: String(size) }, false);\n}\n\nexport function parseSubsonicSong(account: MediaSourceAccount, entry: unknown): MediaSourceItem | null {\n const record = (entry ?? {}) as Record<string, unknown>;\n const id = text(record['id']);\n const title = text(record['title']);\n if (!id || !title || record['isVideo'] === true) return null;\n const coverArt = text(record['coverArt']);\n const item: MediaSourceItem = {\n id: mediaSourceItemId(account.id, id),\n kind: 'audio',\n title,\n url: subsonicStreamUrl(account, id),\n };\n const artist = text(record['artist']);\n if (artist) item.artist = artist;\n const album = text(record['album']);\n if (album) item.album = album;\n const genre = text(record['genre']);\n if (genre) item.genre = genre;\n const year = positiveInteger(record['year']);\n if (year) item.year = year;\n const trackNo = positiveInteger(record['track']);\n if (trackNo) item.trackNo = trackNo;\n const discNo = positiveInteger(record['discNumber']);\n if (discNo) item.discNo = discNo;\n const duration = positiveInteger(record['duration']);\n if (duration) item.durationSec = duration;\n if (coverArt) item.artworkUrl = subsonicCoverUrl(account, coverArt);\n const suffix = text(record['suffix']);\n if (suffix) item.container = suffix;\n return item;\n}\n\nfunction itemOrEmpty(account: MediaSourceAccount, song: unknown): MediaSourceItem[] {\n const item = parseSubsonicSong(account, song);\n return item ? [item] : [];\n}\n\nfunction subsonicUrl(account: MediaSourceAccount, method: string, parameters: Record<string, string>, json: boolean): string {\n const [salt = '', token = ''] = (account.secret ?? '').split(':');\n const query = new URLSearchParams({\n ...parameters,\n u: account.username ?? '',\n t: token,\n s: salt,\n v: SUBSONIC_API_VERSION,\n c: SUBSONIC_CLIENT,\n ...(json ? { f: 'json' } : {}),\n });\n return `${account.baseUrl}/rest/${method}.view?${query}`;\n}\n\n/** Calls a Subsonic method and returns its payload, or throws the server's own error. */\nasync function call(\n http: MediaSourceHttp,\n account: MediaSourceAccount,\n method: string,\n parameters: Record<string, string>,\n signal?: AbortSignal,\n): Promise<Record<string, unknown>> {\n const response = await http.send({ url: subsonicUrl(account, method, parameters, true), ...(signal ? { signal } : {}) });\n if (response.status === 404) throw new Error('No Subsonic API at this address');\n if (response.status >= 400) throw new Error(`Subsonic request failed (HTTP ${response.status})`);\n const body = (await response.json()) as Record<string, unknown> | null;\n const payload = body?.['subsonic-response'] as Record<string, unknown> | undefined;\n if (!payload) throw new Error('No Subsonic API at this address');\n if (payload['status'] !== 'ok') {\n const error = (payload['error'] ?? {}) as Record<string, unknown>;\n const code = Number(error['code']);\n // 40: wrong credentials, 41: token authentication not supported by this server.\n if (code === 40) throw new Error('The server refused this user name or password');\n if (code === 41) throw new Error('This server does not accept signed requests');\n throw new Error(text(error['message']) ?? 'Subsonic request failed');\n }\n return payload;\n}\n\nfunction randomSalt(): string {\n const bytes = new Uint8Array(8);\n globalThis.crypto.getRandomValues(bytes);\n return [...bytes].map((byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\nfunction asArray(value: unknown): unknown[] {\n if (Array.isArray(value)) return value;\n return value === undefined || value === null ? [] : [value];\n}\n\nfunction text(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction positiveInteger(value: unknown): number | undefined {\n const number = Number(value);\n return Number.isInteger(number) && number > 0 ? number : undefined;\n}\n\nfunction capitalize(value: string): string {\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n","import {\n mediaSourceItemId,\n normalizeMediaSourceAddress,\n type MediaSourceAccount,\n type MediaSourceBrowseOptions,\n type MediaSourceConnector,\n type MediaSourceContainer,\n type MediaSourceHttp,\n type MediaSourceInput,\n type MediaSourceItem,\n type MediaSourcePage,\n} from '../domain/media-source';\nimport { audioFieldsFromTags, isIgnoredDirectoryName, isMediaFileName, videoFieldsFromTags } from '../domain/media-library-model';\nimport { decodeXmlEntities, xmlTagContent, xmlTagText } from './xml-text';\n\n/**\n * WebDAV shares (Nextcloud, ownCloud, NAS, rclone, Apache): folders are browsed with PROPFIND and files are read as\n * they are stored. Titles, artists, albums and series come from file and folder names, like local folders.\n *\n * WebDAV has no session tokens, so the account keeps HTTP Basic credentials (an app password is recommended). Browsers\n * cannot send them for `<audio>` and `<video>`, and most servers refuse other origins: applications reach these\n * servers through a native transport and play protected files through a local relay.\n */\nconst PROPFIND_BODY = '<?xml version=\"1.0\" encoding=\"utf-8\"?>'\n + '<d:propfind xmlns:d=\"DAV:\"><d:prop><d:displayname/><d:resourcetype/><d:getcontentlength/>'\n + '<d:getcontenttype/><d:getlastmodified/></d:prop></d:propfind>';\n\nexport interface WebDavEntry {\n /** Decoded path of the entry on the server, starting with `/`. */\n path: string;\n name: string;\n collection: boolean;\n size?: number;\n contentType?: string;\n lastModified?: number;\n}\n\nexport function createWebDavConnector(): MediaSourceConnector {\n return {\n kind: 'webdav',\n connect: (input, http) => connectWebDav(input, http),\n browse: (account, options, http) => browseWebDav(account, options, http),\n lyrics: (account, item, http) => readWebDavLyrics(account, item, http),\n };\n}\n\n/** Checks that the address is a WebDAV folder the credentials can read. */\nexport async function connectWebDav(input: MediaSourceInput, http: MediaSourceHttp): Promise<MediaSourceAccount> {\n const baseUrl = normalizeMediaSourceAddress(input.address);\n const username = input.username?.trim();\n const account: MediaSourceAccount = {\n id: `webdav-${shortHash(`${baseUrl}|${username ?? ''}`)}`,\n kind: 'webdav',\n name: input.name?.trim() || decodeURIComponent(new URL(baseUrl).pathname.split('/').filter(Boolean).pop() ?? '') || new URL(baseUrl).host,\n baseUrl,\n ...(username ? { username, secret: basicCredentials(username, input.password ?? '') } : {}),\n };\n const entries = await propfind(http, account, `${baseUrl}/`, '0');\n if (!entries[0]?.collection) throw new Error('This address is a file, not a WebDAV folder');\n return account;\n}\n\n/** Sub-folders of a folder, then the media files it holds for the kind the app plays. */\nexport async function browseWebDav(account: MediaSourceAccount, options: MediaSourceBrowseOptions, http: MediaSourceHttp): Promise<MediaSourcePage> {\n const kind = options.kind ?? 'audio';\n const basePath = new URL(account.baseUrl).pathname.replace(/\\/+$/, '');\n const folderPath = options.containerId ?? basePath;\n if (!isInside(basePath, folderPath)) throw new Error('This folder is outside the WebDAV share');\n\n const folderUrl = `${new URL(account.baseUrl).origin}${encodePath(folderPath)}/`;\n const entries = await propfind(http, account, folderUrl, '1', options.signal);\n const current = trimSlash(folderPath) || '/';\n const children = entries.filter((entry) => (trimSlash(entry.path) || '/') !== current && isInside(basePath, entry.path));\n\n const containers: MediaSourceContainer[] = children\n .filter((entry) => entry.collection && !isIgnoredDirectoryName(entry.name))\n .sort((left, right) => left.name.localeCompare(right.name, undefined, { numeric: true, sensitivity: 'base' }))\n .map((entry) => ({ id: trimSlash(entry.path), title: entry.name, kind: 'mixed' }));\n\n const items = children\n .filter((entry) => !entry.collection && isMediaFileName(entry.name, kind))\n .sort((left, right) => left.name.localeCompare(right.name, undefined, { numeric: true, sensitivity: 'base' }))\n .map((entry) => webDavItem(account, entry, basePath, kind));\n\n return { containers, items, total: items.length };\n}\n\n/** Parses a WebDAV multistatus document; prefixes and namespaces vary between servers, so tags are matched by name. */\nexport function parseWebDavMultistatus(xml: string): WebDavEntry[] {\n const responses = [...xml.matchAll(/<(?:[\\w.-]+:)?response\\b[^>]*>([\\s\\S]*?)<\\/(?:[\\w.-]+:)?response>/gi)];\n return responses.flatMap((match): WebDavEntry[] => {\n const block = match[1];\n const href = xmlTagText(block, 'href');\n if (!href) return [];\n // Only properties the server found (status 200) are trusted.\n const okProps = [...block.matchAll(/<(?:[\\w.-]+:)?propstat\\b[^>]*>([\\s\\S]*?)<\\/(?:[\\w.-]+:)?propstat>/gi)]\n .map((propstat) => propstat[1])\n .filter((propstat) => !/<(?:[\\w.-]+:)?status\\b[^>]*>[^<]*\\b(?:4\\d\\d|5\\d\\d)\\b/i.test(propstat))\n .join('');\n const props = okProps || block;\n let path: string;\n try {\n path = decodeURIComponent(new URL(decodeXmlEntities(href), 'http://webdav.invalid').pathname);\n } catch {\n return [];\n }\n const collection = /<(?:[\\w.-]+:)?collection\\b/i.test(xmlTagContent(props, 'resourcetype') ?? '');\n const name = xmlTagText(props, 'displayname') || path.replace(/\\/+$/, '').split('/').pop() || '';\n const size = Number(xmlTagText(props, 'getcontentlength'));\n const modified = Date.parse(xmlTagText(props, 'getlastmodified') ?? '');\n const contentType = xmlTagText(props, 'getcontenttype');\n return [{\n path,\n name,\n collection,\n ...(Number.isFinite(size) && size > 0 ? { size } : {}),\n ...(contentType ? { contentType } : {}),\n ...(Number.isFinite(modified) ? { lastModified: modified } : {}),\n }];\n });\n}\n\n/** Value for the `Authorization` header of an account, or undefined for anonymous shares. */\nexport function webDavAuthorization(account: MediaSourceAccount): string | undefined {\n return account.secret?.startsWith('basic:') ? `Basic ${account.secret.slice(6)}` : undefined;\n}\n\n/** Words kept beside the track, as `song.lrc` next to `song.mp3`; anything larger than this is not lyrics. */\nconst MAX_LYRICS_BYTES = 256 * 1024;\n\n/** Reads the `.lrc` file sitting next to the track, the way a music folder usually keeps its lyrics. */\nexport async function readWebDavLyrics(account: MediaSourceAccount, item: MediaSourceItem, http: MediaSourceHttp): Promise<string | null> {\n const extension = item.url.lastIndexOf('.');\n if (extension < 0) return null;\n const authorization = webDavAuthorization(account);\n const response = await http.send({\n url: `${item.url.slice(0, extension)}.lrc`,\n headers: authorization ? { Authorization: authorization } : {},\n });\n // 404 is the usual answer: most folders keep no lyrics.\n if (response.status >= 400) return null;\n const text = await response.text();\n return text.trim() && text.length <= MAX_LYRICS_BYTES ? text : null;\n}\n\nfunction webDavItem(account: MediaSourceAccount, entry: WebDavEntry, basePath: string, kind: 'audio' | 'video'): MediaSourceItem {\n const relativePath = trimSlash(entry.path).slice(basePath.length).replace(/^\\/+/, '');\n const item: MediaSourceItem = {\n id: mediaSourceItemId(account.id, trimSlash(entry.path)),\n kind,\n title: entry.name,\n url: `${new URL(account.baseUrl).origin}${encodePath(entry.path)}`,\n };\n if (kind === 'audio') {\n const fields = audioFieldsFromTags({ relativePath });\n item.title = fields.title;\n if (fields.artist) item.artist = fields.artist;\n if (fields.albumArtist) item.albumArtist = fields.albumArtist;\n if (fields.album) item.album = fields.album;\n if (fields.trackNo) item.trackNo = fields.trackNo;\n } else {\n const fields = videoFieldsFromTags({ relativePath });\n item.title = fields.title;\n if (fields.series) item.series = fields.series;\n if (fields.season) item.season = fields.season;\n if (fields.episode) item.episode = fields.episode;\n if (fields.year) item.year = fields.year;\n }\n return item;\n}\n\nasync function propfind(http: MediaSourceHttp, account: MediaSourceAccount, url: string, depth: '0' | '1', signal?: AbortSignal): Promise<WebDavEntry[]> {\n const authorization = webDavAuthorization(account);\n const response = await http.send({\n url,\n method: 'PROPFIND',\n headers: {\n Depth: depth,\n 'Content-Type': 'application/xml; charset=utf-8',\n ...(authorization ? { Authorization: authorization } : {}),\n },\n body: PROPFIND_BODY,\n ...(signal ? { signal } : {}),\n });\n if (response.status === 401 || response.status === 403) throw new Error('The WebDAV server refused this user name or password');\n if (response.status === 404) throw new Error('No WebDAV folder at this address');\n if (response.status === 405 || response.status === 501) throw new Error('This address does not speak WebDAV');\n if (response.status !== 207 && response.status >= 300) throw new Error(`WebDAV request failed (HTTP ${response.status})`);\n return parseWebDavMultistatus(await response.text());\n}\n\nfunction encodePath(path: string): string {\n return path.split('/').map((segment) => encodeURIComponent(segment)).join('/');\n}\n\nfunction trimSlash(path: string): string {\n return path.length > 1 ? path.replace(/\\/+$/, '') : path;\n}\n\n/** Keeps browsing inside the share the listener connected. */\nfunction isInside(basePath: string, path: string): boolean {\n const base = trimSlash(basePath) || '/';\n const target = trimSlash(path);\n if (target.split('/').includes('..')) return false;\n return base === '/' || target === base || target.startsWith(`${base}/`);\n}\n\nfunction basicCredentials(username: string, password: string): string {\n const bytes = new TextEncoder().encode(`${username}:${password}`);\n let binary = '';\n bytes.forEach((byte) => { binary += String.fromCharCode(byte); });\n return `basic:${btoa(binary)}`;\n}\n\nfunction shortHash(value: string): string {\n let hash = 0;\n for (let index = 0; index < value.length; index += 1) hash = (Math.imul(31, hash) + value.charCodeAt(index)) | 0;\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n","import { createFetchOnlineJsonHttp, type OnlineJsonHttp } from './online-http';\n\n/** Internet Archive public APIs: advanced search, item metadata and file downloads. No key required. */\nexport const INTERNET_ARCHIVE_ORIGIN = 'https://archive.org';\n\nexport type InternetArchiveMediaType = 'movies' | 'audio';\n\nexport interface InternetArchiveRequestOptions {\n /** Defaults to plain `fetch`. */\n http?: OnlineJsonHttp;\n signal?: AbortSignal;\n origin?: string;\n}\n\nexport interface InternetArchiveSearchOptions {\n mediaType: InternetArchiveMediaType;\n /** Extra Lucene clauses joined with AND, e.g. `collection:(prelinger)`. */\n filters?: readonly string[];\n /** Free text matched against title, creator and subject. */\n text?: string;\n rows?: number;\n page?: number;\n /** Defaults to the most downloaded items first. */\n sort?: string;\n origin?: string;\n}\n\nexport interface InternetArchiveSearchItem {\n identifier: string;\n title: string;\n creator?: string;\n year?: number;\n licenseUrl?: string;\n thumbnailUrl: string;\n detailsUrl: string;\n}\n\nexport interface InternetArchiveSearchResult {\n total: number;\n page: number;\n items: InternetArchiveSearchItem[];\n}\n\nexport interface InternetArchiveFile {\n name: string;\n format?: string;\n source?: string;\n /** For derivatives, the name of the file they were generated from. */\n original?: string;\n title?: string;\n creator?: string;\n album?: string;\n track?: string;\n length?: string;\n size?: string;\n}\n\nexport interface InternetArchiveItem {\n identifier: string;\n title: string;\n creator?: string;\n year?: number;\n description?: string;\n licenseUrl?: string;\n /** Lending, stream-only or dark items cannot be played from their download URLs. */\n restricted: boolean;\n thumbnailUrl: string;\n detailsUrl: string;\n /**\n * Storage servers holding the item (`https://<server>/<dir>`). `/download` redirects to a nearby mirror that may omit\n * CORS headers; these servers send them, so apps download files from here and keep `/download` for streaming.\n */\n storageUrls: string[];\n files: InternetArchiveFile[];\n}\n\nexport interface InternetArchiveVideoSource {\n fileName: string;\n format: string;\n url: string;\n /** Same file on the item's storage servers, readable with `fetch` from other origins. */\n storageUrls: string[];\n durationSec?: number;\n}\n\nexport interface InternetArchiveAudioTrack {\n /** `<identifier>/<file name>`, unique across the archive. */\n id: string;\n identifier: string;\n fileName: string;\n title: string;\n artist?: string;\n album: string;\n trackNo?: number;\n durationSec?: number;\n url: string;\n /** Same file on the item's storage servers, readable with `fetch` from other origins. */\n storageUrls: string[];\n artworkUrl: string;\n}\n\n/** Clauses that keep results playable without an account. */\nexport const INTERNET_ARCHIVE_PLAYABLE_FILTERS: readonly string[] = [\n '-collection:(stream_only)',\n '-access-restricted-item:(true)',\n];\n\nconst SEARCH_FIELDS = ['identifier', 'title', 'creator', 'year', 'licenseurl'];\nconst VIDEO_FORMATS = ['h.264', 'MPEG4', 'h.264 HD', '512Kb MPEG4', 'h.264 IA', 'WebM', 'Ogg Video'];\nconst AUDIO_FORMATS = ['VBR MP3', 'MP3', '128Kbps MP3', '64Kbps MP3', 'Ogg Vorbis'];\nconst LUCENE_SPECIAL = /[+\\-&|!(){}[\\]^\"~*?:\\\\/]/g;\n\nexport function buildInternetArchiveSearchUrl(options: InternetArchiveSearchOptions): string {\n const clauses = [`mediatype:(${options.mediaType})`, ...(options.filters ?? [])];\n const terms = (options.text ?? '').replace(LUCENE_SPECIAL, ' ').trim().split(/\\s+/).filter(Boolean);\n if (terms.length) {\n const words = terms.join(' AND ');\n clauses.push(`(title:(${words}) OR creator:(${words}) OR subject:(${words}))`);\n }\n\n const params = new URLSearchParams({ q: clauses.join(' AND ') });\n for (const field of SEARCH_FIELDS) params.append('fl[]', field);\n params.append('sort[]', options.sort ?? 'downloads desc');\n params.set('rows', String(clampInteger(options.rows, 1, 100, 20)));\n params.set('page', String(clampInteger(options.page, 1, 10_000, 1)));\n params.set('output', 'json');\n return `${originOf(options.origin)}/advancedsearch.php?${params}`;\n}\n\nexport async function searchInternetArchive(\n options: InternetArchiveSearchOptions,\n request: InternetArchiveRequestOptions = {},\n): Promise<InternetArchiveSearchResult> {\n const origin = request.origin ?? options.origin;\n const body = await getJson(buildInternetArchiveSearchUrl({ ...options, origin }), request);\n const response = (body as { response?: { numFound?: unknown; docs?: unknown } } | null)?.response;\n const docs = Array.isArray(response?.docs) ? response.docs : [];\n const items = docs.flatMap((doc): InternetArchiveSearchItem[] => {\n const record = doc as Record<string, unknown>;\n const identifier = firstText(record['identifier']);\n if (!identifier) return [];\n return [{\n identifier,\n title: firstText(record['title']) ?? identifier,\n creator: firstText(record['creator']),\n year: parseYear(record['year']),\n licenseUrl: firstText(record['licenseurl']),\n thumbnailUrl: internetArchiveThumbnailUrl(identifier, origin),\n detailsUrl: internetArchiveDetailsUrl(identifier, origin),\n }];\n });\n return {\n total: typeof response?.numFound === 'number' ? response.numFound : items.length,\n page: clampInteger(options.page, 1, 10_000, 1),\n items,\n };\n}\n\nexport async function fetchInternetArchiveItem(\n identifier: string,\n request: InternetArchiveRequestOptions = {},\n): Promise<InternetArchiveItem> {\n const body = await getJson(`${originOf(request.origin)}/metadata/${encodeURIComponent(identifier)}`, request);\n return parseInternetArchiveItem(identifier, body, request.origin);\n}\n\nexport function parseInternetArchiveItem(identifier: string, body: unknown, origin?: string): InternetArchiveItem {\n const record = (body ?? {}) as {\n metadata?: Record<string, unknown>;\n files?: unknown;\n is_dark?: unknown;\n workable_servers?: unknown;\n d1?: unknown;\n d2?: unknown;\n server?: unknown;\n dir?: unknown;\n };\n if (!record.metadata) throw new Error(`Internet Archive item not found: ${identifier}`);\n const metadata = record.metadata;\n const collections = allTexts(metadata['collection']);\n const files = (Array.isArray(record.files) ? record.files : []).flatMap((file): InternetArchiveFile[] => {\n const entry = file as Record<string, unknown>;\n const name = firstText(entry['name']);\n if (!name || firstText(entry['private']) === 'true') return [];\n return [{\n name,\n format: firstText(entry['format']),\n source: firstText(entry['source']),\n original: firstText(entry['original']),\n title: firstText(entry['title']),\n creator: firstText(entry['creator']) ?? firstText(entry['artist']),\n album: firstText(entry['album']),\n track: firstText(entry['track']),\n length: firstText(entry['length']),\n size: firstText(entry['size']),\n }];\n });\n\n return {\n identifier,\n title: firstText(metadata['title']) ?? identifier,\n creator: allTexts(metadata['creator']).join(', ') || undefined,\n year: parseYear(metadata['year']) ?? parseYear(metadata['date']),\n description: plainDescription(firstText(metadata['description'])),\n licenseUrl: firstText(metadata['licenseurl']),\n restricted: record.is_dark === true\n || firstText(metadata['access-restricted-item']) === 'true'\n || collections.includes('stream_only'),\n thumbnailUrl: internetArchiveThumbnailUrl(identifier, origin),\n detailsUrl: internetArchiveDetailsUrl(identifier, origin),\n storageUrls: storageUrlsOf(record),\n files,\n };\n}\n\nconst STORAGE_HOST = /^[a-z0-9-]+(?:\\.[a-z0-9-]+)*\\.archive\\.org$/i;\n\nfunction storageUrlsOf(record: { workable_servers?: unknown; d1?: unknown; d2?: unknown; server?: unknown; dir?: unknown }): string[] {\n const dir = firstText(record.dir);\n if (!dir || !dir.startsWith('/') || dir.includes('..')) return [];\n const hosts = [...allTexts(record.workable_servers), ...allTexts(record.d1), ...allTexts(record.d2), ...allTexts(record.server)];\n // Only archive.org hosts are trusted: the document decides nothing else about where the app connects.\n return [...new Set(hosts.filter((host) => STORAGE_HOST.test(host)))].map((host) => `https://${host}${dir}`);\n}\n\nfunction storageFileUrls(item: InternetArchiveItem, fileName: string): string[] {\n const path = fileName.split('/').map((segment) => encodeURIComponent(segment)).join('/');\n return item.storageUrls.map((base) => `${base}/${path}`);\n}\n\n/** Picks the most widely playable video derivative of an item. */\nexport function selectInternetArchiveVideo(item: InternetArchiveItem, origin?: string): InternetArchiveVideoSource | null {\n if (item.restricted) return null;\n for (const format of VIDEO_FORMATS) {\n const file = item.files.find((candidate) => candidate.format === format);\n if (file) {\n return {\n fileName: file.name,\n format,\n url: internetArchiveDownloadUrl(item.identifier, file.name, origin),\n storageUrls: storageFileUrls(item, file.name),\n durationSec: parseInternetArchiveLength(file.length),\n };\n }\n }\n return null;\n}\n\n/** Tracks of an audio item, using a single format so derivatives are not listed twice. */\nexport function internetArchiveAudioTracks(item: InternetArchiveItem, origin?: string): InternetArchiveAudioTrack[] {\n if (item.restricted) return [];\n const format = AUDIO_FORMATS.find((candidate) => item.files.some((file) => file.format === candidate));\n if (!format) return [];\n\n const candidates = item.files.filter((file) => file.format === format);\n const names = new Set(candidates.map((file) => file.name));\n return candidates\n // Uploaders sometimes store MP3 originals whose VBR derivative carries the same format.\n .filter((file) => !file.original || !names.has(file.original))\n .map((file): InternetArchiveAudioTrack => ({\n id: `${item.identifier}/${file.name}`,\n identifier: item.identifier,\n fileName: file.name,\n title: readableTitle(file.title ?? fileStem(file.name)),\n artist: file.creator ?? item.creator,\n album: file.album ?? item.title,\n trackNo: parseTrackNumber(file.track),\n durationSec: parseInternetArchiveLength(file.length),\n url: internetArchiveDownloadUrl(item.identifier, file.name, origin),\n storageUrls: storageFileUrls(item, file.name),\n artworkUrl: item.thumbnailUrl,\n }))\n .sort((left, right) => (left.trackNo ?? Number.MAX_SAFE_INTEGER) - (right.trackNo ?? Number.MAX_SAFE_INTEGER)\n || left.fileName.localeCompare(right.fileName, undefined, { numeric: true }));\n}\n\nexport function internetArchiveDownloadUrl(identifier: string, fileName: string, origin?: string): string {\n const path = fileName.split('/').map((segment) => encodeURIComponent(segment)).join('/');\n return `${originOf(origin)}/download/${encodeURIComponent(identifier)}/${path}`;\n}\n\nexport function internetArchiveThumbnailUrl(identifier: string, origin?: string): string {\n return `${originOf(origin)}/services/img/${encodeURIComponent(identifier)}`;\n}\n\nexport function internetArchiveDetailsUrl(identifier: string, origin?: string): string {\n return `${originOf(origin)}/details/${encodeURIComponent(identifier)}`;\n}\n\n/** Accepts `240.9` seconds as well as `02:31` or `1:31:44`. */\nexport function parseInternetArchiveLength(length: string | undefined): number | undefined {\n if (!length) return undefined;\n const parts = length.trim().split(':');\n if (parts.some((part) => !/^\\d+(?:\\.\\d+)?$/.test(part))) return undefined;\n const seconds = parts.reduce((total, part) => total * 60 + Number(part), 0);\n return seconds > 0 ? Math.round(seconds) : undefined;\n}\n\nasync function getJson(url: string, request: InternetArchiveRequestOptions): Promise<unknown> {\n const http = request.http ?? createFetchOnlineJsonHttp();\n try {\n return await http.getJson(url, { signal: request.signal });\n } catch (error) {\n if (request.signal?.aborted) throw error;\n throw new Error(`Internet Archive request failed (${error instanceof Error ? error.message : String(error)})`);\n }\n}\n\nfunction originOf(origin: string | undefined): string {\n return (origin ?? INTERNET_ARCHIVE_ORIGIN).replace(/\\/+$/, '');\n}\n\nfunction firstText(value: unknown): string | undefined {\n return allTexts(value)[0];\n}\n\nfunction allTexts(value: unknown): string[] {\n const values = Array.isArray(value) ? value : [value];\n return values.flatMap((entry) => {\n if (typeof entry === 'number') return [String(entry)];\n return typeof entry === 'string' && entry.trim() ? [entry.trim()] : [];\n });\n}\n\nfunction parseYear(value: unknown): number | undefined {\n const match = /\\b(1[89]\\d{2}|20\\d{2})\\b/.exec(firstText(value) ?? '');\n return match ? Number(match[1]) : undefined;\n}\n\nfunction parseTrackNumber(track: string | undefined): number | undefined {\n const match = /^\\s*(\\d+)/.exec(track ?? '');\n return match ? Number(match[1]) : undefined;\n}\n\nfunction plainDescription(description: string | undefined): string | undefined {\n if (!description) return undefined;\n const text = description\n .replace(/<br\\s*\\/?>/gi, ' ')\n .replace(/<[^>]*>/g, ' ')\n .replace(/&nbsp;/g, ' ')\n .replace(/&amp;/g, '&')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n .replace(/\\s+/g, ' ')\n .trim();\n if (!text) return undefined;\n return text.length > 320 ? `${text.slice(0, 317).trimEnd()}...` : text;\n}\n\nfunction fileStem(name: string): string {\n const base = name.split('/').pop() ?? name;\n return base.replace(/\\.[^.]+$/, '') || base;\n}\n\n/** Titles copied from file names (`101.Artist_Song`) lose their numbering and underscores. */\nfunction readableTitle(title: string): string {\n if (/\\s/.test(title) && !title.includes('_')) return title;\n return title.replace(/^\\d{1,3}\\s*[.\\-_)]\\s*/, '').replace(/_+/g, ' ').replace(/\\s+/g, ' ').trim() || title;\n}\n\nfunction clampInteger(value: number | undefined, min: number, max: number, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback;\n return Math.min(max, Math.max(min, Math.trunc(value)));\n}\n","import { createFetchOnlineJsonHttp, type OnlineJsonHttp } from './online-http';\n\n/** Radio Browser community directory of internet radio stations. No key required. */\nexport const RADIO_BROWSER_ORIGIN = 'https://de1.api.radio-browser.info';\n\nexport interface RadioBrowserSearchOptions {\n /** ISO 3166-1 alpha-2 country code, e.g. `CM`. */\n countryCode?: string;\n name?: string;\n tag?: string;\n limit?: number;\n offset?: number;\n /** Defaults to true: stations failing the directory checks are skipped. */\n hideBroken?: boolean;\n /** Defaults to the most listened stations first. */\n order?: 'clickcount' | 'votes' | 'name' | 'bitrate' | 'lastcheckok';\n origin?: string;\n}\n\nexport interface RadioBrowserRequestOptions {\n /** Defaults to plain `fetch`. */\n http?: OnlineJsonHttp;\n signal?: AbortSignal;\n origin?: string;\n}\n\nexport interface RadioStation {\n id: string;\n name: string;\n streamUrl: string;\n homepageUrl?: string;\n faviconUrl?: string;\n country?: string;\n countryCode?: string;\n language?: string;\n tags: string[];\n codec?: string;\n bitrateKbps?: number;\n /** HLS playlists need an adaptive engine; other streams play in a media element. */\n hls: boolean;\n /** Plain http streams are blocked as mixed content on https pages. */\n secure: boolean;\n}\n\nexport function buildRadioBrowserSearchUrl(options: RadioBrowserSearchOptions = {}): string {\n const params = new URLSearchParams();\n if (options.countryCode?.trim()) params.set('countrycode', options.countryCode.trim().toUpperCase());\n if (options.name?.trim()) params.set('name', options.name.trim());\n if (options.tag?.trim()) params.set('tag', options.tag.trim());\n params.set('hidebroken', String(options.hideBroken ?? true));\n params.set('limit', String(clampInteger(options.limit, 1, 500, 20)));\n if (options.offset) params.set('offset', String(clampInteger(options.offset, 0, 100_000, 0)));\n const order = options.order ?? 'clickcount';\n params.set('order', order);\n if (order !== 'name') params.set('reverse', 'true');\n return `${originOf(options.origin)}/json/stations/search?${params}`;\n}\n\nexport async function searchRadioStations(\n options: RadioBrowserSearchOptions = {},\n request: RadioBrowserRequestOptions = {},\n): Promise<RadioStation[]> {\n const url = buildRadioBrowserSearchUrl({ ...options, origin: request.origin ?? options.origin });\n const http = request.http ?? createFetchOnlineJsonHttp();\n let body: unknown;\n try {\n body = await http.getJson(url, { signal: request.signal });\n } catch (error) {\n if (request.signal?.aborted) throw error;\n throw new Error(`Radio Browser request failed (${error instanceof Error ? error.message : String(error)})`);\n }\n const seen = new Set<string>();\n return (Array.isArray(body) ? body : []).flatMap((entry): RadioStation[] => {\n const station = parseRadioStation(entry);\n if (!station || seen.has(station.id)) return [];\n seen.add(station.id);\n return [station];\n });\n}\n\nexport function parseRadioStation(entry: unknown): RadioStation | null {\n const record = (entry ?? {}) as Record<string, unknown>;\n const id = text(record['stationuuid']);\n const streamUrl = httpUrl(text(record['url_resolved'])) ?? httpUrl(text(record['url']));\n if (!id || !streamUrl) return null;\n const bitrate = Number(record['bitrate']);\n\n return {\n id,\n name: text(record['name'])?.replace(/\\s+/g, ' ') ?? streamUrl,\n streamUrl,\n homepageUrl: httpUrl(text(record['homepage'])),\n faviconUrl: httpUrl(text(record['favicon'])),\n country: text(record['country']),\n countryCode: text(record['countrycode']),\n language: text(record['language']),\n tags: (text(record['tags']) ?? '').split(',').map((tag) => tag.trim()).filter(Boolean),\n codec: text(record['codec']),\n bitrateKbps: Number.isFinite(bitrate) && bitrate > 0 ? bitrate : undefined,\n hls: record['hls'] === 1 || record['hls'] === true || /\\.m3u8(?:$|\\?)/i.test(streamUrl),\n secure: streamUrl.startsWith('https://'),\n };\n}\n\nfunction text(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction httpUrl(value: string | undefined): string | undefined {\n return value && /^https?:\\/\\//i.test(value) ? value : undefined;\n}\n\nfunction originOf(origin: string | undefined): string {\n return (origin ?? RADIO_BROWSER_ORIGIN).replace(/\\/+$/, '');\n}\n\nfunction clampInteger(value: number | undefined, min: number, max: number, fallback: number): number {\n if (value === undefined || !Number.isFinite(value)) return fallback;\n return Math.min(max, Math.max(min, Math.trunc(value)));\n}\n","import { createFetchOnlineJsonHttp, type OnlineJsonHttp } from './online-http';\n\n/** MusicBrainz open music encyclopedia (GPL server, CC0 core data). No key; one request per second per client. */\nexport const MUSICBRAINZ_ORIGIN = 'https://musicbrainz.org';\n\nexport interface MusicBrainzRecordingQuery {\n title: string;\n artist?: string;\n durationSec?: number;\n /** Tolerance around `durationSec`, in seconds. */\n durationToleranceSec?: number;\n limit?: number;\n}\n\nexport interface MusicBrainzRequestOptions {\n /** Defaults to plain `fetch`; desktop shells should send a descriptive User-Agent and rate limit requests. */\n http?: OnlineJsonHttp;\n signal?: AbortSignal;\n origin?: string;\n}\n\nexport interface MusicBrainzRelease {\n id: string;\n title: string;\n artist?: string;\n status?: string;\n primaryType?: string;\n year?: number;\n discNo?: number;\n trackNo?: number;\n}\n\nexport interface MusicBrainzRecording {\n id: string;\n /** Search relevance, 0 to 100. */\n score: number;\n title: string;\n artist?: string;\n durationSec?: number;\n releases: MusicBrainzRelease[];\n}\n\nconst LUCENE_SPECIAL = /[+\\-&|!(){}[\\]^\"~*?:\\\\/]/g;\n\nexport function buildMusicBrainzRecordingSearchUrl(query: MusicBrainzRecordingQuery, origin?: string): string {\n const clauses = [`recording:(${luceneWords(query.title)})`];\n if (query.artist && luceneWords(query.artist)) clauses.push(`artist:(${luceneWords(query.artist)})`);\n if (query.durationSec && query.durationSec > 0) {\n const tolerance = Math.max(1, query.durationToleranceSec ?? 4);\n const from = Math.max(0, Math.round((query.durationSec - tolerance) * 1000));\n const to = Math.round((query.durationSec + tolerance) * 1000);\n clauses.push(`dur:[${from} TO ${to}]`);\n }\n const params = new URLSearchParams({\n query: clauses.join(' AND '),\n fmt: 'json',\n limit: String(Math.min(25, Math.max(1, Math.trunc(query.limit ?? 10)))),\n });\n return `${(origin ?? MUSICBRAINZ_ORIGIN).replace(/\\/+$/, '')}/ws/2/recording?${params}`;\n}\n\nexport async function searchMusicBrainzRecordings(\n query: MusicBrainzRecordingQuery,\n request: MusicBrainzRequestOptions = {},\n): Promise<MusicBrainzRecording[]> {\n if (!luceneWords(query.title)) return [];\n const http = request.http ?? createFetchOnlineJsonHttp();\n let body: unknown;\n try {\n body = await http.getJson(buildMusicBrainzRecordingSearchUrl(query, request.origin), { signal: request.signal });\n } catch (error) {\n if (request.signal?.aborted) throw error;\n throw new Error(`MusicBrainz request failed (${error instanceof Error ? error.message : String(error)})`);\n }\n const recordings = (body as { recordings?: unknown } | null)?.recordings;\n return (Array.isArray(recordings) ? recordings : []).flatMap((entry) => {\n const recording = parseMusicBrainzRecording(entry);\n return recording ? [recording] : [];\n });\n}\n\n/** Recording details by MusicBrainz id, with its releases, release groups and track positions. */\nexport async function lookupMusicBrainzRecording(id: string, request: MusicBrainzRequestOptions = {}): Promise<MusicBrainzRecording | null> {\n if (!/^[0-9a-f-]{36}$/i.test(id)) return null;\n const http = request.http ?? createFetchOnlineJsonHttp();\n const params = new URLSearchParams({ inc: 'releases release-groups artist-credits media', fmt: 'json' });\n try {\n const body = await http.getJson(`${(request.origin ?? MUSICBRAINZ_ORIGIN).replace(/\\/+$/, '')}/ws/2/recording/${id}?${params}`, { signal: request.signal });\n return parseMusicBrainzRecording({ score: 100, ...(body as object) });\n } catch (error) {\n if (request.signal?.aborted) throw error;\n throw new Error(`MusicBrainz request failed (${error instanceof Error ? error.message : String(error)})`);\n }\n}\n\nexport function parseMusicBrainzRecording(entry: unknown): MusicBrainzRecording | null {\n const record = (entry ?? {}) as Record<string, unknown>;\n const id = text(record['id']);\n const title = text(record['title']);\n if (!id || !title) return null;\n const length = Number(record['length']);\n const releases = Array.isArray(record['releases']) ? record['releases'] : [];\n\n return {\n id,\n score: Number(record['score']) || 0,\n title,\n artist: artistCredit(record['artist-credit']),\n durationSec: Number.isFinite(length) && length > 0 ? Math.round(length / 1000) : undefined,\n releases: releases.flatMap((release): MusicBrainzRelease[] => {\n const item = (release ?? {}) as Record<string, unknown>;\n const releaseId = text(item['id']);\n const releaseTitle = text(item['title']);\n if (!releaseId || !releaseTitle) return [];\n const medium = (Array.isArray(item['media']) ? item['media'][0] : undefined) as Record<string, unknown> | undefined;\n const track = (Array.isArray(medium?.['track']) ? medium['track'][0] : undefined) as Record<string, unknown> | undefined;\n const year = /^(\\d{4})/.exec(text(item['date']) ?? '');\n return [{\n id: releaseId,\n title: releaseTitle,\n artist: artistCredit(item['artist-credit']),\n status: text(item['status']),\n primaryType: text((item['release-group'] as Record<string, unknown> | undefined)?.['primary-type']),\n year: year ? Number(year[1]) : undefined,\n discNo: positiveInteger(medium?.['position']),\n // Search results list the matching track; lookups only give its offset in the medium.\n trackNo: positiveInteger(track?.['number']) ?? offsetTrackNumber(medium?.['track-offset']),\n }];\n }),\n };\n}\n\nfunction artistCredit(value: unknown): string | undefined {\n if (!Array.isArray(value)) return undefined;\n const credit = value.map((part) => {\n const item = (part ?? {}) as Record<string, unknown>;\n return `${text(item['name']) ?? ''}${typeof item['joinphrase'] === 'string' ? item['joinphrase'] : ''}`;\n }).join('').trim();\n return credit || undefined;\n}\n\nfunction luceneWords(value: string): string {\n return value.replace(LUCENE_SPECIAL, ' ').replace(/\\s+/g, ' ').trim();\n}\n\nfunction text(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction offsetTrackNumber(offset: unknown): number | undefined {\n const number = Number(offset);\n return Number.isInteger(number) && number >= 0 ? number + 1 : undefined;\n}\n\nfunction positiveInteger(value: unknown): number | undefined {\n const number = Number(value);\n return Number.isInteger(number) && number > 0 ? number : undefined;\n}\n","import { createFetchOnlineJsonHttp, type OnlineJsonHttp } from './online-http';\n\n/**\n * Lyrics of a track, timed or plain. They come from the file itself (tags), from an `.lrc` file beside it, or from\n * LRCLIB, an open lyrics database (no key, no account). Timed lines let the player follow the words while it plays.\n */\nexport const LRCLIB_ORIGIN = 'https://lrclib.net';\n\nexport type LyricsSource = 'tags' | 'file' | 'lrclib';\n\nexport interface LyricsLine {\n /** Start of the line in the track. */\n timeSec: number;\n text: string;\n}\n\nexport interface Lyrics {\n source: LyricsSource;\n /** Timed lines, when the source has them. */\n lines?: LyricsLine[];\n /** The whole text, always present when anything was found. */\n plain: string;\n /** What the source says it is, to show which version was picked. */\n title?: string;\n artist?: string;\n /** LRCLIB record, to fetch it again or report a wrong match. */\n id?: number;\n}\n\nexport interface LyricsQuery {\n title: string;\n artist?: string;\n album?: string;\n durationSec?: number;\n}\n\nexport interface LyricsRequestOptions {\n /** Defaults to plain `fetch`; apps plug their HTTP client (cache, retries). */\n http?: OnlineJsonHttp;\n signal?: AbortSignal;\n origin?: string;\n}\n\n/** `[mm:ss.xx]` lines, `[offset:±ms]` and the usual `[ti:]`/`[ar:]` tags; text without timestamps stays plain. */\nexport function parseLrc(text: string, source: LyricsSource = 'file'): Lyrics | null {\n const raw = String(text ?? '').replace(/\\r\\n?/g, '\\n');\n if (!raw.trim()) return null;\n const lines: LyricsLine[] = [];\n const plain: string[] = [];\n let offsetSec = 0;\n let title: string | undefined;\n let artist: string | undefined;\n\n for (const line of raw.split('\\n')) {\n const tag = /^\\s*\\[(ti|ar|al|offset)\\s*:\\s*([^\\]]*)\\]\\s*$/i.exec(line);\n if (tag) {\n const value = tag[2].trim();\n if (/^ti$/i.test(tag[1])) title = value || undefined;\n if (/^ar$/i.test(tag[1])) artist = value || undefined;\n if (/^offset$/i.test(tag[1])) offsetSec = (Number(value) || 0) / 1000;\n continue;\n }\n const stamps = [...line.matchAll(/\\[(\\d{1,3}):(\\d{1,2})(?:[.:](\\d{1,3}))?\\]/g)];\n const content = line.replace(/\\[(\\d{1,3}):(\\d{1,2})(?:[.:](\\d{1,3}))?\\]/g, '').trim();\n if (!stamps.length) {\n if (content) plain.push(content);\n continue;\n }\n for (const stamp of stamps) {\n const fraction = stamp[3] ? Number(`0.${stamp[3]}`) : 0;\n lines.push({ timeSec: Number(stamp[1]) * 60 + Number(stamp[2]) + fraction, text: content });\n }\n if (content) plain.push(content);\n }\n\n if (!lines.length && !plain.length) return null;\n const timed = lines\n // The offset of an LRC file shifts every line; a positive value means the words come earlier.\n .map((line) => ({ ...line, timeSec: Math.max(0, line.timeSec - offsetSec) }))\n .sort((left, right) => left.timeSec - right.timeSec);\n return {\n source,\n ...(timed.length ? { lines: timed } : {}),\n plain: plain.join('\\n'),\n ...(title ? { title } : {}),\n ...(artist ? { artist } : {}),\n };\n}\n\n/** Lyrics tags of a file (ID3 USLT/SYLT, Vorbis LYRICS), as music-metadata reports them. */\nexport interface TaggedLyrics {\n text?: string;\n syncText?: Array<{ text?: string; timestamp?: number }>;\n}\n\n/** Lyrics carried by the file itself; timed words win over a plain block. */\nexport function lyricsFromTags(tags: readonly TaggedLyrics[] | TaggedLyrics | undefined | null): Lyrics | null {\n const entries: TaggedLyrics[] = Array.isArray(tags) ? [...tags] : tags ? [tags] : [];\n for (const entry of entries) {\n const timed = (entry?.syncText ?? []).filter((line) => typeof line?.timestamp === 'number');\n if (timed.length) {\n return {\n source: 'tags',\n // music-metadata reports synchronised lyrics in milliseconds.\n lines: timed.map((line) => ({ timeSec: Math.max(0, (line.timestamp as number) / 1000), text: (line.text ?? '').trim() })),\n plain: timed.map((line) => (line.text ?? '').trim()).filter(Boolean).join('\\n'),\n };\n }\n }\n for (const entry of entries) {\n const parsed = entry?.text ? parseLrc(entry.text, 'tags') : null;\n if (parsed) return parsed;\n }\n return null;\n}\n\n/** Index of the line being sung at this position, or -1 before the first one. */\nexport function lyricsLineIndexAt(lines: readonly LyricsLine[] | undefined, positionSec: number): number {\n if (!lines?.length) return -1;\n let low = 0;\n let high = lines.length - 1;\n let found = -1;\n while (low <= high) {\n const middle = (low + high) >> 1;\n if (lines[middle].timeSec <= positionSec + 0.001) {\n found = middle;\n low = middle + 1;\n } else {\n high = middle - 1;\n }\n }\n return found;\n}\n\ninterface LrclibRecord {\n id?: number;\n trackName?: string;\n artistName?: string;\n duration?: number;\n instrumental?: boolean;\n plainLyrics?: string | null;\n syncedLyrics?: string | null;\n}\n\nexport function buildLrclibGetUrl(query: LyricsQuery, origin: string = LRCLIB_ORIGIN): string {\n const parameters = new URLSearchParams({ track_name: query.title, artist_name: query.artist ?? '' });\n if (query.album) parameters.set('album_name', query.album);\n if (query.durationSec) parameters.set('duration', String(Math.round(query.durationSec)));\n return `${origin}/api/get?${parameters.toString()}`;\n}\n\nexport function buildLrclibSearchUrl(query: LyricsQuery, origin: string = LRCLIB_ORIGIN): string {\n const parameters = new URLSearchParams({ track_name: query.title });\n if (query.artist) parameters.set('artist_name', query.artist);\n return `${origin}/api/search?${parameters.toString()}`;\n}\n\n/**\n * Lyrics for a track from LRCLIB: the exact record when the track, artist, album and duration match, otherwise the\n * closest of the search results. Returns null when the database has nothing, and for instrumental tracks.\n */\nexport async function fetchLrclibLyrics(query: LyricsQuery, options: LyricsRequestOptions = {}): Promise<Lyrics | null> {\n const http = options.http ?? createFetchOnlineJsonHttp();\n const request = options.signal ? { signal: options.signal } : {};\n const title = query.title.trim();\n if (!title) return null;\n\n const exact = await http.getJson(buildLrclibGetUrl({ ...query, title }, options.origin), request).catch(() => null);\n const direct = lyricsFromRecord(exact as LrclibRecord | null);\n if (direct) return direct;\n\n const results = await http.getJson(buildLrclibSearchUrl({ ...query, title }, options.origin), request).catch(() => null);\n if (!Array.isArray(results)) return null;\n const best = bestLrclibMatch(results as LrclibRecord[], { ...query, title });\n return best ? lyricsFromRecord(best) : null;\n}\n\n/** Closest record: a duration within 5 seconds first, then the title and artist that look most alike. */\nexport function bestLrclibMatch(records: readonly LrclibRecord[], query: LyricsQuery): LrclibRecord | null {\n const usable = records.filter((record) => !record.instrumental && (record.syncedLyrics || record.plainLyrics));\n if (!usable.length) return null;\n const score = (record: LrclibRecord): number => {\n const durationGap = query.durationSec && record.duration ? Math.abs(record.duration - query.durationSec) : undefined;\n return (durationGap !== undefined && durationGap <= 5 ? 100 - durationGap * 4 : 0)\n + (record.syncedLyrics ? 40 : 0)\n + similarity(record.trackName, query.title) * 30\n + similarity(record.artistName, query.artist) * 20;\n };\n return [...usable].sort((left, right) => score(right) - score(left))[0] ?? null;\n}\n\nfunction lyricsFromRecord(record: LrclibRecord | null): Lyrics | null {\n if (!record || record.instrumental) return null;\n const parsed = record.syncedLyrics ? parseLrc(record.syncedLyrics, 'lrclib') : null;\n const plain = record.plainLyrics?.trim();\n if (!parsed && !plain) return null;\n return {\n source: 'lrclib',\n ...(parsed?.lines ? { lines: parsed.lines } : {}),\n plain: plain || parsed?.plain || '',\n ...(record.trackName ? { title: record.trackName } : {}),\n ...(record.artistName ? { artist: record.artistName } : {}),\n ...(record.id ? { id: record.id } : {}),\n };\n}\n\n/** How much of the shorter text the two names share, ignoring case, accents and punctuation. */\nfunction similarity(left: string | undefined, right: string | undefined): number {\n const clean = (value: string | undefined) => (value ?? '')\n .normalize('NFD')\n .replace(/[̀-ͯ]/g, '')\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, ' ')\n .trim();\n const a = clean(left);\n const b = clean(right);\n if (!a || !b) return 0;\n if (a === b) return 1;\n const words = new Set(a.split(' '));\n const shared = b.split(' ').filter((word) => words.has(word)).length;\n return shared / Math.max(words.size, b.split(' ').length);\n}\n","import { createFetchOnlineJsonHttp, type OnlineJsonHttp } from './online-http';\n\n/** AcoustID open fingerprint database (MIT server, CC BY-SA data). Free application keys for non-commercial use. */\nexport const ACOUSTID_ORIGIN = 'https://api.acoustid.org';\n\nexport interface AcoustIdLookupQuery {\n /** Application key registered at acoustid.org. */\n clientKey: string;\n /** Compressed Chromaprint fingerprint (`AQAB…`). */\n fingerprint: string;\n durationSec: number;\n}\n\nexport interface AcoustIdRequestOptions {\n http?: OnlineJsonHttp;\n signal?: AbortSignal;\n origin?: string;\n}\n\nexport interface AcoustIdRecording {\n id: string;\n title?: string;\n artist?: string;\n durationSec?: number;\n}\n\nexport interface AcoustIdResult {\n id: string;\n /** Fingerprint similarity, 0 to 1. */\n score: number;\n recordings: AcoustIdRecording[];\n}\n\nexport function buildAcoustIdLookupUrl(query: AcoustIdLookupQuery, origin?: string): string {\n const params = new URLSearchParams({\n client: query.clientKey,\n meta: 'recordings',\n duration: String(Math.max(1, Math.round(query.durationSec))),\n fingerprint: query.fingerprint,\n format: 'json',\n });\n return `${(origin ?? ACOUSTID_ORIGIN).replace(/\\/+$/, '')}/v2/lookup?${params}`;\n}\n\nexport async function lookupAcoustId(query: AcoustIdLookupQuery, request: AcoustIdRequestOptions = {}): Promise<AcoustIdResult[]> {\n if (!query.clientKey || !query.fingerprint || !(query.durationSec > 0)) return [];\n const http = request.http ?? createFetchOnlineJsonHttp();\n let body: unknown;\n try {\n body = await http.getJson(buildAcoustIdLookupUrl(query, request.origin), { signal: request.signal });\n } catch (error) {\n if (request.signal?.aborted) throw error;\n throw new Error(`AcoustID request failed (${error instanceof Error ? error.message : String(error)})`);\n }\n const record = (body ?? {}) as { status?: unknown; error?: { message?: unknown }; results?: unknown };\n if (record.status !== 'ok') {\n throw new Error(`AcoustID lookup refused (${typeof record.error?.message === 'string' ? record.error.message : 'unknown error'})`);\n }\n return (Array.isArray(record.results) ? record.results : []).flatMap((entry): AcoustIdResult[] => {\n const result = (entry ?? {}) as Record<string, unknown>;\n const id = typeof result['id'] === 'string' ? result['id'] : '';\n if (!id) return [];\n const recordings = Array.isArray(result['recordings']) ? result['recordings'] : [];\n return [{\n id,\n score: Number(result['score']) || 0,\n recordings: recordings.flatMap((recording): AcoustIdRecording[] => {\n const item = (recording ?? {}) as Record<string, unknown>;\n if (typeof item['id'] !== 'string') return [];\n const artists = Array.isArray(item['artists']) ? item['artists'] as Array<Record<string, unknown>> : [];\n const artist = artists.map((part) => `${part['name'] ?? ''}${typeof part['joinphrase'] === 'string' ? part['joinphrase'] : ''}`).join('').trim();\n const duration = Number(item['duration']);\n return [{\n id: item['id'],\n title: typeof item['title'] === 'string' ? item['title'] : undefined,\n artist: artist || undefined,\n durationSec: Number.isFinite(duration) && duration > 0 ? Math.round(duration) : undefined,\n }];\n }),\n }];\n });\n}\n"]}