diff --git a/.jshintrc b/.jshintrc index c9de0d5..e2590c2 100644 --- a/.jshintrc +++ b/.jshintrc @@ -19,5 +19,8 @@ "smarttabs": true, "jquery": true, "white": true, - "multistr": true + "multistr": true, + "globals": { + "window": true + } } diff --git a/index.js b/index.js index 7962394..e56fdfe 100644 --- a/index.js +++ b/index.js @@ -11,40 +11,50 @@ * @link http://www.gordejev.lv * */ -var usrg = require('./lib/express-useragent'); -var UserAgent = usrg.UserAgent; -module.exports = new UserAgent(); +var UserAgent = require('./lib/express-useragent').UserAgent; + +var isBrowser = typeof window === 'object' && typeof window.navigator === 'object'; +var defaultUserAgent = isBrowser ? window.navigator.userAgent : ""; +/* Fallback of previous solution. */ +module.exports = new UserAgent(defaultUserAgent); + +/* Override of instance functions to static. */ +module.exports.parse = UserAgent.parse; +module.exports.testNginxGeoIP = UserAgent.testNginxGeoIP; module.exports.UserAgent = UserAgent; + +/** + * Middleware of express.js for parse user agent. + * + * @param {object} req - The request object of express.js. + * @param {object} res - The response object of express.js. + * @param {function} next - Callback of middleware with optional error for run follwing or error middleware. + */ +var middleware = function (req, res, next) { + /* The 'x-ucbrowser-ua' is special case of UC Browser, the 'user-agent' for other browsers. */ + var source = req.headers['x-ucbrowser-ua'] || req.headers['user-agent'] || ''; + req.useragent = UserAgent.parse(source); + + if (typeof res.locals === 'function') { + /* + * Support of express.js version 2.x. + * + * See more: http://expressjs.com/2x/guide.html#res.locals(). + */ + res.locals({ useragent: req.useragent }); + } else { + res.locals.useragent = req.useragent; + } + + next(); +}; +module.exports.middleware = middleware; + +/** + * Getter of express.js middleware. + * + * @returns {function} middleware of express.js for parse user agent. + */ module.exports.express = function () { - return function (req, res, next) { - var source = req.headers['user-agent'] || ''; - if (req.headers['x-ucbrowser-ua']) { //special case of UC Browser - source = req.headers['x-ucbrowser-ua']; - } - var ua = new UserAgent(); - if (typeof source === 'undefined') { - source = "unknown"; - } - ua.Agent.source = source.replace(/^\s*/, '').replace(/\s*$/, ''); - ua.Agent.os = ua.getOS(ua.Agent.source); - ua.Agent.platform = ua.getPlatform(ua.Agent.source); - ua.Agent.browser = ua.getBrowser(ua.Agent.source); - ua.Agent.version = ua.getBrowserVersion(ua.Agent.source); - ua.testNginxGeoIP(req.headers); - ua.testBot(); - ua.testMobile(); - ua.testAndroidTablet(); - ua.testTablet(); - ua.testCompatibilityMode(); - ua.testSilk(); - ua.testKindleFire(); - ua.testWechat(); - req.useragent = ua.Agent; - if ('function' === typeof res.locals) { - res.locals({useragent: ua.Agent}); - } else { - res.locals.useragent = ua.Agent; - } - next(); - }; + return middleware; }; diff --git a/lib/express-useragent.js b/lib/express-useragent.js index a40e393..cfd56b8 100644 --- a/lib/express-useragent.js +++ b/lib/express-useragent.js @@ -6,6 +6,27 @@ (function(exports) { 'use strict'; + /** + * Constructor of default value getter. + * + * @param {function} getter - Function which returns any value. + * + * @returns {DefaultValue} Instance of DefaultValue. + */ + function DefaultValue(getter) { + this.getter = getter; + } + + /** + * Returns the call result of `this.getter`. + * + * @returns {*} Any result of `this.getter`. + */ + DefaultValue.prototype.getValue = function() { + return this.getter(); + }; + + var isBrowser = typeof window === 'object' && typeof window.navigator === 'object'; var BOTS = [ '\\+https:\\/\\/developers.google.com\\/\\+\\/web\\/snippet\\/', 'ad\\smonitoring', @@ -97,779 +118,1023 @@ ]; var IS_BOT_REGEXP = new RegExp('^.*(' + BOTS.join('|') + ').*$'); - var UserAgent = function () { - this.version = '1.0.15'; - this._Versions = { - Edge: /(?:edge|edga|edgios|edg)\/([\d\w\.\-]+)/i, - Firefox: /(?:firefox|fxios)\/([\d\w\.\-]+)/i, - IE: /msie\s([\d\.]+[\d])|trident\/\d+\.\d+;.*[rv:]+(\d+\.\d)/i, - Chrome: /(?:chrome|crios)\/([\d\w\.\-]+)/i, - Chromium: /chromium\/([\d\w\.\-]+)/i, - Safari: /(version|safari)\/([\d\w\.\-]+)/i, - Opera: /version\/([\d\w\.\-]+)|OPR\/([\d\w\.\-]+)/i, - Ps3: /([\d\w\.\-]+)\)\s*$/i, - Psp: /([\d\w\.\-]+)\)?\s*$/i, - Amaya: /amaya\/([\d\w\.\-]+)/i, - SeaMonkey: /seamonkey\/([\d\w\.\-]+)/i, - OmniWeb: /omniweb\/v([\d\w\.\-]+)/i, - Flock: /flock\/([\d\w\.\-]+)/i, - Epiphany: /epiphany\/([\d\w\.\-]+)/i, - WinJs: /msapphost\/([\d\w\.\-]+)/i, - PhantomJS: /phantomjs\/([\d\w\.\-]+)/i, - AlamoFire: /alamofire\/([\d\w\.\-]+)/i, - UC: /ucbrowser\/([\d\w\.]+)/i, - Facebook: /FBAV\/([\d\w\.]+)/i, - WebKit: /applewebkit\/([\d\w\.]+)/i, - Wechat: /micromessenger\/([\d\w\.]+)/i, - Electron: /Electron\/([\d\w\.]+)/i - }; - this._Browsers = { - YaBrowser: /yabrowser/i, - Edge: /edge|edga|edgios|edg/i, - Amaya: /amaya/i, - Konqueror: /konqueror/i, - Epiphany: /epiphany/i, - SeaMonkey: /seamonkey/i, - Flock: /flock/i, - OmniWeb: /omniweb/i, - Chromium: /chromium/i, - Chrome: /chrome|crios/i, - Safari: /safari/i, - IE: /msie|trident/i, - Opera: /opera|OPR\//i, - PS3: /playstation 3/i, - PSP: /playstation portable/i, - Firefox: /firefox|fxios/i, - WinJs: /msapphost/i, - PhantomJS: /phantomjs/i, - AlamoFire: /alamofire/i, - UC: /UCBrowser/i, - Facebook: /FBA[NV]/ - }; - this._OS = { - Windows10: /windows nt 10\.0/i, - Windows81: /windows nt 6\.3/i, - Windows8: /windows nt 6\.2/i, - Windows7: /windows nt 6\.1/i, - UnknownWindows: /windows nt 6\.\d+/i, - WindowsVista: /windows nt 6\.0/i, - Windows2003: /windows nt 5\.2/i, - WindowsXP: /windows nt 5\.1/i, - Windows2000: /windows nt 5\.0/i, - WindowsPhone81: /windows phone 8\.1/i, - WindowsPhone80: /windows phone 8\.0/i, - OSXCheetah: /os x 10[._]0/i, - OSXPuma: /os x 10[._]1(\D|$)/i, - OSXJaguar: /os x 10[._]2/i, - OSXPanther: /os x 10[._]3/i, - OSXTiger: /os x 10[._]4/i, - OSXLeopard: /os x 10[._]5/i, - OSXSnowLeopard: /os x 10[._]6/i, - OSXLion: /os x 10[._]7/i, - OSXMountainLion: /os x 10[._]8/i, - OSXMavericks: /os x 10[._]9/i, - OSXYosemite: /os x 10[._]10/i, - OSXElCapitan: /os x 10[._]11/i, - MacOSSierra: /os x 10[._]12/i, - MacOSHighSierra: /os x 10[._]13/i, - MacOSMojave: /os x 10[._]14/i, - Mac: /os x/i, - Linux: /linux/i, - Linux64: /linux x86\_64/i, - ChromeOS: /cros/i, - Wii: /wii/i, - PS3: /playstation 3/i, - PSP: /playstation portable/i, - iPad: /\(iPad.*os (\d+)[._](\d+)/i, - iPhone: /\(iPhone.*os (\d+)[._](\d+)/i, - iOS: /ios/i, - Bada: /Bada\/(\d+)\.(\d+)/i, - Curl: /curl\/(\d+)\.(\d+)\.(\d+)/i, - Electron: /Electron\/(\d+)\.(\d+)\.(\d+)/i, - }; - this._Platform = { - Windows: /windows nt/i, - WindowsPhone: /windows phone/i, - Mac: /macintosh/i, - Linux: /linux/i, - Wii: /wii/i, - Playstation: /playstation/i, - iPad: /ipad/i, - iPod: /ipod/i, - iPhone: /iphone/i, - Android: /android/i, - Blackberry: /blackberry/i, - Samsung: /samsung/i, - Curl: /curl/i, - Electron: /Electron/i, - iOS: /^ios\-/i - }; - - this.DefaultAgent = { - isYaBrowser: false, - isAuthoritative: true, - isMobile: false, - isMobileNative: false, - isTablet: false, - isiPad: false, - isiPod: false, - isiPhone: false, - isiPhoneNative: false, - isAndroid: false, - isAndroidNative: false, - isBlackberry: false, - isOpera: false, - isIE: false, - isEdge: false, - isIECompatibilityMode: false, - isSafari: false, - isFirefox: false, - isWebkit: false, - isChrome: false, - isKonqueror: false, - isOmniWeb: false, - isSeaMonkey: false, - isFlock: false, - isAmaya: false, - isPhantomJS: false, - isEpiphany: false, - isDesktop: false, - isWindows: false, - isLinux: false, - isLinux64: false, - isMac: false, - isChromeOS: false, - isBada: false, - isSamsung: false, - isRaspberry: false, - isBot: false, - isCurl: false, - isAndroidTablet: false, - isWinJs: false, - isKindleFire: false, - isSilk: false, - isCaptive: false, - isSmartTV: false, - isUC : false, - isFacebook : false, - isAlamoFire: false, - isElectron: false, - silkAccelerated: false, - browser: 'unknown', - version: 'unknown', - os: 'unknown', - platform: 'unknown', - geoIp: {}, - source: '', - isWechat: false, - }; + var _Versions = { + Edge: /(?:edge|edga|edgios|edg)\/([\d\w\.\-]+)/i, + Firefox: /(?:firefox|fxios)\/([\d\w\.\-]+)/i, + IE: /msie\s([\d\.]+[\d])|trident\/\d+\.\d+;.*[rv:]+(\d+\.\d)/i, + Chrome: /(?:chrome|crios)\/([\d\w\.\-]+)/i, + Chromium: /chromium\/([\d\w\.\-]+)/i, + Safari: /(version|safari)\/([\d\w\.\-]+)/i, + Opera: /version\/([\d\w\.\-]+)|OPR\/([\d\w\.\-]+)/i, + Ps3: /([\d\w\.\-]+)\)\s*$/i, + Psp: /([\d\w\.\-]+)\)?\s*$/i, + Amaya: /amaya\/([\d\w\.\-]+)/i, + SeaMonkey: /seamonkey\/([\d\w\.\-]+)/i, + OmniWeb: /omniweb\/v([\d\w\.\-]+)/i, + Flock: /flock\/([\d\w\.\-]+)/i, + Epiphany: /epiphany\/([\d\w\.\-]+)/i, + WinJs: /msapphost\/([\d\w\.\-]+)/i, + PhantomJS: /phantomjs\/([\d\w\.\-]+)/i, + AlamoFire: /alamofire\/([\d\w\.\-]+)/i, + UC: /ucbrowser\/([\d\w\.]+)/i, + Facebook: /FBAV\/([\d\w\.]+)/i, + WebKit: /applewebkit\/([\d\w\.]+)/i, + Wechat: /micromessenger\/([\d\w\.]+)/i, + Electron: /Electron\/([\d\w\.]+)/i + }; + + var _Browsers = { + YaBrowser: /yabrowser/i, + Edge: /edge|edga|edgios|edg/i, + Amaya: /amaya/i, + Konqueror: /konqueror/i, + Epiphany: /epiphany/i, + SeaMonkey: /seamonkey/i, + Flock: /flock/i, + OmniWeb: /omniweb/i, + Chromium: /chromium/i, + Chrome: /chrome|crios/i, + Safari: /safari/i, + IE: /msie|trident/i, + Opera: /opera|OPR\//i, + PS3: /playstation 3/i, + PSP: /playstation portable/i, + Firefox: /firefox|fxios/i, + WinJs: /msapphost/i, + PhantomJS: /phantomjs/i, + AlamoFire: /alamofire/i, + UC: /UCBrowser/i, + Facebook: /FBA[NV]/ + }; + var _OS = { + Windows10: /windows nt 10\.0/i, + Windows81: /windows nt 6\.3/i, + Windows8: /windows nt 6\.2/i, + Windows7: /windows nt 6\.1/i, + UnknownWindows: /windows nt 6\.\d+/i, + WindowsVista: /windows nt 6\.0/i, + Windows2003: /windows nt 5\.2/i, + WindowsXP: /windows nt 5\.1/i, + Windows2000: /windows nt 5\.0/i, + WindowsPhone81: /windows phone 8\.1/i, + WindowsPhone80: /windows phone 8\.0/i, + OSXCheetah: /os x 10[._]0/i, + OSXPuma: /os x 10[._]1(\D|$)/i, + OSXJaguar: /os x 10[._]2/i, + OSXPanther: /os x 10[._]3/i, + OSXTiger: /os x 10[._]4/i, + OSXLeopard: /os x 10[._]5/i, + OSXSnowLeopard: /os x 10[._]6/i, + OSXLion: /os x 10[._]7/i, + OSXMountainLion: /os x 10[._]8/i, + OSXMavericks: /os x 10[._]9/i, + OSXYosemite: /os x 10[._]10/i, + OSXElCapitan: /os x 10[._]11/i, + MacOSSierra: /os x 10[._]12/i, + MacOSHighSierra: /os x 10[._]13/i, + MacOSMojave: /os x 10[._]14/i, + Mac: /os x/i, + Linux: /linux/i, + Linux64: /linux x86\_64/i, + ChromeOS: /cros/i, + Wii: /wii/i, + PS3: /playstation 3/i, + PSP: /playstation portable/i, + iPad: /\(iPad.*os (\d+)[._](\d+)/i, + iPhone: /\(iPhone.*os (\d+)[._](\d+)/i, + iOS: /ios/i, + Bada: /Bada\/(\d+)\.(\d+)/i, + Curl: /curl\/(\d+)\.(\d+)\.(\d+)/i, + Electron: /Electron\/(\d+)\.(\d+)\.(\d+)/i + }; + + var _Platform = { + Windows: /windows nt/i, + WindowsPhone: /windows phone/i, + Mac: /macintosh/i, + Linux: /linux/i, + Wii: /wii/i, + Playstation: /playstation/i, + iPad: /ipad/i, + iPod: /ipod/i, + iPhone: /iphone/i, + Android: /android/i, + Blackberry: /blackberry/i, + Samsung: /samsung/i, + Curl: /curl/i, + Electron: /Electron/i, + iOS: /^ios\-/i + }; + + var defaultAgent = { + isYaBrowser: false, + isAuthoritative: true, + isMobile: false, + isMobileNative: false, + isTablet: false, + isiPad: false, + isiPod: false, + isiPhone: false, + isiPhoneNative: false, + isiOSStandalone: false, + isiOSUiwebview: false, + isAndroid: false, + isAndroidNative: false, + isAndroidWebview: false, + isBlackberry: false, + isOpera: false, + isIE: false, + isEdge: false, + isIECompatibilityMode: false, + isSafari: false, + isFirefox: false, + isWebkit: false, + isChrome: false, + isKonqueror: false, + isOmniWeb: false, + isSeaMonkey: false, + isFlock: false, + isAmaya: false, + isPhantomJS: false, + isEpiphany: false, + isDesktop: false, + isWindows: false, + isLinux: false, + isLinux64: false, + isMac: false, + isChromeOS: false, + isBada: false, + isSamsung: false, + isRaspberry: false, + isBot: false, + isCurl: false, + isAndroidTablet: false, + isWinJs: false, + isKindleFire: false, + isSilk: false, + isCaptive: false, + isSmartTV: false, + isUC : false, + isFacebook : false, + isAlamoFire: false, + isElectron: false, + isWechat: false, + silkAccelerated: false, + browser: 'unknown', + version: 'unknown', + os: 'unknown', + platform: 'unknown', + /* + * The object and arrays will be set by reference, due to this all copies will be the same. + * To avoid this problem the getter should be called on set. Here the `DefaultValue` wrapper + * is used for detect if the value is getter and not just function value. + */ + geoIp: new DefaultValue(function() { return {}; }), + source: '' + }; + + /** + * Constructor of user agent details. + * + * @param {string} [source=''] - The user agent string. + * @param {object} [headers] - Request headers with GEO information. + * + * @returns {UserAgent} Instance of UserAgent. + */ + function UserAgent(source, headers) { + /* Fallback for call constructor without operator `new`. */ + if (!(this instanceof UserAgent)) { + return new UserAgent(source); + } + + if (typeof source !== 'string') { + source = ''; + } + + this.version = '1.0.16'; this.Agent = {}; + /* Fill the this.Agent with default values. */ + this.reset(); - this.getBrowser = function (string) { - switch (true) { - case this._Browsers.YaBrowser.test(string): - this.Agent.isYaBrowser = true; - return 'YaBrowser'; - case this._Browsers.AlamoFire.test(string): - this.Agent.isAlamoFire = true; - return 'AlamoFire'; - case this._Browsers.Edge.test(string): - this.Agent.isEdge = true; - return 'Edge'; - case this._Browsers.PhantomJS.test(string): - this.Agent.isPhantomJS = true; - return 'PhantomJS'; - case this._Browsers.Konqueror.test(string): - this.Agent.isKonqueror = true; - return 'Konqueror'; - case this._Browsers.Amaya.test(string): - this.Agent.isAmaya = true; - return 'Amaya'; - case this._Browsers.Epiphany.test(string): - this.Agent.isEpiphany = true; - return 'Epiphany'; - case this._Browsers.SeaMonkey.test(string): - this.Agent.isSeaMonkey = true; - return 'SeaMonkey'; - case this._Browsers.Flock.test(string): - this.Agent.isFlock = true; - return 'Flock'; - case this._Browsers.OmniWeb.test(string): - this.Agent.isOmniWeb = true; - return 'OmniWeb'; - case this._Browsers.Opera.test(string): - this.Agent.isOpera = true; - return 'Opera'; - case this._Browsers.Chromium.test(string): - this.Agent.isChrome = true; - return 'Chromium'; - case this._Browsers.Facebook.test(string): - this.Agent.isFacebook = true; - return 'Facebook'; - case this._Browsers.Chrome.test(string): - this.Agent.isChrome = true; - return 'Chrome'; - case this._Browsers.WinJs.test(string): - this.Agent.isWinJs = true; - return 'WinJs'; - case this._Browsers.IE.test(string): - this.Agent.isIE = true; - return 'IE'; - case this._Browsers.Firefox.test(string): - this.Agent.isFirefox = true; - return 'Firefox'; - case this._Browsers.Safari.test(string): - this.Agent.isSafari = true; - return 'Safari'; - case this._Browsers.PS3.test(string): - return 'ps3'; - case this._Browsers.PSP.test(string): - return 'psp'; - case this._Browsers.UC.test(string): - this.Agent.isUC = true; - return 'UCBrowser'; - default: - if (string.indexOf('Dalvik') !== -1) { - return 'unknown'; - } + this.Agent.source = source.replace(/^\s*/, '').replace(/\s*$/, ''); + if (this.Agent.source) { + this.Agent.os = this.getOS(); + this.Agent.platform = this.getPlatform(); + this.Agent.browser = this.getBrowser(); + this.Agent.version = this.getBrowserVersion(); + this.Agent.electronVersion = this.getElectronVersion(); - // If the UA does not start with Mozilla guess the user agent. - if (string.indexOf('Mozilla') !== 0 && /^([\d\w\-\.]+)\/[\d\w\.\-]+/i.test(string)) { - this.Agent.isAuthoritative = false; - return RegExp.$1; - } + this.testWebview(); + this.testBot(); + this.testSmartTV(); + this.testMobile(); + this.testAndroidTablet(); + this.testTablet(); + this.testCompatibilityMode(); + this.testSilk(); + this.testKindleFire(); + this.testCaptiveNetwork(); + this.testWebkit(); + this.testWechat(); + } + + if (headers && typeof headers === 'object') { + this.testNginxGeoIP(headers); + } + + /* The fallback for previous solution. */ + this.DefaultAgent = {}; + /* Fill the this.DefaultAgent with default values. */ + this.reset('DefaultAgent'); + } + + /** + * Gets the browser name by user agent. Be careful that function has the side effects related to `this.Agent` state. + * + * @param {string} [string=this.Agent.source] - The user agent. + * + * @returns {string} Name of the browser (the boolean flag like `is${BrowserName}` will be set as side effect). + */ + UserAgent.prototype.getBrowser = function (string) { + string = string || this.Agent.source; + + switch (true) { + case _Browsers.YaBrowser.test(string): + this.Agent.isYaBrowser = true; + return 'YaBrowser'; + case _Browsers.AlamoFire.test(string): + this.Agent.isAlamoFire = true; + return 'AlamoFire'; + case _Browsers.Edge.test(string): + this.Agent.isEdge = true; + return 'Edge'; + case _Browsers.PhantomJS.test(string): + this.Agent.isPhantomJS = true; + return 'PhantomJS'; + case _Browsers.Konqueror.test(string): + this.Agent.isKonqueror = true; + return 'Konqueror'; + case _Browsers.Amaya.test(string): + this.Agent.isAmaya = true; + return 'Amaya'; + case _Browsers.Epiphany.test(string): + this.Agent.isEpiphany = true; + return 'Epiphany'; + case _Browsers.SeaMonkey.test(string): + this.Agent.isSeaMonkey = true; + return 'SeaMonkey'; + case _Browsers.Flock.test(string): + this.Agent.isFlock = true; + return 'Flock'; + case _Browsers.OmniWeb.test(string): + this.Agent.isOmniWeb = true; + return 'OmniWeb'; + case _Browsers.Opera.test(string): + this.Agent.isOpera = true; + return 'Opera'; + case _Browsers.Chromium.test(string): + this.Agent.isChrome = true; + return 'Chromium'; + case _Browsers.Facebook.test(string): + this.Agent.isFacebook = true; + return 'Facebook'; + case _Browsers.Chrome.test(string): + this.Agent.isChrome = true; + return 'Chrome'; + case _Browsers.WinJs.test(string): + this.Agent.isWinJs = true; + return 'WinJs'; + case _Browsers.IE.test(string): + this.Agent.isIE = true; + return 'IE'; + case _Browsers.Firefox.test(string): + this.Agent.isFirefox = true; + return 'Firefox'; + case _Browsers.Safari.test(string): + this.Agent.isSafari = true; + return 'Safari'; + case _Browsers.PS3.test(string): + return 'ps3'; + case _Browsers.PSP.test(string): + return 'psp'; + case _Browsers.UC.test(string): + this.Agent.isUC = true; + return 'UCBrowser'; + default: + if (string.indexOf('Dalvik') !== -1) { return 'unknown'; - } - }; + } - this.getBrowserVersion = function (string) { - var regex; - switch (this.Agent.browser) { - case 'Edge': - if (this._Versions.Edge.test(string)) { - return RegExp.$1; - } - break; - case 'PhantomJS': - if (this._Versions.PhantomJS.test(string)) { - return RegExp.$1; - } - break; - case 'Chrome': - if (this._Versions.Chrome.test(string)) { - return RegExp.$1; - } - break; - case 'Chromium': - if (this._Versions.Chromium.test(string)) { - return RegExp.$1; - } - break; - case 'Safari': - if (this._Versions.Safari.test(string)) { - return RegExp.$2; - } - break; - case 'Opera': - if (this._Versions.Opera.test(string)) { - return RegExp.$1 ? RegExp.$1: RegExp.$2; - } - break; - case 'Firefox': - if (this._Versions.Firefox.test(string)) { - return RegExp.$1; - } - break; - case 'WinJs': - if (this._Versions.WinJs.test(string)) { - return RegExp.$1; - } - break; - case 'IE': - if (this._Versions.IE.test(string)) { - return RegExp.$2 ? RegExp.$2 : RegExp.$1; - } - break; - case 'ps3': - if (this._Versions.Ps3.test(string)) { - return RegExp.$1; - } - break; - case 'psp': - if (this._Versions.Psp.test(string)) { - return RegExp.$1; - } - break; - case 'Amaya': - if (this._Versions.Amaya.test(string)) { - return RegExp.$1; - } - break; - case 'Epiphany': - if (this._Versions.Epiphany.test(string)) { - return RegExp.$1; - } - break; - case 'SeaMonkey': - if (this._Versions.SeaMonkey.test(string)) { - return RegExp.$1; - } - break; - case 'Flock': - if (this._Versions.Flock.test(string)) { - return RegExp.$1; - } - break; - case 'OmniWeb': - if (this._Versions.OmniWeb.test(string)) { - return RegExp.$1; - } - break; - case 'UCBrowser': - if (this._Versions.UC.test(string)) { + // If the UA does not start with Mozilla guess the user agent. + if (string.indexOf('Mozilla') !== 0 && /^([\d\w\-\.]+)\/[\d\w\.\-]+/i.test(string)) { + this.Agent.isAuthoritative = false; + return RegExp.$1; + } + return 'unknown'; + } + }; + + /** + * Gets the browser version by user agent. + * + * @param {string} [string=this.Agent.source] - The user agent. + * + * @returns {string} Version of the browser or 'unknown'. + */ + UserAgent.prototype.getBrowserVersion = function (string) { + string = string || this.Agent.source; + + var regex; + switch (this.Agent.browser) { + case 'Edge': + if (_Versions.Edge.test(string)) { + return RegExp.$1; + } + break; + case 'PhantomJS': + if (_Versions.PhantomJS.test(string)) { + return RegExp.$1; + } + break; + case 'Chrome': + if (_Versions.Chrome.test(string)) { + return RegExp.$1; + } + break; + case 'Chromium': + if (_Versions.Chromium.test(string)) { + return RegExp.$1; + } + break; + case 'Safari': + if (_Versions.Safari.test(string)) { + return RegExp.$2; + } + break; + case 'Opera': + if (_Versions.Opera.test(string)) { + return RegExp.$1 ? RegExp.$1 : RegExp.$2; + } + break; + case 'Firefox': + if (_Versions.Firefox.test(string)) { + return RegExp.$1; + } + break; + case 'WinJs': + if (_Versions.WinJs.test(string)) { + return RegExp.$1; + } + break; + case 'IE': + if (_Versions.IE.test(string)) { + return RegExp.$2 ? RegExp.$2 : RegExp.$1; + } + break; + case 'ps3': + if (_Versions.Ps3.test(string)) { + return RegExp.$1; + } + break; + case 'psp': + if (_Versions.Psp.test(string)) { + return RegExp.$1; + } + break; + case 'Amaya': + if (_Versions.Amaya.test(string)) { + return RegExp.$1; + } + break; + case 'Epiphany': + if (_Versions.Epiphany.test(string)) { + return RegExp.$1; + } + break; + case 'SeaMonkey': + if (_Versions.SeaMonkey.test(string)) { + return RegExp.$1; + } + break; + case 'Flock': + if (_Versions.Flock.test(string)) { + return RegExp.$1; + } + break; + case 'OmniWeb': + if (_Versions.OmniWeb.test(string)) { + return RegExp.$1; + } + break; + case 'UCBrowser': + if (_Versions.UC.test(string)) { + return RegExp.$1; + } + break; + case 'Facebook': + if (_Versions.Facebook.test(string)) { + return RegExp.$1; + } + break; + default: + if (this.Agent.browser !== 'unknown') { + regex = new RegExp(this.Agent.browser + '[\\/ ]([\\d\\w\\.\\-]+)', 'i'); + if (regex.test(string)) { return RegExp.$1; } - break; - case 'Facebook': - if (this._Versions.Facebook.test(string)) { + } else { + this.testWebkit(); + if (this.Agent.isWebkit && _Versions.WebKit.test(string)) { return RegExp.$1; } - break; - default: - if (this.Agent.browser !== 'unknown') { - regex = new RegExp(this.Agent.browser + '[\\/ ]([\\d\\w\\.\\-]+)', 'i'); - if (regex.test(string)) { - return RegExp.$1; - } - } else { - this.testWebkit(); - if (this.Agent.isWebkit && this._Versions.WebKit.test(string)) { - return RegExp.$1; - } - return 'unknown'; - } - } - }; + return 'unknown'; + } + } + }; - this.getWechatVersion = function (string) { - if (this._Versions.Wechat.test(string)) { - return RegExp.$1; - } + /** + * Gets the wechat version by user agent. + * + * @param {string} [string=this.Agent.source] - The user agent. + * + * @returns {string} Version of the wechar or 'unknown'. + */ + UserAgent.prototype.getWechatVersion = function (string) { + string = string || this.Agent.source; - return 'unknown'; - }; + if (_Versions.Wechat.test(string)) { + return RegExp.$1; + } - this.getElectronVersion = function (string) { - if (this._Versions.Electron.test(string)) { - this.Agent.isElectron = true; - return RegExp.$1; - } + return 'unknown'; + }; + + /** + * Gets the electron version by user agent. + * + * @param {string} [string=this.Agent.source] - The user agent. + * + * @returns {string} Version of the electron or 'unknown'. + */ + UserAgent.prototype.getElectronVersion = function (string) { + string = string || this.Agent.source; + + if (_Versions.Electron.test(string)) { + this.Agent.isElectron = true; + return RegExp.$1; + } + + return ''; + }; + + /** + * Gets the OS name by user agent. Be careful that function has the side effects related to `this.Agent` state. + * + * @param {string} [string=this.Agent.source] - The user agent. + * + * @returns {string} Name of the OS (the boolean flag like `is${OS}` will be set as side effect). + */ + UserAgent.prototype.getOS = function (string) { + string = string || this.Agent.source; - return ''; - }; - - this.getOS = function (string) { - switch (true) { - case this._OS.WindowsVista.test(string): - this.Agent.isWindows = true; - return 'Windows Vista'; - case this._OS.Windows7.test(string): - this.Agent.isWindows = true; - return 'Windows 7'; - case this._OS.Windows8.test(string): - this.Agent.isWindows = true; - return 'Windows 8'; - case this._OS.Windows81.test(string): - this.Agent.isWindows = true; - return 'Windows 8.1'; - case this._OS.Windows10.test(string): - this.Agent.isWindows = true; - return 'Windows 10.0'; - case this._OS.Windows2003.test(string): - this.Agent.isWindows = true; - return 'Windows 2003'; - case this._OS.WindowsXP.test(string): - this.Agent.isWindows = true; - return 'Windows XP'; - case this._OS.Windows2000.test(string): - this.Agent.isWindows = true; - return 'Windows 2000'; - case this._OS.WindowsPhone81.test(string): - this.Agent.isWindowsPhone = true; - return 'Windows Phone 8.1'; - case this._OS.WindowsPhone80.test(string): - this.Agent.isWindowsPhone = true; - return 'Windows Phone 8.0'; - case this._OS.Linux64.test(string): - this.Agent.isLinux = true; - this.Agent.isLinux64 = true; - return 'Linux 64'; - case this._OS.Linux.test(string): - this.Agent.isLinux = true; - return 'Linux'; - case this._OS.ChromeOS.test(string): - this.Agent.isChromeOS = true; - return 'Chrome OS'; - case this._OS.Wii.test(string): - return 'Wii'; - case this._OS.PS3.test(string): - return 'Playstation'; - case this._OS.PSP.test(string): - return 'Playstation'; - case this._OS.OSXCheetah.test(string): - this.Agent.isMac = true; - return 'OS X Cheetah'; - case this._OS.OSXPuma.test(string): - this.Agent.isMac = true; - return 'OS X Puma'; - case this._OS.OSXJaguar.test(string): - this.Agent.isMac = true; - return 'OS X Jaguar'; - case this._OS.OSXPanther.test(string): - this.Agent.isMac = true; - return 'OS X Panther'; - case this._OS.OSXTiger.test(string): - this.Agent.isMac = true; - return 'OS X Tiger'; - case this._OS.OSXLeopard.test(string): - this.Agent.isMac = true; - return 'OS X Leopard'; - case this._OS.OSXSnowLeopard.test(string): - this.Agent.isMac = true; - return 'OS X Snow Leopard'; - case this._OS.OSXLion.test(string): - this.Agent.isMac = true; - return 'OS X Lion'; - case this._OS.OSXMountainLion.test(string): - this.Agent.isMac = true; - return 'OS X Mountain Lion'; - case this._OS.OSXMavericks.test(string): - this.Agent.isMac = true; - return 'OS X Mavericks'; - case this._OS.OSXYosemite.test(string): - this.Agent.isMac = true; - return 'OS X Yosemite'; - case this._OS.OSXElCapitan.test(string): - this.Agent.isMac = true; - return 'OS X El Capitan'; - case this._OS.MacOSSierra.test(string): - this.Agent.isMac = true; - return 'macOS Sierra'; - case this._OS.MacOSHighSierra.test(string): - this.Agent.isMac = true; - return 'macOS High Sierra'; - case this._OS.MacOSMojave.test(string): - this.Agent.isMac = true; - return 'macOS Mojave'; - case this._OS.Mac.test(string): - // !('ontouchend' in document); - // navigator.maxTouchPoints > 1 - this.Agent.isMac = true; - return 'OS X'; - case this._OS.iPad.test(string): - // 'ontouchend' in document; + switch (true) { + case _OS.WindowsVista.test(string): + this.Agent.isWindows = true; + return 'Windows Vista'; + case _OS.Windows7.test(string): + this.Agent.isWindows = true; + return 'Windows 7'; + case _OS.Windows8.test(string): + this.Agent.isWindows = true; + return 'Windows 8'; + case _OS.Windows81.test(string): + this.Agent.isWindows = true; + return 'Windows 8.1'; + case _OS.Windows10.test(string): + this.Agent.isWindows = true; + return 'Windows 10.0'; + case _OS.Windows2003.test(string): + this.Agent.isWindows = true; + return 'Windows 2003'; + case _OS.WindowsXP.test(string): + this.Agent.isWindows = true; + return 'Windows XP'; + case _OS.Windows2000.test(string): + this.Agent.isWindows = true; + return 'Windows 2000'; + case _OS.WindowsPhone81.test(string): + this.Agent.isWindowsPhone = true; + return 'Windows Phone 8.1'; + case _OS.WindowsPhone80.test(string): + this.Agent.isWindowsPhone = true; + return 'Windows Phone 8.0'; + case _OS.Linux64.test(string): + this.Agent.isLinux = true; + this.Agent.isLinux64 = true; + return 'Linux 64'; + case _OS.Linux.test(string): + this.Agent.isLinux = true; + return 'Linux'; + case _OS.ChromeOS.test(string): + this.Agent.isChromeOS = true; + return 'Chrome OS'; + case _OS.Wii.test(string): + return 'Wii'; + case _OS.PS3.test(string): + return 'Playstation'; + case _OS.PSP.test(string): + return 'Playstation'; + case _OS.OSXCheetah.test(string): + this.Agent.isMac = true; + return 'OS X Cheetah'; + case _OS.OSXPuma.test(string): + this.Agent.isMac = true; + return 'OS X Puma'; + case _OS.OSXJaguar.test(string): + this.Agent.isMac = true; + return 'OS X Jaguar'; + case _OS.OSXPanther.test(string): + this.Agent.isMac = true; + return 'OS X Panther'; + case _OS.OSXTiger.test(string): + this.Agent.isMac = true; + return 'OS X Tiger'; + case _OS.OSXLeopard.test(string): + this.Agent.isMac = true; + return 'OS X Leopard'; + case _OS.OSXSnowLeopard.test(string): + this.Agent.isMac = true; + return 'OS X Snow Leopard'; + case _OS.OSXLion.test(string): + this.Agent.isMac = true; + return 'OS X Lion'; + case _OS.OSXMountainLion.test(string): + this.Agent.isMac = true; + return 'OS X Mountain Lion'; + case _OS.OSXMavericks.test(string): + this.Agent.isMac = true; + return 'OS X Mavericks'; + case _OS.OSXYosemite.test(string): + this.Agent.isMac = true; + return 'OS X Yosemite'; + case _OS.OSXElCapitan.test(string): + this.Agent.isMac = true; + return 'OS X El Capitan'; + case _OS.MacOSSierra.test(string): + this.Agent.isMac = true; + return 'macOS Sierra'; + case _OS.MacOSHighSierra.test(string): + this.Agent.isMac = true; + return 'macOS High Sierra'; + case _OS.MacOSMojave.test(string): + this.Agent.isMac = true; + return 'macOS Mojave'; + case _OS.Mac.test(string): + if (isBrowser && window.navigator.platform === 'MacIntel' && window.navigator.maxTouchPoints > 1) { this.Agent.isiPad = true; - return string.match(this._OS.iPad)[0].replace('_', '.'); - case this._OS.iPhone.test(string): - // 'ontouchend' in document; - this.Agent.isiPhone = true; - return string.match(this._OS.iPhone)[0].replace('_', '.'); - case this._OS.Bada.test(string): - this.Agent.isBada = true; - return 'Bada'; - case this._OS.Curl.test(string): - this.Agent.isCurl = true; - return 'Curl'; - case this._OS.iOS.test(string): - this.Agent.isiPhone = true; - return 'iOS'; - case this._OS.Electron.test(string): - this.Agent.isElectron = true; - return 'Electron'; - default: - return 'unknown'; - } - }; - - this.getPlatform = function (string) { - switch (true) { - case this._Platform.Windows.test(string): - return 'Microsoft Windows'; - case this._Platform.WindowsPhone.test(string): - this.Agent.isWindowsPhone = true; - return 'Microsoft Windows Phone'; - case this._Platform.Mac.test(string): - return 'Apple Mac'; - case this._Platform.Curl.test(string): - return 'Curl'; - case this._Platform.Electron.test(string): - this.Agent.isElectron = true; - return 'Electron'; - case this._Platform.Android.test(string): - this.Agent.isAndroid = true; - return 'Android'; - case this._Platform.Blackberry.test(string): - this.Agent.isBlackberry = true; - return 'Blackberry'; - case this._Platform.Linux.test(string): - return 'Linux'; - case this._Platform.Wii.test(string): - return 'Wii'; - case this._Platform.Playstation.test(string): - return 'Playstation'; - case this._Platform.iPad.test(string): + return 'iOS 13+'; + } + + this.Agent.isMac = true; + return 'OS X'; + case _OS.iPad.test(string): + this.Agent.isiPad = true; + return string.match(_OS.iPad)[0].replace('_', '.'); + case _OS.iPhone.test(string): + this.Agent.isiPhone = true; + return string.match(_OS.iPhone)[0].replace('_', '.'); + case _OS.Bada.test(string): + this.Agent.isBada = true; + return 'Bada'; + case _OS.Curl.test(string): + this.Agent.isCurl = true; + return 'Curl'; + case _OS.iOS.test(string): + this.Agent.isiPhone = true; + return 'iOS'; + case _OS.Electron.test(string): + this.Agent.isElectron = true; + return 'Electron'; + default: + return 'unknown'; + } + }; + + /** + * Gets the platform name by user agent. Be careful that function has the side effects related to `this.Agent` state. + * + * @param {string} [string=this.Agent.source] - The user agent. + * + * @returns {string} Name of the platform (the boolean flag like `is${Platform}` will be set as side effect). + */ + UserAgent.prototype.getPlatform = function (string) { + string = string || this.Agent.source; + + switch (true) { + case _Platform.Windows.test(string): + return 'Microsoft Windows'; + case _Platform.WindowsPhone.test(string): + this.Agent.isWindowsPhone = true; + return 'Microsoft Windows Phone'; + case _Platform.Mac.test(string): + if (isBrowser && window.navigator.platform === 'MacIntel' && window.navigator.maxTouchPoints > 1) { this.Agent.isiPad = true; return 'iPad'; - case this._Platform.iPod.test(string): - this.Agent.isiPod = true; - return 'iPod'; - case this._Platform.iPhone.test(string): - this.Agent.isiPhone = true; - return 'iPhone'; - case this._Platform.Samsung.test(string): - this.Agent.isSamsung = true; - return 'Samsung'; - case this._Platform.iOS.test(string): - return 'Apple iOS'; - default: - return 'unknown'; - } - }; - - this.testCompatibilityMode = function () { - var ua = this; - if (this.Agent.isIE) { - if (/Trident\/(\d)\.0/i.test(ua.Agent.source)) { - var tridentVersion = parseInt(RegExp.$1, 10); - var version = parseInt(ua.Agent.version, 10); - if (version === 7 && tridentVersion === 7) { - ua.Agent.isIECompatibilityMode = true; - ua.Agent.version = 11.0; - } + } - if (version === 7 && tridentVersion === 6) { - ua.Agent.isIECompatibilityMode = true; - ua.Agent.version = 10.0; - } + return 'Apple Mac'; + case _Platform.Curl.test(string): + return 'Curl'; + case _Platform.Electron.test(string): + this.Agent.isElectron = true; + return 'Electron'; + case _Platform.Android.test(string): + this.Agent.isAndroid = true; + return 'Android'; + case _Platform.Blackberry.test(string): + this.Agent.isBlackberry = true; + return 'Blackberry'; + case _Platform.Linux.test(string): + return 'Linux'; + case _Platform.Wii.test(string): + return 'Wii'; + case _Platform.Playstation.test(string): + return 'Playstation'; + case _Platform.iPad.test(string): + this.Agent.isiPad = true; + return 'iPad'; + case _Platform.iPod.test(string): + this.Agent.isiPod = true; + return 'iPod'; + case _Platform.iPhone.test(string): + this.Agent.isiPhone = true; + return 'iPhone'; + case _Platform.Samsung.test(string): + this.Agent.isSamsung = true; + return 'Samsung'; + case _Platform.iOS.test(string): + return 'Apple iOS'; + default: + return 'unknown'; + } + }; - if (version === 7 && tridentVersion === 5) { - ua.Agent.isIECompatibilityMode = true; - ua.Agent.version = 9.0; - } + /** + * Checks if the compatibility mode is enabled for Internet Explorer. + * Be careful that function has the side effects related to `this.Agent` state of the + * boolean flag `isIECompatibilityMode` and `version` will be set as side effect. + */ + UserAgent.prototype.testCompatibilityMode = function () { + var ua = this; + if (this.Agent.isIE) { + if (/Trident\/(\d)\.0/i.test(ua.Agent.source)) { + var tridentVersion = parseInt(RegExp.$1, 10); + var version = parseInt(ua.Agent.version, 10); + if (version === 7 && tridentVersion === 7) { + ua.Agent.isIECompatibilityMode = true; + ua.Agent.version = 11.0; + } - if (version === 7 && tridentVersion === 4) { - ua.Agent.isIECompatibilityMode = true; - ua.Agent.version = 8.0; - } + if (version === 7 && tridentVersion === 6) { + ua.Agent.isIECompatibilityMode = true; + ua.Agent.version = 10.0; + } + + if (version === 7 && tridentVersion === 5) { + ua.Agent.isIECompatibilityMode = true; + ua.Agent.version = 9.0; + } + + if (version === 7 && tridentVersion === 4) { + ua.Agent.isIECompatibilityMode = true; + ua.Agent.version = 8.0; } } - }; - - this.testSilk = function () { - var ua = this; - switch (true) { - case new RegExp('silk', 'gi').test(ua.Agent.source): - this.Agent.isSilk = true; - break; - default: - } + } + }; + + /** + * Checks if user agent is Silk. + * Be careful that function has the side effects related to `this.Agent` state of the + * boolean flag `isSilk` and `SilkAccelerated` will be set as side effect. + */ + UserAgent.prototype.testSilk = function () { + var ua = this; + switch (true) { + case new RegExp('silk', 'gi').test(ua.Agent.source): + this.Agent.isSilk = true; + break; + default: + } - if (/Silk-Accelerated=true/gi.test(ua.Agent.source)) { + if (/Silk-Accelerated=true/gi.test(ua.Agent.source)) { this.Agent.SilkAccelerated = true; - } - return this.Agent.isSilk ? 'Silk' : false; - }; - - this.testKindleFire = function () { - var ua = this; - switch (true) { - case /KFOT/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire'; - case /KFTT/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HD'; - case /KFJWI/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HD 8.9'; - case /KFJWA/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HD 8.9 4G'; - case /KFSOWI/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HD 7'; - case /KFTHWI/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HDX 7'; - case /KFTHWA/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HDX 7 4G'; - case /KFAPWI/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HDX 8.9'; - case /KFAPWA/gi.test(ua.Agent.source): - this.Agent.isKindleFire = true; - return 'Kindle Fire HDX 8.9 4G'; - default: - return false; - } - }; - - this.testCaptiveNetwork = function () { - var ua = this; - switch (true) { - case /CaptiveNetwork/gi.test(ua.Agent.source): - ua.Agent.isCaptive = true; - ua.Agent.isMac = true; - ua.Agent.platform = 'Apple Mac'; - return 'CaptiveNetwork'; - default: - return false; - } - }; + } + return this.Agent.isSilk ? 'Silk' : false; + }; - this.reset = function reset() { - var ua = this; - for (var key in ua.DefaultAgent) { - ua.Agent[key] = ua.DefaultAgent[key]; - } - return ua; - }; - - this.testMobile = function testMobile() { - var ua = this; - switch (true) { - case ua.Agent.isWindows: - case ua.Agent.isLinux: - case ua.Agent.isMac: - case ua.Agent.isChromeOS: - ua.Agent.isDesktop = true; - break; - case ua.Agent.isAndroid: - case ua.Agent.isSamsung: - ua.Agent.isMobile = true; - break; - default: - } - switch (true) { - case ua.Agent.isiPad: - case ua.Agent.isiPod: - case ua.Agent.isiPhone: - case ua.Agent.isBada: - case ua.Agent.isBlackberry: - case ua.Agent.isAndroid: - case ua.Agent.isWindowsPhone: - ua.Agent.isMobile = true; - ua.Agent.isDesktop = false; - break; - default: + /** + * Checks if user agent is Kindle Fire. + * Be careful that function has the side effects related to `this.Agent`. + * + * @returns {string} Name of Kindle Fire, the boolean flag `isKindleFire` will be set as side effect. + */ + UserAgent.prototype.testKindleFire = function () { + var ua = this; + switch (true) { + case /KFOT/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire'; + case /KFTT/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HD'; + case /KFJWI/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HD 8.9'; + case /KFJWA/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HD 8.9 4G'; + case /KFSOWI/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HD 7'; + case /KFTHWI/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HDX 7'; + case /KFTHWA/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HDX 7 4G'; + case /KFAPWI/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HDX 8.9'; + case /KFAPWA/gi.test(ua.Agent.source): + this.Agent.isKindleFire = true; + return 'Kindle Fire HDX 8.9 4G'; + default: + return false; + } + }; + + /** + * Checks if user agent is Captive Network. + * Be careful that function has the side effects related to `this.Agent`. + * + * @returns {string} Name of Captive Network, the boolean flag `isCaptive` and `isMac` and `platform='Apple Mac'` string will be set as side effect. + */ + UserAgent.prototype.testCaptiveNetwork = function () { + var ua = this; + switch (true) { + case /CaptiveNetwork/gi.test(ua.Agent.source): + ua.Agent.isCaptive = true; + ua.Agent.isMac = true; + ua.Agent.platform = 'Apple Mac'; + return 'CaptiveNetwork'; + default: + return false; + } + }; + + /** + * Set the default values to agent `field`. + * + * @param {string} [field=Agent] - Name of the field which should be reseted. + */ + UserAgent.prototype.reset = function (field) { + field = field || 'Agent'; + + this[field] = {}; + for (var key in defaultAgent) { + var value = defaultAgent[key]; + if (value instanceof DefaultValue) { + value = value.getValue(); } - if (/mobile|^ios\-/i.test(ua.Agent.source)) { + + this[field][key] = value; + } + + return this; + }; + + /** + * Checks if the parsed agent uses the mobile browsers\os. + * Be careful that function has the side effects related to `this.Agent` state of the boolean + * flag `isDesktop`, `isMobile`, `isAndroidNative`, `isMobileNative` and `isiPhoneNative` will + * be set as side effect. + */ + UserAgent.prototype.testMobile = function () { + var ua = this; + switch (true) { + case ua.Agent.isWindows: + case ua.Agent.isLinux: + case ua.Agent.isMac: + case ua.Agent.isChromeOS: + ua.Agent.isDesktop = true; + break; + case ua.Agent.isAndroid: + case ua.Agent.isSamsung: + ua.Agent.isMobile = true; + break; + default: + } + switch (true) { + case ua.Agent.isiPad: + case ua.Agent.isiPod: + case ua.Agent.isiPhone: + case ua.Agent.isBada: + case ua.Agent.isBlackberry: + case ua.Agent.isAndroid: + case ua.Agent.isWindowsPhone: ua.Agent.isMobile = true; ua.Agent.isDesktop = false; - } - if (/dalvik/i.test(ua.Agent.source)) { - ua.Agent.isAndroidNative = true; - ua.Agent.isMobileNative = true; - } - if (/scale/i.test(ua.Agent.source)) { - ua.Agent.isiPhoneNative = true; - ua.Agent.isMobileNative = true; - } - }; - - this.testTablet = function testTablet() { - var ua = this; - switch (true) { - case ua.Agent.isiPad: - case ua.Agent.isAndroidTablet: - case ua.Agent.isKindleFire: - ua.Agent.isTablet = true; - break; - } - if (/tablet/i.test(ua.Agent.source)) { + break; + default: + } + if (/mobile|^ios\-/i.test(ua.Agent.source)) { + ua.Agent.isMobile = true; + ua.Agent.isDesktop = false; + } + if (/dalvik/i.test(ua.Agent.source)) { + ua.Agent.isAndroidNative = true; + ua.Agent.isMobileNative = true; + } + if (/scale/i.test(ua.Agent.source)) { + ua.Agent.isiPhoneNative = true; + ua.Agent.isMobileNative = true; + } + }; + + /** + * Checks if the parsed agent is table. + * Be careful that function has the side effects related to `this.Agent` state of the boolean + * flag `isTablet` will be set as side effect. + */ + UserAgent.prototype.testTablet = function () { + var ua = this; + switch (true) { + case ua.Agent.isiPad: + case ua.Agent.isAndroidTablet: + case ua.Agent.isKindleFire: ua.Agent.isTablet = true; - } - }; + break; + } + if (/tablet/i.test(ua.Agent.source)) { + ua.Agent.isTablet = true; + } + }; - this.testNginxGeoIP = function testNginxGeoIP(headers) { - var ua = this; - Object.keys(headers).forEach(function (key) { - if (/^GEOIP/i.test(key)) { - ua.Agent.geoIp[key] = headers[key]; - } - }); - return ua; - }; - - this.testBot = function testBot() { - var ua = this; - var isBot = IS_BOT_REGEXP.exec(ua.Agent.source.toLowerCase()); - if (isBot) { - ua.Agent.isBot = isBot[1]; - } else if (!ua.Agent.isAuthoritative) { - // Test unauthoritative parse for `bot` in UA to flag for bot - ua.Agent.isBot = /bot/i.test(ua.Agent.source); + /** + * Copies the GEOIP headers to `Agent.geoIp`. + * Be careful that function has the side effects related to `this.Agent`. + * + * @param {object} headers - Request headers. + * + * @returns {UserAgent} Current instanse of UserAgent. + */ + UserAgent.prototype.testNginxGeoIP = function (headers) { + var ua = this; + Object.keys(headers).forEach(function (key) { + if (/^GEOIP/i.test(key)) { + ua.Agent.geoIp[key] = headers[key]; } - }; + }); - this.testSmartTV = function testBot() { - var ua = this; - ua.Agent.isSmartTV = new RegExp('smart-tv|smarttv|googletv|appletv|hbbtv|pov_tv|netcast.tv','gi').test(ua.Agent.source.toLowerCase()); - }; + return ua; + }; - this.testAndroidTablet = function testAndroidTablet() { - var ua = this; - if (ua.Agent.isAndroid && !/mobile/i.test(ua.Agent.source)) { - ua.Agent.isAndroidTablet = true; - } - }; + /** + * Checks if the user agent is bot. + * Be careful that function has the side effects related to `this.Agent` state of the + * string\boolean flag `isBot` will be set as side effect. + */ + UserAgent.prototype.testBot = function () { + var ua = this; + var isBot = IS_BOT_REGEXP.exec(ua.Agent.source.toLowerCase()); + if (isBot) { + ua.Agent.isBot = isBot[1]; + } else if (!ua.Agent.isAuthoritative) { + // Test unauthoritative parse for `bot` in UA to flag for bot + ua.Agent.isBot = /bot/i.test(ua.Agent.source); + } + }; - this.testWebkit = function testWebkit() { - var ua = this; - if (ua.Agent.browser === 'unknown' && /applewebkit/i.test(ua.Agent.source)) { - ua.Agent.browser = 'Apple WebKit'; - ua.Agent.isWebkit = true; - } - }; + /** + * Checks if the user agent is smart tv. + * Be careful that function has the side effects related to `this.Agent` state of the + * boolean flag `isSmartTV` will be set as side effect. + */ + UserAgent.prototype.testSmartTV = function () { + var ua = this; + ua.Agent.isSmartTV = new RegExp('smart-tv|smarttv|googletv|appletv|hbbtv|pov_tv|netcast.tv','gi').test(ua.Agent.source.toLowerCase()); + }; + + /** + * Checks if the user agent is android tablet. + * Be careful that function has the side effects related to `this.Agent` state of the + * boolean flag `isAndroidTablet` will be set as side effect. + */ + UserAgent.prototype.testAndroidTablet = function () { + var ua = this; + if (ua.Agent.isAndroid && !/mobile/i.test(ua.Agent.source)) { + ua.Agent.isAndroidTablet = true; + } + }; + + /** + * Checks if the user agent is a apple webkit browser. + * Be careful that function has the side effects related to `this.Agent` state of the + * boolean flag `isWebkit` and string `browser='Apple WebKit'` will be set as side effect. + */ + UserAgent.prototype.testWebkit = function () { + var ua = this; + if (ua.Agent.browser === 'unknown' && /applewebkit/i.test(ua.Agent.source)) { + ua.Agent.browser = 'Apple WebKit'; + ua.Agent.isWebkit = true; + } + }; + + /** + * Checks if the user agent is a wechat. + * Be careful that function has the side effects related to `this.Agent` state of the + * boolean flag `isWechat` and string `version` will be set as side effect. + */ + UserAgent.prototype.testWechat = function () { + var ua = this; + + if(/micromessenger/i.test(ua.Agent.source)) { + ua.Agent.isWechat = true; + ua.Agent.version = this.getWechatVersion(ua.Agent.source); + } + }; - this.testWechat = function testWechat() { - var ua = this; + /** + * Checks if the user agent is a webview of android or iOS. + * Be careful that function has the side effects related to `this.Agent` state of the + * boolean flag `isiOSStandalone`, `isiOSUiwebview` and `isAndroidWebview` will be set as side effect. + */ + UserAgent.prototype.testWebview = function() { + var isiOS = ['iOS', 'OS X'].indexOf(this.Agent.os) !== -1 || (this.Agent.isiPad || this.Agent.isiPod || this.Agent.isiPhone); + var isStandaloneBrowser = + this.Agent.isYaBrowser || + this.Agent.isOpera || + this.Agent.isIE || + this.Agent.isEdge || + this.Agent.isSafari || + this.Agent.isFirefox || + this.Agent.isChrome || + this.Agent.isUC; - if(/micromessenger/i.test(ua.Agent.source)) { - ua.Agent.isWechat = true; - ua.Agent.version = this.getWechatVersion(ua.Agent.source); + if (isiOS && isBrowser) { + if (window.navigator.standalone && !isStandaloneBrowser) { + this.Agent.isiOSStandalone = true; + } else if (!window.navigator.standalone && !isStandaloneBrowser) { + this.Agent.isiOSUiwebview = true; } - }; - - this.parse = function parse(source) { - var ua = new UserAgent(); - ua.Agent.source = source.replace(/^\s*/, '').replace(/\s*$/, ''); - ua.Agent.os = ua.getOS(ua.Agent.source); - ua.Agent.platform = ua.getPlatform(ua.Agent.source); - ua.Agent.browser = ua.getBrowser(ua.Agent.source); - ua.Agent.version = ua.getBrowserVersion(ua.Agent.source); - ua.Agent.electronVersion = ua.getElectronVersion(ua.Agent.source); - ua.testBot(); - ua.testSmartTV(); - ua.testMobile(); - ua.testAndroidTablet(); - ua.testTablet(); - ua.testCompatibilityMode(); - ua.testSilk(); - ua.testKindleFire(); - ua.testCaptiveNetwork(); - ua.testWebkit(); - ua.testWechat(); - return ua.Agent; - }; - - this.Agent = this.DefaultAgent; - return this; + } else if (this.Agent.isAndroid) { + if (/; ?wv\)/i.test(this.Agent.source)) { + this.Agent.isAndroidWebview = true; + } + } }; - exports.UserAgent = UserAgent; - return new UserAgent(); + /** + * @deprecated + * Method for parse the user agent, like a static but attached to instance. + * + * @param {string} source - The user agent (window.navigator.userAgent for browsers or req.headers['user-agent'] for express.js). + * + * @returns {UserAgent} Instance of UserAgent with parsed source. + */ + UserAgent.prototype.parse = function (source) { + try { + console.warn('The `userAgentInstance.parse` method from instance is deprecated, use the static method instead: `UserAgent.parse`.'); + } catch (e) {} + + /* Fallback for previous solution. */ + return UserAgent.parse(source); + }; + /** + * Static method for parse the user agent. + * + * @param {string} source - The user agent (window.navigator.userAgent for browsers or req.headers['user-agent'] for express.js). + * + * @returns {UserAgent} Instance of UserAgent with parsed source. + */ + UserAgent.parse = function (source) { + var ua = new UserAgent(source); + return ua.Agent; + }; + + /** + * Static method for check NginxGeoIP. + * + * @param {object} headers - Request headers. + * + * @returns {UserAgent} Instance of UserAgent with `Agent.geoIp`. + */ + UserAgent.testNginxGeoIP = function (headers) { + return new UserAgent(null, headers); + }; + + exports.UserAgent = UserAgent; })(this); diff --git a/lib/express-useragent.min.js b/lib/express-useragent.min.js index 53391bb..fcf9ed8 100644 --- a/lib/express-useragent.min.js +++ b/lib/express-useragent.min.js @@ -1,6 +1,6 @@ /*! - * express-useragent.js v1.0.15 (https://github.com/biggora/express-useragent/) - * Copyright 2011-2020 Aleksejs Gordejevs + * express-useragent.js v1.0.16 (https://github.com/biggora/express-useragent/) + * Copyright 2011-2021 Aleksejs Gordejevs * Licensed under MIT (https://github.com/biggora/express-useragent/blob/master/README.md#license) */ -!function(a){"use strict";var b=["\\+https:\\/\\/developers.google.com\\/\\+\\/web\\/snippet\\/","ad\\smonitoring","adsbot","apex","applebot","archive.org_bot","baiduspider","bingbot","chromeheadless","cloudflare","cloudinary","crawler","curl","discordbot","duckduckbot","embedly","exabot","facebookexternalhit","facebot","flipboard","google","googlebot","gsa-crawler","gurujibot","guzzlehttp","heritrix","ia_archiver","insights","linkedinbot","ltx71","mediapartners","msnbot","odklbot","phantom\\.js","phantomjs","pingdom","pinterest","python","rtlnieuws","skypeuripreview","slackbot","slurp","spbot","telegrambot","test\\scertificate","testing","tiabot","tumblr ","twitterbot","vkshare","web\\sscraper","wget","yandexbot","whatsapp","orangebot","smtbot","qwantify","mj12bot","ahrefsbot","seznambot","panscient.com","duckduckgo-favicons-bot","uptimerobot","semrushbot","postman","dotbot","zoominfobot","ifttt","sogou","ru_bot","researchscan","nimbostratus-bot","slack-imgproxy","node-superagent","go-http-client","jersey","dataprovider.com","github-camo","dispatch","checkmarknetwork","screaming frog","whatweb","daum","netcraftsurveyagent","mojeekbot","surdotlybot","springbot"],c=new RegExp("^.*("+b.join("|")+").*$"),d=function(){return this.version="1.0.15",this._Versions={Edge:/(?:edge|edga|edgios|edg)\/([\d\w\.\-]+)/i,Firefox:/(?:firefox|fxios)\/([\d\w\.\-]+)/i,IE:/msie\s([\d\.]+[\d])|trident\/\d+\.\d+;.*[rv:]+(\d+\.\d)/i,Chrome:/(?:chrome|crios)\/([\d\w\.\-]+)/i,Chromium:/chromium\/([\d\w\.\-]+)/i,Safari:/(version|safari)\/([\d\w\.\-]+)/i,Opera:/version\/([\d\w\.\-]+)|OPR\/([\d\w\.\-]+)/i,Ps3:/([\d\w\.\-]+)\)\s*$/i,Psp:/([\d\w\.\-]+)\)?\s*$/i,Amaya:/amaya\/([\d\w\.\-]+)/i,SeaMonkey:/seamonkey\/([\d\w\.\-]+)/i,OmniWeb:/omniweb\/v([\d\w\.\-]+)/i,Flock:/flock\/([\d\w\.\-]+)/i,Epiphany:/epiphany\/([\d\w\.\-]+)/i,WinJs:/msapphost\/([\d\w\.\-]+)/i,PhantomJS:/phantomjs\/([\d\w\.\-]+)/i,AlamoFire:/alamofire\/([\d\w\.\-]+)/i,UC:/ucbrowser\/([\d\w\.]+)/i,Facebook:/FBAV\/([\d\w\.]+)/i,WebKit:/applewebkit\/([\d\w\.]+)/i,Wechat:/micromessenger\/([\d\w\.]+)/i,Electron:/Electron\/([\d\w\.]+)/i},this._Browsers={YaBrowser:/yabrowser/i,Edge:/edge|edga|edgios|edg/i,Amaya:/amaya/i,Konqueror:/konqueror/i,Epiphany:/epiphany/i,SeaMonkey:/seamonkey/i,Flock:/flock/i,OmniWeb:/omniweb/i,Chromium:/chromium/i,Chrome:/chrome|crios/i,Safari:/safari/i,IE:/msie|trident/i,Opera:/opera|OPR\//i,PS3:/playstation 3/i,PSP:/playstation portable/i,Firefox:/firefox|fxios/i,WinJs:/msapphost/i,PhantomJS:/phantomjs/i,AlamoFire:/alamofire/i,UC:/UCBrowser/i,Facebook:/FBA[NV]/},this._OS={Windows10:/windows nt 10\.0/i,Windows81:/windows nt 6\.3/i,Windows8:/windows nt 6\.2/i,Windows7:/windows nt 6\.1/i,UnknownWindows:/windows nt 6\.\d+/i,WindowsVista:/windows nt 6\.0/i,Windows2003:/windows nt 5\.2/i,WindowsXP:/windows nt 5\.1/i,Windows2000:/windows nt 5\.0/i,WindowsPhone81:/windows phone 8\.1/i,WindowsPhone80:/windows phone 8\.0/i,OSXCheetah:/os x 10[._]0/i,OSXPuma:/os x 10[._]1(\D|$)/i,OSXJaguar:/os x 10[._]2/i,OSXPanther:/os x 10[._]3/i,OSXTiger:/os x 10[._]4/i,OSXLeopard:/os x 10[._]5/i,OSXSnowLeopard:/os x 10[._]6/i,OSXLion:/os x 10[._]7/i,OSXMountainLion:/os x 10[._]8/i,OSXMavericks:/os x 10[._]9/i,OSXYosemite:/os x 10[._]10/i,OSXElCapitan:/os x 10[._]11/i,MacOSSierra:/os x 10[._]12/i,MacOSHighSierra:/os x 10[._]13/i,MacOSMojave:/os x 10[._]14/i,Mac:/os x/i,Linux:/linux/i,Linux64:/linux x86\_64/i,ChromeOS:/cros/i,Wii:/wii/i,PS3:/playstation 3/i,PSP:/playstation portable/i,iPad:/\(iPad.*os (\d+)[._](\d+)/i,iPhone:/\(iPhone.*os (\d+)[._](\d+)/i,iOS:/ios/i,Bada:/Bada\/(\d+)\.(\d+)/i,Curl:/curl\/(\d+)\.(\d+)\.(\d+)/i,Electron:/Electron\/(\d+)\.(\d+)\.(\d+)/i},this._Platform={Windows:/windows nt/i,WindowsPhone:/windows phone/i,Mac:/macintosh/i,Linux:/linux/i,Wii:/wii/i,Playstation:/playstation/i,iPad:/ipad/i,iPod:/ipod/i,iPhone:/iphone/i,Android:/android/i,Blackberry:/blackberry/i,Samsung:/samsung/i,Curl:/curl/i,Electron:/Electron/i,iOS:/^ios\-/i},this.DefaultAgent={isYaBrowser:!1,isAuthoritative:!0,isMobile:!1,isMobileNative:!1,isTablet:!1,isiPad:!1,isiPod:!1,isiPhone:!1,isiPhoneNative:!1,isAndroid:!1,isAndroidNative:!1,isBlackberry:!1,isOpera:!1,isIE:!1,isEdge:!1,isIECompatibilityMode:!1,isSafari:!1,isFirefox:!1,isWebkit:!1,isChrome:!1,isKonqueror:!1,isOmniWeb:!1,isSeaMonkey:!1,isFlock:!1,isAmaya:!1,isPhantomJS:!1,isEpiphany:!1,isDesktop:!1,isWindows:!1,isLinux:!1,isLinux64:!1,isMac:!1,isChromeOS:!1,isBada:!1,isSamsung:!1,isRaspberry:!1,isBot:!1,isCurl:!1,isAndroidTablet:!1,isWinJs:!1,isKindleFire:!1,isSilk:!1,isCaptive:!1,isSmartTV:!1,isUC:!1,isFacebook:!1,isAlamoFire:!1,isElectron:!1,silkAccelerated:!1,browser:"unknown",version:"unknown",os:"unknown",platform:"unknown",geoIp:{},source:"",isWechat:!1},this.Agent={},this.getBrowser=function(a){switch(!0){case this._Browsers.YaBrowser.test(a):return this.Agent.isYaBrowser=!0,"YaBrowser";case this._Browsers.AlamoFire.test(a):return this.Agent.isAlamoFire=!0,"AlamoFire";case this._Browsers.Edge.test(a):return this.Agent.isEdge=!0,"Edge";case this._Browsers.PhantomJS.test(a):return this.Agent.isPhantomJS=!0,"PhantomJS";case this._Browsers.Konqueror.test(a):return this.Agent.isKonqueror=!0,"Konqueror";case this._Browsers.Amaya.test(a):return this.Agent.isAmaya=!0,"Amaya";case this._Browsers.Epiphany.test(a):return this.Agent.isEpiphany=!0,"Epiphany";case this._Browsers.SeaMonkey.test(a):return this.Agent.isSeaMonkey=!0,"SeaMonkey";case this._Browsers.Flock.test(a):return this.Agent.isFlock=!0,"Flock";case this._Browsers.OmniWeb.test(a):return this.Agent.isOmniWeb=!0,"OmniWeb";case this._Browsers.Opera.test(a):return this.Agent.isOpera=!0,"Opera";case this._Browsers.Chromium.test(a):return this.Agent.isChrome=!0,"Chromium";case this._Browsers.Facebook.test(a):return this.Agent.isFacebook=!0,"Facebook";case this._Browsers.Chrome.test(a):return this.Agent.isChrome=!0,"Chrome";case this._Browsers.WinJs.test(a):return this.Agent.isWinJs=!0,"WinJs";case this._Browsers.IE.test(a):return this.Agent.isIE=!0,"IE";case this._Browsers.Firefox.test(a):return this.Agent.isFirefox=!0,"Firefox";case this._Browsers.Safari.test(a):return this.Agent.isSafari=!0,"Safari";case this._Browsers.PS3.test(a):return"ps3";case this._Browsers.PSP.test(a):return"psp";case this._Browsers.UC.test(a):return this.Agent.isUC=!0,"UCBrowser";default:return a.indexOf("Dalvik")!==-1?"unknown":0!==a.indexOf("Mozilla")&&/^([\d\w\-\.]+)\/[\d\w\.\-]+/i.test(a)?(this.Agent.isAuthoritative=!1,RegExp.$1):"unknown"}},this.getBrowserVersion=function(a){var b;switch(this.Agent.browser){case"Edge":if(this._Versions.Edge.test(a))return RegExp.$1;break;case"PhantomJS":if(this._Versions.PhantomJS.test(a))return RegExp.$1;break;case"Chrome":if(this._Versions.Chrome.test(a))return RegExp.$1;break;case"Chromium":if(this._Versions.Chromium.test(a))return RegExp.$1;break;case"Safari":if(this._Versions.Safari.test(a))return RegExp.$2;break;case"Opera":if(this._Versions.Opera.test(a))return RegExp.$1?RegExp.$1:RegExp.$2;break;case"Firefox":if(this._Versions.Firefox.test(a))return RegExp.$1;break;case"WinJs":if(this._Versions.WinJs.test(a))return RegExp.$1;break;case"IE":if(this._Versions.IE.test(a))return RegExp.$2?RegExp.$2:RegExp.$1;break;case"ps3":if(this._Versions.Ps3.test(a))return RegExp.$1;break;case"psp":if(this._Versions.Psp.test(a))return RegExp.$1;break;case"Amaya":if(this._Versions.Amaya.test(a))return RegExp.$1;break;case"Epiphany":if(this._Versions.Epiphany.test(a))return RegExp.$1;break;case"SeaMonkey":if(this._Versions.SeaMonkey.test(a))return RegExp.$1;break;case"Flock":if(this._Versions.Flock.test(a))return RegExp.$1;break;case"OmniWeb":if(this._Versions.OmniWeb.test(a))return RegExp.$1;break;case"UCBrowser":if(this._Versions.UC.test(a))return RegExp.$1;break;case"Facebook":if(this._Versions.Facebook.test(a))return RegExp.$1;break;default:if("unknown"===this.Agent.browser)return this.testWebkit(),this.Agent.isWebkit&&this._Versions.WebKit.test(a)?RegExp.$1:"unknown";if(b=new RegExp(this.Agent.browser+"[\\/ ]([\\d\\w\\.\\-]+)","i"),b.test(a))return RegExp.$1}},this.getWechatVersion=function(a){return this._Versions.Wechat.test(a)?RegExp.$1:"unknown"},this.getElectronVersion=function(a){return this._Versions.Electron.test(a)?(this.Agent.isElectron=!0,RegExp.$1):""},this.getOS=function(a){switch(!0){case this._OS.WindowsVista.test(a):return this.Agent.isWindows=!0,"Windows Vista";case this._OS.Windows7.test(a):return this.Agent.isWindows=!0,"Windows 7";case this._OS.Windows8.test(a):return this.Agent.isWindows=!0,"Windows 8";case this._OS.Windows81.test(a):return this.Agent.isWindows=!0,"Windows 8.1";case this._OS.Windows10.test(a):return this.Agent.isWindows=!0,"Windows 10.0";case this._OS.Windows2003.test(a):return this.Agent.isWindows=!0,"Windows 2003";case this._OS.WindowsXP.test(a):return this.Agent.isWindows=!0,"Windows XP";case this._OS.Windows2000.test(a):return this.Agent.isWindows=!0,"Windows 2000";case this._OS.WindowsPhone81.test(a):return this.Agent.isWindowsPhone=!0,"Windows Phone 8.1";case this._OS.WindowsPhone80.test(a):return this.Agent.isWindowsPhone=!0,"Windows Phone 8.0";case this._OS.Linux64.test(a):return this.Agent.isLinux=!0,this.Agent.isLinux64=!0,"Linux 64";case this._OS.Linux.test(a):return this.Agent.isLinux=!0,"Linux";case this._OS.ChromeOS.test(a):return this.Agent.isChromeOS=!0,"Chrome OS";case this._OS.Wii.test(a):return"Wii";case this._OS.PS3.test(a):return"Playstation";case this._OS.PSP.test(a):return"Playstation";case this._OS.OSXCheetah.test(a):return this.Agent.isMac=!0,"OS X Cheetah";case this._OS.OSXPuma.test(a):return this.Agent.isMac=!0,"OS X Puma";case this._OS.OSXJaguar.test(a):return this.Agent.isMac=!0,"OS X Jaguar";case this._OS.OSXPanther.test(a):return this.Agent.isMac=!0,"OS X Panther";case this._OS.OSXTiger.test(a):return this.Agent.isMac=!0,"OS X Tiger";case this._OS.OSXLeopard.test(a):return this.Agent.isMac=!0,"OS X Leopard";case this._OS.OSXSnowLeopard.test(a):return this.Agent.isMac=!0,"OS X Snow Leopard";case this._OS.OSXLion.test(a):return this.Agent.isMac=!0,"OS X Lion";case this._OS.OSXMountainLion.test(a):return this.Agent.isMac=!0,"OS X Mountain Lion";case this._OS.OSXMavericks.test(a):return this.Agent.isMac=!0,"OS X Mavericks";case this._OS.OSXYosemite.test(a):return this.Agent.isMac=!0,"OS X Yosemite";case this._OS.OSXElCapitan.test(a):return this.Agent.isMac=!0,"OS X El Capitan";case this._OS.MacOSSierra.test(a):return this.Agent.isMac=!0,"macOS Sierra";case this._OS.MacOSHighSierra.test(a):return this.Agent.isMac=!0,"macOS High Sierra";case this._OS.MacOSMojave.test(a):return this.Agent.isMac=!0,"macOS Mojave";case this._OS.Mac.test(a):return this.Agent.isMac=!0,"OS X";case this._OS.iPad.test(a):return this.Agent.isiPad=!0,a.match(this._OS.iPad)[0].replace("_",".");case this._OS.iPhone.test(a):return this.Agent.isiPhone=!0,a.match(this._OS.iPhone)[0].replace("_",".");case this._OS.Bada.test(a):return this.Agent.isBada=!0,"Bada";case this._OS.Curl.test(a):return this.Agent.isCurl=!0,"Curl";case this._OS.iOS.test(a):return this.Agent.isiPhone=!0,"iOS";case this._OS.Electron.test(a):return this.Agent.isElectron=!0,"Electron";default:return"unknown"}},this.getPlatform=function(a){switch(!0){case this._Platform.Windows.test(a):return"Microsoft Windows";case this._Platform.WindowsPhone.test(a):return this.Agent.isWindowsPhone=!0,"Microsoft Windows Phone";case this._Platform.Mac.test(a):return"Apple Mac";case this._Platform.Curl.test(a):return"Curl";case this._Platform.Electron.test(a):return this.Agent.isElectron=!0,"Electron";case this._Platform.Android.test(a):return this.Agent.isAndroid=!0,"Android";case this._Platform.Blackberry.test(a):return this.Agent.isBlackberry=!0,"Blackberry";case this._Platform.Linux.test(a):return"Linux";case this._Platform.Wii.test(a):return"Wii";case this._Platform.Playstation.test(a):return"Playstation";case this._Platform.iPad.test(a):return this.Agent.isiPad=!0,"iPad";case this._Platform.iPod.test(a):return this.Agent.isiPod=!0,"iPod";case this._Platform.iPhone.test(a):return this.Agent.isiPhone=!0,"iPhone";case this._Platform.Samsung.test(a):return this.Agent.isSamsung=!0,"Samsung";case this._Platform.iOS.test(a):return"Apple iOS";default:return"unknown"}},this.testCompatibilityMode=function(){var a=this;if(this.Agent.isIE&&/Trident\/(\d)\.0/i.test(a.Agent.source)){var b=parseInt(RegExp.$1,10),c=parseInt(a.Agent.version,10);7===c&&7===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=11),7===c&&6===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=10),7===c&&5===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=9),7===c&&4===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=8)}},this.testSilk=function(){var a=this;switch(!0){case new RegExp("silk","gi").test(a.Agent.source):this.Agent.isSilk=!0}return/Silk-Accelerated=true/gi.test(a.Agent.source)&&(this.Agent.SilkAccelerated=!0),!!this.Agent.isSilk&&"Silk"},this.testKindleFire=function(){var a=this;switch(!0){case/KFOT/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire";case/KFTT/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD";case/KFJWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD 8.9";case/KFJWA/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD 8.9 4G";case/KFSOWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD 7";case/KFTHWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 7";case/KFTHWA/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 7 4G";case/KFAPWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 8.9";case/KFAPWA/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 8.9 4G";default:return!1}},this.testCaptiveNetwork=function(){var a=this;switch(!0){case/CaptiveNetwork/gi.test(a.Agent.source):return a.Agent.isCaptive=!0,a.Agent.isMac=!0,a.Agent.platform="Apple Mac","CaptiveNetwork";default:return!1}},this.reset=function(){var a=this;for(var b in a.DefaultAgent)a.Agent[b]=a.DefaultAgent[b];return a},this.testMobile=function(){var a=this;switch(!0){case a.Agent.isWindows:case a.Agent.isLinux:case a.Agent.isMac:case a.Agent.isChromeOS:a.Agent.isDesktop=!0;break;case a.Agent.isAndroid:case a.Agent.isSamsung:a.Agent.isMobile=!0}switch(!0){case a.Agent.isiPad:case a.Agent.isiPod:case a.Agent.isiPhone:case a.Agent.isBada:case a.Agent.isBlackberry:case a.Agent.isAndroid:case a.Agent.isWindowsPhone:a.Agent.isMobile=!0,a.Agent.isDesktop=!1}/mobile|^ios\-/i.test(a.Agent.source)&&(a.Agent.isMobile=!0,a.Agent.isDesktop=!1),/dalvik/i.test(a.Agent.source)&&(a.Agent.isAndroidNative=!0,a.Agent.isMobileNative=!0),/scale/i.test(a.Agent.source)&&(a.Agent.isiPhoneNative=!0,a.Agent.isMobileNative=!0)},this.testTablet=function(){var a=this;switch(!0){case a.Agent.isiPad:case a.Agent.isAndroidTablet:case a.Agent.isKindleFire:a.Agent.isTablet=!0}/tablet/i.test(a.Agent.source)&&(a.Agent.isTablet=!0)},this.testNginxGeoIP=function(a){var b=this;return Object.keys(a).forEach(function(c){/^GEOIP/i.test(c)&&(b.Agent.geoIp[c]=a[c])}),b},this.testBot=function(){var a=this,b=c.exec(a.Agent.source.toLowerCase());b?a.Agent.isBot=b[1]:a.Agent.isAuthoritative||(a.Agent.isBot=/bot/i.test(a.Agent.source))},this.testSmartTV=function(){var a=this;a.Agent.isSmartTV=new RegExp("smart-tv|smarttv|googletv|appletv|hbbtv|pov_tv|netcast.tv","gi").test(a.Agent.source.toLowerCase())},this.testAndroidTablet=function(){var a=this;a.Agent.isAndroid&&!/mobile/i.test(a.Agent.source)&&(a.Agent.isAndroidTablet=!0)},this.testWebkit=function(){var a=this;"unknown"===a.Agent.browser&&/applewebkit/i.test(a.Agent.source)&&(a.Agent.browser="Apple WebKit",a.Agent.isWebkit=!0)},this.testWechat=function(){var a=this;/micromessenger/i.test(a.Agent.source)&&(a.Agent.isWechat=!0,a.Agent.version=this.getWechatVersion(a.Agent.source))},this.parse=function(a){var b=new d;return b.Agent.source=a.replace(/^\s*/,"").replace(/\s*$/,""),b.Agent.os=b.getOS(b.Agent.source),b.Agent.platform=b.getPlatform(b.Agent.source),b.Agent.browser=b.getBrowser(b.Agent.source),b.Agent.version=b.getBrowserVersion(b.Agent.source),b.Agent.electronVersion=b.getElectronVersion(b.Agent.source),b.testBot(),b.testSmartTV(),b.testMobile(),b.testAndroidTablet(),b.testTablet(),b.testCompatibilityMode(),b.testSilk(),b.testKindleFire(),b.testCaptiveNetwork(),b.testWebkit(),b.testWechat(),b.Agent},this.Agent=this.DefaultAgent,this};return a.UserAgent=d,new d}(this); \ No newline at end of file +!function(a){"use strict";function b(a){this.getter=a}function c(a,b){return this instanceof c?("string"!=typeof a&&(a=""),this.version="1.0.16",this.Agent={},this.reset(),this.Agent.source=a.replace(/^\s*/,"").replace(/\s*$/,""),this.Agent.source&&(this.Agent.os=this.getOS(),this.Agent.platform=this.getPlatform(),this.Agent.browser=this.getBrowser(),this.Agent.version=this.getBrowserVersion(),this.Agent.electronVersion=this.getElectronVersion(),this.testWebview(),this.testBot(),this.testSmartTV(),this.testMobile(),this.testAndroidTablet(),this.testTablet(),this.testCompatibilityMode(),this.testSilk(),this.testKindleFire(),this.testCaptiveNetwork(),this.testWebkit(),this.testWechat()),b&&"object"==typeof b&&this.testNginxGeoIP(b),this.DefaultAgent={},void this.reset("DefaultAgent")):new c(a)}b.prototype.getValue=function(){return this.getter()};var d="object"==typeof window&&"object"==typeof window.navigator,e=["\\+https:\\/\\/developers.google.com\\/\\+\\/web\\/snippet\\/","ad\\smonitoring","adsbot","apex","applebot","archive.org_bot","baiduspider","bingbot","chromeheadless","cloudflare","cloudinary","crawler","curl","discordbot","duckduckbot","embedly","exabot","facebookexternalhit","facebot","flipboard","google","googlebot","gsa-crawler","gurujibot","guzzlehttp","heritrix","ia_archiver","insights","linkedinbot","ltx71","mediapartners","msnbot","odklbot","phantom\\.js","phantomjs","pingdom","pinterest","python","rtlnieuws","skypeuripreview","slackbot","slurp","spbot","telegrambot","test\\scertificate","testing","tiabot","tumblr ","twitterbot","vkshare","web\\sscraper","wget","yandexbot","whatsapp","orangebot","smtbot","qwantify","mj12bot","ahrefsbot","seznambot","panscient.com","duckduckgo-favicons-bot","uptimerobot","semrushbot","postman","dotbot","zoominfobot","ifttt","sogou","ru_bot","researchscan","nimbostratus-bot","slack-imgproxy","node-superagent","go-http-client","jersey","dataprovider.com","github-camo","dispatch","checkmarknetwork","screaming frog","whatweb","daum","netcraftsurveyagent","mojeekbot","surdotlybot","springbot"],f=new RegExp("^.*("+e.join("|")+").*$"),g={Edge:/(?:edge|edga|edgios|edg)\/([\d\w\.\-]+)/i,Firefox:/(?:firefox|fxios)\/([\d\w\.\-]+)/i,IE:/msie\s([\d\.]+[\d])|trident\/\d+\.\d+;.*[rv:]+(\d+\.\d)/i,Chrome:/(?:chrome|crios)\/([\d\w\.\-]+)/i,Chromium:/chromium\/([\d\w\.\-]+)/i,Safari:/(version|safari)\/([\d\w\.\-]+)/i,Opera:/version\/([\d\w\.\-]+)|OPR\/([\d\w\.\-]+)/i,Ps3:/([\d\w\.\-]+)\)\s*$/i,Psp:/([\d\w\.\-]+)\)?\s*$/i,Amaya:/amaya\/([\d\w\.\-]+)/i,SeaMonkey:/seamonkey\/([\d\w\.\-]+)/i,OmniWeb:/omniweb\/v([\d\w\.\-]+)/i,Flock:/flock\/([\d\w\.\-]+)/i,Epiphany:/epiphany\/([\d\w\.\-]+)/i,WinJs:/msapphost\/([\d\w\.\-]+)/i,PhantomJS:/phantomjs\/([\d\w\.\-]+)/i,AlamoFire:/alamofire\/([\d\w\.\-]+)/i,UC:/ucbrowser\/([\d\w\.]+)/i,Facebook:/FBAV\/([\d\w\.]+)/i,WebKit:/applewebkit\/([\d\w\.]+)/i,Wechat:/micromessenger\/([\d\w\.]+)/i,Electron:/Electron\/([\d\w\.]+)/i},h={YaBrowser:/yabrowser/i,Edge:/edge|edga|edgios|edg/i,Amaya:/amaya/i,Konqueror:/konqueror/i,Epiphany:/epiphany/i,SeaMonkey:/seamonkey/i,Flock:/flock/i,OmniWeb:/omniweb/i,Chromium:/chromium/i,Chrome:/chrome|crios/i,Safari:/safari/i,IE:/msie|trident/i,Opera:/opera|OPR\//i,PS3:/playstation 3/i,PSP:/playstation portable/i,Firefox:/firefox|fxios/i,WinJs:/msapphost/i,PhantomJS:/phantomjs/i,AlamoFire:/alamofire/i,UC:/UCBrowser/i,Facebook:/FBA[NV]/},i={Windows10:/windows nt 10\.0/i,Windows81:/windows nt 6\.3/i,Windows8:/windows nt 6\.2/i,Windows7:/windows nt 6\.1/i,UnknownWindows:/windows nt 6\.\d+/i,WindowsVista:/windows nt 6\.0/i,Windows2003:/windows nt 5\.2/i,WindowsXP:/windows nt 5\.1/i,Windows2000:/windows nt 5\.0/i,WindowsPhone81:/windows phone 8\.1/i,WindowsPhone80:/windows phone 8\.0/i,OSXCheetah:/os x 10[._]0/i,OSXPuma:/os x 10[._]1(\D|$)/i,OSXJaguar:/os x 10[._]2/i,OSXPanther:/os x 10[._]3/i,OSXTiger:/os x 10[._]4/i,OSXLeopard:/os x 10[._]5/i,OSXSnowLeopard:/os x 10[._]6/i,OSXLion:/os x 10[._]7/i,OSXMountainLion:/os x 10[._]8/i,OSXMavericks:/os x 10[._]9/i,OSXYosemite:/os x 10[._]10/i,OSXElCapitan:/os x 10[._]11/i,MacOSSierra:/os x 10[._]12/i,MacOSHighSierra:/os x 10[._]13/i,MacOSMojave:/os x 10[._]14/i,Mac:/os x/i,Linux:/linux/i,Linux64:/linux x86\_64/i,ChromeOS:/cros/i,Wii:/wii/i,PS3:/playstation 3/i,PSP:/playstation portable/i,iPad:/\(iPad.*os (\d+)[._](\d+)/i,iPhone:/\(iPhone.*os (\d+)[._](\d+)/i,iOS:/ios/i,Bada:/Bada\/(\d+)\.(\d+)/i,Curl:/curl\/(\d+)\.(\d+)\.(\d+)/i,Electron:/Electron\/(\d+)\.(\d+)\.(\d+)/i},j={Windows:/windows nt/i,WindowsPhone:/windows phone/i,Mac:/macintosh/i,Linux:/linux/i,Wii:/wii/i,Playstation:/playstation/i,iPad:/ipad/i,iPod:/ipod/i,iPhone:/iphone/i,Android:/android/i,Blackberry:/blackberry/i,Samsung:/samsung/i,Curl:/curl/i,Electron:/Electron/i,iOS:/^ios\-/i},k={isYaBrowser:!1,isAuthoritative:!0,isMobile:!1,isMobileNative:!1,isTablet:!1,isiPad:!1,isiPod:!1,isiPhone:!1,isiPhoneNative:!1,isiOSStandalone:!1,isiOSUiwebview:!1,isAndroid:!1,isAndroidNative:!1,isAndroidWebview:!1,isBlackberry:!1,isOpera:!1,isIE:!1,isEdge:!1,isIECompatibilityMode:!1,isSafari:!1,isFirefox:!1,isWebkit:!1,isChrome:!1,isKonqueror:!1,isOmniWeb:!1,isSeaMonkey:!1,isFlock:!1,isAmaya:!1,isPhantomJS:!1,isEpiphany:!1,isDesktop:!1,isWindows:!1,isLinux:!1,isLinux64:!1,isMac:!1,isChromeOS:!1,isBada:!1,isSamsung:!1,isRaspberry:!1,isBot:!1,isCurl:!1,isAndroidTablet:!1,isWinJs:!1,isKindleFire:!1,isSilk:!1,isCaptive:!1,isSmartTV:!1,isUC:!1,isFacebook:!1,isAlamoFire:!1,isElectron:!1,isWechat:!1,silkAccelerated:!1,browser:"unknown",version:"unknown",os:"unknown",platform:"unknown",geoIp:new b(function(){return{}}),source:""};c.prototype.getBrowser=function(a){switch(a=a||this.Agent.source,!0){case h.YaBrowser.test(a):return this.Agent.isYaBrowser=!0,"YaBrowser";case h.AlamoFire.test(a):return this.Agent.isAlamoFire=!0,"AlamoFire";case h.Edge.test(a):return this.Agent.isEdge=!0,"Edge";case h.PhantomJS.test(a):return this.Agent.isPhantomJS=!0,"PhantomJS";case h.Konqueror.test(a):return this.Agent.isKonqueror=!0,"Konqueror";case h.Amaya.test(a):return this.Agent.isAmaya=!0,"Amaya";case h.Epiphany.test(a):return this.Agent.isEpiphany=!0,"Epiphany";case h.SeaMonkey.test(a):return this.Agent.isSeaMonkey=!0,"SeaMonkey";case h.Flock.test(a):return this.Agent.isFlock=!0,"Flock";case h.OmniWeb.test(a):return this.Agent.isOmniWeb=!0,"OmniWeb";case h.Opera.test(a):return this.Agent.isOpera=!0,"Opera";case h.Chromium.test(a):return this.Agent.isChrome=!0,"Chromium";case h.Facebook.test(a):return this.Agent.isFacebook=!0,"Facebook";case h.Chrome.test(a):return this.Agent.isChrome=!0,"Chrome";case h.WinJs.test(a):return this.Agent.isWinJs=!0,"WinJs";case h.IE.test(a):return this.Agent.isIE=!0,"IE";case h.Firefox.test(a):return this.Agent.isFirefox=!0,"Firefox";case h.Safari.test(a):return this.Agent.isSafari=!0,"Safari";case h.PS3.test(a):return"ps3";case h.PSP.test(a):return"psp";case h.UC.test(a):return this.Agent.isUC=!0,"UCBrowser";default:return a.indexOf("Dalvik")!==-1?"unknown":0!==a.indexOf("Mozilla")&&/^([\d\w\-\.]+)\/[\d\w\.\-]+/i.test(a)?(this.Agent.isAuthoritative=!1,RegExp.$1):"unknown"}},c.prototype.getBrowserVersion=function(a){a=a||this.Agent.source;var b;switch(this.Agent.browser){case"Edge":if(g.Edge.test(a))return RegExp.$1;break;case"PhantomJS":if(g.PhantomJS.test(a))return RegExp.$1;break;case"Chrome":if(g.Chrome.test(a))return RegExp.$1;break;case"Chromium":if(g.Chromium.test(a))return RegExp.$1;break;case"Safari":if(g.Safari.test(a))return RegExp.$2;break;case"Opera":if(g.Opera.test(a))return RegExp.$1?RegExp.$1:RegExp.$2;break;case"Firefox":if(g.Firefox.test(a))return RegExp.$1;break;case"WinJs":if(g.WinJs.test(a))return RegExp.$1;break;case"IE":if(g.IE.test(a))return RegExp.$2?RegExp.$2:RegExp.$1;break;case"ps3":if(g.Ps3.test(a))return RegExp.$1;break;case"psp":if(g.Psp.test(a))return RegExp.$1;break;case"Amaya":if(g.Amaya.test(a))return RegExp.$1;break;case"Epiphany":if(g.Epiphany.test(a))return RegExp.$1;break;case"SeaMonkey":if(g.SeaMonkey.test(a))return RegExp.$1;break;case"Flock":if(g.Flock.test(a))return RegExp.$1;break;case"OmniWeb":if(g.OmniWeb.test(a))return RegExp.$1;break;case"UCBrowser":if(g.UC.test(a))return RegExp.$1;break;case"Facebook":if(g.Facebook.test(a))return RegExp.$1;break;default:if("unknown"===this.Agent.browser)return this.testWebkit(),this.Agent.isWebkit&&g.WebKit.test(a)?RegExp.$1:"unknown";if(b=new RegExp(this.Agent.browser+"[\\/ ]([\\d\\w\\.\\-]+)","i"),b.test(a))return RegExp.$1}},c.prototype.getWechatVersion=function(a){return a=a||this.Agent.source,g.Wechat.test(a)?RegExp.$1:"unknown"},c.prototype.getElectronVersion=function(a){return a=a||this.Agent.source,g.Electron.test(a)?(this.Agent.isElectron=!0,RegExp.$1):""},c.prototype.getOS=function(a){switch(a=a||this.Agent.source,!0){case i.WindowsVista.test(a):return this.Agent.isWindows=!0,"Windows Vista";case i.Windows7.test(a):return this.Agent.isWindows=!0,"Windows 7";case i.Windows8.test(a):return this.Agent.isWindows=!0,"Windows 8";case i.Windows81.test(a):return this.Agent.isWindows=!0,"Windows 8.1";case i.Windows10.test(a):return this.Agent.isWindows=!0,"Windows 10.0";case i.Windows2003.test(a):return this.Agent.isWindows=!0,"Windows 2003";case i.WindowsXP.test(a):return this.Agent.isWindows=!0,"Windows XP";case i.Windows2000.test(a):return this.Agent.isWindows=!0,"Windows 2000";case i.WindowsPhone81.test(a):return this.Agent.isWindowsPhone=!0,"Windows Phone 8.1";case i.WindowsPhone80.test(a):return this.Agent.isWindowsPhone=!0,"Windows Phone 8.0";case i.Linux64.test(a):return this.Agent.isLinux=!0,this.Agent.isLinux64=!0,"Linux 64";case i.Linux.test(a):return this.Agent.isLinux=!0,"Linux";case i.ChromeOS.test(a):return this.Agent.isChromeOS=!0,"Chrome OS";case i.Wii.test(a):return"Wii";case i.PS3.test(a):return"Playstation";case i.PSP.test(a):return"Playstation";case i.OSXCheetah.test(a):return this.Agent.isMac=!0,"OS X Cheetah";case i.OSXPuma.test(a):return this.Agent.isMac=!0,"OS X Puma";case i.OSXJaguar.test(a):return this.Agent.isMac=!0,"OS X Jaguar";case i.OSXPanther.test(a):return this.Agent.isMac=!0,"OS X Panther";case i.OSXTiger.test(a):return this.Agent.isMac=!0,"OS X Tiger";case i.OSXLeopard.test(a):return this.Agent.isMac=!0,"OS X Leopard";case i.OSXSnowLeopard.test(a):return this.Agent.isMac=!0,"OS X Snow Leopard";case i.OSXLion.test(a):return this.Agent.isMac=!0,"OS X Lion";case i.OSXMountainLion.test(a):return this.Agent.isMac=!0,"OS X Mountain Lion";case i.OSXMavericks.test(a):return this.Agent.isMac=!0,"OS X Mavericks";case i.OSXYosemite.test(a):return this.Agent.isMac=!0,"OS X Yosemite";case i.OSXElCapitan.test(a):return this.Agent.isMac=!0,"OS X El Capitan";case i.MacOSSierra.test(a):return this.Agent.isMac=!0,"macOS Sierra";case i.MacOSHighSierra.test(a):return this.Agent.isMac=!0,"macOS High Sierra";case i.MacOSMojave.test(a):return this.Agent.isMac=!0,"macOS Mojave";case i.Mac.test(a):return d&&"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1?(this.Agent.isiPad=!0,"iOS 13+"):(this.Agent.isMac=!0,"OS X");case i.iPad.test(a):return this.Agent.isiPad=!0,a.match(i.iPad)[0].replace("_",".");case i.iPhone.test(a):return this.Agent.isiPhone=!0,a.match(i.iPhone)[0].replace("_",".");case i.Bada.test(a):return this.Agent.isBada=!0,"Bada";case i.Curl.test(a):return this.Agent.isCurl=!0,"Curl";case i.iOS.test(a):return this.Agent.isiPhone=!0,"iOS";case i.Electron.test(a):return this.Agent.isElectron=!0,"Electron";default:return"unknown"}},c.prototype.getPlatform=function(a){switch(a=a||this.Agent.source,!0){case j.Windows.test(a):return"Microsoft Windows";case j.WindowsPhone.test(a):return this.Agent.isWindowsPhone=!0,"Microsoft Windows Phone";case j.Mac.test(a):return d&&"MacIntel"===window.navigator.platform&&window.navigator.maxTouchPoints>1?(this.Agent.isiPad=!0,"iPad"):"Apple Mac";case j.Curl.test(a):return"Curl";case j.Electron.test(a):return this.Agent.isElectron=!0,"Electron";case j.Android.test(a):return this.Agent.isAndroid=!0,"Android";case j.Blackberry.test(a):return this.Agent.isBlackberry=!0,"Blackberry";case j.Linux.test(a):return"Linux";case j.Wii.test(a):return"Wii";case j.Playstation.test(a):return"Playstation";case j.iPad.test(a):return this.Agent.isiPad=!0,"iPad";case j.iPod.test(a):return this.Agent.isiPod=!0,"iPod";case j.iPhone.test(a):return this.Agent.isiPhone=!0,"iPhone";case j.Samsung.test(a):return this.Agent.isSamsung=!0,"Samsung";case j.iOS.test(a):return"Apple iOS";default:return"unknown"}},c.prototype.testCompatibilityMode=function(){var a=this;if(this.Agent.isIE&&/Trident\/(\d)\.0/i.test(a.Agent.source)){var b=parseInt(RegExp.$1,10),c=parseInt(a.Agent.version,10);7===c&&7===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=11),7===c&&6===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=10),7===c&&5===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=9),7===c&&4===b&&(a.Agent.isIECompatibilityMode=!0,a.Agent.version=8)}},c.prototype.testSilk=function(){var a=this;switch(!0){case new RegExp("silk","gi").test(a.Agent.source):this.Agent.isSilk=!0}return/Silk-Accelerated=true/gi.test(a.Agent.source)&&(this.Agent.SilkAccelerated=!0),!!this.Agent.isSilk&&"Silk"},c.prototype.testKindleFire=function(){var a=this;switch(!0){case/KFOT/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire";case/KFTT/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD";case/KFJWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD 8.9";case/KFJWA/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD 8.9 4G";case/KFSOWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HD 7";case/KFTHWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 7";case/KFTHWA/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 7 4G";case/KFAPWI/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 8.9";case/KFAPWA/gi.test(a.Agent.source):return this.Agent.isKindleFire=!0,"Kindle Fire HDX 8.9 4G";default:return!1}},c.prototype.testCaptiveNetwork=function(){var a=this;switch(!0){case/CaptiveNetwork/gi.test(a.Agent.source):return a.Agent.isCaptive=!0,a.Agent.isMac=!0,a.Agent.platform="Apple Mac","CaptiveNetwork";default:return!1}},c.prototype.reset=function(a){a=a||"Agent",this[a]={};for(var c in k){var d=k[c];d instanceof b&&(d=d.getValue()),this[a][c]=d}return this},c.prototype.testMobile=function(){var a=this;switch(!0){case a.Agent.isWindows:case a.Agent.isLinux:case a.Agent.isMac:case a.Agent.isChromeOS:a.Agent.isDesktop=!0;break;case a.Agent.isAndroid:case a.Agent.isSamsung:a.Agent.isMobile=!0}switch(!0){case a.Agent.isiPad:case a.Agent.isiPod:case a.Agent.isiPhone:case a.Agent.isBada:case a.Agent.isBlackberry:case a.Agent.isAndroid:case a.Agent.isWindowsPhone:a.Agent.isMobile=!0,a.Agent.isDesktop=!1}/mobile|^ios\-/i.test(a.Agent.source)&&(a.Agent.isMobile=!0,a.Agent.isDesktop=!1),/dalvik/i.test(a.Agent.source)&&(a.Agent.isAndroidNative=!0,a.Agent.isMobileNative=!0),/scale/i.test(a.Agent.source)&&(a.Agent.isiPhoneNative=!0,a.Agent.isMobileNative=!0)},c.prototype.testTablet=function(){var a=this;switch(!0){case a.Agent.isiPad:case a.Agent.isAndroidTablet:case a.Agent.isKindleFire:a.Agent.isTablet=!0}/tablet/i.test(a.Agent.source)&&(a.Agent.isTablet=!0)},c.prototype.testNginxGeoIP=function(a){var b=this;return Object.keys(a).forEach(function(c){/^GEOIP/i.test(c)&&(b.Agent.geoIp[c]=a[c])}),b},c.prototype.testBot=function(){var a=this,b=f.exec(a.Agent.source.toLowerCase());b?a.Agent.isBot=b[1]:a.Agent.isAuthoritative||(a.Agent.isBot=/bot/i.test(a.Agent.source))},c.prototype.testSmartTV=function(){var a=this;a.Agent.isSmartTV=new RegExp("smart-tv|smarttv|googletv|appletv|hbbtv|pov_tv|netcast.tv","gi").test(a.Agent.source.toLowerCase())},c.prototype.testAndroidTablet=function(){var a=this;a.Agent.isAndroid&&!/mobile/i.test(a.Agent.source)&&(a.Agent.isAndroidTablet=!0)},c.prototype.testWebkit=function(){var a=this;"unknown"===a.Agent.browser&&/applewebkit/i.test(a.Agent.source)&&(a.Agent.browser="Apple WebKit",a.Agent.isWebkit=!0)},c.prototype.testWechat=function(){var a=this;/micromessenger/i.test(a.Agent.source)&&(a.Agent.isWechat=!0,a.Agent.version=this.getWechatVersion(a.Agent.source))},c.prototype.testWebview=function(){var a=["iOS","OS X"].indexOf(this.Agent.os)!==-1||this.Agent.isiPad||this.Agent.isiPod||this.Agent.isiPhone;a&&d?window.navigator.standalone&&!this.Agent.isSafari?this.Agent.isiOSStandalone=!0:window.navigator.standalone||this.Agent.isSafari||(this.Agent.isiOSUiwebview=!0):this.Agent.isAndroid&&/; ?wv\)/i.test(this.Agent.source)&&(this.Agent.isAndroidWebview=!0)},c.prototype.parse=function(a){try{console.warn("The `userAgentInstance.parse` method from instance is deprecated, use the static method instead: `UserAgent.parse`.")}catch(b){}return c.parse(a)},c.parse=function(a){var b=new c(a);return b.Agent},c.testNginxGeoIP=function(a){return new c(null,a)},a.UserAgent=c}(this); \ No newline at end of file diff --git a/package.json b/package.json index a2cc0e6..a899bf1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "express-useragent", "description": "ExpressJS/Connect/TrinteJS user-agent middleware exposing", - "version": "1.0.15", + "version": "1.0.16", "homepage": "https://github.com/biggora/express-useragent/", "repository": { "type": "git",