ua-parser-js 2.0.0-beta.2 → 2.0.0-rc.1

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.
Files changed (198) hide show
  1. package/README.md +26 -22
  2. package/dist/icons/color/LICENSE.md +3 -0
  3. package/dist/icons/color/browser/android-browser.svg +1 -0
  4. package/dist/icons/color/browser/avant.png +0 -0
  5. package/dist/icons/color/browser/basilisk.png +0 -0
  6. package/dist/icons/color/browser/basilisk.svg +1 -0
  7. package/dist/icons/color/browser/brave.png +0 -0
  8. package/dist/icons/color/browser/brave.svg +1 -0
  9. package/dist/icons/color/browser/chrome.png +0 -0
  10. package/dist/icons/color/browser/chrome.svg +1 -0
  11. package/dist/icons/color/browser/chromium.png +0 -0
  12. package/dist/icons/color/browser/chromium.svg +1 -0
  13. package/dist/icons/color/browser/coc-coc.png +0 -0
  14. package/dist/icons/color/browser/default.png +0 -0
  15. package/dist/icons/color/browser/default.svg +1 -0
  16. package/dist/icons/color/browser/dolphin.png +0 -0
  17. package/dist/icons/color/browser/edge.png +0 -0
  18. package/dist/icons/color/browser/edge.svg +1 -0
  19. package/dist/icons/color/browser/electron.png +0 -0
  20. package/dist/icons/color/browser/electron.svg +1 -0
  21. package/dist/icons/color/browser/falkon.png +0 -0
  22. package/dist/icons/color/browser/falkon.svg +1 -0
  23. package/dist/icons/color/browser/firefox-reality.png +0 -0
  24. package/dist/icons/color/browser/firefox-reality.svg +1 -0
  25. package/dist/icons/color/browser/firefox.png +0 -0
  26. package/dist/icons/color/browser/firefox.svg +1 -0
  27. package/dist/icons/color/browser/gsa.svg +9 -0
  28. package/dist/icons/color/browser/icecat.png +0 -0
  29. package/dist/icons/color/browser/ie.svg +6 -0
  30. package/dist/icons/color/browser/konqueror.png +0 -0
  31. package/dist/icons/color/browser/konqueror.svg +1 -0
  32. package/dist/icons/color/browser/maxthon.png +0 -0
  33. package/dist/icons/color/browser/midori.png +0 -0
  34. package/dist/icons/color/browser/midori.svg +1 -0
  35. package/dist/icons/color/browser/netsurf.png +0 -0
  36. package/dist/icons/color/browser/netsurf.svg +1 -0
  37. package/dist/icons/color/browser/opera-gx.png +0 -0
  38. package/dist/icons/color/browser/opera-gx.svg +1 -0
  39. package/dist/icons/color/browser/opera-mini.png +0 -0
  40. package/dist/icons/color/browser/opera-touch.png +0 -0
  41. package/dist/icons/color/browser/opera.png +0 -0
  42. package/dist/icons/color/browser/opera.svg +1 -0
  43. package/dist/icons/color/browser/palemoon.png +0 -0
  44. package/dist/icons/color/browser/puffin.png +0 -0
  45. package/dist/icons/color/browser/safari.png +0 -0
  46. package/dist/icons/color/browser/safari.svg +1 -0
  47. package/dist/icons/color/browser/samsung-internet.png +0 -0
  48. package/dist/icons/color/browser/samsung-internet.svg +1 -0
  49. package/dist/icons/color/browser/seamonkey.png +0 -0
  50. package/dist/icons/color/browser/silk.png +0 -0
  51. package/dist/icons/color/browser/sogou-mobile.png +0 -0
  52. package/dist/icons/color/browser/ucbrowser.png +0 -0
  53. package/dist/icons/color/browser/ucbrowser.svg +1 -0
  54. package/dist/icons/color/browser/vivaldi.png +0 -0
  55. package/dist/icons/color/browser/vivaldi.svg +1 -0
  56. package/dist/icons/color/browser/webkit.png +0 -0
  57. package/dist/icons/color/browser/webkit.svg +1 -0
  58. package/dist/icons/color/browser/yandex.png +0 -0
  59. package/dist/icons/color/os/centos.svg +1 -0
  60. package/dist/icons/mono/LICENSE.md +3 -0
  61. package/dist/icons/mono/browser/alipay.svg +1 -0
  62. package/dist/icons/mono/browser/android-browser.svg +1 -0
  63. package/dist/icons/mono/browser/avast-secure-browser.svg +1 -0
  64. package/dist/icons/mono/browser/baidu-browser.svg +1 -0
  65. package/dist/icons/mono/browser/brave.svg +1 -0
  66. package/dist/icons/mono/browser/chrome-headless.svg +1 -0
  67. package/dist/icons/mono/browser/chrome-webview.svg +1 -0
  68. package/dist/icons/mono/browser/chrome.svg +1 -0
  69. package/dist/icons/mono/browser/chromium.svg +1 -0
  70. package/dist/icons/mono/browser/duckduckgo.svg +1 -0
  71. package/dist/icons/mono/browser/edge.svg +1 -0
  72. package/dist/icons/mono/browser/electron.svg +1 -0
  73. package/dist/icons/mono/browser/facebook.svg +1 -0
  74. package/dist/icons/mono/browser/firefox-focus.svg +1 -0
  75. package/dist/icons/mono/browser/firefox-reality.svg +1 -0
  76. package/dist/icons/mono/browser/firefox.svg +1 -0
  77. package/dist/icons/mono/browser/gsa.svg +1 -0
  78. package/dist/icons/mono/browser/huawei-browser.svg +1 -0
  79. package/dist/icons/mono/browser/icecat.svg +1 -0
  80. package/dist/icons/mono/browser/ie.svg +1 -0
  81. package/dist/icons/mono/browser/instagram.svg +1 -0
  82. package/dist/icons/mono/browser/jasmine.svg +1 -0
  83. package/dist/icons/mono/browser/kakaotalk.svg +1 -0
  84. package/dist/icons/mono/browser/klarna.svg +1 -0
  85. package/dist/icons/mono/browser/line.svg +1 -0
  86. package/dist/icons/mono/browser/linkedin.svg +1 -0
  87. package/dist/icons/mono/browser/miui-browser.svg +1 -0
  88. package/dist/icons/mono/browser/mobile-chrome.svg +1 -0
  89. package/dist/icons/mono/browser/mobile-firefox.svg +1 -0
  90. package/dist/icons/mono/browser/mobile-safari.svg +1 -0
  91. package/dist/icons/mono/browser/mozilla.svg +1 -0
  92. package/dist/icons/mono/browser/naver.svg +1 -0
  93. package/dist/icons/mono/browser/nokia-browser.svg +1 -0
  94. package/dist/icons/mono/browser/oculus-browser.svg +1 -0
  95. package/dist/icons/mono/browser/opera-coast.svg +1 -0
  96. package/dist/icons/mono/browser/opera-gx.svg +1 -0
  97. package/dist/icons/mono/browser/opera-mini.svg +1 -0
  98. package/dist/icons/mono/browser/opera-mobi.svg +1 -0
  99. package/dist/icons/mono/browser/opera-tablet.svg +1 -0
  100. package/dist/icons/mono/browser/opera-touch.svg +1 -0
  101. package/dist/icons/mono/browser/opera.svg +1 -0
  102. package/dist/icons/mono/browser/qqbrowser.svg +1 -0
  103. package/dist/icons/mono/browser/qqbrowserlite.svg +1 -0
  104. package/dist/icons/mono/browser/safari.svg +1 -0
  105. package/dist/icons/mono/browser/sailfish-browser.svg +1 -0
  106. package/dist/icons/mono/browser/samsung-internet.svg +1 -0
  107. package/dist/icons/mono/browser/smart-lenovo-browser.svg +1 -0
  108. package/dist/icons/mono/browser/snapchat.svg +1 -0
  109. package/dist/icons/mono/browser/sogou-explorer.svg +1 -0
  110. package/dist/icons/mono/browser/sogou-mobile.svg +1 -0
  111. package/dist/icons/mono/browser/tesla.svg +1 -0
  112. package/dist/icons/mono/browser/tiktok.svg +1 -0
  113. package/dist/icons/mono/browser/twitter.svg +1 -0
  114. package/dist/icons/mono/browser/vivaldi.svg +1 -0
  115. package/dist/icons/mono/browser/vivo-browser.svg +1 -0
  116. package/dist/icons/mono/browser/wechat.svg +1 -0
  117. package/dist/icons/mono/browser/weibo.svg +1 -0
  118. package/dist/icons/mono/browser/yandex.svg +1 -0
  119. package/dist/icons/mono/device/acer.svg +1 -0
  120. package/dist/icons/mono/device/amazon.svg +1 -0
  121. package/dist/icons/mono/device/apple.svg +1 -0
  122. package/dist/icons/mono/device/asus.svg +1 -0
  123. package/dist/icons/mono/device/att.svg +1 -0
  124. package/dist/icons/mono/device/blackberry.svg +1 -0
  125. package/dist/icons/mono/device/dell.svg +1 -0
  126. package/dist/icons/mono/device/facebook.svg +1 -0
  127. package/dist/icons/mono/device/fairphone.svg +1 -0
  128. package/dist/icons/mono/device/google.svg +1 -0
  129. package/dist/icons/mono/device/hp.svg +1 -0
  130. package/dist/icons/mono/device/huawei.svg +1 -0
  131. package/dist/icons/mono/device/lenovo.svg +1 -0
  132. package/dist/icons/mono/device/lg.svg +1 -0
  133. package/dist/icons/mono/device/meizu.svg +1 -0
  134. package/dist/icons/mono/device/microsoft.svg +1 -0
  135. package/dist/icons/mono/device/motorola.svg +1 -0
  136. package/dist/icons/mono/device/nintendo.svg +1 -0
  137. package/dist/icons/mono/device/nokia.svg +1 -0
  138. package/dist/icons/mono/device/nvidia.svg +1 -0
  139. package/dist/icons/mono/device/oneplus.svg +1 -0
  140. package/dist/icons/mono/device/oppo.svg +1 -0
  141. package/dist/icons/mono/device/panasonic.svg +1 -0
  142. package/dist/icons/mono/device/roku.svg +1 -0
  143. package/dist/icons/mono/device/samsung.svg +1 -0
  144. package/dist/icons/mono/device/siemens.svg +1 -0
  145. package/dist/icons/mono/device/sony.svg +1 -0
  146. package/dist/icons/mono/device/tesla.svg +1 -0
  147. package/dist/icons/mono/device/vivo.svg +1 -0
  148. package/dist/icons/mono/device/vodafone.svg +1 -0
  149. package/dist/icons/mono/device/xiaomi.svg +1 -0
  150. package/dist/icons/mono/device/zebra.svg +1 -0
  151. package/dist/icons/mono/os/android.svg +1 -0
  152. package/dist/icons/mono/os/arch.svg +1 -0
  153. package/dist/icons/mono/os/blackberry.svg +1 -0
  154. package/dist/icons/mono/os/centos.svg +1 -0
  155. package/dist/icons/mono/os/chrome-os.svg +1 -0
  156. package/dist/icons/mono/os/chromecast.svg +1 -0
  157. package/dist/icons/mono/os/debian.svg +1 -0
  158. package/dist/icons/mono/os/deepin.svg +1 -0
  159. package/dist/icons/mono/os/elementary-os.svg +1 -0
  160. package/dist/icons/mono/os/fedora.svg +1 -0
  161. package/dist/icons/mono/os/firefox.svg +1 -0
  162. package/dist/icons/mono/os/freebsd.svg +1 -0
  163. package/dist/icons/mono/os/gentoo.svg +1 -0
  164. package/dist/icons/mono/os/gnu.svg +1 -0
  165. package/dist/icons/mono/os/harmonyos.svg +1 -0
  166. package/dist/icons/mono/os/ios.svg +1 -0
  167. package/dist/icons/mono/os/kaios.svg +1 -0
  168. package/dist/icons/mono/os/linux.svg +1 -0
  169. package/dist/icons/mono/os/macos.svg +1 -0
  170. package/dist/icons/mono/os/manjaro.svg +1 -0
  171. package/dist/icons/mono/os/mint.svg +1 -0
  172. package/dist/icons/mono/os/netbsd.svg +1 -0
  173. package/dist/icons/mono/os/nintendo.svg +1 -0
  174. package/dist/icons/mono/os/openbsd.svg +1 -0
  175. package/dist/icons/mono/os/playstation.svg +1 -0
  176. package/dist/icons/mono/os/raspbian.svg +1 -0
  177. package/dist/icons/mono/os/redhat.svg +1 -0
  178. package/dist/icons/mono/os/sailfish.svg +1 -0
  179. package/dist/icons/mono/os/slackware.svg +1 -0
  180. package/dist/icons/mono/os/suse.svg +1 -0
  181. package/dist/icons/mono/os/ubuntu.svg +1 -0
  182. package/dist/icons/mono/os/windows.svg +1 -0
  183. package/dist/icons/mono/os/xbox.svg +1 -0
  184. package/dist/ua-parser.min.js +3 -3
  185. package/dist/ua-parser.pack.js +3 -3
  186. package/package.json +11 -6
  187. package/script/cli.js +4 -0
  188. package/src/enums/ua-parser-enums.js +30 -9
  189. package/src/enums/ua-parser-enums.mjs +30 -9
  190. package/src/extensions/ua-parser-extensions.d.ts +4 -2
  191. package/src/extensions/ua-parser-extensions.js +169 -48
  192. package/src/extensions/ua-parser-extensions.mjs +169 -48
  193. package/src/helpers/ua-parser-helpers.d.ts +12 -4
  194. package/src/helpers/ua-parser-helpers.js +44 -5
  195. package/src/helpers/ua-parser-helpers.mjs +45 -6
  196. package/src/main/ua-parser.d.ts +7 -4
  197. package/src/main/ua-parser.js +121 -54
  198. package/src/main/ua-parser.mjs +121 -54
