@tidal-music/player-web-components 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.
@@ -0,0 +1,3267 @@
1
+ let R = Object.freeze({
2
+ apiUrl: "https://api.tidal.com/v1",
3
+ appVersion: "TIDAL Player",
4
+ clientPlatform: "web",
5
+ desiredVolumeLevel: 1,
6
+ eventUrl: "https://et.tidal.com/api/events",
7
+ gatherEvents: !0,
8
+ loudnessNormalizationMode: "ALBUM",
9
+ outputDevicesEnabled: !1,
10
+ streamingWifiAudioQuality: "LOW"
11
+ });
12
+ function k(t) {
13
+ return R[t];
14
+ }
15
+ function G(t) {
16
+ return R = Object.freeze({
17
+ ...R,
18
+ ...t
19
+ }), Object.keys(t).forEach((e) => {
20
+ const r = e;
21
+ Me.dispatchEvent(new CustomEvent(r, { detail: t[r] }));
22
+ }), R;
23
+ }
24
+ const Me = new EventTarget();
25
+ var ee = (t, e, r) => {
26
+ if (!e.has(t))
27
+ throw TypeError("Cannot " + r);
28
+ }, T = (t, e, r) => (ee(t, e, "read from private field"), r ? r.call(t) : e.get(t)), F = (t, e, r) => {
29
+ if (e.has(t))
30
+ throw TypeError("Cannot add the same private member more than once");
31
+ e instanceof WeakSet ? e.add(t) : e.set(t, r);
32
+ }, B = (t, e, r, s) => (ee(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r), A, C, x, D;
33
+ class te {
34
+ constructor(e) {
35
+ F(this, A, void 0), F(this, C, void 0), F(this, x, !1), F(this, D, void 0), B(this, D, new URL(e)), B(this, A, performance.now());
36
+ }
37
+ now(e = performance.now()) {
38
+ if (!T(this, C) || !T(this, A))
39
+ throw new ReferenceError(
40
+ "Initialization has not been done yet. You need to call and await the synchronize method once."
41
+ );
42
+ return Number.parseInt(
43
+ (T(this, C) + Math.abs(T(this, A) - e)).toFixed(0),
44
+ 10
45
+ );
46
+ }
47
+ /**
48
+ * Use this method to synchronize time with the server.
49
+ *
50
+ * @param url - server url
51
+ */
52
+ async synchronize() {
53
+ if (!T(this, x))
54
+ try {
55
+ const e = await fetch(T(this, D));
56
+ e.ok && e.headers.has("date") && (B(this, C, new Date(e.headers.get("date")).getTime()), B(this, x, !0));
57
+ } catch (e) {
58
+ console.error(e);
59
+ }
60
+ }
61
+ timestamp(e, r) {
62
+ let s;
63
+ if (r) {
64
+ if (s = performance.getEntriesByName(e).find((n) => "detail" in n && n.detail === r), !s)
65
+ throw new ReferenceError(
66
+ `There is no performance entry named "${e}" with detail "${r}"`
67
+ );
68
+ } else
69
+ s = performance.getEntriesByName(e).pop();
70
+ return s ? this.now(s.startTime) : void 0;
71
+ }
72
+ }
73
+ A = /* @__PURE__ */ new WeakMap(), C = /* @__PURE__ */ new WeakMap(), x = /* @__PURE__ */ new WeakMap(), D = /* @__PURE__ */ new WeakMap();
74
+ new te("https://api.tidal.com/v1/ping");
75
+ const b = new te("https://api.tidal.com/v1/ping"), K = (t, e, r) => {
76
+ for (const s of t) {
77
+ const n = s.addedNodes[0];
78
+ s.type === "childList" && n.id === e && r();
79
+ }
80
+ };
81
+ function Ee() {
82
+ const t = document.getElementById("tidal-player-root");
83
+ if (!t)
84
+ return Promise.reject("No player root");
85
+ if ("video-one" in t.children && "video-two" in t.children)
86
+ return Promise.resolve();
87
+ const e = [];
88
+ return "video-one" in t.children || e.push(
89
+ new Promise((r) => {
90
+ new MutationObserver(
91
+ (s) => K(s, "video-one", r)
92
+ ).observe(t, { childList: !0 });
93
+ })
94
+ ), "video-two" in t.children || e.push(
95
+ new Promise((r) => {
96
+ new MutationObserver(
97
+ (s) => K(s, "video-two", r)
98
+ ).observe(t, { childList: !0 });
99
+ })
100
+ ), Promise.all(e);
101
+ }
102
+ const E = document.createElement("video"), P = document.createElement("video"), re = (t) => {
103
+ t.setAttribute("crossorigin", "anonymous"), t.setAttribute("playsinline", "playsinline");
104
+ };
105
+ re(E);
106
+ E.id = "video-one";
107
+ re(P);
108
+ P.id = "video-two";
109
+ const U = "tidal-player-root";
110
+ function Pe() {
111
+ let t = document.getElementById(U);
112
+ if (!t) {
113
+ const e = document.createElement("template");
114
+ e.id = U, document.body.appendChild(e), t = document.getElementById(U);
115
+ }
116
+ return Te();
117
+ }
118
+ function Te() {
119
+ const t = document.getElementById(
120
+ U
121
+ );
122
+ return t && (E.id in t.children || t.appendChild(E), P.id in t.children || t.appendChild(P)), Ee();
123
+ }
124
+ function Ie() {
125
+ return new Promise(
126
+ (t) => document.addEventListener(
127
+ "click",
128
+ () => {
129
+ E.readyState === HTMLMediaElement.HAVE_NOTHING && !E.src && E.load(), P.readyState === HTMLMediaElement.HAVE_NOTHING && !P.src && P.load(), t();
130
+ },
131
+ { once: !0 }
132
+ )
133
+ );
134
+ }
135
+ function Le(t) {
136
+ return new Promise((e) => setTimeout(() => e(), t));
137
+ }
138
+ function Oe(t, e) {
139
+ return new Promise((r) => {
140
+ t.addEventListener(e, (s) => r(s), !1);
141
+ });
142
+ }
143
+ class Ae extends EventTarget {
144
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
145
+ // @ts-ignore - Setter
146
+ #e;
147
+ async dispatchAuthorized() {
148
+ const e = await this.#e.getCredentials();
149
+ e?.token && this.dispatchEvent(
150
+ new CustomEvent("authorized", {
151
+ detail: {
152
+ credentials: e
153
+ }
154
+ })
155
+ );
156
+ }
157
+ set credentialsProvider(e) {
158
+ this.#e = e, this.dispatchAuthorized().catch(console.error), this.#e.bus((r) => {
159
+ switch (r.detail.type) {
160
+ case "credentialsUpdated":
161
+ this.dispatchAuthorized().catch(console.error);
162
+ break;
163
+ default:
164
+ console.warn("Unhandled event from credentials provider: ", r);
165
+ break;
166
+ }
167
+ });
168
+ }
169
+ get credentialsProvider() {
170
+ return this.#e;
171
+ }
172
+ }
173
+ class W extends Error {
174
+ errorCode = null;
175
+ errorId = null;
176
+ referenceId;
177
+ constructor(e, r, s) {
178
+ super(`${e}: ${r} (${s})`), this.errorId = e, this.errorCode = r, this.referenceId = s;
179
+ }
180
+ toJSON() {
181
+ return {
182
+ errorCode: this.errorCode,
183
+ errorId: this.errorId,
184
+ referenceId: this.referenceId
185
+ };
186
+ }
187
+ toString() {
188
+ return JSON.stringify(this.toJSON());
189
+ }
190
+ }
191
+ async function N() {
192
+ if (v.credentialsProvider) {
193
+ const t = await v.credentialsProvider.getCredentials();
194
+ return !!(t.token && t.userId);
195
+ }
196
+ return await Oe(v, "authorized"), N();
197
+ }
198
+ const v = new Ae();
199
+ async function Ce() {
200
+ const t = await N(), e = async () => {
201
+ const { Pushkin: s } = await Promise.resolve().then(() => Lt);
202
+ return s.refresh();
203
+ }, r = async () => (await Promise.resolve().then(() => ft)).start();
204
+ if (t) {
205
+ G({
206
+ gatherEvents: !0
207
+ });
208
+ try {
209
+ await Promise.all([e(), r()]);
210
+ } catch (s) {
211
+ console.error(s);
212
+ }
213
+ } else
214
+ G({
215
+ gatherEvents: !1
216
+ });
217
+ }
218
+ v.addEventListener("authorized", () => {
219
+ Ce().then().catch(console.error);
220
+ });
221
+ async function Y() {
222
+ return v.credentialsProvider ? (await v.credentialsProvider.getCredentials()).token ?? null : null;
223
+ }
224
+ class _e extends EventTarget {
225
+ dispatchError(e) {
226
+ this.dispatchEvent(
227
+ new CustomEvent("error", {
228
+ detail: e.toJSON()
229
+ })
230
+ );
231
+ }
232
+ }
233
+ const h = new _e();
234
+ class Ne {
235
+ #e = /* @__PURE__ */ new Map();
236
+ #r = /* @__PURE__ */ new Map();
237
+ #s = /* @__PURE__ */ new Map();
238
+ /**
239
+ * Clones a session to re-use the media product and playback content for a new session.
240
+ *
241
+ * @param from - streamingSessionId to clone
242
+ * @param to - target streamingSessionId
243
+ */
244
+ clone(e, r) {
245
+ const s = this.getMediaProductTransition(e), n = this.getStreamInfo(e), o = this.getPlaybackInfo(e);
246
+ if (!s || !n || !o)
247
+ throw new Error(
248
+ `Cannot clone ${e}. Missing mediaProductTransition or streamInfo.`
249
+ );
250
+ this.saveMediaProductTransition(r, {
251
+ ...s,
252
+ playbackContext: {
253
+ ...s.playbackContext,
254
+ playbackSessionId: r
255
+ }
256
+ }), this.saveStreamInfo(r, {
257
+ ...n,
258
+ streamingSessionId: r
259
+ }), this.savePlaybackInfo(r, {
260
+ ...o,
261
+ streamingSessionId: r
262
+ });
263
+ }
264
+ deleteMediaProductTransition(e) {
265
+ this.#e.delete(e);
266
+ }
267
+ /**
268
+ * Removed cached playbackInfo, streamInfo and mediaProductTransition for session.
269
+ * For re-using playbackInfo etc for other sessions make sure to run clone before deletion!
270
+ *
271
+ * @see {@link StreamingSessionStore.clone}
272
+ */
273
+ deleteSession(e) {
274
+ this.deleteMediaProductTransition(e), this.#r.delete(e), this.deleteStreamInfo(e);
275
+ }
276
+ deleteStreamInfo(e) {
277
+ this.#s.delete(e);
278
+ }
279
+ getMediaProductTransition(e) {
280
+ return e ? this.#e.get(e) : void 0;
281
+ }
282
+ getPlaybackInfo(e) {
283
+ return e ? this.#r.get(e) : void 0;
284
+ }
285
+ getStreamInfo(e) {
286
+ return e ? this.#s.get(e) : void 0;
287
+ }
288
+ hasMediaProductTransition(e) {
289
+ return this.#e.has(e);
290
+ }
291
+ hasPlaybackInfo(e) {
292
+ return this.#r.has(e);
293
+ }
294
+ hasStreamInfo(e) {
295
+ return this.#s.has(e);
296
+ }
297
+ overwriteDuration(e, r) {
298
+ const s = this.#e.get(e);
299
+ s && (s.playbackContext.actualDuration = r, this.saveMediaProductTransition(e, s));
300
+ }
301
+ saveMediaProductTransition(e, r) {
302
+ this.#e.set(
303
+ e,
304
+ r
305
+ );
306
+ }
307
+ savePlaybackInfo(e, r) {
308
+ this.#r.set(e, r);
309
+ }
310
+ saveStreamInfo(e, r) {
311
+ this.#s.set(e, r);
312
+ }
313
+ }
314
+ const Q = new Ne();
315
+ class Fe {
316
+ activePlayer;
317
+ preloadPlayer;
318
+ get preloadedMediaProduct() {
319
+ return Q.getMediaProductTransition(
320
+ this.preloadedStreamingSessionId
321
+ )?.mediaProduct ?? void 0;
322
+ }
323
+ get preloadedStreamingSessionId() {
324
+ return this.preloadPlayer?.preloadedStreamingSessionId ?? void 0;
325
+ }
326
+ }
327
+ const p = new Fe();
328
+ let Be;
329
+ const Re = [
330
+ {
331
+ itemTypes: ["track", "video"],
332
+ player: "shaka",
333
+ qualities: ["HIGH", "LOSSLESS", "LOW", "HI_RES_LOSSLESS"]
334
+ }
335
+ ];
336
+ let q = Re;
337
+ const w = {
338
+ browser: void 0,
339
+ native: void 0,
340
+ shaka: void 0
341
+ };
342
+ async function xe() {
343
+ await Promise.all(
344
+ q.map((t) => {
345
+ const e = w[t.player];
346
+ return e ? e.reset() : Promise.resolve();
347
+ })
348
+ ), p.activePlayer = void 0, p.preloadPlayer = void 0;
349
+ }
350
+ function De(t) {
351
+ t.name !== "nativePlayer" && w.native && w.native.abandon(), p.activePlayer = t;
352
+ }
353
+ function Ue() {
354
+ h.removeEventListener("ended", Be);
355
+ }
356
+ async function We() {
357
+ const { default: t } = await import("./nativePlayer-U375Dfm5-hUK7oXzY.js");
358
+ return w.native || (w.native = new t()), w.native;
359
+ }
360
+ async function ze() {
361
+ const { default: t } = await import("./browserPlayer-oNOpDVm6-UW0N6pFH.js");
362
+ return w.browser || (w.browser = new t()), w.browser;
363
+ }
364
+ async function Ve() {
365
+ const { default: t } = await import("./shakaPlayer-izGFLVQr--XUsjgT2.js");
366
+ return w.shaka || (w.shaka = new t()), w.shaka;
367
+ }
368
+ async function He(t, e) {
369
+ const r = q.filter((n) => n.itemTypes.includes(t)).filter(
370
+ (n) => t === "track" && n.qualities && e ? n.qualities.includes(e) : !0
371
+ );
372
+ r.length === 0 && console.error(
373
+ `No player found to handle audio quality "${String(
374
+ e
375
+ )}" for product type "${t}" in player config: `,
376
+ q
377
+ );
378
+ const { player: s } = r[0];
379
+ switch (s) {
380
+ case "shaka":
381
+ return Ve();
382
+ case "browser":
383
+ return ze();
384
+ case "native":
385
+ return We();
386
+ default:
387
+ throw new Error("No player found.");
388
+ }
389
+ }
390
+ function qe() {
391
+ return p.activePlayer?.getPosition() ?? 0;
392
+ }
393
+ function Qe() {
394
+ return p.activePlayer?.currentMediaProduct ?? null;
395
+ }
396
+ function $e() {
397
+ const t = p.activePlayer;
398
+ if (t) {
399
+ const e = Q.getMediaProductTransition(
400
+ t.currentStreamingSessionId
401
+ );
402
+ if (e)
403
+ return e.playbackContext;
404
+ }
405
+ }
406
+ function se() {
407
+ return p.activePlayer?.playbackState ?? "IDLE";
408
+ }
409
+ function $(t) {
410
+ return new Promise((e, r) => {
411
+ t.oncomplete = t.onsuccess = () => e(t.result), t.onabort = t.onerror = () => r(t.error);
412
+ });
413
+ }
414
+ function je(t, e) {
415
+ const r = indexedDB.open(t);
416
+ r.onupgradeneeded = () => r.result.createObjectStore(e);
417
+ const s = $(r);
418
+ return (n, o) => s.then((a) => o(a.transaction(e, n).objectStore(e)));
419
+ }
420
+ let V;
421
+ function ie() {
422
+ return V || (V = je("keyval-store", "keyval")), V;
423
+ }
424
+ function ne(t, e = ie()) {
425
+ return e("readonly", (r) => $(r.get(t)));
426
+ }
427
+ function ae(t, e, r = ie()) {
428
+ return r("readwrite", (s) => (s.put(e, t), $(s.transaction)));
429
+ }
430
+ async function L(t, e) {
431
+ let r = /* @__PURE__ */ new Map(), s;
432
+ if (!k("gatherEvents"))
433
+ return (n) => Promise.resolve(void 0);
434
+ try {
435
+ s = await ne(t), s && (r = new Map(s));
436
+ } catch (n) {
437
+ console.error(n);
438
+ }
439
+ return async (n) => {
440
+ const o = r.get(n.streamingSessionId) || e, a = {
441
+ ...o,
442
+ ...n
443
+ };
444
+ for (const c of Object.keys(n)) {
445
+ const d = c;
446
+ Array.isArray(n[d]) && (a[d] = [
447
+ ...o[d] || [],
448
+ ...n[d] || []
449
+ ]);
450
+ }
451
+ r.set(n.streamingSessionId, a);
452
+ try {
453
+ await ae(t, [...r]);
454
+ } catch (c) {
455
+ console.error(c);
456
+ }
457
+ return {
458
+ name: t,
459
+ payload: a
460
+ };
461
+ };
462
+ }
463
+ const Ge = {
464
+ endReason: "COMPLETE",
465
+ endTimestamp: 0,
466
+ errorCode: null,
467
+ errorMessage: null,
468
+ startTimestamp: 0,
469
+ streamingSessionId: ""
470
+ }, Ke = await L(
471
+ "drm_license_fetch",
472
+ Ge
473
+ );
474
+ function Yt(t) {
475
+ return Ke(t);
476
+ }
477
+ const Ye = {
478
+ endReason: "COMPLETE",
479
+ endTimestamp: 0,
480
+ errorCode: null,
481
+ errorMessage: null,
482
+ startTimestamp: 0,
483
+ streamingSessionId: ""
484
+ }, Je = await L(
485
+ "playback_info_fetch",
486
+ Ye
487
+ );
488
+ function H(t) {
489
+ return Je(t);
490
+ }
491
+ function Jt(t) {
492
+ switch (t) {
493
+ case "bluetooth":
494
+ return "BLUETOOTH";
495
+ case "displayPort":
496
+ return "DISPLAY_PORT";
497
+ case "mqa":
498
+ return "MQA";
499
+ case "builtIn":
500
+ return "BUILT_IN";
501
+ case "hdmi":
502
+ return "HDMI";
503
+ case "usb":
504
+ return "USB";
505
+ case "systemDefault":
506
+ return "SYSTEM_DEFAULT";
507
+ case "windowsCommunication":
508
+ case "airplay":
509
+ default:
510
+ return;
511
+ }
512
+ }
513
+ const Xe = {
514
+ actualAssetPresentation: "FULL",
515
+ actualAudioMode: "STEREO",
516
+ actualProductId: null,
517
+ actualQuality: "LOSSLESS",
518
+ actualStartTimestamp: 0,
519
+ actualStreamType: "ON_DEMAND",
520
+ adaptations: [],
521
+ cdm: "WIDEVINE",
522
+ cdmVersion: null,
523
+ endReason: "COMPLETE",
524
+ endTimestamp: 0,
525
+ errorCode: null,
526
+ errorMessage: null,
527
+ hasAds: !1,
528
+ idealStartTimestamp: 0,
529
+ outputDevice: null,
530
+ productType: "TRACK",
531
+ stalls: [],
532
+ streamingSessionId: ""
533
+ }, Ze = await L(
534
+ "playback_statistics",
535
+ Xe
536
+ );
537
+ function J(t) {
538
+ return Ze(t);
539
+ }
540
+ const et = {
541
+ streamingSessionId: "",
542
+ timestamp: 0
543
+ }, tt = await L(
544
+ "streaming_session_end",
545
+ et
546
+ );
547
+ function rt(t) {
548
+ return tt(t);
549
+ }
550
+ const st = {
551
+ "Amazon Silk": "amazon_silk",
552
+ "Android Browser": "android",
553
+ Bada: "bada",
554
+ BlackBerry: "blackberry",
555
+ Chrome: "chrome",
556
+ Chromium: "chromium",
557
+ Electron: "electron",
558
+ Epiphany: "epiphany",
559
+ Firefox: "firefox",
560
+ Focus: "focus",
561
+ Generic: "generic",
562
+ "Google Search": "google_search",
563
+ Googlebot: "googlebot",
564
+ "Internet Explorer": "ie",
565
+ "K-Meleon": "k_meleon",
566
+ Maxthon: "maxthon",
567
+ "Microsoft Edge": "edge",
568
+ "MZ Browser": "mz",
569
+ "NAVER Whale Browser": "naver",
570
+ Opera: "opera",
571
+ "Opera Coast": "opera_coast",
572
+ PhantomJS: "phantomjs",
573
+ Puffin: "puffin",
574
+ QupZilla: "qupzilla",
575
+ QQ: "qq",
576
+ QQLite: "qqlite",
577
+ Safari: "safari",
578
+ Sailfish: "sailfish",
579
+ "Samsung Internet for Android": "samsung_internet",
580
+ SeaMonkey: "seamonkey",
581
+ Sleipnir: "sleipnir",
582
+ Swing: "swing",
583
+ Tizen: "tizen",
584
+ "UC Browser": "uc",
585
+ Vivaldi: "vivaldi",
586
+ "WebOS Browser": "webos",
587
+ WeChat: "wechat",
588
+ "Yandex Browser": "yandex",
589
+ Roku: "roku"
590
+ }, oe = {
591
+ amazon_silk: "Amazon Silk",
592
+ android: "Android Browser",
593
+ bada: "Bada",
594
+ blackberry: "BlackBerry",
595
+ chrome: "Chrome",
596
+ chromium: "Chromium",
597
+ electron: "Electron",
598
+ epiphany: "Epiphany",
599
+ firefox: "Firefox",
600
+ focus: "Focus",
601
+ generic: "Generic",
602
+ googlebot: "Googlebot",
603
+ google_search: "Google Search",
604
+ ie: "Internet Explorer",
605
+ k_meleon: "K-Meleon",
606
+ maxthon: "Maxthon",
607
+ edge: "Microsoft Edge",
608
+ mz: "MZ Browser",
609
+ naver: "NAVER Whale Browser",
610
+ opera: "Opera",
611
+ opera_coast: "Opera Coast",
612
+ phantomjs: "PhantomJS",
613
+ puffin: "Puffin",
614
+ qupzilla: "QupZilla",
615
+ qq: "QQ Browser",
616
+ qqlite: "QQ Browser Lite",
617
+ safari: "Safari",
618
+ sailfish: "Sailfish",
619
+ samsung_internet: "Samsung Internet for Android",
620
+ seamonkey: "SeaMonkey",
621
+ sleipnir: "Sleipnir",
622
+ swing: "Swing",
623
+ tizen: "Tizen",
624
+ uc: "UC Browser",
625
+ vivaldi: "Vivaldi",
626
+ webos: "WebOS Browser",
627
+ wechat: "WeChat",
628
+ yandex: "Yandex Browser"
629
+ }, m = {
630
+ tablet: "tablet",
631
+ mobile: "mobile",
632
+ desktop: "desktop",
633
+ tv: "tv"
634
+ }, g = {
635
+ WindowsPhone: "Windows Phone",
636
+ Windows: "Windows",
637
+ MacOS: "macOS",
638
+ iOS: "iOS",
639
+ Android: "Android",
640
+ WebOS: "WebOS",
641
+ BlackBerry: "BlackBerry",
642
+ Bada: "Bada",
643
+ Tizen: "Tizen",
644
+ Linux: "Linux",
645
+ ChromeOS: "Chrome OS",
646
+ PlayStation4: "PlayStation 4",
647
+ Roku: "Roku"
648
+ }, S = {
649
+ EdgeHTML: "EdgeHTML",
650
+ Blink: "Blink",
651
+ Trident: "Trident",
652
+ Presto: "Presto",
653
+ Gecko: "Gecko",
654
+ WebKit: "WebKit"
655
+ };
656
+ class i {
657
+ /**
658
+ * Get first matched item for a string
659
+ * @param {RegExp} regexp
660
+ * @param {String} ua
661
+ * @return {Array|{index: number, input: string}|*|boolean|string}
662
+ */
663
+ static getFirstMatch(e, r) {
664
+ const s = r.match(e);
665
+ return s && s.length > 0 && s[1] || "";
666
+ }
667
+ /**
668
+ * Get second matched item for a string
669
+ * @param regexp
670
+ * @param {String} ua
671
+ * @return {Array|{index: number, input: string}|*|boolean|string}
672
+ */
673
+ static getSecondMatch(e, r) {
674
+ const s = r.match(e);
675
+ return s && s.length > 1 && s[2] || "";
676
+ }
677
+ /**
678
+ * Match a regexp and return a constant or undefined
679
+ * @param {RegExp} regexp
680
+ * @param {String} ua
681
+ * @param {*} _const Any const that will be returned if regexp matches the string
682
+ * @return {*}
683
+ */
684
+ static matchAndReturnConst(e, r, s) {
685
+ if (e.test(r))
686
+ return s;
687
+ }
688
+ static getWindowsVersionName(e) {
689
+ switch (e) {
690
+ case "NT":
691
+ return "NT";
692
+ case "XP":
693
+ return "XP";
694
+ case "NT 5.0":
695
+ return "2000";
696
+ case "NT 5.1":
697
+ return "XP";
698
+ case "NT 5.2":
699
+ return "2003";
700
+ case "NT 6.0":
701
+ return "Vista";
702
+ case "NT 6.1":
703
+ return "7";
704
+ case "NT 6.2":
705
+ return "8";
706
+ case "NT 6.3":
707
+ return "8.1";
708
+ case "NT 10.0":
709
+ return "10";
710
+ default:
711
+ return;
712
+ }
713
+ }
714
+ /**
715
+ * Get macOS version name
716
+ * 10.5 - Leopard
717
+ * 10.6 - Snow Leopard
718
+ * 10.7 - Lion
719
+ * 10.8 - Mountain Lion
720
+ * 10.9 - Mavericks
721
+ * 10.10 - Yosemite
722
+ * 10.11 - El Capitan
723
+ * 10.12 - Sierra
724
+ * 10.13 - High Sierra
725
+ * 10.14 - Mojave
726
+ * 10.15 - Catalina
727
+ *
728
+ * @example
729
+ * getMacOSVersionName("10.14") // 'Mojave'
730
+ *
731
+ * @param {string} version
732
+ * @return {string} versionName
733
+ */
734
+ static getMacOSVersionName(e) {
735
+ const r = e.split(".").splice(0, 2).map((s) => parseInt(s, 10) || 0);
736
+ if (r.push(0), r[0] === 10)
737
+ switch (r[1]) {
738
+ case 5:
739
+ return "Leopard";
740
+ case 6:
741
+ return "Snow Leopard";
742
+ case 7:
743
+ return "Lion";
744
+ case 8:
745
+ return "Mountain Lion";
746
+ case 9:
747
+ return "Mavericks";
748
+ case 10:
749
+ return "Yosemite";
750
+ case 11:
751
+ return "El Capitan";
752
+ case 12:
753
+ return "Sierra";
754
+ case 13:
755
+ return "High Sierra";
756
+ case 14:
757
+ return "Mojave";
758
+ case 15:
759
+ return "Catalina";
760
+ default:
761
+ return;
762
+ }
763
+ }
764
+ /**
765
+ * Get Android version name
766
+ * 1.5 - Cupcake
767
+ * 1.6 - Donut
768
+ * 2.0 - Eclair
769
+ * 2.1 - Eclair
770
+ * 2.2 - Froyo
771
+ * 2.x - Gingerbread
772
+ * 3.x - Honeycomb
773
+ * 4.0 - Ice Cream Sandwich
774
+ * 4.1 - Jelly Bean
775
+ * 4.4 - KitKat
776
+ * 5.x - Lollipop
777
+ * 6.x - Marshmallow
778
+ * 7.x - Nougat
779
+ * 8.x - Oreo
780
+ * 9.x - Pie
781
+ *
782
+ * @example
783
+ * getAndroidVersionName("7.0") // 'Nougat'
784
+ *
785
+ * @param {string} version
786
+ * @return {string} versionName
787
+ */
788
+ static getAndroidVersionName(e) {
789
+ const r = e.split(".").splice(0, 2).map((s) => parseInt(s, 10) || 0);
790
+ if (r.push(0), !(r[0] === 1 && r[1] < 5)) {
791
+ if (r[0] === 1 && r[1] < 6)
792
+ return "Cupcake";
793
+ if (r[0] === 1 && r[1] >= 6)
794
+ return "Donut";
795
+ if (r[0] === 2 && r[1] < 2)
796
+ return "Eclair";
797
+ if (r[0] === 2 && r[1] === 2)
798
+ return "Froyo";
799
+ if (r[0] === 2 && r[1] > 2)
800
+ return "Gingerbread";
801
+ if (r[0] === 3)
802
+ return "Honeycomb";
803
+ if (r[0] === 4 && r[1] < 1)
804
+ return "Ice Cream Sandwich";
805
+ if (r[0] === 4 && r[1] < 4)
806
+ return "Jelly Bean";
807
+ if (r[0] === 4 && r[1] >= 4)
808
+ return "KitKat";
809
+ if (r[0] === 5)
810
+ return "Lollipop";
811
+ if (r[0] === 6)
812
+ return "Marshmallow";
813
+ if (r[0] === 7)
814
+ return "Nougat";
815
+ if (r[0] === 8)
816
+ return "Oreo";
817
+ if (r[0] === 9)
818
+ return "Pie";
819
+ }
820
+ }
821
+ /**
822
+ * Get version precisions count
823
+ *
824
+ * @example
825
+ * getVersionPrecision("1.10.3") // 3
826
+ *
827
+ * @param {string} version
828
+ * @return {number}
829
+ */
830
+ static getVersionPrecision(e) {
831
+ return e.split(".").length;
832
+ }
833
+ /**
834
+ * Calculate browser version weight
835
+ *
836
+ * @example
837
+ * compareVersions('1.10.2.1', '1.8.2.1.90') // 1
838
+ * compareVersions('1.010.2.1', '1.09.2.1.90'); // 1
839
+ * compareVersions('1.10.2.1', '1.10.2.1'); // 0
840
+ * compareVersions('1.10.2.1', '1.0800.2'); // -1
841
+ * compareVersions('1.10.2.1', '1.10', true); // 0
842
+ *
843
+ * @param {String} versionA versions versions to compare
844
+ * @param {String} versionB versions versions to compare
845
+ * @param {boolean} [isLoose] enable loose comparison
846
+ * @return {Number} comparison result: -1 when versionA is lower,
847
+ * 1 when versionA is bigger, 0 when both equal
848
+ */
849
+ /* eslint consistent-return: 1 */
850
+ static compareVersions(e, r, s = !1) {
851
+ const n = i.getVersionPrecision(e), o = i.getVersionPrecision(r);
852
+ let a = Math.max(n, o), c = 0;
853
+ const d = i.map([e, r], (l) => {
854
+ const y = a - i.getVersionPrecision(l), M = l + new Array(y + 1).join(".0");
855
+ return i.map(M.split("."), (f) => new Array(20 - f.length).join("0") + f).reverse();
856
+ });
857
+ for (s && (c = a - Math.min(n, o)), a -= 1; a >= c; ) {
858
+ if (d[0][a] > d[1][a])
859
+ return 1;
860
+ if (d[0][a] === d[1][a]) {
861
+ if (a === c)
862
+ return 0;
863
+ a -= 1;
864
+ } else if (d[0][a] < d[1][a])
865
+ return -1;
866
+ }
867
+ }
868
+ /**
869
+ * Array::map polyfill
870
+ *
871
+ * @param {Array} arr
872
+ * @param {Function} iterator
873
+ * @return {Array}
874
+ */
875
+ static map(e, r) {
876
+ const s = [];
877
+ let n;
878
+ if (Array.prototype.map)
879
+ return Array.prototype.map.call(e, r);
880
+ for (n = 0; n < e.length; n += 1)
881
+ s.push(r(e[n]));
882
+ return s;
883
+ }
884
+ /**
885
+ * Array::find polyfill
886
+ *
887
+ * @param {Array} arr
888
+ * @param {Function} predicate
889
+ * @return {Array}
890
+ */
891
+ static find(e, r) {
892
+ let s, n;
893
+ if (Array.prototype.find)
894
+ return Array.prototype.find.call(e, r);
895
+ for (s = 0, n = e.length; s < n; s += 1) {
896
+ const o = e[s];
897
+ if (r(o, s))
898
+ return o;
899
+ }
900
+ }
901
+ /**
902
+ * Object::assign polyfill
903
+ *
904
+ * @param {Object} obj
905
+ * @param {Object} ...objs
906
+ * @return {Object}
907
+ */
908
+ static assign(e, ...r) {
909
+ const s = e;
910
+ let n, o;
911
+ if (Object.assign)
912
+ return Object.assign(e, ...r);
913
+ for (n = 0, o = r.length; n < o; n += 1) {
914
+ const a = r[n];
915
+ typeof a == "object" && a !== null && Object.keys(a).forEach((c) => {
916
+ s[c] = a[c];
917
+ });
918
+ }
919
+ return e;
920
+ }
921
+ /**
922
+ * Get short version/alias for a browser name
923
+ *
924
+ * @example
925
+ * getBrowserAlias('Microsoft Edge') // edge
926
+ *
927
+ * @param {string} browserName
928
+ * @return {string}
929
+ */
930
+ static getBrowserAlias(e) {
931
+ return st[e];
932
+ }
933
+ /**
934
+ * Get short version/alias for a browser name
935
+ *
936
+ * @example
937
+ * getBrowserAlias('edge') // Microsoft Edge
938
+ *
939
+ * @param {string} browserAlias
940
+ * @return {string}
941
+ */
942
+ static getBrowserTypeByAlias(e) {
943
+ return oe[e] || "";
944
+ }
945
+ }
946
+ const u = /version\/(\d+(\.?_?\d+)+)/i, it = [
947
+ /* Googlebot */
948
+ {
949
+ test: [/googlebot/i],
950
+ describe(t) {
951
+ const e = {
952
+ name: "Googlebot"
953
+ }, r = i.getFirstMatch(/googlebot\/(\d+(\.\d+))/i, t) || i.getFirstMatch(u, t);
954
+ return r && (e.version = r), e;
955
+ }
956
+ },
957
+ /* Opera < 13.0 */
958
+ {
959
+ test: [/opera/i],
960
+ describe(t) {
961
+ const e = {
962
+ name: "Opera"
963
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:opera)[\s/](\d+(\.?_?\d+)+)/i, t);
964
+ return r && (e.version = r), e;
965
+ }
966
+ },
967
+ /* Opera > 13.0 */
968
+ {
969
+ test: [/opr\/|opios/i],
970
+ describe(t) {
971
+ const e = {
972
+ name: "Opera"
973
+ }, r = i.getFirstMatch(/(?:opr|opios)[\s/](\S+)/i, t) || i.getFirstMatch(u, t);
974
+ return r && (e.version = r), e;
975
+ }
976
+ },
977
+ {
978
+ test: [/SamsungBrowser/i],
979
+ describe(t) {
980
+ const e = {
981
+ name: "Samsung Internet for Android"
982
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:SamsungBrowser)[\s/](\d+(\.?_?\d+)+)/i, t);
983
+ return r && (e.version = r), e;
984
+ }
985
+ },
986
+ {
987
+ test: [/Whale/i],
988
+ describe(t) {
989
+ const e = {
990
+ name: "NAVER Whale Browser"
991
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:whale)[\s/](\d+(?:\.\d+)+)/i, t);
992
+ return r && (e.version = r), e;
993
+ }
994
+ },
995
+ {
996
+ test: [/MZBrowser/i],
997
+ describe(t) {
998
+ const e = {
999
+ name: "MZ Browser"
1000
+ }, r = i.getFirstMatch(/(?:MZBrowser)[\s/](\d+(?:\.\d+)+)/i, t) || i.getFirstMatch(u, t);
1001
+ return r && (e.version = r), e;
1002
+ }
1003
+ },
1004
+ {
1005
+ test: [/focus/i],
1006
+ describe(t) {
1007
+ const e = {
1008
+ name: "Focus"
1009
+ }, r = i.getFirstMatch(/(?:focus)[\s/](\d+(?:\.\d+)+)/i, t) || i.getFirstMatch(u, t);
1010
+ return r && (e.version = r), e;
1011
+ }
1012
+ },
1013
+ {
1014
+ test: [/swing/i],
1015
+ describe(t) {
1016
+ const e = {
1017
+ name: "Swing"
1018
+ }, r = i.getFirstMatch(/(?:swing)[\s/](\d+(?:\.\d+)+)/i, t) || i.getFirstMatch(u, t);
1019
+ return r && (e.version = r), e;
1020
+ }
1021
+ },
1022
+ {
1023
+ test: [/coast/i],
1024
+ describe(t) {
1025
+ const e = {
1026
+ name: "Opera Coast"
1027
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:coast)[\s/](\d+(\.?_?\d+)+)/i, t);
1028
+ return r && (e.version = r), e;
1029
+ }
1030
+ },
1031
+ {
1032
+ test: [/opt\/\d+(?:.?_?\d+)+/i],
1033
+ describe(t) {
1034
+ const e = {
1035
+ name: "Opera Touch"
1036
+ }, r = i.getFirstMatch(/(?:opt)[\s/](\d+(\.?_?\d+)+)/i, t) || i.getFirstMatch(u, t);
1037
+ return r && (e.version = r), e;
1038
+ }
1039
+ },
1040
+ {
1041
+ test: [/yabrowser/i],
1042
+ describe(t) {
1043
+ const e = {
1044
+ name: "Yandex Browser"
1045
+ }, r = i.getFirstMatch(/(?:yabrowser)[\s/](\d+(\.?_?\d+)+)/i, t) || i.getFirstMatch(u, t);
1046
+ return r && (e.version = r), e;
1047
+ }
1048
+ },
1049
+ {
1050
+ test: [/ucbrowser/i],
1051
+ describe(t) {
1052
+ const e = {
1053
+ name: "UC Browser"
1054
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:ucbrowser)[\s/](\d+(\.?_?\d+)+)/i, t);
1055
+ return r && (e.version = r), e;
1056
+ }
1057
+ },
1058
+ {
1059
+ test: [/Maxthon|mxios/i],
1060
+ describe(t) {
1061
+ const e = {
1062
+ name: "Maxthon"
1063
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:Maxthon|mxios)[\s/](\d+(\.?_?\d+)+)/i, t);
1064
+ return r && (e.version = r), e;
1065
+ }
1066
+ },
1067
+ {
1068
+ test: [/epiphany/i],
1069
+ describe(t) {
1070
+ const e = {
1071
+ name: "Epiphany"
1072
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:epiphany)[\s/](\d+(\.?_?\d+)+)/i, t);
1073
+ return r && (e.version = r), e;
1074
+ }
1075
+ },
1076
+ {
1077
+ test: [/puffin/i],
1078
+ describe(t) {
1079
+ const e = {
1080
+ name: "Puffin"
1081
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:puffin)[\s/](\d+(\.?_?\d+)+)/i, t);
1082
+ return r && (e.version = r), e;
1083
+ }
1084
+ },
1085
+ {
1086
+ test: [/sleipnir/i],
1087
+ describe(t) {
1088
+ const e = {
1089
+ name: "Sleipnir"
1090
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:sleipnir)[\s/](\d+(\.?_?\d+)+)/i, t);
1091
+ return r && (e.version = r), e;
1092
+ }
1093
+ },
1094
+ {
1095
+ test: [/k-meleon/i],
1096
+ describe(t) {
1097
+ const e = {
1098
+ name: "K-Meleon"
1099
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/(?:k-meleon)[\s/](\d+(\.?_?\d+)+)/i, t);
1100
+ return r && (e.version = r), e;
1101
+ }
1102
+ },
1103
+ {
1104
+ test: [/micromessenger/i],
1105
+ describe(t) {
1106
+ const e = {
1107
+ name: "WeChat"
1108
+ }, r = i.getFirstMatch(/(?:micromessenger)[\s/](\d+(\.?_?\d+)+)/i, t) || i.getFirstMatch(u, t);
1109
+ return r && (e.version = r), e;
1110
+ }
1111
+ },
1112
+ {
1113
+ test: [/qqbrowser/i],
1114
+ describe(t) {
1115
+ const e = {
1116
+ name: /qqbrowserlite/i.test(t) ? "QQ Browser Lite" : "QQ Browser"
1117
+ }, r = i.getFirstMatch(/(?:qqbrowserlite|qqbrowser)[/](\d+(\.?_?\d+)+)/i, t) || i.getFirstMatch(u, t);
1118
+ return r && (e.version = r), e;
1119
+ }
1120
+ },
1121
+ {
1122
+ test: [/msie|trident/i],
1123
+ describe(t) {
1124
+ const e = {
1125
+ name: "Internet Explorer"
1126
+ }, r = i.getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i, t);
1127
+ return r && (e.version = r), e;
1128
+ }
1129
+ },
1130
+ {
1131
+ test: [/\sedg\//i],
1132
+ describe(t) {
1133
+ const e = {
1134
+ name: "Microsoft Edge"
1135
+ }, r = i.getFirstMatch(/\sedg\/(\d+(\.?_?\d+)+)/i, t);
1136
+ return r && (e.version = r), e;
1137
+ }
1138
+ },
1139
+ {
1140
+ test: [/edg([ea]|ios)/i],
1141
+ describe(t) {
1142
+ const e = {
1143
+ name: "Microsoft Edge"
1144
+ }, r = i.getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i, t);
1145
+ return r && (e.version = r), e;
1146
+ }
1147
+ },
1148
+ {
1149
+ test: [/vivaldi/i],
1150
+ describe(t) {
1151
+ const e = {
1152
+ name: "Vivaldi"
1153
+ }, r = i.getFirstMatch(/vivaldi\/(\d+(\.?_?\d+)+)/i, t);
1154
+ return r && (e.version = r), e;
1155
+ }
1156
+ },
1157
+ {
1158
+ test: [/seamonkey/i],
1159
+ describe(t) {
1160
+ const e = {
1161
+ name: "SeaMonkey"
1162
+ }, r = i.getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i, t);
1163
+ return r && (e.version = r), e;
1164
+ }
1165
+ },
1166
+ {
1167
+ test: [/sailfish/i],
1168
+ describe(t) {
1169
+ const e = {
1170
+ name: "Sailfish"
1171
+ }, r = i.getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i, t);
1172
+ return r && (e.version = r), e;
1173
+ }
1174
+ },
1175
+ {
1176
+ test: [/silk/i],
1177
+ describe(t) {
1178
+ const e = {
1179
+ name: "Amazon Silk"
1180
+ }, r = i.getFirstMatch(/silk\/(\d+(\.?_?\d+)+)/i, t);
1181
+ return r && (e.version = r), e;
1182
+ }
1183
+ },
1184
+ {
1185
+ test: [/phantom/i],
1186
+ describe(t) {
1187
+ const e = {
1188
+ name: "PhantomJS"
1189
+ }, r = i.getFirstMatch(/phantomjs\/(\d+(\.?_?\d+)+)/i, t);
1190
+ return r && (e.version = r), e;
1191
+ }
1192
+ },
1193
+ {
1194
+ test: [/slimerjs/i],
1195
+ describe(t) {
1196
+ const e = {
1197
+ name: "SlimerJS"
1198
+ }, r = i.getFirstMatch(/slimerjs\/(\d+(\.?_?\d+)+)/i, t);
1199
+ return r && (e.version = r), e;
1200
+ }
1201
+ },
1202
+ {
1203
+ test: [/blackberry|\bbb\d+/i, /rim\stablet/i],
1204
+ describe(t) {
1205
+ const e = {
1206
+ name: "BlackBerry"
1207
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/blackberry[\d]+\/(\d+(\.?_?\d+)+)/i, t);
1208
+ return r && (e.version = r), e;
1209
+ }
1210
+ },
1211
+ {
1212
+ test: [/(web|hpw)[o0]s/i],
1213
+ describe(t) {
1214
+ const e = {
1215
+ name: "WebOS Browser"
1216
+ }, r = i.getFirstMatch(u, t) || i.getFirstMatch(/w(?:eb)?[o0]sbrowser\/(\d+(\.?_?\d+)+)/i, t);
1217
+ return r && (e.version = r), e;
1218
+ }
1219
+ },
1220
+ {
1221
+ test: [/bada/i],
1222
+ describe(t) {
1223
+ const e = {
1224
+ name: "Bada"
1225
+ }, r = i.getFirstMatch(/dolfin\/(\d+(\.?_?\d+)+)/i, t);
1226
+ return r && (e.version = r), e;
1227
+ }
1228
+ },
1229
+ {
1230
+ test: [/tizen/i],
1231
+ describe(t) {
1232
+ const e = {
1233
+ name: "Tizen"
1234
+ }, r = i.getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.?_?\d+)+)/i, t) || i.getFirstMatch(u, t);
1235
+ return r && (e.version = r), e;
1236
+ }
1237
+ },
1238
+ {
1239
+ test: [/qupzilla/i],
1240
+ describe(t) {
1241
+ const e = {
1242
+ name: "QupZilla"
1243
+ }, r = i.getFirstMatch(/(?:qupzilla)[\s/](\d+(\.?_?\d+)+)/i, t) || i.getFirstMatch(u, t);
1244
+ return r && (e.version = r), e;
1245
+ }
1246
+ },
1247
+ {
1248
+ test: [/firefox|iceweasel|fxios/i],
1249
+ describe(t) {
1250
+ const e = {
1251
+ name: "Firefox"
1252
+ }, r = i.getFirstMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, t);
1253
+ return r && (e.version = r), e;
1254
+ }
1255
+ },
1256
+ {
1257
+ test: [/electron/i],
1258
+ describe(t) {
1259
+ const e = {
1260
+ name: "Electron"
1261
+ }, r = i.getFirstMatch(/(?:electron)\/(\d+(\.?_?\d+)+)/i, t);
1262
+ return r && (e.version = r), e;
1263
+ }
1264
+ },
1265
+ {
1266
+ test: [/MiuiBrowser/i],
1267
+ describe(t) {
1268
+ const e = {
1269
+ name: "Miui"
1270
+ }, r = i.getFirstMatch(/(?:MiuiBrowser)[\s/](\d+(\.?_?\d+)+)/i, t);
1271
+ return r && (e.version = r), e;
1272
+ }
1273
+ },
1274
+ {
1275
+ test: [/chromium/i],
1276
+ describe(t) {
1277
+ const e = {
1278
+ name: "Chromium"
1279
+ }, r = i.getFirstMatch(/(?:chromium)[\s/](\d+(\.?_?\d+)+)/i, t) || i.getFirstMatch(u, t);
1280
+ return r && (e.version = r), e;
1281
+ }
1282
+ },
1283
+ {
1284
+ test: [/chrome|crios|crmo/i],
1285
+ describe(t) {
1286
+ const e = {
1287
+ name: "Chrome"
1288
+ }, r = i.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i, t);
1289
+ return r && (e.version = r), e;
1290
+ }
1291
+ },
1292
+ {
1293
+ test: [/GSA/i],
1294
+ describe(t) {
1295
+ const e = {
1296
+ name: "Google Search"
1297
+ }, r = i.getFirstMatch(/(?:GSA)\/(\d+(\.?_?\d+)+)/i, t);
1298
+ return r && (e.version = r), e;
1299
+ }
1300
+ },
1301
+ /* Android Browser */
1302
+ {
1303
+ test(t) {
1304
+ const e = !t.test(/like android/i), r = t.test(/android/i);
1305
+ return e && r;
1306
+ },
1307
+ describe(t) {
1308
+ const e = {
1309
+ name: "Android Browser"
1310
+ }, r = i.getFirstMatch(u, t);
1311
+ return r && (e.version = r), e;
1312
+ }
1313
+ },
1314
+ /* PlayStation 4 */
1315
+ {
1316
+ test: [/playstation 4/i],
1317
+ describe(t) {
1318
+ const e = {
1319
+ name: "PlayStation 4"
1320
+ }, r = i.getFirstMatch(u, t);
1321
+ return r && (e.version = r), e;
1322
+ }
1323
+ },
1324
+ /* Safari */
1325
+ {
1326
+ test: [/safari|applewebkit/i],
1327
+ describe(t) {
1328
+ const e = {
1329
+ name: "Safari"
1330
+ }, r = i.getFirstMatch(u, t);
1331
+ return r && (e.version = r), e;
1332
+ }
1333
+ },
1334
+ /* Something else */
1335
+ {
1336
+ test: [/.*/i],
1337
+ describe(t) {
1338
+ const e = /^(.*)\/(.*) /, r = /^(.*)\/(.*)[ \t]\((.*)/, s = t.search("\\(") !== -1 ? r : e;
1339
+ return {
1340
+ name: i.getFirstMatch(s, t),
1341
+ version: i.getSecondMatch(s, t)
1342
+ };
1343
+ }
1344
+ }
1345
+ ], nt = [
1346
+ /* Roku */
1347
+ {
1348
+ test: [/Roku\/DVP/],
1349
+ describe(t) {
1350
+ const e = i.getFirstMatch(/Roku\/DVP-(\d+\.\d+)/i, t);
1351
+ return {
1352
+ name: g.Roku,
1353
+ version: e
1354
+ };
1355
+ }
1356
+ },
1357
+ /* Windows Phone */
1358
+ {
1359
+ test: [/windows phone/i],
1360
+ describe(t) {
1361
+ const e = i.getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i, t);
1362
+ return {
1363
+ name: g.WindowsPhone,
1364
+ version: e
1365
+ };
1366
+ }
1367
+ },
1368
+ /* Windows */
1369
+ {
1370
+ test: [/windows /i],
1371
+ describe(t) {
1372
+ const e = i.getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i, t), r = i.getWindowsVersionName(e);
1373
+ return {
1374
+ name: g.Windows,
1375
+ version: e,
1376
+ versionName: r
1377
+ };
1378
+ }
1379
+ },
1380
+ /* Firefox on iPad */
1381
+ {
1382
+ test: [/Macintosh(.*?) FxiOS(.*?)\//],
1383
+ describe(t) {
1384
+ const e = {
1385
+ name: g.iOS
1386
+ }, r = i.getSecondMatch(/(Version\/)(\d[\d.]+)/, t);
1387
+ return r && (e.version = r), e;
1388
+ }
1389
+ },
1390
+ /* macOS */
1391
+ {
1392
+ test: [/macintosh/i],
1393
+ describe(t) {
1394
+ const e = i.getFirstMatch(/mac os x (\d+(\.?_?\d+)+)/i, t).replace(/[_\s]/g, "."), r = i.getMacOSVersionName(e), s = {
1395
+ name: g.MacOS,
1396
+ version: e
1397
+ };
1398
+ return r && (s.versionName = r), s;
1399
+ }
1400
+ },
1401
+ /* iOS */
1402
+ {
1403
+ test: [/(ipod|iphone|ipad)/i],
1404
+ describe(t) {
1405
+ const e = i.getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i, t).replace(/[_\s]/g, ".");
1406
+ return {
1407
+ name: g.iOS,
1408
+ version: e
1409
+ };
1410
+ }
1411
+ },
1412
+ /* Android */
1413
+ {
1414
+ test(t) {
1415
+ const e = !t.test(/like android/i), r = t.test(/android/i);
1416
+ return e && r;
1417
+ },
1418
+ describe(t) {
1419
+ const e = i.getFirstMatch(/android[\s/-](\d+(\.\d+)*)/i, t), r = i.getAndroidVersionName(e), s = {
1420
+ name: g.Android,
1421
+ version: e
1422
+ };
1423
+ return r && (s.versionName = r), s;
1424
+ }
1425
+ },
1426
+ /* WebOS */
1427
+ {
1428
+ test: [/(web|hpw)[o0]s/i],
1429
+ describe(t) {
1430
+ const e = i.getFirstMatch(/(?:web|hpw)[o0]s\/(\d+(\.\d+)*)/i, t), r = {
1431
+ name: g.WebOS
1432
+ };
1433
+ return e && e.length && (r.version = e), r;
1434
+ }
1435
+ },
1436
+ /* BlackBerry */
1437
+ {
1438
+ test: [/blackberry|\bbb\d+/i, /rim\stablet/i],
1439
+ describe(t) {
1440
+ const e = i.getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i, t) || i.getFirstMatch(/blackberry\d+\/(\d+([_\s]\d+)*)/i, t) || i.getFirstMatch(/\bbb(\d+)/i, t);
1441
+ return {
1442
+ name: g.BlackBerry,
1443
+ version: e
1444
+ };
1445
+ }
1446
+ },
1447
+ /* Bada */
1448
+ {
1449
+ test: [/bada/i],
1450
+ describe(t) {
1451
+ const e = i.getFirstMatch(/bada\/(\d+(\.\d+)*)/i, t);
1452
+ return {
1453
+ name: g.Bada,
1454
+ version: e
1455
+ };
1456
+ }
1457
+ },
1458
+ /* Tizen */
1459
+ {
1460
+ test: [/tizen/i],
1461
+ describe(t) {
1462
+ const e = i.getFirstMatch(/tizen[/\s](\d+(\.\d+)*)/i, t);
1463
+ return {
1464
+ name: g.Tizen,
1465
+ version: e
1466
+ };
1467
+ }
1468
+ },
1469
+ /* Linux */
1470
+ {
1471
+ test: [/linux/i],
1472
+ describe() {
1473
+ return {
1474
+ name: g.Linux
1475
+ };
1476
+ }
1477
+ },
1478
+ /* Chrome OS */
1479
+ {
1480
+ test: [/CrOS/],
1481
+ describe() {
1482
+ return {
1483
+ name: g.ChromeOS
1484
+ };
1485
+ }
1486
+ },
1487
+ /* Playstation 4 */
1488
+ {
1489
+ test: [/PlayStation 4/],
1490
+ describe(t) {
1491
+ const e = i.getFirstMatch(/PlayStation 4[/\s](\d+(\.\d+)*)/i, t);
1492
+ return {
1493
+ name: g.PlayStation4,
1494
+ version: e
1495
+ };
1496
+ }
1497
+ }
1498
+ ], at = [
1499
+ /* Googlebot */
1500
+ {
1501
+ test: [/googlebot/i],
1502
+ describe() {
1503
+ return {
1504
+ type: "bot",
1505
+ vendor: "Google"
1506
+ };
1507
+ }
1508
+ },
1509
+ /* Huawei */
1510
+ {
1511
+ test: [/huawei/i],
1512
+ describe(t) {
1513
+ const e = i.getFirstMatch(/(can-l01)/i, t) && "Nova", r = {
1514
+ type: m.mobile,
1515
+ vendor: "Huawei"
1516
+ };
1517
+ return e && (r.model = e), r;
1518
+ }
1519
+ },
1520
+ /* Nexus Tablet */
1521
+ {
1522
+ test: [/nexus\s*(?:7|8|9|10).*/i],
1523
+ describe() {
1524
+ return {
1525
+ type: m.tablet,
1526
+ vendor: "Nexus"
1527
+ };
1528
+ }
1529
+ },
1530
+ /* iPad */
1531
+ {
1532
+ test: [/ipad/i],
1533
+ describe() {
1534
+ return {
1535
+ type: m.tablet,
1536
+ vendor: "Apple",
1537
+ model: "iPad"
1538
+ };
1539
+ }
1540
+ },
1541
+ /* Firefox on iPad */
1542
+ {
1543
+ test: [/Macintosh(.*?) FxiOS(.*?)\//],
1544
+ describe() {
1545
+ return {
1546
+ type: m.tablet,
1547
+ vendor: "Apple",
1548
+ model: "iPad"
1549
+ };
1550
+ }
1551
+ },
1552
+ /* Amazon Kindle Fire */
1553
+ {
1554
+ test: [/kftt build/i],
1555
+ describe() {
1556
+ return {
1557
+ type: m.tablet,
1558
+ vendor: "Amazon",
1559
+ model: "Kindle Fire HD 7"
1560
+ };
1561
+ }
1562
+ },
1563
+ /* Another Amazon Tablet with Silk */
1564
+ {
1565
+ test: [/silk/i],
1566
+ describe() {
1567
+ return {
1568
+ type: m.tablet,
1569
+ vendor: "Amazon"
1570
+ };
1571
+ }
1572
+ },
1573
+ /* Tablet */
1574
+ {
1575
+ test: [/tablet(?! pc)/i],
1576
+ describe() {
1577
+ return {
1578
+ type: m.tablet
1579
+ };
1580
+ }
1581
+ },
1582
+ /* iPod/iPhone */
1583
+ {
1584
+ test(t) {
1585
+ const e = t.test(/ipod|iphone/i), r = t.test(/like (ipod|iphone)/i);
1586
+ return e && !r;
1587
+ },
1588
+ describe(t) {
1589
+ const e = i.getFirstMatch(/(ipod|iphone)/i, t);
1590
+ return {
1591
+ type: m.mobile,
1592
+ vendor: "Apple",
1593
+ model: e
1594
+ };
1595
+ }
1596
+ },
1597
+ /* Nexus Mobile */
1598
+ {
1599
+ test: [/nexus\s*[0-6].*/i, /galaxy nexus/i],
1600
+ describe() {
1601
+ return {
1602
+ type: m.mobile,
1603
+ vendor: "Nexus"
1604
+ };
1605
+ }
1606
+ },
1607
+ /* Mobile */
1608
+ {
1609
+ test: [/[^-]mobi/i],
1610
+ describe() {
1611
+ return {
1612
+ type: m.mobile
1613
+ };
1614
+ }
1615
+ },
1616
+ /* BlackBerry */
1617
+ {
1618
+ test(t) {
1619
+ return t.getBrowserName(!0) === "blackberry";
1620
+ },
1621
+ describe() {
1622
+ return {
1623
+ type: m.mobile,
1624
+ vendor: "BlackBerry"
1625
+ };
1626
+ }
1627
+ },
1628
+ /* Bada */
1629
+ {
1630
+ test(t) {
1631
+ return t.getBrowserName(!0) === "bada";
1632
+ },
1633
+ describe() {
1634
+ return {
1635
+ type: m.mobile
1636
+ };
1637
+ }
1638
+ },
1639
+ /* Windows Phone */
1640
+ {
1641
+ test(t) {
1642
+ return t.getBrowserName() === "windows phone";
1643
+ },
1644
+ describe() {
1645
+ return {
1646
+ type: m.mobile,
1647
+ vendor: "Microsoft"
1648
+ };
1649
+ }
1650
+ },
1651
+ /* Android Tablet */
1652
+ {
1653
+ test(t) {
1654
+ const e = Number(String(t.getOSVersion()).split(".")[0]);
1655
+ return t.getOSName(!0) === "android" && e >= 3;
1656
+ },
1657
+ describe() {
1658
+ return {
1659
+ type: m.tablet
1660
+ };
1661
+ }
1662
+ },
1663
+ /* Android Mobile */
1664
+ {
1665
+ test(t) {
1666
+ return t.getOSName(!0) === "android";
1667
+ },
1668
+ describe() {
1669
+ return {
1670
+ type: m.mobile
1671
+ };
1672
+ }
1673
+ },
1674
+ /* desktop */
1675
+ {
1676
+ test(t) {
1677
+ return t.getOSName(!0) === "macos";
1678
+ },
1679
+ describe() {
1680
+ return {
1681
+ type: m.desktop,
1682
+ vendor: "Apple"
1683
+ };
1684
+ }
1685
+ },
1686
+ /* Windows */
1687
+ {
1688
+ test(t) {
1689
+ return t.getOSName(!0) === "windows";
1690
+ },
1691
+ describe() {
1692
+ return {
1693
+ type: m.desktop
1694
+ };
1695
+ }
1696
+ },
1697
+ /* Linux */
1698
+ {
1699
+ test(t) {
1700
+ return t.getOSName(!0) === "linux";
1701
+ },
1702
+ describe() {
1703
+ return {
1704
+ type: m.desktop
1705
+ };
1706
+ }
1707
+ },
1708
+ /* PlayStation 4 */
1709
+ {
1710
+ test(t) {
1711
+ return t.getOSName(!0) === "playstation 4";
1712
+ },
1713
+ describe() {
1714
+ return {
1715
+ type: m.tv
1716
+ };
1717
+ }
1718
+ },
1719
+ /* Roku */
1720
+ {
1721
+ test(t) {
1722
+ return t.getOSName(!0) === "roku";
1723
+ },
1724
+ describe() {
1725
+ return {
1726
+ type: m.tv
1727
+ };
1728
+ }
1729
+ }
1730
+ ], ot = [
1731
+ /* EdgeHTML */
1732
+ {
1733
+ test(t) {
1734
+ return t.getBrowserName(!0) === "microsoft edge";
1735
+ },
1736
+ describe(t) {
1737
+ if (/\sedg\//i.test(t))
1738
+ return {
1739
+ name: S.Blink
1740
+ };
1741
+ const e = i.getFirstMatch(/edge\/(\d+(\.?_?\d+)+)/i, t);
1742
+ return {
1743
+ name: S.EdgeHTML,
1744
+ version: e
1745
+ };
1746
+ }
1747
+ },
1748
+ /* Trident */
1749
+ {
1750
+ test: [/trident/i],
1751
+ describe(t) {
1752
+ const e = {
1753
+ name: S.Trident
1754
+ }, r = i.getFirstMatch(/trident\/(\d+(\.?_?\d+)+)/i, t);
1755
+ return r && (e.version = r), e;
1756
+ }
1757
+ },
1758
+ /* Presto */
1759
+ {
1760
+ test(t) {
1761
+ return t.test(/presto/i);
1762
+ },
1763
+ describe(t) {
1764
+ const e = {
1765
+ name: S.Presto
1766
+ }, r = i.getFirstMatch(/presto\/(\d+(\.?_?\d+)+)/i, t);
1767
+ return r && (e.version = r), e;
1768
+ }
1769
+ },
1770
+ /* Gecko */
1771
+ {
1772
+ test(t) {
1773
+ const e = t.test(/gecko/i), r = t.test(/like gecko/i);
1774
+ return e && !r;
1775
+ },
1776
+ describe(t) {
1777
+ const e = {
1778
+ name: S.Gecko
1779
+ }, r = i.getFirstMatch(/gecko\/(\d+(\.?_?\d+)+)/i, t);
1780
+ return r && (e.version = r), e;
1781
+ }
1782
+ },
1783
+ /* Blink */
1784
+ {
1785
+ test: [/(apple)?webkit\/537\.36/i],
1786
+ describe() {
1787
+ return {
1788
+ name: S.Blink
1789
+ };
1790
+ }
1791
+ },
1792
+ /* WebKit */
1793
+ {
1794
+ test: [/(apple)?webkit/i],
1795
+ describe(t) {
1796
+ const e = {
1797
+ name: S.WebKit
1798
+ }, r = i.getFirstMatch(/webkit\/(\d+(\.?_?\d+)+)/i, t);
1799
+ return r && (e.version = r), e;
1800
+ }
1801
+ }
1802
+ ];
1803
+ class X {
1804
+ /**
1805
+ * Create instance of Parser
1806
+ *
1807
+ * @param {String} UA User-Agent string
1808
+ * @param {Boolean} [skipParsing=false] parser can skip parsing in purpose of performance
1809
+ * improvements if you need to make a more particular parsing
1810
+ * like {@link Parser#parseBrowser} or {@link Parser#parsePlatform}
1811
+ *
1812
+ * @throw {Error} in case of empty UA String
1813
+ *
1814
+ * @constructor
1815
+ */
1816
+ constructor(e, r = !1) {
1817
+ if (e == null || e === "")
1818
+ throw new Error("UserAgent parameter can't be empty");
1819
+ this._ua = e, this.parsedResult = {}, r !== !0 && this.parse();
1820
+ }
1821
+ /**
1822
+ * Get UserAgent string of current Parser instance
1823
+ * @return {String} User-Agent String of the current <Parser> object
1824
+ *
1825
+ * @public
1826
+ */
1827
+ getUA() {
1828
+ return this._ua;
1829
+ }
1830
+ /**
1831
+ * Test a UA string for a regexp
1832
+ * @param {RegExp} regex
1833
+ * @return {Boolean}
1834
+ */
1835
+ test(e) {
1836
+ return e.test(this._ua);
1837
+ }
1838
+ /**
1839
+ * Get parsed browser object
1840
+ * @return {Object}
1841
+ */
1842
+ parseBrowser() {
1843
+ this.parsedResult.browser = {};
1844
+ const e = i.find(it, (r) => {
1845
+ if (typeof r.test == "function")
1846
+ return r.test(this);
1847
+ if (r.test instanceof Array)
1848
+ return r.test.some((s) => this.test(s));
1849
+ throw new Error("Browser's test function is not valid");
1850
+ });
1851
+ return e && (this.parsedResult.browser = e.describe(this.getUA())), this.parsedResult.browser;
1852
+ }
1853
+ /**
1854
+ * Get parsed browser object
1855
+ * @return {Object}
1856
+ *
1857
+ * @public
1858
+ */
1859
+ getBrowser() {
1860
+ return this.parsedResult.browser ? this.parsedResult.browser : this.parseBrowser();
1861
+ }
1862
+ /**
1863
+ * Get browser's name
1864
+ * @return {String} Browser's name or an empty string
1865
+ *
1866
+ * @public
1867
+ */
1868
+ getBrowserName(e) {
1869
+ return e ? String(this.getBrowser().name).toLowerCase() || "" : this.getBrowser().name || "";
1870
+ }
1871
+ /**
1872
+ * Get browser's version
1873
+ * @return {String} version of browser
1874
+ *
1875
+ * @public
1876
+ */
1877
+ getBrowserVersion() {
1878
+ return this.getBrowser().version;
1879
+ }
1880
+ /**
1881
+ * Get OS
1882
+ * @return {Object}
1883
+ *
1884
+ * @example
1885
+ * this.getOS();
1886
+ * {
1887
+ * name: 'macOS',
1888
+ * version: '10.11.12'
1889
+ * }
1890
+ */
1891
+ getOS() {
1892
+ return this.parsedResult.os ? this.parsedResult.os : this.parseOS();
1893
+ }
1894
+ /**
1895
+ * Parse OS and save it to this.parsedResult.os
1896
+ * @return {*|{}}
1897
+ */
1898
+ parseOS() {
1899
+ this.parsedResult.os = {};
1900
+ const e = i.find(nt, (r) => {
1901
+ if (typeof r.test == "function")
1902
+ return r.test(this);
1903
+ if (r.test instanceof Array)
1904
+ return r.test.some((s) => this.test(s));
1905
+ throw new Error("Browser's test function is not valid");
1906
+ });
1907
+ return e && (this.parsedResult.os = e.describe(this.getUA())), this.parsedResult.os;
1908
+ }
1909
+ /**
1910
+ * Get OS name
1911
+ * @param {Boolean} [toLowerCase] return lower-cased value
1912
+ * @return {String} name of the OS — macOS, Windows, Linux, etc.
1913
+ */
1914
+ getOSName(e) {
1915
+ const { name: r } = this.getOS();
1916
+ return e ? String(r).toLowerCase() || "" : r || "";
1917
+ }
1918
+ /**
1919
+ * Get OS version
1920
+ * @return {String} full version with dots ('10.11.12', '5.6', etc)
1921
+ */
1922
+ getOSVersion() {
1923
+ return this.getOS().version;
1924
+ }
1925
+ /**
1926
+ * Get parsed platform
1927
+ * @return {{}}
1928
+ */
1929
+ getPlatform() {
1930
+ return this.parsedResult.platform ? this.parsedResult.platform : this.parsePlatform();
1931
+ }
1932
+ /**
1933
+ * Get platform name
1934
+ * @param {Boolean} [toLowerCase=false]
1935
+ * @return {*}
1936
+ */
1937
+ getPlatformType(e = !1) {
1938
+ const { type: r } = this.getPlatform();
1939
+ return e ? String(r).toLowerCase() || "" : r || "";
1940
+ }
1941
+ /**
1942
+ * Get parsed platform
1943
+ * @return {{}}
1944
+ */
1945
+ parsePlatform() {
1946
+ this.parsedResult.platform = {};
1947
+ const e = i.find(at, (r) => {
1948
+ if (typeof r.test == "function")
1949
+ return r.test(this);
1950
+ if (r.test instanceof Array)
1951
+ return r.test.some((s) => this.test(s));
1952
+ throw new Error("Browser's test function is not valid");
1953
+ });
1954
+ return e && (this.parsedResult.platform = e.describe(this.getUA())), this.parsedResult.platform;
1955
+ }
1956
+ /**
1957
+ * Get parsed engine
1958
+ * @return {{}}
1959
+ */
1960
+ getEngine() {
1961
+ return this.parsedResult.engine ? this.parsedResult.engine : this.parseEngine();
1962
+ }
1963
+ /**
1964
+ * Get engines's name
1965
+ * @return {String} Engines's name or an empty string
1966
+ *
1967
+ * @public
1968
+ */
1969
+ getEngineName(e) {
1970
+ return e ? String(this.getEngine().name).toLowerCase() || "" : this.getEngine().name || "";
1971
+ }
1972
+ /**
1973
+ * Get parsed platform
1974
+ * @return {{}}
1975
+ */
1976
+ parseEngine() {
1977
+ this.parsedResult.engine = {};
1978
+ const e = i.find(ot, (r) => {
1979
+ if (typeof r.test == "function")
1980
+ return r.test(this);
1981
+ if (r.test instanceof Array)
1982
+ return r.test.some((s) => this.test(s));
1983
+ throw new Error("Browser's test function is not valid");
1984
+ });
1985
+ return e && (this.parsedResult.engine = e.describe(this.getUA())), this.parsedResult.engine;
1986
+ }
1987
+ /**
1988
+ * Parse full information about the browser
1989
+ * @returns {Parser}
1990
+ */
1991
+ parse() {
1992
+ return this.parseBrowser(), this.parseOS(), this.parsePlatform(), this.parseEngine(), this;
1993
+ }
1994
+ /**
1995
+ * Get parsed result
1996
+ * @return {ParsedResult}
1997
+ */
1998
+ getResult() {
1999
+ return i.assign({}, this.parsedResult);
2000
+ }
2001
+ /**
2002
+ * Check if parsed browser matches certain conditions
2003
+ *
2004
+ * @param {Object} checkTree It's one or two layered object,
2005
+ * which can include a platform or an OS on the first layer
2006
+ * and should have browsers specs on the bottom-laying layer
2007
+ *
2008
+ * @returns {Boolean|undefined} Whether the browser satisfies the set conditions or not.
2009
+ * Returns `undefined` when the browser is no described in the checkTree object.
2010
+ *
2011
+ * @example
2012
+ * const browser = Bowser.getParser(window.navigator.userAgent);
2013
+ * if (browser.satisfies({chrome: '>118.01.1322' }))
2014
+ * // or with os
2015
+ * if (browser.satisfies({windows: { chrome: '>118.01.1322' } }))
2016
+ * // or with platforms
2017
+ * if (browser.satisfies({desktop: { chrome: '>118.01.1322' } }))
2018
+ */
2019
+ satisfies(e) {
2020
+ const r = {};
2021
+ let s = 0;
2022
+ const n = {};
2023
+ let o = 0;
2024
+ if (Object.keys(e).forEach((a) => {
2025
+ const c = e[a];
2026
+ typeof c == "string" ? (n[a] = c, o += 1) : typeof c == "object" && (r[a] = c, s += 1);
2027
+ }), s > 0) {
2028
+ const a = Object.keys(r), c = i.find(a, (l) => this.isOS(l));
2029
+ if (c) {
2030
+ const l = this.satisfies(r[c]);
2031
+ if (l !== void 0)
2032
+ return l;
2033
+ }
2034
+ const d = i.find(
2035
+ a,
2036
+ (l) => this.isPlatform(l)
2037
+ );
2038
+ if (d) {
2039
+ const l = this.satisfies(r[d]);
2040
+ if (l !== void 0)
2041
+ return l;
2042
+ }
2043
+ }
2044
+ if (o > 0) {
2045
+ const a = Object.keys(n), c = i.find(a, (d) => this.isBrowser(d, !0));
2046
+ if (c !== void 0)
2047
+ return this.compareVersion(n[c]);
2048
+ }
2049
+ }
2050
+ /**
2051
+ * Check if the browser name equals the passed string
2052
+ * @param browserName The string to compare with the browser name
2053
+ * @param [includingAlias=false] The flag showing whether alias will be included into comparison
2054
+ * @returns {boolean}
2055
+ */
2056
+ isBrowser(e, r = !1) {
2057
+ const s = this.getBrowserName().toLowerCase();
2058
+ let n = e.toLowerCase();
2059
+ const o = i.getBrowserTypeByAlias(n);
2060
+ return r && o && (n = o.toLowerCase()), n === s;
2061
+ }
2062
+ compareVersion(e) {
2063
+ let r = [0], s = e, n = !1;
2064
+ const o = this.getBrowserVersion();
2065
+ if (typeof o == "string")
2066
+ return e[0] === ">" || e[0] === "<" ? (s = e.substr(1), e[1] === "=" ? (n = !0, s = e.substr(2)) : r = [], e[0] === ">" ? r.push(1) : r.push(-1)) : e[0] === "=" ? s = e.substr(1) : e[0] === "~" && (n = !0, s = e.substr(1)), r.indexOf(
2067
+ i.compareVersions(o, s, n)
2068
+ ) > -1;
2069
+ }
2070
+ isOS(e) {
2071
+ return this.getOSName(!0) === String(e).toLowerCase();
2072
+ }
2073
+ isPlatform(e) {
2074
+ return this.getPlatformType(!0) === String(e).toLowerCase();
2075
+ }
2076
+ isEngine(e) {
2077
+ return this.getEngineName(!0) === String(e).toLowerCase();
2078
+ }
2079
+ /**
2080
+ * Is anything? Check if the browser is called "anything",
2081
+ * the OS called "anything" or the platform called "anything"
2082
+ * @param {String} anything
2083
+ * @param [includingAlias=false] The flag showing whether alias will be included into comparison
2084
+ * @returns {Boolean}
2085
+ */
2086
+ is(e, r = !1) {
2087
+ return this.isBrowser(e, r) || this.isOS(e) || this.isPlatform(e);
2088
+ }
2089
+ /**
2090
+ * Check if any of the given values satisfies this.is(anything)
2091
+ * @param {String[]} anythings
2092
+ * @returns {Boolean}
2093
+ */
2094
+ some(e = []) {
2095
+ return e.some((r) => this.is(r));
2096
+ }
2097
+ }
2098
+ /*!
2099
+ * Bowser - a browser detector
2100
+ * https://github.com/lancedikson/bowser
2101
+ * MIT License | (c) Dustin Diaz 2012-2015
2102
+ * MIT License | (c) Denis Demchenko 2015-2019
2103
+ */
2104
+ class ct {
2105
+ /**
2106
+ * Creates a {@link Parser} instance
2107
+ *
2108
+ * @param {String} UA UserAgent string
2109
+ * @param {Boolean} [skipParsing=false] Will make the Parser postpone parsing until you ask it
2110
+ * explicitly. Same as `skipParsing` for {@link Parser}.
2111
+ * @returns {Parser}
2112
+ * @throws {Error} when UA is not a String
2113
+ *
2114
+ * @example
2115
+ * const parser = Bowser.getParser(window.navigator.userAgent);
2116
+ * const result = parser.getResult();
2117
+ */
2118
+ static getParser(e, r = !1) {
2119
+ if (typeof e != "string")
2120
+ throw new Error("UserAgent should be a string");
2121
+ return new X(e, r);
2122
+ }
2123
+ /**
2124
+ * Creates a {@link Parser} instance and runs {@link Parser.getResult} immediately
2125
+ *
2126
+ * @param UA
2127
+ * @return {ParsedResult}
2128
+ *
2129
+ * @example
2130
+ * const result = Bowser.parse(window.navigator.userAgent);
2131
+ */
2132
+ static parse(e) {
2133
+ return new X(e).getResult();
2134
+ }
2135
+ static get BROWSER_MAP() {
2136
+ return oe;
2137
+ }
2138
+ static get ENGINE_MAP() {
2139
+ return S;
2140
+ }
2141
+ static get OS_MAP() {
2142
+ return g;
2143
+ }
2144
+ static get PLATFORMS_MAP() {
2145
+ return m;
2146
+ }
2147
+ }
2148
+ const O = ct.parse(navigator.userAgent), dt = {
2149
+ abTestGroup: null,
2150
+ abTestName: null,
2151
+ browser: O.browser.name ?? null,
2152
+ browserVersion: O.browser.version ?? null,
2153
+ hardwarePlatform: O.browser.name === "Electron" ? "DESKTOP" : "WEB",
2154
+ isOfflineModeStart: !1,
2155
+ mobileNetworkType: null,
2156
+ networkType: "WIFI",
2157
+ operatingSystem: O.os.name ?? null,
2158
+ operatingSystemVersion: O.os.version ?? null,
2159
+ screenHeight: window.screen.height,
2160
+ screenWidth: window.screen.width,
2161
+ sessionProductId: "",
2162
+ sessionProductType: "TRACK",
2163
+ sessionTags: [],
2164
+ sessionType: "PLAYBACK",
2165
+ startReason: "IMPLICIT",
2166
+ streamingSessionId: "",
2167
+ timestamp: 0
2168
+ }, lt = await L(
2169
+ "streaming_session_start",
2170
+ dt
2171
+ );
2172
+ function ut(t) {
2173
+ return lt(t);
2174
+ }
2175
+ function ce(t) {
2176
+ const e = `(${t.toString()})();`, r = new Blob([e], { type: "text/javascript" });
2177
+ return URL.createObjectURL(r);
2178
+ }
2179
+ let _;
2180
+ async function ht(t) {
2181
+ const e = await ne(t.data.eventName), r = new Map(e);
2182
+ r.delete(t.data.streamingSessionId), await ae(t.data.eventName, [...r]);
2183
+ }
2184
+ async function mt() {
2185
+ if (!_) {
2186
+ const { beacon: t } = await import("./worker-qh_9Fyf6-Li0uY2-a.js");
2187
+ _ = new Worker(ce(t)), _.addEventListener("message", (e) => {
2188
+ ht(e);
2189
+ });
2190
+ }
2191
+ }
2192
+ function pt(t) {
2193
+ return t != null;
2194
+ }
2195
+ async function de(t, e) {
2196
+ if (t) {
2197
+ const r = (await Promise.all(e.events)).filter(pt);
2198
+ e.events = r;
2199
+ const { clientId: s, token: n } = await v.credentialsProvider.getCredentials();
2200
+ if (!n)
2201
+ throw new Error("No accessToken");
2202
+ const o = {
2203
+ ...e,
2204
+ accessToken: n,
2205
+ apiUrl: k("apiUrl"),
2206
+ appVersion: k("appVersion"),
2207
+ clientId: s,
2208
+ clientPlatform: k("clientPlatform"),
2209
+ eventUrl: k("eventUrl"),
2210
+ ts: b.now()
2211
+ };
2212
+ return t.postMessage(JSON.stringify(o)), o;
2213
+ } else
2214
+ console.warn("Event beacon is not running.");
2215
+ }
2216
+ const ft = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2217
+ __proto__: null,
2218
+ commit: de,
2219
+ start: mt,
2220
+ get worker() {
2221
+ return _;
2222
+ },
2223
+ workerize: ce
2224
+ }, Symbol.toStringTag, { value: "Module" }));
2225
+ async function gt(t) {
2226
+ if (await N())
2227
+ return t();
2228
+ }
2229
+ function le(t) {
2230
+ return gt(
2231
+ () => de(_, {
2232
+ type: "streaming_metrics",
2233
+ ...t
2234
+ })
2235
+ );
2236
+ }
2237
+ function wt(t = !0) {
2238
+ const e = t && "crypto" in window && "getRandomValues" in crypto;
2239
+ return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(
2240
+ /[018]/g,
2241
+ (r) => (r ^ (e ? crypto.getRandomValues(new Uint8Array(1))[0] : Math.floor(256 * Math.random())) & 15 >> r / 4).toString(16)
2242
+ );
2243
+ }
2244
+ function yt(t) {
2245
+ return JSON.parse(atob(t));
2246
+ }
2247
+ function bt(t, e) {
2248
+ if ("codecs" in t)
2249
+ switch (t.codecs) {
2250
+ case "aac":
2251
+ return "aac";
2252
+ case "mp4a.40.2":
2253
+ return "mp4a.40.2";
2254
+ case "aac+":
2255
+ return "aac+";
2256
+ case "mp4a.40.5":
2257
+ return "mp4a.40.5";
2258
+ case "flac":
2259
+ return "flac";
2260
+ case "mqa":
2261
+ return "mqa";
2262
+ case "mp3":
2263
+ return "mp3";
2264
+ }
2265
+ else if (e)
2266
+ switch (e) {
2267
+ case "LOW":
2268
+ return "mp4a.40.5";
2269
+ case "HIGH":
2270
+ return "mp4a.40.2";
2271
+ case "LOSSLESS":
2272
+ case "HI_RES":
2273
+ case "HI_RES_LOSSLESS":
2274
+ return "flac";
2275
+ }
2276
+ return "none";
2277
+ }
2278
+ function vt(t) {
2279
+ switch (t) {
2280
+ case "mp3":
2281
+ return "mp3";
2282
+ case "aac":
2283
+ case "aac+":
2284
+ case "mp4a.40.2":
2285
+ case "mp4a.40.5":
2286
+ return "aac";
2287
+ case "flac":
2288
+ case "mqa":
2289
+ return t;
2290
+ default:
2291
+ return;
2292
+ }
2293
+ }
2294
+ function St(t) {
2295
+ const e = /codecs=(["'])?((?:.(?!\1|>))*.?)\1?/.exec(t);
2296
+ if (e === null)
2297
+ return;
2298
+ const r = e[2];
2299
+ if (r.includes("mp4a") || r.includes("aac"))
2300
+ return "aac";
2301
+ if (r === "mqa" || r === "flac")
2302
+ return r;
2303
+ }
2304
+ function kt(t) {
2305
+ const { prefetched: e, streamingSessionId: r } = t, s = "albumReplayGain" in t ? {
2306
+ albumPeakAmplitude: t.albumPeakAmplitude,
2307
+ albumReplayGain: t.albumReplayGain,
2308
+ trackPeakAmplitude: t.trackPeakAmplitude,
2309
+ trackReplayGain: t.trackReplayGain
2310
+ } : {}, n = "audioQuality" in t ? t.audioQuality : t.videoQuality, o = {
2311
+ id: String(
2312
+ "videoId" in t ? t.videoId : t.trackId
2313
+ ),
2314
+ type: "trackId" in t ? "track" : "video"
2315
+ };
2316
+ if (t.manifestMimeType === "application/vnd.tidal.bts" || t.manifestMimeType === "application/vnd.tidal.emu") {
2317
+ const a = yt(t.manifest), c = a.urls[0], d = bt(
2318
+ a,
2319
+ "audioQuality" in t ? t.audioQuality : null
2320
+ );
2321
+ let l;
2322
+ return "keyId" in a && (l = a.keyId), "licenseSecurityToken" in t && (l = t.licenseSecurityToken), {
2323
+ ...s,
2324
+ bitDepth: "bitDepth" in t ? t.bitDepth ?? void 0 : void 0,
2325
+ codec: vt(d),
2326
+ prefetched: e,
2327
+ quality: n,
2328
+ sampleRate: "sampleRate" in t ? t.sampleRate ?? void 0 : void 0,
2329
+ securityToken: l,
2330
+ streamFormat: d,
2331
+ streamUrl: c,
2332
+ streamingSessionId: r,
2333
+ ...o,
2334
+ expires: t.expires
2335
+ };
2336
+ }
2337
+ if (t.manifestMimeType === "application/dash+xml") {
2338
+ const a = `data:${t.manifestMimeType};base64,${t.manifest}`, c = atob(t.manifest);
2339
+ return {
2340
+ ...s,
2341
+ bitDepth: "bitDepth" in t ? t.bitDepth ?? void 0 : void 0,
2342
+ codec: St(c),
2343
+ prefetched: e,
2344
+ quality: n,
2345
+ sampleRate: "sampleRate" in t ? t.sampleRate ?? void 0 : void 0,
2346
+ securityToken: t.licenseSecurityToken,
2347
+ streamUrl: a,
2348
+ streamingSessionId: r,
2349
+ ...o,
2350
+ expires: t.expires
2351
+ };
2352
+ }
2353
+ throw new TypeError(
2354
+ `${t.manifestMimeType} not supported as playback info manifest mime type.`
2355
+ );
2356
+ }
2357
+ const ue = async (t, e = {}, r = 3) => {
2358
+ let s, n;
2359
+ try {
2360
+ s = await fetch(t, e);
2361
+ } catch (c) {
2362
+ if (r === 0)
2363
+ throw c;
2364
+ n = null;
2365
+ }
2366
+ if (s?.ok)
2367
+ return s;
2368
+ const o = s && s.status >= 500 && s.status <= 599, a = n === null || o || s?.status === 429;
2369
+ if (r > 0 && a) {
2370
+ const c = 500 * Math.abs(4 - r);
2371
+ return console.debug(
2372
+ `Retrying request for ${Math.abs(
2373
+ 4 - r
2374
+ )}th time in ${c}ms`
2375
+ ), await Le(c), ue(t, e, r - 1);
2376
+ }
2377
+ if (!s)
2378
+ throw new Error("Retries exchaused. Cannot fetch playbackinfo.");
2379
+ return s;
2380
+ };
2381
+ function Mt(t, e) {
2382
+ switch (e) {
2383
+ case 4032:
2384
+ case 4035:
2385
+ return "PEContentNotAvailableInLocation";
2386
+ case 4033:
2387
+ return "PEContentNotAvailableForSubscription";
2388
+ case 4010:
2389
+ return "PEMonthlyStreamQuotaExceeded";
2390
+ }
2391
+ return t >= 500 && t < 600 || t === 429 ? "PERetryable" : t >= 400 && t < 500 ? "PENotAllowed" : "EUnexpected";
2392
+ }
2393
+ async function Et(t) {
2394
+ const {
2395
+ accessToken: e,
2396
+ audioQuality: r,
2397
+ clientId: s,
2398
+ mediaProduct: n,
2399
+ prefetch: o,
2400
+ streamingSessionId: a
2401
+ } = t, c = k("apiUrl"), d = new URL(
2402
+ `${c}/${n.productType}s/${n.productId}/playbackinfo`
2403
+ ), l = d.searchParams;
2404
+ n.productType === "video" ? l.set("videoquality", "HIGH") : l.set("audioquality", r), l.set("playbackmode", "STREAM"), l.set("assetpresentation", "FULL");
2405
+ const y = new Headers();
2406
+ o && y.set("x-tidal-prefetch", "true"), s && y.set("x-tidal-token", s), e && y.set("authorization", "Bearer " + e), a && y.set("x-tidal-streamingsessionid", a);
2407
+ let M;
2408
+ try {
2409
+ M = await ue(
2410
+ d.toString(),
2411
+ {
2412
+ headers: y,
2413
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2414
+ // @ts-ignore - It is a thing.
2415
+ importance: "high"
2416
+ },
2417
+ 3
2418
+ );
2419
+ } catch {
2420
+ throw new W("PENetwork", "NPBI0");
2421
+ }
2422
+ const f = await M.json();
2423
+ if ("status" in f) {
2424
+ const ke = `A${f.subStatus}`;
2425
+ throw new W(Mt(f.status, f.subStatus), ke);
2426
+ }
2427
+ const ve = "trackId" in f, Se = "videoId" in f;
2428
+ if (!ve && !Se)
2429
+ throw new W("EUnexpected", "B9999");
2430
+ return {
2431
+ ...f,
2432
+ prefetched: o
2433
+ };
2434
+ }
2435
+ async function Pt(t) {
2436
+ const { streamingSessionId: e } = t, r = [];
2437
+ performance.mark("streaming_metrics:playback_info_fetch:startTimestamp", {
2438
+ detail: e
2439
+ });
2440
+ try {
2441
+ const s = await Et(t);
2442
+ if (s === void 0)
2443
+ throw new Error("Playback info was fetched, but undefined.");
2444
+ H({
2445
+ endReason: "COMPLETE",
2446
+ streamingSessionId: e
2447
+ }).catch(console.error), s.expires = Date.now() + 36e5;
2448
+ const n = "adInfo" in s;
2449
+ return "trackId" in s ? J({
2450
+ actualAssetPresentation: s.assetPresentation,
2451
+ actualAudioMode: s.audioMode,
2452
+ actualProductId: String(s.trackId),
2453
+ actualQuality: s.audioQuality,
2454
+ actualStreamType: void 0,
2455
+ hasAds: n,
2456
+ productType: "TRACK",
2457
+ streamingSessionId: e
2458
+ }).catch(console.error) : J({
2459
+ actualAssetPresentation: s.assetPresentation,
2460
+ actualAudioMode: void 0,
2461
+ actualProductId: String(s.videoId),
2462
+ actualQuality: s.videoQuality,
2463
+ actualStreamType: s.streamType,
2464
+ hasAds: n,
2465
+ productType: "VIDEO",
2466
+ streamingSessionId: e
2467
+ }).catch(console.error), performance.mark("streaming_metrics:playback_info_fetch:endTimestamp", {
2468
+ detail: e
2469
+ }), s;
2470
+ } catch (s) {
2471
+ throw performance.mark("streaming_metrics:playback_info_fetch:endTimestamp", {
2472
+ detail: e
2473
+ }), H({
2474
+ endReason: "ERROR",
2475
+ errorCode: s.message,
2476
+ errorMessage: s.stack,
2477
+ streamingSessionId: e
2478
+ }).catch(console.error), r.push(
2479
+ rt({
2480
+ streamingSessionId: e,
2481
+ timestamp: b.timestamp(
2482
+ "streaming_metrics:playback_info_fetch:endTimestamp"
2483
+ )
2484
+ })
2485
+ ), s;
2486
+ } finally {
2487
+ r.push(
2488
+ H({
2489
+ endTimestamp: b.timestamp(
2490
+ "streaming_metrics:playback_info_fetch:endTimestamp"
2491
+ ),
2492
+ startTimestamp: b.timestamp(
2493
+ "streaming_metrics:playback_info_fetch:startTimestamp"
2494
+ ),
2495
+ streamingSessionId: e
2496
+ })
2497
+ ), le({
2498
+ events: r
2499
+ }).catch(console.error), performance.clearMarks(
2500
+ "streaming_metrics:playback_info_fetch:endTimestamp"
2501
+ ), performance.clearMarks(
2502
+ "streaming_metrics:playback_info_fetch:startTimestamp"
2503
+ );
2504
+ }
2505
+ }
2506
+ class he {
2507
+ /**
2508
+ * The current time position to restore playback from when connection is back online.
2509
+ */
2510
+ static #e = 0;
2511
+ static #r = !1;
2512
+ /**
2513
+ * The media product to restore when connection is back online.
2514
+ */
2515
+ static #s = null;
2516
+ static #t;
2517
+ static #i;
2518
+ static #n;
2519
+ static disable() {
2520
+ this.#r && (this.#t && window.removeEventListener("offline", this.#t, !1), this.#i && window.removeEventListener("online", this.#i, !1), this.#i = void 0, this.#t = void 0, this.#r = !1);
2521
+ }
2522
+ static enable() {
2523
+ this.#r || (this.#i = () => this.#o(), this.#t = () => this.#a(), window.addEventListener("offline", this.#t, !1), window.addEventListener("online", this.#i, !1), this.#r = !0);
2524
+ }
2525
+ static #a() {
2526
+ const { activePlayer: e } = p;
2527
+ !e || !e.hasStarted() || (this.#s = e.currentMediaProduct, this.#n = this.#d.bind(this), h.addEventListener(
2528
+ "playback-state-change",
2529
+ this.#n
2530
+ ));
2531
+ }
2532
+ static #o() {
2533
+ const { activePlayer: e } = p;
2534
+ !e || !e.hasStarted() || (e.playbackState !== "PLAYING" && this.#s && (h.dispatchEvent(
2535
+ new CustomEvent("load", {
2536
+ detail: {
2537
+ currentTime: this.#e,
2538
+ mediaProduct: this.#s
2539
+ }
2540
+ })
2541
+ ), this.#c()), h.removeEventListener(
2542
+ "playback-state-change",
2543
+ this.#n
2544
+ ));
2545
+ }
2546
+ static #c() {
2547
+ this.#s = null, this.#e = 0;
2548
+ }
2549
+ static #d() {
2550
+ const { activePlayer: e } = p;
2551
+ e && (this.#e = e.currentTime);
2552
+ }
2553
+ }
2554
+ const Tt = "streaming-privileges-revoked";
2555
+ function It(t) {
2556
+ return new CustomEvent(Tt, {
2557
+ detail: t
2558
+ });
2559
+ }
2560
+ let I;
2561
+ async function me(t) {
2562
+ const e = k("apiUrl"), r = await fetch(e + "/rt/connect", {
2563
+ headers: new Headers({
2564
+ Authorization: "Bearer " + t,
2565
+ "Content-Type": "application/json"
2566
+ }),
2567
+ method: "POST"
2568
+ }), { url: s } = await r.json();
2569
+ return s;
2570
+ }
2571
+ function pe(t) {
2572
+ return new Promise((e) => {
2573
+ t.addEventListener("open", () => e(), { once: !0 });
2574
+ });
2575
+ }
2576
+ class z {
2577
+ #e;
2578
+ #r;
2579
+ #s;
2580
+ #t;
2581
+ constructor() {
2582
+ this.#t = void 0, this.#r = this.#i(), h.addEventListener("user-action", () => {
2583
+ this.connected && this.userAction().then().catch(console.error);
2584
+ });
2585
+ }
2586
+ /**
2587
+ * Call this method to ensure pushkin is running.
2588
+ */
2589
+ static async ensure() {
2590
+ await N() && (I ? I.connected || await I.reconnect() : I = new z());
2591
+ }
2592
+ /**
2593
+ * Call this method when credentials changes to re-setup pushkin with the new credentials
2594
+ */
2595
+ static async refresh() {
2596
+ if (!await N())
2597
+ return;
2598
+ const e = await Y();
2599
+ I && e && I.reconnect().catch(console.error);
2600
+ }
2601
+ async #i() {
2602
+ const e = await Y();
2603
+ if (!e)
2604
+ throw new Error("No access token to connect to Pushkin.");
2605
+ const r = await me(e);
2606
+ r && (this.#t = new WebSocket(r), await pe(this.#t), this.#s = (s) => this.#o(s.data), this.#e = () => this.#a(), this.#t.addEventListener("message", this.#s, !1), this.#t.addEventListener("closed", this.#e, !1), window.addEventListener("online", () => this.#a(), {
2607
+ once: !0
2608
+ }));
2609
+ }
2610
+ async #n(e) {
2611
+ if (!this.#t)
2612
+ throw new Error(
2613
+ "No socket connected. Did you forget to call connect method in Pushkin service first?"
2614
+ );
2615
+ this.#t.readyState !== WebSocket.OPEN && await this.#r, this.#t.send(JSON.stringify(e));
2616
+ }
2617
+ #a() {
2618
+ this.#r = this.#i();
2619
+ }
2620
+ #o(e) {
2621
+ const r = JSON.parse(e);
2622
+ switch (r.type) {
2623
+ case "PRIVILEGED_SESSION_NOTIFICATION": {
2624
+ h.dispatchEvent(
2625
+ It(
2626
+ String(r.payload.clientDisplayName)
2627
+ )
2628
+ ), p.activePlayer?.pause();
2629
+ break;
2630
+ }
2631
+ case "RECONNECT":
2632
+ this.reconnect().catch(console.error);
2633
+ break;
2634
+ default:
2635
+ console.warn("Unhandled event from Pushkin: ", r);
2636
+ break;
2637
+ }
2638
+ }
2639
+ reconnect() {
2640
+ return this.#t ? (this.#s && this.#t.removeEventListener("message", this.#s), this.#e && this.#t.removeEventListener("closed", this.#e), this.#t.close(), this.#r = this.#i(), this.#r) : Promise.resolve();
2641
+ }
2642
+ /**
2643
+ * Call this method to tell Pushkin a user action happened, so it can
2644
+ * make good qualified guesses if you're the session with allowed playback-
2645
+ */
2646
+ async userAction() {
2647
+ this.connected || await this.reconnect();
2648
+ try {
2649
+ await this.#n({
2650
+ payload: {
2651
+ startedAt: b.now()
2652
+ },
2653
+ type: "USER_ACTION"
2654
+ });
2655
+ } catch (e) {
2656
+ console.error(e);
2657
+ }
2658
+ }
2659
+ get connected() {
2660
+ return this.#t && this.#t.readyState === WebSocket.OPEN;
2661
+ }
2662
+ }
2663
+ const Lt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2664
+ __proto__: null,
2665
+ Pushkin: z,
2666
+ fetchWebSocketURL: me,
2667
+ socketOpen: pe
2668
+ }, Symbol.toStringTag, { value: "Module" }));
2669
+ async function Ot() {
2670
+ Ue(), he.disable(), await xe();
2671
+ }
2672
+ const At = {
2673
+ actions: [],
2674
+ actualAssetPresentation: "PREVIEW",
2675
+ actualAudioMode: "STEREO",
2676
+ actualProductId: "",
2677
+ actualQuality: "LOW",
2678
+ endAssetPosition: -1,
2679
+ endTimestamp: -1,
2680
+ isPostPaywall: !1,
2681
+ playbackSessionId: "",
2682
+ productType: "TRACK",
2683
+ requestedProductId: "",
2684
+ sourceId: "",
2685
+ sourceType: "",
2686
+ startAssetPosition: -1,
2687
+ startTimestamp: -1
2688
+ }, fe = await L(
2689
+ "playback_session",
2690
+ At
2691
+ );
2692
+ function Xt(t) {
2693
+ return fe(t);
2694
+ }
2695
+ function Zt(t, e) {
2696
+ return fe({
2697
+ actions: [e],
2698
+ streamingSessionId: t
2699
+ });
2700
+ }
2701
+ async function ge(t, e = 0, r = !1) {
2702
+ if (await b.synchronize(), z.ensure().catch(console.error), p.activePlayer?.nextItem && p.activePlayer.nextItem.mediaProduct.productId === t.productId) {
2703
+ const f = p.activePlayer;
2704
+ return performance.mark(
2705
+ "streaming_metrics:playback_statistics:idealStartTimestamp",
2706
+ { detail: p.preloadedStreamingSessionId }
2707
+ ), await f.reset({ keepPreload: !0 }), t.referenceId && p.preloadedStreamingSessionId && f.overwriteMediaProduct(
2708
+ p.preloadedStreamingSessionId,
2709
+ t
2710
+ ), f.skipToPreloadedMediaProduct();
2711
+ }
2712
+ const s = Ot(), n = wt();
2713
+ le({
2714
+ events: [
2715
+ ut({
2716
+ sessionProductId: t.productId,
2717
+ sessionProductType: t.productType === "track" ? "TRACK" : "VIDEO",
2718
+ sessionType: "PLAYBACK",
2719
+ startReason: "EXPLICIT",
2720
+ streamingSessionId: n,
2721
+ timestamp: b.now()
2722
+ })
2723
+ ]
2724
+ }).catch(console.error), performance.mark(
2725
+ "streaming_metrics:playback_statistics:idealStartTimestamp",
2726
+ { detail: n }
2727
+ );
2728
+ const { clientId: o, token: a } = await v.credentialsProvider.getCredentials(), c = k("streamingWifiAudioQuality");
2729
+ let d = null;
2730
+ try {
2731
+ d = await Pt({
2732
+ accessToken: a,
2733
+ audioQuality: c,
2734
+ clientId: o,
2735
+ mediaProduct: t,
2736
+ prefetch: r,
2737
+ streamingSessionId: n
2738
+ });
2739
+ } catch (f) {
2740
+ f instanceof W && h.dispatchError(f), document.location.href.includes("localhost") && console.error(f);
2741
+ }
2742
+ if (!d)
2743
+ return;
2744
+ const l = kt(d);
2745
+ Q.saveStreamInfo(
2746
+ l.streamingSessionId,
2747
+ l
2748
+ ), await s, he.enable();
2749
+ const y = "trackId" in d ? d.audioQuality : void 0, M = await He(
2750
+ t.productType,
2751
+ y
2752
+ );
2753
+ return De(M), M.load(
2754
+ {
2755
+ assetPosition: e,
2756
+ mediaProduct: t,
2757
+ playbackInfo: d,
2758
+ streamInfo: l
2759
+ },
2760
+ "explicit"
2761
+ );
2762
+ }
2763
+ h.addEventListener("load", (t) => {
2764
+ if (t instanceof CustomEvent) {
2765
+ const { currentTime: e, mediaProduct: r } = t.detail;
2766
+ ge(r, e).then().catch(console.error);
2767
+ }
2768
+ });
2769
+ function Ct() {
2770
+ return p.activePlayer?.pause();
2771
+ }
2772
+ async function _t() {
2773
+ await b.synchronize();
2774
+ const { activePlayer: t } = p;
2775
+ return t ? (h.dispatchEvent(new CustomEvent("user-action")), t.play()) : Promise.reject(new Error("No active player"));
2776
+ }
2777
+ async function Nt(t) {
2778
+ const { activePlayer: e } = p;
2779
+ return e?.seek(t);
2780
+ }
2781
+ function er(t) {
2782
+ v.credentialsProvider = t;
2783
+ }
2784
+ const Ft = "active-device-changed";
2785
+ function tr(t) {
2786
+ return new CustomEvent(Ft, {
2787
+ detail: t
2788
+ });
2789
+ }
2790
+ const Bt = "active-device-mode-changed";
2791
+ function rr(t) {
2792
+ return new CustomEvent(Bt, {
2793
+ detail: t
2794
+ });
2795
+ }
2796
+ const Rt = "active-device-pass-through-changed";
2797
+ function sr(t) {
2798
+ return new CustomEvent(Rt, {
2799
+ detail: t
2800
+ });
2801
+ }
2802
+ b.synchronize().then().catch(console.error);
2803
+ function we() {
2804
+ const { activePlayer: t } = p;
2805
+ if (!t)
2806
+ return null;
2807
+ switch (t.name) {
2808
+ case "shakaPlayer":
2809
+ return t.mediaElement;
2810
+ case "browserPlayer":
2811
+ return t.mediaElement;
2812
+ default:
2813
+ return null;
2814
+ }
2815
+ }
2816
+ Pe().then().catch(console.error);
2817
+ Ie().then().catch(console.error);
2818
+ const j = String.raw, xt = String.raw;
2819
+ function ye(t) {
2820
+ if (t === void 0)
2821
+ return "0:00";
2822
+ const e = parseInt(String(t), 10), r = Math.floor(e / 3600), s = Math.floor((e - r * 3600) / 60), n = e - r * 3600 - s * 60;
2823
+ let o = "";
2824
+ if (r !== 0) {
2825
+ const a = s < 10 ? `0${s}` : String(s);
2826
+ o = `${r}:${a}:`;
2827
+ } else
2828
+ o = `${s}:`;
2829
+ return o += n < 10 ? `0${n}` : String(n), o;
2830
+ }
2831
+ function be(t = 0) {
2832
+ const e = typeof t == "number" ? t : parseInt(t, 10), r = Math.floor(e / 3600) % 24, s = Math.floor(e / 60) % 60, n = e % 60, o = (c, d) => {
2833
+ if (c === 0 && d !== 1)
2834
+ return "";
2835
+ let l;
2836
+ switch (d) {
2837
+ case 0:
2838
+ l = "H";
2839
+ break;
2840
+ case 1:
2841
+ l = "M";
2842
+ break;
2843
+ default:
2844
+ l = "S";
2845
+ break;
2846
+ }
2847
+ return `${l}${c}`;
2848
+ };
2849
+ return `P${[r, s, n].map(o).join("")}`;
2850
+ }
2851
+ const Dt = "tidal-current-time";
2852
+ class Ut extends HTMLElement {
2853
+ #e = void 0;
2854
+ #r = /* @__PURE__ */ new Set();
2855
+ #s;
2856
+ #t;
2857
+ #i;
2858
+ constructor() {
2859
+ super(), this.#i = (e) => this.renderTime(e.target.currentTime), this.#t = () => this.renderTime(0), this.#s = this.#n.bind(this);
2860
+ }
2861
+ #n() {
2862
+ const e = we();
2863
+ e && this.#e && !this.#r.has(e) && (e.addEventListener("timeupdate", this.#i, !1), this.#r.add(e));
2864
+ }
2865
+ connectedCallback() {
2866
+ const e = this.attachShadow({ mode: "open" });
2867
+ e.innerHTML = "<time></time>";
2868
+ const r = e.querySelector("time");
2869
+ this.#e === void 0 && r !== null && (this.#e = r), this.renderTime(qe()), h.addEventListener(
2870
+ "media-product-transition",
2871
+ this.#s,
2872
+ !1
2873
+ ), h.addEventListener("ended", this.#t, !1);
2874
+ }
2875
+ disconnectedCallback() {
2876
+ for (let e of this.#r)
2877
+ e.removeEventListener(
2878
+ "timeupdate",
2879
+ this.#i,
2880
+ !1
2881
+ );
2882
+ h.removeEventListener(
2883
+ "media-product-transition",
2884
+ this.#s,
2885
+ !1
2886
+ ), h.removeEventListener("ended", this.#t, !1);
2887
+ }
2888
+ renderTime(e) {
2889
+ const r = Math.floor(e);
2890
+ this.#e && (this.#e.textContent = ye(r), this.#e.setAttribute("datetime", be(r)));
2891
+ }
2892
+ }
2893
+ customElements.define(Dt, Ut);
2894
+ const Wt = "tidal-duration-time";
2895
+ class zt extends HTMLElement {
2896
+ #e;
2897
+ #r = !1;
2898
+ #s;
2899
+ constructor() {
2900
+ super(), this.#s = (e) => {
2901
+ const r = e;
2902
+ this.renderTime(r.detail.playbackContext.actualDuration);
2903
+ }, this.#t();
2904
+ }
2905
+ #t() {
2906
+ this.#r || (h.addEventListener(
2907
+ "media-product-transition",
2908
+ this.#s,
2909
+ !1
2910
+ ), this.#r = !0);
2911
+ }
2912
+ #i() {
2913
+ const e = this.attachShadow({ mode: "open" });
2914
+ this.#e = document.createElement("time"), e.appendChild(this.#e);
2915
+ }
2916
+ connectedCallback() {
2917
+ this.#t(), this.#i();
2918
+ const e = parseInt(String(this.textContent), 10), r = Number.isNaN(e) ? 0 : e;
2919
+ this.renderTime($e()?.actualDuration ?? r);
2920
+ }
2921
+ disconnectedCallback() {
2922
+ h.removeEventListener(
2923
+ "media-product-transition",
2924
+ this.#s,
2925
+ !1
2926
+ ), this.#r = !1;
2927
+ }
2928
+ renderTime(e) {
2929
+ const r = parseInt(e.toFixed(0), 10);
2930
+ this.#e && (this.#e.textContent = ye(r), this.#e.setAttribute("datetime", be(r)));
2931
+ }
2932
+ }
2933
+ customElements.define(Wt, zt);
2934
+ const Vt = "tidal-play-trigger";
2935
+ class Ht extends HTMLElement {
2936
+ #e;
2937
+ #r = !1;
2938
+ constructor() {
2939
+ super(), this.#e = (e) => {
2940
+ e.preventDefault(), this.#s().catch(console.error);
2941
+ }, this.#i();
2942
+ }
2943
+ static get observedAttributes() {
2944
+ return ["product-id", "product-type"];
2945
+ }
2946
+ async #s() {
2947
+ await this.#t(), se() === "PLAYING" ? Ct() : await _t();
2948
+ }
2949
+ #t() {
2950
+ const e = Qe()?.productId ?? void 0;
2951
+ if (this.mediaProduct && this.mediaProduct.productId !== e)
2952
+ return ge(this.mediaProduct, 0);
2953
+ }
2954
+ #i() {
2955
+ this.#r || this.addEventListener("click", this.#e, { passive: !0 });
2956
+ }
2957
+ #n() {
2958
+ const e = this.attachShadow({ mode: "closed" }), r = document.createElement("style");
2959
+ r.textContent = j`
2960
+ :host {
2961
+ display: contents;
2962
+ }
2963
+ `;
2964
+ const s = document.createElement("slot");
2965
+ e.appendChild(r), e.appendChild(s);
2966
+ }
2967
+ connectedCallback() {
2968
+ this.#i(), this.#n();
2969
+ }
2970
+ disconnectedCallback() {
2971
+ this.removeEventListener("click", this.#e, {
2972
+ passive: !0
2973
+ }), this.#r = !1;
2974
+ }
2975
+ get mediaProduct() {
2976
+ const e = this.getAttribute("product-id");
2977
+ if (!e)
2978
+ return;
2979
+ const r = this.getAttribute("product-type") === "video" ? "video" : "track";
2980
+ return {
2981
+ productId: e,
2982
+ productType: r,
2983
+ sourceId: "",
2984
+ sourceType: ""
2985
+ };
2986
+ }
2987
+ }
2988
+ customElements.define(Vt, Ht);
2989
+ const qt = j`
2990
+ :host {
2991
+ display: inline-block;
2992
+ }
2993
+
2994
+ #wrapper {
2995
+ width: 100%;
2996
+ height: 100%;
2997
+ contain: strict;
2998
+ background-color: rgba(255, 255, 255, 0.2);
2999
+ cursor: pointer;
3000
+ }
3001
+
3002
+ #indicator {
3003
+ width: 100%;
3004
+ height: 100%;
3005
+ transform: none;
3006
+ will-change: transform;
3007
+ background-color: currentColor;
3008
+ pointer-events: none;
3009
+ }
3010
+ `, Z = {
3011
+ NO_DURATION: "You need to set duration before you can start/stop the progress bar."
3012
+ };
3013
+ class Qt extends HTMLElement {
3014
+ #e;
3015
+ #r = 1;
3016
+ #s = null;
3017
+ #t;
3018
+ #i;
3019
+ #n = /* @__PURE__ */ new Set();
3020
+ #a = null;
3021
+ #o;
3022
+ constructor() {
3023
+ super(), this.#t = (e) => {
3024
+ const r = e;
3025
+ if (this.duration = r.detail.playbackContext.actualDuration, se() === "PLAYING")
3026
+ try {
3027
+ this.start();
3028
+ } catch (s) {
3029
+ console.warn(s);
3030
+ }
3031
+ }, this.#i = (e) => {
3032
+ const r = e;
3033
+ try {
3034
+ r.detail.state === "PLAYING" ? this.start() : this.stop();
3035
+ } catch (s) {
3036
+ console.warn(s);
3037
+ }
3038
+ }, this.#o = (e) => {
3039
+ (e instanceof MouseEvent || e instanceof PointerEvent) && this.handleClick(e);
3040
+ }, this.#c();
3041
+ }
3042
+ #c() {
3043
+ this.#n.has("media-product-transition") || (h.addEventListener(
3044
+ "media-product-transition",
3045
+ this.#t,
3046
+ !1
3047
+ ), this.#n.add("media-product-transition")), this.#n.has("playback-state-change") || (h.addEventListener(
3048
+ "playback-state-change",
3049
+ this.#i
3050
+ ), this.#n.add("playback-state-change")), this.#a && !this.#n.has("wrapper-click") && (this.#a.addEventListener("click", this.#o, !1), this.#n.add("wrapper-click"));
3051
+ }
3052
+ #d() {
3053
+ const e = this.attachShadow({ mode: "closed" });
3054
+ e.innerHTML = xt`
3055
+ <style>
3056
+ ${qt}
3057
+ </style>
3058
+ <div id="wrapper">
3059
+ <div id="indicator"></div>
3060
+ </div>
3061
+ `, this.#a = e.querySelector("#wrapper"), this.#s = e.querySelector("#indicator");
3062
+ }
3063
+ /**
3064
+ * Renders the progress bar to a shadow DOM, caches references to the wrapper
3065
+ * && indicator elements and adds a click handler to the wrapper element for
3066
+ * handling the seeking.
3067
+ */
3068
+ connectedCallback() {
3069
+ this.#d(), this.#c();
3070
+ }
3071
+ disconnectedCallback() {
3072
+ h.removeEventListener(
3073
+ "media-product-transition",
3074
+ this.#t,
3075
+ !1
3076
+ ), h.removeEventListener(
3077
+ "playback-state-change",
3078
+ this.#i
3079
+ ), this.#a?.addEventListener("click", this.#o, !1), this.#n.clear();
3080
+ }
3081
+ /**
3082
+ * Calculates where in the progress bar the person clicked
3083
+ * in percent.
3084
+ *
3085
+ * @param {MouseEvent} mouse
3086
+ */
3087
+ getMousePositionAsPercent(e) {
3088
+ if (this.#a) {
3089
+ const r = this.#a.getBoundingClientRect(), s = {
3090
+ left: Math.abs(r.left + window.pageXOffset - e.pageX),
3091
+ width: Math.round(r.width)
3092
+ };
3093
+ return s.left / s.width;
3094
+ }
3095
+ return 0;
3096
+ }
3097
+ /**
3098
+ * Handle clicking the progress bar wrapper. Calculate the percentate
3099
+ * to seek to and emits a progress-bar:seek CustomEvent to be listened
3100
+ * to outside this component to react to the click.
3101
+ *
3102
+ * @param {MouseEvent | PointerEvent} event
3103
+ */
3104
+ handleClick(e) {
3105
+ const r = this.getMousePositionAsPercent(e), s = this.#r * r;
3106
+ this.currentTime = s, Nt(s / 1e3);
3107
+ }
3108
+ /**
3109
+ * Starts the animation if duration is defined.
3110
+ *
3111
+ * @throws Will throw an error if duration is not set.
3112
+ */
3113
+ start() {
3114
+ if (!this.#e)
3115
+ throw new Error(Z.NO_DURATION);
3116
+ this.#e.play();
3117
+ }
3118
+ /**
3119
+ * Stops the animation if duration is defined.
3120
+ *
3121
+ * @throws Will throw an error if duration is not set.
3122
+ */
3123
+ stop() {
3124
+ if (!this.#e)
3125
+ throw new Error(Z.NO_DURATION);
3126
+ this.#e.pause();
3127
+ }
3128
+ /**
3129
+ * Set current time with milliseconds.
3130
+ *
3131
+ * @memberof ProgressBar
3132
+ */
3133
+ set currentTime(e) {
3134
+ this.#e && (this.#e.currentTime = e);
3135
+ }
3136
+ /**
3137
+ * Setting this recrates the animation with the new duraton and pauses the animation.
3138
+ */
3139
+ set duration(e) {
3140
+ this.#r = e * 1e3;
3141
+ const r = [
3142
+ {
3143
+ transform: "translateX(-100%)"
3144
+ },
3145
+ {
3146
+ transform: "translateX(0%)"
3147
+ }
3148
+ ];
3149
+ this.#e = this.#s?.animate(r, {
3150
+ duration: this.#r,
3151
+ iterations: 1
3152
+ }), this.#e?.pause();
3153
+ }
3154
+ /**
3155
+ * Setting this stops the animations, updates the playback rate and plays it again.
3156
+ */
3157
+ set playbackRate(e) {
3158
+ this.stop(), this.#e && (this.#e.playbackRate = e), this.start();
3159
+ }
3160
+ }
3161
+ const $t = "tidal-progress-bar";
3162
+ customElements.define($t, Qt);
3163
+ const jt = j`
3164
+ :host {
3165
+ position: relative;
3166
+ display: block;
3167
+ width: 100%;
3168
+ aspect-ratio: 16/9;
3169
+ background-color: black;
3170
+ }
3171
+
3172
+ ::slotted(video) {
3173
+ display: block;
3174
+ width: 100%;
3175
+ height: 100%;
3176
+ z-index: 1;
3177
+ position: relative;
3178
+ background-color: black;
3179
+ }
3180
+ `, Gt = "tidal-video-view";
3181
+ class Kt extends HTMLElement {
3182
+ #e = !1;
3183
+ #r;
3184
+ #s;
3185
+ constructor() {
3186
+ super(), this.#r = (e) => {
3187
+ e.detail.mediaProduct.productType === "video" && this.mountPlayer();
3188
+ }, this.#s = (e) => {
3189
+ const r = e;
3190
+ this.setAttribute(
3191
+ "playback-state",
3192
+ r.detail.state.toLocaleLowerCase()
3193
+ );
3194
+ }, this.#t();
3195
+ }
3196
+ #t() {
3197
+ this.#e || (h.addEventListener(
3198
+ "media-product-transition",
3199
+ this.#r,
3200
+ !1
3201
+ ), h.addEventListener(
3202
+ "playback-state-change",
3203
+ this.#s,
3204
+ !1
3205
+ ));
3206
+ }
3207
+ connectedCallback() {
3208
+ this.#t();
3209
+ const e = this.attachShadow({ mode: "closed" }), r = document.createElement("style");
3210
+ r.textContent = jt;
3211
+ const s = document.createElement("slot");
3212
+ e.appendChild(r), e.appendChild(s);
3213
+ }
3214
+ disconnectedCallback() {
3215
+ h.removeEventListener(
3216
+ "media-product-transition",
3217
+ this.#r,
3218
+ !1
3219
+ ), h.removeEventListener(
3220
+ "playback-state-change",
3221
+ this.#s,
3222
+ !1
3223
+ ), this.#e = !0;
3224
+ }
3225
+ mountPlayer() {
3226
+ const e = we();
3227
+ e && (this.innerHTML = "", this.appendChild(e));
3228
+ }
3229
+ }
3230
+ customElements.define(Gt, Kt);
3231
+ export {
3232
+ E as A,
3233
+ ge as B,
3234
+ Me as F,
3235
+ Zt as G,
3236
+ W as H,
3237
+ Te as N,
3238
+ P as O,
3239
+ b as P,
3240
+ Jt as Q,
3241
+ Le as R,
3242
+ v as S,
3243
+ Yt as U,
3244
+ er as X,
3245
+ L as _,
3246
+ Xt as a,
3247
+ k as b,
3248
+ gt as c,
3249
+ _ as d,
3250
+ Dt as e,
3251
+ Wt as f,
3252
+ wt as g,
3253
+ ct as h,
3254
+ sr as i,
3255
+ le as j,
3256
+ Q as k,
3257
+ p as l,
3258
+ Vt as m,
3259
+ J as n,
3260
+ rt as o,
3261
+ $t as p,
3262
+ Gt as q,
3263
+ rr as s,
3264
+ tr as t,
3265
+ de as w,
3266
+ h as y
3267
+ };