Make it personal - 2.0.0-rc.3

This commit is contained in:
Faisal Salman
2024-11-14 17:59:13 +07:00
215 changed files with 3069 additions and 465 deletions

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-beta.3
/* Enums for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Personal License */
@@ -8,8 +8,9 @@
/*jshint esversion: 6 */
const Browser = Object.freeze({
_2345_EXPLORER: '2345Explorer',
_360: '360 Browser',
'115': '115',
'2345': '2345',
'360': '360',
ALIPAY: 'Alipay',
AMAYA: 'Amaya',
ANDROID: 'Android Browser',
@@ -32,11 +33,11 @@ const Browser = Object.freeze({
CHROMIUM: 'Chromium',
COBALT: 'Cobalt',
COC_COC: 'Coc Coc',
COMODO_DRAGON: 'Comodo Dragon',
CONKEROR: 'Conkeror',
DILLO: 'Dillo',
DOLPHIN: 'Dolphin',
DORIS: 'Doris',
DRAGON: 'Dragon',
DUCKDUCKGO: 'DuckDuckGo',
EDGE: 'Edge',
EPIPHANY: 'Epiphany',
@@ -52,7 +53,9 @@ const Browser = Object.freeze({
FLOW: 'Flow',
GO: 'GoBrowser',
GOOGLE_SEARCH: 'GSA',
HELIO: 'Helio',
HEYTAP: 'HeyTap',
HONOR: 'Honor',
HUAWEI: 'Huawei Browser',
ICAB: 'iCab',
ICE: 'ICE Browser',
@@ -73,6 +76,7 @@ const Browser = Object.freeze({
KLARNA: 'Klarna',
KINDLE: 'Kindle',
LENOVO: 'Smart Lenovo Browser',
LIBREWOLF: 'LibreWolf',
LIEBAO: 'LBBROWSER',
LINE: 'Line',
LINKEDIN: 'LinkedIn',
@@ -121,7 +125,9 @@ const Browser = Object.freeze({
SILK: 'Silk',
SKYFIRE: 'Skyfire',
SLEIPNIR: 'Sleipnir',
SLIMBOAT: 'SlimBoat',
SLIMBROWSER: 'SlimBrowser',
SLIMJET: 'Slimjet',
SNAPCHAT: 'Snapchat',
SOGOU_EXPLORER: 'Sogou Explorer',
SOGOU_MOBILE: 'Sogou Mobile',
@@ -152,10 +158,12 @@ const BrowserType = Object.freeze({
EMAIL: 'email',
FETCHER: 'fetcher',
INAPP: 'inapp',
MODULE: 'module'
MEDIAPLAYER: 'mediaplayer',
LIBRARY: 'library'
});
const CPU = Object.freeze({
'68K': '68k',
ARM : 'arm',
ARM_64: 'arm64',
ARM_HF: 'armhf',
@@ -166,7 +174,6 @@ const CPU = Object.freeze({
IRIX_64: 'irix64',
MIPS: 'mips',
MIPS_64: 'mips64',
M68K: '68k',
PA_RISC: 'pa-risc',
PPC: 'ppc',
SPARC: 'sparc',
@@ -188,6 +195,7 @@ const Device = Object.freeze({
const Vendor = Object.freeze({
ACER: 'Acer',
ADVAN: 'Advan',
ALCATEL: 'Alcatel',
APPLE: 'Apple',
AMAZON: 'Amazon',
@@ -196,7 +204,9 @@ const Vendor = Object.freeze({
ATT: 'AT&T',
BENQ: 'BenQ',
BLACKBERRY: 'BlackBerry',
CAT: 'Cat',
DELL: 'Dell',
ENERGIZER: 'Energizer',
ESSENTIAL: 'Essential',
FACEBOOK: 'Facebook',
FAIRPHONE: 'Fairphone',
@@ -206,17 +216,21 @@ const Vendor = Object.freeze({
HP: 'HP',
HTC: 'HTC',
HUAWEI: 'Huawei',
IMO: 'IMO',
INFINIX: 'Infinix',
ITEL: 'itel',
JOLLA: 'Jolla',
KOBO: 'Kobo',
LENOVO: 'Lenovo',
LG: 'LG',
MEIZU: 'Meizu',
MICROMAX: 'Micromax',
MICROSOFT: 'Microsoft',
MOTOROLA: 'Motorola',
NEXIAN: 'Nexian',
NINTENDO: 'Nintendo',
NOKIA: 'Nokia',
NOTHING: 'Nothing',
NVIDIA: 'Nvidia',
ONEPLUS: 'OnePlus',
OPPO: 'OPPO',
@@ -224,6 +238,7 @@ const Vendor = Object.freeze({
PALM: 'Palm',
PANASONIC: 'Panasonic',
PEBBLE: 'Pebble',
PICO: 'Pico',
POLYTRON: 'Polytron',
REALME: 'Realme',
RIM: 'RIM',
@@ -231,8 +246,10 @@ const Vendor = Object.freeze({
SAMSUNG: 'Samsung',
SHARP: 'Sharp',
SIEMENS: 'Siemens',
SMARTFREN: 'Smartfren',
SONY: 'Sony',
SPRINT: 'Sprint',
TCL: 'TCL',
TECHNISAT: 'TechniSAT',
TECNO: 'Tecno',
TESLA: 'Tesla',
@@ -249,6 +266,7 @@ const Vendor = Object.freeze({
const Engine = Object.freeze({
AMAYA: 'Amaya',
ARKWEB: 'ArkWeb',
BLINK: 'Blink',
EDGEHTML: 'EdgeHTML',
FLOW: 'Flow',
@@ -262,6 +280,7 @@ const Engine = Object.freeze({
NETFRONT: 'NetFront',
NETSURF: 'NetSurf',
PRESTO: 'Presto',
SERVO: 'Servo',
TASMAN: 'Tasman',
TRIDENT: 'Trident',
W3M: 'w3m',
@@ -280,6 +299,10 @@ const OS = Object.freeze({
CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS',
CHROMECAST: 'Chromecast',
CHROMECAST_ANDROID: 'Chromecast Android',
CHROMECAST_FUCHSIA: 'Chromecast Fuchsia',
CHROMECAST_LINUX: 'Chromecast Linux',
CHROMECAST_SMARTSPEAKER: 'Chromecast SmartSpeaker',
CONTIKI: 'Contiki',
DEBIAN: 'Debian',
DEEPIN: 'Deepin',
@@ -315,12 +338,14 @@ const OS = Object.freeze({
NETRANGE: 'NetRange',
NETTV: 'NetTV',
NINTENDO: 'Nintendo',
OPENHARMONY: 'OpenHarmony',
OPENBSD: 'OpenBSD',
OPENVMS: 'OpenVMS',
OS2: 'OS/2',
PALM: 'Palm',
PC_BSD: 'PC-BSD',
PCLINUXOS: 'PCLinuxOS',
PICO: 'Pico',
PLAN9: 'Plan9',
PLAYSTATION: 'PlayStation',
QNX: 'QNX',
@@ -340,7 +365,6 @@ const OS = Object.freeze({
UBUNTU: 'Ubuntu',
UNIX: 'Unix',
VECTORLINUX: 'VectorLinux',
VIERA: 'Viera',
WATCHOS: 'watchOS',
WEBOS: 'WebOS',
WINDOWS: 'Windows',

View File

@@ -3,7 +3,7 @@
// Source: /src/enums/ua-parser-enums.js
///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-beta.3
/* Enums for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Personal License */
@@ -12,8 +12,9 @@
/*jshint esversion: 6 */
const Browser = Object.freeze({
_2345_EXPLORER: '2345Explorer',
_360: '360 Browser',
'115': '115',
'2345': '2345',
'360': '360',
ALIPAY: 'Alipay',
AMAYA: 'Amaya',
ANDROID: 'Android Browser',
@@ -36,11 +37,11 @@ const Browser = Object.freeze({
CHROMIUM: 'Chromium',
COBALT: 'Cobalt',
COC_COC: 'Coc Coc',
COMODO_DRAGON: 'Comodo Dragon',
CONKEROR: 'Conkeror',
DILLO: 'Dillo',
DOLPHIN: 'Dolphin',
DORIS: 'Doris',
DRAGON: 'Dragon',
DUCKDUCKGO: 'DuckDuckGo',
EDGE: 'Edge',
EPIPHANY: 'Epiphany',
@@ -56,7 +57,9 @@ const Browser = Object.freeze({
FLOW: 'Flow',
GO: 'GoBrowser',
GOOGLE_SEARCH: 'GSA',
HELIO: 'Helio',
HEYTAP: 'HeyTap',
HONOR: 'Honor',
HUAWEI: 'Huawei Browser',
ICAB: 'iCab',
ICE: 'ICE Browser',
@@ -77,6 +80,7 @@ const Browser = Object.freeze({
KLARNA: 'Klarna',
KINDLE: 'Kindle',
LENOVO: 'Smart Lenovo Browser',
LIBREWOLF: 'LibreWolf',
LIEBAO: 'LBBROWSER',
LINE: 'Line',
LINKEDIN: 'LinkedIn',
@@ -125,7 +129,9 @@ const Browser = Object.freeze({
SILK: 'Silk',
SKYFIRE: 'Skyfire',
SLEIPNIR: 'Sleipnir',
SLIMBOAT: 'SlimBoat',
SLIMBROWSER: 'SlimBrowser',
SLIMJET: 'Slimjet',
SNAPCHAT: 'Snapchat',
SOGOU_EXPLORER: 'Sogou Explorer',
SOGOU_MOBILE: 'Sogou Mobile',
@@ -156,10 +162,12 @@ const BrowserType = Object.freeze({
EMAIL: 'email',
FETCHER: 'fetcher',
INAPP: 'inapp',
MODULE: 'module'
MEDIAPLAYER: 'mediaplayer',
LIBRARY: 'library'
});
const CPU = Object.freeze({
'68K': '68k',
ARM : 'arm',
ARM_64: 'arm64',
ARM_HF: 'armhf',
@@ -170,7 +178,6 @@ const CPU = Object.freeze({
IRIX_64: 'irix64',
MIPS: 'mips',
MIPS_64: 'mips64',
M68K: '68k',
PA_RISC: 'pa-risc',
PPC: 'ppc',
SPARC: 'sparc',
@@ -192,6 +199,7 @@ const Device = Object.freeze({
const Vendor = Object.freeze({
ACER: 'Acer',
ADVAN: 'Advan',
ALCATEL: 'Alcatel',
APPLE: 'Apple',
AMAZON: 'Amazon',
@@ -200,7 +208,9 @@ const Vendor = Object.freeze({
ATT: 'AT&T',
BENQ: 'BenQ',
BLACKBERRY: 'BlackBerry',
CAT: 'Cat',
DELL: 'Dell',
ENERGIZER: 'Energizer',
ESSENTIAL: 'Essential',
FACEBOOK: 'Facebook',
FAIRPHONE: 'Fairphone',
@@ -210,17 +220,21 @@ const Vendor = Object.freeze({
HP: 'HP',
HTC: 'HTC',
HUAWEI: 'Huawei',
IMO: 'IMO',
INFINIX: 'Infinix',
ITEL: 'itel',
JOLLA: 'Jolla',
KOBO: 'Kobo',
LENOVO: 'Lenovo',
LG: 'LG',
MEIZU: 'Meizu',
MICROMAX: 'Micromax',
MICROSOFT: 'Microsoft',
MOTOROLA: 'Motorola',
NEXIAN: 'Nexian',
NINTENDO: 'Nintendo',
NOKIA: 'Nokia',
NOTHING: 'Nothing',
NVIDIA: 'Nvidia',
ONEPLUS: 'OnePlus',
OPPO: 'OPPO',
@@ -228,6 +242,7 @@ const Vendor = Object.freeze({
PALM: 'Palm',
PANASONIC: 'Panasonic',
PEBBLE: 'Pebble',
PICO: 'Pico',
POLYTRON: 'Polytron',
REALME: 'Realme',
RIM: 'RIM',
@@ -235,8 +250,10 @@ const Vendor = Object.freeze({
SAMSUNG: 'Samsung',
SHARP: 'Sharp',
SIEMENS: 'Siemens',
SMARTFREN: 'Smartfren',
SONY: 'Sony',
SPRINT: 'Sprint',
TCL: 'TCL',
TECHNISAT: 'TechniSAT',
TECNO: 'Tecno',
TESLA: 'Tesla',
@@ -253,6 +270,7 @@ const Vendor = Object.freeze({
const Engine = Object.freeze({
AMAYA: 'Amaya',
ARKWEB: 'ArkWeb',
BLINK: 'Blink',
EDGEHTML: 'EdgeHTML',
FLOW: 'Flow',
@@ -266,6 +284,7 @@ const Engine = Object.freeze({
NETFRONT: 'NetFront',
NETSURF: 'NetSurf',
PRESTO: 'Presto',
SERVO: 'Servo',
TASMAN: 'Tasman',
TRIDENT: 'Trident',
W3M: 'w3m',
@@ -284,6 +303,10 @@ const OS = Object.freeze({
CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS',
CHROMECAST: 'Chromecast',
CHROMECAST_ANDROID: 'Chromecast Android',
CHROMECAST_FUCHSIA: 'Chromecast Fuchsia',
CHROMECAST_LINUX: 'Chromecast Linux',
CHROMECAST_SMARTSPEAKER: 'Chromecast SmartSpeaker',
CONTIKI: 'Contiki',
DEBIAN: 'Debian',
DEEPIN: 'Deepin',
@@ -319,12 +342,14 @@ const OS = Object.freeze({
NETRANGE: 'NetRange',
NETTV: 'NetTV',
NINTENDO: 'Nintendo',
OPENHARMONY: 'OpenHarmony',
OPENBSD: 'OpenBSD',
OPENVMS: 'OpenVMS',
OS2: 'OS/2',
PALM: 'Palm',
PC_BSD: 'PC-BSD',
PCLINUXOS: 'PCLinuxOS',
PICO: 'Pico',
PLAN9: 'Plan9',
PLAYSTATION: 'PlayStation',
QNX: 'QNX',
@@ -344,7 +369,6 @@ const OS = Object.freeze({
UBUNTU: 'Ubuntu',
UNIX: 'Unix',
VECTORLINUX: 'VectorLinux',
VIERA: 'Viera',
WATCHOS: 'watchOS',
WEBOS: 'WebOS',
WINDOWS: 'Windows',

View File

@@ -1,14 +1,15 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.3
// Type definitions for Helpers submodule of UAParser.js v2.0.0-rc.3
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman>
import type { UAParserExt } from "../main/ua-parser";
export const Bots: UAParserExt;
export const CLIs: UAParserExt;
export const Crawlers: UAParserExt;
export const ExtraDevices: UAParserExt;
export const Emails: UAParserExt;
export const Fetchers: UAParserExt;
export const InApps: UAParserExt;
export const MediaPlayers: UAParserExt;
export const Modules: UAParserExt;
export const Libraries: UAParserExt;
export const MediaPlayers: UAParserExt;

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-beta.3
/* Extensions for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Personal License */
@@ -19,7 +19,8 @@ const CLI = 'cli';
const EMAIL = 'email';
const FETCHER = 'fetcher';
const INAPP = 'inapp';
const MODULE = 'module';
const MEDIAPLAYER = 'mediaplayer';
const LIBRARY = 'library';
//////////////////////
// COMMAND LINE APPS
@@ -38,43 +39,73 @@ const CLIs = Object.freeze({
const Crawlers = Object.freeze({
browser : [
// Amazonbot - https://developer.amazon.com/amazonbot
// Applebot - http://apple.com/go/applebot
// Bingbot - http://www.bing.com/bingbot.htm
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot
[/((?:amazon|apple|bing|duckduck|facebook|gpt)bot)\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, CRAWLER]],
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
[/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, CRAWLER]],
// Bytespider
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
[/((?:bytespider|(?=yahoo! )slurp))/i],
[NAME, [TYPE, CRAWLER]],
// ClaudeBot
[/(claude(?:bot|-web))\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, CRAWLER]],
// Googlebot - http://www.google.com/bot.html
[
/(google(?:bot|other)(?:-image|-video|-news|-extended)?|(?:storebot-)?google(?:-inspectiontool)?)\/?([\w\.]*)/i
],
[NAME, VERSION, [TYPE, CRAWLER]],
// Sogou Spider
[/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i],
// AhrefsBot - https://ahrefs.com/robot
// Amazonbot - https://developer.amazon.com/amazonbot
// Applebot - http://apple.com/go/applebot
// Bingbot - http://www.bing.com/bingbot.htm
// CCBot - https://commoncrawl.org/faq
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot
// MJ12bot - https://mj12bot.com/
// MojeekBot - https://www.mojeek.com/bot.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot
// SemrushBot - http://www.semrush.com/bot.html
/((?:ahrefs|amazon|apple|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush)bot)\/([\w\.]+)/i,
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i,
// ClaudeBot (Anthropic)
/(claude(?:bot|-web))\/([\w\.]+)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i,
// Facebook / Meta
// https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
/(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
// Googlebot - http://www.google.com/bot.html
/(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
// Internet Archive (archive.org)
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
// Sogou Spider
/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i,
// Yahoo! Japan - https://support.yahoo-net.jp/PccSearch/s/article/H000007955
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
// Yeti (Naver)
/(yeti)\/([\w\.]+)/i,
// YisouSpider
/(yisouspider)\/?([\w\.]*)/i
],
[NAME, VERSION, [TYPE, CRAWLER]],
// Yandex Bots - https://yandex.com/bots
[
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i
// Google Bots
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
// Bytespider
// DataForSeoBot - https://dataforseo.com/dataforseo-bot
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
// Qihoo 360Spider
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
/(360spider-?(?:image|video)?|bytespider|(?:aspiegel|dataforseo|petal|turnitin)bot|(?=yahoo! )slurp)/i
],
[NAME, VERSION, [TYPE, CRAWLER]]
[NAME, [TYPE, CRAWLER]]
]
});
@@ -164,8 +195,8 @@ const ExtraDevices = Object.freeze({
const Emails = Object.freeze({
browser : [
// Microsoft Outlook / Thunderbird
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
// Evolution / Kontact/KMail / [Microsoft/Mac] Outlook / Thunderbird
[/(evolution|kmail2?|kontact|(?:microsoft |mac)outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
]
});
@@ -175,29 +206,37 @@ const Emails = Object.freeze({
const Fetchers = Object.freeze({
browser : [
// BingPreview / Mastodon / Pinterestbot / Redditbot / Telegrambot / Twitterbot
[/(bingpreview|mastodon|(?:discord|linkedin|pinterest|reddit|telegram|twitter)bot)\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, FETCHER]],
// Google Bots / Snapchat
[/(feedfetcher-google|google-read-aloud|(?=bot; )snapchat)/i],
[NAME, [TYPE, FETCHER]],
// Slackbot - https://api.slack.com/robots
[/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i],
[NAME, VERSION, [TYPE, FETCHER]],
// WhatsApp
[/(whatsapp)\/([\w\.]+)[\/ ][ianw]/i],
[NAME, VERSION, [TYPE, FETCHER]],
// Yandex Bots - https://yandex.com/bots
[
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
// BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot
/(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i,
// Google Site Verifier
/(google-site-verification)\/([\w\.]+)/i,
// Meta
/(meta-externalfetcher)\/([\w\.]+)/i,
// Slackbot - https://api.slack.com/robots
/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i,
// WhatsApp
/(whatsapp)\/([\w\.]+)[\/ ][ianw]/i,
// Yahoo! Japan
/(y!?j-dlc)\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots
/(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
/(yandex(?:sitelinks|userproxy))/i
],
[NAME, VERSION, [TYPE, FETCHER]]
[NAME, VERSION, [TYPE, FETCHER]],
// Google Bots / Snapchat
[/(feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i],
[NAME, [TYPE, FETCHER]],
]
});
@@ -207,7 +246,11 @@ const Fetchers = Object.freeze({
const InApps = Object.freeze({
browser : [
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]]
// Slack
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]],
// Yahoo! Japan
[/jp\.co\.yahoo\.android\.yjtop\/([\d\.]+)/i], [VERSION, 'Yahoo! Japan', [TYPE, INAPP]]
]
});
@@ -220,13 +263,13 @@ const MediaPlayers = Object.freeze({
/(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia
/(coremedia) v([\w\._]+)/i
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i,
// Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
@@ -234,111 +277,125 @@ const MediaPlayers = Object.freeze({
/(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD
/(lg player|nexplayer)\s([\d\.]+)/i,
/player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(nexplayer)\s([\w\.-]+)/i // Nexplayer
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(flrp)\/([\w\.-]+)/i // Flip Player
], [[NAME, 'Flip Player'], VERSION], [
], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
], [NAME], [
/(fstream|nativehost|queryseekspider)/i
// FStream/NativeHost/QuerySeekSpider
], [NAME, [TYPE, MEDIAPLAYER]], [
/(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i
// Gstreamer
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player
/(java|python-urllib|python-requests|wget|libcurl)\/([\w\.-_]+)/i,
// Java/urllib/requests/wget/cURL
/(lavf)([\d\.]+)/i // Lavf (FFMPEG)
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(htc_one_s)\/([\d\.]+)/i, // HTC One S
], [[NAME, /_/g, ' '], VERSION], [
], [[NAME, /_/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i,
// MPlayer SVN
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer
/(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(mplayer)/i, // MPlayer (no other info)
/(yourmuze)/i, // YourMuze
/(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime
], [NAME], [
], [NAME, [TYPE, MEDIAPLAYER]], [
/(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(nokia\d+)\/([\w\.-]+)/i // Nokia
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(winamp)3 version ([\w\.-]+)/i, // Winamp
/(winamp)\s([\w\.-]+)/i,
/(winamp)mpeg\/([\w\.-]+)/i
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
// inlight radio
], [NAME], [
], [NAME, [TYPE, MEDIAPLAYER]], [
/(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i
// QuickTime/RealMedia/RadioApp/RadioClientApplication/
// SoundTap/Totem/Stagefright/Streamium
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(smp)([\d\.]+)/i // SMP
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(vlc) media player - version ([\w\.]+)/i, // VLC Videolan
/(vlc)\/([\w\.-]+)/i,
/(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp
/(foobar2000)\/([\d\.]+)/i, // Foobar2000
/(itunes)\/([\d\.]+)/i // iTunes
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(wmplayer)\/([\w\.-]+)/i, // Windows Media Player
/(windows-media-player)\/([\w\.-]+)/i
], [[NAME, /-/g, ' '], VERSION], [
], [[NAME, /-/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [
/windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i,
// Windows Media Server
], [VERSION, [NAME, 'Windows']], [
], [VERSION, [NAME, 'Windows'], [TYPE, MEDIAPLAYER]], [
/(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(rad.io)\s([\d\.]+)/i, // Rad.io
/(radio.(?:de|at|fr))\s([\d\.]+)/i
], [[NAME, 'rad.io'], VERSION]
], [[NAME, 'rad.io'], VERSION, [TYPE, MEDIAPLAYER]]
]
});
////////////////////////
// MODULES / LIBRARIES
///////////////////////
/////////////
// LIBRARIES
//////////////
const Modules = Object.freeze({
const Libraries = Object.freeze({
browser : [
// Axios/jsdom/Scrapy
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, MODULE]]
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]]
]
});
//////////
// BOTS
/////////
const Bots = Object.freeze({
browser : [
...CLIs.browser,
...Crawlers.browser,
...Fetchers.browser,
...Libraries.browser
]
});
module.exports = {
Bots,
CLIs,
Crawlers,
ExtraDevices,
Emails,
Fetchers,
InApps,
MediaPlayers,
Modules
Libraries,
MediaPlayers
};

View File

@@ -3,7 +3,7 @@
// Source: /src/extensions/ua-parser-extensions.js
///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-beta.3
/* Extensions for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Personal License */
@@ -23,7 +23,8 @@ const CLI = 'cli';
const EMAIL = 'email';
const FETCHER = 'fetcher';
const INAPP = 'inapp';
const MODULE = 'module';
const MEDIAPLAYER = 'mediaplayer';
const LIBRARY = 'library';
//////////////////////
// COMMAND LINE APPS
@@ -42,43 +43,73 @@ const CLIs = Object.freeze({
const Crawlers = Object.freeze({
browser : [
// Amazonbot - https://developer.amazon.com/amazonbot
// Applebot - http://apple.com/go/applebot
// Bingbot - http://www.bing.com/bingbot.htm
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot
[/((?:amazon|apple|bing|duckduck|facebook|gpt)bot)\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, CRAWLER]],
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
[/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, CRAWLER]],
// Bytespider
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
[/((?:bytespider|(?=yahoo! )slurp))/i],
[NAME, [TYPE, CRAWLER]],
// ClaudeBot
[/(claude(?:bot|-web))\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, CRAWLER]],
// Googlebot - http://www.google.com/bot.html
[
/(google(?:bot|other)(?:-image|-video|-news|-extended)?|(?:storebot-)?google(?:-inspectiontool)?)\/?([\w\.]*)/i
],
[NAME, VERSION, [TYPE, CRAWLER]],
// Sogou Spider
[/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i],
// AhrefsBot - https://ahrefs.com/robot
// Amazonbot - https://developer.amazon.com/amazonbot
// Applebot - http://apple.com/go/applebot
// Bingbot - http://www.bing.com/bingbot.htm
// CCBot - https://commoncrawl.org/faq
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
// GPTBot - https://platform.openai.com/docs/gptbot
// MJ12bot - https://mj12bot.com/
// MojeekBot - https://www.mojeek.com/bot.html
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
// PerplexityBot - https://perplexity.ai/perplexitybot
// SemrushBot - http://www.semrush.com/bot.html
/((?:ahrefs|amazon|apple|bing|cc|dot|duckduck|exa|facebook|gpt|mj12|mojeek|oai-search|perplexity|semrush)bot)\/([\w\.]+)/i,
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i,
// ClaudeBot (Anthropic)
/(claude(?:bot|-web))\/([\w\.]+)/i,
// Coc Coc Bot - https://help.coccoc.com/en/search-engine
/(coccocbot-(?:image|web))\/([\w\.]+)/i,
// Facebook / Meta
// https://developers.facebook.com/docs/sharing/webmasters/web-crawlers
/(facebook(?:externalhit|catalog)|meta-externalagent)\/([\w\.]+)/i,
// Googlebot - http://www.google.com/bot.html
/(google(?:bot|other|-inspectiontool)(?:-image|-video|-news)?|storebot-google)\/?([\w\.]*)/i,
// Internet Archive (archive.org)
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
// Sogou Spider
/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i,
// Yahoo! Japan - https://support.yahoo-net.jp/PccSearch/s/article/H000007955
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
// Yeti (Naver)
/(yeti)\/([\w\.]+)/i,
// YisouSpider
/(yisouspider)\/?([\w\.]*)/i
],
[NAME, VERSION, [TYPE, CRAWLER]],
// Yandex Bots - https://yandex.com/bots
[
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i
// Google Bots
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
// Bytespider
// DataForSeoBot - https://dataforseo.com/dataforseo-bot
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
// Qihoo 360Spider
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
/(360spider-?(?:image|video)?|bytespider|(?:aspiegel|dataforseo|petal|turnitin)bot|(?=yahoo! )slurp)/i
],
[NAME, VERSION, [TYPE, CRAWLER]]
[NAME, [TYPE, CRAWLER]]
]
});
@@ -168,8 +199,8 @@ const ExtraDevices = Object.freeze({
const Emails = Object.freeze({
browser : [
// Microsoft Outlook / Thunderbird
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
// Evolution / Kontact/KMail / [Microsoft/Mac] Outlook / Thunderbird
[/(evolution|kmail2?|kontact|(?:microsoft |mac)outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
]
});
@@ -179,29 +210,37 @@ const Emails = Object.freeze({
const Fetchers = Object.freeze({
browser : [
// BingPreview / Mastodon / Pinterestbot / Redditbot / Telegrambot / Twitterbot
[/(bingpreview|mastodon|(?:discord|linkedin|pinterest|reddit|telegram|twitter)bot)\/([\w\.]+)/i],
[NAME, VERSION, [TYPE, FETCHER]],
// Google Bots / Snapchat
[/(feedfetcher-google|google-read-aloud|(?=bot; )snapchat)/i],
[NAME, [TYPE, FETCHER]],
// Slackbot - https://api.slack.com/robots
[/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i],
[NAME, VERSION, [TYPE, FETCHER]],
// WhatsApp
[/(whatsapp)\/([\w\.]+)[\/ ][ianw]/i],
[NAME, VERSION, [TYPE, FETCHER]],
// Yandex Bots - https://yandex.com/bots
[
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
// BingPreview / Mastodon / Pinterestbot / Redditbot / Rogerbot / Telegrambot / Twitterbot / UptimeRobot
/(ahrefssiteaudit|bingpreview|chatgpt-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|telegram|twitter|uptimero)bot)\/([\w\.]+)/i,
// Google Site Verifier
/(google-site-verification)\/([\w\.]+)/i,
// Meta
/(meta-externalfetcher)\/([\w\.]+)/i,
// Slackbot - https://api.slack.com/robots
/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i,
// WhatsApp
/(whatsapp)\/([\w\.]+)[\/ ][ianw]/i,
// Yahoo! Japan
/(y!?j-dlc)\/([\w\.]+)/i,
// Yandex Bots - https://yandex.com/bots
/(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
/(yandex(?:sitelinks|userproxy))/i
],
[NAME, VERSION, [TYPE, FETCHER]]
[NAME, VERSION, [TYPE, FETCHER]],
// Google Bots / Snapchat
[/(feedfetcher-google|google(?:-read-aloud|producer)|(?=bot; )snapchat)/i],
[NAME, [TYPE, FETCHER]],
]
});
@@ -211,7 +250,11 @@ const Fetchers = Object.freeze({
const InApps = Object.freeze({
browser : [
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]]
// Slack
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]],
// Yahoo! Japan
[/jp\.co\.yahoo\.android\.yjtop\/([\d\.]+)/i], [VERSION, 'Yahoo! Japan', [TYPE, INAPP]]
]
});
@@ -224,13 +267,13 @@ const MediaPlayers = Object.freeze({
/(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia
/(coremedia) v([\w\._]+)/i
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i,
// Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
@@ -238,111 +281,125 @@ const MediaPlayers = Object.freeze({
/(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD
/(lg player|nexplayer)\s([\d\.]+)/i,
/player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(nexplayer)\s([\w\.-]+)/i // Nexplayer
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(flrp)\/([\w\.-]+)/i // Flip Player
], [[NAME, 'Flip Player'], VERSION], [
], [[NAME, 'Flip Player'], VERSION, [TYPE, MEDIAPLAYER]], [
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
], [NAME], [
/(fstream|nativehost|queryseekspider)/i
// FStream/NativeHost/QuerySeekSpider
], [NAME, [TYPE, MEDIAPLAYER]], [
/(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i
// Gstreamer
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player
/(java|python-urllib|python-requests|wget|libcurl)\/([\w\.-_]+)/i,
// Java/urllib/requests/wget/cURL
/(lavf)([\d\.]+)/i // Lavf (FFMPEG)
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(htc_one_s)\/([\d\.]+)/i, // HTC One S
], [[NAME, /_/g, ' '], VERSION], [
], [[NAME, /_/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i,
// MPlayer SVN
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer
/(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(mplayer)/i, // MPlayer (no other info)
/(yourmuze)/i, // YourMuze
/(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime
], [NAME], [
], [NAME, [TYPE, MEDIAPLAYER]], [
/(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(nokia\d+)\/([\w\.-]+)/i // Nokia
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(winamp)3 version ([\w\.-]+)/i, // Winamp
/(winamp)\s([\w\.-]+)/i,
/(winamp)mpeg\/([\w\.-]+)/i
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
// inlight radio
], [NAME], [
], [NAME, [TYPE, MEDIAPLAYER]], [
/(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i
// QuickTime/RealMedia/RadioApp/RadioClientApplication/
// SoundTap/Totem/Stagefright/Streamium
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(smp)([\d\.]+)/i // SMP
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(vlc) media player - version ([\w\.]+)/i, // VLC Videolan
/(vlc)\/([\w\.-]+)/i,
/(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp
/(foobar2000)\/([\d\.]+)/i, // Foobar2000
/(itunes)\/([\d\.]+)/i // iTunes
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(wmplayer)\/([\w\.-]+)/i, // Windows Media Player
/(windows-media-player)\/([\w\.-]+)/i
], [[NAME, /-/g, ' '], VERSION], [
], [[NAME, /-/g, ' '], VERSION, [TYPE, MEDIAPLAYER]], [
/windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i,
// Windows Media Server
], [VERSION, [NAME, 'Windows']], [
], [VERSION, [NAME, 'Windows'], [TYPE, MEDIAPLAYER]], [
/(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm
], [NAME, VERSION], [
], [NAME, VERSION, [TYPE, MEDIAPLAYER]], [
/(rad.io)\s([\d\.]+)/i, // Rad.io
/(radio.(?:de|at|fr))\s([\d\.]+)/i
], [[NAME, 'rad.io'], VERSION]
], [[NAME, 'rad.io'], VERSION, [TYPE, MEDIAPLAYER]]
]
});
////////////////////////
// MODULES / LIBRARIES
///////////////////////
/////////////
// LIBRARIES
//////////////
const Modules = Object.freeze({
const Libraries = Object.freeze({
browser : [
// Axios/jsdom/Scrapy
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, MODULE]]
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, LIBRARY]]
]
});
//////////
// BOTS
/////////
const Bots = Object.freeze({
browser : [
...CLIs.browser,
...Crawlers.browser,
...Fetchers.browser,
...Libraries.browser
]
});
export {
Bots,
CLIs,
Crawlers,
ExtraDevices,
Emails,
Fetchers,
InApps,
MediaPlayers,
Modules
Libraries,
MediaPlayers
};

View File

@@ -1,15 +1,25 @@
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.3
// Type definitions for Helpers submodule of UAParser.js v2.0.0-rc.3
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman>
import { IResult } from "../main/ua-parser";
declare function isAppleSilicon(res: IResult): boolean;
declare function isChromiumBased(res: IResult): boolean;
declare function getDeviceVendor(model: string): string | undefined;
declare function isAppleSilicon(res: IResult, useFeatureDetection?: boolean): boolean;
declare function isBot(res: IResult): boolean;
declare function isChromeFamily(res: IResult): boolean;
declare function isElectron(): boolean;
declare function isFromEU(): boolean;
declare function isFrozenUA(ua: string): boolean;
declare function isStandalonePWA(): boolean;
export {
getDeviceVendor,
isAppleSilicon,
isChromiumBased,
isFrozenUA
isBot,
isChromeFamily,
isElectron,
isFromEU,
isFrozenUA,
isStandalonePWA
}

View File

@@ -1,22 +1,56 @@
///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.0-beta.3
/* Helpers for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */
UAParser.js PRO Personal License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
const { UAParser } = require('../main/ua-parser');
const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
const { isFromEU } = require('detect-europe-js');
const { isFrozenUA } = require('ua-is-frozen');
const { isStandalonePWA } = require('is-standalone-pwa');
const isAppleSilicon = (res) => res.os.is(OS.MACOS) && res.cpu.is(CPU.ARM);
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;
const isChromiumBased = (res) => res.engine.is(Engine.BLINK);
const isAppleSilicon = (res, useFeatureDetection) => {
if (res.os.is(OS.MACOS)) {
if (res.cpu.is(CPU.ARM)) {
return true;
}
if (useFeatureDetection) {
try {
const canvas = document.createElement('canvas');
const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
const debug = webgl.getExtension('WEBGL_debug_renderer_info');
const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
if (renderer.match(/apple m\d/i)) {
return true;
}
} catch {
return false;
}
}
}
return false;
}
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);
const isBot = (res) => ['cli', 'crawler', 'fetcher', 'library'].includes(res.browser.type);
const isChromeFamily = (res) => res.engine.is(Engine.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser
module.exports = {
getDeviceVendor,
isAppleSilicon,
isChromiumBased,
isFrozenUA
isBot,
isChromeFamily,
isElectron,
isFromEU,
isFrozenUA,
isStandalonePWA
}

View File

@@ -3,24 +3,58 @@
// Source: /src/helpers/ua-parser-helpers.js
///////////////////////////////////////////////
/* Helpers for UAParser.js v2.0.0-beta.3
/* Helpers for UAParser.js v2.0.0-rc.3
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
AGPLv3 License */
UAParser.js PRO Personal License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
import { CPU, OS, Engine } from '../enums/ua-parser-enums';
import { UAParser } from '../main/ua-parser.mjs';
import { CPU, OS, Engine } from '../enums/ua-parser-enums.mjs';
import { isFromEU } from 'detect-europe-js';
import { isFrozenUA } from 'ua-is-frozen';
import { isStandalonePWA } from 'is-standalone-pwa';
const isAppleSilicon = (res) => res.os.is(OS.MACOS) && res.cpu.is(CPU.ARM);
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;
const isChromiumBased = (res) => res.engine.is(Engine.BLINK);
const isAppleSilicon = (res, useFeatureDetection) => {
if (res.os.is(OS.MACOS)) {
if (res.cpu.is(CPU.ARM)) {
return true;
}
if (useFeatureDetection) {
try {
const canvas = document.createElement('canvas');
const webgl = canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
const debug = webgl.getExtension('WEBGL_debug_renderer_info');
const renderer = webgl.getParameter(debug.UNMASKED_RENDERER_WEBGL);
if (renderer.match(/apple m\d/i)) {
return true;
}
} catch {
return false;
}
}
}
return false;
}
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);
const isBot = (res) => ['cli', 'crawler', 'fetcher', 'library'].includes(res.browser.type);
const isChromeFamily = (res) => res.engine.is(Engine.BLINK);
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
/ electron\//i.test(navigator?.userAgent)); // browser
export {
getDeviceVendor,
isAppleSilicon,
isChromiumBased,
isFrozenUA
isBot,
isChromeFamily,
isElectron,
isFromEU,
isFrozenUA,
isStandalonePWA
}

View File

@@ -1,4 +1,4 @@
// Type definitions for UAParser.js v2.0.0-beta.3
// Type definitions for UAParser.js v2.0.0-rc.3
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman>
@@ -8,18 +8,18 @@ declare namespace UAParser {
is(val: string): boolean;
toString(): string;
withClientHints(): PromiseLike<T> | T;
withFeatureCheck(): T;
withFeatureCheck(): PromiseLike<T> | T;
}
interface IBrowser extends IData<IBrowser> {
name?: string;
version?: string;
major?: string;
type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'module';
type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'library';
}
interface ICPU extends IData<ICPU> {
architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'ppc' | 'sparc' | 'sparc64';
architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'avr32' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'pa-risc' | 'ppc' | 'sparc' | 'sparc64';
}
interface IDevice extends IData<IDevice> {
@@ -29,7 +29,7 @@ declare namespace UAParser {
}
interface IEngine extends IData<IEngine> {
name?: 'Amaya' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
name?: 'Amaya' | 'ArkWeb' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Servo' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
version?: string;
}

View File

@@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.0-beta.3
/* UAParser.js v2.0.0-rc.3
Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
UAParser.js PRO Personal License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@@ -19,7 +19,7 @@
// Constants
/////////////
var LIBVERSION = '2.0.0-beta.3',
var LIBVERSION = '2.0.0-rc.3',
EMPTY = '',
UNKNOWN = '?',
FUNC_TYPE = 'function',
@@ -40,6 +40,7 @@
WEARABLE = 'wearable',
XR = 'xr',
EMBEDDED = 'embedded',
INAPP = 'inapp',
USER_AGENT = 'user-agent',
UA_MAX_LENGTH = 500,
BRANDS = 'brands',
@@ -71,6 +72,7 @@
GOOGLE = 'Google',
HUAWEI = 'Huawei',
LENOVO = 'Lenovo',
HONOR = 'Honor',
LG = 'LG',
MICROSOFT = 'Microsoft',
MOTOROLA = 'Motorola',
@@ -82,6 +84,7 @@
PREFIX_MOBILE = 'Mobile ',
SUFFIX_BROWSER = ' Browser',
CHROME = 'Chrome',
CHROMECAST = 'Chromecast',
EDGE = 'Edge',
FIREFOX = 'Firefox',
OPERA = 'Opera',
@@ -319,19 +322,23 @@
// Mixed
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
], [VERSION, [NAME, 'Baidu']], [
/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
], [VERSION, [NAME, 'Maxthon']], [
/(kindle)\/([\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
// Trident based
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar)\/([-\w\.]+)/i,
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
// Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
/(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,
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
/(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115
/(weibo)__([\d\.]+)/i // Weibo
], [NAME, VERSION], [
/quark(?:pc)?\/([-\w\.]+)/i // Quark
], [VERSION, [NAME, 'Quark']], [
/\bddg\/([\w\.]+)/i // DuckDuckGo
], [VERSION, [NAME, 'DuckDuckGo']], [
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
@@ -364,31 +371,31 @@
], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
/fxios\/([\w\.-]+)/i // Firefox for iOS
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
/\bqihu|(qi?ho?o?|360)browser/i // 360
], [[NAME, '360' + SUFFIX_BROWSER]], [
/\bqihoobrowser\/?([\w\.]*)/i // 360
], [VERSION, [NAME, '360']], [
/\b(qq)\/([\w\.]+)/i // QQ
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
], [VERSION, [NAME, SOGOU + ' Explorer']], [
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
], [[NAME, SOGOU + ' Mobile'], VERSION], [
/(electron)\/([\w\.]+) safari/i, // Electron-based App
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
], [NAME, VERSION], [
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
/(lbbrowser|rekonq)/i // LieBao Browser/Rekonq
], [NAME], [
/ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
/ome\/([\w\.]+).+qihu (360)[es]e/i // 360
], [VERSION, NAME], [
// WebView
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
], [[NAME, FACEBOOK], VERSION], [
], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
@@ -396,12 +403,17 @@
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
/(alipay)client\/([\w\.]+)/i, // Alipay
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
], [NAME, VERSION], [
/(instagram|snapchat)[\/ ]([-\w\.]+)/i // Instagram/Snapchat
], [NAME, VERSION, [TYPE, INAPP]], [
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
], [VERSION, [NAME, 'GSA']], [
], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
], [VERSION, [NAME, 'TikTok']], [
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [
/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
], [VERSION, [NAME, CHROME+' Headless']], [
@@ -435,7 +447,7 @@
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION], [
/(wolvic)\/([\w\.]+)/i // Wolvic
/(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
], [NAME, VERSION], [
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
], [VERSION, [NAME, FIREFOX+' Reality']], [
@@ -497,8 +509,8 @@
// Samsung
/\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
], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
/\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
/samsung[- ]([-\w]+)/i,
/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
/samsung[- ]((?!sm-[lr])[-\w]+)/i,
/sec-(sgh\w+)/i
], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
@@ -516,10 +528,14 @@
/\b(sh-?[altvz]?\d\d[a-ekm]?)/i
], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
// Honor
/(?:honor)([-\w ]+)[;\)]/i
], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
// Huawei
/\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
/(?:huawei|honor)([-\w ]+)[;\)]/i,
/(?:huawei)([-\w ]+)[;\)]/i,
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
@@ -529,7 +545,7 @@
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
/\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
@@ -584,7 +600,7 @@
], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
// Sony
/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
/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
], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
/sony tablet [ps]/i,
/\b(?:sony)?sgp\w+(?: bui|\))/i
@@ -597,7 +613,7 @@
// Amazon
/(alexa)webm/i,
/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show
/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i, // Kindle Fire without Silk / Echo Show
/(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
@@ -626,6 +642,17 @@
/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
// TCL
/tcl (xess p17aa)/i,
/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
], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [
/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
], [MODEL, [VENDOR, 'TCL'], [TYPE, MOBILE]], [
// itel
/(itel) ((\w+))/i
], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [
// Acer
/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
@@ -639,9 +666,28 @@
/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
// Energizer
/; (energy ?\w+)(?: bui|\))/i,
/; energizer ([\w ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
// Cat
/; cat (b35);/i,
/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
// Smartfren
/((?:new )?andromax[\w- ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
// Nothing
/droid.+; (a(?:015|06[35]|142p?))/i
], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
// MIXED
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan
/; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO
/(hp) ([\w ]+\w)/i, // HP iPAQ
/(asus)-?(\w+)/i, // Asus
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
@@ -650,6 +696,7 @@
/(oppo) ?([\w ]+) bui/i // OPPO
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(imo) (tab \w+)/i, // IMO
/(kobo)\s(ereader|touch)/i, // Kobo
/(archos) (gamepad2?)/i, // Archos
/(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
@@ -683,8 +730,14 @@
], [[VENDOR, LG], [TYPE, SMARTTV]], [
/(apple) ?tv/i // Apple TV
], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
/crkey/i // Google Chromecast
], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/crkey.*devicetype\/chromecast/i // Google Chromecast Third Generation
], [[MODEL, CHROMECAST+' Third Generation'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/crkey.*devicetype\/([^/]*)/i // Google Chromecast with specific device type
], [[MODEL, /^/, 'Chromecast '], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/fuchsia.*crkey/i // Google Chromecast Nest Hub
], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/crkey/i // Google Chromecast, Linux-based or unknown
], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/droid.+aft(\w+)( bui|\))/i // Fire TV
], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
/\(dtv[\);].+(aquos)/i,
@@ -720,6 +773,8 @@
// WEARABLES
///////////////////
/\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch
], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [
/((pebble))app/i // Pebble
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
@@ -733,7 +788,9 @@
/droid.+; (glass) \d/i // Google Glass
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
/(quest( \d| pro)?)/i // Oculus Quest
/(pico) (4|neo3(?: link|pro)?)/i // Pico
], [VENDOR, MODEL, [TYPE, XR]], [
/; (quest( \d| pro)?)/i // Oculus Quest
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
///////////////////
@@ -766,11 +823,14 @@
/windows.+ edge\/([\w\.]+)/i // EdgeHTML
], [VERSION, [NAME, EDGE+'HTML']], [
/(arkweb)\/([\w\.]+)/i // ArkWeb
], [NAME, VERSION], [
/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
], [VERSION, [NAME, 'Blink']], [
/(presto)\/([\w\.]+)/i, // Presto
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
/ekioh(flow)\/([\w\.]+)/i, // Flow
/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
/(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
@@ -802,10 +862,22 @@
/(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS
], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
// Google Chromecast
/android ([\d\.]+).*crkey/i // Google Chromecast, Android-based
], [VERSION, [NAME, CHROMECAST + ' Android']], [
/fuchsia.*crkey\/([\d\.]+)/i // Google Chromecast, Fuchsia-based
], [VERSION, [NAME, CHROMECAST + ' Fuchsia']], [
/crkey\/([\d\.]+).*devicetype\/smartspeaker/i // Google Chromecast, Linux-based Smart Speaker
], [VERSION, [NAME, CHROMECAST + ' SmartSpeaker']], [
/linux.*crkey\/([\d\.]+)/i // Google Chromecast, Legacy Linux-based
], [VERSION, [NAME, CHROMECAST + ' Linux']], [
/crkey\/([\d\.]+)/i // Google Chromecast, unknown
], [VERSION, [NAME, CHROMECAST]], [
// Mobile OSes
/droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS
], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
/(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony
/(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i,
/(blackberry)\w*\/([\w\.]*)/i, // Blackberry
/(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS
/\((series40);/i // Series 40
@@ -822,9 +894,7 @@
/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
], [VERSION, [NAME, 'watchOS']], [
// Google Chromecast
/crkey\/([\d\.]+)/i // Google Chromecast
], [VERSION, [NAME, CHROME+'cast']], [
// Google ChromeOS
/(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
], [[NAME, "Chrome OS"], VERSION],[
@@ -836,6 +906,7 @@
// Console
/(nintendo|playstation) (\w+)/i, // Nintendo/Playstation
/(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
/(pico) .+os([\w\.]+)/i, // Pico
// Other
/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
@@ -1186,14 +1257,21 @@
headers = extensions; // case UAParser(ua, headers)
extensions = undefined;
}
// Convert Headers object into a plain object
if (headers && typeof headers.append === FUNC_TYPE) {
var kv = {};
headers.forEach(function (v, k) { kv[k] = v; });
headers = kv;
}
if (!(this instanceof UAParser)) {
return new UAParser(ua, extensions, headers).getResult();
}
var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
(headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
EMPTY)), // empty string
httpUACH = new UACHData(headers, true),

View File

@@ -3,7 +3,7 @@
// Source: /src/main/ua-parser.js
/////////////////////////////////////////////////////////////////////////////////
/* UAParser.js v2.0.0-beta.3
/* UAParser.js v2.0.0-rc.3
Copyright © 2012-2024 Faisal Salman <f@faisalman.com>
UAParser.js PRO Personal License *//*
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
@@ -21,7 +21,7 @@
// Constants
/////////////
var LIBVERSION = '2.0.0-beta.3',
var LIBVERSION = '2.0.0-rc.3',
EMPTY = '',
UNKNOWN = '?',
FUNC_TYPE = 'function',
@@ -42,6 +42,7 @@
WEARABLE = 'wearable',
XR = 'xr',
EMBEDDED = 'embedded',
INAPP = 'inapp',
USER_AGENT = 'user-agent',
UA_MAX_LENGTH = 500,
BRANDS = 'brands',
@@ -73,6 +74,7 @@
GOOGLE = 'Google',
HUAWEI = 'Huawei',
LENOVO = 'Lenovo',
HONOR = 'Honor',
LG = 'LG',
MICROSOFT = 'Microsoft',
MOTOROLA = 'Motorola',
@@ -84,6 +86,7 @@
PREFIX_MOBILE = 'Mobile ',
SUFFIX_BROWSER = ' Browser',
CHROME = 'Chrome',
CHROMECAST = 'Chromecast',
EDGE = 'Edge',
FIREFOX = 'Firefox',
OPERA = 'Opera',
@@ -321,19 +324,23 @@
// Mixed
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
], [VERSION, [NAME, 'Baidu']], [
/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i // Maxthon
], [VERSION, [NAME, 'Maxthon']], [
/(kindle)\/([\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
// Trident based
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar)\/([-\w\.]+)/i,
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
// Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
/(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,
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon
/(heytap|ovi|115)browser\/([\d\.]+)/i, // HeyTap/Ovi/115
/(weibo)__([\d\.]+)/i // Weibo
], [NAME, VERSION], [
/quark(?:pc)?\/([-\w\.]+)/i // Quark
], [VERSION, [NAME, 'Quark']], [
/\bddg\/([\w\.]+)/i // DuckDuckGo
], [VERSION, [NAME, 'DuckDuckGo']], [
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
@@ -366,31 +373,31 @@
], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [
/fxios\/([\w\.-]+)/i // Firefox for iOS
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
/\bqihu|(qi?ho?o?|360)browser/i // 360
], [[NAME, '360' + SUFFIX_BROWSER]], [
/\bqihoobrowser\/?([\w\.]*)/i // 360
], [VERSION, [NAME, '360']], [
/\b(qq)\/([\w\.]+)/i // QQ
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
], [VERSION, [NAME, SOGOU + ' Explorer']], [
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
], [[NAME, SOGOU + ' Mobile'], VERSION], [
/(electron)\/([\w\.]+) safari/i, // Electron-based App
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i // QQ/2345
], [NAME, VERSION], [
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
/(lbbrowser|rekonq)/i // LieBao Browser/Rekonq
], [NAME], [
/ome\/([\w\.]+) \w* ?(iron) saf/i, // Iron
/ome\/([\w\.]+).+qihu (360)[es]e/i // 360
], [VERSION, NAME], [
// WebView
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
], [[NAME, FACEBOOK], VERSION], [
], [[NAME, FACEBOOK], VERSION, [TYPE, INAPP]], [
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
@@ -398,12 +405,17 @@
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
/(alipay)client\/([\w\.]+)/i, // Alipay
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
], [NAME, VERSION], [
/(instagram|snapchat)[\/ ]([-\w\.]+)/i // Instagram/Snapchat
], [NAME, VERSION, [TYPE, INAPP]], [
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
], [VERSION, [NAME, 'GSA']], [
], [VERSION, [NAME, 'GSA'], [TYPE, INAPP]], [
/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i // TikTok
], [VERSION, [NAME, 'TikTok']], [
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
], [NAME, [TYPE, INAPP]], [
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
], [NAME, VERSION], [
/headlesschrome(?:\/([\w\.]+)| )/i // Chrome Headless
], [VERSION, [NAME, CHROME+' Headless']], [
@@ -437,7 +449,7 @@
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION], [
/(wolvic)\/([\w\.]+)/i // Wolvic
/(wolvic|librewolf)\/([\w\.]+)/i // Wolvic/LibreWolf
], [NAME, VERSION], [
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
], [VERSION, [NAME, FIREFOX+' Reality']], [
@@ -499,8 +511,8 @@
// Samsung
/\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
], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [
/\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
/samsung[- ]([-\w]+)/i,
/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,
/samsung[- ]((?!sm-[lr])[-\w]+)/i,
/sec-(sgh\w+)/i
], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [
@@ -518,10 +530,14 @@
/\b(sh-?[altvz]?\d\d[a-ekm]?)/i
], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [
// Honor
/(?:honor)([-\w ]+)[;\)]/i
], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [
// Huawei
/\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [
/(?:huawei|honor)([-\w ]+)[;\)]/i,
/(?:huawei)([-\w ]+)[;\)]/i,
/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i
], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [
@@ -531,7 +547,7 @@
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i // Xiaomi Mi
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
/\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i // Mi Pad tablets
@@ -586,7 +602,7 @@
], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [
// Sony
/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
/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
], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [
/sony tablet [ps]/i,
/\b(?:sony)?sgp\w+(?: bui|\))/i
@@ -599,7 +615,7 @@
// Amazon
/(alexa)webm/i,
/(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, // Kindle Fire without Silk / Echo Show
/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i, // Kindle Fire without Silk / Echo Show
/(kf[a-z]+)( bui|\)).+silk\//i // Kindle Fire HD
], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [
/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i // Fire Phone
@@ -628,6 +644,17 @@
/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony
], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [
// TCL
/tcl (xess p17aa)/i,
/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
], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [
/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
], [MODEL, [VENDOR, 'TCL'], [TYPE, MOBILE]], [
// itel
/(itel) ((\w+))/i
], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [
// Acer
/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i
], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [
@@ -641,9 +668,28 @@
/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i
], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [
// Energizer
/; (energy ?\w+)(?: bui|\))/i,
/; energizer ([\w ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [
// Cat
/; cat (b35);/i,
/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i
], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [
// Smartfren
/((?:new )?andromax[\w- ]+)(?: bui|\))/i
], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [
// Nothing
/droid.+; (a(?:015|06[35]|142p?))/i
], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [
// MIXED
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i,
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron
/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,
// BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan
/; (imo) ((?!tab)[\w ]+?)(?: bui|\))/i, // IMO
/(hp) ([\w ]+\w)/i, // HP iPAQ
/(asus)-?(\w+)/i, // Asus
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
@@ -652,6 +698,7 @@
/(oppo) ?([\w ]+) bui/i // OPPO
], [VENDOR, MODEL, [TYPE, MOBILE]], [
/(imo) (tab \w+)/i, // IMO
/(kobo)\s(ereader|touch)/i, // Kobo
/(archos) (gamepad2?)/i, // Archos
/(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad
@@ -685,8 +732,14 @@
], [[VENDOR, LG], [TYPE, SMARTTV]], [
/(apple) ?tv/i // Apple TV
], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [
/crkey/i // Google Chromecast
], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/crkey.*devicetype\/chromecast/i // Google Chromecast Third Generation
], [[MODEL, CHROMECAST+' Third Generation'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/crkey.*devicetype\/([^/]*)/i // Google Chromecast with specific device type
], [[MODEL, /^/, 'Chromecast '], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/fuchsia.*crkey/i // Google Chromecast Nest Hub
], [[MODEL, CHROMECAST+' Nest Hub'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/crkey/i // Google Chromecast, Linux-based or unknown
], [[MODEL, CHROMECAST], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [
/droid.+aft(\w+)( bui|\))/i // Fire TV
], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [
/\(dtv[\);].+(aquos)/i,
@@ -722,6 +775,8 @@
// WEARABLES
///////////////////
/\b(sm-[lr]\d\d[05][fnuw]?s?)\b/i // Samsung Galaxy Watch
], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [
/((pebble))app/i // Pebble
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
@@ -735,7 +790,9 @@
/droid.+; (glass) \d/i // Google Glass
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
/(quest( \d| pro)?)/i // Oculus Quest
/(pico) (4|neo3(?: link|pro)?)/i // Pico
], [VENDOR, MODEL, [TYPE, XR]], [
/; (quest( \d| pro)?)/i // Oculus Quest
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
///////////////////
@@ -768,11 +825,14 @@
/windows.+ edge\/([\w\.]+)/i // EdgeHTML
], [VERSION, [NAME, EDGE+'HTML']], [
/(arkweb)\/([\w\.]+)/i // ArkWeb
], [NAME, VERSION], [
/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i // Blink
], [VERSION, [NAME, 'Blink']], [
/(presto)\/([\w\.]+)/i, // Presto
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo
/ekioh(flow)\/([\w\.]+)/i, // Flow
/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, // KHTML/Tasman/Links
/(icab)[\/ ]([23]\.[\d\.]+)/i, // iCab
@@ -804,10 +864,22 @@
/(macintosh|mac_powerpc\b)(?!.+haiku)/i // Mac OS
], [[NAME, 'macOS'], [VERSION, /_/g, '.']], [
// Google Chromecast
/android ([\d\.]+).*crkey/i // Google Chromecast, Android-based
], [VERSION, [NAME, CHROMECAST + ' Android']], [
/fuchsia.*crkey\/([\d\.]+)/i // Google Chromecast, Fuchsia-based
], [VERSION, [NAME, CHROMECAST + ' Fuchsia']], [
/crkey\/([\d\.]+).*devicetype\/smartspeaker/i // Google Chromecast, Linux-based Smart Speaker
], [VERSION, [NAME, CHROMECAST + ' SmartSpeaker']], [
/linux.*crkey\/([\d\.]+)/i // Google Chromecast, Legacy Linux-based
], [VERSION, [NAME, CHROMECAST + ' Linux']], [
/crkey\/([\d\.]+)/i // Google Chromecast, unknown
], [VERSION, [NAME, CHROMECAST]], [
// Mobile OSes
/droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS
], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS
/(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i,
], [VERSION, NAME], [ // Android/WebOS/QNX/Bada/RIM/Maemo/MeeGo/Sailfish OS/OpenHarmony
/(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish|openharmony)[-\/ ]?([\w\.]*)/i,
/(blackberry)\w*\/([\w\.]*)/i, // Blackberry
/(tizen|kaios)[\/ ]([\w\.]+)/i, // Tizen/KaiOS
/\((series40);/i // Series 40
@@ -824,9 +896,7 @@
/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i // watchOS
], [VERSION, [NAME, 'watchOS']], [
// Google Chromecast
/crkey\/([\d\.]+)/i // Google Chromecast
], [VERSION, [NAME, CHROME+'cast']], [
// Google ChromeOS
/(cros) [\w]+(?:\)| ([\w\.]+)\b)/i // Chromium OS
], [[NAME, "Chrome OS"], VERSION],[
@@ -838,6 +908,7 @@
// Console
/(nintendo|playstation) (\w+)/i, // Nintendo/Playstation
/(xbox); +xbox ([^\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)
/(pico) .+os([\w\.]+)/i, // Pico
// Other
/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, // Joli/Palm
@@ -1188,14 +1259,21 @@
headers = extensions; // case UAParser(ua, headers)
extensions = undefined;
}
// Convert Headers object into a plain object
if (headers && typeof headers.append === FUNC_TYPE) {
var kv = {};
headers.forEach(function (v, k) { kv[k] = v; });
headers = kv;
}
if (!(this instanceof UAParser)) {
return new UAParser(ua, extensions, headers).getResult();
}
var userAgent = typeof ua === STR_TYPE ? ua : // Passed user-agent string
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
(headers && headers[USER_AGENT] ? headers[USER_AGENT] : // User-Agent from passed headers
((NAVIGATOR && NAVIGATOR.userAgent) ? NAVIGATOR.userAgent : // navigator.userAgent
EMPTY)), // empty string
httpUACH = new UACHData(headers, true),