@@ -3,12 +3,12 @@
3
3
  // Source: /src/main/ua-parser.js
4
4
 
5
5
  /////////////////////////////////////////////////////////////////////////////////
6
- /* UAParser.js v2.0.0-beta.2
7
- Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
6
+ /* UAParser.js v2.0.0-rc.1
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.
10
10
  Supports browser & node.js environment.
11
- Demo : https://faisalman.github.io/ua-parser-js
11
+ Demo : https://uaparser.dev
12
12
  Source : https://github.com/faisalman/ua-parser-js */
13
13
  /////////////////////////////////////////////////////////////////////////////////
14
14
 
@@ -21,7 +21,7 @@
21
21
  // Constants
22
22
  /////////////
23
23
 
24
- var LIBVERSION = '2.0.0-beta.2',
24
+ var LIBVERSION = '2.0.0-rc.1',
25
25
  EMPTY = '',
26
26
  UNKNOWN = '?',
27
27
  FUNC_TYPE = 'function',
@@ -40,11 +40,12 @@
40
40
  TABLET = 'tablet',
41
41
  SMARTTV = 'smarttv',
42
42
  WEARABLE = 'wearable',
43
+ XR = 'xr',
43
44
  EMBEDDED = 'embedded',
44
45
  USER_AGENT = 'user-agent',
