ua-parser-js 2.0.0-rc.1 → 2.0.0-rc.3

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.
@@ -1,5 +1,5 @@
1
1
  ///////////////////////////////////////////////
2
- /* Helpers for UAParser.js v2.0.0-rc.1
2
+ /* Helpers for UAParser.js v2.0.0-rc.3
3
3
  https://github.com/faisalman/ua-parser-js
4
4
  Author: Faisal Salman <f@faisalman.com>
5
5
  AGPLv3 License */
@@ -7,52 +7,47 @@
7
7
 
8
8
  /*jshint esversion: 6 */
9
9
 
10
- const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
11
10
  const { UAParser } = require('../main/ua-parser');
11
+ const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
12
12
  const { isFromEU } = require('detect-europe-js');
13
+ const { isFrozenUA } = require('ua-is-frozen');
14
+ const { isStandalonePWA } = require('is-standalone-pwa');
13
15
 
14
16
  const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36`).device.vendor;
15
17
 
16
- const isAppleSilicon = (res) => {
18
+ const isAppleSilicon = (res, useFeatureDetection) => {
17
19
  if (res.os.is(OS.MACOS)) {
18
20
  if (res.cpu.is(CPU.ARM)) {
19
21
  return true;
20
22
  }
21
- try {
22
- const canvas = document.createElement('canvas');
23
- const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
24
- const debug = webgl.getExtension('WEBGL_debug_renderer_info');
25
- const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
26
- if (renderer.match(/apple m\d/i)) {
27
- return true;
23
+ if (useFeatureDetection) {
24
+ try {
25
+ const canvas = document.createElement('canvas');
26
+ const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
27
+ const debug = webgl.getExtension('WEBGL_debug_renderer_info');
28
+ const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
29
+ if (renderer.match(/apple m\d/i)) {
30
+ return true;
31
+ }
32
+ } catch {
33
+ return false;
28
34
  }
29
- } catch {
30
- return false;
31
35
  }
32
36
  }
33
37
  return false;
34
38
  }
35
39
 
40
+ const isBot = (res) => ['cli', 'crawler', 'fetcher', 'library'].includes(res.browser.type);
41
+
36
42
  const isChromeFamily = (res) => res.engine.is(Engine.BLINK);
37
43
 
38
44
  const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
39
45
  / electron\//i.test(navigator?.userAgent)); // browser
40
46
 
41
- const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua);
42
-
43
- const isStandalonePWA = () => window && (window.matchMedia('(display-mode: standalone)').matches ||
44
- // iOS
45
- navigator.standalone ||
46
- // Android
47
- document.referrer.startsWith('android-app://') ||
48
- // Windows
49
- window.Windows ||
50
- /trident.+(msapphost|webview)\//i.test(navigator.userAgent) ||
51
- document.referrer.startsWith('app-info://platform/microsoft-store'));
52
-
53
47
  module.exports = {
54
48
  getDeviceVendor,
55
49
  isAppleSilicon,
50
+ isBot,
56
51
  isChromeFamily,
57
52
  isElectron,
58
53
  isFromEU,
@@ -3,7 +3,7 @@
3
3
  // Source: /src/helpers/ua-parser-helpers.js
4
4
 
5
5
  ///////////////////////////////////////////////
6
- /* Helpers for UAParser.js v2.0.0-rc.1
6
+ /* Helpers for UAParser.js v2.0.0-rc.3
7
7
  https://github.com/faisalman/ua-parser-js
8
8
  Author: Faisal Salman <f@faisalman.com>
9
9
  AGPLv3 License */
@@ -11,52 +11,47 @@
11
11
 
12
12
  /*jshint esversion: 6 */
13
13
 
14
- import { CPU, OS, Engine } from './enums/ua-parser-enums.mjs';
15
- import { UAParser } from './main/ua-parser.mjs';
14
+ import { UAParser } from '../main/ua-parser.mjs';
15
+ import { CPU, OS, Engine } from '../enums/ua-parser-enums.mjs';
16
16
  import { isFromEU } from 'detect-europe-js';
17
+ import { isFrozenUA } from 'ua-is-frozen';
18
+ import { isStandalonePWA } from 'is-standalone-pwa';
17
19
 
18
20
  const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${model}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.0.0 Safari/537.36`).device.vendor;
