Compare commits

..

39 Commits

Author SHA1 Message Date
Faisal Salman
8087a1b4f0 Bump version 1.0.37 (mirror of 0.7.37) 2023-10-27 19:49:46 +07:00
Faisal Salman
d30ad46992 Bump version 0.7.37 2023-10-27 09:58:43 +07:00
Faisal Salman
5302e2df6a Update changelog 2023-10-27 09:55:33 +07:00
Faisal Salman
f3de7b7cea Backport - Improve browser detection: WeChat (cherry picked from commit 17f0c1e1cd) 2023-10-27 09:42:59 +07:00
Faisal Salman
c41100ebb5 Backport - Improve browser detection: unified name for Baidu (cherry picked from commit 9cc274fb6f) 2023-10-27 09:40:06 +07:00
Faisal Salman
23c5d7765d Backport - Improve browser detection: remove unnecessary extra space in "Avant " (cherry picked from commit f56073bb3e) 2023-10-27 09:39:36 +07:00
Faisal Salman
e3d5f7649d Backport - Improve browser detection: rename "Samsung Browser" to "Samsung Internet" (cherry picked from commit 5c10e2b107)
https://developer.samsung.com/internet/user-agent-string-format.html
2023-10-27 09:39:12 +07:00
Faisal Salman
02af42fcf0 Backport - Fix #682 - Add new browser: Smart Lenovo Browser (cherry picked from commit d565f65280)
https://browser.lenovo.com.cn/
2023-10-27 09:37:13 +07:00
Faisal Salman
57d1ac05f5 Backport - Fix #683 - change MetaSr into Sogou Explorer (+add Sogou Mobile) (cherry picked from commit 69ed6cec77) 2023-10-27 09:35:02 +07:00
Faisal Salman
ea2c82948f Backport - Fix misidentified WebView token as device model - found in #681 (cherry picked from commit b51ae9eb38) 2023-10-27 09:33:37 +07:00
Faisal Salman
3b896d50b7 Backport - Fix #681 - Add new browser: Vivo Browser (cherry picked from commit 125f0d9f16)
https://play.google.com/store/apps/details?id=com.vivo.browser
2023-10-27 09:31:03 +07:00
Faisal Salman
5a724cbde8 Backport - Increase UA_MAX_LENGTH to 500 (cherry picked from commit e614108911) 2023-10-27 09:28:58 +07:00
Faisal Salman
c76139632f Backport - Fix #563 #631 - Add new browser: Alipay (cherry picked from commit 77e0aa1ac6) 2023-10-27 09:25:04 +07:00
Faisal Salman
310cab9c3a Backport - add Klarna Shopping Browser UA parser (#669) (cherry picked from commit 177a496c34)
Co-authored-by: Ilya Daraseliya <ilya.daraseliya@klarna.com>
2023-10-27 09:24:15 +07:00
Faisal Salman
c6dea6361c Backport - Fix #651 - Improve device detection: Xiaomi Redmi (cherry picked from commit aa76da90d9) 2023-10-27 09:22:10 +07:00
Faisal Salman
daab1e76f8 Backport - Add new device vendor: Ulefone (cherry picked from commit 817c5835ef) 2023-10-27 09:21:49 +07:00
Faisal Salman
f78e468020 Backport - Improve device detection: Realme (cherry picked from commit 6ea6936632) 2023-10-27 09:21:00 +07:00
Faisal Salman
056f5e358f Bump version 0.7.36 (mirror of v1.0.36) 2023-09-09 20:10:57 +07:00
Faisal Salman
91f3185eb2 Bump version 1.0.36 2023-09-09 20:06:12 +07:00
Faisal Salman
9bcfbe2460 Backport - Update sponsors section in readme (cherry picked from commit f2e4b242ce) 2023-09-09 19:50:28 +07:00
Faisal Salman
eeaf198197 Backport - Add Snapchat user agent. (cherry picked from commit 153831d2ed) 2023-09-09 19:48:54 +07:00
Faisal Salman
59edeef380 Backport - Fix Amazon Fire TV device detection (cherry picked from commit b20d09655c) 2023-09-09 19:47:23 +07:00
Faisal Salman
f92d409909 Add some tests; Add new devices: Infinix, Tecno; Improve detection: Xiaomi POCO Source: https://www.useragents.me
(cherry picked from commit 15d17e97a1)
2023-09-09 19:46:47 +07:00
Faisal Salman
5af24a6cf7 Fix #643 - Improve iOS detection (cherry picked from commit 29fb85658a) 2023-09-09 19:45:30 +07:00
Faisal Salman
d810feb844 Bump version 1.0.35 (mirror of v0.7.35) 2023-04-02 06:08:37 +07:00
Faisal Salman
32d326b35b Update readme 2023-04-02 06:03:31 +07:00
Faisal Salman
786d502b01 Bump version 0.7.35 2023-03-31 17:56:50 +07:00
Faisal Salman
5b8adfef7b Backport - Prevent altering the result when supplied user-agent is different from current user-agent
Reference:
Commit: b09878934f
2023-03-31 15:55:44 +07:00
Faisal Salman
2e06a34062 Backport - Add new browser: TikTok
(cherry picked from commit 4af26c7a5e)
2023-03-31 15:49:21 +07:00
Faisal Salman
bf9ac43328 Backport - Add new engine: LibWeb + Add new OS: SerenityOS
(cherry picked from commit a6c85d0148)
2023-03-31 15:47:18 +07:00
Faisal Salman
3f8b5ba9cf Backport - Add new browser: Heytap
Reference:
Commit: 172f57ffea
2023-03-31 15:44:13 +07:00
Faisal Salman
1747707be6 Backport - Fix #678 - Improve Yandex detection
(cherry picked from commit 33f02099d1)
2023-03-31 15:40:54 +07:00
Faisal Salman
d41404551f Backport - Fix #519 #521 #616 - Improve iPhone & iOS detection
(cherry picked from commit a1d816ae21)
2023-03-31 15:37:30 +07:00
Faisal Salman
ba067bd351 Backport - Fix #624 - Detect Amazon Echo
(cherry picked from commit df1a1c7bb4)
2023-03-31 15:35:03 +07:00
Faisal Salman
a486f28732 Bump version 1.0.34 (mirror of v0.7.34) 2023-03-05 20:52:38 +07:00
Faisal Salman
3218051f07 Bump version 0.7.34 2023-03-05 20:46:16 +07:00
Faisal Salman
551ad88474 Add new device: Apple Watch, new os: watchOS
(cherry picked from commit 18730452f2)
2023-03-04 22:45:23 +07:00
Faisal Salman
097f736c4d Fix #387 #554 - Detect iPadOS 13
https://stackoverflow.com/questions/9038625/detect-if-device-is-ios
(cherry picked from commit 5ea9f0ec16)
2023-03-04 22:43:28 +07:00
Faisal Salman
73c25771dc Fix #498 - Detect Brave Browser by checking navigator.brave
https://github.com/brave/brave-browser/issues/10165#issuecomment-641128278
(cherry picked from commit 03b0a5afa6)
2023-03-04 22:42:39 +07:00
53 changed files with 1476 additions and 9707 deletions

2
.github/FUNDING.yml vendored
View File

@@ -1,6 +1,6 @@
# These are supported funding model platforms
github: faisalman
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: ua-parser-js
ko_fi: # Replace with a single Ko-fi username

View File

@@ -1,43 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Library version**
Which version of the library that you use, eg: v0.7.35 or v2.0.0-alpha.3
For the issue related with detection result, you can use the demo section in https://uaparser.js.org to confirm
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -1 +0,0 @@
- [ ] I have read and accept the [Contributor License Agreement (CLA)](https://gist.github.com/faisalman/2ed16621ebb544157eba85a7f7381417) Document and I hereby sign the CLA

View File

@@ -1,78 +0,0 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: CodeQL Analysis
on:
push:
branches: [ "master"]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '15 6 * * 0'
permissions: read-all
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Use only 'java' to analyze code written in Java, Kotlin or both
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
# - name: Autobuild
# uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"

View File

@@ -1,20 +0,0 @@
# Dependency Review Action
#
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: Dependency Analysis
on: [pull_request]
permissions:
contents: read
jobs:
dependency-review:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
uses: actions/checkout@v3
- name: 'Dependency Review'
uses: actions/dependency-review-action@v2

View File

@@ -1,72 +0,0 @@
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: OpenSSF's Scorecard Analysis
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '45 2 * * 4'
push:
branches: [ "master" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: read
steps:
- name: "Checkout code"
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4
with:
sarif_file: results.sarif

View File

@@ -1,22 +0,0 @@
name: Publish to GitHub Package
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18.x'
registry-url: https://npm.pkg.github.com/
- run: npm ci
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,23 +0,0 @@
name: Publish to NPM
on:
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18.x'
registry-url: 'https://registry.npmjs.org'
- run: npm install -g npm
- run: npm ci
- run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

View File

@@ -1,4 +1,4 @@
name: UAParser.js CI-Test
name: ua-parser-js-run-test
on: [push, pull_request]
@@ -12,12 +12,9 @@ jobs:
matrix:
arch: [amd64, ppc64le]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 'lts/*'
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- name: Run the test
run: |
npm ci
npx playwright install
npm test
npm install
npm run test-ci

2
.gitignore vendored
View File

@@ -1,7 +1,5 @@
node_modules/
npm-debug.log
playwright-report/
test-results/
### vim ###
.*.s[a-w][a-z]

3
.jshintrc Normal file
View File

@@ -0,0 +1,3 @@
{
"esversion": 3
}

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
package-lock=false

18
.travis.yml Normal file
View File

@@ -0,0 +1,18 @@
arch:
- amd64
- ppc64le
language: node_js
node_js:
- stable
- lts/*
notifications:
email: false
cache:
directories:
- node_modules
sudo: false
script: npm run test-ci

View File

@@ -1,29 +0,0 @@
# UAParser.js Code of Conduct
## Introduction
Welcome to the UAParser.js community! We're here to collaborate on developing an awesome project. Here are some general guidelines to make our community a great place:
### 1. Be Kind, Honest, and Respectful
Always treat others with kindness and respect. We value different opinions and encourage positive communication.
### 2. Keep Conversations Civil and On-Topic
Please keep discussions related to the project. If you want to talk about something else, find the right place for it.
### 3. Mutual Assistance, Appreciation, and Acknowledgement
Feel free to ask for help, show gratitude for contributions, and make sure to give credit where it's due.
### 4. Resolving Disagreements
In the event of a disagreement, we encourage open and respectful dialogue. It's important to remember that it's okay to have differing opinions, and if a common ground can't be reached, we suggest using the 'agree to disagree' approach.
## Reporting Issues
If you see any behavior that goes against this code of conduct, report it to [f@faisalman.com](mailto:f@faisalman.com).
## Conclusion
Together, we can make this project awesome!

View File

@@ -1,7 +0,0 @@
# UAParser.js: How to Contribute
* Fork and clone this repository
* Make some changes as required
* Write unit test to showcase its functionality under `/test`
* Run the test suites to make sure it's not breaking anything `$ npm run build+test`
* Submit a pull request under `develop` branch & check the CLA in the submission form

View File

@@ -1,71 +0,0 @@
# UAPARSER.JS PRO ENTERPRISE LICENSE
Version 1, October 2023
Copyright (C) 2023 Faisal Salman <f+ua-parser-js@faisalman.com>
---
## Definitions
"We" are the team behind UAParser.js.
"You" are the individual/organization/company who is responsible for purchasing this license.
"The Code" is UAParser.js.
"Project" is what you built with The Code.
---
## License
We retains 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.
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/organization/company and can not be transferred to other individual/organization/company.
---
## Rights
You may use, copy, and modify The Code for an indefinite number of Projects.
You have the right to get lifetime updates and a 1 (one) year support, starting from the time you make the purchase.
---
## Restriction
You may not redistribute The Code, as-is or modified, except as a part of a Project that you made.
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 use The Code for unlawful, inappropriate, illegal, or offensive purposes.
---
## Limitations
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 reserve the rights 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.
---
## Terminations
This license works indefinitely but can be revoked at any time if there is a violation to any of the terms.
---
END OF TERMS AND CONDITIONS

View File

@@ -1,23 +0,0 @@
<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>
</p>
# UAParser.js
Thank you for purchasing UAParser.js PRO Enterprise License, if you haven't please order here: https://store.faisalman.com
# Download
```sh
npm install @ua-parser-js/pro-enterprise
```
# Documentation
https://docs.uaparser.js.org/v2
# License
UAParser.js PRO Enterprise
Copyright (c) 2012-2023 Faisal Salman <<f@faisalman.com>>

View File

@@ -1,7 +0,0 @@
# Security Policy
## Reporting a Vulnerability
To report a security issue, please email `f@faisalman.com` with a description of the issue, reproducible steps to get the issue, affected versions, and, if known, mitigations for the issue.
If the issue is confirmed as a vulnerability, we will open a new security advisory draft in our GitHub's Security Advisory page [https://github.com/faisalman/ua-parser-js/security/advisories](https://github.com/faisalman/ua-parser-js/security/advisories) and acknowledge your contributions as part of it. This project follows a 90 days disclosure timeline.

17
bower.json Normal file
View File

@@ -0,0 +1,17 @@
{
"name": "ua-parser-js",
"version": "1.0.37",
"authors": [
"Faisal Salman <f@faisalman.com>"
],
"private": false,
"main": "src/ua-parser.js",
"ignore": [
"build",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {}
}

View File

@@ -1,25 +1,17 @@
# UAParser.js Changelog
# Version 2.0
- What's breaking:
- Dual-licensed under AGPLv3 or PRO License
- Browser detection on mobile device: `"Chrome" => "Mobile Chrome"`, `"Firefox" => "Mobile Firefox"`
- OS detection: `"Mac OS" => "macOS"`, `"Chromium OS" => "Chrome OS"`
- What's new:
- Some new methods in result object:
- Support for client hints: `withClientHints()`
- Support for feature detection: `withFeatureCheck()`
- Utility for easy comparison: `is()`
- Utility to print full-name: `toString()`
- Support for ES module `import { UAParser } from 'ua-parser-js'`
- Provided Enums submodule `'ua-parser-js/enums'`
- Provided Extensions submodule `'ua-parser-js/extensions'`
- Provided Helpers submodule `'ua-parser-js/helpers'`
# 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 0.7.37 / 1.0.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
- Add new browser: Snapchat
- Add new devices: Infinix, Tecno

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

21
license.md Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2012-2023 Faisal Salman <<f@faisalman.com>>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

5032
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
Package.describe({
name: 'faisalman:ua-parser-js',
version: '2.0.0-beta.1',
version: '1.0.37',
summary: 'Lightweight JavaScript-based user-agent string parser',
git: 'https://github.com/faisalman/ua-parser-js.git',
documentation: 'readme.md'

View File

@@ -1,12 +1,11 @@
{
"title": "UAParser.js PRO Enterprise",
"name": "@ua-parser-js/pro-enterprise",
"version": "2.0.0-beta.1",
"title": "UAParser.js",
"name": "ua-parser-js",
"version": "1.0.37",
"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 data. Supports browser & node.js environment",
"keywords": [
"user-agent",
"client-hints",
"parser",
"browser",
"engine",
@@ -16,9 +15,13 @@
"jquery-plugin",
"ecosystem:jquery",
"ua-parser-js",
"browser-detection",
"client-hints",
"user-agent-detection",
"device-detection",
"os-detection"
"platform-detection",
"mobile-detection",
"browser-detection",
"architecture-detection"
],
"homepage": "https://github.com/faisalman/ua-parser-js",
"contributors": [
@@ -39,11 +42,8 @@
"Carl C Von Lewin <carlchristianlewin@gmail.com>",
"CESAR RAMOS <c@imagenproactiva.com>",
"Chad Killingsworth <ckillingsworth@jackhenry.com>",
"chenhui9279 <chenhui9279@autohome.com.cn>",
"chenyuan-new <53860479+chenyuan-new@users.noreply.github.com>",
"Christopher De Cairos <chris.decairos@gmail.com>",
"Cyrille David <cyrille@qonto.eu>",
"Dante <duanjl.china@gmail.com>",
"Dario Vladovic <d.vladimyr@gmail.com>",
"David Annez <david.annez@gmail.com>",
"Davit Barbakadze <jayarjo@gmail.com>",
@@ -66,12 +66,10 @@
"Faisal Salman <f@faisalman.com>",
"Frédéric Camblor <fcamblor@gmail.com>",
"Frederik Ring <frederik.ring@gmail.com>",
"Garrit Franke <garrit@slashdev.space>",
"Gerald Host <me@jacobford.co.uk>",
"Germán M. Bravo <german.mb@gmail.com>",
"Grigory Dmitrenko <grigory@snsk.ru>",
"gulpin <gulping.gulpin@gmail.com>",
"Hans Ott <hansott@hotmail.be>",
"Hendrik Helwich <h.helwich@iplabs.de>",
"Hermann Ebert <ebbmo@HE.local>",
"hr6r <hedian@gmail.com>",
@@ -79,7 +77,6 @@
"Ildar Kamalov <i.kamalov@adguard.com>",
"insanehong <insane.hong@navercorp.com>",
"jackpoll <jackpoll123456@gmail.com>",
"Jacky Choo <jackychoo@adly-macbook.local>",
"Jake Mc <startswithaj@users.noreply.github.com>",
"JBYoshi <12983479+JBYoshi@users.noreply.github.com>",
"Joey Parrish <joeyparrish@google.com>",
@@ -89,14 +86,11 @@
"Josh Goldberg <joshuakgoldberg@outlook.com>",
"Junki-Ishida <junki_ishida@dwango.co.jp>",
"Kendall Buchanan <kendall@kendagriff.com>",
"KnifeLemon <role___play@naver.com>",
"kNoAPP <alldoneb@gmail.com>",
"Lee Treveil <leetreveil@gmail.com>",
"leonardo <leofiore@libero.it>",
"Levente Balogh <balogh.levente.hu@gmail.com>",
"Liam Quinn <lquinn@blackberry.com>",
"Lithin <lithin@webklipper.com>",
"liujunlve <liujunlve@henhaoji.com>",
"ll-syber <670159357@qq.com>",
"Loris Guignard <loris.guignard@gmail.com>",
"Lukas Drgon <lukas.drgon@gmail.com>",
@@ -111,8 +105,6 @@
"Max Nordlund <max.nordlund@gmail.com>",
"Michael Hess <mhess@connectify.me>",
"MimyyK <michele.marais@hakisa.com>",
"Mok <mok@moekm.com>",
"nabetama <mao.nabeta@gmail.com>",
"naoh <naoh.cs03g@nctu.edu.tw>",
"Nicholas Ionata <nionata@ufl.edu>",
"Nikhil Motiani <nikhil.motiani@outlook.com>",
@@ -121,9 +113,7 @@
"niris <nirisix@gmail.com>",
"Nobuo Okada <nookada@yahoo-corp.jp>",
"o.drapeza <o.drapeza@tinkoff.ru>",
"Oscar Becerra <oscarbecerra@google.com>",
"otakuSiD <otakusid@gmail.com>",
"Paris Morgan <paris@8thwall.com>",
"patrick-nurt <github@pereira.dk>",
"Pavel Studeny <studeny@avast.com>",
"Peter Dave Hello <PeterDaveHello@users.noreply.github.com>",
@@ -133,24 +123,19 @@
"Queen Vinyl Darkscratch <vinyldarkscratch@gmail.com>",
"Raine Makelainen <raine.makelainen@jolla.com>",
"Raman Savaryn <homeneartheocean@gmail.com>",
"Riley Shaw <rileyjshaw@users.noreply.github.com>",
"Robert Tod <robert@qubit.com>",
"roman.savarin <roman.savarin@skywindgroup.com>",
"Ron Korland <ron@testim.io>",
"Ross Noble <rosshnoble@gmail.com>",
"ruicong <466403866@qq.com>",
"Runar Heggset <rukki093@gmail.com>",
"Ryohei Shima <shima01dev@gmail.com>",
"Sandro Sonntag <sandro.sonntag@adorsys.de>",
"sgautrea <shanegautreau@gmail.com>",
"shaharmor <shahar@peer5.com>",
"Shane Gautreau <sgautrea@opentext.com>",
"Shane Thacker <shane@steadymade.com>",
"Shreedhar <shreedhar@uber.com>",
"Simon Eisenmann <simon@longsleep.org>",
"Simon Lang <me@simonlang.org>",
"Stiekel <histkc@gmail.com>",
"sunny-mwx <30586210+sunny-mwx@users.noreply.github.com>",
"sUP <dani3l@gmail.com>",
"Sylvain Gizard <sylvain.gizard@gmail.com>",
"szchenghuang <szchenghuang@gmail.com>",
@@ -158,78 +143,60 @@
"Tony Tomarchio <tony@tomarchio.cc>",
"Ulrich Schmidt <u.schmidt@velian.de>",
"Vadim Kurachevsky <vadim@hmvs.org>",
"Varun Sharma <varunsh@stepsecurity.io>",
"XhmikosR <xhmikosr@gmail.com>",
"Yılmaz <yilmazdemir36@gmail.com>",
"yuanyang <work_yuanyang@163.com>",
"Yun Young-jin <yupmin@yupmin-office-macmini.local>",
"Zach Bjornson <zbbjornson@gmail.com>",
"Ziding Zhang <zidingz@gmail.com>"
"Zach Bjornson <zbbjornson@gmail.com>"
],
"type": "commonjs",
"types": "src/main/ua-parser.d.ts",
"main": "src/main/ua-parser.js",
"module": "src/main/ua-parser.mjs",
"browser": "dist/ua-parser.pack.js",
"exports": {
".": {
"require": "./src/main/ua-parser.js",
"import": "./src/main/ua-parser.mjs"
},
"./enums": {
"require": "./src/enums/ua-parser-enums.js",
"import": "./src/enums/ua-parser-enums.mjs"
},
"./extensions": {
"require": "./src/extensions/ua-parser-extensions.js",
"import": "./src/extensions/ua-parser-extensions.mjs"
}
},
"main": "src/ua-parser.js",
"files": [
"dist",
"src"
],
"scripts": {
"build": "./script/build-dist.sh && ./script/build-module.js",
"build+test": "npm run build && npm run test",
"fuzz": "jazzer ./test/jazzer-fuzz-test.js --sync",
"test": "./script/test-all.sh",
"test:dts": "tsd --typings src/main/ua-parser.d.ts --files test/dts-test.ts",
"test:eslint": "eslint src && eslint script",
"test:jshint": "jshint src/main",
"test:lockfile-lint": "npx lockfile-lint -p package-lock.json",
"test:mocha": "mocha -R list test/mocha*js",
"test:playwright": "playwright test"
"build": "uglifyjs src/ua-parser.js -o dist/ua-parser.min.js --comments '/^ UA/' && uglifyjs src/ua-parser.js -o dist/ua-parser.pack.js --comments '/^ UA/' --compress --mangle",
"test": "jshint src/ua-parser.js && mocha -R nyan test/test.js",
"test-ci": "jshint src/ua-parser.js && mocha -R spec test/test.js",
"verup": "node ./node_modules/verup",
"version": "node ./node_modules/verup 0"
},
"verup": {
"files": [
"bower.json",
"package.js",
"src/ua-parser.js"
],
"regs": [
"^((?:\\$|(\\s*\\*\\s*@)|(\\s*(?:var|,)?\\s+))(?:LIBVERSION|version)[\\s\\:='\"]+)([0-9]+(?:\\.[0-9]+){2,2})",
"^(\\/?\\s?\\*.*v)([0-9]+(?:\\.[0-9]+){2,2})"
]
},
"devDependencies": {
"@babel/parser": "7.15.8",
"@babel/traverse": "7.15.4",
"@jazzer.js/core": "^1.4.0",
"@playwright/test": "~1.32.2",
"jshint": "~2.13.6",
"jshint": "~2.12.0",
"mocha": "~8.2.0",
"requirejs": "2.3.2",
"requirejs": "^2.3.2",
"safe-regex": "^2.1.1",
"tsd": "^0.29.0",
"uglify-js": "~3.12.0"
"uglify-js": "~3.12.0",
"verup": "^1.3.x"
},
"repository": {
"type": "git",
"url": "https://github.com/faisalman/ua-parser-js.git"
},
"license": "UAParser.js-PRO-Enterprise",
"license": "MIT",
"engines": {
"node": "*"
},
"directories": {
"dist": "dist",
"script": "script",
"src": "src",
"test": "test"
},
"bugs": "https://github.com/faisalman/ua-parser-js/issues",
"demo": "https://uaparser.js.org",
"download": "https://raw.github.com/faisalman/ua-parser-js/master/dist/ua-parser.pack.js",
"demo": "https://faisalman.github.io/ua-parser-js",
"download": "https://raw.github.com/faisalman/ua-parser-js/master/dist/ua-parser.min.js",
"funding": [
{
"type": "opencollective",
@@ -240,8 +207,8 @@
"url": "https://paypal.me/faisalman"
},
{
"type": "github",
"url": "https://github.com/sponsors/faisalman"
"type": "github",
"url": "https://github.com/sponsors/faisalman"
}
]
}

385
readme.md Normal file
View File

@@ -0,0 +1,385 @@
<p align="center">
<img src="https://raw.githubusercontent.com/faisalman/ua-parser-js/gh-pages/images/logo.png" width="256" height="256">
</p>
<p align="center">
<a href="https://travis-ci.org/faisalman/ua-parser-js"><img src="https://travis-ci.org/faisalman/ua-parser-js.svg?branch=master"></a>
<a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/v/ua-parser-js.svg"></a>
<a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/dw/ua-parser-js.svg"></a>
<a href="https://www.jsdelivr.com/package/npm/ua-parser-js"><img src="https://data.jsdelivr.com/v1/package/npm/ua-parser-js/badge"></a>
<a href="https://cdnjs.com/libraries/UAParser.js"><img src="https://img.shields.io/cdnjs/v/UAParser.js.svg"></a>
</p>
# UAParser.js
JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data with relatively small footprint (~17KB minified, ~6KB gzipped) that can be used either in browser (client-side) or node.js (server-side).
* Author : Faisal Salman <<f@faisalman.com>>
* Demo : https://faisalman.github.io/ua-parser-js
* Source : https://github.com/faisalman/ua-parser-js
* Documentation :
* v1 : https://github.com/faisalman/ua-parser-js/tree/1.0.35#documentation
* v2 : https://faisalman.github.io/ua-parser-js-docs/v2
***
### From Our Sponsors:
<table>
<thead>
</thead>
<tbody>
<tr>
<td colspan="2">
<a href="https://opencollective.com/ua-parser-js">↗ Become a sponsor</a>
</td>
</tr>
</tbody>
</table>
---
# Documentation
### UAParser([user-agent][,extensions])
typeof `user-agent` "string".
typeof `extensions` "array".
In The Browser environment you dont need to pass the user-agent string to the function, you can just call the funtion and it should automatically get the string from the `window.navigator.userAgent`, but that is not the case in nodejs. The user-agent string must be passed in nodejs for the function to work.
Usually you can find the user agent in:
`request.headers["user-agent"]`.
## Constructor
When you call `UAParser` with the `new` keyword `UAParser` will return a new instance with an empty result object, you have to call one of the available methods to get the information from the user-agent string.
Like so:
* `new UAParser([uastring][,extensions])`
```js
let parser = new UAParser("user-agent"); // you need to pass the user-agent for nodejs
console.log(parser); // {}
let parserResults = parser.getResult();
console.log(parserResults);
/** {
"ua": "",
"browser": {},
"engine": {},
"os": {},
"device": {},
"cpu": {}
} */
```
When you call UAParser without the `new` keyword, it will automatically call `getResult()` function and return the parsed results.
* `UAParser([uastring][,extensions])`
* returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`
## Methods
#### Methods table
The methods are self explanatory, here's a small overview on all the available methods:
* `getResult()` - returns all function object calls, user-agent string, browser info, cpu, device, engine, os:
`{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`.
* `getBrowser()` - returns the browser name and version.
* `getDevice()` - returns the device model, type, vendor.
* `getEngine()` - returns the current browser engine name and version.
* `getOS()` - returns the running operating system name and version.
* `getCPU()` - returns CPU architectural design name.
* `getUA()` - returns the user-agent string.
* `setUA(user-agent)` - set a custom user-agent to be parsed.
---
* `getResult()`
* returns `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`
* `getBrowser()`
* returns `{ name: '', version: '' }`
```sh
# Possible 'browser.name':
2345Explorer, 360 Browser, Alipay, Amaya, Android Browser, Arora, Avant, Avast,
AVG, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera,
Chrome Headless, Chrome WebView, Chrome, Chromium, Cobalt, Comodo Dragon, Dillo,
Dolphin, Doris, DuckDuckGo, Edge, Electron, Epiphany, Facebook, Falkon, Fennec,
Firebird, Firefox [Focus/Reality], Flock, Flow, GSA, GoBrowser, Heytap,
Huawei Browser, iCab, ICE Browser, IE, IEMobile, IceApe, IceCat, IceDragon,
Iceweasel, Instagram, Iridium, Iron, Jasmine, Kakao[Story/Talk], K-Meleon,
Kindle, Klar, Klarna, Konqueror, LBBROWSER, Line, LinkedIn, Links, Lunascape,
Lynx, MIUI Browser, Maemo, Maxthon, Midori, Minimo, Mobile Safari, Mosaic,
Mozilla, NetFront, NetSurf, Netfront, Netscape, NokiaBrowser, Obigo,
Oculus Browser, OmniWeb, Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon,
PhantomJS, Phoenix, Polaris, Puffin, QQ, QQBrowser, QQBrowserLite, Quark,
QupZilla, RockMelt, Safari, Sailfish Browser, Samsung Internet, SeaMonkey, Silk,
Skyfire, Sleipnir, Slim, SlimBrowser, Smart Lenovo Browser, Snapchat,
Sogou [Explorer/Mobile], Swiftfox, Tesla, TikTok, Tizen Browser, UCBrowser,
UP.Browser, Viera, Vivaldi, Vivo Browser, Waterfox, WeChat, Weibo, Yandex, w3m,
Whale Browser, ...
# 'browser.version' determined dynamically
```
* `getDevice()`
* returns `{ model: '', type: '', vendor: '' }`
```sh
# Possible 'device.type':
console, mobile, tablet, smarttv, wearable, embedded
##########
# NOTE: 'desktop' is not a possible device type.
# UAParser only reports info directly available from the UA string, which is not the case for 'desktop' device type.
# If you wish to detect desktop devices, you must handle the needed logic yourself.
# You can read more about it in this issue: https://github.com/faisalman/ua-parser-js/issues/182
##########
# Possible 'device.vendor':
Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell,
Essential, Facebook, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Infinix,
Jolla, Kobo, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia,
Nvidia, OnePlus, OPPO, Ouya, Palm, Panasonic, Pebble, Polytron, Realme, RIM,
Roku, Samsung, Sharp, Siemens, Sony[Ericsson], Sprint, Tecno, Tesla, Ulefone,
Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ...
# 'device.model' determined dynamically
```
* `getEngine()`
* returns `{ name: '', version: '' }`
```sh
# Possible 'engine.name'
Amaya, Blink, EdgeHTML, Flow, Gecko, Goanna, iCab, KHTML, LibWeb, Links, Lynx,
NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit
# 'engine.version' determined dynamically
```
* `getOS()`
* returns `{ name: '', version: '' }`
```sh
# Possible 'os.name'
AIX, Amiga OS, Android[-x86], Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS,
Contiki, Fedora, Firefox OS, FreeBSD, Debian, Deepin, DragonFly, elementary OS,
Fuchsia, Gentoo, GhostBSD, GNU, Haiku, HarmonyOS, HP-UX, Hurd, iOS, Joli, KaiOS,
Linpus, Linspire,Linux, Mac OS, Maemo, Mageia, Mandriva, Manjaro, MeeGo, Minix,
Mint, Morph OS, NetBSD, NetRange, NetTV, Nintendo, OpenBSD, OpenVMS, OS/2, Palm,
PC-BSD, PCLinuxOS, Plan9, PlayStation, QNX, Raspbian, RedHat, RIM Tablet OS,
RISC OS, Sabayon, Sailfish, SerenityOS, Series40, Slackware, Solaris, SUSE,
Symbian, Tizen, Ubuntu, Unix, VectorLinux, Viera, watchOS, WebOS,
Windows [Phone/Mobile], Zenwalk, ...
# 'os.version' determined dynamically
```
* `getCPU()`
* returns `{ architecture: '' }`
```sh
# Possible 'cpu.architecture'
68k, amd64, arm[64/hf], avr, ia[32/64], irix[64], mips[64], pa-risc, ppc,
sparc[64]
```
* `getUA()`
* returns UA string of current instance
* `setUA(uastring)`
* set UA string to be parsed
* returns current instance
# Usage
## Using HTML
```html
<!doctype html>
<html>
<head>
<script src="ua-parser.min.js"></script>
<script>
var parser = new UAParser();
console.log(parser.getResult());
/*
/// This will print an object structured like this:
{
ua: "",
browser: {
name: "",
version: "",
major: "" //@deprecated
},
engine: {
name: "",
version: ""
},
os: {
name: "",
version: ""
},
device: {
model: "",
type: "",
vendor: ""
},
cpu: {
architecture: ""
}
}
*/
// Default result depends on current window.navigator.userAgent value
// Now let's try a custom user-agent string as an example
var uastring1 = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.2 (KHTML, like Gecko) Ubuntu/11.10 Chromium/15.0.874.106 Chrome/15.0.874.106 Safari/535.2";
parser.setUA(uastring1);
var result = parser.getResult();
// You can also use UAParser constructor directly without having to create an instance:
// var result = UAParser(uastring1);
console.log(result.browser); // {name: "Chromium", version: "15.0.874.106"}
console.log(result.device); // {model: undefined, type: undefined, vendor: undefined}
console.log(result.os); // {name: "Ubuntu", version: "11.10"}
console.log(result.os.version); // "11.10"
console.log(result.engine.name); // "WebKit"
console.log(result.cpu.architecture); // "amd64"
// Do some other tests
var uastring2 = "Mozilla/5.0 (compatible; Konqueror/4.1; OpenBSD) KHTML/4.1.4 (like Gecko)";
console.log(parser.setUA(uastring2).getBrowser().name); // "Konqueror"
console.log(parser.getOS()); // {name: "OpenBSD", version: undefined}
console.log(parser.getEngine()); // {name: "KHTML", version: "4.1.4"}
var uastring3 = 'Mozilla/5.0 (PlayBook; U; RIM Tablet OS 1.0.0; en-US) AppleWebKit/534.11 (KHTML, like Gecko) Version/7.1.0.7 Safari/534.11';
console.log(parser.setUA(uastring3).getDevice().model); // "PlayBook"
console.log(parser.getOS()) // {name: "RIM Tablet OS", version: "1.0.0"}
console.log(parser.getBrowser().name); // "Safari"
</script>
</head>
<body>
</body>
</html>
```
## Using node.js
Note: Device information is not available in the NodeJS environment.
```sh
$ npm install ua-parser-js
```
```js
var http = require('http');
var parser = require('ua-parser-js');
http.createServer(function (req, res) {
// get user-agent header
var ua = parser(req.headers['user-agent']);
// write the result as response
res.end(JSON.stringify(ua, null, ' '));
})
.listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
```
## Using TypeScript
```sh
$ npm install --save @types/ua-parser-js
# Download TS type definition from DefinitelyTyped repository:
# https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/ua-parser-js
```
## Using jQuery/Zepto ($.ua)
Although written in vanilla js, this library will automatically detect if jQuery/Zepto is present and create `$.ua` object (with values based on its User-Agent) along with `window.UAParser` constructor. To get/set user-agent you can use: `$.ua.get()` / `$.ua.set(uastring)`.
```js
// Say we are in a browser with default user-agent: 'Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0':
// Get the details
console.log($.ua.device); // {vendor: "HTC", model: "Evo Shift 4G", type: "mobile"}
console.log($.ua.os); // {name: "Android", version: "2.3.4"}
console.log($.ua.os.name); // "Android"
console.log($.ua.get()); // "Mozilla/5.0 (Linux; U; Android 2.3.4; en-us; Sprint APA7373KT Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0"
// Now lets try to reset to another custom user-agent
$.ua.set('Mozilla/5.0 (Linux; U; Android 3.0.1; en-us; Xoom Build/HWI69) AppleWebKit/534.13 (KHTML, like Gecko) Version/4.0 Safari/534.13');
// Test again
console.log($.ua.browser.name); // "Safari"
console.log($.ua.engine.name); // "Webkit"
console.log($.ua.device); // {vendor: "Motorola", model: "Xoom", type: "tablet"}
console.log(parseInt($.ua.browser.version.split('.')[0], 10)); // 4
// Add class to <body> tag
// <body class="ua-browser-safari ua-devicetype-tablet">
$('body').addClass('ua-browser-' + $.ua.browser.name + ' ua-devicetype-' + $.ua.device.type);
```
## Using Extension
* `UAParser([uastring,] extensions)`
```js
// Example:
var myOwnListOfBrowsers = [
[/(mybrowser)\/([\w\.]+)/i], [UAParser.BROWSER.NAME, UAParser.BROWSER.VERSION]
];
var myParser = new UAParser({ browser: myOwnListOfBrowsers });
var myUA = 'Mozilla/5.0 MyBrowser/1.3';
console.log(myParser.setUA(myUA).getBrowser()); // {name: "MyBrowser", version: "1.3"}
```
# Development
## Backers & Sponsors
<a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/organizations.svg?avatarHeight=64"></a>
<a href="https://opencollective.com/ua-parser-js"><img src="https://opencollective.com/ua-parser-js/individuals.svg?avatarHeight=64"></a>
<a href="https://www.paypal.me/faisalman/"><img src="https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg" height="40"></a>
## Contributors
<a href="https://github.com/faisalman/ua-parser-js/graphs/contributors">
<img src="https://contrib.rocks/image?repo=faisalman/ua-parser-js" />
</a>
Made with [contributors-img](https://contrib.rocks).
## How To Contribute
* Fork and clone this repository
* Make some changes as required
* Write unit test to showcase its functionality
* Run the test suites to make sure it's not breaking anything `$ npm test`
* Submit a pull request under `develop` branch
# License
MIT License
Copyright (c) 2012-2021 Faisal Salman <<f@faisalman.com>>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,13 +0,0 @@
#!/usr/bin/env bash
SRC_PATH="src/main/ua-parser.js"
MIN_PATH="dist/ua-parser.min.js"
PACK_PATH="dist/ua-parser.pack.js"
# minified
echo "Generate ${MIN_PATH}"
uglifyjs $SRC_PATH -o $MIN_PATH --comments "/^ UA/"
# packed
echo "Generate ${PACK_PATH}"
uglifyjs $SRC_PATH -o $PACK_PATH --comments "/^ UA/" --compress --mangle

View File

@@ -1,52 +0,0 @@
#!/usr/bin/env node
/* jshint esversion: 6 */
const fs = require('fs');
const generateMJS = (module) => {
let { src, dest, title, replacements } = module;
let text = fs.readFileSync(src, 'utf-8');
replacements.push(
[/const (.+?)\s*=\s*require\((.+)\)/ig, 'import $1 from $2'],
[/module\.exports =/ig, 'export']
);
replacements.forEach(rep => {
text = text.replace(rep[0], rep[1]);
});
console.log(`Generate ${dest}`);
fs.writeFileSync(dest,
`// Generated ESM version of ${title}
// DO NOT EDIT THIS FILE!
// Source: /${src}
${text}`, 'utf-8');
};
const modules = [
{
src : 'src/main/ua-parser.js',
dest : 'src/main/ua-parser.mjs',
title : 'ua-parser-js',
replacements : [
[/\(func[\s\S]+strict\';/ig, ''],
[/esversion\: 3/ig, 'esversion: 6'],
[/\/[\/\s]+export[\s\S]+/ig,'export {UAParser};']
]
},{
src : 'src/enums/ua-parser-enums.js',
dest :'src/enums/ua-parser-enums.mjs',
title : 'ua-parser-js/enums',
replacements : []
},
{
src : 'src/extensions/ua-parser-extensions.js',
dest : 'src/extensions/ua-parser-extensions.mjs',
title : 'ua-parser-js/extensions',
replacements : []
}
];
modules.forEach(module => generateMJS(module));

View File

@@ -1,32 +0,0 @@
#!/usr/bin/env bash
echo '
- run build
'
npm run build || exit 1
echo '
- lint js code
'
npm run test:jshint || exit 1
#npm run test:eslint || exit 1
echo '
- test using mocha
'
npm run test:mocha || exit 1
echo '
- test using playwright
'
npm run test:playwright || exit 1
echo '
- lint lockfile
'
npm run test:lockfile-lint || exit 1
echo '
- lint d.ts files
'
npm run test:dts || exit 1

5
security.md Normal file
View File

@@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
Please report security issues to `f@faisalman.com`

View File

@@ -1,236 +0,0 @@
///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-beta.1
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Enterorise License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
const Browser = Object.freeze({
ANDROID: 'Android Browser',
BRAVE: 'Brave',
CHROME: 'Chrome',
CHROMIUM: 'Chromium',
DOLPHIN: 'Dolphin',
DUCKDUCKGO: 'DuckDuckGo',
EDGE: 'Edge',
FIREFOX: 'Firefox',
FOCUS: 'Focus',
IE: 'IE',
KONQUEROR: 'Konqueror',
MOBILE_CHROME: 'Mobile Chrome',
MOBILE_FIREFOX: 'Mobile Firefox',
MOBILE_SAFARI: 'Mobile Safari',
OPERA: 'Opera',
PALEMOON: 'PaleMoon',
PUFFIN: 'Puffin',
QQ: 'QQ Browser',
SAFARI: 'Safari',
SAMSUNG: 'Samsung Internet',
UC: 'UC Browser',
VIVALDI: 'Vivaldi',
YANDEX: 'Yandex'
// TODO : test!
});
const CPU = Object.freeze({
ARM : 'arm',
ARM64: 'arm64',
ARMHF: 'armhf',
AVR: 'avr',
IA64: 'ia64',
IRIX: 'irix',
IRIX64: 'irix64',
MIPS: 'mips',
MIPS64: 'mips64',
MOTO_68K: '68k',
PPC: 'ppc',
SPARC: 'sparc',
SPARC64: 'sparc64',
X86: 'ia32',
X86_64: 'amd64'
});
const Device = Object.freeze({
CONSOLE: 'console',
DEKSTOP: 'desktop',
EMBEDDED: 'embedded',
MOBILE: 'mobile',
SMARTTV: 'smarttv',
TABLET: 'tablet',
WEARABLE: 'wearable'
});
const Vendor = Object.freeze({
ACER: 'Acer',
ALCATEL: 'Alcatel',
APPLE: 'Apple',
AMAZON: 'Amazon',
ARCHOS: 'Archos',
ASUS: 'ASUS',
ATT: 'AT&T',
BENQ: 'BenQ',
BLACKBERRY: 'BlackBerry',
DELL: 'Dell',
ESSENTIAL: 'Essential',
FACEBOOK: 'Facebook',
FAIRPHONE: 'Fairphone',
GEEKSPHONE: 'GeeksPhone',
GENERIC: 'Generic',
GOOGLE: 'Google',
HP: 'HP',
HTC: 'HTC',
HUAWEI: 'Huawei',
INFINIX: 'Infinix',
JOLLA: 'Jolla',
KOBO: 'Kobo',
LENOVO: 'Lenovo',
LG: 'LG',
MEIZU: 'Meizu',
MICROSOFT: 'Microsoft',
MOTOROLA: 'Motorola',
NEXIAN: 'Nexian',
NINTENDO: 'Nintendo',
NOKIA: 'Nokia',
NVIDIA: 'Nvidia',
ONEPLUS: 'OnePlus',
OPPO: 'OPPO',
OUYA: 'Ouya',
PALM: 'Palm',
PANASONIC: 'Panasonic',
PEBBLE: 'Pebble',
POLYTRON: 'Polytron',
REALME: 'Realme',
RIM: 'RIM',
ROKU: 'Roku',
SAMSUNG: 'Samsung',
SHARP: 'Sharp',
SIEMENS: 'Siemens',
SONY: 'Sony',
SPRINT: 'Sprint',
TECNO: 'Tecno',
TESLA: 'Tesla',
ULEFONE: 'Ulefone',
VIVO: 'Vivo',
VODAFONE: 'Vodafone',
XBOX: 'Xbox',
XIAOMI: 'Xiaomi',
ZEBRA: 'Zebra',
ZTE: 'ZTE',
// TODO : test!
});
const Engine = Object.freeze({
AMAYA: 'Amaya',
BLINK: 'Blink',
EDGEHTML: 'EdgeHTML',
FLOW: 'Flow',
GECKO: 'Gecko',
GOANNA: 'Goanna',
ICAB: 'iCab',
KHTML: 'KHTML',
LIBWEB: 'LibWeb',
LINKS: 'Links',
LYNX: 'Lynx',
NETFRONT: 'NetFront',
NETSURF: 'NetSurf',
PRESTO: 'Presto',
TASMAN: 'Tasman',
TRIDENT: 'Trident',
W3M: 'w3m',
WEBKIT: 'WebKit'
});
const OS = Object.freeze({
AIX: 'AIX',
AMIGA_OS: 'Amiga OS',
ANDROID: 'Android',
ANDROID_X86: 'Android-x86',
ARCH: 'Arch',
BADA: 'Bada',
BEOS: 'BeOS',
BLACKBERRY: 'BlackBerry',
CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS',
CONTIKI: 'Contiki',
FEDORA: 'Fedora',
FIREFOX_OS: 'Firefox OS',
FREEBSD: 'FreeBSD',
DEBIAN: 'Debian',
DEEPIN: 'Deepin',
DRAGONFLY: 'DragonFly',
ELEMENTARY_OS: 'elementary OS',
FUCHSIA: 'Fuchsia',
GENTOO: 'Gentoo',
GHOSTBSD: 'GhostBSD',
GNU: 'GNU',
HAIKU: 'Haiku',
HARMONYOS: 'HarmonyOS',
HP_UX: 'HP-UX',
HURD: 'Hurd',
IOS: 'iOS',
JOLI: 'Joli',
KAIOS: 'KaiOS',
LINPUS: 'Linpus',
LINSPIRE: 'Linspire',
LINUX: 'Linux',
MACOS: 'macOS',
MAEMO: 'Maemo',
MAGEIA: 'Mageia',
MANDRIVA: 'Mandriva',
MANJARO: 'Manjaro',
MEEGO: 'MeeGo',
MINIX: 'Minix',
MINT: 'Mint',
MORPH_OS: 'Morph OS',
NETBSD: 'NetBSD',
NETRANGE: 'NetRange',
NETTV: 'NetTV',
NINTENDO: 'Nintendo',
OPENBSD: 'OpenBSD',
OPENVMS: 'OpenVMS',
OS2: 'OS/2',
PALM: 'Palm',
PC_BSD: 'PC-BSD',
PCLINUXOS: 'PCLinuxOS',
PLAN9: 'Plan9',
PLAYSTATION: 'PlayStation',
QNX: 'QNX',
RASPBIAN: 'Raspbian',
REDHAT: 'RedHat',
RIM_TABLET_OS: 'RIM Tablet OS',
RISC_OS: 'RISC OS',
SABAYON: 'Sabayon',
SAILFISH: 'Sailfish',
SERENITYOS: 'SerenityOS',
SERIES40: 'Series40',
SLACKWARE: 'Slackware',
SOLARIS: 'Solaris',
SUSE: 'SUSE',
SYMBIAN: 'Symbian',
TIZEN: 'Tizen',
UBUNTU: 'Ubuntu',
UNIX: 'Unix',
VECTORLINUX: 'VectorLinux',
VIERA: 'Viera',
WATCHOS: 'watchOS',
WEBOS: 'WebOS',
WINDOWS: 'Windows',
WINDOWS_MOBILE: 'Windows Mobile',
WINDOWS_PHONE: 'Windows Phone',
ZENWALK: 'Zenwalk'
// TODO : test!
});
module.exports = {
Browser,
CPU,
Device,
Vendor,
Engine,
OS
};

View File

@@ -1,240 +0,0 @@
// Generated ESM version of ua-parser-js/enums
// DO NOT EDIT THIS FILE!
// Source: /src/enums/ua-parser-enums.js
///////////////////////////////////////////////
/* Enums for UAParser.js v2.0.0-beta.1
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Enterorise License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
const Browser = Object.freeze({
ANDROID: 'Android Browser',
BRAVE: 'Brave',
CHROME: 'Chrome',
CHROMIUM: 'Chromium',
DOLPHIN: 'Dolphin',
DUCKDUCKGO: 'DuckDuckGo',
EDGE: 'Edge',
FIREFOX: 'Firefox',
FOCUS: 'Focus',
IE: 'IE',
KONQUEROR: 'Konqueror',
MOBILE_CHROME: 'Mobile Chrome',
MOBILE_FIREFOX: 'Mobile Firefox',
MOBILE_SAFARI: 'Mobile Safari',
OPERA: 'Opera',
PALEMOON: 'PaleMoon',
PUFFIN: 'Puffin',
QQ: 'QQ Browser',
SAFARI: 'Safari',
SAMSUNG: 'Samsung Internet',
UC: 'UC Browser',
VIVALDI: 'Vivaldi',
YANDEX: 'Yandex'
// TODO : test!
});
const CPU = Object.freeze({
ARM : 'arm',
ARM64: 'arm64',
ARMHF: 'armhf',
AVR: 'avr',
IA64: 'ia64',
IRIX: 'irix',
IRIX64: 'irix64',
MIPS: 'mips',
MIPS64: 'mips64',
MOTO_68K: '68k',
PPC: 'ppc',
SPARC: 'sparc',
SPARC64: 'sparc64',
X86: 'ia32',
X86_64: 'amd64'
});
const Device = Object.freeze({
CONSOLE: 'console',
DEKSTOP: 'desktop',
EMBEDDED: 'embedded',
MOBILE: 'mobile',
SMARTTV: 'smarttv',
TABLET: 'tablet',
WEARABLE: 'wearable'
});
const Vendor = Object.freeze({
ACER: 'Acer',
ALCATEL: 'Alcatel',
APPLE: 'Apple',
AMAZON: 'Amazon',
ARCHOS: 'Archos',
ASUS: 'ASUS',
ATT: 'AT&T',
BENQ: 'BenQ',
BLACKBERRY: 'BlackBerry',
DELL: 'Dell',
ESSENTIAL: 'Essential',
FACEBOOK: 'Facebook',
FAIRPHONE: 'Fairphone',
GEEKSPHONE: 'GeeksPhone',
GENERIC: 'Generic',
GOOGLE: 'Google',
HP: 'HP',
HTC: 'HTC',
HUAWEI: 'Huawei',
INFINIX: 'Infinix',
JOLLA: 'Jolla',
KOBO: 'Kobo',
LENOVO: 'Lenovo',
LG: 'LG',
MEIZU: 'Meizu',
MICROSOFT: 'Microsoft',
MOTOROLA: 'Motorola',
NEXIAN: 'Nexian',
NINTENDO: 'Nintendo',
NOKIA: 'Nokia',
NVIDIA: 'Nvidia',
ONEPLUS: 'OnePlus',
OPPO: 'OPPO',
OUYA: 'Ouya',
PALM: 'Palm',
PANASONIC: 'Panasonic',
PEBBLE: 'Pebble',
POLYTRON: 'Polytron',
REALME: 'Realme',
RIM: 'RIM',
ROKU: 'Roku',
SAMSUNG: 'Samsung',
SHARP: 'Sharp',
SIEMENS: 'Siemens',
SONY: 'Sony',
SPRINT: 'Sprint',
TECNO: 'Tecno',
TESLA: 'Tesla',
ULEFONE: 'Ulefone',
VIVO: 'Vivo',
VODAFONE: 'Vodafone',
XBOX: 'Xbox',
XIAOMI: 'Xiaomi',
ZEBRA: 'Zebra',
ZTE: 'ZTE',
// TODO : test!
});
const Engine = Object.freeze({
AMAYA: 'Amaya',
BLINK: 'Blink',
EDGEHTML: 'EdgeHTML',
FLOW: 'Flow',
GECKO: 'Gecko',
GOANNA: 'Goanna',
ICAB: 'iCab',
KHTML: 'KHTML',
LIBWEB: 'LibWeb',
LINKS: 'Links',
LYNX: 'Lynx',
NETFRONT: 'NetFront',
NETSURF: 'NetSurf',
PRESTO: 'Presto',
TASMAN: 'Tasman',
TRIDENT: 'Trident',
W3M: 'w3m',
WEBKIT: 'WebKit'
});
const OS = Object.freeze({
AIX: 'AIX',
AMIGA_OS: 'Amiga OS',
ANDROID: 'Android',
ANDROID_X86: 'Android-x86',
ARCH: 'Arch',
BADA: 'Bada',
BEOS: 'BeOS',
BLACKBERRY: 'BlackBerry',
CENTOS: 'CentOS',
CHROME_OS: 'Chrome OS',
CONTIKI: 'Contiki',
FEDORA: 'Fedora',
FIREFOX_OS: 'Firefox OS',
FREEBSD: 'FreeBSD',
DEBIAN: 'Debian',
DEEPIN: 'Deepin',
DRAGONFLY: 'DragonFly',
ELEMENTARY_OS: 'elementary OS',
FUCHSIA: 'Fuchsia',
GENTOO: 'Gentoo',
GHOSTBSD: 'GhostBSD',
GNU: 'GNU',
HAIKU: 'Haiku',
HARMONYOS: 'HarmonyOS',
HP_UX: 'HP-UX',
HURD: 'Hurd',
IOS: 'iOS',
JOLI: 'Joli',
KAIOS: 'KaiOS',
LINPUS: 'Linpus',
LINSPIRE: 'Linspire',
LINUX: 'Linux',
MACOS: 'macOS',
MAEMO: 'Maemo',
MAGEIA: 'Mageia',
MANDRIVA: 'Mandriva',
MANJARO: 'Manjaro',
MEEGO: 'MeeGo',
MINIX: 'Minix',
MINT: 'Mint',
MORPH_OS: 'Morph OS',
NETBSD: 'NetBSD',
NETRANGE: 'NetRange',
NETTV: 'NetTV',
NINTENDO: 'Nintendo',
OPENBSD: 'OpenBSD',
OPENVMS: 'OpenVMS',
OS2: 'OS/2',
PALM: 'Palm',
PC_BSD: 'PC-BSD',
PCLINUXOS: 'PCLinuxOS',
PLAN9: 'Plan9',
PLAYSTATION: 'PlayStation',
QNX: 'QNX',
RASPBIAN: 'Raspbian',
REDHAT: 'RedHat',
RIM_TABLET_OS: 'RIM Tablet OS',
RISC_OS: 'RISC OS',
SABAYON: 'Sabayon',
SAILFISH: 'Sailfish',
SERENITYOS: 'SerenityOS',
SERIES40: 'Series40',
SLACKWARE: 'Slackware',
SOLARIS: 'Solaris',
SUSE: 'SUSE',
SYMBIAN: 'Symbian',
TIZEN: 'Tizen',
UBUNTU: 'Ubuntu',
UNIX: 'Unix',
VECTORLINUX: 'VectorLinux',
VIERA: 'Viera',
WATCHOS: 'watchOS',
WEBOS: 'WebOS',
WINDOWS: 'Windows',
WINDOWS_MOBILE: 'Windows Mobile',
WINDOWS_PHONE: 'Windows Phone',
ZENWALK: 'Zenwalk'
// TODO : test!
});
export {
Browser,
CPU,
Device,
Vendor,
Engine,
OS
};

View File

@@ -1,248 +0,0 @@
///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-beta.1
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Enterorise License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
const MODEL = 'model';
const NAME = 'name';
const TYPE = 'type';
const VENDOR = 'vendor';
const VERSION = 'version';
const MOBILE = 'mobile';
const TABLET = 'tablet';
const Apps = Object.freeze({
browser : [
[/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({
browser : [
// wget / curl / lynx
[/(wget|curl|lynx)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'cli']]
]
});
const ExtraDevices = Object.freeze({
device : [[
/(nook)[\w ]+build\/(\w+)/i, // Nook
/(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak
/(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets
/(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets
/(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets
/(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone
], [VENDOR, MODEL, [TYPE, TABLET]], [
/(u304aa)/i // AT&T
], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [
/\bsie-(\w*)/i // Siemens
], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
/\b(rct\w+) b/i // RCA Tablets
], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
/\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets
], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
/\b(q(?:mv|ta)\w+) b/i // Verizon Tablet
], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
/\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet
], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [
/\b(tm\d{3}\w+) b/i
], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
/\b(k88) b/i // ZTE K Series Tablet
], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
/\b(nx\d{3}j) b/i // ZTE Nubia
], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
/\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile
], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
/\b(zur\d{3}) b/i // Swiss ZUR Tablet
], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
/\b((zeki)?tb.*\b) b/i // Zeki Tablets
], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
/\b([yr]\d{2}) b/i,
/\b(?:dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet
], [MODEL, [VENDOR, 'Dragon Touch'], [TYPE, TABLET]], [
/\b(ns-?\w{0,9}) b/i // Insignia Tablets
], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
/\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets
], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
/\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones
], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [
/\b(lvtel\-)?(v1[12]) b/i // LvTel Phones
], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
/\b(ph-1) /i // Essential PH-1
], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [
/\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets
], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
/\b(trio[-\w\. ]+) b/i // MachSpeed Tablets
], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
/\btu_(1491) b/i // Rotor Tablets
], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]]
]
});
const Emails = Object.freeze({
browser : [
// Microsoft Outlook / Thunderbird
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, 'email']]
]
});
const MediaPlayers = Object.freeze({
browser : [[
/(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia
/(coremedia) v([\w\._]+)/i
], [NAME, VERSION], [
/(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer
], [NAME, VERSION], [
/(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy
], [NAME, VERSION], [
/(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i,
// Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
// NSPlayer/PSP-InternetRadioPlayer/Videos
/(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD
/(lg player|nexplayer)\s([\d\.]+)/i,
/player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player
], [NAME, VERSION], [
/(nexplayer)\s([\w\.-]+)/i // Nexplayer
], [NAME, VERSION], [
/(flrp)\/([\w\.-]+)/i // Flip Player
], [[NAME, 'Flip Player'], VERSION], [
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
], [NAME], [
/(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i
// Gstreamer
], [NAME, VERSION], [
/(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player
/(java|python-urllib|python-requests|wget|libcurl)\/([\w\.-_]+)/i,
// Java/urllib/requests/wget/cURL
/(lavf)([\d\.]+)/i // Lavf (FFMPEG)
], [NAME, VERSION], [
/(htc_one_s)\/([\d\.]+)/i, // HTC One S
], [[NAME, /_/g, ' '], VERSION], [
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i,
// MPlayer SVN
], [NAME, VERSION], [
/(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer
/(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN
], [NAME, VERSION], [
/(mplayer)/i, // MPlayer (no other info)
/(yourmuze)/i, // YourMuze
/(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime
], [NAME], [
/(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout
], [NAME, VERSION], [
/(nokia\d+)\/([\w\.-]+)/i // Nokia
], [NAME, VERSION], [
/\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird
], [NAME, VERSION], [
/(winamp)3 version ([\w\.-]+)/i, // Winamp
/(winamp)\s([\w\.-]+)/i,
/(winamp)mpeg\/([\w\.-]+)/i
], [NAME, VERSION], [
/(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
// inlight radio
], [NAME], [
/(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i
// QuickTime/RealMedia/RadioApp/RadioClientApplication/
// SoundTap/Totem/Stagefright/Streamium
], [NAME, VERSION], [
/(smp)([\d\.]+)/i // SMP
], [NAME, VERSION], [
/(vlc) media player - version ([\w\.]+)/i, // VLC Videolan
/(vlc)\/([\w\.-]+)/i,
/(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp
/(foobar2000)\/([\d\.]+)/i, // Foobar2000
/(itunes)\/([\d\.]+)/i // iTunes
], [NAME, VERSION], [
/(wmplayer)\/([\w\.-]+)/i, // Windows Media Player
/(windows-media-player)\/([\w\.-]+)/i
], [[NAME, /-/g, ' '], VERSION], [
/windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i,
// Windows Media Server
], [VERSION, [NAME, 'Windows']], [
/(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm
], [NAME, VERSION], [
/(rad.io)\s([\d\.]+)/i, // Rad.io
/(radio.(?:de|at|fr))\s([\d\.]+)/i
], [[NAME, 'rad.io'], VERSION]
]
});
const Modules = Object.freeze({
browser : [
// Axios/jsdom/Scrapy
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'module']]
]
});
module.exports = {
Apps,
Bots,
CLIs,
ExtraDevices,
Emails,
MediaPlayers,
Modules
};

View File

@@ -1,252 +0,0 @@
// Generated ESM version of ua-parser-js/extensions
// DO NOT EDIT THIS FILE!
// Source: /src/extensions/ua-parser-extensions.js
///////////////////////////////////////////////
/* Extensions for UAParser.js v2.0.0-beta.1
https://github.com/faisalman/ua-parser-js
Author: Faisal Salman <f@faisalman.com>
UAParser.js PRO Enterorise License */
//////////////////////////////////////////////
/*jshint esversion: 6 */
const MODEL = 'model';
const NAME = 'name';
const TYPE = 'type';
const VENDOR = 'vendor';
const VERSION = 'version';
const MOBILE = 'mobile';
const TABLET = 'tablet';
const Apps = Object.freeze({
browser : [
[/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({
browser : [
// wget / curl / lynx
[/(wget|curl|lynx)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'cli']]
]
});
const ExtraDevices = Object.freeze({
device : [[
/(nook)[\w ]+build\/(\w+)/i, // Nook
/(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak
/(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets
/(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets
/(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets
/(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone
], [VENDOR, MODEL, [TYPE, TABLET]], [
/(u304aa)/i // AT&T
], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [
/\bsie-(\w*)/i // Siemens
], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
/\b(rct\w+) b/i // RCA Tablets
], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
/\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets
], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
/\b(q(?:mv|ta)\w+) b/i // Verizon Tablet
], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
/\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet
], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [
/\b(tm\d{3}\w+) b/i
], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
/\b(k88) b/i // ZTE K Series Tablet
], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
/\b(nx\d{3}j) b/i // ZTE Nubia
], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
/\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile
], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
/\b(zur\d{3}) b/i // Swiss ZUR Tablet
], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
/\b((zeki)?tb.*\b) b/i // Zeki Tablets
], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
/\b([yr]\d{2}) b/i,
/\b(?:dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet
], [MODEL, [VENDOR, 'Dragon Touch'], [TYPE, TABLET]], [
/\b(ns-?\w{0,9}) b/i // Insignia Tablets
], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
/\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets
], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
/\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones
], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [
/\b(lvtel\-)?(v1[12]) b/i // LvTel Phones
], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
/\b(ph-1) /i // Essential PH-1
], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [
/\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets
], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
/\b(trio[-\w\. ]+) b/i // MachSpeed Tablets
], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
/\btu_(1491) b/i // Rotor Tablets
], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]]
]
});
const Emails = Object.freeze({
browser : [
// Microsoft Outlook / Thunderbird
[/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, 'email']]
]
});
const MediaPlayers = Object.freeze({
browser : [[
/(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia
/(coremedia) v([\w\._]+)/i
], [NAME, VERSION], [
/(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer
], [NAME, VERSION], [
/(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy
], [NAME, VERSION], [
/(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i,
// Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
// NSPlayer/PSP-InternetRadioPlayer/Videos
/(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD
/(lg player|nexplayer)\s([\d\.]+)/i,
/player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player
], [NAME, VERSION], [
/(nexplayer)\s([\w\.-]+)/i // Nexplayer
], [NAME, VERSION], [
/(flrp)\/([\w\.-]+)/i // Flip Player
], [[NAME, 'Flip Player'], VERSION], [
/(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
// FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
], [NAME], [
/(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i
// Gstreamer
], [NAME, VERSION], [
/(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player
/(java|python-urllib|python-requests|wget|libcurl)\/([\w\.-_]+)/i,
// Java/urllib/requests/wget/cURL
/(lavf)([\d\.]+)/i // Lavf (FFMPEG)
], [NAME, VERSION], [
/(htc_one_s)\/([\d\.]+)/i, // HTC One S
], [[NAME, /_/g, ' '], VERSION], [
/(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i,
// MPlayer SVN
], [NAME, VERSION], [
/(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer
/(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN
], [NAME, VERSION], [
/(mplayer)/i, // MPlayer (no other info)
/(yourmuze)/i, // YourMuze
/(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime
], [NAME], [
/(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout
], [NAME, VERSION], [
/(nokia\d+)\/([\w\.-]+)/i // Nokia
], [NAME, VERSION], [
/\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird
], [NAME, VERSION], [
/(winamp)3 version ([\w\.-]+)/i, // Winamp
/(winamp)\s([\w\.-]+)/i,
/(winamp)mpeg\/([\w\.-]+)/i
], [NAME, VERSION], [
/(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
// inlight radio
], [NAME], [
/(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i
// QuickTime/RealMedia/RadioApp/RadioClientApplication/
// SoundTap/Totem/Stagefright/Streamium
], [NAME, VERSION], [
/(smp)([\d\.]+)/i // SMP
], [NAME, VERSION], [
/(vlc) media player - version ([\w\.]+)/i, // VLC Videolan
/(vlc)\/([\w\.-]+)/i,
/(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp
/(foobar2000)\/([\d\.]+)/i, // Foobar2000
/(itunes)\/([\d\.]+)/i // iTunes
], [NAME, VERSION], [
/(wmplayer)\/([\w\.-]+)/i, // Windows Media Player
/(windows-media-player)\/([\w\.-]+)/i
], [[NAME, /-/g, ' '], VERSION], [
/windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i,
// Windows Media Server
], [VERSION, [NAME, 'Windows']], [
/(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm
], [NAME, VERSION], [
/(rad.io)\s([\d\.]+)/i, // Rad.io
/(radio.(?:de|at|fr))\s([\d\.]+)/i
], [[NAME, 'rad.io'], VERSION]
]
});
const Modules = Object.freeze({
browser : [
// Axios/jsdom/Scrapy
[/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'module']]
]
});
export {
Apps,
Bots,
CLIs,
ExtraDevices,
Emails,
MediaPlayers,
Modules
};

View File

@@ -1,104 +0,0 @@
// Type definitions for UAParser.js v2.0.0-beta.1
// Project: https://github.com/faisalman/ua-parser-js
// Definitions by: Faisal Salman <https://github.com/faisalman>
declare namespace UAParser {
interface IData<T> {
is(val: string): boolean;
toString(): string;
withClientHints(): PromiseLike<T> | T;
withFeatureCheck(): T;
}
interface IBrowser extends IData<IBrowser> {
name?: string;
version?: string;
major?: string;
}
interface ICPU extends IData<ICPU> {
architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'ppc' | 'sparc' | 'sparc64';
}
interface IDevice extends IData<IDevice> {
type?: 'mobile' | 'tablet' | 'console' | 'smarttv' | 'wearable';
vendor?: string;
model?: string;
}
interface IEngine extends IData<IEngine> {
name?: 'Amaya' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
version?: string;
}
interface IOS extends IData<IOS> {
name?: string;
version?: string;
}
interface IResult extends IData<IResult> {
ua: string;
browser: IBrowser;
cpu: ICPU;
device: IDevice;
engine: IEngine;
os: IOS;
}
type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[];
export function UAParser(uastring?: string, extensions?: Record<string, RegexMap>, 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(headers?: Record<string, string>): IResult;
export class UAParser {
static readonly BROWSER: {
NAME: 'name';
VERSION: 'version';
MAJOR: 'major';
};
static readonly CPU: {
ARCHITECTURE: 'architecture';
};
static readonly DEVICE: {
TYPE: 'type';
VENDOR: 'vendor';
MODEL: 'model';
CONSOLE: 'console';
MOBILE: 'mobile';
SMARTTV: 'smarttv';
TABLET: 'tablet';
WEARABLE: 'wearable';
EMBEDDED: 'embedded';
};
static readonly ENGINE: {
NAME: 'name';
VERSION: 'version';
};
static readonly OS: {
NAME: 'name';
VERSION: 'version';
};
static readonly VERSION: string;
constructor(uastring?: string, extensions?: Record<string, RegexMap>, headers?: Record<string, string>);
constructor(uastring?: string, headers?: Record<string, string>);
constructor(extensions?: Record<string, RegexMap>, headers?: Record<string, string>);
constructor(headers?: Record<string, string>);
getUA(): string;
getBrowser(): IBrowser;
getCPU(): ICPU;
getDevice(): IDevice;
getEngine(): IEngine;
getOS(): IOS;
getResult(): IResult;
setUA(uastring: string): UAParser;
}
}
export as namespace UAParser;
export = UAParser;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,26 @@
"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",
"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",
"expect" :
{
"name" : "Samsung Browser",
"name" : "Samsung Internet",
"version" : "3.0",
"major" : "3"
}
@@ -94,7 +114,7 @@
"ua" : "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB5; Avant Browser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",
"expect" :
{
"name" : "Avant ",
"name" : "Avant",
"version" : "undefined",
"major" : "undefined"
}
@@ -124,11 +144,71 @@
"ua" : "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; baidubrowser 1.x)",
"expect" :
{
"name" : "baidubrowser",
"name" : "Baidu",
"version" : "1.x",
"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" : "Bolt",
"ua" : "Mozilla/5.0 (X11; 78; CentOS; US-en) AppleWebKit/527+ (KHTML, like Gecko) Bolt/0.862 Version/3.0 Safari/523.15",
@@ -274,7 +354,7 @@
"ua" : "Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3",
"expect" :
{
"name" : "Mobile Chrome",
"name" : "Chrome",
"version" : "19.0.1084.60",
"major" : "19"
}
@@ -294,7 +374,7 @@
"ua" : "Mozilla/5.0 (Linux; U; Android-4.0.3; en-us; Galaxy Nexus Build/IML74K) AppleWebKit/535.7 (KHTML, like Gecko) CrMo/16.0.912.75 Mobile Safari/535.7",
"expect" :
{
"name" : "Mobile Chrome",
"name" : "Chrome",
"version" : "16.0.912.75",
"major" : "16"
}
@@ -429,6 +509,26 @@
"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",
"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",
@@ -548,16 +648,6 @@
"major" : "1"
}
},
{
"desc" : "HeyTap",
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.61 Safari/537.36 HeyTapBrowser/40.8.10.1",
"expect" :
{
"name" : "HeyTap",
"version" : "40.8.10.1",
"major" : "40"
}
},
{
"desc" : "HuaweiBrowser",
"ua" : "Mozilla/5.0 (Linux; Android 6.0.1; LYA-AL00HMSCore/4.0.0 GMS/10.4 ) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.64 HuaweiBrowser/10.0.3.102 Mobile Safari/537.36",
@@ -708,6 +798,26 @@
"major" : "5"
}
},
{
"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",
"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",
@@ -808,16 +918,6 @@
"major" : "4"
}
},
{
"desc" : "Mobile Safari",
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 16_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Safari/604.1",
"expect" :
{
"name" : "Mobile Safari",
"version" : "undefined",
"major" : "undefined"
}
},
{
"desc" : "Mosaic",
"ua" : "NCSA_Mosaic/2.6 (X11; SunOS 4.1.3 sun4m)",
@@ -1124,16 +1224,46 @@
"expect" :
{
"name" : "Safari",
"version" : "1",
"version" : "2.0.4",
"major" : "2"
}
},
{
"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",
"expect" :
{
"name" : "Samsung Internet",
"version" : "4.0",
"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 Browser",
"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",
"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 Browser",
"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"
}
@@ -1348,6 +1478,16 @@
"major" : "2"
}
},
{
"desc" : "Vivo Browser",
"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" :
{
"name" : "Vivo Browser",
"version" : "16.7.1.1",
"major" : "16"
}
},
{
"desc" : "Viera",
"ua" : "HbbTV/1.2.1 (;Panasonic;VIERA 2015;3.014;a001-003 4000-0000;)",
@@ -1438,16 +1578,6 @@
"major" : "6"
}
},
{
"desc" : "Puffin",
"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",
"expect" :
{
"name" : "Puffin",
"version" : "9.2.0.50586AP",
"major" : "9"
}
},
{
"desc" : "Microsoft Edge 0.1",
"ua" : "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0",
@@ -1533,7 +1663,7 @@
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) FxiOS/1.1 Mobile/13B143 Safari/601.1.46",
"expect" :
{
"name" : "Mobile Firefox",
"name" : "Firefox",
"version" : "1.1",
"major" : "1"
}
@@ -1543,7 +1673,7 @@
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 16_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/112.0 Mobile/15E148 Safari/605.1.15",
"expect" :
{
"name" : "Mobile Firefox",
"name" : "Firefox",
"version" : "112.0",
"major" : "112"
}
@@ -1553,7 +1683,7 @@
"ua" : "Mozilla/5.0 (iPad; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) FxiOS/1.0 Mobile/12F69 Safari/600.1.4",
"expect" :
{
"name" : "Mobile Firefox",
"name" : "Firefox",
"version" : "1.0",
"major" : "1"
}
@@ -1578,32 +1708,12 @@
"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",
"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" : "WeChat(Win) Desktop",
"name" : "WeChat",
"version" : "3.43.901.400",
"major" : "3"
}
@@ -1613,7 +1723,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",
"expect" :
{
"name" : "WeChat(Win) Desktop",
"name" : "WeChat",
"version" : "4.0.1301.400",
"major" : "4"
}
@@ -1643,7 +1753,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",
"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 +1776,6 @@
"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",
"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",
@@ -1865,7 +1977,7 @@
"ua" : "Mozilla/5.0 (Linux; Android 7.1.2; Nexus 5X Build/N2G47W) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.83 Mobile Safari/537.36",
"expect" :
{
"name" : "Mobile Chrome",
"name" : "Chrome",
"version" : "58.0.3029.83",
"major" : "58"
}
@@ -1875,7 +1987,7 @@
"ua" : "Mozilla/5.0 (Linux; Android 7.1.2; Nexus 5X Build/N2G47W) AppleWebKit/537.36 (KHTML, like Gecko) FxiOS/7.5b3349 Mobile/14F89 Safari/603.2.4",
"expect" :
{
"name" : "Mobile Firefox",
"name" : "Firefox",
"version" : "7.5b3349",
"major" : "7"
}
@@ -1885,7 +1997,7 @@
"ua" : "Mozilla/5.0 (Android 5.0; Mobile; rv:41.0) Gecko/41.0 Firefox/41.0",
"expect" :
{
"name" : "Mobile Firefox",
"name" : "Firefox",
"version" : "41.0",
"major" : "41"
}
@@ -1900,4 +2012,4 @@
"major" : "12"
}
}
]
]

View File

@@ -167,14 +167,6 @@
"architecture" : "arm64"
}
},
{
"desc" : "Google Search App",
"ua" : "Mozilla/5.0 (Linux; Android 6.0; M5s Build/MRA58K; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/44.0.2403.147 Mobile Safari/537.36 GSA/12.40.17.23.arm64",
"expect" :
{
"architecture" : "arm64"
}
},
{
"desc" : "Pocket PC",
"ua" : "Opera/9.7 (Windows Mobile; PPC; Opera Mobi/35166; U; en) Presto/2.2.1",
@@ -254,13 +246,5 @@
{
"architecture" : "irix64"
}
},
{
"desc" : "68k",
"ua" : "'Mozilla/1.1 (Macintosh; U; 68K)'",
"expect" :
{
"architecture" : "68k"
}
}
]

View File

@@ -152,15 +152,6 @@
"type": "mobile"
}
},
{
"desc": "ASUS Zenfone 2 Laser",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; ASUS_Z00ED) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36",
"expect": {
"vendor": "ASUS",
"model": "Z00ED",
"type": "mobile"
}
},
{
"desc": "Acer Iconia A1-810",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; A1-810 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Safari/537.36",
@@ -233,6 +224,15 @@
"type": "mobile"
}
},
{
"desc": "Essential PH-1",
"ua": "Mozilla/5.0 (Linux; Android 9; PH-1 Build/PPR1.180905.036) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36",
"expect": {
"vendor": "Essential",
"model": "PH-1",
"type": "mobile"
}
},
{
"desc": "Fairphone 1U",
"ua": "Mozilla/5.0 (Linux; U; Android 4.2.2; FP1U Build/JDQ39) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
@@ -980,15 +980,6 @@
"type": "tablet"
}
},
{
"desc": "Lenovo IdeaTab S6000",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; IdeaTab S6000-H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 YaBrowser/18.11.1.1011.01 Safari/537.36",
"expect": {
"vendor": "Lenovo",
"model": "IdeaTab S6000-H",
"type": "tablet"
}
},
{
"desc": "LG V40 ThinQ",
"ua": "Mozilla/5.0 (Linux; Android 9; LM-V405) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.136 Mobile Safari/537.36",
@@ -1610,15 +1601,6 @@
"type": "mobile"
}
},
{
"desc": "OPPO F5",
"ua": "ozilla/5.0 (Linux; Android 7.1.1; CPH1723) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Mobile Safari/537.36",
"expect": {
"vendor": "OPPO",
"model": "CPH1723",
"type": "mobile"
}
},
{
"desc": "Realme C1",
"ua": "Mozilla/5.0 (Linux; Android 8.1; RMX1811 Build/OPM1.171019.026) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.126 Mobile Safari/537.36",
@@ -2357,15 +2339,6 @@
"type": "mobile"
}
},
{
"desc": "Tecno Spark 8C",
"ua": "Mozilla/5.0 (Linux; Android 11; TECNO KG5n) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36",
"expect": {
"vendor": "TECNO",
"model": "KG5n",
"type": "mobile"
}
},
{
"desc": "Tesla",
"ua": "Mozilla/5.0 (X11; GNU/Linux) AppleWebKit/601.1 (KHTML, like Gecko) Tesla QtCarBrowser Safari/601.1",
@@ -2735,15 +2708,6 @@
"type": "mobile"
}
},
{
"desc": "Xiaomi POCOPHONE F1",
"ua": "Mozilla/5.0 (Linux; Android 10; POCOPHONE F1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36",
"expect": {
"vendor": "Xiaomi",
"model": "POCOPHONE F1",
"type": "mobile"
}
},
{
"desc": "Xiaomi Redmi 4A",
"ua": "Mozilla/5.0 (Linux; Android 6.0; Redmi 4A Build/MMB29M; xx-xx) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Mobile Safari/537.36",
@@ -2843,6 +2807,15 @@
"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",
"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",
@@ -3158,15 +3131,6 @@
"type": "mobile"
}
},
{
"desc": "Google Pixel 7",
"ua": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36",
"expect": {
"vendor": "Google",
"model": "Pixel 7",
"type": "mobile"
}
},
{
"desc": "Generic Android Device",
"ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; i980 Build/MRA58K)",
@@ -3226,6 +3190,294 @@
"type": "tablet"
}
},
{
"desc": "RCA Voyager III Tablet",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; RCT6973W43 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "RCA",
"model": "RCT6973W43",
"type": "tablet"
}
},
{
"desc": "RCA Voyager II Tablet",
"ua": "Mozilla/5.0 (Linux; Android 5.0; RCT6773W22B Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "RCA",
"model": "RCT6773W22B",
"type": "tablet"
}
},
{
"desc": "Verizon Quanta Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; QMV7B Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Verizon",
"model": "QMV7B",
"type": "tablet"
}
},
{
"desc": "Verizon Ellipsis 8 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 5.1.1; QTAQZ3 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Verizon",
"model": "QTAQZ3",
"type": "tablet"
}
},
{
"desc": "Verizon Ellipsis 8HD Tablet",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; QTASUN1 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Safari/537.36",
"expect": {
"vendor": "Verizon",
"model": "QTASUN1",
"type": "tablet"
}
},
{
"desc": "Dell Venue 8 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 8 3830 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Dell",
"model": "Venue 8 3830",
"type": "tablet"
}
},
{
"desc": "Dell Venue 7 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 7 3730 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Dell",
"model": "Venue 7 3730",
"type": "tablet"
}
},
{
"desc": "Barnes & Noble Nook HD+ Tablet",
"ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; Barnes & Noble Nook HD+ Build/JZO54K; CyanogenMod-10) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
"expect": {
"vendor": "Barnes & Noble",
"model": "Nook HD+",
"type": "tablet"
}
},
{
"desc": "Barnes & Noble V400 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.0.4; BNTV400 Build/IMM76L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.111 Safari/537.36",
"expect": {
"vendor": "Barnes & Noble",
"model": "V400",
"type": "tablet"
}
},
{
"desc": "NuVision TM101A540N Tablet",
"ua": "Mozilla/5.0 (Linux; Android 5.1; TM101A540N Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/50.0.2661.86 Safari/537.36",
"expect": {
"vendor": "NuVision",
"model": "TM101A540N",
"type": "tablet"
}
},
{
"desc": "ZTE-Z431",
"ua": "ZTE-Z431/1.4.0 NetFront/4.2 QTV5.1 Profile/MIDP-2.1 Configuration/CLDC-1.1",
"expect": {
"vendor": "ZTE",
"model": "Z431",
"type": "mobile"
}
},
{
"desc": "ZTE",
"ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; ZTE-Z740G Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
"expect": {
"vendor": "ZTE",
"model": "Z740G",
"type": "mobile"
}
},
{
"desc": "ZTE K Series Tablet",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; K88 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "K88",
"type": "tablet"
}
},
{
"desc": "ZTE Nubia Red Magic 3",
"ua": "Mozilla/5.0 (Linux; Android 9; NX629J Build/PKQ1.190321.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/45016 Mobile Safari/537.36 MMWEBID/4064 MicroMessenger/7.0.10.1580(0x27000A34) Process/tools NetType/WIFI Language/zh_CN ABI/arm64",
"expect": {
"vendor": "ZTE",
"model": "NX629J",
"type": "mobile"
}
},
{
"desc": "ZTE Blade A5",
"ua": "Mozilla/5.0 (Linux; Android 9; ZTE Blade A5 2019) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "Blade A5 2019",
"type": "mobile"
}
},
{
"desc": "ZTE BLADE V0730",
"ua": "Mozilla/5.0 (Linux; Android 6.0; ZTE BLADE V0730) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "BLADE V0730",
"type": "mobile"
}
},
{
"desc": "ZTE B2017G",
"ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE B2017G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "B2017G",
"type": "mobile"
}
},
{
"desc": "Swizz GEN610",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; GEN610 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36",
"expect": {
"vendor": "Swiss",
"model": "GEN610",
"type": "mobile"
}
},
{
"desc": "Swizz ZUR700",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; ZUR700 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Safari/537.36",
"expect": {
"vendor": "Swiss",
"model": "ZUR700",
"type": "tablet"
}
},
{
"desc": "Zeki TB782b Tablet",
"ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-US; TB782B Build/IMM76D) AppleWebKit/534.31 (KHTML, like Gecko) UCBrowser/9.0.2.299 U3/0.8.0 Mobile Safari/534.31",
"expect": {
"vendor": "Zeki",
"model": "TB782B",
"type": "tablet"
}
},
{
"desc": "Dragon Touch Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.0.4; DT9138B Build/IMM76D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Mobile Safari/537.36",
"expect": {
"vendor": "Dragon Touch",
"model": "9138B",
"type": "tablet"
}
},
{
"desc": "Insignia Tablet",
"ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; NS-P08A7100 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Insignia",
"model": "NS-P08A7100",
"type": "tablet"
}
},
{
"desc": "Voice Xtreme V75",
"ua": "Mozilla/5.0 (Linux; U; Android 4.2.1; en-us; V75 Build/JOP40D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
"expect": {
"vendor": "Voice",
"model": "V75",
"type": "mobile"
}
},
{
"desc": "LvTel V11",
"ua": "Mozilla/5.0 (Linux; Android 5.1.1; V11 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Safari/537.36",
"expect": {
"vendor": "LvTel",
"model": "V11",
"type": "mobile"
}
},
{
"desc": "Envizen Tablet V100MD",
"ua": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; V100MD Build/V100MD.20130816) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",
"expect": {
"vendor": "Envizen",
"model": "V100MD",
"type": "tablet"
}
},
{
"desc": "Rotor Tablet",
"ua": "mozilla/5.0 (linux; android 5.0.1; tu_1491 build/lrx22c) applewebkit/537.36 (khtml, like gecko) chrome/43.0.2357.93 safari/537.36",
"expect": {
"vendor": "Rotor",
"model": "1491",
"type": "tablet"
}
},
{
"desc": "MachSpeed Tablets",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Trio 7.85 vQ Build/Trio_7.85_vQ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36",
"expect": {
"vendor": "MachSpeed",
"model": "Trio 7.85 vQ",
"type": "tablet"
}
},
{
"desc": "Trinity Tablets",
"ua": "Mozilla/5.0 (Linux; Android 5.0.1; Trinity T101 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Safari/537.36",
"expect": {
"vendor": "Trinity",
"model": "T101",
"type": "tablet"
}
},
{
"desc": "NextBook Next7",
"ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Next7P12 Build/IMM76I) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",
"expect": {
"vendor": "NextBook",
"model": "Next7P12",
"type": "tablet"
}
},
{
"desc": "NextBook Tablets",
"ua": "Mozilla/5.0 (Linux; Android 5.0; NXA8QC116 Build/LRX21V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "NextBook",
"model": "NXA8QC116",
"type": "tablet"
}
},
{
"desc": "Le Pan Tablets",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Le Pan",
"model": "TC802A",
"type": "tablet"
}
},
{
"desc": "Le Pan Tablets",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Le Pan",
"model": "TC802A",
"type": "tablet"
}
},
{
"desc": "Amazon Alexa Echo Show",
"ua": "AlexaWebMediaPlayer/1.0.200641.0 (Linux;Android 5.1.1)",
@@ -3298,6 +3550,15 @@
"type": "smarttv"
}
},
{
"desc": "Gigaset Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Gigaset QV830 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Gigaset",
"model": "QV830",
"type": "tablet"
}
},
{
"desc": "Amazon Fire 7",
"ua": "Mozilla/5.0 (Linux; Android 5.1.1; KFAUWI) AppleWebKit/537.36 (KHTML, like Gecko) Silk/80.5.3 like Chrome/80.0.3987.162 Safari/537.36",
@@ -3307,6 +3568,42 @@
"type": "tablet"
}
},
{
"desc": "AT&T Radiant Core U304AA",
"ua": "Dalvik/2.1.0 (Linux; U; Android 9; U304AA Build/P00610)",
"expect": {
"vendor": "AT&T",
"model": "U304AA",
"type": "mobile"
}
},
{
"desc": "Vodafone Smart Tab 4G",
"ua": "Mozilla/5.0 (Linux; Android 4.4.4; Vodafone Smart Tab 4G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
"expect": {
"vendor": "Vodafone",
"model": "Smart Tab 4G",
"type": "tablet"
}
},
{
"desc": "Vodafone Smart ultra 6",
"ua": "Mozilla/5.0 (Linux; Android 5.0.2; Vodafone Smart ultra 6 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36",
"expect": {
"vendor": "Vodafone",
"model": "Smart ultra 6",
"type": "tablet"
}
},
{
"desc": "4ife 4K Smart TV Box",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre",
"expect": {
"vendor": "undefined",
"model": "undefined",
"type": "smarttv"
}
},
{
"desc": "FaceBook Mobile App",
"ua": "[FBAN/FBIOS;FBAV/283.0.0.44.117;FBBV/238386386;FBDV/iPhone12,1;FBMD/iPhone;FBSN/iOS;FBSV/13.6.1;FBSS/2;FBID/phone;FBLC/en_US;FBOP/5;FBRV/240127608]",
@@ -3397,15 +3694,6 @@
"type": "console"
}
},
{
"desc": "Vivo S1 Pro",
"ua": "Mozilla/5.0 (Linux; Android 11; vivo 1920) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Mobile Safari/537.36",
"expect": {
"vendor": "Vivo",
"model": "1920",
"type": "mobile"
}
},
{
"desc": "Vivo Y52s",
"ua": "Mozilla/5.0 (Linux; Android 10; V2057A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/76.0.3809.89 Mobile Safari/537.36 T7/12.10 SP-engine/2.28.0 baiduboxapp/12.10.0.10 (Baidu; P1 10) NABar/1.0",

View File

@@ -1,42 +0,0 @@
import { expectType } from 'tsd';
import { UAParser, IResult, IBrowser, ICPU, IEngine, IDevice, IOS } from "../src/main/ua-parser";
const uastring = 'Mozilla/5.0 (X11; MyCustomOS; Linux i686; rv:19.0) Gecko/20100101 Firefox/19.0';
const extensions = {
os : [
[/(mycustomos)/], [UAParser.OS.NAME, [UAParser.OS.VERSION, '10']]
]
};
const headers = {
'sec-ch-ua-mobile' : '?1'
};
expectType<IResult>(UAParser());
expectType<IResult>(UAParser(uastring));
expectType<IResult>(UAParser(uastring, extensions));
expectType<IResult>(UAParser(uastring, headers));
expectType<IResult>(UAParser(extensions, headers));
expectType<IResult>(UAParser(extensions));
expectType<IResult>(UAParser(headers));
expectType<UAParser>(new UAParser());
const parser = new UAParser(uastring);
const browser = parser.getBrowser();
expectType<IBrowser>(browser);
expectType<string | undefined>(browser.name);
expectType<string | undefined>(browser.version);
expectType<string | undefined>(browser.major);
expectType<boolean>(browser.is(''));
expectType<string>(browser.toString());
expectType<IBrowser | PromiseLike<IBrowser>>(browser.withClientHints());
expectType<IBrowser>((<IBrowser>browser.withClientHints()).withFeatureCheck());
expectType<boolean>((<IBrowser>browser.withClientHints()).withFeatureCheck().is(''));
expectType<ICPU>(parser.getCPU());
expectType<IDevice>(parser.getDevice());
expectType<IEngine>(parser.getEngine());
expectType<IOS>(parser.getOS());
expectType<IResult>(parser.getResult());
expectType<string>(parser.getUA());
expectType<UAParser>(parser.setUA(uastring));

View File

@@ -1,20 +0,0 @@
const { FuzzedDataProvider } = require('@jazzer.js/core');
const UAParser = require('ua-parser-js');
const UA_MAX_LENGTH = 350;
module.exports.fuzz = function (buffer) {
const data = new FuzzedDataProvider(buffer);
const userAgent = data.consumeString(UA_MAX_LENGTH, 'utf-8', true);
const start = process.hrtime();
UAParser(userAgent);
const elapsed = process.hrtime(start);
const milisec = (elapsed[0]*1e3+elapsed[1]*1e-6).toFixed(3);
if (milisec > 1000) {
throw new Error(
`Potential ReDoS\n` +
`Time taken: ${milisec} ms.\n` +
`User agent: ${userAgent}`);
}
};

View File

@@ -1,27 +0,0 @@
import { UAParser } from '../src/main/ua-parser.mjs';
import { CPU, Device, Engine } from '../src/enums/ua-parser-enums.mjs';
import * as assert from 'assert';
describe('Returns', () => {
it('getResult() should returns object', () => {
assert.deepEqual(new UAParser('').getResult(),
{
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 },
cpu: { architecture: undefined },
device: { vendor: undefined, model: undefined, type: undefined },
engine: { name: undefined, version: undefined},
os: { name: undefined, version: undefined }
});
});
});
describe('Enums', () => {
it('Can use enum', () => {
const { cpu, device, engine } = UAParser('Mozilla/5.0 (X11; U; Linux armv7l; en-GB; rv:1.9.2a1pre) Gecko/20090928 Firefox/3.5 Maemo Browser 1.4.1.22 RX-51 N900');
assert.strictEqual(cpu.is(CPU.ARM), true);
assert.strictEqual(device.is(Device.MOBILE), true);
assert.strictEqual(engine.is(Engine.GECKO), true);
});
});

