@ngxsplayer/ngx-smart-player 0.0.1-next.0 → 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/LICENSE +21 -0
- package/README.md +26 -0
- package/fesm2022/ngxsplayer-ngx-smart-player.mjs +2982 -675
- package/fesm2022/ngxsplayer-ngx-smart-player.mjs.map +1 -1
- package/index.d.ts +488 -26
- package/package.json +10 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngxsplayer-ngx-smart-player.mjs","sources":["../../../projects/ngx-smart-player/src/lib/smart-player.component.ts","../../../projects/ngx-smart-player/src/lib/smart-player.providers.ts","../../../projects/ngx-smart-player/src/ngxsplayer-ngx-smart-player.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, HostListener, Input, OnDestroy, OnInit, Output, ViewChild } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\n\nimport { MediaTrack, PlayerConfig, PlayerState, PlayerPorts, createSsaiManifestRewritePlugin, type EngineFactory } from '@ngxsp/core';\nimport { PlayerFacade } from '@ngxsp/core';\nimport { PlayerPlugin } from '@ngxsp/core';\n\n@Component({\n selector: 'ngx-smart-player',\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"ngxsp-root\" [class.ngxsp-skin-netflix]=\"uiSkin==='netflix'\" [class.ngxsp-ui-visible]=\"uiVisible\" [attr.data-kind]=\"state?.kind\">\n <div class=\"ngxsp-video\" (dblclick)=\"toggleFullscreen()\" (mousemove)=\"onInteraction()\" (mouseenter)=\"onInteraction()\" (mouseleave)=\"onPointerLeave()\" (focusin)=\"onInteraction()\" (touchstart)=\"onInteraction(true)\" (click)=\"onRootClick($event)\">\n <video #video playsinline (timeupdate)=\"noop()\" (loadedmetadata)=\"onLoadedMetadata()\" (ended)=\"onEnded()\"></video>\n@if (state?.kind==='error') {\n<div class=\"ngxsp-overlay\" role=\"alert\">\n <div class=\"ngxsp-overlay-card\">\n <div class=\"ngxsp-overlay-title\">Playback error</div>\n <div class=\"ngxsp-overlay-msg\">\n <div style=\"font-weight:600; margin-bottom:6px;\">{{errorTitle()}}</div>\n <div style=\"opacity:.85; font-size: 13px; line-height: 1.3;\">{{errorHint()}}</div>\n <div style=\"margin-top:10px; display:flex; gap:8px; flex-wrap:wrap;\">\n\t <button type=\"button\" class=\"ngxsp-btn\" (click)=\"reload()\">Retry</button>\n @if (autoplayBlocked) {\n\t <button type=\"button\" class=\"ngxsp-btn\" (click)=\"tryPlay()\">Play</button>\n }\n </div>\n </div>\n </div>\n</div>\n}\n\n@if (debug) {\n<details class=\"ngxsp-debug\" (click)=\"$event.stopPropagation()\">\n <summary>Debug</summary>\n\t <div style=\"display:flex; gap:8px; margin:8px 0; flex-wrap:wrap;\">\n\t <button type=\"button\" class=\"ngxsp-btn\" (click)=\"copyDebug()\">Copy JSON</button>\n\t <button type=\"button\" class=\"ngxsp-btn\" (click)=\"downloadDebug()\">Download</button>\n\t </div>\n <pre>{{debugJson}}</pre>\n</details>\n}\n\n @if (uiSkin==='netflix') {\n <div class=\"ngxsp-nfx-top\">\n <div class=\"ngxsp-nfx-titleWrap\">\n <div class=\"ngxsp-nfx-eyebrow\">Now Playing</div>\n <div class=\"ngxsp-nfx-title\">{{displayTitle}}</div>\n </div>\n <div class=\"ngxsp-nfx-spacer\"></div>\n <div class=\"ngxsp-nfx-status\">{{ statusLabel() }}</div>\n <div class=\"ngxsp-nfx-topHint\">Double-click for fullscreen</div>\n </div>\n\n <div class=\"ngxsp-nfx-centerDock\">\n @if (hasPlaylistControls) {\n <button type=\"button\" class=\"ngxsp-nfx-side\" (click)=\"emitPrev()\" [disabled]=\"!canPrev\" aria-label=\"Previous item\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M9.53 12 18 18.47v-12L9.53 12Zm-1.53 6.25a.75.75 0 0 0 1.25-.56V6.31a.75.75 0 0 0-1.25-.56L1.06 11.44a.75.75 0 0 0 0 1.12L8 18.25Z\"/></svg>\n </button>\n }\n <button type=\"button\" class=\"ngxsp-nfx-side ngxsp-nfx-side-wide\" (click)=\"seekRel(-10)\" aria-label=\"Seek backward 10 seconds\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M9 5H5m0 0v4m0-4 4.5 4.5A7 7 0 1 1 5 12\"/></svg>\n <span class=\"ngxsp-iconBadge\">10</span>\n </button>\n <button type=\"button\" class=\"ngxsp-nfx-center\" (click)=\"togglePlay()\" aria-label=\"Play/Pause\">\n @if (state?.kind==='playing') {\n <svg class=\"ngxsp-icon ngxsp-icon-lg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M7.5 5.25A1.25 1.25 0 0 1 8.75 6.5v11A1.25 1.25 0 0 1 6.25 17.5v-11A1.25 1.25 0 0 1 7.5 5.25Zm8 0a1.25 1.25 0 0 1 1.25 1.25v11a1.25 1.25 0 1 1-2.5 0v-11A1.25 1.25 0 0 1 15.5 5.25Z\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon ngxsp-icon-lg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8.25 6.82c0-1.3 1.43-2.1 2.54-1.43l8.12 4.93a1.96 1.96 0 0 1 0 3.36l-8.12 4.93a1.67 1.67 0 0 1-2.54-1.43V6.82Z\"/></svg>\n }\n </button>\n <button type=\"button\" class=\"ngxsp-nfx-side ngxsp-nfx-side-wide\" (click)=\"seekRel(10)\" aria-label=\"Seek forward 10 seconds\">\n <span class=\"ngxsp-iconBadge\">10</span>\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M15 5h4m0 0v4m0-4-4.5 4.5A7 7 0 1 0 19 12\"/></svg>\n </button>\n @if (hasPlaylistControls) {\n <button type=\"button\" class=\"ngxsp-nfx-side\" (click)=\"emitNext()\" [disabled]=\"!canNext\" aria-label=\"Next item\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M14.47 12 6 5.53v12L14.47 12ZM16 5.75a.75.75 0 0 0-1.25.56v11.38a.75.75 0 0 0 1.25.56l6.94-5.69a.75.75 0 0 0 0-1.12L16 5.75Z\"/></svg>\n </button>\n }\n </div>\n\n <div class=\"ngxsp-controls ngxsp-nfx-bottom\">\n <div class=\"ngxsp-nfx-metaRow\">\n <div class=\"ngxsp-nfx-time\">{{fmtTime(currentTime)}} / {{fmtTime(duration)}}</div>\n <div class=\"ngxsp-nfx-volumeGroup\">\n <button type=\"button\" class=\"ngxsp-nfx-chip ngxsp-nfx-chip-quiet\" (click)=\"toggleMute()\" [attr.title]=\"volumeLabel()\" [attr.aria-label]=\"volumeLabel()\">\n @if (volume <= 0.001) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm3.5 5.5 5 5m0-5-5 5\"/></svg>\n } @else if (volume < 0.5) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm4.5 4.75a3.5 3.5 0 0 1 0 4.95\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm4.5 4.75a3.5 3.5 0 0 1 0 4.95m2.75-7.7a7.5 7.5 0 0 1 0 10.45\"/></svg>\n }\n </button>\n <input class=\"ngxsp-range ngxsp-nfx-volume\" type=\"range\"\n min=\"0\" max=\"1\" step=\"0.01\"\n [value]=\"volume\"\n (input)=\"onVolume(($any($event.target).value))\"\n aria-label=\"Volume\"\n />\n </div>\n <div class=\"ngxsp-nfx-spacer\"></div>\n @if (hasPlaylistControls) {\n <button type=\"button\" class=\"ngxsp-nfx-chip\" [class.accent]=\"shuffleActive\" (click)=\"toggleShuffle.emit()\" [attr.title]=\"shuffleLabel\" [attr.aria-label]=\"shuffleLabel\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 6h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m20 6-4.5 4.5\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 7h3.2c1 0 1.95.4 2.66 1.1l6.28 6.3A3.75 3.75 0 0 0 18.82 15H20\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 15h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m20 18-4.56-4.56\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 17h3.2c1 0 1.95-.4 2.66-1.1l1.54-1.54\"/></svg>\n </button>\n <button type=\"button\" class=\"ngxsp-nfx-chip\" [class.accent]=\"repeatMode !== 'off'\" (click)=\"cycleRepeat.emit()\" [attr.title]=\"repeatLabel\" [attr.aria-label]=\"repeatLabel\">\n @if (repeatMode === 'one') {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 4h3v3\"/>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M20 7l-2.8-2.8A4 4 0 0 0 14.37 3H8a4 4 0 0 0-4 4v1\"/>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M7 20H4v-3\"/>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m4 17 2.8 2.8A4 4 0 0 0 9.63 21H16a4 4 0 0 0 4-4v-1\"/>\n <text x=\"16.8\" y=\"17.6\" fill=\"currentColor\" stroke=\"none\" font-size=\"7.5\" font-weight=\"700\" text-anchor=\"middle\">1</text>\n </svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 4h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M20 7l-2.8-2.8A4 4 0 0 0 14.37 3H8a4 4 0 0 0-4 4v1\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M7 20H4v-3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m4 17 2.8 2.8A4 4 0 0 0 9.63 21H16a4 4 0 0 0 4-4v-1\"/></svg>\n }\n </button>\n }\n <button type=\"button\" class=\"ngxsp-nfx-chip\" (click)=\"toggleMenu('tracks')\" [attr.title]=\"tracksButtonLabel()\" [attr.aria-label]=\"tracksButtonLabel()\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 6.75h16M4 12h16M4 17.25h16\"/></svg>\n </button>\n <button type=\"button\" class=\"ngxsp-nfx-chip\" (click)=\"subtitles.emit()\" [attr.title]=\"captionsLabel()\" [attr.aria-label]=\"captionsLabel()\">\n @if (selectedTextTrackId !== null) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8 11.25h2.5m2 0H14m2 0h.5M8 14.75h3.5m2 0H16\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8 11.25h2.5m2 0H14m2 0h.5M8 14.75h3.5m2 0H16\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M6 6l12 12\"/></svg>\n }\n </button>\n <button type=\"button\" class=\"ngxsp-nfx-chip\" (click)=\"toggleMenu('speed')\" [attr.title]=\"playbackRateLabel()\" [attr.aria-label]=\"playbackRateLabel()\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5.25 5.82c0-1.3 1.43-2.1 2.54-1.43l5.71 3.47a1.96 1.96 0 0 1 0 3.36L7.79 14.7a1.67 1.67 0 0 1-2.54-1.43V5.82Zm8.5 0c0-1.3 1.43-2.1 2.54-1.43L22 7.86a1.96 1.96 0 0 1 0 3.36l-5.71 3.47a1.67 1.67 0 0 1-2.54-1.43V5.82Z\"/></svg>\n </button>\n @if (isPiPSupported()) {\n <button type=\"button\" class=\"ngxsp-nfx-chip\" (click)=\"togglePiP()\" [attr.title]=\"pipLabel()\" [attr.aria-label]=\"pipLabel()\">\n @if (isPiPActive()) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><rect x=\"12.25\" y=\"11.25\" width=\"5.25\" height=\"4.5\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><rect x=\"12.25\" y=\"11.25\" width=\"5.25\" height=\"4.5\" rx=\"1\" stroke-width=\"1.8\"/></svg>\n }\n </button>\n }\n </div>\n\n <input class=\"ngxsp-range ngxsp-nfx-range\" type=\"range\"\n min=\"0\" [max]=\"duration || 0\" step=\"0.1\"\n [value]=\"currentTime\"\n (input)=\"onScrub(($any($event.target).value))\"\n aria-label=\"Seek\"\n />\n\n <div class=\"ngxsp-nfx-metaRow\">\n <div class=\"ngxsp-nfx-spacer\"></div>\n <div class=\"ngxsp-nfx-label\">{{ keyboardHintLabel() }}</div>\n </div>\n\n <div class=\"ngxsp-buffer\" aria-hidden=\"true\">\n <div class=\"ngxsp-bufferFill\" [style.width.%]=\"bufferPercent()\"></div>\n </div>\n\n @if (openMenu === 'tracks') {\n <div class=\"ngxsp-menu\" (click)=\"$event.stopPropagation()\">\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">Captions</div>\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedTextTrackId === null\" (click)=\"selectTextTrack(null)\">Off</button>\n @for (track of textTracks; track track.id) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedTextTrackId === track.id\" (click)=\"selectTextTrack(track.id)\">\n {{ trackLabel(track) }}\n </button>\n }\n </div>\n\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">Audio</div>\n @if (audioTracks.length) {\n @for (track of audioTracks; track track.id) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedAudioTrackId === track.id\" (click)=\"selectAudioTrack(track.id)\">\n {{ trackLabel(track) }}\n </button>\n }\n } @else {\n <div class=\"ngxsp-menuHint\">Single audio track</div>\n }\n </div>\n\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">Quality</div>\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedVideoTrackId === null\" (click)=\"selectVideoTrack(null)\">Auto</button>\n @if (videoTracks.length) {\n @for (track of videoTracks; track track.id) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedVideoTrackId === track.id\" (click)=\"selectVideoTrack(track.id)\">\n {{ qualityLabel(track) }}\n </button>\n }\n } @else {\n <div class=\"ngxsp-menuHint\">Single quality</div>\n }\n </div>\n </div>\n }\n\n @if (openMenu === 'speed') {\n <div class=\"ngxsp-menu ngxsp-menuCompact\" (click)=\"$event.stopPropagation()\">\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">Playback speed</div>\n @for (rate of playbackRates; track rate) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"playbackRate === rate\" (click)=\"setPlaybackRate(rate)\">\n {{ rate }}x\n </button>\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <div class=\"ngxsp-controls\">\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"togglePlay()\" aria-label=\"Play/Pause\" title=\"Play/Pause\">\n @if (state?.kind==='playing') {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M7.5 5.25A1.25 1.25 0 0 1 8.75 6.5v11A1.25 1.25 0 0 1 6.25 17.5v-11A1.25 1.25 0 0 1 7.5 5.25Zm8 0a1.25 1.25 0 0 1 1.25 1.25v11a1.25 1.25 0 1 1-2.5 0v-11A1.25 1.25 0 0 1 15.5 5.25Z\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8.25 6.82c0-1.3 1.43-2.1 2.54-1.43l8.12 4.93a1.96 1.96 0 0 1 0 3.36l-8.12 4.93a1.67 1.67 0 0 1-2.54-1.43V6.82Z\"/></svg>\n }\n </button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"seekRel(-10)\" aria-label=\"Seek backward 10 seconds\" title=\"Seek backward 10 seconds\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M9 5H5m0 0v4m0-4 4.5 4.5A7 7 0 1 1 5 12\"/></svg>\n <span class=\"ngxsp-iconBadge\">10</span>\n </button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"seekRel(10)\" aria-label=\"Seek forward 10 seconds\" title=\"Seek forward 10 seconds\">\n <span class=\"ngxsp-iconBadge\">10</span>\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M15 5h4m0 0v4m0-4-4.5 4.5A7 7 0 1 0 19 12\"/></svg>\n </button>\n @if (hasPlaylistControls) {\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"emitPrev()\" [disabled]=\"!canPrev\" aria-label=\"Previous item\" title=\"Previous item\"><svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M9.53 12 18 18.47v-12L9.53 12Zm-1.53 6.25a.75.75 0 0 0 1.25-.56V6.31a.75.75 0 0 0-1.25-.56L1.06 11.44a.75.75 0 0 0 0 1.12L8 18.25Z\"/></svg></button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"emitNext()\" [disabled]=\"!canNext\" aria-label=\"Next item\" title=\"Next item\"><svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M14.47 12 6 5.53v12L14.47 12ZM16 5.75a.75.75 0 0 0-1.25.56v11.38a.75.75 0 0 0 1.25.56l6.94-5.69a.75.75 0 0 0 0-1.12L16 5.75Z\"/></svg></button>\n <button type=\"button\" class=\"ngxsp-btn\" [class.accent]=\"shuffleActive\" (click)=\"toggleShuffle.emit()\" [attr.title]=\"shuffleLabel\" [attr.aria-label]=\"shuffleLabel\">\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 6h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m20 6-4.5 4.5\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 7h3.2c1 0 1.95.4 2.66 1.1l6.28 6.3A3.75 3.75 0 0 0 18.82 15H20\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 15h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m20 18-4.56-4.56\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 17h3.2c1 0 1.95-.4 2.66-1.1l1.54-1.54\"/></svg>\n </button>\n <button type=\"button\" class=\"ngxsp-btn\" [class.accent]=\"repeatMode !== 'off'\" (click)=\"cycleRepeat.emit()\" [attr.title]=\"repeatLabel\" [attr.aria-label]=\"repeatLabel\">\n @if (repeatMode === 'one') {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 4h3v3\"/>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M20 7l-2.8-2.8A4 4 0 0 0 14.37 3H8a4 4 0 0 0-4 4v1\"/>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M7 20H4v-3\"/>\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m4 17 2.8 2.8A4 4 0 0 0 9.63 21H16a4 4 0 0 0 4-4v-1\"/>\n <text x=\"16.8\" y=\"17.6\" fill=\"currentColor\" stroke=\"none\" font-size=\"7.5\" font-weight=\"700\" text-anchor=\"middle\">1</text>\n </svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 4h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M20 7l-2.8-2.8A4 4 0 0 0 14.37 3H8a4 4 0 0 0-4 4v1\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M7 20H4v-3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m4 17 2.8 2.8A4 4 0 0 0 9.63 21H16a4 4 0 0 0 4-4v-1\"/></svg>\n }\n </button>\n }\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"toggleMenu('tracks')\" [attr.title]=\"tracksButtonLabel()\" [attr.aria-label]=\"tracksButtonLabel()\"><svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 6.75h16M4 12h16M4 17.25h16\"/></svg></button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"subtitles.emit()\" [attr.title]=\"captionsLabel()\" [attr.aria-label]=\"captionsLabel()\">\n @if (selectedTextTrackId !== null) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8 11.25h2.5m2 0H14m2 0h.5M8 14.75h3.5m2 0H16\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8 11.25h2.5m2 0H14m2 0h.5M8 14.75h3.5m2 0H16\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M6 6l12 12\"/></svg>\n }\n </button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"toggleMenu('speed')\" [attr.title]=\"playbackRateLabel()\" [attr.aria-label]=\"playbackRateLabel()\"><svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5.25 5.82c0-1.3 1.43-2.1 2.54-1.43l5.71 3.47a1.96 1.96 0 0 1 0 3.36L7.79 14.7a1.67 1.67 0 0 1-2.54-1.43V5.82Zm8.5 0c0-1.3 1.43-2.1 2.54-1.43L22 7.86a1.96 1.96 0 0 1 0 3.36l-5.71 3.47a1.67 1.67 0 0 1-2.54-1.43V5.82Z\"/></svg></button>\n @if (isPiPSupported()) {\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"togglePiP()\" [attr.title]=\"pipLabel()\" [attr.aria-label]=\"pipLabel()\">\n @if (isPiPActive()) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><rect x=\"12.25\" y=\"11.25\" width=\"5.25\" height=\"4.5\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><rect x=\"12.25\" y=\"11.25\" width=\"5.25\" height=\"4.5\" rx=\"1\" stroke-width=\"1.8\"/></svg>\n }\n </button>\n }\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"toggleMute()\" [attr.title]=\"volumeLabel()\" [attr.aria-label]=\"volumeLabel()\">\n @if (volume <= 0.001) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm3.5 5.5 5 5m0-5-5 5\"/></svg>\n } @else if (volume < 0.5) {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm4.5 4.75a3.5 3.5 0 0 1 0 4.95\"/></svg>\n } @else {\n <svg class=\"ngxsp-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm4.5 4.75a3.5 3.5 0 0 1 0 4.95m2.75-7.7a7.5 7.5 0 0 1 0 10.45\"/></svg>\n }\n </button>\n\n <input class=\"ngxsp-range\" type=\"range\"\n min=\"0\" [max]=\"duration || 0\" step=\"0.1\"\n [value]=\"currentTime\"\n (input)=\"onScrub(($any($event.target).value))\"\n />\n\n <div class=\"ngxsp-time\">{{fmtTime(currentTime)}} / {{fmtTime(duration)}}</div>\n\n <input class=\"ngxsp-range\" style=\"max-width:140px\" type=\"range\"\n min=\"0\" max=\"1\" step=\"0.01\"\n [value]=\"volume\"\n (input)=\"onVolume(($any($event.target).value))\"\n aria-label=\"Volume\"\n />\n </div>\n }\n\n </div>\n </div>\n `,\n styles: [`\n .ngxsp-root{position:relative;width:100%;height:100%;background:#000;color:#fff;font-family:system-ui,sans-serif;}\n .ngxsp-video{position:relative;width:100%;height:100%;isolation:isolate}\n .ngxsp-video video{width:100%;height:100%;display:block;background:#000;object-fit:contain;}\n .ngxsp-controls{display:flex;gap:8px;align-items:center;padding:10px;flex-wrap:wrap}\n .ngxsp-btn{background:rgba(255,255,255,.12);border:1px solid rgba(255,255,255,.2);color:#fff;border-radius:10px;padding:8px 10px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px}\n .ngxsp-btn.accent{background:rgba(86,63,27,.5);border-color:rgba(232,190,118,.24);color:#f3d59c}\n .ngxsp-icon{width:18px;height:18px;display:block;flex:0 0 auto}\n .ngxsp-icon-lg{width:32px;height:32px}\n .ngxsp-iconBadge{font-size:11px;font-weight:800;line-height:1}\n .ngxsp-range{flex:1;min-width:160px}\n .ngxsp-time{opacity:.85;font-variant-numeric:tabular-nums}\n .ngxsp-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;background:rgba(0,0,0,.7);padding:20px;text-align:center}\n .ngxsp-debug{position:absolute; top:12px; right:12px; z-index:6; margin:0; max-width:min(420px, calc(100% - 24px)); opacity:0; transform:translateY(-6px); transition:opacity .18s ease, transform .18s ease}\n .ngxsp-root.ngxsp-ui-visible .ngxsp-debug,\n .ngxsp-debug[open]{opacity:1; transform:translateY(0)}\n .ngxsp-debug summary{cursor:pointer; list-style:none; background:rgba(10,10,10,.82); border:1px solid rgba(255,255,255,.16); border-radius:999px; padding:8px 12px; width:max-content; margin-left:auto;}\n .ngxsp-debug[open]{background:rgba(10,10,10,.92); border:1px solid rgba(255,255,255,.16); border-radius:16px; padding:12px; max-height:calc(100% - 24px); overflow:auto;}\n .ngxsp-overlay-title{font-size:18px;font-weight:600}\n .ngxsp-overlay-msg{opacity:.9;max-width:720px}\n\n /* Netflix skin */\n .ngxsp-skin-netflix .ngxsp-video{position:relative}\n .ngxsp-skin-netflix .ngxsp-video::before{content:''; position:absolute; inset:0; background:radial-gradient(circle at center, rgba(0,0,0,0) 32%, rgba(0,0,0,.22) 100%); opacity:.85; pointer-events:none; z-index:0}\n .ngxsp-skin-netflix .ngxsp-video::after{content:''; position:absolute; inset:auto 0 0 0; height:180px; background:linear-gradient(to top, rgba(0,0,0,.9), rgba(0,0,0,.48) 38%, rgba(0,0,0,0)); opacity:0; transition:opacity .18s ease; pointer-events:none}\n .ngxsp-skin-netflix.ngxsp-ui-visible .ngxsp-video::after{opacity:1}\n .ngxsp-nfx-top{position:absolute;left:0;right:0;top:0;display:flex;align-items:flex-start;gap:12px;padding:18px 18px 22px;background:linear-gradient(to bottom, rgba(0,0,0,.78), rgba(0,0,0,0));pointer-events:none; opacity:0; transition:opacity .18s ease; z-index:3}\n .ngxsp-root.ngxsp-ui-visible .ngxsp-nfx-top{opacity:1}\n .ngxsp-nfx-titleWrap{display:flex; flex-direction:column; gap:3px}\n .ngxsp-nfx-eyebrow{font-size:11px; text-transform:uppercase; letter-spacing:.16em; opacity:.62}\n .ngxsp-nfx-title{font-weight:700;letter-spacing:.01em;opacity:.98;pointer-events:none;text-shadow:0 1px 2px rgba(0,0,0,.6); font-size:18px}\n .ngxsp-nfx-topHint{font-size:12px; opacity:.6; padding-top:4px}\n .ngxsp-nfx-status{font-size:11px; text-transform:uppercase; letter-spacing:.12em; padding:7px 10px; border-radius:999px; border:1px solid rgba(255,255,255,.12); background:rgba(255,255,255,.06); opacity:.78}\n .ngxsp-nfx-spacer{flex:1}\n .ngxsp-nfx-centerDock{position:absolute; inset:0; margin:auto; width:max-content; height:max-content; display:flex; align-items:center; gap:14px; z-index:4; opacity:0; transform:translateY(10px) scale(.98); transition:opacity .18s ease, transform .18s ease}\n .ngxsp-root.ngxsp-ui-visible .ngxsp-nfx-centerDock{opacity:1; transform:translateY(0) scale(1)}\n .ngxsp-nfx-center{height:96px;width:96px;border-radius:999px;border:1px solid rgba(255,255,255,.26);background:rgba(248,248,248,.12);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer; backdrop-filter:blur(16px); box-shadow:0 20px 60px rgba(0,0,0,.35)}\n .ngxsp-nfx-side{height:58px; min-width:58px; border-radius:999px; border:1px solid rgba(255,255,255,.18); background:rgba(8,8,8,.42); color:#fff; padding:0 18px; cursor:pointer; backdrop-filter:blur(10px); font-weight:700; font-size:14px; display:inline-flex; align-items:center; justify-content:center; gap:8px}\n .ngxsp-nfx-side-wide{min-width:78px}\n .ngxsp-nfx-bottom{position:absolute;left:14px;right:14px;bottom:14px;padding:12px 14px 14px;background:linear-gradient(to top, rgba(7,7,7,.92), rgba(7,7,7,.7));border:1px solid rgba(255,255,255,.1);border-radius:20px;gap:10px;flex-direction:column;align-items:stretch;backdrop-filter:blur(20px);z-index:4;opacity:0;transform:translateY(12px);transition:opacity .18s ease, transform .18s ease;box-shadow:0 16px 50px rgba(0,0,0,.32)}\n .ngxsp-root.ngxsp-ui-visible .ngxsp-nfx-bottom{opacity:1; transform:translateY(0)}\n .ngxsp-nfx-metaRow{display:flex; align-items:center; gap:10px; width:100%}\n .ngxsp-nfx-time{opacity:.92;font-variant-numeric:tabular-nums;font-size:12px; font-weight:600}\n .ngxsp-nfx-range{min-width:100%}\n .ngxsp-nfx-volumeGroup{display:inline-flex;align-items:center;gap:8px}\n .ngxsp-nfx-volume{max-width:0;min-width:0;opacity:0;transform:scaleX(.72);transform-origin:left center;pointer-events:none;transition:opacity .18s ease, transform .18s ease, max-width .18s ease}\n .ngxsp-nfx-volumeGroup:hover .ngxsp-nfx-volume,\n .ngxsp-nfx-volumeGroup:focus-within .ngxsp-nfx-volume{max-width:160px;min-width:96px;opacity:1;transform:scaleX(1);pointer-events:auto}\n .ngxsp-nfx-label{font-size:12px; opacity:.72}\n .ngxsp-nfx-chip{background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.16); color:#fff; border-radius:999px; padding:8px 12px; cursor:pointer; font-size:12px; font-weight:700; display:inline-flex; align-items:center; justify-content:center; gap:8px}\n .ngxsp-nfx-chip.accent{background:rgba(86,63,27,.5); border-color:rgba(232,190,118,.24); color:#f3d59c}\n .ngxsp-nfx-chip-quiet{background:rgba(255,255,255,.05)}\n .ngxsp-nfx-center:hover,\n .ngxsp-nfx-side:hover,\n .ngxsp-nfx-chip:hover{border-color:rgba(255,255,255,.3); background:rgba(24,24,24,.62)}\n .ngxsp-nfx-center:disabled,\n .ngxsp-nfx-side:disabled{opacity:.38; cursor:not-allowed}\n .ngxsp-range{appearance:none; height:4px; border-radius:999px; background:linear-gradient(to right, rgba(255,255,255,.95), rgba(255,255,255,.28)); outline:none}\n .ngxsp-range::-webkit-slider-thumb{appearance:none; width:14px; height:14px; border-radius:50%; background:#fff; box-shadow:0 0 0 3px rgba(255,255,255,.16)}\n .ngxsp-range::-moz-range-thumb{width:14px; height:14px; border:none; border-radius:50%; background:#fff; box-shadow:0 0 0 3px rgba(255,255,255,.16)}\n .ngxsp-range::-moz-range-track{height:4px; border:none; border-radius:999px; background:rgba(255,255,255,.22)}\n .ngxsp-buffer{height:4px; border-radius:999px; background:rgba(255,255,255,.08); overflow:hidden}\n .ngxsp-bufferFill{height:100%; border-radius:999px; background:linear-gradient(to right, rgba(245,245,245,.28), rgba(245,245,245,.82))}\n .ngxsp-menu{display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:14px; padding-top:6px}\n .ngxsp-menuCompact{grid-template-columns:minmax(180px, 240px)}\n .ngxsp-menuSection{display:flex; flex-direction:column; gap:6px}\n .ngxsp-menuTitle{font-size:11px; text-transform:uppercase; letter-spacing:.14em; opacity:.58}\n .ngxsp-menuItem{background:rgba(255,255,255,.05); border:1px solid rgba(255,255,255,.1); color:#fff; border-radius:12px; padding:9px 11px; text-align:left; cursor:pointer; font-size:12px}\n .ngxsp-menuItem.active{border-color:rgba(232,190,118,.28); background:rgba(86,63,27,.38); color:#f3d59c}\n .ngxsp-menuHint{font-size:12px; opacity:.62; padding:8px 2px}\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SmartPlayerComponent implements OnInit, OnDestroy {\n @Input({ required: true }) config!: PlayerConfig;\n @Input() plugins: PlayerPlugin[] = [];\n @Input() ports?: Partial<PlayerPorts>;\n @Input() engines?: EngineFactory[];\n @Input() debug = false;\n /** Optional start time (seconds) used for \"resume playback\". */\n @Input() startTimeSec: number | null = null;\n @Input() canPrev = false;\n @Input() canNext = false;\n @Input() shuffleActive = false;\n @Input() shuffleLabel = 'Shuffle: off';\n @Input() repeatMode: 'off' | 'one' | 'all' = 'off';\n @Input() repeatLabel = 'Repeat: off';\n @Input() hasPlaylistControls = false;\n\n @Output() ended = new EventEmitter<void>();\n @Output() videoSize = new EventEmitter<{ width: number; height: number }>();\n /** Emits playback position updates. */\n @Output() progress = new EventEmitter<{ currentTime: number; duration: number }>();\n @Output() prev = new EventEmitter<void>();\n @Output() next = new EventEmitter<void>();\n @Output() toggleShuffle = new EventEmitter<void>();\n @Output() cycleRepeat = new EventEmitter<void>();\n @Output() subtitles = new EventEmitter<void>();\n\n @ViewChild('video', { static: true }) videoEl!: ElementRef<HTMLVideoElement>;\n\n state: PlayerState | null = null;\n\n duration = 0;\n currentTime = 0;\n volume = 1;\n private lastVolumeBeforeMute = 1;\n playbackRate = 1;\n bufferAheadSec = 0;\n tracks: MediaTrack[] = [];\n openMenu: 'tracks' | 'speed' | null = null;\n controlsVisible = true;\n\n readonly playbackRates = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n\n private facade = new PlayerFacade();\n private sub = new Subscription();\n private hideControlsTimer: ReturnType<typeof setTimeout> | null = null;\n\n get uiSkin(): 'classic' | 'netflix' {\n return (((this.config as any)?.ui?.skin as any) ?? 'classic') === 'netflix' ? 'netflix' : 'classic';\n }\n\n get uiVisible(): boolean {\n const kind = this.state?.kind;\n return this.controlsVisible || this.openMenu !== null || kind === 'paused' || kind === 'loading' || kind === 'buffering' || kind === 'error';\n }\n\n get displayTitle(): string {\n const ui: any = (this.config as any)?.ui;\n const src: any = (this.config as any)?.source;\n return (\n ui?.title ??\n ui?.displayTitle ??\n src?.title ??\n src?.contentId ??\n 'Player'\n );\n }\n\n get audioTracks(): MediaTrack[] {\n return this.tracks.filter((track) => track.kind === 'audio');\n }\n\n get textTracks(): MediaTrack[] {\n return this.tracks.filter((track) => track.kind === 'text');\n }\n\n get videoTracks(): MediaTrack[] {\n return this.tracks.filter((track) => track.kind === 'video');\n }\n\n get selectedAudioTrackId(): string | null {\n return this.audioTracks.find((track) => track.active)?.id ?? null;\n }\n\n get selectedTextTrackId(): string | null {\n return this.textTracks.find((track) => track.active)?.id ?? null;\n }\n\n get selectedVideoTrackId(): string | null {\n return this.videoTracks.find((track) => track.active)?.id ?? null;\n }\n\n ngOnInit(): void {\n const plugins: PlayerPlugin[] = [...(this.plugins ?? [])];\n\n // v1.11: SSAI (server-side stitched streams) – rewrite manifest URL if configured.\n if ((this.config as any)?.ads?.enabled && (this.config as any)?.ads?.mode === 'ssai') {\n plugins.push(createSsaiManifestRewritePlugin());\n }\n\n this.facade.attach(this.videoEl.nativeElement, plugins, this.config, this.ports, this.engines);\n\n this.sub.add(this.facade.state$.subscribe((s: PlayerState) => {\n this.state = s;\n this.syncControlVisibility();\n }));\n this.sub.add(this.facade.time$.subscribe((t: any) => {\n this.currentTime = t.currentTime;\n this.duration = t.duration;\n this.progress.emit({ currentTime: this.currentTime, duration: this.duration });\n }));\n this.sub.add(this.facade.bufferAheadSec$.subscribe((value) => {\n this.bufferAheadSec = value;\n }));\n this.sub.add(this.facade.tracks$.subscribe((tracks) => {\n this.tracks = tracks;\n }));\n\n this.facade.setVolume(this.volume);\n this.facade.load(this.config)\n .then(async () => {\n const start = Number(this.startTimeSec ?? 0);\n if (Number.isFinite(start) && start > 0.2) {\n try {\n const safe = Math.max(0, Math.min(start, (this.duration || start + 1) - 0.3));\n await this.facade.seekTo(safe);\n } catch { /* ignore */ }\n }\n await this.facade.play().catch(() => {});\n })\n .catch(() => {});\n }\n\n ngOnDestroy(): void {\n this.clearHideControlsTimer();\n this.sub.unsubscribe();\n this.facade.destroy();\n }\n\n tryPlay(): void {\n void this.facade.play().catch(() => {});\n }\n\n get debugJson(): string {\n try {\n const d = (this.facade as any).diagnostics?.() ?? {};\n const tel = this.ports?.telemetry?.export?.();\n return JSON.stringify({ ...d, telemetry: tel }, null, 2);\n } catch {\n return '{}';\n }\n }\n\n get autoplayBlocked(): boolean {\n const s: any = this.state as any;\n return s?.kind === 'error' && s?.error?.code === 'AUTOPLAY_BLOCKED';\n }\n\n async copyDebug(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.debugJson);\n } catch {\n // clipboard may be unavailable\n }\n }\n\n downloadDebug(): void {\n try {\n const blob = new Blob([this.debugJson], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'ngxsp-diagnostics.json';\n a.click();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n } catch {\n // ignore\n }\n }\n\n togglePlay(): void {\n if (this.state?.kind === 'playing') this.facade.pause();\n else this.facade.play();\n }\n\n seekRel(deltaSec: number): void {\n this.facade.seekTo(Math.max(0, this.currentTime + deltaSec));\n }\n\n onScrub(value: number): void {\n const v = Number(value);\n if (Number.isFinite(v)) this.facade.seekTo(v);\n }\n\n onVolume(value: number): void {\n const v = Math.max(0, Math.min(1, Number(value)));\n this.volume = Number.isFinite(v) ? v : this.volume;\n if (this.volume > 0) this.lastVolumeBeforeMute = this.volume;\n this.facade.setVolume(this.volume);\n }\n\n toggleMute(): void {\n if (this.volume <= 0.001) {\n this.volume = Math.max(0.5, this.lastVolumeBeforeMute || 0.5);\n } else {\n this.lastVolumeBeforeMute = this.volume;\n this.volume = 0;\n }\n this.facade.setVolume(this.volume);\n this.onInteraction();\n }\n\n async setPlaybackRate(rate: number): Promise<void> {\n this.playbackRate = rate;\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setRate(rate);\n }\n\n reload(): void {\n this.facade.reload().catch(() => void 0);\n }\n\n\n onLoadedMetadata(): void {\n const v = this.videoEl?.nativeElement;\n if (!v) return;\n const width = v.videoWidth || 0;\n const height = v.videoHeight || 0;\n if (width > 0 && height > 0) {\n this.videoSize.emit({ width, height });\n }\n }\n\n onEnded(): void {\n // facade already emits 'ended' based on engine events; this output lets host apps chain playlists.\n this.ended.emit();\n }\n\n toggleFullscreen(): void {\n const host = this.videoEl.nativeElement.parentElement;\n if (!host) return;\n\n const doc: any = document;\n const el: any = host;\n\n if (!doc.fullscreenElement && el.requestFullscreen) {\n el.requestFullscreen().catch(() => void 0);\n } else if (doc.exitFullscreen) {\n doc.exitFullscreen().catch(() => void 0);\n }\n }\n\n toggleMenu(menu: 'tracks' | 'speed'): void {\n this.openMenu = this.openMenu === menu ? null : menu;\n this.onInteraction(this.openMenu !== null);\n }\n\n async selectTextTrack(trackId: string | null): Promise<void> {\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setTextTrack(trackId);\n }\n\n async selectAudioTrack(trackId: string): Promise<void> {\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setAudioTrack(trackId);\n }\n\n async selectVideoTrack(trackId: string | null): Promise<void> {\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setVideoTrack(trackId);\n }\n\n async togglePiP(): Promise<void> {\n const video = this.videoEl.nativeElement as HTMLVideoElement & {\n requestPictureInPicture?: () => Promise<unknown>;\n disablePictureInPicture?: boolean;\n };\n const doc = document as Document & {\n pictureInPictureElement?: Element | null;\n pictureInPictureEnabled?: boolean;\n exitPictureInPicture?: () => Promise<void>;\n };\n\n try {\n if (doc.pictureInPictureElement) {\n await doc.exitPictureInPicture?.();\n } else {\n await video.requestPictureInPicture?.();\n }\n } catch {\n // Ignore unsupported or blocked PiP transitions.\n }\n this.onInteraction();\n }\n\n isPiPSupported(): boolean {\n const video = this.videoEl?.nativeElement as (HTMLVideoElement & { disablePictureInPicture?: boolean }) | undefined;\n const doc = document as Document & { pictureInPictureEnabled?: boolean };\n return !!doc.pictureInPictureEnabled && !video?.disablePictureInPicture;\n }\n\n pipLabel(): string {\n const doc = document as Document & { pictureInPictureElement?: Element | null };\n return doc.pictureInPictureElement ? 'Exit PiP' : 'PiP';\n }\n\n isPiPActive(): boolean {\n const doc = document as Document & { pictureInPictureElement?: Element | null };\n return !!doc.pictureInPictureElement;\n }\n\n captionsLabel(): string {\n return this.selectedTextTrackId !== null ? 'Captions on' : 'Load subtitles';\n }\n\n volumeLabel(): string {\n if (this.volume <= 0.001) return 'Muted';\n if (this.volume < 0.5) return 'Vol';\n return 'Volume';\n }\n\n volumeIcon(): string {\n if (this.volume <= 0.001) return '🔇';\n if (this.volume < 0.5) return '🔉';\n return '🔊';\n }\n\n playbackRateLabel(): string {\n return `${this.playbackRate}x`;\n }\n\n statusLabel(): string {\n const kind = this.state?.kind;\n if (kind === 'playing') return this.playbackRate === 1 ? 'Playing' : `Playing ${this.playbackRate}x`;\n if (kind === 'paused') return 'Paused';\n if (kind === 'buffering') return 'Buffering';\n if (kind === 'loading') return 'Loading';\n if (kind === 'ended') return 'Ended';\n if (kind === 'error') return 'Error';\n return 'Ready';\n }\n\n keyboardHintLabel(): string {\n return 'Space play • Arrows seek • F fullscreen';\n }\n\n tracksButtonLabel(): string {\n return this.textTracks.length || this.audioTracks.length ? 'Tracks' : 'Media';\n }\n\n trackLabel(track: MediaTrack): string {\n return track.label || track.language || track.id;\n }\n\n qualityLabel(track: MediaTrack): string {\n if (track.label) return track.label;\n const parts: string[] = [];\n if (track.height) parts.push(`${track.height}p`);\n if (track.bandwidth) parts.push(`${(track.bandwidth / 1_000_000).toFixed(1)} Mbps`);\n return parts.join(' • ') || track.id;\n }\n\n bufferPercent(): number {\n if (!this.duration || !Number.isFinite(this.duration) || this.duration <= 0) return 0;\n return Math.max(0, Math.min(100, (this.bufferAheadSec / this.duration) * 100));\n }\n\n fmtTime(sec: number): string {\n const s = Math.max(0, Math.floor(sec || 0));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const r = s % 60;\n if (h > 0) return `${h}:${String(m).padStart(2,'0')}:${String(r).padStart(2,'0')}`;\n return `${m}:${String(r).padStart(2,'0')}`;\n }\n\n noop(): void {}\n onInteraction(persist = false): void {\n this.controlsVisible = true;\n this.clearHideControlsTimer();\n if (!persist && this.state?.kind === 'playing' && this.openMenu === null) {\n this.hideControlsTimer = setTimeout(() => {\n this.controlsVisible = false;\n }, 2200);\n }\n }\n\n onPointerLeave(): void {\n if (this.state?.kind === 'playing' && this.openMenu === null) {\n this.clearHideControlsTimer();\n this.controlsVisible = false;\n }\n }\n\n onRootClick(event: MouseEvent): void {\n const target = event.target as HTMLElement | null;\n if (!target) return;\n if (target.closest('.ngxsp-menu, .ngxsp-nfx-chip, .ngxsp-btn, .ngxsp-debug, .ngxsp-nfx-side, .ngxsp-nfx-center, .ngxsp-range')) {\n return;\n }\n this.openMenu = null;\n this.onInteraction();\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.openMenu !== null) {\n this.openMenu = null;\n this.onInteraction();\n }\n }\n\n @HostListener('document:keydown', ['$event'])\n onKeydown(event: KeyboardEvent): void {\n if (this.isInteractiveTarget(event.target)) return;\n\n if (event.code === 'Space') {\n event.preventDefault();\n this.togglePlay();\n this.onInteraction();\n return;\n }\n if (event.code === 'ArrowLeft') {\n event.preventDefault();\n this.seekRel(-10);\n this.onInteraction();\n return;\n }\n if (event.code === 'ArrowRight') {\n event.preventDefault();\n this.seekRel(10);\n this.onInteraction();\n return;\n }\n if (event.code === 'KeyF') {\n event.preventDefault();\n this.toggleFullscreen();\n this.onInteraction();\n return;\n }\n if (event.code === 'KeyM') {\n event.preventDefault();\n this.toggleMute();\n }\n }\n\n private syncControlVisibility(): void {\n if (this.state?.kind === 'playing' && this.openMenu === null) {\n this.onInteraction();\n return;\n }\n this.clearHideControlsTimer();\n this.controlsVisible = true;\n }\n\n private clearHideControlsTimer(): void {\n if (this.hideControlsTimer) {\n clearTimeout(this.hideControlsTimer);\n this.hideControlsTimer = null;\n }\n }\n\n private isInteractiveTarget(target: EventTarget | null): boolean {\n const el = target as HTMLElement | null;\n if (!el) return false;\n return !!el.closest('input, button, textarea, select, summary, [contenteditable=\"true\"]');\n }\n\nerrorTitle(): string {\n const s: any = this.state as any;\n const code: string = s?.error?.code ?? s?.error?.name ?? 'UNKNOWN';\n if (code === 'ENGINE_MISSING') return 'Playback engine missing';\n if (code === 'AUTOPLAY_BLOCKED') return 'Click to start playback';\n if (code === 'NETWORK_HTTP') return 'Network error';\n if (code === 'DECODE_ERROR') return 'Decode error';\n if (code === 'SRC_NOT_SUPPORTED') return 'Format not supported';\n return 'Playback error';\n}\n\nerrorHint(): string {\n const s: any = this.state as any;\n const code: string = s?.error?.code ?? s?.error?.name ?? 'UNKNOWN';\n if (code === 'ENGINE_MISSING') {\n return 'This source requires an additional engine. Install @ngxsp/engine-shaka and pass it via [engines].';\n }\n if (code === 'AUTOPLAY_BLOCKED') return 'Your browser blocked autoplay. Press Play to start.';\n if (code === 'NETWORK_HTTP') return 'Check your connection or try again.';\n return s?.error?.message ? String(s.error.message) : 'Unknown error';\n}\n\nasync onRetry(): Promise<void> {\n try { await this.facade.reload(); } catch {}\n}\n\nasync onUserPlay(): Promise<void> {\n try { await this.facade.play(); } catch {}\n}\n\n\nemitNext(): void {\n this.next.emit();\n}\n\nemitPrev(): void {\n this.prev.emit();\n}\n\n}\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { SubtitleProvider } from '@ngxsp/core';\nimport { MetadataProvider } from '@ngxsp/core';\n\nexport interface SmartPlayerProvidersConfig {\n subtitleProviders?: SubtitleProvider[];\n metadataProviders?: MetadataProvider[];\n}\n\n/**\n * Register provider implementations for subtitles/metadata.\n * You can call this in your app `bootstrapApplication()` providers array.\n */\nexport function provideSmartPlayer(cfg: SmartPlayerProvidersConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: 'SMART_PLAYER_SUBTITLE_PROVIDERS', useValue: cfg.subtitleProviders ?? [] },\n { provide: 'SMART_PLAYER_METADATA_PROVIDERS', useValue: cfg.metadataProviders ?? [] }\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngxsplayer-ngx-smart-player.mjs","sources":["../../../projects/ngx-smart-player/src/lib/smart-player-icon.component.ts","../../../projects/ngx-smart-player/src/lib/smart-settings.component.ts","../../../projects/ngx-smart-player/src/lib/smart-confirm-dialog.component.ts","../../../projects/ngx-smart-player/src/lib/player-menu.component.ts","../../../projects/ngx-smart-player/src/lib/player-overlays.component.ts","../../../projects/ngx-smart-player/src/lib/player-controls.component.ts","../../../projects/ngx-smart-player/src/lib/player-controls-vod.component.ts","../../../projects/ngx-smart-player/src/lib/player-controls-edition.component.ts","../../../projects/ngx-smart-player/src/lib/smart-player.component.ts","../../../projects/ngx-smart-player/src/lib/smart-player.providers.ts","../../../projects/ngx-smart-player/src/ngxsplayer-ngx-smart-player.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, Input } from '@angular/core';\n\nexport type SmartPlayerIconName =\n | 'play'\n | 'pause'\n | 'prev'\n | 'next'\n | 'seek-back'\n | 'seek-forward'\n | 'volume-mute'\n | 'volume-low'\n | 'volume-high'\n | 'shuffle'\n | 'repeat'\n | 'repeat-one'\n | 'tracks'\n | 'captions'\n | 'captions-off'\n | 'speed'\n | 'pip'\n | 'pip-active'\n | 'airplay'\n | 'airplay-active'\n | 'cast'\n | 'cast-active'\n | 'devices'\n | 'devices-active'\n | 'radio'\n | 'server'\n | 'window-mini'\n | 'window-bar'\n | 'window-restore'\n | 'cinema'\n | 'cinema-active'\n | 'lyrics'\n | 'info'\n | 'bell'\n | 'thumb-up'\n | 'thumb-down'\n | 'share'\n | 'playlist-plus'\n | 'clock'\n | 'home'\n | 'layers'\n | 'video'\n | 'music'\n | 'broadcast'\n | 'heart'\n | 'download'\n | 'trash'\n | 'folder'\n | 'settings'\n | 'search'\n | 'grid'\n | 'list'\n | 'more'\n | 'waveform'\n | 'sliders'\n | 'network'\n | 'cloud'\n | 'spark'\n | 'disc'\n | 'user'\n | 'tag'\n | 'close'\n | 'plus'\n | 'check'\n | 'menu'\n | 'panel-right'\n | 'chevron-left'\n | 'chevron-right'\n | 'chevron-up'\n | 'chevron-down'\n | 'fullscreen'\n | 'fullscreen-exit';\n\n@Component({\n selector: 'ngxsp-smart-icon',\n standalone: true,\n template: `\n @switch (name) {\n @case ('play') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M8.25 6.82c0-1.3 1.43-2.1 2.54-1.43l8.12 4.93a1.96 1.96 0 0 1 0 3.36l-8.12 4.93a1.67 1.67 0 0 1-2.54-1.43V6.82Z\"/></svg>\n }\n @case ('pause') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M7.5 5.25A1.25 1.25 0 0 1 8.75 6.5v11A1.25 1.25 0 0 1 6.25 17.5v-11A1.25 1.25 0 0 1 7.5 5.25Zm8 0a1.25 1.25 0 0 1 1.25 1.25v11a1.25 1.25 0 1 1-2.5 0v-11A1.25 1.25 0 0 1 15.5 5.25Z\"/></svg>\n }\n @case ('prev') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M6 5.25a1 1 0 0 1 1 1v11.5a1 1 0 1 1-2 0V6.25a1 1 0 0 1 1-1Z\"/><path d=\"M19 6.55v10.9a1.25 1.25 0 0 1-1.93 1.05l-8.2-5.45a1.25 1.25 0 0 1 0-2.1l8.2-5.45A1.25 1.25 0 0 1 19 6.55Z\"/></svg>\n }\n @case ('next') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M18 5.25a1 1 0 0 1 1 1v11.5a1 1 0 1 1-2 0V6.25a1 1 0 0 1 1-1Z\"/><path d=\"M5 6.55v10.9a1.25 1.25 0 0 0 1.93 1.05l8.2-5.45a1.25 1.25 0 0 0 0-2.1l-8.2-5.45A1.25 1.25 0 0 0 5 6.55Z\"/></svg>\n }\n @case ('seek-back') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M5.5 13a6.5 6.5 0 1 0 6.5-6.5H8M10 4.5 8 6.5l2 2\"/><text x=\"12\" y=\"15.8\" font-size=\"7.5\" font-weight=\"700\" text-anchor=\"middle\" fill=\"currentColor\" stroke=\"none\" font-family=\"system-ui, sans-serif\">10</text></svg>\n }\n @case ('seek-forward') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M18.5 13a6.5 6.5 0 1 1-6.5-6.5H16M14 4.5 16 6.5l-2 2\"/><text x=\"12\" y=\"15.8\" font-size=\"7.5\" font-weight=\"700\" text-anchor=\"middle\" fill=\"currentColor\" stroke=\"none\" font-family=\"system-ui, sans-serif\">10</text></svg>\n }\n @case ('volume-mute') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm3.5 5.5 5 5m0-5-5 5\"/></svg>\n }\n @case ('volume-low') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm4.5 4.75a3.5 3.5 0 0 1 0 4.95\"/></svg>\n }\n @case ('volume-high') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M11 5 6.5 9H3.75v6h2.75L11 19V5Zm4.5 4.75a3.5 3.5 0 0 1 0 4.95m2.75-7.7a7.5 7.5 0 0 1 0 10.45\"/></svg>\n }\n @case ('shuffle') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 6h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m20 6-4.5 4.5\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 7h3.2c1 0 1.95.4 2.66 1.1l6.28 6.3A3.75 3.75 0 0 0 18.82 15H20\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M17 15h3v3\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m20 18-4.56-4.56\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 17h3.2c1 0 1.95-.4 2.66-1.1l1.54-1.54\"/></svg>\n }\n @case ('repeat') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M17 3.5 20 6.5 17 9.5\"/><path d=\"M4 11.5v-1a4 4 0 0 1 4-4h12\"/><path d=\"M7 20.5 4 17.5 7 14.5\"/><path d=\"M20 12.5v1a4 4 0 0 1-4 4H4\"/></svg>\n }\n @case ('repeat-one') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M17 3.5 20 6.5 17 9.5\"/><path d=\"M4 11.5v-1a4 4 0 0 1 4-4h12\"/><path d=\"M7 20.5 4 17.5 7 14.5\"/><path d=\"M20 12.5v1a4 4 0 0 1-4 4H4\"/><path d=\"M11 10.9 12.4 10v4.1\"/></svg>\n }\n @case ('tracks') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 6.75h16M4 12h16M4 17.25h16\"/></svg>\n }\n @case ('captions') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8 11.25h2.5m2 0H14m2 0h.5M8 14.75h3.5m2 0H16\"/></svg>\n }\n @case ('captions-off') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"5.5\" width=\"17\" height=\"13\" rx=\"2.5\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8 11.25h2.5m2 0H14m2 0h.5M8 14.75h3.5m2 0H16\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M6 6l12 12\"/></svg>\n }\n @case ('speed') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><path d=\"M5.25 5.82c0-1.3 1.43-2.1 2.54-1.43l5.71 3.47a1.96 1.96 0 0 1 0 3.36L7.79 14.7a1.67 1.67 0 0 1-2.54-1.43V5.82Zm8.5 0c0-1.3 1.43-2.1 2.54-1.43L22 7.86a1.96 1.96 0 0 1 0 3.36l-5.71 3.47a1.67 1.67 0 0 1-2.54-1.43V5.82Z\"/></svg>\n }\n @case ('pip') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"4.5\" width=\"18\" height=\"15\" rx=\"2.5\"/><rect x=\"12\" y=\"11\" width=\"7\" height=\"6\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"/></svg>\n }\n @case ('pip-active') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"4.5\" width=\"18\" height=\"15\" rx=\"2.5\" fill=\"currentColor\" fill-opacity=\".22\"/><rect x=\"12\" y=\"11\" width=\"7\" height=\"6\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"/></svg>\n }\n @case ('airplay') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M6 16.5H4.75A1.75 1.75 0 0 1 3 14.75v-8A1.75 1.75 0 0 1 4.75 5h14.5A1.75 1.75 0 0 1 21 6.75v8a1.75 1.75 0 0 1-1.75 1.75H18\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m12 14 4.5 6h-9L12 14Z\"/></svg>\n }\n @case ('airplay-active') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M6 16.5H4.75A1.75 1.75 0 0 1 3 14.75v-8A1.75 1.75 0 0 1 4.75 5h14.5A1.75 1.75 0 0 1 21 6.75v8a1.75 1.75 0 0 1-1.75 1.75H18\"/><path fill=\"currentColor\" stroke=\"none\" d=\"m12 13.4 5.2 6.9H6.8L12 13.4Z\"/></svg>\n }\n @case ('cast') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.75 18.25a3.5 3.5 0 0 1 3.5 3.5\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.75 13.75A8 8 0 0 1 12.75 21.75\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.75 9.25A12.5 12.5 0 0 1 17.25 21.75\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M5.5 5.5h13a1.75 1.75 0 0 1 1.75 1.75v4.5\"/></svg>\n }\n @case ('cast-active') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.75 18.25a3.5 3.5 0 0 1 3.5 3.5\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.75 13.75A8 8 0 0 1 12.75 21.75\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.75 9.25A12.5 12.5 0 0 1 17.25 21.75\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M5.5 5.5h13a1.75 1.75 0 0 1 1.75 1.75v4.5\"/><circle cx=\"7\" cy=\"19\" r=\"1.5\" fill=\"currentColor\" stroke=\"none\"/></svg>\n }\n @case ('devices') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2.75\" y=\"4.75\" width=\"12.5\" height=\"9.5\" rx=\"1.75\"/><path d=\"M6.5 18.75h5M9 14.25v4.5\"/><rect x=\"16.25\" y=\"8.25\" width=\"5\" height=\"12\" rx=\"1.5\"/><circle cx=\"18.75\" cy=\"16.25\" r=\"1.4\"/><path d=\"M18.75 11.25h.01\"/></svg>\n }\n @case ('devices-active') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2.75\" y=\"4.75\" width=\"12.5\" height=\"9.5\" rx=\"1.75\"/><path d=\"M6.5 18.75h5M9 14.25v4.5\"/><rect x=\"16.25\" y=\"8.25\" width=\"5\" height=\"12\" rx=\"1.5\"/><circle cx=\"18.75\" cy=\"16.25\" r=\"1.6\" fill=\"currentColor\" stroke=\"none\"/><path d=\"M18.75 11.25h.01\"/></svg>\n }\n @case ('radio') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M7.5 8 16.5 3.75\"/><rect x=\"3\" y=\"8\" width=\"18\" height=\"12.5\" rx=\"2.5\"/><circle cx=\"15.25\" cy=\"14.25\" r=\"2.75\"/><path d=\"M6.75 12.75h3.5M6.75 15.75h3.5\"/></svg>\n }\n @case ('server') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"4\" y=\"3.25\" width=\"16\" height=\"11\" rx=\"2\"/><path d=\"M7.5 6.75h.01M7.5 10.75h.01M10.5 6.75h6M10.5 10.75h6\"/><path d=\"M12 14.25v4.5M3.5 20.5h6.75M13.75 20.5h6.75\"/><circle cx=\"12\" cy=\"20.5\" r=\"1.6\"/></svg>\n }\n @case ('window-mini') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"4.5\" width=\"18\" height=\"15\" rx=\"2.5\"/><path d=\"M10 12.5 15 9.5M11 9.5h4v4\"/><rect x=\"5.5\" y=\"13\" width=\"6\" height=\"4.5\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"/></svg>\n }\n @case ('window-bar') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"4.5\" width=\"18\" height=\"15\" rx=\"2.5\"/><rect x=\"5\" y=\"15\" width=\"14\" height=\"2.8\" rx=\"1\" fill=\"currentColor\" stroke=\"none\"/></svg>\n }\n @case ('cinema') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"7\" width=\"20\" height=\"10\" rx=\"2\"/><path d=\"M6 12h12M6 12l2-2M6 12l2 2M18 12l-2-2M18 12l-2 2\"/></svg>\n }\n @case ('cinema-active') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"2\" y=\"7\" width=\"20\" height=\"10\" rx=\"2\" fill=\"currentColor\" fill-opacity=\".22\"/><path d=\"M6 12h12M6 12l2-2M6 12l2 2M18 12l-2-2M18 12l-2 2\"/></svg>\n }\n @case ('info') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M12 11v5.5M12 7.5h.01\"/></svg>\n }\n @case ('lyrics') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M4 5.5h16v10H10l-4.5 4v-4H4z\"/><path d=\"M8 9.5h8M8 12.5h5\"/></svg>\n }\n @case ('window-restore') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><rect x=\"3\" y=\"4.5\" width=\"18\" height=\"15\" rx=\"2.5\"/><path d=\"M10 14.5 15 9.5M11 9.5h4v4\"/></svg>\n }\n @case ('bell') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M6.75 10.4a5.25 5.25 0 0 1 10.5 0c0 4.65 1.75 5.6 1.75 5.6H5s1.75-.95 1.75-5.6Z\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M10 19a2.15 2.15 0 0 0 4 0\"/></svg>\n }\n @case ('thumb-up') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M7.25 10.5v9.25H4.7a1.7 1.7 0 0 1-1.7-1.7V12.2a1.7 1.7 0 0 1 1.7-1.7h2.55Zm0 0 4.85-7.05a1.75 1.75 0 0 1 3.18 1.16l-.44 3.2h3.88a2.1 2.1 0 0 1 2.05 2.55l-1.35 6.45a3.7 3.7 0 0 1-3.62 2.94H7.25\"/></svg>\n }\n @case ('thumb-down') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M7.25 13.5V4.25H4.7A1.7 1.7 0 0 0 3 5.95v5.85a1.7 1.7 0 0 0 1.7 1.7h2.55Zm0 0 4.85 7.05a1.75 1.75 0 0 0 3.18-1.16l-.44-3.2h3.88a2.1 2.1 0 0 0 2.05-2.55L19.42 7.2a3.7 3.7 0 0 0-3.62-2.94H7.25\"/></svg>\n }\n @case ('share') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M18.25 8.25 21 5.5l-2.75-2.75\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M20.4 5.5h-5.2A8.2 8.2 0 0 0 7 13.7v.8\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4 11.5v6.75A1.75 1.75 0 0 0 5.75 20h12.5A1.75 1.75 0 0 0 20 18.25V14\"/></svg>\n }\n @case ('playlist-plus') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M4 6.5h11M4 11.5h11M4 16.5h8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M18 13.5v6m-3-3h6\"/></svg>\n }\n @case ('clock') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"8.25\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M12 7.75v4.65l3.45 2.05\"/></svg>\n }\n @case ('home') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m4 11.5 8-6.75 8 6.75\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M6.5 10.5v8.25h11v-8.25\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M10 18.75v-5h4v5\"/></svg>\n }\n @case ('layers') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M12 3.75 3.75 8 12 12.25 20.25 8 12 3.75Z\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m5 12 7 3.6 7-3.6M5 16l7 3.6 7-3.6\"/></svg>\n }\n @case ('video') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2.25\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8 5v14M16 5v14M4 9h4M4 15h4M16 9h4M16 15h4\"/></svg>\n }\n @case ('music') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M9 18.25a2.75 2.75 0 1 1-1.6-2.5V6.5l10-2v11.25a2.75 2.75 0 1 1-1.6-2.5V8.2l-8.4 1.68\"/></svg>\n }\n @case ('broadcast') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"2\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M8.7 8.7a4.65 4.65 0 0 0 0 6.6m6.6 0a4.65 4.65 0 0 0 0-6.6M6.1 6.1a8.35 8.35 0 0 0 0 11.8m11.8 0a8.35 8.35 0 0 0 0-11.8\"/></svg>\n }\n @case ('heart') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M20.2 6.2c-1.8-1.9-4.8-1.8-6.5.2L12 8.3l-1.7-1.9c-1.7-2-4.7-2.1-6.5-.2-1.9 2-1.7 5.1.4 6.9L12 20l7.8-6.9c2.1-1.8 2.3-4.9.4-6.9Z\"/></svg>\n }\n @case ('download') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M12 4v10m0 0 4-4m-4 4-4-4M5 19h14\"/></svg>\n }\n @case ('trash') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.5 6.75h15M9.75 6.75V5.25A1.5 1.5 0 0 1 11.25 3.75h1.5a1.5 1.5 0 0 1 1.5 1.5v1.5M6.75 6.75l.7 12a1.5 1.5 0 0 0 1.5 1.5h6.1a1.5 1.5 0 0 0 1.5-1.5l.7-12M10.5 10.5v6M13.5 10.5v6\"/></svg>\n }\n @case ('folder') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M3.75 7.5A2.25 2.25 0 0 1 6 5.25h4.15l2.1 2.25H18a2.25 2.25 0 0 1 2.25 2.25v6.75A2.25 2.25 0 0 1 18 18.75H6a2.25 2.25 0 0 1-2.25-2.25v-9Z\"/></svg>\n }\n @case ('settings') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M12 15.25A3.25 3.25 0 1 0 12 8.75a3.25 3.25 0 0 0 0 6.5Z\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M19.4 13.5a7.8 7.8 0 0 0 .05-3l2-1.55-2-3.45-2.42.98a8 8 0 0 0-2.58-1.5L14.1 2.4h-4.2l-.35 2.58a8 8 0 0 0-2.58 1.5L4.55 5.5l-2 3.45 2 1.55a7.8 7.8 0 0 0 .05 3l-2.05 1.55 2 3.45 2.46-.98a8 8 0 0 0 2.54 1.47l.35 2.61h4.2l.35-2.6a8 8 0 0 0 2.54-1.48l2.46.98 2-3.45-2.05-1.55Z\"/></svg>\n }\n @case ('search') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><circle cx=\"10.75\" cy=\"10.75\" r=\"6.25\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"m15.4 15.4 4.85 4.85\"/></svg>\n }\n @case ('grid') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"4\" y=\"4\" width=\"6\" height=\"6\" rx=\"1.4\" stroke-width=\"1.8\"/><rect x=\"14\" y=\"4\" width=\"6\" height=\"6\" rx=\"1.4\" stroke-width=\"1.8\"/><rect x=\"4\" y=\"14\" width=\"6\" height=\"6\" rx=\"1.4\" stroke-width=\"1.8\"/><rect x=\"14\" y=\"14\" width=\"6\" height=\"6\" rx=\"1.4\" stroke-width=\"1.8\"/></svg>\n }\n @case ('list') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M9 6h11M9 12h11M9 18h11\"/><circle cx=\"4.8\" cy=\"6\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4.8\" cy=\"12\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"4.8\" cy=\"18\" r=\"1.2\" fill=\"currentColor\" stroke=\"none\"/></svg>\n }\n @case ('more') {\n <svg viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\"><circle cx=\"5\" cy=\"12\" r=\"1.7\"/><circle cx=\"12\" cy=\"12\" r=\"1.7\"/><circle cx=\"19\" cy=\"12\" r=\"1.7\"/></svg>\n }\n @case ('waveform') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M4 13v-2m4 5V8m4 11V5m4 10V9m4 4v-2\"/></svg>\n }\n @case ('sliders') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M4 7h5m6 0h5M4 17h9m6 0h1\"/><circle cx=\"12\" cy=\"7\" r=\"2.25\" stroke-width=\"1.8\"/><circle cx=\"16\" cy=\"17\" r=\"2.25\" stroke-width=\"1.8\"/></svg>\n }\n @case ('network') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"5\" r=\"2.3\" stroke-width=\"1.8\"/><circle cx=\"6\" cy=\"18\" r=\"2.3\" stroke-width=\"1.8\"/><circle cx=\"18\" cy=\"18\" r=\"2.3\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M11 7.1 7.1 15.9M13 7.1l3.9 8.8M8.3 18h7.4\"/></svg>\n }\n @case ('cloud') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M7.25 18.5h10.2a4.05 4.05 0 0 0 .5-8.07 6.25 6.25 0 0 0-12-1.75A4.95 4.95 0 0 0 7.25 18.5Z\"/></svg>\n }\n @case ('spark') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M12 3.5 14.3 9l5.7 2.2-5.7 2.3L12 20l-2.3-6.5L4 11.2 9.7 9 12 3.5Z\"/></svg>\n }\n @case ('disc') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"12\" r=\"8.25\" stroke-width=\"1.8\"/><circle cx=\"12\" cy=\"12\" r=\"2.25\" stroke-width=\"1.8\"/></svg>\n }\n @case ('user') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><circle cx=\"12\" cy=\"8.5\" r=\"3.75\" stroke-width=\"1.8\"/><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.75 19.75a7.25 7.25 0 0 1 14.5 0\"/></svg>\n }\n @case ('tag') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M3.75 5.75v5.1c0 .6.24 1.17.66 1.6l7.4 7.4a2 2 0 0 0 2.83 0l5.1-5.1a2 2 0 0 0 0-2.83l-7.4-7.4a2.25 2.25 0 0 0-1.6-.66h-5a2 2 0 0 0-2 1.89Z\"/><circle cx=\"8.25\" cy=\"8.25\" r=\"1.25\" fill=\"currentColor\" stroke=\"none\"/></svg>\n }\n @case ('close') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"m6.5 6.5 11 11m0-11-11 11\"/></svg>\n }\n @case ('plus') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M12 5v14M5 12h14\"/></svg>\n }\n @case ('check') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m5 12.5 4.5 4.5L19 7.5\"/></svg>\n }\n @case ('menu') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-width=\"1.8\" d=\"M4 7h16M4 12h16M4 17h16\"/></svg>\n }\n @case ('panel-right') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><rect x=\"3.5\" y=\"4.5\" width=\"17\" height=\"15\" rx=\"2.5\" stroke-width=\"1.8\"/><path stroke-width=\"1.8\" d=\"M14.5 4.5v15\"/></svg>\n }\n @case ('chevron-left') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m14.5 6-6 6 6 6\"/></svg>\n }\n @case ('chevron-right') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m9.5 6 6 6-6 6\"/></svg>\n }\n @case ('chevron-up') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m6 14.5 6-6 6 6\"/></svg>\n }\n @case ('chevron-down') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"m6 9.5 6 6 6-6\"/></svg>\n }\n @case ('fullscreen') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M4.5 9V5.5a1 1 0 0 1 1-1H9m6 0h3.5a1 1 0 0 1 1 1V9m0 6v3.5a1 1 0 0 1-1 1H15m-6 0H5.5a1 1 0 0 1-1-1V15\"/></svg>\n }\n @case ('fullscreen-exit') {\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"1.8\" d=\"M9 4.5V8a1 1 0 0 1-1 1H4.5m15 0H16a1 1 0 0 1-1-1V4.5m0 15V16a1 1 0 0 1 1-1h3.5m-15 0H8a1 1 0 0 1 1 1v3.5\"/></svg>\n }\n }\n `,\n styles: [`\n :host{display:block;width:1em;height:1em;line-height:0;flex:0 0 auto}\n svg{display:block;width:100%;height:100%}\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SmartPlayerIconComponent {\n @Input({ required: true }) name: SmartPlayerIconName = 'play';\n}\n","import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';\nimport { SmartPlayerIconComponent } from './smart-player-icon.component';\n\nexport interface SmartSettingOption {\n id: string;\n label: string;\n}\n\n/** A line of a list setting, such as a library folder. */\nexport interface SmartSettingEntry {\n id: string;\n label: string;\n detail?: string;\n /** An entry the listener always keeps, such as a folder the app owns: it is shown without its remove button. */\n fixed?: boolean;\n}\n\ninterface SmartSettingBase {\n id: string;\n label: string;\n description?: string;\n}\n\n/**\n * One setting. The host owns every value and hears what the listener asks for through the component's outputs:\n * - `switch`: on or off;\n * - `choice`: one of a few options, shown side by side;\n * - `list`: entries the listener can remove one by one, with an optional action for the whole list;\n * - `action`: a button that does something now (scan again, clear a cache);\n * - `secret`: something typed that must not be read over a shoulder, sent when it is submitted\n * and never held afterwards — the field empties itself, and the host is the only one that\n * ever sees what was typed.\n */\nexport type SmartSettingItem =\n | (SmartSettingBase & { kind: 'switch'; value: boolean; disabled?: boolean })\n | (SmartSettingBase & { kind: 'choice'; value: string; options: SmartSettingOption[] })\n | (SmartSettingBase & { kind: 'list'; entries: SmartSettingEntry[]; removeLabel: string; emptyLabel?: string; actionLabel?: string; busy?: boolean })\n | (SmartSettingBase & { kind: 'action'; actionLabel: string; busy?: boolean; disabled?: boolean })\n | (SmartSettingBase & {\n kind: 'secret';\n actionLabel: string;\n placeholder?: string;\n /** A second field, when what is typed has to be given twice — an old code and a new one. */\n secondPlaceholder?: string;\n /** Digits only, which is what a device's own lock screen asks for. */\n digits?: boolean;\n busy?: boolean;\n disabled?: boolean;\n });\n\nexport interface SmartSettingsSection {\n id: string;\n title: string;\n items: SmartSettingItem[];\n}\n\nexport interface SmartSettingChange {\n id: string;\n value: boolean | string;\n /** A `secret` setting's second field, when it has one: the old code beside the new one. */\n previous?: string;\n}\n\n/** An action: a list's own action (no entry), the removal of one of its entries, or an action setting. */\nexport interface SmartSettingAction {\n id: string;\n entryId?: string;\n}\n\n/**\n * The settings of a player, grouped in sections. Colours come from the host through CSS variables\n * (`--ngxsp-settings-surface`, `-text`, `-muted`, `-line`, `-control`, `-accent`, `-accent-text`, `-radius`).\n */\n@Component({\n selector: 'ngxsp-settings',\n standalone: true,\n imports: [SmartPlayerIconComponent],\n template: `\n @for (section of sections; track section.id) {\n <section class=\"ngxsp-settings-section\" [attr.aria-labelledby]=\"'ngxsp-settings-' + section.id\">\n <h2 [id]=\"'ngxsp-settings-' + section.id\">{{ section.title }}</h2>\n <ul class=\"ngxsp-settings-items\">\n @for (item of section.items; track item.id) {\n <li class=\"ngxsp-settings-item\" [class.stacked]=\"item.kind === 'list'\" [class.wraps]=\"item.kind === 'choice' || item.kind === 'action'\">\n <span class=\"ngxsp-settings-copy\">\n <strong [id]=\"'ngxsp-setting-' + item.id\">{{ item.label }}</strong>\n @if (item.description) { <small [id]=\"'ngxsp-setting-help-' + item.id\">{{ item.description }}</small> }\n </span>\n @switch (item.kind) {\n @case ('switch') {\n <button class=\"ngxsp-settings-switch\" type=\"button\" role=\"switch\" [attr.aria-checked]=\"item.value\" [disabled]=\"item.disabled\" [attr.aria-labelledby]=\"'ngxsp-setting-' + item.id\" [attr.aria-describedby]=\"item.description ? 'ngxsp-setting-help-' + item.id : null\" (click)=\"settingChange.emit({ id: item.id, value: !item.value })\">\n <span class=\"ngxsp-settings-knob\" aria-hidden=\"true\"></span>\n </button>\n }\n @case ('choice') {\n <span class=\"ngxsp-settings-choice\" role=\"group\" [attr.aria-labelledby]=\"'ngxsp-setting-' + item.id\">\n @for (option of item.options; track option.id) {\n <button type=\"button\" [class.active]=\"option.id === item.value\" [attr.aria-pressed]=\"option.id === item.value\" (click)=\"option.id !== item.value && settingChange.emit({ id: item.id, value: option.id })\">{{ option.label }}</button>\n }\n </span>\n }\n @case ('secret') {\n <form class=\"ngxsp-settings-secret\" (submit)=\"submitSecret($event, item.id)\">\n @if (item.secondPlaceholder) {\n <input\n #firstSecret\n type=\"password\"\n autocomplete=\"off\"\n [attr.inputmode]=\"item.digits ? 'numeric' : null\"\n [attr.placeholder]=\"item.secondPlaceholder\"\n [attr.aria-label]=\"item.secondPlaceholder\"\n [disabled]=\"item.disabled || item.busy\"\n />\n }\n <input\n #secondSecret\n type=\"password\"\n autocomplete=\"off\"\n [attr.inputmode]=\"item.digits ? 'numeric' : null\"\n [attr.placeholder]=\"item.placeholder ?? null\"\n [attr.aria-label]=\"item.placeholder ?? item.label\"\n [attr.aria-describedby]=\"item.description ? 'ngxsp-setting-help-' + item.id : null\"\n [disabled]=\"item.disabled || item.busy\"\n />\n <button class=\"ngxsp-settings-button\" type=\"submit\" [disabled]=\"item.disabled || item.busy\">{{ item.actionLabel }}</button>\n </form>\n }\n @case ('action') {\n <button class=\"ngxsp-settings-button\" type=\"button\" [disabled]=\"item.disabled || item.busy\" [attr.aria-describedby]=\"item.description ? 'ngxsp-setting-help-' + item.id : null\" (click)=\"settingAction.emit({ id: item.id })\">{{ item.actionLabel }}</button>\n }\n @case ('list') {\n <ul class=\"ngxsp-settings-entries\" [attr.aria-labelledby]=\"'ngxsp-setting-' + item.id\">\n @for (entry of item.entries; track entry.id) {\n <li>\n <span class=\"ngxsp-settings-entry\"><span>{{ entry.label }}</span>@if (entry.detail) { <small>{{ entry.detail }}</small> }</span>\n @if (!entry.fixed) {\n <button class=\"ngxsp-settings-remove\" type=\"button\" [title]=\"item.removeLabel\" [attr.aria-label]=\"item.removeLabel + ' - ' + entry.label\" [disabled]=\"item.busy\" (click)=\"settingAction.emit({ id: item.id, entryId: entry.id })\">\n <ngxsp-smart-icon name=\"close\" />\n </button>\n }\n </li>\n } @empty {\n @if (item.emptyLabel) { <li class=\"empty\">{{ item.emptyLabel }}</li> }\n }\n </ul>\n @if (item.actionLabel) {\n <button class=\"ngxsp-settings-button\" type=\"button\" [disabled]=\"item.busy\" (click)=\"settingAction.emit({ id: item.id })\">{{ item.actionLabel }}</button>\n }\n }\n }\n </li>\n }\n </ul>\n </section>\n }\n `,\n styles: [`\n :host{\n --_surface:var(--ngxsp-settings-surface, rgb(255 255 255 / .04));\n --_text:var(--ngxsp-settings-text, currentColor);\n --_muted:var(--ngxsp-settings-muted, rgb(127 127 127));\n --_line:var(--ngxsp-settings-line, rgb(127 127 127 / .3));\n --_control:var(--ngxsp-settings-control, rgb(127 127 127 / .2));\n --_accent:var(--ngxsp-settings-accent, #5b5bd6);\n --_accent-text:var(--ngxsp-settings-accent-text, #fff);\n --_radius:var(--ngxsp-settings-radius, 10px);\n display:grid;\n gap:28px;\n max-width:760px;\n color:var(--_text);\n }\n .ngxsp-settings-section{display:grid;gap:10px}\n h2{margin:0;font-size:13px;font-weight:600;letter-spacing:.02em;color:var(--_muted);text-transform:uppercase}\n .ngxsp-settings-items{margin:0;padding:0;list-style:none;display:grid;gap:2px;border-radius:var(--_radius);overflow:hidden}\n .ngxsp-settings-item{display:flex;align-items:center;justify-content:space-between;gap:12px 24px;padding:14px 16px;background:var(--_surface)}\n .ngxsp-settings-item.stacked{display:grid;justify-content:stretch}\n /* A choice or a button goes under its text when the text would otherwise shrink to a thin column (side panels). */\n .ngxsp-settings-item.wraps{flex-wrap:wrap}\n .ngxsp-settings-item.wraps .ngxsp-settings-copy{flex:1 1 220px}\n .ngxsp-settings-copy{min-width:0;display:grid;gap:4px}\n .ngxsp-settings-copy strong{font-size:14px;font-weight:600}\n .ngxsp-settings-copy small{font-size:12px;line-height:1.45;color:var(--_muted)}\n .ngxsp-settings-switch{position:relative;flex:0 0 auto;width:42px;height:24px;padding:0;border:1px solid var(--_line);border-radius:999px;background:var(--_control);cursor:pointer;transition:background-color .16s ease, border-color .16s ease}\n .ngxsp-settings-knob{position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgb(0 0 0 / .3);transition:transform .16s ease}\n .ngxsp-settings-switch[aria-checked=\"true\"]{border-color:var(--_accent);background:var(--_accent)}\n .ngxsp-settings-switch[aria-checked=\"true\"] .ngxsp-settings-knob{transform:translateX(18px)}\n .ngxsp-settings-choice{flex:0 0 auto;display:inline-flex;padding:2px;gap:2px;border:1px solid var(--_line);border-radius:999px;background:var(--_control)}\n .ngxsp-settings-choice button{height:28px;padding:0 12px;border:0;border-radius:999px;background:transparent;color:var(--_text);font:inherit;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap}\n .ngxsp-settings-choice button.active{background:var(--_accent);color:var(--_accent-text)}\n .ngxsp-settings-button{justify-self:start;flex:0 0 auto;height:32px;padding:0 14px;border:1px solid var(--_line);border-radius:999px;background:var(--_control);color:var(--_text);font:inherit;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap}\n .ngxsp-settings-button:disabled,.ngxsp-settings-switch:disabled,.ngxsp-settings-remove:disabled{opacity:.5;cursor:default}\n .ngxsp-settings-secret{display:flex;align-items:center;gap:8px;min-width:0}\n .ngxsp-settings-secret input{\n flex:1 1 96px;\n min-width:0;\n height:32px;\n padding:0 10px;\n border:1px solid var(--_line);\n border-radius:8px;\n background:var(--_control);\n color:var(--_text);\n font:inherit;\n font-size:12px;\n letter-spacing:.14em;\n }\n .ngxsp-settings-secret input::placeholder{color:var(--_muted);letter-spacing:0}\n .ngxsp-settings-entries{margin:0;padding:0;list-style:none;display:grid;gap:4px}\n .ngxsp-settings-entries li{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 8px 8px 12px;border:1px solid var(--_line);border-radius:8px}\n .ngxsp-settings-entries li.empty{display:block;color:var(--_muted);font-size:12px}\n .ngxsp-settings-entry{min-width:0;display:grid;gap:2px;font-size:13px}\n .ngxsp-settings-entry small{overflow:hidden;color:var(--_muted);font-size:11px;text-overflow:ellipsis;white-space:nowrap}\n .ngxsp-settings-remove{flex:0 0 auto;width:30px;height:30px;display:grid;place-items:center;padding:0;border:0;border-radius:8px;background:transparent;color:var(--_muted);cursor:pointer}\n .ngxsp-settings-remove:hover{background:var(--_control);color:var(--_text)}\n .ngxsp-settings-remove ngxsp-smart-icon{width:16px;height:16px}\n button:focus-visible{outline:2px solid var(--_accent);outline-offset:2px}\n @media (max-width:560px){\n .ngxsp-settings-secret{flex-wrap:wrap}\n .ngxsp-settings-choice{flex-wrap:wrap}\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SmartSettingsComponent {\n @Input() sections: SmartSettingsSection[] = [];\n @Output() settingChange = new EventEmitter<SmartSettingChange>();\n @Output() settingAction = new EventEmitter<SmartSettingAction>();\n\n /**\n * Sends what was typed and empties the fields at once. Nothing secret stays in the component:\n * the host is the only place it goes, and it does not come back through an input.\n */\n protected submitSecret(event: Event, id: string): void {\n event.preventDefault();\n const form = event.target as HTMLFormElement;\n const inputs = Array.from(form.querySelectorAll('input')) as HTMLInputElement[];\n const value = inputs.at(-1)?.value ?? '';\n const previous = inputs.length > 1 ? inputs[0].value : undefined;\n inputs.forEach((input) => { input.value = ''; });\n if (!value) return;\n this.settingChange.emit({ id, value, ...(previous === undefined ? {} : { previous }) });\n }\n}\n","import { AfterViewInit, ChangeDetectionStrategy, Component, ElementRef, EventEmitter, HostListener, Input, Output, ViewChild } from '@angular/core';\n\nlet nextDialogId = 0;\n\n/**\n * A question the user answers before anything happens (another device asking to send its playback here). The\n * cautious answer has the focus and Escape; the dialog stays until one of the two buttons is pressed. Colours come\n * from the host through CSS variables (`--ngxsp-dialog-surface`, `-text`, `-muted`, `-line`, `-accent`,\n * `-accent-text`, `-radius`).\n */\n@Component({\n selector: 'ngxsp-confirm-dialog',\n standalone: true,\n template: `\n <div class=\"ngxsp-dialog-backdrop\" role=\"presentation\">\n <section class=\"ngxsp-dialog\" role=\"alertdialog\" aria-modal=\"true\" [attr.aria-labelledby]=\"id + '-title'\" [attr.aria-describedby]=\"id + '-message'\">\n <h2 [id]=\"id + '-title'\">{{ title }}</h2>\n <p [id]=\"id + '-message'\">{{ message }}</p>\n <div class=\"ngxsp-dialog-actions\">\n <button #cancelButton class=\"ngxsp-dialog-button\" type=\"button\" (click)=\"cancelled.emit()\">{{ cancelLabel }}</button>\n <button class=\"ngxsp-dialog-button primary\" type=\"button\" (click)=\"confirmed.emit()\">{{ confirmLabel }}</button>\n </div>\n </section>\n </div>\n `,\n styles: [`\n :host{\n --_surface:var(--ngxsp-dialog-surface, #17181d);\n --_text:var(--ngxsp-dialog-text, #ededf0);\n --_muted:var(--ngxsp-dialog-muted, #a3a5ae);\n --_line:var(--ngxsp-dialog-line, rgb(255 255 255 / .13));\n --_accent:var(--ngxsp-dialog-accent, #5b5bd6);\n --_accent-text:var(--ngxsp-dialog-accent-text, #fff);\n --_radius:var(--ngxsp-dialog-radius, 14px);\n }\n .ngxsp-dialog-backdrop{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:16px;background:rgb(5 6 8 / .6);backdrop-filter:blur(2px)}\n .ngxsp-dialog{width:min(420px, 100%);display:grid;gap:12px;padding:20px;border:1px solid var(--_line);border-radius:var(--_radius);background:var(--_surface);color:var(--_text);box-shadow:0 24px 64px rgb(0 0 0 / .45)}\n h2{margin:0;font-size:17px;font-weight:650;line-height:1.3}\n p{margin:0;color:var(--_muted);font-size:14px;line-height:1.5}\n .ngxsp-dialog-actions{display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px;margin-top:4px}\n .ngxsp-dialog-button{min-height:36px;padding:0 16px;border:1px solid var(--_line);border-radius:999px;background:transparent;color:var(--_text);font:inherit;font-size:13px;font-weight:600;cursor:pointer}\n .ngxsp-dialog-button.primary{border-color:var(--_accent);background:var(--_accent);color:var(--_accent-text)}\n .ngxsp-dialog-button:focus-visible{outline:2px solid var(--_accent);outline-offset:2px}\n `],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SmartConfirmDialogComponent implements AfterViewInit {\n @Input() title = '';\n @Input() message = '';\n @Input() confirmLabel = 'OK';\n @Input() cancelLabel = 'Cancel';\n @Output() confirmed = new EventEmitter<void>();\n @Output() cancelled = new EventEmitter<void>();\n @ViewChild('cancelButton') private cancelButton?: ElementRef<HTMLButtonElement>;\n protected readonly id = `ngxsp-dialog-${++nextDialogId}`;\n\n ngAfterViewInit(): void {\n this.cancelButton?.nativeElement.focus({ preventScroll: true });\n }\n\n @HostListener('document:keydown.escape', ['$event'])\n protected onEscape(event: Event): void {\n event.preventDefault();\n this.cancelled.emit();\n }\n}\n","import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { MediaTrack } from '@ngxsp/core';\n\nexport type PlayerMenuKind = 'tracks' | 'speed' | 'captions' | null;\n\n/** The words of the player's menus; English by default. */\nexport interface PlayerMenuLabels {\n captions: string;\n off: string;\n audio: string;\n singleAudio: string;\n quality: string;\n auto: string;\n singleQuality: string;\n speed: string;\n /** Title of the subtitles menu, and of its button. */\n subtitles: string;\n /** Before the name of the subtitles shown now. */\n current: string;\n noSubtitles: string;\n loadSubtitles: string;\n tracks: string;\n media: string;\n /** Locale for the names of languages (\"fr\" becomes \"French\"); the device's by default. */\n locale?: string;\n}\n\nexport const DEFAULT_PLAYER_MENU_LABELS: PlayerMenuLabels = {\n captions: 'Captions',\n off: 'Off',\n audio: 'Audio',\n singleAudio: 'Single audio track',\n quality: 'Quality',\n auto: 'Auto',\n singleQuality: 'Single quality',\n speed: 'Playback speed',\n subtitles: 'Subtitles',\n current: 'Showing',\n noSubtitles: 'No subtitles in this video yet.',\n loadSubtitles: 'Load a file (SRT, VTT)…',\n tracks: 'Tracks',\n media: 'Media',\n};\n\n/**\n * Menu de pistes (sous-titres / audio / qualité) et de vitesse de lecture.\n * Extrait du SmartPlayerComponent (décomposition, cf. docs/AUDIT.md).\n * Sans logique de lecture : émet des événements, l'hôte applique l'action.\n */\n@Component({\n selector: 'ngxsp-player-menu',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (openMenu() === 'tracks') {\n <div class=\"ngxsp-menu\">\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">{{ labels().captions }}</div>\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedTextTrackId() === null\" (click)=\"selectText.emit(null)\">{{ labels().off }}</button>\n @for (track of textTracks(); track track.id) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedTextTrackId() === track.id\" (click)=\"selectText.emit(track.id)\">\n {{ trackLabel(track) }}\n </button>\n }\n </div>\n\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">{{ labels().audio }}</div>\n @if (audioTracks().length) {\n @for (track of audioTracks(); track track.id) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedAudioTrackId() === track.id\" (click)=\"selectAudio.emit(track.id)\">\n {{ trackLabel(track) }}\n </button>\n }\n } @else {\n <div class=\"ngxsp-menuHint\">{{ labels().singleAudio }}</div>\n }\n </div>\n\n @if (!isAudioMode()) {\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">{{ labels().quality }}</div>\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedVideoTrackId() === null\" (click)=\"selectVideo.emit(null)\">{{ labels().auto }}</button>\n @if (videoTracks().length) {\n @for (track of videoTracks(); track track.id) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedVideoTrackId() === track.id\" (click)=\"selectVideo.emit(track.id)\">\n {{ qualityLabel(track) }}\n </button>\n }\n } @else {\n <div class=\"ngxsp-menuHint\">{{ labels().singleQuality }}</div>\n }\n </div>\n }\n </div>\n }\n\n @if (openMenu() === 'speed') {\n <div class=\"ngxsp-menu ngxsp-menuCompact\">\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">{{ labels().speed }}</div>\n @for (rate of playbackRates(); track rate) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"playbackRate() === rate\" (click)=\"selectRate.emit(rate)\">\n {{ rate }}x\n </button>\n }\n </div>\n </div>\n }\n\n @if (openMenu() === 'captions') {\n <div class=\"ngxsp-menu ngxsp-menuCompact ngxsp-menuCaptions\">\n <div class=\"ngxsp-menuSection\">\n <div class=\"ngxsp-menuTitle\">{{ labels().subtitles }}</div>\n <div class=\"ngxsp-menuCurrent\">{{ labels().current }} <strong>{{ currentTextLabel() }}</strong></div>\n <div class=\"ngxsp-menuScroll\" role=\"group\" [attr.aria-label]=\"labels().subtitles\">\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedTextTrackId() === null\" [attr.aria-pressed]=\"selectedTextTrackId() === null\" (click)=\"selectText.emit(null)\">{{ labels().off }}</button>\n @for (track of textTracks(); track track.id) {\n <button type=\"button\" class=\"ngxsp-menuItem\" [class.active]=\"selectedTextTrackId() === track.id\" [attr.aria-pressed]=\"selectedTextTrackId() === track.id\" (click)=\"selectText.emit(track.id)\">\n <span class=\"ngxsp-menuItemLabel\">{{ trackLabel(track) }}</span>\n @if (track.language && track.label) { <small>{{ languageName(track.language) }}</small> }\n </button>\n }\n </div>\n @if (!textTracks().length) { <div class=\"ngxsp-menuHint\">{{ labels().noSubtitles }}</div> }\n <button type=\"button\" class=\"ngxsp-menuItem ngxsp-menuAction\" (click)=\"loadSubtitles.emit()\">{{ labels().loadSubtitles }}</button>\n </div>\n </div>\n }\n `,\n styles: `\n :host { display: block; }\n .ngxsp-menu{display:grid;grid-template-columns:repeat(auto-fit, minmax(160px, 1fr));gap:12px;margin:6px 0 4px;padding:12px;border-radius:10px;background:rgb(18 19 23 / .92);box-shadow:0 12px 32px rgb(0 0 0 / .45), 0 0 0 1px rgb(255 255 255 / .08);backdrop-filter:blur(16px)}\n .ngxsp-menuCompact{grid-template-columns:minmax(160px, 220px);justify-self:end}\n .ngxsp-menuSection{display:flex;flex-direction:column;gap:2px}\n .ngxsp-menuTitle{padding:0 8px 6px;font-size:12px;font-weight:600;color:rgb(255 255 255 / .6)}\n .ngxsp-menuItem{height:32px;padding:0 10px;border:0;border-radius:6px;background:transparent;color:rgb(255 255 255 / .9);text-align:left;cursor:pointer;font:inherit;font-size:13px}\n .ngxsp-menuItem:hover{background:rgb(255 255 255 / .1)}\n .ngxsp-menuItem.active{background:rgb(139 144 255 / .18);color:var(--nsp-media-accent, #8b90ff);font-weight:500}\n .ngxsp-menuItem:focus-visible{outline:2px solid var(--nsp-media-accent, #8b90ff);outline-offset:-2px}\n .ngxsp-menuHint{font-size:12px;color:rgb(255 255 255 / .6);padding:6px 8px}\n .ngxsp-menuCaptions{grid-template-columns:minmax(200px, 280px)}\n .ngxsp-menuCurrent{padding:0 8px 8px;font-size:12px;color:rgb(255 255 255 / .6);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n .ngxsp-menuCurrent strong{color:rgb(255 255 255 / .92);font-weight:600}\n .ngxsp-menuScroll{display:flex;flex-direction:column;gap:2px;max-height:min(36vh, 232px);overflow:auto;overscroll-behavior:contain}\n .ngxsp-menuItem{display:flex;align-items:center;gap:8px;flex:none}\n .ngxsp-menuItemLabel{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n .ngxsp-menuItem small{flex:none;font-size:11px;color:rgb(255 255 255 / .55)}\n .ngxsp-menuAction{margin-top:6px;border-top:1px solid rgb(255 255 255 / .1);border-radius:0 0 6px 6px;color:var(--nsp-media-accent, #8b90ff)}\n @media (max-width: 860px){ .ngxsp-menu{grid-template-columns:1fr} }\n `,\n})\nexport class PlayerMenuComponent {\n readonly openMenu = input<PlayerMenuKind>(null);\n readonly isAudioMode = input(false);\n readonly textTracks = input<MediaTrack[]>([]);\n readonly audioTracks = input<MediaTrack[]>([]);\n readonly videoTracks = input<MediaTrack[]>([]);\n readonly selectedTextTrackId = input<string | null>(null);\n readonly selectedAudioTrackId = input<string | null>(null);\n readonly selectedVideoTrackId = input<string | null>(null);\n readonly playbackRates = input<number[]>([]);\n readonly playbackRate = input(1);\n readonly labels = input<PlayerMenuLabels>(DEFAULT_PLAYER_MENU_LABELS);\n\n readonly selectText = output<string | null>();\n readonly selectAudio = output<string>();\n readonly selectVideo = output<string | null>();\n readonly selectRate = output<number>();\n /** \"Load a file\" in the subtitles menu: the host opens its file picker. */\n readonly loadSubtitles = output<void>();\n\n currentTextLabel(): string {\n const track = this.textTracks().find((entry) => entry.id === this.selectedTextTrackId());\n return track ? this.trackLabel(track) : this.labels().off;\n }\n\n /** \"French\" for \"fr\", in the labels' locale. */\n languageName(code: string): string {\n try {\n return new Intl.DisplayNames(this.labels().locale ? [this.labels().locale as string] : undefined, { type: 'language' }).of(code) ?? code;\n } catch {\n return code;\n }\n }\n\n trackLabel(track: MediaTrack): string {\n return track.label || (track.language ? this.languageName(track.language) : track.id);\n }\n\n qualityLabel(track: MediaTrack): string {\n if (track.label) return track.label;\n const parts: string[] = [];\n if (track.height) parts.push(`${track.height}p`);\n if (track.bandwidth) parts.push(`${(track.bandwidth / 1_000_000).toFixed(1)} Mbps`);\n return parts.join(' • ') || track.id;\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, input, output } from '@angular/core';\nimport { PlayerError } from '@ngxsp/core';\n\n/**\n * Surcouches du lecteur : carte d'erreur de lecture et panneau de diagnostic.\n * Extrait du SmartPlayerComponent (décomposition, cf. docs/AUDIT.md).\n * Sans accès au moteur : reçoit l'erreur/diagnostic en entrée et émet les actions.\n */\n@Component({\n selector: 'ngxsp-player-overlays',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (error()) {\n <div class=\"ngxsp-overlay\" role=\"alert\">\n <div class=\"ngxsp-overlay-card\">\n <span class=\"ngxsp-overlay-icon\" aria-hidden=\"true\">!</span>\n <div class=\"ngxsp-overlay-title\">{{ title() }}</div>\n <div class=\"ngxsp-overlay-msg\">{{ hint() }}</div>\n <div class=\"ngxsp-overlay-actions\">\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"retry.emit()\">Retry</button>\n @if (autoplayBlocked()) {\n <button type=\"button\" class=\"ngxsp-btn primary\" (click)=\"requestPlay.emit()\">Play</button>\n }\n </div>\n </div>\n </div>\n }\n\n @if (debug()) {\n <details class=\"ngxsp-debug\">\n <summary>Debug</summary>\n <div class=\"ngxsp-debug-actions\">\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"copyJson.emit()\">Copy JSON</button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"downloadJson.emit()\">Download</button>\n </div>\n <pre>{{ debugJson() }}</pre>\n </details>\n }\n `,\n styles: `\n :host { display: contents; }\n .ngxsp-btn{height:32px;padding:0 14px;border:1px solid rgb(255 255 255 / .16);border-radius:6px;background:rgb(255 255 255 / .06);color:#fff;font:inherit;font-size:13px;font-weight:500;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px}\n .ngxsp-btn:hover{background:rgb(255 255 255 / .12)}\n .ngxsp-btn.primary{border-color:transparent;background:var(--nsp-accent-strong, #5d63ee)}\n .ngxsp-btn:focus-visible{outline:2px solid var(--nsp-media-accent, #8b90ff);outline-offset:2px}\n .ngxsp-overlay{position:absolute;inset:0;z-index:5;display:grid;place-items:center;padding:24px;background:rgb(0 0 0 / .78);text-align:center}\n .ngxsp-overlay-card{display:grid;justify-items:center;gap:8px;max-width:440px}\n .ngxsp-overlay-icon{width:40px;height:40px;display:grid;place-items:center;margin-bottom:4px;border-radius:999px;background:rgb(242 95 92 / .16);color:var(--nsp-danger, #f25f5c);font-size:18px;font-weight:700}\n .ngxsp-overlay-title{font-size:16px;font-weight:600;color:#fff}\n .ngxsp-overlay-msg{color:rgb(255 255 255 / .7);font-size:13px;line-height:1.5}\n .ngxsp-overlay-actions{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin-top:8px}\n .ngxsp-debug{position:absolute;top:12px;right:12px;z-index:6;margin:0;max-width:min(420px, calc(100% - 24px));opacity:0;transform:translateY(-6px);transition:opacity .18s ease, transform .18s ease;color:#fff}\n :host-context(.ngxsp-ui-visible) .ngxsp-debug,\n .ngxsp-debug[open]{opacity:1;transform:translateY(0)}\n .ngxsp-debug summary{cursor:pointer;list-style:none;width:max-content;margin-left:auto;padding:4px 10px;border-radius:999px;background:rgb(0 0 0 / .6);color:rgb(255 255 255 / .8);font-size:12px}\n .ngxsp-debug[open]{padding:12px;max-height:calc(100% - 24px);overflow:auto;border-radius:10px;background:rgb(18 19 23 / .96);box-shadow:0 12px 32px rgb(0 0 0 / .45), 0 0 0 1px rgb(255 255 255 / .08)}\n .ngxsp-debug-actions{display:flex;gap:8px;margin:8px 0;flex-wrap:wrap}\n .ngxsp-debug pre{margin:0;white-space:pre-wrap;word-break:break-word;font-family:var(--nsp-font-mono, ui-monospace, Menlo, monospace);font-size:11px}\n `,\n})\nexport class PlayerOverlaysComponent {\n readonly error = input<PlayerError | null>(null);\n readonly debug = input(false);\n readonly debugJson = input('{}');\n\n readonly retry = output<void>();\n readonly requestPlay = output<void>();\n readonly copyJson = output<void>();\n readonly downloadJson = output<void>();\n\n private readonly code = computed(() => this.error()?.code ?? 'UNKNOWN');\n\n readonly autoplayBlocked = computed(() => this.code() === 'AUTOPLAY_BLOCKED');\n\n readonly title = computed(() => {\n switch (this.code()) {\n case 'ENGINE_MISSING':\n return 'Playback engine missing';\n case 'AUTOPLAY_BLOCKED':\n return 'Click to start playback';\n case 'NETWORK_HTTP':\n return 'Network error';\n case 'DECODE_ERROR':\n return 'Decode error';\n case 'SRC_NOT_SUPPORTED':\n return 'Format not supported';\n default:\n return 'Playback error';\n }\n });\n\n readonly hint = computed(() => {\n switch (this.code()) {\n case 'ENGINE_MISSING':\n return 'This source requires an additional engine. Install @ngxsp/engine-shaka and pass it via [engines].';\n case 'AUTOPLAY_BLOCKED':\n return 'Your browser blocked autoplay. Press Play to start.';\n case 'NETWORK_HTTP':\n return 'Check your connection or try again.';\n default:\n return this.error()?.message ? String(this.error()!.message) : 'Unknown error';\n }\n });\n}\n","import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { SmartPlayerIconComponent } from './smart-player-icon.component';\nimport { NgxspPlayButton, NgxspTimeSlider, NgxspVolumeControl, type SourceProfile } from '@ngxsplayer/ngx-smart-player-ui-core';\n\nexport type RepeatMode = 'off' | 'one' | 'all';\nexport type PlayerMenuKind = 'tracks' | 'speed';\n\n/**\n * Barre de contrôle du skin classique, extraite du SmartPlayerComponent\n * (décomposition, cf. docs/AUDIT.md). Sans accès au moteur ni au <video> :\n * reçoit l'état + les capacités (cast/PiP) en entrée et émet les commandes ;\n * l'hôte applique l'action (et possède l'élément vidéo pour PiP/cast).\n */\n@Component({\n selector: 'ngxsp-player-controls',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SmartPlayerIconComponent, NgxspPlayButton, NgxspTimeSlider, NgxspVolumeControl],\n template: `\n <div class=\"ngxsp-controls\">\n <ngxsp-play-button class=\"ngxsp-btn\" [playing]=\"playing()\" (playToggle)=\"playToggle.emit()\">\n @if (playing()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"pause\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"play\" />\n }\n </ngxsp-play-button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"seekRelative.emit(-10)\" aria-label=\"Seek backward 10 seconds\" title=\"Seek backward 10 seconds\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"seek-back\" />\n </button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"seekRelative.emit(10)\" aria-label=\"Seek forward 10 seconds\" title=\"Seek forward 10 seconds\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"seek-forward\" />\n </button>\n @if (hasPlaylistControls()) {\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"prev.emit()\" [disabled]=\"!canPrev()\" aria-label=\"Previous item\" title=\"Previous item\"><ngxsp-smart-icon class=\"ngxsp-icon\" name=\"prev\" /></button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"next.emit()\" [disabled]=\"!canNext()\" aria-label=\"Next item\" title=\"Next item\"><ngxsp-smart-icon class=\"ngxsp-icon\" name=\"next\" /></button>\n <button type=\"button\" class=\"ngxsp-btn\" [class.accent]=\"shuffleActive()\" (click)=\"toggleShuffle.emit()\" [attr.title]=\"shuffleLabel()\" [attr.aria-label]=\"shuffleLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"shuffle\" />\n </button>\n <button type=\"button\" class=\"ngxsp-btn\" [class.accent]=\"repeatMode() !== 'off'\" (click)=\"cycleRepeat.emit()\" [attr.title]=\"repeatLabel()\" [attr.aria-label]=\"repeatLabel()\">\n @if (repeatMode() === 'one') {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"repeat-one\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"repeat\" />\n }\n </button>\n }\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"openMenu.emit('tracks')\" [attr.title]=\"tracksLabel()\" [attr.aria-label]=\"tracksLabel()\"><ngxsp-smart-icon class=\"ngxsp-icon\" name=\"tracks\" /></button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"captions.emit()\" [attr.title]=\"captionsLabel()\" [attr.aria-label]=\"captionsLabel()\">\n @if (captionsActive()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"captions\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"captions-off\" />\n }\n </button>\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"openMenu.emit('speed')\" [attr.title]=\"speedLabel()\" [attr.aria-label]=\"speedLabel()\"><ngxsp-smart-icon class=\"ngxsp-icon\" name=\"speed\" /></button>\n @if (showAirPlay()) {\n <button type=\"button\" class=\"ngxsp-btn\" [class.accent]=\"airPlayActive()\" (click)=\"airPlay.emit()\" [attr.title]=\"airPlayLabel()\" [attr.aria-label]=\"airPlayLabel()\">\n @if (airPlayActive()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"airplay-active\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"airplay\" />\n }\n </button>\n }\n @if (showCast()) {\n <button type=\"button\" class=\"ngxsp-btn\" [class.accent]=\"castActive()\" (click)=\"cast.emit()\" [attr.title]=\"castHint()\" [attr.aria-label]=\"castLabel()\">\n @if (castActive()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"cast-active\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"cast\" />\n }\n </button>\n }\n @if (!isAudioMode() && pipSupported()) {\n <button type=\"button\" class=\"ngxsp-btn\" (click)=\"pip.emit()\" [attr.title]=\"pipLabel()\" [attr.aria-label]=\"pipLabel()\">\n @if (pipActive()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"pip-active\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"pip\" />\n }\n </button>\n }\n <ngxsp-volume-control\n class=\"ngxsp-volumeControl\"\n [volume]=\"volume()\"\n [volumeLabel]=\"volumeLabel()\"\n [muteLabel]=\"muteLabel()\"\n [unmuteLabel]=\"unmuteLabel()\"\n (muteToggle)=\"mute.emit()\"\n (volumeChange)=\"volumeChange.emit($event)\"\n />\n\n <ngxsp-time-slider\n style=\"flex:1 1 160px; min-width:160px\"\n [currentTime]=\"currentTime()\"\n [duration]=\"duration()\"\n [buffered]=\"buffered()\"\n [profile]=\"profile()\"\n (seek)=\"scrub.emit($event)\"\n />\n\n <div class=\"ngxsp-time\">{{ fmtTime(currentTime()) }} / {{ fmtTime(duration()) }}</div>\n\n </div>\n `,\n styles: `\n :host { display: block; }\n .ngxsp-controls{display:flex;gap:8px;align-items:center;padding:10px;flex-wrap:wrap}\n .ngxsp-btn{background:linear-gradient(180deg, rgba(19,34,54,.92), rgba(11,21,35,.92));border:1px solid var(--ngxsp-border, rgba(148,163,184,.18));color:var(--ngxsp-text, #e6eef8);border-radius:12px;padding:8px 10px;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:8px;box-shadow:inset 0 1px 0 rgba(255,255,255,.05), 0 10px 24px rgba(2,6,23,.18);transition:border-color .18s ease, background .18s ease, transform .18s ease, color .18s ease}\n .ngxsp-btn.accent{background:linear-gradient(180deg, rgba(20,48,74,.96), rgba(13,33,53,.96));border-color:var(--ngxsp-border-strong, rgba(191,219,254,.24));color:#d8f3ff}\n .ngxsp-btn:hover{border-color:rgba(191,219,254,.34); background:linear-gradient(180deg, rgba(24,46,71,.94), rgba(12,27,44,.94))}\n .ngxsp-btn:disabled{opacity:.38; cursor:not-allowed}\n .ngxsp-btn:focus-visible{outline:none; box-shadow:var(--ngxsp-focus-ring, 0 0 0 3px rgb(108 182 255 / .5))}\n .ngxsp-icon{width:18px;height:18px;display:block;flex:0 0 auto}\n .ngxsp-time{color:var(--ngxsp-text-dim, rgba(230,238,248,.72));font-variant-numeric:tabular-nums}\n .ngxsp-volumeControl{\n --ngxsp-control-size: 38px;\n --ngxsp-volume-range-max: 140px;\n --ngxsp-volume-button-bg: linear-gradient(180deg, rgba(19,34,54,.92), rgba(11,21,35,.92));\n --ngxsp-volume-button-border: 1px solid var(--ngxsp-border, rgba(148,163,184,.18));\n --ngxsp-volume-accent: var(--nsp-accent, #7dd3fc);\n --ngxsp-volume-thumb-bg: var(--nsp-text, #f8fbff);\n color: var(--ngxsp-text, #e6eef8);\n }\n @media (max-width: 640px){\n .ngxsp-controls{padding:8px;gap:6px}\n .ngxsp-btn{padding:7px 9px;border-radius:10px}\n .ngxsp-icon{width:16px;height:16px}\n }\n `,\n})\nexport class PlayerControlsComponent {\n readonly playing = input(false);\n readonly isAudioMode = input(false);\n readonly hasPlaylistControls = input(false);\n readonly canPrev = input(false);\n readonly canNext = input(false);\n readonly shuffleActive = input(false);\n readonly shuffleLabel = input('Shuffle: off');\n readonly repeatMode = input<RepeatMode>('off');\n readonly repeatLabel = input('Repeat: off');\n readonly captionsActive = input(false);\n readonly tracksLabel = input('Tracks');\n readonly captionsLabel = input('Load subtitles');\n readonly speedLabel = input('1x');\n readonly volumeLabel = input('Volume');\n readonly muteLabel = input('Mute');\n readonly unmuteLabel = input('Restore sound');\n readonly showAirPlay = input(false);\n readonly airPlayActive = input(false);\n readonly airPlayLabel = input('AirPlay');\n readonly showCast = input(false);\n readonly castActive = input(false);\n readonly castLabel = input('Play on device');\n readonly castHint = input('');\n readonly pipSupported = input(false);\n readonly pipActive = input(false);\n readonly pipLabel = input('PiP');\n readonly volume = input(1);\n readonly currentTime = input(0);\n readonly duration = input(0);\n readonly buffered = input(0);\n readonly profile = input<SourceProfile>('vod');\n\n readonly playToggle = output<void>();\n readonly seekRelative = output<number>();\n readonly prev = output<void>();\n readonly next = output<void>();\n readonly toggleShuffle = output<void>();\n readonly cycleRepeat = output<void>();\n readonly openMenu = output<PlayerMenuKind>();\n readonly captions = output<void>();\n readonly airPlay = output<void>();\n readonly cast = output<void>();\n readonly pip = output<void>();\n readonly mute = output<void>();\n readonly scrub = output<number>();\n readonly volumeChange = output<number>();\n\n fmtTime(sec: number): string {\n const s = Math.max(0, Math.floor(sec || 0));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const r = s % 60;\n if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(r).padStart(2, '0')}`;\n return `${m}:${String(r).padStart(2, '0')}`;\n }\n}\n","import { ChangeDetectionStrategy, Component, input, output, computed } from '@angular/core';\nimport { SmartPlayerIconComponent } from './smart-player-icon.component';\nimport { NgxspPlayButton, NgxspTimeSlider, NgxspVolumeControl, type NgxspTimelineMarker, type SourceProfile } from '@ngxsplayer/ngx-smart-player-ui-core';\nimport type { RepeatMode, PlayerMenuKind } from './player-controls.component';\n\n/**\n * Barre de contrôle du skin vod (top bar + center dock + bottom bar),\n * extraite du SmartPlayerComponent (décomposition, cf. docs/AUDIT.md).\n * Le menu pistes/vitesse est projeté par l'hôte via <ng-content>.\n * PiP/cast restent au parent (propriétaire du <video>) : capacités en entrée,\n * commandes en sortie.\n */\n@Component({\n selector: 'ngxsp-player-controls-vod',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SmartPlayerIconComponent, NgxspPlayButton, NgxspTimeSlider, NgxspVolumeControl],\n template: `\n <div class=\"ngxsp-vod-top\">\n <div class=\"ngxsp-vod-titleWrap\">\n <div class=\"ngxsp-vod-eyebrow\">{{ isAudioMode() ? nowListeningLabel() : nowPlayingLabel() }}</div>\n <div class=\"ngxsp-vod-title\">{{ displayTitle() }}</div>\n </div>\n <div class=\"ngxsp-vod-spacer\"></div>\n <div class=\"ngxsp-vod-status\" [attr.data-state]=\"playing() ? 'playing' : 'idle'\">{{ statusLabel() }}</div>\n @if (!isAudioMode()) {\n <div class=\"ngxsp-vod-topHint\">{{ fullscreenHintLabel() }}</div>\n }\n </div>\n\n <div class=\"ngxsp-vod-centerDock\">\n @if (hasPlaylistControls()) {\n <button type=\"button\" class=\"ngxsp-vod-side\" (click)=\"prev.emit()\" [disabled]=\"!canPrev()\" [attr.aria-label]=\"previousLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"prev\" />\n </button>\n }\n <button type=\"button\" class=\"ngxsp-vod-side ngxsp-vod-side-wide\" (click)=\"seekRelative.emit(-10)\" aria-label=\"Seek backward 10 seconds\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"seek-back\" />\n </button>\n <ngxsp-play-button class=\"ngxsp-vod-center\" [playing]=\"playing()\" [playLabel]=\"playLabel()\" [pauseLabel]=\"pauseLabel()\" (playToggle)=\"playToggle.emit()\">\n @if (playing()) {\n <ngxsp-smart-icon class=\"ngxsp-icon ngxsp-icon-lg\" name=\"pause\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon ngxsp-icon-lg\" name=\"play\" />\n }\n </ngxsp-play-button>\n <button type=\"button\" class=\"ngxsp-vod-side ngxsp-vod-side-wide\" (click)=\"seekRelative.emit(10)\" aria-label=\"Seek forward 10 seconds\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"seek-forward\" />\n </button>\n @if (hasPlaylistControls()) {\n <button type=\"button\" class=\"ngxsp-vod-side\" (click)=\"next.emit()\" [disabled]=\"!canNext()\" [attr.aria-label]=\"nextLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"next\" />\n </button>\n }\n </div>\n\n <div class=\"ngxsp-controls ngxsp-vod-bottom\">\n <div class=\"ngxsp-vod-metaRow\">\n @if (hasPlaylistControls()) {\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-prev\" (click)=\"prev.emit()\" [disabled]=\"!canPrev()\" [attr.title]=\"previousLabel()\" [attr.aria-label]=\"previousLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"prev\" />\n </button>\n }\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-play\" (click)=\"playToggle.emit()\" [attr.title]=\"playing() ? pauseLabel() : playLabel()\" [attr.aria-label]=\"playing() ? pauseLabel() : playLabel()\">\n @if (playing()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"pause\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"play\" />\n }\n </button>\n @if (hasPlaylistControls()) {\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-next\" (click)=\"next.emit()\" [disabled]=\"!canNext()\" [attr.title]=\"nextLabel()\" [attr.aria-label]=\"nextLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"next\" />\n </button>\n }\n <div class=\"ngxsp-vod-time\">{{ fmtTime(currentTime()) }} / {{ fmtTime(duration()) }}</div>\n <div class=\"ngxsp-vod-volumeGroup\">\n <ngxsp-volume-control\n class=\"ngxsp-vod-volumeControl\"\n [compact]=\"true\"\n [volume]=\"volume()\"\n [volumeLabel]=\"volumeLabel()\"\n [muteLabel]=\"muteLabel()\"\n [unmuteLabel]=\"unmuteLabel()\"\n (muteToggle)=\"mute.emit()\"\n (volumeChange)=\"volumeChange.emit($event)\"\n />\n </div>\n <ng-content select=\"[ngxsp-player-inline-controls]\" />\n <div class=\"ngxsp-vod-spacer\"></div>\n @if (hasPlaylistControls()) {\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-playlist\" [class.accent]=\"shuffleActive()\" (click)=\"toggleShuffle.emit()\" [attr.title]=\"shuffleLabel()\" [attr.aria-label]=\"shuffleLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"shuffle\" />\n </button>\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-playlist\" [class.accent]=\"repeatMode() !== 'off'\" (click)=\"cycleRepeat.emit()\" [attr.title]=\"repeatLabel()\" [attr.aria-label]=\"repeatLabel()\">\n @if (repeatMode() === 'one') {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"repeat-one\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"repeat\" />\n }\n </button>\n }\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-tracks\" (click)=\"openMenu.emit('tracks')\" [attr.title]=\"tracksLabel()\" [attr.aria-label]=\"tracksLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"tracks\" />\n </button>\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-captions\" (click)=\"captions.emit()\" [attr.title]=\"captionsLabel()\" [attr.aria-label]=\"captionsLabel()\">\n @if (captionsActive()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"captions\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"captions-off\" />\n }\n </button>\n <!-- The rate itself, as a pill: what it is shows at a glance. -->\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-speed\" (click)=\"openMenu.emit('speed')\" [attr.title]=\"speedLabel()\" [attr.aria-label]=\"speedLabel()\">\n <span class=\"ngxsp-vod-speedBadge\">{{ speedBadge() }}</span>\n </button>\n @if (showAirPlay()) {\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-airplay\" [class.accent]=\"airPlayActive()\" (click)=\"airPlay.emit()\" [attr.title]=\"airPlayLabel()\" [attr.aria-label]=\"airPlayLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" [name]=\"airPlayActive() ? 'airplay-active' : 'airplay'\" />\n </button>\n }\n @if (showCast()) {\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-cast\" [class.accent]=\"castActive()\" (click)=\"cast.emit()\" [attr.title]=\"castHint()\" [attr.aria-label]=\"castLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" [name]=\"castActive() ? 'devices-active' : 'devices'\" />\n </button>\n }\n @if (!isAudioMode() && pipSupported()) {\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-pip\" (click)=\"pip.emit()\" [attr.title]=\"pipLabel()\" [attr.aria-label]=\"pipLabel()\">\n @if (pipActive()) {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"pip-active\" />\n } @else {\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"pip\" />\n }\n </button>\n }\n @if (!isAudioMode()) {\n <button type=\"button\" class=\"ngxsp-vod-chip ngxsp-vod-chip-fullscreen\" (click)=\"fullscreen.emit()\" [attr.title]=\"fullscreenLabel()\" [attr.aria-label]=\"fullscreenLabel()\">\n <ngxsp-smart-icon class=\"ngxsp-icon\" name=\"fullscreen\" />\n </button>\n }\n </div>\n\n <ngxsp-time-slider\n class=\"ngxsp-vod-range\"\n [currentTime]=\"currentTime()\"\n [duration]=\"duration()\"\n [buffered]=\"buffered()\"\n [profile]=\"profile()\"\n [durationHintSec]=\"timelineDurationSec()\"\n [markers]=\"timelineMarkers()\"\n (seek)=\"scrub.emit($event)\"\n />\n\n <ng-content select=\"ngxsp-player-menu\" />\n </div>\n `,\n styles: `\n :host { display: contents; }\n .ngxsp-icon{width:20px;height:20px;display:block;flex:0 0 auto}\n .ngxsp-icon-lg{width:28px;height:28px}\n .ngxsp-vod-top{position:absolute;left:0;right:0;top:0;display:flex;align-items:flex-start;gap:12px;padding:16px 18px 40px;background:linear-gradient(to bottom, rgb(0 0 0 / .62), rgb(0 0 0 / 0));pointer-events:none;opacity:0;transition:opacity .2s ease;z-index:3}\n :host-context(.ngxsp-ui-visible) .ngxsp-vod-top{opacity:1}\n .ngxsp-vod-titleWrap{min-width:0;display:flex;flex-direction:column;gap:2px}\n .ngxsp-vod-eyebrow{font-size:12px;font-weight:600;color:rgb(255 255 255 / .72)}\n .ngxsp-vod-title{font-weight:600;font-size:16px;color:#fff;text-shadow:0 1px 2px rgb(0 0 0 / .5);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n .ngxsp-vod-topHint{display:none}\n .ngxsp-vod-status{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 10px;border-radius:999px;background:rgb(0 0 0 / .45);color:rgb(255 255 255 / .86);font-size:11px;font-weight:500;backdrop-filter:blur(8px)}\n .ngxsp-vod-status::before{content:'';width:6px;height:6px;border-radius:50%;background:rgb(255 255 255 / .5)}\n .ngxsp-vod-status[data-state='playing']::before{background:var(--nsp-success, #3ecf8e)}\n .ngxsp-vod-spacer{flex:1}\n .ngxsp-vod-centerDock{position:absolute;inset:0;margin:auto;width:max-content;height:max-content;display:flex;align-items:center;gap:20px;z-index:4;opacity:0;visibility:hidden;transform:scale(.96);transition:opacity .2s ease, transform .2s ease, visibility 0s linear .2s;pointer-events:none}\n :host-context(.ngxsp-ui-visible) .ngxsp-vod-centerDock{opacity:1;visibility:visible;transform:none;pointer-events:auto;transition:opacity .2s ease, transform .2s ease, visibility 0s}\n :host-context(.ngxsp-root[data-kind='error']) .ngxsp-vod-centerDock,\n :host-context(.ngxsp-root[data-kind='error']) .ngxsp-vod-top{display:none}\n .ngxsp-vod-center{height:68px;width:68px;border-radius:999px;border:0;background:rgb(255 255 255 / .94);color:#0d0e11;display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 12px 40px rgb(0 0 0 / .45);transition:transform .15s ease, background-color .15s ease}\n .ngxsp-vod-center:hover{transform:scale(1.05);background:#fff}\n .ngxsp-vod-side{position:relative;height:48px;min-width:48px;width:48px;border-radius:999px;border:0;background:rgb(0 0 0 / .45);color:#fff;padding:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;backdrop-filter:blur(10px);transition:background-color .15s ease}\n .ngxsp-vod-side-wide{min-width:48px}\n .ngxsp-vod-side-wide .ngxsp-icon{width:24px;height:24px}\n .ngxsp-vod-side:hover{background:rgb(0 0 0 / .65)}\n .ngxsp-vod-bottom{position:absolute;left:0;right:0;bottom:0;padding:40px 14px 8px;background:linear-gradient(180deg, rgb(0 0 0 / 0), rgb(0 0 0 / .55) 45%, rgb(0 0 0 / .82));display:flex;flex-direction:column;align-items:stretch;gap:0;z-index:4;opacity:0;transition:opacity .2s ease}\n :host-context(.ngxsp-ui-visible) .ngxsp-vod-bottom{opacity:1}\n .ngxsp-vod-metaRow{display:flex;align-items:center;gap:4px;width:100%;min-height:40px}\n .ngxsp-vod-speedBadge{box-sizing:border-box;min-width:30px;padding:2px 5px;border:1.5px solid currentColor;border-radius:999px;font-size:11px;font-weight:700;line-height:1.2;font-variant-numeric:tabular-nums;white-space:nowrap}\n .ngxsp-vod-time{padding:0 8px;color:rgb(255 255 255 / .92);font-variant-numeric:tabular-nums;font-size:12px;font-weight:500;white-space:nowrap}\n .ngxsp-vod-range{\n order:-1;\n min-width:100%;\n min-height:32px;\n --ngxsp-track-size:4px;\n --ngxsp-track-bg:rgb(255 255 255 / .22);\n --ngxsp-buffered-bg:rgb(255 255 255 / .34);\n --ngxsp-accent:var(--nsp-media-accent, #8b90ff);\n --ngxsp-thumb-size:13px;\n --ngxsp-thumb-bg:#fff;\n --ngxsp-marker-width:2px;\n --ngxsp-marker-height:8px;\n --ngxsp-marker-bg:rgb(0 0 0 / .55);\n --ngxsp-marker-active-bg:#fff;\n --ngxsp-marker-active-shadow:none;\n --ngxsp-preview-bg:rgb(13 14 17 / .92);\n --ngxsp-preview-border:rgb(255 255 255 / .12);\n --ngxsp-preview-muted:rgb(255 255 255 / .64);\n }\n .ngxsp-vod-range:hover{--ngxsp-track-size:6px}\n .ngxsp-vod-volumeGroup{display:inline-flex;align-items:center}\n .ngxsp-vod-volumeControl{\n --ngxsp-control-size:36px;\n --ngxsp-volume-compact-min:72px;\n --ngxsp-volume-compact-max:104px;\n --ngxsp-volume-button-bg:transparent;\n --ngxsp-volume-button-border:0;\n --ngxsp-volume-button-radius:6px;\n --ngxsp-volume-accent:#fff;\n --ngxsp-volume-track-bg:rgb(255 255 255 / .28);\n --ngxsp-volume-thumb-bg:#fff;\n --ngxsp-volume-thumb-size:12px;\n --ngxsp-volume-thumb-shadow:none;\n --ngxsp-focus-ring:0 0 0 2px var(--nsp-media-accent, #8b90ff);\n color:#fff;\n }\n .ngxsp-vod-label{font-size:12px;color:rgb(255 255 255 / .64)}\n .ngxsp-vod-chip{position:relative;width:36px;height:36px;min-width:36px;min-height:36px;padding:0;border:0;border-radius:6px;background:transparent;color:rgb(255 255 255 / .92);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;transition:background-color .15s ease, color .15s ease}\n .ngxsp-vod-chip:hover:not(:disabled){background:rgb(255 255 255 / .12);color:#fff}\n .ngxsp-vod-chip:disabled{opacity:.4;cursor:default}\n .ngxsp-vod-chip.accent{color:var(--nsp-media-accent, #8b90ff)}\n .ngxsp-vod-chip-quiet{background:transparent}\n .ngxsp-vod-center:disabled,\n .ngxsp-vod-side:disabled{opacity:.38;cursor:not-allowed}\n .ngxsp-vod-center:focus-visible,\n .ngxsp-vod-side:focus-visible,\n .ngxsp-vod-chip:focus-visible{outline:2px solid var(--nsp-media-accent, #8b90ff);outline-offset:1px}\n .ngxsp-buffer{height:4px;border-radius:999px;background:rgb(255 255 255 / .12);overflow:hidden}\n .ngxsp-bufferFill{height:100%;border-radius:999px;background:var(--nsp-media-accent, #8b90ff)}\n @media (max-width: 860px){\n .ngxsp-vod-top{padding:12px 14px 28px}\n .ngxsp-vod-centerDock{gap:14px}\n .ngxsp-vod-center{height:58px;width:58px}\n .ngxsp-vod-side{height:42px;width:42px;min-width:42px}\n .ngxsp-vod-bottom{padding:36px 8px 6px}\n .ngxsp-vod-chip-speed,\n .ngxsp-vod-chip-tracks{display:none}\n }\n @media (max-width: 640px){\n .ngxsp-icon{width:18px;height:18px}\n .ngxsp-icon-lg{width:24px;height:24px}\n .ngxsp-vod-title{font-size:14px}\n .ngxsp-vod-status{display:none}\n .ngxsp-vod-time{font-size:11px;padding:0 4px}\n .ngxsp-vod-center{height:52px;width:52px}\n .ngxsp-vod-side{height:38px;width:38px;min-width:38px}\n .ngxsp-vod-metaRow{min-height:34px;gap:2px}\n .ngxsp-vod-chip{width:32px;height:32px;min-width:32px;min-height:32px}\n .ngxsp-vod-bottom .ngxsp-vod-volumeControl.ngxsp-vc-compact ::ng-deep .ngxsp-vc-shell{grid-template-columns:32px 64px}\n .ngxsp-vod-bottom .ngxsp-vod-volumeControl.ngxsp-vc-compact ::ng-deep .ngxsp-vc-range{opacity:1;visibility:visible;transform:none;pointer-events:auto}\n .ngxsp-vod-chip-playlist,\n .ngxsp-vod-chip-captions,\n .ngxsp-vod-chip-pip,\n .ngxsp-vod-top,\n .ngxsp-vod-side{display:none}\n }\n @media (prefers-reduced-motion: reduce){\n .ngxsp-vod-top,.ngxsp-vod-centerDock,.ngxsp-vod-bottom,.ngxsp-vod-center,.ngxsp-vod-side,.ngxsp-vod-chip{transition:none}\n }\n `,\n})\nexport class PlayerControlsVodComponent {\n readonly playing = input(false);\n readonly isAudioMode = input(false);\n readonly displayTitle = input('Player');\n readonly nowPlayingLabel = input('Now playing');\n readonly nowListeningLabel = input('Now listening');\n readonly fullscreenHintLabel = input('Double-click for fullscreen');\n readonly statusLabel = input('Ready');\n readonly keyboardHint = input('');\n readonly hasPlaylistControls = input(false);\n readonly canPrev = input(false);\n readonly canNext = input(false);\n readonly previousLabel = input('Previous item');\n readonly nextLabel = input('Next item');\n readonly playLabel = input('Play');\n readonly pauseLabel = input('Pause');\n readonly shuffleActive = input(false);\n readonly shuffleLabel = input('Shuffle: off');\n readonly repeatMode = input<RepeatMode>('off');\n readonly repeatLabel = input('Repeat: off');\n readonly captionsActive = input(false);\n readonly tracksLabel = input('Tracks');\n readonly captionsLabel = input('Load subtitles');\n readonly speedLabel = input('1x');\n /** \"1×\", \"1.5×\": the rate on the speed pill. */\n readonly speedBadge = computed(() => this.speedLabel().replace(/x$/i, '×'));\n readonly volumeLabel = input('Volume');\n readonly muteLabel = input('Mute');\n readonly unmuteLabel = input('Restore sound');\n readonly showAirPlay = input(false);\n readonly airPlayActive = input(false);\n readonly airPlayLabel = input('AirPlay');\n readonly showCast = input(false);\n readonly castActive = input(false);\n readonly castLabel = input('Play on device');\n readonly castHint = input('');\n readonly pipSupported = input(false);\n readonly pipActive = input(false);\n readonly pipLabel = input('PiP');\n readonly fullscreenLabel = input('Fullscreen');\n readonly volume = input(1);\n readonly currentTime = input(0);\n readonly duration = input(0);\n readonly buffered = input(0);\n readonly bufferPercent = input(0);\n readonly profile = input<SourceProfile>('vod');\n readonly timelineDurationSec = input(0);\n readonly timelineMarkers = input<ReadonlyArray<NgxspTimelineMarker>>([]);\n\n readonly playToggle = output<void>();\n readonly seekRelative = output<number>();\n readonly prev = output<void>();\n readonly next = output<void>();\n readonly toggleShuffle = output<void>();\n readonly cycleRepeat = output<void>();\n readonly openMenu = output<PlayerMenuKind>();\n readonly captions = output<void>();\n readonly airPlay = output<void>();\n readonly cast = output<void>();\n readonly pip = output<void>();\n readonly fullscreen = output<void>();\n readonly mute = output<void>();\n readonly scrub = output<number>();\n readonly volumeChange = output<number>();\n\n fmtTime(sec: number): string {\n const s = Math.max(0, Math.floor(sec || 0));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const r = s % 60;\n if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(r).padStart(2, '0')}`;\n return `${m}:${String(r).padStart(2, '0')}`;\n }\n}\n","import { ChangeDetectionStrategy, Component, input, output } from '@angular/core';\nimport { SmartPlayerIconComponent } from './smart-player-icon.component';\nimport {\n NgxspPlayButton,\n NgxspTimeSlider,\n NgxspVolumeControl,\n NgxspLabeledControl,\n NgxspLiveBadge,\n type SourceProfile,\n} from '@ngxsplayer/ngx-smart-player-ui-core';\nimport type { PlayerMenuKind } from './player-controls.component';\n\n/**\n * Skin « édition » du lecteur : registre instrument (cf. docs/UX_VISION.md).\n * Titre display, coins francs, libellés en capitales, accent champagne, et le\n * traitement direct (NgxspLiveBadge + « Au direct ») en profil `live`.\n * Compose les primitives de @ngxsp/ui-core. Le menu est projeté via <ng-content>.\n */\n@Component({\n selector: 'ngxsp-player-controls-edition',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [SmartPlayerIconComponent, NgxspPlayButton, NgxspTimeSlider, NgxspVolumeControl, NgxspLabeledControl, NgxspLiveBadge],\n template: `\n <div class=\"ed-top\">\n @if (profile() === 'live') {\n <ngxsp-live-badge [behindSec]=\"behindSec()\" />\n }\n <div class=\"ed-titleWrap\">\n <div class=\"ed-title\">{{ displayTitle() }}</div>\n <div class=\"ed-meta\">{{ metaLabel() }}</div>\n </div>\n <span class=\"ed-spacer\"></span>\n <div class=\"ed-status\">{{ statusLabel() }}</div>\n </div>\n\n <div class=\"ed-bottom\">\n <div class=\"ed-scrubRow\">\n <span class=\"ed-time\">{{ fmtTime(currentTime()) }}</span>\n <ngxsp-time-slider\n style=\"flex:1\"\n [currentTime]=\"currentTime()\"\n [duration]=\"duration()\"\n [buffered]=\"buffered()\"\n [profile]=\"profile()\"\n (seek)=\"scrub.emit($event)\"\n />\n <span class=\"ed-time ed-time-dim\">{{ profile() === 'live' ? liveLabel() : fmtTime(duration()) }}</span>\n </div>\n\n <div class=\"ed-controlsRow\">\n @if (profile() === 'live') {\n <button type=\"button\" class=\"ed-live\" (click)=\"goLive.emit()\">\n <ngxsp-smart-icon class=\"ed-icon\" name=\"next\" /> Au direct\n </button>\n <ngxsp-play-button class=\"ed-transport\" [playing]=\"playing()\" (playToggle)=\"playToggle.emit()\">\n @if (playing()) { <ngxsp-smart-icon class=\"ed-icon\" name=\"pause\" /> } @else { <ngxsp-smart-icon class=\"ed-icon\" name=\"play\" /> }\n </ngxsp-play-button>\n } @else {\n <button type=\"button\" class=\"ed-transport\" (click)=\"seekRelative.emit(-10)\" aria-label=\"Reculer 10 secondes\"><ngxsp-smart-icon class=\"ed-icon\" name=\"seek-back\" /></button>\n <ngxsp-play-button class=\"ed-transport ed-transport-primary\" [playing]=\"playing()\" (playToggle)=\"playToggle.emit()\">\n @if (playing()) { <ngxsp-smart-icon class=\"ed-icon\" name=\"pause\" /> } @else { <ngxsp-smart-icon class=\"ed-icon\" name=\"play\" /> }\n </ngxsp-play-button>\n <button type=\"button\" class=\"ed-transport\" (click)=\"seekRelative.emit(10)\" aria-label=\"Avancer 10 secondes\"><ngxsp-smart-icon class=\"ed-icon\" name=\"seek-forward\" /></button>\n }\n\n <span class=\"ed-spacer\"></span>\n\n <ngxsp-labeled-control label=\"Sous-titres\" [pressed]=\"captionsActive()\" (activate)=\"captions.emit()\"><ngxsp-smart-icon class=\"ed-icon\" [name]=\"captionsActive() ? 'captions' : 'captions-off'\" /></ngxsp-labeled-control>\n <ngxsp-labeled-control label=\"Pistes\" (activate)=\"openMenu.emit('tracks')\"><ngxsp-smart-icon class=\"ed-icon\" name=\"tracks\" /></ngxsp-labeled-control>\n <ngxsp-labeled-control [label]=\"speedLabel()\" (activate)=\"openMenu.emit('speed')\"><ngxsp-smart-icon class=\"ed-icon\" name=\"speed\" /></ngxsp-labeled-control>\n @if (showAirPlay()) {\n <ngxsp-labeled-control [label]=\"airPlayLabel()\" [active]=\"airPlayActive()\" (activate)=\"airPlay.emit()\"><ngxsp-smart-icon class=\"ed-icon\" [name]=\"airPlayActive() ? 'airplay-active' : 'airplay'\" /></ngxsp-labeled-control>\n }\n @if (showCast()) {\n <ngxsp-labeled-control label=\"Diffuser\" [active]=\"castActive()\" (activate)=\"cast.emit()\"><ngxsp-smart-icon class=\"ed-icon\" [name]=\"castActive() ? 'cast-active' : 'cast'\" /></ngxsp-labeled-control>\n }\n @if (pipSupported()) {\n <ngxsp-labeled-control label=\"PiP\" [active]=\"pipActive()\" (activate)=\"pip.emit()\"><ngxsp-smart-icon class=\"ed-icon\" [name]=\"pipActive() ? 'pip-active' : 'pip'\" /></ngxsp-labeled-control>\n }\n <ngxsp-volume-control\n class=\"ed-volumeControl\"\n [compact]=\"true\"\n [volume]=\"volume()\"\n [volumeLabel]=\"volumeLabel()\"\n [muteLabel]=\"muteLabel()\"\n [unmuteLabel]=\"unmuteLabel()\"\n (muteToggle)=\"mute.emit()\"\n (volumeChange)=\"volumeChange.emit($event)\"\n />\n </div>\n\n <ng-content />\n </div>\n `,\n styles: `\n :host { display: contents; }\n .ed-icon { width: 20px; height: 20px; display: block; }\n .ed-top {\n position: absolute; left: 0; right: 0; top: 0; z-index: 3;\n display: flex; align-items: center; gap: 14px;\n padding: 18px 22px 14px;\n background: color-mix(in srgb, var(--nsp-bg, #14161b) 55%, transparent);\n border-bottom: 1px solid var(--nsp-line, rgb(255 255 255 / 0.1));\n opacity: 0; transition: opacity var(--nsp-dur, .18s) var(--nsp-ease, ease);\n }\n :host-context(.ngxsp-ui-visible) .ed-top { opacity: 1; }\n .ed-titleWrap { display: flex; flex-direction: column; gap: 6px; }\n .ed-title { font-size: 24px; font-weight: 500; letter-spacing: -.025em; line-height: 1; color: var(--nsp-text, #f4f2ec); }\n .ed-meta { font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--nsp-text-2, #b4afa6); }\n .ed-status { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--nsp-text-3, #7c776f); }\n .ed-spacer { flex: 1; }\n .ed-bottom {\n position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;\n display: flex; flex-direction: column; gap: 14px;\n padding: 16px 22px 18px;\n background: color-mix(in srgb, var(--nsp-bg, #14161b) 82%, transparent);\n border-top: 1px solid var(--nsp-line-strong, rgb(255 255 255 / 0.18));\n opacity: 0; transform: translateY(8px);\n transition: opacity var(--nsp-dur, .18s) var(--nsp-ease, ease), transform var(--nsp-dur, .18s) var(--nsp-ease, ease);\n }\n :host-context(.ngxsp-ui-visible) .ed-bottom { opacity: 1; transform: translateY(0); }\n .ed-scrubRow { display: flex; align-items: center; gap: 14px; }\n .ed-time { font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; color: var(--nsp-text, #f4f2ec); }\n .ed-time-dim { color: var(--nsp-text-2, #b4afa6); }\n .ed-controlsRow { display: flex; align-items: center; gap: 6px; }\n .ed-transport {\n all: unset; box-sizing: border-box;\n width: 46px; height: 46px;\n display: inline-flex; align-items: center; justify-content: center;\n border: 1px solid var(--nsp-line-strong, rgb(255 255 255 / 0.18));\n border-radius: var(--nsp-radius-sharp, 3px);\n color: var(--nsp-text, #f4f2ec); cursor: pointer;\n }\n .ed-transport-primary { background: var(--nsp-accent, #e3b26a); color: var(--nsp-on-accent, #14161b); border: none; }\n .ed-transport:focus-visible { outline: none; box-shadow: var(--nsp-focus-ring, 0 0 0 3px rgb(227 178 106 / .55)); }\n .ed-live {\n all: unset; box-sizing: border-box; height: 46px; padding: 0 16px;\n display: inline-flex; align-items: center; gap: 8px;\n background: var(--nsp-live, #e5402a); color: #fff; cursor: pointer;\n border-radius: var(--nsp-radius-sharp, 3px);\n font-size: 12px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase;\n }\n .ed-live:focus-visible { outline: none; box-shadow: var(--nsp-focus-ring, 0 0 0 3px rgb(227 178 106 / .55)); }\n .ed-volumeControl {\n --ngxsp-control-size: 46px;\n --ngxsp-volume-button-radius: var(--nsp-radius-sharp, 3px);\n --ngxsp-volume-button-bg: transparent;\n --ngxsp-volume-button-border: 1px solid var(--nsp-line-strong, rgb(255 255 255 / 0.18));\n --ngxsp-volume-accent: var(--nsp-accent, #e3b26a);\n --ngxsp-volume-compact-min: 96px;\n --ngxsp-volume-compact-max: 150px;\n --ngxsp-volume-color: var(--nsp-text, #f4f2ec);\n --ngxsp-focus-ring: var(--nsp-focus-ring, 0 0 0 3px rgb(227 178 106 / .55));\n }\n `,\n})\nexport class PlayerControlsEditionComponent {\n readonly profile = input<SourceProfile>('vod');\n readonly playing = input(false);\n readonly displayTitle = input('Player');\n readonly metaLabel = input('');\n readonly statusLabel = input('');\n readonly behindSec = input(0);\n readonly liveLabel = input('Direct');\n readonly captionsActive = input(false);\n readonly speedLabel = input('1x');\n readonly showAirPlay = input(false);\n readonly airPlayActive = input(false);\n readonly airPlayLabel = input('AirPlay');\n readonly showCast = input(false);\n readonly castActive = input(false);\n readonly pipSupported = input(false);\n readonly pipActive = input(false);\n readonly volume = input(1);\n readonly volumeLabel = input('Volume');\n readonly muteLabel = input('Mute');\n readonly unmuteLabel = input('Restore sound');\n readonly currentTime = input(0);\n readonly duration = input(0);\n readonly buffered = input(0);\n\n readonly playToggle = output<void>();\n readonly seekRelative = output<number>();\n readonly openMenu = output<PlayerMenuKind>();\n readonly captions = output<void>();\n readonly airPlay = output<void>();\n readonly cast = output<void>();\n readonly pip = output<void>();\n readonly mute = output<void>();\n readonly scrub = output<number>();\n readonly volumeChange = output<number>();\n readonly goLive = output<void>();\n\n fmtTime(sec: number): string {\n const s = Math.max(0, Math.floor(sec || 0));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const r = s % 60;\n if (h > 0) return `${h}:${String(m).padStart(2, '0')}:${String(r).padStart(2, '0')}`;\n return `${m}:${String(r).padStart(2, '0')}`;\n }\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, ViewChild, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { Subscription } from 'rxjs';\n\nimport { MediaTrack, PlayerConfig, PlayerState, PlayerPorts, PlayerError, createSsaiManifestRewritePlugin, decodeSubtitleBytes, describeSubtitleFile, subtitleTextToVtt, type EngineFactory } from '@ngxsp/core';\nimport { PlayerFacade } from '@ngxsp/core';\nimport { PlayerPlugin } from '@ngxsp/core';\nimport { type NgxspTimelineMarker, type SourceProfile } from '@ngxsplayer/ngx-smart-player-ui-core';\nimport { DEFAULT_PLAYER_MENU_LABELS, PlayerMenuComponent, type PlayerMenuLabels } from './player-menu.component';\nimport { PlayerOverlaysComponent } from './player-overlays.component';\nimport { PlayerControlsComponent } from './player-controls.component';\nimport { PlayerControlsVodComponent } from './player-controls-vod.component';\nimport { PlayerControlsEditionComponent } from './player-controls-edition.component';\nimport { SmartPlayerIconComponent } from './smart-player-icon.component';\n\n/** A playback position and the media it was measured on. */\nexport interface SmartPlayerProgress {\n currentTime: number;\n duration: number;\n contentId?: string;\n sourceUrl?: string;\n}\n\n@Component({\n selector: 'ngx-smart-player',\n standalone: true,\n imports: [CommonModule, PlayerMenuComponent, PlayerOverlaysComponent, PlayerControlsComponent, PlayerControlsVodComponent, PlayerControlsEditionComponent, SmartPlayerIconComponent],\n template: `\n <div class=\"ngxsp-root\" [class.ngxsp-skin-vod]=\"uiSkin==='vod'\" [class.ngxsp-ui-visible]=\"uiVisible\" [class.ngxsp-mode-audio]=\"isAudioMode\" [class.ngxsp-mode-video]=\"!isAudioMode\" [attr.data-kind]=\"state?.kind\">\n <!-- Surface de présentation : interactions pointeur non essentielles, toutes\n dupliquées au clavier par @HostListener('document:keydown') (Espace/flèches/F/M/C)\n et par les contrôles focusables. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div class=\"ngxsp-video\" (dblclick)=\"onPrimarySurfaceDoubleClick()\" (mousemove)=\"onInteraction()\" (mouseenter)=\"onInteraction()\" (mouseleave)=\"onPointerLeave()\" (focusin)=\"onInteraction()\" (touchstart)=\"onInteraction(true)\" (click)=\"onRootClick($event)\">\n <video #video playsinline x-webkit-airplay=\"allow\" (timeupdate)=\"noop()\" (loadedmetadata)=\"onLoadedMetadata()\" (ended)=\"onEnded()\"></video>\n <!-- Subtitles loaded from a file, drawn here at the bottom of the picture, above the controls when they show. -->\n <div #captionsLayer class=\"ngxsp-captions\" aria-hidden=\"true\"></div>\n @if (!isAudioMode) {\n <input #subtitleFileInput class=\"ngxsp-subtitleInput\" type=\"file\" accept=\".srt,.vtt,text/vtt,application/x-subrip\" hidden (change)=\"onSubtitleFileChosen($event)\" />\n }\n@if (isAudioMode) {\n<div class=\"ngxsp-audio-stage\" aria-hidden=\"true\">\n <div class=\"ngxsp-audio-disc\"></div>\n <div class=\"ngxsp-audio-copy\">\n <div class=\"ngxsp-audio-eyebrow\">Now Listening</div>\n <div class=\"ngxsp-audio-title\">{{displayTitle}}</div>\n <div class=\"ngxsp-audio-subtitle\">{{displaySubtitle}}</div>\n </div>\n <div class=\"ngxsp-audio-bars\">\n <span></span><span></span><span></span><span></span><span></span>\n </div>\n</div>\n}\n<ngxsp-player-overlays\n [error]=\"currentError\"\n [debug]=\"debug\"\n [debugJson]=\"debugJson\"\n (retry)=\"reload()\"\n (requestPlay)=\"tryPlay()\"\n (copyJson)=\"copyDebug()\"\n (downloadJson)=\"downloadDebug()\"\n/>\n@if (surfaceGesture) {\n<div class=\"ngxsp-gesturePulse\" aria-hidden=\"true\">\n @if (surfaceGesture === 'pause') {\n <ngxsp-smart-icon name=\"pause\" />\n } @else {\n <ngxsp-smart-icon name=\"play\" />\n }\n</div>\n}\n\n @if (uiSkin==='vod') {\n <ngxsp-player-controls-vod\n [playing]=\"state?.kind==='playing'\"\n [isAudioMode]=\"isAudioMode\"\n [displayTitle]=\"displayTitle\"\n [nowPlayingLabel]=\"nowPlayingLabel\"\n [nowListeningLabel]=\"nowListeningLabel\"\n [fullscreenHintLabel]=\"fullscreenHintLabel\"\n [statusLabel]=\"statusLabel()\"\n [keyboardHint]=\"keyboardHintLabel()\"\n [hasPlaylistControls]=\"hasPlaylistControls\"\n [canPrev]=\"canPrev\"\n [canNext]=\"canNext\"\n [previousLabel]=\"previousLabel\"\n [nextLabel]=\"nextLabel\"\n [playLabel]=\"playLabel\"\n [pauseLabel]=\"pauseLabel\"\n [shuffleActive]=\"shuffleActive\"\n [shuffleLabel]=\"shuffleLabel\"\n [repeatMode]=\"repeatMode\"\n [repeatLabel]=\"repeatLabel\"\n [captionsActive]=\"selectedTextTrackId !== null\"\n [tracksLabel]=\"tracksButtonLabel()\"\n [captionsLabel]=\"captionsLabel()\"\n [speedLabel]=\"playbackRateLabel()\"\n [volumeLabel]=\"outputVolumeLabel || volumeLabel()\"\n [muteLabel]=\"outputMuteLabel\"\n [unmuteLabel]=\"outputUnmuteLabel\"\n [showAirPlay]=\"showAirPlayButton()\"\n [airPlayActive]=\"isAirPlayActive()\"\n [airPlayLabel]=\"airPlayLabel()\"\n (airPlay)=\"openAirPlayPicker()\"\n [showCast]=\"showCastButton()\"\n [castActive]=\"isCastActive()\"\n [castLabel]=\"castLabel()\"\n [castHint]=\"castHintLabel()\"\n [pipSupported]=\"isPiPSupported()\"\n [pipActive]=\"isPiPActive()\"\n [pipLabel]=\"pipLabel()\"\n [fullscreenLabel]=\"fullscreenLabel\"\n [volume]=\"volume\"\n [currentTime]=\"currentTime\"\n [duration]=\"duration\"\n [buffered]=\"bufferAheadSec\"\n [bufferPercent]=\"bufferPercent()\"\n [profile]=\"sourceProfile\"\n [timelineDurationSec]=\"timelineDurationSec ?? 0\"\n [timelineMarkers]=\"timelineMarkers\"\n (playToggle)=\"requestPlaybackToggle()\"\n (seekRelative)=\"seekRel($event)\"\n (prev)=\"emitPrev()\"\n (next)=\"emitNext()\"\n (toggleShuffle)=\"toggleShuffle.emit()\"\n (cycleRepeat)=\"cycleRepeat.emit()\"\n (openMenu)=\"toggleMenu($event)\"\n (captions)=\"onCaptionsClick()\"\n (cast)=\"onCastClick()\"\n (pip)=\"togglePiP()\"\n (fullscreen)=\"toggleFullscreen()\"\n (mute)=\"toggleMute()\"\n (scrub)=\"onScrub($event)\"\n (volumeChange)=\"onVolume($event)\"\n >\n <div ngxsp-player-inline-controls class=\"ngxsp-inline-projection\">\n <ng-content select=\"[ngxsp-player-inline-controls]\" />\n </div>\n <ngxsp-player-menu\n [openMenu]=\"openMenu\"\n [isAudioMode]=\"isAudioMode\"\n [textTracks]=\"textTracks\"\n [audioTracks]=\"audioTracks\"\n [videoTracks]=\"videoTracks\"\n [selectedTextTrackId]=\"selectedTextTrackId\"\n [selectedAudioTrackId]=\"selectedAudioTrackId\"\n [selectedVideoTrackId]=\"selectedVideoTrackId\"\n [playbackRates]=\"playbackRates\"\n [playbackRate]=\"playbackRate\"\n [labels]=\"playerMenuLabels\"\n (loadSubtitles)=\"openSubtitlePicker()\"\n (selectText)=\"selectTextTrack($event)\"\n (selectAudio)=\"selectAudioTrack($event)\"\n (selectVideo)=\"selectVideoTrack($event)\"\n (selectRate)=\"setPlaybackRate($event)\"\n />\n </ngxsp-player-controls-vod>\n } @else if (uiSkin==='edition') {\n <ngxsp-player-controls-edition\n [profile]=\"sourceProfile\"\n [playing]=\"state?.kind==='playing'\"\n [displayTitle]=\"displayTitle\"\n [metaLabel]=\"editionMeta\"\n [statusLabel]=\"statusLabel()\"\n [captionsActive]=\"selectedTextTrackId !== null\"\n [speedLabel]=\"playbackRateLabel()\"\n [showAirPlay]=\"showAirPlayButton()\"\n [airPlayActive]=\"isAirPlayActive()\"\n [airPlayLabel]=\"airPlayLabel()\"\n (airPlay)=\"openAirPlayPicker()\"\n [showCast]=\"showCastButton()\"\n [castActive]=\"isCastActive()\"\n [pipSupported]=\"isPiPSupported()\"\n [pipActive]=\"isPiPActive()\"\n [volume]=\"volume\"\n [volumeLabel]=\"outputVolumeLabel || volumeLabel()\"\n [muteLabel]=\"outputMuteLabel\"\n [unmuteLabel]=\"outputUnmuteLabel\"\n [currentTime]=\"currentTime\"\n [duration]=\"duration\"\n [buffered]=\"bufferAheadSec\"\n (playToggle)=\"requestPlaybackToggle()\"\n (seekRelative)=\"seekRel($event)\"\n (openMenu)=\"toggleMenu($event)\"\n (captions)=\"onCaptionsClick()\"\n (cast)=\"onCastClick()\"\n (pip)=\"togglePiP()\"\n (mute)=\"toggleMute()\"\n (scrub)=\"onScrub($event)\"\n (volumeChange)=\"onVolume($event)\"\n (goLive)=\"reload()\"\n >\n <ngxsp-player-menu\n [openMenu]=\"openMenu\"\n [isAudioMode]=\"isAudioMode\"\n [textTracks]=\"textTracks\"\n [audioTracks]=\"audioTracks\"\n [videoTracks]=\"videoTracks\"\n [selectedTextTrackId]=\"selectedTextTrackId\"\n [selectedAudioTrackId]=\"selectedAudioTrackId\"\n [selectedVideoTrackId]=\"selectedVideoTrackId\"\n [playbackRates]=\"playbackRates\"\n [playbackRate]=\"playbackRate\"\n [labels]=\"playerMenuLabels\"\n (loadSubtitles)=\"openSubtitlePicker()\"\n (selectText)=\"selectTextTrack($event)\"\n (selectAudio)=\"selectAudioTrack($event)\"\n (selectVideo)=\"selectVideoTrack($event)\"\n (selectRate)=\"setPlaybackRate($event)\"\n />\n </ngxsp-player-controls-edition>\n } @else {\n <ngxsp-player-controls\n [playing]=\"state?.kind==='playing'\"\n [isAudioMode]=\"isAudioMode\"\n [hasPlaylistControls]=\"hasPlaylistControls\"\n [canPrev]=\"canPrev\"\n [canNext]=\"canNext\"\n [shuffleActive]=\"shuffleActive\"\n [shuffleLabel]=\"shuffleLabel\"\n [repeatMode]=\"repeatMode\"\n [repeatLabel]=\"repeatLabel\"\n [captionsActive]=\"selectedTextTrackId !== null\"\n [tracksLabel]=\"tracksButtonLabel()\"\n [captionsLabel]=\"captionsLabel()\"\n [speedLabel]=\"playbackRateLabel()\"\n [volumeLabel]=\"volumeLabel()\"\n [showCast]=\"showCastButton()\"\n [castActive]=\"isCastActive()\"\n [castLabel]=\"castLabel()\"\n [castHint]=\"castHintLabel()\"\n [pipSupported]=\"isPiPSupported()\"\n [pipActive]=\"isPiPActive()\"\n [pipLabel]=\"pipLabel()\"\n [volume]=\"volume\"\n [muteLabel]=\"outputMuteLabel\"\n [unmuteLabel]=\"outputUnmuteLabel\"\n [currentTime]=\"currentTime\"\n [duration]=\"duration\"\n [buffered]=\"bufferAheadSec\"\n [profile]=\"sourceProfile\"\n (playToggle)=\"requestPlaybackToggle()\"\n (seekRelative)=\"seekRel($event)\"\n (prev)=\"emitPrev()\"\n (next)=\"emitNext()\"\n (toggleShuffle)=\"toggleShuffle.emit()\"\n (cycleRepeat)=\"cycleRepeat.emit()\"\n (openMenu)=\"toggleMenu($event)\"\n (captions)=\"subtitles.emit()\"\n (cast)=\"onCastClick()\"\n (pip)=\"togglePiP()\"\n (mute)=\"toggleMute()\"\n (scrub)=\"onScrub($event)\"\n (volumeChange)=\"onVolume($event)\"\n />\n }\n\n </div>\n </div>\n `,\n styles: [`\n .ngxsp-root{\n /* Pilotable par le thème @ngxsp/ui-theme (--nsp-*) ; valeurs actuelles en fallback. */\n --ngxsp-bg:#000;\n --ngxsp-bg-elev:var(--nsp-surface-1, #17181d);\n --ngxsp-bg-soft:var(--nsp-surface-2, #1e1f25);\n --ngxsp-border:var(--nsp-line, rgb(255 255 255 / .07));\n --ngxsp-border-strong:var(--nsp-line-strong, rgb(255 255 255 / .13));\n --ngxsp-text:var(--nsp-text, #ededf0);\n --ngxsp-text-dim:var(--nsp-text-2, #a3a5ae);\n --ngxsp-accent:var(--nsp-media-accent, #8b90ff);\n --ngxsp-accent-soft:rgb(139 144 255 / .14);\n --ngxsp-focus-ring:0 0 0 2px var(--nsp-media-accent, #8b90ff);\n position:relative;\n width:100%;\n height:100%;\n background:#000;\n color:var(--ngxsp-text);\n font-family:var(--nsp-font, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Ubuntu, sans-serif);\n }\n .ngxsp-video{position:relative;width:100%;height:100%;isolation:isolate;container-type:inline-size}\n .ngxsp-captions{position:absolute;left:6%;right:6%;bottom:5%;z-index:3;display:flex;flex-direction:column;align-items:center;gap:.15em;pointer-events:none;text-align:center;font-size:clamp(13px, 2.6cqw, 34px);line-height:1.3;transition:bottom .2s ease}\n .ngxsp-captions:empty{display:none}\n .ngxsp-ui-visible .ngxsp-captions{bottom:calc(2% + var(--ngxsp-captions-lift, 96px))}\n /* The cue lines are made at run time: they carry none of this component's style attributes. */\n .ngxsp-captions ::ng-deep .ngxsp-cue{max-width:100%;padding:.08em .45em;border-radius:.2em;background:rgb(0 0 0 / .74);color:#fff;white-space:pre-line;text-shadow:0 1px 2px rgb(0 0 0 / .5)}\n .ngxsp-mode-audio .ngxsp-captions{display:none}\n .ngxsp-video video{width:100%;height:100%;display:block;background:#000;object-fit:contain;}\n .ngxsp-mode-audio .ngxsp-video video{opacity:.02;filter:blur(10px) saturate(120%);transform:scale(1.08)}\n .ngxsp-audio-stage{\n position:absolute;\n inset:0;\n z-index:0;\n display:flex;\n flex-direction:column;\n align-items:center;\n justify-content:center;\n gap:18px;\n padding:40px 24px 140px;\n background:\n radial-gradient(circle at 50% 24%, rgba(96,165,250,.22), transparent 30%),\n radial-gradient(circle at 22% 78%, rgba(45,212,191,.12), transparent 28%),\n linear-gradient(180deg, rgba(4,12,24,.92), rgba(5,10,18,.82));\n pointer-events:none;\n text-align:center;\n }\n .ngxsp-audio-disc{\n width:min(32vw, 220px);\n aspect-ratio:1;\n border-radius:50%;\n background:\n radial-gradient(circle at center, rgba(248,250,252,.9) 0 10%, rgba(15,23,42,.92) 11% 20%, rgba(100,116,139,.85) 21% 22%, rgba(15,23,42,.98) 23% 100%);\n box-shadow:0 24px 80px rgba(15,23,42,.5), inset 0 0 0 10px rgba(255,255,255,.05);\n animation:ngxspSpin 18s linear infinite;\n }\n .ngxsp-audio-copy{display:flex;flex-direction:column;gap:6px;max-width:min(76ch, 100%)}\n .ngxsp-audio-eyebrow{\n font-size:11px;\n letter-spacing:.22em;\n text-transform:uppercase;\n color:rgba(191,219,254,.8);\n font-weight:700;\n }\n .ngxsp-audio-title{\n font-size:36px;\n font-weight:800;\n letter-spacing:0;\n color:#f8fbff;\n text-shadow:0 18px 60px rgba(15,23,42,.6);\n }\n .ngxsp-audio-subtitle{\n font-size:16px;\n color:rgba(226,232,240,.78);\n }\n .ngxsp-audio-bars{display:flex;align-items:flex-end;gap:8px;height:40px}\n .ngxsp-audio-bars span{\n width:6px;\n height:16px;\n border-radius:999px;\n background:linear-gradient(180deg, rgba(147,197,253,.95), rgba(34,211,238,.55));\n animation:ngxspBars 1.15s ease-in-out infinite;\n box-shadow:0 0 18px rgba(56,189,248,.22);\n }\n .ngxsp-audio-bars span:nth-child(2){animation-delay:.12s}\n .ngxsp-audio-bars span:nth-child(3){animation-delay:.24s}\n .ngxsp-audio-bars span:nth-child(4){animation-delay:.36s}\n .ngxsp-audio-bars span:nth-child(5){animation-delay:.48s}\n /* VOD skin (video surface only — controls live in ngxsp-player-controls*) */\n .ngxsp-skin-vod .ngxsp-video{position:relative}\n .ngxsp-skin-vod .ngxsp-video::before{content:none}\n .ngxsp-skin-vod .ngxsp-video::after{content:none}\n .ngxsp-mode-audio.ngxsp-skin-vod .ngxsp-video::before{background:linear-gradient(180deg, rgba(3,8,18,.35), rgba(3,8,18,.12)); opacity:1}\n .ngxsp-inline-projection{display:inline-flex;flex:0 0 auto;align-items:center;gap:8px;width:max-content}\n .ngxsp-inline-projection:empty{display:none}\n .ngxsp-gesturePulse{position:absolute;inset:0;z-index:5;display:grid;place-items:center;pointer-events:none;color:#f8fbff;animation:ngxspGesturePulse .52s ease both}\n .ngxsp-gesturePulse ngxsp-smart-icon{width:64px;height:64px;padding:18px;box-sizing:border-box;display:grid;place-items:center;border-radius:50%;background:rgb(0 0 0 / .5);backdrop-filter:blur(10px)}\n\n @media (max-width: 640px){\n .ngxsp-audio-stage{padding:28px 16px 128px;gap:14px}\n .ngxsp-audio-disc{width:min(48vw, 168px)}\n .ngxsp-audio-title{font-size:28px}\n .ngxsp-audio-subtitle{font-size:14px}\n .ngxsp-skin-vod .ngxsp-inline-projection{display:none}\n .ngxsp-gesturePulse ngxsp-smart-icon{width:64px;height:64px}\n }\n\n @keyframes ngxspSpin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n\n @keyframes ngxspBars {\n 0%, 100% { height: 14px; opacity: .45; }\n 50% { height: 40px; opacity: 1; }\n }\n\n @keyframes ngxspGesturePulse {\n 0% { opacity: 0; transform: scale(.82); }\n 24% { opacity: 1; transform: scale(1); }\n 100% { opacity: 0; transform: scale(1.16); }\n }\n `],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class SmartPlayerComponent implements OnChanges, OnInit, OnDestroy {\n @Input({ required: true }) config!: PlayerConfig;\n @Input() plugins: PlayerPlugin[] = [];\n @Input() ports?: Partial<PlayerPorts>;\n @Input() engines?: EngineFactory[];\n @Input() debug = false;\n /** Optional start time (seconds) used for \"resume playback\". */\n @Input() startTimeSec: number | null = null;\n /** Starts the first source as soon as it is loaded. WebViews and desktop shells do not block it like browsers do. */\n @Input() autoplayOnInit = true;\n /** Increment when the user picks something to play: a new source starts, the current one resumes. */\n @Input() playRequest = 0;\n @Input() canPrev = false;\n @Input() canNext = false;\n @Input() previousLabel = 'Previous item';\n @Input() nextLabel = 'Next item';\n @Input() playLabel = 'Play';\n @Input() pauseLabel = 'Pause';\n @Input() shuffleActive = false;\n @Input() shuffleLabel = 'Shuffle: off';\n @Input() repeatMode: 'off' | 'one' | 'all' = 'off';\n @Input() repeatLabel = 'Repeat: off';\n @Input() hasPlaylistControls = false;\n @Input() mediaMode: 'video' | 'audio' = 'video';\n @Input() castEnabled = false;\n /** The media plays on a device the app drives (castEnabled): the devices button shows it. */\n @Input() castConnected = false;\n private airPlayAvailable = false;\n private airPlayActive = false;\n @Input() documentShortcuts = true;\n @Input() nowPlayingLabel = 'Now playing';\n @Input() nowListeningLabel = 'Now listening';\n @Input() fullscreenHintLabel = 'Double-click for fullscreen';\n @Input() fullscreenLabel = 'Fullscreen';\n @Input() readyStatusLabel = 'Ready';\n @Input() playingStatusLabel = 'Playing';\n @Input() pausedStatusLabel = 'Paused';\n @Input() bufferingStatusLabel = 'Buffering';\n @Input() loadingStatusLabel = 'Loading';\n @Input() endedStatusLabel = 'Ended';\n @Input() errorStatusLabel = 'Error';\n @Input() outputVolume: number | null = null;\n @Input() outputVolumeLabel = '';\n @Input() outputMuteLabel = 'Mute';\n @Input() outputUnmuteLabel = 'Restore sound';\n @Input() timelineDurationSec: number | null = null;\n @Input() timelineMarkers: ReadonlyArray<NgxspTimelineMarker> = [];\n\n // Noms volontairement alignés sur les événements média natifs (API publique).\n // eslint-disable-next-line @angular-eslint/no-output-native\n @Output() ended = new EventEmitter<void>();\n @Output() videoSize = new EventEmitter<{ width: number; height: number }>();\n /**\n * Emits playback position updates, tagged with the media they belong to: a host switching tracks can still receive\n * a position of the previous one, and must not file it under the new one.\n */\n // eslint-disable-next-line @angular-eslint/no-output-native\n @Output() progress = new EventEmitter<SmartPlayerProgress>();\n @Output() prev = new EventEmitter<void>();\n @Output() next = new EventEmitter<void>();\n @Output() toggleShuffle = new EventEmitter<void>();\n @Output() cycleRepeat = new EventEmitter<void>();\n /** CC pressed; the vod and edition skins also open their subtitles menu. */\n @Output() subtitles = new EventEmitter<void>();\n /** A subtitle file was read (ok) or could not be (error). */\n @Output() subtitlesLoaded = new EventEmitter<{ label: string; ok: boolean; error?: string }>();\n /** The words of the player's menus and of its subtitles button. */\n @Input() menuLabels: Partial<PlayerMenuLabels> = {};\n @Output() cast = new EventEmitter<void>();\n @Output() stateChange = new EventEmitter<PlayerState>();\n @Output() playbackToggle = new EventEmitter<'play' | 'pause'>();\n @Output() outputVolumeChange = new EventEmitter<number>();\n\n @ViewChild('video', { static: true }) videoEl!: ElementRef<HTMLVideoElement>;\n @ViewChild('captionsLayer', { static: true }) captionsLayer!: ElementRef<HTMLElement>;\n /** Absent in audio mode, which has no subtitles. */\n @ViewChild('subtitleFileInput') subtitleFileInput?: ElementRef<HTMLInputElement>;\n\n state: PlayerState | null = null;\n\n duration = 0;\n currentTime = 0;\n volume = 1;\n private lastVolumeBeforeMute = 1;\n playbackRate = 1;\n bufferAheadSec = 0;\n tracks: MediaTrack[] = [];\n openMenu: 'tracks' | 'speed' | 'captions' | null = null;\n controlsVisible = true;\n surfaceGesture: 'play' | 'pause' | null = null;\n castState: 'disconnected' | 'connecting' | 'connected' = 'disconnected';\n\n readonly playbackRates = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];\n\n private facade = new PlayerFacade();\n private readonly cdr = inject(ChangeDetectorRef);\n private sub = new Subscription();\n private hideControlsTimer: ReturnType<typeof setTimeout> | null = null;\n private surfaceClickTimer: ReturnType<typeof setTimeout> | null = null;\n private gestureTimer: ReturnType<typeof setTimeout> | null = null;\n private remotePlaybackCleanup: (() => void) | null = null;\n private initialized = false;\n private loadedSourceSignature = '';\n private loadSequence = 0;\n private loading = false;\n private pendingPlay = false;\n /** Whether the load in progress was asked to start playback. */\n private loadingAutoplay = false;\n /** Load whose end was already reported; reset when playback starts again (repeat one). */\n private endedLoadSequence = -1;\n private pendingSeekSec: number | null = null;\n\n get uiSkin(): 'classic' | 'vod' | 'edition' {\n const skin = this.config?.ui?.skin;\n return skin === 'vod' || skin === 'edition' ? skin : 'classic';\n }\n\n /** Libellé méta du skin édition (genre · format). */\n get editionMeta(): string {\n return this.isAudioMode ? 'Audio' : 'Vidéo';\n }\n\n get uiVisible(): boolean {\n const kind = this.state?.kind;\n return this.controlsVisible || this.openMenu !== null || kind === 'paused' || kind === 'loading' || kind === 'buffering' || kind === 'error';\n }\n\n get displayTitle(): string {\n const ui = this.config?.ui;\n const src = this.config?.source;\n return ui?.title ?? ui?.displayTitle ?? src?.title ?? src?.contentId ?? 'Player';\n }\n\n get displaySubtitle(): string {\n const ui = this.config?.ui;\n const src = this.config?.source;\n return (\n ui?.subtitle ??\n ui?.description ??\n src?.subtitle ??\n src?.artist ??\n src?.album ??\n this.audioTracks.find((track) => track.active)?.label ??\n 'Audio playback'\n );\n }\n\n get isAudioMode(): boolean {\n return this.mediaMode === 'audio';\n }\n\n /** Profil de source transmis aux primitives UI (cf. @ngxsp/ui-core). */\n get sourceProfile(): SourceProfile {\n if (this.config?.source?.live) return 'live';\n return this.isAudioMode ? 'audio' : 'vod';\n }\n\n get audioTracks(): MediaTrack[] {\n return this.tracks.filter((track) => track.kind === 'audio');\n }\n\n get textTracks(): MediaTrack[] {\n return this.tracks.filter((track) => track.kind === 'text');\n }\n\n get videoTracks(): MediaTrack[] {\n return this.tracks.filter((track) => track.kind === 'video');\n }\n\n get selectedAudioTrackId(): string | null {\n return this.audioTracks.find((track) => track.active)?.id ?? null;\n }\n\n get selectedTextTrackId(): string | null {\n return this.textTracks.find((track) => track.active)?.id ?? null;\n }\n\n get selectedVideoTrackId(): string | null {\n return this.videoTracks.find((track) => track.active)?.id ?? null;\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['outputVolume']) this.syncOutputVolumeInput();\n if (!this.initialized) return;\n const playRequested = !!changes['playRequest'] && !changes['playRequest'].firstChange;\n\n if (changes['engines'] && !changes['engines'].firstChange) {\n this.facade.setEngines(this.engines);\n // Playback moves to a device (or comes back): the media is loaded again from the same position. It keeps playing\n // when it moves to a device, and waits on this one when it comes back, unless the host asks for playback.\n // A different media arriving in the same change is not a move: it loads below from its own start, or it would\n // inherit the position of the one it replaces.\n if (this.sourceSignature(this.config) === this.loadedSourceSignature) {\n const kind = this.state?.kind;\n const wasPlaying = kind === 'playing' || kind === 'buffering' || (this.loading && (this.loadingAutoplay || this.pendingPlay));\n // Hosts keep their own engines (adaptive streaming) in the list: only the remote engine means a device.\n const toDevice = (this.engines ?? []).some((engine) => engine.id === 'remote');\n if (this.pendingSeekSec === null && this.currentTime > 0.5) this.pendingSeekSec = this.currentTime;\n void this.loadConfig(playRequested || (toDevice && wasPlaying));\n return;\n }\n }\n\n if (changes['config'] && this.sourceSignature(this.config) !== this.loadedSourceSignature) {\n // Keeps playing when the source is swapped while playing or stalled, right after the previous media ended (queue\n // chaining) or while a load meant to start is still in progress (a local copy replacing the network source),\n // and starts when the host asked for playback; nothing starts on its own otherwise.\n const kind = this.state?.kind;\n const autoplay = playRequested || kind === 'playing' || kind === 'buffering' || kind === 'ended'\n || (this.loading && (this.loadingAutoplay || this.pendingPlay));\n // A position still waiting for the previous media belongs to it: a session restored on a\n // paused track must not send the next file there (past its end, it would \"finish\" at once).\n // The new media starts where `startTimeSec` says.\n this.pendingSeekSec = null;\n void this.loadConfig(autoplay);\n return;\n }\n\n if (playRequested) {\n // Same source picked again (a paused track the listener clicks): play it, once any load has finished.\n if (this.loading) this.pendingPlay = true;\n else void this.facade.play().catch(() => {});\n }\n }\n\n ngOnInit(): void {\n const plugins: PlayerPlugin[] = [...(this.plugins ?? [])];\n\n // v1.11: SSAI (server-side stitched streams) – rewrite manifest URL if configured.\n if (this.config?.ads?.enabled && this.config?.ads?.mode === 'ssai') {\n plugins.push(createSsaiManifestRewritePlugin());\n }\n\n const media = this.mediaElementForMode();\n this.watchAirPlay(media);\n this.facade.attach(media, plugins, this.config, this.ports, this.engines);\n\n // markForCheck() requis : la stratégie OnPush ne détecte pas les mutations\n // poussées depuis des souscriptions RxJS (cf. docs/AUDIT.md, manquement #7).\n this.sub.add(this.facade.state$.subscribe((s: PlayerState) => {\n this.state = s;\n // Engines without a media element (remote devices) only report the end through their state.\n if (s.kind === 'ended') this.onEnded();\n else if (s.kind === 'playing') this.endedLoadSequence = -1;\n this.stateChange.emit(s);\n this.syncControlVisibility();\n this.cdr.markForCheck();\n }));\n this.sub.add(this.facade.time$.subscribe((t) => {\n // While a new source loads, the time still reported is the previous media's. Passed on, a\n // host would file it under the new track and resume that track there — past its end for a\n // short file, which then \"finishes\" at once.\n if (this.loading) return;\n this.currentTime = t.currentTime;\n this.duration = t.duration;\n this.progress.emit({\n currentTime: this.currentTime,\n duration: this.duration,\n contentId: this.config?.source?.contentId,\n sourceUrl: this.config?.source?.url,\n });\n this.cdr.markForCheck();\n }));\n this.sub.add(this.facade.bufferAheadSec$.subscribe((value) => {\n this.bufferAheadSec = value;\n this.cdr.markForCheck();\n }));\n this.sub.add(this.facade.tracks$.subscribe((tracks) => {\n this.tracks = tracks;\n this.cdr.markForCheck();\n }));\n this.sub.add(this.facade.captionCues$.subscribe((cues) => this.drawCaptions(cues)));\n this.bindRemotePlaybackState();\n\n this.applyVolume();\n this.initialized = true;\n void this.loadConfig(this.autoplayOnInit);\n }\n\n ngOnDestroy(): void {\n this.controlsObserver?.disconnect();\n this.clearHideControlsTimer();\n this.clearSurfaceClickTimer();\n this.clearGestureTimer();\n this.remotePlaybackCleanup?.();\n this.sub.unsubscribe();\n this.facade.destroy();\n }\n\n tryPlay(): void {\n void this.facade.play().catch(() => {});\n }\n\n get debugJson(): string {\n try {\n const d = this.facade.diagnostics();\n const tel = this.ports?.telemetry?.export?.();\n return JSON.stringify({ ...d, telemetry: tel }, null, 2);\n } catch {\n return '{}';\n }\n }\n\n get currentError(): PlayerError | null {\n return this.state?.kind === 'error' ? this.state.error : null;\n }\n\n async copyDebug(): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.debugJson);\n } catch {\n // clipboard may be unavailable\n }\n }\n\n downloadDebug(): void {\n try {\n const blob = new Blob([this.debugJson], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'ngxsp-diagnostics.json';\n a.click();\n setTimeout(() => URL.revokeObjectURL(url), 0);\n } catch {\n // ignore\n }\n }\n\n togglePlay(): void {\n if (this.state?.kind === 'playing') this.facade.pause();\n else this.facade.play();\n }\n\n requestPlaybackToggle(): void {\n const intent = this.playbackToggleIntent();\n this.togglePlay();\n this.playbackToggle.emit(intent);\n this.showSurfaceGesture(intent);\n }\n\n seekRel(deltaSec: number): void {\n this.seekTo(this.currentTime + deltaSec);\n }\n\n seekTo(timeSec: number): void {\n const value = Number(timeSec);\n if (!Number.isFinite(value)) return;\n const target = Math.max(0, value);\n this.pendingSeekSec = target;\n // A load in progress applies the pending position once the media is ready: seeking now would hit no engine.\n if (this.loading) return;\n void this.applySeek(target).then((applied) => {\n if (applied && this.pendingSeekSec === target) this.pendingSeekSec = null;\n });\n }\n\n onScrub(value: number): void {\n const v = Number(value);\n if (Number.isFinite(v)) this.seekTo(v);\n }\n\n onVolume(value: number): void {\n this.setVolume(value, true);\n }\n\n toggleMute(): void {\n if (this.volume <= 0.001) {\n this.volume = Math.max(0.5, this.lastVolumeBeforeMute || 0.5);\n } else {\n this.lastVolumeBeforeMute = this.volume;\n this.volume = 0;\n }\n this.applyVolume();\n this.outputVolumeChange.emit(this.volume);\n this.onInteraction();\n }\n\n async setPlaybackRate(rate: number): Promise<void> {\n this.playbackRate = rate;\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setRate(rate);\n }\n\n reload(): void {\n this.facade.reload().catch(() => void 0);\n }\n\n\n onLoadedMetadata(): void {\n const v = this.videoEl?.nativeElement;\n if (!v) return;\n // A position requested while the media was loading and not applied yet is applied now that it can be.\n if (this.pendingSeekSec !== null && !this.loading) {\n const target = this.pendingSeekSec;\n void this.applySeek(target).then((applied) => {\n if (applied && this.pendingSeekSec === target) this.pendingSeekSec = null;\n });\n }\n const width = v.videoWidth || 0;\n const height = v.videoHeight || 0;\n if (width > 0 && height > 0) {\n this.videoSize.emit({ width, height });\n }\n }\n\n onEnded(): void {\n // The media element's event and the engine state both announce the same end: handle it once per playback.\n if (this.endedLoadSequence === this.loadSequence) return;\n this.endedLoadSequence = this.loadSequence;\n // Repeat one replays the same media; otherwise hosts are told so they can chain their queue.\n if (this.repeatMode === 'one') {\n void this.facade.seekTo(0).then(() => this.facade.play()).catch(() => {});\n return;\n }\n this.ended.emit();\n }\n\n toggleFullscreen(): void {\n if (this.isAudioMode) return;\n const host = this.videoEl.nativeElement.parentElement;\n if (!host) return;\n\n const doc = document as Document & { fullscreenElement?: Element | null; exitFullscreen?: () => Promise<void> };\n const el = host as HTMLElement & { requestFullscreen?: () => Promise<void> };\n\n if (!doc.fullscreenElement && el.requestFullscreen) {\n el.requestFullscreen().catch(() => void 0);\n } else if (doc.exitFullscreen) {\n doc.exitFullscreen().catch(() => void 0);\n }\n }\n\n toggleMenu(menu: 'tracks' | 'speed' | 'captions'): void {\n this.openMenu = this.openMenu === menu ? null : menu;\n this.onInteraction(this.openMenu !== null);\n }\n\n get playerMenuLabels(): PlayerMenuLabels {\n return { ...DEFAULT_PLAYER_MENU_LABELS, ...this.menuLabels };\n }\n\n onCaptionsClick(): void {\n this.toggleMenu('captions');\n this.subtitles.emit();\n }\n\n openSubtitlePicker(): void {\n this.openMenu = null;\n this.onInteraction();\n this.subtitleFileInput?.nativeElement.click();\n }\n\n async onSubtitleFileChosen(event: Event): Promise<void> {\n const input = event.target as HTMLInputElement;\n const file = input.files?.[0];\n input.value = '';\n if (file) await this.loadSubtitleFile(file);\n }\n\n /** Reads a SubRip or WebVTT file and shows it over the video. */\n async loadSubtitleFile(file: File): Promise<void> {\n const { label, language } = describeSubtitleFile(file.name);\n try {\n const vtt = subtitleTextToVtt(decodeSubtitleBytes(new Uint8Array(await file.arrayBuffer())));\n if (!/-->/.test(vtt)) throw new Error('No subtitle in this file');\n await this.facade.addExternalTextTrack({ label, ...(language ? { language } : {}), vtt });\n this.subtitlesLoaded.emit({ label, ok: true });\n } catch (error) {\n this.subtitlesLoaded.emit({ label, ok: false, error: error instanceof Error ? error.message : String(error) });\n }\n }\n\n private controlsObserver?: ResizeObserver;\n\n /** While the controls show, the subtitles sit just above them, however tall they are (a menu makes them taller). */\n private followControlsHeight(): void {\n if (this.controlsObserver || typeof ResizeObserver !== 'function') return;\n const bar = this.videoEl.nativeElement.parentElement?.querySelector<HTMLElement>('.ngxsp-vod-bottom');\n const layer = this.captionsLayer?.nativeElement;\n if (!bar || !layer) return;\n // The top of the bar is a fade over the picture: the subtitles may overlap it.\n const lift = () => layer.style.setProperty('--ngxsp-captions-lift', `${Math.max(0, bar.offsetHeight - 24)}px`);\n this.controlsObserver = new ResizeObserver(lift);\n this.controlsObserver.observe(bar);\n lift();\n }\n\n /** Draws the cues of the loaded subtitles (their markup parsed by the browser: italics, bold, no script). */\n private drawCaptions(cues: TextTrackCue[]): void {\n const layer = this.captionsLayer?.nativeElement;\n if (!layer) return;\n if (cues.length) this.followControlsHeight();\n layer.replaceChildren(...cues.map((cue) => {\n const line = document.createElement('span');\n line.className = 'ngxsp-cue';\n const html = (cue as VTTCue).getCueAsHTML?.();\n if (html) line.append(html);\n else line.textContent = (cue as VTTCue).text ?? '';\n return line;\n }));\n }\n\n async selectTextTrack(trackId: string | null): Promise<void> {\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setTextTrack(trackId);\n }\n\n async selectAudioTrack(trackId: string): Promise<void> {\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setAudioTrack(trackId);\n }\n\n async selectVideoTrack(trackId: string | null): Promise<void> {\n this.openMenu = null;\n this.onInteraction();\n await this.facade.setVideoTrack(trackId);\n }\n\n async togglePiP(): Promise<void> {\n const video = this.videoEl.nativeElement as HTMLVideoElement & {\n requestPictureInPicture?: () => Promise<unknown>;\n disablePictureInPicture?: boolean;\n };\n const doc = document as Document & {\n pictureInPictureElement?: Element | null;\n pictureInPictureEnabled?: boolean;\n exitPictureInPicture?: () => Promise<void>;\n };\n\n try {\n if (doc.pictureInPictureElement) {\n await doc.exitPictureInPicture?.();\n } else {\n await video.requestPictureInPicture?.();\n }\n } catch {\n // Ignore unsupported or blocked PiP transitions.\n }\n this.onInteraction();\n }\n\n isPiPSupported(): boolean {\n if (this.isAudioMode) return false;\n const video = this.videoEl?.nativeElement as (HTMLVideoElement & { disablePictureInPicture?: boolean }) | undefined;\n const doc = document as Document & { pictureInPictureEnabled?: boolean };\n return !!doc.pictureInPictureEnabled && !video?.disablePictureInPicture;\n }\n\n pipLabel(): string {\n const doc = document as Document & { pictureInPictureElement?: Element | null };\n return doc.pictureInPictureElement ? 'Exit PiP' : 'PiP';\n }\n\n isPiPActive(): boolean {\n const doc = document as Document & { pictureInPictureElement?: Element | null };\n return !!doc.pictureInPictureElement;\n }\n\n async requestCast(): Promise<void> {\n const video = this.videoEl?.nativeElement as HTMLVideoElement & {\n remote?: {\n state?: 'disconnected' | 'connecting' | 'connected';\n prompt?: () => Promise<void>;\n };\n webkitShowPlaybackTargetPicker?: () => void;\n };\n if (!video) return;\n\n try {\n if (video.remote?.prompt) {\n this.castState = video.remote.state ?? 'connecting';\n await video.remote.prompt();\n this.castState = video.remote.state ?? this.castState;\n } else if (typeof video.webkitShowPlaybackTargetPicker === 'function') {\n video.webkitShowPlaybackTargetPicker();\n }\n } catch {\n this.castState = video.remote?.state ?? 'disconnected';\n }\n this.onInteraction();\n }\n\n isCastSupported(): boolean {\n const video = this.videoEl?.nativeElement as HTMLVideoElement & {\n remote?: { prompt?: () => Promise<void> };\n webkitShowPlaybackTargetPicker?: () => void;\n };\n return !!video && (!!video.remote?.prompt || typeof video.webkitShowPlaybackTargetPicker === 'function');\n }\n\n isCastActive(): boolean {\n return this.castConnected || this.castState === 'connected';\n }\n\n showCastButton(): boolean {\n return this.castEnabled || this.isCastSupported();\n }\n\n /**\n * AirPlay, as WebKit offers it: the system decides what is reachable and draws the picker\n * itself. Nothing is discovered here, and nothing is sent — the route belongs to the device.\n * Everywhere else these stay false and the button never appears.\n */\n showAirPlayButton(): boolean {\n return this.airPlayAvailable;\n }\n\n isAirPlayActive(): boolean {\n return this.airPlayActive;\n }\n\n airPlayLabel(): string {\n return this.airPlayActive ? 'Stop AirPlay' : 'AirPlay';\n }\n\n openAirPlayPicker(): void {\n const media = this.videoEl?.nativeElement as HTMLVideoElement & { webkitShowPlaybackTargetPicker?: () => void };\n media?.webkitShowPlaybackTargetPicker?.();\n }\n\n /** Wired to the media element whenever one is created, for video and for audio alike. */\n private watchAirPlay(media: HTMLMediaElement): void {\n const target = media as HTMLMediaElement & { webkitCurrentPlaybackTargetIsWireless?: boolean };\n if (!('webkitShowPlaybackTargetPicker' in target)) return;\n this.airPlayActive = target.webkitCurrentPlaybackTargetIsWireless === true;\n media.addEventListener('webkitplaybacktargetavailabilitychanged', (event) => {\n this.airPlayAvailable = (event as Event & { availability?: string }).availability === 'available';\n });\n media.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', () => {\n this.airPlayActive = target.webkitCurrentPlaybackTargetIsWireless === true;\n });\n }\n\n castLabel(): string {\n if (this.castEnabled) return 'Play on device';\n if (this.castState === 'connected') return 'Playing on remote device';\n if (this.castState === 'connecting') return 'Connecting to remote device';\n return 'Play on device';\n }\n\n castHintLabel(): string {\n if (this.castEnabled) return 'Choose a device on your local network.';\n if (this.castState === 'connected') return 'This media is currently playing on a nearby device.';\n if (this.castState === 'connecting') return 'Trying to connect to a nearby playback device.';\n return 'Available when your platform supports remote playback on the same network.';\n }\n\n onCastClick(): void {\n if (this.castEnabled) {\n this.cast.emit();\n this.onInteraction();\n return;\n }\n void this.requestCast();\n }\n\n captionsLabel(): string {\n const labels = this.playerMenuLabels;\n const shown = this.textTracks.find((track) => track.id === this.selectedTextTrackId);\n return shown ? `${labels.subtitles} - ${shown.label || shown.language || shown.id}` : labels.subtitles;\n }\n\n volumeLabel(): string {\n if (this.volume <= 0.001) return 'Muted';\n if (this.volume < 0.5) return 'Vol';\n return 'Volume';\n }\n\n playbackRateLabel(): string {\n return `${this.playbackRate}x`;\n }\n\n statusLabel(): string {\n const kind = this.state?.kind;\n if (kind === 'playing') return this.playbackRate === 1 ? this.playingStatusLabel : `${this.playingStatusLabel} ${this.playbackRate}x`;\n if (kind === 'paused') return this.pausedStatusLabel;\n if (kind === 'buffering') return this.bufferingStatusLabel;\n if (kind === 'loading') return this.loadingStatusLabel;\n if (kind === 'ended') return this.endedStatusLabel;\n if (kind === 'error') return this.errorStatusLabel;\n return this.readyStatusLabel;\n }\n\n keyboardHintLabel(): string {\n return this.isAudioMode ? 'Space play • Arrows seek • C device' : 'Space play • Arrows seek • F fullscreen • C device';\n }\n\n tracksButtonLabel(): string {\n return this.textTracks.length || this.audioTracks.length ? this.playerMenuLabels.tracks : this.playerMenuLabels.media;\n }\n\n onPrimarySurfaceDoubleClick(): void {\n if (this.isAudioMode) return;\n this.clearSurfaceClickTimer();\n this.toggleFullscreen();\n }\n\n bufferPercent(): number {\n if (!this.duration || !Number.isFinite(this.duration) || this.duration <= 0) return 0;\n return Math.max(0, Math.min(100, (this.bufferAheadSec / this.duration) * 100));\n }\n\n fmtTime(sec: number): string {\n const s = Math.max(0, Math.floor(sec || 0));\n const h = Math.floor(s / 3600);\n const m = Math.floor((s % 3600) / 60);\n const r = s % 60;\n if (h > 0) return `${h}:${String(m).padStart(2,'0')}:${String(r).padStart(2,'0')}`;\n return `${m}:${String(r).padStart(2,'0')}`;\n }\n\n noop(): void {}\n\n /**\n * Music plays in a real <audio> element: mobile browsers and Android WebViews pause <video> elements as soon as\n * the page is hidden, which would stop the music when the app goes to the background or the screen turns off.\n */\n private mediaElementForMode(): HTMLVideoElement {\n const video = this.videoEl.nativeElement;\n if (!this.isAudioMode || typeof document === 'undefined') return video;\n const audio = document.createElement('audio');\n audio.preload = 'metadata';\n audio.setAttribute('x-webkit-airplay', 'allow');\n audio.addEventListener('timeupdate', () => this.noop());\n audio.addEventListener('loadedmetadata', () => this.onLoadedMetadata());\n audio.addEventListener('ended', () => this.onEnded());\n video.replaceWith(audio);\n // The facade and helpers only use HTMLMediaElement members for audio (video-only APIs are feature-checked).\n this.videoEl = new ElementRef(audio as unknown as HTMLVideoElement);\n return this.videoEl.nativeElement;\n }\n onInteraction(persist = false): void {\n this.controlsVisible = true;\n this.clearHideControlsTimer();\n if (!persist && this.state?.kind === 'playing' && this.openMenu === null) {\n this.hideControlsTimer = setTimeout(() => {\n this.controlsVisible = false;\n this.cdr.markForCheck();\n }, 2200);\n }\n }\n\n onPointerLeave(): void {\n if (this.state?.kind === 'playing' && this.openMenu === null) {\n this.clearHideControlsTimer();\n this.controlsVisible = false;\n }\n }\n\n onRootClick(event: MouseEvent): void {\n const target = event.target as HTMLElement | null;\n if (!target) return;\n if (target.closest('button, input, textarea, select, summary, [contenteditable=\"true\"], .ngxsp-menu, .ngxsp-controls, .ngxsp-debug, .ngxsp-overlay, .ngxsp-range')) {\n return;\n }\n if (event.detail > 1) {\n this.clearSurfaceClickTimer();\n return;\n }\n this.openMenu = null;\n this.onInteraction();\n if (this.uiSkin === 'vod' && !this.isAudioMode) {\n this.queueSurfacePlaybackToggle();\n }\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.openMenu !== null) {\n this.openMenu = null;\n this.onInteraction();\n }\n }\n\n @HostListener('document:keydown', ['$event'])\n onKeydown(event: KeyboardEvent): void {\n if (!this.documentShortcuts) return;\n if (this.isInteractiveTarget(event.target)) return;\n\n if (event.code === 'Space') {\n event.preventDefault();\n this.requestPlaybackToggle();\n this.onInteraction();\n return;\n }\n if (event.code === 'ArrowLeft') {\n event.preventDefault();\n this.seekRel(-10);\n this.onInteraction();\n return;\n }\n if (event.code === 'ArrowRight') {\n event.preventDefault();\n this.seekRel(10);\n this.onInteraction();\n return;\n }\n if (event.code === 'KeyF') {\n if (this.isAudioMode) return;\n event.preventDefault();\n this.toggleFullscreen();\n this.onInteraction();\n return;\n }\n if (event.code === 'KeyM') {\n event.preventDefault();\n this.toggleMute();\n return;\n }\n if (event.code === 'KeyC') {\n if (!this.showCastButton()) return;\n event.preventDefault();\n this.onCastClick();\n }\n }\n\n private async loadConfig(autoplay: boolean): Promise<void> {\n const sequence = ++this.loadSequence;\n this.loading = true;\n this.loadingAutoplay = autoplay;\n this.loadedSourceSignature = this.sourceSignature(this.config);\n this.duration = 0;\n this.currentTime = 0;\n this.bufferAheadSec = 0;\n this.tracks = [];\n this.cdr.markForCheck();\n\n try {\n await this.facade.load(this.config);\n if (this.pendingSeekSec !== null) {\n const target = this.pendingSeekSec;\n // Cleared only when the position really reached an engine; otherwise the metadata event retries it.\n if (await this.applySeek(target) && this.pendingSeekSec === target) this.pendingSeekSec = null;\n } else {\n await this.applyStartTime();\n }\n // A newer load owns playback: only the latest request may start it.\n if (sequence === this.loadSequence && (autoplay || this.pendingPlay)) {\n this.pendingPlay = false;\n await this.facade.play().catch(() => {});\n }\n } catch {\n // The facade has already emitted a typed player error.\n } finally {\n if (sequence === this.loadSequence) {\n this.loading = false;\n // A position asked for while this load was finishing, after it looked for one, is applied now.\n const target = this.pendingSeekSec;\n if (target !== null) {\n void this.applySeek(target).then((applied) => {\n if (applied && this.pendingSeekSec === target) this.pendingSeekSec = null;\n });\n }\n }\n }\n }\n\n private async applyStartTime(): Promise<void> {\n const start = Number(this.startTimeSec ?? 0);\n if (!Number.isFinite(start) || start <= 0.2) return;\n\n await this.applySeek(start);\n }\n\n private async applySeek(timeSec: number): Promise<boolean> {\n try {\n return await this.facade.seekTo(this.safeSeekTime(timeSec));\n } catch {\n // Best effort: some engines only allow seeking after enough metadata is loaded.\n return false;\n }\n }\n\n private safeSeekTime(timeSec: number): number {\n return Math.max(0, Math.min(timeSec, (this.duration || timeSec + 1) - 0.3));\n }\n\n private sourceSignature(config: PlayerConfig | null | undefined): string {\n const source = config?.source;\n if (!source) return '';\n return [\n source.type,\n source.url,\n source.contentId,\n source.live ? 'live' : 'vod',\n source.offlineEligible ? 'offline' : 'online',\n ].join('|');\n }\n\n private bindRemotePlaybackState(): void {\n const video = this.videoEl?.nativeElement as HTMLVideoElement & {\n remote?: {\n state?: 'disconnected' | 'connecting' | 'connected';\n addEventListener?: (type: string, listener: EventListener) => void;\n removeEventListener?: (type: string, listener: EventListener) => void;\n };\n addEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n removeEventListener: (type: string, listener: EventListenerOrEventListenerObject) => void;\n };\n const remote = video?.remote;\n if (!video || !remote) return;\n\n const sync = () => {\n this.castState = remote.state ?? 'disconnected';\n this.cdr.markForCheck();\n };\n\n sync();\n remote.addEventListener?.('connecting', sync);\n remote.addEventListener?.('connect', sync);\n remote.addEventListener?.('disconnect', sync);\n video.addEventListener('webkitcurrentplaybacktargetiswirelesschanged', sync as EventListener);\n\n this.remotePlaybackCleanup = () => {\n remote.removeEventListener?.('connecting', sync);\n remote.removeEventListener?.('connect', sync);\n remote.removeEventListener?.('disconnect', sync);\n video.removeEventListener('webkitcurrentplaybacktargetiswirelesschanged', sync as EventListener);\n };\n }\n\n private syncControlVisibility(): void {\n if (this.state?.kind === 'playing' && this.openMenu === null) {\n this.onInteraction();\n return;\n }\n this.clearHideControlsTimer();\n this.controlsVisible = true;\n }\n\n private applyVolume(): void {\n try {\n const media = this.videoEl.nativeElement;\n media.volume = this.volume;\n // iOS ignores volume writes: without this, muting and the volume slider have no effect on iPhone and iPad.\n media.muted = this.volume <= 0.001;\n } catch {\n // Some browser environments reject direct volume writes; the engine path remains available.\n }\n this.facade.setVolume(this.volume);\n }\n\n private syncOutputVolumeInput(): void {\n this.setVolume(this.outputVolume, false);\n }\n\n setOutputVolume(value: number): void {\n this.setVolume(value, false);\n }\n\n private setVolume(value: unknown, emitChange: boolean): void {\n const nextVolume = this.normalizeVolume(value, this.volume);\n if (Math.abs(nextVolume - this.volume) < 0.001) return;\n this.volume = nextVolume;\n if (this.volume > 0) this.lastVolumeBeforeMute = this.volume;\n if (this.initialized) this.applyVolume();\n if (emitChange) this.outputVolumeChange.emit(this.volume);\n }\n\n private normalizeVolume(value: unknown, fallback: number): number {\n const numeric = Number(value);\n if (!Number.isFinite(numeric)) return fallback;\n return Math.max(0, Math.min(1, numeric));\n }\n\n private clearHideControlsTimer(): void {\n if (this.hideControlsTimer) {\n clearTimeout(this.hideControlsTimer);\n this.hideControlsTimer = null;\n }\n }\n\n private queueSurfacePlaybackToggle(): void {\n this.clearSurfaceClickTimer();\n this.surfaceClickTimer = setTimeout(() => {\n this.surfaceClickTimer = null;\n this.requestPlaybackToggle();\n this.cdr.markForCheck();\n }, 180);\n }\n\n private clearSurfaceClickTimer(): void {\n if (this.surfaceClickTimer) {\n clearTimeout(this.surfaceClickTimer);\n this.surfaceClickTimer = null;\n }\n }\n\n private playbackToggleIntent(): 'play' | 'pause' {\n return this.state?.kind === 'playing' ? 'pause' : 'play';\n }\n\n private showSurfaceGesture(intent: 'play' | 'pause'): void {\n this.surfaceGesture = intent;\n this.clearGestureTimer();\n this.gestureTimer = setTimeout(() => {\n this.surfaceGesture = null;\n this.cdr.markForCheck();\n }, 520);\n this.cdr.markForCheck();\n }\n\n private clearGestureTimer(): void {\n if (this.gestureTimer) {\n clearTimeout(this.gestureTimer);\n this.gestureTimer = null;\n }\n }\n\n private isInteractiveTarget(target: EventTarget | null): boolean {\n const el = target as HTMLElement | null;\n if (!el) return false;\n return !!el.closest('input, button, textarea, select, summary, [contenteditable=\"true\"]');\n }\n\nemitNext(): void {\n this.next.emit();\n}\n\nemitPrev(): void {\n this.prev.emit();\n}\n\n}\n","import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders } from '@angular/core';\nimport { MetadataProvider, SubtitleProvider } from '@ngxsp/core';\n\n/**\n * Jetons d'injection typés pour les providers de sous-titres / métadonnées.\n * (Remplace les jetons `string` non typés — cf. docs/AUDIT.md, manquement #10.)\n * Un consommateur peut les injecter directement :\n * `inject(SMART_PLAYER_SUBTITLE_PROVIDERS)`.\n */\nexport const SMART_PLAYER_SUBTITLE_PROVIDERS = new InjectionToken<SubtitleProvider[]>(\n 'SMART_PLAYER_SUBTITLE_PROVIDERS',\n { factory: () => [] },\n);\n\nexport const SMART_PLAYER_METADATA_PROVIDERS = new InjectionToken<MetadataProvider[]>(\n 'SMART_PLAYER_METADATA_PROVIDERS',\n { factory: () => [] },\n);\n\nexport interface SmartPlayerProvidersConfig {\n subtitleProviders?: SubtitleProvider[];\n metadataProviders?: MetadataProvider[];\n}\n\n/**\n * Enregistre les implémentations de providers (sous-titres / métadonnées).\n * À appeler dans le tableau `providers` de `bootstrapApplication()`.\n */\nexport function provideSmartPlayer(cfg: SmartPlayerProvidersConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: SMART_PLAYER_SUBTITLE_PROVIDERS, useValue: cfg.subtitleProviders ?? [] },\n { provide: SMART_PLAYER_METADATA_PROVIDERS, useValue: cfg.metadataProviders ?? [] },\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|