45
46
  UA_MAX_LENGTH = 500,
46
47
  BRANDS = 'brands',
47
- FORMFACTOR = 'formFactor',
48
+ FORMFACTORS = 'formFactors',
48
49
  FULLVERLIST = 'fullVersionList',
49
50
  PLATFORM = 'platform',
50
51
  PLATFORMVER = 'platformVersion',
@@ -53,12 +54,12 @@
53
54
  CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
54
55
  CH_HEADER_ARCH = CH_HEADER + '-arch',
55
56
  CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
56
- CH_HEADER_FORM_FACTOR = CH_HEADER + '-form-factor',
57
+ CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors',
57
58
  CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
58
59
  CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
59
60
  CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
60
61
  CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
61
- CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTOR, BITNESS],
62
+ CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
62
63
  UA_BROWSER = 'browser',
63
64
  UA_CPU = 'cpu',
64
65
  UA_DEVICE = 'device',
@@ -83,6 +84,7 @@
83
84
  PREFIX_MOBILE = 'Mobile ',
84
85
  SUFFIX_BROWSER = ' Browser',
85
86
  CHROME = 'Chrome',
87
+ CHROMECAST = 'Chromecast',
86
88
  EDGE = 'Edge',
87
89
  FIREFOX = 'Firefox',
