mirror of
https://github.com/faisalman/ua-parser-js.git
synced 2025-11-16 15:11:50 +03:00
Compare commits
70 Commits
2.0.0-beta
...
2.0.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d50be39f3b | ||
|
|
44d9d5700f | ||
|
|
99d59f7e4c | ||
|
|
768b622603 | ||
|
|
5328642e18 | ||
|
|
bdcd927304 | ||
|
|
db3423a76c | ||
|
|
173325faa1 | ||
|
|
5190905df8 | ||
|
|
0a46ac396a | ||
|
|
f7810dbfcf | ||
|
|
0543b87c02 | ||
|
|
39590f112d | ||
|
|
1a22c6951f | ||
|
|
8991d34e56 | ||
|
|
1a2ef00509 | ||
|
|
12c2c2e48a | ||
|
|
85bf7076d3 | ||
|
|
1fa3d02594 | ||
|
|
4cd867a36e | ||
|
|
6b6fcc68f5 | ||
|
|
760e85bbe7 | ||
|
|
5a8ce35054 | ||
|
|
150d3c6b4a | ||
|
|
e87c794fd9 | ||
|
|
d0db40c290 | ||
|
|
8dce4cc514 | ||
|
|
a43d659577 | ||
|
|
b29a9a7ffb | ||
|
|
10ec6349e2 | ||
|
|
6f02da06e0 | ||
|
|
23dc320be4 | ||
|
|
8852b03739 | ||
|
|
4d950db145 | ||
|
|
b5b5475ab4 | ||
|
|
7c22bc587f | ||
|
|
d6d8ac7cb4 | ||
|
|
54c633aac5 | ||
|
|
9c5d6ee70e | ||
|
|
b5c62b0c82 | ||
|
|
0c49d75074 | ||
|
|
09904a0a47 | ||
|
|
3622b614a7 | ||
|
|
e4f2463849 | ||
|
|
fdbeabbaed | ||
|
|
2046fe5209 | ||
|
|
5173a5442f | ||
|
|
106d882fba | ||
|
|
7abc8b9ecc | ||
|
|
7ad3e3b451 | ||
|
|
26f7e7d59e | ||
|
|
f8f71c65d4 | ||
|
|
17f0c1e1cd | ||
|
|
9cc274fb6f | ||
|
|
f56073bb3e | ||
|
|
5c10e2b107 | ||
|
|
46ff3df974 | ||
|
|
cfc01470b5 | ||
|
|
d565f65280 | ||
|
|
69ed6cec77 | ||
|
|
b51ae9eb38 | ||
|
|
125f0d9f16 | ||
|
|
e614108911 | ||
|
|
77e0aa1ac6 | ||
|
|
119515edd2 | ||
|
|
c8c6d121e0 | ||
|
|
f9ac3566cb | ||
|
|
1d776d469b | ||
|
|
e6a085f710 | ||
|
|
177a496c34 |
58
CHANGELOG.md
58
CHANGELOG.md
@@ -16,10 +16,68 @@
|
|||||||
- Provided Extensions submodule `'ua-parser-js/extensions'`
|
- Provided Extensions submodule `'ua-parser-js/extensions'`
|
||||||
- Provided Helpers submodule `'ua-parser-js/helpers'`
|
- Provided Helpers submodule `'ua-parser-js/helpers'`
|
||||||
|
|
||||||
|
## Version 2.0.0-beta.3
|
||||||
|
|
||||||
|
- Breaking:
|
||||||
|
- AR/VR devices moved to new device type: `xr`
|
||||||
|
- New property in `browser`: `type`
|
||||||
|
- In `ua-parser-js/extensions` submodule, `bots` divided into `crawler` / `fetcher`
|
||||||
|
- New features:
|
||||||
|
- Parse directly from command line using `npx ua-parser-js`
|
||||||
|
- Extensions can be passed as a list to `UAParser()`
|
||||||
|
- Add new browser: Pico Browser, Twitter, Wolvic
|
||||||
|
- Improve browser detection: DuckDuckGo, ICEBrowser, Klar, QQ, Sleipnir
|
||||||
|
- Improve device detection: Oculus Quest & Oppo Pad
|
||||||
|
- Update latest client hints spec: `formFactor` -> `formFactors`
|
||||||
|
|
||||||
|
## Version 2.0.0-beta.2
|
||||||
|
|
||||||
|
- Increase UA_MAX_LENGTH to 500
|
||||||
|
- Add TypeScript declaration file in `ua-parser-js/extensions` submodule
|
||||||
|
- Improve TypeScript module resolution
|
||||||
|
- Add new methods in `ua-parser-js/helpers` submodule: `isAppleSilicon()` & `isChromiumBased()`
|
||||||
|
- Fix misidentified WebView token as device model
|
||||||
|
- Add new browser: Alipay, Klarna, Opera GX, Smart Lenovo Browser, Vivo Browser
|
||||||
|
- Rename browser: Avant, Baidu, Samsung Internet, Sogou Explorer, Sogou Mobile, WeChat
|
||||||
|
- Improve client-hints detection: Edge, Xbox
|
||||||
|
|
||||||
|
## Version 2.0.0-beta.1
|
||||||
|
|
||||||
|
- Update Client Hints Form-Factor
|
||||||
|
- Provide in-package type definitions
|
||||||
|
- Add new device: Ulefone
|
||||||
|
- Improve device detection: Realme, Xiaomi Redmi
|
||||||
|
|
||||||
|
## Version 2.0.0-alpha.3
|
||||||
|
|
||||||
|
- Add `withFeatureCheck()` method
|
||||||
|
- Add `isFrozenUA()` method in `ua-parser-js/helpers` submodule
|
||||||
|
- Add `MediaPlayers` & `Modules` in `ua-parser-js/extensions` submodule
|
||||||
|
- Fix issue with ESM import
|
||||||
|
|
||||||
|
## Version 2.0.0-alpha.2
|
||||||
|
|
||||||
|
- Fix browser result always returning Chromium when using withClientHints()
|
||||||
|
- Fix infinite-loop when await-ing withClientHints() in non-client-hints browser
|
||||||
|
|
||||||
|
## Version 2.0.0-alpha.1
|
||||||
|
|
||||||
|
- Initial work on new major version
|
||||||
|
|
||||||
|
|
||||||
# Version 0.7 / 1.0
|
# Version 0.7 / 1.0
|
||||||
|
|
||||||
Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion.
|
Version 1.0.x is basically the equivalent of version 0.7.x. See [#536](https://github.com/faisalman/ua-parser-js/issues/536) for the reason behind this confusion.
|
||||||
|
|
||||||
|
## Version 0.7.37
|
||||||
|
|
||||||
|
- Fix misidentified WebView token as device model
|
||||||
|
- Increase UA_MAX_LENGTH to 500
|
||||||
|
- Add new browser: Alipay, Klarna, Smart Lenovo Browser, Vivo Browser
|
||||||
|
- Add new device: Ulefone
|
||||||
|
- Improve device detection: Realme, Xiaomi Redmi
|
||||||
|
- Rename browser: Avant, Baidu, Samsung Internet, Sogou Explorer, Sogou Mobile, WeChat
|
||||||
|
|
||||||
## Version 0.7.36 / 1.0.36
|
## Version 0.7.36 / 1.0.36
|
||||||
- Add new browser: Snapchat
|
- Add new browser: Snapchat
|
||||||
- Add new devices: Infinix, Tecno
|
- Add new devices: Infinix, Tecno
|
||||||
|
|||||||
38
LICENSE.md
38
LICENSE.md
@@ -1,8 +1,8 @@
|
|||||||
# UAPARSER.JS PRO PERSONAL LICENSE
|
# UAPARSER.JS PRO ENTERPRISE LICENSE
|
||||||
|
|
||||||
Version 1, October 2023
|
Version 2, July 2024
|
||||||
|
|
||||||
Copyright (C) 2023 Faisal Salman <f+ua-parser-js@faisalman.com>
|
Copyright (C) 2023-2024 Faisal Salman <f+ua-parser-js@faisalman.com>
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ Copyright (C) 2023 Faisal Salman <f+ua-parser-js@faisalman.com>
|
|||||||
|
|
||||||
"We" are the team behind UAParser.js.
|
"We" are the team behind UAParser.js.
|
||||||
|
|
||||||
"You" are the individual who is responsible for purchasing this license.
|
"You" are the individual, organization, or company who is responsible for purchasing this license.
|
||||||
|
|
||||||
"The Code" is UAParser.js.
|
"The Code" is UAParser.js.
|
||||||
|
|
||||||
@@ -20,33 +20,31 @@ Copyright (C) 2023 Faisal Salman <f+ua-parser-js@faisalman.com>
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
We retains all title, intellectual property, and ownership rights to The Code.
|
We retain all title, intellectual property, and ownership rights to The Code.
|
||||||
|
|
||||||
The Code is licensed, not sold, to You for use solely subject to the terms and conditions detailed here.
|
The Code is licensed, not sold, to You for use solely subject to the terms and conditions detailed here.
|
||||||
|
|
||||||
We grant you (and only you) a personal, limited, non-exclusive, non-transferable, non-sublicensable, royalty-free right to use, copy, and modify The Code.
|
We grant You (and only You) a limited, non-exclusive, non-transferable, non-sublicensable, royalty-free right to use, copy, and modify The Code.
|
||||||
|
|
||||||
This license is only valid for You as 1 (one) individual and can not be transferred to other individual or organization.
|
This license is only valid for You as one (1) individual, organization, or company and cannot be transferred to another individual, organization, or company.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Rights
|
## Rights
|
||||||
|
|
||||||
You may use and modify The Code to create as many personal, hobby, educational, and other non-profit use as you want for yourself.
|
You may use, copy, and modify The Code for an indefinite number of Projects.
|
||||||
|
|
||||||
You may create any number of copies of The Code for yourself.
|
You have the right to receive lifetime updates and one (1) year of support, starting from the time you make the purchase.
|
||||||
|
|
||||||
You have the right to get lifetime updates and a 1 (one) year support, starting from the time you make the purchase.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Restriction
|
## Restrictions
|
||||||
|
|
||||||
You may not use and modify The Code in such a way that may be used directly for commercial purpose.
|
You may not redistribute The Code, as-is or modified, except as a part of a Project that you made.
|
||||||
|
|
||||||
You may not redistribute The Code, as-is or modified, except as a part of a Project that you made for yourself.
|
If You transfer a Project to a client, the use of The Code must be limited to the original functionality that You created for them. The Code must not be extracted, reproduced, or used in any other way. You must inform your client of this condition.
|
||||||
|
|
||||||
You may not deliver a Project that contains The Code as an open-source Project that might be used for commercial purpose to the general public, except with our written consent.
|
You may not deliver a Project that contains The Code as an open-source Project that might be used for commercial purposes by the general public, except with our written consent.
|
||||||
|
|
||||||
You may not use The Code for unlawful, inappropriate, illegal, or offensive purposes.
|
You may not use The Code for unlawful, inappropriate, illegal, or offensive purposes.
|
||||||
|
|
||||||
@@ -54,19 +52,19 @@ You may not use The Code for unlawful, inappropriate, illegal, or offensive purp
|
|||||||
|
|
||||||
## Limitations
|
## Limitations
|
||||||
|
|
||||||
The Code is provided 'as is' without warranty of any kind, expressed, or implied.
|
The Code is provided 'as is' without warranty of any kind, expressed or implied.
|
||||||
|
|
||||||
We shall not be liable for any damages, including but not limited to, direct, indirect, special, incidental, or consequential damages or losses that occur by the use of The Code.
|
We shall not be liable for any damages, including but not limited to, direct, indirect, special, incidental, or consequential damages or losses that occur by the use of The Code.
|
||||||
|
|
||||||
We reserve the rights to discontinue the lifetime updates for The Code at any time, with or without notice.
|
We reserve the right to discontinue the lifetime updates for The Code at any time, with or without notice.
|
||||||
|
|
||||||
We offer support only for question within the scope of The Code functionality or related at our sole discretion.
|
We offer support only for questions within the scope of The Code's functionality or related issues at our sole discretion.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Terminations
|
## Termination
|
||||||
|
|
||||||
This license works indefinitely but can be revoked at any time if there is a violation to any of the terms.
|
This license is effective indefinitely but can be revoked at any time if there is a violation of any of the terms.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
22
PULL_REQUEST_TEMPLATE.md
Normal file
22
PULL_REQUEST_TEMPLATE.md
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Prerequisites
|
||||||
|
|
||||||
|
- [ ] I have read and follow the contributing guidelines
|
||||||
|
- [ ] I have read and accept the [Contributor License Agreement (CLA)](https://gist.github.com/faisalman/2ed16621ebb544157eba85a7f7381417) Document and I hereby sign the CLA
|
||||||
|
|
||||||
|
# Type of Change
|
||||||
|
|
||||||
|
Bug fix, feature, docs update, ...
|
||||||
|
|
||||||
|
# Description
|
||||||
|
|
||||||
|
Please include a summary of the change (current behavior vs new behavior), which issue is fixed (you can also link to an open issue here), and why this change is necessary.
|
||||||
|
|
||||||
|
# Test
|
||||||
|
|
||||||
|
Please describe the tests that you ran to verify your changes.
|
||||||
|
|
||||||
|
# Impact
|
||||||
|
|
||||||
|
Does this PR introduce a breaking change? What changes might users need to make due to this PR?
|
||||||
|
|
||||||
|
# Other Info
|
||||||
12
README.md
12
README.md
@@ -1,23 +1,23 @@
|
|||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://uaparser.js.org"><img src="https://raw.githubusercontent.com/faisalman/ua-parser-js/gh-pages/images/uap-header.png"></a>
|
<a href="https://uaparser.dev"><img src="https://raw.githubusercontent.com/faisalman/ua-parser-js/gh-pages/images/uap-header.png"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# UAParser.js
|
# UAParser.js
|
||||||
|
|
||||||
Thank you for purchasing UAParser.js PRO Personal License, if you haven't please oreder here: https://store.faisalman.com
|
Thank you for purchasing UAParser.js PRO Enterprise License, if you haven't please order here: https://store.faisalman.com
|
||||||
|
|
||||||
# Download
|
# Download
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm install @ua-parser-js/pro-personal
|
npm install @ua-parser-js/pro-enterprise
|
||||||
```
|
```
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
https://docs.uaparser.js.org/v2
|
https://docs.uaparser.dev
|
||||||
|
|
||||||
# License
|
# License
|
||||||
|
|
||||||
UAParser.js PRO Personal
|
UAParser.js PRO Enterprise
|
||||||
|
|
||||||
Copyright (c) 2012-2023 Faisal Salman <<f@faisalman.com>>
|
Copyright (c) 2012-2024 Faisal Salman <<f@faisalman.com>>
|
||||||
|
|||||||
6
dist/ua-parser.min.js
vendored
6
dist/ua-parser.min.js
vendored
File diff suppressed because one or more lines are too long
6
dist/ua-parser.pack.js
vendored
6
dist/ua-parser.pack.js
vendored
File diff suppressed because one or more lines are too long
240
package-lock.json
generated
240
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ua-parser-js",
|
"name": "@ua-parser-js/pro-enterprise",
|
||||||
"version": "2.0.0-beta.1",
|
"version": "2.0.0-beta.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ua-parser-js",
|
"name": "@ua-parser-js/pro-enterprise",
|
||||||
"version": "2.0.0-beta.1",
|
"version": "2.0.0-beta.3",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -21,10 +21,13 @@
|
|||||||
"url": "https://github.com/sponsors/faisalman"
|
"url": "https://github.com/sponsors/faisalman"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "UAParser.js-PRO-Personal",
|
"license": "UAParser.js-PRO-Enterprise",
|
||||||
|
"bin": {
|
||||||
|
"pro-enterprise": "script/cli.js"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/parser": "7.15.8",
|
"@babel/parser": "7.15.8",
|
||||||
"@babel/traverse": "7.15.4",
|
"@babel/traverse": "7.23.2",
|
||||||
"@jazzer.js/core": "^1.4.0",
|
"@jazzer.js/core": "^1.4.0",
|
||||||
"@playwright/test": "~1.32.2",
|
"@playwright/test": "~1.32.2",
|
||||||
"jshint": "~2.13.6",
|
"jshint": "~2.13.6",
|
||||||
@@ -52,12 +55,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
"version": "7.21.4",
|
"version": "7.22.13",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
|
||||||
"integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
|
"integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/highlight": "^7.18.6"
|
"@babel/highlight": "^7.22.13",
|
||||||
|
"chalk": "^2.4.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -114,34 +118,13 @@
|
|||||||
"node": ">=6.0.0"
|
"node": ">=6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/core/node_modules/@babel/traverse": {
|
|
||||||
"version": "7.21.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz",
|
|
||||||
"integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.21.4",
|
|
||||||
"@babel/generator": "^7.21.4",
|
|
||||||
"@babel/helper-environment-visitor": "^7.18.9",
|
|
||||||
"@babel/helper-function-name": "^7.21.0",
|
|
||||||
"@babel/helper-hoist-variables": "^7.18.6",
|
|
||||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
|
||||||
"@babel/parser": "^7.21.4",
|
|
||||||
"@babel/types": "^7.21.4",
|
|
||||||
"debug": "^4.1.0",
|
|
||||||
"globals": "^11.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/generator": {
|
"node_modules/@babel/generator": {
|
||||||
"version": "7.21.4",
|
"version": "7.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
|
||||||
"integrity": "sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA==",
|
"integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.21.4",
|
"@babel/types": "^7.23.0",
|
||||||
"@jridgewell/gen-mapping": "^0.3.2",
|
"@jridgewell/gen-mapping": "^0.3.2",
|
||||||
"@jridgewell/trace-mapping": "^0.3.17",
|
"@jridgewell/trace-mapping": "^0.3.17",
|
||||||
"jsesc": "^2.5.1"
|
"jsesc": "^2.5.1"
|
||||||
@@ -170,34 +153,34 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-environment-visitor": {
|
"node_modules/@babel/helper-environment-visitor": {
|
||||||
"version": "7.18.9",
|
"version": "7.22.20",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
|
||||||
"integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
|
"integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-function-name": {
|
"node_modules/@babel/helper-function-name": {
|
||||||
"version": "7.21.0",
|
"version": "7.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
|
||||||
"integrity": "sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==",
|
"integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/template": "^7.20.7",
|
"@babel/template": "^7.22.15",
|
||||||
"@babel/types": "^7.21.0"
|
"@babel/types": "^7.23.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-hoist-variables": {
|
"node_modules/@babel/helper-hoist-variables": {
|
||||||
"version": "7.18.6",
|
"version": "7.22.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
|
||||||
"integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
|
"integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.18.6"
|
"@babel/types": "^7.22.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -234,39 +217,6 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": {
|
|
||||||
"version": "7.21.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz",
|
|
||||||
"integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==",
|
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
|
||||||
"parser": "bin/babel-parser.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/helper-module-transforms/node_modules/@babel/traverse": {
|
|
||||||
"version": "7.21.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz",
|
|
||||||
"integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.21.4",
|
|
||||||
"@babel/generator": "^7.21.4",
|
|
||||||
"@babel/helper-environment-visitor": "^7.18.9",
|
|
||||||
"@babel/helper-function-name": "^7.21.0",
|
|
||||||
"@babel/helper-hoist-variables": "^7.18.6",
|
|
||||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
|
||||||
"@babel/parser": "^7.21.4",
|
|
||||||
"@babel/types": "^7.21.4",
|
|
||||||
"debug": "^4.1.0",
|
|
||||||
"globals": "^11.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/helper-simple-access": {
|
"node_modules/@babel/helper-simple-access": {
|
||||||
"version": "7.20.2",
|
"version": "7.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
|
||||||
@@ -280,30 +230,30 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-split-export-declaration": {
|
"node_modules/@babel/helper-split-export-declaration": {
|
||||||
"version": "7.18.6",
|
"version": "7.22.6",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||||
"integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
|
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/types": "^7.18.6"
|
"@babel/types": "^7.22.5"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-string-parser": {
|
"node_modules/@babel/helper-string-parser": {
|
||||||
"version": "7.19.4",
|
"version": "7.22.5",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
|
||||||
"integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
|
"integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-validator-identifier": {
|
"node_modules/@babel/helper-validator-identifier": {
|
||||||
"version": "7.19.1",
|
"version": "7.22.20",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||||
"integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
|
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
@@ -332,47 +282,14 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helpers/node_modules/@babel/parser": {
|
|
||||||
"version": "7.21.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz",
|
|
||||||
"integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==",
|
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
|
||||||
"parser": "bin/babel-parser.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/helpers/node_modules/@babel/traverse": {
|
|
||||||
"version": "7.21.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz",
|
|
||||||
"integrity": "sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/code-frame": "^7.21.4",
|
|
||||||
"@babel/generator": "^7.21.4",
|
|
||||||
"@babel/helper-environment-visitor": "^7.18.9",
|
|
||||||
"@babel/helper-function-name": "^7.21.0",
|
|
||||||
"@babel/helper-hoist-variables": "^7.18.6",
|
|
||||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
|
||||||
"@babel/parser": "^7.21.4",
|
|
||||||
"@babel/types": "^7.21.4",
|
|
||||||
"debug": "^4.1.0",
|
|
||||||
"globals": "^11.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@babel/highlight": {
|
"node_modules/@babel/highlight": {
|
||||||
"version": "7.18.6",
|
"version": "7.22.20",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
|
||||||
"integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
|
"integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-validator-identifier": "^7.18.6",
|
"@babel/helper-validator-identifier": "^7.22.20",
|
||||||
"chalk": "^2.0.0",
|
"chalk": "^2.4.2",
|
||||||
"js-tokens": "^4.0.0"
|
"js-tokens": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -392,23 +309,23 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/template": {
|
"node_modules/@babel/template": {
|
||||||
"version": "7.20.7",
|
"version": "7.22.15",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
|
||||||
"integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
|
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.18.6",
|
"@babel/code-frame": "^7.22.13",
|
||||||
"@babel/parser": "^7.20.7",
|
"@babel/parser": "^7.22.15",
|
||||||
"@babel/types": "^7.20.7"
|
"@babel/types": "^7.22.15"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/template/node_modules/@babel/parser": {
|
"node_modules/@babel/template/node_modules/@babel/parser": {
|
||||||
"version": "7.21.4",
|
"version": "7.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
|
||||||
"integrity": "sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw==",
|
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"parser": "bin/babel-parser.js"
|
"parser": "bin/babel-parser.js"
|
||||||
@@ -418,18 +335,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/traverse": {
|
"node_modules/@babel/traverse": {
|
||||||
"version": "7.15.4",
|
"version": "7.23.2",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
|
||||||
"integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==",
|
"integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.14.5",
|
"@babel/code-frame": "^7.22.13",
|
||||||
"@babel/generator": "^7.15.4",
|
"@babel/generator": "^7.23.0",
|
||||||
"@babel/helper-function-name": "^7.15.4",
|
"@babel/helper-environment-visitor": "^7.22.20",
|
||||||
"@babel/helper-hoist-variables": "^7.15.4",
|
"@babel/helper-function-name": "^7.23.0",
|
||||||
"@babel/helper-split-export-declaration": "^7.15.4",
|
"@babel/helper-hoist-variables": "^7.22.5",
|
||||||
"@babel/parser": "^7.15.4",
|
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||||
"@babel/types": "^7.15.4",
|
"@babel/parser": "^7.23.0",
|
||||||
|
"@babel/types": "^7.23.0",
|
||||||
"debug": "^4.1.0",
|
"debug": "^4.1.0",
|
||||||
"globals": "^11.1.0"
|
"globals": "^11.1.0"
|
||||||
},
|
},
|
||||||
@@ -437,14 +355,26 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@babel/traverse/node_modules/@babel/parser": {
|
||||||
|
"version": "7.23.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
|
||||||
|
"integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"parser": "bin/babel-parser.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@babel/types": {
|
"node_modules/@babel/types": {
|
||||||
"version": "7.21.4",
|
"version": "7.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
|
||||||
"integrity": "sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA==",
|
"integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/helper-string-parser": "^7.19.4",
|
"@babel/helper-string-parser": "^7.22.5",
|
||||||
"@babel/helper-validator-identifier": "^7.19.1",
|
"@babel/helper-validator-identifier": "^7.22.20",
|
||||||
"to-fast-properties": "^2.0.0"
|
"to-fast-properties": "^2.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1021,9 +951,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "1.3.6",
|
"version": "1.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.3.6.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
|
||||||
"integrity": "sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg==",
|
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.15.0",
|
"follow-redirects": "^1.15.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
Package.describe({
|
Package.describe({
|
||||||
name: 'faisalman:ua-parser-js',
|
name: 'faisalman:ua-parser-js',
|
||||||
version: '2.0.0-beta.1',
|
version: '2.0.0-beta.3',
|
||||||
summary: 'Lightweight JavaScript-based user-agent string parser',
|
summary: 'Lightweight JavaScript-based user-agent string parser',
|
||||||
git: 'https://github.com/faisalman/ua-parser-js.git',
|
git: 'https://github.com/faisalman/ua-parser-js.git',
|
||||||
documentation: 'readme.md'
|
documentation: 'readme.md'
|
||||||
|
|||||||
29
package.json
Normal file → Executable file
29
package.json
Normal file → Executable file
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"title": "UAParser.js PRO Personal",
|
"title": "UAParser.js PRO Enterprise",
|
||||||
"name": "@ua-parser-js/pro-personal",
|
"name": "@ua-parser-js/pro-enterprise",
|
||||||
"version": "2.0.0-beta.1",
|
"version": "2.0.0-beta.3",
|
||||||
"author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)",
|
"author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)",
|
||||||
"description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment",
|
"description": "Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent & Client Hints data. Supports browser & node.js environment",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
@@ -18,7 +18,8 @@
|
|||||||
"ua-parser-js",
|
"ua-parser-js",
|
||||||
"browser-detection",
|
"browser-detection",
|
||||||
"device-detection",
|
"device-detection",
|
||||||
"os-detection"
|
"os-detection",
|
||||||
|
"bot-detection"
|
||||||
],
|
],
|
||||||
"homepage": "https://github.com/faisalman/ua-parser-js",
|
"homepage": "https://github.com/faisalman/ua-parser-js",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -174,7 +175,8 @@
|
|||||||
"exports": {
|
"exports": {
|
||||||
".": {
|
".": {
|
||||||
"require": "./src/main/ua-parser.js",
|
"require": "./src/main/ua-parser.js",
|
||||||
"import": "./src/main/ua-parser.mjs"
|
"import": "./src/main/ua-parser.mjs",
|
||||||
|
"types": "./src/main/ua-parser.d.ts"
|
||||||
},
|
},
|
||||||
"./enums": {
|
"./enums": {
|
||||||
"require": "./src/enums/ua-parser-enums.js",
|
"require": "./src/enums/ua-parser-enums.js",
|
||||||
@@ -182,28 +184,35 @@
|
|||||||
},
|
},
|
||||||
"./extensions": {
|
"./extensions": {
|
||||||
"require": "./src/extensions/ua-parser-extensions.js",
|
"require": "./src/extensions/ua-parser-extensions.js",
|
||||||
"import": "./src/extensions/ua-parser-extensions.mjs"
|
"import": "./src/extensions/ua-parser-extensions.mjs",
|
||||||
|
"types": "./src/extensions/ua-parser-extensions.d.ts"
|
||||||
|
},
|
||||||
|
"./helpers": {
|
||||||
|
"require": "./src/helpers/ua-parser-helpers.js",
|
||||||
|
"import": "./src/helpers/ua-parser-helpers.mjs",
|
||||||
|
"types": "./src/helpers/ua-parser-helpers.d.ts"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"src"
|
"src"
|
||||||
],
|
],
|
||||||
|
"bin": "./script/cli.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "./script/build-dist.sh && ./script/build-module.js",
|
"build": "./script/build-dist.sh && ./script/build-module.js",
|
||||||
"build+test": "npm run build && npm run test",
|
"build+test": "npm run build && npm run test",
|
||||||
"fuzz": "jazzer ./test/jazzer-fuzz-test.js --sync",
|
"fuzz": "jazzer ./test/jazzer-fuzz-test.js --sync",
|
||||||
"test": "./script/test-all.sh",
|
"test": "./script/test-all.sh",
|
||||||
"test:dts": "tsd --typings src/main/ua-parser.d.ts --files test/dts-test.ts",
|
"test:dts-lint": "tsd --typings src/main/ua-parser.d.ts --files test/dts-test.ts",
|
||||||
"test:eslint": "eslint src && eslint script",
|
"test:eslint": "eslint src && eslint script",
|
||||||
"test:jshint": "jshint src/main",
|
"test:jshint": "jshint src/main",
|
||||||
"test:lockfile-lint": "npx lockfile-lint -p package-lock.json",
|
"test:lockfile-lint": "npx lockfile-lint -p package-lock.json",
|
||||||
"test:mocha": "mocha -R list test/mocha*js",
|
"test:mocha": "mocha test/mocha*js",
|
||||||
"test:playwright": "playwright test"
|
"test:playwright": "playwright test"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/parser": "7.15.8",
|
"@babel/parser": "7.15.8",
|
||||||
"@babel/traverse": "7.15.4",
|
"@babel/traverse": "7.23.2",
|
||||||
"@jazzer.js/core": "^1.4.0",
|
"@jazzer.js/core": "^1.4.0",
|
||||||
"@playwright/test": "~1.32.2",
|
"@playwright/test": "~1.32.2",
|
||||||
"jshint": "~2.13.6",
|
"jshint": "~2.13.6",
|
||||||
@@ -217,7 +226,7 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/faisalman/ua-parser-js.git"
|
"url": "https://github.com/faisalman/ua-parser-js.git"
|
||||||
},
|
},
|
||||||
"license": "UAParser.js-PRO-Personal",
|
"license": "UAParser.js-PRO-Enterprise",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -46,6 +46,12 @@ const modules = [
|
|||||||
dest : 'src/extensions/ua-parser-extensions.mjs',
|
dest : 'src/extensions/ua-parser-extensions.mjs',
|
||||||
title : 'ua-parser-js/extensions',
|
title : 'ua-parser-js/extensions',
|
||||||
replacements : []
|
replacements : []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src : 'src/helpers/ua-parser-helpers.js',
|
||||||
|
dest : 'src/helpers/ua-parser-helpers.mjs',
|
||||||
|
title : 'ua-parser-js/helpers',
|
||||||
|
replacements : []
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
4
script/cli.js
Executable file
4
script/cli.js
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const UAParser = require('ua-parser-js');
|
||||||
|
console.log(JSON.stringify(process.argv.slice(2).map(ua => UAParser(ua)), null, 4));
|
||||||
@@ -29,4 +29,4 @@ npm run test:lockfile-lint || exit 1
|
|||||||
echo '
|
echo '
|
||||||
- lint d.ts files
|
- lint d.ts files
|
||||||
'
|
'
|
||||||
npm run test:dts || exit 1
|
npm run test:dts-lint || exit 1
|
||||||
@@ -1,66 +1,189 @@
|
|||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
/* Enums for UAParser.js v2.0.0-beta.1
|
/* Enums for UAParser.js v2.0.0-beta.3
|
||||||
https://github.com/faisalman/ua-parser-js
|
https://github.com/faisalman/ua-parser-js
|
||||||
Author: Faisal Salman <f@faisalman.com>
|
Author: Faisal Salman <f@faisalman.com>
|
||||||
UAParser.js PRO Personal License */
|
UAParser.js PRO Enterorise License */
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
/*jshint esversion: 6 */
|
/*jshint esversion: 6 */
|
||||||
|
|
||||||
const Browser = Object.freeze({
|
const Browser = Object.freeze({
|
||||||
|
_2345_EXPLORER: '2345Explorer',
|
||||||
|
_360: '360 Browser',
|
||||||
|
ALIPAY: 'Alipay',
|
||||||
|
AMAYA: 'Amaya',
|
||||||
ANDROID: 'Android Browser',
|
ANDROID: 'Android Browser',
|
||||||
|
ARORA: 'Arora',
|
||||||
|
AVANT: 'Avant',
|
||||||
|
AVAST: 'Avast Secure Browser',
|
||||||
|
AVG: 'AVG Secure Browser',
|
||||||
|
BAIDU: 'Baidu Browser',
|
||||||
|
BASILISK: 'Basilisk',
|
||||||
|
BLAZER: 'Blazer',
|
||||||
|
BOLT: 'Bolt',
|
||||||
|
BOWSER: 'Bowser',
|
||||||
BRAVE: 'Brave',
|
BRAVE: 'Brave',
|
||||||
|
CAMINO: 'Camino',
|
||||||
|
CHIMERA: 'Chimera',
|
||||||
CHROME: 'Chrome',
|
CHROME: 'Chrome',
|
||||||
|
CHROME_HEADLESS: 'Chrome Headless',
|
||||||
|
CHROME_MOBILE: 'Mobile Chrome',
|
||||||
|
CHROME_WEBVIEW: 'Chrome WebView',
|
||||||
CHROMIUM: 'Chromium',
|
CHROMIUM: 'Chromium',
|
||||||
|
COBALT: 'Cobalt',
|
||||||
|
COC_COC: 'Coc Coc',
|
||||||
|
COMODO_DRAGON: 'Comodo Dragon',
|
||||||
|
CONKEROR: 'Conkeror',
|
||||||
|
DILLO: 'Dillo',
|
||||||
DOLPHIN: 'Dolphin',
|
DOLPHIN: 'Dolphin',
|
||||||
|
DORIS: 'Doris',
|
||||||
DUCKDUCKGO: 'DuckDuckGo',
|
DUCKDUCKGO: 'DuckDuckGo',
|
||||||
EDGE: 'Edge',
|
EDGE: 'Edge',
|
||||||
|
EPIPHANY: 'Epiphany',
|
||||||
|
FACEBOOK: 'Facebook',
|
||||||
|
FALKON: 'Falkon',
|
||||||
|
FIREBIRD: 'Firebird',
|
||||||
FIREFOX: 'Firefox',
|
FIREFOX: 'Firefox',
|
||||||
FOCUS: 'Focus',
|
FIREFOX_FOCUS: 'Firefox Focus',
|
||||||
|
FIREFOX_MOBILE: 'Mobile Firefox',
|
||||||
|
FIREFOX_REALITY: 'Firefox Reality',
|
||||||
|
FENNEC: 'Fennec',
|
||||||
|
FLOCK: 'Flock',
|
||||||
|
FLOW: 'Flow',
|
||||||
|
GO: 'GoBrowser',
|
||||||
|
GOOGLE_SEARCH: 'GSA',
|
||||||
|
HEYTAP: 'HeyTap',
|
||||||
|
HUAWEI: 'Huawei Browser',
|
||||||
|
ICAB: 'iCab',
|
||||||
|
ICE: 'ICE Browser',
|
||||||
|
ICEAPE: 'IceApe',
|
||||||
|
ICECAT: 'IceCat',
|
||||||
|
ICEDRAGON: 'IceDragon',
|
||||||
|
ICEWEASEL: 'IceWeasel',
|
||||||
IE: 'IE',
|
IE: 'IE',
|
||||||
|
INSTAGRAM: 'Instagram',
|
||||||
|
IRIDIUM: 'Iridium',
|
||||||
|
IRON: 'Iron',
|
||||||
|
JASMINE: 'Jasmine',
|
||||||
KONQUEROR: 'Konqueror',
|
KONQUEROR: 'Konqueror',
|
||||||
MOBILE_CHROME: 'Mobile Chrome',
|
KAKAO: 'KakaoTalk',
|
||||||
MOBILE_FIREFOX: 'Mobile Firefox',
|
KHTML: 'KHTML',
|
||||||
MOBILE_SAFARI: 'Mobile Safari',
|
K_MELEON: 'K-Meleon',
|
||||||
|
KLAR: 'Klar',
|
||||||
|
KLARNA: 'Klarna',
|
||||||
|
KINDLE: 'Kindle',
|
||||||
|
LENOVO: 'Smart Lenovo Browser',
|
||||||
|
LIEBAO: 'LBBROWSER',
|
||||||
|
LINE: 'Line',
|
||||||
|
LINKEDIN: 'LinkedIn',
|
||||||
|
LINKS: 'Links',
|
||||||
|
LUNASCAPE: 'Lunascape',
|
||||||
|
LYNX: 'Lynx',
|
||||||
|
MAEMO: 'Maemo Browser',
|
||||||
|
MAXTHON: 'Maxthon',
|
||||||
|
MIDORI: 'Midori',
|
||||||
|
MINIMO: 'Minimo',
|
||||||
|
MIUI: 'MIUI Browser',
|
||||||
|
MOZILLA: 'Mozilla',
|
||||||
|
MOSAIC: 'Mosaic',
|
||||||
|
NAVER: 'Naver',
|
||||||
|
NETFRONT: 'NetFront',
|
||||||
|
NETSCAPE: 'Netscape',
|
||||||
|
NETSURF: 'Netsurf',
|
||||||
|
NOKIA: 'Nokia Browser',
|
||||||
|
OBIGO: 'Obigo',
|
||||||
|
OCULUS: 'Oculus Browser',
|
||||||
|
OMNIWEB: 'OmniWeb',
|
||||||
OPERA: 'Opera',
|
OPERA: 'Opera',
|
||||||
|
OPERA_COAST: 'Opera Coast',
|
||||||
|
OPERA_MINI: 'Opera Mini',
|
||||||
|
OPERA_MOBI: 'Opera Mobi',
|
||||||
|
OPERA_TABLET: 'Opera Tablet',
|
||||||
|
OPERA_TOUCH: 'Opera Touch',
|
||||||
|
OVI: 'OviBrowser',
|
||||||
PALEMOON: 'PaleMoon',
|
PALEMOON: 'PaleMoon',
|
||||||
|
PHANTOMJS: 'PhantomJS',
|
||||||
|
PHOENIX: 'Phoenix',
|
||||||
|
PICOBROWSER: 'Pico Browser',
|
||||||
|
POLARIS: 'Polaris',
|
||||||
PUFFIN: 'Puffin',
|
PUFFIN: 'Puffin',
|
||||||
QQ: 'QQBrowser',
|
QQ: 'QQBrowser',
|
||||||
|
QQ_LITE: 'QQBrowserLite',
|
||||||
|
QUARK: 'Quark',
|
||||||
|
QUPZILLA: 'QupZilla',
|
||||||
|
REKONQ: 'rekonq',
|
||||||
|
ROCKMELT: 'Rockmelt',
|
||||||
SAFARI: 'Safari',
|
SAFARI: 'Safari',
|
||||||
|
SAFARI_MOBILE: 'Mobile Safari',
|
||||||
|
SAILFISH: 'Sailfish Browser',
|
||||||
SAMSUNG: 'Samsung Internet',
|
SAMSUNG: 'Samsung Internet',
|
||||||
|
SEAMONKEY: 'SeaMonkey',
|
||||||
|
SILK: 'Silk',
|
||||||
|
SKYFIRE: 'Skyfire',
|
||||||
|
SLEIPNIR: 'Sleipnir',
|
||||||
|
SLIMBROWSER: 'SlimBrowser',
|
||||||
|
SNAPCHAT: 'Snapchat',
|
||||||
|
SOGOU_EXPLORER: 'Sogou Explorer',
|
||||||
|
SOGOU_MOBILE: 'Sogou Mobile',
|
||||||
|
SWIFTFOX: 'Swiftfox',
|
||||||
|
TESLA: 'Tesla',
|
||||||
|
TIKTOK: 'TikTok',
|
||||||
|
TIZEN: 'Tizen Browser',
|
||||||
|
TWITTER: 'Twitter',
|
||||||
UC: 'UCBrowser',
|
UC: 'UCBrowser',
|
||||||
|
UP: 'UP.Browser',
|
||||||
VIVALDI: 'Vivaldi',
|
VIVALDI: 'Vivaldi',
|
||||||
|
VIVO: 'Vivo Browser',
|
||||||
|
W3M: 'w3m',
|
||||||
|
WATERFOX: 'Waterfox',
|
||||||
|
WEBKIT: 'WebKit',
|
||||||
|
WECHAT: 'WeChat',
|
||||||
|
WEIBO: 'Weibo',
|
||||||
|
WHALE: 'Whale',
|
||||||
|
WOLVIC: 'Wolvic',
|
||||||
YANDEX: 'Yandex'
|
YANDEX: 'Yandex'
|
||||||
|
|
||||||
// TODO : test!
|
// TODO : test!
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const BrowserType = Object.freeze({
|
||||||
|
CRAWLER: 'crawler',
|
||||||
|
CLI: 'cli',
|
||||||
|
EMAIL: 'email',
|
||||||
|
FETCHER: 'fetcher',
|
||||||
|
INAPP: 'inapp',
|
||||||
|
MODULE: 'module'
|
||||||
|
});
|
||||||
|
|
||||||
const CPU = Object.freeze({
|
const CPU = Object.freeze({
|
||||||
ARM : 'arm',
|
ARM : 'arm',
|
||||||
ARM64: 'arm64',
|
ARM_64: 'arm64',
|
||||||
ARMHF: 'armhf',
|
ARM_HF: 'armhf',
|
||||||
AVR: 'avr',
|
AVR: 'avr',
|
||||||
|
AVR_32: 'avr32',
|
||||||
IA64: 'ia64',
|
IA64: 'ia64',
|
||||||
IRIX: 'irix',
|
IRIX: 'irix',
|
||||||
IRIX64: 'irix64',
|
IRIX_64: 'irix64',
|
||||||
MIPS: 'mips',
|
MIPS: 'mips',
|
||||||
MIPS64: 'mips64',
|
MIPS_64: 'mips64',
|
||||||
MOTO_68K: '68k',
|
M68K: '68k',
|
||||||
|
PA_RISC: 'pa-risc',
|
||||||
PPC: 'ppc',
|
PPC: 'ppc',
|
||||||
SPARC: 'sparc',
|
SPARC: 'sparc',
|
||||||
SPARC64: 'sparc64',
|
SPARC_64: 'sparc64',
|
||||||
X86: 'ia32',
|
X86: 'ia32',
|
||||||
X86_64: 'amd64'
|
X86_64: 'amd64'
|
||||||
});
|
});
|
||||||
|
|
||||||
const Device = Object.freeze({
|
const Device = Object.freeze({
|
||||||
CONSOLE: 'console',
|
CONSOLE: 'console',
|
||||||
DEKSTOP: 'desktop',
|
DESKTOP: 'desktop',
|
||||||
EMBEDDED: 'embedded',
|
EMBEDDED: 'embedded',
|
||||||
MOBILE: 'mobile',
|
MOBILE: 'mobile',
|
||||||
SMARTTV: 'smarttv',
|
SMARTTV: 'smarttv',
|
||||||
TABLET: 'tablet',
|
TABLET: 'tablet',
|
||||||
WEARABLE: 'wearable'
|
WEARABLE: 'wearable',
|
||||||
|
XR: 'xr'
|
||||||
});
|
});
|
||||||
|
|
||||||
const Vendor = Object.freeze({
|
const Vendor = Object.freeze({
|
||||||
@@ -110,6 +233,7 @@ const Vendor = Object.freeze({
|
|||||||
SIEMENS: 'Siemens',
|
SIEMENS: 'Siemens',
|
||||||
SONY: 'Sony',
|
SONY: 'Sony',
|
||||||
SPRINT: 'Sprint',
|
SPRINT: 'Sprint',
|
||||||
|
TECHNISAT: 'TechniSAT',
|
||||||
TECNO: 'Tecno',
|
TECNO: 'Tecno',
|
||||||
TESLA: 'Tesla',
|
TESLA: 'Tesla',
|
||||||
ULEFONE: 'Ulefone',
|
ULEFONE: 'Ulefone',
|
||||||
@@ -155,14 +279,15 @@ const OS = Object.freeze({
|
|||||||
BLACKBERRY: 'BlackBerry',
|
BLACKBERRY: 'BlackBerry',
|
||||||
CENTOS: 'CentOS',
|
CENTOS: 'CentOS',
|
||||||
CHROME_OS: 'Chrome OS',
|
CHROME_OS: 'Chrome OS',
|
||||||
|
CHROMECAST: 'Chromecast',
|
||||||
CONTIKI: 'Contiki',
|
CONTIKI: 'Contiki',
|
||||||
FEDORA: 'Fedora',
|
|
||||||
FIREFOX_OS: 'Firefox OS',
|
|
||||||
FREEBSD: 'FreeBSD',
|
|
||||||
DEBIAN: 'Debian',
|
DEBIAN: 'Debian',
|
||||||
DEEPIN: 'Deepin',
|
DEEPIN: 'Deepin',
|
||||||
DRAGONFLY: 'DragonFly',
|
DRAGONFLY: 'DragonFly',
|
||||||
ELEMENTARY_OS: 'elementary OS',
|
ELEMENTARY_OS: 'elementary OS',
|
||||||
|
FEDORA: 'Fedora',
|
||||||
|
FIREFOX_OS: 'Firefox OS',
|
||||||
|
FREEBSD: 'FreeBSD',
|
||||||
FUCHSIA: 'Fuchsia',
|
FUCHSIA: 'Fuchsia',
|
||||||
GENTOO: 'Gentoo',
|
GENTOO: 'Gentoo',
|
||||||
GHOSTBSD: 'GhostBSD',
|
GHOSTBSD: 'GhostBSD',
|
||||||
@@ -221,6 +346,7 @@ const OS = Object.freeze({
|
|||||||
WINDOWS: 'Windows',
|
WINDOWS: 'Windows',
|
||||||
WINDOWS_MOBILE: 'Windows Mobile',
|
WINDOWS_MOBILE: 'Windows Mobile',
|
||||||
WINDOWS_PHONE: 'Windows Phone',
|
WINDOWS_PHONE: 'Windows Phone',
|
||||||
|
XBOX: 'Xbox',
|
||||||
ZENWALK: 'Zenwalk'
|
ZENWALK: 'Zenwalk'
|
||||||
|
|
||||||
// TODO : test!
|
// TODO : test!
|
||||||
@@ -228,6 +354,7 @@ const OS = Object.freeze({
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Browser,
|
Browser,
|
||||||
|
BrowserType,
|
||||||
CPU,
|
CPU,
|
||||||
Device,
|
Device,
|
||||||
Vendor,
|
Vendor,
|
||||||
|
|||||||
@@ -3,68 +3,191 @@
|
|||||||
// Source: /src/enums/ua-parser-enums.js
|
// Source: /src/enums/ua-parser-enums.js
|
||||||
|
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
/* Enums for UAParser.js v2.0.0-beta.1
|
/* Enums for UAParser.js v2.0.0-beta.3
|
||||||
https://github.com/faisalman/ua-parser-js
|
https://github.com/faisalman/ua-parser-js
|
||||||
Author: Faisal Salman <f@faisalman.com>
|
Author: Faisal Salman <f@faisalman.com>
|
||||||
UAParser.js PRO Personal License */
|
UAParser.js PRO Enterorise License */
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
/*jshint esversion: 6 */
|
/*jshint esversion: 6 */
|
||||||
|
|
||||||
const Browser = Object.freeze({
|
const Browser = Object.freeze({
|
||||||
|
_2345_EXPLORER: '2345Explorer',
|
||||||
|
_360: '360 Browser',
|
||||||
|
ALIPAY: 'Alipay',
|
||||||
|
AMAYA: 'Amaya',
|
||||||
ANDROID: 'Android Browser',
|
ANDROID: 'Android Browser',
|
||||||
|
ARORA: 'Arora',
|
||||||
|
AVANT: 'Avant',
|
||||||
|
AVAST: 'Avast Secure Browser',
|
||||||
|
AVG: 'AVG Secure Browser',
|
||||||
|
BAIDU: 'Baidu Browser',
|
||||||
|
BASILISK: 'Basilisk',
|
||||||
|
BLAZER: 'Blazer',
|
||||||
|
BOLT: 'Bolt',
|
||||||
|
BOWSER: 'Bowser',
|
||||||
BRAVE: 'Brave',
|
BRAVE: 'Brave',
|
||||||
|
CAMINO: 'Camino',
|
||||||
|
CHIMERA: 'Chimera',
|
||||||
CHROME: 'Chrome',
|
CHROME: 'Chrome',
|
||||||
|
CHROME_HEADLESS: 'Chrome Headless',
|
||||||
|
CHROME_MOBILE: 'Mobile Chrome',
|
||||||
|
CHROME_WEBVIEW: 'Chrome WebView',
|
||||||
CHROMIUM: 'Chromium',
|
CHROMIUM: 'Chromium',
|
||||||
|
COBALT: 'Cobalt',
|
||||||
|
COC_COC: 'Coc Coc',
|
||||||
|
COMODO_DRAGON: 'Comodo Dragon',
|
||||||
|
CONKEROR: 'Conkeror',
|
||||||
|
DILLO: 'Dillo',
|
||||||
DOLPHIN: 'Dolphin',
|
DOLPHIN: 'Dolphin',
|
||||||
|
DORIS: 'Doris',
|
||||||
DUCKDUCKGO: 'DuckDuckGo',
|
DUCKDUCKGO: 'DuckDuckGo',
|
||||||
EDGE: 'Edge',
|
EDGE: 'Edge',
|
||||||
|
EPIPHANY: 'Epiphany',
|
||||||
|
FACEBOOK: 'Facebook',
|
||||||
|
FALKON: 'Falkon',
|
||||||
|
FIREBIRD: 'Firebird',
|
||||||
FIREFOX: 'Firefox',
|
FIREFOX: 'Firefox',
|
||||||
FOCUS: 'Focus',
|
FIREFOX_FOCUS: 'Firefox Focus',
|
||||||
|
FIREFOX_MOBILE: 'Mobile Firefox',
|
||||||
|
FIREFOX_REALITY: 'Firefox Reality',
|
||||||
|
FENNEC: 'Fennec',
|
||||||
|
FLOCK: 'Flock',
|
||||||
|
FLOW: 'Flow',
|
||||||
|
GO: 'GoBrowser',
|
||||||
|
GOOGLE_SEARCH: 'GSA',
|
||||||
|
HEYTAP: 'HeyTap',
|
||||||
|
HUAWEI: 'Huawei Browser',
|
||||||
|
ICAB: 'iCab',
|
||||||
|
ICE: 'ICE Browser',
|
||||||
|
ICEAPE: 'IceApe',
|
||||||
|
ICECAT: 'IceCat',
|
||||||
|
ICEDRAGON: 'IceDragon',
|
||||||
|
ICEWEASEL: 'IceWeasel',
|
||||||
IE: 'IE',
|
IE: 'IE',
|
||||||
|
INSTAGRAM: 'Instagram',
|
||||||
|
IRIDIUM: 'Iridium',
|
||||||
|
IRON: 'Iron',
|
||||||
|
JASMINE: 'Jasmine',
|
||||||
KONQUEROR: 'Konqueror',
|
KONQUEROR: 'Konqueror',
|
||||||
MOBILE_CHROME: 'Mobile Chrome',
|
KAKAO: 'KakaoTalk',
|
||||||
MOBILE_FIREFOX: 'Mobile Firefox',
|
KHTML: 'KHTML',
|
||||||
MOBILE_SAFARI: 'Mobile Safari',
|
K_MELEON: 'K-Meleon',
|
||||||
|
KLAR: 'Klar',
|
||||||
|
KLARNA: 'Klarna',
|
||||||
|
KINDLE: 'Kindle',
|
||||||
|
LENOVO: 'Smart Lenovo Browser',
|
||||||
|
LIEBAO: 'LBBROWSER',
|
||||||
|
LINE: 'Line',
|
||||||
|
LINKEDIN: 'LinkedIn',
|
||||||
|
LINKS: 'Links',
|
||||||
|
LUNASCAPE: 'Lunascape',
|
||||||
|
LYNX: 'Lynx',
|
||||||
|
MAEMO: 'Maemo Browser',
|
||||||
|
MAXTHON: 'Maxthon',
|
||||||
|
MIDORI: 'Midori',
|
||||||
|
MINIMO: 'Minimo',
|
||||||
|
MIUI: 'MIUI Browser',
|
||||||
|
MOZILLA: 'Mozilla',
|
||||||
|
MOSAIC: 'Mosaic',
|
||||||
|
NAVER: 'Naver',
|
||||||
|
NETFRONT: 'NetFront',
|
||||||
|
NETSCAPE: 'Netscape',
|
||||||
|
NETSURF: 'Netsurf',
|
||||||
|
NOKIA: 'Nokia Browser',
|
||||||
|
OBIGO: 'Obigo',
|
||||||
|
OCULUS: 'Oculus Browser',
|
||||||
|
OMNIWEB: 'OmniWeb',
|
||||||
OPERA: 'Opera',
|
OPERA: 'Opera',
|
||||||
|
OPERA_COAST: 'Opera Coast',
|
||||||
|
OPERA_MINI: 'Opera Mini',
|
||||||
|
OPERA_MOBI: 'Opera Mobi',
|
||||||
|
OPERA_TABLET: 'Opera Tablet',
|
||||||
|
OPERA_TOUCH: 'Opera Touch',
|
||||||
|
OVI: 'OviBrowser',
|
||||||
PALEMOON: 'PaleMoon',
|
PALEMOON: 'PaleMoon',
|
||||||
|
PHANTOMJS: 'PhantomJS',
|
||||||
|
PHOENIX: 'Phoenix',
|
||||||
|
PICOBROWSER: 'Pico Browser',
|
||||||
|
POLARIS: 'Polaris',
|
||||||
PUFFIN: 'Puffin',
|
PUFFIN: 'Puffin',
|
||||||
QQ: 'QQBrowser',
|
QQ: 'QQBrowser',
|
||||||
|
QQ_LITE: 'QQBrowserLite',
|
||||||
|
QUARK: 'Quark',
|
||||||
|
QUPZILLA: 'QupZilla',
|
||||||
|
REKONQ: 'rekonq',
|
||||||
|
ROCKMELT: 'Rockmelt',
|
||||||
SAFARI: 'Safari',
|
SAFARI: 'Safari',
|
||||||
|
SAFARI_MOBILE: 'Mobile Safari',
|
||||||
|
SAILFISH: 'Sailfish Browser',
|
||||||
SAMSUNG: 'Samsung Internet',
|
SAMSUNG: 'Samsung Internet',
|
||||||
|
SEAMONKEY: 'SeaMonkey',
|
||||||
|
SILK: 'Silk',
|
||||||
|
SKYFIRE: 'Skyfire',
|
||||||
|
SLEIPNIR: 'Sleipnir',
|
||||||
|
SLIMBROWSER: 'SlimBrowser',
|
||||||
|
SNAPCHAT: 'Snapchat',
|
||||||
|
SOGOU_EXPLORER: 'Sogou Explorer',
|
||||||
|
SOGOU_MOBILE: 'Sogou Mobile',
|
||||||
|
SWIFTFOX: 'Swiftfox',
|
||||||
|
TESLA: 'Tesla',
|
||||||
|
TIKTOK: 'TikTok',
|
||||||
|
TIZEN: 'Tizen Browser',
|
||||||
|
TWITTER: 'Twitter',
|
||||||
UC: 'UCBrowser',
|
UC: 'UCBrowser',
|
||||||
|
UP: 'UP.Browser',
|
||||||
VIVALDI: 'Vivaldi',
|
VIVALDI: 'Vivaldi',
|
||||||
|
VIVO: 'Vivo Browser',
|
||||||
|
W3M: 'w3m',
|
||||||
|
WATERFOX: 'Waterfox',
|
||||||
|
WEBKIT: 'WebKit',
|
||||||
|
WECHAT: 'WeChat',
|
||||||
|
WEIBO: 'Weibo',
|
||||||
|
WHALE: 'Whale',
|
||||||
|
WOLVIC: 'Wolvic',
|
||||||
YANDEX: 'Yandex'
|
YANDEX: 'Yandex'
|
||||||
|
|
||||||
// TODO : test!
|
// TODO : test!
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const BrowserType = Object.freeze({
|
||||||
|
CRAWLER: 'crawler',
|
||||||
|
CLI: 'cli',
|
||||||
|
EMAIL: 'email',
|
||||||
|
FETCHER: 'fetcher',
|
||||||
|
INAPP: 'inapp',
|
||||||
|
MODULE: 'module'
|
||||||
|
});
|
||||||
|
|
||||||
const CPU = Object.freeze({
|
const CPU = Object.freeze({
|
||||||
ARM : 'arm',
|
ARM : 'arm',
|
||||||
ARM64: 'arm64',
|
ARM_64: 'arm64',
|
||||||
ARMHF: 'armhf',
|
ARM_HF: 'armhf',
|
||||||
AVR: 'avr',
|
AVR: 'avr',
|
||||||
|
AVR_32: 'avr32',
|
||||||
IA64: 'ia64',
|
IA64: 'ia64',
|
||||||
IRIX: 'irix',
|
IRIX: 'irix',
|
||||||
IRIX64: 'irix64',
|
IRIX_64: 'irix64',
|
||||||
MIPS: 'mips',
|
MIPS: 'mips',
|
||||||
MIPS64: 'mips64',
|
MIPS_64: 'mips64',
|
||||||
MOTO_68K: '68k',
|
M68K: '68k',
|
||||||
|
PA_RISC: 'pa-risc',
|
||||||
PPC: 'ppc',
|
PPC: 'ppc',
|
||||||
SPARC: 'sparc',
|
SPARC: 'sparc',
|
||||||
SPARC64: 'sparc64',
|
SPARC_64: 'sparc64',
|
||||||
X86: 'ia32',
|
X86: 'ia32',
|
||||||
X86_64: 'amd64'
|
X86_64: 'amd64'
|
||||||
});
|
});
|
||||||
|
|
||||||
const Device = Object.freeze({
|
const Device = Object.freeze({
|
||||||
CONSOLE: 'console',
|
CONSOLE: 'console',
|
||||||
DEKSTOP: 'desktop',
|
DESKTOP: 'desktop',
|
||||||
EMBEDDED: 'embedded',
|
EMBEDDED: 'embedded',
|
||||||
MOBILE: 'mobile',
|
MOBILE: 'mobile',
|
||||||
SMARTTV: 'smarttv',
|
SMARTTV: 'smarttv',
|
||||||
TABLET: 'tablet',
|
TABLET: 'tablet',
|
||||||
WEARABLE: 'wearable'
|
WEARABLE: 'wearable',
|
||||||
|
XR: 'xr'
|
||||||
});
|
});
|
||||||
|
|
||||||
const Vendor = Object.freeze({
|
const Vendor = Object.freeze({
|
||||||
@@ -114,6 +237,7 @@ const Vendor = Object.freeze({
|
|||||||
SIEMENS: 'Siemens',
|
SIEMENS: 'Siemens',
|
||||||
SONY: 'Sony',
|
SONY: 'Sony',
|
||||||
SPRINT: 'Sprint',
|
SPRINT: 'Sprint',
|
||||||
|
TECHNISAT: 'TechniSAT',
|
||||||
TECNO: 'Tecno',
|
TECNO: 'Tecno',
|
||||||
TESLA: 'Tesla',
|
TESLA: 'Tesla',
|
||||||
ULEFONE: 'Ulefone',
|
ULEFONE: 'Ulefone',
|
||||||
@@ -159,14 +283,15 @@ const OS = Object.freeze({
|
|||||||
BLACKBERRY: 'BlackBerry',
|
BLACKBERRY: 'BlackBerry',
|
||||||
CENTOS: 'CentOS',
|
CENTOS: 'CentOS',
|
||||||
CHROME_OS: 'Chrome OS',
|
CHROME_OS: 'Chrome OS',
|
||||||
|
CHROMECAST: 'Chromecast',
|
||||||
CONTIKI: 'Contiki',
|
CONTIKI: 'Contiki',
|
||||||
FEDORA: 'Fedora',
|
|
||||||
FIREFOX_OS: 'Firefox OS',
|
|
||||||
FREEBSD: 'FreeBSD',
|
|
||||||
DEBIAN: 'Debian',
|
DEBIAN: 'Debian',
|
||||||
DEEPIN: 'Deepin',
|
DEEPIN: 'Deepin',
|
||||||
DRAGONFLY: 'DragonFly',
|
DRAGONFLY: 'DragonFly',
|
||||||
ELEMENTARY_OS: 'elementary OS',
|
ELEMENTARY_OS: 'elementary OS',
|
||||||
|
FEDORA: 'Fedora',
|
||||||
|
FIREFOX_OS: 'Firefox OS',
|
||||||
|
FREEBSD: 'FreeBSD',
|
||||||
FUCHSIA: 'Fuchsia',
|
FUCHSIA: 'Fuchsia',
|
||||||
GENTOO: 'Gentoo',
|
GENTOO: 'Gentoo',
|
||||||
GHOSTBSD: 'GhostBSD',
|
GHOSTBSD: 'GhostBSD',
|
||||||
@@ -225,6 +350,7 @@ const OS = Object.freeze({
|
|||||||
WINDOWS: 'Windows',
|
WINDOWS: 'Windows',
|
||||||
WINDOWS_MOBILE: 'Windows Mobile',
|
WINDOWS_MOBILE: 'Windows Mobile',
|
||||||
WINDOWS_PHONE: 'Windows Phone',
|
WINDOWS_PHONE: 'Windows Phone',
|
||||||
|
XBOX: 'Xbox',
|
||||||
ZENWALK: 'Zenwalk'
|
ZENWALK: 'Zenwalk'
|
||||||
|
|
||||||
// TODO : test!
|
// TODO : test!
|
||||||
@@ -232,6 +358,7 @@ const OS = Object.freeze({
|
|||||||
|
|
||||||
export {
|
export {
|
||||||
Browser,
|
Browser,
|
||||||
|
BrowserType,
|
||||||
CPU,
|
CPU,
|
||||||
Device,
|
Device,
|
||||||
Vendor,
|
Vendor,
|
||||||
|
|||||||
14
src/extensions/ua-parser-extensions.d.ts
vendored
Normal file
14
src/extensions/ua-parser-extensions.d.ts
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.3
|
||||||
|
// Project: https://github.com/faisalman/ua-parser-js
|
||||||
|
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
||||||
|
|
||||||
|
import type { UAParserExt } from "../main/ua-parser";
|
||||||
|
|
||||||
|
export const CLIs: UAParserExt;
|
||||||
|
export const Crawlers: UAParserExt;
|
||||||
|
export const ExtraDevices: UAParserExt;
|
||||||
|
export const Emails: UAParserExt;
|
||||||
|
export const Fetchers: UAParserExt;
|
||||||
|
export const InApps: UAParserExt;
|
||||||
|
export const MediaPlayers: UAParserExt;
|
||||||
|
export const Modules: UAParserExt;
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
/* Extensions for UAParser.js v2.0.0-beta.1
|
/* Extensions for UAParser.js v2.0.0-beta.3
|
||||||
https://github.com/faisalman/ua-parser-js
|
https://github.com/faisalman/ua-parser-js
|
||||||
Author: Faisal Salman <f@faisalman.com>
|
Author: Faisal Salman <f@faisalman.com>
|
||||||
UAParser.js PRO Personal License */
|
UAParser.js PRO Enterorise License */
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
/*jshint esversion: 6 */
|
/*jshint esversion: 6 */
|
||||||
@@ -14,33 +14,74 @@ const VENDOR = 'vendor';
|
|||||||
const VERSION = 'version';
|
const VERSION = 'version';
|
||||||
const MOBILE = 'mobile';
|
const MOBILE = 'mobile';
|
||||||
const TABLET = 'tablet';
|
const TABLET = 'tablet';
|
||||||
|
const CRAWLER = 'crawler';
|
||||||
|
const CLI = 'cli';
|
||||||
|
const EMAIL = 'email';
|
||||||
|
const FETCHER = 'fetcher';
|
||||||
|
const INAPP = 'inapp';
|
||||||
|
const MODULE = 'module';
|
||||||
|
|
||||||
const Apps = Object.freeze({
|
//////////////////////
|
||||||
browser : [
|
// COMMAND LINE APPS
|
||||||
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, 'app']]
|
/////////////////////
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const Bots = Object.freeze({
|
|
||||||
browser : [
|
|
||||||
// Googlebot / BingBot / MSNBot / FacebookBot
|
|
||||||
[/((?:google|bing|msn|facebook)bot(?:[\-imagevdo]{0,6})|bingpreview)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']],
|
|
||||||
|
|
||||||
// GPTBot - https://platform.openai.com/docs/gptbot
|
|
||||||
[/(gptbot)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']],
|
|
||||||
|
|
||||||
// Slackbot - https://api.slack.com/robots
|
|
||||||
[/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const CLIs = Object.freeze({
|
const CLIs = Object.freeze({
|
||||||
browser : [
|
browser : [
|
||||||
// wget / curl / lynx
|
// wget / curl / lynx
|
||||||
[/(wget|curl|lynx)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'cli']]
|
[/(wget|curl|lynx)[\/ ]([\w\.]+)/i], [NAME, VERSION, [TYPE, CLI]]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// CRAWLERS / SPIDERS
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
const Crawlers = Object.freeze({
|
||||||
|
browser : [
|
||||||
|
// Amazonbot - https://developer.amazon.com/amazonbot
|
||||||
|
// Applebot - http://apple.com/go/applebot
|
||||||
|
// Bingbot - http://www.bing.com/bingbot.htm
|
||||||
|
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
|
||||||
|
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
|
||||||
|
// GPTBot - https://platform.openai.com/docs/gptbot
|
||||||
|
[/((?:amazon|apple|bing|duckduck|facebook|gpt)bot)\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
|
||||||
|
[/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Bytespider
|
||||||
|
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
|
||||||
|
[/((?:bytespider|(?=yahoo! )slurp))/i],
|
||||||
|
[NAME, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// ClaudeBot
|
||||||
|
[/(claude(?:bot|-web))\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Googlebot - http://www.google.com/bot.html
|
||||||
|
[
|
||||||
|
/(google(?:bot|other)(?:-image|-video|-news|-extended)?|(?:storebot-)?google(?:-inspectiontool)?)\/?([\w\.]*)/i
|
||||||
|
],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Sogou Spider
|
||||||
|
[/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Yandex Bots - https://yandex.com/bots
|
||||||
|
[
|
||||||
|
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i
|
||||||
|
],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
// EXTRA DEVICES
|
||||||
|
/////////////////
|
||||||
|
|
||||||
const ExtraDevices = Object.freeze({
|
const ExtraDevices = Object.freeze({
|
||||||
device : [[
|
device : [[
|
||||||
/(nook)[\w ]+build\/(\w+)/i, // Nook
|
/(nook)[\w ]+build\/(\w+)/i, // Nook
|
||||||
@@ -117,13 +158,63 @@ const ExtraDevices = Object.freeze({
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// EMAIL APPS
|
||||||
|
//////////////
|
||||||
|
|
||||||
const Emails = Object.freeze({
|
const Emails = Object.freeze({
|
||||||
browser : [
|
browser : [
|
||||||
// Microsoft Outlook / Thunderbird
|
// Microsoft Outlook / Thunderbird
|
||||||
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, 'email']]
|
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// ON-DEMAND SCRAPERS
|
||||||
|
//////////////////////
|
||||||
|
|
||||||
|
const Fetchers = Object.freeze({
|
||||||
|
browser : [
|
||||||
|
// BingPreview / Mastodon / Pinterestbot / Redditbot / Telegrambot / Twitterbot
|
||||||
|
[/(bingpreview|mastodon|(?:discord|linkedin|pinterest|reddit|telegram|twitter)bot)\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
// Google Bots / Snapchat
|
||||||
|
[/(feedfetcher-google|google-read-aloud|(?=bot; )snapchat)/i],
|
||||||
|
[NAME, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
|
||||||
|
// Slackbot - https://api.slack.com/robots
|
||||||
|
[/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
// WhatsApp
|
||||||
|
[/(whatsapp)\/([\w\.]+)[\/ ][ianw]/i],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
// Yandex Bots - https://yandex.com/bots
|
||||||
|
[
|
||||||
|
/(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
|
||||||
|
/(yandex(?:sitelinks|userproxy))/i
|
||||||
|
],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// IN-APP BROWSERS
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
const InApps = Object.freeze({
|
||||||
|
browser : [
|
||||||
|
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// MEDIA PLAYER APPS
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
const MediaPlayers = Object.freeze({
|
const MediaPlayers = Object.freeze({
|
||||||
browser : [[
|
browser : [[
|
||||||
|
|
||||||
@@ -230,19 +321,24 @@ const MediaPlayers = Object.freeze({
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// MODULES / LIBRARIES
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
const Modules = Object.freeze({
|
const Modules = Object.freeze({
|
||||||
browser : [
|
browser : [
|
||||||
// Axios/jsdom/Scrapy
|
// Axios/jsdom/Scrapy
|
||||||
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'module']]
|
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, MODULE]]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
Apps,
|
|
||||||
Bots,
|
|
||||||
CLIs,
|
CLIs,
|
||||||
|
Crawlers,
|
||||||
ExtraDevices,
|
ExtraDevices,
|
||||||
Emails,
|
Emails,
|
||||||
|
Fetchers,
|
||||||
|
InApps,
|
||||||
MediaPlayers,
|
MediaPlayers,
|
||||||
Modules
|
Modules
|
||||||
};
|
};
|
||||||
@@ -3,10 +3,10 @@
|
|||||||
// Source: /src/extensions/ua-parser-extensions.js
|
// Source: /src/extensions/ua-parser-extensions.js
|
||||||
|
|
||||||
///////////////////////////////////////////////
|
///////////////////////////////////////////////
|
||||||
/* Extensions for UAParser.js v2.0.0-beta.1
|
/* Extensions for UAParser.js v2.0.0-beta.3
|
||||||
https://github.com/faisalman/ua-parser-js
|
https://github.com/faisalman/ua-parser-js
|
||||||
Author: Faisal Salman <f@faisalman.com>
|
Author: Faisal Salman <f@faisalman.com>
|
||||||
UAParser.js PRO Personal License */
|
UAParser.js PRO Enterorise License */
|
||||||
//////////////////////////////////////////////
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
/*jshint esversion: 6 */
|
/*jshint esversion: 6 */
|
||||||
@@ -18,33 +18,74 @@ const VENDOR = 'vendor';
|
|||||||
const VERSION = 'version';
|
const VERSION = 'version';
|
||||||
const MOBILE = 'mobile';
|
const MOBILE = 'mobile';
|
||||||
const TABLET = 'tablet';
|
const TABLET = 'tablet';
|
||||||
|
const CRAWLER = 'crawler';
|
||||||
|
const CLI = 'cli';
|
||||||
|
const EMAIL = 'email';
|
||||||
|
const FETCHER = 'fetcher';
|
||||||
|
const INAPP = 'inapp';
|
||||||
|
const MODULE = 'module';
|
||||||
|
|
||||||
const Apps = Object.freeze({
|
//////////////////////
|
||||||
browser : [
|
// COMMAND LINE APPS
|
||||||
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, 'app']]
|
/////////////////////
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const Bots = Object.freeze({
|
|
||||||
browser : [
|
|
||||||
// Googlebot / BingBot / MSNBot / FacebookBot
|
|
||||||
[/((?:google|bing|msn|facebook)bot(?:[\-imagevdo]{0,6})|bingpreview)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']],
|
|
||||||
|
|
||||||
// GPTBot - https://platform.openai.com/docs/gptbot
|
|
||||||
[/(gptbot)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']],
|
|
||||||
|
|
||||||
// Slackbot - https://api.slack.com/robots
|
|
||||||
[/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
const CLIs = Object.freeze({
|
const CLIs = Object.freeze({
|
||||||
browser : [
|
browser : [
|
||||||
// wget / curl / lynx
|
// wget / curl / lynx
|
||||||
[/(wget|curl|lynx)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'cli']]
|
[/(wget|curl|lynx)[\/ ]([\w\.]+)/i], [NAME, VERSION, [TYPE, CLI]]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// CRAWLERS / SPIDERS
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
|
const Crawlers = Object.freeze({
|
||||||
|
browser : [
|
||||||
|
// Amazonbot - https://developer.amazon.com/amazonbot
|
||||||
|
// Applebot - http://apple.com/go/applebot
|
||||||
|
// Bingbot - http://www.bing.com/bingbot.htm
|
||||||
|
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
|
||||||
|
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
|
||||||
|
// GPTBot - https://platform.openai.com/docs/gptbot
|
||||||
|
[/((?:amazon|apple|bing|duckduck|facebook|gpt)bot)\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Baiduspider https://help.baidu.com/question?prod_id=99&class=0&id=3001
|
||||||
|
[/(baiduspider)[-imagevdonsfcpr]{0,6}\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Bytespider
|
||||||
|
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
|
||||||
|
[/((?:bytespider|(?=yahoo! )slurp))/i],
|
||||||
|
[NAME, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// ClaudeBot
|
||||||
|
[/(claude(?:bot|-web))\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Googlebot - http://www.google.com/bot.html
|
||||||
|
[
|
||||||
|
/(google(?:bot|other)(?:-image|-video|-news|-extended)?|(?:storebot-)?google(?:-inspectiontool)?)\/?([\w\.]*)/i
|
||||||
|
],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Sogou Spider
|
||||||
|
[/(sogou (?:pic|head|web|orion|news) spider)\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||||
|
|
||||||
|
// Yandex Bots - https://yandex.com/bots
|
||||||
|
[
|
||||||
|
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i
|
||||||
|
],
|
||||||
|
[NAME, VERSION, [TYPE, CRAWLER]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
//////////////////
|
||||||
|
// EXTRA DEVICES
|
||||||
|
/////////////////
|
||||||
|
|
||||||
const ExtraDevices = Object.freeze({
|
const ExtraDevices = Object.freeze({
|
||||||
device : [[
|
device : [[
|
||||||
/(nook)[\w ]+build\/(\w+)/i, // Nook
|
/(nook)[\w ]+build\/(\w+)/i, // Nook
|
||||||
@@ -121,13 +162,63 @@ const ExtraDevices = Object.freeze({
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// EMAIL APPS
|
||||||
|
//////////////
|
||||||
|
|
||||||
const Emails = Object.freeze({
|
const Emails = Object.freeze({
|
||||||
browser : [
|
browser : [
|
||||||
// Microsoft Outlook / Thunderbird
|
// Microsoft Outlook / Thunderbird
|
||||||
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, 'email']]
|
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, EMAIL]]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
///////////////////////
|
||||||
|
// ON-DEMAND SCRAPERS
|
||||||
|
//////////////////////
|
||||||
|
|
||||||
|
const Fetchers = Object.freeze({
|
||||||
|
browser : [
|
||||||
|
// BingPreview / Mastodon / Pinterestbot / Redditbot / Telegrambot / Twitterbot
|
||||||
|
[/(bingpreview|mastodon|(?:discord|linkedin|pinterest|reddit|telegram|twitter)bot)\/([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
// Google Bots / Snapchat
|
||||||
|
[/(feedfetcher-google|google-read-aloud|(?=bot; )snapchat)/i],
|
||||||
|
[NAME, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
|
||||||
|
// Slackbot - https://api.slack.com/robots
|
||||||
|
[/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
// WhatsApp
|
||||||
|
[/(whatsapp)\/([\w\.]+)[\/ ][ianw]/i],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]],
|
||||||
|
|
||||||
|
// Yandex Bots - https://yandex.com/bots
|
||||||
|
[
|
||||||
|
/(yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
|
||||||
|
/(yandex(?:sitelinks|userproxy))/i
|
||||||
|
],
|
||||||
|
[NAME, VERSION, [TYPE, FETCHER]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// IN-APP BROWSERS
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
const InApps = Object.freeze({
|
||||||
|
browser : [
|
||||||
|
[/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, INAPP]]
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
//////////////////////
|
||||||
|
// MEDIA PLAYER APPS
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
const MediaPlayers = Object.freeze({
|
const MediaPlayers = Object.freeze({
|
||||||
browser : [[
|
browser : [[
|
||||||
|
|
||||||
@@ -234,19 +325,24 @@ const MediaPlayers = Object.freeze({
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
////////////////////////
|
||||||
|
// MODULES / LIBRARIES
|
||||||
|
///////////////////////
|
||||||
|
|
||||||
const Modules = Object.freeze({
|
const Modules = Object.freeze({
|
||||||
browser : [
|
browser : [
|
||||||
// Axios/jsdom/Scrapy
|
// Axios/jsdom/Scrapy
|
||||||
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'module']]
|
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, MODULE]]
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Apps,
|
|
||||||
Bots,
|
|
||||||
CLIs,
|
CLIs,
|
||||||
|
Crawlers,
|
||||||
ExtraDevices,
|
ExtraDevices,
|
||||||
Emails,
|
Emails,
|
||||||
|
Fetchers,
|
||||||
|
InApps,
|
||||||
MediaPlayers,
|
MediaPlayers,
|
||||||
Modules
|
Modules
|
||||||
};
|
};
|
||||||
15
src/helpers/ua-parser-helpers.d.ts
vendored
Normal file
15
src/helpers/ua-parser-helpers.d.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// Type definitions for Helpers submodule of UAParser.js v2.0.0-beta.3
|
||||||
|
// Project: https://github.com/faisalman/ua-parser-js
|
||||||
|
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
||||||
|
|
||||||
|
import { IResult } from "../main/ua-parser";
|
||||||
|
|
||||||
|
declare function isAppleSilicon(res: IResult): boolean;
|
||||||
|
declare function isChromiumBased(res: IResult): boolean;
|
||||||
|
declare function isFrozenUA(ua: string): boolean;
|
||||||
|
|
||||||
|
export {
|
||||||
|
isAppleSilicon,
|
||||||
|
isChromiumBased,
|
||||||
|
isFrozenUA
|
||||||
|
}
|
||||||
22
src/helpers/ua-parser-helpers.js
Normal file
22
src/helpers/ua-parser-helpers.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
///////////////////////////////////////////////
|
||||||
|
/* Helpers for UAParser.js v2.0.0-beta.3
|
||||||
|
https://github.com/faisalman/ua-parser-js
|
||||||
|
Author: Faisal Salman <f@faisalman.com>
|
||||||
|
AGPLv3 License */
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*jshint esversion: 6 */
|
||||||
|
|
||||||
|
const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
|
||||||
|
|
||||||
|
const isAppleSilicon = (res) => res.os.is(OS.MACOS) && res.cpu.is(CPU.ARM);
|
||||||
|
|
||||||
|
const isChromiumBased = (res) => res.engine.is(Engine.BLINK);
|
||||||
|
|
||||||
|
const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
isAppleSilicon,
|
||||||
|
isChromiumBased,
|
||||||
|
isFrozenUA
|
||||||
|
}
|
||||||
26
src/helpers/ua-parser-helpers.mjs
Normal file
26
src/helpers/ua-parser-helpers.mjs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
// Generated ESM version of ua-parser-js/helpers
|
||||||
|
// DO NOT EDIT THIS FILE!
|
||||||
|
// Source: /src/helpers/ua-parser-helpers.js
|
||||||
|
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
/* Helpers for UAParser.js v2.0.0-beta.3
|
||||||
|
https://github.com/faisalman/ua-parser-js
|
||||||
|
Author: Faisal Salman <f@faisalman.com>
|
||||||
|
AGPLv3 License */
|
||||||
|
//////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*jshint esversion: 6 */
|
||||||
|
|
||||||
|
import { CPU, OS, Engine } from '../enums/ua-parser-enums';
|
||||||
|
|
||||||
|
const isAppleSilicon = (res) => res.os.is(OS.MACOS) && res.cpu.is(CPU.ARM);
|
||||||
|
|
||||||
|
const isChromiumBased = (res) => res.engine.is(Engine.BLINK);
|
||||||
|
|
||||||
|
const isFrozenUA = (ua) => /^Mozilla\/5\.0 \((Windows NT 10\.0; Win64; x64|Macintosh; Intel Mac OS X 10_15_7|X11; Linux x86_64|X11; CrOS x86_64 14541\.0\.0|Fuchsia|Linux; Android 10; K)\) AppleWebKit\/537\.36 \(KHTML, like Gecko\) Chrome\/\d+\.0\.0\.0 (Mobile )?Safari\/537\.36/.test(ua);
|
||||||
|
|
||||||
|
export {
|
||||||
|
isAppleSilicon,
|
||||||
|
isChromiumBased,
|
||||||
|
isFrozenUA
|
||||||
|
}
|
||||||
17
src/main/ua-parser.d.ts
vendored
17
src/main/ua-parser.d.ts
vendored
@@ -1,4 +1,4 @@
|
|||||||
// Type definitions for UAParser.js v2.0.0-beta.1
|
// Type definitions for UAParser.js v2.0.0-beta.3
|
||||||
// Project: https://github.com/faisalman/ua-parser-js
|
// Project: https://github.com/faisalman/ua-parser-js
|
||||||
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ declare namespace UAParser {
|
|||||||
name?: string;
|
name?: string;
|
||||||
version?: string;
|
version?: string;
|
||||||
major?: string;
|
major?: string;
|
||||||
|
type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'module';
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ICPU extends IData<ICPU> {
|
interface ICPU extends IData<ICPU> {
|
||||||
@@ -22,7 +23,7 @@ declare namespace UAParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IDevice extends IData<IDevice> {
|
interface IDevice extends IData<IDevice> {
|
||||||
type?: 'mobile' | 'tablet' | 'console' | 'smarttv' | 'wearable';
|
type?: 'mobile' | 'tablet' | 'console' | 'smarttv' | 'wearable' | 'xr' | 'embedded';
|
||||||
vendor?: string;
|
vendor?: string;
|
||||||
model?: string;
|
model?: string;
|
||||||
}
|
}
|
||||||
@@ -47,10 +48,12 @@ declare namespace UAParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[];
|
type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[];
|
||||||
|
type UAParserProps = 'browser' | 'cpu' | 'device' | 'engine' | 'os';
|
||||||
|
type UAParserExt = Partial<Record<UAParserProps, RegexMap>> | Partial<Record<UAParserProps, RegexMap>>[];
|
||||||
|
|
||||||
export function UAParser(uastring?: string, extensions?: Record<string, RegexMap>, headers?: Record<string, string>): IResult;
|
export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: Record<string, string>): IResult;
|
||||||
export function UAParser(uastring?: string, headers?: Record<string, string>): IResult;
|
export function UAParser(uastring?: string, headers?: Record<string, string>): IResult;
|
||||||
export function UAParser(extensions?: Record<string, RegexMap>, headers?: Record<string, string>): IResult;
|
export function UAParser(extensions?: UAParserExt, headers?: Record<string, string>): IResult;
|
||||||
export function UAParser(headers?: Record<string, string>): IResult;
|
export function UAParser(headers?: Record<string, string>): IResult;
|
||||||
|
|
||||||
export class UAParser {
|
export class UAParser {
|
||||||
@@ -59,6 +62,7 @@ declare namespace UAParser {
|
|||||||
NAME: 'name';
|
NAME: 'name';
|
||||||
VERSION: 'version';
|
VERSION: 'version';
|
||||||
MAJOR: 'major';
|
MAJOR: 'major';
|
||||||
|
TYPE: 'type';
|
||||||
};
|
};
|
||||||
static readonly CPU: {
|
static readonly CPU: {
|
||||||
ARCHITECTURE: 'architecture';
|
ARCHITECTURE: 'architecture';
|
||||||
@@ -72,6 +76,7 @@ declare namespace UAParser {
|
|||||||
SMARTTV: 'smarttv';
|
SMARTTV: 'smarttv';
|
||||||
TABLET: 'tablet';
|
TABLET: 'tablet';
|
||||||
WEARABLE: 'wearable';
|
WEARABLE: 'wearable';
|
||||||
|
XR: 'xr';
|
||||||
EMBEDDED: 'embedded';
|
EMBEDDED: 'embedded';
|
||||||
};
|
};
|
||||||
static readonly ENGINE: {
|
static readonly ENGINE: {
|
||||||
@@ -84,9 +89,9 @@ declare namespace UAParser {
|
|||||||
};
|
};
|
||||||
static readonly VERSION: string;
|
static readonly VERSION: string;
|
||||||
|
|
||||||
constructor(uastring?: string, extensions?: Record<string, RegexMap>, headers?: Record<string, string>);
|
constructor(uastring?: string, extensions?: UAParserExt, headers?: Record<string, string>);
|
||||||
constructor(uastring?: string, headers?: Record<string, string>);
|
constructor(uastring?: string, headers?: Record<string, string>);
|
||||||
constructor(extensions?: Record<string, RegexMap>, headers?: Record<string, string>);
|
constructor(extensions?: UAParserExt, headers?: Record<string, string>);
|
||||||
constructor(headers?: Record<string, string>);
|
constructor(headers?: Record<string, string>);
|
||||||
|
|
||||||
getUA(): string;
|
getUA(): string;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
/* UAParser.js v2.0.0-beta.1
|
/* UAParser.js v2.0.0-beta.3
|
||||||
Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
|
Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
|
||||||
UAParser.js PRO Personal License *//*
|
UAParser.js PRO Enterorise License *//*
|
||||||
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
||||||
Supports browser & node.js environment.
|
Supports browser & node.js environment.
|
||||||
Demo : https://faisalman.github.io/ua-parser-js
|
Demo : https://uaparser.dev
|
||||||
Source : https://github.com/faisalman/ua-parser-js */
|
Source : https://github.com/faisalman/ua-parser-js */
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -19,8 +19,7 @@
|
|||||||
// Constants
|
// Constants
|
||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
|
var LIBVERSION = '2.0.0-beta.3',
|
||||||
var LIBVERSION = '2.0.0-beta.1',
|
|
||||||
EMPTY = '',
|
EMPTY = '',
|
||||||
UNKNOWN = '?',
|
UNKNOWN = '?',
|
||||||
FUNC_TYPE = 'function',
|
FUNC_TYPE = 'function',
|
||||||
@@ -39,11 +38,12 @@
|
|||||||
TABLET = 'tablet',
|
TABLET = 'tablet',
|
||||||
SMARTTV = 'smarttv',
|
SMARTTV = 'smarttv',
|
||||||
WEARABLE = 'wearable',
|
WEARABLE = 'wearable',
|
||||||
|
XR = 'xr',
|
||||||
EMBEDDED = 'embedded',
|
EMBEDDED = 'embedded',
|
||||||
USER_AGENT = 'user-agent',
|
USER_AGENT = 'user-agent',
|
||||||
UA_MAX_LENGTH = 350,
|
UA_MAX_LENGTH = 500,
|
||||||
BRANDS = 'brands',
|
BRANDS = 'brands',
|
||||||
FORMFACTOR = 'formFactor',
|
FORMFACTORS = 'formFactors',
|
||||||
FULLVERLIST = 'fullVersionList',
|
FULLVERLIST = 'fullVersionList',
|
||||||
PLATFORM = 'platform',
|
PLATFORM = 'platform',
|
||||||
PLATFORMVER = 'platformVersion',
|
PLATFORMVER = 'platformVersion',
|
||||||
@@ -52,12 +52,12 @@
|
|||||||
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
||||||
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
||||||
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
||||||
CH_HEADER_FORM_FACTOR = CH_HEADER + '-form-factor',
|
CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors',
|
||||||
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
||||||
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
||||||
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
||||||
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
||||||
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTOR, BITNESS],
|
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
|
||||||
UA_BROWSER = 'browser',
|
UA_BROWSER = 'browser',
|
||||||
UA_CPU = 'cpu',
|
UA_CPU = 'cpu',
|
||||||
UA_DEVICE = 'device',
|
UA_DEVICE = 'device',
|
||||||
@@ -70,6 +70,7 @@
|
|||||||
BLACKBERRY = 'BlackBerry',
|
BLACKBERRY = 'BlackBerry',
|
||||||
GOOGLE = 'Google',
|
GOOGLE = 'Google',
|
||||||
HUAWEI = 'Huawei',
|
HUAWEI = 'Huawei',
|
||||||
|
LENOVO = 'Lenovo',
|
||||||
LG = 'LG',
|
LG = 'LG',
|
||||||
MICROSOFT = 'Microsoft',
|
MICROSOFT = 'Microsoft',
|
||||||
MOTOROLA = 'Motorola',
|
MOTOROLA = 'Motorola',
|
||||||
@@ -85,9 +86,11 @@
|
|||||||
FIREFOX = 'Firefox',
|
FIREFOX = 'Firefox',
|
||||||
OPERA = 'Opera',
|
OPERA = 'Opera',
|
||||||
FACEBOOK = 'Facebook',
|
FACEBOOK = 'Facebook',
|
||||||
|
SOGOU = 'Sogou',
|
||||||
WINDOWS = 'Windows';
|
WINDOWS = 'Windows';
|
||||||
|
|
||||||
var NAVIGATOR = (typeof window !== UNDEF_TYPE && window.navigator) ?
|
var isWindow = typeof window !== UNDEF_TYPE,
|
||||||
|
NAVIGATOR = (isWindow && window.navigator) ?
|
||||||
window.navigator :
|
window.navigator :
|
||||||
undefined,
|
undefined,
|
||||||
NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
|
NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
|
||||||
@@ -98,12 +101,21 @@
|
|||||||
// Helper
|
// Helper
|
||||||
//////////
|
//////////
|
||||||
|
|
||||||
var extend = function (regexes, extensions) {
|
var extend = function (defaultRgx, extensions) {
|
||||||
var mergedRegexes = {};
|
var mergedRgx = {};
|
||||||
for (var i in regexes) {
|
var extraRgx = extensions;
|
||||||
mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i];
|
if (!isExtensions(extensions)) {
|
||||||
|
extraRgx = {};
|
||||||
|
for (var i in extensions) {
|
||||||
|
for (var j in extensions[i]) {
|
||||||
|
extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
|
||||||
}
|
}
|
||||||
return mergedRegexes;
|
}
|
||||||
|
}
|
||||||
|
for (var k in defaultRgx) {
|
||||||
|
mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
|
||||||
|
}
|
||||||
|
return mergedRgx;
|
||||||
},
|
},
|
||||||
enumerize = function (arr) {
|
enumerize = function (arr) {
|
||||||
var enums = {};
|
var enums = {};
|
||||||
@@ -119,13 +131,16 @@
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
||||||
},
|
},
|
||||||
isExtensions = function (obj) {
|
isExtensions = function (obj, deep) {
|
||||||
for (var prop in obj) {
|
for (var prop in obj) {
|
||||||
return /^(browser|cpu|device|engine|os)$/.test(prop);
|
return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isString = function (val) {
|
||||||
|
return typeof val === STR_TYPE;
|
||||||
|
},
|
||||||
itemListToArray = function (header) {
|
itemListToArray = function (header) {
|
||||||
if (!header) return undefined;
|
if (!header) return undefined;
|
||||||
var arr = [];
|
var arr = [];
|
||||||
@@ -135,16 +150,16 @@
|
|||||||
var token = trim(tokens[i]).split(';v=');
|
var token = trim(tokens[i]).split(';v=');
|
||||||
arr[i] = { brand : token[0], version : token[1] };
|
arr[i] = { brand : token[0], version : token[1] };
|
||||||
} else {
|
} else {
|
||||||
arr[i] = tokens[i];
|
arr[i] = trim(tokens[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
},
|
},
|
||||||
lowerize = function (str) {
|
lowerize = function (str) {
|
||||||
return typeof(str) === STR_TYPE ? str.toLowerCase() : str;
|
return isString(str) ? str.toLowerCase() : str;
|
||||||
},
|
},
|
||||||
majorize = function (version) {
|
majorize = function (version) {
|
||||||
return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
||||||
},
|
},
|
||||||
setProps = function (arr) {
|
setProps = function (arr) {
|
||||||
for (var i in arr) {
|
for (var i in arr) {
|
||||||
@@ -158,15 +173,15 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
strip = function (pattern, str) {
|
strip = function (pattern, str) {
|
||||||
return str.replace(pattern, EMPTY);
|
return isString(str) ? str.replace(pattern, EMPTY) : str;
|
||||||
},
|
},
|
||||||
stripQuotes = function (val) {
|
stripQuotes = function (str) {
|
||||||
return typeof val === STR_TYPE ? strip(/\\?\"/g, val) : val;
|
return strip(/\\?\"/g, str);
|
||||||
},
|
},
|
||||||
trim = function (str, len) {
|
trim = function (str, len) {
|
||||||
if (typeof(str) === STR_TYPE) {
|
if (isString(str)) {
|
||||||
str = strip(/^\s\s*/, str);
|
str = strip(/^\s\s*/, str);
|
||||||
return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -264,12 +279,13 @@
|
|||||||
'RT' : 'ARM'
|
'RT' : 'ARM'
|
||||||
},
|
},
|
||||||
|
|
||||||
formFactorMap = {
|
formFactorsMap = {
|
||||||
'embedded' : 'Automotive',
|
'embedded' : 'Automotive',
|
||||||
'mobile' : 'Mobile',
|
'mobile' : 'Mobile',
|
||||||
'tablet' : ['Tablet', 'EInk'],
|
'tablet' : ['Tablet', 'EInk'],
|
||||||
'smarttv' : 'TV',
|
'smarttv' : 'TV',
|
||||||
'wearable' : ['VR', 'XR', 'Watch'],
|
'wearable' : 'Watch',
|
||||||
|
'xr' : ['VR', 'XR'],
|
||||||
'?' : ['Desktop', 'Unknown'],
|
'?' : ['Desktop', 'Unknown'],
|
||||||
'*' : undefined
|
'*' : undefined
|
||||||
};
|
};
|
||||||
@@ -295,28 +311,33 @@
|
|||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
|
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
|
||||||
], [VERSION, [NAME, OPERA+' Mini']], [
|
], [VERSION, [NAME, OPERA+' Mini']], [
|
||||||
|
/\bop(?:rg)?x\/([\w\.]+)/i // Opera GX
|
||||||
|
], [VERSION, [NAME, OPERA+' GX']], [
|
||||||
/\bopr\/([\w\.]+)/i // Opera Webkit
|
/\bopr\/([\w\.]+)/i // Opera Webkit
|
||||||
], [VERSION, [NAME, OPERA]], [
|
], [VERSION, [NAME, OPERA]], [
|
||||||
|
|
||||||
// Mixed
|
// Mixed
|
||||||
|
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
|
||||||
|
], [VERSION, [NAME, 'Baidu']], [
|
||||||
/(kindle)\/([\w\.]+)/i, // Kindle
|
/(kindle)\/([\w\.]+)/i, // Kindle
|
||||||
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
|
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
|
||||||
|
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
|
||||||
// Trident based
|
// Trident based
|
||||||
/(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
||||||
/(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser
|
|
||||||
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
||||||
|
|
||||||
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
||||||
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
|
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar)\/([-\w\.]+)/i,
|
||||||
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
|
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar
|
||||||
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
|
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
|
||||||
/(weibo)__([\d\.]+)/i // Weibo
|
/(weibo)__([\d\.]+)/i // Weibo
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
|
/\bddg\/([\w\.]+)/i // DuckDuckGo
|
||||||
|
], [VERSION, [NAME, 'DuckDuckGo']], [
|
||||||
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
||||||
], [VERSION, [NAME, 'UCBrowser']], [
|
], [VERSION, [NAME, 'UCBrowser']], [
|
||||||
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
||||||
/\bqbcore\/([\w\.]+).+microm/i
|
/\bqbcore\/([\w\.]+).+microm/i,
|
||||||
], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
|
|
||||||
/micromessenger\/([\w\.]+)/i // WeChat
|
/micromessenger\/([\w\.]+)/i // WeChat
|
||||||
], [VERSION, [NAME, 'WeChat']], [
|
], [VERSION, [NAME, 'WeChat']], [
|
||||||
/konqueror\/([\w\.]+)/i // Konqueror
|
/konqueror\/([\w\.]+)/i // Konqueror
|
||||||
@@ -325,6 +346,8 @@
|
|||||||
], [VERSION, [NAME, 'IE']], [
|
], [VERSION, [NAME, 'IE']], [
|
||||||
/ya(?:search)?browser\/([\w\.]+)/i // Yandex
|
/ya(?:search)?browser\/([\w\.]+)/i // Yandex
|
||||||
], [VERSION, [NAME, 'Yandex']], [
|
], [VERSION, [NAME, 'Yandex']], [
|
||||||
|
/slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
|
||||||
|
], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [
|
||||||
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
|
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
|
||||||
], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
|
], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
|
||||||
/\bfocus\/([\w\.]+)/i // Firefox Focus
|
/\bfocus\/([\w\.]+)/i // Firefox Focus
|
||||||
@@ -343,26 +366,36 @@
|
|||||||
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
||||||
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
||||||
], [[NAME, '360' + SUFFIX_BROWSER]], [
|
], [[NAME, '360' + SUFFIX_BROWSER]], [
|
||||||
/(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i
|
/\b(qq)\/([\w\.]+)/i // QQ
|
||||||
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser
|
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
|
||||||
|
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
|
||||||
|
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
|
||||||
|
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
||||||
|
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
||||||
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
||||||
], [[NAME, /_/g, ' '], VERSION], [
|
], [[NAME, /_/g, ' '], VERSION], [
|
||||||
|
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
|
||||||
|
], [VERSION, [NAME, SOGOU + ' Explorer']], [
|
||||||
|
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
|
||||||
|
], [[NAME, SOGOU + ' Mobile'], VERSION], [
|
||||||
/(electron)\/([\w\.]+) safari/i, // Electron-based App
|
/(electron)\/([\w\.]+) safari/i, // Electron-based App
|
||||||
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
||||||
/m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser
|
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser
|
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
|
||||||
/(lbbrowser)/i, // LieBao Browser
|
|
||||||
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
||||||
], [NAME], [
|
], [NAME], [
|
||||||
|
|
||||||
// WebView
|
// WebView
|
||||||
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
||||||
], [[NAME, FACEBOOK], VERSION], [
|
], [[NAME, FACEBOOK], VERSION], [
|
||||||
|
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
|
||||||
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
|
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
|
||||||
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
|
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
|
||||||
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
||||||
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
||||||
|
/(alipay)client\/([\w\.]+)/i, // Alipay
|
||||||
|
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
|
||||||
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
|
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
||||||
@@ -402,23 +435,24 @@
|
|||||||
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
|
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
|
||||||
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
||||||
], [[NAME, 'Netscape'], VERSION], [
|
], [[NAME, 'Netscape'], VERSION], [
|
||||||
|
/(wolvic)\/([\w\.]+)/i // Wolvic
|
||||||
|
], [NAME, VERSION], [
|
||||||
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
||||||
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
||||||
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
||||||
/(swiftfox)/i, // Swiftfox
|
/(swiftfox)/i, // Swiftfox
|
||||||
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
|
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
|
||||||
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
|
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
||||||
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
||||||
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
||||||
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
||||||
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
||||||
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
|
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser
|
||||||
/(links) \(([\w\.]+)/i, // Links
|
/(links) \(([\w\.]+)/i // Links
|
||||||
/panasonic;(viera)/i // Panasonic Viera
|
], [NAME, [VERSION, /_/g, '.']], [
|
||||||
], [NAME, VERSION], [
|
|
||||||
|
|
||||||
/(cobalt)\/([\w\.]+)/i // Cobalt
|
/(cobalt)\/([\w\.]+)/i // Cobalt
|
||||||
], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
|
], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
|
||||||
@@ -494,7 +528,7 @@
|
|||||||
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
||||||
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
||||||
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
||||||
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|\))/i, // Xiaomi Redmi 'numeric' models
|
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
|
||||||
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
|
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
|
||||||
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
||||||
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
|
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
|
||||||
@@ -505,6 +539,8 @@
|
|||||||
/; (\w+) bui.+ oppo/i,
|
/; (\w+) bui.+ oppo/i,
|
||||||
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
||||||
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
|
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
|
||||||
|
/\b(opd2\d{3}a?) bui/i
|
||||||
|
], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [
|
||||||
|
|
||||||
// Vivo
|
// Vivo
|
||||||
/vivo (\w+)(?: bui|\))/i,
|
/vivo (\w+)(?: bui|\))/i,
|
||||||
@@ -534,7 +570,7 @@
|
|||||||
// Lenovo
|
// Lenovo
|
||||||
/(ideatab[-\w ]+)/i,
|
/(ideatab[-\w ]+)/i,
|
||||||
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
|
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
|
||||||
], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
|
], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
|
||||||
|
|
||||||
// Nokia
|
// Nokia
|
||||||
/(?:maemo|nokia).*(n900|lumia \d+)/i,
|
/(?:maemo|nokia).*(n900|lumia \d+)/i,
|
||||||
@@ -688,12 +724,17 @@
|
|||||||
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
||||||
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
|
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
|
||||||
], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
|
], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
|
||||||
/droid.+; (glass) \d/i // Google Glass
|
|
||||||
], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
|
|
||||||
/droid.+; (wt63?0{2,3})\)/i
|
/droid.+; (wt63?0{2,3})\)/i
|
||||||
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
||||||
/(quest( 2| pro)?)/i // Oculus Quest
|
|
||||||
], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
|
///////////////////
|
||||||
|
// XR
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
/droid.+; (glass) \d/i // Google Glass
|
||||||
|
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
||||||
|
/(quest( \d| pro)?)/i // Oculus Quest
|
||||||
|
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// EMBEDDED
|
// EMBEDDED
|
||||||
@@ -708,7 +749,7 @@
|
|||||||
// MIXED (GENERIC)
|
// MIXED (GENERIC)
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
/droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
|
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
|
||||||
], [MODEL, [TYPE, MOBILE]], [
|
], [MODEL, [TYPE, MOBILE]], [
|
||||||
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
|
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
|
||||||
], [MODEL, [TYPE, TABLET]], [
|
], [MODEL, [TYPE, TABLET]], [
|
||||||
@@ -745,12 +786,12 @@
|
|||||||
// Windows
|
// Windows
|
||||||
/microsoft (windows) (vista|xp)/i // Windows (iTunes)
|
/microsoft (windows) (vista|xp)/i // Windows (iTunes)
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/(windows) nt 6\.2; (arm)/i, // Windows RT
|
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone
|
||||||
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone
|
|
||||||
/(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
|
|
||||||
], [NAME, [VERSION, strMapper, windowsVersionMap]], [
|
], [NAME, [VERSION, strMapper, windowsVersionMap]], [
|
||||||
/(win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
/windows nt 6\.2; (arm)/i, // Windows RT
|
||||||
], [[NAME, WINDOWS], [VERSION, strMapper, windowsVersionMap]], [
|
/windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i,
|
||||||
|
/(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
||||||
|
], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [
|
||||||
|
|
||||||
// iOS/macOS
|
// iOS/macOS
|
||||||
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
||||||
@@ -824,7 +865,7 @@
|
|||||||
var defaultProps = (function () {
|
var defaultProps = (function () {
|
||||||
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
||||||
setProps.call(props.init, [
|
setProps.call(props.init, [
|
||||||
[UA_BROWSER, [NAME, VERSION, MAJOR]],
|
[UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]],
|
||||||
[UA_CPU, [ARCHITECTURE]],
|
[UA_CPU, [ARCHITECTURE]],
|
||||||
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
|
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
|
||||||
[UA_ENGINE, [NAME, VERSION]],
|
[UA_ENGINE, [NAME, VERSION]],
|
||||||
@@ -952,7 +993,7 @@
|
|||||||
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
||||||
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
||||||
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
||||||
[FORMFACTOR, itemListToArray(uach[CH_HEADER_FORM_FACTOR])],
|
[FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])],
|
||||||
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
@@ -1039,15 +1080,16 @@
|
|||||||
|
|
||||||
switch (this.itemType) {
|
switch (this.itemType) {
|
||||||
case UA_BROWSER:
|
case UA_BROWSER:
|
||||||
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS];
|
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
|
||||||
if (brands) {
|
if (brands) {
|
||||||
for (var i in brands) {
|
for (var i in brands) {
|
||||||
var brandName = brands[i].brand,
|
var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]),
|
||||||
brandVersion = brands[i].version;
|
brandVersion = brands[i].version;
|
||||||
if (!/not.a.brand/i.test(brandName) && (i < 1 || /chromi/i.test(this.get(NAME)))) {
|
if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) {
|
||||||
this.set(NAME, strip(GOOGLE+' ', brandName))
|
this.set(NAME, brandName)
|
||||||
.set(VERSION, brandVersion)
|
.set(VERSION, brandVersion)
|
||||||
.set(MAJOR, majorize(brandVersion));
|
.set(MAJOR, majorize(brandVersion));
|
||||||
|
prevName = brandName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1066,15 +1108,20 @@
|
|||||||
if (uaCH[MODEL]) {
|
if (uaCH[MODEL]) {
|
||||||
this.set(MODEL, uaCH[MODEL]);
|
this.set(MODEL, uaCH[MODEL]);
|
||||||
}
|
}
|
||||||
if (uaCH[FORMFACTOR]) {
|
// Xbox-Specific Detection
|
||||||
|
if (uaCH[MODEL] == 'Xbox') {
|
||||||
|
this.set(TYPE, CONSOLE)
|
||||||
|
.set(VENDOR, MICROSOFT);
|
||||||
|
}
|
||||||
|
if (uaCH[FORMFACTORS]) {
|
||||||
var ff;
|
var ff;
|
||||||
if (typeof uaCH[FORMFACTOR] !== 'string') {
|
if (typeof uaCH[FORMFACTORS] !== 'string') {
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
while (!ff && idx < uaCH[FORMFACTOR].length) {
|
while (!ff && idx < uaCH[FORMFACTORS].length) {
|
||||||
ff = strMapper(uaCH[FORMFACTOR][idx++], formFactorMap);
|
ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ff = strMapper(uaCH[FORMFACTOR], formFactorMap);
|
ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
|
||||||
}
|
}
|
||||||
this.set(TYPE, ff);
|
this.set(TYPE, ff);
|
||||||
}
|
}
|
||||||
@@ -1087,6 +1134,11 @@
|
|||||||
this.set(NAME, osName)
|
this.set(NAME, osName)
|
||||||
.set(VERSION, osVersion);
|
.set(VERSION, osVersion);
|
||||||
}
|
}
|
||||||
|
// Xbox-Specific Detection
|
||||||
|
if (this.get(NAME) == WINDOWS && uaCH[MODEL] == 'Xbox') {
|
||||||
|
this.set(NAME, 'Xbox')
|
||||||
|
.set(VERSION, undefined);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case UA_RESULT:
|
case UA_RESULT:
|
||||||
var data = this.data;
|
var data = this.data;
|
||||||
@@ -1120,7 +1172,7 @@
|
|||||||
function UAParser (ua, extensions, headers) {
|
function UAParser (ua, extensions, headers) {
|
||||||
|
|
||||||
if (typeof ua === OBJ_TYPE) {
|
if (typeof ua === OBJ_TYPE) {
|
||||||
if (isExtensions(ua)) {
|
if (isExtensions(ua, true)) {
|
||||||
if (typeof extensions === OBJ_TYPE) {
|
if (typeof extensions === OBJ_TYPE) {
|
||||||
headers = extensions; // case UAParser(extensions, headers)
|
headers = extensions; // case UAParser(extensions, headers)
|
||||||
}
|
}
|
||||||
@@ -1130,7 +1182,7 @@
|
|||||||
extensions = undefined;
|
extensions = undefined;
|
||||||
}
|
}
|
||||||
ua = undefined;
|
ua = undefined;
|
||||||
} else if (typeof ua === STR_TYPE && !isExtensions(extensions)) {
|
} else if (typeof ua === STR_TYPE && !isExtensions(extensions, true)) {
|
||||||
headers = extensions; // case UAParser(ua, headers)
|
headers = extensions; // case UAParser(ua, headers)
|
||||||
extensions = undefined;
|
extensions = undefined;
|
||||||
}
|
}
|
||||||
@@ -1180,7 +1232,7 @@
|
|||||||
['getResult', createItemFunc(UA_RESULT)],
|
['getResult', createItemFunc(UA_RESULT)],
|
||||||
['getUA', function () { return userAgent; }],
|
['getUA', function () { return userAgent; }],
|
||||||
['setUA', function (ua) {
|
['setUA', function (ua) {
|
||||||
if (typeof ua === STR_TYPE)
|
if (isString(ua))
|
||||||
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
|
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
|
||||||
return this;
|
return this;
|
||||||
}]
|
}]
|
||||||
@@ -1191,7 +1243,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
UAParser.VERSION = LIBVERSION;
|
UAParser.VERSION = LIBVERSION;
|
||||||
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
|
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
|
||||||
UAParser.CPU = enumerize([ARCHITECTURE]);
|
UAParser.CPU = enumerize([ARCHITECTURE]);
|
||||||
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
||||||
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
||||||
@@ -1201,7 +1253,7 @@
|
|||||||
//////////
|
//////////
|
||||||
|
|
||||||
// check js environment
|
// check js environment
|
||||||
if (typeof(exports) !== UNDEF_TYPE) {
|
if (typeof exports !== UNDEF_TYPE) {
|
||||||
// nodejs env
|
// nodejs env
|
||||||
if (typeof module !== UNDEF_TYPE && module.exports) {
|
if (typeof module !== UNDEF_TYPE && module.exports) {
|
||||||
exports = module.exports = UAParser;
|
exports = module.exports = UAParser;
|
||||||
@@ -1209,11 +1261,11 @@
|
|||||||
exports.UAParser = UAParser;
|
exports.UAParser = UAParser;
|
||||||
} else {
|
} else {
|
||||||
// requirejs env (optional)
|
// requirejs env (optional)
|
||||||
if (typeof(define) === FUNC_TYPE && define.amd) {
|
if (typeof define === FUNC_TYPE && define.amd) {
|
||||||
define(function () {
|
define(function () {
|
||||||
return UAParser;
|
return UAParser;
|
||||||
});
|
});
|
||||||
} else if (typeof window !== UNDEF_TYPE) {
|
} else if (isWindow) {
|
||||||
// browser env
|
// browser env
|
||||||
window.UAParser = UAParser;
|
window.UAParser = UAParser;
|
||||||
}
|
}
|
||||||
@@ -1224,7 +1276,7 @@
|
|||||||
// In AMD env the global scope should be kept clean, but jQuery is an exception.
|
// In AMD env the global scope should be kept clean, but jQuery is an exception.
|
||||||
// jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
|
// jQuery always exports to global scope, unless jQuery.noConflict(true) is used,
|
||||||
// and we should catch that.
|
// and we should catch that.
|
||||||
var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);
|
var $ = isWindow && (window.jQuery || window.Zepto);
|
||||||
if ($ && !$.ua) {
|
if ($ && !$.ua) {
|
||||||
var parser = new UAParser();
|
var parser = new UAParser();
|
||||||
$.ua = parser.getResult();
|
$.ua = parser.getResult();
|
||||||
|
|||||||
@@ -3,12 +3,12 @@
|
|||||||
// Source: /src/main/ua-parser.js
|
// Source: /src/main/ua-parser.js
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
/* UAParser.js v2.0.0-beta.1
|
/* UAParser.js v2.0.0-beta.3
|
||||||
Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
|
Copyright © 2012-2023 Faisal Salman <f@faisalman.com>
|
||||||
UAParser.js PRO Personal License *//*
|
UAParser.js PRO Enterorise License *//*
|
||||||
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
||||||
Supports browser & node.js environment.
|
Supports browser & node.js environment.
|
||||||
Demo : https://faisalman.github.io/ua-parser-js
|
Demo : https://uaparser.dev
|
||||||
Source : https://github.com/faisalman/ua-parser-js */
|
Source : https://github.com/faisalman/ua-parser-js */
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -21,8 +21,7 @@
|
|||||||
// Constants
|
// Constants
|
||||||
/////////////
|
/////////////
|
||||||
|
|
||||||
|
var LIBVERSION = '2.0.0-beta.3',
|
||||||
var LIBVERSION = '2.0.0-beta.1',
|
|
||||||
EMPTY = '',
|
EMPTY = '',
|
||||||
UNKNOWN = '?',
|
UNKNOWN = '?',
|
||||||
FUNC_TYPE = 'function',
|
FUNC_TYPE = 'function',
|
||||||
@@ -41,11 +40,12 @@
|
|||||||
TABLET = 'tablet',
|
TABLET = 'tablet',
|
||||||
SMARTTV = 'smarttv',
|
SMARTTV = 'smarttv',
|
||||||
WEARABLE = 'wearable',
|
WEARABLE = 'wearable',
|
||||||
|
XR = 'xr',
|
||||||
EMBEDDED = 'embedded',
|
EMBEDDED = 'embedded',
|
||||||
USER_AGENT = 'user-agent',
|
USER_AGENT = 'user-agent',
|
||||||
UA_MAX_LENGTH = 350,
|
UA_MAX_LENGTH = 500,
|
||||||
BRANDS = 'brands',
|
BRANDS = 'brands',
|
||||||
FORMFACTOR = 'formFactor',
|
FORMFACTORS = 'formFactors',
|
||||||
FULLVERLIST = 'fullVersionList',
|
FULLVERLIST = 'fullVersionList',
|
||||||
PLATFORM = 'platform',
|
PLATFORM = 'platform',
|
||||||
PLATFORMVER = 'platformVersion',
|
PLATFORMVER = 'platformVersion',
|
||||||
@@ -54,12 +54,12 @@
|
|||||||
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
CH_HEADER_FULL_VER_LIST = CH_HEADER + '-full-version-list',
|
||||||
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
CH_HEADER_ARCH = CH_HEADER + '-arch',
|
||||||
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
CH_HEADER_BITNESS = CH_HEADER + '-' + BITNESS,
|
||||||
CH_HEADER_FORM_FACTOR = CH_HEADER + '-form-factor',
|
CH_HEADER_FORM_FACTORS = CH_HEADER + '-form-factors',
|
||||||
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
CH_HEADER_MOBILE = CH_HEADER + '-' + MOBILE,
|
||||||
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
CH_HEADER_MODEL = CH_HEADER + '-' + MODEL,
|
||||||
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
CH_HEADER_PLATFORM = CH_HEADER + '-' + PLATFORM,
|
||||||
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
CH_HEADER_PLATFORM_VER = CH_HEADER_PLATFORM + '-version',
|
||||||
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTOR, BITNESS],
|
CH_ALL_VALUES = [BRANDS, FULLVERLIST, MOBILE, MODEL, PLATFORM, PLATFORMVER, ARCHITECTURE, FORMFACTORS, BITNESS],
|
||||||
UA_BROWSER = 'browser',
|
UA_BROWSER = 'browser',
|
||||||
UA_CPU = 'cpu',
|
UA_CPU = 'cpu',
|
||||||
UA_DEVICE = 'device',
|
UA_DEVICE = 'device',
|
||||||
@@ -72,6 +72,7 @@
|
|||||||
BLACKBERRY = 'BlackBerry',
|
BLACKBERRY = 'BlackBerry',
|
||||||
GOOGLE = 'Google',
|
GOOGLE = 'Google',
|
||||||
HUAWEI = 'Huawei',
|
HUAWEI = 'Huawei',
|
||||||
|
LENOVO = 'Lenovo',
|
||||||
LG = 'LG',
|
LG = 'LG',
|
||||||
MICROSOFT = 'Microsoft',
|
MICROSOFT = 'Microsoft',
|
||||||
MOTOROLA = 'Motorola',
|
MOTOROLA = 'Motorola',
|
||||||
@@ -87,9 +88,11 @@
|
|||||||
FIREFOX = 'Firefox',
|
FIREFOX = 'Firefox',
|
||||||
OPERA = 'Opera',
|
OPERA = 'Opera',
|
||||||
FACEBOOK = 'Facebook',
|
FACEBOOK = 'Facebook',
|
||||||
|
SOGOU = 'Sogou',
|
||||||
WINDOWS = 'Windows';
|
WINDOWS = 'Windows';
|
||||||
|
|
||||||
var NAVIGATOR = (typeof window !== UNDEF_TYPE && window.navigator) ?
|
var isWindow = typeof window !== UNDEF_TYPE,
|
||||||
|
NAVIGATOR = (isWindow && window.navigator) ?
|
||||||
window.navigator :
|
window.navigator :
|
||||||
undefined,
|
undefined,
|
||||||
NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
|
NAVIGATOR_UADATA = (NAVIGATOR && NAVIGATOR.userAgentData) ?
|
||||||
@@ -100,12 +103,21 @@
|
|||||||
// Helper
|
// Helper
|
||||||
//////////
|
//////////
|
||||||
|
|
||||||
var extend = function (regexes, extensions) {
|
var extend = function (defaultRgx, extensions) {
|
||||||
var mergedRegexes = {};
|
var mergedRgx = {};
|
||||||
for (var i in regexes) {
|
var extraRgx = extensions;
|
||||||
mergedRegexes[i] = extensions[i] && extensions[i].length % 2 === 0 ? extensions[i].concat(regexes[i]) : regexes[i];
|
if (!isExtensions(extensions)) {
|
||||||
|
extraRgx = {};
|
||||||
|
for (var i in extensions) {
|
||||||
|
for (var j in extensions[i]) {
|
||||||
|
extraRgx[j] = extensions[i][j].concat(extraRgx[j] ? extraRgx[j] : []);
|
||||||
}
|
}
|
||||||
return mergedRegexes;
|
}
|
||||||
|
}
|
||||||
|
for (var k in defaultRgx) {
|
||||||
|
mergedRgx[k] = extraRgx[k] && extraRgx[k].length % 2 === 0 ? extraRgx[k].concat(defaultRgx[k]) : defaultRgx[k];
|
||||||
|
}
|
||||||
|
return mergedRgx;
|
||||||
},
|
},
|
||||||
enumerize = function (arr) {
|
enumerize = function (arr) {
|
||||||
var enums = {};
|
var enums = {};
|
||||||
@@ -121,13 +133,16 @@
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
return isString(str1) ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;
|
||||||
},
|
},
|
||||||
isExtensions = function (obj) {
|
isExtensions = function (obj, deep) {
|
||||||
for (var prop in obj) {
|
for (var prop in obj) {
|
||||||
return /^(browser|cpu|device|engine|os)$/.test(prop);
|
return /^(browser|cpu|device|engine|os)$/.test(prop) || (deep ? isExtensions(obj[prop]) : false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isString = function (val) {
|
||||||
|
return typeof val === STR_TYPE;
|
||||||
|
},
|
||||||
itemListToArray = function (header) {
|
itemListToArray = function (header) {
|
||||||
if (!header) return undefined;
|
if (!header) return undefined;
|
||||||
var arr = [];
|
var arr = [];
|
||||||
@@ -137,16 +152,16 @@
|
|||||||
var token = trim(tokens[i]).split(';v=');
|
var token = trim(tokens[i]).split(';v=');
|
||||||
arr[i] = { brand : token[0], version : token[1] };
|
arr[i] = { brand : token[0], version : token[1] };
|
||||||
} else {
|
} else {
|
||||||
arr[i] = tokens[i];
|
arr[i] = trim(tokens[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
},
|
},
|
||||||
lowerize = function (str) {
|
lowerize = function (str) {
|
||||||
return typeof(str) === STR_TYPE ? str.toLowerCase() : str;
|
return isString(str) ? str.toLowerCase() : str;
|
||||||
},
|
},
|
||||||
majorize = function (version) {
|
majorize = function (version) {
|
||||||
return typeof(version) === STR_TYPE ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
return isString(version) ? strip(/[^\d\.]/g, version).split('.')[0] : undefined;
|
||||||
},
|
},
|
||||||
setProps = function (arr) {
|
setProps = function (arr) {
|
||||||
for (var i in arr) {
|
for (var i in arr) {
|
||||||
@@ -160,15 +175,15 @@
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
strip = function (pattern, str) {
|
strip = function (pattern, str) {
|
||||||
return str.replace(pattern, EMPTY);
|
return isString(str) ? str.replace(pattern, EMPTY) : str;
|
||||||
},
|
},
|
||||||
stripQuotes = function (val) {
|
stripQuotes = function (str) {
|
||||||
return typeof val === STR_TYPE ? strip(/\\?\"/g, val) : val;
|
return strip(/\\?\"/g, str);
|
||||||
},
|
},
|
||||||
trim = function (str, len) {
|
trim = function (str, len) {
|
||||||
if (typeof(str) === STR_TYPE) {
|
if (isString(str)) {
|
||||||
str = strip(/^\s\s*/, str);
|
str = strip(/^\s\s*/, str);
|
||||||
return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -266,12 +281,13 @@
|
|||||||
'RT' : 'ARM'
|
'RT' : 'ARM'
|
||||||
},
|
},
|
||||||
|
|
||||||
formFactorMap = {
|
formFactorsMap = {
|
||||||
'embedded' : 'Automotive',
|
'embedded' : 'Automotive',
|
||||||
'mobile' : 'Mobile',
|
'mobile' : 'Mobile',
|
||||||
'tablet' : ['Tablet', 'EInk'],
|
'tablet' : ['Tablet', 'EInk'],
|
||||||
'smarttv' : 'TV',
|
'smarttv' : 'TV',
|
||||||
'wearable' : ['VR', 'XR', 'Watch'],
|
'wearable' : 'Watch',
|
||||||
|
'xr' : ['VR', 'XR'],
|
||||||
'?' : ['Desktop', 'Unknown'],
|
'?' : ['Desktop', 'Unknown'],
|
||||||
'*' : undefined
|
'*' : undefined
|
||||||
};
|
};
|
||||||
@@ -297,28 +313,33 @@
|
|||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
|
/opios[\/ ]+([\w\.]+)/i // Opera mini on iphone >= 8.0
|
||||||
], [VERSION, [NAME, OPERA+' Mini']], [
|
], [VERSION, [NAME, OPERA+' Mini']], [
|
||||||
|
/\bop(?:rg)?x\/([\w\.]+)/i // Opera GX
|
||||||
|
], [VERSION, [NAME, OPERA+' GX']], [
|
||||||
/\bopr\/([\w\.]+)/i // Opera Webkit
|
/\bopr\/([\w\.]+)/i // Opera Webkit
|
||||||
], [VERSION, [NAME, OPERA]], [
|
], [VERSION, [NAME, OPERA]], [
|
||||||
|
|
||||||
// Mixed
|
// Mixed
|
||||||
|
/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i // Baidu
|
||||||
|
], [VERSION, [NAME, 'Baidu']], [
|
||||||
/(kindle)\/([\w\.]+)/i, // Kindle
|
/(kindle)\/([\w\.]+)/i, // Kindle
|
||||||
/(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, // Lunascape/Maxthon/Netfront/Jasmine/Blazer
|
/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,
|
||||||
|
// Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir
|
||||||
// Trident based
|
// Trident based
|
||||||
/(avant |iemobile|slim)(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
/(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, // Avant/IEMobile/SlimBrowser
|
||||||
/(ba?idubrowser)[\/ ]?([\w\.]+)/i, // Baidu Browser
|
|
||||||
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
/(?:ms|\()(ie) ([\w\.]+)/i, // Internet Explorer
|
||||||
|
|
||||||
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
// Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon
|
||||||
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i,
|
/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar)\/([-\w\.]+)/i,
|
||||||
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo
|
// Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar
|
||||||
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
|
/(heytap|ovi)browser\/([\d\.]+)/i, // HeyTap/Ovi
|
||||||
/(weibo)__([\d\.]+)/i // Weibo
|
/(weibo)__([\d\.]+)/i // Weibo
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
|
/\bddg\/([\w\.]+)/i // DuckDuckGo
|
||||||
|
], [VERSION, [NAME, 'DuckDuckGo']], [
|
||||||
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i // UCBrowser
|
||||||
], [VERSION, [NAME, 'UCBrowser']], [
|
], [VERSION, [NAME, 'UCBrowser']], [
|
||||||
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
/microm.+\bqbcore\/([\w\.]+)/i, // WeChat Desktop for Windows Built-in Browser
|
||||||
/\bqbcore\/([\w\.]+).+microm/i
|
/\bqbcore\/([\w\.]+).+microm/i,
|
||||||
], [VERSION, [NAME, 'WeChat(Win) Desktop']], [
|
|
||||||
/micromessenger\/([\w\.]+)/i // WeChat
|
/micromessenger\/([\w\.]+)/i // WeChat
|
||||||
], [VERSION, [NAME, 'WeChat']], [
|
], [VERSION, [NAME, 'WeChat']], [
|
||||||
/konqueror\/([\w\.]+)/i // Konqueror
|
/konqueror\/([\w\.]+)/i // Konqueror
|
||||||
@@ -327,6 +348,8 @@
|
|||||||
], [VERSION, [NAME, 'IE']], [
|
], [VERSION, [NAME, 'IE']], [
|
||||||
/ya(?:search)?browser\/([\w\.]+)/i // Yandex
|
/ya(?:search)?browser\/([\w\.]+)/i // Yandex
|
||||||
], [VERSION, [NAME, 'Yandex']], [
|
], [VERSION, [NAME, 'Yandex']], [
|
||||||
|
/slbrowser\/([\w\.]+)/i // Smart Lenovo Browser
|
||||||
|
], [VERSION, [NAME, 'Smart ' + LENOVO + SUFFIX_BROWSER]], [
|
||||||
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
|
/(avast|avg)\/([\w\.]+)/i // Avast/AVG Secure Browser
|
||||||
], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
|
], [[NAME, /(.+)/, '$1 Secure' + SUFFIX_BROWSER], VERSION], [
|
||||||
/\bfocus\/([\w\.]+)/i // Firefox Focus
|
/\bfocus\/([\w\.]+)/i // Firefox Focus
|
||||||
@@ -345,26 +368,36 @@
|
|||||||
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
], [VERSION, [NAME, PREFIX_MOBILE + FIREFOX]], [
|
||||||
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
/\bqihu|(qi?ho?o?|360)browser/i // 360
|
||||||
], [[NAME, '360' + SUFFIX_BROWSER]], [
|
], [[NAME, '360' + SUFFIX_BROWSER]], [
|
||||||
/(oculus|samsung|sailfish|huawei)browser\/([\w\.]+)/i
|
/\b(qq)\/([\w\.]+)/i // QQ
|
||||||
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Samsung/Sailfish/Huawei Browser
|
], [[NAME, /(.+)/, '$1Browser'], VERSION], [
|
||||||
|
/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i
|
||||||
|
], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser
|
||||||
|
/samsungbrowser\/([\w\.]+)/i // Samsung Internet
|
||||||
|
], [VERSION, [NAME, SAMSUNG + ' Internet']], [
|
||||||
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
|
||||||
], [[NAME, /_/g, ' '], VERSION], [
|
], [[NAME, /_/g, ' '], VERSION], [
|
||||||
|
/metasr[\/ ]?([\d\.]+)/i // Sogou Explorer
|
||||||
|
], [VERSION, [NAME, SOGOU + ' Explorer']], [
|
||||||
|
/(sogou)mo\w+\/([\d\.]+)/i // Sogou Mobile
|
||||||
|
], [[NAME, SOGOU + ' Mobile'], VERSION], [
|
||||||
/(electron)\/([\w\.]+) safari/i, // Electron-based App
|
/(electron)\/([\w\.]+) safari/i, // Electron-based App
|
||||||
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, // Tesla
|
||||||
/m?(qqbrowser|baiduboxapp|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/Baidu App/2345 Browser
|
/m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i // QQBrowser/2345 Browser
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/(metasr)[\/ ]?([\w\.]+)/i, // SouGouBrowser
|
/(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq
|
||||||
/(lbbrowser)/i, // LieBao Browser
|
|
||||||
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
||||||
], [NAME], [
|
], [NAME], [
|
||||||
|
|
||||||
// WebView
|
// WebView
|
||||||
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i // Facebook App for iOS & Android
|
||||||
], [[NAME, FACEBOOK], VERSION], [
|
], [[NAME, FACEBOOK], VERSION], [
|
||||||
|
/(Klarna)\/([\w\.]+)/i, // Klarna Shopping Browser for iOS & Android
|
||||||
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
|
/(kakao(?:talk|story))[\/ ]([\w\.]+)/i, // Kakao App
|
||||||
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
|
/(naver)\(.*?(\d+\.[\w\.]+).*\)/i, // Naver InApp
|
||||||
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
/safari (line)\/([\w\.]+)/i, // Line App for iOS
|
||||||
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
/\b(line)\/([\w\.]+)\/iab/i, // Line App for Android
|
||||||
|
/(alipay)client\/([\w\.]+)/i, // Alipay
|
||||||
|
/(twitter)(?:and| f.+e\/([\w\.]+))/i, // Twitter
|
||||||
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
|
/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i // Chromium/Instagram/Snapchat
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
/\bgsa\/([\w\.]+) .*safari\//i // Google Search Appliance on iOS
|
||||||
@@ -404,23 +437,24 @@
|
|||||||
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
|
], [[NAME, PREFIX_MOBILE + FIREFOX], VERSION], [
|
||||||
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
/(navigator|netscape\d?)\/([-\w\.]+)/i // Netscape
|
||||||
], [[NAME, 'Netscape'], VERSION], [
|
], [[NAME, 'Netscape'], VERSION], [
|
||||||
|
/(wolvic)\/([\w\.]+)/i // Wolvic
|
||||||
|
], [NAME, VERSION], [
|
||||||
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
/mobile vr; rv:([\w\.]+)\).+firefox/i // Firefox Reality
|
||||||
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
], [VERSION, [NAME, FIREFOX+' Reality']], [
|
||||||
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
/ekiohf.+(flow)\/([\w\.]+)/i, // Flow
|
||||||
/(swiftfox)/i, // Swiftfox
|
/(swiftfox)/i, // Swiftfox
|
||||||
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i,
|
/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,
|
||||||
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror/Klar
|
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
|
||||||
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,
|
||||||
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
|
||||||
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
/(firefox)\/([\w\.]+)/i, // Other Firefox-based
|
||||||
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, // Mozilla
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,
|
||||||
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Sleipnir/Obigo/Mosaic/Go/ICE/UP.Browser
|
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser
|
||||||
/(links) \(([\w\.]+)/i, // Links
|
/(links) \(([\w\.]+)/i // Links
|
||||||
/panasonic;(viera)/i // Panasonic Viera
|
], [NAME, [VERSION, /_/g, '.']], [
|
||||||
], [NAME, VERSION], [
|
|
||||||
|
|
||||||
/(cobalt)\/([\w\.]+)/i // Cobalt
|
/(cobalt)\/([\w\.]+)/i // Cobalt
|
||||||
], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
|
], [NAME, [VERSION, /[^\d\.]+./, EMPTY]]
|
||||||
@@ -496,7 +530,7 @@
|
|||||||
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
/\b; (\w+) build\/hm\1/i, // Xiaomi Hongmi 'numeric' models
|
||||||
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, // Xiaomi Hongmi
|
||||||
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, // Xiaomi Redmi
|
||||||
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|\))/i, // Xiaomi Redmi 'numeric' models
|
/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, // Xiaomi Redmi 'numeric' models
|
||||||
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
|
/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i // Xiaomi Mi
|
||||||
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [
|
||||||
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
|
/oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, // Redmi Pad
|
||||||
@@ -507,6 +541,8 @@
|
|||||||
/; (\w+) bui.+ oppo/i,
|
/; (\w+) bui.+ oppo/i,
|
||||||
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i
|
||||||
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
|
], [MODEL, [VENDOR, 'OPPO'], [TYPE, MOBILE]], [
|
||||||
|
/\b(opd2\d{3}a?) bui/i
|
||||||
|
], [MODEL, [VENDOR, 'OPPO'], [TYPE, TABLET]], [
|
||||||
|
|
||||||
// Vivo
|
// Vivo
|
||||||
/vivo (\w+)(?: bui|\))/i,
|
/vivo (\w+)(?: bui|\))/i,
|
||||||
@@ -536,7 +572,7 @@
|
|||||||
// Lenovo
|
// Lenovo
|
||||||
/(ideatab[-\w ]+)/i,
|
/(ideatab[-\w ]+)/i,
|
||||||
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
|
/lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i
|
||||||
], [MODEL, [VENDOR, 'Lenovo'], [TYPE, TABLET]], [
|
], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [
|
||||||
|
|
||||||
// Nokia
|
// Nokia
|
||||||
/(?:maemo|nokia).*(n900|lumia \d+)/i,
|
/(?:maemo|nokia).*(n900|lumia \d+)/i,
|
||||||
@@ -690,12 +726,17 @@
|
|||||||
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
], [VENDOR, MODEL, [TYPE, WEARABLE]], [
|
||||||
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
|
/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i // Apple Watch
|
||||||
], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
|
], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [
|
||||||
/droid.+; (glass) \d/i // Google Glass
|
|
||||||
], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [
|
|
||||||
/droid.+; (wt63?0{2,3})\)/i
|
/droid.+; (wt63?0{2,3})\)/i
|
||||||
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [
|
||||||
/(quest( 2| pro)?)/i // Oculus Quest
|
|
||||||
], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [
|
///////////////////
|
||||||
|
// XR
|
||||||
|
///////////////////
|
||||||
|
|
||||||
|
/droid.+; (glass) \d/i // Google Glass
|
||||||
|
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
||||||
|
/(quest( \d| pro)?)/i // Oculus Quest
|
||||||
|
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// EMBEDDED
|
// EMBEDDED
|
||||||
@@ -710,7 +751,7 @@
|
|||||||
// MIXED (GENERIC)
|
// MIXED (GENERIC)
|
||||||
///////////////////
|
///////////////////
|
||||||
|
|
||||||
/droid .+?; ([^;]+?)(?: bui|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
|
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors
|
||||||
], [MODEL, [TYPE, MOBILE]], [
|
], [MODEL, [TYPE, MOBILE]], [
|
||||||
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
|
/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors
|
||||||
], [MODEL, [TYPE, TABLET]], [
|
], [MODEL, [TYPE, TABLET]], [
|
||||||
@@ -747,12 +788,12 @@
|
|||||||
// Windows
|
// Windows
|
||||||
/microsoft (windows) (vista|xp)/i // Windows (iTunes)
|
/microsoft (windows) (vista|xp)/i // Windows (iTunes)
|
||||||
], [NAME, VERSION], [
|
], [NAME, VERSION], [
|
||||||
/(windows) nt 6\.2; (arm)/i, // Windows RT
|
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i // Windows Phone
|
||||||
/(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i, // Windows Phone
|
|
||||||
/(windows)[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i
|
|
||||||
], [NAME, [VERSION, strMapper, windowsVersionMap]], [
|
], [NAME, [VERSION, strMapper, windowsVersionMap]], [
|
||||||
/(win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
/windows nt 6\.2; (arm)/i, // Windows RT
|
||||||
], [[NAME, WINDOWS], [VERSION, strMapper, windowsVersionMap]], [
|
/windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i,
|
||||||
|
/(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i
|
||||||
|
], [[VERSION, strMapper, windowsVersionMap], [NAME, WINDOWS]], [
|
||||||
|
|
||||||
// iOS/macOS
|
// iOS/macOS
|
||||||
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
/ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, // iOS
|
||||||
@@ -826,7 +867,7 @@
|
|||||||
var defaultProps = (function () {
|
var defaultProps = (function () {
|
||||||
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
var props = { init : {}, isIgnore : {}, isIgnoreRgx : {}, toString : {}};
|
||||||
setProps.call(props.init, [
|
setProps.call(props.init, [
|
||||||
[UA_BROWSER, [NAME, VERSION, MAJOR]],
|
[UA_BROWSER, [NAME, VERSION, MAJOR, TYPE]],
|
||||||
[UA_CPU, [ARCHITECTURE]],
|
[UA_CPU, [ARCHITECTURE]],
|
||||||
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
|
[UA_DEVICE, [TYPE, MODEL, VENDOR]],
|
||||||
[UA_ENGINE, [NAME, VERSION]],
|
[UA_ENGINE, [NAME, VERSION]],
|
||||||
@@ -954,7 +995,7 @@
|
|||||||
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
[PLATFORM, stripQuotes(uach[CH_HEADER_PLATFORM])],
|
||||||
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
[PLATFORMVER, stripQuotes(uach[CH_HEADER_PLATFORM_VER])],
|
||||||
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
[ARCHITECTURE, stripQuotes(uach[CH_HEADER_ARCH])],
|
||||||
[FORMFACTOR, itemListToArray(uach[CH_HEADER_FORM_FACTOR])],
|
[FORMFACTORS, itemListToArray(uach[CH_HEADER_FORM_FACTORS])],
|
||||||
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
[BITNESS, stripQuotes(uach[CH_HEADER_BITNESS])]
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
@@ -1041,15 +1082,16 @@
|
|||||||
|
|
||||||
switch (this.itemType) {
|
switch (this.itemType) {
|
||||||
case UA_BROWSER:
|
case UA_BROWSER:
|
||||||
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS];
|
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
|
||||||
if (brands) {
|
if (brands) {
|
||||||
for (var i in brands) {
|
for (var i in brands) {
|
||||||
var brandName = brands[i].brand,
|
var brandName = strip(/(Google|Microsoft) /, brands[i].brand || brands[i]),
|
||||||
brandVersion = brands[i].version;
|
brandVersion = brands[i].version;
|
||||||
if (!/not.a.brand/i.test(brandName) && (i < 1 || /chromi/i.test(this.get(NAME)))) {
|
if (!/not.a.brand/i.test(brandName) && (!prevName || (/chrom/i.test(prevName) && !/chromi/i.test(brandName)))) {
|
||||||
this.set(NAME, strip(GOOGLE+' ', brandName))
|
this.set(NAME, brandName)
|
||||||
.set(VERSION, brandVersion)
|
.set(VERSION, brandVersion)
|
||||||
.set(MAJOR, majorize(brandVersion));
|
.set(MAJOR, majorize(brandVersion));
|
||||||
|
prevName = brandName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1068,15 +1110,20 @@
|
|||||||
if (uaCH[MODEL]) {
|
if (uaCH[MODEL]) {
|
||||||
this.set(MODEL, uaCH[MODEL]);
|
this.set(MODEL, uaCH[MODEL]);
|
||||||
}
|
}
|
||||||
if (uaCH[FORMFACTOR]) {
|
// Xbox-Specific Detection
|
||||||
|
if (uaCH[MODEL] == 'Xbox') {
|
||||||
|
this.set(TYPE, CONSOLE)
|
||||||
|
.set(VENDOR, MICROSOFT);
|
||||||
|
}
|
||||||
|
if (uaCH[FORMFACTORS]) {
|
||||||
var ff;
|
var ff;
|
||||||
if (typeof uaCH[FORMFACTOR] !== 'string') {
|
if (typeof uaCH[FORMFACTORS] !== 'string') {
|
||||||
var idx = 0;
|
var idx = 0;
|
||||||
while (!ff && idx < uaCH[FORMFACTOR].length) {
|
while (!ff && idx < uaCH[FORMFACTORS].length) {
|
||||||
ff = strMapper(uaCH[FORMFACTOR][idx++], formFactorMap);
|
ff = strMapper(uaCH[FORMFACTORS][idx++], formFactorsMap);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ff = strMapper(uaCH[FORMFACTOR], formFactorMap);
|
ff = strMapper(uaCH[FORMFACTORS], formFactorsMap);
|
||||||
}
|
}
|
||||||
this.set(TYPE, ff);
|
this.set(TYPE, ff);
|
||||||
}
|
}
|
||||||
@@ -1089,6 +1136,11 @@
|
|||||||
this.set(NAME, osName)
|
this.set(NAME, osName)
|
||||||
.set(VERSION, osVersion);
|
.set(VERSION, osVersion);
|
||||||
}
|
}
|
||||||
|
// Xbox-Specific Detection
|
||||||
|
if (this.get(NAME) == WINDOWS && uaCH[MODEL] == 'Xbox') {
|
||||||
|
this.set(NAME, 'Xbox')
|
||||||
|
.set(VERSION, undefined);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case UA_RESULT:
|
case UA_RESULT:
|
||||||
var data = this.data;
|
var data = this.data;
|
||||||
@@ -1122,7 +1174,7 @@
|
|||||||
function UAParser (ua, extensions, headers) {
|
function UAParser (ua, extensions, headers) {
|
||||||
|
|
||||||
if (typeof ua === OBJ_TYPE) {
|
if (typeof ua === OBJ_TYPE) {
|
||||||
if (isExtensions(ua)) {
|
if (isExtensions(ua, true)) {
|
||||||
if (typeof extensions === OBJ_TYPE) {
|
if (typeof extensions === OBJ_TYPE) {
|
||||||
headers = extensions; // case UAParser(extensions, headers)
|
headers = extensions; // case UAParser(extensions, headers)
|
||||||
}
|
}
|
||||||
@@ -1132,7 +1184,7 @@
|
|||||||
extensions = undefined;
|
extensions = undefined;
|
||||||
}
|
}
|
||||||
ua = undefined;
|
ua = undefined;
|
||||||
} else if (typeof ua === STR_TYPE && !isExtensions(extensions)) {
|
} else if (typeof ua === STR_TYPE && !isExtensions(extensions, true)) {
|
||||||
headers = extensions; // case UAParser(ua, headers)
|
headers = extensions; // case UAParser(ua, headers)
|
||||||
extensions = undefined;
|
extensions = undefined;
|
||||||
}
|
}
|
||||||
@@ -1182,7 +1234,7 @@
|
|||||||
['getResult', createItemFunc(UA_RESULT)],
|
['getResult', createItemFunc(UA_RESULT)],
|
||||||
['getUA', function () { return userAgent; }],
|
['getUA', function () { return userAgent; }],
|
||||||
['setUA', function (ua) {
|
['setUA', function (ua) {
|
||||||
if (typeof ua === STR_TYPE)
|
if (isString(ua))
|
||||||
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
|
userAgent = ua.length > UA_MAX_LENGTH ? trim(ua, UA_MAX_LENGTH) : ua;
|
||||||
return this;
|
return this;
|
||||||
}]
|
}]
|
||||||
@@ -1193,7 +1245,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
UAParser.VERSION = LIBVERSION;
|
UAParser.VERSION = LIBVERSION;
|
||||||
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);
|
UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR, TYPE]);
|
||||||
UAParser.CPU = enumerize([ARCHITECTURE]);
|
UAParser.CPU = enumerize([ARCHITECTURE]);
|
||||||
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);
|
||||||
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { expectType } from 'tsd';
|
import { expectType } from 'tsd';
|
||||||
import { UAParser, IResult, IBrowser, ICPU, IEngine, IDevice, IOS } from "../src/main/ua-parser";
|
import { UAParser, IResult, IBrowser, ICPU, IEngine, IDevice, IOS } from "../src/main/ua-parser";
|
||||||
|
import { isAppleSilicon, isChromiumBased } from "../src/helpers/ua-parser-helpers";
|
||||||
|
|
||||||
const uastring = 'Mozilla/5.0 (X11; MyCustomOS; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0';
|
const uastring = 'Mozilla/5.0 (X11; MyCustomOS; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0';
|
||||||
const extensions = {
|
const extensions = {
|
||||||
@@ -27,6 +28,7 @@ expectType<IBrowser>(browser);
|
|||||||
expectType<string | undefined>(browser.name);
|
expectType<string | undefined>(browser.name);
|
||||||
expectType<string | undefined>(browser.version);
|
expectType<string | undefined>(browser.version);
|
||||||
expectType<string | undefined>(browser.major);
|
expectType<string | undefined>(browser.major);
|
||||||
|
expectType<'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'module' | undefined>(browser.type);
|
||||||
expectType<boolean>(browser.is(''));
|
expectType<boolean>(browser.is(''));
|
||||||
expectType<string>(browser.toString());
|
expectType<string>(browser.toString());
|
||||||
expectType<IBrowser | PromiseLike<IBrowser>>(browser.withClientHints());
|
expectType<IBrowser | PromiseLike<IBrowser>>(browser.withClientHints());
|
||||||
@@ -40,3 +42,8 @@ expectType<IOS>(parser.getOS());
|
|||||||
expectType<IResult>(parser.getResult());
|
expectType<IResult>(parser.getResult());
|
||||||
expectType<string>(parser.getUA());
|
expectType<string>(parser.getUA());
|
||||||
expectType<UAParser>(parser.setUA(uastring));
|
expectType<UAParser>(parser.setUA(uastring));
|
||||||
|
|
||||||
|
const result = parser.getResult();
|
||||||
|
|
||||||
|
expectType<boolean>(isAppleSilicon(result));
|
||||||
|
expectType<boolean>(isChromiumBased(result));
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
const { FuzzedDataProvider } = require('@jazzer.js/core');
|
const { FuzzedDataProvider } = require('@jazzer.js/core');
|
||||||
const UAParser = require('ua-parser-js');
|
const { UAParser } = require('../src/main/ua-parser');
|
||||||
const UA_MAX_LENGTH = 350;
|
const UA_MAX_LENGTH = 350;
|
||||||
|
|
||||||
module.exports.fuzz = function (buffer) {
|
module.exports.fuzz = function (buffer) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { UAParser } from 'ua-parser-js';
|
import { UAParser } from '../src/main/ua-parser.mjs';
|
||||||
import { CPU, Device, Engine } from 'ua-parser-js/enums';
|
import { CPU, Device, Engine } from '../src/enums/ua-parser-enums.mjs';
|
||||||
import * as assert from 'assert';
|
import * as assert from 'assert';
|
||||||
|
|
||||||
describe('Returns', () => {
|
describe('Returns', () => {
|
||||||
@@ -7,8 +7,7 @@ describe('Returns', () => {
|
|||||||
assert.deepEqual(new UAParser('').getResult(),
|
assert.deepEqual(new UAParser('').getResult(),
|
||||||
{
|
{
|
||||||
ua : '',
|
ua : '',
|
||||||
//ua_ch : { architecture: undefined, bitness: undefined, brands: undefined, fullVersionList: undefined, mobile: false, model: undefined, platform: undefined, platformVersion: undefined },
|
browser: { name: undefined, version: undefined, major: undefined, type: undefined },
|
||||||
browser: { name: undefined, version: undefined, major: undefined },
|
|
||||||
cpu: { architecture: undefined },
|
cpu: { architecture: undefined },
|
||||||
device: { vendor: undefined, model: undefined, type: undefined },
|
device: { vendor: undefined, model: undefined, type: undefined },
|
||||||
engine: { name: undefined, version: undefined},
|
engine: { name: undefined, version: undefined},
|
||||||
|
|||||||
@@ -3,37 +3,41 @@ const assert = require('assert');
|
|||||||
const parseJS = require('@babel/parser').parse;
|
const parseJS = require('@babel/parser').parse;
|
||||||
const traverse = require('@babel/traverse').default;
|
const traverse = require('@babel/traverse').default;
|
||||||
const safe = require('safe-regex');
|
const safe = require('safe-regex');
|
||||||
const UAParser = require('ua-parser-js');
|
const { UAParser } = require('../src/main/ua-parser');
|
||||||
const { Bots, CLIs, Emails, Modules } = require('ua-parser-js/extensions');
|
const clis = require('./specs/browser-clis.json');
|
||||||
|
const crawlers = require('./specs/browser-crawlers.json');
|
||||||
|
const emails = require('./specs/browser-emails.json');
|
||||||
|
const fetchers = require('./specs/browser-fetchers.json');
|
||||||
|
const modules = require('./specs/browser-modules.json');
|
||||||
|
const { CLIs, Crawlers, Emails, Fetchers, Modules } = require('../src/extensions/ua-parser-extensions');
|
||||||
|
|
||||||
|
describe('Extensions', () => {
|
||||||
|
[
|
||||||
|
['CLIs', clis, CLIs],
|
||||||
|
['Crawlers', crawlers, Crawlers],
|
||||||
|
['Emails', emails, Emails],
|
||||||
|
['Fetchers', fetchers, Fetchers],
|
||||||
|
['Modules', modules, Modules]
|
||||||
|
]
|
||||||
|
.forEach((list) => {
|
||||||
|
describe(list[0], () => {
|
||||||
|
list[1].forEach((agent) => {
|
||||||
|
it(`Can detect ${agent.desc}`, () => {
|
||||||
|
let browser = UAParser(agent.ua, list[2]).browser;
|
||||||
|
assert.strictEqual(String(browser.name), agent.expect.name);
|
||||||
|
assert.strictEqual(String(browser.version), agent.expect.version);
|
||||||
|
assert.strictEqual(String(browser.type), agent.expect.type);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Bots', () => {
|
|
||||||
it('Can detect bots', () => {
|
|
||||||
const googleBot = 'Googlebot-Video/1.0';
|
|
||||||
const gptBot = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.0; +https://openai.com/gptbot)';
|
|
||||||
const msnBot = 'msnbot-media/1.1 (+http://search.msn.com/msnbot.htm)';
|
|
||||||
const bingPreview = 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b';
|
|
||||||
const opera = 'Opera/8.5 (Macintosh; PPC Mac OS X; U; en)';
|
|
||||||
const wget = 'Wget/1.21.1';
|
|
||||||
const facebookBot = 'Mozilla/5.0 (compatible; FacebookBot/1.0; +https://developers.facebook.com/docs/sharing/webmasters/facebookbot/)';
|
|
||||||
const outlook = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Microsoft Outlook 16.0.9126; Microsoft Outlook 16.0.9126; ms-office; MSOffice 16)';
|
const outlook = 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; Microsoft Outlook 16.0.9126; Microsoft Outlook 16.0.9126; ms-office; MSOffice 16)';
|
||||||
const thunderbird = 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0';
|
const thunderbird = 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0';
|
||||||
const axios = 'axios/1.3.5';
|
const axios = 'axios/1.3.5';
|
||||||
const jsdom = 'Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/20.0.3';
|
const jsdom = 'Mozilla/5.0 (darwin) AppleWebKit/537.36 (KHTML, like Gecko) jsdom/20.0.3';
|
||||||
const scrapy = 'Scrapy/1.5.0 (+https://scrapy.org)';
|
const scrapy = 'Scrapy/1.5.0 (+https://scrapy.org)';
|
||||||
|
|
||||||
const botParser = new UAParser(Bots);
|
|
||||||
assert.deepEqual(botParser.setUA(googleBot).getBrowser(), {name: "Googlebot-Video", version: "1.0", major: "1", type: "bot"});
|
|
||||||
assert.deepEqual(botParser.setUA(gptBot).getBrowser(), {name: "GPTBot", version: "1.0", major: "1", type: "bot"});
|
|
||||||
assert.deepEqual(botParser.setUA(msnBot).getBrowser(), {name: "msnbot-media", version: "1.1", major: "1", type: "bot"});
|
|
||||||
assert.deepEqual(botParser.setUA(bingPreview).getBrowser(), {name: "BingPreview", version: "1.0b", major: "1", type: "bot"});
|
|
||||||
assert.deepEqual(botParser.setUA(opera).getBrowser(), {name: "Opera", version: "8.5", major: "8"});
|
|
||||||
|
|
||||||
// try merging Bots & CLIs
|
|
||||||
const botsAndCLIs = { browser : [...Bots.browser, ...CLIs.browser]};
|
|
||||||
const botsAndCLIsParser = new UAParser(botsAndCLIs);
|
|
||||||
assert.deepEqual(botsAndCLIsParser.setUA(wget).getBrowser(), {name: "Wget", version: "1.21.1", major: "1", type:"cli"});
|
|
||||||
assert.deepEqual(botsAndCLIsParser.setUA(facebookBot).getBrowser(), {name: "FacebookBot", version: "1.0", major: "1", type:"bot"});
|
|
||||||
|
|
||||||
const emailParser = new UAParser(Emails);
|
const emailParser = new UAParser(Emails);
|
||||||
assert.deepEqual(emailParser.setUA(outlook).getBrowser(), {name: "Microsoft Outlook", version: "16.0.9126", major: "16", type: "email"});
|
assert.deepEqual(emailParser.setUA(outlook).getBrowser(), {name: "Microsoft Outlook", version: "16.0.9126", major: "16", type: "email"});
|
||||||
assert.deepEqual(emailParser.setUA(thunderbird).getBrowser(), {name: "Thunderbird", version: "78.13.0", major: "78", type: "email"});
|
assert.deepEqual(emailParser.setUA(thunderbird).getBrowser(), {name: "Thunderbird", version: "78.13.0", major: "78", type: "email"});
|
||||||
@@ -43,15 +47,29 @@ describe('Bots', () => {
|
|||||||
assert.deepEqual(moduleParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "module"});
|
assert.deepEqual(moduleParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "module"});
|
||||||
assert.deepEqual(moduleParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "module"});
|
assert.deepEqual(moduleParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "module"});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// TODO : move test spec to JSON file
|
describe('Merge', () => {
|
||||||
|
it('Can merge multiple extensions', () => {
|
||||||
|
const wget = 'Wget/1.21.1';
|
||||||
|
const facebookBot = 'Mozilla/5.0 (compatible; FacebookBot/1.0; +https://developers.facebook.com/docs/sharing/webmasters/facebookbot/)';
|
||||||
|
|
||||||
|
// try merging crawlers & CLIs
|
||||||
|
const crawlersAndCLIs = { browser : [...Crawlers.browser, ...CLIs.browser]};
|
||||||
|
const crawlersAndCLIsParser = new UAParser(crawlersAndCLIs);
|
||||||
|
assert.deepEqual(crawlersAndCLIsParser.setUA(wget).getBrowser(), {name: "Wget", version: "1.21.1", major: "1", type:"cli"});
|
||||||
|
assert.deepEqual(crawlersAndCLIsParser.setUA(facebookBot).getBrowser(), {name: "FacebookBot", version: "1.0", major: "1", type:"crawler"});
|
||||||
|
|
||||||
|
// alternative merge options
|
||||||
|
const crawlersAndCLIsParser2 = new UAParser([Crawlers, CLIs]);
|
||||||
|
const crawlersAndCLIsParser3 = new UAParser(facebookBot, [Crawlers, CLIs]);
|
||||||
|
assert.deepEqual(crawlersAndCLIsParser2.setUA(wget).getBrowser(), {name: "Wget", version: "1.21.1", major: "1", type:"cli"});
|
||||||
|
assert.deepEqual(crawlersAndCLIsParser3.getBrowser(), {name: "FacebookBot", version: "1.0", major: "1", type:"crawler"});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('Testing regexes', () => {
|
describe('Testing regexes', () => {
|
||||||
|
|
||||||
let regexes;
|
let regexes;
|
||||||
|
|
||||||
before('Read main js file', () => {
|
|
||||||
let code = fs.readFileSync('src/extensions/ua-parser-extensions.js', 'utf8').toString();
|
let code = fs.readFileSync('src/extensions/ua-parser-extensions.js', 'utf8').toString();
|
||||||
let ast = parseJS(code, { sourceType: 'script' });
|
let ast = parseJS(code, { sourceType: 'script' });
|
||||||
regexes = [];
|
regexes = [];
|
||||||
@@ -60,20 +78,16 @@ describe('Testing regexes', () => {
|
|||||||
regexes.push(path.node.pattern);
|
regexes.push(path.node.pattern);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (regexes.length === 0) {
|
if (regexes.length === 0) {
|
||||||
throw new Error('Regexes cannot be empty!');
|
throw new Error('Regexes cannot be empty!');
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
describe('Begin testing', () => {
|
describe('Checking for potentially vulnerable regex', () => {
|
||||||
it('all regexes in extension file', () => {
|
for (let regex of regexes) {
|
||||||
regexes.forEach(regex => {
|
it('Test against `safe-regex` : ' + regex, () => {
|
||||||
describe('Test against `safe-regex` : ' + regex, () => {
|
|
||||||
it('should be safe from potentially vulnerable regex', () => {
|
|
||||||
assert.strictEqual(safe(regex), true);
|
assert.strictEqual(safe(regex), true);
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
26
test/mocha-test-helpers.js
Normal file
26
test/mocha-test-helpers.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
const assert = require('assert');
|
||||||
|
const { UAParser } = require('../src/main/ua-parser');
|
||||||
|
const { isAppleSilicon, isChromiumBased } = require('../src/helpers/ua-parser-helpers');
|
||||||
|
|
||||||
|
describe('isAppleSilicon', () => {
|
||||||
|
it('Can detect Apple Silicon device', () => {
|
||||||
|
|
||||||
|
// non-real ua
|
||||||
|
const macARM = 'Mozilla/5.0 (Macintosh; ARM; Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0';
|
||||||
|
const macIntel = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:97.0) Gecko/20100101 Firefox/97.0';
|
||||||
|
|
||||||
|
assert.equal(isAppleSilicon(UAParser(macIntel)), false);
|
||||||
|
assert.equal(isAppleSilicon(UAParser(macARM)), true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isChromiumBased', () => {
|
||||||
|
it('Can detect Chromium-based browser', () => {
|
||||||
|
|
||||||
|
const edge = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.2151.58';
|
||||||
|
const firefox = 'Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/111.0';
|
||||||
|
|
||||||
|
assert.equal(isChromiumBased(UAParser(edge)), true);
|
||||||
|
assert.equal(isChromiumBased(UAParser(firefox)), false);
|
||||||
|
});
|
||||||
|
});
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,3 @@
|
|||||||
// @ts-check
|
|
||||||
import { test, expect } from '@playwright/test';
|
import { test, expect } from '@playwright/test';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import url from 'url';
|
import url from 'url';
|
||||||
@@ -41,7 +40,7 @@ test('read client hints data', async ({ page }) => {
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
platform: 'New OS',
|
platform: 'New OS',
|
||||||
formFactor: 'New Form Factor'
|
formFactors: 'New Form Factor'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,26 @@
|
|||||||
"major" : "undefined"
|
"major" : "undefined"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Alipay",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; U; Android 10; zh-CN; V2034A Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/69.0.3497.100 UWS/3.22.2.33 Mobile Safari/537.36 UCBS/3.22.2.33_211025173018 NebulaSDK/1.8.100112 Nebula AlipayDefined(nt:WIFI,ws:360|0|2.0) AliApp(AP/10.2.51.7100) AlipayClient/10.2.51.7100 Language/zh-Hans useStatusBar/true isConcaveScreen/true Region/CNAriver/1.0.0",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Alipay",
|
||||||
|
"version" : "10.2.51.7100",
|
||||||
|
"major" : "10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Alipay",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 10; VOG-AL00 Build/HUAWEIVOG-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/105.0.5195.148 MYWeb/0.2.103.0_20230131112530 UWS/3.22.2.9999 UCBS/3.22.2.9999_220000000000 Mobile Safari/537.36 NebulaSDK/1.8.100112 Nebula AlipayDefined(nt:WIFI,ws:360|0|3.0) AliApp(AP/10.3.50.9999) AlipayClient/10.3.50.9999 Language/en isConcaveScreen/true Region/CN ProductType/devAriver/1.0.0",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Alipay",
|
||||||
|
"version" : "10.3.50.9999",
|
||||||
|
"major" : "10"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Android Browser on Galaxy Nexus",
|
"desc" : "Android Browser on Galaxy Nexus",
|
||||||
"ua" : "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
|
"ua" : "Mozilla/5.0 (Linux; U; Android 4.0.2; en-us; Galaxy Nexus Build/ICL53F) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
|
||||||
@@ -64,7 +84,7 @@
|
|||||||
"ua" : "Mozilla/5.0 (Linux; Android 5.0.2; SAMSUNG SM-G925F Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.0 Chrome/38.0.2125.102 Mobile Safari/537.36",
|
"ua" : "Mozilla/5.0 (Linux; Android 5.0.2; SAMSUNG SM-G925F Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/3.0 Chrome/38.0.2125.102 Mobile Safari/537.36",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "Samsung Browser",
|
"name" : "Samsung Internet",
|
||||||
"version" : "3.0",
|
"version" : "3.0",
|
||||||
"major" : "3"
|
"major" : "3"
|
||||||
}
|
}
|
||||||
@@ -124,11 +144,81 @@
|
|||||||
"ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; baidubrowser 1.x)",
|
"ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; baidubrowser 1.x)",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "baidubrowser",
|
"name" : "Baidu",
|
||||||
"version" : "1.x",
|
"version" : "1.x",
|
||||||
"major" : "1"
|
"major" : "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Baidu",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 9; Redmi Note 5 Build/PKQ1.180904.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/110.0.5481.153 Mobile Safari/537.36 bdbrowser/6.4.0.4",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Baidu",
|
||||||
|
"version" : "6.4.0.4",
|
||||||
|
"major" : "6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Baidu",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.4.9999.1900 Safari/537.31 BDSpark/26.4",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Baidu",
|
||||||
|
"version" : "26.4",
|
||||||
|
"major" : "26"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Baidu",
|
||||||
|
"ua" : "Mozilla/5.0 (iPad; CPU OS 9_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) BaiduHD/5.4.0.0 Mobile/10A406 Safari/8536.25",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Baidu",
|
||||||
|
"version" : "5.4.0.0",
|
||||||
|
"major" : "5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "BaiDu Browser",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 BIDUBrowser/8.7 Safari/537.36",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Baidu",
|
||||||
|
"version" : "8.7",
|
||||||
|
"major" : "8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "baidu app on iOS",
|
||||||
|
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16C101 main%2F1.0 baiduboxapp/11.12.0.18 (Baidu; P2 12.1.2)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Baidu",
|
||||||
|
"version" : "11.12.0.18",
|
||||||
|
"major" : "11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "baidu app on Android",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 8.1.0; BKK-AL10 Build/HONORBKK-AL10; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.83 Mobile Safari/537.36 T7/11.11 baiduboxapp/11.11.0.0 (Baidu; P1 8.1.0)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Baidu",
|
||||||
|
"version" : "11.11.0.0",
|
||||||
|
"major" : "11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Blazer",
|
||||||
|
"ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows 98; PalmSource/hspr-H102; Blazer/4.0) 16;320x320",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Blazer",
|
||||||
|
"version" : "4.0",
|
||||||
|
"major" : "4"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Bolt",
|
"desc" : "Bolt",
|
||||||
"ua" : "Mozilla/5.0 (X11; 78; CentOS; US-en) AppleWebKit/527+ (KHTML, like Gecko) Bolt/0.862 Version/3.0 Safari/523.15",
|
"ua" : "Mozilla/5.0 (X11; 78; CentOS; US-en) AppleWebKit/527+ (KHTML, like Gecko) Bolt/0.862 Version/3.0 Safari/523.15",
|
||||||
@@ -309,6 +399,26 @@
|
|||||||
"major" : "78"
|
"major" : "78"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Comodo Dragon",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.7 (KHTML, like Gecko) Comodo_Dragon/16.1.1.0 Chrome/16.0.912.63 Safari/535.7",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Comodo Dragon",
|
||||||
|
"version" : "16.1.1.0",
|
||||||
|
"major" : "16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Conkeror",
|
||||||
|
"ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:6.0.1) Gecko/20110831 conkeror/0.9.3",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "conkeror",
|
||||||
|
"version" : "0.9.3",
|
||||||
|
"major" : "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Dillo",
|
"desc" : "Dillo",
|
||||||
"ua" : "Dillo/2.2",
|
"ua" : "Dillo/2.2",
|
||||||
@@ -339,6 +449,16 @@
|
|||||||
"major" : "1"
|
"major" : "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "DuckDuckGo",
|
||||||
|
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.1517.4.1 Ddg/17.4.1",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "DuckDuckGo",
|
||||||
|
"version" : "17.4.1",
|
||||||
|
"major" : "17"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "DuckDuckGo",
|
"desc" : "DuckDuckGo",
|
||||||
"ua" : "Mozilla/5.0 (Linux; Android 8.1.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile DuckDuckGo/5 Safari/537.36",
|
"ua" : "Mozilla/5.0 (Linux; Android 8.1.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/92.0.4515.131 Mobile DuckDuckGo/5 Safari/537.36",
|
||||||
@@ -369,6 +489,16 @@
|
|||||||
"major" : "5"
|
"major" : "5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Go Browser",
|
||||||
|
"ua" : "NokiaE66/GoBrowser/2.0.297",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "GoBrowser",
|
||||||
|
"version" : "2.0.297",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Waterfox",
|
"desc" : "Waterfox",
|
||||||
"ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.2.2 Waterfox/55.2.2",
|
"ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.2.2 Waterfox/55.2.2",
|
||||||
@@ -429,6 +559,26 @@
|
|||||||
"major" : "undefined"
|
"major" : "undefined"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Klarna in-App Browser for iOS",
|
||||||
|
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Klarna/23.36.223",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Klarna",
|
||||||
|
"version" : "23.36.223",
|
||||||
|
"major" : "23"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Klarna in-App Browser for Android",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 12; moto g(60)s Build/S3RLS32.114-25-13; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/116.0.0.0 Mobile Safari/537.36 Klarna/23.36.215",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Klarna",
|
||||||
|
"version" : "23.36.215",
|
||||||
|
"major" : "23"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Instagram in-App Browser for iOS",
|
"desc" : "Instagram in-App Browser for iOS",
|
||||||
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 14_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Instagram 142.0.0.22.109 (iPhone12,5; iOS 14_1; en_US; en-US; scale=3.00; 1242x2688; 214888322) NW/1",
|
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 14_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Instagram 142.0.0.22.109 (iPhone12,5; iOS 14_1; en_US; en-US; scale=3.00; 1242x2688; 214888322) NW/1",
|
||||||
@@ -608,6 +758,16 @@
|
|||||||
"major" : "2"
|
"major" : "2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "ICEBrowser",
|
||||||
|
"ua" : "Mozilla/5.0 (Java 1.6.0_01; Windows XP 5.1 x86; en) ICEbrowser/v6_1_2",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "ICEbrowser",
|
||||||
|
"version" : "6.1.2",
|
||||||
|
"major" : "6"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "IceCat",
|
"desc" : "IceCat",
|
||||||
"ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092921 IceCat/3.0.3-g1",
|
"ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.3) Gecko/2008092921 IceCat/3.0.3-g1",
|
||||||
@@ -668,6 +828,26 @@
|
|||||||
"major" : "11"
|
"major" : "11"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Iron",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1250.0 Iron/22.0.2150.0 Safari/537.4",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Iron",
|
||||||
|
"version" : "22.0.2150.0",
|
||||||
|
"major" : "22"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Jasmine",
|
||||||
|
"ua" : "SAMSUNG-S8000/S8000XXIF3 SHP/VPP/R5 Jasmine/1.0 Nextreaming SMM-MMS/1.2.0 profile/MIDP-2.1 configuration/CLDC-1.1",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Jasmine",
|
||||||
|
"version" : "1.0",
|
||||||
|
"major" : "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "K-Meleon",
|
"desc" : "K-Meleon",
|
||||||
"ua" : "Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.5) Gecko/20031016 K-Meleon/0.8.2",
|
"ua" : "Mozilla/5.0 (Windows; U; Win98; en-US; rv:1.5) Gecko/20031016 K-Meleon/0.8.2",
|
||||||
@@ -688,6 +868,16 @@
|
|||||||
"major" : "2"
|
"major" : "2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Klar < 4.1",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 7.0) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Klar/1.0 Chrome/58.0.3029.83 Mobile Safari/537.36",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Klar",
|
||||||
|
"version" : "1.0",
|
||||||
|
"major" : "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Konqueror",
|
"desc" : "Konqueror",
|
||||||
"ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux; X11; x86_64) KHTML/3.5.6 (like Gecko) (Kubuntu)",
|
"ua" : "Mozilla/5.0 (compatible; Konqueror/3.5; Linux; X11; x86_64) KHTML/3.5.6 (like Gecko) (Kubuntu)",
|
||||||
@@ -708,6 +898,56 @@
|
|||||||
"major" : "5"
|
"major" : "5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "PicoBrowser",
|
||||||
|
"ua" : "Mozilla/5.0 (X11; Linux x86_64; Pico Neo3 Link OS5.8.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Pico Browser",
|
||||||
|
"version" : "3.3.22",
|
||||||
|
"major" : "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "PicoBrowser",
|
||||||
|
"ua" : "Mozilla/5.0 (X11; Linux x86_64; PICO 4 OS5.4.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.22 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Pico Browser",
|
||||||
|
"version" : "3.3.22",
|
||||||
|
"major" : "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Rekonq",
|
||||||
|
"ua" : "Mozilla/5.0 (X11; U; Linux x86_64; cs-CZ) AppleWebKit/533.3 (KHTML, like Gecko) rekonq Safari/533.3",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "rekonq",
|
||||||
|
"version" : "undefined",
|
||||||
|
"major" : "undefined"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Smart Lenovo Browser",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36 SLBrowser/8.0.0.10171 SLBChan/8",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Smart Lenovo Browser",
|
||||||
|
"version" : "8.0.0.10171",
|
||||||
|
"major" : "8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Smart Lenovo Browser",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 SLBrowser/9.0.0.9011 SLBChan/10",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Smart Lenovo Browser",
|
||||||
|
"version" : "9.0.0.9011",
|
||||||
|
"major" : "9"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "LINE on Android",
|
"desc" : "LINE on Android",
|
||||||
"ua" : "Mozilla/5.0 (Linux; Android 5.0; ASUS_Z00AD Build/LRX21V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 Line/6.5.1/IAB",
|
"ua" : "Mozilla/5.0 (Linux; Android 5.0; ASUS_Z00AD Build/LRX21V; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/51.0.2704.81 Mobile Safari/537.36 Line/6.5.1/IAB",
|
||||||
@@ -888,6 +1128,26 @@
|
|||||||
"major" : "6"
|
"major" : "6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "NetSurf in Plan9",
|
||||||
|
"ua" : "Mozilla/5.0 (Plan9) NetSurf/3.12",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "NetSurf",
|
||||||
|
"version" : "3.12",
|
||||||
|
"major" : "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "NetSurf in Linux",
|
||||||
|
"ua" : "NetSurf/3.10 (Linux; Arch Linux)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "NetSurf",
|
||||||
|
"version" : "3.10",
|
||||||
|
"major" : "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Nokia Browser",
|
"desc" : "Nokia Browser",
|
||||||
"ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/025.007; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba",
|
"ua" : "Mozilla/5.0 (Symbian/3; Series60/5.2 NokiaN8-00/025.007; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/533.4 (KHTML, like Gecko) NokiaBrowser/7.3.1.37 Mobile Safari/533.4 3gpp-gba",
|
||||||
@@ -1018,6 +1278,26 @@
|
|||||||
"major" : "12"
|
"major" : "12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Opera GX on Android",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 10; Redmi Note 8 Pro Build/QP1A.190711.020) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.168 Mobile Safari/537.36 OPX/2",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Opera GX",
|
||||||
|
"version" : "2",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Opera GX on Windows",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36 OPR/60.0.3255.50747 OPRGX/60.0.3255.50747",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Opera GX",
|
||||||
|
"version" : "60.0.3255.50747",
|
||||||
|
"major" : "60"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Opera Tablet",
|
"desc" : "Opera Tablet",
|
||||||
"ua" : "Opera/9.80 (Windows NT 6.1; Opera Tablet/15165; U; en) Presto/2.8.149 Version/11.1",
|
"ua" : "Opera/9.80 (Windows NT 6.1; Opera Tablet/15165; U; en) Presto/2.8.149 Version/11.1",
|
||||||
@@ -1048,6 +1328,16 @@
|
|||||||
"major" : "1"
|
"major" : "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "OviBrowser",
|
||||||
|
"ua" : "Mozilla/5.0 (Series40; NokiaX3-02/le6.32; Profile/MIDP-2.1 Configuration/CLDC-1.1) Gecko/20100401 S40OviBrowser/1.0.0.11.8",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "OviBrowser",
|
||||||
|
"version" : "1.0.0.11.8",
|
||||||
|
"major" : "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "PhantomJS",
|
"desc" : "PhantomJS",
|
||||||
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.2 Safari/534.34",
|
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.34 (KHTML, like Gecko) PhantomJS/1.9.2 Safari/534.34",
|
||||||
@@ -1079,7 +1369,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"desc" : "QQ",
|
"desc" : "QQBrowser",
|
||||||
"ua" : "Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; OPPO R7s Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.1 Mobile Safari/537.36",
|
"ua" : "Mozilla/5.0 (Linux; U; Android 4.4.4; zh-cn; OPPO R7s Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko)Version/4.0 Chrome/37.0.0.0 MQQBrowser/7.1 Mobile Safari/537.36",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
@@ -1088,6 +1378,26 @@
|
|||||||
"major" : "7"
|
"major" : "7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "QQBrowser",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; U; Android 9; zh-cn; vivo X21 Build/PKQ1.180819.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/9.9 Mobile Safari/537.36",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "QQBrowser",
|
||||||
|
"version" : "9.9",
|
||||||
|
"major" : "9"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Quark",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; U; Android 12; zh-Hans-CN; JLH-AN00 Build/HONORJLH-AN00) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Quark/5.8.2.221 Mobile Safari/537.36",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Quark",
|
||||||
|
"version" : "5.8.2.221",
|
||||||
|
"major" : "5"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "QupZilla",
|
"desc" : "QupZilla",
|
||||||
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) QupZilla/1.8.9 Safari/538.1",
|
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/538.1 (KHTML, like Gecko) QupZilla/1.8.9 Safari/538.1",
|
||||||
@@ -1098,6 +1408,16 @@
|
|||||||
"major" : "1"
|
"major" : "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Rekonq 2",
|
||||||
|
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.21 (KHTML, like Gecko) rekonq/2.2.1 Safari/537.21",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "rekonq",
|
||||||
|
"version" : "2.2.1",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "RockMelt",
|
"desc" : "RockMelt",
|
||||||
"ua" : "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) RockMelt/0.8.36.78 Chrome/7.0.517.44 Safari/534.7",
|
"ua" : "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.7 (KHTML, like Gecko) RockMelt/0.8.36.78 Chrome/7.0.517.44 Safari/534.7",
|
||||||
@@ -1129,15 +1449,55 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Samsung Browser",
|
"desc" : "Samsung Internet for Android",
|
||||||
"ua" : "Mozilla/5.0 (Linux; Android 6.0.1; SAMSUNG-SM-G925A Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36",
|
"ua" : "Mozilla/5.0 (Linux; Android 6.0.1; SAMSUNG-SM-G925A Build/MMB29K) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "Samsung Browser",
|
"name" : "Samsung Internet",
|
||||||
"version" : "4.0",
|
"version" : "4.0",
|
||||||
"major" : "4"
|
"major" : "4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Samsung Internet for Tizen Mobile",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Tizen 2.3; SAMSUNG SM-Z130H) AppleWebKit/537.3 (KHTML, like Gecko) SamsungBrowser/1.0 Mobile Safari/537.3",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Samsung Internet",
|
||||||
|
"version" : "1.0",
|
||||||
|
"major" : "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Samsung Internet for Smart-TV",
|
||||||
|
"ua" : "Mozilla/5.0 (SMART-TV; Linux; Tizen 2.3) AppleWebkit/538.1 (KHTML, like Gecko) SamsungBrowser/1.0 TV Safari/538.1",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Samsung Internet",
|
||||||
|
"version" : "1.0",
|
||||||
|
"major" : "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Samsung Internet for Gear VR",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 5.0.2; SAMSUNG SM-G925K Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile VR Safari/537.36",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Samsung Internet",
|
||||||
|
"version" : "4.0",
|
||||||
|
"major" : "4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Samsung Internet in Redmi 8A",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 10; Redmi 8A) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/23.0 Chrome/115.0.0.0 Mobile Safari/537.36",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Samsung Internet",
|
||||||
|
"version" : "23.0",
|
||||||
|
"major" : "23"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "SeaMonkey",
|
"desc" : "SeaMonkey",
|
||||||
"ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b4pre) Gecko/20090405 SeaMonkey/2.0b1pre",
|
"ua" : "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b4pre) Gecko/20090405 SeaMonkey/2.0b1pre",
|
||||||
@@ -1178,6 +1538,37 @@
|
|||||||
"major" : "2"
|
"major" : "2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Sleipnir",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 10; SOV37 Build/52.1.C.0.220; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/123.0.6312.120 Mobile Safari/537.36 Sleipnir/3.7.5",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Sleipnir",
|
||||||
|
"version" : "3.7.5",
|
||||||
|
"major" : "3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"desc" : "Sleipnir",
|
||||||
|
"ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Sleipnir 2.8.4)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Sleipnir",
|
||||||
|
"version" : "2.8.4",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Sleipnir",
|
||||||
|
"ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; InfoPath.1; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022) Sleipnir/2.8.4",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Sleipnir",
|
||||||
|
"version" : "2.8.4",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "SlimBrowser",
|
"desc" : "SlimBrowser",
|
||||||
"ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SlimBrowser)",
|
"ua" : "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; SlimBrowser)",
|
||||||
@@ -1289,7 +1680,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"desc" : "UPBrowser",
|
"desc" : "UP.Browser",
|
||||||
"ua" : "BenQ-CF61/1.00/WAP2.0/MIDP2.0/CLDC1.0 UP.Browser/6.3.0.4.c.1.102 (GUI) MMP/2.0",
|
"ua" : "BenQ-CF61/1.00/WAP2.0/MIDP2.0/CLDC1.0 UP.Browser/6.3.0.4.c.1.102 (GUI) MMP/2.0",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
@@ -1349,13 +1740,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Viera",
|
"desc" : "Vivo Browser",
|
||||||
"ua" : "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)",
|
"ua" : "Mozilla/5.0 (Linux; Android 13; 23049RAD8C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/16.7.1.1",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "VIERA",
|
"name" : "Vivo Browser",
|
||||||
"version" : "undefined",
|
"version" : "16.7.1.1",
|
||||||
"major" : "undefined"
|
"major" : "16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "w3m",
|
||||||
|
"ua" : "w3m/0.5.1",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "w3m",
|
||||||
|
"version" : "0.5.1",
|
||||||
|
"major" : "0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Wolvic",
|
||||||
|
"ua" : "Mozilla/5.0 (Android 12; Mobile VR; rv:121.0) Gecko/121.0 Firefox/121.0 Wolvic/1.6.1",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Wolvic",
|
||||||
|
"version" : "1.6.1",
|
||||||
|
"major" : "1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1563,7 +1974,7 @@
|
|||||||
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Mobile/14A456 QQ/6.5.3.410 V1_IPH_SQ_6.5.3_1_APP_A Pixel/1080 Core/UIWebView NetType/WIFI Mem/26",
|
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Mobile/14A456 QQ/6.5.3.410 V1_IPH_SQ_6.5.3_1_APP_A Pixel/1080 Core/UIWebView NetType/WIFI Mem/26",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "QQ",
|
"name" : "QQBrowser",
|
||||||
"version" : "6.5.3.410",
|
"version" : "6.5.3.410",
|
||||||
"major" : "6"
|
"major" : "6"
|
||||||
}
|
}
|
||||||
@@ -1573,37 +1984,17 @@
|
|||||||
"ua" : "Mozilla/5.0 (Linux; Android 6.0; PRO 6 Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile MQQBrowser/6.8 TBS/036824 Safari/537.36 V1_AND_SQ_6.5.8_422_YYB_D PA QQ/6.5.8.2910 NetType/WIFI WebP/0.3.0 Pixel/1080",
|
"ua" : "Mozilla/5.0 (Linux; Android 6.0; PRO 6 Build/MRA58K) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/37.0.0.0 Mobile MQQBrowser/6.8 TBS/036824 Safari/537.36 V1_AND_SQ_6.5.8_422_YYB_D PA QQ/6.5.8.2910 NetType/WIFI WebP/0.3.0 Pixel/1080",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "QQ",
|
"name" : "QQBrowser",
|
||||||
"version" : "6.5.8.2910",
|
"version" : "6.5.8.2910",
|
||||||
"major" : "6"
|
"major" : "6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"desc" : "baidu app on iOS",
|
|
||||||
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16C101 main%2F1.0 baiduboxapp/11.12.0.18 (Baidu; P2 12.1.2)",
|
|
||||||
"expect" :
|
|
||||||
{
|
|
||||||
"name" : "baiduboxapp",
|
|
||||||
"version" : "11.12.0.18",
|
|
||||||
"major" : "11"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"desc" : "baidu app on Android",
|
|
||||||
"ua" : "Mozilla/5.0 (Linux; Android 8.1.0; BKK-AL10 Build/HONORBKK-AL10; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/63.0.3239.83 Mobile Safari/537.36 T7/11.11 baiduboxapp/11.11.0.0 (Baidu; P1 8.1.0)",
|
|
||||||
"expect" :
|
|
||||||
{
|
|
||||||
"name" : "baiduboxapp",
|
|
||||||
"version" : "11.11.0.0",
|
|
||||||
"major" : "11"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"desc" : "WeChat Desktop for Windows Built-in Browser",
|
"desc" : "WeChat Desktop for Windows Built-in Browser",
|
||||||
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400",
|
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "WeChat(Win) Desktop",
|
"name" : "WeChat",
|
||||||
"version" : "3.43.901.400",
|
"version" : "3.43.901.400",
|
||||||
"major" : "3"
|
"major" : "3"
|
||||||
}
|
}
|
||||||
@@ -1613,7 +2004,7 @@
|
|||||||
"ua" : "mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/53.0.2785.116 safari/537.36 qbcore/4.0.1301.400 qqbrowser/9.0.2524.400 mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat",
|
"ua" : "mozilla/5.0 (windows nt 10.0; wow64) applewebkit/537.36 (khtml, like gecko) chrome/53.0.2785.116 safari/537.36 qbcore/4.0.1301.400 qqbrowser/9.0.2524.400 mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "WeChat(Win) Desktop",
|
"name" : "WeChat",
|
||||||
"version" : "4.0.1301.400",
|
"version" : "4.0.1301.400",
|
||||||
"major" : "4"
|
"major" : "4"
|
||||||
}
|
}
|
||||||
@@ -1643,7 +2034,19 @@
|
|||||||
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0",
|
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0",
|
||||||
"expect" :
|
"expect" :
|
||||||
{
|
{
|
||||||
"name" : "MetaSr"
|
"name" : "Sogou Explorer",
|
||||||
|
"version" : "1.0",
|
||||||
|
"major" : "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Sogou Mobile Browser",
|
||||||
|
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30 SogouMSE,SogouMobileBrowser/3.7.4",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Sogou Mobile",
|
||||||
|
"version" : "3.7.4",
|
||||||
|
"major" : "3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1654,16 +2057,6 @@
|
|||||||
"name" : "LBBROWSER"
|
"name" : "LBBROWSER"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"desc" : "BaiDu Browser",
|
|
||||||
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 BIDUBrowser/8.7 Safari/537.36",
|
|
||||||
"expect" :
|
|
||||||
{
|
|
||||||
"name" : "BIDUBrowser",
|
|
||||||
"version" : "8.7",
|
|
||||||
"major" : "8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"desc" : "2345 Browser",
|
"desc" : "2345 Browser",
|
||||||
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.2.1.17116",
|
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.90 Safari/537.36 2345Explorer/9.2.1.17116",
|
||||||
@@ -1732,6 +2125,46 @@
|
|||||||
"name" : "LinkedIn"
|
"name" : "LinkedIn"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Links in Linux",
|
||||||
|
"ua" : "Links (2.xpre7; Linux 2.4.18 i586; x)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Links",
|
||||||
|
"version" : "2.xpre7",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Links in Mac",
|
||||||
|
"ua" : "Links (2.1pre33; Darwin 8.11.0 Power Macintosh; 169x55)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Links",
|
||||||
|
"version" : "2.1pre33",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Links in NetBSD",
|
||||||
|
"ua" : "Links (2.29; NetBSD 10.0 i386; GNU C 10.5; x)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Links",
|
||||||
|
"version" : "2.29",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Links in FreeBSD",
|
||||||
|
"ua" : "Links (2.1pre15; FreeBSD 5.3-RELEASE i386; 196x84)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Links",
|
||||||
|
"version" : "2.1pre15",
|
||||||
|
"major" : "2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Safari including comma in minor version number",
|
"desc" : "Safari including comma in minor version number",
|
||||||
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6,2 Safari/605.1.15",
|
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.6,2 Safari/605.1.15",
|
||||||
@@ -1899,5 +2332,25 @@
|
|||||||
"version" : "12.33.0.36",
|
"version" : "12.33.0.36",
|
||||||
"major" : "12"
|
"major" : "12"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Twitter",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 13; CPH2531 Build/SP1A.210812.016; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/123.0.6312.120 Mobile Safari/537.36 TwitterAndroid",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Twitter",
|
||||||
|
"version" : "undefined",
|
||||||
|
"major" : "undefined"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Twitter",
|
||||||
|
"ua" : "Mozilla/5.0 (iPad; CPU OS 15_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/19H12 Twitter for iPhone/10.34",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Twitter",
|
||||||
|
"version" : "10.34",
|
||||||
|
"major" : "10"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
42
test/specs/browser-clis.json
Normal file
42
test/specs/browser-clis.json
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"desc" : "curl",
|
||||||
|
"ua" : "curl/7.38.0",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "curl",
|
||||||
|
"version" : "7.38.0",
|
||||||
|
"type" : "cli"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "lynx",
|
||||||
|
"ua" : "Lynx 2.8.8dev.3",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Lynx",
|
||||||
|
"version" : "2.8.8dev.3",
|
||||||
|
"type" : "cli"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "lynx",
|
||||||
|
"ua" : "Lynx/2.6",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Lynx",
|
||||||
|
"version" : "2.6",
|
||||||
|
"type" : "cli"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "wget",
|
||||||
|
"ua" : "Wget/1.21.1",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Wget",
|
||||||
|
"version" : "1.21.1",
|
||||||
|
"type" : "cli"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
92
test/specs/browser-crawlers.json
Normal file
92
test/specs/browser-crawlers.json
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"desc" : "Applebot",
|
||||||
|
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4 (Applebot/0.1;+http://www.apple.com/go/applebot)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Applebot",
|
||||||
|
"version" : "0.1",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Amazonbot",
|
||||||
|
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/600.2.5 (KHTML, like Gecko) Version/8.0.2 Safari/600.2.5 (Amazonbot/0.1; +https://developer.amazon.com/support/amazonbot)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Amazonbot",
|
||||||
|
"version" : "0.1",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Bytespider",
|
||||||
|
"ua" : "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.1511.1269 Mobile Safari/537.36; Bytespider",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Bytespider",
|
||||||
|
"version" : "undefined",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "ClaudeBot",
|
||||||
|
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "ClaudeBot",
|
||||||
|
"version" : "1.0",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "ClaudeWeb",
|
||||||
|
"ua" : "Claude-Web/1.0 (web crawler; +https://www.anthropic.com/; bots@anthropic.com)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Claude-Web",
|
||||||
|
"version" : "1.0",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "FacebookBot",
|
||||||
|
"ua" : "Mozilla/5.0 (compatible; FacebookBot/1.0; +https://developers.facebook.com/docs/sharing/webmasters/facebookbot/",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "FacebookBot",
|
||||||
|
"version" : "1.0",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "Googlebot-Video",
|
||||||
|
"ua" : "Googlebot-Video/1.0",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Googlebot-Video",
|
||||||
|
"version" : "1.0",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "GPTBot",
|
||||||
|
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; GPTBot/1.0; +https://openai.com/gptbot)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "GPTBot",
|
||||||
|
"version" : "1.0",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "YandexBot",
|
||||||
|
"ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "YandexBot",
|
||||||
|
"version" : "3.0",
|
||||||
|
"type" : "crawler"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
12
test/specs/browser-emails.json
Normal file
12
test/specs/browser-emails.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"desc" : "Thunderbird",
|
||||||
|
"ua" : "Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Thunderbird",
|
||||||
|
"version" : "78.13.0",
|
||||||
|
"type" : "email"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
12
test/specs/browser-fetchers.json
Normal file
12
test/specs/browser-fetchers.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"desc" : "BingPreview",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534+ (KHTML, like Gecko) BingPreview/1.0b",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "BingPreview",
|
||||||
|
"version" : "1.0b",
|
||||||
|
"type" : "fetcher"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
12
test/specs/browser-modules.json
Normal file
12
test/specs/browser-modules.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"desc" : "Scrapy",
|
||||||
|
"ua" : "Scrapy/1.5.0 (+https://scrapy.org)",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Scrapy",
|
||||||
|
"version" : "1.5.0",
|
||||||
|
"type" : "module"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1373,7 +1373,7 @@
|
|||||||
"expect": {
|
"expect": {
|
||||||
"vendor": "Facebook",
|
"vendor": "Facebook",
|
||||||
"model": "Quest",
|
"model": "Quest",
|
||||||
"type": "wearable"
|
"type": "xr"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1382,7 +1382,16 @@
|
|||||||
"expect": {
|
"expect": {
|
||||||
"vendor": "Facebook",
|
"vendor": "Facebook",
|
||||||
"model": "Quest 2",
|
"model": "Quest 2",
|
||||||
"type": "wearable"
|
"type": "xr"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc": "Oculus Quest 3",
|
||||||
|
"ua": "Mozilla/5.0 (X11; Linux x86_64; Quest 3) AppleWebKit/537.36 (KHTML, like Gecko) OculusBrowser/31.4.0.6.51.566757996 Chrome/120.0.6099.283 VR Safari/537.36",
|
||||||
|
"expect": {
|
||||||
|
"vendor": "Facebook",
|
||||||
|
"model": "Quest 3",
|
||||||
|
"type": "xr"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1391,7 +1400,7 @@
|
|||||||
"expect": {
|
"expect": {
|
||||||
"vendor": "Facebook",
|
"vendor": "Facebook",
|
||||||
"model": "Quest Pro",
|
"model": "Quest Pro",
|
||||||
"type": "wearable"
|
"type": "xr"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1502,6 +1511,15 @@
|
|||||||
"type": "mobile"
|
"type": "mobile"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc": "OPPO Pad",
|
||||||
|
"ua": "Mozilla/5.0 (Linux; U; Android 13; zh-CN; OPD2101 Build/TP1A.220905.001) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/100.0.4896.58 UCBrowser/16.3.9.1290 Mobile Safari/537.36",
|
||||||
|
"expect": {
|
||||||
|
"vendor": "OPPO",
|
||||||
|
"model": "OPD2101",
|
||||||
|
"type": "tablet"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc": "OPPO Neo",
|
"desc": "OPPO Neo",
|
||||||
"ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30",
|
"ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; zh-cn; R831T Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 OppoBrowser/3.3.2 Mobile Safari/534.30",
|
||||||
@@ -2843,6 +2861,15 @@
|
|||||||
"type": "mobile"
|
"type": "mobile"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc": "XiaoMi Redmi Note 12 Turbo",
|
||||||
|
"ua": "Mozilla/5.0 (Linux; Android 13; 23049RAD8C; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.141 Mobile Safari/537.36 VivoBrowser/16.7.1.1",
|
||||||
|
"expect": {
|
||||||
|
"vendor": "Xiaomi",
|
||||||
|
"model": "23049RAD8C",
|
||||||
|
"type": "mobile"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc": "ZTE Blade A6",
|
"desc": "ZTE Blade A6",
|
||||||
"ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE BLADE A0620 Build/NMF26F; ru-ru) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.2.0.50586AP",
|
"ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE BLADE A0620 Build/NMF26F; ru-ru) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.136 Mobile Safari/537.36 Puffin/9.2.0.50586AP",
|
||||||
|
|||||||
@@ -80,6 +80,24 @@
|
|||||||
"version" : "10"
|
"version" : "10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"desc" : "WeChat Desktop for Windows Built-in Browser",
|
||||||
|
"ua" : "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 MicroMessenger/6.5.2.501 NetType/WIFI WindowsWechat QBCore/3.43.901.400 QQBrowser/9.0.2524.400",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Windows",
|
||||||
|
"version" : "7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"desc" : "WeChat Desktop for Windows Built-in Browser major version in 4",
|
||||||
|
"ua" : "mozilla/5.0 (windows nt 6.1; wow64) applewebkit/537.36 (khtml, like gecko) chrome/81.0.4044.138 safari/537.36 nettype/wifi micromessenger/7.0.20.1781(0x6700143b) windowswechat",
|
||||||
|
"expect" :
|
||||||
|
{
|
||||||
|
"name" : "Windows",
|
||||||
|
"version" : "7"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"desc" : "Windows RT",
|
"desc" : "Windows RT",
|
||||||
"ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)",
|
"ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)",
|
||||||
|
|||||||
Reference in New Issue
Block a user