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