88
90
  OPERA = 'Opera',
@@ -102,12 +104,21 @@
102
104
  // Helper
103
105
  //////////
104
106
 
105
- var extend = function (regexes, extensions) {
106
- var mergedRegexes = {};
107
- for (var i in regexes) {
108
- mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i];
107
+ var extend = function (defaultRgx, extensions) {
108
+ var mergedRgx = {};
109
+ var extraRgx = extensions;
110
+ if (!isExtensions(extensions)) {
111
+ extraRgx = {};
112
+ for (var i in extensions) {
113
+ for (var j in extensions[i]) {
114
+ extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
115
+ }
116
+ }
117
+ }
118
+ for (var k in defaultRgx) {
119
+ mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
109
120
  }
110
- return mergedRegexes;
121
+ return mergedRgx;
111
122
  },
112
123
  enumerize = function (arr) {
113
124
  var enums = {};
@@ -125,9 +136,9 @@
125
136
  }
126
137
  return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
127
138
  },
128
- isExtensions = function (obj) {
139
+ isExtensions = function (obj, deep) {
129
140
  for (var prop in obj) {
130
- return /^(browser|cpu|device|engine|os)$/.test(prop);
141
+ return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
131
142
  }
132
143
  },
133
144
  isString = function (val) {
@@ -271,12 +282,13 @@
271
282
  'RT' : 'ARM'
272
283
  },
273
284
 
274
- formFactorMap = {
285
+ formFactorsMap = {
275
286
  'embedded' : 'Automotive',
276
287
  'mobile' : 'Mobile',
277
288
  'tablet' : ['Tablet', 'EInk'],
278
289
  'smarttv' : 'TV',
279
- 'wearable' : ['VR', 'XR', 'Watch'],
290
+ 'wearable' : 'Watch',
291
+ 'xr' : ['VR', 'XR'],
280
292
  '?' : ['Desktop', 'Unknown'],
281
293
  '*' : undefined
282
294
  };
@@ -311,17 +323,22 @@
311
323
  /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
312
324
  ], [VERSION, [NAME, 'Baidu']], [
313
325
  /(kindle)\/([\w\.]+)/i, // Kindle
314
- /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
326
+ /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
327
+ // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
315
328
  // Trident based
316
329
  /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
317
330
  /(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
318
331
 
319
332
  // Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
320
- /(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,
321
- // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
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
322
335
  /(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
323
336
  /(weibo)__([\d\.]+)/i // Weibo
324
337
  ], [NAME, VERSION], [
338
+ /quark(?:pc)?\/([-\w\.]+)/i // Quark
339
+ ], [VERSION, [NAME, 'Quark']], [
340
+ /\bddg\/([\w\.]+)/i // DuckDuckGo
341
+ ], [VERSION, [NAME, 'DuckDuckGo']], [
325
342
  /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
326
343
  ], [VERSION, [NAME, 'UCBrowser']], [
327
344
  /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
@@ -354,8 +371,10 @@
354
371
  ], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
355
372
  /\bqihu|(qi?ho?o?|360)browser/i // 360
356
373
  ], [[NAME, '360' + SUFFIX_BROWSER]], [
357
- /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i
358
- ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser
374
+ /\b(qq)\/([\w\.]+)/i // QQ
375
+ ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
376
+ /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
377
+ ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
359
378
  /samsungbrowser\/([\w\.]+)/i // Samsung Internet
360
379
  ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
361
380
  /(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
@@ -368,7 +387,7 @@
368
387
  /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
369
388
  /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
370
389
  ], [NAME, VERSION], [
371
- /(lbbrowser)/i, // LieBao Browser
390
+ /(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
372
391
  /\[(linkedin)app\]/i // LinkedIn App for iOS & Android
373
392
  ], [NAME], [
374
393
 
@@ -381,6 +400,7 @@
381
400
  /safari (line)\/([\w\.]+)/i, // Line App for iOS
382
401
  /\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
383
402
  /(alipay)client\/([\w\.]+)/i, // Alipay
403
+ /(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
384
404
  /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
385
405
  ], [NAME, VERSION], [
386
406
  /\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
@@ -420,23 +440,24 @@
420
440
  ], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
421
441
  /(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
422
442
  ], [[NAME, 'Netscape'], VERSION], [
443
+ /(wolvic)\/([\w\.]+)/i // Wolvic
444
+ ], [NAME, VERSION], [
423
445
  /mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
424
446
  ], [VERSION, [NAME, FIREFOX+' Reality']], [
425
447
  /ekiohf.+(flow)\/([\w\.]+)/i, // Flow
426
448
  /(swiftfox)/i, // Swiftfox
427
- /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
428
- // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
449
+ /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
450
+ // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
429
451
  /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
430
452
  // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
431
453
  /(firefox)\/([\w\.]+)/i, // Other Firefox-based
432
454
  /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
433
455
 
434
456
  // Other
435
- /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
436
- // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
437
- /(links) \(([\w\.]+)/i, // Links
438
- /panasonic;(viera)/i // Panasonic Viera
439
- ], [NAME, VERSION], [
457
+ /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
458
+ // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser
459
+ /(links) \(([\w\.]+)/i // Links
460
+ ], [NAME, [VERSION, /_/g, '.']], [
440
461
 
441
462
  /(cobalt)\/([\w\.]+)/i // Cobalt
442
463
  ], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
@@ -481,8 +502,8 @@
481
502
  // Samsung
482
503
  /\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
483
504
  ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
484
- /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
485
- /samsung[- ]([-\w]+)/i,
505
+ /\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
506
+ /samsung[- ]((?!sm-[lr])[-\w]+)/i,
486
507
  /sec-(sgh\w+)/i
487
508
  ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
488
509
 
@@ -513,7 +534,7 @@
513
534
  /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
514
535
  /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
515
536
  /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
516
- /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
537
+ /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi
517
538
  ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
518
539
  /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
519
540
  /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
@@ -523,6 +544,8 @@
523
544
  /; (\w+) bui.+ oppo/i,
524
545
  /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
525
546
  ], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
547
+ /\b(opd2\d{3}a?) bui/i
548
+ ], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [
526
549
 
527
550
  // Vivo
528
551
  /vivo (\w+)(?: bui|\))/i,
@@ -579,7 +602,7 @@
579
602
 
580
603
  // Amazon
581
604
  /(alexa)webm/i,
582
- /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show
605
+ /(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i, // Kindle Fire without Silk / Echo Show
583
606
  /(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
584
607
  ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
585
608
  /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
@@ -608,6 +631,17 @@
608
631
  /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
609
632
  ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
610
633
 
634
+ // TCL
635
+ /tcl (xess p17aa)/i,
636
+ /droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])(_\w(\w|\w\w))?(\)| bui)/i
637
+ ], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [
638
+ /droid [\w\.]+; (418(?:7d|8v)|5087z|5102l|61(?:02[dh]|25[adfh]|27[ai]|56[dh]|59k|65[ah])|a509dl|t(?:43(?:0w|1[adepqu])|50(?:6d|7[adju])|6(?:09dl|10k|12b|71[efho]|76[hjk])|7(?:66[ahju]|67[hw]|7[045][bh]|71[hk]|73o|76[ho]|79w|81[hks]?|82h|90[bhsy]|99b)|810[hs]))(_\w(\w|\w\w))?(\)| bui)/i
639
+ ], [MODEL, [VENDOR, 'TCL'], [TYPE, MOBILE]], [
640
+
641
+ // itel
642
+ /(itel) ((\w+))/i
643
+ ], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [
644
+
611
645
  // Acer
612
646
  /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
613
647
  ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
@@ -621,6 +655,10 @@
621
655
  /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
622
656
  ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
623
657
 
658
+ // Nothing
659
+ /droid.+; (a(?:015|06[35]|142p?))/i
660
+ ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
661
+
624
662
  // MIXED
625
663
  /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
626
664
  // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
@@ -665,8 +703,14 @@
665
703
  ], [[VENDOR, LG], [TYPE, SMARTTV]], [
666
704
  /(apple) ?tv/i // Apple TV
667
705
  ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
668
- /crkey/i // Google Chromecast
669
- ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
706
+ /crkey.*devicetype\/chromecast/i // Google Chromecast Third Generation
707
+ ], [[MODEL, CHROMECAST+' Third Generation'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
708
+ /crkey.*devicetype\/([^/]*)/i // Google Chromecast with specific device type
709
+ ], [[MODEL, /^/, 'Chromecast '], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
710
+ /fuchsia.*crkey/i // Google Chromecast Nest Hub
711
+ ], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
712
+ /crkey/i // Google Chromecast, Linux-based or unknown
713
+ ], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
670
714
  /droid.+aft(\w+)( bui|\))/i // Fire TV
671
715
  ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
672
716
  /\(dtv[\);].+(aquos)/i,
@@ -702,16 +746,25 @@
702
746
  // WEARABLES
703
747
  ///////////////////
704
748
 
749
+ /\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch
750
+ ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [
705
751
  /((pebble))app/i // Pebble
706
752
  ], [VENDOR, MODEL, [TYPE, WEARABLE]], [
707
753
  /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
708
754
  ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
709
- /droid.+; (glass) \d/i // Google Glass
710
- ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
711
755
  /droid.+; (wt63?0{2,3})\)/i
712
756
  ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
713
- /(quest( 2| pro)?)/i // Oculus Quest
714
- ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
757
+
758
+ ///////////////////
759
+ // XR
760
+ ///////////////////
761
+
762
+ /droid.+; (glass) \d/i // Google Glass
763
+ ], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
764
+ /(pico) (4|neo3(?: link|pro)?)/i // Pico
765
+ ], [VENDOR, MODEL, [TYPE, XR]], [
766
+ /; (quest( \d| pro)?)/i // Oculus Quest
767
+ ], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
715
768
 
