ua-parser-js 2.0.8 → 2.0.10

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 (209) hide show
  1. package/README.md +6 -10
  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.min.mjs +3 -3
  186. package/dist/ua-parser.pack.js +3 -3
  187. package/dist/ua-parser.pack.mjs +3 -3
  188. package/package.json +20 -2
  189. package/src/bot-detection/bot-detection.d.ts +6 -4
  190. package/src/bot-detection/bot-detection.js +10 -1
  191. package/src/bot-detection/bot-detection.mjs +10 -1
  192. package/src/browser-detection/browser-detection.d.ts +1 -1
  193. package/src/browser-detection/browser-detection.js +6 -3
  194. package/src/browser-detection/browser-detection.mjs +6 -3
  195. package/src/device-detection/device-detection.d.ts +1 -1
  196. package/src/device-detection/device-detection.js +1 -1
  197. package/src/device-detection/device-detection.mjs +1 -1
  198. package/src/enums/ua-parser-enums.d.ts +40 -4
  199. package/src/enums/ua-parser-enums.js +40 -4
  200. package/src/enums/ua-parser-enums.mjs +40 -4
  201. package/src/extensions/ua-parser-extensions.d.ts +1 -1
  202. package/src/extensions/ua-parser-extensions.js +24 -12
  203. package/src/extensions/ua-parser-extensions.mjs +24 -12
  204. package/src/helpers/ua-parser-helpers.d.ts +1 -1
  205. package/src/helpers/ua-parser-helpers.js +2 -2
  206. package/src/helpers/ua-parser-helpers.mjs +2 -2
  207. package/src/main/ua-parser.d.ts +11 -5
  208. package/src/main/ua-parser.js +69 -38
  209. package/src/main/ua-parser.mjs +69 -38
@@ -1,5 +1,5 @@
1
1
  ///////////////////////////////////////////////
2
- /* Extensions for UAParser.js v2.0.8
2
+ /* Extensions for UAParser.js v2.0.10
3
3
  https://github.com/faisalman/ua-parser-js
4
4
  Author: Faisal Salman <f@faisalman.com>
5
5
  AGPLv3 License */
