node-device-detector
Advanced tools
Comparing version 2.0.18 to 2.1.0
@@ -5,3 +5,3 @@ export default class ClientHints { | ||
parse(objHeaders: JSONObject): JSONObject; | ||
parse(hints: JSONObject, meta: JSONObject): JSONObject; | ||
} | ||
@@ -8,0 +8,0 @@ |
@@ -1,8 +0,6 @@ | ||
const header = require('./parser/helper'); | ||
const helper = require("./parser/helper"); | ||
const attr = header.getPropertyValue; | ||
const helper = require('./parser/helper'); | ||
const CH_UA_FULL_VERSION = 'sec-ch-ua-full-version'; | ||
const CH_UA_FULL_VERSION_LIST = 'sec-ch-ua-full-version-list'; | ||
const CH_UA_MOBILE = 'sec-ch-ua-mobile'; | ||
const CH_UA_MODEL = 'sec-ch-ua-model'; | ||
@@ -17,57 +15,61 @@ const CH_UA_PLATFORM_VERSION = 'sec-ch-ua-platform-version'; | ||
/* | ||
sec-ch-ua',ua, | ||
sec-ch-ua-platform, ua-platform', | ||
sec-ch-ua-mobile,ua-mobile | ||
sec-ch-ua-full-version',ua-full-version,sec-ch-ua-full-version-list | ||
sec-ch-ua-platform-version,ua-platform-version, | ||
sec-ch-ua-arch,ua-arch, | ||
sec-ch-ua-bitness,ua-bitness, | ||
sec-ch-ua-model,ua-model, | ||
sec-ch-lang,lang, | ||
sec-ch-save-data,save-data, | ||
sec-ch-width, width, | ||
sec-ch-viewport-width,viewport-width, | ||
sec-ch-viewport-height,viewport-height, | ||
sec-ch-dpr,dpr, | ||
sec-ch-device-memory,device-memory, | ||
sec-ch-rtt,rtt, | ||
sec-ch-downlink,downlink, | ||
sec-ch-ect,ect, | ||
sec-ch-prefers-color-scheme, | ||
sec-ch-prefers-reduced-motion, | ||
sec-ch-prefers-reduced-transparency, | ||
sec-ch-prefers-contrast,sec-ch-forced-colors, | ||
sec-ch-prefers-reduced-data]; | ||
All combinations | ||
[ | ||
'device-memory', | ||
'downlink', | ||
'dpr', | ||
'ect', | ||
'lang', | ||
'rtt', | ||
'save-data', | ||
'sec-ch-device-memory', | ||
'sec-ch-downlink', | ||
'sec-ch-dpr', | ||
'sec-ch-ect', | ||
'sec-ch-forced-colors', | ||
'sec-ch-lang', | ||
'sec-ch-prefers-color-scheme', | ||
'sec-ch-prefers-contrast', | ||
'sec-ch-prefers-reduced-data' | ||
'sec-ch-prefers-reduced-motion', | ||
'sec-ch-prefers-reduced-transparency', | ||
'sec-ch-rtt', | ||
'sec-ch-save-data', | ||
'sec-ch-ua', | ||
'sec-ch-ua-arch', | ||
'sec-ch-ua-bitness', | ||
'sec-ch-ua-full-version', | ||
'sec-ch-ua-full-version-list', | ||
'sec-ch-ua-mobile', | ||
'sec-ch-ua-model', | ||
'sec-ch-ua-platform', | ||
'sec-ch-ua-platform-version', | ||
'sec-ch-viewport-height', | ||
'sec-ch-viewport-width', | ||
'sec-ch-width', | ||
'ua', | ||
'ua-arch', | ||
'ua-bitness', | ||
'ua-full-version', | ||
'ua-mobile', | ||
'ua-model', | ||
'ua-platform', | ||
'ua-platform-version', | ||
'viewport-height', | ||
'viewport-width', | ||
'width', | ||
] | ||
*/ | ||
function getBrowserNames(headers) { | ||
let value = attr(headers, CH_UA_FULL_VERSION_LIST, attr(headers, CH_UA, '')); | ||
let pattern = new RegExp('"([^"]+)"; ?v="([^"]+)"(?:, )?', 'gi'); | ||
let items = []; | ||
let matches = null; | ||
while (matches = pattern.exec(value)) { | ||
let brand = matches[1]; | ||
let skip = brand.indexOf('Not;A') !== -1 | ||
|| brand.indexOf('Not A;') !== -1 | ||
if (skip) { | ||
continue | ||
} | ||
items.push({brand, version: helper.trimChars(matches[2], '"')}); | ||
} | ||
return items; | ||
} | ||
class ClientHints { | ||
/** | ||
* @returns {{"accept-ch": ""}} | ||
* @returns {{'accept-ch': ''}} | ||
* @example | ||
* ```js | ||
const hintHeaders = ClientHints.getHeaderClientHints(); | ||
for (let name in hintHeaders) { | ||
res.setHeader(name, hintHeaders[headerName]); | ||
} | ||
const hintHeaders = ClientHints.getHeaderClientHints(); | ||
for (let name in hintHeaders) { | ||
res.setHeader(name, hintHeaders[headerName]); | ||
} | ||
* ``` | ||
@@ -78,9 +80,10 @@ */ | ||
'accept-ch': [ | ||
'sec-ch-ua-full-version', | ||
'sec-ch-ua-full-version-list', 'sec-ch-ua-platform', | ||
'sec-ch-ua-platform-version', | ||
'sec-ch-ua-model', | ||
'sec-ch-ua-arch', | ||
'sec-ch-ua-bitness', | ||
'sec-ch-prefers-color-scheme', | ||
CH_UA_FULL_VERSION, | ||
CH_UA_FULL_VERSION_LIST, | ||
CH_UA_PLATFORM, | ||
CH_UA_PLATFORM_VERSION, | ||
CH_UA_MODEL, | ||
CH_UA_ARCH, | ||
CH_BITNESS, | ||
CH_UA_PREFERS_COLOR_SCHEME | ||
].join(', ') | ||
@@ -95,59 +98,160 @@ }; | ||
* ```js | ||
console.log('is support client hints', ClientHints.isSupport(res.headers)); | ||
console.log('is support client hints', ClientHints.isSupport(res.headers)); | ||
* js | ||
*/ | ||
static isSupport(headers) { | ||
return headers[CH_UA] !== void 0 | ||
|| headers[CH_UA.toLowerCase()] !== void 0 | ||
|| headers[CH_UA_FULL_VERSION_LIST.toLowerCase()] !== void 0; | ||
return headers[CH_UA] !== void 0 || headers[CH_UA.toLowerCase()] !== void 0 || headers[CH_UA_FULL_VERSION_LIST.toLowerCase()] !== void 0; | ||
} | ||
/** | ||
* @param objHeaders | ||
* @param {{}} hints | ||
* @param {{}} result | ||
* @private | ||
*/ | ||
parse(objHeaders) { | ||
let headers = {}; | ||
for( let key in objHeaders) { | ||
headers[key.toLowerCase()] = objHeaders[key]; | ||
__parseHints(hints, result) { | ||
for (let key in hints) { | ||
let value = hints[key]; | ||
let lowerCaseKey = key.toLowerCase().replace('_', '-'); | ||
switch (lowerCaseKey) { | ||
case 'http-sec-ch-ua-arch': | ||
case 'sec-ch-ua-arch': | ||
case 'arch': | ||
case 'architecture': | ||
result.os.platform = helper.trimChars(value, '"'); | ||
break; | ||
case 'http-sec-ch-ua-bitness': | ||
case 'sec-ch-ua-bitness': | ||
case 'bitness': | ||
result.os.bitness = helper.trimChars(value, '"'); | ||
break; | ||
case 'http-sec-ch-ua-mobile': | ||
case 'sec-ch-ua-mobile': | ||
case 'mobile': | ||
result.isMobile = true === value || '1' === value || '?1' === value; | ||
break; | ||
case 'http-sec-ch-ua-model': | ||
case 'sec-ch-ua-model': | ||
case 'model': | ||
result.device.model = helper.trimChars(value, '"'); | ||
break; | ||
case 'http-sec-ch-ua-full-version': | ||
case 'sec-ch-ua-full-version': | ||
case 'uafullversion': | ||
result.upgradeHeader = true; | ||
result.client.version = helper.trimChars(value, '"'); | ||
break; | ||
case 'http-sec-ch-ua-platform': | ||
case 'sec-ch-ua-platform': | ||
case 'platform': | ||
result.os.name = helper.trimChars(value, '"'); | ||
break; | ||
case 'http-sec-ch-ua-platform-version': | ||
case 'sec-ch-ua-platform-version': | ||
case 'platformversion': | ||
result.os.version = helper.trimChars(value, '"'); | ||
break; | ||
case 'brands': | ||
if (result.client.brands.length > 0) { | ||
break; | ||
} | ||
// eslint-disable-next-line no-fallthrough | ||
case 'fullversionlist': | ||
if (Array.isArray(value)) { | ||
result.client.brands = value; | ||
} | ||
break; | ||
case 'http-sec-ch-ua': | ||
case 'sec-ch-ua': | ||
if (result.client.brands.length > 0) { | ||
break; | ||
} | ||
// eslint-disable-next-line no-fallthrough | ||
case 'http-sec-ch-ua-full-version-list': | ||
case 'sec-ch-ua-full-version-list': | ||
let pattern = new RegExp('"([^"]+)"; ?v="([^"]+)"(?:, )?', 'gi'); | ||
let items = []; | ||
let matches = null; | ||
while (matches = pattern.exec(value)) { | ||
let brand = matches[1]; | ||
let skip = brand.indexOf('Not;A') !== -1 || brand.indexOf('Not A;') !== -1 || brand.indexOf('Not.A') !== -1; | ||
if (skip) { | ||
continue; | ||
} | ||
items.push({ brand, version: helper.trimChars(matches[2], '"') }); | ||
} | ||
if (items.length > 0) { | ||
result.client.brands = items; | ||
} | ||
break; | ||
case 'x-requested-with': | ||
case 'http-x-requested-with': | ||
result.app = value; | ||
if (value.toLowerCase() === 'xmlhttprequest') { | ||
result.app = ''; | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
let result = {}; | ||
result.upgradeHeader = headers[CH_UA_FULL_VERSION] !== void 0; | ||
/** | ||
* @param {{}} meta | ||
* @param {{}} result | ||
* @private | ||
*/ | ||
__parseMeta(meta, result) { | ||
for (let key in meta) { | ||
let value = meta[key]; | ||
let lowerCaseKey = key.toLowerCase(); | ||
result.isMobile = attr(headers, CH_UA_MOBILE, '') === '?1'; | ||
result.prefers = { | ||
colorScheme: helper.trimChars(attr(headers, CH_UA_PREFERS_COLOR_SCHEME, ''), '"') | ||
if (value === void 0) { | ||
continue; | ||
} | ||
switch (lowerCaseKey) { | ||
case 'width': | ||
case 'height': | ||
result.meta[key] = String(parseInt(value)); | ||
break; | ||
case 'gpu': | ||
case 'gamut': | ||
case 'ram': | ||
result.meta[key] = value; | ||
break; | ||
case 'colordepth': | ||
result.meta.colorDepth = value; | ||
break; | ||
case 'cores': | ||
result.meta.cpuCores = value; | ||
break; | ||
} | ||
} | ||
let osName = attr(headers, CH_UA_PLATFORM, ''); | ||
let platform = attr(headers, CH_UA_ARCH, ''); | ||
let bitness = attr(headers, CH_BITNESS, ''); | ||
let osVersion = attr(headers, CH_UA_PLATFORM_VERSION, ''); | ||
// os | ||
result.os = { | ||
name: helper.trimChars(osName, '"'), | ||
platform: helper.trimChars(platform.toLowerCase(), '"'), | ||
bitness: helper.trimChars(bitness, '"'), | ||
version: helper.trimChars(osVersion, '"') | ||
}; | ||
} | ||
// client | ||
let clientData = getBrowserNames(headers); | ||
result.client = { | ||
brands: clientData, | ||
version: helper.trimChars(attr(headers, CH_UA_FULL_VERSION, ''), '"'), | ||
/** | ||
* @param {{}} hints - headers or client-hints params | ||
* @param {{}} meta - client custom js metric params | ||
*/ | ||
parse(hints, meta = {}) { | ||
let result = { | ||
upgradeHeader: false, | ||
isMobile: false, | ||
meta: { | ||
width: '', | ||
height: '', | ||
gpu: '', | ||
gamut: '', | ||
ram: '', | ||
colorDepth: '', | ||
cpuCores: '' | ||
}, | ||
prefers: { colorScheme: '' }, | ||
os: { name: '', platform: '', bitness: '', version: '' }, | ||
client: { brands: [], version: '' }, | ||
device: { model: '' } | ||
}; | ||
result.device = { | ||
model: helper.trimChars(attr(headers, CH_UA_MODEL, ''), '"') | ||
} | ||
this.__parseHints(hints, result); | ||
this.__parseMeta(meta, result); | ||
let xRequested = attr(headers, 'x-requested-with', | ||
attr(headers, 'http-x-requested-with', '') | ||
); | ||
result.app = helper.trimChars(xRequested, '"') | ||
if (result.app.toLowerCase() === 'xmlhttprequest') { | ||
result.app = ''; | ||
} | ||
return result; | ||
@@ -154,0 +258,0 @@ } |
@@ -35,2 +35,8 @@ export default class DeviceDetector { | ||
set deviceTrusted(arg: boolean); | ||
get deviceTrusted(): boolean; | ||
set deviceInfo(arg: boolean); | ||
get deviceInfo(): boolean; | ||
/** | ||
@@ -165,2 +171,4 @@ * @param {boolean} arg - true use indexes, false not use indexes | ||
deviceAliasCode?: boolean; | ||
deviceTrusted?: boolean; | ||
deviceInfo?: boolean; | ||
} | ||
@@ -207,2 +215,4 @@ | ||
code?: string; | ||
trusted?: boolean|null; | ||
info?: ResultDeviceInfo|null | ||
} | ||
@@ -221,1 +231,56 @@ | ||
} | ||
export interface ResultDeviceInfoDisplay { | ||
size: string; | ||
resolution?: string|ResultDeviceInfoResolution; | ||
ratio?: string; | ||
ppi?: string; | ||
} | ||
export interface ResultDeviceInfoResolution { | ||
width: string; | ||
height: string; | ||
} | ||
export interface ResultDeviceInfoPerformance { | ||
antutu?: number; | ||
geekbench?: number; | ||
} | ||
export interface ResultDeviceInfoHardwareGPU { | ||
name: string; | ||
clock_rate?: number; | ||
} | ||
export interface ResultDeviceInfoHardware { | ||
ram: number | ||
cpu_id?: number | ||
cpu?: ResultDeviceInfoHardwareCPU | ||
gpu?: ResultDeviceInfoHardwareGPU | ||
} | ||
export interface ResultDeviceInfoSize { | ||
width: string; | ||
height: string; | ||
thickness: string; | ||
} | ||
export interface ResultDeviceInfoHardwareCPU { | ||
name: string; | ||
type: string; | ||
cores?: number; | ||
clock_rate?: number; | ||
process?: string; | ||
gpu_id?: number; | ||
} | ||
export interface ResultDeviceInfo { | ||
display?: ResultDeviceInfoDisplay; | ||
sim?: number|null; | ||
size?: string|ResultDeviceInfoSize|null; | ||
weight?: string|null; | ||
release?: string|null; | ||
os?: string|null; | ||
hardware?: ResultDeviceInfoHardware|null; | ||
performance?: ResultDeviceInfoPerformance|null; | ||
} |
329
index.js
@@ -32,3 +32,5 @@ const helper = require('./parser/helper'); | ||
const IndexerDevice = require('./parser/device/indexer-device'); | ||
const InfoDevice = require('./parser/device/info-device'); | ||
// checks | ||
const DeviceTrusted = require('./parser/device/device-trusted'); | ||
// const, lists, parser names | ||
@@ -47,5 +49,9 @@ const DEVICE_TYPE = require('./parser/const/device-type'); | ||
// =========================== | ||
// static private parser init | ||
// =========================== | ||
const aliasDevice = new AliasDevice(); | ||
aliasDevice.setReplaceBrand(false); | ||
const infoDevice = new InfoDevice(); | ||
@@ -61,5 +67,8 @@ IndexerDevice.init(); | ||
* @param {number|null} clientVersionTruncate | ||
* @param {number|null} maxUserAgentSize | ||
* @param {boolean} deviceIndexes | ||
* @param {boolean} clientIndexes | ||
* @param {boolean} deviceAliasCode | ||
* @param {boolean} deviceInfo | ||
* @param {boolean} deviceTrusted | ||
*/ | ||
@@ -81,2 +90,4 @@ | ||
this.__deviceAliasCode = false; | ||
this.__deviceTrusted = false; | ||
this.__deviceInfo = false; | ||
this.__clientVersionTruncate = null; | ||
@@ -95,10 +106,13 @@ this.__osVersionTruncate = null; | ||
this.maxUserAgentSize = attr(options, 'maxUserAgentSize', null); | ||
this.deviceTrusted = attr(options, 'deviceTrusted', false); | ||
this.deviceInfo = attr(options, 'deviceInfo', false); | ||
} | ||
init() { | ||
this.addParseOs(OS_PARSER, new OsParser()); | ||
this.addParseClient(CLIENT_PARSER_LIST.FEED_READER, new FeedReaderParser()); | ||
this.addParseClient(CLIENT_PARSER_LIST.MOBILE_APP, new MobileAppParser()); | ||
this.addParseClient(CLIENT_PARSER_LIST.MEDIA_PLAYER, | ||
new MediaPlayerParser()); | ||
this.addParseClient(CLIENT_PARSER_LIST.MEDIA_PLAYER, new MediaPlayerParser()); | ||
this.addParseClient(CLIENT_PARSER_LIST.PIM, new PIMParser()); | ||
@@ -114,6 +128,3 @@ this.addParseClient(CLIENT_PARSER_LIST.BROWSER, new BrowserParser()); | ||
this.addParseDevice(DEVICE_PARSER_LIST.CAMERA, new CameraParser()); | ||
this.addParseDevice( | ||
DEVICE_PARSER_LIST.PORTABLE_MEDIA_PLAYER, | ||
new PortableMediaPlayerParser(), | ||
); | ||
this.addParseDevice(DEVICE_PARSER_LIST.PORTABLE_MEDIA_PLAYER, new PortableMediaPlayerParser()); | ||
this.addParseDevice(DEVICE_PARSER_LIST.MOBILE, new MobileParser()); | ||
@@ -126,2 +137,18 @@ | ||
set deviceTrusted(check) { | ||
this.__deviceTrusted = check; | ||
} | ||
get deviceTrusted() { | ||
return this.__deviceTrusted; | ||
} | ||
set deviceInfo(stage) { | ||
this.__deviceInfo = stage; | ||
} | ||
get deviceInfo() { | ||
return this.__deviceInfo; | ||
} | ||
/** | ||
@@ -313,2 +340,10 @@ * Set string size limit for the useragent | ||
/** | ||
* get bot parser by name | ||
* @param name | ||
* @return {*} | ||
*/ | ||
getParseBot(name) { | ||
return this.botParserList[name] ? this.botParserList[name] : null; | ||
} | ||
/** | ||
* get os parser by name | ||
@@ -340,2 +375,30 @@ * @param name | ||
/** | ||
* get info device parser | ||
* @returns {InfoDevice} | ||
*/ | ||
getParseInfoDevice() { | ||
return infoDevice; | ||
} | ||
getDeviceParserNames() { | ||
return DEVICE_PARSER_LIST; | ||
} | ||
getClientParserNames() { | ||
return CLIENT_PARSER_LIST; | ||
} | ||
getBotParserNames() { | ||
return { | ||
'DEFAULT': BOT_PARSER | ||
}; | ||
} | ||
getOsParserNames() { | ||
return { | ||
'DEFAULT': OS_PARSER | ||
}; | ||
} | ||
/** | ||
* add device type parser | ||
@@ -345,3 +408,2 @@ * @param {string} name | ||
*/ | ||
addParseDevice(name, parser) { | ||
@@ -413,3 +475,3 @@ this.deviceParserList[name] = parser; | ||
if (userAgent && this.maxUserAgentSize && this.maxUserAgentSize < userAgent.length) { | ||
return String(userAgent.substr(0, this.maxUserAgentSize)); | ||
return String(userAgent).substring(0, this.maxUserAgentSize); | ||
} | ||
@@ -433,3 +495,3 @@ return userAgent; | ||
deviceData, | ||
clientHints, | ||
clientHints | ||
) { | ||
@@ -450,15 +512,20 @@ | ||
if ( | ||
deviceType === '' && | ||
osFamily === 'Android' && | ||
helper.matchUserAgent('Chrome/[.0-9]*', userAgent) | ||
) { | ||
if ( | ||
helper.matchUserAgent('(Mobile|eliboM) Safari/', userAgent) !== | ||
null | ||
) { | ||
/** | ||
* All devices containing VR fragment are assumed to be a wearable | ||
*/ | ||
if (deviceType === '' && helper.hasVRFragment(userAgent)) { | ||
deviceType = DEVICE_TYPE.WEARABLE; | ||
} | ||
/** | ||
* Chrome on Android passes the device type based on the keyword 'Mobile' | ||
* If it is present the device should be a smartphone, otherwise it's a tablet | ||
* See https://developer.chrome.com/multidevice/user-agent#chrome_for_android_user_agent | ||
* Note: We do not check for browser (family) here, as there might be mobile apps using Chrome, that won't have | ||
* a detected browser, but can still be detected. So we check the useragent for Chrome instead. | ||
*/ | ||
if (deviceType === '' && osFamily === 'Android' && helper.matchUserAgent('Chrome/[.0-9]*', userAgent)) { | ||
if (helper.matchUserAgent('(Mobile|eliboM)', userAgent) !== null) { | ||
deviceType = DEVICE_TYPE.SMARTPHONE; | ||
} else if ( | ||
helper.matchUserAgent('(?!Mobile )Safari/', userAgent) !== null | ||
) { | ||
} else{ | ||
deviceType = DEVICE_TYPE.TABLET; | ||
@@ -471,16 +538,16 @@ } | ||
*/ | ||
if (deviceType === DEVICE_TYPE.SMARTPHONE | ||
&& helper.matchUserAgent('Pad/APad', userAgent) | ||
) { | ||
if (deviceType === DEVICE_TYPE.SMARTPHONE && helper.matchUserAgent('Pad/APad', userAgent)) { | ||
deviceType = DEVICE_TYPE.TABLET; | ||
} | ||
if ( | ||
deviceType === '' && | ||
(helper.hasAndroidTableFragment(userAgent) || | ||
helper.hasOperaTableFragment(userAgent)) | ||
) { | ||
/** | ||
* Some UA contain the fragment 'Android; Tablet;' or 'Opera Tablet', so we assume those devices as tablets | ||
*/ | ||
if (deviceType === '' && (helper.hasAndroidTableFragment(userAgent) || helper.hasOperaTableFragment(userAgent))) { | ||
deviceType = DEVICE_TYPE.TABLET; | ||
} | ||
/** | ||
* Some user agents simply contain the fragment 'Android; Mobile;', so we assume those devices as smartphones | ||
*/ | ||
if (deviceType === '' && helper.hasAndroidMobileFragment(userAgent)) { | ||
@@ -490,2 +557,10 @@ deviceType = DEVICE_TYPE.SMARTPHONE; | ||
/** | ||
* Android up to 3.0 was designed for smartphones only. But as 3.0, which was tablet only, was published | ||
* too late, there were a bunch of tablets running with 2.x | ||
* With 4.0 the two trees were merged and it is for smartphones and tablets | ||
* | ||
* So were are expecting that all devices running Android < 2 are smartphones | ||
* Devices running Android 3.X are tablets. Device type of Android 2.X and 4.X+ are unknown | ||
*/ | ||
if (deviceType === '' && osName === 'Android' && osVersion !== '') { | ||
@@ -502,2 +577,5 @@ if (helper.versionCompare(osVersion, '2.0') === -1) { | ||
/** | ||
* All detected feature phones running android are more likely a smartphone | ||
*/ | ||
if (deviceType === DEVICE_TYPE.FEATURE_PHONE && osFamily === 'Android') { | ||
@@ -515,2 +593,11 @@ deviceType = DEVICE_TYPE.SMARTPHONE; | ||
/** | ||
* According to http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx | ||
* Internet Explorer 10 introduces the "Touch" UA string token. If this token is present at the end of the | ||
* UA string, the computer has touch capability, and is running Windows 8 (or later). | ||
* This UA string will be transmitted on a touch-enabled system running Windows 8 (RT) | ||
* | ||
* As most touch enabled devices are tablets and only a smaller part are desktops/notebooks we assume that | ||
* all Windows 8 touch devices are tablets. | ||
*/ | ||
if ( | ||
@@ -525,10 +612,24 @@ deviceType === '' && | ||
// check tv fragments and tv clients | ||
/** | ||
* All devices running Opera TV Store are assumed to be a tv | ||
*/ | ||
if (helper.hasOperaTVStoreFragment(userAgent)) { | ||
deviceType = DEVICE_TYPE.TV; | ||
} else if (helper.hasAndroidTVFragment(userAgent)) { | ||
} | ||
/** | ||
* All devices that contain Andr0id in string are assumed to be a tv | ||
*/ | ||
if (helper.hasAndroidTVFragment(userAgent)) { | ||
deviceType = DEVICE_TYPE.TV; | ||
} else if (deviceType === '' && helper.hasTVFragment(userAgent)) { | ||
} | ||
/** | ||
* All devices running Tizen TV or SmartTV are assumed to be a tv | ||
*/ | ||
if (deviceType === '' && helper.hasTVFragment(userAgent)) { | ||
deviceType = DEVICE_TYPE.TV; | ||
} else if (CLIENT_TV_LIST.indexOf(clientName) !== -1) { | ||
} | ||
/** | ||
* Devices running those clients are assumed to be a TV | ||
*/ | ||
if (CLIENT_TV_LIST.indexOf(clientName) !== -1) { | ||
deviceType = DEVICE_TYPE.TV; | ||
@@ -563,3 +664,3 @@ } | ||
return { | ||
type: deviceType, | ||
type: deviceType | ||
}; | ||
@@ -592,7 +693,7 @@ } | ||
* @param {string} userAgent | ||
* @param {{os:{version:""}, device: {model:""}}} clientHints | ||
* @param {{os:{version:''}, device: {model:''}}} clientHints | ||
*/ | ||
restoreUserAgentForClientHints( | ||
userAgent, | ||
clientHints, | ||
userAgent, | ||
clientHints | ||
) { | ||
@@ -607,5 +708,6 @@ if (!clientHints || !clientHints.device) { | ||
return userAgent.replace(/(Android 10[.\d]*; K)/, | ||
`Android ${osVersion !== '' ? osVersion : '10'} ${deviceModel};`, | ||
`Android ${osVersion !== '' ? osVersion: '10'}; ${deviceModel}` | ||
); | ||
} | ||
return userAgent; | ||
@@ -618,19 +720,10 @@ } | ||
* @param {string} userAgent | ||
* @param clientHints | ||
* @param {Object} clientHints | ||
* @return {ResultDevice} | ||
*/ | ||
parseDevice(userAgent, clientHints) { | ||
let ua = this.restoreUserAgentForClientHints(userAgent, clientHints) | ||
let ua = this.restoreUserAgentForClientHints(userAgent, clientHints); | ||
let brandIndexes = []; | ||
let deviceCode = ''; | ||
if (this.deviceIndexes) { | ||
let alias = this.parseDeviceCode(ua); | ||
deviceCode = alias.name ? alias.name : ''; | ||
brandIndexes = this.getBrandsByDeviceCode(deviceCode); | ||
} else if (this.deviceAliasCode) { | ||
let alias = this.parseDeviceCode(ua); | ||
deviceCode = alias.name ? alias.name : ''; | ||
} | ||
let result = { | ||
@@ -641,14 +734,28 @@ id: '', | ||
model: '', | ||
code: '', | ||
info: {}, | ||
trusted: null | ||
}; | ||
if (this.deviceAliasCode) { | ||
result.code = deviceCode; | ||
if (this.deviceIndexes || this.deviceAliasCode || this.deviceInfo || this.deviceTrusted) { | ||
if (clientHints.device && clientHints.device.model) { | ||
result.code = clientHints.device.model; | ||
} else { | ||
const alias = this.parseDeviceCode(ua); | ||
result.code = alias.name ? alias.name : ''; | ||
} | ||
} | ||
for (let name in this.deviceParserList) { | ||
let parser = this.deviceParserList[name]; | ||
let resultMerge = parser.parse(ua, brandIndexes); | ||
if (resultMerge) { | ||
result = Object.assign({}, result, resultMerge); | ||
break; | ||
if (this.deviceIndexes) { | ||
brandIndexes = this.getBrandsByDeviceCode(result.code); | ||
} | ||
if (result && result.brand === '') { | ||
for (let name in this.deviceParserList) { | ||
let parser = this.deviceParserList[name]; | ||
let resultMerge = parser.parse(ua, brandIndexes); | ||
if (resultMerge) { | ||
result = Object.assign({}, result, resultMerge); | ||
break; | ||
} | ||
} | ||
@@ -666,8 +773,13 @@ } | ||
// client hints | ||
if (result.model === '') { | ||
if (clientHints.device && clientHints.device.model !== '') { | ||
result.model = clientHints.device.model; | ||
} | ||
if (result.model === '' && clientHints.device && clientHints.device.model !== '') { | ||
result.model = clientHints.device.model; | ||
} | ||
// device info or deviceTrusted | ||
if (this.deviceInfo || this.deviceTrusted) { | ||
result.info = this.getParseInfoDevice().info( | ||
result.brand, result.code ? result.code : result.model | ||
); | ||
} | ||
return result; | ||
@@ -689,3 +801,3 @@ } | ||
* @param {string} userAgent | ||
* @param clientHints | ||
* @param {Object} clientHints | ||
* @return {ResultBot} | ||
@@ -719,6 +831,5 @@ */ | ||
const extendParsers = [CLIENT_PARSER_LIST.MOBILE_APP, CLIENT_PARSER_LIST.BROWSER]; | ||
let result = {}; | ||
for (let name in this.clientParserList) { | ||
let parser = this.clientParserList[name]; | ||
if (this.clientIndexes && extendParsers.includes(name)) { | ||
@@ -730,29 +841,12 @@ let hash = parser.parseFromHashHintsApp(clientHints); | ||
if (result !== null && result.name) { | ||
return result; | ||
return Object.assign({}, result); | ||
} | ||
continue; | ||
} | ||
let resultMerge = parser.parse(userAgent, clientHints); | ||
if (resultMerge) { | ||
return Object.assign(result, resultMerge); | ||
let result = parser.parse(userAgent, clientHints); | ||
if (result && result.name) { | ||
return Object.assign({}, result); | ||
} | ||
} | ||
if (this.clientIndexes) { | ||
for(let i=0, l = extendParsers.length; i <l; i++) { | ||
let name = extendParsers[i]; | ||
let parser = this.clientParserList[name]; | ||
if (!parser) { | ||
continue; | ||
} | ||
let resultMerge = parser.parse(userAgent, clientHints); | ||
if (resultMerge) { | ||
return Object.assign(result, resultMerge); | ||
} | ||
} | ||
} | ||
return result; | ||
return {}; | ||
} | ||
@@ -765,17 +859,9 @@ | ||
deviceData, | ||
clientHints, | ||
clientHints | ||
) { | ||
let deviceDataType = this.parseDeviceType( | ||
userAgent, | ||
osData, | ||
clientData, | ||
deviceData, | ||
clientHints, | ||
); | ||
deviceData = Object.assign(deviceData, deviceDataType); | ||
/** | ||
* if it's fake UA then it's best not to identify it as Apple running Android OS | ||
* if it's fake UA then it's best not to identify it as Apple running Android OS or GNU/Linux | ||
*/ | ||
if ('Android' === osData.name && 'Apple' === deviceData.brand) { | ||
if (deviceData.brand === 'Apple' && APPLE_OS_LIST.indexOf(osData.name) === -1) { | ||
deviceData.id = ''; | ||
@@ -786,16 +872,39 @@ deviceData.brand = ''; | ||
} | ||
/** Assume all devices running iOS / Mac OS are from Apple */ | ||
if ( | ||
deviceData.brand === '' && | ||
osData.name !== '' && | ||
APPLE_OS_LIST.indexOf(osData.name) !== -1 | ||
) { | ||
deviceData.id = 'AP'; | ||
/** | ||
* Assume all devices running iOS / Mac OS are from Apple | ||
*/ | ||
if (deviceData.brand === '' && APPLE_OS_LIST.indexOf(osData.name) !== -1) { | ||
deviceData.brand = 'Apple'; | ||
} | ||
let deviceDataType = this.parseDeviceType( | ||
userAgent, | ||
osData, | ||
clientData, | ||
deviceData, | ||
clientHints | ||
); | ||
deviceData = Object.assign(deviceData, deviceDataType); | ||
if (this.deviceTrusted) { | ||
deviceData.trusted = DeviceTrusted.check(osData, clientData, deviceData, clientHints); | ||
} else { | ||
delete deviceData.trusted; | ||
} | ||
if (!this.deviceAliasCode) { | ||
delete deviceData.code; | ||
} | ||
if (!this.deviceInfo) { | ||
delete deviceData.info; | ||
} | ||
return { | ||
os: osData, | ||
client: clientData, | ||
device: deviceData, | ||
device: deviceData | ||
}; | ||
@@ -823,3 +932,3 @@ } | ||
let [deviceData, osData, clientData] = await Promise.all([ | ||
devicePromise, osPromise, clientPromise, | ||
devicePromise, osPromise, clientPromise | ||
]); | ||
@@ -833,3 +942,3 @@ | ||
clientHints | ||
) | ||
); | ||
} | ||
@@ -840,3 +949,3 @@ | ||
* @param {string} userAgent - string from request header['user-agent'] | ||
* @param clientHints | ||
* @param {{}} clientHints | ||
* @return {DetectResult} | ||
@@ -856,3 +965,3 @@ */ | ||
clientHints | ||
) | ||
); | ||
} | ||
@@ -859,0 +968,0 @@ } |
{ | ||
"name": "node-device-detector", | ||
"version": "2.0.18", | ||
"version": "2.1.0", | ||
"description": "Nodejs device detector (port matomo-org/device-detector)", | ||
@@ -27,3 +27,5 @@ "main": "index.js", | ||
"detect device model", | ||
"detect user-agent" | ||
"detect user-agent", | ||
"detect trusted device", | ||
"client-hints" | ||
], | ||
@@ -44,2 +46,3 @@ "author": "sanchezzzhak", | ||
"devDependencies": { | ||
"@fast-csv/parse": "^5.0.0", | ||
"@typescript-eslint/eslint-plugin": "^5.42.1", | ||
@@ -50,5 +53,5 @@ "@typescript-eslint/parser": "^5.42.1", | ||
"cli-table": "^0.3.6", | ||
"commander": "^11.1.0", | ||
"eslint": "^8.27.0", | ||
"mocha": "^9.1.3", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.4.1", | ||
@@ -55,0 +58,0 @@ "typescript": "^4.8.4" |
@@ -23,6 +23,7 @@ const helper = require('./helper'); | ||
const collectionMap = {}; | ||
class ParserAbstract { | ||
constructor() { | ||
this.fixtureFile = null; | ||
this.collection = null; | ||
this.type = null; | ||
@@ -33,2 +34,13 @@ this.versionTruncation = null; | ||
get collection() { | ||
if (!this.hasLoadCollection()) { | ||
return null; | ||
} | ||
return collectionMap[this.fixtureFile]; | ||
} | ||
hasLoadCollection() { | ||
return collectionMap[this.fixtureFile] !== void 0 | ||
} | ||
/** | ||
@@ -38,3 +50,5 @@ * load collection | ||
loadCollection() { | ||
this.collection = this.loadYMLFile(this.fixtureFile); | ||
if (!this.hasLoadCollection()) { | ||
collectionMap[this.fixtureFile] = this.loadYMLFile(this.fixtureFile); | ||
} | ||
} | ||
@@ -60,13 +74,3 @@ | ||
item = item.toString(); | ||
let max = matches.length-1 || 1; | ||
if (item.indexOf('$') !== -1) { | ||
for (let nb = 1; nb <= max; nb++) { | ||
if (item.indexOf('$' + nb) === -1) { | ||
continue; | ||
} | ||
let replace = matches[nb] !== void 0 ? matches[nb] : ''; | ||
item = item.replace(new RegExp('\\$' + nb, 'g'), replace); | ||
} | ||
} | ||
return item; | ||
return helper.matchReplace(item, matches) | ||
} | ||
@@ -73,0 +77,0 @@ |
@@ -32,3 +32,6 @@ // prettier-ignore | ||
'1W', 'EV', 'I9', 'V4', 'H4', '1T', 'M5', '0S', '0C', | ||
'ZR', 'D6', 'F6', | ||
'ZR', 'D6', 'F6', 'RC', 'WD', 'P3', 'FT', 'A9', 'X2', | ||
'N3', 'GD', 'O9', 'Q3', 'F7', 'K2', 'P5', 'H5', 'V3', | ||
'K3', 'Q4', 'G2', 'R2', 'WX', 'XP', '3I', 'BG', 'R0', | ||
'JO', 'OL', 'GN', 'W4', 'QI', 'E1', 'RI', '8B', '5B', | ||
], | ||
@@ -39,6 +42,7 @@ 'Firefox': [ | ||
'IW', 'LH', 'LY', 'MB', 'MN', 'MO', 'MY', 'OA', 'OS', | ||
'PI', 'PX', 'QA', 'QM', 'S5', 'SX', 'TF', 'TO', 'WF', | ||
'ZV', 'FP', 'AD', 'WL', | ||
'PI', 'PX', 'QA', 'S5', 'SX', 'TF', 'TO', 'WF', 'ZV', | ||
'FP', 'AD', 'WL', '2I', 'P9', 'KJ', 'WY', 'VK', 'W5', | ||
'7C', | ||
], | ||
'Internet Explorer': ['BZ', 'CZ', 'IE', 'IM', 'PS'], | ||
'Internet Explorer': ['BZ', 'CZ', 'IE', 'IM', 'PS', '3A', '4A', 'RN'], | ||
'Konqueror': ['KO'], | ||
@@ -45,0 +49,0 @@ 'NetFront': ['NF'], |
@@ -18,4 +18,7 @@ // prettier-ignore | ||
'1W', 'EV', 'Z0', 'I9', 'V4', 'H4', 'M5', '0S', '0C', | ||
'ZR', 'D6', 'F6', | ||
'ZR', 'D6', 'F6', 'P3', 'FT', 'A9', 'X2', 'NI', 'FG', | ||
'TH', 'N3', 'GD', 'O9', 'Q3', 'F7', 'K2', 'N4', 'P5', | ||
'H5', 'V3', 'G2', 'BG', 'OL', 'II', 'TL', 'M6', 'Y3', | ||
'M7', 'GN', | ||
]; |
@@ -31,3 +31,3 @@ // prettier-ignore | ||
'2B': '2345 Browser', | ||
'3B': '360 Browser', | ||
'3B': '360 Secure Browser', | ||
'36': '360 Phone Browser', | ||
@@ -37,4 +37,6 @@ '7B': '7654 Browser', | ||
'AB': 'ABrowse', | ||
'4A': 'Acoo Browser', | ||
'BW': 'AdBlock Browser', | ||
'A7': 'Adult Browser', | ||
'A9': 'Airfind Secure Browser', | ||
'AF': 'ANT Fresco', | ||
@@ -50,5 +52,7 @@ 'AG': 'ANTGalio', | ||
'AN': 'Android Browser', | ||
'3A': 'AOL Explorer', | ||
'AE': 'AOL Desktop', | ||
'AD': 'AOL Shield', | ||
'A4': 'AOL Shield Pro', | ||
'2A': 'Aplix', | ||
'A6': 'AppBrowzer', | ||
@@ -61,2 +65,3 @@ 'AP': 'APUS Browser', | ||
'PN': 'APN Browser', | ||
'RA': 'Arc', | ||
'AI': 'Arvin', | ||
@@ -72,5 +77,8 @@ 'AK': 'Ask.com', | ||
'A1': 'AwoX', | ||
'5B': 'Basic Web Browser', | ||
'BA': 'Beaker Browser', | ||
'BM': 'Beamrise', | ||
'F7': 'BF Browser', | ||
'BB': 'BlackBerry Browser', | ||
'6B': 'Bluefy', | ||
'H1': 'BrowseHere', | ||
@@ -80,2 +88,3 @@ 'B8': 'Browser Hup Pro', | ||
'BS': 'Baidu Spark', | ||
'BG': 'Bang', | ||
'B9': 'Bangla Browser', | ||
@@ -98,2 +107,3 @@ 'BI': 'Basilisk', | ||
'BK': 'BriskBard', | ||
'K2': 'BroKeep Browser', | ||
'B3': 'Browspeed Browser', | ||
@@ -106,4 +116,6 @@ 'BX': 'BrowseX', | ||
'BF': 'Byffox', | ||
'B4': 'BF Browser', | ||
'B4': 'BXE Browser', | ||
'CA': 'Camino', | ||
'5C': 'Catalyst', | ||
'XP': 'Catsxp', | ||
'0C': 'Cave Browser', | ||
@@ -116,5 +128,7 @@ 'CL': 'CCleaner', | ||
'C0': 'Centaury', | ||
'CQ': 'Cliqz', | ||
'CC': 'Coc Coc', | ||
'C4': 'CoolBrowser', | ||
'C2': 'Colibri', | ||
'6C': 'Columbus Browser', | ||
'CD': 'Comodo Dragon', | ||
@@ -132,3 +146,5 @@ 'C1': 'Coast', | ||
'3C': 'Chowbo', | ||
'7C': 'Classilla', | ||
'CN': 'CoolNovo', | ||
'4C': 'Colom Browser', | ||
'CO': 'CometBird', | ||
@@ -144,2 +160,3 @@ '2C': 'Comfort Browser', | ||
'CS': 'Cheshire', | ||
'RC': 'Crow Browser', | ||
'CT': 'Crusta', | ||
@@ -161,2 +178,4 @@ 'CG': 'Craving Explorer', | ||
'DS': 'DeskBrowse', | ||
'II': 'Diigo Browser', | ||
'D2': 'DoCoMo', | ||
'DF': 'Dolphin', | ||
@@ -170,2 +189,3 @@ 'DZ': 'Dolphin Zero', | ||
'DD': 'DuckDuckGo Privacy Browser', | ||
'E1': 'East Browser', | ||
'EC': 'Ecosia', | ||
@@ -179,4 +199,6 @@ 'EW': 'Edge WebView', | ||
'EE': 'Elements Browser', | ||
'EO': 'Eolie', | ||
'EX': 'Explore Browser', | ||
'EZ': 'eZ Browser', | ||
'E2': 'EudoraWeb', | ||
'EU': 'EUI Browser', | ||
@@ -186,2 +208,3 @@ 'EP': 'GNOME Web', | ||
'ES': 'Espial TV Browser', | ||
'FG': 'fGet', | ||
'FA': 'Falkon', | ||
@@ -212,2 +235,3 @@ 'FX': 'Faux Browser', | ||
'F6': 'Freedom Browser', | ||
'FT': 'Frost', | ||
'F3': 'Frost+', | ||
@@ -220,2 +244,3 @@ 'FI': 'Fulldive', | ||
'GB': 'Glass Browser', | ||
'GD': 'Godzilla Browser', | ||
'GE': 'Google Earth', | ||
@@ -225,2 +250,5 @@ 'GP': 'Google Earth Pro', | ||
'GR': 'GoBrowser', | ||
'GK': 'GoKu', | ||
'G2': 'GO Browser', | ||
'RN': 'GreenBrowser', | ||
'HB': 'Harman Browser', | ||
@@ -235,2 +263,3 @@ 'HS': 'HasBrowser', | ||
'H4': 'Holla Web Browser', | ||
'H5': 'HotBrowser', | ||
'HJ': 'HotJava', | ||
@@ -254,2 +283,4 @@ 'HT': 'HTC Browser', | ||
'IW': 'Iceweasel', | ||
'2I': 'Impervious Browser', | ||
'N3': 'Incognito Browser', | ||
'IN': 'Inspect Browser', | ||
@@ -259,2 +290,3 @@ 'I9': 'Insta Browser', | ||
'I7': 'Internet Browser Secure', | ||
'3I': 'Intune Managed Browser', | ||
'I5': 'Indian UC Mini Browser', | ||
@@ -270,4 +302,4 @@ 'Z0': 'InBrowser', | ||
'JP': 'Jig Browser Plus', | ||
'JO': 'Jio Browser', | ||
'J1': 'JioPages', | ||
'JO': 'JioSphere', | ||
'JZ': 'JUZI Browser', | ||
'KB': 'K.Browser', | ||
@@ -278,2 +310,3 @@ 'KF': 'Keepsafe Browser', | ||
'KM': 'K-meleon', | ||
'KJ': 'K-Ninja', | ||
'KO': 'Konqueror', | ||
@@ -289,2 +322,3 @@ 'KP': 'Kapiko', | ||
'LA': 'Lagatos Browser', | ||
'GN': 'Legan Browser', | ||
'LR': 'Lexi Browser', | ||
@@ -297,4 +331,6 @@ 'LV': 'Lenovo Browser', | ||
'LI': 'Links', | ||
'RI': 'Liri Browser', | ||
'LC': 'LogicUI TV Browser', | ||
'IF': 'Lolifox', | ||
'L3': 'Lotus', | ||
'LO': 'Lovense Browser', | ||
@@ -311,2 +347,3 @@ 'LT': 'LT Browser', | ||
'M5': 'MarsLab Web Browser', | ||
'M7': 'MaxBrowser', | ||
'M1': 'mCent', | ||
@@ -321,5 +358,7 @@ 'MB': 'MicroB', | ||
'M3': 'Midori Lite', | ||
'M6': 'MixerBox AI', | ||
'MO': 'Mobicip', | ||
'MU': 'MIUI Browser', | ||
'MS': 'Mobile Silk', | ||
'MK': 'Mogok Browser', | ||
'MN': 'Minimo', | ||
@@ -339,6 +378,7 @@ 'MT': 'Mint Browser', | ||
'NR': 'NFS Browser', | ||
'N5': 'Ninetails', | ||
'NB': 'Nokia Browser', | ||
'NO': 'Nokia OSS Browser', | ||
'NV': 'Nokia Ovi Browser', | ||
'N2': 'Norton Secure Browser', | ||
'N2': 'Norton Private Browser', | ||
'NX': 'Nox Browser', | ||
@@ -354,2 +394,4 @@ 'N1': 'NOMone VR Browser', | ||
'NU': 'Nuanti Meta', | ||
'NI': 'Nuviu', | ||
'O9': 'Ocean Browser', | ||
'OC': 'Oculus Browser', | ||
@@ -366,3 +408,5 @@ 'O6': 'Odd Browser', | ||
'HH': 'OhHai Browser', | ||
'OL': 'OnBrowser Lite', | ||
'OE': 'ONE Browser', | ||
'N4': 'Onion Browser', | ||
'Y1': 'Opera Crypto', | ||
@@ -407,2 +451,3 @@ 'OX': 'Opera GX', | ||
'PB': 'Phoenix Browser', | ||
'P9': 'PirateBrowser', | ||
'P8': 'PICO Browser', | ||
@@ -416,2 +461,4 @@ 'PF': 'PlayFree Browser', | ||
'P4': 'Privacy Explorer Fast Safe', | ||
'P3': 'Private Internet Browser', | ||
'P5': 'Proxy Browser', | ||
'P2': 'Pi Browser', | ||
@@ -423,2 +470,6 @@ 'P0': 'PronHub Browser', | ||
'QA': 'Qazweb', | ||
'QI': 'Qiyu', | ||
'QJ': 'QJY TV Browser', | ||
'Q3': 'Qmamu', | ||
'Q4': 'Quick Search TV', | ||
'Q2': 'QQ Browser Lite', | ||
@@ -433,2 +484,5 @@ 'Q1': 'QQ Browser Mini', | ||
'QW': 'QtWebEngine', | ||
'R3': 'Rakuten Browser', | ||
'R4': 'Rakuten Web Search', | ||
'R2': 'Raspbian Chromium', | ||
'RE': 'Realme Browser', | ||
@@ -441,2 +495,3 @@ 'RK': 'Rekonq', | ||
'SA': 'Sailfish Browser', | ||
'R0': 'SberBrowser', | ||
'S8': 'Seewo Browser', | ||
@@ -462,2 +517,3 @@ 'SC': 'SEMC-Browser', | ||
'SY': 'Sizzy', | ||
'K3': 'Skye', | ||
'SK': 'Skyfire', | ||
@@ -467,2 +523,3 @@ 'SS': 'Seraphic Sraf', | ||
'SL': 'Sleipnir', | ||
'8B': 'SlimBoat', | ||
'S6': 'Slimjet', | ||
@@ -472,2 +529,3 @@ 'S7': 'SP Browser', | ||
'8S': 'Secure Private Browser', | ||
'X2': 'SecureX', | ||
'T1': 'Stampy Browser', | ||
@@ -491,2 +549,3 @@ '7S': '7Star', | ||
'4S': 'Surf Browser', | ||
'RY': 'Surfy Browser', | ||
'SG': 'Stargon', | ||
@@ -504,2 +563,4 @@ 'S0': 'START Internet Browser', | ||
'TA': 'Tao Browser', | ||
'T2': 'tararia', | ||
'TH': 'Thor', | ||
'1T': 'Tor Browser', | ||
@@ -511,2 +572,3 @@ 'TF': 'TenFourFox', | ||
'TI': 'Tint Browser', | ||
'TL': 'TrueLocation Browser', | ||
'TC': 'TUC Mini Browser', | ||
@@ -529,3 +591,6 @@ 'TU': 'Tungsten', | ||
'VA': 'Vast Browser', | ||
'V3': 'VD Browser', | ||
'VE': 'Venus Browser', | ||
'WD': 'Vewd Browser', | ||
'V5': 'VibeMate', | ||
'N0': 'Nova Video Downloader Pro', | ||
@@ -539,6 +604,10 @@ 'VS': 'Viasat Browser', | ||
'VM': 'VMware AirWatch', | ||
'VK': 'Vonkeror', | ||
'WI': 'Wear Internet Browser', | ||
'WP': 'Web Explorer', | ||
'W3': 'Web Browser & Explorer', | ||
'W5': 'Webian Shell', | ||
'W4': 'WebDiscover', | ||
'WE': 'WebPositive', | ||
'WX': 'Wexond', | ||
'WF': 'Waterfox', | ||
@@ -549,5 +618,7 @@ 'WB': 'Wave Browser', | ||
'WO': 'wOSBrowser', | ||
'3W': 'w3m', | ||
'WT': 'WeTab Browser', | ||
'1W': 'World Browser', | ||
'WL': 'Wolvic', | ||
'WY': 'Wyzo', | ||
'YG': 'YAGI', | ||
@@ -561,2 +632,3 @@ 'YJ': 'Yahoo! Japan Browser', | ||
'YO': 'YouCare', | ||
'Y3': 'YouBrowser', | ||
'YZ': 'Yuzu Browser', | ||
@@ -578,5 +650,5 @@ 'XR': 'xBrowser', | ||
// detected browsers in older versions | ||
// 'IA': 'Iceape', => pim | ||
// 'SM': 'SeaMonkey', => pim | ||
// 'IA': 'Iceape',: pim | ||
// 'SM': 'SeaMonkey',: pim | ||
}; |
@@ -12,5 +12,10 @@ const ClientAbstractParser = require('./../client-abstract-parser'); | ||
const CLIENTHINT_MAPPING = { | ||
'Chrome': ['Google Chrome'] | ||
'Chrome': ['Google Chrome'], | ||
'Chrome Webview': ['Android WebView'], | ||
'DuckDuckGo Privacy Browser': ['DuckDuckGo'], | ||
'Edge WebView': ['Microsoft Edge WebView2'], | ||
'Microsoft Edge': ['Edge'], | ||
'Norton Private Browser': ['Norton Secure Browser'], | ||
'Vewd Browser': ['Vewd Core'], | ||
}; | ||
const IRIDIUM_VERSIONS = ['2022.04', '2022', '2022.11', '2021.12']; | ||
@@ -26,3 +31,3 @@ const compareBrandForClientHints = (brand) => { | ||
return brand; | ||
} | ||
}; | ||
@@ -66,2 +71,3 @@ class Browser extends ClientAbstractParser { | ||
) { | ||
let type = CLIENT_TYPE.BROWSER; | ||
@@ -72,6 +78,6 @@ let name = ''; | ||
let engineVersion = ''; | ||
let short = '' | ||
let short = ''; | ||
let family = ''; | ||
// client-hint+user-agent | ||
if (hint.name && hint.version) { | ||
if (hint && hint.name && hint.version) { | ||
name = hint.name; | ||
@@ -83,7 +89,16 @@ version = hint.version; | ||
if (data) { | ||
// If version from client hints report 2022.04, then is the Iridium browser | ||
// https://iridiumbrowser.de/news/2022/05/16/version-2022-04-released | ||
if (IRIDIUM_VERSIONS.indexOf(version) !== -1) { | ||
name = 'Iridium'; | ||
short = 'I1'; | ||
// If the version reported from the client hints is YYYY or YYYY.MM (e.g., 2022 or 2022.04), | ||
// then it is the Iridium browser | ||
// https://iridiumbrowser.de/news/ | ||
if (/^202[0-4]/.test(version)) { | ||
name = 'Iridium'; | ||
short = 'I1'; | ||
engine = data.engine; | ||
engineVersion = data.engine_version; | ||
} | ||
// https://bbs.360.cn/thread-16096544-1-1.html | ||
if (/^15/.test(version) && /^114/.test(data.version)) { | ||
name = '360 Secure Browser'; | ||
short = '3B'; | ||
engine = data.engine; | ||
@@ -97,10 +112,16 @@ engineVersion = data.engine_version; | ||
if ( | ||
data.name && | ||
'Chromium' === name && | ||
'Chromium' !== data.name | ||
) { | ||
if ('DuckDuckGo Privacy Browser' === name) { | ||
version = ''; | ||
} | ||
if ('Vewd Browser' === name) { | ||
engine = data.engine; | ||
engineVersion = data.engine_version; | ||
} | ||
// If client hints report Chromium, but user agent detects a Chromium based browser, we favor this instead | ||
if (data.name && 'Chromium' === name && 'Chromium' !== data.name) { | ||
name = data.name; | ||
short = data.short_name; | ||
version = data.version | ||
version = data.version; | ||
family = this.buildFamily(short); | ||
@@ -141,6 +162,6 @@ } | ||
version = ''; | ||
short = this.buildShortName(name) | ||
short = this.buildShortName(name); | ||
if (/Chrome\/.+ Safari\/537.36/.test(userAgent)) { | ||
engine = 'Blink' | ||
engine = 'Blink'; | ||
family = this.buildFamily(short) || 'Chrome'; | ||
@@ -173,4 +194,4 @@ engineVersion = this.buildEngineVersion(userAgent, engine); | ||
engine_version: String(engineVersion), | ||
family: String(family), | ||
} | ||
family: String(family) | ||
}; | ||
} | ||
@@ -202,3 +223,2 @@ | ||
let brands = ArrayPath.get(clientHints, 'client.brands', []); | ||
for (let brandItem of brands) { | ||
@@ -219,9 +239,8 @@ let brand = compareBrandForClientHints(brandItem.brand); | ||
} | ||
} | ||
// If we detected a brand, that is not chromium, | ||
// we will use it, otherwise we will look further | ||
if ('' !== name && 'Chromium' !== name) { | ||
break; | ||
} | ||
// If we detected a brand, that is not chromium, | ||
// we will use it, otherwise we will look further | ||
if ('' !== name && 'Chromium' !== name && 'Microsoft Edge' !== name) { | ||
break; | ||
} | ||
@@ -231,3 +250,3 @@ } | ||
if (clientHints.client.version) { | ||
version = String(clientHints.client.version) | ||
version = String(clientHints.client.version); | ||
} | ||
@@ -275,3 +294,3 @@ } | ||
engine_version: String(engineVersion), | ||
family: family, | ||
family: family | ||
}; | ||
@@ -403,9 +422,8 @@ } | ||
} | ||
if (engine === 'Gecko') { | ||
let pattern = '[ ](?:rv[: ]([0-9.]+)).*gecko/[0-9]{8,10}'; | ||
if (engine === 'Gecko' || engine === 'Clecko') { | ||
let pattern = '[ ](?:rv[: ])([0-9.]+)'; | ||
let regexp = new RegExp(pattern, 'i'); | ||
let match = regexp.exec(userAgent); | ||
if (match !== null) { | ||
return match.pop(); | ||
if (match !== null && /(?:g|cl)ecko\/[0-9]{8,10}/i.test(userAgent)) { | ||
return match[1]; | ||
} | ||
@@ -427,3 +445,3 @@ } | ||
if (match !== null) { | ||
return match.pop(); | ||
return match[1] | ||
} | ||
@@ -430,0 +448,0 @@ return ''; |
@@ -10,2 +10,8 @@ // eslint-disable-next-line no-undef | ||
'Opera Devices', | ||
'Crow Browser', | ||
'Vewd Browser', | ||
'TiviMate', | ||
'Quick Search TV', | ||
'QJY TV Browser', | ||
'TV Bro', | ||
]; |
@@ -9,3 +9,7 @@ const ParserAbstract = require('./abstract-parser'); | ||
const DESKTOP_PATTERN = '(?:Windows (?:NT|IoT)|X11; Linux x86_64)'; | ||
const DESKTOP_EXCLUDE_PATTERN = ' Mozilla/|CE-HTML|Andr[o0]id|Tablet|Mobile|iPhone|Windows Phone|OculusBrowser|ricoh|Lenovo|compatible; MSIE|Trident/|Tesla/|XBOX|FBMD/|ARM; ?([^)]+)'; | ||
const DESKTOP_EXCLUDE_PATTERN = [ | ||
'CE-HTML', | ||
' Mozilla/|Andr[o0]id|Tablet|Mobile|iPhone|Windows Phone|ricoh|OculusBrowser', | ||
'PicoBrowser|Lenovo|compatible; MSIE|Trident/|Tesla/|XBOX|FBMD/|ARM; ?([^)]+)', | ||
].join('|'); | ||
@@ -160,5 +164,6 @@ class DeviceParserAbstract extends ParserAbstract { | ||
model: '', | ||
type: result[0].type, | ||
type: '', | ||
}; | ||
} | ||
return result[0]; | ||
@@ -165,0 +170,0 @@ } |
@@ -213,2 +213,3 @@ // prettier-ignore | ||
'Y8': 'Bubblegum', | ||
'BMW': 'BMW', | ||
'C9': 'CAGI', | ||
@@ -276,2 +277,3 @@ 'CT': 'Capitel', | ||
'COO': 'Coopers', | ||
'CDE': 'COOD-E', | ||
'4R': 'CORN', | ||
@@ -364,2 +366,3 @@ '1O': 'Cosmote', | ||
'ZD': 'DORLAND', | ||
'DRO': 'Droidlogic', | ||
'D8': 'Droxio', | ||
@@ -438,2 +441,3 @@ 'DJ': 'Dragon Touch', | ||
'6E': 'eSTAR', | ||
'ETO': 'ETOE', | ||
'EN': 'Eton', | ||
@@ -478,2 +482,3 @@ 'ET': 'eTouch', | ||
'FE': 'Fengxiang', | ||
'FEN': 'Fenoti', | ||
'F7': 'Fero', | ||
@@ -509,2 +514,3 @@ '67': 'FEONAL', | ||
'FOS': 'FOSSiBOT', | ||
'FRE': 'free', | ||
'FT': 'Freetel', | ||
@@ -662,2 +668,3 @@ 'FEY': 'FreeYond', | ||
'INN': 'I-INN', | ||
'IPL': 'I-Plus', | ||
'OF': 'iOutdoor', | ||
@@ -688,2 +695,3 @@ 'IB': 'iBall', | ||
'IL': 'IMO Mobile', | ||
'IMA': 'Imaq', | ||
'IM1': 'Imose', | ||
@@ -694,2 +702,3 @@ 'I3': 'Impression', | ||
'6I': 'Inco', | ||
'INK': 'Inka', | ||
'IW': 'iNew', | ||
@@ -701,2 +710,3 @@ 'IF': 'Infinix', | ||
'II': 'Inkti', | ||
'MIR': 'Infomir', | ||
'81': 'InfoKit', | ||
@@ -744,5 +754,7 @@ 'I5': 'InnJoo', | ||
'IXT': 'iXTech', | ||
'IOT': 'IOTWE', | ||
'JA': 'JAY-Tech', | ||
'KJ': 'Jiake', | ||
'JD': 'Jedi', | ||
'JEE': 'Jeep', | ||
'J6': 'Jeka', | ||
@@ -925,2 +937,3 @@ 'JF': 'JFone', | ||
'0M': 'Mecool', | ||
'MEM': 'MeMobile', | ||
'MC': 'Mediacom', | ||
@@ -1144,2 +1157,3 @@ 'MK': 'MediaTek', | ||
'7P': 'P-UP', | ||
'PRA': 'Pacific Research Alliance', | ||
'YP': 'Paladin', | ||
@@ -1149,4 +1163,6 @@ 'PM': 'Palm', | ||
'PA': 'Panasonic', | ||
'PNV': 'Panavox', | ||
'PT': 'Pantech', | ||
'PAN': 'Pano', | ||
'PND': 'Panodic', | ||
'PA1': 'Panoramic', | ||
@@ -1442,3 +1458,2 @@ 'PLT': 'Platoon', | ||
'1W': 'Swisstone', | ||
'W7': 'SWTV', | ||
'SSK': 'SSKY', | ||
@@ -1448,2 +1463,3 @@ 'SYC': 'Syco', | ||
'4S': 'Syrox', | ||
'SYS': 'System76', | ||
'TM': 'T-Mobile', | ||
@@ -1473,2 +1489,3 @@ 'T96': 'T96', | ||
'7F': 'Technopc', | ||
'TCH': 'Techstorm', | ||
'T7': 'Teclast', | ||
@@ -1478,2 +1495,3 @@ 'TB': 'Tecno Mobile', | ||
'91': 'TEENO', | ||
'TLK': 'Telkom', | ||
'2L': 'Tele2', | ||
@@ -1485,2 +1503,3 @@ 'TL': 'Telefunken', | ||
'65': 'Telia', | ||
'TLY': 'Telly', | ||
'TEL': 'Telma', | ||
@@ -1534,2 +1553,3 @@ 'PW': 'Telpo', | ||
'T3': 'Trevi', | ||
'TRI': 'TriaPlay', | ||
'TJ': 'Trifone', | ||
@@ -1543,2 +1563,3 @@ 'Q5': 'Trident', | ||
'5C': 'TTEC', | ||
'TTF': 'TTfone', | ||
'TTK': 'TTK-TV', | ||
@@ -1560,2 +1581,3 @@ 'TU': 'Tunisie Telecom', | ||
'UC': 'U.S. Cellular', | ||
'UD1': 'UD', | ||
'UGI': 'UGINE', | ||
@@ -1666,2 +1688,4 @@ 'UG': 'Ugoos', | ||
'VO1': 'Volt', | ||
'VOP': 'Volla', | ||
'V02': 'VOLIA', | ||
'VH': 'Vsmart', | ||
@@ -1680,2 +1704,3 @@ 'V9': 'Vsun', | ||
'WBL': 'We. by Loewe.', | ||
'WCP': 'WeChip', | ||
'WM': 'Weimei', | ||
@@ -1682,0 +1707,0 @@ 'WE': 'WellcoM', |
@@ -5,50 +5,2 @@ const ParserAbstract = require('./../abstract-parser'); | ||
/** | ||
* @typedef InfoResult | ||
* @param {InfoDisplay} display | ||
* @param {number|null} sim | ||
* @param {string|InfoSize} size | ||
* @param {string} weight | ||
* @param {string|null} release | ||
* @param {string|null} os | ||
* @param {InfoHardware} hardware | ||
* @param {InfoPerformance} performance | ||
* | ||
* @typedef InfoResolution | ||
* @param {string} width | ||
* @param {string} height | ||
* | ||
* @typedef InfoDisplay | ||
* @param {string} size | ||
* @param {string|InfoResolution} resolution | ||
* @param {string} ratio | ||
* @param {string} ppi | ||
* | ||
* @typedef InfoPerformance | ||
* @param {number} antutu | ||
* | ||
* @typedef InfoHardwareCPU: | ||
* @param {string} name | ||
* @param {string} type | ||
* @param {number} cores | ||
* @param {number} clock_rate | ||
* @param {string|null} process | ||
* @param {number} gpu_id | ||
* | ||
* @typedef InfoHardwareGPU: | ||
* @param {string} name | ||
* @param {number} clock_rate | ||
* | ||
* @typedef InfoHardware | ||
* @param {number} ram | ||
* @param {number} cpu_id | ||
* @param {InfoHardwareCPU} cpu | ||
* @param {InfoHardwareGPU} gpu | ||
* | ||
* @typedef InfoSize | ||
* @param {string} width | ||
* @param {string} height | ||
* @param {string} thickness | ||
* | ||
*/ | ||
@@ -61,3 +13,3 @@ /* | ||
const InfoDevice = require('node-device-detector/parser/device/info-device'); | ||
const infoDevice = new InfoDevice; | ||
const infoDevice = new InfoDevice(); | ||
const result = infoDevice.info('Asus', 'Zenfone 4'); | ||
@@ -130,3 +82,3 @@ console.log('Result information about device', result); | ||
Math.sqrt(Math.pow(parseInt(width), 2) + Math.pow(parseInt(height), 2)) / | ||
parseFloat(size) | ||
parseFloat(size) | ||
); | ||
@@ -167,4 +119,4 @@ }; | ||
: source[prop] | ||
? source[prop] | ||
: target[prop], | ||
? source[prop] | ||
: target[prop] | ||
})) | ||
@@ -175,3 +127,3 @@ .reduce((a, b) => ({ ...a, ...b }), {}); | ||
...target, | ||
...replaced, | ||
...replaced | ||
}; | ||
@@ -200,3 +152,3 @@ }; | ||
* @usage | ||
* let i = new InfoDevice | ||
* let i = new InfoDevice(); | ||
* let result = i.info('Asus', 'ZenFone 4') | ||
@@ -230,5 +182,10 @@ * console.log({result}); | ||
SM: 'sim', // int: count SIM | ||
TT: 'performance.antutu', // int: antutu score | ||
TT: 'performance.antutu', // int: antutu score | ||
TG: 'performance.geekbench' // int: geekbench score | ||
}; | ||
let collectionHardwareCPU = null; | ||
let collectionHardwareGPU = null; | ||
let collectionSoftware = null; | ||
/** | ||
@@ -247,5 +204,2 @@ * Class for obtaining information on a device | ||
this.fixtureFile = 'device-info/device.yml'; | ||
this.collectionHardwareCPU = {}; | ||
this.collectionHardwareGPU = {}; | ||
this.loadCollection(); | ||
@@ -257,12 +211,12 @@ } | ||
// load hardware properties | ||
this.collectionHardwareCPU = this.loadYMLFile( | ||
'device-info/hardware-cpu.yml' | ||
); | ||
this.collectionHardwareGPU = this.loadYMLFile( | ||
'device-info/hardware-gpu.yml' | ||
); | ||
if (collectionHardwareCPU === null) { | ||
collectionHardwareCPU = this.loadYMLFile('device-info/hardware-cpu.yml'); | ||
} | ||
if (collectionHardwareGPU === null) { | ||
collectionHardwareGPU = this.loadYMLFile('device-info/hardware-gpu.yml'); | ||
} | ||
// load software properties | ||
this.collectionSoftware = this.loadYMLFile( | ||
'device-info/software.yml' | ||
); | ||
if (collectionSoftware === null) { | ||
collectionSoftware = this.loadYMLFile('device-info/software.yml'); | ||
} | ||
} | ||
@@ -291,23 +245,24 @@ | ||
getOsById(id) { | ||
if (this.collectionSoftware['os'] === void 0) { | ||
if (collectionSoftware['os'] === void 0) { | ||
return null; | ||
} | ||
return getDataByIdInCollection(this.collectionSoftware['os'], id); | ||
return getDataByIdInCollection(collectionSoftware['os'], id); | ||
} | ||
getGpuById(id) { | ||
if (this.collectionHardwareGPU['gpu'] === void 0) { | ||
if (collectionHardwareGPU['gpu'] === void 0) { | ||
return null; | ||
} | ||
return getDataByIdInCollection(this.collectionHardwareGPU['gpu'], id); | ||
return getDataByIdInCollection(collectionHardwareGPU['gpu'], id); | ||
} | ||
getCpuById(id) { | ||
if (this.collectionHardwareCPU['cpu'] === void 0) { | ||
if (collectionHardwareCPU['cpu'] === void 0) { | ||
return null; | ||
} | ||
return getDataByIdInCollection(this.collectionHardwareCPU['cpu'], id); | ||
return getDataByIdInCollection(collectionHardwareCPU['cpu'], id); | ||
} | ||
find(deviceBrand, deviceModel, mergeData = {}) { | ||
if (!deviceBrand.length || !deviceModel.length) { | ||
@@ -319,8 +274,5 @@ return null; | ||
deviceBrand = fixStringName(deviceBrand); | ||
deviceModel = fixStringName(deviceModel); | ||
let brand = fixStringName(deviceBrand).trim().toLowerCase(); | ||
let model = fixStringName(deviceModel).trim().toLowerCase(); | ||
let brand = deviceBrand.trim().toLowerCase(); | ||
let model = deviceModel.trim().toLowerCase(); | ||
if ( | ||
@@ -366,7 +318,7 @@ this.collection[brand] === void 0 || | ||
} | ||
if(result.os_version) { | ||
if (result.os_version) { | ||
output.push(result.os_version); | ||
delete result.os_version; | ||
} | ||
if(output.length === 2) { | ||
if (output.length === 2) { | ||
result.os = output.join(' '); | ||
@@ -444,8 +396,11 @@ } | ||
* Converts the values of the performance section to the desired format type | ||
* @param result {InfoResult} | ||
* @param result {ResultDeviceInfo} | ||
*/ | ||
prepareResultPerformance(result) { | ||
if(result.performance !== void 0 && result.performance.antutu !== void 0) { | ||
if (result.performance !== void 0 && result.performance.antutu !== void 0) { | ||
result.performance.antutu = parseInt(result.performance.antutu); | ||
} | ||
if (result.performance !== void 0 && result.performance.geekbench !== void 0) { | ||
result.performance.geekbench = parseInt(result.performance.geekbench); | ||
} | ||
} | ||
@@ -457,3 +412,3 @@ | ||
* @param {String} deviceModel | ||
* @return {InfoResult|null} | ||
* @return {ResultDeviceInfo|null} | ||
*/ | ||
@@ -460,0 +415,0 @@ info(deviceBrand, deviceModel) { |
@@ -17,2 +17,16 @@ const YAML = require('js-yaml'); | ||
function matchReplace(template, matches) { | ||
let max = matches.length-1 || 1; | ||
if (template.indexOf('$') !== -1) { | ||
for (let nb = 1; nb <= max; nb++) { | ||
if (template.indexOf('$' + nb) === -1) { | ||
continue; | ||
} | ||
let replace = matches[nb] !== void 0 ? matches[nb] : ''; | ||
template = template.replace(new RegExp('\\$' + nb, 'g'), replace); | ||
} | ||
} | ||
return template; | ||
} | ||
/** | ||
@@ -29,3 +43,10 @@ * | ||
} | ||
function fuzzyCompareNumber(value1, value2, num = 3) { | ||
return parseFloat(value1).toFixed(num) === parseFloat(value2).toFixed(num); | ||
} | ||
function fuzzyBetweenNumber(value, min, max) { | ||
return value >= min && value <= max; | ||
} | ||
function createHash(str) { | ||
@@ -95,3 +116,3 @@ var hash = 0, i = 0, len = str.length; | ||
return ( | ||
matchUserAgent('Android( [\\.0-9]+)?; Tablet', userAgent) !== null | ||
matchUserAgent('Android( [.0-9]+)?; Tablet', userAgent) !== null | ||
); | ||
@@ -117,2 +138,6 @@ } | ||
function hasVRFragment(userAgent) { | ||
return matchUserAgent('Android( [.0-9]+)?; Mobile VR;| VR ', userAgent) !== null | ||
} | ||
/** | ||
@@ -142,3 +167,3 @@ * @param {string} userAgent | ||
return matchUserAgent( | ||
'Andr0id|(?:Android(?: UHD)?|Google) TV|[(]lite[)] TV|[(]TV;|BRAVIA', | ||
'Andr0id|(?:Android(?: UHD)?|Google) TV|[(]lite[)] TV|BRAVIA|[(]TV;', | ||
userAgent | ||
@@ -266,3 +291,3 @@ ) !== null; | ||
let groups = getGroupForUserAgentTokens(tokens); | ||
let parts = []; | ||
@@ -289,11 +314,18 @@ for (let key in groups) { | ||
let path = parts.join('.'); | ||
// console.log({tokens, groups, hash, path}); | ||
return {tokens, groups, hash, path}; | ||
} | ||
module.exports = { | ||
matchUserAgent, | ||
fuzzyCompare, | ||
fuzzyCompareNumber, | ||
fuzzyBetweenNumber, | ||
versionCompare, | ||
versionTruncate, | ||
hasVRFragment, | ||
hasAndroidTableFragment, | ||
@@ -313,2 +345,3 @@ hasOperaTableFragment, | ||
splitUserAgent, | ||
matchReplace | ||
}; |
@@ -6,2 +6,3 @@ const ParserAbstract = require('./abstract-parser'); | ||
const OS_FAMILIES = require('./os/os_families'); | ||
const ANDROID_APP_LIST = [ | ||
@@ -13,2 +14,3 @@ 'com.hisense.odinbrowser', | ||
]; | ||
const CLIENTHINT_MAPPING = { | ||
@@ -19,17 +21,17 @@ 'GNU/Linux': ['Linux'], | ||
const FIREOS_VERSION_MAPPING = { | ||
'11': '8', | ||
'10': '8', | ||
'9': '7', | ||
'7': '6', | ||
'5': '5', | ||
'4.4.3': '4.5.1', | ||
'4.4.2': '4', | ||
'4.2.2': '3', | ||
'4.0.3': '3', | ||
'4.0.2': '3', | ||
'4': '2', | ||
'2': '1' | ||
}; | ||
const FIRE_OS_VERSION_MAPPING = require('./os/fire-os-version-map'); | ||
const LINEAGE_OS_VERSION_MAPPING = require('./os/lineage-os-version-map'); | ||
const getVersionForMapping = (version, map) => { | ||
const majorVersion = ~~version.split('.', 1)[0]; | ||
if (map[version]) { | ||
return map[version]; | ||
} | ||
if (map[majorVersion]) { | ||
return map[majorVersion]; | ||
} | ||
return ''; | ||
} | ||
const compareOsForClientHints = (brand) => { | ||
@@ -56,6 +58,8 @@ for (let mapName in CLIENTHINT_MAPPING) { | ||
} | ||
if (platform.indexOf('sparc64') !== -1) { | ||
return 'SPARC64'; | ||
} | ||
if (platform.indexOf('x64') !== -1 || (platform.indexOf('x86') !== -1 && bitness === '64')) { | ||
return 'x64'; | ||
} | ||
if (platform.indexOf('x86') !== -1) { | ||
@@ -230,10 +234,10 @@ return 'x86'; | ||
if (data && 'Fire OS' === data.name) { | ||
let majorVersion = ~~version.split('.', 1)[0]; | ||
if ('PICO OS' === name) { | ||
version = data.version; | ||
short = 'PIC'; | ||
} | ||
if (data && data.name === 'Fire OS') { | ||
short = data.short_name; | ||
if (FIREOS_VERSION_MAPPING[version]) { | ||
version = FIREOS_VERSION_MAPPING[version]; | ||
} else if (FIREOS_VERSION_MAPPING[majorVersion]) { | ||
version = FIREOS_VERSION_MAPPING[majorVersion]; | ||
} | ||
version = getVersionForMapping(version, FIRE_OS_VERSION_MAPPING); | ||
} | ||
@@ -251,13 +255,29 @@ | ||
family = this.parseOsFamily(short); | ||
} else if (data && data.name) { | ||
name = data.name; | ||
version = data.version; | ||
short = data.short_name; | ||
platform = data.platform; | ||
family = data.family; | ||
} | ||
if (clientHints | ||
&& data | ||
&& clientHints.app | ||
&& ANDROID_APP_LIST.indexOf(clientHints.app) !== -1 | ||
&& data.name !== 'Android' | ||
) { | ||
name = 'Android'; | ||
short = 'ADR'; | ||
family = 'Android'; | ||
if (clientHints && data && clientHints.app) { | ||
if (ANDROID_APP_LIST.indexOf(clientHints.app) !== -1 && data.name !== 'Android') { | ||
name = 'Android'; | ||
short = 'ADR'; | ||
family = 'Android'; | ||
version = ''; | ||
} | ||
if (clientHints.app === 'org.mozilla.tv.firefox' && name !== 'Fire OS') { | ||
name = 'Fire OS'; | ||
family = 'Android'; | ||
short = 'FIR'; | ||
version = getVersionForMapping(version, FIRE_OS_VERSION_MAPPING); | ||
} | ||
if (clientHints.app === 'org.lineageos.jelly' && name !== 'Lineage OS') { | ||
name = 'Lineage OS'; | ||
family = 'Android'; | ||
short = 'LEN'; | ||
version = getVersionForMapping(data.version, LINEAGE_OS_VERSION_MAPPING); | ||
} | ||
} | ||
@@ -299,2 +319,5 @@ | ||
} | ||
if (this.getBaseRegExp('sparc64').test(userAgent)) { | ||
return 'SPARC64'; | ||
} | ||
if (this.getBaseRegExp('64-?bit|WOW64|(?:Intel)?x64|WINDOWS_64|win64|amd64|x86_?64').test(userAgent)) { | ||
@@ -301,0 +324,0 @@ return 'x64'; |
@@ -5,3 +5,4 @@ // prettier-ignore | ||
'AND', 'CYN', 'FIR', 'REM', 'RZD', 'MLD', 'MCD', 'YNS', 'GRI', 'HAR', | ||
'ADR', 'CLR', 'BOS', 'REV', 'LEN', 'SIR', 'RRS', 'WER', 'PIC', | ||
'ADR', 'CLR', 'BOS', 'REV', 'LEN', 'SIR', 'RRS', 'WER', 'PIC', 'ARM', | ||
'HEL', | ||
], | ||
@@ -25,3 +26,4 @@ 'AmigaOS': ['AMG', 'MOR'], | ||
'FOR', 'MON', 'KAN', 'ZEN', 'LND', 'LNS', 'CHN', 'AMZ', 'TEN', 'CST', | ||
'NOV', 'ROU', 'ZOR', 'RED', 'KAL', 'ORA', 'VID', 'TIV', | ||
'NOV', 'ROU', 'ZOR', 'RED', 'KAL', 'ORA', 'VID', 'TIV', 'BSN', 'RAS', | ||
'UOS', 'PIO', 'FRI', 'LIR', 'WEB', 'SER', 'ASP', | ||
], | ||
@@ -28,0 +30,0 @@ 'Mac': ['MAC'], |
@@ -8,4 +8,6 @@ // prettier-ignore | ||
'AMG': 'AmigaOS', | ||
'ARM': 'Armadillo OS', | ||
'ATV': 'tvOS', | ||
'ARL': 'Arch Linux', | ||
'ASP': 'ASPLinux', | ||
'BTR': 'BackTrack', | ||
@@ -18,2 +20,3 @@ 'SBA': 'Bada', | ||
'BMP': 'Brew', | ||
'BSN': 'BrightSignOS', | ||
'CAI': 'Caixa Mágica', | ||
@@ -38,2 +41,3 @@ 'CES': 'CentOS', | ||
'BSD': 'FreeBSD', | ||
'FRI': 'FRITZ!OS', | ||
'FYD': 'FydeOS', | ||
@@ -49,2 +53,3 @@ 'FUC': 'Fuchsia', | ||
'HAS': 'HasCodingOS', | ||
'HEL': 'HELIX OS', | ||
'IRI': 'IRIX', | ||
@@ -63,2 +68,3 @@ 'INF': 'Inferno', | ||
'LEN': 'Lineage OS', | ||
'LIR': 'Liri OS', | ||
'LBT': 'Lubuntu', | ||
@@ -98,2 +104,4 @@ 'LOS': 'Lumin OS', | ||
'PUR': 'PureOS', | ||
'PIO': 'Raspberry Pi OS', | ||
'RAS': 'Raspbian', | ||
'RHT': 'Red Hat', | ||
@@ -114,2 +122,3 @@ 'RED': 'RedOS', | ||
'SEE': 'SeewoOS', | ||
'SER': 'SerenityOS', | ||
'SIR': 'Sirin OS', | ||
@@ -130,2 +139,3 @@ 'SLW': 'Slackware', | ||
'UBT': 'Ubuntu', | ||
'UOS': 'UOS', | ||
'VID': 'VIDAA', | ||
@@ -149,4 +159,5 @@ 'WAS': 'watchOS', | ||
'POS': 'palmOS', | ||
'WEB': 'Webian', | ||
'WOS': 'webOS', | ||
}; |
718
README.md
# [node-device-detector](https://www.npmjs.com/package/node-device-detector) | ||
_Last update: 11/01/2024_ | ||
_Last update: 27/03/2024_ | ||
@@ -24,2 +24,3 @@ ## Description | ||
+ [Settings](#options) | ||
+ [Specific methods](#specific-methods) | ||
+ [Examples](#others) | ||
@@ -30,4 +31,2 @@ + [Support brands](#brands-list) | ||
Install | ||
@@ -54,2 +53,5 @@ - | ||
deviceAliasCode: false, | ||
deviceTrusted: false, | ||
deviceInfo: false, | ||
maxUserAgentSize: 500, | ||
}); | ||
@@ -60,3 +62,3 @@ const userAgent = 'Mozilla/5.0 (Linux; Android 5.0; NX505J Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.78 Mobile Safari/537.36'; | ||
``` | ||
> PS: When creating an object`detector = new DeviceDetector;` data for parsing is reloaded from files, consider this, the best option is initialization at application start | ||
> PS: When creating an object`detector = new DeviceDetector(DeviceDetectorOptions);` data for parsing is reloaded from files, consider this, the best option is initialization at application start | ||
> I recommend seeing [examples](#others) | ||
@@ -69,7 +71,7 @@ | ||
os: { | ||
name: 'Android', // os name | ||
short_name: 'AND', // os short code name (format A-Z0-9{3}) | ||
version: '5.0', // os version | ||
platform: '', // os platform (x64, x32, amd etc.) | ||
family: 'Android' // os family | ||
name: 'Android', // os name | ||
short_name: 'AND', // os short code name (format A-Z0-9{3}) | ||
version: '5.0', // os version | ||
platform: '', // os platform (x64, x32, amd etc.) | ||
family: 'Android' // os family | ||
}, | ||
@@ -91,2 +93,4 @@ client: { | ||
code: 'NX505J' // device model code (only result for enable detector.deviceAliasCode) | ||
trusted: true // device trusted (result only for enable detector.deviceTrusted and have fixture data + ClientHints are required) | ||
info: {} // device specs (result only fir enable detector.deviceInfo) | ||
} | ||
@@ -181,13 +185,28 @@ } | ||
deviceAliasCode: false, | ||
deviceTrusted: false, | ||
deviceInfo: false, | ||
// ... all options scroll to Setter/Getter/Options | ||
}); | ||
/** server side use celint hinsts */ | ||
const clientHints = new ClientHints(); | ||
const userAgent = res.headers['user-agent']; | ||
const clientHintData = clientHints.parse(res.headers); | ||
const result = detector.detect(userAgent, clientHintData); | ||
let headers = res.headers; | ||
let meta = {} | ||
/** | ||
option meta interface (needed to detect whether the device is trusted, | ||
this information can be obtained from browser) | ||
{ | ||
width: '720', // Math.ceil(window.screen.width * window.devicePixelRatio) | ||
height: '1440', // Math.ceil(window.screen.height * window.devicePixelRatio) | ||
gpu: 'PowerVR SGX Doma', // (()=>{let e=document.createElement("canvas"),t=e.getContext("webgl")||e.getContext("experimental-webgl");return t?t.getParameter(t.getExtension("WEBGL_debug_renderer_info").UNMASKED_RENDERER_WEBGL):null})(); | ||
} | ||
More details in file docs/CLIENT_HINTS_BROWSER.MD | ||
*/ | ||
let hints = clientHints.parse(headers /* or body.hints */, meta /* or body.meta */); | ||
const result = detector.detect(userAgent, hints); | ||
// result promise | ||
// added for 2.0.4 version or later | ||
const result = detector.detectAsync(userAgent, clientHintData); | ||
const result = detector.detectAsync(userAgent, hints); | ||
``` | ||
@@ -279,4 +298,6 @@ | ||
clientIndexes: true, // Using indexes for faster client search (default false) | ||
deviceAliasCode: false, // adds the device code to result device.code as is (default false) | ||
deviceAliasCode: true, // adds the device code to result device.code as is (default false) | ||
maxUserAgentSize: 500, // uses only 500 chars from useragent string (default null - unlimited) | ||
deviceTrusted: true, // check device by specification (default false) | ||
deviceInfo: true, // adds the device info to result device.info (default false) | ||
}); | ||
@@ -291,2 +312,4 @@ | ||
detector.maxUserAgentSize = 500; | ||
detector.deviceTrusted = true; | ||
detector.deviceInfo = true; | ||
@@ -301,10 +324,41 @@ // Array available device types | ||
### Specific methods <a name="specific-methods"></a> ### | ||
```js | ||
const DEVICE_PARSER_NAMES = detector.getDeviceParserNames(); // result colection names for device parsers | ||
const CLIENT_PARSER_NAMES = detector.getClientParserNames(); // result colection names for client parsers | ||
const OS_PARSER_NAMES = detector.getOsParserNames(); // result collection names for os parsers | ||
const BOT_PARSER_NAMES = detector.getBotParserNames(); // result collection names for bot parsers | ||
const aliasDevice = detector.getParseAliasDevice(); // result AliasDevice parser | ||
const deviceAppleHint = detector.getParseDeviceAppleHint(); // result DeviceAppleHint parser | ||
const deviceInfo = detector.getParseInfoDevice(); // result InfoDevice parser | ||
// added custom parser | ||
detector.addParseDevice('MyDeviceParser', new MyDeviceParser()); | ||
detector.addParseClient('MyClientParser', new MyClientParser()); | ||
detector.addParseOs('MyOsParser', new MyOsParser()); | ||
detector.addParseBot('MyBotParser', new MyBotParser()); | ||
// get single parser by name | ||
detector.getParseDevice('MyDeviceParser' /* or DEVICE_PARSER_NAMES.MOBILE */); | ||
detector.getParseClient('MyClientParser' /* or CLIENT_PARSER_NAMES.BROWSER */); | ||
detector.getParseOs('MyOsParser'/* or OS_PARSER_NAMES.DEFAULT */); | ||
detector.getParseBot('MyBotParser'); | ||
``` | ||
### Getting device code as it (experimental) <a name="device-code"></a> | ||
[[top]](#top) | ||
```js | ||
const DeviceDetector = require('node-device-detector'); | ||
const detector = new DeviceDetector() | ||
const aliasDevice = detector.getParseAliasDevice(); | ||
const result = aliasDevice.parse(userAgent); | ||
console.log('Result parse code model', result); | ||
// or | ||
const AliasDevice = require('node-device-detector/parser/device/alias-device'); | ||
const userAgent = 'Mozilla/5.0 (Linux; Android 5.0; NX505J Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.78 Mobile Safari/537.36'; | ||
const aliasDevice = new AliasDevice; | ||
const aliasDevice = new AliasDevice(); | ||
const result = aliasDevice.parse(userAgent); | ||
console.log('Result parse code model', result); | ||
/* | ||
@@ -371,6 +425,6 @@ result | ||
### What about tests? | ||
Yes we use tests, total tests 73.7k | ||
Yes we use tests, total tests 74.9k | ||
### Get more information about a device (experimental) | ||
> This parser is experimental and contains few devices. (1815 devices, alias devices 3881) | ||
> This parser is experimental and contains few devices. (1832 devices, alias devices 3898) | ||
> | ||
@@ -426,3 +480,3 @@ ##### Support detail brands/models list: | ||
| bkav | 1 | 0 | - | black bear | 2 | 0 | | ||
| black fox | 18 | 12 | - | blackview | 15 | 9 | | ||
| black fox | 18 | 12 | - | blackview | 16 | 9 | | ||
| blu | 13 | 15 | - | bravis | 24 | 17 | | ||
@@ -447,6 +501,6 @@ | cgv | 1 | 0 | - | clarmin | 3 | 0 | | ||
| nuvo | 3 | 2 | - | oneplus | 18 | 48 | | ||
| oppo | 103 | 202 | - | oukitel | 8 | 0 | | ||
| oppo | 104 | 204 | - | oukitel | 8 | 0 | | ||
| öwn | 1 | 2 | - | panasonic | 5 | 8 | | ||
| pipo | 5 | 0 | - | poco | 8 | 14 | | ||
| realme | 65 | 94 | - | samsung | 167 | 714 | | ||
| pipo | 5 | 0 | - | poco | 9 | 15 | | ||
| realme | 67 | 96 | - | samsung | 170 | 718 | | ||
| sony | 44 | 172 | - | supra | 1 | 0 | | ||
@@ -459,3 +513,4 @@ | tecno mobile | 91 | 131 | - | tiphone | 1 | 0 | | ||
| wileyfox | 9 | 0 | - | wink | 4 | 0 | | ||
| zync | 2 | 0 | - | zyq | 1 | 13 | | ||
| xiaomi | 9 | 8 | - | zync | 2 | 0 | | ||
| zyq | 1 | 13 | - | | | | | ||
@@ -465,6 +520,13 @@ </details> | ||
```js | ||
const DeviceDetector = require('node-device-detector'); | ||
const detector = new DeviceDetector(); | ||
const infoDevice = detector.getParseInfoDevice(); | ||
const result = infoDevice.info('Asus', 'Zenfone 4'); | ||
console.log('Result information', result); | ||
// or | ||
const InfoDevice = require('node-device-detector/parser/device/info-device'); | ||
const infoDevice = new InfoDevice; | ||
const infoDevice = new InfoDevice(); | ||
const result = infoDevice.info('Asus', 'Zenfone 4'); | ||
console.log('Result information', result); | ||
/* | ||
@@ -550,6 +612,7 @@ result | ||
* [detect device in typescript](docs/TYPE_SCRIPT.MD) | ||
* [get client hints in browser](docs/CLIENT_HINTS_BROWSER.MD) | ||
<a name="brands-list"></a> | ||
##### Support detect brands list (1773): | ||
##### Support detect brands list (1798): | ||
@@ -587,230 +650,233 @@ <details> | ||
Blloc | Blow | Blu | Bluboo | Bluebird | Bluedot | Bluegood | ||
BlueSky | Bluewave | BluSlate | BMAX | Bmobile | BMXC | Bobarry | ||
bogo | Bolva | Bookeen | Boost | Botech | Boway | bq | ||
BrandCode | Brandt | BRAVE | Bravis | BrightSign | Brigmton | Brondi | ||
BROR | BS Mobile | Bubblegum | Bundy | Bush | BuzzTV | C5 Mobile | ||
CAGI | Camfone | Canal Digital | Canal+ | Canguro | Capitel | Captiva | ||
Carbon Mobile | Carrefour | Casio | Casper | Cat | Cavion | Cecotec | ||
Ceibal | Celcus | Celkon | Cell-C | Cellacom | CellAllure | Cellution | ||
Centric | CG Mobile | CGV | Chainway | Changhong | Cherry Mobile | Chico Mobile | ||
ChiliGreen | China Mobile | China Telecom | Chuwi | CipherLab | Citycall | CKK Mobile | ||
Claresta | Clarmin | CLAYTON | ClearPHONE | Clementoni | Cloud | Cloudfone | ||
Cloudpad | Clout | CnM | Cobalt | Coby Kyros | Colors | Comio | ||
Compal | Compaq | COMPUMAX | ComTrade Tesla | Conceptum | Concord | ConCorde | ||
Condor | Connectce | Connex | Conquest | Continental Edison | Contixo | Coolpad | ||
Coopers | CORN | Cosmote | Covia | Cowon | COYOTE | CreNova | ||
Crescent | Cricket | Crius Mea | Crony | Crosscall | Crown | Ctroniq | ||
Cube | CUBOT | CVTE | Cwowdefu | Cyrus | D-Link | D-Tech | ||
Daewoo | Danew | DangcapHD | Dany | DASS | Datalogic | Datamini | ||
Datang | Datawind | Datsun | Dazen | DbPhone | Dbtel | Dcode | ||
DEALDIG | Dell | Denali | Denver | Desay | DeWalt | DEXP | ||
DEYI | DF | DGTEC | Dialog | Dicam | Digi | Digicel | ||
DIGICOM | Digidragon | DIGIFORS | Digihome | Digiland | Digit4G | Digma | ||
DIJITSU | DIKOM | DIMO | Dinalink | Dinax | DING DING | DIORA | ||
DISH | Disney | Ditecma | Diva | DiverMax | Divisat | DIXON | ||
DL | DMM | DNS | DoCoMo | Doffler | Dolamee | Dom.ru | ||
Doogee | Doopro | Doov | Dopod | Doppio | DORLAND | Doro | ||
DPA | DRAGON | Dragon Touch | Dreamgate | DreamStar | DreamTab | Droxio | ||
DSDevices | DSIC | Dtac | Dune HD | DUNNS Mobile | Durabook | Duubee | ||
Dyon | E-Boda | E-Ceros | E-tel | Eagle | EAS Electric | Easypix | ||
EBEN | EBEST | Echo Mobiles | ecom | ECON | ECOO | ECS | ||
Edenwood | EE | EFT | EGL | Einstein | EKINOX | EKO | ||
Eks Mobility | EKT | ELARI | Elecson | Electroneum | ELECTRONIA | Elekta | ||
Elektroland | Element | Elenberg | Elephone | Elevate | Elong Mobile | Eltex | ||
Ematic | Emporia | ENACOM | Energizer | Energy Sistem | Engel | ENIE | ||
Enot | eNOVA | Entity | Envizen | Ephone | Epic | Epik One | ||
Epson | Equator | Ergo | Ericsson | Ericy | Erisson | Essential | ||
Essentielb | eSTAR | Eton | eTouch | Etuline | Eurocase | Eurostar | ||
Evercoss | Everest | Everex | Evertek | Evolio | Evolveo | Evoo | ||
EVPAD | EvroMedia | EWIS | EXCEED | Exmart | ExMobile | EXO | ||
Explay | Express LUCK | Extrem | EYU | Ezio | Ezze | F&U | ||
F+ | F150 | F2 Mobile | Facebook | Facetel | Facime | Fairphone | ||
Famoco | Famous | Fantec | FaRao Pro | Farassoo | FarEasTone | Fengxiang | ||
FEONAL | Fero | FFF SmartLife | Figgers | FiGi | FiGO | FiiO | ||
Filimo | FILIX | FinePower | Finlux | FireFly Mobile | FISE | FITCO | ||
Fluo | Fly | FLYCAT | FMT | FNB | FNF | Fobem | ||
Fondi | Fonos | FOODO | FORME | Formuler | Forstar | Fortis | ||
FOSSiBOT | Four Mobile | Fourel | Foxconn | FoxxD | FPT | Freetel | ||
FreeYond | Frunsi | Fuego | Fujitsu | Funai | Fusion5 | Future Mobile Technology | ||
Fxtec | G-TiDE | G-Touch | Galactic | Galaxy Innovations | Gamma | Garmin-Asus | ||
Gateway | Gazer | Geanee | Geant | Gear Mobile | Gemini | General Mobile | ||
Genesis | GEOFOX | Geotel | Geotex | GEOZON | Getnord | GFive | ||
Gfone | Ghia | Ghong | Ghost | Gigabyte | Gigaset | Gini | ||
Ginzzu | Gionee | GIRASOLE | Globex | Glofiish | GLONYX | GLX | ||
GOCLEVER | Gocomma | GoGEN | Gol Mobile | GoldMaster | Goly | Gome | ||
GoMobile | GOODTEL | Google | Goophone | Gooweel | Gplus | Gradiente | ||
Graetz | Grape | Great Asia | Gree | Green Orange | Greentel | Gresso | ||
Gretel | GroBerwert | Grundig | Gtel | GTMEDIA | GTX | Guophone | ||
H133 | H96 | Hafury | Haier | Haipai | Hamlet | Hammer | ||
Handheld | HannSpree | Hanseatic | HAOQIN | HAOVM | Hardkernel | Harper | ||
Hartens | Hasee | Hathway | HDC | HeadWolf | Helio | HERO | ||
HexaByte | Hezire | Hi | Hi Nova | Hi-Level | Hiberg | High Q | ||
Highscreen | HiHi | HiKing | HiMax | HIPER | Hipstreet | Hiremco | ||
Hisense | Hitachi | Hitech | HKC | HKPro | HLLO | HOFER | ||
Hoffmann | Homatics | Hometech | Homtom | Honeywell | Hoozo | Horizon | ||
Horizont | Hosin | Hot Pepper | Hotel | HOTREALS | Hotwav | How | ||
HP | HTC | Huadoo | Huagan | Huavi | Huawei | Hugerock | ||
Humax | Hurricane | Huskee | Hykker | Hyrican | Hytera | Hyundai | ||
Hyve | i-Cherry | I-INN | i-Joy | i-mate | i-mobile | iBall | ||
BlueSky | Bluewave | BluSlate | BMAX | Bmobile | BMW | BMXC | ||
Bobarry | bogo | Bolva | Bookeen | Boost | Botech | Boway | ||
bq | BrandCode | Brandt | BRAVE | Bravis | BrightSign | Brigmton | ||
Brondi | BROR | BS Mobile | Bubblegum | Bundy | Bush | BuzzTV | ||
C5 Mobile | CAGI | Camfone | Canal Digital | Canal+ | Canguro | Capitel | ||
Captiva | Carbon Mobile | Carrefour | Casio | Casper | Cat | Cavion | ||
Cecotec | Ceibal | Celcus | Celkon | Cell-C | Cellacom | CellAllure | ||
Cellution | Centric | CG Mobile | CGV | Chainway | Changhong | Cherry Mobile | ||
Chico Mobile | ChiliGreen | China Mobile | China Telecom | Chuwi | CipherLab | Citycall | ||
CKK Mobile | Claresta | Clarmin | CLAYTON | ClearPHONE | Clementoni | Cloud | ||
Cloudfone | Cloudpad | Clout | CnM | Cobalt | Coby Kyros | Colors | ||
Comio | Compal | Compaq | COMPUMAX | ComTrade Tesla | Conceptum | Concord | ||
ConCorde | Condor | Connectce | Connex | Conquest | Continental Edison | Contixo | ||
COOD-E | Coolpad | Coopers | CORN | Cosmote | Covia | Cowon | ||
COYOTE | CreNova | Crescent | Cricket | Crius Mea | Crony | Crosscall | ||
Crown | Ctroniq | Cube | CUBOT | CVTE | Cwowdefu | Cyrus | ||
D-Link | D-Tech | Daewoo | Danew | DangcapHD | Dany | DASS | ||
Datalogic | Datamini | Datang | Datawind | Datsun | Dazen | DbPhone | ||
Dbtel | Dcode | DEALDIG | Dell | Denali | Denver | Desay | ||
DeWalt | DEXP | DEYI | DF | DGTEC | Dialog | Dicam | ||
Digi | Digicel | DIGICOM | Digidragon | DIGIFORS | Digihome | Digiland | ||
Digit4G | Digma | DIJITSU | DIKOM | DIMO | Dinalink | Dinax | ||
DING DING | DIORA | DISH | Disney | Ditecma | Diva | DiverMax | ||
Divisat | DIXON | DL | DMM | DNS | DoCoMo | Doffler | ||
Dolamee | Dom.ru | Doogee | Doopro | Doov | Dopod | Doppio | ||
DORLAND | Doro | DPA | DRAGON | Dragon Touch | Dreamgate | DreamStar | ||
DreamTab | Droidlogic | Droxio | DSDevices | DSIC | Dtac | Dune HD | ||
DUNNS Mobile | Durabook | Duubee | Dyon | E-Boda | E-Ceros | E-tel | ||
Eagle | EAS Electric | Easypix | EBEN | EBEST | Echo Mobiles | ecom | ||
ECON | ECOO | ECS | Edenwood | EE | EFT | EGL | ||
Einstein | EKINOX | EKO | Eks Mobility | EKT | ELARI | Elecson | ||
Electroneum | ELECTRONIA | Elekta | Elektroland | Element | Elenberg | Elephone | ||
Elevate | Elong Mobile | Eltex | Ematic | Emporia | ENACOM | Energizer | ||
Energy Sistem | Engel | ENIE | Enot | eNOVA | Entity | Envizen | ||
Ephone | Epic | Epik One | Epson | Equator | Ergo | Ericsson | ||
Ericy | Erisson | Essential | Essentielb | eSTAR | ETOE | Eton | ||
eTouch | Etuline | Eurocase | Eurostar | Evercoss | Everest | Everex | ||
Evertek | Evolio | Evolveo | Evoo | EVPAD | EvroMedia | EWIS | ||
EXCEED | Exmart | ExMobile | EXO | Explay | Express LUCK | Extrem | ||
EYU | Ezio | Ezze | F&U | F+ | F150 | F2 Mobile | ||
Facebook | Facetel | Facime | Fairphone | Famoco | Famous | Fantec | ||
FaRao Pro | Farassoo | FarEasTone | Fengxiang | Fenoti | FEONAL | Fero | ||
FFF SmartLife | Figgers | FiGi | FiGO | FiiO | Filimo | FILIX | ||
FinePower | Finlux | FireFly Mobile | FISE | FITCO | Fluo | Fly | ||
FLYCAT | FMT | FNB | FNF | Fobem | Fondi | Fonos | ||
FOODO | FORME | Formuler | Forstar | Fortis | FOSSiBOT | Four Mobile | ||
Fourel | Foxconn | FoxxD | FPT | free | Freetel | FreeYond | ||
Frunsi | Fuego | Fujitsu | Funai | Fusion5 | Future Mobile Technology | Fxtec | ||
G-TiDE | G-Touch | Galactic | Galaxy Innovations | Gamma | Garmin-Asus | Gateway | ||
Gazer | Geanee | Geant | Gear Mobile | Gemini | General Mobile | Genesis | ||
GEOFOX | Geotel | Geotex | GEOZON | Getnord | GFive | Gfone | ||
Ghia | Ghong | Ghost | Gigabyte | Gigaset | Gini | Ginzzu | ||
Gionee | GIRASOLE | Globex | Glofiish | GLONYX | GLX | GOCLEVER | ||
Gocomma | GoGEN | Gol Mobile | GoldMaster | Goly | Gome | GoMobile | ||
GOODTEL | Google | Goophone | Gooweel | Gplus | Gradiente | Graetz | ||
Grape | Great Asia | Gree | Green Orange | Greentel | Gresso | Gretel | ||
GroBerwert | Grundig | Gtel | GTMEDIA | GTX | Guophone | H133 | ||
H96 | Hafury | Haier | Haipai | Hamlet | Hammer | Handheld | ||
HannSpree | Hanseatic | HAOQIN | HAOVM | Hardkernel | Harper | Hartens | ||
Hasee | Hathway | HDC | HeadWolf | Helio | HERO | HexaByte | ||
Hezire | Hi | Hi Nova | Hi-Level | Hiberg | High Q | Highscreen | ||
HiHi | HiKing | HiMax | HIPER | Hipstreet | Hiremco | Hisense | ||
Hitachi | Hitech | HKC | HKPro | HLLO | HOFER | Hoffmann | ||
Homatics | Hometech | Homtom | Honeywell | Hoozo | Horizon | Horizont | ||
Hosin | Hot Pepper | Hotel | HOTREALS | Hotwav | How | HP | ||
HTC | Huadoo | Huagan | Huavi | Huawei | Hugerock | Humax | ||
Hurricane | Huskee | Hykker | Hyrican | Hytera | Hyundai | Hyve | ||
i-Cherry | I-INN | i-Joy | i-mate | i-mobile | I-Plus | iBall | ||
iBerry | ibowin | iBrit | IconBIT | iData | iDino | iDroid | ||
iGet | iHunt | Ikea | IKI Mobile | iKoMo | iKon | iKonia | ||
IKU Mobile | iLA | iLepo | iLife | iMan | iMars | iMI | ||
IMO Mobile | Imose | Impression | iMuz | iNavi | INCAR | Inch | ||
Inco | iNew | Infiniton | Infinix | InFocus | InfoKit | InFone | ||
Inhon | Inkti | InnJoo | Innos | Innostream | iNo Mobile | Inoi | ||
iNOVA | INQ | Insignia | INSYS | Intek | Intel | Intex | ||
Invens | Inverto | Invin | iOcean | iOutdoor | iPEGTOP | iPro | ||
iQ&T | IQM | IRA | Irbis | iReplace | Iris | iRobot | ||
iRola | iRulu | iSafe Mobile | iStar | iSWAG | IT | iTel | ||
iTruck | IUNI | iVA | iView | iVooMi | ivvi | iWaylink | ||
iXTech | iYou | iZotron | JAY-Tech | Jedi | Jeka | Jesy | ||
JFone | Jiake | Jiayu | Jinga | Jio | Jivi | JKL | ||
Jolla | Joy | JoySurf | JPay | JREN | Jumper | Juniper Systems | ||
Just5 | JVC | JXD | K-Lite | K-Touch | Kaan | Kaiomy | ||
Kalley | Kanji | Kapsys | Karbonn | Kata | KATV1 | Kazam | ||
Kazuna | KDDI | Kempler & Strauss | Kenbo | Kendo | Keneksi | Kenxinda | ||
Khadas | Kiano | Kingbox | Kingstar | Kingsun | KINGZONE | Kinstone | ||
Kiowa | Kivi | Klipad | KN Mobile | Kocaso | Kodak | Kogan | ||
Komu | Konka | Konrow | Koobee | Koolnee | Kooper | KOPO | ||
Koridy | Koslam | Kraft | KREZ | KRIP | KRONO | Krüger&Matz | ||
KT-Tech | KUBO | KuGou | Kuliao | Kult | Kumai | Kurio | ||
Kvant | Kydos | Kyocera | Kyowon | Kzen | KZG | L-Max | ||
LAIQ | Land Rover | Landvo | Lanin | Lanix | Lark | Laurus | ||
Lava | LCT | Le Pan | Leader Phone | Leagoo | Leben | LeBest | ||
Lectrus | Ledstar | LeEco | Leelbox | Leff | Legend | Leke | ||
Lemco | LEMFO | Lemhoov | Lenco | Lenovo | Leotec | Lephone | ||
Lesia | Lexand | Lexibook | LG | Liberton | Lifemaxx | Lime | ||
Lingwin | Linnex | Linsar | Linsay | Listo | LNMBBS | Loewe | ||
Logic | Logic Instrument | Logicom | Logik | LOKMAT | Loview | Lovme | ||
LPX-G | LT Mobile | Lumigon | Lumitel | Lumus | Luna | Luxor | ||
LYF | M-Horse | M-Tech | M.T.T. | M3 Mobile | M4tel | MAC AUDIO | ||
Macoox | Mafe | Magicsee | Magnus | Majestic | Malata | Mango | ||
Manhattan | Mann | Manta Multimedia | Mantra | Mara | Marshal | Mascom | ||
Massgo | Masstel | Master-G | Mastertech | Matco Tools | Matrix | Maunfeld | ||
Maxcom | Maxfone | Maximus | Maxtron | MAXVI | Maxwell | Maxwest | ||
MAXX | Maze | Maze Speed | MBI | MBOX | MDC Store | MDTV | ||
meanIT | Mecer | Mecool | Mediacom | MediaTek | Medion | MEEG | ||
MEGA VISION | MegaFon | Meitu | Meizu | Melrose | Memup | MEO | ||
Meta | Metz | MEU | MicroMax | Microsoft | Microtech | Minix | ||
Mint | Mintt | Mio | Mione | Miray | Mitchell & Brown | Mito | ||
Mitsubishi | Mitsui | MIVO | MIWANG | MIXC | MiXzo | MLAB | ||
MLLED | MLS | MMI | Mobell | Mobicel | MobiIoT | Mobiistar | ||
Mobile Kingdom | Mobiola | Mobistel | MobiWire | Mobo | Mobvoi | Modecom | ||
Mofut | Mosimosi | Motiv | Motorola | Movic | MOVISUN | Movitel | ||
Moxee | mPhone | Mpman | MSI | MStar | MTC | MTN | ||
Multilaser | MultiPOS | MwalimuPlus | MYFON | MyGica | MygPad | Mymaga | ||
MyMobile | MyPhone | Myria | Myros | Mystery | MyTab | MyWigo | ||
N-one | Nabi | NABO | Nanho | Naomi Phone | NASCO | National | ||
Navcity | Navitech | Navitel | Navon | NavRoad | NEC | Necnot | ||
Nedaphone | Neffos | NEKO | Neo | neoCore | Neolix | Neomi | ||
Neon IQ | NetBox | Netgear | Netmak | NeuImage | NeuTab | NEVIR | ||
New Balance | New Bridge | Newgen | Newland | Newman | Newsday | NewsMy | ||
Nexa | NEXBOX | Nexian | NEXON | NEXT | Next & NextStar | Nextbit | ||
NextBook | NextTab | NG Optics | NGM | NGpon | Nikon | NINETEC | ||
Nintendo | nJoy | NOA | Noain | Nobby | Noblex | NOBUX | ||
noDROPOUT | NOGA | Nokia | Nomi | Nomu | Noontec | Nordmende | ||
NORMANDE | NorthTech | Nos | Nothing Phone | Nous | Novacom | Novex | ||
Novey | NOVO | NTT West | NuAns | Nubia | NUU Mobile | NuVision | ||
Nuvo | Nvidia | NYX Mobile | O+ | O2 | Oale | Oangcc | ||
OASYS | Obabox | Ober | Obi | OCEANIC | Odotpad | Odys | ||
OINOM | Ok | Okapia | Oking | OKSI | OKWU | Olax | ||
Olkya | Ollee | OLTO | Olympia | OMIX | Onda | OneClick | ||
OneLern | OnePlus | Onida | Onix | Onkyo | ONN | ONVO | ||
ONYX BOOX | Ookee | Ooredoo | OpelMobile | Openbox | Ophone | OPPO | ||
Opsson | Optoma | Orange | Orava | Orbic | Orbita | Orbsmart | ||
Ordissimo | Orion | OSCAL | OTTO | OUJIA | Ouki | Oukitel | ||
OUYA | Overmax | Ovvi | öwn | Owwo | OYSIN | Oysters | ||
Oyyu | OzoneHD | P-UP | Packard Bell | Paladin | Palm | Panacom | ||
Panasonic | Pano | Panoramic | Pantech | PAPYRE | Parrot Mobile | Partner Mobile | ||
PC Smart | PCBOX | PCD | PCD Argentina | PEAQ | Pelitt | Pendoo | ||
Penta | Pentagram | Perfeo | Phicomm | Philco | Philips | Phonemax | ||
phoneOne | Pico | PINE | Pioneer | Pioneer Computers | PiPO | PIRANHA | ||
Pixela | Pixelphone | Pixus | Planet Computers | Platoon | Play Now | Ployer | ||
Plum | PlusStyle | Pluzz | PocketBook | POCO | Point Mobile | Point of View | ||
Polar | PolarLine | Polaroid | Polestar | PolyPad | Polytron | Pomp | ||
Poppox | POPTEL | Porsche | Positivo | Positivo BGH | PPTV | Premier | ||
Premio | Prestigio | PRIME | Primepad | Primux | Pritom | Prixton | ||
PROFiLO | Proline | Prology | ProScan | PROSONIC | Protruly | ProVision | ||
PULID | Punos | Purism | Q-Box | Q-Touch | Q.Bell | QFX | ||
Qilive | QLink | QMobile | Qnet Mobile | QTECH | Qtek | Quantum | ||
Quatro | Qubo | Quechua | Quest | Quipus | Qumo | Qware | ||
R-TV | Rakuten | Ramos | Raspberry | Ravoz | Raylandz | Razer | ||
RCA Tablets | Reach | Readboy | Realme | RED | Redbean | Redfox | ||
RedLine | Redway | Reeder | REGAL | RelNAT | Remdun | Retroid Pocket | ||
Revo | Revomovil | Ricoh | Rikomagic | RIM | Rinno | Ritmix | ||
Ritzviva | Riviera | Rivo | Rizzen | ROADMAX | Roadrover | Roam Cat | ||
ROiK | Rokit | Roku | Rombica | Ross&Moor | Rover | RoverPad | ||
Royole | RoyQueen | RT Project | RugGear | RuggeTech | Ruggex | Ruio | ||
Runbo | Rupa | Ryte | S-TELL | S2Tel | Saba | Safaricom | ||
Sagem | Sagemcom | Saiet | SAILF | Salora | Samsung | Samtech | ||
Samtron | Sanei | Sankey | Sansui | Santin | SANY | Sanyo | ||
Savio | Sber | SCBC | Schneider | Schok | Scosmos | Seatel | ||
SEBBE | Seeken | SEEWO | SEG | Sega | SEHMAX | Selecline | ||
Selenga | Selevision | Selfix | SEMP TCL | Sencor | Sendo | Senkatel | ||
Senseit | Senwa | Seuic | Sewoo | SFR | SGIN | Shanling | ||
Sharp | Shift Phones | Shivaki | Shtrikh-M | Shuttle | Sico | Siemens | ||
Sigma | Silelis | Silent Circle | Silva Schneider | Simbans | simfer | Simply | ||
Singtech | Siragon | Sirin Labs | SK Broadband | SKG | SKK Mobile | Sky | ||
Skyline | SkyStream | Skytech | Skyworth | Smadl | Smailo | Smart | ||
Smart Electronic | Smart Kassel | Smartab | SmartBook | SMARTEC | Smartex | Smartfren | ||
Smartisan | Smarty | Smooth Mobile | Smotreshka | SNAMI | SobieTech | Soda | ||
Softbank | Soho Style | Solas | SOLE | SOLO | Solone | Sonim | ||
SONOS | Sony | Sony Ericsson | SOSH | Soundmax | Soyes | Spark | ||
Sparx | SPC | Spectralink | Spectrum | Spice | Sprint | SPURT | ||
SQOOL | SSKY | Star | Starlight | Starmobile | Starway | Starwind | ||
STF Mobile | STG Telecom | STK | Stonex | Storex | StrawBerry | Stream | ||
STRONG | Stylo | Subor | Sugar | Sumvision | Sunmax | Sunmi | ||
Sunny | Sunstech | SunVan | Sunvell | SUNWIND | Super General | SuperBOX | ||
SuperSonic | SuperTab | Supra | Supraim | Surge | Suzuki | Sveon | ||
Swipe | SWISSMOBILITY | Swisstone | Switel | SWTV | Syco | SYH | ||
Sylvania | Symphony | Syrox | T-Mobile | T96 | TADAAM | TAG Tech | ||
Taiga System | Takara | Talius | Tambo | Tanix | TAUBE | TB Touch | ||
TCL | TD Systems | TD Tech | TeachTouch | Technicolor | Technika | TechniSat | ||
Technopc | TechnoTrend | TechPad | TechSmart | Techwood | Teclast | Tecno Mobile | ||
TecToy | TEENO | Teknosa | Tele2 | Telefunken | Telego | Telenor | ||
Telia | Telit | Telma | TeloSystems | Telpo | TENPLUS | Teracube | ||
Tesco | Tesla | TETC | Tetratab | teXet | ThL | Thomson | ||
Thuraya | TIANYU | Tibuta | Tigers | Time2 | Timovi | TIMvision | ||
Tinai | Tinmo | TiPhone | TiVo | TJC | TOKYO | Tolino | ||
Tone | TOOGO | Tooky | Top House | TopDevice | TOPDON | Topelotek | ||
Toplux | TOPSHOWS | Topsion | Topway | Torex | Torque | TOSCIDO | ||
Toshiba | Touch Plus | Touchmate | TOX | TPS | Transpeed | TrekStor | ||
Trevi | Trident | Trifone | Trio | Tronsmart | True | True Slim | ||
Tsinghua Tongfang | TTEC | TTK-TV | TuCEL | Tunisie Telecom | Turbo | Turbo-X | ||
IKU Mobile | iLA | iLepo | iLife | iMan | Imaq | iMars | ||
iMI | IMO Mobile | Imose | Impression | iMuz | iNavi | INCAR | ||
Inch | Inco | iNew | Infiniton | Infinix | InFocus | InfoKit | ||
Infomir | InFone | Inhon | Inka | Inkti | InnJoo | Innos | ||
Innostream | iNo Mobile | Inoi | iNOVA | INQ | Insignia | INSYS | ||
Intek | Intel | Intex | Invens | Inverto | Invin | iOcean | ||
IOTWE | iOutdoor | iPEGTOP | iPro | iQ&T | IQM | IRA | ||
Irbis | iReplace | Iris | iRobot | iRola | iRulu | iSafe Mobile | ||
iStar | iSWAG | IT | iTel | iTruck | IUNI | iVA | ||
iView | iVooMi | ivvi | iWaylink | iXTech | iYou | iZotron | ||
JAY-Tech | Jedi | Jeep | Jeka | Jesy | JFone | Jiake | ||
Jiayu | Jinga | Jio | Jivi | JKL | Jolla | Joy | ||
JoySurf | JPay | JREN | Jumper | Juniper Systems | Just5 | JVC | ||
JXD | K-Lite | K-Touch | Kaan | Kaiomy | Kalley | Kanji | ||
Kapsys | Karbonn | Kata | KATV1 | Kazam | Kazuna | KDDI | ||
Kempler & Strauss | Kenbo | Kendo | Keneksi | Kenxinda | Khadas | Kiano | ||
Kingbox | Kingstar | Kingsun | KINGZONE | Kinstone | Kiowa | Kivi | ||
Klipad | KN Mobile | Kocaso | Kodak | Kogan | Komu | Konka | ||
Konrow | Koobee | Koolnee | Kooper | KOPO | Koridy | Koslam | ||
Kraft | KREZ | KRIP | KRONO | Krüger&Matz | KT-Tech | KUBO | ||
KuGou | Kuliao | Kult | Kumai | Kurio | Kvant | Kydos | ||
Kyocera | Kyowon | Kzen | KZG | L-Max | LAIQ | Land Rover | ||
Landvo | Lanin | Lanix | Lark | Laurus | Lava | LCT | ||
Le Pan | Leader Phone | Leagoo | Leben | LeBest | Lectrus | Ledstar | ||
LeEco | Leelbox | Leff | Legend | Leke | Lemco | LEMFO | ||
Lemhoov | Lenco | Lenovo | Leotec | Lephone | Lesia | Lexand | ||
Lexibook | LG | Liberton | Lifemaxx | Lime | Lingwin | Linnex | ||
Linsar | Linsay | Listo | LNMBBS | Loewe | Logic | Logic Instrument | ||
Logicom | Logik | LOKMAT | Loview | Lovme | LPX-G | LT Mobile | ||
Lumigon | Lumitel | Lumus | Luna | Luxor | LYF | M-Horse | ||
M-Tech | M.T.T. | M3 Mobile | M4tel | MAC AUDIO | Macoox | Mafe | ||
Magicsee | Magnus | Majestic | Malata | Mango | Manhattan | Mann | ||
Manta Multimedia | Mantra | Mara | Marshal | Mascom | Massgo | Masstel | ||
Master-G | Mastertech | Matco Tools | Matrix | Maunfeld | Maxcom | Maxfone | ||
Maximus | Maxtron | MAXVI | Maxwell | Maxwest | MAXX | Maze | ||
Maze Speed | MBI | MBOX | MDC Store | MDTV | meanIT | Mecer | ||
Mecool | Mediacom | MediaTek | Medion | MEEG | MEGA VISION | MegaFon | ||
Meitu | Meizu | Melrose | MeMobile | Memup | MEO | Meta | ||
Metz | MEU | MicroMax | Microsoft | Microtech | Minix | Mint | ||
Mintt | Mio | Mione | Miray | Mitchell & Brown | Mito | Mitsubishi | ||
Mitsui | MIVO | MIWANG | MIXC | MiXzo | MLAB | MLLED | ||
MLS | MMI | Mobell | Mobicel | MobiIoT | Mobiistar | Mobile Kingdom | ||
Mobiola | Mobistel | MobiWire | Mobo | Mobvoi | Modecom | Mofut | ||
Mosimosi | Motiv | Motorola | Movic | MOVISUN | Movitel | Moxee | ||
mPhone | Mpman | MSI | MStar | MTC | MTN | Multilaser | ||
MultiPOS | MwalimuPlus | MYFON | MyGica | MygPad | Mymaga | MyMobile | ||
MyPhone | Myria | Myros | Mystery | MyTab | MyWigo | N-one | ||
Nabi | NABO | Nanho | Naomi Phone | NASCO | National | Navcity | ||
Navitech | Navitel | Navon | NavRoad | NEC | Necnot | Nedaphone | ||
Neffos | NEKO | Neo | neoCore | Neolix | Neomi | Neon IQ | ||
NetBox | Netgear | Netmak | NeuImage | NeuTab | NEVIR | New Balance | ||
New Bridge | Newgen | Newland | Newman | Newsday | NewsMy | Nexa | ||
NEXBOX | Nexian | NEXON | NEXT | Next & NextStar | Nextbit | NextBook | ||
NextTab | NG Optics | NGM | NGpon | Nikon | NINETEC | Nintendo | ||
nJoy | NOA | Noain | Nobby | Noblex | NOBUX | noDROPOUT | ||
NOGA | Nokia | Nomi | Nomu | Noontec | Nordmende | NORMANDE | ||
NorthTech | Nos | Nothing Phone | Nous | Novacom | Novex | Novey | ||
NOVO | NTT West | NuAns | Nubia | NUU Mobile | NuVision | Nuvo | ||
Nvidia | NYX Mobile | O+ | O2 | Oale | Oangcc | OASYS | ||
Obabox | Ober | Obi | OCEANIC | Odotpad | Odys | OINOM | ||
Ok | Okapia | Oking | OKSI | OKWU | Olax | Olkya | ||
Ollee | OLTO | Olympia | OMIX | Onda | OneClick | OneLern | ||
OnePlus | Onida | Onix | Onkyo | ONN | ONVO | ONYX BOOX | ||
Ookee | Ooredoo | OpelMobile | Openbox | Ophone | OPPO | Opsson | ||
Optoma | Orange | Orava | Orbic | Orbita | Orbsmart | Ordissimo | ||
Orion | OSCAL | OTTO | OUJIA | Ouki | Oukitel | OUYA | ||
Overmax | Ovvi | öwn | Owwo | OYSIN | Oysters | Oyyu | ||
OzoneHD | P-UP | Pacific Research Alliance | Packard Bell | Paladin | Palm | Panacom | ||
Panasonic | Panavox | Pano | Panodic | Panoramic | Pantech | PAPYRE | ||
Parrot Mobile | Partner Mobile | PC Smart | PCBOX | PCD | PCD Argentina | PEAQ | ||
Pelitt | Pendoo | Penta | Pentagram | Perfeo | Phicomm | Philco | ||
Philips | Phonemax | phoneOne | Pico | PINE | Pioneer | Pioneer Computers | ||
PiPO | PIRANHA | Pixela | Pixelphone | Pixus | Planet Computers | Platoon | ||
Play Now | Ployer | Plum | PlusStyle | Pluzz | PocketBook | POCO | ||
Point Mobile | Point of View | Polar | PolarLine | Polaroid | Polestar | PolyPad | ||
Polytron | Pomp | Poppox | POPTEL | Porsche | Positivo | Positivo BGH | ||
PPTV | Premier | Premio | Prestigio | PRIME | Primepad | Primux | ||
Pritom | Prixton | PROFiLO | Proline | Prology | ProScan | PROSONIC | ||
Protruly | ProVision | PULID | Punos | Purism | Q-Box | Q-Touch | ||
Q.Bell | QFX | Qilive | QLink | QMobile | Qnet Mobile | QTECH | ||
Qtek | Quantum | Quatro | Qubo | Quechua | Quest | Quipus | ||
Qumo | Qware | R-TV | Rakuten | Ramos | Raspberry | Ravoz | ||
Raylandz | Razer | RCA Tablets | Reach | Readboy | Realme | RED | ||
Redbean | Redfox | RedLine | Redway | Reeder | REGAL | RelNAT | ||
Remdun | Retroid Pocket | Revo | Revomovil | Ricoh | Rikomagic | RIM | ||
Rinno | Ritmix | Ritzviva | Riviera | Rivo | Rizzen | ROADMAX | ||
Roadrover | Roam Cat | ROiK | Rokit | Roku | Rombica | Ross&Moor | ||
Rover | RoverPad | Royole | RoyQueen | RT Project | RugGear | RuggeTech | ||
Ruggex | Ruio | Runbo | Rupa | Ryte | S-TELL | S2Tel | ||
Saba | Safaricom | Sagem | Sagemcom | Saiet | SAILF | Salora | ||
Samsung | Samtech | Samtron | Sanei | Sankey | Sansui | Santin | ||
SANY | Sanyo | Savio | Sber | SCBC | Schneider | Schok | ||
Scosmos | Seatel | SEBBE | Seeken | SEEWO | SEG | Sega | ||
SEHMAX | Selecline | Selenga | Selevision | Selfix | SEMP TCL | Sencor | ||
Sendo | Senkatel | Senseit | Senwa | Seuic | Sewoo | SFR | ||
SGIN | Shanling | Sharp | Shift Phones | Shivaki | Shtrikh-M | Shuttle | ||
Sico | Siemens | Sigma | Silelis | Silent Circle | Silva Schneider | Simbans | ||
simfer | Simply | Singtech | Siragon | Sirin Labs | SK Broadband | SKG | ||
SKK Mobile | Sky | Skyline | SkyStream | Skytech | Skyworth | Smadl | ||
Smailo | Smart | Smart Electronic | Smart Kassel | Smartab | SmartBook | SMARTEC | ||
Smartex | Smartfren | Smartisan | Smarty | Smooth Mobile | Smotreshka | SNAMI | ||
SobieTech | Soda | Softbank | Soho Style | Solas | SOLE | SOLO | ||
Solone | Sonim | SONOS | Sony | Sony Ericsson | SOSH | Soundmax | ||
Soyes | Spark | Sparx | SPC | Spectralink | Spectrum | Spice | ||
Sprint | SPURT | SQOOL | SSKY | Star | Starlight | Starmobile | ||
Starway | Starwind | STF Mobile | STG Telecom | STK | Stonex | Storex | ||
StrawBerry | Stream | STRONG | Stylo | Subor | Sugar | Sumvision | ||
Sunmax | Sunmi | Sunny | Sunstech | SunVan | Sunvell | SUNWIND | ||
Super General | SuperBOX | SuperSonic | SuperTab | Supra | Supraim | Surge | ||
Suzuki | Sveon | Swipe | SWISSMOBILITY | Swisstone | Switel | Syco | ||
SYH | Sylvania | Symphony | Syrox | System76 | T-Mobile | T96 | ||
TADAAM | TAG Tech | Taiga System | Takara | Talius | Tambo | Tanix | ||
TAUBE | TB Touch | TCL | TD Systems | TD Tech | TeachTouch | Technicolor | ||
Technika | TechniSat | Technopc | TechnoTrend | TechPad | TechSmart | Techstorm | ||
Techwood | Teclast | Tecno Mobile | TecToy | TEENO | Teknosa | Tele2 | ||
Telefunken | Telego | Telenor | Telia | Telit | Telkom | Telly | ||
Telma | TeloSystems | Telpo | TENPLUS | Teracube | Tesco | Tesla | ||
TETC | Tetratab | teXet | ThL | Thomson | Thuraya | TIANYU | ||
Tibuta | Tigers | Time2 | Timovi | TIMvision | Tinai | Tinmo | ||
TiPhone | TiVo | TJC | TOKYO | Tolino | Tone | TOOGO | ||
Tooky | Top House | TopDevice | TOPDON | Topelotek | Toplux | TOPSHOWS | ||
Topsion | Topway | Torex | Torque | TOSCIDO | Toshiba | Touch Plus | ||
Touchmate | TOX | TPS | Transpeed | TrekStor | Trevi | TriaPlay | ||
Trident | Trifone | Trio | Tronsmart | True | True Slim | Tsinghua Tongfang | ||
TTEC | TTfone | TTK-TV | TuCEL | Tunisie Telecom | Turbo | Turbo-X | ||
TurboKids | TurboPad | Türk Telekom | Turkcell | TVC | TwinMOS | TWM | ||
Twoe | TWZ | Tymes | U-Magic | U.S. Cellular | UE | UGINE | ||
Ugoos | Uhans | Uhappy | Ulefone | Umax | UMIDIGI | Unblock Tech | ||
Uniden | Unihertz | Unimax | Uniqcell | Uniscope | Unistrong | Unitech | ||
UNIWA | Unknown | Unnecto | Unnion Technologies | UNNO | Unonu | Unowhy | ||
UOOGOU | Urovo | UTime | UTOK | UTStarcom | UZ Mobile | V-Gen | ||
V-HOME | V-HOPE | v-mobile | VAIO | VALEM | VALTECH | VANGUARD | ||
Vankyo | Vargo | Vastking | VAVA | VC | VDVD | Vega | ||
Vekta | Venso | Venstar | Venturer | VEON | Verico | Verizon | ||
Vernee | Verssed | Versus | Vertex | Vertu | Verykool | Vesta | ||
Vestel | VETAS | Vexia | VGO TEL | ViBox | Victurio | VIDA | ||
Videocon | Videoweb | ViewSonic | VIIPOO | Vinabox | Vinga | Vinsoc | ||
Vios | Viper | Vipro | Virzo | Vision Touch | Visual Land | Vitelcom | ||
Vityaz | Viumee | Vivax | VIVIMAGE | Vivo | VIWA | Vizio | ||
Vizmo | VK Mobile | VKworld | Vodacom | Vodafone | VOGA | Völfen | ||
VOLKANO | Volt | Vonino | Vontar | Vorago | Vorcom | Vorke | ||
Vormor | Vortex | Voto | VOX | Voxtel | Voyo | Vsmart | ||
Vsun | VUCATIMES | Vue Micro | Vulcan | VVETIME | WAF | Walker | ||
Walton | Waltter | Wanmukang | WANSA | WE | We. by Loewe. | Web TV | ||
Webfleet | Wecool | Weelikeit | Weimei | WellcoM | WELLINGTON | Western Digital | ||
Westpoint | Wexler | White Mobile | Wieppo | Wigor | Wiko | Wileyfox | ||
Winds | Wink | Winmax | Winnovo | Winstar | Wintouch | Wiseasy | ||
WIWA | WizarPos | Wizz | Wolder | Wolfgang | Wolki | WONDER | ||
Wonu | Woo | Wortmann | Woxter | X-AGE | X-BO | X-Mobile | ||
X-TIGI | X-View | X.Vision | X88 | X96 | X96Q | Xcell | ||
XCOM | Xcruiser | XElectron | XGEM | XGIMI | Xgody | Xiaodu | ||
Xiaolajiao | Xiaomi | Xion | Xolo | Xoro | Xshitou | Xtouch | ||
Xtratech | Xwave | XY Auto | Yandex | Yarvik | YASIN | YELLYOUTH | ||
YEPEN | Yes | Yestel | Yezz | Yoka TV | Yooz | Yota | ||
YOTOPT | Youin | Youwei | Ytone | Yu | YU Fly | Yuandao | ||
YUHO | YUMKEM | YUNDOO | Yuno | YunSong | Yusun | Yxtel | ||
Z-Kai | Zaith | Zamolxe | Zatec | Zealot | Zeblaze | Zebra | ||
Zeeker | Zeemi | Zen | Zenek | Zentality | Zfiner | ZH&K | ||
Zidoo | ZIFRO | Zigo | ZIK | Zinox | Ziox | Zonda | ||
Zonko | Zoom | ZoomSmart | Zopo | ZTE | Zuum | Zync | ||
ZYQ | Zyrex | ||
Twoe | TWZ | Tymes | U-Magic | U.S. Cellular | UD | UE | ||
UGINE | Ugoos | Uhans | Uhappy | Ulefone | Umax | UMIDIGI | ||
Unblock Tech | Uniden | Unihertz | Unimax | Uniqcell | Uniscope | Unistrong | ||
Unitech | UNIWA | Unknown | Unnecto | Unnion Technologies | UNNO | Unonu | ||
Unowhy | UOOGOU | Urovo | UTime | UTOK | UTStarcom | UZ Mobile | ||
V-Gen | V-HOME | V-HOPE | v-mobile | VAIO | VALEM | VALTECH | ||
VANGUARD | Vankyo | Vargo | Vastking | VAVA | VC | VDVD | ||
Vega | Vekta | Venso | Venstar | Venturer | VEON | Verico | ||
Verizon | Vernee | Verssed | Versus | Vertex | Vertu | Verykool | ||
Vesta | Vestel | VETAS | Vexia | VGO TEL | ViBox | Victurio | ||
VIDA | Videocon | Videoweb | ViewSonic | VIIPOO | Vinabox | Vinga | ||
Vinsoc | Vios | Viper | Vipro | Virzo | Vision Touch | Visual Land | ||
Vitelcom | Vityaz | Viumee | Vivax | VIVIMAGE | Vivo | VIWA | ||
Vizio | Vizmo | VK Mobile | VKworld | Vodacom | Vodafone | VOGA | ||
Völfen | VOLIA | VOLKANO | Volla | Volt | Vonino | Vontar | ||
Vorago | Vorcom | Vorke | Vormor | Vortex | Voto | VOX | ||
Voxtel | Voyo | Vsmart | Vsun | VUCATIMES | Vue Micro | Vulcan | ||
VVETIME | WAF | Walker | Walton | Waltter | Wanmukang | WANSA | ||
WE | We. by Loewe. | Web TV | Webfleet | WeChip | Wecool | Weelikeit | ||
Weimei | WellcoM | WELLINGTON | Western Digital | Westpoint | Wexler | White Mobile | ||
Wieppo | Wigor | Wiko | Wileyfox | Winds | Wink | Winmax | ||
Winnovo | Winstar | Wintouch | Wiseasy | WIWA | WizarPos | Wizz | ||
Wolder | Wolfgang | Wolki | WONDER | Wonu | Woo | Wortmann | ||
Woxter | X-AGE | X-BO | X-Mobile | X-TIGI | X-View | X.Vision | ||
X88 | X96 | X96Q | Xcell | XCOM | Xcruiser | XElectron | ||
XGEM | XGIMI | Xgody | Xiaodu | Xiaolajiao | Xiaomi | Xion | ||
Xolo | Xoro | Xshitou | Xtouch | Xtratech | Xwave | XY Auto | ||
Yandex | Yarvik | YASIN | YELLYOUTH | YEPEN | Yes | Yestel | ||
Yezz | Yoka TV | Yooz | Yota | YOTOPT | Youin | Youwei | ||
Ytone | Yu | YU Fly | Yuandao | YUHO | YUMKEM | YUNDOO | ||
Yuno | YunSong | Yusun | Yxtel | Z-Kai | Zaith | Zamolxe | ||
Zatec | Zealot | Zeblaze | Zebra | Zeeker | Zeemi | Zen | ||
Zenek | Zentality | Zfiner | ZH&K | Zidoo | ZIFRO | Zigo | ||
ZIK | Zinox | Ziox | Zonda | Zonko | Zoom | ZoomSmart | ||
Zopo | ZTE | Zuum | Zync | ZYQ | Zyrex | ||
@@ -846,3 +912,3 @@ | ||
##### Support detect browsers list (529): | ||
##### Support detect browsers list (601): | ||
@@ -854,78 +920,88 @@ <details> | ||
--- | --- | --- | --- | --- | --- | --- | ||
115 Browser | 18+ Privacy Browser | 1DM Browser | 1DM+ Browser | 2345 Browser | 360 Browser | 360 Phone Browser | ||
7654 Browser | 7Star | ABrowse | AdBlock Browser | Adult Browser | Aloha Browser | Aloha Browser Lite | ||
ALVA | Amaya | Amaze Browser | Amerigo | Amiga Aweb | Amiga Voyager | Amigo | ||
Android Browser | Anka Browser | ANT Fresco | ANTGalio | AOL Desktop | AOL Shield | AOL Shield Pro | ||
APN Browser | AppBrowzer | APUS Browser | Arctic Fox | Arora | Arvin | Ask.com | ||
Asus Browser | Atlas | Atom | Atomic Web Browser | Avant Browser | Avast Secure Browser | AVG Secure Browser | ||
Avira Secure Browser | AwoX | Azka Browser | B-Line | Baidu Browser | Baidu Spark | Bangla Browser | ||
115 Browser | 18+ Privacy Browser | 1DM Browser | 1DM+ Browser | 2345 Browser | 360 Phone Browser | 360 Secure Browser | ||
7654 Browser | 7Star | ABrowse | Acoo Browser | AdBlock Browser | Adult Browser | Airfind Secure Browser | ||
Aloha Browser | Aloha Browser Lite | ALVA | Amaya | Amaze Browser | Amerigo | Amiga Aweb | ||
Amiga Voyager | Amigo | Android Browser | Anka Browser | ANT Fresco | ANTGalio | AOL Desktop | ||
AOL Explorer | AOL Shield | AOL Shield Pro | Aplix | APN Browser | AppBrowzer | APUS Browser | ||
Arc | Arctic Fox | Arora | Arvin | Ask.com | Asus Browser | Atlas | ||
Atom | Atomic Web Browser | Avant Browser | Avast Secure Browser | AVG Secure Browser | Avira Secure Browser | AwoX | ||
Azka Browser | B-Line | Baidu Browser | Baidu Spark | Bang | Bangla Browser | Basic Web Browser | ||
Basilisk | Beaker Browser | Beamrise | Belva Browser | Beonex | Berry Browser | Beyond Private Browser | ||
BF Browser | Bitchute Browser | Biyubi | Black Lion Browser | BlackBerry Browser | BlackHawk | Bloket | ||
Blue Browser | Bonsai | Borealis Navigator | Brave | BriskBard | Browlser | BrowsBit | ||
BrowseHere | Browser Hup Pro | BrowseX | Browspeed Browser | Browzar | Bunjalloo | Byffox | ||
Cake Browser | Camino | Cave Browser | CCleaner | Centaury | CG Browser | ChanjetCloud | ||
Charon | Chedot | Cheetah Browser | Cherry Browser | Cheshire | Chim Lac | Chowbo | ||
Chrome | Chrome Frame | Chrome Mobile | Chrome Mobile iOS | Chrome Webview | ChromePlus | Chromium | ||
Chromium GOST | CM Browser | CM Mini | Coast | Coc Coc | Colibri | CometBird | ||
Comfort Browser | Comodo Dragon | Conkeror | CoolBrowser | CoolNovo | Cornowser | COS Browser | ||
Craving Explorer | Crazy Browser | Crusta | Cunaguaro | Cyberfox | CyBrowser | Dark Browser | ||
Dark Web Browser | dbrowser | Debuggable Browser | Decentr | Deepnet Explorer | deg-degan | Deledao | ||
Delta Browser | Desi Browser | DeskBrowse | Dillo | Dolphin | Dolphin Zero | Dooble | ||
Dorado | Dot Browser | Dragon Browser | DUC Browser | DuckDuckGo Privacy Browser | Easy Browser | Ecosia | ||
Edge WebView | EinkBro | Element Browser | Elements Browser | Elinks | Epic | Espial TV Browser | ||
EUI Browser | Every Browser | Explore Browser | eZ Browser | Falkon | Fast Browser UC Lite | Fast Explorer | ||
Faux Browser | Fennec | Fiery Browser | Firebird | Firefox | Firefox Focus | Firefox Klar | ||
Firefox Mobile | Firefox Mobile iOS | Firefox Reality | Firefox Rocket | Fireweb | Fireweb Navigator | Flash Browser | ||
Flast | Float Browser | Flock | Floorp | Flow | Flow Browser | Fluid | ||
Flyperlink | Freedom Browser | FreeU | Frost+ | Fulldive | G Browser | Galeon | ||
Gener8 | Ghostery Privacy Browser | GinxDroid Browser | Glass Browser | GNOME Web | GoBrowser | GOG Galaxy | ||
Google Earth | Google Earth Pro | Harman Browser | HasBrowser | Hawk Quick Browser | Hawk Turbo Browser | Headless Chrome | ||
Helio | Hexa Web Browser | Hi Browser | hola! Browser | Holla Web Browser | HotJava | HTC Browser | ||
Huawei Browser | Huawei Browser Mobile | HUB Browser | IBrowse | iBrowser | iBrowser Mini | iCab | ||
iCab Mobile | IceCat | IceDragon | Iceweasel | iDesktop PC Browser | IE Browser Fast | IE Mobile | ||
InBrowser | Indian UC Mini Browser | Inspect Browser | Insta Browser | Internet Browser Secure | Internet Explorer | Iridium | ||
Iron | Iron Mobile | Isivioo | IVVI Browser | Japan Browser | Jasmine | JavaFX | ||
Jelly | Jig Browser | Jig Browser Plus | Jio Browser | JioPages | K-meleon | K.Browser | ||
Kapiko | Kazehakase | Keepsafe Browser | Kids Safe Browser | Kindle Browser | Kinza | Kiwi | ||
Kode Browser | Konqueror | KUTO Mini Browser | Kylo | Lagatos Browser | Lark Browser | Lenovo Browser | ||
Lexi Browser | LG Browser | LieBaoFast | Light | Lightning Browser | Lilo | Links | ||
LogicUI TV Browser | Lolifox | Lovense Browser | LT Browser | LuaKit | LUJO TV Browser | Lulumi | ||
Lunascape | Lunascape Lite | Lynket Browser | Lynx | Maelstrom | Mandarin | MarsLab Web Browser | ||
MAUI WAP Browser | Maxthon | MaxTube Browser | mCent | Me Browser | Meizu Browser | Mercury | ||
MicroB | Microsoft Edge | Midori | Midori Lite | Minimo | Mint Browser | MIUI Browser | ||
Mmx Browser | Mobicip | Mobile Safari | Mobile Silk | Monument Browser | MxNitro | Mypal | ||
Naked Browser | Naked Browser Pro | Navigateur Web | NCSA Mosaic | NetFront | NetFront Life | NetPositive | ||
Netscape | NetSurf | NextWord Browser | NFS Browser | Nokia Browser | Nokia OSS Browser | Nokia Ovi Browser | ||
NOMone VR Browser | Norton Secure Browser | Nova Video Downloader Pro | Nox Browser | NTENT Browser | Nuanti Meta | Obigo | ||
Blue Browser | Bluefy | Bonsai | Borealis Navigator | Brave | BriskBard | BroKeep Browser | ||
Browlser | BrowsBit | BrowseHere | Browser Hup Pro | BrowseX | Browspeed Browser | Browzar | ||
Bunjalloo | BXE Browser | Byffox | Cake Browser | Camino | Catalyst | Catsxp | ||
Cave Browser | CCleaner | Centaury | CG Browser | ChanjetCloud | Charon | Chedot | ||
Cheetah Browser | Cherry Browser | Cheshire | Chim Lac | Chowbo | Chrome | Chrome Frame | ||
Chrome Mobile | Chrome Mobile iOS | Chrome Webview | ChromePlus | Chromium | Chromium GOST | Classilla | ||
Cliqz | CM Browser | CM Mini | Coast | Coc Coc | Colibri | Colom Browser | ||
Columbus Browser | CometBird | Comfort Browser | Comodo Dragon | Conkeror | CoolBrowser | CoolNovo | ||
Cornowser | COS Browser | Craving Explorer | Crazy Browser | Crow Browser | Crusta | Cunaguaro | ||
Cyberfox | CyBrowser | Dark Browser | Dark Web Browser | dbrowser | Debuggable Browser | Decentr | ||
Deepnet Explorer | deg-degan | Deledao | Delta Browser | Desi Browser | DeskBrowse | Diigo Browser | ||
Dillo | DoCoMo | Dolphin | Dolphin Zero | Dooble | Dorado | Dot Browser | ||
Dragon Browser | DUC Browser | DuckDuckGo Privacy Browser | East Browser | Easy Browser | Ecosia | Edge WebView | ||
EinkBro | Element Browser | Elements Browser | Elinks | Eolie | Epic | Espial TV Browser | ||
EudoraWeb | EUI Browser | Every Browser | Explore Browser | eZ Browser | Falkon | Fast Browser UC Lite | ||
Fast Explorer | Faux Browser | Fennec | fGet | Fiery Browser | Firebird | Firefox | ||
Firefox Focus | Firefox Klar | Firefox Mobile | Firefox Mobile iOS | Firefox Reality | Firefox Rocket | Fireweb | ||
Fireweb Navigator | Flash Browser | Flast | Float Browser | Flock | Floorp | Flow | ||
Flow Browser | Fluid | Flyperlink | Freedom Browser | FreeU | Frost | Frost+ | ||
Fulldive | G Browser | Galeon | Gener8 | Ghostery Privacy Browser | GinxDroid Browser | Glass Browser | ||
GNOME Web | GO Browser | GoBrowser | Godzilla Browser | GOG Galaxy | GoKu | Google Earth | ||
Google Earth Pro | GreenBrowser | Harman Browser | HasBrowser | Hawk Quick Browser | Hawk Turbo Browser | Headless Chrome | ||
Helio | Hexa Web Browser | Hi Browser | hola! Browser | Holla Web Browser | HotBrowser | HotJava | ||
HTC Browser | Huawei Browser | Huawei Browser Mobile | HUB Browser | IBrowse | iBrowser | iBrowser Mini | ||
iCab | iCab Mobile | IceCat | IceDragon | Iceweasel | iDesktop PC Browser | IE Browser Fast | ||
IE Mobile | Impervious Browser | InBrowser | Incognito Browser | Indian UC Mini Browser | Inspect Browser | Insta Browser | ||
Internet Browser Secure | Internet Explorer | Intune Managed Browser | Iridium | Iron | Iron Mobile | Isivioo | ||
IVVI Browser | Japan Browser | Jasmine | JavaFX | Jelly | Jig Browser | Jig Browser Plus | ||
JioSphere | JUZI Browser | K-meleon | K-Ninja | K.Browser | Kapiko | Kazehakase | ||
Keepsafe Browser | Kids Safe Browser | Kindle Browser | Kinza | Kiwi | Kode Browser | Konqueror | ||
KUTO Mini Browser | Kylo | Lagatos Browser | Lark Browser | Legan Browser | Lenovo Browser | Lexi Browser | ||
LG Browser | LieBaoFast | Light | Lightning Browser | Lilo | Links | Liri Browser | ||
LogicUI TV Browser | Lolifox | Lotus | Lovense Browser | LT Browser | LuaKit | LUJO TV Browser | ||
Lulumi | Lunascape | Lunascape Lite | Lynket Browser | Lynx | Maelstrom | Mandarin | ||
MarsLab Web Browser | MAUI WAP Browser | MaxBrowser | Maxthon | MaxTube Browser | mCent | Me Browser | ||
Meizu Browser | Mercury | MicroB | Microsoft Edge | Midori | Midori Lite | Minimo | ||
Mint Browser | MIUI Browser | MixerBox AI | Mmx Browser | Mobicip | Mobile Safari | Mobile Silk | ||
Mogok Browser | Monument Browser | MxNitro | Mypal | Naked Browser | Naked Browser Pro | Navigateur Web | ||
NCSA Mosaic | NetFront | NetFront Life | NetPositive | Netscape | NetSurf | NextWord Browser | ||
NFS Browser | Ninetails | Nokia Browser | Nokia OSS Browser | Nokia Ovi Browser | NOMone VR Browser | Norton Private Browser | ||
Nova Video Downloader Pro | Nox Browser | NTENT Browser | Nuanti Meta | Nuviu | Obigo | Ocean Browser | ||
OceanHero | Oculus Browser | Odd Browser | Odin | Odin Browser | Odyssey Web Browser | Off By One | ||
Office Browser | OH Browser | OH Private Browser | OhHai Browser | OmniWeb | ONE Browser | Open Browser | ||
Open Browser 4U | Open Browser fast 5G | Open TV Browser | OpenFin | Openwave Mobile Browser | Opera | Opera Crypto | ||
Opera Devices | Opera GX | Opera Mini | Opera Mini iOS | Opera Mobile | Opera Neon | Opera Next | ||
Opera Touch | Oppo Browser | Opus Browser | Orca | Ordissimo | Oregano | Origin In-Game Overlay | ||
Origyn Web Browser | OrNET Browser | Otter Browser | Pale Moon | Palm Blazer | Palm Pre | Palm WebPro | ||
Palmscape | Pawxy | Peeps dBrowser | Perfect Browser | Phantom Browser | Phantom.me | Phoenix | ||
Phoenix Browser | Pi Browser | PICO Browser | PlayFree Browser | Pluma | PocketBook Browser | Polaris | ||
Polarity | PolyBrowser | Polypane | Privacy Explorer Fast Safe | PrivacyWall | PronHub Browser | PSI Secure Browser | ||
Puffin | Puffin Web Browser | Pure Lite Browser | Pure Mini Browser | Qazweb | QQ Browser | QQ Browser Lite | ||
QQ Browser Mini | QtWebEngine | Quark | Quick Browser | QupZilla | Qutebrowser | Qwant Mobile | ||
Rabbit Private Browser | Raise Fast Browser | Realme Browser | Rekonq | Reqwireless WebViewer | RockMelt | Roku Browser | ||
Safari | Safari Technology Preview | Safe Exam Browser | Sailfish Browser | SalamWeb | Samsung Browser | Samsung Browser Lite | ||
Savannah Browser | SavySoda | Secure Browser | Secure Private Browser | Seewo Browser | SEMC-Browser | Seraphic Sraf | ||
Office Browser | OH Browser | OH Private Browser | OhHai Browser | OmniWeb | OnBrowser Lite | ONE Browser | ||
Onion Browser | Open Browser | Open Browser 4U | Open Browser fast 5G | Open TV Browser | OpenFin | Openwave Mobile Browser | ||
Opera | Opera Crypto | Opera Devices | Opera GX | Opera Mini | Opera Mini iOS | Opera Mobile | ||
Opera Neon | Opera Next | Opera Touch | Oppo Browser | Opus Browser | Orca | Ordissimo | ||
Oregano | Origin In-Game Overlay | Origyn Web Browser | OrNET Browser | Otter Browser | Pale Moon | Palm Blazer | ||
Palm Pre | Palm WebPro | Palmscape | Pawxy | Peeps dBrowser | Perfect Browser | Phantom Browser | ||
Phantom.me | Phoenix | Phoenix Browser | Pi Browser | PICO Browser | PirateBrowser | PlayFree Browser | ||
Pluma | PocketBook Browser | Polaris | Polarity | PolyBrowser | Polypane | Privacy Explorer Fast Safe | ||
PrivacyWall | Private Internet Browser | PronHub Browser | Proxy Browser | PSI Secure Browser | Puffin | Puffin Web Browser | ||
Pure Lite Browser | Pure Mini Browser | Qazweb | Qiyu | QJY TV Browser | Qmamu | QQ Browser | ||
QQ Browser Lite | QQ Browser Mini | QtWebEngine | Quark | Quick Browser | Quick Search TV | QupZilla | ||
Qutebrowser | Qwant Mobile | Rabbit Private Browser | Raise Fast Browser | Rakuten Browser | Rakuten Web Search | Raspbian Chromium | ||
Realme Browser | Rekonq | Reqwireless WebViewer | RockMelt | Roku Browser | Safari | Safari Technology Preview | ||
Safe Exam Browser | Sailfish Browser | SalamWeb | Samsung Browser | Samsung Browser Lite | Savannah Browser | SavySoda | ||
SberBrowser | Secure Browser | Secure Private Browser | SecureX | Seewo Browser | SEMC-Browser | Seraphic Sraf | ||
Seznam Browser | SFive | Sharkee Browser | Shiira | Sidekick | SilverMob US | SimpleBrowser | ||
SiteKiosk | Sizzy | Skyfire | Sleipnir | Slimjet | Smart Browser | Smart Lenovo Browser | ||
Smart Search & Web Browser | Smooz | Snowshoe | Sogou Explorer | Sogou Mobile Browser | Sony Small Browser | SOTI Surf | ||
Soul Browser | Soundy Browser | SP Browser | Spectre Browser | Splash | Sputnik Browser | Stampy Browser | ||
Stargon | START Internet Browser | Steam In-Game Overlay | Streamy | Sunflower Browser | Sunrise | Super Fast Browser | ||
SuperBird | SuperFast Browser | surf | Surf Browser | Sushi Browser | Sweet Browser | Swiftfox | ||
SX Browser | T-Browser | t-online.de Browser | T+Browser | Tao Browser | TenFourFox | Tenta Browser | ||
Tesla Browser | Tint Browser | Tizen Browser | ToGate | Tor Browser | TUC Mini Browser | Tungsten | ||
TV Bro | TweakStyle | U Browser | UBrowser | UC Browser | UC Browser HD | UC Browser Mini | ||
UC Browser Turbo | Ui Browser Mini | Ume Browser | UR Browser | Uzbl | Vast Browser | vBrowser | ||
Vegas Browser | Venus Browser | Vertex Surf | Via | Viasat Browser | Vision Mobile Browser | Vivaldi | ||
Vivid Browser Mini | vivo Browser | VMware AirWatch | Waterfox | Wave Browser | Wavebox | Wear Internet Browser | ||
Web Browser & Explorer | Web Explorer | WebPositive | WeTab Browser | Whale Browser | Wolvic | World Browser | ||
wOSBrowser | X Browser Lite | X-VPN | xBrowser | XBrowser Mini | xBrowser Pro Super Fast | Xiino | ||
XNX Browser | Xooloo Internet | xStand | XtremeCast | Xvast | Yaani Browser | YAGI | ||
Yahoo! Japan Browser | Yandex Browser | Yandex Browser Lite | Yo Browser | Yolo Browser | YouCare | Yuzu Browser | ||
Zetakey | Zirco Browser | Zordo Browser | Zvu | ||
SiteKiosk | Sizzy | Skye | Skyfire | Sleipnir | SlimBoat | Slimjet | ||
Smart Browser | Smart Lenovo Browser | Smart Search & Web Browser | Smooz | Snowshoe | Sogou Explorer | Sogou Mobile Browser | ||
Sony Small Browser | SOTI Surf | Soul Browser | Soundy Browser | SP Browser | Spectre Browser | Splash | ||
Sputnik Browser | Stampy Browser | Stargon | START Internet Browser | Steam In-Game Overlay | Streamy | Sunflower Browser | ||
Sunrise | Super Fast Browser | SuperBird | SuperFast Browser | surf | Surf Browser | Surfy Browser | ||
Sushi Browser | Sweet Browser | Swiftfox | SX Browser | T-Browser | t-online.de Browser | T+Browser | ||
Tao Browser | tararia | TenFourFox | Tenta Browser | Tesla Browser | Thor | Tint Browser | ||
Tizen Browser | ToGate | Tor Browser | TrueLocation Browser | TUC Mini Browser | Tungsten | TV Bro | ||
TweakStyle | U Browser | UBrowser | UC Browser | UC Browser HD | UC Browser Mini | UC Browser Turbo | ||
Ui Browser Mini | Ume Browser | UR Browser | Uzbl | Vast Browser | vBrowser | VD Browser | ||
Vegas Browser | Venus Browser | Vertex Surf | Vewd Browser | Via | Viasat Browser | VibeMate | ||
Vision Mobile Browser | Vivaldi | Vivid Browser Mini | vivo Browser | VMware AirWatch | Vonkeror | w3m | ||
Waterfox | Wave Browser | Wavebox | Wear Internet Browser | Web Browser & Explorer | Web Explorer | WebDiscover | ||
Webian Shell | WebPositive | WeTab Browser | Wexond | Whale Browser | Wolvic | World Browser | ||
wOSBrowser | Wyzo | X Browser Lite | X-VPN | xBrowser | XBrowser Mini | xBrowser Pro Super Fast | ||
Xiino | XNX Browser | Xooloo Internet | xStand | XtremeCast | Xvast | Yaani Browser | ||
YAGI | Yahoo! Japan Browser | Yandex Browser | Yandex Browser Lite | Yo Browser | Yolo Browser | YouBrowser | ||
YouCare | Yuzu Browser | Zetakey | Zirco Browser | Zordo Browser | Zvu | ||
@@ -932,0 +1008,0 @@ </details> |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2647307
85
7224
992
11