716
769
  ///////////////////
717
770
  // EMBEDDED
@@ -743,6 +796,9 @@
743
796
  /windows.+ edge\/([\w\.]+)/i // EdgeHTML
744
797
  ], [VERSION, [NAME, EDGE+'HTML']], [
745
798
 
799
+ /(arkweb)\/([\w\.]+)/i // ArkWeb
800
+ ], [NAME, VERSION], [
801
+
746
802
  /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
747
803
  ], [VERSION, [NAME, 'Blink']], [
748
804
 
@@ -779,10 +835,22 @@
779
835
  /(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS
780
836
  ], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
781
837
 
838
+ // Google Chromecast
839
+ /android ([\d\.]+).*crkey/i // Google Chromecast, Android-based
840
+ ], [VERSION, [NAME, CHROMECAST + ' Android']], [
841
+ /fuchsia.*crkey\/([\d\.]+)/i // Google Chromecast, Fuchsia-based
842
+ ], [VERSION, [NAME, CHROMECAST + ' Fuchsia']], [
843
+ /crkey\/([\d\.]+).*devicetype\/smartspeaker/i // Google Chromecast, Linux-based Smart Speaker
844
+ ], [VERSION, [NAME, CHROMECAST + ' SmartSpeaker']], [
845
+ /linux.*crkey\/([\d\.]+)/i // Google Chromecast, Legacy Linux-based
846
+ ], [VERSION, [NAME, CHROMECAST + ' Linux']], [
847
+ /crkey\/([\d\.]+)/i // Google Chromecast, unknown
848
+ ], [VERSION, [NAME, CHROMECAST]], [
849
+
782
850
  // Mobile OSes
783
851
  /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS
784
- ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
785
- /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
852
+ ], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony
853
+ /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i,
786
854
  /(blackberry)\w*\/([\w\.]*)/i, // Blackberry