View File

@@ -1,79 +0,0 @@
const fs = require('fs');
const assert = require('assert');
const parseJS = require('@babel/parser').parse;
const traverse = require('@babel/traverse').default;
const safe = require('safe-regex');
const UAParser = require('../src/main/ua-parser');
const { Bots, CLIs, Emails, Modules } = require('../src/extensions/ua-parser-extensions');
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 thunderbird = 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0';
const axios = 'axios/1.3.5';
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 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);
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"});
const moduleParser = new UAParser(Modules);
assert.deepEqual(moduleParser.setUA(axios).getBrowser(), {name: "axios", version: "1.3.5", major: "1", 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"});
});
});
// TODO : move test spec to JSON file
describe('Testing regexes', () => {
let regexes;
before('Read main js file', () => {
let code = fs.readFileSync('src/extensions/ua-parser-extensions.js', 'utf8').toString();
let ast = parseJS(code, { sourceType: 'script' });
regexes = [];
traverse(ast, {
RegExpLiteral: (path) => {
regexes.push(path.node.pattern);
}
});
if (regexes.length === 0) {
throw new Error('Regexes cannot be empty!');
}
});
describe('Begin testing', () => {
it('all regexes in extension file', () => {
regexes.forEach(regex => {
describe('Test against `safe-regex` : ' + regex, () => {
it('should be safe from potentially vulnerable regex', () => {
assert.strictEqual(safe(regex), true);
});
});
});
});
});
});

