ua-parser-js 2.0.3 → 2.0.6
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/README.md +62 -33
- package/dist/ua-parser.min.js +2 -2
- package/dist/ua-parser.min.mjs +2 -2
- package/dist/ua-parser.pack.js +2 -2
- package/dist/ua-parser.pack.mjs +2 -2
- package/package.json +7 -9
- package/script/cli.js +92 -2
- package/src/enums/ua-parser-enums.d.ts +734 -364
- package/src/enums/ua-parser-enums.js +371 -16
- package/src/enums/ua-parser-enums.mjs +371 -16
- package/src/extensions/ua-parser-extensions.d.ts +1 -1
- package/src/extensions/ua-parser-extensions.js +89 -24
- package/src/extensions/ua-parser-extensions.mjs +89 -24
- package/src/helpers/ua-parser-helpers.d.ts +10 -22
- package/src/helpers/ua-parser-helpers.js +88 -43
- package/src/helpers/ua-parser-helpers.mjs +88 -43
- package/src/main/ua-parser.d.ts +7 -8
- package/src/main/ua-parser.js +316 -244
- package/src/main/ua-parser.mjs +313 -241
package/src/main/ua-parser.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Source: /src/main/ua-parser.js
|
|
4
4
|
|
|
5
5
|
/////////////////////////////////////////////////////////////////////////////////
|
|
6
|
-
/* UAParser.js v2.0.
|
|
6
|
+
/* UAParser.js v2.0.6
|
|
7
7
|
Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
|
|
8
8
|
AGPLv3 License *//*
|
|
9
9
|
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
|
@@ -21,26 +21,26 @@
|
|
|
21
21
|
// Constants
|
|
22
22
|
/////////////
|
|
23
23
|
|
|
24
|
-
var LIBVERSION = '2.0.
|
|
24
|
+
var LIBVERSION = '2.0.6',
|
|
25
25
|
UA_MAX_LENGTH = 500,
|
|
26
26
|
USER_AGENT = 'user-agent',
|
|
27
27
|
EMPTY = '',
|
|
28
28
|
UNKNOWN = '?',
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
TYPEOF = {
|
|
30
|
+
FUNCTION : 'function',
|
|
31
|
+
OBJECT : 'object',
|
|
32
|
+
STRING : 'string',
|
|
33
|
+
UNDEFINED : 'undefined'
|
|
34
|
+
},
|
|
35
35
|
|
|
36
36
|
// properties
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
BROWSER = 'browser',
|
|
38
|
+
CPU = 'cpu',
|
|
39
|
+
DEVICE = 'device',
|
|
40
|
+
ENGINE = 'engine',
|
|
41
|
+
OS = 'os',
|
|
42
|
+
RESULT = 'result',
|
|
43
|
+
|
|
44
44
|
NAME = 'name',
|
|
45
45
|
TYPE = 'type',
|
|
46
46
|
VENDOR = 'vendor',
|
|
@@ -68,16 +68,16 @@
|
|
|
68
68
|
PLATFORM = 'platform',
|
|
69
69
|
PLATFORMVER = 'platformVersion',
|
|
70
70
|
BITNESS = 'bitness',
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
CH_ALL_VALUES
|
|
71
|
+
CH = 'sec-ch-ua',
|
|
72
|
+
CH_FULL_VER_LIST= CH + '-full-version-list',
|
|
73
|
+
CH_ARCH = CH + '-arch',
|
|
74
|
+
CH_BITNESS = CH + '-' + BITNESS,
|
|
75
|
+
CH_FORM_FACTORS = CH + '-form-factors',
|
|
76
|
+
CH_MOBILE = CH + '-' + MOBILE,
|
|
77
|
+
CH_MODEL = CH + '-' + MODEL,
|
|
78
|
+
CH_PLATFORM = CH + '-' + PLATFORM,
|
|
79
|
+
CH_PLATFORM_VER = CH_PLATFORM + '-version',
|
|
80
|
+
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
|
|
81
81
|
|
|
82
82
|
// device vendors
|
|
83
83
|
AMAZON = 'Amazon',
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
// os
|
|
117
117
|
WINDOWS = 'Windows';
|
|
118
118
|
|
|
119
|
-
var isWindow = typeof window !==
|
|
119
|
+
var isWindow = typeof window !== TYPEOF.UNDEFINED,
|
|
120
120
|
NAVIGATOR = (isWindow && window.navigator) ?
|
|
121
121
|
window.navigator :
|
|
122
122
|
undefined,
|
|
@@ -152,13 +152,13 @@
|
|
|
152
152
|
return enums;
|
|
153
153
|
},
|
|
154
154
|
has = function (str1, str2) {
|
|
155
|
-
if (typeof str1 ===
|
|
155
|
+
if (typeof str1 === TYPEOF.OBJECT && str1.length > 0) {
|
|
156
156
|
for (var i in str1) {
|
|
157
|
-
if (lowerize(
|
|
157
|
+
if (lowerize(str2) == lowerize(str1[i])) return true;
|
|
158
158
|
}
|
|
159
159
|
return false;
|
|
160
160
|
}
|
|
161
|
-
return isString(str1) ? lowerize(str2)
|
|
161
|
+
return isString(str1) ? lowerize(str2) == lowerize(str1) : false;
|
|
162
162
|
},
|
|
163
163
|
isExtensions = function (obj, deep) {
|
|
164
164
|
for (var prop in obj) {
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
}
|
|
167
167
|
},
|
|
168
168
|
isString = function (val) {
|
|
169
|
-
return typeof val ===
|
|
169
|
+
return typeof val === TYPEOF.STRING;
|
|
170
170
|
},
|
|
171
171
|
itemListToArray = function (header) {
|
|
172
172
|
if (!header) return undefined;
|
|
@@ -190,8 +190,10 @@
|
|
|
190
190
|
},
|
|
191
191
|
setProps = function (arr) {
|
|
192
192
|
for (var i in arr) {
|
|
193
|
+
if (!arr.hasOwnProperty(i)) continue;
|
|
194
|
+
|
|
193
195
|
var propName = arr[i];
|
|
194
|
-
if (typeof propName ==
|
|
196
|
+
if (typeof propName == TYPEOF.OBJECT && propName.length == 2) {
|
|
195
197
|
this[propName[0]] = propName[1];
|
|
196
198
|
} else {
|
|
197
199
|
this[propName] = undefined;
|
|
@@ -206,10 +208,8 @@
|
|
|
206
208
|
return strip(/\\?\"/g, str);
|
|
207
209
|
},
|
|
208
210
|
trim = function (str, len) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
|
212
|
-
}
|
|
211
|
+
str = strip(/^\s\s*/, String(str));
|
|
212
|
+
return typeof len === TYPEOF.UNDEFINED ? str : str.substring(0, len);
|
|
213
213
|
};
|
|
214
214
|
|
|
215
215
|
///////////////
|
|
@@ -240,26 +240,34 @@
|
|
|
240
240
|
match = matches[++k];
|
|
241
241
|
q = props[p];
|
|
242
242
|
// check if given property is actually array
|
|
243
|
-
if (typeof q ===
|
|
243
|
+
if (typeof q === TYPEOF.OBJECT && q.length > 0) {
|
|
244
244
|
if (q.length === 2) {
|
|
245
|
-
if (typeof q[1] ==
|
|
245
|
+
if (typeof q[1] == TYPEOF.FUNCTION) {
|
|
246
246
|
// assign modified match
|
|
247
247
|
this[q[0]] = q[1].call(this, match);
|
|
248
248
|
} else {
|
|
249
249
|
// assign given value, ignore regex match
|
|
250
250
|
this[q[0]] = q[1];
|
|
251
251
|
}
|
|
252
|
-
} else if (q.length
|
|
253
|
-
//
|
|
254
|
-
if (typeof q[1] ===
|
|
255
|
-
|
|
256
|
-
|
|
252
|
+
} else if (q.length >= 3) {
|
|
253
|
+
// Check whether q[1] FUNCTION or REGEX
|
|
254
|
+
if (typeof q[1] === TYPEOF.FUNCTION && !(q[1].exec && q[1].test)) {
|
|
255
|
+
if (q.length > 3) {
|
|
256
|
+
this[q[0]] = match ? q[1].apply(this, q.slice(2)) : undefined;
|
|
257
|
+
} else {
|
|
258
|
+
// call function (usually string mapper)
|
|
259
|
+
this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
|
|
260
|
+
}
|
|
257
261
|
} else {
|
|
258
|
-
|
|
259
|
-
|
|
262
|
+
if (q.length == 3) {
|
|
263
|
+
// sanitize match using given regex
|
|
264
|
+
this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
|
|
265
|
+
} else if (q.length == 4) {
|
|
266
|
+
this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
|
|
267
|
+
} else if (q.length > 4) {
|
|
268
|
+
this[q[0]] = match ? q[3].apply(this, [match.replace(q[1], q[2])].concat(q.slice(4))) : undefined;
|
|
269
|
+
}
|
|
260
270
|
}
|
|
261
|
-
} else if (q.length === 4) {
|
|
262
|
-
this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
|
|
263
271
|
}
|
|
264
272
|
} else {
|
|
265
273
|
this[q] = match ? match : undefined;
|
|
@@ -275,7 +283,7 @@
|
|
|
275
283
|
|
|
276
284
|
for (var i in map) {
|
|
277
285
|
// check if current value is array
|
|
278
|
-
if (typeof map[i] ===
|
|
286
|
+
if (typeof map[i] === TYPEOF.OBJECT && map[i].length > 0) {
|
|
279
287
|
for (var j = 0; j < map[i].length; j++) {
|
|
280
288
|
if (has(map[i][j], str)) {
|
|
281
289
|
return (i === UNKNOWN) ? undefined : i;
|
|
@@ -293,17 +301,17 @@
|
|
|
293
301
|
//////////////
|
|
294
302
|
|
|
295
303
|
var windowsVersionMap = {
|
|
296
|
-
'ME'
|
|
297
|
-
'NT 3.
|
|
298
|
-
'NT 4.0'
|
|
299
|
-
'2000'
|
|
300
|
-
'XP'
|
|
301
|
-
'Vista'
|
|
302
|
-
'7'
|
|
303
|
-
'8'
|
|
304
|
-
'8.1'
|
|
305
|
-
'10'
|
|
306
|
-
'
|
|
304
|
+
'ME' : '4.90',
|
|
305
|
+
'NT 3.51': '3.51',
|
|
306
|
+
'NT 4.0': '4.0',
|
|
307
|
+
'2000' : ['5.0', '5.01'],
|
|
308
|
+
'XP' : ['5.1', '5.2'],
|
|
309
|
+
'Vista' : '6.0',
|
|
310
|
+
'7' : '6.1',
|
|
311
|
+
'8' : '6.2',
|
|
312
|
+
'8.1' : '6.3',
|
|
313
|
+
'10' : ['6.4', '10.0'],
|
|
314
|
+
'NT' : ''
|
|
307
315
|
},
|
|
308
316
|
|
|
309
317
|
formFactorsMap = {
|
|
@@ -315,6 +323,18 @@
|
|
|
315
323
|
'xr' : ['VR', 'XR'],
|
|
316
324
|
'?' : ['Desktop', 'Unknown'],
|
|
317
325
|
'*' : undefined
|
|
326
|
+
},
|
|
327
|
+
|
|
328
|
+
browserHintsMap = {
|
|
329
|
+
'Chrome' : 'Google Chrome',
|
|
330
|
+
'Edge' : 'Microsoft Edge',
|
|
331
|
+
'Edge WebView2' : 'Microsoft Edge WebView2',
|
|
332
|
+
'Chrome WebView': 'Android WebView',
|
|
333
|
+
'Chrome Headless':'HeadlessChrome',
|
|
334
|
+
'Huawei Browser': 'HuaweiBrowser',
|
|
335
|
+
'MIUI Browser' : 'Miui Browser',
|
|
336
|
+
'Opera Mobi' : 'OperaMobile',
|
|
337
|
+
'Yandex' : 'YaBrowser'
|
|
318
338
|
};
|
|
319
339
|
|
|
320
340
|
//////////////
|
|
@@ -328,7 +348,9 @@
|
|
|
328
348
|
// Most common regardless engine
|
|
329
349
|
/\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
|
|
330
350
|
], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
|
|
331
|
-
/
|
|
351
|
+
/webview.+edge\/([\w\.]+)/i // Microsoft Edge
|
|
352
|
+
], [VERSION, [NAME, EDGE+' WebView']], [
|
|
353
|
+
/edg(?:e|ios|a)?\/([\w\.]+)/i
|
|
332
354
|
], [VERSION, [NAME, 'Edge']], [
|
|
333
355
|
|
|
334
356
|
// Presto based
|
|
@@ -355,10 +377,11 @@
|
|
|
355
377
|
/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
|
|
356
378
|
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
|
357
379
|
|
|
358
|
-
// Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble
|
|
359
|
-
/(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)\/([-\w\.]+)/i,
|
|
380
|
+
// Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon/LG Browser/Otter/qutebrowser/Dooble/Palemoon
|
|
381
|
+
/(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,
|
|
360
382
|
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
|
|
361
|
-
/(heytap|ovi|115|surf)browser\/([\d\.]+)/i,
|
|
383
|
+
/(heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf
|
|
384
|
+
/(qwant)(?:ios|mobile)\/([\d\.]+)/i, // Qwant
|
|
362
385
|
/(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo
|
|
363
386
|
], [NAME, VERSION], [
|
|
364
387
|
/quark(?:pc)?\/([-\w\.]+)/i // Quark
|
|
@@ -420,7 +443,6 @@
|
|
|
420
443
|
// WebView
|
|
421
444
|
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
|
422
445
|
], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
|
|
423
|
-
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
|
|
424
446
|
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
|
|
425
447
|
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
|
|
426
448
|
/(daum)apps[\/ ]([\w\.]+)/i, // Daum App
|
|
@@ -428,7 +450,8 @@
|
|
|
428
450
|
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
|
429
451
|
/(alipay)client\/([\w\.]+)/i, // Alipay
|
|
430
452
|
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
|
|
431
|
-
/(
|
|
453
|
+
/(bing)(?:web|sapphire)\/([\w\.]+)/i, // Bing
|
|
454
|
+
/(instagram|snapchat|klarna)[\/ ]([-\w\.]+)/i // Instagram/Snapchat/Klarna
|
|
432
455
|
], [NAME, VERSION, [TYPE, INAPP]], [
|
|
433
456
|
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
|
434
457
|
], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
|
|
@@ -436,6 +459,8 @@
|
|
|
436
459
|
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
|
|
437
460
|
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
|
438
461
|
], [NAME, [TYPE, INAPP]], [
|
|
462
|
+
/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
|
|
463
|
+
], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
|
|
439
464
|
|
|
440
465
|
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
|
|
441
466
|
], [NAME, VERSION], [
|
|
@@ -443,6 +468,9 @@
|
|
|
443
468
|
/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
|
|
444
469
|
], [VERSION, [NAME, CHROME+' Headless']], [
|
|
445
470
|
|
|
471
|
+
/wv\).+chrome\/([\w\.]+).+edgw\//i // Edge WebView2
|
|
472
|
+
], [VERSION, [NAME, EDGE+' WebView2']], [
|
|
473
|
+
|
|
446
474
|
/ wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
|
|
447
475
|
], [[NAME, CHROME+' WebView'], VERSION], [
|
|
448
476
|
|
|
@@ -480,10 +508,10 @@
|
|
|
480
508
|
/(swiftfox)/i, // Swiftfox
|
|
481
509
|
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
|
|
482
510
|
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
|
483
|
-
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|
|
|
511
|
+
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|basilisk|waterfox)\/([-\w\.]+)$/i,
|
|
484
512
|
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
|
485
513
|
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
|
486
|
-
/(mozilla)\/([\w\.]+
|
|
514
|
+
/(mozilla)\/([\w\.]+(?= .+rv\:.+gecko\/\d+)|[0-4][\w\.]+(?!.+compatible))/i, // Mozilla
|
|
487
515
|
|
|
488
516
|
// Other
|
|
489
517
|
/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
|
@@ -514,15 +542,17 @@
|
|
|
514
542
|
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
|
|
515
543
|
], [[ARCHITECTURE, 'arm']], [
|
|
516
544
|
|
|
517
|
-
/((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
|
|
518
|
-
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
|
519
|
-
|
|
520
545
|
/ sun4\w[;\)]/i // SPARC
|
|
521
546
|
], [[ARCHITECTURE, 'sparc']], [
|
|
522
|
-
|
|
523
|
-
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
|
|
524
547
|
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
|
|
525
|
-
]
|
|
548
|
+
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
|
|
549
|
+
/((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
|
|
550
|
+
/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
|
|
551
|
+
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
|
552
|
+
/mc680.0/i
|
|
553
|
+
], [[ARCHITECTURE, '68k']], [
|
|
554
|
+
/winnt.+\[axp/i
|
|
555
|
+
], [[ARCHITECTURE, 'alpha']]
|
|
526
556
|
],
|
|
527
557
|
|
|
528
558
|
device : [[
|
|
@@ -535,16 +565,15 @@
|
|
|
535
565
|
/\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
|
|
536
566
|
], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
|
|
537
567
|
/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
|
|
538
|
-
/samsung[- ]((?!sm-[lr])[-\w]+)/i,
|
|
568
|
+
/samsung[- ]((?!sm-[lr]|browser)[-\w]+)/i,
|
|
539
569
|
/sec-(sgh\w+)/i
|
|
540
570
|
], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
|
|
541
571
|
|
|
542
572
|
// Apple
|
|
543
|
-
/(?:\/|\()(ip(?:hone|od)[\w, ]*)
|
|
573
|
+
/(?:\/|\()(ip(?:hone|od)[\w, ]*)[\/\);]/i // iPod/iPhone
|
|
544
574
|
], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [
|
|
545
|
-
/\(
|
|
546
|
-
|
|
547
|
-
/\b(ipad)\d\d?,\d\d?[;\]].+ios/i
|
|
575
|
+
/\b(?:ios|apple\w+)\/.+[\(\/](ipad)/i, // iPad
|
|
576
|
+
/\b(ipad)[\d,]*[;\] ].+(mac |i(pad)?)os/i
|
|
548
577
|
], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [
|
|
549
578
|
/(macintosh);/i
|
|
550
579
|
], [MODEL, [VENDOR, APPLE]], [
|
|
@@ -562,13 +591,13 @@
|
|
|
562
591
|
// Huawei
|
|
563
592
|
/\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
|
|
564
593
|
], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
|
|
565
|
-
/(?:huawei)([-\w ]+)[;\)]/i,
|
|
566
|
-
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][
|
|
594
|
+
/(?:huawei) ?([-\w ]+)[;\)]/i,
|
|
595
|
+
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][\dc][adnt]?)\b(?!.+d\/s)/i
|
|
567
596
|
], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
|
|
568
597
|
|
|
569
598
|
// Xiaomi
|
|
570
599
|
/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,
|
|
571
|
-
/\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i
|
|
600
|
+
/\b(?:xiao)?((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i // Mi Pad tablets
|
|
572
601
|
],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [
|
|
573
602
|
|
|
574
603
|
/\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, // Xiaomi POCO
|
|
@@ -576,20 +605,26 @@
|
|
|
576
605
|
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
|
577
606
|
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
|
578
607
|
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
|
|
579
|
-
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note
|
|
608
|
+
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i, // Xiaomi Mi
|
|
580
609
|
/ ([\w ]+) miui\/v?\d/i
|
|
581
610
|
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
|
582
611
|
|
|
612
|
+
// OnePlus
|
|
613
|
+
/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,
|
|
614
|
+
/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
|
|
615
|
+
], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [
|
|
616
|
+
|
|
583
617
|
// OPPO
|
|
584
618
|
/; (\w+) bui.+ oppo/i,
|
|
585
619
|
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
|
586
620
|
], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [
|
|
587
621
|
/\b(opd2(\d{3}a?))(?: bui|\))/i
|
|
588
|
-
], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '
|
|
622
|
+
], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['203', '304', '403', '404', '413', '415'], '*' : OPPO }], [TYPE, TABLET]], [
|
|
623
|
+
|
|
624
|
+
// BLU
|
|
625
|
+
/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i // Vivo series
|
|
626
|
+
], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [
|
|
589
627
|
|
|
590
|
-
// BLU Vivo Series
|
|
591
|
-
/(vivo (5r?|6|8l?|go|one|s|x[il]?[2-4]?)[\w\+ ]*)(?: bui|\))/i
|
|
592
|
-
], [MODEL, [VENDOR, 'BLU'], [TYPE, MOBILE]], [
|
|
593
628
|
// Vivo
|
|
594
629
|
/; vivo (\w+)(?: bui|\))/i,
|
|
595
630
|
/\b(v[12]\d{3}\w?[at])(?: bui|;)/i
|
|
@@ -599,10 +634,17 @@
|
|
|
599
634
|
/\b(rmx[1-3]\d{3})(?: bui|;|\))/i
|
|
600
635
|
], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [
|
|
601
636
|
|
|
637
|
+
// Lenovo
|
|
638
|
+
/(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,
|
|
639
|
+
/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i
|
|
640
|
+
], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
|
|
641
|
+
/lenovo[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i
|
|
642
|
+
], [MODEL, [VENDOR, LENOVO], [TYPE, MOBILE]], [
|
|
643
|
+
|
|
602
644
|
// Motorola
|
|
603
645
|
/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,
|
|
604
|
-
/\bmot(?:orola)?[- ](\w
|
|
605
|
-
/((?:moto(?! 360)[
|
|
646
|
+
/\bmot(?:orola)?[- ]([\w\s]+)(\)| bui)/i,
|
|
647
|
+
/((?:moto(?! 360)[-\w\(\) ]+|xt\d{3,4}[cgkosw\+]?[-\d]*|nexus 6)(?= bui|\)))/i
|
|
606
648
|
], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [
|
|
607
649
|
/\b(mz60\d|xoom[2 ]{0,2}) build\//i
|
|
608
650
|
], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [
|
|
@@ -611,40 +653,33 @@
|
|
|
611
653
|
/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i
|
|
612
654
|
], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [
|
|
613
655
|
/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,
|
|
614
|
-
/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch))(\w+)/i,
|
|
656
|
+
/\blg[-e;\/ ]+(?!.*(?:browser|netcast|android tv|watch|webos))(\w+)/i,
|
|
615
657
|
/\blg-?([\d\w]+) bui/i
|
|
616
658
|
], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [
|
|
617
659
|
|
|
618
|
-
// Lenovo
|
|
619
|
-
/(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,
|
|
620
|
-
/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i
|
|
621
|
-
], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
|
|
622
|
-
|
|
623
660
|
// Nokia
|
|
624
661
|
/(nokia) (t[12][01])/i
|
|
625
662
|
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
|
626
663
|
/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,
|
|
627
|
-
/nokia[-_ ]?(([-\w\. ]
|
|
664
|
+
/nokia[-_ ]?(([-\w\. ]*?))( bui|\)|;|\/)/i
|
|
628
665
|
], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [
|
|
629
666
|
|
|
630
667
|
// Google
|
|
631
668
|
/(pixel (c|tablet))\b/i // Google Pixel C/Tablet
|
|
632
669
|
], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [
|
|
633
|
-
|
|
670
|
+
// Google Pixel
|
|
671
|
+
/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
|
|
634
672
|
], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
|
|
673
|
+
/(google) (pixelbook( go)?)/i
|
|
674
|
+
], [VENDOR, MODEL], [
|
|
635
675
|
|
|
636
676
|
// Sony
|
|
637
|
-
/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq
|
|
677
|
+
/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
|
|
638
678
|
], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
|
|
639
679
|
/sony tablet [ps]/i,
|
|
640
680
|
/\b(?:sony)?sgp\w+(?: bui|\))/i
|
|
641
681
|
], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [
|
|
642
682
|
|
|
643
|
-
// OnePlus
|
|
644
|
-
/ (kb2005|in20[12]5|be20[12][59])\b/i,
|
|
645
|
-
/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i
|
|
646
|
-
], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [
|
|
647
|
-
|
|
648
683
|
// Amazon
|
|
649
684
|
/(alexa)webm/i,
|
|
650
685
|
/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i, // Kindle Fire without Silk / Echo Show
|
|
@@ -657,7 +692,7 @@
|
|
|
657
692
|
/(playbook);[-\w\),; ]+(rim)/i // BlackBerry PlayBook
|
|
658
693
|
], [MODEL, VENDOR, [TYPE, TABLET]], [
|
|
659
694
|
/\b((?:bb[a-f]|st[hv])100-\d)/i,
|
|
660
|
-
|
|
695
|
+
/(?:blackberry|\(bb10;) (\w+)/i
|
|
661
696
|
], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [
|
|
662
697
|
|
|
663
698
|
// Asus
|
|
@@ -715,7 +750,7 @@
|
|
|
715
750
|
], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
|
|
716
751
|
|
|
717
752
|
// Nothing
|
|
718
|
-
/droid.+; (a(
|
|
753
|
+
/droid.+; (a(in)?(0(15|59|6[35])|142)p?)/i
|
|
719
754
|
], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
|
|
720
755
|
|
|
721
756
|
// Archos
|
|
@@ -726,18 +761,24 @@
|
|
|
726
761
|
/; (ac[3-6]\d\w{2,8})( b|\))/i
|
|
727
762
|
], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [
|
|
728
763
|
|
|
764
|
+
// HMD
|
|
765
|
+
/; (n159v)/i
|
|
766
|
+
], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [
|
|
767
|
+
|
|
729
768
|
// MIXED
|
|
730
769
|
/(imo) (tab \w+)/i, // IMO
|
|
731
|
-
/(infinix) (x1101b
|
|
770
|
+
/(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i // Infinix XPad / Tecno
|
|
732
771
|
], [VENDOR, MODEL, [TYPE, TABLET]], [
|
|
733
772
|
|
|
734
|
-
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|
|
|
735
|
-
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/
|
|
736
|
-
|
|
773
|
+
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
|
|
774
|
+
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
|
|
775
|
+
// BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
|
|
776
|
+
/; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,
|
|
737
777
|
/(hp) ([\w ]+\w)/i, // HP iPAQ
|
|
738
778
|
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
|
|
739
|
-
/(
|
|
740
|
-
/(
|
|
779
|
+
/(oppo) ?([\w ]+) bui/i, // OPPO
|
|
780
|
+
/(hisense) ([ehv][\w ]+)\)/i, // Hisense
|
|
781
|
+
/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i // Philips
|
|
741
782
|
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
|
742
783
|
|
|
743
784
|
/(kobo)\s(ereader|touch)/i, // Kobo
|
|
@@ -764,10 +805,12 @@
|
|
|
764
805
|
// SMARTTVS
|
|
765
806
|
///////////////////
|
|
766
807
|
|
|
808
|
+
/(philips)[\w ]+tv/i, // Philips
|
|
767
809
|
/smart-tv.+(samsung)/i // Samsung
|
|
768
810
|
], [VENDOR, [TYPE, SMARTTV]], [
|
|
769
811
|
/hbbtv.+maple;(\d+)/i
|
|
770
812
|
], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [
|
|
813
|
+
/(vizio)(?: |.+model\/)(\w+-\w+)/i, // Vizio
|
|
771
814
|
/tcast.+(lg)e?. ([-\w]+)/i // LG SmartTV
|
|
772
815
|
], [VENDOR, MODEL, [TYPE, SMARTTV]], [
|
|
773
816
|
/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i
|
|
@@ -799,26 +842,22 @@
|
|
|
799
842
|
], [VENDOR, MODEL, [TYPE, SMARTTV]], [
|
|
800
843
|
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
|
|
801
844
|
/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
|
|
802
|
-
], [[VENDOR,
|
|
803
|
-
// SmartTV from Unidentified Vendors
|
|
804
|
-
/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i
|
|
805
|
-
], [MODEL, [TYPE, SMARTTV]], [
|
|
806
|
-
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i
|
|
807
|
-
], [[TYPE, SMARTTV]], [
|
|
845
|
+
], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
|
|
808
846
|
|
|
809
847
|
///////////////////
|
|
810
848
|
// CONSOLES
|
|
811
849
|
///////////////////
|
|
812
850
|
|
|
813
|
-
/(ouya)/i, // Ouya
|
|
814
|
-
/(nintendo) (\w+)/i // Nintendo
|
|
815
|
-
], [VENDOR, MODEL, [TYPE, CONSOLE]], [
|
|
816
|
-
/droid.+; (shield)( bui|\))/i // Nvidia Portable
|
|
817
|
-
], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [
|
|
818
851
|
/(playstation \w+)/i // Playstation
|
|
819
852
|
], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [
|
|
820
853
|
/\b(xbox(?: one)?(?!; xbox))[\); ]/i // Microsoft Xbox
|
|
821
854
|
], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [
|
|
855
|
+
/(ouya)/i, // Ouya
|
|
856
|
+
/(nintendo) (\w+)/i, // Nintendo
|
|
857
|
+
/(retroid) (pocket ([^\)]+))/i // Retroid Pocket
|
|
858
|
+
], [VENDOR, MODEL, [TYPE, CONSOLE]], [
|
|
859
|
+
/droid.+; (shield)( bui|\))/i // Nvidia Portable
|
|
860
|
+
], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [
|
|
822
861
|
|
|
823
862
|
///////////////////
|
|
824
863
|
// WEARABLES
|
|
@@ -850,10 +889,12 @@
|
|
|
850
889
|
|
|
851
890
|
/droid.+; (glass) \d/i // Google Glass
|
|
852
891
|
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
|
853
|
-
/(pico) (
|
|
892
|
+
/(pico) ([\w ]+) os\d/i // Pico
|
|
854
893
|
], [VENDOR, MODEL, [TYPE, XR]], [
|
|
855
894
|
/(quest( \d| pro)?s?).+vr/i // Meta Quest
|
|
856
895
|
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
|
896
|
+
/mobile vr; rv.+firefox/i // Unidentifiable VR device using Firefox Reality / Wolvic
|
|
897
|
+
], [[TYPE, XR]], [
|
|
857
898
|
|
|
858
899
|
///////////////////
|
|
859
900
|
// EMBEDDED
|
|
@@ -865,14 +906,18 @@
|
|
|
865
906
|
], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [
|
|
866
907
|
/(homepod).+mac os/i // Apple HomePod
|
|
867
908
|
], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [
|
|
868
|
-
/windows iot/i
|
|
909
|
+
/windows iot/i // Unidentifiable embedded device using Windows IoT
|
|
869
910
|
], [[TYPE, EMBEDDED]], [
|
|
870
911
|
|
|
871
912
|
////////////////////
|
|
872
913
|
// MIXED (GENERIC)
|
|
873
914
|
///////////////////
|
|
874
915
|
|
|
875
|
-
/droid
|
|
916
|
+
/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i // Unidentifiable SmartTV
|
|
917
|
+
], [MODEL, [TYPE, SMARTTV]], [
|
|
918
|
+
/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
|
|
919
|
+
], [[TYPE, SMARTTV]], [
|
|
920
|
+
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew|; hmsc).+?(mobile|vr|\d) safari/i
|
|
876
921
|
], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
|
|
877
922
|
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
|
|
878
923
|
], [[TYPE, TABLET]], [
|
|
@@ -911,22 +956,25 @@
|
|
|
911
956
|
os : [[
|
|
912
957
|
|
|
913
958
|
// Windows
|
|
914
|
-
/
|
|
959
|
+
/(windows nt) (6\.[23]); arm/i // Windows RT
|
|
960
|
+
], [[NAME, /N/, 'R'], [VERSION, strMapper, windowsVersionMap]], [
|
|
961
|
+
/(windows (?:phone|mobile|iot))(?: os)?[\/ ]?([\d\.]*( se)?)/i, // Windows IoT/Mobile/Phone
|
|
962
|
+
// Windows NT/3.1/95/98/ME/2000/XP/Vista/7/8/8.1/10/11
|
|
963
|
+
/(windows)[\/ ](1[01]|2000|3\.1|7|8(\.1)?|9[58]|me|server 20\d\d( r2)?|vista|xp)/i
|
|
964
|
+
], [NAME, VERSION], [
|
|
965
|
+
/windows nt ?([\d\.\)]*)(?!.+xbox)/i,
|
|
966
|
+
/\bwin(?=3| ?9|n)(?:nt| 9x )?([\d\.;]*)/i
|
|
967
|
+
], [[VERSION, /(;|\))/g, '', strMapper, windowsVersionMap], [NAME, WINDOWS]], [
|
|
968
|
+
/(windows ce)\/?([\d\.]*)/i // Windows CE
|
|
915
969
|
], [NAME, VERSION], [
|
|
916
|
-
/(windows (?:phone(?: os)?|mobile|iot))[\/ ]?([\d\.\w ]*)/i // Windows Phone
|
|
917
|
-
], [NAME, [VERSION, strMapper, windowsVersionMap]], [
|
|
918
|
-
/windows nt 6\.2; (arm)/i, // Windows RT
|
|
919
|
-
/windows[\/ ]([ntce\d\. ]+\w)(?!.+xbox)/i,
|
|
920
|
-
/(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
|
921
|
-
], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [
|
|
922
970
|
|
|
923
971
|
// iOS/macOS
|
|
924
972
|
/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
|
925
|
-
/(?:ios;fbsv
|
|
973
|
+
/(?:ios;fbsv|ios(?=.+ip(?:ad|hone))|ip(?:ad|hone)(?: |.+i(?:pad)?)os)[\/ ]([\w\.]+)/i,
|
|
926
974
|
/cfnetwork\/.+darwin/i
|
|
927
975
|
], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [
|
|
928
976
|
/(mac os x) ?([\w\. ]*)/i,
|
|
929
|
-
/(macintosh|mac_powerpc\b)(?!.+haiku)/i
|
|
977
|
+
/(macintosh|mac_powerpc\b)(?!.+(haiku|morphos))/i // Mac OS
|
|
930
978
|
], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
|
|
931
979
|
|
|
932
980
|
// Google Chromecast
|
|
@@ -942,12 +990,13 @@
|
|
|
942
990
|
], [VERSION, [NAME, CHROMECAST]], [
|
|
943
991
|
|
|
944
992
|
// Mobile OSes
|
|
945
|
-
/droid ([\w\.]+)\b.+(android[- ]x86
|
|
993
|
+
/droid ([\w\.]+)\b.+(android[- ]x86)/i // Android-x86
|
|
946
994
|
], [VERSION, NAME], [
|
|
947
995
|
/(ubuntu) ([\w\.]+) like android/i // Ubuntu Touch
|
|
948
996
|
], [[NAME, /(.+)/, '$1 Touch'], VERSION], [
|
|
997
|
+
/(harmonyos)[\/ ]?([\d\.]*)/i, // HarmonyOS
|
|
949
998
|
// Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen
|
|
950
|
-
/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen
|
|
999
|
+
/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen)\w*[-\/\.; ]?([\d\.]*)/i
|
|
951
1000
|
], [NAME, VERSION], [
|
|
952
1001
|
/\(bb(10);/i // BlackBerry 10
|
|
953
1002
|
], [VERSION, [NAME, BLACKBERRY]], [
|
|
@@ -955,9 +1004,12 @@
|
|
|
955
1004
|
], [VERSION, [NAME, 'Symbian']], [
|
|
956
1005
|
/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i // Firefox OS
|
|
957
1006
|
], [VERSION, [NAME, FIREFOX+' OS']], [
|
|
958
|
-
|
|
959
|
-
|
|
1007
|
+
/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i, // WebOS
|
|
1008
|
+
/webos(?:[ \/]?|\.tv-20(?=2[2-9]))(\d[\d\.]*)/i
|
|
960
1009
|
], [VERSION, [NAME, 'webOS']], [
|
|
1010
|
+
/web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i
|
|
1011
|
+
// https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine
|
|
1012
|
+
], [[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']], [
|
|
961
1013
|
/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
|
|
962
1014
|
], [VERSION, [NAME, 'watchOS']], [
|
|
963
1015
|
|
|
@@ -977,20 +1029,20 @@
|
|
|
977
1029
|
|
|
978
1030
|
// Other
|
|
979
1031
|
/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
|
|
980
|
-
/(mint)[\/\(\) ]?(\w*)/i,
|
|
981
|
-
/(mageia|vectorlinux)[; ]/i,
|
|
982
|
-
/([kxln]?ubuntu|debian|suse|opensuse|gentoo|
|
|
983
|
-
// Ubuntu/Debian/SUSE/Gentoo/
|
|
984
|
-
/(
|
|
1032
|
+
/linux.+(mint)[\/\(\) ]?([\w\.]*)/i, // Mint
|
|
1033
|
+
/(mageia|vectorlinux|fuchsia|arcaos|arch(?= ?linux))[;l ]([\d\.]*)/i, // Mageia/VectorLinux/Fuchsia/ArcaOS/Arch
|
|
1034
|
+
/([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,
|
|
1035
|
+
// Ubuntu/Debian/SUSE/Gentoo/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire/Knoppix
|
|
1036
|
+
/((?:open)?solaris)[-\/ ]?([\w\.]*)/i, // Solaris
|
|
1037
|
+
/\b(aix)[; ]([1-9\.]{0,4})/i, // AIX
|
|
1038
|
+
/(hurd|linux|morphos)(?: (?:arm|x86|ppc)\w*| ?)([\w\.]*)/i, // Hurd/Linux/MorphOS
|
|
985
1039
|
/(gnu) ?([\w\.]*)/i, // GNU
|
|
986
1040
|
/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly
|
|
987
|
-
/(haiku) (\
|
|
1041
|
+
/(haiku) ?(r\d)?/i // Haiku
|
|
988
1042
|
], [NAME, VERSION], [
|
|
989
|
-
/(sunos) ?([\
|
|
1043
|
+
/(sunos) ?([\d\.]*)/i // Solaris
|
|
990
1044
|
], [[NAME, 'Solaris'], VERSION], [
|
|
991
|
-
|
|
992
|
-
/(aix) ((\d)(?=\.|\)| )[\w\.])*/i, // AIX
|
|
993
|
-
/\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS
|
|
1045
|
+
/\b(beos|os\/2|amigaos|openvms|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/OpenVMS/HP-UX/SerenityOS
|
|
994
1046
|
/(unix) ?([\w\.]*)/i // UNIX
|
|
995
1047
|
], [NAME, VERSION]
|
|
996
1048
|
]
|
|
@@ -1003,27 +1055,27 @@
|
|
|
1003
1055
|
var defaultProps = (function () {
|
|
1004
1056
|
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
|
1005
1057
|
setProps.call(props.init, [
|
|
1006
|
-
[
|
|
1007
|
-
[
|
|
1008
|
-
[
|
|
1009
|
-
[
|
|
1010
|
-
[
|
|
1058
|
+
[BROWSER, [NAME, VERSION, MAJOR, TYPE]],
|
|
1059
|
+
[CPU, [ARCHITECTURE]],
|
|
1060
|
+
[DEVICE, [TYPE, MODEL, VENDOR]],
|
|
1061
|
+
[ENGINE, [NAME, VERSION]],
|
|
1062
|
+
[OS, [NAME, VERSION]]
|
|
1011
1063
|
]);
|
|
1012
1064
|
setProps.call(props.isIgnore, [
|
|
1013
|
-
[
|
|
1014
|
-
[
|
|
1015
|
-
[
|
|
1065
|
+
[BROWSER, [VERSION, MAJOR]],
|
|
1066
|
+
[ENGINE, [VERSION]],
|
|
1067
|
+
[OS, [VERSION]]
|
|
1016
1068
|
]);
|
|
1017
1069
|
setProps.call(props.isIgnoreRgx, [
|
|
1018
|
-
[
|
|
1019
|
-
[
|
|
1070
|
+
[BROWSER, / ?browser$/i],
|
|
1071
|
+
[OS, / ?os$/i]
|
|
1020
1072
|
]);
|
|
1021
1073
|
setProps.call(props.toString, [
|
|
1022
|
-
[
|
|
1023
|
-
[
|
|
1024
|
-
[
|
|
1025
|
-
[
|
|
1026
|
-
[
|
|
1074
|
+
[BROWSER, [NAME, VERSION]],
|
|
1075
|
+
[CPU, [ARCHITECTURE]],
|
|
1076
|
+
[DEVICE, [VENDOR, MODEL]],
|
|
1077
|
+
[ENGINE, [NAME, VERSION]],
|
|
1078
|
+
[OS, [NAME, VERSION]]
|
|
1027
1079
|
]);
|
|
1028
1080
|
return props;
|
|
1029
1081
|
})();
|
|
@@ -1067,14 +1119,14 @@
|
|
|
1067
1119
|
return item.detectFeature().get();
|
|
1068
1120
|
};
|
|
1069
1121
|
|
|
1070
|
-
if (itemType !=
|
|
1122
|
+
if (itemType != RESULT) {
|
|
1071
1123
|
IData.prototype.is = function (strToCheck) {
|
|
1072
1124
|
var is = false;
|
|
1073
1125
|
for (var i in this) {
|
|
1074
1126
|
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)) {
|
|
1075
1127
|
is = true;
|
|
1076
|
-
if (strToCheck !=
|
|
1077
|
-
} else if (strToCheck ==
|
|
1128
|
+
if (strToCheck != TYPEOF.UNDEFINED) break;
|
|
1129
|
+
} else if (strToCheck == TYPEOF.UNDEFINED && is) {
|
|
1078
1130
|
is = !is;
|
|
1079
1131
|
break;
|
|
1080
1132
|
}
|
|
@@ -1084,11 +1136,11 @@
|
|
|
1084
1136
|
IData.prototype.toString = function () {
|
|
1085
1137
|
var str = EMPTY;
|
|
1086
1138
|
for (var i in toString_props) {
|
|
1087
|
-
if (typeof(this[toString_props[i]]) !==
|
|
1139
|
+
if (typeof(this[toString_props[i]]) !== TYPEOF.UNDEFINED) {
|
|
1088
1140
|
str += (str ? ' ' : EMPTY) + this[toString_props[i]];
|
|
1089
1141
|
}
|
|
1090
1142
|
}
|
|
1091
|
-
return str ||
|
|
1143
|
+
return str || TYPEOF.UNDEFINED;
|
|
1092
1144
|
};
|
|
1093
1145
|
}
|
|
1094
1146
|
|
|
@@ -1124,19 +1176,19 @@
|
|
|
1124
1176
|
setProps.call(this, CH_ALL_VALUES);
|
|
1125
1177
|
if (isHttpUACH) {
|
|
1126
1178
|
setProps.call(this, [
|
|
1127
|
-
[BRANDS, itemListToArray(uach[
|
|
1128
|
-
[FULLVERLIST, itemListToArray(uach[
|
|
1129
|
-
[MOBILE, /\?1/.test(uach[
|
|
1130
|
-
[MODEL, stripQuotes(uach[
|
|
1131
|
-
[PLATFORM, stripQuotes(uach[
|
|
1132
|
-
[PLATFORMVER, stripQuotes(uach[
|
|
1133
|
-
[ARCHITECTURE, stripQuotes(uach[
|
|
1134
|
-
[FORMFACTORS, itemListToArray(uach[
|
|
1135
|
-
[BITNESS, stripQuotes(uach[
|
|
1179
|
+
[BRANDS, itemListToArray(uach[CH])],
|
|
1180
|
+
[FULLVERLIST, itemListToArray(uach[CH_FULL_VER_LIST])],
|
|
1181
|
+
[MOBILE, /\?1/.test(uach[CH_MOBILE])],
|
|
1182
|
+
[MODEL, stripQuotes(uach[CH_MODEL])],
|
|
1183
|
+
[PLATFORM, stripQuotes(uach[CH_PLATFORM])],
|
|
1184
|
+
[PLATFORMVER, stripQuotes(uach[CH_PLATFORM_VER])],
|
|
1185
|
+
[ARCHITECTURE, stripQuotes(uach[CH_ARCH])],
|
|
1186
|
+
[FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],
|
|
1187
|
+
[BITNESS, stripQuotes(uach[CH_BITNESS])]
|
|
1136
1188
|
]);
|
|
1137
1189
|
} else {
|
|
1138
1190
|
for (var prop in uach) {
|
|
1139
|
-
if(this.hasOwnProperty(prop) && typeof uach[prop] !==
|
|
1191
|
+
if(this.hasOwnProperty(prop) && typeof uach[prop] !== TYPEOF.UNDEFINED) this[prop] = uach[prop];
|
|
1140
1192
|
}
|
|
1141
1193
|
}
|
|
1142
1194
|
}
|
|
@@ -1161,30 +1213,30 @@
|
|
|
1161
1213
|
this.detectFeature = function () {
|
|
1162
1214
|
if (NAVIGATOR && NAVIGATOR.userAgent == this.ua) {
|
|
1163
1215
|
switch (this.itemType) {
|
|
1164
|
-
case
|
|
1216
|
+
case BROWSER:
|
|
1165
1217
|
// Brave-specific detection
|
|
1166
|
-
if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave ==
|
|
1218
|
+
if (NAVIGATOR.brave && typeof NAVIGATOR.brave.isBrave == TYPEOF.FUNCTION) {
|
|
1167
1219
|
this.set(NAME, 'Brave');
|
|
1168
1220
|
}
|
|
1169
1221
|
break;
|
|
1170
|
-
case
|
|
1222
|
+
case DEVICE:
|
|
1171
1223
|
// Chrome-specific detection: check for 'mobile' value of navigator.userAgentData
|
|
1172
1224
|
if (!this.get(TYPE) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[MOBILE]) {
|
|
1173
1225
|
this.set(TYPE, MOBILE);
|
|
1174
1226
|
}
|
|
1175
1227
|
// iPadOS-specific detection: identified as Mac, but has some iOS-only properties
|
|
1176
|
-
if (this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !==
|
|
1228
|
+
if (this.get(MODEL) == 'Macintosh' && NAVIGATOR && typeof NAVIGATOR.standalone !== TYPEOF.UNDEFINED && NAVIGATOR.maxTouchPoints && NAVIGATOR.maxTouchPoints > 2) {
|
|
1177
1229
|
this.set(MODEL, 'iPad')
|
|
1178
1230
|
.set(TYPE, TABLET);
|
|
1179
1231
|
}
|
|
1180
1232
|
break;
|
|
1181
|
-
case
|
|
1233
|
+
case OS:
|
|
1182
1234
|
// Chrome-specific detection: check for 'platform' value of navigator.userAgentData
|
|
1183
1235
|
if (!this.get(NAME) && NAVIGATOR_UADATA && NAVIGATOR_UADATA[PLATFORM]) {
|
|
1184
1236
|
this.set(NAME, NAVIGATOR_UADATA[PLATFORM]);
|
|
1185
1237
|
}
|
|
1186
1238
|
break;
|
|
1187
|
-
case
|
|
1239
|
+
case RESULT:
|
|
1188
1240
|
var data = this.data;
|
|
1189
1241
|
var detect = function (itemType) {
|
|
1190
1242
|
return data[itemType]
|
|
@@ -1192,22 +1244,33 @@
|
|
|
1192
1244
|
.detectFeature()
|
|
1193
1245
|
.get();
|
|
1194
1246
|
};
|
|
1195
|
-
this.set(
|
|
1196
|
-
.set(
|
|
1197
|
-
.set(
|
|
1198
|
-
.set(
|
|
1199
|
-
.set(
|
|
1247
|
+
this.set(BROWSER, detect(BROWSER))
|
|
1248
|
+
.set(CPU, detect(CPU))
|
|
1249
|
+
.set(DEVICE, detect(DEVICE))
|
|
1250
|
+
.set(ENGINE, detect(ENGINE))
|
|
1251
|
+
.set(OS, detect(OS));
|
|
1200
1252
|
}
|
|
1201
1253
|
}
|
|
1202
1254
|
return this;
|
|
1203
1255
|
};
|
|
1204
1256
|
|
|
1205
1257
|
this.parseUA = function () {
|
|
1206
|
-
if (this.itemType !=
|
|
1258
|
+
if (this.itemType != RESULT) {
|
|
1207
1259
|
rgxMapper.call(this.data, this.ua, this.rgxMap);
|
|
1208
1260
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1261
|
+
switch (this.itemType) {
|
|
1262
|
+
case BROWSER:
|
|
1263
|
+
this.set(MAJOR, majorize(this.get(VERSION)));
|
|
1264
|
+
break;
|
|
1265
|
+
case OS:
|
|
1266
|
+
if (this.get(NAME) == 'iOS' && this.get(VERSION) == '18.6') {
|
|
1267
|
+
// Based on the assumption that iOS version is tightly coupled with Safari version
|
|
1268
|
+
var realVersion = /\) Version\/([\d\.]+)/.exec(this.ua); // Get Safari version
|
|
1269
|
+
if (realVersion && parseInt(realVersion[1].substring(0,2), 10) >= 26) {
|
|
1270
|
+
this.set(VERSION, realVersion[1]); // Set as iOS version
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
break;
|
|
1211
1274
|
}
|
|
1212
1275
|
return this;
|
|
1213
1276
|
};
|
|
@@ -1217,43 +1280,42 @@
|
|
|
1217
1280
|
rgxMap = this.rgxMap;
|
|
1218
1281
|
|
|
1219
1282
|
switch (this.itemType) {
|
|
1220
|
-
case
|
|
1221
|
-
case
|
|
1283
|
+
case BROWSER:
|
|
1284
|
+
case ENGINE:
|
|
1222
1285
|
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
|
|
1223
1286
|
if (brands) {
|
|
1224
|
-
for (var i
|
|
1287
|
+
for (var i=0; i<brands.length; i++) {
|
|
1225
1288
|
var brandName = brands[i].brand || brands[i],
|
|
1226
1289
|
brandVersion = brands[i].version;
|
|
1227
|
-
if (this.itemType ==
|
|
1228
|
-
brandName
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
prevName = brandName;
|
|
1290
|
+
if (this.itemType == BROWSER &&
|
|
1291
|
+
!/not.a.brand/i.test(brandName) &&
|
|
1292
|
+
(!prevName ||
|
|
1293
|
+
(/Chrom/.test(prevName) && brandName != CHROMIUM) ||
|
|
1294
|
+
(prevName == EDGE && /WebView2/.test(brandName))
|
|
1295
|
+
)) {
|
|
1296
|
+
brandName = strMapper(brandName, browserHintsMap);
|
|
1297
|
+
prevName = this.get(NAME);
|
|
1298
|
+
if (!(prevName && !/Chrom/.test(prevName) && /Chrom/.test(brandName))) {
|
|
1299
|
+
this.set(NAME, brandName)
|
|
1300
|
+
.set(VERSION, brandVersion)
|
|
1301
|
+
.set(MAJOR, majorize(brandVersion));
|
|
1302
|
+
}
|
|
1303
|
+
prevName = brandName;
|
|
1242
1304
|
}
|
|
1243
|
-
if (this.itemType ==
|
|
1305
|
+
if (this.itemType == ENGINE && brandName == CHROMIUM) {
|
|
1244
1306
|
this.set(VERSION, brandVersion);
|
|
1245
1307
|
}
|
|
1246
1308
|
}
|
|
1247
1309
|
}
|
|
1248
1310
|
break;
|
|
1249
|
-
case
|
|
1311
|
+
case CPU:
|
|
1250
1312
|
var archName = uaCH[ARCHITECTURE];
|
|
1251
1313
|
if (archName) {
|
|
1252
1314
|
if (archName && uaCH[BITNESS] == '64') archName += '64';
|
|
1253
1315
|
rgxMapper.call(this.data, archName + ';', rgxMap);
|
|
1254
1316
|
}
|
|
1255
1317
|
break;
|
|
1256
|
-
case
|
|
1318
|
+
case DEVICE:
|
|
1257
1319
|
if (uaCH[MOBILE]) {
|
|
1258
1320
|
this.set(TYPE, MOBILE);
|
|
1259
1321
|
}
|
|
@@ -1283,7 +1345,7 @@
|
|
|
1283
1345
|
this.set(TYPE, ff);
|
|
1284
1346
|
}
|
|
1285
1347
|
break;
|
|
1286
|
-
case
|
|
1348
|
+
case OS:
|
|
1287
1349
|
var osName = uaCH[PLATFORM];
|
|
1288
1350
|
if(osName) {
|
|
1289
1351
|
var osVersion = uaCH[PLATFORMVER];
|
|
@@ -1297,7 +1359,7 @@
|
|
|
1297
1359
|
.set(VERSION, undefined);
|
|
1298
1360
|
}
|
|
1299
1361
|
break;
|
|
1300
|
-
case
|
|
1362
|
+
case RESULT:
|
|
1301
1363
|
var data = this.data;
|
|
1302
1364
|
var parse = function (itemType) {
|
|
1303
1365
|
return data[itemType]
|
|
@@ -1306,11 +1368,11 @@
|
|
|
1306
1368
|
.parseCH()
|
|
1307
1369
|
.get();
|
|
1308
1370
|
};
|
|
1309
|
-
this.set(
|
|
1310
|
-
.set(
|
|
1311
|
-
.set(
|
|
1312
|
-
.set(
|
|
1313
|
-
.set(
|
|
1371
|
+
this.set(BROWSER, parse(BROWSER))
|
|
1372
|
+
.set(CPU, parse(CPU))
|
|
1373
|
+
.set(DEVICE, parse(DEVICE))
|
|
1374
|
+
.set(ENGINE, parse(ENGINE))
|
|
1375
|
+
.set(OS, parse(OS));
|
|
1314
1376
|
}
|
|
1315
1377
|
return this;
|
|
1316
1378
|
};
|
|
@@ -1328,9 +1390,9 @@
|
|
|
1328
1390
|
|
|
1329
1391
|
function UAParser (ua, extensions, headers) {
|
|
1330
1392
|
|
|
1331
|
-
if (typeof ua ===
|
|
1393
|
+
if (typeof ua === TYPEOF.OBJECT) {
|
|
1332
1394
|
if (isExtensions(ua, true)) {
|
|
1333
|
-
if (typeof extensions ===
|
|
1395
|
+
if (typeof extensions === TYPEOF.OBJECT) {
|
|
1334
1396
|
headers = extensions; // case UAParser(extensions, headers)
|
|
1335
1397
|
}
|
|
1336
1398
|
extensions = ua; // case UAParser(extensions)
|
|
@@ -1339,23 +1401,34 @@
|
|
|
1339
1401
|
extensions = undefined;
|
|
1340
1402
|
}
|
|
1341
1403
|
ua = undefined;
|
|
1342
|
-
} else if (typeof ua ===
|
|
1404
|
+
} else if (typeof ua === TYPEOF.STRING && !isExtensions(extensions, true)) {
|
|
1343
1405
|
headers = extensions; // case UAParser(ua, headers)
|
|
1344
1406
|
extensions = undefined;
|
|
1345
1407
|
}
|
|
1346
1408
|
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1409
|
+
if (headers) {
|
|
1410
|
+
if (typeof headers.append === TYPEOF.FUNCTION) {
|
|
1411
|
+
// Convert Headers object into a plain object
|
|
1412
|
+
var kv = {};
|
|
1413
|
+
headers.forEach(function (v, k) { kv[String(k).toLowerCase()] = v; });
|
|
1414
|
+
headers = kv;
|
|
1415
|
+
} else {
|
|
1416
|
+
// Normalize headers field name into lowercase
|
|
1417
|
+
var normalized = {};
|
|
1418
|
+
for (var header in headers) {
|
|
1419
|
+
if (headers.hasOwnProperty(header)) {
|
|
1420
|
+
normalized[String(header).toLowerCase()] = headers[header];
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
headers = normalized;
|
|
1424
|
+
}
|
|
1352
1425
|
}
|
|
1353
1426
|
|
|
1354
1427
|
if (!(this instanceof UAParser)) {
|
|
1355
1428
|
return new UAParser(ua, extensions, headers).getResult();
|
|
1356
1429
|
}
|
|
1357
1430
|
|
|
1358
|
-
var userAgent = typeof ua ===
|
|
1431
|
+
var userAgent = typeof ua === TYPEOF.STRING ? ua : // Passed user-agent string
|
|
1359
1432
|
(headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
|
|
1360
1433
|
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
|
|
1361
1434
|
EMPTY)), // empty string
|
|
@@ -1366,15 +1439,15 @@
|
|
|
1366
1439
|
defaultRegexes,
|
|
1367
1440
|
|
|
1368
1441
|
createItemFunc = function (itemType) {
|
|
1369
|
-
if (itemType ==
|
|
1442
|
+
if (itemType == RESULT) {
|
|
1370
1443
|
return function () {
|
|
1371
1444
|
return new UAItem(itemType, userAgent, regexMap, httpUACH)
|
|
1372
1445
|
.set('ua', userAgent)
|
|
1373
|
-
.set(
|
|
1374
|
-
.set(
|
|
1375
|
-
.set(
|
|
1376
|
-
.set(
|
|
1377
|
-
.set(
|
|
1446
|
+
.set(BROWSER, this.getBrowser())
|
|
1447
|
+
.set(CPU, this.getCPU())
|
|
1448
|
+
.set(DEVICE, this.getDevice())
|
|
1449
|
+
.set(ENGINE, this.getEngine())
|
|
1450
|
+
.set(OS, this.getOS())
|
|
1378
1451
|
.get();
|
|
1379
1452
|
};
|
|
1380
1453
|
} else {
|
|
@@ -1388,16 +1461,15 @@
|
|
|
1388
1461
|
|
|
1389
1462
|
// public methods
|
|
1390
1463
|
setProps.call(this, [
|
|
1391
|
-
['getBrowser', createItemFunc(
|
|
1392
|
-
['getCPU', createItemFunc(
|
|
1393
|
-
['getDevice', createItemFunc(
|
|
1394
|
-
['getEngine', createItemFunc(
|
|
1395
|
-
['getOS', createItemFunc(
|
|
1396
|
-
['getResult', createItemFunc(
|
|
1464
|
+
['getBrowser', createItemFunc(BROWSER)],
|
|
1465
|
+
['getCPU', createItemFunc(CPU)],
|
|
1466
|
+
['getDevice', createItemFunc(DEVICE)],
|
|
1467
|
+
['getEngine', createItemFunc(ENGINE)],
|
|
1468
|
+
['getOS', createItemFunc(OS)],
|
|
1469
|
+
['getResult', createItemFunc(RESULT)],
|
|
1397
1470
|
['getUA', function () { return userAgent; }],
|
|
1398
1471
|
['setUA', function (ua) {
|
|
1399
|
-
if (isString(ua))
|
|
1400
|
-
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
|
|
1472
|
+
if (isString(ua)) userAgent = trim(ua, UA_MAX_LENGTH);
|
|
1401
1473
|
return this;
|
|
1402
1474
|
}]
|
|
1403
1475
|
])
|