@spotify-confidence/session-recording 0.18.6 → 0.18.7

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/dist/index.js CHANGED
@@ -1,25 +1,4 @@
1
- //#region \0rolldown/runtime.js
2
- var __create = Object.create;
3
- var __defProp$2 = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
9
- var __copyProps = (to, from, except, desc) => {
10
- if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) __defProp$2(to, key, {
13
- get: ((k) => from[k]).bind(null, key),
14
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
- });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp$2(target, "default", {
20
- value: mod,
21
- enumerable: true
22
- }) : target, mod));
1
+ import { t as createUploader } from "./uploader-CkAqZXJP.js";
23
2
  const VALID_KEY_PATTERN = /^[a-zA-Z0-9_.-]+$/;
24
3
  function validateKey(key) {
25
4
  if (typeof key !== "string" || key.length === 0) return "key is empty";
@@ -70,6 +49,33 @@ function defaultParameterizeRoute(route) {
70
49
  }).join("/");
71
50
  }
72
51
  //#endregion
52
+ //#region ../csr-recorder/src/graphql-request.ts
53
+ function operationNameFromDocument(document) {
54
+ return document.match(/\b(?:query|mutation|subscription)\s+([_A-Za-z][_0-9A-Za-z]*)/)?.[1];
55
+ }
56
+ function operationNameFromBody(body) {
57
+ if (typeof body !== "string") return void 0;
58
+ try {
59
+ const request = JSON.parse(body);
60
+ if (typeof request.operationName === "string" && request.operationName) return request.operationName;
61
+ return typeof request.query === "string" ? operationNameFromDocument(request.query) : void 0;
62
+ } catch (_error) {
63
+ return operationNameFromDocument(body);
64
+ }
65
+ }
66
+ function isGraphQLRequestUrl(url) {
67
+ try {
68
+ return new URL(url, globalThis.location?.href).pathname.endsWith("/graphql");
69
+ } catch (_error) {
70
+ return url.split(/[?#]/, 1)[0].endsWith("/graphql");
71
+ }
72
+ }
73
+ function extractGraphQLRequestMetadata(url, body) {
74
+ if (!isGraphQLRequestUrl(url)) return void 0;
75
+ const operationName = operationNameFromBody(body);
76
+ return operationName ? { operationName } : void 0;
77
+ }
78
+ //#endregion
73
79
  //#region ../csr-recorder/src/recorder.ts
74
80
  var Recorder = class Recorder {
75
81
  engine;
@@ -151,6 +157,7 @@ var Recorder = class Recorder {
151
157
  else if (input instanceof URL) url = input.href;
152
158
  else url = String(input);
153
159
  const requestSize = init?.body ? new Blob([init.body]).size : void 0;
160
+ const graphql = extractGraphQLRequestMetadata(url, init?.body);
154
161
  const start = Date.now();
155
162
  return originalFetch.call(globalThis, input, init).then((response) => {
156
163
  const contentLength = response.headers.get("content-length");
@@ -161,7 +168,8 @@ var Recorder = class Recorder {
161
168
  status: response.status,
162
169
  durationMs: Date.now() - start,
163
170
  ...requestSize !== null && requestSize !== void 0 ? { requestSize } : {},
164
- ...contentLength ? { responseSize: Number(contentLength) } : {}
171
+ ...contentLength ? { responseSize: Number(contentLength) } : {},
172
+ ...graphql ? { graphql } : {}
165
173
  });
166
174
  return response;
167
175
  }, (error) => {
@@ -171,7 +179,8 @@ var Recorder = class Recorder {
171
179
  url,
172
180
  status: 0,
173
181
  durationMs: Date.now() - start,
174
- ...requestSize !== null && requestSize !== void 0 ? { requestSize } : {}
182
+ ...requestSize !== null && requestSize !== void 0 ? { requestSize } : {},
183
+ ...graphql ? { graphql } : {}
175
184
  });
176
185
  throw error;
177
186
  });
@@ -198,6 +207,7 @@ var Recorder = class Recorder {
198
207
  const method = meta.__csr_method ?? "GET";
199
208
  const url = meta.__csr_url ?? "";
200
209
  const requestSize = body !== null && body !== void 0 ? new Blob([body]).size : void 0;
210
+ const graphql = extractGraphQLRequestMetadata(url, body);
201
211
  const start = Date.now();
202
212
  this.addEventListener("loadend", function csrLoadend() {
203
213
  const contentLength = this.getResponseHeader("content-length");
@@ -208,7 +218,8 @@ var Recorder = class Recorder {
208
218
  status: this.status,
209
219
  durationMs: Date.now() - start,
210
220
  ...requestSize !== null && requestSize !== void 0 ? { requestSize } : {},
211
- ...contentLength ? { responseSize: Number(contentLength) } : {}
221
+ ...contentLength ? { responseSize: Number(contentLength) } : {},
222
+ ...graphql ? { graphql } : {}
212
223
  });
213
224
  });
214
225
  return originalSend.call(this, body);
@@ -11176,2047 +11187,8 @@ function observeFlags(onFlagWrite) {
11176
11187
  };
11177
11188
  }
11178
11189
  //#endregion
11179
- //#region ../csr-common/src/uploader/client-context.ts
11180
- var import_es5 = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
11181
- (function(e, t) {
11182
- "object" == typeof exports && "object" == typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define([], t) : "object" == typeof exports ? exports.bowser = t() : e.bowser = t();
11183
- })(exports, (function() {
11184
- return function(e) {
11185
- var t = {};
11186
- function r(i) {
11187
- if (t[i]) return t[i].exports;
11188
- var n = t[i] = {
11189
- i,
11190
- l: !1,
11191
- exports: {}
11192
- };
11193
- return e[i].call(n.exports, n, n.exports, r), n.l = !0, n.exports;
11194
- }
11195
- return r.m = e, r.c = t, r.d = function(e, t, i) {
11196
- r.o(e, t) || Object.defineProperty(e, t, {
11197
- enumerable: !0,
11198
- get: i
11199
- });
11200
- }, r.r = function(e) {
11201
- "undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 });
11202
- }, r.t = function(e, t) {
11203
- if (1 & t && (e = r(e)), 8 & t) return e;
11204
- if (4 & t && "object" == typeof e && e && e.__esModule) return e;
11205
- var i = Object.create(null);
11206
- if (r.r(i), Object.defineProperty(i, "default", {
11207
- enumerable: !0,
11208
- value: e
11209
- }), 2 & t && "string" != typeof e) for (var n in e) r.d(i, n, function(t) {
11210
- return e[t];
11211
- }.bind(null, n));
11212
- return i;
11213
- }, r.n = function(e) {
11214
- var t = e && e.__esModule ? function() {
11215
- return e.default;
11216
- } : function() {
11217
- return e;
11218
- };
11219
- return r.d(t, "a", t), t;
11220
- }, r.o = function(e, t) {
11221
- return Object.prototype.hasOwnProperty.call(e, t);
11222
- }, r.p = "", r(r.s = 90);
11223
- }({
11224
- 17: function(e, t, r) {
11225
- "use strict";
11226
- t.__esModule = !0, t.default = void 0;
11227
- var i = r(18);
11228
- t.default = function() {
11229
- function e() {}
11230
- return e.getFirstMatch = function(e, t) {
11231
- var r = t.match(e);
11232
- return r && r.length > 0 && r[1] || "";
11233
- }, e.getSecondMatch = function(e, t) {
11234
- var r = t.match(e);
11235
- return r && r.length > 1 && r[2] || "";
11236
- }, e.matchAndReturnConst = function(e, t, r) {
11237
- if (e.test(t)) return r;
11238
- }, e.getWindowsVersionName = function(e) {
11239
- switch (e) {
11240
- case "NT": return "NT";
11241
- case "XP": return "XP";
11242
- case "NT 5.0": return "2000";
11243
- case "NT 5.1": return "XP";
11244
- case "NT 5.2": return "2003";
11245
- case "NT 6.0": return "Vista";
11246
- case "NT 6.1": return "7";
11247
- case "NT 6.2": return "8";
11248
- case "NT 6.3": return "8.1";
11249
- case "NT 10.0": return "10";
11250
- default: return;
11251
- }
11252
- }, e.getMacOSVersionName = function(e) {
11253
- var t = e.split(".").splice(0, 2).map((function(e) {
11254
- return parseInt(e, 10) || 0;
11255
- }));
11256
- t.push(0);
11257
- var r = t[0], i = t[1];
11258
- if (10 === r) switch (i) {
11259
- case 5: return "Leopard";
11260
- case 6: return "Snow Leopard";
11261
- case 7: return "Lion";
11262
- case 8: return "Mountain Lion";
11263
- case 9: return "Mavericks";
11264
- case 10: return "Yosemite";
11265
- case 11: return "El Capitan";
11266
- case 12: return "Sierra";
11267
- case 13: return "High Sierra";
11268
- case 14: return "Mojave";
11269
- case 15: return "Catalina";
11270
- default: return;
11271
- }
11272
- switch (r) {
11273
- case 11: return "Big Sur";
11274
- case 12: return "Monterey";
11275
- case 13: return "Ventura";
11276
- case 14: return "Sonoma";
11277
- case 15: return "Sequoia";
11278
- default: return;
11279
- }
11280
- }, e.getAndroidVersionName = function(e) {
11281
- var t = e.split(".").splice(0, 2).map((function(e) {
11282
- return parseInt(e, 10) || 0;
11283
- }));
11284
- if (t.push(0), !(1 === t[0] && t[1] < 5)) return 1 === t[0] && t[1] < 6 ? "Cupcake" : 1 === t[0] && t[1] >= 6 ? "Donut" : 2 === t[0] && t[1] < 2 ? "Eclair" : 2 === t[0] && 2 === t[1] ? "Froyo" : 2 === t[0] && t[1] > 2 ? "Gingerbread" : 3 === t[0] ? "Honeycomb" : 4 === t[0] && t[1] < 1 ? "Ice Cream Sandwich" : 4 === t[0] && t[1] < 4 ? "Jelly Bean" : 4 === t[0] && t[1] >= 4 ? "KitKat" : 5 === t[0] ? "Lollipop" : 6 === t[0] ? "Marshmallow" : 7 === t[0] ? "Nougat" : 8 === t[0] ? "Oreo" : 9 === t[0] ? "Pie" : void 0;
11285
- }, e.getVersionPrecision = function(e) {
11286
- return e.split(".").length;
11287
- }, e.compareVersions = function(t, r, i) {
11288
- void 0 === i && (i = !1);
11289
- var n = e.getVersionPrecision(t), a = e.getVersionPrecision(r), o = Math.max(n, a), s = 0, u = e.map([t, r], (function(t) {
11290
- var r = o - e.getVersionPrecision(t), i = t + new Array(r + 1).join(".0");
11291
- return e.map(i.split("."), (function(e) {
11292
- return new Array(20 - e.length).join("0") + e;
11293
- })).reverse();
11294
- }));
11295
- for (i && (s = o - Math.min(n, a)), o -= 1; o >= s;) {
11296
- if (u[0][o] > u[1][o]) return 1;
11297
- if (u[0][o] === u[1][o]) {
11298
- if (o === s) return 0;
11299
- o -= 1;
11300
- } else if (u[0][o] < u[1][o]) return -1;
11301
- }
11302
- }, e.map = function(e, t) {
11303
- var r, i = [];
11304
- if (Array.prototype.map) return Array.prototype.map.call(e, t);
11305
- for (r = 0; r < e.length; r += 1) i.push(t(e[r]));
11306
- return i;
11307
- }, e.find = function(e, t) {
11308
- var r, i;
11309
- if (Array.prototype.find) return Array.prototype.find.call(e, t);
11310
- for (r = 0, i = e.length; r < i; r += 1) {
11311
- var n = e[r];
11312
- if (t(n, r)) return n;
11313
- }
11314
- }, e.assign = function(e) {
11315
- for (var t, r, i = e, n = arguments.length, a = new Array(n > 1 ? n - 1 : 0), o = 1; o < n; o++) a[o - 1] = arguments[o];
11316
- if (Object.assign) return Object.assign.apply(Object, [e].concat(a));
11317
- var s = function() {
11318
- var e = a[t];
11319
- "object" == typeof e && null !== e && Object.keys(e).forEach((function(t) {
11320
- i[t] = e[t];
11321
- }));
11322
- };
11323
- for (t = 0, r = a.length; t < r; t += 1) s();
11324
- return e;
11325
- }, e.getBrowserAlias = function(e) {
11326
- return i.BROWSER_ALIASES_MAP[e];
11327
- }, e.getBrowserTypeByAlias = function(e) {
11328
- return i.BROWSER_MAP[e] || "";
11329
- }, e;
11330
- }(), e.exports = t.default;
11331
- },
11332
- 18: function(e, t, r) {
11333
- "use strict";
11334
- t.__esModule = !0, t.ENGINE_MAP = t.OS_MAP = t.PLATFORMS_MAP = t.BROWSER_MAP = t.BROWSER_ALIASES_MAP = void 0;
11335
- t.BROWSER_ALIASES_MAP = {
11336
- AmazonBot: "amazonbot",
11337
- "Amazon Silk": "amazon_silk",
11338
- "Android Browser": "android",
11339
- BaiduSpider: "baiduspider",
11340
- Bada: "bada",
11341
- BingCrawler: "bingcrawler",
11342
- Brave: "brave",
11343
- BlackBerry: "blackberry",
11344
- "ChatGPT-User": "chatgpt_user",
11345
- Chrome: "chrome",
11346
- ClaudeBot: "claudebot",
11347
- Chromium: "chromium",
11348
- Diffbot: "diffbot",
11349
- DuckDuckBot: "duckduckbot",
11350
- DuckDuckGo: "duckduckgo",
11351
- Electron: "electron",
11352
- Epiphany: "epiphany",
11353
- FacebookExternalHit: "facebookexternalhit",
11354
- Firefox: "firefox",
11355
- Focus: "focus",
11356
- Generic: "generic",
11357
- "Google Search": "google_search",
11358
- Googlebot: "googlebot",
11359
- GPTBot: "gptbot",
11360
- "Internet Explorer": "ie",
11361
- InternetArchiveCrawler: "internetarchivecrawler",
11362
- "K-Meleon": "k_meleon",
11363
- LibreWolf: "librewolf",
11364
- Linespider: "linespider",
11365
- Maxthon: "maxthon",
11366
- "Meta-ExternalAds": "meta_externalads",
11367
- "Meta-ExternalAgent": "meta_externalagent",
11368
- "Meta-ExternalFetcher": "meta_externalfetcher",
11369
- "Meta-WebIndexer": "meta_webindexer",
11370
- "Microsoft Edge": "edge",
11371
- "MZ Browser": "mz",
11372
- "NAVER Whale Browser": "naver",
11373
- "OAI-SearchBot": "oai_searchbot",
11374
- Omgilibot: "omgilibot",
11375
- Opera: "opera",
11376
- "Opera Coast": "opera_coast",
11377
- "Pale Moon": "pale_moon",
11378
- PerplexityBot: "perplexitybot",
11379
- "Perplexity-User": "perplexity_user",
11380
- PhantomJS: "phantomjs",
11381
- PingdomBot: "pingdombot",
11382
- Puffin: "puffin",
11383
- QQ: "qq",
11384
- QQLite: "qqlite",
11385
- QupZilla: "qupzilla",
11386
- Roku: "roku",
11387
- Safari: "safari",
11388
- Sailfish: "sailfish",
11389
- "Samsung Internet for Android": "samsung_internet",
11390
- SlackBot: "slackbot",
11391
- SeaMonkey: "seamonkey",
11392
- Sleipnir: "sleipnir",
11393
- "Sogou Browser": "sogou",
11394
- Swing: "swing",
11395
- Tizen: "tizen",
11396
- "UC Browser": "uc",
11397
- Vivaldi: "vivaldi",
11398
- "WebOS Browser": "webos",
11399
- WeChat: "wechat",
11400
- YahooSlurp: "yahooslurp",
11401
- "Yandex Browser": "yandex",
11402
- YandexBot: "yandexbot",
11403
- YouBot: "youbot"
11404
- };
11405
- t.BROWSER_MAP = {
11406
- amazonbot: "AmazonBot",
11407
- amazon_silk: "Amazon Silk",
11408
- android: "Android Browser",
11409
- baiduspider: "BaiduSpider",
11410
- bada: "Bada",
11411
- bingcrawler: "BingCrawler",
11412
- blackberry: "BlackBerry",
11413
- brave: "Brave",
11414
- chatgpt_user: "ChatGPT-User",
11415
- chrome: "Chrome",
11416
- claudebot: "ClaudeBot",
11417
- chromium: "Chromium",
11418
- diffbot: "Diffbot",
11419
- duckduckbot: "DuckDuckBot",
11420
- duckduckgo: "DuckDuckGo",
11421
- edge: "Microsoft Edge",
11422
- electron: "Electron",
11423
- epiphany: "Epiphany",
11424
- facebookexternalhit: "FacebookExternalHit",
11425
- firefox: "Firefox",
11426
- focus: "Focus",
11427
- generic: "Generic",
11428
- google_search: "Google Search",
11429
- googlebot: "Googlebot",
11430
- gptbot: "GPTBot",
11431
- ie: "Internet Explorer",
11432
- internetarchivecrawler: "InternetArchiveCrawler",
11433
- k_meleon: "K-Meleon",
11434
- librewolf: "LibreWolf",
11435
- linespider: "Linespider",
11436
- maxthon: "Maxthon",
11437
- meta_externalads: "Meta-ExternalAds",
11438
- meta_externalagent: "Meta-ExternalAgent",
11439
- meta_externalfetcher: "Meta-ExternalFetcher",
11440
- meta_webindexer: "Meta-WebIndexer",
11441
- mz: "MZ Browser",
11442
- naver: "NAVER Whale Browser",
11443
- oai_searchbot: "OAI-SearchBot",
11444
- omgilibot: "Omgilibot",
11445
- opera: "Opera",
11446
- opera_coast: "Opera Coast",
11447
- pale_moon: "Pale Moon",
11448
- perplexitybot: "PerplexityBot",
11449
- perplexity_user: "Perplexity-User",
11450
- phantomjs: "PhantomJS",
11451
- pingdombot: "PingdomBot",
11452
- puffin: "Puffin",
11453
- qq: "QQ Browser",
11454
- qqlite: "QQ Browser Lite",
11455
- qupzilla: "QupZilla",
11456
- roku: "Roku",
11457
- safari: "Safari",
11458
- sailfish: "Sailfish",
11459
- samsung_internet: "Samsung Internet for Android",
11460
- seamonkey: "SeaMonkey",
11461
- slackbot: "SlackBot",
11462
- sleipnir: "Sleipnir",
11463
- sogou: "Sogou Browser",
11464
- swing: "Swing",
11465
- tizen: "Tizen",
11466
- uc: "UC Browser",
11467
- vivaldi: "Vivaldi",
11468
- webos: "WebOS Browser",
11469
- wechat: "WeChat",
11470
- yahooslurp: "YahooSlurp",
11471
- yandex: "Yandex Browser",
11472
- yandexbot: "YandexBot",
11473
- youbot: "YouBot"
11474
- };
11475
- t.PLATFORMS_MAP = {
11476
- bot: "bot",
11477
- desktop: "desktop",
11478
- mobile: "mobile",
11479
- tablet: "tablet",
11480
- tv: "tv"
11481
- };
11482
- t.OS_MAP = {
11483
- Android: "Android",
11484
- Bada: "Bada",
11485
- BlackBerry: "BlackBerry",
11486
- ChromeOS: "Chrome OS",
11487
- HarmonyOS: "HarmonyOS",
11488
- iOS: "iOS",
11489
- Linux: "Linux",
11490
- MacOS: "macOS",
11491
- PlayStation4: "PlayStation 4",
11492
- Roku: "Roku",
11493
- Tizen: "Tizen",
11494
- WebOS: "WebOS",
11495
- Windows: "Windows",
11496
- WindowsPhone: "Windows Phone"
11497
- };
11498
- t.ENGINE_MAP = {
11499
- Blink: "Blink",
11500
- EdgeHTML: "EdgeHTML",
11501
- Gecko: "Gecko",
11502
- Presto: "Presto",
11503
- Trident: "Trident",
11504
- WebKit: "WebKit"
11505
- };
11506
- },
11507
- 90: function(e, t, r) {
11508
- "use strict";
11509
- t.__esModule = !0, t.default = void 0;
11510
- var i, n = (i = r(91)) && i.__esModule ? i : { default: i }, a = r(18);
11511
- function o(e, t) {
11512
- for (var r = 0; r < t.length; r++) {
11513
- var i = t[r];
11514
- i.enumerable = i.enumerable || !1, i.configurable = !0, "value" in i && (i.writable = !0), Object.defineProperty(e, i.key, i);
11515
- }
11516
- }
11517
- t.default = function() {
11518
- function e() {}
11519
- var t, r, i;
11520
- return e.getParser = function(e, t, r) {
11521
- if (void 0 === t && (t = !1), void 0 === r && (r = null), "string" != typeof e) throw new Error("UserAgent should be a string");
11522
- return new n.default(e, t, r);
11523
- }, e.parse = function(e, t) {
11524
- return void 0 === t && (t = null), new n.default(e, t).getResult();
11525
- }, t = e, i = [
11526
- {
11527
- key: "BROWSER_MAP",
11528
- get: function() {
11529
- return a.BROWSER_MAP;
11530
- }
11531
- },
11532
- {
11533
- key: "ENGINE_MAP",
11534
- get: function() {
11535
- return a.ENGINE_MAP;
11536
- }
11537
- },
11538
- {
11539
- key: "OS_MAP",
11540
- get: function() {
11541
- return a.OS_MAP;
11542
- }
11543
- },
11544
- {
11545
- key: "PLATFORMS_MAP",
11546
- get: function() {
11547
- return a.PLATFORMS_MAP;
11548
- }
11549
- }
11550
- ], (r = null) && o(t.prototype, r), i && o(t, i), e;
11551
- }(), e.exports = t.default;
11552
- },
11553
- 91: function(e, t, r) {
11554
- "use strict";
11555
- t.__esModule = !0, t.default = void 0;
11556
- var i = u(r(92)), n = u(r(93)), a = u(r(94)), o = u(r(95)), s = u(r(17));
11557
- function u(e) {
11558
- return e && e.__esModule ? e : { default: e };
11559
- }
11560
- t.default = function() {
11561
- function e(e, t, r) {
11562
- if (void 0 === t && (t = !1), void 0 === r && (r = null), null == e || "" === e) throw new Error("UserAgent parameter can't be empty");
11563
- this._ua = e;
11564
- var i = !1;
11565
- "boolean" == typeof t ? (i = t, this._hints = r) : this._hints = null != t && "object" == typeof t ? t : null, this.parsedResult = {}, !0 !== i && this.parse();
11566
- }
11567
- var t = e.prototype;
11568
- return t.getHints = function() {
11569
- return this._hints;
11570
- }, t.hasBrand = function(e) {
11571
- if (!this._hints || !Array.isArray(this._hints.brands)) return !1;
11572
- var t = e.toLowerCase();
11573
- return this._hints.brands.some((function(e) {
11574
- return e.brand && e.brand.toLowerCase() === t;
11575
- }));
11576
- }, t.getBrandVersion = function(e) {
11577
- if (this._hints && Array.isArray(this._hints.brands)) {
11578
- var t = e.toLowerCase(), r = this._hints.brands.find((function(e) {
11579
- return e.brand && e.brand.toLowerCase() === t;
11580
- }));
11581
- return r ? r.version : void 0;
11582
- }
11583
- }, t.getUA = function() {
11584
- return this._ua;
11585
- }, t.test = function(e) {
11586
- return e.test(this._ua);
11587
- }, t.parseBrowser = function() {
11588
- var e = this;
11589
- this.parsedResult.browser = {};
11590
- var t = s.default.find(i.default, (function(t) {
11591
- if ("function" == typeof t.test) return t.test(e);
11592
- if (Array.isArray(t.test)) return t.test.some((function(t) {
11593
- return e.test(t);
11594
- }));
11595
- throw new Error("Browser's test function is not valid");
11596
- }));
11597
- return t && (this.parsedResult.browser = t.describe(this.getUA(), this)), this.parsedResult.browser;
11598
- }, t.getBrowser = function() {
11599
- return this.parsedResult.browser ? this.parsedResult.browser : this.parseBrowser();
11600
- }, t.getBrowserName = function(e) {
11601
- return e ? String(this.getBrowser().name).toLowerCase() || "" : this.getBrowser().name || "";
11602
- }, t.getBrowserVersion = function() {
11603
- return this.getBrowser().version;
11604
- }, t.getOS = function() {
11605
- return this.parsedResult.os ? this.parsedResult.os : this.parseOS();
11606
- }, t.parseOS = function() {
11607
- var e = this;
11608
- this.parsedResult.os = {};
11609
- var t = s.default.find(n.default, (function(t) {
11610
- if ("function" == typeof t.test) return t.test(e);
11611
- if (Array.isArray(t.test)) return t.test.some((function(t) {
11612
- return e.test(t);
11613
- }));
11614
- throw new Error("Browser's test function is not valid");
11615
- }));
11616
- return t && (this.parsedResult.os = t.describe(this.getUA())), this.parsedResult.os;
11617
- }, t.getOSName = function(e) {
11618
- var t = this.getOS().name;
11619
- return e ? String(t).toLowerCase() || "" : t || "";
11620
- }, t.getOSVersion = function() {
11621
- return this.getOS().version;
11622
- }, t.getPlatform = function() {
11623
- return this.parsedResult.platform ? this.parsedResult.platform : this.parsePlatform();
11624
- }, t.getPlatformType = function(e) {
11625
- void 0 === e && (e = !1);
11626
- var t = this.getPlatform().type;
11627
- return e ? String(t).toLowerCase() || "" : t || "";
11628
- }, t.parsePlatform = function() {
11629
- var e = this;
11630
- this.parsedResult.platform = {};
11631
- var t = s.default.find(a.default, (function(t) {
11632
- if ("function" == typeof t.test) return t.test(e);
11633
- if (Array.isArray(t.test)) return t.test.some((function(t) {
11634
- return e.test(t);
11635
- }));
11636
- throw new Error("Browser's test function is not valid");
11637
- }));
11638
- return t && (this.parsedResult.platform = t.describe(this.getUA())), this.parsedResult.platform;
11639
- }, t.getEngine = function() {
11640
- return this.parsedResult.engine ? this.parsedResult.engine : this.parseEngine();
11641
- }, t.getEngineName = function(e) {
11642
- return e ? String(this.getEngine().name).toLowerCase() || "" : this.getEngine().name || "";
11643
- }, t.parseEngine = function() {
11644
- var e = this;
11645
- this.parsedResult.engine = {};
11646
- var t = s.default.find(o.default, (function(t) {
11647
- if ("function" == typeof t.test) return t.test(e);
11648
- if (Array.isArray(t.test)) return t.test.some((function(t) {
11649
- return e.test(t);
11650
- }));
11651
- throw new Error("Browser's test function is not valid");
11652
- }));
11653
- return t && (this.parsedResult.engine = t.describe(this.getUA())), this.parsedResult.engine;
11654
- }, t.parse = function() {
11655
- return this.parseBrowser(), this.parseOS(), this.parsePlatform(), this.parseEngine(), this;
11656
- }, t.getResult = function() {
11657
- return s.default.assign({}, this.parsedResult);
11658
- }, t.satisfies = function(e) {
11659
- var t = this, r = {}, i = 0, n = {}, a = 0;
11660
- if (Object.keys(e).forEach((function(t) {
11661
- var o = e[t];
11662
- "string" == typeof o ? (n[t] = o, a += 1) : "object" == typeof o && (r[t] = o, i += 1);
11663
- })), i > 0) {
11664
- var o = Object.keys(r), u = s.default.find(o, (function(e) {
11665
- return t.isOS(e);
11666
- }));
11667
- if (u) {
11668
- var d = this.satisfies(r[u]);
11669
- if (void 0 !== d) return d;
11670
- }
11671
- var c = s.default.find(o, (function(e) {
11672
- return t.isPlatform(e);
11673
- }));
11674
- if (c) {
11675
- var f = this.satisfies(r[c]);
11676
- if (void 0 !== f) return f;
11677
- }
11678
- }
11679
- if (a > 0) {
11680
- var l = Object.keys(n), b = s.default.find(l, (function(e) {
11681
- return t.isBrowser(e, !0);
11682
- }));
11683
- if (void 0 !== b) return this.compareVersion(n[b]);
11684
- }
11685
- }, t.isBrowser = function(e, t) {
11686
- void 0 === t && (t = !1);
11687
- var r = this.getBrowserName().toLowerCase(), i = e.toLowerCase(), n = s.default.getBrowserTypeByAlias(i);
11688
- return t && n && (i = n.toLowerCase()), i === r;
11689
- }, t.compareVersion = function(e) {
11690
- var t = [0], r = e, i = !1, n = this.getBrowserVersion();
11691
- if ("string" == typeof n) return ">" === e[0] || "<" === e[0] ? (r = e.substr(1), "=" === e[1] ? (i = !0, r = e.substr(2)) : t = [], ">" === e[0] ? t.push(1) : t.push(-1)) : "=" === e[0] ? r = e.substr(1) : "~" === e[0] && (i = !0, r = e.substr(1)), t.indexOf(s.default.compareVersions(n, r, i)) > -1;
11692
- }, t.isOS = function(e) {
11693
- return this.getOSName(!0) === String(e).toLowerCase();
11694
- }, t.isPlatform = function(e) {
11695
- return this.getPlatformType(!0) === String(e).toLowerCase();
11696
- }, t.isEngine = function(e) {
11697
- return this.getEngineName(!0) === String(e).toLowerCase();
11698
- }, t.is = function(e, t) {
11699
- return void 0 === t && (t = !1), this.isBrowser(e, t) || this.isOS(e) || this.isPlatform(e);
11700
- }, t.some = function(e) {
11701
- var t = this;
11702
- return void 0 === e && (e = []), e.some((function(e) {
11703
- return t.is(e);
11704
- }));
11705
- }, e;
11706
- }(), e.exports = t.default;
11707
- },
11708
- 92: function(e, t, r) {
11709
- "use strict";
11710
- t.__esModule = !0, t.default = void 0;
11711
- var i, n = (i = r(17)) && i.__esModule ? i : { default: i };
11712
- var a = /version\/(\d+(\.?_?\d+)+)/i;
11713
- t.default = [
11714
- {
11715
- test: [/gptbot/i],
11716
- describe: function(e) {
11717
- var t = { name: "GPTBot" }, r = n.default.getFirstMatch(/gptbot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11718
- return r && (t.version = r), t;
11719
- }
11720
- },
11721
- {
11722
- test: [/chatgpt-user/i],
11723
- describe: function(e) {
11724
- var t = { name: "ChatGPT-User" }, r = n.default.getFirstMatch(/chatgpt-user\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11725
- return r && (t.version = r), t;
11726
- }
11727
- },
11728
- {
11729
- test: [/oai-searchbot/i],
11730
- describe: function(e) {
11731
- var t = { name: "OAI-SearchBot" }, r = n.default.getFirstMatch(/oai-searchbot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11732
- return r && (t.version = r), t;
11733
- }
11734
- },
11735
- {
11736
- test: [
11737
- /claudebot/i,
11738
- /claude-web/i,
11739
- /claude-user/i,
11740
- /claude-searchbot/i
11741
- ],
11742
- describe: function(e) {
11743
- var t = { name: "ClaudeBot" }, r = n.default.getFirstMatch(/(?:claudebot|claude-web|claude-user|claude-searchbot)\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11744
- return r && (t.version = r), t;
11745
- }
11746
- },
11747
- {
11748
- test: [/omgilibot/i, /webzio-extended/i],
11749
- describe: function(e) {
11750
- var t = { name: "Omgilibot" }, r = n.default.getFirstMatch(/(?:omgilibot|webzio-extended)\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11751
- return r && (t.version = r), t;
11752
- }
11753
- },
11754
- {
11755
- test: [/diffbot/i],
11756
- describe: function(e) {
11757
- var t = { name: "Diffbot" }, r = n.default.getFirstMatch(/diffbot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11758
- return r && (t.version = r), t;
11759
- }
11760
- },
11761
- {
11762
- test: [/perplexitybot/i],
11763
- describe: function(e) {
11764
- var t = { name: "PerplexityBot" }, r = n.default.getFirstMatch(/perplexitybot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11765
- return r && (t.version = r), t;
11766
- }
11767
- },
11768
- {
11769
- test: [/perplexity-user/i],
11770
- describe: function(e) {
11771
- var t = { name: "Perplexity-User" }, r = n.default.getFirstMatch(/perplexity-user\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11772
- return r && (t.version = r), t;
11773
- }
11774
- },
11775
- {
11776
- test: [/youbot/i],
11777
- describe: function(e) {
11778
- var t = { name: "YouBot" }, r = n.default.getFirstMatch(/youbot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11779
- return r && (t.version = r), t;
11780
- }
11781
- },
11782
- {
11783
- test: [/meta-webindexer/i],
11784
- describe: function(e) {
11785
- var t = { name: "Meta-WebIndexer" }, r = n.default.getFirstMatch(/meta-webindexer\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11786
- return r && (t.version = r), t;
11787
- }
11788
- },
11789
- {
11790
- test: [/meta-externalads/i],
11791
- describe: function(e) {
11792
- var t = { name: "Meta-ExternalAds" }, r = n.default.getFirstMatch(/meta-externalads\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11793
- return r && (t.version = r), t;
11794
- }
11795
- },
11796
- {
11797
- test: [/meta-externalagent/i],
11798
- describe: function(e) {
11799
- var t = { name: "Meta-ExternalAgent" }, r = n.default.getFirstMatch(/meta-externalagent\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11800
- return r && (t.version = r), t;
11801
- }
11802
- },
11803
- {
11804
- test: [/meta-externalfetcher/i],
11805
- describe: function(e) {
11806
- var t = { name: "Meta-ExternalFetcher" }, r = n.default.getFirstMatch(/meta-externalfetcher\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11807
- return r && (t.version = r), t;
11808
- }
11809
- },
11810
- {
11811
- test: [/googlebot/i],
11812
- describe: function(e) {
11813
- var t = { name: "Googlebot" }, r = n.default.getFirstMatch(/googlebot\/(\d+(\.\d+))/i, e) || n.default.getFirstMatch(a, e);
11814
- return r && (t.version = r), t;
11815
- }
11816
- },
11817
- {
11818
- test: [/linespider/i],
11819
- describe: function(e) {
11820
- var t = { name: "Linespider" }, r = n.default.getFirstMatch(/(?:linespider)(?:-[-\w]+)?[\s/](\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11821
- return r && (t.version = r), t;
11822
- }
11823
- },
11824
- {
11825
- test: [/amazonbot/i],
11826
- describe: function(e) {
11827
- var t = { name: "AmazonBot" }, r = n.default.getFirstMatch(/amazonbot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11828
- return r && (t.version = r), t;
11829
- }
11830
- },
11831
- {
11832
- test: [/bingbot/i],
11833
- describe: function(e) {
11834
- var t = { name: "BingCrawler" }, r = n.default.getFirstMatch(/bingbot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11835
- return r && (t.version = r), t;
11836
- }
11837
- },
11838
- {
11839
- test: [/baiduspider/i],
11840
- describe: function(e) {
11841
- var t = { name: "BaiduSpider" }, r = n.default.getFirstMatch(/baiduspider\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11842
- return r && (t.version = r), t;
11843
- }
11844
- },
11845
- {
11846
- test: [/duckduckbot/i],
11847
- describe: function(e) {
11848
- var t = { name: "DuckDuckBot" }, r = n.default.getFirstMatch(/duckduckbot\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11849
- return r && (t.version = r), t;
11850
- }
11851
- },
11852
- {
11853
- test: [/ia_archiver/i],
11854
- describe: function(e) {
11855
- var t = { name: "InternetArchiveCrawler" }, r = n.default.getFirstMatch(/ia_archiver\/(\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11856
- return r && (t.version = r), t;
11857
- }
11858
- },
11859
- {
11860
- test: [/facebookexternalhit/i, /facebookcatalog/i],
11861
- describe: function() {
11862
- return { name: "FacebookExternalHit" };
11863
- }
11864
- },
11865
- {
11866
- test: [/slackbot/i, /slack-imgProxy/i],
11867
- describe: function(e) {
11868
- var t = { name: "SlackBot" }, r = n.default.getFirstMatch(/(?:slackbot|slack-imgproxy)(?:-[-\w]+)?[\s/](\d+(\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11869
- return r && (t.version = r), t;
11870
- }
11871
- },
11872
- {
11873
- test: [/yahoo!?[\s/]*slurp/i],
11874
- describe: function() {
11875
- return { name: "YahooSlurp" };
11876
- }
11877
- },
11878
- {
11879
- test: [/yandexbot/i, /yandexmobilebot/i],
11880
- describe: function() {
11881
- return { name: "YandexBot" };
11882
- }
11883
- },
11884
- {
11885
- test: [/pingdom/i],
11886
- describe: function() {
11887
- return { name: "PingdomBot" };
11888
- }
11889
- },
11890
- {
11891
- test: [/opera/i],
11892
- describe: function(e) {
11893
- var t = { name: "Opera" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:opera)[\s/](\d+(\.?_?\d+)+)/i, e);
11894
- return r && (t.version = r), t;
11895
- }
11896
- },
11897
- {
11898
- test: [/opr\/|opios/i],
11899
- describe: function(e) {
11900
- var t = { name: "Opera" }, r = n.default.getFirstMatch(/(?:opr|opios)[\s/](\S+)/i, e) || n.default.getFirstMatch(a, e);
11901
- return r && (t.version = r), t;
11902
- }
11903
- },
11904
- {
11905
- test: [/SamsungBrowser/i],
11906
- describe: function(e) {
11907
- var t = { name: "Samsung Internet for Android" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:SamsungBrowser)[\s/](\d+(\.?_?\d+)+)/i, e);
11908
- return r && (t.version = r), t;
11909
- }
11910
- },
11911
- {
11912
- test: [/Whale/i],
11913
- describe: function(e) {
11914
- var t = { name: "NAVER Whale Browser" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:whale)[\s/](\d+(?:\.\d+)+)/i, e);
11915
- return r && (t.version = r), t;
11916
- }
11917
- },
11918
- {
11919
- test: [/PaleMoon/i],
11920
- describe: function(e) {
11921
- var t = { name: "Pale Moon" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:PaleMoon)[\s/](\d+(?:\.\d+)+)/i, e);
11922
- return r && (t.version = r), t;
11923
- }
11924
- },
11925
- {
11926
- test: [/MZBrowser/i],
11927
- describe: function(e) {
11928
- var t = { name: "MZ Browser" }, r = n.default.getFirstMatch(/(?:MZBrowser)[\s/](\d+(?:\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11929
- return r && (t.version = r), t;
11930
- }
11931
- },
11932
- {
11933
- test: [/focus/i],
11934
- describe: function(e) {
11935
- var t = { name: "Focus" }, r = n.default.getFirstMatch(/(?:focus)[\s/](\d+(?:\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11936
- return r && (t.version = r), t;
11937
- }
11938
- },
11939
- {
11940
- test: [/swing/i],
11941
- describe: function(e) {
11942
- var t = { name: "Swing" }, r = n.default.getFirstMatch(/(?:swing)[\s/](\d+(?:\.\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11943
- return r && (t.version = r), t;
11944
- }
11945
- },
11946
- {
11947
- test: [/coast/i],
11948
- describe: function(e) {
11949
- var t = { name: "Opera Coast" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:coast)[\s/](\d+(\.?_?\d+)+)/i, e);
11950
- return r && (t.version = r), t;
11951
- }
11952
- },
11953
- {
11954
- test: [/opt\/\d+(?:.?_?\d+)+/i],
11955
- describe: function(e) {
11956
- var t = { name: "Opera Touch" }, r = n.default.getFirstMatch(/(?:opt)[\s/](\d+(\.?_?\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11957
- return r && (t.version = r), t;
11958
- }
11959
- },
11960
- {
11961
- test: [/yabrowser/i],
11962
- describe: function(e) {
11963
- var t = { name: "Yandex Browser" }, r = n.default.getFirstMatch(/(?:yabrowser)[\s/](\d+(\.?_?\d+)+)/i, e) || n.default.getFirstMatch(a, e);
11964
- return r && (t.version = r), t;
11965
- }
11966
- },
11967
- {
11968
- test: [/ucbrowser/i],
11969
- describe: function(e) {
11970
- var t = { name: "UC Browser" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:ucbrowser)[\s/](\d+(\.?_?\d+)+)/i, e);
11971
- return r && (t.version = r), t;
11972
- }
11973
- },
11974
- {
11975
- test: [/Maxthon|mxios/i],
11976
- describe: function(e) {
11977
- var t = { name: "Maxthon" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:Maxthon|mxios)[\s/](\d+(\.?_?\d+)+)/i, e);
11978
- return r && (t.version = r), t;
11979
- }
11980
- },
11981
- {
11982
- test: [/epiphany/i],
11983
- describe: function(e) {
11984
- var t = { name: "Epiphany" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:epiphany)[\s/](\d+(\.?_?\d+)+)/i, e);
11985
- return r && (t.version = r), t;
11986
- }
11987
- },
11988
- {
11989
- test: [/puffin/i],
11990
- describe: function(e) {
11991
- var t = { name: "Puffin" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:puffin)[\s/](\d+(\.?_?\d+)+)/i, e);
11992
- return r && (t.version = r), t;
11993
- }
11994
- },
11995
- {
11996
- test: [/sleipnir/i],
11997
- describe: function(e) {
11998
- var t = { name: "Sleipnir" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:sleipnir)[\s/](\d+(\.?_?\d+)+)/i, e);
11999
- return r && (t.version = r), t;
12000
- }
12001
- },
12002
- {
12003
- test: [/k-meleon/i],
12004
- describe: function(e) {
12005
- var t = { name: "K-Meleon" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/(?:k-meleon)[\s/](\d+(\.?_?\d+)+)/i, e);
12006
- return r && (t.version = r), t;
12007
- }
12008
- },
12009
- {
12010
- test: [/micromessenger/i],
12011
- describe: function(e) {
12012
- var t = { name: "WeChat" }, r = n.default.getFirstMatch(/(?:micromessenger)[\s/](\d+(\.?_?\d+)+)/i, e) || n.default.getFirstMatch(a, e);
12013
- return r && (t.version = r), t;
12014
- }
12015
- },
12016
- {
12017
- test: [/qqbrowser/i],
12018
- describe: function(e) {
12019
- var t = { name: /qqbrowserlite/i.test(e) ? "QQ Browser Lite" : "QQ Browser" }, r = n.default.getFirstMatch(/(?:qqbrowserlite|qqbrowser)[/](\d+(\.?_?\d+)+)/i, e) || n.default.getFirstMatch(a, e);
12020
- return r && (t.version = r), t;
12021
- }
12022
- },
12023
- {
12024
- test: [/msie|trident/i],
12025
- describe: function(e) {
12026
- var t = { name: "Internet Explorer" }, r = n.default.getFirstMatch(/(?:msie |rv:)(\d+(\.?_?\d+)+)/i, e);
12027
- return r && (t.version = r), t;
12028
- }
12029
- },
12030
- {
12031
- test: [/\sedg\//i],
12032
- describe: function(e) {
12033
- var t = { name: "Microsoft Edge" }, r = n.default.getFirstMatch(/\sedg\/(\d+(\.?_?\d+)+)/i, e);
12034
- return r && (t.version = r), t;
12035
- }
12036
- },
12037
- {
12038
- test: [/edg([ea]|ios)/i],
12039
- describe: function(e) {
12040
- var t = { name: "Microsoft Edge" }, r = n.default.getSecondMatch(/edg([ea]|ios)\/(\d+(\.?_?\d+)+)/i, e);
12041
- return r && (t.version = r), t;
12042
- }
12043
- },
12044
- {
12045
- test: [/vivaldi/i],
12046
- describe: function(e) {
12047
- var t = { name: "Vivaldi" }, r = n.default.getFirstMatch(/vivaldi\/(\d+(\.?_?\d+)+)/i, e);
12048
- return r && (t.version = r), t;
12049
- }
12050
- },
12051
- {
12052
- test: [/seamonkey/i],
12053
- describe: function(e) {
12054
- var t = { name: "SeaMonkey" }, r = n.default.getFirstMatch(/seamonkey\/(\d+(\.?_?\d+)+)/i, e);
12055
- return r && (t.version = r), t;
12056
- }
12057
- },
12058
- {
12059
- test: [/sailfish/i],
12060
- describe: function(e) {
12061
- var t = { name: "Sailfish" }, r = n.default.getFirstMatch(/sailfish\s?browser\/(\d+(\.\d+)?)/i, e);
12062
- return r && (t.version = r), t;
12063
- }
12064
- },
12065
- {
12066
- test: [/silk/i],
12067
- describe: function(e) {
12068
- var t = { name: "Amazon Silk" }, r = n.default.getFirstMatch(/silk\/(\d+(\.?_?\d+)+)/i, e);
12069
- return r && (t.version = r), t;
12070
- }
12071
- },
12072
- {
12073
- test: [/phantom/i],
12074
- describe: function(e) {
12075
- var t = { name: "PhantomJS" }, r = n.default.getFirstMatch(/phantomjs\/(\d+(\.?_?\d+)+)/i, e);
12076
- return r && (t.version = r), t;
12077
- }
12078
- },
12079
- {
12080
- test: [/slimerjs/i],
12081
- describe: function(e) {
12082
- var t = { name: "SlimerJS" }, r = n.default.getFirstMatch(/slimerjs\/(\d+(\.?_?\d+)+)/i, e);
12083
- return r && (t.version = r), t;
12084
- }
12085
- },
12086
- {
12087
- test: [/blackberry|\bbb\d+/i, /rim\stablet/i],
12088
- describe: function(e) {
12089
- var t = { name: "BlackBerry" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/blackberry[\d]+\/(\d+(\.?_?\d+)+)/i, e);
12090
- return r && (t.version = r), t;
12091
- }
12092
- },
12093
- {
12094
- test: [/(web|hpw)[o0]s/i],
12095
- describe: function(e) {
12096
- var t = { name: "WebOS Browser" }, r = n.default.getFirstMatch(a, e) || n.default.getFirstMatch(/w(?:eb)?[o0]sbrowser\/(\d+(\.?_?\d+)+)/i, e);
12097
- return r && (t.version = r), t;
12098
- }
12099
- },
12100
- {
12101
- test: [/bada/i],
12102
- describe: function(e) {
12103
- var t = { name: "Bada" }, r = n.default.getFirstMatch(/dolfin\/(\d+(\.?_?\d+)+)/i, e);
12104
- return r && (t.version = r), t;
12105
- }
12106
- },
12107
- {
12108
- test: [/tizen/i],
12109
- describe: function(e) {
12110
- var t = { name: "Tizen" }, r = n.default.getFirstMatch(/(?:tizen\s?)?browser\/(\d+(\.?_?\d+)+)/i, e) || n.default.getFirstMatch(a, e);
12111
- return r && (t.version = r), t;
12112
- }
12113
- },
12114
- {
12115
- test: [/qupzilla/i],
12116
- describe: function(e) {
12117
- var t = { name: "QupZilla" }, r = n.default.getFirstMatch(/(?:qupzilla)[\s/](\d+(\.?_?\d+)+)/i, e) || n.default.getFirstMatch(a, e);
12118
- return r && (t.version = r), t;
12119
- }
12120
- },
12121
- {
12122
- test: [/librewolf/i],
12123
- describe: function(e) {
12124
- var t = { name: "LibreWolf" }, r = n.default.getFirstMatch(/(?:librewolf)[\s/](\d+(\.?_?\d+)+)/i, e);
12125
- return r && (t.version = r), t;
12126
- }
12127
- },
12128
- {
12129
- test: [/firefox|iceweasel|fxios/i],
12130
- describe: function(e) {
12131
- var t = { name: "Firefox" }, r = n.default.getFirstMatch(/(?:firefox|iceweasel|fxios)[\s/](\d+(\.?_?\d+)+)/i, e);
12132
- return r && (t.version = r), t;
12133
- }
12134
- },
12135
- {
12136
- test: [/electron/i],
12137
- describe: function(e) {
12138
- var t = { name: "Electron" }, r = n.default.getFirstMatch(/(?:electron)\/(\d+(\.?_?\d+)+)/i, e);
12139
- return r && (t.version = r), t;
12140
- }
12141
- },
12142
- {
12143
- test: [
12144
- /sogoumobilebrowser/i,
12145
- /metasr/i,
12146
- /se 2\.[x]/i
12147
- ],
12148
- describe: function(e) {
12149
- var t = { name: "Sogou Browser" }, r = n.default.getFirstMatch(/(?:sogoumobilebrowser)[\s/](\d+(\.?_?\d+)+)/i, e), i = n.default.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i, e), a = n.default.getFirstMatch(/se ([\d.]+)x/i, e), o = r || i || a;
12150
- return o && (t.version = o), t;
12151
- }
12152
- },
12153
- {
12154
- test: [/MiuiBrowser/i],
12155
- describe: function(e) {
12156
- var t = { name: "Miui" }, r = n.default.getFirstMatch(/(?:MiuiBrowser)[\s/](\d+(\.?_?\d+)+)/i, e);
12157
- return r && (t.version = r), t;
12158
- }
12159
- },
12160
- {
12161
- test: function(e) {
12162
- return !!e.hasBrand("DuckDuckGo") || e.test(/\sDdg\/[\d.]+$/i);
12163
- },
12164
- describe: function(e, t) {
12165
- var r = { name: "DuckDuckGo" };
12166
- if (t) {
12167
- var i = t.getBrandVersion("DuckDuckGo");
12168
- if (i) return r.version = i, r;
12169
- }
12170
- var a = n.default.getFirstMatch(/\sDdg\/([\d.]+)$/i, e);
12171
- return a && (r.version = a), r;
12172
- }
12173
- },
12174
- {
12175
- test: function(e) {
12176
- return e.hasBrand("Brave");
12177
- },
12178
- describe: function(e, t) {
12179
- var r = { name: "Brave" };
12180
- if (t) {
12181
- var i = t.getBrandVersion("Brave");
12182
- if (i) return r.version = i, r;
12183
- }
12184
- return r;
12185
- }
12186
- },
12187
- {
12188
- test: [/chromium/i],
12189
- describe: function(e) {
12190
- var t = { name: "Chromium" }, r = n.default.getFirstMatch(/(?:chromium)[\s/](\d+(\.?_?\d+)+)/i, e) || n.default.getFirstMatch(a, e);
12191
- return r && (t.version = r), t;
12192
- }
12193
- },
12194
- {
12195
- test: [/chrome|crios|crmo/i],
12196
- describe: function(e) {
12197
- var t = { name: "Chrome" }, r = n.default.getFirstMatch(/(?:chrome|crios|crmo)\/(\d+(\.?_?\d+)+)/i, e);
12198
- return r && (t.version = r), t;
12199
- }
12200
- },
12201
- {
12202
- test: [/GSA/i],
12203
- describe: function(e) {
12204
- var t = { name: "Google Search" }, r = n.default.getFirstMatch(/(?:GSA)\/(\d+(\.?_?\d+)+)/i, e);
12205
- return r && (t.version = r), t;
12206
- }
12207
- },
12208
- {
12209
- test: function(e) {
12210
- var t = !e.test(/like android/i), r = e.test(/android/i);
12211
- return t && r;
12212
- },
12213
- describe: function(e) {
12214
- var t = { name: "Android Browser" }, r = n.default.getFirstMatch(a, e);
12215
- return r && (t.version = r), t;
12216
- }
12217
- },
12218
- {
12219
- test: [/playstation 4/i],
12220
- describe: function(e) {
12221
- var t = { name: "PlayStation 4" }, r = n.default.getFirstMatch(a, e);
12222
- return r && (t.version = r), t;
12223
- }
12224
- },
12225
- {
12226
- test: [/safari|applewebkit/i],
12227
- describe: function(e) {
12228
- var t = { name: "Safari" }, r = n.default.getFirstMatch(a, e);
12229
- return r && (t.version = r), t;
12230
- }
12231
- },
12232
- {
12233
- test: [/.*/i],
12234
- describe: function(e) {
12235
- var t = -1 !== e.search("\\(") ? /^(.*)\/(.*)[ \t]\((.*)/ : /^(.*)\/(.*) /;
12236
- return {
12237
- name: n.default.getFirstMatch(t, e),
12238
- version: n.default.getSecondMatch(t, e)
12239
- };
12240
- }
12241
- }
12242
- ], e.exports = t.default;
12243
- },
12244
- 93: function(e, t, r) {
12245
- "use strict";
12246
- t.__esModule = !0, t.default = void 0;
12247
- var i, n = (i = r(17)) && i.__esModule ? i : { default: i }, a = r(18);
12248
- t.default = [
12249
- {
12250
- test: [/Roku\/DVP/],
12251
- describe: function(e) {
12252
- var t = n.default.getFirstMatch(/Roku\/DVP-(\d+\.\d+)/i, e);
12253
- return {
12254
- name: a.OS_MAP.Roku,
12255
- version: t
12256
- };
12257
- }
12258
- },
12259
- {
12260
- test: [/windows phone/i],
12261
- describe: function(e) {
12262
- var t = n.default.getFirstMatch(/windows phone (?:os)?\s?(\d+(\.\d+)*)/i, e);
12263
- return {
12264
- name: a.OS_MAP.WindowsPhone,
12265
- version: t
12266
- };
12267
- }
12268
- },
12269
- {
12270
- test: [/windows /i],
12271
- describe: function(e) {
12272
- var t = n.default.getFirstMatch(/Windows ((NT|XP)( \d\d?.\d)?)/i, e), r = n.default.getWindowsVersionName(t);
12273
- return {
12274
- name: a.OS_MAP.Windows,
12275
- version: t,
12276
- versionName: r
12277
- };
12278
- }
12279
- },
12280
- {
12281
- test: [/Macintosh(.*?) FxiOS(.*?)\//],
12282
- describe: function(e) {
12283
- var t = { name: a.OS_MAP.iOS }, r = n.default.getSecondMatch(/(Version\/)(\d[\d.]+)/, e);
12284
- return r && (t.version = r), t;
12285
- }
12286
- },
12287
- {
12288
- test: [/macintosh/i],
12289
- describe: function(e) {
12290
- var t = n.default.getFirstMatch(/mac os x (\d+(\.?_?\d+)+)/i, e).replace(/[_\s]/g, "."), r = n.default.getMacOSVersionName(t), i = {
12291
- name: a.OS_MAP.MacOS,
12292
- version: t
12293
- };
12294
- return r && (i.versionName = r), i;
12295
- }
12296
- },
12297
- {
12298
- test: [/(ipod|iphone|ipad)/i],
12299
- describe: function(e) {
12300
- var t = n.default.getFirstMatch(/os (\d+([_\s]\d+)*) like mac os x/i, e).replace(/[_\s]/g, ".");
12301
- return {
12302
- name: a.OS_MAP.iOS,
12303
- version: t
12304
- };
12305
- }
12306
- },
12307
- {
12308
- test: [/OpenHarmony/i],
12309
- describe: function(e) {
12310
- var t = n.default.getFirstMatch(/OpenHarmony\s+(\d+(\.\d+)*)/i, e);
12311
- return {
12312
- name: a.OS_MAP.HarmonyOS,
12313
- version: t
12314
- };
12315
- }
12316
- },
12317
- {
12318
- test: function(e) {
12319
- var t = !e.test(/like android/i), r = e.test(/android/i);
12320
- return t && r;
12321
- },
12322
- describe: function(e) {
12323
- var t = n.default.getFirstMatch(/android[\s/-](\d+(\.\d+)*)/i, e), r = n.default.getAndroidVersionName(t), i = {
12324
- name: a.OS_MAP.Android,
12325
- version: t
12326
- };
12327
- return r && (i.versionName = r), i;
12328
- }
12329
- },
12330
- {
12331
- test: [/(web|hpw)[o0]s/i],
12332
- describe: function(e) {
12333
- var t = n.default.getFirstMatch(/(?:web|hpw)[o0]s\/(\d+(\.\d+)*)/i, e), r = { name: a.OS_MAP.WebOS };
12334
- return t && t.length && (r.version = t), r;
12335
- }
12336
- },
12337
- {
12338
- test: [/blackberry|\bbb\d+/i, /rim\stablet/i],
12339
- describe: function(e) {
12340
- var t = n.default.getFirstMatch(/rim\stablet\sos\s(\d+(\.\d+)*)/i, e) || n.default.getFirstMatch(/blackberry\d+\/(\d+([_\s]\d+)*)/i, e) || n.default.getFirstMatch(/\bbb(\d+)/i, e);
12341
- return {
12342
- name: a.OS_MAP.BlackBerry,
12343
- version: t
12344
- };
12345
- }
12346
- },
12347
- {
12348
- test: [/bada/i],
12349
- describe: function(e) {
12350
- var t = n.default.getFirstMatch(/bada\/(\d+(\.\d+)*)/i, e);
12351
- return {
12352
- name: a.OS_MAP.Bada,
12353
- version: t
12354
- };
12355
- }
12356
- },
12357
- {
12358
- test: [/tizen/i],
12359
- describe: function(e) {
12360
- var t = n.default.getFirstMatch(/tizen[/\s](\d+(\.\d+)*)/i, e);
12361
- return {
12362
- name: a.OS_MAP.Tizen,
12363
- version: t
12364
- };
12365
- }
12366
- },
12367
- {
12368
- test: [/linux/i],
12369
- describe: function() {
12370
- return { name: a.OS_MAP.Linux };
12371
- }
12372
- },
12373
- {
12374
- test: [/CrOS/],
12375
- describe: function() {
12376
- return { name: a.OS_MAP.ChromeOS };
12377
- }
12378
- },
12379
- {
12380
- test: [/PlayStation 4/],
12381
- describe: function(e) {
12382
- var t = n.default.getFirstMatch(/PlayStation 4[/\s](\d+(\.\d+)*)/i, e);
12383
- return {
12384
- name: a.OS_MAP.PlayStation4,
12385
- version: t
12386
- };
12387
- }
12388
- }
12389
- ], e.exports = t.default;
12390
- },
12391
- 94: function(e, t, r) {
12392
- "use strict";
12393
- t.__esModule = !0, t.default = void 0;
12394
- var i, n = (i = r(17)) && i.__esModule ? i : { default: i }, a = r(18);
12395
- t.default = [
12396
- {
12397
- test: [/googlebot/i],
12398
- describe: function() {
12399
- return {
12400
- type: a.PLATFORMS_MAP.bot,
12401
- vendor: "Google"
12402
- };
12403
- }
12404
- },
12405
- {
12406
- test: [/linespider/i],
12407
- describe: function() {
12408
- return {
12409
- type: a.PLATFORMS_MAP.bot,
12410
- vendor: "Line"
12411
- };
12412
- }
12413
- },
12414
- {
12415
- test: [/amazonbot/i],
12416
- describe: function() {
12417
- return {
12418
- type: a.PLATFORMS_MAP.bot,
12419
- vendor: "Amazon"
12420
- };
12421
- }
12422
- },
12423
- {
12424
- test: [/gptbot/i],
12425
- describe: function() {
12426
- return {
12427
- type: a.PLATFORMS_MAP.bot,
12428
- vendor: "OpenAI"
12429
- };
12430
- }
12431
- },
12432
- {
12433
- test: [/chatgpt-user/i],
12434
- describe: function() {
12435
- return {
12436
- type: a.PLATFORMS_MAP.bot,
12437
- vendor: "OpenAI"
12438
- };
12439
- }
12440
- },
12441
- {
12442
- test: [/oai-searchbot/i],
12443
- describe: function() {
12444
- return {
12445
- type: a.PLATFORMS_MAP.bot,
12446
- vendor: "OpenAI"
12447
- };
12448
- }
12449
- },
12450
- {
12451
- test: [/baiduspider/i],
12452
- describe: function() {
12453
- return {
12454
- type: a.PLATFORMS_MAP.bot,
12455
- vendor: "Baidu"
12456
- };
12457
- }
12458
- },
12459
- {
12460
- test: [/bingbot/i],
12461
- describe: function() {
12462
- return {
12463
- type: a.PLATFORMS_MAP.bot,
12464
- vendor: "Bing"
12465
- };
12466
- }
12467
- },
12468
- {
12469
- test: [/duckduckbot/i],
12470
- describe: function() {
12471
- return {
12472
- type: a.PLATFORMS_MAP.bot,
12473
- vendor: "DuckDuckGo"
12474
- };
12475
- }
12476
- },
12477
- {
12478
- test: [
12479
- /claudebot/i,
12480
- /claude-web/i,
12481
- /claude-user/i,
12482
- /claude-searchbot/i
12483
- ],
12484
- describe: function() {
12485
- return {
12486
- type: a.PLATFORMS_MAP.bot,
12487
- vendor: "Anthropic"
12488
- };
12489
- }
12490
- },
12491
- {
12492
- test: [/omgilibot/i, /webzio-extended/i],
12493
- describe: function() {
12494
- return {
12495
- type: a.PLATFORMS_MAP.bot,
12496
- vendor: "Webz.io"
12497
- };
12498
- }
12499
- },
12500
- {
12501
- test: [/diffbot/i],
12502
- describe: function() {
12503
- return {
12504
- type: a.PLATFORMS_MAP.bot,
12505
- vendor: "Diffbot"
12506
- };
12507
- }
12508
- },
12509
- {
12510
- test: [/perplexitybot/i],
12511
- describe: function() {
12512
- return {
12513
- type: a.PLATFORMS_MAP.bot,
12514
- vendor: "Perplexity AI"
12515
- };
12516
- }
12517
- },
12518
- {
12519
- test: [/perplexity-user/i],
12520
- describe: function() {
12521
- return {
12522
- type: a.PLATFORMS_MAP.bot,
12523
- vendor: "Perplexity AI"
12524
- };
12525
- }
12526
- },
12527
- {
12528
- test: [/youbot/i],
12529
- describe: function() {
12530
- return {
12531
- type: a.PLATFORMS_MAP.bot,
12532
- vendor: "You.com"
12533
- };
12534
- }
12535
- },
12536
- {
12537
- test: [/ia_archiver/i],
12538
- describe: function() {
12539
- return {
12540
- type: a.PLATFORMS_MAP.bot,
12541
- vendor: "Internet Archive"
12542
- };
12543
- }
12544
- },
12545
- {
12546
- test: [/meta-webindexer/i],
12547
- describe: function() {
12548
- return {
12549
- type: a.PLATFORMS_MAP.bot,
12550
- vendor: "Meta"
12551
- };
12552
- }
12553
- },
12554
- {
12555
- test: [/meta-externalads/i],
12556
- describe: function() {
12557
- return {
12558
- type: a.PLATFORMS_MAP.bot,
12559
- vendor: "Meta"
12560
- };
12561
- }
12562
- },
12563
- {
12564
- test: [/meta-externalagent/i],
12565
- describe: function() {
12566
- return {
12567
- type: a.PLATFORMS_MAP.bot,
12568
- vendor: "Meta"
12569
- };
12570
- }
12571
- },
12572
- {
12573
- test: [/meta-externalfetcher/i],
12574
- describe: function() {
12575
- return {
12576
- type: a.PLATFORMS_MAP.bot,
12577
- vendor: "Meta"
12578
- };
12579
- }
12580
- },
12581
- {
12582
- test: [/facebookexternalhit/i, /facebookcatalog/i],
12583
- describe: function() {
12584
- return {
12585
- type: a.PLATFORMS_MAP.bot,
12586
- vendor: "Meta"
12587
- };
12588
- }
12589
- },
12590
- {
12591
- test: [/slackbot/i, /slack-imgProxy/i],
12592
- describe: function() {
12593
- return {
12594
- type: a.PLATFORMS_MAP.bot,
12595
- vendor: "Slack"
12596
- };
12597
- }
12598
- },
12599
- {
12600
- test: [/yahoo/i],
12601
- describe: function() {
12602
- return {
12603
- type: a.PLATFORMS_MAP.bot,
12604
- vendor: "Yahoo"
12605
- };
12606
- }
12607
- },
12608
- {
12609
- test: [/yandexbot/i, /yandexmobilebot/i],
12610
- describe: function() {
12611
- return {
12612
- type: a.PLATFORMS_MAP.bot,
12613
- vendor: "Yandex"
12614
- };
12615
- }
12616
- },
12617
- {
12618
- test: [/pingdom/i],
12619
- describe: function() {
12620
- return {
12621
- type: a.PLATFORMS_MAP.bot,
12622
- vendor: "Pingdom"
12623
- };
12624
- }
12625
- },
12626
- {
12627
- test: [/huawei/i],
12628
- describe: function(e) {
12629
- var t = n.default.getFirstMatch(/(can-l01)/i, e) && "Nova", r = {
12630
- type: a.PLATFORMS_MAP.mobile,
12631
- vendor: "Huawei"
12632
- };
12633
- return t && (r.model = t), r;
12634
- }
12635
- },
12636
- {
12637
- test: [/nexus\s*(?:7|8|9|10).*/i],
12638
- describe: function() {
12639
- return {
12640
- type: a.PLATFORMS_MAP.tablet,
12641
- vendor: "Nexus"
12642
- };
12643
- }
12644
- },
12645
- {
12646
- test: [/ipad/i],
12647
- describe: function() {
12648
- return {
12649
- type: a.PLATFORMS_MAP.tablet,
12650
- vendor: "Apple",
12651
- model: "iPad"
12652
- };
12653
- }
12654
- },
12655
- {
12656
- test: [/Macintosh(.*?) FxiOS(.*?)\//],
12657
- describe: function() {
12658
- return {
12659
- type: a.PLATFORMS_MAP.tablet,
12660
- vendor: "Apple",
12661
- model: "iPad"
12662
- };
12663
- }
12664
- },
12665
- {
12666
- test: [/kftt build/i],
12667
- describe: function() {
12668
- return {
12669
- type: a.PLATFORMS_MAP.tablet,
12670
- vendor: "Amazon",
12671
- model: "Kindle Fire HD 7"
12672
- };
12673
- }
12674
- },
12675
- {
12676
- test: [/silk/i],
12677
- describe: function() {
12678
- return {
12679
- type: a.PLATFORMS_MAP.tablet,
12680
- vendor: "Amazon"
12681
- };
12682
- }
12683
- },
12684
- {
12685
- test: [/tablet(?! pc)/i],
12686
- describe: function() {
12687
- return { type: a.PLATFORMS_MAP.tablet };
12688
- }
12689
- },
12690
- {
12691
- test: function(e) {
12692
- var t = e.test(/ipod|iphone/i), r = e.test(/like (ipod|iphone)/i);
12693
- return t && !r;
12694
- },
12695
- describe: function(e) {
12696
- var t = n.default.getFirstMatch(/(ipod|iphone)/i, e);
12697
- return {
12698
- type: a.PLATFORMS_MAP.mobile,
12699
- vendor: "Apple",
12700
- model: t
12701
- };
12702
- }
12703
- },
12704
- {
12705
- test: [/nexus\s*[0-6].*/i, /galaxy nexus/i],
12706
- describe: function() {
12707
- return {
12708
- type: a.PLATFORMS_MAP.mobile,
12709
- vendor: "Nexus"
12710
- };
12711
- }
12712
- },
12713
- {
12714
- test: [/Nokia/i],
12715
- describe: function(e) {
12716
- var t = n.default.getFirstMatch(/Nokia\s+([0-9]+(\.[0-9]+)?)/i, e), r = {
12717
- type: a.PLATFORMS_MAP.mobile,
12718
- vendor: "Nokia"
12719
- };
12720
- return t && (r.model = t), r;
12721
- }
12722
- },
12723
- {
12724
- test: [/[^-]mobi/i],
12725
- describe: function() {
12726
- return { type: a.PLATFORMS_MAP.mobile };
12727
- }
12728
- },
12729
- {
12730
- test: function(e) {
12731
- return "blackberry" === e.getBrowserName(!0);
12732
- },
12733
- describe: function() {
12734
- return {
12735
- type: a.PLATFORMS_MAP.mobile,
12736
- vendor: "BlackBerry"
12737
- };
12738
- }
12739
- },
12740
- {
12741
- test: function(e) {
12742
- return "bada" === e.getBrowserName(!0);
12743
- },
12744
- describe: function() {
12745
- return { type: a.PLATFORMS_MAP.mobile };
12746
- }
12747
- },
12748
- {
12749
- test: function(e) {
12750
- return "windows phone" === e.getBrowserName();
12751
- },
12752
- describe: function() {
12753
- return {
12754
- type: a.PLATFORMS_MAP.mobile,
12755
- vendor: "Microsoft"
12756
- };
12757
- }
12758
- },
12759
- {
12760
- test: function(e) {
12761
- var t = Number(String(e.getOSVersion()).split(".")[0]);
12762
- return "android" === e.getOSName(!0) && t >= 3;
12763
- },
12764
- describe: function() {
12765
- return { type: a.PLATFORMS_MAP.tablet };
12766
- }
12767
- },
12768
- {
12769
- test: function(e) {
12770
- return "android" === e.getOSName(!0);
12771
- },
12772
- describe: function() {
12773
- return { type: a.PLATFORMS_MAP.mobile };
12774
- }
12775
- },
12776
- {
12777
- test: [/smart-?tv|smarttv/i],
12778
- describe: function() {
12779
- return { type: a.PLATFORMS_MAP.tv };
12780
- }
12781
- },
12782
- {
12783
- test: [/netcast/i],
12784
- describe: function() {
12785
- return { type: a.PLATFORMS_MAP.tv };
12786
- }
12787
- },
12788
- {
12789
- test: function(e) {
12790
- return "macos" === e.getOSName(!0);
12791
- },
12792
- describe: function() {
12793
- return {
12794
- type: a.PLATFORMS_MAP.desktop,
12795
- vendor: "Apple"
12796
- };
12797
- }
12798
- },
12799
- {
12800
- test: function(e) {
12801
- return "windows" === e.getOSName(!0);
12802
- },
12803
- describe: function() {
12804
- return { type: a.PLATFORMS_MAP.desktop };
12805
- }
12806
- },
12807
- {
12808
- test: function(e) {
12809
- return "linux" === e.getOSName(!0);
12810
- },
12811
- describe: function() {
12812
- return { type: a.PLATFORMS_MAP.desktop };
12813
- }
12814
- },
12815
- {
12816
- test: function(e) {
12817
- return "playstation 4" === e.getOSName(!0);
12818
- },
12819
- describe: function() {
12820
- return { type: a.PLATFORMS_MAP.tv };
12821
- }
12822
- },
12823
- {
12824
- test: function(e) {
12825
- return "roku" === e.getOSName(!0);
12826
- },
12827
- describe: function() {
12828
- return { type: a.PLATFORMS_MAP.tv };
12829
- }
12830
- }
12831
- ], e.exports = t.default;
12832
- },
12833
- 95: function(e, t, r) {
12834
- "use strict";
12835
- t.__esModule = !0, t.default = void 0;
12836
- var i, n = (i = r(17)) && i.__esModule ? i : { default: i }, a = r(18);
12837
- t.default = [
12838
- {
12839
- test: function(e) {
12840
- return "microsoft edge" === e.getBrowserName(!0);
12841
- },
12842
- describe: function(e) {
12843
- if (/\sedg\//i.test(e)) return { name: a.ENGINE_MAP.Blink };
12844
- var t = n.default.getFirstMatch(/edge\/(\d+(\.?_?\d+)+)/i, e);
12845
- return {
12846
- name: a.ENGINE_MAP.EdgeHTML,
12847
- version: t
12848
- };
12849
- }
12850
- },
12851
- {
12852
- test: [/trident/i],
12853
- describe: function(e) {
12854
- var t = { name: a.ENGINE_MAP.Trident }, r = n.default.getFirstMatch(/trident\/(\d+(\.?_?\d+)+)/i, e);
12855
- return r && (t.version = r), t;
12856
- }
12857
- },
12858
- {
12859
- test: function(e) {
12860
- return e.test(/presto/i);
12861
- },
12862
- describe: function(e) {
12863
- var t = { name: a.ENGINE_MAP.Presto }, r = n.default.getFirstMatch(/presto\/(\d+(\.?_?\d+)+)/i, e);
12864
- return r && (t.version = r), t;
12865
- }
12866
- },
12867
- {
12868
- test: function(e) {
12869
- var t = e.test(/gecko/i), r = e.test(/like gecko/i);
12870
- return t && !r;
12871
- },
12872
- describe: function(e) {
12873
- var t = { name: a.ENGINE_MAP.Gecko }, r = n.default.getFirstMatch(/gecko\/(\d+(\.?_?\d+)+)/i, e);
12874
- return r && (t.version = r), t;
12875
- }
12876
- },
12877
- {
12878
- test: [/(apple)?webkit\/537\.36/i],
12879
- describe: function() {
12880
- return { name: a.ENGINE_MAP.Blink };
12881
- }
12882
- },
12883
- {
12884
- test: [/(apple)?webkit/i],
12885
- describe: function(e) {
12886
- var t = { name: a.ENGINE_MAP.WebKit }, r = n.default.getFirstMatch(/webkit\/(\d+(\.?_?\d+)+)/i, e);
12887
- return r && (t.version = r), t;
12888
- }
12889
- }
12890
- ], e.exports = t.default;
12891
- }
12892
- });
12893
- }));
12894
- })))(), 1);
12895
- function collectUserAgentContext() {
12896
- if (typeof window === "undefined" || typeof navigator === "undefined") return void 0;
12897
- const parsed = import_es5.default.parse(navigator.userAgent);
12898
- let timeZone;
12899
- try {
12900
- timeZone = new Intl.DateTimeFormat().resolvedOptions().timeZone;
12901
- } catch (_e) {}
12902
- return {
12903
- userAgent: navigator.userAgent,
12904
- os: parsed.os.name?.toLowerCase().replace(/\s+/g, ""),
12905
- browser: parsed.browser.name?.toLowerCase().replace(/\s+/g, ""),
12906
- browserVersion: parsed.browser.version?.split(".")[0],
12907
- mobile: parsed.platform.type ? parsed.platform.type === "mobile" || parsed.platform.type === "tablet" : void 0,
12908
- languageCode: navigator.language,
12909
- timeZone,
12910
- viewportWidth: window.innerWidth,
12911
- viewportHeight: window.innerHeight,
12912
- screenWidth: window.screen.width,
12913
- screenHeight: window.screen.height,
12914
- devicePixelRatio: window.devicePixelRatio,
12915
- uri: `${window.location.origin}${window.location.pathname}`,
12916
- referrer: document.referrer
12917
- };
12918
- }
12919
- //#endregion
12920
- //#region ../csr-common/src/uploader/worker/worker-script.ts
12921
- const workerScript = "//#region src/uploader/worker/web-socket-transport.ts\n/**\n* WebSocket-backed Transport. Internal retry policy: clean server-initiated close after the\n* first successful open → reconnect and resume; abrupt close (or any close before the first\n* open) → fire `onClose` and stop. Frames received while a (re)connect is in progress are\n* buffered and flushed on open.\n*\n* `ready()` resolves on the first successful open and rejects on close-before-open. Callers\n* should await it before treating the Transport as live, so a failure to open can be caught\n* (e.g. 4404 unknown session) and recovered from.\n*/\nvar WebSocketTransport = class {\n url;\n ws = null;\n onCloseCb = null;\n onStateChangeCb = null;\n intentionallyClosed = false;\n dead = false;\n /** Frames buffered while a (re)connect is in progress. */\n pending = [];\n readyPromise;\n constructor(url) {\n this.url = url;\n this.readyPromise = new Promise((resolve, reject) => {\n this.connect(false, resolve, reject);\n });\n this.readyPromise.catch(() => {});\n }\n ready() {\n return this.readyPromise;\n }\n send(frame) {\n if (this.dead || this.intentionallyClosed) return;\n if (this.ws?.readyState === WebSocket.OPEN) this.ws.send(JSON.stringify(frame));\n else this.pending.push(frame);\n }\n close(reason = \"transport-close\") {\n this.intentionallyClosed = true;\n this.ws?.close(1e3, reason);\n }\n onClose(cb) {\n this.onCloseCb = cb;\n }\n onStateChange(cb) {\n this.onStateChangeCb = cb;\n }\n connect(isReconnect, onReady, onReadyFail) {\n const ws = new WebSocket(this.url);\n this.ws = ws;\n let opened = false;\n ws.onopen = () => {\n opened = true;\n onReady?.();\n if (isReconnect) this.onStateChangeCb?.({ connected: true });\n while (this.pending.length > 0) {\n const f = this.pending.shift();\n ws.send(JSON.stringify(f));\n }\n };\n ws.onclose = (event) => {\n if (this.intentionallyClosed) return;\n if (!opened) {\n const reason = `${isReconnect ? \"reconnect\" : \"initial\"}-failed code=${event.code}`;\n if (onReadyFail) {\n onReadyFail(new Error(reason));\n this.dead = true;\n } else this.die(reason);\n return;\n }\n if (event.wasClean && (event.code === 1e3 || event.code === 1001)) {\n this.onStateChangeCb?.({ connected: false });\n this.connect(true);\n } else this.die(`close code=${event.code} wasClean=${event.wasClean}`);\n };\n }\n die(reason) {\n this.dead = true;\n this.onCloseCb?.({ reason });\n }\n};\n//#endregion\n//#region src/uploader/worker/csr-client.ts\n/**\n* Single Client implementation that talks to the recording backend's REST + WS protocol.\n* Both dev-server and prod implement the same protocol, so we don't need polymorphism here yet.\n*/\nvar CsrClient = class {\n apiUrl;\n clientSecret;\n context;\n websocketUrl;\n log;\n forceRecord;\n constructor(apiUrl, clientSecret, context, websocketUrl, log = () => {}, forceRecord) {\n this.apiUrl = apiUrl;\n this.clientSecret = clientSecret;\n this.context = context;\n this.websocketUrl = websocketUrl;\n this.log = log;\n this.forceRecord = forceRecord;\n }\n async initSession() {\n const url = `${this.trimSlash(this.apiUrl)}/v1/sessions:initSession`;\n this.log(`fetch POST ${url}`);\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n clientSecret: this.clientSecret,\n ...this.context && Object.keys(this.context).length > 0 ? { context: this.context } : {},\n ...this.forceRecord ? { forceRecord: true } : {}\n })\n });\n if (!res.ok) throw new Error(`init-session failed: HTTP ${res.status}`);\n const data = await res.json();\n if (data.skipRecording) return { skipRecording: true };\n if (!data.sessionId || !data.sessionToken) throw new Error(\"init-session response missing sessionId or sessionToken\");\n return {\n sessionId: data.sessionId,\n sessionToken: data.sessionToken\n };\n }\n async openTransport(sessionToken) {\n const wsBase = this.websocketUrl ?? `${this.toWsScheme(this.trimSlash(this.apiUrl))}/sessions/stream`;\n const url = `${wsBase}${wsBase.includes(\"?\") ? \"&\" : \"?\"}session_token=${encodeURIComponent(sessionToken)}`;\n this.log(`WebSocket connect ${url.replace(/session_token=[^&]*/, \"session_token=[REDACTED]\")}`);\n const transport = new WebSocketTransport(url);\n await transport.ready();\n return transport;\n }\n trimSlash(s) {\n return s.endsWith(\"/\") ? s.slice(0, -1) : s;\n }\n toWsScheme(base) {\n if (base.startsWith(\"https://\")) return `wss://${base.slice(8)}`;\n if (base.startsWith(\"http://\")) return `ws://${base.slice(7)}`;\n return base;\n }\n};\n//#endregion\n//#region src/uploader/worker/core.ts\nconst IDLE_GRACE_MS = 5e3;\nlet state = { phase: \"init\" };\nconst ports = [];\nlet idleTimer = null;\nfunction cancelIdleTimer() {\n if (idleTimer !== null) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n}\nfunction log(msg) {\n for (const handle of ports) if (handle.debugLogs) handle.port.postMessage({\n type: \"log\",\n msg\n });\n}\n/**\n* The first hello \"locks in\" the session's apiUrl/clientSecret. Any later tab arriving\n* with different values is misconfigured — we reject it rather than silently using the\n* locked values. In SharedWorker mode the `name = hash(clientSecret)` scoping already\n* prevents secret-mismatch from sharing a worker, but this defends against the dedicated\n* path and against future bugs.\n*/\nlet lockedConfig = null;\nfunction registerPort(adapter) {\n cancelIdleTimer();\n const handle = {\n port: adapter,\n hello: null,\n debugLogs: false\n };\n ports.push(handle);\n adapter.onmessage((data) => {\n handleMessage(handle, data);\n });\n}\nfunction handleMessage(handle, message) {\n switch (message.type) {\n case \"hello\":\n handle.hello = message;\n handle.debugLogs = message.debugLogs ?? false;\n if (rejectIfIncompatible(handle)) return;\n if (state.phase !== \"dead\" && state.phase !== \"skipping\") detectDuplicateTab(handle);\n onHello(handle);\n return;\n case \"frame\":\n onFrame(message.frame);\n return;\n case \"bye\":\n onBye(handle);\n return;\n default: break;\n }\n}\n/**\n* Reject hellos whose `apiUrl`/`clientSecret` don't match the values established by the\n* first hello. Returns true if the port was rejected (caller should not continue\n* processing this hello).\n*/\nfunction rejectIfIncompatible(handle) {\n if (lockedConfig === null) return false;\n const incoming = handle.hello;\n if (incoming.apiUrl === lockedConfig.apiUrl && incoming.websocketUrl === lockedConfig.websocketUrl && incoming.clientSecret === lockedConfig.clientSecret) return false;\n handle.port.postMessage({\n type: \"dead\",\n reason: \"incompatible-options: apiUrl/websocketUrl/clientSecret differ from the worker session\"\n });\n const idx = ports.indexOf(handle);\n if (idx >= 0) ports.splice(idx, 1);\n return true;\n}\n/**\n* If another already-connected port has the same `tabId`, this hello is from a duplicate\n* tab (browser \"Duplicate\" command clones sessionStorage). Mint a fresh `tabId` so the two\n* tabs don't collide on the same `(sessionId, tabId)` Recording. The new tabId is returned\n* to the tab in `welcome` so it can update its own state and sessionStorage.\n*/\nfunction detectDuplicateTab(handle) {\n const tabId = handle.hello.tabId;\n if (!ports.some((p) => p !== handle && p.hello?.tabId === tabId)) return;\n const fresh = crypto.randomUUID();\n handle.newTabId = fresh;\n handle.hello.tabId = fresh;\n}\nfunction onHello(handle) {\n switch (state.phase) {\n case \"init\":\n lockedConfig = {\n apiUrl: handle.hello.apiUrl,\n websocketUrl: handle.hello.websocketUrl,\n clientSecret: handle.hello.clientSecret\n };\n log(`hello received apiUrl=${handle.hello.apiUrl} websocketUrl=${handle.hello.websocketUrl ?? \"(derive)\"} sessionIdHint=${handle.hello.sessionIdHint ?? \"(none)\"}`);\n state = { phase: \"initializing\" };\n initializeSession(handle.hello).then(flushPendingWelcomes);\n return;\n case \"initializing\": return;\n case \"active\":\n sendActiveWelcome(handle, state.sessionId, state.sessionToken);\n return;\n case \"idle\": {\n const { client, sessionId, sessionToken } = state;\n state = { phase: \"initializing\" };\n resumeTransport(client, sessionId, sessionToken).then(flushPendingWelcomes);\n return;\n }\n case \"skipping\":\n if (handle.hello.forceRecord) {\n log(\"forceRecord set; re-initializing from skipping state\");\n state = { phase: \"initializing\" };\n initializeSession(handle.hello).then(flushPendingWelcomes);\n return;\n }\n handle.port.postMessage({\n type: \"welcome\",\n result: { skipRecording: true }\n });\n return;\n case \"dead\":\n handle.port.postMessage({\n type: \"dead\",\n reason: state.reason\n });\n return;\n default: break;\n }\n}\nasync function initializeSession(firstHello) {\n const client = new CsrClient(firstHello.apiUrl, firstHello.clientSecret, firstHello.context, firstHello.websocketUrl, log, firstHello.forceRecord);\n if (firstHello.sessionIdHint && firstHello.sessionTokenHint) {\n log(`adopting sessionIdHint=${firstHello.sessionIdHint}`);\n try {\n const transport = await client.openTransport(firstHello.sessionTokenHint);\n wireTransport(transport);\n state = {\n phase: \"active\",\n client,\n transport,\n sessionId: firstHello.sessionIdHint,\n sessionToken: firstHello.sessionTokenHint\n };\n log(\"hint adopted; transport open\");\n if (ports.length === 0) idleTimer = setTimeout(enterIdle, IDLE_GRACE_MS);\n return;\n } catch (err) {\n log(`hint rejected (${String(err)}); falling back to fresh init`);\n }\n }\n let result;\n try {\n result = await client.initSession();\n } catch (err) {\n log(`init-session threw: ${String(err)}`);\n transitionToDead(`init-session-failed: ${String(err)}`);\n return;\n }\n if (\"skipRecording\" in result) {\n log(\"init-session: skipRecording\");\n state = { phase: \"skipping\" };\n return;\n }\n log(`init-session ok sessionId=${result.sessionId}`);\n let transport;\n try {\n transport = await client.openTransport(result.sessionToken);\n } catch (err) {\n log(`openTransport threw: ${String(err)}`);\n transitionToDead(`open-transport-failed: ${String(err)}`);\n return;\n }\n wireTransport(transport);\n log(\"transport open; session active\");\n state = {\n phase: \"active\",\n client,\n transport,\n sessionId: result.sessionId,\n sessionToken: result.sessionToken\n };\n if (ports.length === 0) idleTimer = setTimeout(enterIdle, IDLE_GRACE_MS);\n}\nasync function resumeTransport(client, sessionId, sessionToken) {\n log(\"resuming transport from idle\");\n let transport;\n try {\n transport = await client.openTransport(sessionToken);\n } catch (err) {\n log(`resume-transport threw: ${String(err)}`);\n transitionToDead(`resume-transport-failed: ${String(err)}`);\n return;\n }\n wireTransport(transport);\n log(\"transport resumed\");\n state = {\n phase: \"active\",\n client,\n transport,\n sessionId,\n sessionToken\n };\n if (ports.length === 0) idleTimer = setTimeout(enterIdle, IDLE_GRACE_MS);\n}\nfunction wireTransport(transport) {\n transport.onClose((info) => {\n if (state.phase !== \"active\") return;\n transitionToDead(info.reason);\n });\n transport.onStateChange((info) => {\n if (state.phase !== \"active\") return;\n for (const handle of ports) handle.port.postMessage({\n type: \"state\",\n connected: info.connected\n });\n });\n}\nfunction transitionToDead(reason) {\n state = {\n phase: \"dead\",\n reason\n };\n for (const handle of ports) handle.port.postMessage({\n type: \"dead\",\n reason\n });\n}\nfunction flushPendingWelcomes() {\n for (const handle of ports) {\n if (handle.hello === null) continue;\n if (state.phase === \"active\") sendActiveWelcome(handle, state.sessionId, state.sessionToken);\n else if (state.phase === \"skipping\") handle.port.postMessage({\n type: \"welcome\",\n result: { skipRecording: true }\n });\n else if (state.phase === \"dead\") handle.port.postMessage({\n type: \"dead\",\n reason: state.reason\n });\n }\n}\nfunction sendActiveWelcome(handle, currentSessionId, currentSessionToken) {\n const hint = handle.hello?.sessionIdHint;\n const adopted = hint !== void 0 && hint !== currentSessionId;\n const newTabId = handle.newTabId;\n handle.port.postMessage({\n type: \"welcome\",\n result: {\n sessionId: currentSessionId,\n sessionToken: currentSessionToken\n },\n adoptedFromSessionId: adopted ? hint : void 0,\n newTabId,\n resetCounter: adopted || newTabId !== void 0\n });\n}\nfunction onFrame(frame) {\n if (state.phase !== \"active\") return;\n state.transport.send(frame);\n}\nfunction onBye(handle) {\n const idx = ports.indexOf(handle);\n if (idx >= 0) ports.splice(idx, 1);\n if (ports.length === 0 && state.phase === \"active\") {\n log(`last tab disconnected; closing transport in ${IDLE_GRACE_MS}ms`);\n idleTimer = setTimeout(enterIdle, IDLE_GRACE_MS);\n }\n}\nfunction enterIdle() {\n idleTimer = null;\n if (state.phase !== \"active\" || ports.length > 0) return;\n log(\"idle timeout; closing transport\");\n state.transport.close(\"idle\");\n state = {\n phase: \"idle\",\n client: state.client,\n sessionId: state.sessionId,\n sessionToken: state.sessionToken\n };\n}\n//#endregion\n//#region src/uploader/worker/entry.ts\nconst SharedWorkerScopeCtor = globalThis.SharedWorkerGlobalScope;\nif (typeof SharedWorkerScopeCtor === \"function\" && self instanceof SharedWorkerScopeCtor) self.onconnect = (event) => {\n const port = event.ports[0];\n port.start();\n registerPort(adaptMessagePort(port));\n};\nelse registerPort(adaptDedicatedSelf());\nfunction adaptMessagePort(port) {\n return {\n postMessage: (message) => port.postMessage(message),\n onmessage: (cb) => {\n port.onmessage = (e) => cb(e.data);\n }\n };\n}\nfunction adaptDedicatedSelf() {\n const ws = self;\n return {\n postMessage: (message) => ws.postMessage(message),\n onmessage: (cb) => {\n ws.onmessage = (e) => cb(e.data);\n }\n };\n}\n//#endregion\n";
12922
- //#endregion
12923
- //#region ../csr-common/src/uploader/create-uploader.ts
12924
- const STORAGE_TAB_ID = "csr:tabId";
12925
- const STORAGE_SESSION = "csr:session";
12926
- const STORAGE_COUNTER = "csr:counter";
12927
- const DEFAULT_SESSION_TTL_MS = 1800 * 1e3;
12928
- const WELCOME_TIMEOUT_MS = 1e4;
12929
- async function createUploader(opts) {
12930
- const log = opts.debugLogger;
12931
- const sessionTtlMs = opts.sessionTtlMs ?? DEFAULT_SESSION_TTL_MS;
12932
- const tabId = readOrMintTabId();
12933
- const sessionHint = readSessionHint(sessionTtlMs);
12934
- const counterHint = readCounter();
12935
- const mode = resolveMode(opts.workerMode ?? "auto");
12936
- log?.(`tab: createUploader mode=${mode} tabId=${tabId} sessionHint=${sessionHint?.id ?? "(none)"} counterHint=${counterHint}`);
12937
- const workerName = mode === "shared" ? await hashSecret(opts.clientSecret) : void 0;
12938
- const { port, urlScheme } = await openWorkerPort(mode, opts.workerUrl, workerName, log);
12939
- log?.(`tab: worker loaded via ${urlScheme}${urlScheme === "blob" ? " (fallback — cross-tab sharing unavailable)" : ""}`);
12940
- let phase = "awaiting-welcome";
12941
- let sessionId = null;
12942
- let sessionToken = null;
12943
- let effectiveTabId = tabId;
12944
- let resolveWelcome;
12945
- const welcomePromise = new Promise((res) => {
12946
- resolveWelcome = res;
12947
- });
12948
- port.setHandler((data) => {
12949
- const msg = data;
12950
- if (msg.type === "log") {
12951
- log?.(`worker: ${msg.msg}`);
12952
- return;
12953
- }
12954
- if (phase === "awaiting-welcome") {
12955
- if (msg.type === "welcome" || msg.type === "dead") {
12956
- phase = msg.type === "welcome" ? "active" : "dead";
12957
- resolveWelcome(msg);
12958
- }
12959
- return;
12960
- }
12961
- if (msg.type === "state" && sessionId !== null) {
12962
- opts.onStateChange?.({
12963
- sessionId,
12964
- tabId: effectiveTabId,
12965
- connected: msg.connected,
12966
- sessionToken
12967
- });
12968
- return;
12969
- }
12970
- if (msg.type === "dead") {
12971
- phase = "dead";
12972
- if (sessionId !== null) opts.onStateChange?.({
12973
- sessionId,
12974
- tabId: effectiveTabId,
12975
- connected: false,
12976
- sessionToken
12977
- });
12978
- opts.onTerminate?.({ reason: msg.reason });
12979
- }
12980
- });
12981
- const autoUA = collectUserAgentContext();
12982
- const context = {
12983
- ...autoUA ? { userAgent: autoUA } : {},
12984
- ...opts.context ?? {}
12985
- };
12986
- port.postMessage({
12987
- type: "hello",
12988
- apiUrl: opts.apiUrl,
12989
- websocketUrl: opts.websocketUrl,
12990
- clientSecret: opts.clientSecret,
12991
- context,
12992
- forceRecord: opts.forceRecord,
12993
- sessionIdHint: sessionHint?.id,
12994
- sessionTokenHint: sessionHint?.token,
12995
- tabId,
12996
- debugLogs: log !== void 0
12997
- });
12998
- log?.("tab: hello sent, awaiting welcome");
12999
- const timeoutMs = opts._welcomeTimeoutMs ?? WELCOME_TIMEOUT_MS;
13000
- let welcomeTimer;
13001
- const welcomeDeadline = new Promise((_, reject) => {
13002
- port.onError((err) => reject(err));
13003
- welcomeTimer = setTimeout(() => reject(/* @__PURE__ */ new Error(`uploader: welcome timeout. The worker did not respond within ${timeoutMs / 1e3}s. This may indicate a CSP policy blocking the worker script from loading. Check your browser console for errors.`)), timeoutMs);
13004
- });
13005
- welcomeDeadline.catch(() => {});
13006
- const welcome = await Promise.race([welcomePromise.then((msg) => {
13007
- clearTimeout(welcomeTimer);
13008
- return msg;
13009
- }), welcomeDeadline]);
13010
- log?.(welcome.type === "welcome" ? `tab: welcome (${"sessionId" in welcome.result ? `sessionId=${welcome.result.sessionId}` : "skipRecording"})` : `tab: dead reason=${welcome.reason}`);
13011
- if (welcome.type === "dead") throw new Error(`uploader: ${welcome.reason}`);
13012
- if ("skipRecording" in welcome.result) {
13013
- if (opts.forceRecord) log?.("tab: forceRecord was set but backend still skipped — backend may not support forceRecord yet");
13014
- return null;
13015
- }
13016
- sessionId = welcome.result.sessionId;
13017
- sessionToken = welcome.result.sessionToken;
13018
- writeSession(welcome.result.sessionId, welcome.result.sessionToken);
13019
- if (welcome.newTabId !== void 0) {
13020
- effectiveTabId = welcome.newTabId;
13021
- sessionStorage.setItem(STORAGE_TAB_ID, effectiveTabId);
13022
- }
13023
- let counter = welcome.resetCounter ? 0 : counterHint;
13024
- let nextAdoptionMeta = welcome.adoptedFromSessionId !== void 0 ? {
13025
- adoptedFromSessionId: welcome.adoptedFromSessionId,
13026
- adoptedAt: Date.now()
13027
- } : void 0;
13028
- opts.onStateChange?.({
13029
- sessionId,
13030
- tabId: effectiveTabId,
13031
- connected: true,
13032
- sessionToken
13033
- });
13034
- const flush = () => {
13035
- writeCounter(counter);
13036
- };
13037
- window.addEventListener("pagehide", () => {
13038
- flush();
13039
- try {
13040
- port.postMessage({
13041
- type: "bye",
13042
- reason: "pagehide"
13043
- });
13044
- } catch (_e) {}
13045
- });
13046
- document.addEventListener("visibilitychange", () => {
13047
- if (document.visibilityState === "hidden") flush();
13048
- });
13049
- const uploader = ((event) => {
13050
- if (phase === "dead") throw new Error("uploader: terminated");
13051
- const frame = {
13052
- tabId: effectiveTabId,
13053
- eventCounter: counter,
13054
- data: event,
13055
- ...nextAdoptionMeta ?? {}
13056
- };
13057
- counter += 1;
13058
- nextAdoptionMeta = void 0;
13059
- port.postMessage({
13060
- type: "frame",
13061
- frame
13062
- });
13063
- });
13064
- uploader.close = () => {
13065
- flush();
13066
- try {
13067
- port.postMessage({
13068
- type: "bye",
13069
- reason: "stop"
13070
- });
13071
- } catch (_e) {}
13072
- };
13073
- return uploader;
13074
- }
13075
- function resolveMode(mode) {
13076
- if (mode === "auto") return typeof SharedWorker !== "undefined" ? "shared" : "dedicated";
13077
- return mode;
13078
- }
13079
- async function openWorkerPort(mode, workerUrl, workerName, log) {
13080
- if (workerUrl) return {
13081
- port: createWorker(mode, workerUrl, workerName),
13082
- urlScheme: "custom"
13083
- };
13084
- const dataUrl = toDataUrl(workerScript);
13085
- try {
13086
- const port = createWorker(mode, dataUrl, workerName);
13087
- await new Promise((resolve) => setTimeout(resolve, 0));
13088
- const asyncErr = port.getBufferedError();
13089
- if (asyncErr) throw asyncErr;
13090
- return {
13091
- port,
13092
- urlScheme: "data"
13093
- };
13094
- } catch (_dataErr) {
13095
- log?.("tab: data: worker blocked, falling back to blob: URL (dedicated mode)");
13096
- const blobUrl = toBlobUrl(workerScript);
13097
- try {
13098
- return {
13099
- port: createDedicatedWorker(blobUrl),
13100
- urlScheme: "blob"
13101
- };
13102
- } catch (blobErr) {
13103
- const hint = "Your Content Security Policy blocks both `data:` and `blob:` in `worker-src`. To fix this, either add `blob:` to your `worker-src` directive, or use the `workerUrl` option to serve the worker script from your own origin.";
13104
- log?.(`tab: worker-load-failed: ${hint}`);
13105
- throw new Error(`worker-load-failed: ${hint}`, blobErr instanceof Error ? { cause: blobErr } : void 0);
13106
- }
13107
- }
13108
- }
13109
- function createWorker(mode, url, workerName) {
13110
- if (mode === "shared") return createSharedWorker(url, workerName);
13111
- return createDedicatedWorker(url);
13112
- }
13113
- function createSharedWorker(url, name) {
13114
- const options = {
13115
- name,
13116
- type: "module",
13117
- extendedLifetime: true
13118
- };
13119
- const worker = new SharedWorker(url, options);
13120
- let errorCb = null;
13121
- let bufferedError = null;
13122
- worker.onerror = (e) => {
13123
- const err = workerLoadError(e, url);
13124
- if (errorCb) errorCb(err);
13125
- else bufferedError = err;
13126
- };
13127
- worker.port.start();
13128
- return {
13129
- postMessage: (m) => worker.port.postMessage(m),
13130
- setHandler: (cb) => {
13131
- worker.port.onmessage = (e) => cb(e.data);
13132
- },
13133
- onError: (cb) => {
13134
- errorCb = cb;
13135
- if (bufferedError) cb(bufferedError);
13136
- },
13137
- getBufferedError: () => bufferedError
13138
- };
13139
- }
13140
- function createDedicatedWorker(url) {
13141
- const worker = new Worker(url, { type: "module" });
13142
- let errorCb = null;
13143
- let bufferedError = null;
13144
- worker.onerror = (e) => {
13145
- const err = workerLoadError(e, url);
13146
- if (errorCb) errorCb(err);
13147
- else bufferedError = err;
13148
- };
13149
- return {
13150
- postMessage: (m) => worker.postMessage(m),
13151
- setHandler: (cb) => {
13152
- worker.onmessage = (e) => cb(e.data);
13153
- },
13154
- onError: (cb) => {
13155
- errorCb = cb;
13156
- if (bufferedError) cb(bufferedError);
13157
- },
13158
- getBufferedError: () => bufferedError
13159
- };
13160
- }
13161
- function workerLoadError(cause, url) {
13162
- const msg = `worker-load-failed: ${url.startsWith("data:") ? "This is likely caused by a Content Security Policy (CSP) that blocks `data:` in `worker-src`. To fix this, either add `data:` to your `worker-src` directive, or use the `workerUrl` option to serve the worker script from your own origin." : `Failed to load the worker script from ${url}. Check that the URL is reachable and that your CSP \`worker-src\` directive allows it.`}`;
13163
- return new Error(msg, cause instanceof Error ? { cause } : void 0);
13164
- }
13165
- function toDataUrl(script) {
13166
- const bytes = new TextEncoder().encode(script);
13167
- let binary = "";
13168
- for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
13169
- return `data:application/javascript;base64,${btoa(binary)}`;
13170
- }
13171
- function toBlobUrl(script) {
13172
- return URL.createObjectURL(new Blob([script], { type: "application/javascript" }));
13173
- }
13174
- async function hashSecret(secret) {
13175
- const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(secret));
13176
- return Array.from(new Uint8Array(buf)).slice(0, 8).map((b) => b.toString(16).padStart(2, "0")).join("");
13177
- }
13178
- function readOrMintTabId() {
13179
- let id = sessionStorage.getItem(STORAGE_TAB_ID);
13180
- if (!id) {
13181
- id = crypto.randomUUID();
13182
- sessionStorage.setItem(STORAGE_TAB_ID, id);
13183
- }
13184
- return id;
13185
- }
13186
- function readSessionHint(ttlMs) {
13187
- const raw = sessionStorage.getItem(STORAGE_SESSION);
13188
- if (!raw) return null;
13189
- try {
13190
- const parsed = JSON.parse(raw);
13191
- if (Date.now() - parsed.ts > ttlMs) return null;
13192
- if (!parsed.token) return null;
13193
- return {
13194
- id: parsed.id,
13195
- token: parsed.token
13196
- };
13197
- } catch (_e) {
13198
- return null;
13199
- }
13200
- }
13201
- function writeSession(sessionId, sessionToken) {
13202
- sessionStorage.setItem(STORAGE_SESSION, JSON.stringify({
13203
- id: sessionId,
13204
- token: sessionToken,
13205
- ts: Date.now()
13206
- }));
13207
- }
13208
- function readCounter() {
13209
- const raw = sessionStorage.getItem(STORAGE_COUNTER);
13210
- if (!raw) return 0;
13211
- const n = Number(raw);
13212
- return Number.isFinite(n) ? n : 0;
13213
- }
13214
- function writeCounter(counter) {
13215
- sessionStorage.setItem(STORAGE_COUNTER, String(counter));
13216
- }
13217
- //#endregion
13218
11190
  //#region src/version.ts
13219
- const SDK_VERSION = "0.18.6";
11191
+ const SDK_VERSION = "0.18.7";
13220
11192
  //#endregion
13221
11193
  //#region src/index.ts
13222
11194
  const DEFAULT_API_URL = "https://recording.confidence.dev";
@@ -13263,6 +11235,7 @@ function initSessionRecorder(options) {
13263
11235
  _csr_sdk_version: SDK_VERSION,
13264
11236
  ...options.appVersion ? { _app_version: options.appVersion } : {}
13265
11237
  },
11238
+ workerUrl: options.workerUrl,
13266
11239
  forceRecord,
13267
11240
  debugLogger,
13268
11241
  onTerminate: ({ reason }) => {