File diff suppressed because one or more lines are too long

View File

@@ -80,6 +80,24 @@
"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",
"ua" : "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0)",
@@ -670,7 +688,7 @@
"ua" : "Mozilla/5.0 (X11; CrOS x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.0.0 Safari/537.36",
"expect" :
{
"name" : "Chrome OS",
"name" : "Chromium OS",
"version" : "undefined"
}
},
@@ -679,7 +697,7 @@
"ua" : "Mozilla/5.0 (X11; CrOS x86_64 10575.58.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36",
"expect" :
{
"name" : "Chrome OS",
"name" : "Chromium OS",
"version" : "10575.58.0"
}
},
@@ -814,7 +832,7 @@
"ua" : "Mozilla/4.0 (compatible; MSIE 5.0b1; Mac_PowerPC)",
"expect" :
{
"name" : "macOS",
"name" : "Mac OS",
"version" : "undefined"
}
},
@@ -823,7 +841,7 @@
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0",
"expect" :
{
"name" : "macOS",
"name" : "Mac OS",
"version" : "x.y"
}
},
@@ -832,7 +850,7 @@
"ua" : "Mozilla/5.0 (Macintosh; PPC Mac OS X x.y; rv:10.0) Gecko/20100101 Firefox/10.0",
"expect" :
{
"name" : "macOS",
"name" : "Mac OS",
"version" : "x.y"
}
},
@@ -841,7 +859,7 @@
"ua" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36",
"expect" :
{
"name" : "macOS",
"name" : "Mac OS",
"version" : "10.6.8"
}
},