19
21
 
20
- const isAppleSilicon = (res) => {
22
+ const isAppleSilicon = (res, useFeatureDetection) => {
21
23
  if (res.os.is(OS.MACOS)) {
22
24
  if (res.cpu.is(CPU.ARM)) {
23
25
  return true;
24
26
  }
25
- try {
26
- const canvas = document.createElement('canvas');
27
- const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
28
- const debug = webgl.getExtension('WEBGL_debug_renderer_info');
29
- const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
30
- if (renderer.match(/apple m\d/i)) {
31
- return true;
27
+ if (useFeatureDetection) {
28
+ try {
29
+ const canvas = document.createElement('canvas');
30
+ const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
31
+ const debug = webgl.getExtension('WEBGL_debug_renderer_info');
32
+ const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
33
+ if (renderer.match(/apple m\d/i)) {
34
+ return true;
35
+ }
36
+ } catch {
37
+ return false;
32
38
  }
33
- } catch {
34
- return false;
35
39
  }
36
40
  }
37
41
  return false;
38
42
  }
39
43
 
44
+ const isBot = (res) => ['cli', 'crawler', 'fetcher', 'library'].includes(res.browser.type);
45
+
40
46
  const isChromeFamily = (res) => res.engine.is(Engine.BLINK);
41
47
 
42
48
  const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
43
49
  / electron\//i.test(navigator?.userAgent)); // browser
44
50
 
45
- const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua);
46
-
47
- const isStandalonePWA = () => window && (window.matchMedia('(display-mode: standalone)').matches ||
48
- // iOS
49
- navigator.standalone ||
50
- // Android
51
- document.referrer.startsWith('android-app://') ||
52
- // Windows
53
- window.Windows ||
54
- /trident.+(msapphost|webview)\//i.test(navigator.userAgent) ||
55
- document.referrer.startsWith('app-info://platform/microsoft-store'));
56
-
57
51
  export {
58
52
  getDeviceVendor,
59
53
  isAppleSilicon,
54
+ isBot,
60
55
  isChromeFamily,
61
56
  isElectron,
62
57
  isFromEU,
@@ -1,4 +1,4 @@
1
- // Type definitions for UAParser.js v2.0.0-beta.3
1
+ // Type definitions for UAParser.js v2.0.0-rc.3
2
2
  // Project: https://github.com/faisalman/ua-parser-js
3
3
  // Definitions by: Faisal Salman <https://github.com/faisalman>
4
4
 
@@ -15,11 +15,11 @@ declare namespace UAParser {
15
15
  name?: string;
16
16
  version?: string;
17
17
  major?: string;
18
- type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'module';
18
+ type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'library';
19
19
  }
20
20
 
21
21
  interface ICPU extends IData<ICPU> {
22
- architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'ppc' | 'sparc' | 'sparc64';
22
+ architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'avr32' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'pa-risc' | 'ppc' | 'sparc' | 'sparc64';
23
23
  }
24
24
 
25
25
  interface IDevice extends IData<IDevice> {
@@ -29,7 +29,7 @@ declare namespace UAParser {
29
29
  }
30
30
 
31
31
  interface IEngine extends IData<IEngine> {
32
- name?: 'Amaya' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
32
+ name?: 'Amaya' | 'ArkWeb' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Servo' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
33
33
  version?: string;
34
34
  }
35
35
 
@@ -1,5 +1,5 @@
1
1
  /////////////////////////////////////////////////////////////////////////////////
2
- /* UAParser.js v2.0.0-rc.1
2
+ /* UAParser.js v2.0.0-rc.3
3
3
  Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
4
4
  AGPLv3 License *//*
5
5
  Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@@ -19,7 +19,7 @@
19
19
  // Constants
20
20
  /////////////
21
21
 
22
- var LIBVERSION = '2.0.0-rc.1',
22
+ var LIBVERSION = '2.0.0-rc.3',
23
23
  EMPTY = '',
24
24
  UNKNOWN = '?',
25
25
  FUNC_TYPE = 'function',
@@ -40,6 +40,7 @@
40
40
  WEARABLE = 'wearable',
41
41
  XR = 'xr',
42
42
  EMBEDDED = 'embedded',
43
+ INAPP = 'inapp',
43
44
  USER_AGENT = 'user-agent',
44
45
  UA_MAX_LENGTH = 500,
45
46
  BRANDS = 'brands',
@@ -71,6 +72,7 @@
71
72
  GOOGLE = 'Google',
72
73
  HUAWEI = 'Huawei',
73
74
  LENOVO = 'Lenovo',
75
+ HONOR = 'Honor',
74
76
  LG = 'LG',
75
77
  MICROSOFT = 'Microsoft',
76
78
  MOTOROLA = 'Motorola',
@@ -320,17 +322,19 @@
320
322
  // Mixed
321
323
  /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
322
324
  ], [VERSION, [NAME, 'Baidu']], [
325
+ /\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
326
+ ], [VERSION, [NAME, 'Maxthon']], [
323
327
  /(kindle)\/([\w\.]+)/i, // Kindle
324
328
  /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
325
329
  // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
326
330
  // Trident based
327
- /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
331
+ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
328
332
  /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
329
333
 
330
- // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
331
- /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio)\/([-\w\.]+)/i,
332
- // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio
333
- /(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
334
+ // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
335
+ /(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)\/([-\w\.]+)/i,
336
+ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
337
+ /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115
334
338
  /(weibo)__([\d\.]+)/i // Weibo
335
339
  ], [NAME, VERSION], [
336
340
  /quark(?:pc)?\/([-\w\.]+)/i // Quark
@@ -367,31 +371,31 @@
367
371
  ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
368
372
  /fxios\/([\w\.-]+)/i // Firefox for iOS
369
373
  ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
370
- /\bqihu|(qi?ho?o?|360)browser/i // 360
371
- ], [[NAME, '360' + SUFFIX_BROWSER]], [
374
+ /\bqihoobrowser\/?([\w\.]*)/i // 360
375
+ ], [VERSION, [NAME, '360']], [
372
376
  /\b(qq)\/([\w\.]+)/i // QQ
373
377
  ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
374
378
  /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
375
379
  ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
376
380
  /samsungbrowser\/([\w\.]+)/i // Samsung Internet
377
381
  ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
378
- /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
379
- ], [[NAME, /_/g, ' '], VERSION], [
380
382
  /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
381
383
  ], [VERSION, [NAME, SOGOU + ' Explorer']], [
382
384
  /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
383
385
  ], [[NAME, SOGOU + ' Mobile'], VERSION], [
384
386
  /(electron)\/([\w\.]+) safari/i, // Electron-based App
385
387
  /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
386
- /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
388
+ /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
387
389
  ], [NAME, VERSION], [
388
- /(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
389
- /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
390
+ /(lbbrowser|rekonq)/i // LieBao Browser/Rekonq
390
391
  ], [NAME], [
392
+ /ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
393
+ /ome\/([\w\.]+).+qihu (360)[es]e/i // 360
394
+ ], [VERSION, NAME], [
391
395
 
392
396
  // WebView
393
397
  /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
394
- ], [[NAME, FACEBOOK], VERSION], [
398
+ ], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
395
399
  /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
396
400
  /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
397
401
  /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
@@ -399,12 +403,17 @@
399
403
  /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
400
404
  /(alipay)client\/([\w\.]+)/i, // Alipay
401
405
  /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
402
- /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
403
- ], [NAME, VERSION], [
406
+ /(instagram|snapchat)[\/ ]([-\w\.]+)/i // Instagram/Snapchat
407
+ ], [NAME, VERSION, [TYPE, INAPP]], [
404
408
  /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
405
- ], [VERSION, [NAME, 'GSA']], [
409
+ ], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
406
410
  /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
407
- ], [VERSION, [NAME, 'TikTok']], [
411
+ ], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
412
+ /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
413
+ ], [NAME, [TYPE, INAPP]], [
414
+
415
+ /(chromium)[\/ ]([-\w\.]+)/i // Chromium
416
+ ], [NAME, VERSION], [
408
417
 
409
418
  /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
410
419
  ], [VERSION, [NAME, CHROME+' Headless']], [
@@ -438,7 +447,7 @@
438
447
  ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
439
448
  /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
440
449
  ], [[NAME, 'Netscape'], VERSION], [
441
- /(wolvic)\/([\w\.]+)/i // Wolvic
450
+ /(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
442
451
  ], [NAME, VERSION], [
443
452
  /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
444
453
  ], [VERSION, [NAME, FIREFOX+' Reality']], [
@@ -519,10 +528,14 @@
519
528
  /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
520
529
  ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
521
530
 
531
+ // Honor
532
+ /(?:honor)([-\w ]+)[;\)]/i
533
+ ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
534
+
522
535
  // Huawei
523
536
  /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
524
537
  ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
525
- /(?:huawei|honor)([-\w ]+)[;\)]/i,
538
+ /(?:huawei)([-\w ]+)[;\)]/i,
526
539
  /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
527
540
  ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
528
541
 
@@ -587,7 +600,7 @@
587
600
  ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
588
601
 
589
602
  // Sony
590
- /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
603
+ /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
591
604
  ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
592
605
  /sony tablet [ps]/i,
593
606
  /\b(?:sony)?sgp\w+(?: bui|\))/i
@@ -653,13 +666,28 @@
653
666
  /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
654
667
  ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
655
668
 
669
+ // Energizer
670
+ /; (energy ?\w+)(?: bui|\))/i,
671
+ /; energizer ([\w ]+)(?: bui|\))/i
672
+ ], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
673
+
674
+ // Cat
675
+ /; cat (b35);/i,
676
+ /; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
677
+ ], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
678
+
679
+ // Smartfren
680
+ /((?:new )?andromax[\w- ]+)(?: bui|\))/i
681
+ ], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
682
+
656
683
  // Nothing
657
684
  /droid.+; (a(?:015|06[35]|142p?))/i
658
685
  ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
659
686
 
660
687
  // MIXED
661
- /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
662
- // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
688
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
689
+ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan
690
+ /; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO
663
691
  /(hp) ([\w ]+\w)/i, // HP iPAQ
664
692
  /(asus)-?(\w+)/i, // Asus
665
693
  /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
@@ -668,6 +696,7 @@
668
696
  /(oppo) ?([\w ]+) bui/i // OPPO
669
697
  ], [VENDOR, MODEL, [TYPE, MOBILE]], [
670
698
 
699
+ /(imo) (tab \w+)/i, // IMO
671
700
  /(kobo)\s(ereader|touch)/i, // Kobo
672
701
  /(archos) (gamepad2?)/i, // Archos
673
702
  /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
@@ -801,7 +830,7 @@
801
830
  ], [VERSION, [NAME, 'Blink']], [
802
831
 
803
832
  /(presto)\/([\w\.]+)/i, // Presto
804
- /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
833
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
805
834
  /ekioh(flow)\/([\w\.]+)/i, // Flow
806
835
  /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
807
836
  /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
@@ -1228,14 +1257,21 @@
1228
1257
  headers = extensions; // case UAParser(ua, headers)
1229
1258
  extensions = undefined;
1230
1259
  }
1260
+
1261
+ // Convert Headers object into a plain object
1262
+ if (headers && typeof headers.append === FUNC_TYPE) {
1263
+ var kv = {};
1264
+ headers.forEach(function (v, k) { kv[k] = v; });
1265
+ headers = kv;
1266
+ }
1231
1267
 
1232
1268
  if (!(this instanceof UAParser)) {
1233
1269
  return new UAParser(ua, extensions, headers).getResult();
1234
1270
  }
1235
1271
 
1236
1272
  var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
1237
- ((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
1238
1273
  (headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
1274
+ ((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
1239
1275
  EMPTY)), // empty string
1240
1276
 
1241
1277
  httpUACH = new UACHData(headers, true),
@@ -3,7 +3,7 @@
3
3
  // Source: /src/main/ua-parser.js
4
4
 
5
5
  /////////////////////////////////////////////////////////////////////////////////
6
- /* UAParser.js v2.0.0-rc.1
6
+ /* UAParser.js v2.0.0-rc.3
7
7
  Copyright © 2012-2024 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,7 +21,7 @@
21
21
  // Constants
22
22
  /////////////
23
23
 
24
- var LIBVERSION = '2.0.0-rc.1',
24
+ var LIBVERSION = '2.0.0-rc.3',
25
25
  EMPTY = '',
26
26
  UNKNOWN = '?',
27
27
  FUNC_TYPE = 'function',
@@ -42,6 +42,7 @@
42
42
  WEARABLE = 'wearable',
43
43
  XR = 'xr',
44
44
  EMBEDDED = 'embedded',
45
+ INAPP = 'inapp',
45
46
  USER_AGENT = 'user-agent',
46
47
  UA_MAX_LENGTH = 500,
47
48
  BRANDS = 'brands',
@@ -73,6 +74,7 @@
73
74
  GOOGLE = 'Google',
74
75
  HUAWEI = 'Huawei',
75
76
  LENOVO = 'Lenovo',
77
+ HONOR = 'Honor',
76
78
  LG = 'LG',
77
79
  MICROSOFT = 'Microsoft',
78
80
  MOTOROLA = 'Motorola',
@@ -322,17 +324,19 @@
322
324
  // Mixed
323
325
  /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
324
326
  ], [VERSION, [NAME, 'Baidu']], [
327
+ /\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
328
+ ], [VERSION, [NAME, 'Maxthon']], [
325
329
  /(kindle)\/([\w\.]+)/i, // Kindle
326
330
  /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
327
331
  // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
328
332
  // Trident based
329
- /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
333
+ /(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
330
334
  /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
331
335
 
332
- // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
333
- /(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio)\/([-\w\.]+)/i,
334
- // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio
335
- /(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
336
+ // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
337
+ /(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)\/([-\w\.]+)/i,
338
+ // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
339
+ /(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115
336
340
  /(weibo)__([\d\.]+)/i // Weibo
337
341
  ], [NAME, VERSION], [
338
342
  /quark(?:pc)?\/([-\w\.]+)/i // Quark
@@ -369,31 +373,31 @@
369
373
  ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
370
374
  /fxios\/([\w\.-]+)/i // Firefox for iOS
371
375
  ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
372
- /\bqihu|(qi?ho?o?|360)browser/i // 360
373
- ], [[NAME, '360' + SUFFIX_BROWSER]], [
376
+ /\bqihoobrowser\/?([\w\.]*)/i // 360
377
+ ], [VERSION, [NAME, '360']], [
374
378
  /\b(qq)\/([\w\.]+)/i // QQ
375
379
  ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
376
380
  /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
377
381
  ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
378
382
  /samsungbrowser\/([\w\.]+)/i // Samsung Internet
379
383
  ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
380
- /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
381
- ], [[NAME, /_/g, ' '], VERSION], [
382
384
  /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
383
385
  ], [VERSION, [NAME, SOGOU + ' Explorer']], [
384
386
  /(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
385
387
  ], [[NAME, SOGOU + ' Mobile'], VERSION], [
386
388
  /(electron)\/([\w\.]+) safari/i, // Electron-based App
387
389
  /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
388
- /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
390
+ /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
389
391
  ], [NAME, VERSION], [
390
- /(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
391
- /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
392
+ /(lbbrowser|rekonq)/i // LieBao Browser/Rekonq
392
393
  ], [NAME], [
394
+ /ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
395
+ /ome\/([\w\.]+).+qihu (360)[es]e/i // 360
396
+ ], [VERSION, NAME], [
393
397
 
394
398
  // WebView
395
399
  /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
396
- ], [[NAME, FACEBOOK], VERSION], [
400
+ ], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
397
401
  /(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
398
402
  /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
399
403
  /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
@@ -401,12 +405,17 @@
401
405
  /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
402
406
  /(alipay)client\/([\w\.]+)/i, // Alipay
403
407
  /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
404
- /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
405
- ], [NAME, VERSION], [
408
+ /(instagram|snapchat)[\/ ]([-\w\.]+)/i // Instagram/Snapchat
409
+ ], [NAME, VERSION, [TYPE, INAPP]], [
406
410
  /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
407
- ], [VERSION, [NAME, 'GSA']], [
411
+ ], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
408
412
  /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
409
- ], [VERSION, [NAME, 'TikTok']], [
413
+ ], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
414
+ /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
415
+ ], [NAME, [TYPE, INAPP]], [
416
+
417
+ /(chromium)[\/ ]([-\w\.]+)/i // Chromium
418
+ ], [NAME, VERSION], [
410
419
 
411
420
  /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
412
421
  ], [VERSION, [NAME, CHROME+' Headless']], [
@@ -440,7 +449,7 @@
440
449
  ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
441
450
  /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
442
451
  ], [[NAME, 'Netscape'], VERSION], [
443
- /(wolvic)\/([\w\.]+)/i // Wolvic
452
+ /(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
444
453
  ], [NAME, VERSION], [
445
454
  /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
446
455
  ], [VERSION, [NAME, FIREFOX+' Reality']], [
@@ -521,10 +530,14 @@
521
530
  /\b(sh-?[altvz]?\d\d[a-ekm]?)/i
522
531
  ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
523
532
 
533
+ // Honor
534
+ /(?:honor)([-\w ]+)[;\)]/i
535
+ ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
536
+
524
537
  // Huawei
525
538
  /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
526
539
  ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
527
- /(?:huawei|honor)([-\w ]+)[;\)]/i,
540
+ /(?:huawei)([-\w ]+)[;\)]/i,
528
541
  /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
529
542
  ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
530
543
 
@@ -589,7 +602,7 @@
589
602
  ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
590
603
 
591
604
  // Sony
592
- /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
605
+ /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
593
606
  ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
594
607
  /sony tablet [ps]/i,
595
608
  /\b(?:sony)?sgp\w+(?: bui|\))/i
@@ -655,13 +668,28 @@
655
668
  /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
656
669
  ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
657
670
 
671
+ // Energizer
672
+ /; (energy ?\w+)(?: bui|\))/i,
673
+ /; energizer ([\w ]+)(?: bui|\))/i
674
+ ], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
675
+
676
+ // Cat
677
+ /; cat (b35);/i,
678
+ /; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
679
+ ], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
680
+
681
+ // Smartfren
682
+ /((?:new )?andromax[\w- ]+)(?: bui|\))/i
683
+ ], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
684
+
658
685
  // Nothing
659
686
  /droid.+; (a(?:015|06[35]|142p?))/i
660
687
  ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
661
688
 
662
689
  // MIXED
663
- /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
664
- // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
690
+ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
691
+ // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan
692
+ /; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO
665
693
  /(hp) ([\w ]+\w)/i, // HP iPAQ
666
694
  /(asus)-?(\w+)/i, // Asus
667
695
  /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
@@ -670,6 +698,7 @@
670
698
  /(oppo) ?([\w ]+) bui/i // OPPO
671
699
  ], [VENDOR, MODEL, [TYPE, MOBILE]], [
672
700
 
701
+ /(imo) (tab \w+)/i, // IMO
673
702
  /(kobo)\s(ereader|touch)/i, // Kobo
674
703
  /(archos) (gamepad2?)/i, // Archos
675
704
  /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
@@ -803,7 +832,7 @@
803
832
  ], [VERSION, [NAME, 'Blink']], [
804
833
 
805
834
  /(presto)\/([\w\.]+)/i, // Presto
806
- /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
835
+ /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
807
836
  /ekioh(flow)\/([\w\.]+)/i, // Flow
808
837
  /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
809
838
  /(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
@@ -1230,14 +1259,21 @@
1230
1259
  headers = extensions; // case UAParser(ua, headers)
1231
1260
  extensions = undefined;
1232
1261
  }
1262
+
1263
+ // Convert Headers object into a plain object
1264
+ if (headers && typeof headers.append === FUNC_TYPE) {
1265
+ var kv = {};
1266
+ headers.forEach(function (v, k) { kv[k] = v; });
1267
+ headers = kv;
1268
+ }
1233
1269
 
1234
1270
  if (!(this instanceof UAParser)) {
1235
1271
  return new UAParser(ua, extensions, headers).getResult();
1236
1272
  }
1237
1273
 
1238
1274
  var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
1239
- ((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
1240
1275
  (headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
1276
+ ((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
1241
1277
  EMPTY)), // empty string
1242
1278
 
1243
1279
  httpUACH = new UACHData(headers, true),