ua-parser-js 1.0.35 → 2.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1126 @@
1
+ // Generated ESM version of UAParser.js
2
+ // DO NOT EDIT THIS FILE!
3
+ // Source: /src/ua-parser.js
4
+
5
+ const window = undefined;
6
+
7
+ /////////////////////////////////////////////////////////////////////////////////
8
+ /* UAParser.js v2.0.0-alpha.2
9
+ Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
10
+ MIT License *//*
11
+ Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
12
+ Supports browser & node.js environment.
13
+ Demo : https://faisalman.github.io/ua-parser-js
14
+ Source : https://github.com/faisalman/ua-parser-js */
15
+ /////////////////////////////////////////////////////////////////////////////////
16
+
17
+
18
+
19
+ //////////////
20
+ // Constants
21
+ /////////////
22
+
23
+
24
+ var LIBVERSION = '2.0.0-alpha.2',
25
+ EMPTY = '',
26
+ UNKNOWN = '?',
27
+ FUNC_TYPE = 'function',
28
+ UNDEF_TYPE = 'undefined',
29
+ OBJ_TYPE = 'object',
30
+ STR_TYPE = 'string',
31
+ MAJOR = 'major',
32
+ MODEL = 'model',
33
+ NAME = 'name',
34
+ TYPE = 'type',
35
+ VENDOR = 'vendor',
36
+ VERSION = 'version',
37
+ ARCHITECTURE= 'architecture',
38
+ CONSOLE = 'console',
39
+ MOBILE = 'mobile',
40
+ TABLET = 'tablet',
41
+ SMARTTV = 'smarttv',
42
+ WEARABLE = 'wearable',
43
+ EMBEDDED = 'embedded',
44
+ USER_AGENT = 'user-agent',
45
+ UA_MAX_LENGTH = 350,
46
+ BRANDS = 'brands',
47
+ FULLVERLIST = 'fullVersionList',
48
+ PLATFORM = 'platform',
49
+ PLATFORMVER = 'platformVersion',
50
+ BITNESS = 'bitness',
51
+ CH_HEADER = 'sec-ch-ua',
52
+ CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
53
+ CH_HEADER_ARCH = CH_HEADER + '-arch',
54
+ CH_HEADER_BITNESS = CH_HEADER + '-bitness',
55
+ CH_HEADER_MOBILE = CH_HEADER + '-mobile',
56
+ CH_HEADER_MODEL = CH_HEADER + '-model',
57
+ CH_HEADER_PLATFORM = CH_HEADER + '-platform',
58
+ CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
59
+ CH_ALL_VALUES = ['brands', 'fullVersionList', MOBILE, MODEL, 'platform', 'platformVersion', ARCHITECTURE, 'bitness'],
60
+ UA_BROWSER = 'browser',
61
+ UA_CPU = 'cpu',
62
+ UA_DEVICE = 'device',
63
+ UA_ENGINE = 'engine',
64
+ UA_OS = 'os',
65
+ UA_RESULT = 'result',
66
+ AMAZON = 'Amazon',
67
+ APPLE = 'Apple',
68
+ ASUS = 'ASUS',
69
+ BLACKBERRY = 'BlackBerry',
70
+ GOOGLE = 'Google',
71
+ HUAWEI = 'Huawei',
72
+ LG = 'LG',
73
+ MICROSOFT = 'Microsoft',
74
+ MOTOROLA = 'Motorola',
75
+ SAMSUNG = 'Samsung',
76
+ SHARP = 'Sharp',
77
+ SONY = 'Sony',
78
+ XIAOMI = 'Xiaomi',
79
+ ZEBRA = 'Zebra',
80
+ PREFIX_MOBILE = 'Mobile ',
81
+ SUFFIX_BROWSER = ' Browser',
82
+ CHROME = 'Chrome',
83
+ EDGE = 'Edge',
84
+ FIREFOX = 'Firefox',
85
+ OPERA = 'Opera',
86
+ FACEBOOK = 'Facebook',
87
+ WINDOWS = 'Windows';
88
+
89
+ var NAVIGATOR = (typeof window !== UNDEF_TYPE && window.navigator) ?
90
+ window.navigator :
91
+ undefined,
92
+ NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
93
+ NAVIGATOR.userAgentData :
94
+ undefined;
95
+
96
+ ///////////
97
+ // Helper
98
+ //////////
99
+
100
+ var assignFromEntries = function (arr) {
101
+ for (var i in arr) {
102
+ var propName = arr[i];
103
+ if (typeof propName == OBJ_TYPE && propName.length == 2) {
104
+ this[propName[0]] = propName[1];
105
+ } else {
106
+ this[propName] = undefined;
107
+ }
108
+ }
109
+ return this;
110
+ },
111
+ extend = function (regexes, extensions) {
112
+ var mergedRegexes = {};
113
+ for (var i in regexes) {
114
+ mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i];
115
+ }
116
+ return mergedRegexes;
117
+ },
118
+ enumerize = function (arr) {
119
+ var enums = {};
120
+ for (var i=0; i<arr.length; i++) {
121
+ enums[arr[i].toUpperCase()] = arr[i];
122
+ }
123
+ return enums;
124
+ },
125
+ has = function (str1, str2) {
126
+ if (typeof str1 === OBJ_TYPE && str1.length > 0) {
127
+ for (var i in str1) {
128
+ if (lowerize(str1[i]) == lowerize(str2)) return true;
129
+ }
130
+ return false;
131
+ }
132
+ return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
133
+ },
134
+ isExtensions = function (obj) {
135
+ for (var prop in obj) {
136
+ return /^(browser|cpu|device|engine|os)$/.test(prop);
137
+ }
138
+ },
139
+ itemListToArray = function (header) {
140
+ if (!header) return undefined;
141
+ var arr = [];
142
+ var tokens = strip(/\\?\"/g, header).split(', ');
143
+ for (var i = 0; i < tokens.length; i++) {
144
+ var token = tokens[i].split(';v=');
145
+ arr[i] = { brand : token[0], version : token[1] };
146
+ }
147
+ return arr;
148
+ },
149
+ lowerize = function (str) {
150
+ return typeof(str) === STR_TYPE ? str.toLowerCase() : str;
151
+ },
152
+ majorize = function (version) {
153
+ return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
154
+ },
155
+ strip = function (pattern, str) {
156
+ return str.replace(pattern, EMPTY);
157
+ },
158
+ stripQuotes = function (val) {
159
+ return typeof val === STR_TYPE ? strip(/\"/g, val) : val;
160
+ },
161
+ trim = function (str, len) {
162
+ if (typeof(str) === STR_TYPE) {
163
+ str = strip(/^\s\s*/, str);
164
+ return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
165
+ }
166
+ };
167
+
168
+ ///////////////
169
+ // Map helper
170
+ //////////////
171
+
172
+ var rgxMapper = function (ua, arrays) {
173
+
174
+ if(!ua || !arrays) return;
175
+
176
+ var i = 0, j, k, p, q, matches, match;
177
+
178
+ // loop through all regexes maps
179
+ while (i < arrays.length && !matches) {
180
+
181
+ var regex = arrays[i], // even sequence (0,2,4,..)
182
+ props = arrays[i + 1]; // odd sequence (1,3,5,..)
183
+ j = k = 0;
184
+
185
+ // try matching uastring with regexes
186
+ while (j < regex.length && !matches) {
187
+
188
+ if (!regex[j]) { break; }
189
+ matches = regex[j++].exec(ua);
190
+
191
+ if (!!matches) {
192
+ for (p = 0; p < props.length; p++) {
193
+ match = matches[++k];
194
+ q = props[p];
195
+ // check if given property is actually array
196
+ if (typeof q === OBJ_TYPE && q.length > 0) {
197
+ if (q.length === 2) {
198
+ if (typeof q[1] == FUNC_TYPE) {
199
+ // assign modified match
200
+ this[q[0]] = q[1].call(this, match);
201
+ } else {
202
+ // assign given value, ignore regex match
203
+ this[q[0]] = q[1];
204
+ }
205
+ } else if (q.length === 3) {
206
+ // check whether function or regex
207
+ if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {
208
+ // call function (usually string mapper)
209
+ this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
210
+ } else {
211
+ // sanitize match using given regex
212
+ this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
213
+ }
214
+ } else if (q.length === 4) {
215
+ this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
216
+ }
217
+ } else {
218
+ this[q] = match ? match : undefined;
219
+ }
220
+ }
221
+ }
222
+ }
223
+ i += 2;
224
+ }
225
+ },
226
+
227
+ strMapper = function (str, map) {
228
+
229
+ for (var i in map) {
230
+ // check if current value is array
231
+ if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {
232
+ for (var j = 0; j < map[i].length; j++) {
233
+ if (has(map[i][j], str)) {
234
+ return (i === UNKNOWN) ? undefined : i;
235
+ }
236
+ }
237
+ } else if (has(map[i], str)) {
238
+ return (i === UNKNOWN) ? undefined : i;
239
+ }
240
+ }
241
+ return str;
242
+ };
243
+
244
+ ///////////////
245
+ // String map
246
+ //////////////
247
+
248
+ // Safari < 3.0
249
+ var oldSafariMap = {
250
+ '1.0' : '/8',
251
+ '1.2' : '/1',
252
+ '1.3' : '/3',
253
+ '2.0' : '/412',
254
+ '2.0.2' : '/416',
255
+ '2.0.3' : '/417',
256
+ '2.0.4' : '/419',
257
+ '?' : '/'
258
+ },
259
+ windowsVersionMap = {
260
+ 'ME' : '4.90',
261
+ 'NT 3.11' : 'NT3.51',
262
+ 'NT 4.0' : 'NT4.0',
263
+ '2000' : 'NT 5.0',
264
+ 'XP' : ['NT 5.1', 'NT 5.2'],
265
+ 'Vista' : 'NT 6.0',
266
+ '7' : 'NT 6.1',
267
+ '8' : 'NT 6.2',
268
+ '8.1' : 'NT 6.3',
269
+ '10' : ['NT 6.4', 'NT 10.0'],
270
+ 'RT' : 'ARM'
271
+ };
272
+
273
+ //////////////
274
+ // Regex map
275
+ /////////////
276
+
277
+ var defaultRegexes = {
278
+
279
+ browser : [[
280
+
281
+ // Most common regardless engine
282
+ /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
283
+ ], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
284
+ /edg(?:e|ios|a)?\/([\w\.]+)/i // Microsoft Edge
285
+ ], [VERSION, [NAME, 'Edge']], [
286
+
287
+ // Presto based
288
+ /(opera mini)\/([-\w\.]+)/i, // Opera Mini
289
+ /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, // Opera Mobi/Tablet
290
+ /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i // Opera
291
+ ], [NAME, VERSION], [
292
+ /opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
293
+ ], [VERSION, [NAME, OPERA+' Mini']], [
294
+ /\bopr\/([\w\.]+)/i // Opera Webkit
295
+ ], [VERSION, [NAME, OPERA]], [
296
+
297
+ // Mixed
298
+ /(kindle)\/([\w\.]+)/i, // Kindle
299
+ /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
300
+ // Trident based
301
+ /(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
302
+ /(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser
303
+ /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
304
+
305
+ // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
306
+ /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
307
+ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
308
+ /(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
309
+ /(weibo)__([\d\.]+)/i // Weibo
310
+ ], [NAME, VERSION], [
311
+ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
312
+ ], [VERSION, [NAME, 'UCBrowser']], [
313
+ /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
314
+ /\bqbcore\/([\w\.]+).+microm/i
315
+ ], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
316
+ /micromessenger\/([\w\.]+)/i // WeChat
317
+ ], [VERSION, [NAME, 'WeChat']], [
318
+ /konqueror\/([\w\.]+)/i // Konqueror
319
+ ], [VERSION, [NAME, 'Konqueror']], [
320
+ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i // IE11
321
+ ], [VERSION, [NAME, 'IE']], [
322
+ /ya(?:search)?browser\/([\w\.]+)/i // Yandex
323
+ ], [VERSION, [NAME, 'Yandex']], [
324
+ /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
325
+ ], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
326
+ /\bfocus\/([\w\.]+)/i // Firefox Focus
327
+ ], [VERSION, [NAME, FIREFOX+' Focus']], [
328
+ /\bopt\/([\w\.]+)/i // Opera Touch
329
+ ], [VERSION, [NAME, OPERA+' Touch']], [
330
+ /coc_coc\w+\/([\w\.]+)/i // Coc Coc Browser
331
+ ], [VERSION, [NAME, 'Coc Coc']], [
332
+ /dolfin\/([\w\.]+)/i // Dolphin
333
+ ], [VERSION, [NAME, 'Dolphin']], [
334
+ /coast\/([\w\.]+)/i // Opera Coast
335
+ ], [VERSION, [NAME, OPERA+' Coast']], [
336
+ /miuibrowser\/([\w\.]+)/i // MIUI Browser
337
+ ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
338
+ /fxios\/([\w\.-]+)/i // Firefox for iOS
339
+ ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
340
+ /\bqihu|(qi?ho?o?|360)browser/i // 360
341
+ ], [[NAME, '360' + SUFFIX_BROWSER]], [
342
+ /(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i
343
+ ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser
344
+ /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
345
+ ], [[NAME, /_/g, ' '], VERSION], [
346
+ /(electron)\/([\w\.]+) safari/i, // Electron-based App
347
+ /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
348
+ /m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser
349
+ ], [NAME, VERSION], [
350
+ /(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser
351
+ /(lbbrowser)/i, // LieBao Browser
352
+ /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
353
+ ], [NAME], [
354
+
355
+ // WebView
356
+ /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
357
+ ], [[NAME, FACEBOOK], VERSION], [
358
+ /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
359
+ /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
360
+ /safari (line)\/([\w\.]+)/i, // Line App for iOS
361
+ /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
362
+ /(chromium|instagram)[\/ ]([-\w\.]+)/i // Chromium/Instagram
363
+ ], [NAME, VERSION], [
364
+ /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
365
+ ], [VERSION, [NAME, 'GSA']], [
366
+ /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
367
+ ], [VERSION, [NAME, 'TikTok']], [
368
+
369
+ /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
370
+ ], [VERSION, [NAME, CHROME+' Headless']], [
371
+
372
+ / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
373
+ ], [[NAME, CHROME+' WebView'], VERSION], [
374
+
375
+ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
376
+ ], [VERSION, [NAME, 'Android' + SUFFIX_BROWSER]], [
377
+
378
+ /chrome\/([\w\.]+) mobile/i // Chrome Mobile
379
+ ], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
380
+
381
+ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia
382
+ ], [NAME, VERSION], [
383
+
384
+ /version\/([\w\.\,]+) .*mobile(?:\/\w+ | ?)safari/i // Safari Mobile
385
+ ], [VERSION, [NAME, PREFIX_MOBILE + 'Safari']], [
386
+ /iphone .*mobile(?:\/\w+ | ?)safari/i
387
+ ], [[NAME, PREFIX_MOBILE + 'Safari']], [
388
+ /version\/([\w\.\,]+) .*(safari)/i // Safari
389
+ ], [VERSION, NAME], [
390
+ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
391
+ ], [NAME, [VERSION, strMapper, oldSafariMap]], [
392
+
393
+ /(webkit|khtml)\/([\w\.]+)/i
394
+ ], [NAME, VERSION], [
395
+
396
+ // Gecko based
397
+ /(?:mobile|tablet);.*(firefox)\/([\w\.-]+)/i // Firefox Mobile
398
+ ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
399
+ /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
400
+ ], [[NAME, 'Netscape'], VERSION], [
401
+ /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
402
+ ], [VERSION, [NAME, FIREFOX+' Reality']], [
403
+ /ekiohf.+(flow)\/([\w\.]+)/i, // Flow
404
+ /(swiftfox)/i, // Swiftfox
405
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
406
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
407
+ /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
408
+ // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
409
+ /(firefox)\/([\w\.]+)/i, // Other Firefox-based
410
+ /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
411
+
412
+ // Other
413
+ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
414
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
415
+ /(links) \(([\w\.]+)/i, // Links
416
+ /panasonic;(viera)/i // Panasonic Viera
417
+ ], [NAME, VERSION], [
418
+
419
+ /(cobalt)\/([\w\.]+)/i // Cobalt
420
+ ], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
421
+ ],
422
+
423
+ cpu : [[
424
+
425
+ /\b(?:(amd|x|x86[-_]?|wow|win)64)\b/i // AMD64 (x64)
426
+ ], [[ARCHITECTURE, 'amd64']], [
427
+
428
+ /(ia32(?=;))/i, // IA32 (quicktime)
429
+ /((?:i[346]|x)86)[;\)]/i // IA32 (x86)
430
+ ], [[ARCHITECTURE, 'ia32']], [
431
+
432
+ /\b(aarch64|arm(v?8e?l?|_?64))\b/i // ARM64
433
+ ], [[ARCHITECTURE, 'arm64']], [
434
+
435
+ /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i // ARMHF
436
+ ], [[ARCHITECTURE, 'armhf']], [
437
+
438
+ // PocketPC mistakenly identified as PowerPC
439
+ /windows (ce|mobile); ppc;/i
440
+ ], [[ARCHITECTURE, 'arm']], [
441
+
442
+ /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i // PowerPC
443
+ ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
444
+
445
+ /(sun4\w)[;\)]/i // SPARC
446
+ ], [[ARCHITECTURE, 'sparc']], [
447
+
448
+ /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i
449
+ // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
450
+ ], [[ARCHITECTURE, lowerize]]
451
+ ],
452
+
453
+ device : [[
454
+
455
+ //////////////////////////
456
+ // MOBILES & TABLETS
457
+ /////////////////////////
458
+
459
+ // Samsung
460
+ /\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
461
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
462
+ /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
463
+ /samsung[- ]([-\w]+)/i,
464
+ /sec-(sgh\w+)/i
465
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
466
+
467
+ // Apple
468
+ /(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i // iPod/iPhone
469
+ ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
470
+ /\((ipad);[-\w\),; ]+apple/i, // iPad
471
+ /applecoremedia\/[\w\.]+ \((ipad)/i,
472
+ /\b(ipad)\d\d?,\d\d?[;\]].+ios/i
473
+ ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [
474
+ /(macintosh);/i
475
+ ], [MODEL, [VENDOR, APPLE]], [
476
+
477
+ // Sharp
478
+ /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
479
+ ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
480
+
481
+ // Huawei
482
+ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
483
+ ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
484
+ /(?:huawei|honor)([-\w ]+)[;\)]/i,
485
+ /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
486
+ ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
487
+
488
+ // Xiaomi
489
+ /\b(poco[\w ]+)(?: bui|\))/i, // Xiaomi POCO
490
+ /\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
491
+ /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
492
+ /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
493
+ /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
494
+ ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
495
+ /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
496
+ ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
497
+
498
+ // OPPO
499
+ /; (\w+) bui.+ oppo/i,
500
+ /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
501
+ ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
502
+
503
+ // Vivo
504
+ /vivo (\w+)(?: bui|\))/i,
505
+ /\b(v[12]\d{3}\w?[at])(?: bui|;)/i
506
+ ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [
507
+
508
+ // Realme
509
+ /\b(rmx[12]\d{3})(?: bui|;|\))/i
510
+ ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
511
+
512
+ // Motorola
513
+ /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
514
+ /\bmot(?:orola)?[- ](\w*)/i,
515
+ /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i
516
+ ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [
517
+ /\b(mz60\d|xoom[2 ]{0,2}) build\//i
518
+ ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [
519
+
520
+ // LG
521
+ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
522
+ ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [
523
+ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
524
+ /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i,
525
+ /\blg-?([\d\w]+) bui/i
526
+ ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [
527
+
528
+ // Lenovo
529
+ /(ideatab[-\w ]+)/i,
530
+ /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
531
+ ], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
532
+
533
+ // Nokia
534
+ /(?:maemo|nokia).*(n900|lumia \d+)/i,
535
+ /nokia[-_ ]?([-\w\.]*)/i
536
+ ], [[MODEL, /_/g, ' '], [VENDOR, 'Nokia'], [TYPE, MOBILE]], [
537
+
538
+ // Google
539
+ /(pixel c)\b/i // Google Pixel C
540
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [
541
+ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i // Google Pixel
542
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
543
+
544
+ // Sony
545
+ /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i
546
+ ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
547
+ /sony tablet [ps]/i,
548
+ /\b(?:sony)?sgp\w+(?: bui|\))/i
549
+ ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [
550
+
551
+ // OnePlus
552
+ / (kb2005|in20[12]5|be20[12][59])\b/i,
553
+ /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
554
+ ], [MODEL, [VENDOR, 'OnePlus'], [TYPE, MOBILE]], [
555
+
556
+ // Amazon
557
+ /(alexa)webm/i,
558
+ /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show
559
+ /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
560
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
561
+ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
562
+ ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [
563
+
564
+ // BlackBerry
565
+ /(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook
566
+ ], [MODEL, VENDOR, [TYPE, TABLET]], [
567
+ /\b((?:bb[a-f]|st[hv])100-\d)/i,
568
+ /\(bb10; (\w+)/i // BlackBerry 10
569
+ ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [
570
+
571
+ // Asus
572
+ /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i
573
+ ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [
574
+ / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i
575
+ ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [
576
+
577
+ // HTC
578
+ /(nexus 9)/i // HTC Nexus 9
579
+ ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [
580
+ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, // HTC
581
+
582
+ // ZTE
583
+ /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,
584
+ /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
585
+ ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
586
+
587
+ // Acer
588
+ /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
589
+ ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
590
+
591
+ // Meizu
592
+ /droid.+; (m[1-5] note) bui/i,
593
+ /\bmz-([-\w]{2,})/i
594
+ ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [
595
+
596
+ // MIXED
597
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron)[-_ ]?([-\w]*)/i,
598
+ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
599
+ /(hp) ([\w ]+\w)/i, // HP iPAQ
600
+ /(asus)-?(\w+)/i, // Asus
601
+ /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
602
+ /(lenovo)[-_ ]?([-\w]+)/i, // Lenovo
603
+ /(jolla)/i, // Jolla
604
+ /(oppo) ?([\w ]+) bui/i // OPPO
605
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
606
+
607
+ /(kobo)\s(ereader|touch)/i, // Kobo
608
+ /(archos) (gamepad2?)/i, // Archos
609
+ /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
610
+ /(kindle)\/([\w\.]+)/i // Kindle
611
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
612
+
613
+ /(surface duo)/i // Surface Duo
614
+ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [
615
+ /droid [\d\.]+; (fp\du?)(?: b|\))/i // Fairphone
616
+ ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [
617
+ /(shield[\w ]+) b/i // Nvidia Shield Tablets
618
+ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, TABLET]], [
619
+ /(sprint) (\w+)/i // Sprint Phones
620
+ ], [VENDOR, MODEL, [TYPE, MOBILE]], [
621
+ /(kin\.[onetw]{3})/i // Microsoft Kin
622
+ ], [[MODEL, /\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [
623
+ /droid.+; ([c6]+|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i // Zebra
624
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [
625
+ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i
626
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [
627
+
628
+ ///////////////////
629
+ // SMARTTVS
630
+ ///////////////////
631
+
632
+ /smart-tv.+(samsung)/i // Samsung
633
+ ], [VENDOR, [TYPE, SMARTTV]], [
634
+ /hbbtv.+maple;(\d+)/i
635
+ ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [
636
+ /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i // LG SmartTV
637
+ ], [[VENDOR, LG], [TYPE, SMARTTV]], [
638
+ /(apple) ?tv/i // Apple TV
639
+ ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
640
+ /crkey/i // Google Chromecast
641
+ ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
642
+ /droid.+aft(\w)( bui|\))/i // Fire TV
643
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
644
+ /\(dtv[\);].+(aquos)/i,
645
+ /(aquos-tv[\w ]+)\)/i // Sharp
646
+ ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[
647
+ /(bravia[\w ]+)( bui|\))/i // Sony
648
+ ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [
649
+ /(mitv-\w{5}) bui/i // Xiaomi
650
+ ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [
651
+ /Hbbtv.*(technisat) (.*);/i // TechniSAT
652
+ ], [VENDOR, MODEL, [TYPE, SMARTTV]], [
653
+ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
654
+ /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
655
+ ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [
656
+ /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i // SmartTV from Unidentified Vendors
657
+ ], [[TYPE, SMARTTV]], [
658
+
659
+ ///////////////////
660
+ // CONSOLES
661
+ ///////////////////
662
+
663
+ /(ouya)/i, // Ouya
664
+ /(nintendo) (\w+)/i // Nintendo
665
+ ], [VENDOR, MODEL, [TYPE, CONSOLE]], [
666
+ /droid.+; (shield) bui/i // Nvidia
667
+ ], [MODEL, [VENDOR, 'Nvidia'], [TYPE, CONSOLE]], [
668
+ /(playstation \w+)/i // Playstation
669
+ ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [
670
+ /\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox
671
+ ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [
672
+
673
+ ///////////////////
674
+ // WEARABLES
675
+ ///////////////////
676
+
677
+ /((pebble))app/i // Pebble
678
+ ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
679
+ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
680
+ ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
681
+ /droid.+; (glass) \d/i // Google Glass
682
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
683
+ /droid.+; (wt63?0{2,3})\)/i
684
+ ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
685
+ /(quest( 2| pro)?)/i // Oculus Quest
686
+ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
687
+
688
+ ///////////////////
689
+ // EMBEDDED
690
+ ///////////////////
691
+
692
+ /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i // Tesla
693
+ ], [VENDOR, [TYPE, EMBEDDED]], [
694
+ /(aeobc)\b/i // Echo Dot
695
+ ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [
696
+
697
+ ////////////////////
698
+ // MIXED (GENERIC)
699
+ ///////////////////
700
+
701
+ /droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
702
+ ], [MODEL, [TYPE, MOBILE]], [
703
+ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
704
+ ], [MODEL, [TYPE, TABLET]], [
705
+ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
706
+ ], [[TYPE, TABLET]], [
707
+ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile
708
+ ], [[TYPE, MOBILE]], [
709
+ /(android[-\w\. ]{0,9});.+buil/i // Generic Android Device
710
+ ], [MODEL, [VENDOR, 'Generic']]
711
+ ],
712
+
713
+ engine : [[
714
+
715
+ /windows.+ edge\/([\w\.]+)/i // EdgeHTML
716
+ ], [VERSION, [NAME, EDGE+'HTML']], [
717
+
718
+ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
719
+ ], [VERSION, [NAME, 'Blink']], [
720
+
721
+ /(presto)\/([\w\.]+)/i, // Presto
722
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
723
+ /ekioh(flow)\/([\w\.]+)/i, // Flow
724
+ /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
725
+ /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
726
+ /\b(libweb)/i
727
+ ], [NAME, VERSION], [
728
+
729
+ /rv\:([\w\.]{1,9})\b.+(gecko)/i // Gecko
730
+ ], [VERSION, NAME]
731
+ ],
732
+
733
+ os : [[
734
+
735
+ // Windows
736
+ /microsoft (windows) (vista|xp)/i // Windows (iTunes)
737
+ ], [NAME, VERSION], [
738
+ /(windows) nt 6\.2; (arm)/i, // Windows RT
739
+ /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone
740
+ /(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
741
+ ], [NAME, [VERSION, strMapper, windowsVersionMap]], [
742
+ /(win(?=3|9|n)|win 9x )([nt\d\.]+)/i
743
+ ], [[NAME, WINDOWS], [VERSION, strMapper, windowsVersionMap]], [
744
+
745
+ // iOS/macOS
746
+ /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
747
+ /ios;fbsv\/([\d\.]+)/i,
748
+ /cfnetwork\/.+darwin/i
749
+ ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
750
+ /(mac os x) ?([\w\. ]*)/i,
751
+ /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS
752
+ ], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
753
+
754
+ // Mobile OSes
755
+ /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS
756
+ ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
757
+ /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
758
+ /(blackberry)\w*\/([\w\.]*)/i, // Blackberry
759
+ /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS
760
+ /\((series40);/i // Series 40
761
+ ], [NAME, VERSION], [
762
+ /\(bb(10);/i // BlackBerry 10
763
+ ], [VERSION, [NAME, BLACKBERRY]], [
764
+ /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i // Symbian
765
+ ], [VERSION, [NAME, 'Symbian']], [
766
+ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS
767
+ ], [VERSION, [NAME, FIREFOX+' OS']], [
768
+ /web0s;.+rt(tv)/i,
769
+ /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i // WebOS
770
+ ], [VERSION, [NAME, 'webOS']], [
771
+ /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
772
+ ], [VERSION, [NAME, 'watchOS']], [
773
+
774
+ // Google Chromecast
775
+ /crkey\/([\d\.]+)/i // Google Chromecast
776
+ ], [VERSION, [NAME, CHROME+'cast']], [
777
+ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
778
+ ], [[NAME, "Chrome OS"], VERSION],[
779
+
780
+ // Smart TVs
781
+ /panasonic;(viera)/i, // Panasonic Viera
782
+ /(netrange)mmh/i, // Netrange
783
+ /(nettv)\/(\d+\.[\w\.]+)/i, // NetTV
784
+
785
+ // Console
786
+ /(nintendo|playstation) (\w+)/i, // Nintendo/Playstation
787
+ /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
788
+
789
+ // Other
790
+ /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
791
+ /(mint)[\/\(\) ]?(\w*)/i, // Mint
792
+ /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux
793
+ /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,
794
+ // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire
795
+ /(hurd|linux) ?([\w\.]*)/i, // Hurd/Linux
796
+ /(gnu) ?([\w\.]*)/i, // GNU
797
+ /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
798
+ /(haiku) (\w+)/i // Haiku
799
+ ], [NAME, VERSION], [
800
+ /(sunos) ?([\w\.\d]*)/i // Solaris
801
+ ], [[NAME, 'Solaris'], VERSION], [
802
+ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris
803
+ /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX
804
+ /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS
805
+ /(unix) ?([\w\.]*)/i // UNIX
806
+ ], [NAME, VERSION]
807
+ ]
808
+ };
809
+
810
+ /////////////////
811
+ // Factories
812
+ ////////////////
813
+
814
+ var defaultProps = (function () {
815
+ var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
816
+ assignFromEntries.call(props.init, [
817
+ [UA_BROWSER, [NAME, VERSION, MAJOR]],
818
+ [UA_CPU, [ARCHITECTURE]],
819
+ [UA_DEVICE, [TYPE, MODEL, VENDOR]],
820
+ [UA_ENGINE, [NAME, VERSION]],
821
+ [UA_OS, [NAME, VERSION]]
822
+ ]);
823
+ assignFromEntries.call(props.isIgnore, [
824
+ [UA_BROWSER, [VERSION, MAJOR]],
825
+ [UA_ENGINE, [VERSION]],
826
+ [UA_OS, [VERSION]]
827
+ ]);
828
+ assignFromEntries.call(props.isIgnoreRgx, [
829
+ [UA_BROWSER, / ?browser$/i],
830
+ [UA_OS, / ?os$/i]
831
+ ]);
832
+ assignFromEntries.call(props.toString, [
833
+ [UA_BROWSER, [NAME, VERSION]],
834
+ [UA_CPU, [ARCHITECTURE]],
835
+ [UA_DEVICE, [VENDOR, MODEL]],
836
+ [UA_ENGINE, [NAME, VERSION]],
837
+ [UA_OS, [NAME, VERSION]]
838
+ ]);
839
+ return props;
840
+ })();
841
+
842
+ var createUAParserData = function (itemType, ua, rgxMap, uaCH) {
843
+
844
+ var init_props = defaultProps.init[itemType],
845
+ is_ignoreProps = defaultProps.isIgnore[itemType] || 0,
846
+ is_ignoreRgx = defaultProps.isIgnoreRgx[itemType] || 0,
847
+ toString_props = defaultProps.toString[itemType] || 0;
848
+
849
+ function UAParserData () {
850
+ assignFromEntries.call(this, init_props);
851
+ }
852
+ UAParserData.prototype.withClientHints = function () {
853
+
854
+ // nodejs / non-client-hints browsers
855
+ if (!NAVIGATOR_UADATA) {
856
+ return new UAParserItem(itemType, ua, rgxMap, uaCH).parseCH().get();
857
+ }
858
+
859
+ // browsers based on chromium 85+
860
+ return NAVIGATOR_UADATA
861
+ .getHighEntropyValues(CH_ALL_VALUES)
862
+ .then(function (res) {
863
+ var JS_UACH = new UAParserDataCH(res, false);
864
+ return new UAParserItem(itemType, ua, rgxMap, JS_UACH).parseCH().get();
865
+ });
866
+ };
867
+
868
+ if (itemType != UA_RESULT) {
869
+ UAParserData.prototype.is = function (strToCheck) {
870
+ var is = false;
871
+ for (var i in this) {
872
+ 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)) {
873
+ is = true;
874
+ if (strToCheck != UNDEF_TYPE) break;
875
+ } else if (strToCheck == UNDEF_TYPE && is) {
876
+ is = !is;
877
+ break;
878
+ }
879
+ }
880
+ return is;
881
+ };
882
+ UAParserData.prototype.toString = function () {
883
+ var str = EMPTY;
884
+ for (var i in toString_props) {
885
+ if (typeof(this[toString_props[i]]) !== UNDEF_TYPE) {
886
+ str += (str ? ' ' : EMPTY) + this[toString_props[i]];
887
+ }
888
+ }
889
+ return str || UNDEF_TYPE;
890
+ };
891
+ }
892
+
893
+ if (!NAVIGATOR_UADATA) {
894
+ UAParserData.prototype.then = function (cb) {
895
+ var that = this;
896
+ var UAParserDataResolve = function () {
897
+ for (var prop in that) {
898
+ if (that.hasOwnProperty(prop)) {
899
+ this[prop] = that[prop];
900
+ }
901
+ }
902
+ };
903
+ UAParserDataResolve.prototype = {
904
+ is : UAParserData.prototype.is,
905
+ toString : UAParserData.prototype.toString
906
+ };
907
+ var resolveData = new UAParserDataResolve();
908
+ cb(resolveData);
909
+ return resolveData;
910
+ };
911
+ }
912
+
913
+ return new UAParserData();
914
+ };
915
+
916
+ /////////////////
917
+ // Constructor
918
+ ////////////////
919
+
920
+ function UAParserDataCH (uach, isHTTP_UACH) {
921
+ uach = uach || {};
922
+ assignFromEntries.call(this, CH_ALL_VALUES);
923
+ if (isHTTP_UACH) {
924
+ assignFromEntries.call(this, [
925
+ [BRANDS, itemListToArray(uach[CH_HEADER])],
926
+ [FULLVERLIST, itemListToArray(uach[CH_HEADER_FULL_VER_LIST])],
927
+ [BRANDS, itemListToArray(uach[CH_HEADER])],
928
+ [MOBILE, /\?1/.test(uach[CH_HEADER_MOBILE])],
929
+ [MODEL, stripQuotes(uach[CH_HEADER_MODEL])],
930
+ [PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
931
+ [PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
932
+ [ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
933
+ [BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
934
+ ]);
935
+ } else {
936
+ for (var prop in uach) {
937
+ if(this.hasOwnProperty(prop) && typeof uach[prop] !== UNDEF_TYPE) this[prop] = uach[prop];
938
+ }
939
+ }
940
+ return this;
941
+ }
942
+
943
+ function UAParserItem (itemType, ua, rgxMap, uaCH) {
944
+ assignFromEntries.call(this, [
945
+ ['itemType', itemType],
946
+ ['ua', ua],
947
+ ['uaCH', uaCH],
948
+ ['rgxMap', rgxMap],
949
+ ['data', createUAParserData(itemType, ua, rgxMap, uaCH)]
950
+ ]);
951
+ this.parse();
952
+ var isSelfNav = NAVIGATOR && NAVIGATOR.userAgent == ua;
953
+ switch(this.itemType) {
954
+ case UA_BROWSER:
955
+ // Brave-specific detection
956
+ if (isSelfNav && NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == FUNC_TYPE) {
957
+ this.set(NAME, 'Brave');
958
+ }
959
+ this.set(MAJOR, majorize(this.get(VERSION)));
960
+ break;
961
+ case UA_DEVICE:
962
+ if (isSelfNav && !this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
963
+ this.set(TYPE, MOBILE);
964
+ }
965
+ // iPadOS-specific detection: identified as Mac, but has some iOS-only properties
966
+ if (isSelfNav && this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== UNDEF_TYPE && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
967
+ this.set(MODEL, 'iPad')
968
+ .set(TYPE, TABLET);
969
+ }
970
+ break;
971
+ case UA_OS:
972
+ if (isSelfNav && !this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
973
+ this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
974
+ }
975
+ break;
976
+ case UA_RESULT:
977
+ var createUAParserItem = function (itemType) {
978
+ return new UAParserItem(itemType, ua, rgxMap[itemType], uaCH).get();
979
+ };
980
+ this.set('ua', ua)
981
+ .set(UA_BROWSER, createUAParserItem(UA_BROWSER))
982
+ .set(UA_CPU, createUAParserItem(UA_CPU))
983
+ .set(UA_DEVICE, createUAParserItem(UA_DEVICE))
984
+ .set(UA_ENGINE, createUAParserItem(UA_ENGINE))
985
+ .set(UA_OS, createUAParserItem(UA_OS))
986
+ .get();
987
+ }
988
+ return this;
989
+ }
990
+ UAParserItem.prototype.get = function (prop) {
991
+ if (!prop) return this.data;
992
+ return this.data.hasOwnProperty(prop) ? this.data[prop] : undefined;
993
+ };
994
+ UAParserItem.prototype.parse = function () {
995
+ if (this.itemType != UA_RESULT) {
996
+ rgxMapper.call(this.data, this.ua, this.rgxMap);
997
+ }
998
+ return this;
999
+ };
1000
+ UAParserItem.prototype.parseCH = function () {
1001
+ var ua = this.ua,
1002
+ uaCH = this.uaCH,
1003
+ rgxMap = this.rgxMap;
1004
+
1005
+ switch (this.itemType) {
1006
+ case UA_BROWSER:
1007
+ var brands = uaCH[FULLVERLIST] || uaCH[BRANDS];
1008
+ if (brands) {
1009
+ for (var i in brands) {
1010
+ var brandName = brands[i].brand,
1011
+ brandVersion = brands[i].version;
1012
+ if (!/not.a.brand/i.test(brandName) && (i < 1 || /chromi/i.test(this.get(NAME)))) {
1013
+ this.set(NAME, strip(GOOGLE+' ', brandName))
1014
+ .set(VERSION, brandVersion)
1015
+ .set(MAJOR, majorize(brandVersion));
1016
+ }
1017
+ }
1018
+ }
1019
+ break;
1020
+ case UA_CPU:
1021
+ var archName = uaCH[ARCHITECTURE];
1022
+ if (archName) {
1023
+ if (archName && uaCH[BITNESS] == '64') archName += '64';
1024
+ rgxMapper.call(this.data, archName + ';', rgxMap);
1025
+ }
1026
+ break;
1027
+ case UA_DEVICE:
1028
+ if (uaCH[MOBILE]) {
1029
+ this.set(TYPE, MOBILE);
1030
+ }
1031
+ if (uaCH[MODEL]) {
1032
+ this.set(MODEL, uaCH[MODEL]);
1033
+ }
1034
+ break;
1035
+ case UA_OS:
1036
+ var osName = uaCH[PLATFORM];
1037
+ if(osName) {
1038
+ var osVersion = uaCH[PLATFORMVER];
1039
+ if (osName == WINDOWS) osVersion = (parseInt(majorize(osVersion), 10) >= 13 ? '11' : '10');
1040
+ this.set(NAME, osName)
1041
+ .set(VERSION, osVersion);
1042
+ }
1043
+ break;
1044
+ case UA_RESULT:
1045
+ var createUAParserItemWithCH = function (itemType) {
1046
+ return new UAParserItem(itemType, ua, rgxMap[itemType], uaCH).parseCH().get();
1047
+ };
1048
+ this.set('ua', ua)
1049
+ .set(UA_BROWSER, createUAParserItemWithCH(UA_BROWSER))
1050
+ .set(UA_CPU, createUAParserItemWithCH(UA_CPU))
1051
+ .set(UA_DEVICE, createUAParserItemWithCH(UA_DEVICE))
1052
+ .set(UA_ENGINE, createUAParserItemWithCH(UA_ENGINE))
1053
+ .set(UA_OS, createUAParserItemWithCH(UA_OS));
1054
+ }
1055
+ return this;
1056
+ };
1057
+ UAParserItem.prototype.set = function (prop, val) {
1058
+ this.data[prop] = val;
1059
+ return this;
1060
+ };
1061
+
1062
+ function UAParser (ua, extensions, headers) {
1063
+
1064
+ if (typeof ua === OBJ_TYPE) {
1065
+ if (isExtensions(ua)) {
1066
+ if (typeof extensions === OBJ_TYPE) {
1067
+ headers = extensions; // case UAParser(extensions, headers)
1068
+ }
1069
+ extensions = ua; // case UAParser(extensions)
1070
+ } else {
1071
+ headers = ua; // case UAParser(headers)
1072
+ extensions = undefined;
1073
+ }
1074
+ ua = undefined;
1075
+ } else if (typeof ua === STR_TYPE && !isExtensions(extensions)) {
1076
+ headers = extensions; // case UAParser(ua, headers)
1077
+ extensions = undefined;
1078
+ }
1079
+
1080
+ if (!(this instanceof UAParser)) {
1081
+ return new UAParser(ua, extensions, headers).getResult();
1082
+ }
1083
+
1084
+ var userAgent = ua ||
1085
+ ((NAVIGATOR && NAVIGATOR.userAgent) ?
1086
+ NAVIGATOR.userAgent :
1087
+ (headers && headers[USER_AGENT] ?
1088
+ headers[USER_AGENT] :
1089
+ EMPTY)),
1090
+
1091
+ HTTP_UACH = new UAParserDataCH(headers, true),
1092
+
1093
+ regexMap = extensions ?
1094
+ extend(defaultRegexes, extensions) :
1095
+ defaultRegexes,
1096
+
1097
+ createUAParserItemFunc = function (itemType) {
1098
+ return function () {
1099
+ return new UAParserItem(itemType, userAgent, itemType == UA_RESULT ? regexMap : regexMap[itemType], HTTP_UACH).get();
1100
+ };
1101
+ };
1102
+
1103
+ // public methods
1104
+ assignFromEntries.call(this, [
1105
+ ['getBrowser', createUAParserItemFunc(UA_BROWSER)],
1106
+ ['getCPU', createUAParserItemFunc(UA_CPU)],
1107
+ ['getDevice', createUAParserItemFunc(UA_DEVICE)],
1108
+ ['getEngine', createUAParserItemFunc(UA_ENGINE)],
1109
+ ['getOS', createUAParserItemFunc(UA_OS)],
1110
+ ['getResult', createUAParserItemFunc(UA_RESULT)],
1111
+ ['getUA', function () { return userAgent; }],
1112
+ ['setUA', function (ua) {
1113
+ userAgent = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;
1114
+ return this;
1115
+ }]
1116
+ ]).setUA(userAgent);
1117
+ return this;
1118
+ }
1119
+
1120
+ UAParser.VERSION = LIBVERSION;
1121
+ UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
1122
+ UAParser.CPU = enumerize([ARCHITECTURE]);
1123
+ UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1124
+ UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
1125
+
1126
+ export {UAParser};