View File

@@ -1,79 +0,0 @@
// @ts-check
import { test, expect } from '@playwright/test';
import path from 'path';
import url from 'url';
const localHtml = `file://${path.resolve(path.dirname(url.fileURLToPath(import.meta.url)), '../')}/dist/ua-parser.html`;
test.describe('test input', () => {
test.beforeEach(async ({ page }) => {
await page.goto(localHtml);
});
test('accept empty string', async ({ page }) => {
// @ts-ignore
const uap = await page.evaluate(async () => await UAParser(''));
expect(uap).toHaveProperty('ua', '');
});
});
test('read client hints data', async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(navigator, 'userAgentData', {
value: {
brands: [],
platform: '',
mobile: false,
getHighEntropyValues: () => {
return Promise.resolve({
brands: [
{
brand: 'Chromium',
version: '110'
},
{
brand: 'Not(A:Brand',
version: '110'
},
{
brand: 'New Browser',
version: '110'
}
],
platform: 'New OS',
formFactor: 'New Form Factor'
});
}
}
});
});
await page.goto(localHtml);
// @ts-ignore
const uap = await page.evaluate(async () => await UAParser().withClientHints());
expect(uap).toHaveProperty('browser.name', 'New Browser');
expect(uap).toHaveProperty('os.name', 'New OS');
expect(uap).toHaveProperty('device.type', undefined);
});
test('detect Brave', async ({ page }) => {
await page.addInitScript(() => {
Object.defineProperty(navigator, 'brave', {
value: {
isBrave: () => true
}
});
});
await page.goto(localHtml);
// @ts-ignore
let uap = await page.evaluate(() => UAParser());
expect(uap).toHaveProperty('browser.name', 'Chrome Headless');
// @ts-ignore
uap = await page.evaluate(() => UAParser().withFeatureCheck());
expect(uap).toHaveProperty('browser.name', 'Brave');
});

