@lark-sentry/utils 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1875 @@
1
+ 'use strict';
2
+
3
+ var constants = require('@lark-sentry/constants');
4
+ var types = require('@lark-sentry/types');
5
+
6
+ function base64(raw) {
7
+ return btoa(encodeURIComponent(raw));
8
+ }
9
+ function base64v2(str) {
10
+ const bytes = new TextEncoder().encode(str);
11
+ let binary = "";
12
+ for (const b of bytes) {
13
+ binary += String.fromCharCode(b);
14
+ }
15
+ const base642 = btoa(binary);
16
+ return base642.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
17
+ }
18
+
19
+ var __defProp$1 = Object.defineProperty;
20
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
21
+ var __publicField$1 = (obj, key, value) => __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
22
+ class MinHeap {
23
+ constructor(capacity = constants.MAX_BREADCRUMBS, itemArray = []) {
24
+ __publicField$1(this, "capacity", constants.MAX_BREADCRUMBS);
25
+ __publicField$1(this, "heap", []);
26
+ this.capacity = capacity;
27
+ this.heap = itemArray.slice(0, capacity);
28
+ this.buildHeap();
29
+ if (itemArray.length > capacity) {
30
+ const rest = itemArray.slice(capacity);
31
+ for (const item of rest) {
32
+ if (item.timestamp >= this.heap[0].timestamp) {
33
+ this.heap[0] = item;
34
+ this.heapifyDown(0);
35
+ }
36
+ }
37
+ }
38
+ }
39
+ get size() {
40
+ return this.heap.length;
41
+ }
42
+ push(item) {
43
+ if (this.size < this.capacity) {
44
+ this.heap.push(item);
45
+ this.heapifyUp(this.size - 1);
46
+ return true;
47
+ }
48
+ if (item.timestamp >= this.heap[0].timestamp) {
49
+ this.heap[0] = item;
50
+ this.heapifyDown(0);
51
+ return true;
52
+ }
53
+ return false;
54
+ }
55
+ peek() {
56
+ return this.heap[0];
57
+ }
58
+ heapifyUp(idx) {
59
+ while (idx > 0) {
60
+ const parentIdx = Math.floor((idx - 1) / 2);
61
+ if (this.heap[parentIdx].timestamp <= this.heap[idx].timestamp) {
62
+ break;
63
+ }
64
+ [this.heap[idx], this.heap[parentIdx]] = [
65
+ this.heap[parentIdx],
66
+ this.heap[idx]
67
+ ];
68
+ idx = parentIdx;
69
+ }
70
+ }
71
+ heapifyDown(idx) {
72
+ while (true) {
73
+ let childIdx = idx;
74
+ const left = idx * 2 + 1;
75
+ const right = idx * 2 + 2;
76
+ if (left < this.size && this.heap[left].timestamp < this.heap[childIdx].timestamp) {
77
+ childIdx = left;
78
+ }
79
+ if (right < this.size && this.heap[right].timestamp < this.heap[childIdx].timestamp) {
80
+ childIdx = right;
81
+ }
82
+ if (childIdx === idx) {
83
+ break;
84
+ }
85
+ [this.heap[idx], this.heap[childIdx]] = [
86
+ this.heap[childIdx],
87
+ this.heap[idx]
88
+ ];
89
+ idx = childIdx;
90
+ }
91
+ }
92
+ buildHeap() {
93
+ const lastLeafIdx = this.size - 1;
94
+ const lastNonLeafIdx = Math.floor((lastLeafIdx - 1) / 2);
95
+ for (let i = lastNonLeafIdx; i >= 0; i--) {
96
+ this.heapifyDown(i);
97
+ }
98
+ }
99
+ dump() {
100
+ return this.heap;
101
+ }
102
+ clear() {
103
+ this.heap = [];
104
+ }
105
+ pop() {
106
+ if (this.size === 0) {
107
+ return void 0;
108
+ }
109
+ const peek = this.heap[0];
110
+ this.heap[0] = this.heap[this.size - 1];
111
+ this.heap.pop();
112
+ if (this.size > 0) {
113
+ this.heapifyDown(0);
114
+ }
115
+ return peek;
116
+ }
117
+ }
118
+ class CallbackQueue {
119
+ constructor() {
120
+ __publicField$1(this, "cbList", []);
121
+ }
122
+ push(cb, ctx, ...args) {
123
+ if (typeof cb !== "function") {
124
+ return;
125
+ }
126
+ this.callByRequestIdleCallback(cb, ctx, ...args);
127
+ }
128
+ callByRequestIdleCallback(cb, ctx, ...args) {
129
+ if (typeof requestIdleCallback !== "function") {
130
+ this.callByPromise(cb, ctx, ...args);
131
+ return;
132
+ }
133
+ this.cbList.push(cb.bind(ctx, ...args));
134
+ requestIdleCallback(() => {
135
+ this.flushFuncList();
136
+ });
137
+ }
138
+ callByPromise(cb, ctx, ...args) {
139
+ this.cbList.push(cb.bind(ctx, ...args));
140
+ Promise.resolve().then(() => {
141
+ this.flushFuncList();
142
+ });
143
+ }
144
+ clear() {
145
+ this.cbList = [];
146
+ }
147
+ flushFuncList() {
148
+ const oldFuncList = this.cbList;
149
+ this.cbList = [];
150
+ oldFuncList.forEach((func) => {
151
+ func();
152
+ });
153
+ }
154
+ }
155
+
156
+ function debounce(fn, delay = 300) {
157
+ let timer = null;
158
+ return function(...args) {
159
+ if (timer !== null) {
160
+ clearTimeout(timer);
161
+ }
162
+ timer = setTimeout(() => {
163
+ fn.apply(this, args);
164
+ timer = null;
165
+ }, delay);
166
+ };
167
+ }
168
+
169
+ function decorateProp(obj, propKey, decorator) {
170
+ const oldPropVal = obj[propKey];
171
+ const propVal = decorator(oldPropVal);
172
+ obj[propKey] = propVal;
173
+ }
174
+
175
+ function dom2str(target, maxDepth = 10) {
176
+ if (maxDepth <= 0) {
177
+ return "...";
178
+ }
179
+ const tagName = target.tagName.toLowerCase();
180
+ const attrs = Array.from(target.attributes).map((attr) => ` ${attr.name}="${attr.value}"`).join("");
181
+ const children = Array.from(target.children).map((child) => dom2str(child, maxDepth - 1)).join("");
182
+ return `<${tagName}${attrs}>${children}</${tagName}>`;
183
+ }
184
+
185
+ function event2breadcrumb(type) {
186
+ switch (type) {
187
+ case types.EventType.Xhr:
188
+ case types.EventType.Fetch: {
189
+ return types.BreadcrumbType.Http;
190
+ }
191
+ case types.EventType.Click: {
192
+ return types.BreadcrumbType.Click;
193
+ }
194
+ case types.EventType.HashChange:
195
+ case types.EventType.History: {
196
+ return types.BreadcrumbType.Route;
197
+ }
198
+ case types.EventType.Resource: {
199
+ return types.BreadcrumbType.Resource;
200
+ }
201
+ case types.EventType.UnhandledRejection: {
202
+ return types.BreadcrumbType.CodeError;
203
+ }
204
+ case types.EventType.Error:
205
+ case types.EventType.Vue:
206
+ case types.EventType.React:
207
+ case types.EventType.Performance:
208
+ case types.EventType.ScreenRecord:
209
+ case types.EventType.WhiteScreen:
210
+ case types.EventType.Custom: {
211
+ return types.BreadcrumbType.Custom;
212
+ }
213
+ default: {
214
+ return types.BreadcrumbType.Custom;
215
+ }
216
+ }
217
+ }
218
+
219
+ function getCssSelectors(elem) {
220
+ if (!elem || elem.nodeType !== 1) {
221
+ return ["", "", ""];
222
+ }
223
+ const excludedAttrs = ["id", "class", "style"];
224
+ const idSelector = elem.id ? `#${elem.id}` : "";
225
+ const classSelector = Array.from(elem.classList).map((c) => `.${c}`).join("");
226
+ const attrSelector = Array.from(elem.attributes).filter((attr) => !excludedAttrs.includes(attr.name)).map((attr) => `[${attr.name}="${attr.value}"]`).join("");
227
+ const elemSelector = elem.tagName.toLowerCase();
228
+ return [idSelector, classSelector + attrSelector, elemSelector];
229
+ }
230
+
231
+ function getTime() {
232
+ return {
233
+ time: (/* @__PURE__ */ new Date()).toISOString(),
234
+ timestamp: Date.now()
235
+ };
236
+ }
237
+
238
+ // Generated ESM version of ua-parser-js
239
+ // DO NOT EDIT THIS FILE!
240
+ // Source: /src/main/ua-parser.js
241
+
242
+ /////////////////////////////////////////////////////////////////////////////////
243
+ /* UAParser.js v2.0.7
244
+ Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
245
+ AGPLv3 License *//*
246
+ Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
247
+ Supports browser & node.js environment.
248
+ Demo : https://uaparser.dev
249
+ Source : https://github.com/faisalman/ua-parser-js */
250
+ /////////////////////////////////////////////////////////////////////////////////
251
+
252
+ /* jshint esversion: 6 */
253
+ /* globals window */
254
+
255
+
256
+
257
+ //////////////
258
+ // Constants
259
+ /////////////
260
+
261
+ var LIBVERSION = '2.0.7',
262
+ UA_MAX_LENGTH = 500,
263
+ USER_AGENT = 'user-agent',
264
+ EMPTY = '',
265
+ UNKNOWN = '?',
266
+ TYPEOF = {
267
+ FUNCTION : 'function',
268
+ OBJECT : 'object',
269
+ STRING : 'string',
270
+ UNDEFINED : 'undefined'
271
+ },
272
+
273
+ // properties
274
+ BROWSER = 'browser',
275
+ CPU = 'cpu',
276
+ DEVICE = 'device',
277
+ ENGINE = 'engine',
278
+ OS = 'os',
279
+ RESULT = 'result',
280
+
281
+ NAME = 'name',
282
+ TYPE = 'type',
283
+ VENDOR = 'vendor',
284
+ VERSION = 'version',
285
+ ARCHITECTURE= 'architecture',
286
+ MAJOR = 'major',
287
+ MODEL = 'model',
288
+
289
+ // device types
290
+ CONSOLE = 'console',
291
+ MOBILE = 'mobile',
292
+ TABLET = 'tablet',
293
+ SMARTTV = 'smarttv',
294
+ WEARABLE = 'wearable',
295
+ XR = 'xr',
296
+ EMBEDDED = 'embedded',
297
+
298
+ // browser types
299
+ INAPP = 'inapp',
300
+
301
+ // client hints
302
+ BRANDS = 'brands',
303
+ FORMFACTORS = 'formFactors',
304
+ FULLVERLIST = 'fullVersionList',
305
+ PLATFORM = 'platform',
306
+ PLATFORMVER = 'platformVersion',
307
+ BITNESS = 'bitness',
308
+ CH = 'sec-ch-ua',
309
+ CH_FULL_VER_LIST= CH + '-full-version-list',
310
+ CH_ARCH = CH + '-arch',
311
+ CH_BITNESS = CH + '-' + BITNESS,
312
+ CH_FORM_FACTORS = CH + '-form-factors',
313
+ CH_MOBILE = CH + '-' + MOBILE,
314
+ CH_MODEL = CH + '-' + MODEL,
315
+ CH_PLATFORM = CH + '-' + PLATFORM,
316
+ CH_PLATFORM_VER = CH_PLATFORM + '-version',
317
+ CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
318
+
319
+ // device vendors
320
+ AMAZON = 'Amazon',
321
+ APPLE = 'Apple',
322
+ ASUS = 'ASUS',
323
+ BLACKBERRY = 'BlackBerry',
324
+ GOOGLE = 'Google',
325
+ HUAWEI = 'Huawei',
326
+ LENOVO = 'Lenovo',
327
+ HONOR = 'Honor',
328
+ LG = 'LG',
329
+ MICROSOFT = 'Microsoft',
330
+ MOTOROLA = 'Motorola',
331
+ NVIDIA = 'Nvidia',
332
+ ONEPLUS = 'OnePlus',
333
+ OPPO = 'OPPO',
334
+ SAMSUNG = 'Samsung',
335
+ SHARP = 'Sharp',
336
+ SONY = 'Sony',
337
+ XIAOMI = 'Xiaomi',
338
+ ZEBRA = 'Zebra',
339
+
340
+ // browsers
341
+ CHROME = 'Chrome',
342
+ CHROMIUM = 'Chromium',
343
+ CHROMECAST = 'Chromecast',
344
+ EDGE = 'Edge',
345
+ FIREFOX = 'Firefox',
346
+ OPERA = 'Opera',
347
+ FACEBOOK = 'Facebook',
348
+ SOGOU = 'Sogou',
349
+
350
+ PREFIX_MOBILE = 'Mobile ',
351
+ SUFFIX_BROWSER = ' Browser',
352
+
353
+ // os
354
+ WINDOWS = 'Windows';
355
+
356
+ var isWindow = typeof window !== TYPEOF.UNDEFINED,
357
+ NAVIGATOR = (isWindow && window.navigator) ?
358
+ window.navigator :
359
+ undefined,
360
+ NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
361
+ NAVIGATOR.userAgentData :
362
+ undefined;
363
+
364
+ ///////////
365
+ // Helper
366
+ //////////
367
+
368
+ var extend = function (defaultRgx, extensions) {
369
+ var mergedRgx = {};
370
+ var extraRgx = extensions;
371
+ if (!isExtensions(extensions)) {
372
+ extraRgx = {};
373
+ for (var i in extensions) {
374
+ for (var j in extensions[i]) {
375
+ extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
376
+ }
377
+ }
378
+ }
379
+ for (var k in defaultRgx) {
380
+ mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
381
+ }
382
+ return mergedRgx;
383
+ },
384
+ enumerize = function (arr) {
385
+ var enums = {};
386
+ for (var i=0; i<arr.length; i++) {
387
+ enums[arr[i].toUpperCase()] = arr[i];
388
+ }
389
+ return enums;
390
+ },
391
+ has = function (str1, str2) {
392
+ if (typeof str1 === TYPEOF.OBJECT && str1.length > 0) {
393
+ for (var i in str1) {
394
+ if (lowerize(str2) == lowerize(str1[i])) return true;
395
+ }
396
+ return false;
397
+ }
398
+ return isString(str1) ? lowerize(str2) == lowerize(str1) : false;
399
+ },
400
+ isExtensions = function (obj, deep) {
401
+ for (var prop in obj) {
402
+ return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
403
+ }
404
+ },
405
+ isString = function (val) {
406
+ return typeof val === TYPEOF.STRING;
407
+ },
408
+ itemListToArray = function (header) {
409
+ if (!header) return undefined;
410
+ var arr = [];
411
+ var tokens = strip(/\\?\"/g, header).split(',');
412
+ for (var i = 0; i < tokens.length; i++) {
413
+ if (tokens[i].indexOf(';') > -1) {
414
+ var token = trim(tokens[i]).split(';v=');
415
+ arr[i] = { brand : token[0], version : token[1] };
416
+ } else {
417
+ arr[i] = trim(tokens[i]);
418
+ }
419
+ }
420
+ return arr;
421
+ },
422
+ lowerize = function (str) {
423
+ return isString(str) ? str.toLowerCase() : str;
424
+ },
425
+ majorize = function (version) {
426
+ return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
427
+ },
428
+ setProps = function (arr) {
429
+ for (var i in arr) {
430
+ if (!arr.hasOwnProperty(i)) continue;
431
+
432
+ var propName = arr[i];
433
+ if (typeof propName == TYPEOF.OBJECT && propName.length == 2) {
434
+ this[propName[0]] = propName[1];
435
+ } else {
436
+ this[propName] = undefined;
437
+ }
438
+ }
439
+ return this;
440
+ },
441
+ strip = function (pattern, str) {
442
+ return isString(str) ? str.replace(pattern, EMPTY) : str;
443
+ },
444
+ stripQuotes = function (str) {
445
+ return strip(/\\?\"/g, str);
446
+ },
447
+ trim = function (str, len) {
448
+ str = strip(/^\s\s*/, String(str));
449
+ return typeof len === TYPEOF.UNDEFINED ? str : str.substring(0, len);
450
+ };
451
+
452
+ ///////////////
453
+ // Map helper
454
+ //////////////
455
+
456
+ var rgxMapper = function (ua, arrays) {
457
+
458
+ if(!ua || !arrays) return;
459
+
460
+ var i = 0, j, k, p, q, matches, match;
461
+
462
+ // loop through all regexes maps
463
+ while (i < arrays.length && !matches) {
464
+
465
+ var regex = arrays[i], // even sequence (0,2,4,..)
466
+ props = arrays[i + 1]; // odd sequence (1,3,5,..)
467
+ j = k = 0;
468
+
469
+ // try matching uastring with regexes
470
+ while (j < regex.length && !matches) {
471
+
472
+ if (!regex[j]) { break; }
473
+ matches = regex[j++].exec(ua);
474
+
475
+ if (!!matches) {
476
+ for (p = 0; p < props.length; p++) {
477
+ match = matches[++k];
478
+ q = props[p];
479
+ // check if given property is actually array
480
+ if (typeof q === TYPEOF.OBJECT && q.length > 0) {
481
+ if (q.length === 2) {
482
+ if (typeof q[1] == TYPEOF.FUNCTION) {
483
+ // assign modified match
484
+ this[q[0]] = q[1].call(this, match);
485
+ } else {
486
+ // assign given value, ignore regex match
487
+ this[q[0]] = q[1];
488
+ }
489
+ } else if (q.length >= 3) {
490
+ // Check whether q[1] FUNCTION or REGEX
491
+ if (typeof q[1] === TYPEOF.FUNCTION && !(q[1].exec && q[1].test)) {
492
+ if (q.length > 3) {
493
+ this[q[0]] = match ? q[1].apply(this, q.slice(2)) : undefined;
494
+ } else {
495
+ // call function (usually string mapper)
496
+ this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
497
+ }
498
+ } else {
499
+ if (q.length == 3) {
500
+ // sanitize match using given regex
501
+ this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
502
+ } else if (q.length == 4) {
503
+ this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
504
+ } else if (q.length > 4) {
505
+ this[q[0]] = match ? q[3].apply(this, [match.replace(q[1], q[2])].concat(q.slice(4))) : undefined;
506
+ }
507
+ }
508
+ }
509
+ } else {
510
+ this[q] = match ? match : undefined;
511
+ }
512
+ }
513
+ }
514
+ }
515
+ i += 2;
516
+ }
517
+ },
518
+
519
+ strMapper = function (str, map) {
520
+
521
+ for (var i in map) {
522
+ // check if current value is array
523
+ if (typeof map[i] === TYPEOF.OBJECT && map[i].length > 0) {
524
+ for (var j = 0; j < map[i].length; j++) {
525
+ if (has(map[i][j], str)) {
526
+ return (i === UNKNOWN) ? undefined : i;
527
+ }
528
+ }
529
+ } else if (has(map[i], str)) {
530
+ return (i === UNKNOWN) ? undefined : i;
531
+ }
532
+ }
533
+ return map.hasOwnProperty('*') ? map['*'] : str;
534
+ };
535
+
536
+ ///////////////
537
+ // String map
538
+ //////////////
539
+
540
+ var windowsVersionMap = {
541
+ 'ME' : '4.90',
542
+ 'NT 3.51': '3.51',
543
+ 'NT 4.0': '4.0',
544
+ '2000' : ['5.0', '5.01'],
545
+ 'XP' : ['5.1', '5.2'],
546
+ 'Vista' : '6.0',
547
+ '7' : '6.1',
548
+ '8' : '6.2',
549
+ '8.1' : '6.3',
550
+ '10' : ['6.4', '10.0'],
551
+ 'NT' : ''
552
+ },
553
+
554
+ formFactorsMap = {
555
+ 'embedded' : 'Automotive',
556
+ 'mobile' : 'Mobile',
557
+ 'tablet' : ['Tablet', 'EInk'],
558
+ 'smarttv' : 'TV',
559
+ 'wearable' : 'Watch',
560
+ 'xr' : ['VR', 'XR'],
561
+ '?' : ['Desktop', 'Unknown'],
562
+ '*' : undefined
563
+ },
564
+
565
+ browserHintsMap = {
566
+ 'Chrome' : 'Google Chrome',
567
+ 'Edge' : 'Microsoft Edge',
568
+ 'Edge WebView2' : 'Microsoft Edge WebView2',
569
+ 'Chrome WebView': 'Android WebView',
570
+ 'Chrome Headless':'HeadlessChrome',
571
+ 'Huawei Browser': 'HuaweiBrowser',
572
+ 'MIUI Browser' : 'Miui Browser',
573
+ 'Opera Mobi' : 'OperaMobile',
574
+ 'Yandex' : 'YaBrowser'
575
+ };
576
+
577
+ //////////////
578
+ // Regex map
579
+ /////////////
580
+
581
+ var defaultRegexes = {
582
+
583
+ browser : [[
584
+
585
+ // Most common regardless engine
586
+ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
587
+ ], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
588
+ /webview.+edge\/([\w\.]+)/i // Microsoft Edge
589
+ ], [VERSION, [NAME, EDGE+' WebView']], [
590
+ /edg(?:e|ios|a)?\/([\w\.]+)/i
591
+ ], [VERSION, [NAME, 'Edge']], [
592
+
593
+ // Presto based
594
+ /(opera mini)\/([-\w\.]+)/i, // Opera Mini
595
+ /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet
596
+ /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera
597
+ ], [NAME, VERSION], [
598
+ /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
599
+ ], [VERSION, [NAME, OPERA+' Mini']], [
600
+ /\bop(?:rg)?x\/([\w\.]+)/i // Opera GX
601
+ ], [VERSION, [NAME, OPERA+' GX']], [
602
+ /\bopr\/([\w\.]+)/i // Opera Webkit
603
+ ], [VERSION, [NAME, OPERA]], [
604
+
605
+ // Mixed
606
+ /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
607
+ ], [VERSION, [NAME, 'Baidu']], [
608
+ /\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
609
+ ], [VERSION, [NAME, 'Maxthon']], [
610
+ /(kindle)\/([\w\.]+)/i, // Kindle
611
+ /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
612
+ // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
613
+ // Trident based
614
+ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
615
+ /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
616
+
617
+ // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble/Palemoon
618
+ /(atlas|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:lg |qute)browser|palemoon)\/([-\w\.]+)/i,
619
+ // Atlas/Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
620
+ /(heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf
621
+ /(qwant)(?:ios|mobile)\/([\d\.]+)/i, // Qwant
622
+ /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo
623
+ ], [NAME, VERSION], [
624
+ /quark(?:pc)?\/([-\w\.]+)/i // Quark
625
+ ], [VERSION, [NAME, 'Quark']], [
626
+ /\bddg\/([\w\.]+)/i // DuckDuckGo
627
+ ], [VERSION, [NAME, 'DuckDuckGo']], [
628
+ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
629
+ ], [VERSION, [NAME, 'UCBrowser']], [
630
+ /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
631
+ /\bqbcore\/([\w\.]+).+microm/i,
632
+ /micromessenger\/([\w\.]+)/i // WeChat
633
+ ], [VERSION, [NAME, 'WeChat']], [
634
+ /konqueror\/([\w\.]+)/i // Konqueror
635
+ ], [VERSION, [NAME, 'Konqueror']], [
636
+ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11
637
+ ], [VERSION, [NAME, 'IE']], [
638
+ /ya(?:search)?browser\/([\w\.]+)/i // Yandex
639
+ ], [VERSION, [NAME, 'Yandex']], [
640
+ /slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
641
+ ], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [
642
+ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
643
+ ], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
644
+ /\bfocus\/([\w\.]+)/i // Firefox Focus
645
+ ], [VERSION, [NAME, FIREFOX+' Focus']], [
646
+ /\bopt\/([\w\.]+)/i // Opera Touch
647
+ ], [VERSION, [NAME, OPERA+' Touch']], [
648
+ /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser
649
+ ], [VERSION, [NAME, 'Coc Coc']], [
650
+ /dolfin\/([\w\.]+)/i // Dolphin
651
+ ], [VERSION, [NAME, 'Dolphin']], [
652
+ /coast\/([\w\.]+)/i // Opera Coast
653
+ ], [VERSION, [NAME, OPERA+' Coast']], [
654
+ /miuibrowser\/([\w\.]+)/i // MIUI Browser
655
+ ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
656
+ /fxios\/([\w\.-]+)/i // Firefox for iOS
657
+ ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
658
+ /\bqihoobrowser\/?([\w\.]*)/i // 360
659
+ ], [VERSION, [NAME, '360']], [
660
+ /\b(qq)\/([\w\.]+)/i // QQ
661
+ ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
662
+ /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
663
+ ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
664
+ /samsungbrowser\/([\w\.]+)/i // Samsung Internet
665
+ ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
666
+ /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
667
+ ], [VERSION, [NAME, SOGOU + ' Explorer']], [
668
+ /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
669
+ ], [[NAME, SOGOU + ' Mobile'], VERSION], [
670
+ /(electron)\/([\w\.]+) safari/i, // Electron-based App
671
+ /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
672
+ /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
673
+ ], [NAME, VERSION], [
674
+ /(lbbrowser|rekonq|steam(?= (clie|tenf|gameo)))/i // LieBao Browser/Rekonq/Steam
675
+ ], [NAME], [
676
+ /ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
677
+ /ome\/([\w\.]+).+qihu (360)[es]e/i // 360
678
+ ], [VERSION, NAME], [
679
+
680
+ // WebView
681
+ /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
682
+ ], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
683
+ /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
684
+ /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
685
+ /(daum)apps[\/ ]([\w\.]+)/i, // Daum App
686
+ /safari (line)\/([\w\.]+)/i, // Line App for iOS
687
+ /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
688
+ /(alipay)client\/([\w\.]+)/i, // Alipay
689
+ /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
690
+ /(bing)(?:web|sapphire)\/([\w\.]+)/i, // Bing
691
+ /(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i // Instagram/Snapchat/Klarna
692
+ ], [NAME, VERSION, [TYPE, INAPP]], [
693
+ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
694
+ ], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
695
+ /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
696
+ ], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
697
+ /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
698
+ ], [NAME, [TYPE, INAPP]], [
699
+ /(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
700
+ ], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
701
+
702
+ /(chromium)[\/ ]([-\w\.]+)/i // Chromium
703
+ ], [NAME, VERSION], [
704
+
705
+ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
706
+ ], [VERSION, [NAME, CHROME+' Headless']], [
707
+
708
+ /wv\).+chrome\/([\w\.]+).+edgw\//i // Edge WebView2
709
+ ], [VERSION, [NAME, EDGE+' WebView2']], [
710
+
711
+ / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
712
+ ], [[NAME, CHROME+' WebView'], VERSION], [
713
+
714
+ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
715
+ ], [VERSION, [NAME, 'Android' + SUFFIX_BROWSER]], [
716
+
717
+ /chrome\/([\w\.]+) mobile/i // Chrome Mobile
718
+ ], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
719
+
720
+ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia
721
+ ], [NAME, VERSION], [
722
+
723
+ /version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i // Safari Mobile
724
+ ], [VERSION, [NAME, PREFIX_MOBILE + 'Safari']], [
725
+ /iphone .*mobile(?:\/\w+ | ?)safari/i
726
+ ], [[NAME, PREFIX_MOBILE + 'Safari']], [
727
+ /version\/([\w\.\,]+) .*(safari)/i // Safari
728
+ ], [VERSION, NAME], [
729
+ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
730
+ ], [NAME, [VERSION, '1']], [
731
+
732
+ /(webkit|khtml)\/([\w\.]+)/i
733
+ ], [NAME, VERSION], [
734
+
735
+ // Gecko based
736
+ /(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i // Firefox Mobile
737
+ ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
738
+ /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
739
+ ], [[NAME, 'Netscape'], VERSION], [
740
+ /(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
741
+ ], [NAME, VERSION], [
742
+ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
743
+ ], [VERSION, [NAME, FIREFOX+' Reality']], [
744
+ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow
745
+ /(swiftfox)/i, // Swiftfox
746
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
747
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
748
+ /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,
749
+ // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
750
+ /(firefox)\/([\w\.]+)/i, // Other Firefox-based
751
+ /(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i, // Mozilla
752
+
753
+ // Other
754
+ /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
755
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird
756
+ /\b(links) \(([\w\.]+)/i // Links
757
+ ], [NAME, [VERSION, /_/g, '.']], [
758
+
759
+ /(cobalt)\/([\w\.]+)/i // Cobalt
760
+ ], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
761
+ ],
762
+
763
+ cpu : [[
764
+
765
+ /\b((amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64)
766
+ ], [[ARCHITECTURE, 'amd64']], [
767
+
768
+ /(ia32(?=;))/i, // IA32 (quicktime)
769
+ /\b((i[346]|x)86)(pc)?\b/i // IA32 (x86)
770
+ ], [[ARCHITECTURE, 'ia32']], [
771
+
772
+ /\b(aarch64|arm(v?[89]e?l?|_?64))\b/i // ARM64
773
+ ], [[ARCHITECTURE, 'arm64']], [
774
+
775
+ /\b(arm(v[67])?ht?n?[fl]p?)\b/i // ARMHF
776
+ ], [[ARCHITECTURE, 'armhf']], [
777
+
778
+ // PocketPC mistakenly identified as PowerPC
779
+ /( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
780
+ ], [[ARCHITECTURE, 'arm']], [
781
+
782
+ / sun4\w[;\)]/i // SPARC
783
+ ], [[ARCHITECTURE, 'sparc']], [
784
+ // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
785
+ /\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
786
+ /((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
787
+ /(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
788
+ ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
789
+ /mc680.0/i
790
+ ], [[ARCHITECTURE, '68k']], [
791
+ /winnt.+\[axp/i
792
+ ], [[ARCHITECTURE, 'alpha']]
793
+ ],
794
+
795
+ device : [[
796
+
797
+ //////////////////////////
798
+ // MOBILES & TABLETS
799
+ /////////////////////////
800
+
801
+ // Samsung
802
+ /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i
803
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
804
+ /\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
805
+ /samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,
806
+ /sec-(sgh\w+)/i
807
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
808
+
809
+ // Apple
810
+ /(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i // iPod/iPhone
811
+ ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
812
+ /\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i, // iPad
813
+ /\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i
814
+ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [
815
+ /(macintosh);/i
816
+ ], [MODEL, [VENDOR, APPLE]], [
817
+
818
+ // Sharp
819
+ /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
820
+ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
821
+
822
+ // Honor
823
+ /\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i
824
+ ], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [
825
+ /honor([-\w ]+)[;\)]/i
826
+ ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
827
+
828
+ // Huawei
829
+ /\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i
830
+ ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
831
+ /(?:huawei) ?([-\w ]+)[;\)]/i,
832
+ /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i
833
+ ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
834
+
835
+ // Xiaomi
836
+ /oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,
837
+ /\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i // Mi Pad tablets
838
+ ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
839
+
840
+ /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
841
+ /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
842
+ // Xiaomi Redmi / POCO / Black Shark / Qin
843
+ /oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,
844
+ // Xiaomi Mi
845
+ /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,
846
+ / ([\w ]+) miui\/v?\d/i
847
+ ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
848
+
849
+ // OnePlus
850
+ /droid.+; (cph2[3-6]\d[13579]|((gm|hd)19|(ac|be|in|kb)20|(d[en]|eb|le|mt)21|ne22)[0-2]\d|p[g-k]\w[1m]10)\b/i,
851
+ /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
852
+ ], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [
853
+
854
+ // OPPO
855
+ /; (\w+) bui.+ oppo/i,
856
+ /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
857
+ ], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [
858
+ /\b(opd2(\d{3}a?))(?: bui|\))/i
859
+ ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['203', '304', '403', '404', '413', '415'], '*' : OPPO }], [TYPE, TABLET]], [
860
+
861
+ // BLU
862
+ /(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i // Vivo series
863
+ ], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [
864
+
865
+ // Vivo
866
+ /; vivo (\w+)(?: bui|\))/i,
867
+ /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
868
+ ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
869
+
870
+ // Realme
871
+ /\b(rmx[1-3]\d{3})(?: bui|;|\))/i
872
+ ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
873
+
874
+ // Lenovo
875
+ /(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,
876
+ /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i
877
+ ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
878
+ /lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i
879
+ ], [MODEL, [VENDOR, LENOVO], [TYPE, MOBILE]], [
880
+
881
+ // Motorola
882
+ /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
883
+ /\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,
884
+ /((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i
885
+ ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [
886
+ /\b(mz60\d|xoom[2 ]{0,2}) build\//i
887
+ ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [
888
+
889
+ // LG
890
+ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
891
+ ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [
892
+ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
893
+ /\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,
894
+ /\blg-?([\d\w]+) bui/i
895
+ ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [
896
+
897
+ // Nokia
898
+ /(nokia) (t[12][01])/i
899
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
900
+ /(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,
901
+ /nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i
902
+ ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [
903
+
904
+ // Google
905
+ /(pixel (c|tablet))\b/i // Google Pixel C/Tablet
906
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [
907
+ // Google Pixel
908
+ /droid.+;(?: google)? (g(01[13]a|020[aem]|025[jn]|1b60|1f8f|2ybb|4s1m|576d|5nz6|8hhn|8vou|a02099|c15s|d1yq|e2ae|ec77|gh2x|kv4x|p4bc|pj41|r83y|tt9q|ur25|wvk6)|pixel[\d ]*a?( pro)?( xl)?( fold)?( \(5g\))?)( bui|\))/i
909
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
910
+ /(google) (pixelbook( go)?)/i
911
+ ], [VENDOR, MODEL], [
912
+
913
+ // Sony
914
+ /droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-\w\w\d\d)(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
915
+ ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
916
+ /sony tablet [ps]/i,
917
+ /\b(?:sony)?sgp\w+(?: bui|\))/i
918
+ ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [
919
+
920
+ // Amazon
921
+ /(alexa)webm/i,
922
+ /(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i, // Kindle Fire without Silk / Echo Show
923
+ /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
924
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
925
+ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
926
+ ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [
927
+
928
+ // BlackBerry
929
+ /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook
930
+ ], [MODEL, VENDOR, [TYPE, TABLET]], [
931
+ /\b((?:bb[a-f]|st[hv])100-\d)/i,
932
+ /(?:blackberry|\(bb10;) (\w+)/i
933
+ ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [
934
+
935
+ // Asus
936
+ /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
937
+ ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [
938
+ / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
939
+ ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [
940
+
941
+ // HTC
942
+ /(nexus 9)/i // HTC Nexus 9
943
+ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
944
+ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC
945
+
946
+ // ZTE
947
+ /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
948
+ /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
949
+ ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
950
+
951
+ // TCL
952
+ /tcl (xess p17aa)/i,
953
+ /droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i
954
+ ], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [
955
+ /droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i
956
+ ], [MODEL, [VENDOR, 'TCL'], [TYPE, MOBILE]], [
957
+
958
+ // itel
959
+ /(itel) ((\w+))/i
960
+ ], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [
961
+
962
+ // Acer
963
+ /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
964
+ ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
965
+
966
+ // Meizu
967
+ /droid.+; (m[1-5] note) bui/i,
968
+ /\bmz-([-\w]{2,})/i
969
+ ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
970
+
971
+ // Ulefone
972
+ /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
973
+ ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
974
+
975
+ // Energizer
976
+ /; (energy ?\w+)(?: bui|\))/i,
977
+ /; energizer ([\w ]+)(?: bui|\))/i
978
+ ], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
979
+
980
+ // Cat
981
+ /; cat (b35);/i,
982
+ /; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
983
+ ], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
984
+
985
+ // Smartfren
986
+ /((?:new )?andromax[\w- ]+)(?: bui|\))/i
987
+ ], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
988
+
989
+ // Nothing
990
+ /droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i
991
+ ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
992
+
993
+ // Archos
994
+ /; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,
995
+ /archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i
996
+ ], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [
997
+ /archos ([\w ]+)( b|\))/i,
998
+ /; (ac[3-6]\d\w{2,8})( b|\))/i
999
+ ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [
1000
+
1001
+ // HMD
1002
+ /; (n159v)/i
1003
+ ], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [
1004
+
1005
+ // MIXED
1006
+ /(imo) (tab \w+)/i, // IMO
1007
+ /(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i // Infinix XPad / Tecno
1008
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
1009
+
1010
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
1011
+ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
1012
+ // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
1013
+ /; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,
1014
+ /(hp) ([\w ]+\w)/i, // HP iPAQ
1015
+ /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
1016
+ /(oppo) ?([\w ]+) bui/i, // OPPO
1017
+ /(hisense) ([ehv][\w ]+)\)/i, // Hisense
1018
+ /droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i // Philips
1019
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1020
+
1021
+ /(kobo)\s(ereader|touch)/i, // Kobo
1022
+ /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
1023
+ /(kindle)\/([\w\.]+)/i // Kindle
1024
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
1025
+
1026
+ /(surface duo)/i // Surface Duo
1027
+ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [
1028
+ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone
1029
+ ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [
1030
+ /((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i // Nvidia Tablets
1031
+ ], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [
1032
+ /(sprint) (\w+)/i // Sprint Phones
1033
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
1034
+ /(kin\.[onetw]{3})/i // Microsoft Kin
1035
+ ], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [
1036
+ /droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra
1037
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [
1038
+ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
1039
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [
1040
+
1041
+ ///////////////////
1042
+ // SMARTTVS
1043
+ ///////////////////
1044
+
1045
+ /(philips)[\w ]+tv/i, // Philips
1046
+ /smart-tv.+(samsung)/i // Samsung
1047
+ ], [VENDOR, [TYPE, SMARTTV]], [
1048
+ /hbbtv.+maple;(\d+)/i
1049
+ ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [
1050
+ /(vizio)(?: |.+model\/)(\w+-\w+)/i, // Vizio
1051
+ /tcast.+(lg)e?. ([-\w]+)/i // LG SmartTV
1052
+ ], [VENDOR, MODEL, [TYPE, SMARTTV]], [
1053
+ /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
1054
+ ], [[VENDOR, LG], [TYPE, SMARTTV]], [
1055
+ /(apple) ?tv/i // Apple TV
1056
+ ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
1057
+ /crkey.*devicetype\/chromecast/i // Google Chromecast Third Generation
1058
+ ], [[MODEL, CHROMECAST+' Third Generation'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
1059
+ /crkey.*devicetype\/([^/]*)/i // Google Chromecast with specific device type
1060
+ ], [[MODEL, /^/, 'Chromecast '], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
1061
+ /fuchsia.*crkey/i // Google Chromecast Nest Hub
1062
+ ], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
1063
+ /crkey/i // Google Chromecast, Linux-based or unknown
1064
+ ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
1065
+ /(portaltv)/i // Facebook Portal TV
1066
+ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, SMARTTV]], [
1067
+ /droid.+aft(\w+)( bui|\))/i // Fire TV
1068
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
1069
+ /(shield \w+ tv)/i // Nvidia Shield TV
1070
+ ], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [
1071
+ /\(dtv[\);].+(aquos)/i,
1072
+ /(aquos-tv[\w ]+)\)/i // Sharp
1073
+ ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[
1074
+ /(bravia[\w ]+)( bui|\))/i // Sony
1075
+ ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [
1076
+ /(mi(tv|box)-?\w+) bui/i // Xiaomi
1077
+ ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [
1078
+ /Hbbtv.*(technisat) (.*);/i // TechniSAT
1079
+ ], [VENDOR, MODEL, [TYPE, SMARTTV]], [
1080
+ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
1081
+ /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
1082
+ ], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
1083
+
1084
+ ///////////////////
1085
+ // CONSOLES
1086
+ ///////////////////
1087
+
1088
+ /(playstation \w+)/i // Playstation
1089
+ ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [
1090
+ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox
1091
+ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [
1092
+ /(ouya)/i, // Ouya
1093
+ /(nintendo) (\w+)/i, // Nintendo
1094
+ /(retroid) (pocket ([^\)]+))/i, // Retroid Pocket
1095
+ /(valve).+(steam deck)/i,
1096
+ /droid.+; ((shield|rgcube|gr0006))( bui|\))/i // Nvidia Portable/Anbernic/Logitech
1097
+ ], [[VENDOR, strMapper, { 'Nvidia': 'Shield', 'Anbernic': 'RGCUBE', 'Logitech': 'GR0006' }], MODEL, [TYPE, CONSOLE]], [
1098
+
1099
+ ///////////////////
1100
+ // WEARABLES
1101
+ ///////////////////
1102
+
1103
+ /\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i // Samsung Galaxy Watch
1104
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [
1105
+ /((pebble))app/i, // Pebble
1106
+ /(asus|google|lg|oppo|xiaomi) ((pixel |zen)?watch[\w ]*)( bui|\))/i // Asus ZenWatch / LG Watch / Pixel Watch / Xiaomi Watch
1107
+ ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
1108
+ /(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch
1109
+ ], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [
1110
+ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
1111
+ ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
1112
+ /(opwwe\d{3})/i // OnePlus Watch
1113
+ ], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [
1114
+ /(moto 360)/i // Motorola 360
1115
+ ], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [
1116
+ /(smartwatch 3)/i // Sony SmartWatch
1117
+ ], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [
1118
+ /(g watch r)/i // LG G Watch R
1119
+ ], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [
1120
+ /droid.+; (wt63?0{2,3})\)/i
1121
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
1122
+
1123
+ ///////////////////
1124
+ // XR
1125
+ ///////////////////
1126
+
1127
+ /droid.+; (glass) \d/i // Google Glass
1128
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
1129
+ /(pico) ([\w ]+) os\d/i // Pico
1130
+ ], [VENDOR, MODEL, [TYPE, XR]], [
1131
+ /(quest( \d| pro)?s?).+vr/i // Meta Quest
1132
+ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
1133
+ /mobile vr; rv.+firefox/i // Unidentifiable VR device using Firefox Reality / Wolvic
1134
+ ], [[TYPE, XR]], [
1135
+
1136
+ ///////////////////
1137
+ // EMBEDDED
1138
+ ///////////////////
1139
+
1140
+ /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla
1141
+ ], [VENDOR, [TYPE, EMBEDDED]], [
1142
+ /(aeobc)\b/i // Echo Dot
1143
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [
1144
+ /(homepod).+mac os/i // Apple HomePod
1145
+ ], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [
1146
+ /windows iot/i // Unidentifiable embedded device using Windows IoT
1147
+ ], [[TYPE, EMBEDDED]], [
1148
+
1149
+ ////////////////////
1150
+ // MIXED (GENERIC)
1151
+ ///////////////////
1152
+
1153
+ /droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i // Unidentifiable SmartTV
1154
+ ], [MODEL, [TYPE, SMARTTV]], [
1155
+ /\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
1156
+ ], [[TYPE, SMARTTV]], [
1157
+ /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i
1158
+ ], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
1159
+ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
1160
+ ], [[TYPE, TABLET]], [
1161
+ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile
1162
+ ], [[TYPE, MOBILE]], [
1163
+ /droid .+?; ([\w\. -]+)( bui|\))/i // Generic Android Device
1164
+ ], [MODEL, [VENDOR, 'Generic']]
1165
+ ],
1166
+
1167
+ engine : [[
1168
+
1169
+ /windows.+ edge\/([\w\.]+)/i // EdgeHTML
1170
+ ], [VERSION, [NAME, EDGE+'HTML']], [
1171
+
1172
+ /(arkweb)\/([\w\.]+)/i // ArkWeb
1173
+ ], [NAME, VERSION], [
1174
+
1175
+ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
1176
+ ], [VERSION, [NAME, 'Blink']], [
1177
+
1178
+ /(presto)\/([\w\.]+)/i, // Presto
1179
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
1180
+ /ekioh(flow)\/([\w\.]+)/i, // Flow
1181
+ /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
1182
+ /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
1183
+
1184
+ /\b(libweb)/i // LibWeb
1185
+ ], [NAME, VERSION], [
1186
+ /ladybird\//i
1187
+ ], [[NAME, 'LibWeb']], [
1188
+
1189
+ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko
1190
+ ], [VERSION, NAME]
1191
+ ],
1192
+
1193
+ os : [[
1194
+
1195
+ // Windows
1196
+ /(windows nt) (6\.[23]); arm/i // Windows RT
1197
+ ], [[NAME, /N/, 'R'], [VERSION, strMapper, windowsVersionMap]], [
1198
+ /(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i, // Windows IoT/Mobile/Phone
1199
+ // Windows NT/3.1/95/98/ME/2000/XP/Vista/7/8/8.1/10/11
1200
+ /(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i
1201
+ ], [NAME, VERSION], [
1202
+ /windows nt ?([\d\.\)]*)(?!.+xbox)/i,
1203
+ /\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i
1204
+ ], [[VERSION, /(;|\))/g, '', strMapper, windowsVersionMap], [NAME, WINDOWS]], [
1205
+ /(windows ce)\/?([\d\.]*)/i // Windows CE
1206
+ ], [NAME, VERSION], [
1207
+
1208
+ // iOS/macOS
1209
+ /[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
1210
+ /(?:ios;fbsv|ios(?=.+ip(?:ad|hone)|.+apple ?tv)|ip(?:ad|hone)(?: |.+i(?:pad)?)os|apple ?tv.+ios)[\/ ]([\w\.]+)/i,
1211
+ /\btvos ?([\w\.]+)/i,
1212
+ /cfnetwork\/.+darwin/i
1213
+ ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
1214
+ /(mac os x) ?([\w\. ]*)/i,
1215
+ /(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i // Mac OS
1216
+ ], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
1217
+
1218
+ // Google Chromecast
1219
+ /android ([\d\.]+).*crkey/i // Google Chromecast, Android-based
1220
+ ], [VERSION, [NAME, CHROMECAST + ' Android']], [
1221
+ /fuchsia.*crkey\/([\d\.]+)/i // Google Chromecast, Fuchsia-based
1222
+ ], [VERSION, [NAME, CHROMECAST + ' Fuchsia']], [
1223
+ /crkey\/([\d\.]+).*devicetype\/smartspeaker/i // Google Chromecast, Linux-based Smart Speaker
1224
+ ], [VERSION, [NAME, CHROMECAST + ' SmartSpeaker']], [
1225
+ /linux.*crkey\/([\d\.]+)/i // Google Chromecast, Legacy Linux-based
1226
+ ], [VERSION, [NAME, CHROMECAST + ' Linux']], [
1227
+ /crkey\/([\d\.]+)/i // Google Chromecast, unknown
1228
+ ], [VERSION, [NAME, CHROMECAST]], [
1229
+
1230
+ // Mobile OSes
1231
+ /droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86
1232
+ ], [VERSION, NAME], [
1233
+ /(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch
1234
+ ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [
1235
+ /(harmonyos)[\/ ]?([\d\.]*)/i, // HarmonyOS
1236
+ // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen
1237
+ /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i
1238
+ ], [NAME, VERSION], [
1239
+ /\(bb(10);/i // BlackBerry 10
1240
+ ], [VERSION, [NAME, BLACKBERRY]], [
1241
+ /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i // Symbian
1242
+ ], [VERSION, [NAME, 'Symbian']], [
1243
+ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS
1244
+ ], [VERSION, [NAME, FIREFOX+' OS']], [
1245
+ /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i, // WebOS
1246
+ /webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i
1247
+ ], [VERSION, [NAME, 'webOS']], [
1248
+ /web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i
1249
+ // https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine
1250
+ ], [[VERSION, strMapper, {'25':'120','24':'108','23':'94','22':'87','6':'79','5':'68','4':'53','3':'38','2':'538','1':'537','*':'TV'}], [NAME, 'webOS']], [
1251
+ /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
1252
+ ], [VERSION, [NAME, 'watchOS']], [
1253
+
1254
+ // Google ChromeOS
1255
+ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
1256
+ ], [[NAME, "Chrome OS"], VERSION],[
1257
+
1258
+ // Smart TVs
1259
+ /panasonic;(viera)/i, // Panasonic Viera
1260
+ /(netrange)mmh/i, // Netrange
1261
+ /(nettv)\/(\d+\.[\w\.]+)/i, // NetTV
1262
+
1263
+ // Console
1264
+ /(nintendo|playstation) (\w+)/i, // Nintendo/Playstation
1265
+ /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
1266
+ /(pico) .+os([\w\.]+)/i, // Pico
1267
+
1268
+ // Other
1269
+ /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
1270
+ /linux.+(mint)[\/\(\) ]?([\w\.]*)/i, // Mint
1271
+ /(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i, // Mageia/VectorLinux/Fuchsia/ArcaOS/Arch
1272
+ /([kxln]?ubuntu|debian|suse|opensuse|gentoo|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire|knoppix)(?: gnu[\/ ]linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
1273
+ // Ubuntu/Debian/SUSE/Gentoo/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire/Knoppix
1274
+ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris
1275
+ /\b(aix)[; ]([1-9\.]{0,4})/i, // AIX
1276
+ /(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i, // Hurd/Linux/MorphOS
1277
+ /(gnu) ?([\w\.]*)/i, // GNU
1278
+ /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
1279
+ /(haiku) ?(r\d)?/i // Haiku
1280
+ ], [NAME, VERSION], [
1281
+ /(sunos) ?([\d\.]*)/i // Solaris
1282
+ ], [[NAME, 'Solaris'], VERSION], [
1283
+ /\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/OpenVMS/HP-UX/SerenityOS
1284
+ /(unix) ?([\w\.]*)/i // UNIX
1285
+ ], [NAME, VERSION]
1286
+ ]
1287
+ };
1288
+
1289
+ /////////////////
1290
+ // Factories
1291
+ ////////////////
1292
+
1293
+ var defaultProps = (function () {
1294
+ var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
1295
+ setProps.call(props.init, [
1296
+ [BROWSER, [NAME, VERSION, MAJOR, TYPE]],
1297
+ [CPU, [ARCHITECTURE]],
1298
+ [DEVICE, [TYPE, MODEL, VENDOR]],
1299
+ [ENGINE, [NAME, VERSION]],
1300
+ [OS, [NAME, VERSION]]
1301
+ ]);
1302
+ setProps.call(props.isIgnore, [
1303
+ [BROWSER, [VERSION, MAJOR]],
1304
+ [ENGINE, [VERSION]],
1305
+ [OS, [VERSION]]
1306
+ ]);
1307
+ setProps.call(props.isIgnoreRgx, [
1308
+ [BROWSER, / ?browser$/i],
1309
+ [OS, / ?os$/i]
1310
+ ]);
1311
+ setProps.call(props.toString, [
1312
+ [BROWSER, [NAME, VERSION]],
1313
+ [CPU, [ARCHITECTURE]],
1314
+ [DEVICE, [VENDOR, MODEL]],
1315
+ [ENGINE, [NAME, VERSION]],
1316
+ [OS, [NAME, VERSION]]
1317
+ ]);
1318
+ return props;
1319
+ })();
1320
+
1321
+ var createIData = function (item, itemType) {
1322
+
1323
+ var init_props = defaultProps.init[itemType],
1324
+ is_ignoreProps = defaultProps.isIgnore[itemType] || 0,
1325
+ is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0,
1326
+ toString_props = defaultProps.toString[itemType] || 0;
1327
+
1328
+ function IData () {
1329
+ setProps.call(this, init_props);
1330
+ }
1331
+
1332
+ IData.prototype.getItem = function () {
1333
+ return item;
1334
+ };
1335
+
1336
+ IData.prototype.withClientHints = function () {
1337
+
1338
+ // nodejs / non-client-hints browsers
1339
+ if (!NAVIGATOR_UADATA) {
1340
+ return item
1341
+ .parseCH()
1342
+ .get();
1343
+ }
1344
+
1345
+ // browsers based on chromium 85+
1346
+ return NAVIGATOR_UADATA
1347
+ .getHighEntropyValues(CH_ALL_VALUES)
1348
+ .then(function (res) {
1349
+ return item
1350
+ .setCH(new UACHData(res, false))
1351
+ .parseCH()
1352
+ .get();
1353
+ });
1354
+ };
1355
+
1356
+ IData.prototype.withFeatureCheck = function () {
1357
+ return item.detectFeature().get();
1358
+ };
1359
+
1360
+ if (itemType != RESULT) {
1361
+ IData.prototype.is = function (strToCheck) {
1362
+ var is = false;
1363
+ for (var i in this) {
1364
+ if (this.hasOwnProperty(i) && !has(is_ignoreProps, i) && lowerize(is_ignoreRgx ? strip(is_ignoreRgx, this[i]) : this[i]) == lowerize(is_ignoreRgx ? strip(is_ignoreRgx, strToCheck) : strToCheck)) {
1365
+ is = true;
1366
+ if (strToCheck != TYPEOF.UNDEFINED) break;
1367
+ } else if (strToCheck == TYPEOF.UNDEFINED && is) {
1368
+ is = !is;
1369
+ break;
1370
+ }
1371
+ }
1372
+ return is;
1373
+ };
1374
+ IData.prototype.toString = function () {
1375
+ var str = EMPTY;
1376
+ for (var i in toString_props) {
1377
+ if (typeof(this[toString_props[i]]) !== TYPEOF.UNDEFINED) {
1378
+ str += (str ? ' ' : EMPTY) + this[toString_props[i]];
1379
+ }
1380
+ }
1381
+ return str || TYPEOF.UNDEFINED;
1382
+ };
1383
+ }
1384
+
1385
+ IData.prototype.then = function (cb) {
1386
+ var that = this;
1387
+ var IDataResolve = function () {
1388
+ for (var prop in that) {
1389
+ if (that.hasOwnProperty(prop)) {
1390
+ this[prop] = that[prop];
1391
+ }
1392
+ }
1393
+ };
1394
+ IDataResolve.prototype = {
1395
+ is : IData.prototype.is,
1396
+ toString : IData.prototype.toString,
1397
+ withClientHints : IData.prototype.withClientHints,
1398
+ withFeatureCheck : IData.prototype.withFeatureCheck
1399
+ };
1400
+ var resolveData = new IDataResolve();
1401
+ cb(resolveData);
1402
+ return resolveData;
1403
+ };
1404
+
1405
+ return new IData();
1406
+ };
1407
+
1408
+ /////////////////
1409
+ // Constructor
1410
+ ////////////////
1411
+
1412
+ function UACHData (uach, isHttpUACH) {
1413
+ uach = uach || {};
1414
+ setProps.call(this, CH_ALL_VALUES);
1415
+ if (isHttpUACH) {
1416
+ setProps.call(this, [
1417
+ [BRANDS, itemListToArray(uach[CH])],
1418
+ [FULLVERLIST, itemListToArray(uach[CH_FULL_VER_LIST])],
1419
+ [MOBILE, /\?1/.test(uach[CH_MOBILE])],
1420
+ [MODEL, stripQuotes(uach[CH_MODEL])],
1421
+ [PLATFORM, stripQuotes(uach[CH_PLATFORM])],
1422
+ [PLATFORMVER, stripQuotes(uach[CH_PLATFORM_VER])],
1423
+ [ARCHITECTURE, stripQuotes(uach[CH_ARCH])],
1424
+ [FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],
1425
+ [BITNESS, stripQuotes(uach[CH_BITNESS])]
1426
+ ]);
1427
+ } else {
1428
+ for (var prop in uach) {
1429
+ if(this.hasOwnProperty(prop) && typeof uach[prop] !== TYPEOF.UNDEFINED) this[prop] = uach[prop];
1430
+ }
1431
+ }
1432
+ }
1433
+
1434
+ function UAItem (itemType, ua, rgxMap, uaCH) {
1435
+ setProps.call(this, [
1436
+ ['itemType', itemType],
1437
+ ['ua', ua],
1438
+ ['uaCH', uaCH],
1439
+ ['rgxMap', rgxMap],
1440
+ ['data', createIData(this, itemType)]
1441
+ ]);
1442
+ return this;
1443
+ }
1444
+
1445
+ UAItem.prototype.get = function (prop) {
1446
+ if (!prop) return this.data;
1447
+ return this.data.hasOwnProperty(prop) ? this.data[prop] : undefined;
1448
+ };
1449
+
1450
+ UAItem.prototype.set = function (prop, val) {
1451
+ this.data[prop] = val;
1452
+ return this;
1453
+ };
1454
+
1455
+ UAItem.prototype.setCH = function (ch) {
1456
+ this.uaCH = ch;
1457
+ return this;
1458
+ };
1459
+
1460
+ UAItem.prototype.detectFeature = function () {
1461
+ if (NAVIGATOR && NAVIGATOR.userAgent == this.ua) {
1462
+ switch (this.itemType) {
1463
+ case BROWSER:
1464
+ // Brave-specific detection
1465
+ if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == TYPEOF.FUNCTION) {
1466
+ this.set(NAME, 'Brave');
1467
+ }
1468
+ break;
1469
+ case DEVICE:
1470
+ // Chrome-specific detection: check for 'mobile' value of navigator.userAgentData
1471
+ if (!this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
1472
+ this.set(TYPE, MOBILE);
1473
+ }
1474
+ // iPadOS-specific detection: identified as Mac, but has some iOS-only properties
1475
+ if (this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== TYPEOF.UNDEFINED && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
1476
+ this.set(MODEL, 'iPad')
1477
+ .set(TYPE, TABLET);
1478
+ }
1479
+ break;
1480
+ case OS:
1481
+ // Chrome-specific detection: check for 'platform' value of navigator.userAgentData
1482
+ if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
1483
+ this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
1484
+ }
1485
+ break;
1486
+ case RESULT:
1487
+ var data = this.data;
1488
+ var detect = function (itemType) {
1489
+ return data[itemType]
1490
+ .getItem()
1491
+ .detectFeature()
1492
+ .get();
1493
+ };
1494
+ this.set(BROWSER, detect(BROWSER))
1495
+ .set(CPU, detect(CPU))
1496
+ .set(DEVICE, detect(DEVICE))
1497
+ .set(ENGINE, detect(ENGINE))
1498
+ .set(OS, detect(OS));
1499
+ }
1500
+ }
1501
+ return this;
1502
+ };
1503
+
1504
+ UAItem.prototype.parseUA = function () {
1505
+ if (this.itemType != RESULT) {
1506
+ rgxMapper.call(this.data, this.ua, this.rgxMap);
1507
+ }
1508
+ switch (this.itemType) {
1509
+ case BROWSER:
1510
+ this.set(MAJOR, majorize(this.get(VERSION)));
1511
+ break;
1512
+ case OS:
1513
+ if (this.get(NAME) == 'iOS' && this.get(VERSION) == '18.6') {
1514
+ // Based on the assumption that iOS version is tightly coupled with Safari version
1515
+ var realVersion = /\) Version\/([\d\.]+)/.exec(this.ua); // Get Safari version
1516
+ if (realVersion && parseInt(realVersion[1].substring(0,2), 10) >= 26) {
1517
+ this.set(VERSION, realVersion[1]); // Set as iOS version
1518
+ }
1519
+ }
1520
+ break;
1521
+ }
1522
+ return this;
1523
+ };
1524
+
1525
+ UAItem.prototype.parseCH = function () {
1526
+ var uaCH = this.uaCH,
1527
+ rgxMap = this.rgxMap;
1528
+
1529
+ switch (this.itemType) {
1530
+ case BROWSER:
1531
+ case ENGINE:
1532
+ var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
1533
+ if (brands) {
1534
+ for (var i=0; i<brands.length; i++) {
1535
+ var brandName = brands[i].brand || brands[i],
1536
+ brandVersion = brands[i].version;
1537
+ if (this.itemType == BROWSER &&
1538
+ !/not.a.brand/i.test(brandName) &&
1539
+ (!prevName ||
1540
+ (/Chrom/.test(prevName) && brandName != CHROMIUM) ||
1541
+ (prevName == EDGE && /WebView2/.test(brandName))
1542
+ )) {
1543
+ brandName = strMapper(brandName, browserHintsMap);
1544
+ prevName = this.get(NAME);
1545
+ if (!(prevName && !/Chrom/.test(prevName) && /Chrom/.test(brandName))) {
1546
+ this.set(NAME, brandName)
1547
+ .set(VERSION, brandVersion)
1548
+ .set(MAJOR, majorize(brandVersion));
1549
+ }
1550
+ prevName = brandName;
1551
+ }
1552
+ if (this.itemType == ENGINE && brandName == CHROMIUM) {
1553
+ this.set(VERSION, brandVersion);
1554
+ }
1555
+ }
1556
+ }
1557
+ break;
1558
+ case CPU:
1559
+ var archName = uaCH[ARCHITECTURE];
1560
+ if (archName) {
1561
+ if (archName && uaCH[BITNESS] == '64') archName += '64';
1562
+ rgxMapper.call(this.data, archName + ';', rgxMap);
1563
+ }
1564
+ break;
1565
+ case DEVICE:
1566
+ if (uaCH[MOBILE]) {
1567
+ this.set(TYPE, MOBILE);
1568
+ }
1569
+ if (uaCH[MODEL]) {
1570
+ this.set(MODEL, uaCH[MODEL]);
1571
+ if (!this.get(TYPE) || !this.get(VENDOR)) {
1572
+ var reParse = {};
1573
+ rgxMapper.call(reParse, 'droid 9; ' + uaCH[MODEL] + ')', rgxMap);
1574
+ if (!this.get(TYPE) && !!reParse.type) {
1575
+ this.set(TYPE, reParse.type);
1576
+ }
1577
+ if (!this.get(VENDOR) && !!reParse.vendor) {
1578
+ this.set(VENDOR, reParse.vendor);
1579
+ }
1580
+ }
1581
+ }
1582
+ if (uaCH[FORMFACTORS]) {
1583
+ var ff;
1584
+ if (typeof uaCH[FORMFACTORS] !== 'string') {
1585
+ var idx = 0;
1586
+ while (!ff && idx < uaCH[FORMFACTORS].length) {
1587
+ ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
1588
+ }
1589
+ } else {
1590
+ ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
1591
+ }
1592
+ this.set(TYPE, ff);
1593
+ }
1594
+ break;
1595
+ case OS:
1596
+ var osName = uaCH[PLATFORM];
1597
+ if(osName) {
1598
+ var osVersion = uaCH[PLATFORMVER];
1599
+ if (osName == WINDOWS) osVersion = (parseInt(majorize(osVersion), 10) >= 13 ? '11' : '10');
1600
+ this.set(NAME, osName)
1601
+ .set(VERSION, osVersion);
1602
+ }
1603
+ // Xbox-Specific Detection
1604
+ if (this.get(NAME) == WINDOWS && uaCH[MODEL] == 'Xbox') {
1605
+ this.set(NAME, 'Xbox')
1606
+ .set(VERSION, undefined);
1607
+ }
1608
+ break;
1609
+ case RESULT:
1610
+ var data = this.data;
1611
+ var parse = function (itemType) {
1612
+ return data[itemType]
1613
+ .getItem()
1614
+ .setCH(uaCH)
1615
+ .parseCH()
1616
+ .get();
1617
+ };
1618
+ this.set(BROWSER, parse(BROWSER))
1619
+ .set(CPU, parse(CPU))
1620
+ .set(DEVICE, parse(DEVICE))
1621
+ .set(ENGINE, parse(ENGINE))
1622
+ .set(OS, parse(OS));
1623
+ }
1624
+ return this;
1625
+ };
1626
+
1627
+ function UAParser (ua, extensions, headers) {
1628
+
1629
+ if (typeof ua === TYPEOF.OBJECT) {
1630
+ if (isExtensions(ua, true)) {
1631
+ if (typeof extensions === TYPEOF.OBJECT) {
1632
+ headers = extensions; // case UAParser(extensions, headers)
1633
+ }
1634
+ extensions = ua; // case UAParser(extensions)
1635
+ } else {
1636
+ headers = ua; // case UAParser(headers)
1637
+ extensions = undefined;
1638
+ }
1639
+ ua = undefined;
1640
+ } else if (typeof ua === TYPEOF.STRING && !isExtensions(extensions, true)) {
1641
+ headers = extensions; // case UAParser(ua, headers)
1642
+ extensions = undefined;
1643
+ }
1644
+
1645
+ if (headers) {
1646
+ if (typeof headers.append === TYPEOF.FUNCTION) {
1647
+ // Convert Headers object into a plain object
1648
+ var kv = {};
1649
+ headers.forEach(function (v, k) { kv[String(k).toLowerCase()] = v; });
1650
+ headers = kv;
1651
+ } else {
1652
+ // Normalize headers field name into lowercase
1653
+ var normalized = {};
1654
+ for (var header in headers) {
1655
+ if (headers.hasOwnProperty(header)) {
1656
+ normalized[String(header).toLowerCase()] = headers[header];
1657
+ }
1658
+ }
1659
+ headers = normalized;
1660
+ }
1661
+ }
1662
+
1663
+ if (!(this instanceof UAParser)) {
1664
+ return new UAParser(ua, extensions, headers).getResult();
1665
+ }
1666
+
1667
+ var userAgent = typeof ua === TYPEOF.STRING ? ua : // Passed user-agent string
1668
+ (headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
1669
+ ((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
1670
+ EMPTY)), // empty string
1671
+
1672
+ httpUACH = new UACHData(headers, true),
1673
+ regexMap = extensions ?
1674
+ extend(defaultRegexes, extensions) :
1675
+ defaultRegexes,
1676
+
1677
+ createItemFunc = function (itemType) {
1678
+ if (itemType == RESULT) {
1679
+ return function () {
1680
+ return new UAItem(itemType, userAgent, regexMap, httpUACH)
1681
+ .set('ua', userAgent)
1682
+ .set(BROWSER, this.getBrowser())
1683
+ .set(CPU, this.getCPU())
1684
+ .set(DEVICE, this.getDevice())
1685
+ .set(ENGINE, this.getEngine())
1686
+ .set(OS, this.getOS())
1687
+ .get();
1688
+ };
1689
+ } else {
1690
+ return function () {
1691
+ return new UAItem(itemType, userAgent, regexMap[itemType], httpUACH)
1692
+ .parseUA()
1693
+ .get();
1694
+ };
1695
+ }
1696
+ };
1697
+
1698
+ // public methods
1699
+ setProps.call(this, [
1700
+ ['getBrowser', createItemFunc(BROWSER)],
1701
+ ['getCPU', createItemFunc(CPU)],
1702
+ ['getDevice', createItemFunc(DEVICE)],
1703
+ ['getEngine', createItemFunc(ENGINE)],
1704
+ ['getOS', createItemFunc(OS)],
1705
+ ['getResult', createItemFunc(RESULT)],
1706
+ ['getUA', function () { return userAgent; }],
1707
+ ['setUA', function (ua) {
1708
+ if (isString(ua)) userAgent = trim(ua, UA_MAX_LENGTH);
1709
+ return this;
1710
+ }]
1711
+ ])
1712
+ .setUA(userAgent);
1713
+
1714
+ return this;
1715
+ }
1716
+
1717
+ UAParser.VERSION = LIBVERSION;
1718
+ UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
1719
+ UAParser.CPU = enumerize([ARCHITECTURE]);
1720
+ UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1721
+ UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
1722
+
1723
+ var __defProp = Object.defineProperty;
1724
+ var __typeError = (msg) => {
1725
+ throw TypeError(msg);
1726
+ };
1727
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1728
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1729
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
1730
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1731
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1732
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
1733
+ var _instance;
1734
+ const _Sentry = class _Sentry {
1735
+ constructor() {
1736
+ __publicField(this, "codeErrors", /* @__PURE__ */ new Set());
1737
+ __publicField(this, "whiteScreenTimer", null);
1738
+ __publicField(this, "options", constants.DEFAULT_OPTIONS);
1739
+ __publicField(this, "deviceInfo");
1740
+ __publicField(this, "shouldRecordScreen", false);
1741
+ const res = new UAParser().getResult();
1742
+ this.deviceInfo = {
1743
+ browserName: res.browser.name ?? constants.UNKNOWN,
1744
+ browserVersion: res.browser.version ?? constants.UNKNOWN,
1745
+ osName: res.os.name ?? constants.UNKNOWN,
1746
+ osVersion: res.os.version ?? constants.UNKNOWN,
1747
+ userAgent: res.ua,
1748
+ deviceModel: res.device.model ?? constants.UNKNOWN,
1749
+ deviceType: res.device.type ?? constants.UNKNOWN
1750
+ };
1751
+ }
1752
+ static get instance() {
1753
+ if (!__privateGet(this, _instance)) {
1754
+ __privateSet(this, _instance, new _Sentry());
1755
+ globalThis.__sentry__ = __privateGet(this, _instance);
1756
+ }
1757
+ return __privateGet(this, _instance);
1758
+ }
1759
+ setOptions(newOptions) {
1760
+ __privateGet(_Sentry, _instance).options = {
1761
+ ...this.options,
1762
+ ...newOptions
1763
+ };
1764
+ }
1765
+ };
1766
+ _instance = new WeakMap();
1767
+ __privateAdd(_Sentry, _instance);
1768
+ let Sentry = _Sentry;
1769
+ var sentry = Sentry.instance;
1770
+
1771
+ function isExcludedApi(api) {
1772
+ for (const excludedApi of sentry.options.excludeApis) {
1773
+ if (typeof excludedApi === "string") {
1774
+ if (api === excludedApi) {
1775
+ return true;
1776
+ }
1777
+ } else {
1778
+ if (excludedApi.test(api)) {
1779
+ return true;
1780
+ }
1781
+ }
1782
+ }
1783
+ return false;
1784
+ }
1785
+
1786
+ function isHTMLElement(node) {
1787
+ return node.nodeType === Node.ELEMENT_NODE;
1788
+ }
1789
+ function isError(err) {
1790
+ return err instanceof Error;
1791
+ }
1792
+ function isErrorEvent(err) {
1793
+ return err instanceof ErrorEvent;
1794
+ }
1795
+ function isIExtendedErrorEvent(err) {
1796
+ return err instanceof ErrorEvent && err.target !== null && "src" in err.target && typeof err.target.src === "string" && "href" in err.target && typeof err.target.href === "string" && "localName" in err.target && typeof err.target.localName === "string";
1797
+ }
1798
+
1799
+ function metric2perfData(metric) {
1800
+ const { id, name, value, rating } = metric;
1801
+ return {
1802
+ id,
1803
+ name,
1804
+ value,
1805
+ rating,
1806
+ message: "",
1807
+ ...getTime(),
1808
+ type: types.EventType.Performance,
1809
+ status: types.Status.OK
1810
+ };
1811
+ }
1812
+
1813
+ function throttle(fn, delay = 300) {
1814
+ let latestTimestamp = 0;
1815
+ return function(...args) {
1816
+ const now = Date.now();
1817
+ if (now - latestTimestamp > delay) {
1818
+ latestTimestamp = Date.now();
1819
+ fn.apply(this, args);
1820
+ return;
1821
+ }
1822
+ };
1823
+ }
1824
+ function throttleV2(fn, delay = 300) {
1825
+ let timer = null;
1826
+ return function(...args) {
1827
+ if (timer) {
1828
+ return;
1829
+ }
1830
+ timer = setTimeout(() => {
1831
+ fn.apply(this, args);
1832
+ timer = null;
1833
+ }, delay);
1834
+ };
1835
+ }
1836
+
1837
+ function transformHttpData(data) {
1838
+ const { statusCode } = data;
1839
+ if (statusCode >= 100 && statusCode < 200) {
1840
+ data.message = "Informational response";
1841
+ } else if (statusCode >= 200 && statusCode < 300) {
1842
+ data.message = "Successful responses";
1843
+ } else if (statusCode >= 300 && statusCode < 400) {
1844
+ data.message = "Redirection messages";
1845
+ } else if (statusCode >= 400 && statusCode < 500) {
1846
+ data.message = "Client error responses";
1847
+ } else if (statusCode >= 500 && statusCode < 600) {
1848
+ data.message = "Server error responses";
1849
+ } else {
1850
+ data.message = "Invalid status code";
1851
+ }
1852
+ return data;
1853
+ }
1854
+
1855
+ exports.CallbackQueue = CallbackQueue;
1856
+ exports.MinHeap = MinHeap;
1857
+ exports.base64 = base64;
1858
+ exports.base64v2 = base64v2;
1859
+ exports.debounce = debounce;
1860
+ exports.decorateProp = decorateProp;
1861
+ exports.dom2str = dom2str;
1862
+ exports.event2breadcrumb = event2breadcrumb;
1863
+ exports.getCssSelectors = getCssSelectors;
1864
+ exports.getTime = getTime;
1865
+ exports.isError = isError;
1866
+ exports.isErrorEvent = isErrorEvent;
1867
+ exports.isExcludedApi = isExcludedApi;
1868
+ exports.isHTMLElement = isHTMLElement;
1869
+ exports.isIExtendedErrorEvent = isIExtendedErrorEvent;
1870
+ exports.metric2perfData = metric2perfData;
1871
+ exports.sentry = sentry;
1872
+ exports.throttle = throttle;
1873
+ exports.throttleV2 = throttleV2;
1874
+ exports.transformHttpData = transformHttpData;
1875
+ //# sourceMappingURL=index.cjs.map