@spotify-confidence/session-recording 0.18.6 → 0.18.8

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