View File

@@ -1,342 +0,0 @@
[{
"desc": "Essential PH-1",
"ua": "Mozilla/5.0 (Linux; Android 9; PH-1 Build/PPR1.180905.036) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.86 Mobile Safari/537.36",
"expect": {
"vendor": "Essential",
"model": "PH-1",
"type": "mobile"
}
},
{
"desc": "Gigaset Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Gigaset QV830 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Gigaset",
"model": "QV830",
"type": "tablet"
}
},
{
"desc": "RCA Voyager III Tablet",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; RCT6973W43 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "RCA",
"model": "RCT6973W43",
"type": "tablet"
}
},
{
"desc": "RCA Voyager II Tablet",
"ua": "Mozilla/5.0 (Linux; Android 5.0; RCT6773W22B Build/LRX21M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "RCA",
"model": "RCT6773W22B",
"type": "tablet"
}
},
{
"desc": "Verizon Quanta Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; QMV7B Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Verizon",
"model": "QMV7B",
"type": "tablet"
}
},
{
"desc": "Verizon Ellipsis 8 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 5.1.1; QTAQZ3 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Verizon",
"model": "QTAQZ3",
"type": "tablet"
}
},
{
"desc": "Verizon Ellipsis 8HD Tablet",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; QTASUN1 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Safari/537.36",
"expect": {
"vendor": "Verizon",
"model": "QTASUN1",
"type": "tablet"
}
},
{
"desc": "Dell Venue 8 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 8 3830 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Dell",
"model": "Venue 8 3830",
"type": "tablet"
}
},
{
"desc": "Dell Venue 7 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Venue 7 3730 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Dell",
"model": "Venue 7 3730",
"type": "tablet"
}
},
{
"desc": "Barnes & Noble Nook HD+ Tablet",
"ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; Barnes & Noble Nook HD+ Build/JZO54K; CyanogenMod-10) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
"expect": {
"vendor": "Barnes & Noble",
"model": "Nook HD+",
"type": "tablet"
}
},
{
"desc": "Barnes & Noble V400 Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.0.4; BNTV400 Build/IMM76L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.111 Safari/537.36",
"expect": {
"vendor": "Barnes & Noble",
"model": "V400",
"type": "tablet"
}
},
{
"desc": "NuVision TM101A540N Tablet",
"ua": "Mozilla/5.0 (Linux; Android 5.1; TM101A540N Build/LMY47I; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/50.0.2661.86 Safari/537.36",
"expect": {
"vendor": "NuVision",
"model": "TM101A540N",
"type": "tablet"
}
},
{
"desc": "ZTE-Z431",
"ua": "ZTE-Z431/1.4.0 NetFront/4.2 QTV5.1 Profile/MIDP-2.1 Configuration/CLDC-1.1",
"expect": {
"vendor": "ZTE",
"model": "Z431",
"type": "mobile"
}
},
{
"desc": "ZTE",
"ua": "Mozilla/5.0 (Linux; U; Android 4.1.2; en-us; ZTE-Z740G Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
"expect": {
"vendor": "ZTE",
"model": "Z740G",
"type": "mobile"
}
},
{
"desc": "ZTE K Series Tablet",
"ua": "Mozilla/5.0 (Linux; Android 6.0.1; K88 Build/MMB29M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "K88",
"type": "tablet"
}
},
{
"desc": "ZTE Nubia Red Magic 3",
"ua": "Mozilla/5.0 (Linux; Android 9; NX629J Build/PKQ1.190321.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/6.2 TBS/45016 Mobile Safari/537.36 MMWEBID/4064 MicroMessenger/7.0.10.1580(0x27000A34) Process/tools NetType/WIFI Language/zh_CN ABI/arm64",
"expect": {
"vendor": "ZTE",
"model": "NX629J",
"type": "mobile"
}
},
{
"desc": "ZTE Blade A5",
"ua": "Mozilla/5.0 (Linux; Android 9; ZTE Blade A5 2019) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "Blade A5 2019",
"type": "mobile"
}
},
{
"desc": "ZTE BLADE V0730",
"ua": "Mozilla/5.0 (Linux; Android 6.0; ZTE BLADE V0730) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.116 Mobile Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "BLADE V0730",
"type": "mobile"
}
},
{
"desc": "ZTE B2017G",
"ua": "Mozilla/5.0 (Linux; Android 7.1.1; ZTE B2017G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36",
"expect": {
"vendor": "ZTE",
"model": "B2017G",
"type": "mobile"
}
},
{
"desc": "Swizz GEN610",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; GEN610 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36",
"expect": {
"vendor": "Swiss",
"model": "GEN610",
"type": "mobile"
}
},
{
"desc": "Swizz ZUR700",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; ZUR700 Build/KVT49L) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Safari/537.36",
"expect": {
"vendor": "Swiss",
"model": "ZUR700",
"type": "tablet"
}
},
{
"desc": "Zeki TB782b Tablet",
"ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-US; TB782B Build/IMM76D) AppleWebKit/534.31 (KHTML, like Gecko) UCBrowser/9.0.2.299 U3/0.8.0 Mobile Safari/534.31",
"expect": {
"vendor": "Zeki",
"model": "TB782B",
"type": "tablet"
}
},
{
"desc": "Dragon Touch Tablet",
"ua": "Mozilla/5.0 (Linux; Android 4.0.4; DT9138B Build/IMM76D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.72 Mobile Safari/537.36",
"expect": {
"vendor": "Dragon Touch",
"model": "9138B",
"type": "tablet"
}
},
{
"desc": "Insignia Tablet",
"ua": "Mozilla/5.0 (Linux; U; Android 6.0.1; NS-P08A7100 Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Insignia",
"model": "NS-P08A7100",
"type": "tablet"
}
},
{
"desc": "Voice Xtreme V75",
"ua": "Mozilla/5.0 (Linux; U; Android 4.2.1; en-us; V75 Build/JOP40D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30",
"expect": {
"vendor": "Voice",
"model": "V75",
"type": "mobile"
}
},
{
"desc": "LvTel V11",
"ua": "Mozilla/5.0 (Linux; Android 5.1.1; V11 Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Safari/537.36",
"expect": {
"vendor": "LvTel",
"model": "V11",
"type": "mobile"
}
},
{
"desc": "Envizen Tablet V100MD",
"ua": "Mozilla/5.0 (Linux; U; Android 4.1.1; en-us; V100MD Build/V100MD.20130816) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",
"expect": {
"vendor": "Envizen",
"model": "V100MD",
"type": "tablet"
}
},
{
"desc": "Rotor Tablet",
"ua": "mozilla/5.0 (linux; android 5.0.1; tu_1491 build/lrx22c) applewebkit/537.36 (khtml, like gecko) chrome/43.0.2357.93 safari/537.36",
"expect": {
"vendor": "Rotor",
"model": "1491",
"type": "tablet"
}
},
{
"desc": "MachSpeed Tablets",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; Trio 7.85 vQ Build/Trio_7.85_vQ) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36",
"expect": {
"vendor": "MachSpeed",
"model": "Trio 7.85 vQ",
"type": "tablet"
}
},
{
"desc": "Trinity Tablets",
"ua": "Mozilla/5.0 (Linux; Android 5.0.1; Trinity T101 Build/LRX22C) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Safari/537.36",
"expect": {
"vendor": "Trinity",
"model": "T101",
"type": "tablet"
}
},
{
"desc": "NextBook Next7",
"ua": "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; Next7P12 Build/IMM76I) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30",
"expect": {
"vendor": "NextBook",
"model": "Next7P12",
"type": "tablet"
}
},
{
"desc": "NextBook Tablets",
"ua": "Mozilla/5.0 (Linux; Android 5.0; NXA8QC116 Build/LRX21V) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "NextBook",
"model": "NXA8QC116",
"type": "tablet"
}
},
{
"desc": "Le Pan Tablets",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Le Pan",
"model": "TC802A",
"type": "tablet"
}
},
{
"desc": "Le Pan Tablets",
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Le Pan TC802A Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
"expect": {
"vendor": "Le Pan",
"model": "TC802A",
"type": "tablet"
}
},
{
"desc": "AT&T Radiant Core U304AA",
"ua": "Dalvik/2.1.0 (Linux; U; Android 9; U304AA Build/P00610)",
"expect": {
"vendor": "AT&T",
"model": "U304AA",
"type": "mobile"
}
},
{
"desc": "Vodafone Smart Tab 4G",
"ua": "Mozilla/5.0 (Linux; Android 4.4.4; Vodafone Smart Tab 4G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36",
"expect": {
"vendor": "Vodafone",
"model": "Smart Tab 4G",
"type": "tablet"
}
},
{
"desc": "Vodafone Smart ultra 6",
"ua": "Mozilla/5.0 (Linux; Android 5.0.2; Vodafone Smart ultra 6 Build/LRX22G) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.133 Mobile Safari/537.36",
"expect": {
"vendor": "Vodafone",
"model": "Smart ultra 6",
"type": "tablet"
}
},
{
"desc": "4ife 4K Smart TV Box",
"ua": "Mozilla/5.0 (Linux; Android 4.4.2; 4ife 4K Smart TV Box Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36 Vinebre",
"expect": {
"vendor": "undefined",
"model": "undefined",
"type": "smarttv"
}
}]

168
test/test.js Normal file

File diff suppressed because one or more lines are too long