boss-web-player-sdk 1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GoBOSS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,340 @@
1
+ # @goboss/web-video-player-sdk
2
+
3
+ A unified, high-performance OTT web video player SDK for adaptive streaming — HLS/DASH, token-based DRM, dynamic watermarking, captions, chapters, casting, and premium UI controls.
4
+
5
+ > **Heads up:** the high-level `<BossVideoPlayer>` component is **tenant-gated**. It validates a GoBOSS **player key** against the GoBOSS API before playback starts, and resolves its feature set (subtitles, DRM, chromecast, etc.) from your plan. You need a player key from the GoBOSS dashboard to use it. For a generic, ungated player use the [headless core entry](#headless-core-no-react).
6
+
7
+ ## Features
8
+
9
+ - **Adaptive streaming** — HLS (bundled `hls.js`) and DASH (optional `dashjs`) with automatic quality switching
10
+ - **DRM** — token-based authorization, FairPlay / Widevine, dynamic watermarking
11
+ - **Rich controls** — quality, playback speed, subtitles, PiP, fullscreen, chapters/key-moments
12
+ - **Casting** — Chromecast and AirPlay
13
+ - **Server-side ads (SSAI)** — AWS MediaTailor ad-break tracking and skip-ad flow
14
+ - **Analytics** — `onAnalyticsEvent` callback + optional Firebase Analytics provider
15
+ - **Framework-agnostic** — React component, a vanilla `createPlayer()` mount, and a zero-React headless core
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @goboss/web-video-player-sdk
21
+ ```
22
+
23
+ ### Peer dependencies
24
+
25
+ | Package | Required? | Notes |
26
+ |---|---|---|
27
+ | `react`, `react-dom` (`^18` or `^19`) | **Required** for the React component & `createPlayer` | Not needed if you only use the headless `/core` entry |
28
+ | `firebase` (`>=10`) | **Optional** | Only loaded (lazily) if you pass `firebaseConfig`. The SDK installs and runs fine without it. |
29
+ | `dashjs` (`^5`) | **Optional** | Only needed to play **DASH** (`.mpd`) streams. HLS works without it. |
30
+
31
+ ```bash
32
+ # Only if you use Firebase analytics:
33
+ npm install firebase
34
+ # Only if you play DASH (.mpd) streams:
35
+ npm install dashjs
36
+ ```
37
+
38
+ ### CSS — required, import once
39
+
40
+ > **The player stylesheet must be imported separately.** The SDK ships CSS as a standalone
41
+ > file so your bundler can handle it correctly (critical for SSR frameworks like Next.js).
42
+ > Forgetting this import will result in a broken, unstyled player.
43
+
44
+ ```ts
45
+ import '@goboss/web-video-player-sdk/css';
46
+ ```
47
+
48
+ Import it once at your app entry point (e.g. `main.tsx`, `_app.tsx`, `layout.tsx`) and it
49
+ applies globally — you do not need to import it in every file that uses `<BossVideoPlayer>`.
50
+
51
+ ## Quick start (React)
52
+
53
+ ```tsx
54
+ import { BossVideoPlayer } from '@goboss/web-video-player-sdk';
55
+ import '@goboss/web-video-player-sdk/css';
56
+
57
+ export default function App() {
58
+ return (
59
+ <BossVideoPlayer
60
+ playerKey="bsp_your_player_key" // from the GoBOSS dashboard (required)
61
+ src="https://cdn.example.com/video.m3u8" // HLS (.m3u8) or DASH (.mpd)
62
+ title="My Video"
63
+ themeColor="#6366f1"
64
+ autoplay
65
+ muted
66
+ />
67
+ );
68
+ }
69
+ ```
70
+
71
+ The component shows a loading spinner while it validates the player key, then renders the
72
+ player. If the key is invalid or the API is unreachable, it renders an error state instead.
73
+
74
+ ## Next.js
75
+
76
+ The SDK works in Next.js (both Pages Router and App Router). The player is entirely
77
+ client-side — it uses browser APIs (`HTMLVideoElement`, `window`, `navigator`) that do not
78
+ exist on the server.
79
+
80
+ **App Router** — mark any file that imports the player as a Client Component:
81
+
82
+ ```tsx
83
+ // app/watch/page.tsx
84
+ 'use client';
85
+
86
+ import { BossVideoPlayer } from '@goboss/web-video-player-sdk';
87
+
88
+ export default function WatchPage() {
89
+ return (
90
+ <BossVideoPlayer
91
+ playerKey="bsp_your_player_key"
92
+ src="https://cdn.example.com/video.m3u8"
93
+ autoplay
94
+ muted
95
+ />
96
+ );
97
+ }
98
+ ```
99
+
100
+ Import the CSS in your root layout so it loads once for the whole app:
101
+
102
+ ```tsx
103
+ // app/layout.tsx
104
+ import '@goboss/web-video-player-sdk/css';
105
+
106
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
107
+ return <html><body>{children}</body></html>;
108
+ }
109
+ ```
110
+
111
+ **Pages Router** — import the CSS in `_app.tsx` (or `_app.js`):
112
+
113
+ ```tsx
114
+ // pages/_app.tsx
115
+ import '@goboss/web-video-player-sdk/css';
116
+ import type { AppProps } from 'next/app';
117
+
118
+ export default function App({ Component, pageProps }: AppProps) {
119
+ return <Component {...pageProps} />;
120
+ }
121
+ ```
122
+
123
+ No `'use client'` directive is needed in the Pages Router — all pages are client-rendered
124
+ by default.
125
+
126
+ ## `<BossVideoPlayer>` props
127
+
128
+ ```ts
129
+ interface BossVideoPlayerProps {
130
+ // ── Required ──────────────────────────────────────────────
131
+ playerKey: string; // GoBOSS player key — gates playback & features
132
+ src: string; // HLS (.m3u8) or DASH (.mpd) URL
133
+
134
+ // ── Identity / theming ────────────────────────────────────
135
+ title?: string; // Title shown in the player UI
136
+ watermark?: string; // Watermark text stamped on the video
137
+ themeColor?: string; // Accent color (hex). Default '#6366f1'
138
+ licenseKey?: string; // Required by DRM-enabled plans (presence-checked)
139
+
140
+ // ── Networking ────────────────────────────────────────────
141
+ apiBaseUrl?: string; // Override the GoBOSS API base URL (see note below)
142
+ proxyDomains?: string; // CORS proxy map, "host=/path,host2=/path2" (see CORS)
143
+
144
+ // ── Ads (AWS MediaTailor SSAI) ────────────────────────────
145
+ adTrackingUrl?: string; // Ad-break tracking URL
146
+ overlayAdUrl?: string; // Overlay ad tracking URL
147
+ enableSkipAd?: boolean;
148
+ skipAdAfterSeconds?: number;
149
+
150
+ // ── Behavior / UI ─────────────────────────────────────────
151
+ autoplay?: boolean; // Default false
152
+ muted?: boolean; // Default false (use with autoplay — browsers block unmuted autoplay)
153
+ autoFullscreen?: boolean;
154
+ enableControls?: boolean; // Default true
155
+ chaptersDisplayMode?: 'strip' | 'panel'; // Default 'strip'
156
+ volumeControlType?: 'slider' | 'button'; // Default 'slider'
157
+ subtitleStyle?: { size?: 'small'|'medium'|'large'; background?: 'none'|'dim'|'solid'; color?: string };
158
+
159
+ // ── Integrations ──────────────────────────────────────────
160
+ firebaseConfig?: FirebaseConfig; // Enables Firebase Analytics (lazy-loads `firebase`)
161
+ drmConfig?: DRMConfig; // DRM license / token configuration
162
+
163
+ // ── Callbacks ─────────────────────────────────────────────
164
+ onAnalyticsEvent?: (event: AnalyticsEvent) => void; // Every analytics event
165
+ onKeyMomentsLoaded?: (keyMoments: Chapter[]) => void; // When chapters parse from the stream
166
+ }
167
+ ```
168
+
169
+ > Feature availability (subtitles, chromecast, DRM, multiple resolutions, etc.) is **resolved from your
170
+ > plan** by the GoBOSS API at init — it is not toggled by individual props on this component.
171
+
172
+ ## Use without JSX — `createPlayer()`
173
+
174
+ For Vue, Angular, Svelte, or vanilla JS. Renders the same gated `<BossVideoPlayer>` into any element.
175
+
176
+ ```ts
177
+ import { createPlayer } from '@goboss/web-video-player-sdk';
178
+ import '@goboss/web-video-player-sdk/css';
179
+
180
+ const player = createPlayer(document.getElementById('player')!, {
181
+ playerKey: 'bsp_your_player_key',
182
+ src: 'https://cdn.example.com/video.m3u8',
183
+ autoplay: true,
184
+ muted: true,
185
+ });
186
+
187
+ player.update({ src: 'https://cdn.example.com/other.m3u8' }); // re-render with new props
188
+ player.destroy(); // unmount & release resources
189
+ ```
190
+
191
+ ## Headless core (no React)
192
+
193
+ Import from the `/core` subpath for a zero-React, zero-UI player and modules. This entry is **not**
194
+ player-key gated — you drive everything yourself.
195
+
196
+ ```ts
197
+ import { VideoPlayerSDK } from '@goboss/web-video-player-sdk/core';
198
+
199
+ const player = new VideoPlayerSDK({
200
+ container: document.getElementById('player')!,
201
+ src: 'https://cdn.example.com/video.m3u8',
202
+ autoplay: false,
203
+ muted: false,
204
+ });
205
+
206
+ // Playback
207
+ player.play();
208
+ player.pause();
209
+ player.seek(30);
210
+ player.setVolume(0.8);
211
+ player.setMute(false);
212
+ player.setPlaybackRate(1.5);
213
+ player.setQuality(qualityId); // id from a `qualitylevels` event entry
214
+
215
+ // Events (EventEmitter-style)
216
+ player.on('play', () => {});
217
+ player.on('qualitychange', (q) => {});
218
+ player.on('subtitlesloaded', (tracks) => {});
219
+
220
+ player.destroy(); // clean up
221
+ ```
222
+
223
+ **Emitted events:** `play`, `pause`, `ended`, `timeupdate`, `seeking`, `buffering`, `volumechange`,
224
+ `ratechange`, `pipchange`, `error`, `qualitylevels`, `qualitychange`, `subtitlesloaded`,
225
+ `audiotracksloaded`, `audiotrackchange`, `keymomentsloaded`, `chaptersloaded`, `adbreaksloaded`,
226
+ `adbreakchange`.
227
+
228
+ The `/core` entry also exposes the individual modules: `AnalyticsModule`, `FirebaseAnalyticsProvider`,
229
+ `SubtitlesModule`, `ThumbnailsModule`, `KeyMomentsModule`, `ChaptersModule`, `CastingModule`,
230
+ `DRMModule`, and `BasePlayerPlugin`.
231
+
232
+ ## CORS & proxying
233
+
234
+ The player fetches the manifest and media segments **from the browser**, so those origins must send CORS
235
+ headers. Two tools help:
236
+
237
+ - **`apiBaseUrl`** — point the SDK's GoBOSS API calls at your own reverse proxy (useful to avoid CORS on
238
+ the API in development).
239
+ - **`proxyDomains`** — a comma-separated `"<host>=/<proxyPath>"` map. Any stream URL whose host matches is
240
+ rewritten to `<proxyPath><pathname><search>`, and applied to the manifest **and** every segment/key
241
+ request. Back each `<proxyPath>` with a same-origin dev proxy.
242
+
243
+ ```tsx
244
+ <BossVideoPlayer
245
+ playerKey="bsp_..."
246
+ src="https://master.example.com/index.m3u8"
247
+ apiBaseUrl="/boss-api"
248
+ proxyDomains="segments.example.com=/seg-proxy,master.example.com=/mt-proxy"
249
+ />
250
+ ```
251
+
252
+ > Proxying is a **development** convenience. For production, configure CORS on the content origin
253
+ > (S3 / CloudFront / MediaTailor) — you cannot proxy every viewer's traffic.
254
+
255
+ ## DRM
256
+
257
+ ```ts
258
+ const drmConfig = {
259
+ authToken: 'bearer-token', // sent with license/segment requests
260
+ watermarkText: 'Your Brand',
261
+ fairplayLicenseUrl: 'https://...', // Safari / Apple
262
+ widevineServiceUrl: 'https://...', // Chrome / Android
263
+ };
264
+ ```
265
+
266
+ `licenseKey` is a separate, plan-level gate: when your resolved plan has DRM enabled, a non-empty
267
+ `licenseKey` must be provided or the player shows a "Playback restricted" overlay.
268
+
269
+ ## Analytics
270
+
271
+ Every player event flows through `onAnalyticsEvent`:
272
+
273
+ ```tsx
274
+ <BossVideoPlayer
275
+ playerKey="bsp_..."
276
+ src="https://cdn.example.com/video.m3u8"
277
+ onAnalyticsEvent={(e) => console.log(e.eventType, e)}
278
+ />
279
+ ```
280
+
281
+ To also forward events to **Firebase Analytics (GA4)**, pass a `firebaseConfig` (and install `firebase`).
282
+ Firebase is loaded lazily — omit the config and the `firebase` package is never required.
283
+
284
+ ## Keyboard shortcuts
285
+
286
+ | Key | Action |
287
+ |---|---|
288
+ | `Space` / `K` | Play / Pause |
289
+ | `J` / `←` | Seek back 10s |
290
+ | `L` / `→` | Seek forward 10s |
291
+ | `↑` / `↓` | Volume ±10% |
292
+ | `M` | Mute toggle |
293
+ | `F` | Fullscreen toggle |
294
+ | `P` | Picture-in-Picture toggle |
295
+ | `C` | Subtitles toggle |
296
+
297
+ ## Exports
298
+
299
+ ```ts
300
+ // React component (gated, drop-in)
301
+ import { BossVideoPlayer, type BossVideoPlayerProps } from '@goboss/web-video-player-sdk';
302
+
303
+ // Framework-agnostic mount
304
+ import { createPlayer, type PlayerProps, type PlayerInstance } from '@goboss/web-video-player-sdk';
305
+
306
+ // Lower-level React UI / headless core
307
+ import { WebVideoPlayer, VideoPlayerSDK } from '@goboss/web-video-player-sdk';
308
+
309
+ // Optional Firebase analytics
310
+ import { FirebaseAnalyticsProvider, type FirebaseConfig } from '@goboss/web-video-player-sdk';
311
+
312
+ // Advanced: raw SDK API calls
313
+ import { initSdk, startSession, sendHeartbeat, endSession } from '@goboss/web-video-player-sdk';
314
+
315
+ // Types
316
+ import type {
317
+ AnalyticsEvent, AnalyticsCallback, Chapter, KeyMoment, SubtitleTrack,
318
+ VideoQuality, ThumbnailConfig, DRMConfig, PlayerSDKOptions,
319
+ FeatureFlags, SubtitleStyle,
320
+ } from '@goboss/web-video-player-sdk';
321
+ ```
322
+
323
+ ## Browser support
324
+
325
+ | Browser | Version |
326
+ |---|---|
327
+ | Chrome / Edge | 90+ |
328
+ | Firefox | 88+ |
329
+ | Safari (incl. iOS) | 14+ |
330
+ | Android Chrome | 90+ |
331
+
332
+ ## Module formats
333
+
334
+ Ships **ES Module** (`dist/index.js`) and **CommonJS** (`dist/index.cjs`) builds with bundled TypeScript
335
+ definitions and an extracted stylesheet (`@goboss/web-video-player-sdk/css`). `react`, `react-dom`,
336
+ `firebase`, and `dashjs` are externalized (see peer dependencies).
337
+
338
+ ## License
339
+
340
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,2 @@
1
+ .sdk-player-container{--sdk-theme-color:#6366f1;--sdk-theme-color-rgb:99, 102, 241;--sdk-ad-color:#ff9800;--sdk-ad-color-rgb:255, 152, 0;-webkit-user-select:none;user-select:none;aspect-ratio:16/9;cursor:none;background:#000;border-radius:12px;width:100%;height:100%;font-family:Outfit,Inter,system-ui,-apple-system,sans-serif;position:relative;overflow:hidden;box-shadow:0 25px 50px -12px #000000b3}.sdk-player-container.controls-active{cursor:default}.sdk-watermark-overlay{z-index:4!important;transition:left 4s ease-in-out,top 4s ease-in-out!important}.sdk-ad-countdown{z-index:90;pointer-events:none;-webkit-user-select:none;user-select:none;background:#4b3c00;border:1px solid #ffe000;border-radius:20px;justify-content:center;align-items:center;gap:6px;min-width:88px;padding:6px 2px;display:flex;position:absolute;top:16px;right:16px}.sdk-ad-countdown-label{letter-spacing:.06em;color:#ffe000;font-size:13px;font-weight:500}.sdk-ad-countdown-sep{color:#ffe000;opacity:.5;font-size:13px}.sdk-ad-countdown-time{font-variant-numeric:tabular-nums;color:#ffe000;font-size:13px;font-weight:500}.sdk-skip-ad-btn{z-index:90;text-align:center;color:#ffffff8c;letter-spacing:.03em;cursor:not-allowed;-webkit-user-select:none;user-select:none;pointer-events:all;background:#000000b3;border:1px solid #ffffff59;border-radius:20px;width:92px;padding:8px 0;font-size:13px;font-weight:500;transition:background .15s,border-color .15s,color .15s;position:absolute;bottom:84px;right:16px}.sdk-skip-ad-btn--ready{color:#fff;cursor:pointer;border-color:#fffc}.sdk-skip-ad-btn--ready:hover{background:#ffffff2e;border-color:#fff}.sdk-overlay-ad{z-index:85;pointer-events:all;background:#000000d1;border-radius:4px;max-width:calc(100% - 32px);position:absolute;bottom:72px;overflow:visible}.sdk-overlay-ad--bottom_center{animation:.25s sdk-overlay-ad-in-center;left:50%;transform:translate(-50%)}.sdk-overlay-ad--bottom_left{animation:.25s sdk-overlay-ad-in-side;left:16px}.sdk-overlay-ad--bottom_right{animation:.25s sdk-overlay-ad-in-side;right:16px}.sdk-overlay-ad--top_center{animation:.25s sdk-overlay-ad-in-center;top:16px;bottom:auto;left:50%;transform:translate(-50%)}.sdk-overlay-ad--top_left{animation:.25s sdk-overlay-ad-in-side;top:16px;bottom:auto;left:16px}.sdk-overlay-ad--top_right{animation:.25s sdk-overlay-ad-in-side;top:16px;bottom:auto;right:16px}.sdk-overlay-ad-topbar{justify-content:space-between;align-items:center;height:20px;display:flex;position:absolute;top:-20px;left:0;right:0}.sdk-overlay-ad-label{letter-spacing:.08em;text-transform:uppercase;color:#ffffffa6;-webkit-user-select:none;user-select:none;background:#000000b8;border-radius:3px 3px 0 0;padding:2px 7px;font-size:10px;font-weight:600;line-height:16px}.sdk-overlay-ad-close{color:#ffffffb3;cursor:pointer;background:#000000b8;border:none;border-radius:3px 3px 0 0;padding:2px 7px;font-size:11px;line-height:16px;transition:color .15s,background .15s}.sdk-overlay-ad-close:hover{color:#fff;background:#282828e6}.sdk-overlay-ad-img{cursor:pointer;border-radius:4px;max-width:100%;height:auto;transition:opacity .15s;display:block}.sdk-overlay-ad-img:hover{opacity:.88}@keyframes sdk-overlay-ad-in-center{0%{opacity:0;transform:translate(-50%)translateY(6px)}to{opacity:1;transform:translate(-50%)translateY(0)}}@keyframes sdk-overlay-ad-in-side{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.sdk-spinner-overlay{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:8;pointer-events:none;opacity:0;background:#0f172a73;flex-direction:column;justify-content:center;align-items:center;transition:opacity .3s;display:flex;position:absolute;inset:0}.sdk-spinner-overlay.active{opacity:1}.sdk-spinner{border:4px solid rgba(var(--sdk-theme-color-rgb), .1);border-left-color:var(--sdk-theme-color);border-right-color:rgba(var(--sdk-theme-color-rgb), .2);width:60px;height:60px;filter:drop-shadow(0 0 10px rgba(var(--sdk-theme-color-rgb), .5));border-radius:50%;animation:1s linear infinite sdk-spin}@keyframes sdk-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.sdk-spinner-text{color:#fff;letter-spacing:2px;text-transform:uppercase;text-shadow:0 2px 4px #00000080;margin-top:16px;font-size:13px;font-weight:500;animation:1.5s ease-in-out infinite alternate sdk-pulse}@keyframes sdk-pulse{0%{opacity:.6}to{opacity:1;filter:drop-shadow(0 0 4px var(--sdk-theme-color))}}.sdk-subtitles-overlay{z-index:7;text-align:center;pointer-events:none;justify-content:center;width:80%;display:flex;position:absolute;bottom:80px;left:50%;transform:translate(-50%)}.sdk-subtitles-text{text-shadow:0 1px 3px #000000e6;word-wrap:break-word;border-radius:8px;max-width:100%;padding:8px 16px;font-weight:500;line-height:1.5;transition:font-size .15s,background .15s,color .15s;box-shadow:0 10px 25px -5px #0006}.sdk-cast-bg{z-index:7;pointer-events:none;background:#0000008c;position:absolute;inset:0}.sdk-cast-indicator{color:#3b82f6;white-space:nowrap;letter-spacing:.02em;background:#3b82f626;border:1px solid #3b82f659;border-radius:20px;align-items:center;gap:5px;padding:3px 8px;font-size:11px;font-weight:600;display:inline-flex}.sdk-cast-screen{z-index:8;color:#fff;background:radial-gradient(at top,#1e1b4b 0%,#030712 70%);flex-direction:column;justify-content:center;align-items:center;gap:28px;padding:24px;display:flex;position:absolute;inset:0}.sdk-cast-icon-glow{color:#3b82f6;filter:drop-shadow(0 0 12px #3b82f699);flex-shrink:0;animation:2s infinite alternate sdk-pulse}.sdk-cast-header{flex-direction:row;align-items:center;gap:0;display:flex}.sdk-cast-title{margin-bottom:4px;font-size:18px;font-weight:600}.sdk-cast-desc{color:#9ca3af;font-size:13px}.sdk-cast-controls{flex-direction:column;align-items:center;gap:18px;width:100%;max-width:480px;display:flex}.sdk-cast-seekbar-row{align-items:center;gap:10px;width:100%;display:flex}.sdk-cast-time-label{color:#9ca3af;white-space:nowrap;text-align:center;min-width:38px;font-size:12px}.sdk-cast-seekbar{cursor:pointer;background:#fff3;border-radius:2px;flex:1;height:4px;transition:height .15s;position:relative}.sdk-cast-seekbar:hover{height:6px}.sdk-cast-seekbar-fill{pointer-events:none;background:#3b82f6;border-radius:2px;position:absolute;inset:0 auto 0 0}.sdk-cast-seekbar-thumb{pointer-events:none;opacity:0;background:#fff;border-radius:50%;width:12px;height:12px;transition:opacity .15s;position:absolute;top:50%;transform:translate(-50%,-50%);box-shadow:0 0 6px #3b82f699}.sdk-cast-seekbar:hover .sdk-cast-seekbar-thumb{opacity:1}.sdk-cast-playback-row{align-items:center;gap:28px;display:flex}.sdk-cast-ctrl-btn{color:#e2e8f0;cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;padding:6px;transition:color .15s,background .15s;display:flex;position:relative}.sdk-cast-ctrl-btn:hover{color:#fff;background:#ffffff1a}.sdk-cast-seek-label{pointer-events:none;font-size:9px;font-weight:700;line-height:1;position:absolute}.sdk-cast-play-pause-btn{color:#fff;cursor:pointer;background:#3b82f633;border:2px solid #3b82f680;border-radius:50%;justify-content:center;align-items:center;width:60px;height:60px;transition:background .18s,border-color .18s,transform .1s;display:flex}.sdk-cast-play-pause-btn:hover{background:#3b82f680;border-color:#3b82f6;transform:scale(1.06)}.sdk-cast-play-pause-btn:active{transform:scale(.96)}.sdk-cast-volume-row{align-items:center;gap:10px;width:220px;display:flex}.sdk-cast-vol-btn{color:#9ca3af;cursor:pointer;background:0 0;border:none;align-items:center;padding:4px;transition:color .15s;display:flex}.sdk-cast-vol-btn:hover{color:#fff}.sdk-cast-volume-slider{appearance:none;cursor:pointer;background:#fff3;border-radius:2px;outline:none;flex:1;height:4px}.sdk-cast-volume-slider::-webkit-slider-thumb{appearance:none;cursor:pointer;background:#fff;border-radius:50%;width:14px;height:14px;box-shadow:0 0 4px #0006}.sdk-cast-volume-slider::-moz-range-thumb{cursor:pointer;background:#fff;border:none;border-radius:50%;width:14px;height:14px}.sdk-cast-disconnect-btn{color:#ef4444;cursor:pointer;background:#ef444426;border:1px solid #ef444459;border-radius:6px;padding:8px 20px;font-size:13px;font-weight:500;transition:all .2s}.sdk-cast-disconnect-btn:hover{color:#fff;background:#ef4444;box-shadow:0 0 15px #ef444466}.sdk-controls-overlay{z-index:9;opacity:0;background:linear-gradient(#000000a6 0%,#0000 22%),linear-gradient(#0000 58%,#000c 100%);flex-direction:column;justify-content:flex-end;padding:0;transition:opacity .3s cubic-bezier(.4,0,.2,1);display:flex;position:absolute;inset:0}.sdk-player-container.controls-active .sdk-controls-overlay{opacity:1}.sdk-desktop-header{pointer-events:auto;justify-content:space-between;align-items:center;padding:18px 22px;display:flex;position:absolute;top:0;left:0;right:0}.sdk-desktop-header-left{flex:1;align-items:center;gap:10px;min-width:0;display:flex}.sdk-desktop-header-right{flex-shrink:0;align-items:center;gap:4px;display:flex}.sdk-desktop-back-btn{color:#fff;cursor:pointer;opacity:.9;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:4px;transition:opacity .15s;display:flex}.sdk-desktop-back-btn:hover{opacity:1}.sdk-desktop-title{color:#fff;white-space:nowrap;text-overflow:ellipsis;letter-spacing:.01em;font-size:16px;font-weight:600;overflow:hidden}.sdk-desktop-hdr-btn{color:#ffffffd9;cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:7px;transition:all .18s;display:flex}.sdk-desktop-hdr-btn:hover{color:#fff;background:#ffffff1a}.sdk-desktop-hdr-btn:disabled{opacity:.38;cursor:default}.sdk-desktop-center-controls{align-items:center;gap:36px;display:flex;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.sdk-desktop-seek-btn{color:#fff;cursor:pointer;opacity:.9;background:0 0;border:none;justify-content:center;align-items:center;padding:10px;transition:opacity .15s,transform .12s;display:flex;position:relative}.sdk-desktop-seek-btn:hover{opacity:1;transform:scale(1.12)}.sdk-desktop-seek-btn:active{transform:scale(.9)}.sdk-desktop-seek-btn:disabled{opacity:.35;cursor:default;transform:none!important}.sdk-desktop-seek-label{pointer-events:none;font-family:sans-serif;font-size:8px;font-weight:700;line-height:1;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.sdk-desktop-play-btn{color:#fff;cursor:pointer;opacity:.95;background:0 0;border:none;justify-content:center;align-items:center;padding:10px;transition:opacity .15s,transform .15s;display:flex}.sdk-desktop-play-btn:hover{opacity:1;transform:scale(1.1)}.sdk-desktop-play-btn:active{transform:scale(.9)}.sdk-desktop-bottom{pointer-events:auto;flex-direction:column;display:flex}.sdk-desktop-chapters-strip{scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;gap:14px;padding:0 22px 18px;animation:.22s sdkFadeIn;display:flex;overflow-x:auto}.sdk-desktop-chapters-strip::-webkit-scrollbar{display:none}.sdk-desktop-chapter-card{cursor:pointer;scroll-snap-align:start;flex-shrink:0;width:170px;transition:transform .12s}.sdk-desktop-chapter-card:hover{transform:scale(1.04)}.sdk-desktop-chapter-card:active{transform:scale(.97)}.sdk-desktop-chapter-thumb{background:#ffffff12;border:2px solid #0000;border-radius:8px;justify-content:center;align-items:center;width:100%;height:100px;transition:border-color .15s;display:flex;overflow:hidden}.sdk-desktop-chapter-card.active .sdk-desktop-chapter-thumb{border-color:#ffffff8c}.sdk-desktop-chapter-title{color:#fff;white-space:nowrap;text-overflow:ellipsis;text-align:center;margin-top:7px;font-size:12px;font-weight:500;line-height:1.3;overflow:hidden}.sdk-desktop-chapter-time{color:#fff;text-align:center;letter-spacing:.02em;margin-top:3px;font-size:11px;font-weight:600}.sdk-desktop-seekbar{background:#ffffff47;border-radius:0;height:3px;margin:0}.sdk-desktop-seekbar:hover{height:5px}.sdk-desktop-seekbar .sdk-seekbar-buffered{background:#ffffff59}.sdk-desktop-seekbar .sdk-seekbar-progress{box-shadow:none!important;background:#fff!important}.sdk-desktop-seekbar .sdk-seekbar-handle{background:#fff;width:14px;height:14px;right:-7px}.sdk-desktop-chapter-dot{z-index:3;width:2px;display:none;background:#5a5f69e6!important}.sdk-desktop-controls-row{justify-content:space-between;align-items:center;gap:16px;padding:10px 22px 20px;display:flex}.sdk-desktop-left-controls{align-items:center;gap:6px;display:flex}.sdk-volume-control{align-items:center;gap:2px;display:flex}.sdk-volume-slider{appearance:none;cursor:pointer;background:#ffffff47;background-image:linear-gradient(to right, #fff calc(var(--vol-pct,100%) * 1%), #ffffff47 calc(var(--vol-pct,100%) * 1%));border-radius:3px;outline:none;width:80px;height:3px;transition:height .15s}.sdk-volume-slider:hover{height:5px}.sdk-volume-slider::-webkit-slider-thumb{appearance:none;cursor:pointer;background:#fff;border-radius:50%;width:12px;height:12px;transition:transform .12s;box-shadow:0 0 6px #00000080}.sdk-volume-slider:hover::-webkit-slider-thumb{transform:scale(1.2)}.sdk-volume-slider::-moz-range-thumb{cursor:pointer;background:#fff;border:none;border-radius:50%;width:12px;height:12px;box-shadow:0 0 6px #00000080}.sdk-desktop-right-icons{align-items:center;gap:2px;display:flex}.sdk-desktop-icon-btn{color:#ffffffd1;cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:7px;transition:all .18s;display:flex}.sdk-desktop-icon-btn:hover{color:#fff;background:#ffffff1a}.sdk-desktop-icon-btn:disabled{opacity:.38;cursor:default;transform:none!important}.sdk-seekbar-container{cursor:pointer;background:#ffffff26;border-radius:3px;align-items:center;width:100%;height:6px;transition:height .15s;display:flex;position:relative}.sdk-seekbar-container:before{content:"";z-index:1;position:absolute;inset:-12px 0}.sdk-seekbar-container:hover{height:8px}.sdk-seekbar-buffered{pointer-events:none;background:#ffffff40;border-radius:3px;position:absolute;top:0;bottom:0;left:0}.sdk-seekbar-progress{background:var(--sdk-theme-color);pointer-events:none;box-shadow:0 0 8px rgba(var(--sdk-theme-color-rgb), .6);border-radius:3px;justify-content:flex-end;align-items:center;display:flex;position:absolute;top:0;bottom:0;left:0}.sdk-seekbar-container.sdk-ad-mode,.sdk-seekbar-container.sdk-ad-mode:hover,.sdk-seekbar-container.sdk-ad-mode:active{cursor:default;background:#ffffff26;height:3px!important}.sdk-ad-progress-fill{pointer-events:none;background:#ffe000;border-radius:3px;position:absolute;top:0;bottom:0;left:0}.sdk-seekbar-handle{opacity:0;background:#fff;border-radius:50%;width:12px;height:12px;transition:opacity .15s,transform .15s;position:absolute;right:-6px;transform:scale(.8);box-shadow:0 0 10px #00000080}.sdk-seekbar-container:hover .sdk-seekbar-handle{opacity:1;transform:scale(1)}.sdk-seekbar-adbreak{opacity:.7;pointer-events:none;z-index:3;background:#ffe000;border-radius:1px;width:3px;height:100%;transition:opacity .15s,height .15s,top .15s;position:absolute;top:0}.sdk-seekbar-container:hover .sdk-seekbar-adbreak{opacity:1;height:calc(100% + 4px);top:-2px}.sdk-seekbar-chapter-marker{pointer-events:none;z-index:2;background:#0f172acc;width:2px;position:absolute;top:0;bottom:0}.sdk-thumbnail-tooltip{z-index:10;pointer-events:none;filter:drop-shadow(0 8px 20px #000000a6);flex-direction:column;align-items:center;display:flex;position:absolute;bottom:22px;transform:translate(-50%)}.sdk-thumbnail-preview{background-color:#0c0a09;border:1.5px solid #ffffff2e;border-radius:8px;justify-content:center;align-items:center;width:192px;height:108px;display:flex;overflow:hidden}.sdk-thumbnail-chapter-name{color:#fff;white-space:nowrap;text-align:center;letter-spacing:.01em;margin-top:7px;font-size:12px;font-weight:500}.sdk-thumbnail-time-label{color:#fff;text-align:center;letter-spacing:.02em;margin-top:3px;font-size:11px;font-weight:600}.sdk-control-btn{color:#fff;opacity:.85;cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:6px;transition:all .2s;display:flex}.sdk-control-btn[disabled],.sdk-control-btn.disabled{opacity:.45;cursor:default;transform:none!important}.sdk-control-btn:hover{opacity:1;background:#ffffff14}.sdk-control-btn:active{transform:scale(.95)}.sdk-time-display{color:#fff;font-variant-numeric:tabular-nums;opacity:.9;letter-spacing:.01em;font-size:13px;font-weight:500}.sdk-chapter-badge{color:var(--sdk-theme-color);background:rgba(var(--sdk-theme-color-rgb), .12);border:1px solid rgba(var(--sdk-theme-color-rgb), .25);white-space:nowrap;text-overflow:ellipsis;max-width:180px;box-shadow:0 0 10px rgba(var(--sdk-theme-color-rgb), .15);border-radius:20px;padding:2px 8px;font-size:11px;font-weight:600;overflow:hidden}.sdk-menu-container{position:relative}.sdk-dropup-menu{-webkit-backdrop-filter:blur(32px)saturate(200%);backdrop-filter:blur(32px)saturate(200%);z-index:12;background:#14141c73;border:1px solid #ffffff14;border-radius:12px;flex-direction:column;min-width:172px;padding:0;animation:.18s cubic-bezier(.16,1,.3,1) sdk-menu-slideup;display:flex;position:absolute;bottom:calc(100% + 24px);left:50%;right:auto;overflow:hidden;transform:translate(-50%);box-shadow:0 20px 40px #000000bf}.sdk-dropup-menu.large{scrollbar-width:thin;scrollbar-color:#ffffff1f transparent;min-width:200px;max-height:240px;overflow-y:auto}.sdk-dropup-menu.large::-webkit-scrollbar{width:4px}.sdk-dropup-menu.large::-webkit-scrollbar-track{background:0 0}.sdk-dropup-menu.large::-webkit-scrollbar-thumb{background:#ffffff1f;border-radius:4px}@keyframes sdk-menu-slideup{0%{opacity:0;transform:translate(-50%)translateY(8px)}to{opacity:1;transform:translate(-50%)translateY(0)}}.sdk-dropup-header{color:#fff;letter-spacing:0;border-bottom:1px solid #ffffff1f;padding:14px 16px 12px;font-size:14px;font-weight:700}.sdk-dropup-item{color:#ffffffc7;cursor:pointer;justify-content:space-between;align-items:center;gap:10px;padding:11px 16px;font-size:13px;font-weight:400;transition:background .12s;display:flex}.sdk-dropup-item:hover{color:#fff;background:#ffffff0f}.sdk-dropup-item.active{color:#fff;background:0 0;font-weight:700}.sdk-cast-modal-backdrop{-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);z-index:15;background:#030712cc;justify-content:center;align-items:center;animation:.25s sdk-fadein;display:flex;position:absolute;inset:0}@keyframes sdk-fadein{0%{opacity:0}to{opacity:1}}.sdk-cast-modal{background:#0f172a;border:1px solid #ffffff14;border-radius:12px;flex-direction:column;gap:12px;width:280px;padding:16px;display:flex;box-shadow:0 25px 50px -12px #000c}.sdk-cast-modal-header{border-bottom:1px solid #ffffff0f;justify-content:space-between;align-items:center;padding-bottom:8px;display:flex}.sdk-cast-modal-title{color:#fff;font-size:14px;font-weight:600}.sdk-cast-device-list{flex-direction:column;gap:6px;display:flex}.sdk-cast-device-item{color:#e5e7eb;cursor:pointer;background:#ffffff05;border:1px solid #ffffff0a;border-radius:6px;align-items:center;gap:10px;padding:10px;font-size:13px;transition:all .15s;display:flex}.sdk-cast-device-item:hover{background:rgba(var(--sdk-theme-color-rgb), .1);border-color:rgba(var(--sdk-theme-color-rgb), .3);color:#fff}.sdk-mobile-only{display:none!important}.sdk-dropup-divider{background:#ffffff1f;height:1px;margin:2px 0}.sdk-mobile-settings-menu{scrollbar-width:thin;scrollbar-color:#ffffff1f transparent;min-width:190px;max-height:320px;overflow-y:auto}.sdk-mobile-settings-menu::-webkit-scrollbar{width:4px}.sdk-mobile-settings-menu::-webkit-scrollbar-track{background:0 0}.sdk-mobile-settings-menu::-webkit-scrollbar-thumb{background:#ffffff1f;border-radius:4px}.sdk-chapters-panel{-webkit-backdrop-filter:blur(28px)saturate(160%);backdrop-filter:blur(28px)saturate(160%);z-index:10;pointer-events:auto;background:#0c0c10c7;border:1px solid #ffffff1a;border-radius:14px;flex-direction:column;width:380px;animation:.2s sdkFadeIn;display:flex;position:absolute;top:60px;bottom:80px;right:20px;overflow:hidden}.sdk-chapters-panel-header{border-bottom:1px solid #ffffff1f;flex-shrink:0;padding:16px 18px 14px}.sdk-chapters-panel-title{color:#fff;letter-spacing:.01em;font-size:16px;font-weight:700}.sdk-chapters-panel-list{scrollbar-width:thin;scrollbar-color:#ffffff1f transparent;flex:1;padding:6px 0;overflow-y:auto}.sdk-chapters-panel-list::-webkit-scrollbar{width:4px}.sdk-chapters-panel-list::-webkit-scrollbar-track{background:0 0}.sdk-chapters-panel-list::-webkit-scrollbar-thumb{background:#ffffff1f;border-radius:4px}.sdk-chapters-panel-item{cursor:pointer;border-bottom:1px solid #ffffff0d;align-items:flex-start;gap:14px;padding:12px 16px;transition:background .15s;display:flex}.sdk-chapters-panel-item:last-child{border-bottom:none}.sdk-chapters-panel-item:hover{background:#ffffff0f}.sdk-chapters-panel-item.active{background:#ffffff17}.sdk-chapters-panel-thumb{color:#ffffff4d;background:#ffffff0f;border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;width:128px;height:76px;display:flex;overflow:hidden}.sdk-chapters-panel-info{flex-direction:column;flex:1;gap:4px;min-width:0;padding-top:2px;display:flex}.sdk-chapters-panel-item-title{color:#fff;font-size:14px;font-weight:600;line-height:1.3}.sdk-chapters-panel-item-desc{color:#ffffff7a;-webkit-line-clamp:3;line-clamp:3;-webkit-box-orient:vertical;font-size:12px;line-height:1.45;display:-webkit-box;overflow:hidden}.sdk-chapters-panel-item-time{color:#fff;opacity:.75;margin-top:2px;font-size:12px;font-weight:500}@media (width<=768px){.sdk-desktop-header{padding:14px 16px}.sdk-desktop-controls-row{padding:8px 16px 16px}.sdk-desktop-chapters-strip{padding:0 16px 14px}}@media (width<=480px){.sdk-subtitles-overlay{width:90%;bottom:72px}.sdk-subtitles-text{padding:4px 10px;line-height:1.4;font-size:12px!important}.sdk-seekbar-container:before{top:-16px;bottom:-16px}.sdk-seekbar-handle{opacity:1;width:14px;height:14px;right:-7px;transform:scale(1)}.sdk-dropup-menu{min-width:140px}.sdk-dropup-menu.large{min-width:160px}}@media (width<=360px){.sdk-control-btn{min-width:26px;padding:4px 3px}.sdk-time-display{font-size:9px}}.sdk-mobile-overlay{z-index:9;opacity:0;pointer-events:none;background:linear-gradient(#0000008c 0%,#0000 25% 65%,#000000a6 100%);flex-direction:column;justify-content:space-between;transition:opacity .25s;display:flex;position:absolute;inset:0}.sdk-mobile-overlay.active{opacity:1;pointer-events:auto}.sdk-mobile-header{justify-content:space-between;align-items:center;gap:8px;padding:10px 14px;display:flex}.sdk-mobile-header-left{flex:1;align-items:center;gap:8px;min-width:0;display:flex}.sdk-mobile-back-btn{color:#fff;cursor:pointer;opacity:.9;background:0 0;border:none;flex-shrink:0;align-items:center;padding:4px;display:flex}.sdk-mobile-title{color:#fff;white-space:nowrap;text-overflow:ellipsis;font-size:14px;font-weight:600;overflow:hidden}@media (orientation:portrait){.sdk-mobile-title{display:none}}.sdk-mobile-header-actions{flex-shrink:0;align-items:center;gap:2px;display:flex}.sdk-mobile-hdr-btn{color:#fff;opacity:.9;cursor:pointer;background:0 0;border:none;border-radius:50%;justify-content:center;align-items:center;min-width:44px;min-height:44px;transition:background .15s,opacity .15s;display:flex}.sdk-mobile-hdr-btn:hover,.sdk-mobile-hdr-btn:focus{opacity:1;background:#ffffff1f}.sdk-mobile-hdr-btn:disabled{opacity:.35;cursor:default}.sdk-dropdown-menu{inset:calc(100% + 8px) 0 auto auto}.sdk-mobile-center-controls{justify-content:center;align-items:center;gap:36px;display:flex}.sdk-mobile-seek-btn{color:#fff;cursor:pointer;opacity:.9;background:0 0;border:none;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;width:50px;height:50px;transition:transform .1s,opacity .12s;display:flex;position:relative}.sdk-mobile-seek-btn:hover{opacity:1}.sdk-mobile-seek-btn:active{transform:scale(.9)}.sdk-mobile-seek-btn:disabled{opacity:.35;cursor:default}.sdk-mobile-seek-label{pointer-events:none;font-family:sans-serif;font-size:8px;font-weight:700;line-height:1;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.sdk-mobile-play-btn{color:#fff;cursor:pointer;background:0 0;border:none;flex-shrink:0;justify-content:center;align-items:center;padding:6px;transition:transform .12s;display:flex}.sdk-mobile-play-btn:active{transform:scale(.9)}@keyframes sdk-doubletap-fade{0%{opacity:1}60%{opacity:1}to{opacity:0}}.sdk-mobile-doubletap{pointer-events:none;z-index:20;justify-content:center;align-items:center;width:40%;animation:.7s forwards sdk-doubletap-fade;display:flex;position:absolute;top:0;bottom:0}.sdk-mobile-doubletap.left{background:#ffffff1f;border-radius:0 100% 100% 0/0 50% 50% 0;left:0}.sdk-mobile-doubletap.right{background:#ffffff1f;border-radius:100% 0 0 100%/50% 0 0 50%;right:0}.sdk-mobile-doubletap-icon{color:#fff;filter:drop-shadow(0 1px 4px #00000080);flex-direction:column;align-items:center;gap:4px;display:flex}.sdk-mobile-doubletap-label{letter-spacing:.02em;color:#fff;font-size:11px;font-weight:600;line-height:1}.sdk-mobile-bottom-bar{flex-direction:column;gap:0;display:flex}.sdk-mobile-seekbar{background:#ffffff47;border-radius:0;width:100%;height:3px}.sdk-mobile-seekbar:hover,.sdk-mobile-seekbar:active{height:4px}.sdk-mobile-seekbar .sdk-seekbar-progress{box-shadow:none!important;background:#fff!important}.sdk-mobile-seekbar .sdk-seekbar-handle{background:#fff;width:14px;height:14px;right:-7px;opacity:1!important;transform:scale(1)!important}.sdk-mobile-controls-row{justify-content:space-between;align-items:center;gap:8px;padding:8px 14px 12px;display:flex}.sdk-mobile-bottom-icons .sdk-dropup-menu{border-radius:8px;min-width:130px}.sdk-mobile-bottom-icons .sdk-dropup-header{padding:10px 12px 8px;font-size:12px}.sdk-mobile-bottom-icons .sdk-dropup-item{padding:8px 12px;font-size:12px}.sdk-mobile-bottom-icons{align-items:center;gap:2px;display:flex}.sdk-mobile-icon-btn{color:#ffffffd1;cursor:pointer;background:0 0;border:none;border-radius:5px;justify-content:center;align-items:center;min-width:30px;min-height:30px;padding:6px;transition:color .15s,background .15s;display:flex}.sdk-mobile-icon-btn:hover{color:#fff;background:#ffffff14}.sdk-mobile-icon-btn:disabled{opacity:.35;cursor:default}.sdk-mobile-key-moments-bar{color:#ffffffe6;letter-spacing:.3px;cursor:pointer;justify-content:center;align-items:center;gap:6px;padding:4px 0 2px;font-size:13px;font-weight:600;transition:opacity .15s;display:flex}.sdk-mobile-key-moments-bar:hover{opacity:.8}.sdk-mobile-km-star{opacity:.85;font-size:12px}.sdk-mobile-chapters-scroll{scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;scrollbar-width:none;gap:10px;padding:4px 0 2px;animation:.2s sdkFadeIn;display:flex;overflow-x:auto}.sdk-mobile-chapters-scroll::-webkit-scrollbar{display:none}@keyframes sdkFadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.sdk-mobile-chapter-card{cursor:pointer;scroll-snap-align:start;border:2px solid #0000;border-radius:8px;flex-shrink:0;width:108px;transition:border-color .15s,transform .1s}.sdk-mobile-chapter-card:active{transform:scale(.96)}.sdk-mobile-chapter-card.active{border-color:var(--sdk-theme-color)}.sdk-mobile-chapter-thumb{background:#ffffff0f;border-radius:6px;justify-content:center;align-items:center;width:100%;height:64px;display:flex;position:relative;overflow:hidden}.sdk-mobile-chapter-time-badge{color:#fff;letter-spacing:.3px;background:#000000bf;border-radius:3px;padding:1px 4px;font-size:8px;font-weight:600;position:absolute;bottom:3px;right:4px}.sdk-mobile-chapter-title{color:#fffc;white-space:nowrap;text-overflow:ellipsis;text-align:center;margin-top:5px;padding:0 2px;font-size:10px;font-weight:500;line-height:1.3;overflow:hidden}@media (orientation:landscape) and (height<=500px){.sdk-mobile-header{padding:4px 12px}.sdk-mobile-center-controls{gap:18px}.sdk-mobile-play-circle{width:46px;height:46px}.sdk-mobile-seek-circle{width:38px;height:38px}.sdk-mobile-bottom-bar{gap:4px;padding:0 12px 6px}.sdk-mobile-time{font-size:11px}.sdk-mobile-chapter-thumb{height:48px}.sdk-mobile-chapter-card{width:88px}.sdk-mobile-key-moments-bar{padding:2px 0 0;font-size:12px}.sdk-spinner{width:40px;height:40px}.sdk-subtitles-overlay{bottom:56px}}.sdk-player-container.sdk-fs-simulated .sdk-mobile-header{padding-left:max(14px, env(safe-area-inset-left));padding-right:max(14px, env(safe-area-inset-right))}.sdk-player-container.sdk-fs-simulated .sdk-mobile-bottom-bar{padding-left:max(14px, env(safe-area-inset-left));padding-right:max(14px, env(safe-area-inset-right));padding-bottom:max(10px, env(safe-area-inset-bottom))}.sdk-player-container:fullscreen{width:100%!important;height:100%!important;aspect-ratio:unset!important;border-radius:0!important;max-width:none!important;max-height:none!important}.sdk-player-container:fullscreen{width:100%!important;height:100%!important;aspect-ratio:unset!important;border-radius:0!important;max-width:none!important;max-height:none!important}.sdk-player-container.sdk-fs-simulated{width:100vw!important;height:100vh!important;height:100dvh!important;aspect-ratio:unset!important;z-index:9999!important;border-radius:0!important;position:fixed!important;top:0!important;left:0!important;overflow:hidden!important}.sdk-sr-only{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.sdk-player-container :focus:not(:focus-visible){outline:none}.sdk-desktop-icon-btn:focus-visible,.sdk-desktop-play-btn:focus-visible,.sdk-desktop-seek-btn:focus-visible,.sdk-desktop-back-btn:focus-visible,.sdk-desktop-hdr-btn:focus-visible,.sdk-mobile-icon-btn:focus-visible,.sdk-mobile-play-btn:focus-visible,.sdk-mobile-seek-btn:focus-visible,.sdk-mobile-back-btn:focus-visible,.sdk-mobile-hdr-btn:focus-visible{outline-offset:2px;background:#ffffff1f;border-radius:6px;outline:2px solid #fff}.sdk-skip-ad-btn:focus-visible{outline-offset:3px;outline:2px solid #fff}.sdk-seekbar-container:focus-visible,.sdk-volume-slider:focus-visible{outline-offset:4px;border-radius:4px;outline:2px solid #fff}.sdk-dropup-item:focus-visible{outline-offset:-2px;background:#ffffff24;border-radius:4px;outline:2px solid #fff9}.sdk-desktop-chapter-card:focus-visible,.sdk-chapters-panel-item:focus-visible,.sdk-mobile-chapter-card:focus-visible{outline-offset:2px;border-radius:4px;outline:2px solid #fff}.sdk-desktop-icon-btn,.sdk-mobile-icon-btn,.sdk-desktop-hdr-btn{min-width:32px;min-height:32px}
2
+ /*$vite$:1*/
package/dist/core.cjs ADDED
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./src-kY7Z_lKn.cjs");var t=class{player;install(e){this.player=e,this.onInstall()}destroy(){this.onDestroy()}onDestroy(){}};exports.AnalyticsModule=e.l,exports.BasePlayerPlugin=t,exports.CastingModule=e.r,exports.ChaptersModule=e.o,exports.DRMModule=e.i,exports.FirebaseAnalyticsProvider=e.c,exports.KeyMomentsModule=e.s,exports.SubtitlesModule=e.a,exports.ThumbnailsModule=e.n,exports.VideoPlayerSDK=e.t;
2
+ //# sourceMappingURL=core.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.cjs","names":[],"sources":["../../plugins/src/plugins.ts"],"sourcesContent":["export interface PlayerPlugin {\r\n id: string;\r\n name: string;\r\n install(player: any): void;\r\n destroy?(): void;\r\n}\r\n\r\nexport abstract class BasePlayerPlugin implements PlayerPlugin {\r\n public abstract id: string;\r\n public abstract name: string;\r\n protected player: any;\r\n\r\n public install(player: any): void {\r\n this.player = player;\r\n this.onInstall();\r\n }\r\n\r\n protected abstract onInstall(): void;\r\n\r\n public destroy(): void {\r\n this.onDestroy();\r\n }\r\n\r\n protected onDestroy(): void {}\r\n}\r\n"],"mappings":"yGAOA,IAAsB,EAAtB,KAA+D,CAG7D,OAEA,QAAe,EAAmB,CAChC,KAAK,OAAS,EACd,KAAK,UAAU,CACjB,CAIA,SAAuB,CACrB,KAAK,UAAU,CACjB,CAEA,WAA4B,CAAC,CAC/B"}