@@ -55,6 +55,7 @@ const Crawlers = Object.freeze({
55
55
  [
56
56
  // AhrefsBot - https://ahrefs.com/robot
57
57
  // Amazonbot - https://developer.amazon.com/amazonbot
58
+ // Awario - https://awario.com/bots.html
58
59
  // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
59
60
  // Bravebot - https://search.brave.com/help/brave-search-crawler
60
61
  // CCBot - https://commoncrawl.org/faq
@@ -79,7 +80,7 @@ const Crawlers = Object.freeze({
79
80
  // SurdotlyBot - http://sur.ly/bot.html
80
81
  // Swiftbot - https://swiftype.com/swiftbot
81
82
  // YepBot - https://yep.com/yepbot/
82
- /((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,
83
+ /((?:adidx|ahrefs|amazon|(?:amzn|oai)-search|awario(?:smart|rss)?|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,
83
84
 
84
85
  // Algolia Crawler
85
86
  /(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
@@ -96,12 +97,12 @@ const Crawlers = Object.freeze({
96
97
  // Coc Coc Bot - https://help.coccoc.com/en/search-engine
97
98
  /(coccocbot-(?:image|web))\/([\w\.]+)/i,
98
99
 
99
- // Daum
100
- /(daum(?:oa)?(?:-image)?)[ \/]([\w\.]+)/i,
100
+ // Daum / HubSpot Crawler
101
+ /(daum(?:oa)?(?:-image)?|hubspot crawler)[ \/]([\w\.]+)/i,
101
102
 
102
103
  // Facebook / Meta
103
104
  // https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
104
- /(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
105
+ /(facebook(?:externalhit|catalog)|meta-(?:externalagent|externalads|webindexer))\/([\w\.]+)/i,
105
106
 
106
107
  // Googlebot - http://www.google.com/bot.html
107
108
  /(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
@@ -130,13 +131,19 @@ const Crawlers = Object.freeze({
130
131
  // Yeti (Naver)
131
132
  /(yeti)\/([\w\.]+)/i,
132
133
 
133
- // aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
134
+ // aiHitBot / Algolia Crawler / Audisto Crawler / BLEXBot / BrightEdge Crawler / Cloudflare AutoRAG / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
134
135
  // Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/
135
136
  // Freespoke - https://docs.freespoke.com/search/bot/
136
- /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
137
+ /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:audisto |brightedge |magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i
137
138
  ],
138
139
  [NAME, VERSION, [TYPE, CRAWLER]],
139
140
 
141
+ [
142
+ // Headline - https://headline.com/legal/crawler
143
+ /(ev-crawler)\/([\w\.]+)/i
144
+ ],
145
+ [[NAME, 'Headline'], VERSION, [TYPE, CRAWLER]],
146
+
140
147
  [
141
148
  // YandexBot MirrorDetector
142
149
  /(yandexbot\/([\w\.]+); mirrordetector)/i
@@ -145,7 +152,7 @@ const Crawlers = Object.freeze({
145
152
 
146
153
  [
147
154
  // Google Bots
148
- /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
155
+ /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|notebooklm|safety))/i,
149
156
 
150
157
  // AI2Bot - https://allenai.org/crawler
151
158
  // DataForSeoBot - https://dataforseo.com/dataforseo-bot
@@ -156,7 +163,7 @@ const Crawlers = Object.freeze({
156
163
  // v0bot - https://vercel.com/docs/bot-management
157
164
  // Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
158
165
  // Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
159
- /\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
166
+ /\b((ai2|aspiegel|atlassian-|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0|yacy)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|proximic|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
160
167
  ],
161
168
  [NAME, [TYPE, CRAWLER]]
162
169
  ]
@@ -306,16 +313,21 @@ const Fetchers = Object.freeze({
306
313
  // Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
307
314
  // ChatGPT-User - https://platform.openai.com/docs/plugins/bot
308
315
  // DuckAssistBot - https://duckduckgo.com/duckassistbot/
316
+ // Feedly - https://feedly.com/fetcher.html
317
+ // FlipboardProxy - https://about.flipboard.com/proxy-service/
309
318
  // Google Site Verifier / Meta / Yahoo! Japan
310
319
  // Iframely - https://iframely.com/docs/about
311
320
  // Perplexity-User - https://docs.perplexity.ai/guides/bots
312
321
  // MistralAI-User - https://docs.mistral.ai/robots/
313
322
  // Yandex Bots - https://yandex.com/bots
314
- /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i,
323
+ /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:amzn|chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptime(?:ro)?|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i,
315
324
 
316
325
  // Bluesky
317
326
  /(bluesky) cardyb\/([\w\.]+)/i,
318
327
 
328
+ // Feedly
329
+ /(feedly)(?:bot)?\/([\w\.]+)/i,
330
+
319
331
  // Nova Act - https://github.com/aws/nova-act
320
332
  /agent-(novaact)\/([\w\.]+)/i,
321
333
 
@@ -329,7 +341,7 @@ const Fetchers = Object.freeze({
329
341
 
330
342
  [
331
343
  // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / KeybaseBot / Snapchat / Vercelbot / Yandex Bots
332
- /((?:better uptime |keybase|telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
344
+ /((?:better uptime |keybase|telegram|vercel)bot|lighthouse$|feedfetcher-google|gemini-deep-research|google(?:docs|imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|virustotal(?=cloud)|yandex(?:sitelinks|userproxy))/i
333
345
  ],
334
346
  [NAME, [TYPE, FETCHER]],
335
347
  ],
@@ -439,7 +451,7 @@ const Libraries = Object.freeze({
439
451
  /(nutch)-([\w\.-]+)(\(|$)/i,
440
452
  /\((java)\/([\w\.]+)/i
441
453
  ], [NAME, VERSION, [TYPE, LIBRARY]], [
442
- /(node-fetch|undici)/i
454
+ /(node-fetch|phpcrawl|undici)/i
443
455
  ], [NAME, [TYPE, LIBRARY]]
444
456
  ]
445
457
  });
@@ -3,7 +3,7 @@
3
3
  // Source: /src/extensions/ua-parser-extensions.js
4
4
 
5
5
  ///////////////////////////////////////////////
6
- /* Extensions for UAParser.js v2.0.8
6
+ /* Extensions for UAParser.js v2.0.10
7
7
  https://github.com/faisalman/ua-parser-js
8
8
  Author: Faisal Salman <f@faisalman.com>
9
9
  AGPLv3 License */
@@ -59,6 +59,7 @@ const Crawlers = Object.freeze({
59
59
  [
60
60
  // AhrefsBot - https://ahrefs.com/robot
61
61
  // Amazonbot - https://developer.amazon.com/amazonbot
62
+ // Awario - https://awario.com/bots.html
62
63
  // Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
63
64
  // Bravebot - https://search.brave.com/help/brave-search-crawler
64
65
  // CCBot - https://commoncrawl.org/faq
@@ -83,7 +84,7 @@ const Crawlers = Object.freeze({
83
84
  // SurdotlyBot - http://sur.ly/bot.html
84
85
  // Swiftbot - https://swiftype.com/swiftbot
85
86
  // YepBot - https://yep.com/yepbot/
86
- /((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,
87
+ /((?:adidx|ahrefs|amazon|(?:amzn|oai)-search|awario(?:smart|rss)?|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|onespot-scraper|perplexity|sbintuitions|semrush|seznam|surdotly|swift|yep)bot)\/([\w\.-]+)/i,
87
88
 
88
89
  // Algolia Crawler
89
90
  /(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
@@ -100,12 +101,12 @@ const Crawlers = Object.freeze({
100
101
  // Coc Coc Bot - https://help.coccoc.com/en/search-engine
101
102
  /(coccocbot-(?:image|web))\/([\w\.]+)/i,
102
103
 
103
- // Daum
104
- /(daum(?:oa)?(?:-image)?)[ \/]([\w\.]+)/i,
104
+ // Daum / HubSpot Crawler
105
+ /(daum(?:oa)?(?:-image)?|hubspot crawler)[ \/]([\w\.]+)/i,
105
106
 
106
107
  // Facebook / Meta
107
108
  // https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
108
- /(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
109
+ /(facebook(?:externalhit|catalog)|meta-(?:externalagent|externalads|webindexer))\/([\w\.]+)/i,
109
110
 
110
111
  // Googlebot - http://www.google.com/bot.html
111
112
  /(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
@@ -134,13 +135,19 @@ const Crawlers = Object.freeze({
134
135
  // Yeti (Naver)
135
136
  /(yeti)\/([\w\.]+)/i,
136
137
 
137
- // aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
138
+ // aiHitBot / Algolia Crawler / Audisto Crawler / BLEXBot / BrightEdge Crawler / Cloudflare AutoRAG / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
138
139
  // Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/
139
140
  // Freespoke - https://docs.freespoke.com/search/bot/
140
- /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
141
+ /((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:audisto |brightedge |magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cloudflare-autorag|cotoyogi|(?:firecrawl|twin)agent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|webzio-extended)\/?([\w\.]*)/i
141
142
  ],
142
143
  [NAME, VERSION, [TYPE, CRAWLER]],
143
144
 
145
+ [
146
+ // Headline - https://headline.com/legal/crawler
147
+ /(ev-crawler)\/([\w\.]+)/i
148
+ ],
149
+ [[NAME, 'Headline'], VERSION, [TYPE, CRAWLER]],
150
+
144
151
  [
145
152
  // YandexBot MirrorDetector
146
153
  /(yandexbot\/([\w\.]+); mirrordetector)/i
@@ -149,7 +156,7 @@ const Crawlers = Object.freeze({
149
156
 
150
157
  [
151
158
  // Google Bots
152
- /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
159
+ /((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|notebooklm|safety))/i,
153
160
 
154
161
  // AI2Bot - https://allenai.org/crawler
155
162
  // DataForSeoBot - https://dataforseo.com/dataforseo-bot
@@ -160,7 +167,7 @@ const Crawlers = Object.freeze({
160
167
  // v0bot - https://vercel.com/docs/bot-management
161
168
  // Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
162
169
  // Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
163
- /\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
170
+ /\b((ai2|aspiegel|atlassian-|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0|yacy)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|proximic|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
164
171
  ],
165
172
  [NAME, [TYPE, CRAWLER]]
166
173
  ]
@@ -310,16 +317,21 @@ const Fetchers = Object.freeze({
310
317
  // Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
311
318
  // ChatGPT-User - https://platform.openai.com/docs/plugins/bot
312
319
  // DuckAssistBot - https://duckduckgo.com/duckassistbot/
320
+ // Feedly - https://feedly.com/fetcher.html
321
+ // FlipboardProxy - https://about.flipboard.com/proxy-service/
313
322
  // Google Site Verifier / Meta / Yahoo! Japan
314
323
  // Iframely - https://iframely.com/docs/about
315
324
  // Perplexity-User - https://docs.perplexity.ai/guides/bots
316
325
  // MistralAI-User - https://docs.mistral.ai/robots/
317
326
  // Yandex Bots - https://yandex.com/bots
318
- /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i,
327
+ /(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:amzn|chatgpt|claude|mistralai|perplexity)-user|cohere-ai|flipboardproxy|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptime(?:ro)?|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher|whatsapp)\/([\w\.]+)/i,
319
328
 
320
329
  // Bluesky
321
330
  /(bluesky) cardyb\/([\w\.]+)/i,
322
331
 
332
+ // Feedly
333
+ /(feedly)(?:bot)?\/([\w\.]+)/i,
334
+
323
335
  // Nova Act - https://github.com/aws/nova-act
324
336
  /agent-(novaact)\/([\w\.]+)/i,
325
337
 
@@ -333,7 +345,7 @@ const Fetchers = Object.freeze({
333
345
 
334
346
  [
335
347
  // Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / KeybaseBot / Snapchat / Vercelbot / Yandex Bots
336
- /((?:better uptime |keybase|telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
348
+ /((?:better uptime |keybase|telegram|vercel)bot|lighthouse$|feedfetcher-google|gemini-deep-research|google(?:docs|imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|virustotal(?=cloud)|yandex(?:sitelinks|userproxy))/i
337
349
  ],
338
350
  [NAME, [TYPE, FETCHER]],
339
351
  ],
@@ -443,7 +455,7 @@ const Libraries = Object.freeze({
443
455
  /(nutch)-([\w\.-]+)(\(|$)/i,
444
456
  /\((java)\/([\w\.]+)/i
445
457
  ], [NAME, VERSION, [TYPE, LIBRARY]], [
446
- /(node-fetch|undici)/i
458
+ /(node-fetch|phpcrawl|undici)/i
447
459
  ], [NAME, [TYPE, LIBRARY]]
448
460
  ]
449
461
  });
@@ -1,4 +1,4 @@
1
- // Type definitions for Helpers submodule of UAParser.js v2.0.8
1
+ // Type definitions for Helpers submodule of UAParser.js v2.0.10
2
2
  // Project: https://github.com/faisalman/ua-parser-js
3
3
  // Definitions by: Faisal Salman <https://github.com/faisalman>
4
4
 
@@ -1,5 +1,5 @@
1
1
  ///////////////////////////////////////////////
2
- /* Helpers for UAParser.js v2.0.8
2
+ /* Helpers for UAParser.js v2.0.10
3
3
  https://github.com/faisalman/ua-parser-js
4
4
  Author: Faisal Salman <f@faisalman.com>
5
5
  AGPLv3 License */
@@ -41,7 +41,7 @@ const isChromeFamily = _isChromeFamily;
41
41
  /**
42
42
  * @deprecated Moved to `browser-detection` submodule
43
43
  */
44
- const isElectron = () => _isElectron;
44
+ const isElectron = _isElectron;
45
45
 
46
46
  /**
47
47
  * @deprecated Moved to `browser-detection` submodule
@@ -3,7 +3,7 @@
3
3
  // Source: /src/helpers/ua-parser-helpers.js
4
4
 
5
5
  ///////////////////////////////////////////////
6
- /* Helpers for UAParser.js v2.0.8
6
+ /* Helpers for UAParser.js v2.0.10
7
7
  https://github.com/faisalman/ua-parser-js
8
8
  Author: Faisal Salman <f@faisalman.com>
9
9
  AGPLv3 License */
@@ -45,7 +45,7 @@ const isChromeFamily = _isChromeFamily;
45
45
  /**
46
46
  * @deprecated Moved to `browser-detection` submodule
47
47
  */
48
- const isElectron = () => _isElectron;
48
+ const isElectron = _isElectron;
49
49
 
50
50
  /**
51
51
  * @deprecated Moved to `browser-detection` submodule
@@ -1,10 +1,15 @@
1
- // Type definitions for UAParser.js v2.0.8
1
+ // Type definitions for UAParser.js v2.0.10
2
2
  // Project: https://github.com/faisalman/ua-parser-js
3
3
  // Definitions by: Faisal Salman <https://github.com/faisalman>
4
4
 
5
5
  import { BrowserType, CPUArch, DeviceType, EngineName } from "../enums/ua-parser-enums";
6
6
 
7
7
  declare namespace UAParser {
8
+
9
+ type BrowserTypes = typeof BrowserType[keyof typeof BrowserType];
10
+ type CPUArchs = typeof CPUArch[keyof typeof CPUArch];
11
+ type DeviceTypes = typeof DeviceType[keyof typeof DeviceType];
12
+ type EngineNames = typeof EngineName[keyof typeof EngineName];
8
13
 
9
14
  interface IData<T> {
10
15
  is(val: string): boolean;
@@ -17,21 +22,21 @@ declare namespace UAParser {
17
22
  name?: string;
18
23
  version?: string;
19
24
  major?: string;
20
- type?: typeof BrowserType[keyof typeof BrowserType];
25
+ type?: BrowserTypes;
21
26
  }
22
27
 
23
28
  interface ICPU extends IData<ICPU> {
24
- architecture?: typeof CPUArch[keyof typeof CPUArch];
29
+ architecture?: CPUArchs;
25
30
  }
26
31
 
27
32
  interface IDevice extends IData<IDevice> {
28
- type?: typeof DeviceType[keyof typeof DeviceType];
33
+ type?: DeviceTypes;
29
34
  vendor?: string;
30
35
  model?: string;
31
36
  }
32
37
 
33
38
  interface IEngine extends IData<IEngine> {
34
- name?: typeof EngineName[keyof typeof EngineName];
39
+ name?: EngineNames;
35
40
  version?: string;
36
41
  }
37
42
 
@@ -105,6 +110,7 @@ declare namespace UAParser {
105
110
  getOS(): IOS;
106
111
  getResult(): IResult;
107
112
  setUA(uastring: string): UAParser;
113
+ useExtension(extensions: UAParserExt): UAParser;
108
114
  }
109
115
  }
110
116
 
@@ -1,6 +1,6 @@
1
1
  /////////////////////////////////////////////////////////////////////////////////
2
- /* UAParser.js v2.0.8
3
- Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
2
+ /* UAParser.js v2.0.10
3
+ Copyright © 2012-2026 Faisal Salman <f@faisalman.com>
4
4
  AGPLv3 License *//*
5
5
  Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
6
6
  Supports browser & node.js environment.
@@ -19,7 +19,7 @@
19
19
  // Constants
20
20
  /////////////
21
21
 
22
- var LIBVERSION = '2.0.8',
22
+ var LIBVERSION = '2.0.10',
23
23
  UA_MAX_LENGTH = 500,
24
24
  USER_AGENT = 'user-agent',
25
25
  EMPTY = '',
@@ -57,6 +57,7 @@
57
57
  EMBEDDED = 'embedded',
58
58
 
59
59
  // browser types
60
+ FETCHER = 'fetcher',
60
61
  INAPP = 'inapp',
61
62
 
62
63
  // client hints
@@ -169,7 +170,7 @@
169
170
  itemListToArray = function (header) {
170
171
  if (!header) return undefined;
171
172
  var arr = [];
172
- var tokens = strip(/\\?\"/g, header).split(',');
173
+ var tokens = normalizeHeaderValue(header).split(',');
173
174
  for (var i = 0; i < tokens.length; i++) {
174
175
  if (tokens[i].indexOf(';') > -1) {
175
176
  var token = trim(tokens[i]).split(';v=');
@@ -186,6 +187,9 @@
186
187
  majorize = function (version) {
187
188
  return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
188
189
  },
190
+ normalizeHeaderValue = function (str) {
191
+ return isString(str) ? trim(strip(/\\?\"/g, str), UA_MAX_LENGTH) : undefined;
192
+ },
189
193
  setProps = function (arr) {
190
194
  for (var i in arr) {
191
195
  if (!arr.hasOwnProperty(i)) continue;
@@ -202,9 +206,6 @@
202
206
  strip = function (pattern, str) {
203
207
  return isString(str) ? str.replace(pattern, EMPTY) : str;
204
208
  },
205
- stripQuotes = function (str) {
206
- return strip(/\\?\"/g, str);
207
- },
208
209
  trim = function (str, len) {
209
210
  str = strip(/^\s\s*/, String(str));
210
211
  return typeof len === TYPEOF.UNDEFINED ? str : str.substring(0, len);
@@ -277,6 +278,10 @@
277
278
  }
278
279
  },
279
280
 
281
+ strTest = function (str, map) {
282
+ return map.test.test(str) ? map.ifTrue : map.ifFalse;
283
+ },
284
+
280
285
  strMapper = function (str, map) {
281
286
 
282
287
  for (var i in map) {
@@ -347,7 +352,7 @@
347
352
  /\b(?:crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
348
353
  ], [VERSION, [NAME, PREFIX_MOBILE + 'Chrome']], [
349
354
  /webview.+edge\/([\w\.]+)/i // Microsoft Edge
350
- ], [VERSION, [NAME, EDGE+' WebView']], [
355
+ ], [VERSION, [NAME, EDGE+' WebView'], [TYPE, INAPP]], [
351
356
  /edg(?:e|ios|a)?\/([\w\.]+)/i
352
357
  ], [VERSION, [NAME, 'Edge']], [
353
358
 
@@ -379,7 +384,7 @@
379
384
  /(atlas|flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon|otter|dooble|(?:hi|lg |ovi|qute)browser|palemoon)\/v?([-\w\.]+)/i,
380
385
  // Atlas/Rekonq/Puffin/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
381
386
  /(brave)(?: chrome)?\/([\d\.]+)/i, // Brave
382
- /(heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i, // HeyTap/Ovi/115/Surf
387
+ /(aloha|heytap|ovi|115|surf|qwant)browser\/([\d\.]+)/i, // Aloha/HeyTap/Ovi/115/Surf
383
388
  /(qwant)(?:ios|mobile)\/([\d\.]+)/i, // Qwant
384
389
  /(ecosia|weibo)(?:__| \w+@)([\d\.]+)/i // Ecosia/Weibo
385
390
  ], [NAME, VERSION], [
@@ -387,7 +392,7 @@
387
392
  ], [VERSION, [NAME, 'Quark']], [
388
393
  /\bddg\/([\w\.]+)/i // DuckDuckGo
389
394
  ], [VERSION, [NAME, 'DuckDuckGo']], [
390
- /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
395
+ /(?:\buc? ?browser|(?:juc.+)ucweb| ucpc)[\/ ]?([\w\.]+)/i // UCBrowser
391
396
  ], [VERSION, [NAME, 'UCBrowser']], [
392
397
  /microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
393
398
  /\bqbcore\/([\w\.]+).+microm/i,
@@ -401,8 +406,10 @@
401
406
  ], [VERSION, [NAME, 'Yandex']], [
402
407
  /slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
403
408
  ], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [
404
- /(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
409
+ /(av(?:ast|g|ira))\/([\w\.]+)/i // Avast/AVG/Avira Secure Browser
405
410
  ], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
411
+ /norton\/([\w\.]+)/i // Norton Private Browser
412
+ ], [VERSION, [NAME, 'Norton Private' + SUFFIX_BROWSER]], [
406
413
  /\bfocus\/([\w\.]+)/i // Firefox Focus
407
414
  ], [VERSION, [NAME, FIREFOX+' Focus']], [
408
415
  / mms\/([\w\.]+)$/i // Opera Neon
@@ -424,7 +431,9 @@
424
431
  /\b(qq)\/([\w\.]+)/i // QQ
425
432
  ], [[NAME, /(.+)/, '$1Browser'], VERSION], [
426
433
  /(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
427
- ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
434
+ ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/VivoBrowser/PicoBrowser
435
+ / HBPC\/([\w\.]+)/ // Huawei Browser
436
+ ], [VERSION, [NAME, HUAWEI + SUFFIX_BROWSER]], [
428
437
  /samsungbrowser\/([\w\.]+)/i // Samsung Internet
429
438
  ], [VERSION, [NAME, SAMSUNG + ' Internet']], [
430
439
  /metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
@@ -435,10 +444,9 @@
435
444
  /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
436
445
  /m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
437
446
  ], [NAME, VERSION], [
438
- /(lbbrowser|rekonq|steam(?= (clie|tenf|gameo)))/i // LieBao Browser/Rekonq/Steam
447
+ /(lbbrowser|luakit|rekonq|steam(?= (clie|tenf|gameo)))/i // LieBao Browser/Luakit/Rekonq/Steam
439
448
  ], [NAME], [
440
- /ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
441
- /ome\/([\w\.]+).+qihu (360)[es]e/i // 360
449
+ /ome\/([\w\.]+).+(iron(?= saf)|360(?=[es]e$))/i // Iron / 360
442
450
  ], [VERSION, NAME], [
443
451
 
444
452
  // WebView
@@ -466,14 +474,17 @@
466
474
  /(chromium)[\/ ]([-\w\.]+)/i // Chromium
467
475
  ], [NAME, VERSION], [
468
476
 
477
+ /ome-(lighthouse)$/i // Chrome Lighthouse
478
+ ], [NAME, [TYPE, FETCHER]], [
479
+
469
480
  /headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
470
481
  ], [VERSION, [NAME, CHROME+' Headless']], [
471
482
 
472
483
  /wv\).+chrome\/([\w\.]+).+edgw\//i // Edge WebView2
473
- ], [VERSION, [NAME, EDGE+' WebView2']], [
484
+ ], [VERSION, [NAME, EDGE+' WebView2'], [TYPE, INAPP]], [
474
485
 
475
- / wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
476
- ], [[NAME, CHROME+' WebView'], VERSION], [
486
+ /; wv\).+(chrome)\/([\w\.]+)/i // Chrome WebView
487
+ ], [[NAME, CHROME+' WebView'], VERSION, [TYPE, INAPP]], [
477
488
 
478
489
  /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i // Android Browser
479
490
  ], [VERSION, [NAME, 'Android' + SUFFIX_BROWSER]], [
@@ -607,7 +618,7 @@
607
618
  /oid[^\)]+; (redmi[\-_ ]?(?:note|k)?[\w_ ]+|m?[12]\d[01]\d\w{3,6}|poco[\w ]+|(shark )?\w{3}-[ah]0|qin ?[1-3](s\+|ultra| pro)?)( bui|; wv|\))/i,
608
619
  // Xiaomi Mi
609
620
  /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note|max|cc)?[_ ]?(?:\d{0,2}\w?)[_ ]?(?:plus|se|lite|pro)?( 5g|lte)?)(?: bui|\))/i,
610
- / ([\w ]+) miui\/v?\d/i
621
+ /; ([\w ]+) miui\/v?\d/i
611
622
  ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
612
623
 
613
624
  // OnePlus
@@ -762,10 +773,19 @@
762
773
  /; (ac[3-6]\d\w{2,8})( b|\))/i
763
774
  ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [
764
775
 
776
+ // Blackview
777
+ /blackview ([-\w ]+)( b|\))/i,
778
+ /; (bv\d{4}[-\w ]*)( b|\))/i
779
+ ], [MODEL, [VENDOR, 'Blackview'], [TYPE, MOBILE]], [
780
+
765
781
  // HMD
766
782
  /; (n159v)/i
767
783
  ], [MODEL, [VENDOR, 'HMD'], [TYPE, MOBILE]], [
768
784
 
785
+ // T-Mobile
786
+ /((revvl[ \w\+]+|tm(?:rv|af)\w*[45]g(?:tb)?))( b|\))/i
787
+ ], [MODEL, [TYPE, strTest, { 'test': /ta?b/i, 'ifTrue': TABLET, 'ifFalse': MOBILE }], [VENDOR, 'T-Mobile']], [
788
+
769
789
  // MIXED
770
790
  /(imo) (tab \w+)/i, // IMO
771
791
  /(infinix|tecno) (x1101b?|p904|dp(7c|8d|10a)( pro)?|p70[1-3]a?|p904|t1101)/i // Infinix XPad / Tecno
@@ -773,8 +793,8 @@
773
793
 
774
794
  /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
775
795
  // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Tecno/Micromax/Advan
776
- // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
777
- /; (blu|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i,
796
+ // BLU/Coolpad/CUBOT/HMD/IMO/Infinix/Lava/OnePlus/TCL/Wiko
797
+ /; (blu|coolpad|cubot|hmd|imo|infinix|lava|oneplus|tcl|wiko)[_ ]([-\w\+ ]+?)(?: bui|\)|; r)/i,
778
798
  /(hp) ([\w ]+\w)/i, // HP iPAQ
779
799
  /(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
780
800
  /(oppo) ?([\w ]+) bui/i, // OPPO
@@ -1012,14 +1032,16 @@
1012
1032
  /web0s;.+?(?:chr[o0]me|safari)\/(\d+)/i
1013
1033
  // https://webostv.developer.lge.com/develop/specifications/web-api-and-web-engine
1014
1034
  ], [[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']], [
1015
- /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
1035
+ /watch(?: ?os[,\/ ]|\d,\d\/)([\d\.]+)/i // watchOS
1016
1036
  ], [VERSION, [NAME, 'watchOS']], [
1017
1037
 
1018
1038
  // Google ChromeOS
1019
- /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
1020
- ], [[NAME, "Chrome OS"], VERSION],[
1039
+ /cros [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
1040
+ ], [VERSION, [NAME, 'Chrome OS']],[
1021
1041
 
1022
1042
  // Smart TVs
1043
+ /kepler ([\w\.]+); (aft|aeo)/i // Vega OS
1044
+ ], [VERSION, [NAME, 'Vega OS']],[
1023
1045
  /(netrange)mmh/i, // Netrange
1024
1046
  /(nettv)\/(\d+\.[\w\.]+)/i, // NetTV
1025
1047
 
@@ -1180,12 +1202,12 @@
1180
1202
  [BRANDS, itemListToArray(uach[CH])],
1181
1203
  [FULLVERLIST, itemListToArray(uach[CH_FULL_VER_LIST])],
1182
1204
  [MOBILE, /\?1/.test(uach[CH_MOBILE])],
1183
- [MODEL, stripQuotes(uach[CH_MODEL])],
1184
- [PLATFORM, stripQuotes(uach[CH_PLATFORM])],
1185
- [PLATFORMVER, stripQuotes(uach[CH_PLATFORM_VER])],
1186
- [ARCHITECTURE, stripQuotes(uach[CH_ARCH])],
1205
+ [MODEL, normalizeHeaderValue(uach[CH_MODEL])],
1206
+ [PLATFORM, normalizeHeaderValue(uach[CH_PLATFORM])],
1207
+ [PLATFORMVER, normalizeHeaderValue(uach[CH_PLATFORM_VER])],
1208
+ [ARCHITECTURE, normalizeHeaderValue(uach[CH_ARCH])],
1187
1209
  [FORMFACTORS, itemListToArray(uach[CH_FORM_FACTORS])],
1188
- [BITNESS, stripQuotes(uach[CH_BITNESS])]
1210
+ [BITNESS, normalizeHeaderValue(uach[CH_BITNESS])]
1189
1211
  ]);
1190
1212
  } else {
1191
1213
  for (var prop in uach) {
@@ -1273,11 +1295,17 @@
1273
1295
  this.set(MAJOR, majorize(this.get(VERSION)));
1274
1296
  break;
1275
1297
  case OS:
1276
- if (this.get(NAME) == 'iOS' && this.get(VERSION) == '18.6') {
1277
- // Based on the assumption that iOS version is tightly coupled with Safari version
1278
- var realVersion = /\) Version\/([\d\.]+)/.exec(this.ua); // Get Safari version
1279
- if (realVersion && parseInt(realVersion[1].substring(0,2), 10) >= 26) {
1280
- this.set(VERSION, realVersion[1]); // Set as iOS version
1298
+ // Since iOS 26, Safari's UA reports the OS version as frozen at 18:
1299
+ // https://webkit.org/blog/17333/webkit-features-in-safari-26-0/#update-to-ua-string
1300
+ if (this.get(NAME) == 'iOS' && this.get(VERSION)) {
1301
+ // Only perform this if iOS version is 18/19
1302
+ if (/^1[89][^\d]/.exec(this.get(VERSION))) {
1303
+ // Based on the assumption that "iOS" version is tightly coupled with "Safari" version
1304
+ var realVersion = /\) Version\/((\d+)[\d\.]*)/.exec(this.ua);
1305
+ if (realVersion && parseInt(realVersion[2], 10) >= 26) {
1306
+ // iOS version = Safari version
1307
+ this.set(VERSION, realVersion[1]);
1308
+ }
1281
1309
  }
1282
1310
  }
1283
1311
  break;
@@ -1433,9 +1461,7 @@
1433
1461
  EMPTY)), // empty string
1434
1462
 
1435
1463
  httpUACH = new UACHData(headers, true),
1436
- regexMap = extensions ?
1437
- extend(defaultRegexes, extensions) :
1438
- defaultRegexes,
1464
+ regexMap = defaultRegexes,
1439
1465
 
1440
1466
  createItemFunc = function (itemType) {
1441
1467
  if (itemType == RESULT) {
@@ -1470,9 +1496,14 @@
1470
1496
  ['setUA', function (ua) {
1471
1497
  if (isString(ua)) userAgent = trim(ua, UA_MAX_LENGTH);
1472
1498
  return this;
1499
+ }],
1500
+ ['useExtension', function (exts) {
1501
+ if (exts) regexMap = extend(regexMap, exts);
1502
+ return this;
1473
1503
  }]
1474
1504
  ])
1475
- .setUA(userAgent);
1505
+ .setUA(userAgent)
1506
+ .useExtension(extensions);
1476
1507
 
1477
1508
  return this;
1478
1509
  }