787
855
  /(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS
788
856
  /\((series40);/i // Series 40
@@ -799,9 +867,7 @@
799
867
  /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
800
868
  ], [VERSION, [NAME, 'watchOS']], [
801
869
 
802
- // Google Chromecast
803
- /crkey\/([\d\.]+)/i // Google Chromecast
804
- ], [VERSION, [NAME, CHROME+'cast']], [
870
+ // Google ChromeOS
805
871
  /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
806
872
  ], [[NAME, "Chrome OS"], VERSION],[
807
873
 
@@ -813,6 +879,7 @@
813
879
  // Console
814
880
  /(nintendo|playstation) (\w+)/i, // Nintendo/Playstation
815
881
  /(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
882
+ /(pico) .+os([\w\.]+)/i, // Pico
816
883
 
817
884
  // Other
818
885
  /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
@@ -842,7 +909,7 @@
842
909
  var defaultProps = (function () {
843
910
  var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
844
911
  setProps.call(props.init, [
845
- [UA_BROWSER, [NAME, VERSION, MAJOR]],
912
+ [UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]],
846
913
  [UA_CPU, [ARCHITECTURE]],
847
914
  [UA_DEVICE, [TYPE, MODEL, VENDOR]],
848
915
  [UA_ENGINE, [NAME, VERSION]],
@@ -970,7 +1037,7 @@
970
1037
  [PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
971
1038
  [PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
972
1039
  [ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
973
- [FORMFACTOR, itemListToArray(uach[CH_HEADER_FORM_FACTOR])],
1040
+ [FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])],
974
1041
  [BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
975
1042
  ]);
976
1043
  } else {
@@ -1090,15 +1157,15 @@
1090
1157
  this.set(TYPE, CONSOLE)
1091
1158
  .set(VENDOR, MICROSOFT);
1092
1159
  }
1093
- if (uaCH[FORMFACTOR]) {
1160
+ if (uaCH[FORMFACTORS]) {
1094
1161
  var ff;
1095
- if (typeof uaCH[FORMFACTOR] !== 'string') {
1162
+ if (typeof uaCH[FORMFACTORS] !== 'string') {
1096
1163
  var idx = 0;
1097
- while (!ff && idx < uaCH[FORMFACTOR].length) {
1098
- ff = strMapper(uaCH[FORMFACTOR][idx++], formFactorMap);
1164
+ while (!ff && idx < uaCH[FORMFACTORS].length) {
1165
+ ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
1099
1166
  }
1100
1167
  } else {
1101
- ff = strMapper(uaCH[FORMFACTOR], formFactorMap);
1168
+ ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
1102
1169
  }
1103
1170
  this.set(TYPE, ff);
1104
1171
  }
@@ -1149,7 +1216,7 @@
1149
1216
  function UAParser (ua, extensions, headers) {
1150
1217
 
1151
1218
  if (typeof ua === OBJ_TYPE) {
1152
- if (isExtensions(ua)) {
1219
+ if (isExtensions(ua, true)) {
1153
1220
  if (typeof extensions === OBJ_TYPE) {
1154
1221
  headers = extensions; // case UAParser(extensions, headers)
1155
1222
  }
@@ -1159,7 +1226,7 @@
1159
1226
  extensions = undefined;
1160
1227
  }
1161
1228
  ua = undefined;
1162
- } else if (typeof ua === STR_TYPE && !isExtensions(extensions)) {
1229
+ } else if (typeof ua === STR_TYPE && !isExtensions(extensions, true)) {
1163
1230
  headers = extensions; // case UAParser(ua, headers)
1164
1231
  extensions = undefined;
1165
1232
  }
@@ -1220,7 +1287,7 @@
1220
1287
  }
1221
1288
 
1222
1289
  UAParser.VERSION = LIBVERSION;
1223
- UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
1290
+ UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
1224
1291
  UAParser.CPU = enumerize([ARCHITECTURE]);
1225
1292
  UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
1226
1293
  UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);