mirror of
https://github.com/faisalman/ua-parser-js.git
synced 2025-09-27 16:08:47 +03:00
Compare commits
30 Commits
2.0.4-pro-
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
3ea5721e86 | ||
|
a4342b01d4 | ||
|
31bf36c36d | ||
|
9bef871e41 | ||
|
b1d9dcafcd | ||
|
146f182533 | ||
|
ce242a362f | ||
|
2078b1ec92 | ||
|
7dcbb8def3 | ||
|
f810a6d1d9 | ||
|
0e05332609 | ||
|
48a1f34c28 | ||
|
fb1ed5cf6b | ||
|
3e65196b57 | ||
|
4e421e72fe | ||
|
98cf19c8c5 | ||
|
c9badeb345 | ||
|
9003fe5724 | ||
|
975c4860f4 | ||
|
647b6232bd | ||
|
95485f7b5d | ||
|
74ef71cf63 | ||
|
9e6dff6dc3 | ||
|
bf5155ec8a | ||
|
ecbc0336b6 | ||
|
ab299a23b7 | ||
|
3fe137e533 | ||
|
0bb6e24837 | ||
|
a19977ce4c | ||
|
088383b9bd |
39
CHANGELOG.md
39
CHANGELOG.md
@ -65,6 +65,35 @@
|
||||
|
||||
---
|
||||
|
||||
## Version 2.0.5
|
||||
|
||||
- Add new browser: Zalo
|
||||
- Add new CPU arch: alpha
|
||||
- Add new device vendor: Philips
|
||||
- Improve device detection: Pico
|
||||
- Fix parsing error on pages with modified Array prototypes
|
||||
- Improve type declarations:
|
||||
- Replace `node-fetch` dependency with `undici`
|
||||
- Replace hardcoded string values with enum from `enum` submodule
|
||||
- `enums` submodule:
|
||||
- Add `Extension` enum for `extensions` submodule
|
||||
- Type declaration file now automatically generated using build script
|
||||
- Naming adjustments:
|
||||
- `Browser` => `BrowserName`
|
||||
- `CPU` => `CPUArch`
|
||||
- `Device` => `DeviceType`
|
||||
- `Vendor` => `DeviceVendor`
|
||||
- `Engine` => `EngineName`
|
||||
- `OS` => `OSName`
|
||||
- `extensions` submodule:
|
||||
- Add new crawlers:
|
||||
APIs-Google, Algolia Crawler, Algolia Crawler Renderscript, Baidu-ADS, BLEXBot, botify, Bravebot, Claude-Web, cohere-training-data-crawler, contxbot, Cotoyogi, Coveobot, CriteoBot, DeepSeekBot, DuckDuckGo-Favicons-Bot, Elastic, FirecrawlAgent, Freespoke, Google-CloudVertexBot, HuggingFace-Bot, Kagibot, Kangaroo Bot, marginalia, msnbot, OnCrawl, Replicate-Bot, RunPod-Bot, SBIntuitionsBot, SeekportBot, Siteimprove, Sogou Pic Spider, TikTokSpider, TwinAgent, v0bot, webzio, Webzio-Extended, xAI-Bot, YandexAccessibilityBot, YandexAdditionalBot, YandexAdNet, YandexBot MirrorDetector, YandexBlogs, YandexComBot, YandexFavicons, YandexImageResizer, YandexImages, YandexMarket, YandexMetrika, YandexMedia, YandexMobileBot, YandexMobileScreenShotBot, YandexNews, YandexOntoDB, YandexOntoDBAPI, YandexPartner, YandexRCA, YandexRenderResourcesBot, YandexScreenshotBot, YandexSpravBot, YandexTracker, YandexVertis, YandexVerticals, YandexVideo, YandexVideoParser, YandexWebmaster, YepBot, ZumBot
|
||||
- Add new fetchers:
|
||||
Asana, bitlybot, Blueno, BufferLinkPreviewBot, Chrome-Lighthouse, Gemini-Deep-Research, HubSpot Page Fetcher, kakaotalk-scrap, vercel-favicon-bot, vercel-screenshot-bot, vercelflags, verceltracing, YaDirectFetcher, YandexCalendar, YandexDirect, YandexDirectDyn, YandexForDomain, YandexPagechecker, YandexSearchShop, YandexSitelinks, YandexUserproxy
|
||||
- `helpers` submodule:
|
||||
- Add some crawler to `isAIBot()`:
|
||||
Bravebot, cohere-training-data-crawler, FirecrawlAgent, HuggingFace-Bot, Kangaroo Bot, PanguBot, Replicate-Bot, RunPod-Bot, TikTokSpider, Together-Bot, v0bot, xAI-Bot
|
||||
|
||||
## Version 2.0.4
|
||||
|
||||
- Add new browser: Edge WebView, Edge WebView2
|
||||
@ -240,6 +269,16 @@
|
||||
|
||||
---
|
||||
|
||||
## Version 0.7.41 / 1.0.41
|
||||
- Add new browser: Daum, Ladybird
|
||||
- Add new device vendor: HMD
|
||||
- Add new engine: LibWeb
|
||||
- Add new os: Windows IoT, Ubuntu Touch
|
||||
- Improve cpu detection: ARM, x86
|
||||
- Improve device vendor detection: Apple, Archos, Generic, Google, Honor, Huawei, Infinix, Nvidia, Lenovo, Nokia, OnePlus, Xiaomi
|
||||
- Improve device type detection: smarttv, wearables
|
||||
- Improve os detection: Linux, Symbian
|
||||
|
||||
## Version 0.7.40 / 1.0.40
|
||||
- Add new browser: 115, LibreWolf, Slimboat, Slimjet
|
||||
- Add new device: Advan, Cat, Energizer, IMO, Micromax, Smartfren
|
||||
|
615
LICENSE.md
615
LICENSE.md
@ -1,73 +1,616 @@
|
||||
# UAPARSER.JS PRO PERSONAL LICENSE
|
||||
# GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
|
||||
Version 2, July 2024
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2023-2024 Faisal Salman <f+ua-parser-js@faisalman.com>
|
||||
Copyright (C) 2007 Free Software Foundation, Inc.
|
||||
<https://fsf.org/>
|
||||
|
||||
---
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
## Definitions
|
||||
## Preamble
|
||||
|
||||
"We" are the team behind UAParser.js.
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
"You" are the individual who is responsible for purchasing this license.
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains
|
||||
free software for all its users.
|
||||
|
||||
"The Code" is UAParser.js.
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
"Project" is what you built with The Code.
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
---
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
## License
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
We retain all title, intellectual property, and ownership rights to The Code.
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing
|
||||
under this license.
|
||||
|
||||
The Code is licensed, not sold, to You for use solely subject to the terms and conditions detailed here.
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
We grant You (and only You) a personal, limited, non-exclusive, non-transferable, non-sublicensable, royalty-free right to use, copy, and modify The Code.
|
||||
## TERMS AND CONDITIONS
|
||||
|
||||
This license is only valid for You as one (1) individual and cannot be transferred to another individual or organization.
|
||||
### 0. Definitions.
|
||||
|
||||
---
|
||||
"This License" refers to version 3 of the GNU Affero General Public
|
||||
License.
|
||||
|
||||
## Rights
|
||||
"Copyright" also means copyright-like laws that apply to other kinds
|
||||
of works, such as semiconductor masks.
|
||||
|
||||
You may use and modify The Code to create as many personal, hobby, educational, and other non-profit projects as you want for yourself.
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
You may create any number of copies of The Code for yourself.
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of
|
||||
an exact copy. The resulting work is called a "modified version" of
|
||||
the earlier work or a work "based on" the earlier work.
|
||||
|
||||
You have the right to get lifetime updates and one (1) year of support, starting from the time you make the purchase.
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
---
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
## Restrictions
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user
|
||||
through a computer network, with no transfer of a copy, is not
|
||||
conveying.
|
||||
|
||||
You may not use or modify The Code in such a way that it may be used directly for commercial purposes.
|
||||
An interactive user interface displays "Appropriate Legal Notices" to
|
||||
the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
You may not redistribute The Code, as-is or modified, except as a part of a Project that you made for yourself.
|
||||
### 1. Source Code.
|
||||
|
||||
You may not deliver a Project that contains The Code as an open-source Project that might be used for commercial purposes by the general public, except with our written consent.
|
||||
The "source code" for a work means the preferred form of the work for
|
||||
making modifications to it. "Object code" means any non-source form of
|
||||
a work.
|
||||
|
||||
You may not use The Code for unlawful, inappropriate, illegal, or offensive purposes.
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
---
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
## Limitations
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Code is provided 'as is' without warranty of any kind, expressed or implied.
|
||||
The Corresponding Source need not include anything that users can
|
||||
regenerate automatically from other parts of the Corresponding Source.
|
||||
|
||||
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.
|
||||
The Corresponding Source for a work in source code form is that same
|
||||
work.
|
||||
|
||||
We reserve the right to discontinue the lifetime updates for The Code at any time, with or without notice.
|
||||
### 2. Basic Permissions.
|
||||
|
||||
We offer support only for questions within the scope of The Code's functionality or related issues at our sole discretion.
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
---
|
||||
You may make, run and propagate covered works that you do not convey,
|
||||
without conditions so long as your license otherwise remains in force.
|
||||
You may convey covered works to others for the sole purpose of having
|
||||
them make modifications exclusively for you, or provide you with
|
||||
facilities for running those works, provided that you comply with the
|
||||
terms of this License in conveying all material for which you do not
|
||||
control copyright. Those thus making or running the covered works for
|
||||
you must do so exclusively on your behalf, under your direction and
|
||||
control, on terms that prohibit them from making any copies of your
|
||||
copyrighted material outside their relationship with you.
|
||||
|
||||
## Termination
|
||||
Conveying under any other circumstances is permitted solely under the
|
||||
conditions stated below. Sublicensing is not allowed; section 10 makes
|
||||
it unnecessary.
|
||||
|
||||
This license is effective indefinitely but can be revoked at any time if there is a violation of any of the terms.
|
||||
### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
---
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such
|
||||
circumvention is effected by exercising rights under this License with
|
||||
respect to the covered work, and you disclaim any intention to limit
|
||||
operation or modification of the work as a means of enforcing, against
|
||||
the work's users, your or third parties' legal rights to forbid
|
||||
circumvention of technological measures.
|
||||
|
||||
### 4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
### 5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these
|
||||
conditions:
|
||||
|
||||
- a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
- b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under
|
||||
section 7. This requirement modifies the requirement in section 4
|
||||
to "keep intact all notices".
|
||||
- c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
- d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
### 6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms of
|
||||
sections 4 and 5, provided that you also convey the machine-readable
|
||||
Corresponding Source under the terms of this License, in one of these
|
||||
ways:
|
||||
|
||||
- a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
- b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the Corresponding
|
||||
Source from a network server at no charge.
|
||||
- c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
- d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
- e) Convey the object code using peer-to-peer transmission,
|
||||
provided you inform other peers where the object code and
|
||||
Corresponding Source of the work are being offered to the general
|
||||
public at no charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal,
|
||||
family, or household purposes, or (2) anything designed or sold for
|
||||
incorporation into a dwelling. In determining whether a product is a
|
||||
consumer product, doubtful cases shall be resolved in favor of
|
||||
coverage. For a particular product received by a particular user,
|
||||
"normally used" refers to a typical or common use of that class of
|
||||
product, regardless of the status of the particular user or of the way
|
||||
in which the particular user actually uses, or expects or is expected
|
||||
to use, the product. A product is a consumer product regardless of
|
||||
whether the product has substantial commercial, industrial or
|
||||
non-consumer uses, unless such uses represent the only significant
|
||||
mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to
|
||||
install and execute modified versions of a covered work in that User
|
||||
Product from a modified version of its Corresponding Source. The
|
||||
information must suffice to ensure that the continued functioning of
|
||||
the modified object code is in no case prevented or interfered with
|
||||
solely because modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or
|
||||
updates for a work that has been modified or installed by the
|
||||
recipient, or for the User Product in which it has been modified or
|
||||
installed. Access to a network may be denied when the modification
|
||||
itself materially and adversely affects the operation of the network
|
||||
or violates the rules and protocols for communication across the
|
||||
network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
### 7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders
|
||||
of that material) supplement the terms of this License with terms:
|
||||
|
||||
- a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
- b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
- c) Prohibiting misrepresentation of the origin of that material,
|
||||
or requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
- d) Limiting the use for publicity purposes of names of licensors
|
||||
or authors of the material; or
|
||||
- e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
- f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions
|
||||
of it) with contractual assumptions of liability to the recipient,
|
||||
for any liability that these contractual assumptions directly
|
||||
impose on those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions; the
|
||||
above requirements apply either way.
|
||||
|
||||
### 8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your license
|
||||
from a particular copyright holder is reinstated (a) provisionally,
|
||||
unless and until the copyright holder explicitly and finally
|
||||
terminates your license, and (b) permanently, if the copyright holder
|
||||
fails to notify you of the violation by some reasonable means prior to
|
||||
60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
### 9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or run
|
||||
a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
### 10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
### 11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims owned
|
||||
or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within the
|
||||
scope of its coverage, prohibits the exercise of, or is conditioned on
|
||||
the non-exercise of one or more of the rights that are specifically
|
||||
granted under this License. You may not convey a covered work if you
|
||||
are a party to an arrangement with a third party that is in the
|
||||
business of distributing software, under which you make payment to the
|
||||
third party based on the extent of your activity of conveying the
|
||||
work, and under which the third party grants, to any of the parties
|
||||
who would receive the covered work from you, a discriminatory patent
|
||||
license (a) in connection with copies of the covered work conveyed by
|
||||
you (or copies made from those copies), or (b) primarily for and in
|
||||
connection with specific products or compilations that contain the
|
||||
covered work, unless you entered into that arrangement, or that patent
|
||||
license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
### 12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under
|
||||
this License and any other pertinent obligations, then as a
|
||||
consequence you may not convey it at all. For example, if you agree to
|
||||
terms that obligate you to collect a royalty for further conveying
|
||||
from those to whom you convey the Program, the only way you could
|
||||
satisfy both those terms and this License would be to refrain entirely
|
||||
from conveying the Program.
|
||||
|
||||
### 13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your
|
||||
version supports such interaction) an opportunity to receive the
|
||||
Corresponding Source of your version by providing access to the
|
||||
Corresponding Source from a network server at no charge, through some
|
||||
standard or customary means of facilitating copying of software. This
|
||||
Corresponding Source shall include the Corresponding Source for any
|
||||
work covered by version 3 of the GNU General Public License that is
|
||||
incorporated pursuant to the following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
### 14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Affero General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever
|
||||
published by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future versions
|
||||
of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
### 15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
||||
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE
|
||||
DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
|
||||
CORRECTION.
|
||||
|
||||
### 16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
|
||||
CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
|
||||
NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR
|
||||
LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM
|
||||
TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
|
||||
PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
### 17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
279
README.md
279
README.md
@ -1,29 +1,274 @@
|
||||
# UAParser.js PRO Personal License
|
||||
[](https://uaparser.dev)
|
||||
[](https://uaparser.dev)
|
||||
[](https://uaparser.dev)
|
||||
[](https://uaparser.dev)
|
||||
|
||||
<p align="center">
|
||||
<a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/dw/ua-parser-js?color=red&logo=npm&label=NPM%20DOWNLOADS&style=for-the-badge"></a>
|
||||
<a href="https://www.jsdelivr.com/package/npm/ua-parser-js"><img src="https://img.shields.io/jsdelivr/gh/hw/faisalman/ua-parser-js?logo=jsdelivr&style=for-the-badge"></a>
|
||||
<a href="https://github.com/faisalman/ua-parser-js"><img src="https://img.shields.io/github/stars/faisalman/ua-parser-js?color=yellow&logo=github&style=for-the-badge"></a>
|
||||
<a href="https://bundlephobia.com/package/ua-parser-js@1.0.35"><img src="https://img.shields.io/bundlephobia/minzip/ua-parser-js?logo=hackthebox&logoColor=white&style=for-the-badge"/></a>
|
||||
<a href="https://github.com/faisalman/ua-parser-js/graphs/contributors"><img src="https://img.shields.io/github/contributors/faisalman/ua-parser-js?color=purple&logo=githubsponsors&style=for-the-badge"></a>
|
||||
<a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/v/ua-parser-js.svg?logo=npm&color=red&style=for-the-badge"></a>
|
||||
<a href="https://cdnjs.com/libraries/UAParser.js"><img src="https://img.shields.io/cdnjs/v/UAParser.js.svg?color=orange&style=for-the-badge"></a>
|
||||
<img src="https://img.shields.io/ossf-scorecard/github.com/faisalman/ua-parser-js?label=openssf%20scorecard&style=for-the-badge">
|
||||
<a target="_blank" href="https://discord.gg/stt86vmr"><img alt="Discord invite" src="https://dcbadge.limes.pink/api/server/https://discord.gg/stt86vmr"></a>
|
||||
</p>
|
||||
|
||||
Thank you for choosing the UAParser.js PRO Personal License.
|
||||
# UAParser.js
|
||||
|
||||
Please be aware that using this package without a valid license purchase is strictly prohibited and constitutes a violation of applicable copyright laws.
|
||||
The most comprehensive, compact, and up-to-date JavaScript library to detect user's browser, OS, CPU, and device type/model. Also detect bots, apps, and more. Runs seamlessly in the browser (client-side) or Node.js (server-side).
|
||||
|
||||
An exception applies if the package is used solely as a part of a product developed by a valid license holder, in accordance with their license terms.
|
||||
# Demo
|
||||
|
||||
If you have not yet purchased a license, you may do so at https://store.faisalman.com.
|
||||
* Live demo: https://uaparser.dev
|
||||
|
||||
# Download
|
||||
|
||||
```sh
|
||||
npm install @ua-parser-js/pro-personal
|
||||
```
|
||||
|
||||
# Documentation
|
||||
|
||||
https://docs.uaparser.dev
|
||||
* `version 1.x` : https://github.com/faisalman/ua-parser-js/tree/1.0.x#documentation
|
||||
* `version 2.x` : https://docs.uaparser.dev
|
||||
|
||||
```js
|
||||
import { UAParser } from '@ua-parser-js/pro-personal';
|
||||
```
|
||||
Before upgrading from `v0.7` / `v1.0`, please read [CHANGELOG](CHANGELOG.md) to
|
||||
see what's new & breaking.
|
||||
|
||||
# License
|
||||
# Package & Pricing
|
||||
|
||||
UAParser.js PRO Personal
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th colspan="2">Open-Source Editions</th>
|
||||
<th colspan="3">PRO / Commercial Editions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>License options</td>
|
||||
<td>MIT (v1.x)</td>
|
||||
<td>AGPL (v2.x)</td>
|
||||
<td>PRO Personal</td>
|
||||
<td>PRO Business</td>
|
||||
<td>PRO Enterprise</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Browser detection</td>
|
||||
<td><a href="#demo" title="Basic detection">⚠️</a></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CPU detection</td>
|
||||
<td><a href="#demo" title="Basic detection">⚠️</a></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Device detection</td>
|
||||
<td><a href="#demo" title="Basic detection">⚠️</a></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Engine detection</td>
|
||||
<td><a href="#demo" title="Basic detection">⚠️</a></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>OS detection</td>
|
||||
<td><a href="#demo" title="Basic detection">⚠️</a></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Bot detection</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>AI Bot detection</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Extras (Apps, Libs, Emails, Media Players, etc) detection</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Enhanced detection result</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Client Hints support</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>CommonJS support</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>ES modules support</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TypeScript declarations</td>
|
||||
<td><a href="#demo" title="Community version">⚠️</a></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>npm module available</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Direct downloads available</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Allows commercial usage</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Permissive (non-copyleft) license</td>
|
||||
<td>✅</td>
|
||||
<td><strong title="Copyleft license">❌</strong></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>No open-source obligations</td>
|
||||
<td>✅</td>
|
||||
<td><strong title="Copyleft license">❌</strong></td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unlimited end-products</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td><strong title="1 end-product per license">❌</strong></td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Unlimited deployments</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td><strong title="1 TLD or deliverable per license">❌</strong></td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>1-year product support</td>
|
||||
<td>❌</td>
|
||||
<td>❌</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Lifetime updates</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
<td>✅</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Price</td>
|
||||
<td><strong title="Pay as you want">FREE<sup>*</sup> (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/1.0.x/license.md">License</a>)</strong></td>
|
||||
<td><strong title="Pay as you want">FREE<sup>*</sup> (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/master/LICENSE.md">License</a>)</strong></td>
|
||||
<td><strong title="$14 (one-time fee)">$14 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-personal/LICENSE.md">License</a>)</strong></td>
|
||||
<td><strong title="$29 (one-time fee)">$29 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-business/LICENSE.md">License</a>)</strong></td>
|
||||
<td><strong title="$599 (one-time fee)">$599 (<a target="_blank" href="https://raw.githubusercontent.com/faisalman/ua-parser-js/pro-enterprise/LICENSE.md">License</a>)</strong></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th align="right" colspan="6">
|
||||
<h3><a target="_blank" href="https://store.faisalman.com/checkout/buy/e236ea87-9b2b-400e-9683-24367f731b35"> GET THE PRO PACKAGES 📥</a></h3>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
Copyright (c) 2023-2024 Faisal Salman <<f@faisalman.com>>
|
||||
# Development
|
||||
|
||||
## Contributors
|
||||
|
||||
Please read [CONTRIBUTING](CONTRIBUTING.md) guide first for the instruction details.
|
||||
|
||||
<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).
|
||||
|
||||
## Backers & Sponsors
|
||||
|
||||
Support the **open-source editions** of UAParser.js through one of the following options:
|
||||
|
||||
[](https://opencollective.com/ua-parser-js)
|
||||
[](https://github.com/sponsors/faisalman)
|
||||
[](https://paypal.me/faisalman)
|
||||
[](https://store.faisalman.com/buy/3d71f2f3-cf4d-473c-892a-9d4497c890be)
|
||||
|
||||
<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>
|
6
dist/ua-parser.min.js
vendored
6
dist/ua-parser.min.js
vendored
File diff suppressed because one or more lines are too long
6
dist/ua-parser.min.mjs
vendored
6
dist/ua-parser.min.mjs
vendored
File diff suppressed because one or more lines are too long
6
dist/ua-parser.pack.js
vendored
6
dist/ua-parser.pack.js
vendored
File diff suppressed because one or more lines are too long
6
dist/ua-parser.pack.mjs
vendored
6
dist/ua-parser.pack.mjs
vendored
File diff suppressed because one or more lines are too long
140
package-lock.json
generated
140
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@ua-parser-js/pro-personal",
|
||||
"version": "2.0.4",
|
||||
"name": "ua-parser-js",
|
||||
"version": "2.0.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@ua-parser-js/pro-personal",
|
||||
"version": "2.0.4",
|
||||
"name": "ua-parser-js",
|
||||
"version": "2.0.5",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@ -21,16 +21,15 @@
|
||||
"url": "https://github.com/sponsors/faisalman"
|
||||
}
|
||||
],
|
||||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"detect-europe-js": "^0.1.2",
|
||||
"is-standalone-pwa": "^0.1.1",
|
||||
"node-fetch": "^2.7.0",
|
||||
"ua-is-frozen": "^0.1.2"
|
||||
"ua-is-frozen": "^0.1.2",
|
||||
"undici": "^7.12.0"
|
||||
},
|
||||
"bin": {
|
||||
"pro-personal": "script/cli.js"
|
||||
"ua-parser-js": "script/cli.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/parser": "7.15.8",
|
||||
@ -402,23 +401,6 @@
|
||||
"integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.13.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.1.tgz",
|
||||
"integrity": "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew==",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node-fetch": {
|
||||
"version": "2.6.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.12.tgz",
|
||||
"integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/normalize-package-data": {
|
||||
"version": "2.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
|
||||
@ -519,11 +501,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@ -664,17 +641,6 @@
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
@ -753,14 +719,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-europe-js": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-europe-js/-/detect-europe-js-0.1.2.tgz",
|
||||
@ -1011,19 +969,6 @@
|
||||
"flat": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
|
||||
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
@ -1591,25 +1536,6 @@
|
||||
"node": ">=8.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/min-indent": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||
@ -1963,25 +1889,6 @@
|
||||
"node": "^10 || ^12 || >=13.7"
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"dependencies": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.x || >=6.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"encoding": "^0.1.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"encoding": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-package-data": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
|
||||
@ -2713,11 +2620,6 @@
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"node_modules/trim-newlines": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
|
||||
@ -2791,10 +2693,14 @@
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
|
||||
"node_modules/undici": {
|
||||
"version": "7.12.0",
|
||||
"resolved": "https://registry.npmjs.org/undici/-/undici-7.12.0.tgz",
|
||||
"integrity": "sha512-GrKEsc3ughskmGA9jevVlIOPMiiAHJ4OFUtaAH+NhfTUSiZ1wMPIQqQvAJUrJspFXJt3EBWgpAeoHEDVT1IBug==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.18.1"
|
||||
}
|
||||
},
|
||||
"node_modules/validate-npm-package-license": {
|
||||
"version": "3.0.4",
|
||||
@ -2806,20 +2712,6 @@
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"node_modules/whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"dependencies": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
|
11
package.json
11
package.json
@ -1,7 +1,7 @@
|
||||
{
|
||||
"title": "UAParser.js PRO Personal",
|
||||
"name": "@ua-parser-js/pro-personal",
|
||||
"version": "2.0.4",
|
||||
"title": "UAParser.js",
|
||||
"name": "ua-parser-js",
|
||||
"version": "2.0.5",
|
||||
"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",
|
||||
"keywords": [
|
||||
@ -227,8 +227,7 @@
|
||||
"detect-europe-js": "^0.1.2",
|
||||
"is-standalone-pwa": "^0.1.1",
|
||||
"ua-is-frozen": "^0.1.2",
|
||||
"node-fetch": "^2.7.0",
|
||||
"@types/node-fetch": "^2.6.12"
|
||||
"undici": "^7.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/parser": "7.15.8",
|
||||
@ -245,7 +244,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/faisalman/ua-parser-js.git"
|
||||
},
|
||||
"license": "SEE LICENSE IN LICENSE.md",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
|
@ -2,15 +2,18 @@
|
||||
/* 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 defaultReplacements = {
|
||||
mjs: [
|
||||
[/const (.+?)\s*=\s*require\(\'\.(.+)\'\)/ig, 'import $1 from \'\.$2.mjs\''],
|
||||
[/const (.+?)\s*=\s*require\(\'(.+)\'\)/ig, 'import $1 from \'$2\''],
|
||||
[/module\.exports =/ig, 'export']
|
||||
);
|
||||
]
|
||||
}
|
||||
|
||||
const generateFile = (module) => {
|
||||
let { src, dest, title, replacements } = module;
|
||||
let text = fs.readFileSync(src, 'utf-8');
|
||||
|
||||
replacements.forEach(rep => {
|
||||
text = text.replace(rep[0], rep[1]);
|
||||
});
|
||||
@ -18,42 +21,54 @@ const generateMJS = (module) => {
|
||||
console.log(`Generate ${dest}`);
|
||||
|
||||
fs.writeFileSync(dest,
|
||||
`// Generated ESM version of ${title}
|
||||
`// ${title}
|
||||
// DO NOT EDIT THIS FILE!
|
||||
// Source: /${src}
|
||||
|
||||
${text}`, 'utf-8');
|
||||
|
||||
};
|
||||
|
||||
const modules = [
|
||||
const files = [
|
||||
{
|
||||
src : 'src/main/ua-parser.js',
|
||||
dest : 'src/main/ua-parser.mjs',
|
||||
title : 'ua-parser-js',
|
||||
title : 'Generated ESM version of ua-parser-js',
|
||||
replacements : [
|
||||
[/\(func[\s\S]+strict\';/ig, ''],
|
||||
[/esversion\: 3/ig, 'esversion: 6'],
|
||||
[/\/[\/\s]+export[\s\S]+/ig,'export {UAParser};']
|
||||
[/\/[\/\s]+export[\s\S]+/ig,'export {UAParser};'],
|
||||
...defaultReplacements.mjs
|
||||
]
|
||||
},{
|
||||
},
|
||||
{
|
||||
src : 'src/enums/ua-parser-enums.js',
|
||||
dest :'src/enums/ua-parser-enums.mjs',
|
||||
title : 'ua-parser-js/enums',
|
||||
replacements : []
|
||||
title : 'Generated ESM version of ua-parser-js/enums',
|
||||
replacements : [...defaultReplacements.mjs]
|
||||
},
|
||||
{
|
||||
src : 'src/enums/ua-parser-enums.js',
|
||||
dest :'src/enums/ua-parser-enums.d.ts',
|
||||
title : 'Generated type declarations of ua-parser-js/enums',
|
||||
replacements : [
|
||||
[/(const .+) = object\.freeze\(/ig, 'export $1: Readonly<'],
|
||||
[/(const .+) =( .+;)/ig, 'export $1: typeof$2'],
|
||||
[/}\);/ig, '}>;'],
|
||||
[/module\.exports =.+/igs, '']
|
||||
]
|
||||
},
|
||||
{
|
||||
src : 'src/extensions/ua-parser-extensions.js',
|
||||
dest : 'src/extensions/ua-parser-extensions.mjs',
|
||||
title : 'ua-parser-js/extensions',
|
||||
replacements : []
|
||||
title : 'Generated ESM version of ua-parser-js/extensions',
|
||||
replacements : [...defaultReplacements.mjs]
|
||||
},
|
||||
{
|
||||
src : 'src/helpers/ua-parser-helpers.js',
|
||||
dest : 'src/helpers/ua-parser-helpers.mjs',
|
||||
title : 'ua-parser-js/helpers',
|
||||
replacements : []
|
||||
title : 'Generated ESM version of ua-parser-js/helpers',
|
||||
replacements : [...defaultReplacements.mjs]
|
||||
}
|
||||
];
|
||||
|
||||
modules.forEach(module => generateMJS(module));
|
||||
files.forEach(module => generateFile(module));
|
1095
src/enums/ua-parser-enums.d.ts
vendored
1095
src/enums/ua-parser-enums.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,13 @@
|
||||
///////////////////////////////////////////////
|
||||
/* Enums for UAParser.js v2.0.4
|
||||
/* Enums for UAParser.js v2.0.5
|
||||
https://github.com/faisalman/ua-parser-js
|
||||
Author: Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License */
|
||||
AGPLv3 License */
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
|
||||
const Browser = Object.freeze({
|
||||
const BrowserName = Object.freeze({
|
||||
'115': '115',
|
||||
'2345': '2345',
|
||||
'360': '360',
|
||||
@ -158,10 +158,15 @@ const Browser = Object.freeze({
|
||||
WEIBO: 'Weibo',
|
||||
WHALE: 'Whale',
|
||||
WOLVIC: 'Wolvic',
|
||||
YANDEX: 'Yandex'
|
||||
YANDEX: 'Yandex',
|
||||
ZALO: 'Zalo'
|
||||
|
||||
// TODO : test!
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `BrowserName` instead
|
||||
*/
|
||||
const Browser = BrowserName;
|
||||
|
||||
const BrowserType = Object.freeze({
|
||||
CRAWLER: 'crawler',
|
||||
@ -173,8 +178,9 @@ const BrowserType = Object.freeze({
|
||||
LIBRARY: 'library'
|
||||
});
|
||||
|
||||
const CPU = Object.freeze({
|
||||
const CPUArch = Object.freeze({
|
||||
'68K': '68k',
|
||||
ALPHA: 'alpha',
|
||||
ARM : 'arm',
|
||||
ARM_64: 'arm64',
|
||||
ARM_HF: 'armhf',
|
||||
@ -192,8 +198,12 @@ const CPU = Object.freeze({
|
||||
X86: 'ia32',
|
||||
X86_64: 'amd64'
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `CPUArch` instead
|
||||
*/
|
||||
const CPU = CPUArch;
|
||||
|
||||
const Device = Object.freeze({
|
||||
const DeviceType = Object.freeze({
|
||||
CONSOLE: 'console',
|
||||
DESKTOP: 'desktop',
|
||||
EMBEDDED: 'embedded',
|
||||
@ -203,8 +213,12 @@ const Device = Object.freeze({
|
||||
WEARABLE: 'wearable',
|
||||
XR: 'xr'
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `DeviceType` instead
|
||||
*/
|
||||
const Device = DeviceType;
|
||||
|
||||
const Vendor = Object.freeze({
|
||||
const DeviceVendor = Object.freeze({
|
||||
ACER: 'Acer',
|
||||
ADVAN: 'Advan',
|
||||
ALCATEL: 'Alcatel',
|
||||
@ -252,6 +266,7 @@ const Vendor = Object.freeze({
|
||||
PALM: 'Palm',
|
||||
PANASONIC: 'Panasonic',
|
||||
PEBBLE: 'Pebble',
|
||||
PHILIPS: 'Philips',
|
||||
PICO: 'Pico',
|
||||
POLYTRON: 'Polytron',
|
||||
REALME: 'Realme',
|
||||
@ -266,7 +281,7 @@ const Vendor = Object.freeze({
|
||||
SPRINT: 'Sprint',
|
||||
TCL: 'TCL',
|
||||
TECHNISAT: 'TechniSAT',
|
||||
TECNO: 'Tecno',
|
||||
TECNO: 'TECNO',
|
||||
TESLA: 'Tesla',
|
||||
ULEFONE: 'Ulefone',
|
||||
VIVO: 'Vivo',
|
||||
@ -279,8 +294,12 @@ const Vendor = Object.freeze({
|
||||
|
||||
// TODO : test!
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `DeviceVendor` instead
|
||||
*/
|
||||
const Vendor = DeviceVendor;
|
||||
|
||||
const Engine = Object.freeze({
|
||||
const EngineName = Object.freeze({
|
||||
AMAYA: 'Amaya',
|
||||
ARKWEB: 'ArkWeb',
|
||||
BLINK: 'Blink',
|
||||
@ -302,8 +321,12 @@ const Engine = Object.freeze({
|
||||
W3M: 'w3m',
|
||||
WEBKIT: 'WebKit'
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `EngineName` instead
|
||||
*/
|
||||
const Engine = EngineName;
|
||||
|
||||
const OS = Object.freeze({
|
||||
const OSName = Object.freeze({
|
||||
AIX: 'AIX',
|
||||
AMIGA_OS: 'Amiga OS',
|
||||
ANDROID: 'Android',
|
||||
@ -399,13 +422,322 @@ const OS = Object.freeze({
|
||||
|
||||
// TODO : test!
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `OSName` instead
|
||||
*/
|
||||
const OS = OSName;
|
||||
|
||||
/*////////////////////////////////
|
||||
* Enums for Extensions submodule
|
||||
*///////////////////////////////
|
||||
|
||||
const Extension = Object.freeze({
|
||||
BrowserName: {
|
||||
CLI: {
|
||||
CURL: 'curl',
|
||||
ELINKS: 'ELinks',
|
||||
HTTPIE: 'HTTPie',
|
||||
LYNX: 'Lynx',
|
||||
WGET: 'Wget'
|
||||
},
|
||||
Crawler: {
|
||||
AHREFS_BOT: 'AhrefsBot',
|
||||
AI2_BOT: 'AI2Bot',
|
||||
AIHIT_BOT: 'aiHitBot',
|
||||
ALGOLIA_CRAWLER: 'Algolia Crawler',
|
||||
APPLE_BOT: 'Applebot',
|
||||
APPLE_BOT_EXTENDED: 'Applebot-Extended',
|
||||
ASK_TEOMA: 'Teoma',
|
||||
AMAZON_BOT: 'Amazonbot',
|
||||
AMAZON_CONTXBOT: 'contxbot',
|
||||
ANTHROPIC_AI: 'anthropic-ai',
|
||||
ANTHROPIC_CLAUDE_BOT: 'ClaudeBot',
|
||||
ANTHROPIC_CLAUDE_SEARCHBOT: 'Claude-SearchBot',
|
||||
ANTHROPIC_CLAUDE_WEB: 'Claude-Web',
|
||||
ARCHIVEORG_BOT: 'archive.org_bot',
|
||||
BAIDU_ADS: 'Baidu-ADS',
|
||||
BAIDU_SPIDER: 'Baiduspider',
|
||||
BAIDU_SPIDER_ADS: 'Baiduspider-ads',
|
||||
BAIDU_SPIDER_CPRO: 'Baiduspider-cpro',
|
||||
BAIDU_SPIDER_FAVO: 'Baiduspider-favo',
|
||||
BAIDU_SPIDER_IMAGE: 'Baiduspider-image',
|
||||
BAIDU_SPIDER_NEWS: 'Baiduspider-news',
|
||||
BAIDU_SPIDER_RENDER: 'Baiduspider-render',
|
||||
BAIDU_SPIDER_VIDEO: 'Baiduspider-video',
|
||||
BLEX_BOT: 'BLEXBot',
|
||||
BOTIFY: 'botify',
|
||||
BRAVE_BOT: 'Bravebot',
|
||||
BYTEDANCE_BYTESPIDER: 'Bytespider',
|
||||
BYTEDANCE_TIKTOKSPIDER: 'TikTokSpider',
|
||||
COMMON_CRAWL_CCBOT: 'CCBot',
|
||||
COCCOC_BOT_WEB: 'coccocbot-web',
|
||||
COCCOC_BOT_IMAGE: 'coccocbot-image',
|
||||
COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',
|
||||
COTOYOGI: 'Cotoyogi',
|
||||
COVEO_BOT: 'Coveobot',
|
||||
CRITEO_BOT: 'CriteoBot',
|
||||
DATAFORSEO_BOT: 'DataForSeoBot',
|
||||
DAUM: 'Daum',
|
||||
DAUM_DAUMOA: 'Daumoa',
|
||||
DAUM_DAUMOA_IMAGE: 'Daumoa-image',
|
||||
DEEPSEEK_BOT: 'DeepSeekBot',
|
||||
DIFFBOT: 'Diffbot',
|
||||
DUCKDUCKGO_BOT: 'DuckDuckBot',
|
||||
DUCKDUCKGO_FAVICONS_BOT: 'DuckDuckGo-Favicons-Bot',
|
||||
ELASTIC: 'Elastic',
|
||||
EXALEAD_EXABOT: 'Exabot',
|
||||
FIRECRAWL_AGENT: 'FirecrawlAgent',
|
||||
FREESPOKE: 'Freespoke',
|
||||
GOOGLE_ADSBOT: 'AdsBot-Google',
|
||||
GOOGLE_ADSBOT_MOBILE: 'Adsbot-Google-Mobile',
|
||||
GOOGLE_ADSENSE: 'AdSense',
|
||||
GOOGLE_APIS: 'APIs-Google',
|
||||
GOOGLE_BOT: 'Googlebot',
|
||||
GOOGLE_BOT_IMAGE: 'Googlebot-Image',
|
||||
GOOGLE_BOT_NEWS: 'Googlebot-News',
|
||||
GOOGLE_BOT_VIDEO: 'Googlebot-Video',
|
||||
GOOGLE_CLOUDVERTEXBOT: 'Google-CloudVertexBot',
|
||||
GOOGLE_EXTENDED: 'Google-Extended',
|
||||
GOOGLE_INSPECTIONTOOL: 'Google-InspectionTool',
|
||||
GOOGLE_OTHER: 'GoogleOther',
|
||||
GOOGLE_OTHER_IMAGE: 'GoogleOther-Image',
|
||||
GOOGLE_OTHER_VIDEO: 'GoogleOther-Video',
|
||||
GOOGLE_SAFETY: 'Google-Safety',
|
||||
GOOGLE_STOREBOT: 'Storebot-Google',
|
||||
HIVE_IMAGESIFTBOT: 'ImagesiftBot',
|
||||
HUAWEI_PANGUBOT: 'PanguBot',
|
||||
HUAWEI_PETALBOT: 'PetalBot',
|
||||
HUGGINGFACE_BOT: 'HuggingFace-Bot',
|
||||
HUNTER_VELENPUBLICWEBCRAWLER: 'VelenPublicWebCrawler',
|
||||
IA_ARCHIVER: 'ia_archiver',
|
||||
IASK_BOT: 'iAskBot',
|
||||
KAGI_BOT: 'Kagibot',
|
||||
KANGAROO_BOT: 'Kangaroo Bot',
|
||||
LINE_SPIDER: 'Linespider',
|
||||
LINKEDIN_BOT: 'LinkedInBot',
|
||||
MAGPIE_CRAWLER: 'magpie-crawler',
|
||||
MARGINALIA: 'marginalia',
|
||||
META_EXTERNALAGENT: 'meta-externalagent',
|
||||
META_FACEBOOKBOT: 'FacebookBot',
|
||||
META_FACEBOOKCATALOG: 'facebookcatalog',
|
||||
META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',
|
||||
MAJESTIC_MJ12BOT: 'MJ12bot',
|
||||
MICROSOFT_BINGBOT: 'Bingbot',
|
||||
MICROSOFT_MSNBOT: 'msnbot',
|
||||
MICROSOFT_ADIDXBOT: 'adidxbot',
|
||||
MOJEEK_BOT: 'MojeekBot',
|
||||
MOZ_DOTBOT: 'DotBot',
|
||||
ONCRAWL: 'OnCrawl',
|
||||
ONESPOT_SCRAPERBOT: 'Onespot-ScraperBot',
|
||||
OPENAI_GPTBOT: 'GPTBot',
|
||||
OPENAI_SEARCH_BOT: 'OAI-SearchBot',
|
||||
PERPLEXITY_BOT: 'PerplexityBot',
|
||||
QIHOO_360_SPIDER: '360Spider',
|
||||
QWANT_BOT: 'Qwantbot',
|
||||
REPLICATE_BOT: 'Replicate-Bot',
|
||||
RUNPOD_BOT: 'RunPod-Bot',
|
||||
SB_INTUITIONS_BOT: 'SBIntuitionsBot',
|
||||
SEEKPORT_BOT: 'SeekportBot',
|
||||
SEMRUSH_BOT: 'SemrushBot',
|
||||
SEMRUSH_BOT_BACKLINK: 'SemrushBot-BA',
|
||||
SEMRUSH_BOT_CONTENTSHAKE: 'SemrushBot-OCOB',
|
||||
SEMRUSH_BOT_SEO_CHECKER: 'SemrushBot-SI',
|
||||
SEZNAM_BOT: 'SeznamBot',
|
||||
SITEIMPROVE: 'Siteimprove',
|
||||
SOGOU_PIC_SPIDER: 'Sogou Pic Spider',
|
||||
SOGOU_WEB_SPIDER: 'Sogou web spider',
|
||||
STARTPAGE: 'Startpage',
|
||||
TIMPI_BOT: 'Timpibot',
|
||||
TOGETHER_BOT: 'Together-Bot',
|
||||
TURNITIN_BOT: 'TurnitinBot',
|
||||
TWIN_AGENT: 'TwinAgent',
|
||||
VERCEL_V0BOT: 'v0bot',
|
||||
WEBZIO: 'webzio',
|
||||
WEBZIO_EXTENDED: 'Webzio-Extended',
|
||||
WEBZIO_OMGILI: 'omgili',
|
||||
WEBZIO_OMGILI_BOT: 'omgilibot',
|
||||
XAI_BOT: 'xAI-Bot',
|
||||
YAHOO_JAPAN: 'Y!J-BRW',
|
||||
YAHOO_SLURP: 'Yahoo! Slurp',
|
||||
YANDEX_ACCESSIBILITY_BOT: 'YandexAccessibilityBot',
|
||||
YANDEX_ADDITIONAL_BOT: 'YandexAdditionalBot',
|
||||
YANDEX_ADNET: 'YandexAdNet',
|
||||
YANDEX_BLOGS: 'YandexBlogs',
|
||||
YANDEX_BOT: 'YandexBot',
|
||||
YANDEX_BOT_MIRRORDETECTOR: 'YandexBot MirrorDetector',
|
||||
YANDEX_COMBOT: 'YandexComBot',
|
||||
YANDEX_FAVICONS: 'YandexFavicons',
|
||||
YANDEX_IMAGE_RESIZER: 'YandexImageResizer',
|
||||
YANDEX_IMAGES: 'YandexImages',
|
||||
YANDEX_MARKET: 'YandexMarket',
|
||||
YANDEX_MEDIA: 'YandexMedia',
|
||||
YANDEX_METRIKA: 'YandexMetrika',
|
||||
YANDEX_MOBILE_BOT: 'YandexMobileBot',
|
||||
YANDEX_MOBILE_SCREENSHOT_BOT: 'YandexMobileScreenShotBot',
|
||||
YANDEX_NEWS: 'YandexNews',
|
||||
YANDEX_ONTODB: 'YandexOntoDB',
|
||||
YANDEX_ONTODB_API: 'YandexOntoDBAPI',
|
||||
YANDEX_PARTNER: 'YandexPartner',
|
||||
YANDEX_RCA: 'YandexRCA',
|
||||
YANDEX_RENDERRESOURCES_BOT: 'YandexRenderResourcesBot',
|
||||
YANDEX_SCREENSHOT_BOT: 'YandexScreenshotBot',
|
||||
YANDEX_SPRAV_BOT: 'YandexSpravBot',
|
||||
YANDEX_TRACKER: 'YandexTracker',
|
||||
YANDEX_VERTICALS: 'YandexVerticals',
|
||||
YANDEX_VERTIS: 'YandexVertis',
|
||||
YANDEX_VIDEO: 'YandexVideo',
|
||||
YANDEX_VIDEO_PARSER: 'YandexVideoParser',
|
||||
YANDEX_WEBMASTER: 'YandexWebmaster',
|
||||
YEP_BOT: 'YepBot',
|
||||
YETI: 'Yeti',
|
||||
YISOU_SPIDER: 'YisouSpider',
|
||||
YOU_BOT: 'YouBot',
|
||||
ZHIPU_CHATGLM_SPIDER: 'ChatGLM-Spider',
|
||||
ZUM_BOT: 'ZumBot'
|
||||
},
|
||||
Email: {
|
||||
AIRMAIL: 'Airmail',
|
||||
APPLE_MAIL: 'Mail',
|
||||
BLUEMAIL: 'BlueMail',
|
||||
DAUM_MAIL: 'DaumMail',
|
||||
EVOLUTION: 'Evolution',
|
||||
EM_CLIENT: 'eM Client',
|
||||
FOXMAIL: 'Foxmail',
|
||||
KMAIL: 'KMail',
|
||||
KMAIL2: 'kmail2',
|
||||
KONTACT: 'Kontact',
|
||||
MICROSOFT_OUTLOOK: 'Microsoft Outlook',
|
||||
MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
|
||||
NAVER_MAILAPP: 'NaverMailApp',
|
||||
POLYMAIL: 'Polymail',
|
||||
PROTON_MAIL: 'ProtonMail',
|
||||
SPARK_MAIL: 'SparkDesktop',
|
||||
SPARROW: 'Sparrow',
|
||||
THUNDERBIRD: 'Thunderbird',
|
||||
YAHOO_MAIL: 'Yahoo',
|
||||
ZIMBRA: 'Zimbra',
|
||||
ZOHO_MAIL: 'ZohoMail-Desktop'
|
||||
},
|
||||
Fetcher: {
|
||||
AHREFS_SITEAUDIT: 'AhrefsSiteAudit',
|
||||
ANTHROPIC_CLAUDE_USER: 'Claude-User',
|
||||
ASANA: 'Asana',
|
||||
BETTER_UPTIME_BOT: 'Better Uptime Bot',
|
||||
BITLY_BOT: 'bitlybot',
|
||||
BLUESKY: 'Bluesky',
|
||||
BUFFER_LINKPREVIEWBOT: 'BufferLinkPreviewBot',
|
||||
COHERE_AI: 'Cohere-AI',
|
||||
DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',
|
||||
GOOGLE_CHROME_LIGHTHOUSE: 'Chrome-Lighthouse',
|
||||
GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',
|
||||
GOOGLE_GEMINI_DEEP_RESEARCH: 'Gemini-Deep-Research',
|
||||
GOOGLE_IMAGEPROXY: 'GoogleImageProxy',
|
||||
GOOGLE_PAGERENDERER: 'Google-PageRenderer',
|
||||
GOOGLE_READ_ALOUD: 'Google-Read-Aloud',
|
||||
GOOGLE_PRODUCER: 'GoogleProducer',
|
||||
GOOGLE_SITE_VERIFICATION: 'Google-Site-Verification',
|
||||
HUBSPOT_PAGE_FETCHER: 'HubSpot Page Fetcher',
|
||||
IFRAMELY: 'Iframely',
|
||||
KAKAOTALK_SCRAP: 'kakaotalk-scrap',
|
||||
META_EXTERNALFETCHER: 'meta-externalfetcher',
|
||||
META_WHATSAPP: 'WhatsApp',
|
||||
MICROSOFT_BINGPREVIEW: 'BingPreview',
|
||||
MICROSOFT_PREVIEW: 'MicrosoftPreview',
|
||||
MISTRALAI_USER: 'MistralAI-User',
|
||||
NAVER_BLUENO: 'Blueno',
|
||||
ONCRAWL_ROGERBOT: 'rogerbot',
|
||||
OPENAI_CHATGPT_USER: 'ChatGPT-User',
|
||||
PERPLEXITY_USER: 'Perplexity-User',
|
||||
PINTEREST_BOT: 'Pinterestbot',
|
||||
SEMRUSH_SITEAUDITBOT: 'SiteAuditBot',
|
||||
SNAP_URL_PREVIEW: 'Snap URL Preview',
|
||||
SKYPE_URIPREVIEW: 'SkypeUriPreview',
|
||||
TELEGRAM_BOT: 'TelegramBot',
|
||||
UPTIMEROBOT: 'UptimeRobot',
|
||||
VERCEL_FAVICON_BOT: 'vercel-favicon-bot',
|
||||
VERCEL_SCREENSHOT_BOT: 'vercel-screenshot-bot',
|
||||
VERCEL_BOT: 'Vercelbot',
|
||||
VERCEL_FLAGS: 'vercelflags',
|
||||
VERCEL_TRACING: 'verceltracing',
|
||||
YANDEX_CALENDAR: 'YandexCalendar',
|
||||
YANDEX_DIRECT: 'YandexDirect',
|
||||
YANDEX_DIRECTDYN: 'YandexDirectDyn',
|
||||
YANDEX_DIRECTFETCHER: 'YaDirectFetcher',
|
||||
YANDEX_FORDOMAIN: 'YandexForDomain',
|
||||
YANDEX_PAGECHECKER: 'YandexPagechecker',
|
||||
YANDEX_SEARCHSHOP: 'YandexSearchShop',
|
||||
YANDEX_SITELINKS: 'YandexSitelinks',
|
||||
YANDEX_USERPROXY: 'YandexUserproxy',
|
||||
ZOOMINFO_BOT: 'Zoombot'
|
||||
},
|
||||
InApp: {
|
||||
DISCORD: 'Discord',
|
||||
EVERNOTE: 'Evernote',
|
||||
FIGMA: 'Figma',
|
||||
FLIPBOARD: 'Flipboard',
|
||||
MATTERMOST: 'Mattermost',
|
||||
TEAMS: 'Teams',
|
||||
NOTION: 'Notion',
|
||||
POSTMAN: 'Postman',
|
||||
RAMBOX: 'Rambox',
|
||||
ROCKETCHAT: 'Rocket.Chat',
|
||||
SLACK: 'Slack',
|
||||
TIKTOK_LITE: 'TikTok Lite',
|
||||
VSCODE: 'VS Code',
|
||||
YAHOO_JAPAN: 'Yahoo! Japan'
|
||||
},
|
||||
Library: {
|
||||
ADOBE_AIR: 'AdobeAIR',
|
||||
AIOHTTP: 'aiohttp',
|
||||
APACHE_HTTPCLIENT: 'Apache-HttpClient',
|
||||
AXIOS: 'axios',
|
||||
GO_HTTP_CLIENT: 'go-http-client',
|
||||
GOT: 'got',
|
||||
GUZZLEHTTP: 'GuzzleHttp',
|
||||
JAVA: 'Java',
|
||||
JAVA_HTTPCLIENT: 'Java-http-client',
|
||||
JSDOM: 'jsdom',
|
||||
LIBWWW_PERL: 'libwww-perl',
|
||||
LUA_RESTY_HTTP: 'lua-resty-http',
|
||||
NEEDLE: 'Needle',
|
||||
NUTCH: 'Nutch',
|
||||
OKHTTP: 'OkHttp',
|
||||
NODE_FETCH: 'node-fetch',
|
||||
NODE_SUPERAGENT: 'node-superagent',
|
||||
PHP_SOAP: 'PHP-SOAP',
|
||||
POSTMAN_RUNTIME: 'PostmanRuntime',
|
||||
PYTHON_HTTPX: 'python-httpx',
|
||||
PYTHON_URLLIB: 'python-urllib',
|
||||
PYTHON_URLLIB3: 'python-urllib3',
|
||||
PYTHON_REQUESTS: 'python-requests',
|
||||
SCRAPY: 'Scrapy'
|
||||
}
|
||||
},
|
||||
DeviceVendor: {
|
||||
Vehicle: {
|
||||
BMW: 'BMW',
|
||||
BYD: 'BYD',
|
||||
JEEP: 'Jeep',
|
||||
RIVIAN: 'Rivian',
|
||||
TESLA: 'Tesla',
|
||||
VOLVO: 'Volvo'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
Browser,
|
||||
Browser,// deprecated
|
||||
CPU, // deprecated
|
||||
Device, // deprecated
|
||||
Vendor, // deprecated
|
||||
Engine, // deprecated
|
||||
OS, // deprecated
|
||||
BrowserName,
|
||||
BrowserType,
|
||||
CPU,
|
||||
Device,
|
||||
Vendor,
|
||||
Engine,
|
||||
OS
|
||||
CPUArch,
|
||||
DeviceType,
|
||||
DeviceVendor,
|
||||
EngineName,
|
||||
OSName,
|
||||
Extension
|
||||
};
|
@ -3,15 +3,15 @@
|
||||
// Source: /src/enums/ua-parser-enums.js
|
||||
|
||||
///////////////////////////////////////////////
|
||||
/* Enums for UAParser.js v2.0.4
|
||||
/* Enums for UAParser.js v2.0.5
|
||||
https://github.com/faisalman/ua-parser-js
|
||||
Author: Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License */
|
||||
AGPLv3 License */
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
|
||||
const Browser = Object.freeze({
|
||||
const BrowserName = Object.freeze({
|
||||
'115': '115',
|
||||
'2345': '2345',
|
||||
'360': '360',
|
||||
@ -162,10 +162,15 @@ const Browser = Object.freeze({
|
||||
WEIBO: 'Weibo',
|
||||
WHALE: 'Whale',
|
||||
WOLVIC: 'Wolvic',
|
||||
YANDEX: 'Yandex'
|
||||
YANDEX: 'Yandex',
|
||||
ZALO: 'Zalo'
|
||||
|
||||
// TODO : test!
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `BrowserName` instead
|
||||
*/
|
||||
const Browser = BrowserName;
|
||||
|
||||
const BrowserType = Object.freeze({
|
||||
CRAWLER: 'crawler',
|
||||
@ -177,8 +182,9 @@ const BrowserType = Object.freeze({
|
||||
LIBRARY: 'library'
|
||||
});
|
||||
|
||||
const CPU = Object.freeze({
|
||||
const CPUArch = Object.freeze({
|
||||
'68K': '68k',
|
||||
ALPHA: 'alpha',
|
||||
ARM : 'arm',
|
||||
ARM_64: 'arm64',
|
||||
ARM_HF: 'armhf',
|
||||
@ -196,8 +202,12 @@ const CPU = Object.freeze({
|
||||
X86: 'ia32',
|
||||
X86_64: 'amd64'
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `CPUArch` instead
|
||||
*/
|
||||
const CPU = CPUArch;
|
||||
|
||||
const Device = Object.freeze({
|
||||
const DeviceType = Object.freeze({
|
||||
CONSOLE: 'console',
|
||||
DESKTOP: 'desktop',
|
||||
EMBEDDED: 'embedded',
|
||||
@ -207,8 +217,12 @@ const Device = Object.freeze({
|
||||
WEARABLE: 'wearable',
|
||||
XR: 'xr'
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `DeviceType` instead
|
||||
*/
|
||||
const Device = DeviceType;
|
||||
|
||||
const Vendor = Object.freeze({
|
||||
const DeviceVendor = Object.freeze({
|
||||
ACER: 'Acer',
|
||||
ADVAN: 'Advan',
|
||||
ALCATEL: 'Alcatel',
|
||||
@ -256,6 +270,7 @@ const Vendor = Object.freeze({
|
||||
PALM: 'Palm',
|
||||
PANASONIC: 'Panasonic',
|
||||
PEBBLE: 'Pebble',
|
||||
PHILIPS: 'Philips',
|
||||
PICO: 'Pico',
|
||||
POLYTRON: 'Polytron',
|
||||
REALME: 'Realme',
|
||||
@ -270,7 +285,7 @@ const Vendor = Object.freeze({
|
||||
SPRINT: 'Sprint',
|
||||
TCL: 'TCL',
|
||||
TECHNISAT: 'TechniSAT',
|
||||
TECNO: 'Tecno',
|
||||
TECNO: 'TECNO',
|
||||
TESLA: 'Tesla',
|
||||
ULEFONE: 'Ulefone',
|
||||
VIVO: 'Vivo',
|
||||
@ -283,8 +298,12 @@ const Vendor = Object.freeze({
|
||||
|
||||
// TODO : test!
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `DeviceVendor` instead
|
||||
*/
|
||||
const Vendor = DeviceVendor;
|
||||
|
||||
const Engine = Object.freeze({
|
||||
const EngineName = Object.freeze({
|
||||
AMAYA: 'Amaya',
|
||||
ARKWEB: 'ArkWeb',
|
||||
BLINK: 'Blink',
|
||||
@ -306,8 +325,12 @@ const Engine = Object.freeze({
|
||||
W3M: 'w3m',
|
||||
WEBKIT: 'WebKit'
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `EngineName` instead
|
||||
*/
|
||||
const Engine = EngineName;
|
||||
|
||||
const OS = Object.freeze({
|
||||
const OSName = Object.freeze({
|
||||
AIX: 'AIX',
|
||||
AMIGA_OS: 'Amiga OS',
|
||||
ANDROID: 'Android',
|
||||
@ -403,13 +426,322 @@ const OS = Object.freeze({
|
||||
|
||||
// TODO : test!
|
||||
});
|
||||
/**
|
||||
* @deprecated Use `OSName` instead
|
||||
*/
|
||||
const OS = OSName;
|
||||
|
||||
/*////////////////////////////////
|
||||
* Enums for Extensions submodule
|
||||
*///////////////////////////////
|
||||
|
||||
const Extension = Object.freeze({
|
||||
BrowserName: {
|
||||
CLI: {
|
||||
CURL: 'curl',
|
||||
ELINKS: 'ELinks',
|
||||
HTTPIE: 'HTTPie',
|
||||
LYNX: 'Lynx',
|
||||
WGET: 'Wget'
|
||||
},
|
||||
Crawler: {
|
||||
AHREFS_BOT: 'AhrefsBot',
|
||||
AI2_BOT: 'AI2Bot',
|
||||
AIHIT_BOT: 'aiHitBot',
|
||||
ALGOLIA_CRAWLER: 'Algolia Crawler',
|
||||
APPLE_BOT: 'Applebot',
|
||||
APPLE_BOT_EXTENDED: 'Applebot-Extended',
|
||||
ASK_TEOMA: 'Teoma',
|
||||
AMAZON_BOT: 'Amazonbot',
|
||||
AMAZON_CONTXBOT: 'contxbot',
|
||||
ANTHROPIC_AI: 'anthropic-ai',
|
||||
ANTHROPIC_CLAUDE_BOT: 'ClaudeBot',
|
||||
ANTHROPIC_CLAUDE_SEARCHBOT: 'Claude-SearchBot',
|
||||
ANTHROPIC_CLAUDE_WEB: 'Claude-Web',
|
||||
ARCHIVEORG_BOT: 'archive.org_bot',
|
||||
BAIDU_ADS: 'Baidu-ADS',
|
||||
BAIDU_SPIDER: 'Baiduspider',
|
||||
BAIDU_SPIDER_ADS: 'Baiduspider-ads',
|
||||
BAIDU_SPIDER_CPRO: 'Baiduspider-cpro',
|
||||
BAIDU_SPIDER_FAVO: 'Baiduspider-favo',
|
||||
BAIDU_SPIDER_IMAGE: 'Baiduspider-image',
|
||||
BAIDU_SPIDER_NEWS: 'Baiduspider-news',
|
||||
BAIDU_SPIDER_RENDER: 'Baiduspider-render',
|
||||
BAIDU_SPIDER_VIDEO: 'Baiduspider-video',
|
||||
BLEX_BOT: 'BLEXBot',
|
||||
BOTIFY: 'botify',
|
||||
BRAVE_BOT: 'Bravebot',
|
||||
BYTEDANCE_BYTESPIDER: 'Bytespider',
|
||||
BYTEDANCE_TIKTOKSPIDER: 'TikTokSpider',
|
||||
COMMON_CRAWL_CCBOT: 'CCBot',
|
||||
COCCOC_BOT_WEB: 'coccocbot-web',
|
||||
COCCOC_BOT_IMAGE: 'coccocbot-image',
|
||||
COHERE_TRAINING_DATA_CRAWLER: 'cohere-training-data-crawler',
|
||||
COTOYOGI: 'Cotoyogi',
|
||||
COVEO_BOT: 'Coveobot',
|
||||
CRITEO_BOT: 'CriteoBot',
|
||||
DATAFORSEO_BOT: 'DataForSeoBot',
|
||||
DAUM: 'Daum',
|
||||
DAUM_DAUMOA: 'Daumoa',
|
||||
DAUM_DAUMOA_IMAGE: 'Daumoa-image',
|
||||
DEEPSEEK_BOT: 'DeepSeekBot',
|
||||
DIFFBOT: 'Diffbot',
|
||||
DUCKDUCKGO_BOT: 'DuckDuckBot',
|
||||
DUCKDUCKGO_FAVICONS_BOT: 'DuckDuckGo-Favicons-Bot',
|
||||
ELASTIC: 'Elastic',
|
||||
EXALEAD_EXABOT: 'Exabot',
|
||||
FIRECRAWL_AGENT: 'FirecrawlAgent',
|
||||
FREESPOKE: 'Freespoke',
|
||||
GOOGLE_ADSBOT: 'AdsBot-Google',
|
||||
GOOGLE_ADSBOT_MOBILE: 'Adsbot-Google-Mobile',
|
||||
GOOGLE_ADSENSE: 'AdSense',
|
||||
GOOGLE_APIS: 'APIs-Google',
|
||||
GOOGLE_BOT: 'Googlebot',
|
||||
GOOGLE_BOT_IMAGE: 'Googlebot-Image',
|
||||
GOOGLE_BOT_NEWS: 'Googlebot-News',
|
||||
GOOGLE_BOT_VIDEO: 'Googlebot-Video',
|
||||
GOOGLE_CLOUDVERTEXBOT: 'Google-CloudVertexBot',
|
||||
GOOGLE_EXTENDED: 'Google-Extended',
|
||||
GOOGLE_INSPECTIONTOOL: 'Google-InspectionTool',
|
||||
GOOGLE_OTHER: 'GoogleOther',
|
||||
GOOGLE_OTHER_IMAGE: 'GoogleOther-Image',
|
||||
GOOGLE_OTHER_VIDEO: 'GoogleOther-Video',
|
||||
GOOGLE_SAFETY: 'Google-Safety',
|
||||
GOOGLE_STOREBOT: 'Storebot-Google',
|
||||
HIVE_IMAGESIFTBOT: 'ImagesiftBot',
|
||||
HUAWEI_PANGUBOT: 'PanguBot',
|
||||
HUAWEI_PETALBOT: 'PetalBot',
|
||||
HUGGINGFACE_BOT: 'HuggingFace-Bot',
|
||||
HUNTER_VELENPUBLICWEBCRAWLER: 'VelenPublicWebCrawler',
|
||||
IA_ARCHIVER: 'ia_archiver',
|
||||
IASK_BOT: 'iAskBot',
|
||||
KAGI_BOT: 'Kagibot',
|
||||
KANGAROO_BOT: 'Kangaroo Bot',
|
||||
LINE_SPIDER: 'Linespider',
|
||||
LINKEDIN_BOT: 'LinkedInBot',
|
||||
MAGPIE_CRAWLER: 'magpie-crawler',
|
||||
MARGINALIA: 'marginalia',
|
||||
META_EXTERNALAGENT: 'meta-externalagent',
|
||||
META_FACEBOOKBOT: 'FacebookBot',
|
||||
META_FACEBOOKCATALOG: 'facebookcatalog',
|
||||
META_FACEBOOKEXTERNALHIT: 'facebookexternalhit',
|
||||
MAJESTIC_MJ12BOT: 'MJ12bot',
|
||||
MICROSOFT_BINGBOT: 'Bingbot',
|
||||
MICROSOFT_MSNBOT: 'msnbot',
|
||||
MICROSOFT_ADIDXBOT: 'adidxbot',
|
||||
MOJEEK_BOT: 'MojeekBot',
|
||||
MOZ_DOTBOT: 'DotBot',
|
||||
ONCRAWL: 'OnCrawl',
|
||||
ONESPOT_SCRAPERBOT: 'Onespot-ScraperBot',
|
||||
OPENAI_GPTBOT: 'GPTBot',
|
||||
OPENAI_SEARCH_BOT: 'OAI-SearchBot',
|
||||
PERPLEXITY_BOT: 'PerplexityBot',
|
||||
QIHOO_360_SPIDER: '360Spider',
|
||||
QWANT_BOT: 'Qwantbot',
|
||||
REPLICATE_BOT: 'Replicate-Bot',
|
||||
RUNPOD_BOT: 'RunPod-Bot',
|
||||
SB_INTUITIONS_BOT: 'SBIntuitionsBot',
|
||||
SEEKPORT_BOT: 'SeekportBot',
|
||||
SEMRUSH_BOT: 'SemrushBot',
|
||||
SEMRUSH_BOT_BACKLINK: 'SemrushBot-BA',
|
||||
SEMRUSH_BOT_CONTENTSHAKE: 'SemrushBot-OCOB',
|
||||
SEMRUSH_BOT_SEO_CHECKER: 'SemrushBot-SI',
|
||||
SEZNAM_BOT: 'SeznamBot',
|
||||
SITEIMPROVE: 'Siteimprove',
|
||||
SOGOU_PIC_SPIDER: 'Sogou Pic Spider',
|
||||
SOGOU_WEB_SPIDER: 'Sogou web spider',
|
||||
STARTPAGE: 'Startpage',
|
||||
TIMPI_BOT: 'Timpibot',
|
||||
TOGETHER_BOT: 'Together-Bot',
|
||||
TURNITIN_BOT: 'TurnitinBot',
|
||||
TWIN_AGENT: 'TwinAgent',
|
||||
VERCEL_V0BOT: 'v0bot',
|
||||
WEBZIO: 'webzio',
|
||||
WEBZIO_EXTENDED: 'Webzio-Extended',
|
||||
WEBZIO_OMGILI: 'omgili',
|
||||
WEBZIO_OMGILI_BOT: 'omgilibot',
|
||||
XAI_BOT: 'xAI-Bot',
|
||||
YAHOO_JAPAN: 'Y!J-BRW',
|
||||
YAHOO_SLURP: 'Yahoo! Slurp',
|
||||
YANDEX_ACCESSIBILITY_BOT: 'YandexAccessibilityBot',
|
||||
YANDEX_ADDITIONAL_BOT: 'YandexAdditionalBot',
|
||||
YANDEX_ADNET: 'YandexAdNet',
|
||||
YANDEX_BLOGS: 'YandexBlogs',
|
||||
YANDEX_BOT: 'YandexBot',
|
||||
YANDEX_BOT_MIRRORDETECTOR: 'YandexBot MirrorDetector',
|
||||
YANDEX_COMBOT: 'YandexComBot',
|
||||
YANDEX_FAVICONS: 'YandexFavicons',
|
||||
YANDEX_IMAGE_RESIZER: 'YandexImageResizer',
|
||||
YANDEX_IMAGES: 'YandexImages',
|
||||
YANDEX_MARKET: 'YandexMarket',
|
||||
YANDEX_MEDIA: 'YandexMedia',
|
||||
YANDEX_METRIKA: 'YandexMetrika',
|
||||
YANDEX_MOBILE_BOT: 'YandexMobileBot',
|
||||
YANDEX_MOBILE_SCREENSHOT_BOT: 'YandexMobileScreenShotBot',
|
||||
YANDEX_NEWS: 'YandexNews',
|
||||
YANDEX_ONTODB: 'YandexOntoDB',
|
||||
YANDEX_ONTODB_API: 'YandexOntoDBAPI',
|
||||
YANDEX_PARTNER: 'YandexPartner',
|
||||
YANDEX_RCA: 'YandexRCA',
|
||||
YANDEX_RENDERRESOURCES_BOT: 'YandexRenderResourcesBot',
|
||||
YANDEX_SCREENSHOT_BOT: 'YandexScreenshotBot',
|
||||
YANDEX_SPRAV_BOT: 'YandexSpravBot',
|
||||
YANDEX_TRACKER: 'YandexTracker',
|
||||
YANDEX_VERTICALS: 'YandexVerticals',
|
||||
YANDEX_VERTIS: 'YandexVertis',
|
||||
YANDEX_VIDEO: 'YandexVideo',
|
||||
YANDEX_VIDEO_PARSER: 'YandexVideoParser',
|
||||
YANDEX_WEBMASTER: 'YandexWebmaster',
|
||||
YEP_BOT: 'YepBot',
|
||||
YETI: 'Yeti',
|
||||
YISOU_SPIDER: 'YisouSpider',
|
||||
YOU_BOT: 'YouBot',
|
||||
ZHIPU_CHATGLM_SPIDER: 'ChatGLM-Spider',
|
||||
ZUM_BOT: 'ZumBot'
|
||||
},
|
||||
Email: {
|
||||
AIRMAIL: 'Airmail',
|
||||
APPLE_MAIL: 'Mail',
|
||||
BLUEMAIL: 'BlueMail',
|
||||
DAUM_MAIL: 'DaumMail',
|
||||
EVOLUTION: 'Evolution',
|
||||
EM_CLIENT: 'eM Client',
|
||||
FOXMAIL: 'Foxmail',
|
||||
KMAIL: 'KMail',
|
||||
KMAIL2: 'kmail2',
|
||||
KONTACT: 'Kontact',
|
||||
MICROSOFT_OUTLOOK: 'Microsoft Outlook',
|
||||
MICROSOFT_OUTLOOK_MAC: 'MacOutlook',
|
||||
NAVER_MAILAPP: 'NaverMailApp',
|
||||
POLYMAIL: 'Polymail',
|
||||
PROTON_MAIL: 'ProtonMail',
|
||||
SPARK_MAIL: 'SparkDesktop',
|
||||
SPARROW: 'Sparrow',
|
||||
THUNDERBIRD: 'Thunderbird',
|
||||
YAHOO_MAIL: 'Yahoo',
|
||||
ZIMBRA: 'Zimbra',
|
||||
ZOHO_MAIL: 'ZohoMail-Desktop'
|
||||
},
|
||||
Fetcher: {
|
||||
AHREFS_SITEAUDIT: 'AhrefsSiteAudit',
|
||||
ANTHROPIC_CLAUDE_USER: 'Claude-User',
|
||||
ASANA: 'Asana',
|
||||
BETTER_UPTIME_BOT: 'Better Uptime Bot',
|
||||
BITLY_BOT: 'bitlybot',
|
||||
BLUESKY: 'Bluesky',
|
||||
BUFFER_LINKPREVIEWBOT: 'BufferLinkPreviewBot',
|
||||
COHERE_AI: 'Cohere-AI',
|
||||
DUCKDUCKGO_ASSISTBOT: 'DuckAssistBot',
|
||||
GOOGLE_CHROME_LIGHTHOUSE: 'Chrome-Lighthouse',
|
||||
GOOGLE_FEEDFETCHER: 'FeedFetcher-Google',
|
||||
GOOGLE_GEMINI_DEEP_RESEARCH: 'Gemini-Deep-Research',
|
||||
GOOGLE_IMAGEPROXY: 'GoogleImageProxy',
|
||||
GOOGLE_PAGERENDERER: 'Google-PageRenderer',
|
||||
GOOGLE_READ_ALOUD: 'Google-Read-Aloud',
|
||||
GOOGLE_PRODUCER: 'GoogleProducer',
|
||||
GOOGLE_SITE_VERIFICATION: 'Google-Site-Verification',
|
||||
HUBSPOT_PAGE_FETCHER: 'HubSpot Page Fetcher',
|
||||
IFRAMELY: 'Iframely',
|
||||
KAKAOTALK_SCRAP: 'kakaotalk-scrap',
|
||||
META_EXTERNALFETCHER: 'meta-externalfetcher',
|
||||
META_WHATSAPP: 'WhatsApp',
|
||||
MICROSOFT_BINGPREVIEW: 'BingPreview',
|
||||
MICROSOFT_PREVIEW: 'MicrosoftPreview',
|
||||
MISTRALAI_USER: 'MistralAI-User',
|
||||
NAVER_BLUENO: 'Blueno',
|
||||
ONCRAWL_ROGERBOT: 'rogerbot',
|
||||
OPENAI_CHATGPT_USER: 'ChatGPT-User',
|
||||
PERPLEXITY_USER: 'Perplexity-User',
|
||||
PINTEREST_BOT: 'Pinterestbot',
|
||||
SEMRUSH_SITEAUDITBOT: 'SiteAuditBot',
|
||||
SNAP_URL_PREVIEW: 'Snap URL Preview',
|
||||
SKYPE_URIPREVIEW: 'SkypeUriPreview',
|
||||
TELEGRAM_BOT: 'TelegramBot',
|
||||
UPTIMEROBOT: 'UptimeRobot',
|
||||
VERCEL_FAVICON_BOT: 'vercel-favicon-bot',
|
||||
VERCEL_SCREENSHOT_BOT: 'vercel-screenshot-bot',
|
||||
VERCEL_BOT: 'Vercelbot',
|
||||
VERCEL_FLAGS: 'vercelflags',
|
||||
VERCEL_TRACING: 'verceltracing',
|
||||
YANDEX_CALENDAR: 'YandexCalendar',
|
||||
YANDEX_DIRECT: 'YandexDirect',
|
||||
YANDEX_DIRECTDYN: 'YandexDirectDyn',
|
||||
YANDEX_DIRECTFETCHER: 'YaDirectFetcher',
|
||||
YANDEX_FORDOMAIN: 'YandexForDomain',
|
||||
YANDEX_PAGECHECKER: 'YandexPagechecker',
|
||||
YANDEX_SEARCHSHOP: 'YandexSearchShop',
|
||||
YANDEX_SITELINKS: 'YandexSitelinks',
|
||||
YANDEX_USERPROXY: 'YandexUserproxy',
|
||||
ZOOMINFO_BOT: 'Zoombot'
|
||||
},
|
||||
InApp: {
|
||||
DISCORD: 'Discord',
|
||||
EVERNOTE: 'Evernote',
|
||||
FIGMA: 'Figma',
|
||||
FLIPBOARD: 'Flipboard',
|
||||
MATTERMOST: 'Mattermost',
|
||||
TEAMS: 'Teams',
|
||||
NOTION: 'Notion',
|
||||
POSTMAN: 'Postman',
|
||||
RAMBOX: 'Rambox',
|
||||
ROCKETCHAT: 'Rocket.Chat',
|
||||
SLACK: 'Slack',
|
||||
TIKTOK_LITE: 'TikTok Lite',
|
||||
VSCODE: 'VS Code',
|
||||
YAHOO_JAPAN: 'Yahoo! Japan'
|
||||
},
|
||||
Library: {
|
||||
ADOBE_AIR: 'AdobeAIR',
|
||||
AIOHTTP: 'aiohttp',
|
||||
APACHE_HTTPCLIENT: 'Apache-HttpClient',
|
||||
AXIOS: 'axios',
|
||||
GO_HTTP_CLIENT: 'go-http-client',
|
||||
GOT: 'got',
|
||||
GUZZLEHTTP: 'GuzzleHttp',
|
||||
JAVA: 'Java',
|
||||
JAVA_HTTPCLIENT: 'Java-http-client',
|
||||
JSDOM: 'jsdom',
|
||||
LIBWWW_PERL: 'libwww-perl',
|
||||
LUA_RESTY_HTTP: 'lua-resty-http',
|
||||
NEEDLE: 'Needle',
|
||||
NUTCH: 'Nutch',
|
||||
OKHTTP: 'OkHttp',
|
||||
NODE_FETCH: 'node-fetch',
|
||||
NODE_SUPERAGENT: 'node-superagent',
|
||||
PHP_SOAP: 'PHP-SOAP',
|
||||
POSTMAN_RUNTIME: 'PostmanRuntime',
|
||||
PYTHON_HTTPX: 'python-httpx',
|
||||
PYTHON_URLLIB: 'python-urllib',
|
||||
PYTHON_URLLIB3: 'python-urllib3',
|
||||
PYTHON_REQUESTS: 'python-requests',
|
||||
SCRAPY: 'Scrapy'
|
||||
}
|
||||
},
|
||||
DeviceVendor: {
|
||||
Vehicle: {
|
||||
BMW: 'BMW',
|
||||
BYD: 'BYD',
|
||||
JEEP: 'Jeep',
|
||||
RIVIAN: 'Rivian',
|
||||
TESLA: 'Tesla',
|
||||
VOLVO: 'Volvo'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export {
|
||||
Browser,
|
||||
Browser,// deprecated
|
||||
CPU, // deprecated
|
||||
Device, // deprecated
|
||||
Vendor, // deprecated
|
||||
Engine, // deprecated
|
||||
OS, // deprecated
|
||||
BrowserName,
|
||||
BrowserType,
|
||||
CPU,
|
||||
Device,
|
||||
Vendor,
|
||||
Engine,
|
||||
OS
|
||||
CPUArch,
|
||||
DeviceType,
|
||||
DeviceVendor,
|
||||
EngineName,
|
||||
OSName,
|
||||
Extension
|
||||
};
|
2
src/extensions/ua-parser-extensions.d.ts
vendored
2
src/extensions/ua-parser-extensions.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
// Type definitions for Helpers submodule of UAParser.js v2.0.4
|
||||
// Type definitions for Helpers submodule of UAParser.js v2.0.5
|
||||
// Project: https://github.com/faisalman/ua-parser-js
|
||||
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
///////////////////////////////////////////////
|
||||
/* Extensions for UAParser.js v2.0.4
|
||||
/* Extensions for UAParser.js v2.0.5
|
||||
https://github.com/faisalman/ua-parser-js
|
||||
Author: Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License */
|
||||
AGPLv3 License */
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
@ -43,20 +43,31 @@ const Crawlers = Object.freeze({
|
||||
// AhrefsBot - https://ahrefs.com/robot
|
||||
// Amazonbot - https://developer.amazon.com/amazonbot
|
||||
// Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
|
||||
// Bravebot - https://search.brave.com/help/brave-search-crawler
|
||||
// CCBot - https://commoncrawl.org/faq
|
||||
// contxbot - https://affiliate-program.amazon.com/help/node/topic/GT98G5PPRERNVZ2C
|
||||
// Coveobot - https://connect.coveo.com/s/article/19648
|
||||
// CriteoBot - https://www.criteo.com/criteo-crawler/
|
||||
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
|
||||
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
|
||||
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
|
||||
// GPTBot - https://platform.openai.com/docs/gptbot
|
||||
// iAskBot - https://iask.ai
|
||||
// Kagibot - https://kagi.com/bot
|
||||
// Kangaroo Bot - https://kangaroollm.com.au/kangaroo-bot/
|
||||
// LinkedInBot - http://www.linkedin.com
|
||||
// MJ12bot - https://mj12bot.com/
|
||||
// MojeekBot - https://www.mojeek.com/bot.html
|
||||
// Onespot - https://www.onespot.com/identifying-traffic.html
|
||||
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
|
||||
// PerplexityBot - https://perplexity.ai/perplexitybot
|
||||
// SBIntuitionsBot - https://www.sbintuitions.co.jp/bot/
|
||||
// SeznamBot - http://napoveda.seznam.cz/seznambot-intro
|
||||
/((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|iask|linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i,
|
||||
// YepBot - https://yep.com/yepbot/
|
||||
/((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|yep)bot)\/([\w\.-]+)/i,
|
||||
|
||||
// Algolia Crawler
|
||||
/(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
|
||||
|
||||
// Applebot - http://apple.com/go/applebot
|
||||
/(applebot(?:-extended)?)\/?([\w\.]*)/i,
|
||||
@ -65,7 +76,7 @@ const Crawlers = Object.freeze({
|
||||
/(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i,
|
||||
|
||||
// ClaudeBot (Anthropic)
|
||||
/(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i,
|
||||
/(claude(?:bot|-searchbot|-web)|anthropic-ai)\/?([\w\.]*)/i,
|
||||
|
||||
// Coc Coc Bot - https://help.coccoc.com/en/search-engine
|
||||
/(coccocbot-(?:image|web))\/([\w\.]+)/i,
|
||||
@ -83,6 +94,9 @@ const Crawlers = Object.freeze({
|
||||
// Internet Archive (archive.org)
|
||||
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
|
||||
|
||||
// OnCrawl
|
||||
/(oncrawl) mobile\/([\w\.]+)/i,
|
||||
|
||||
// Qwantbot - https://help.qwant.com/bot
|
||||
/(qwantbot)[-\w]*\/?([\w\.]*)/i,
|
||||
|
||||
@ -96,30 +110,38 @@ const Crawlers = Object.freeze({
|
||||
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
|
||||
|
||||
// Yandex Bots - https://yandex.com/bots
|
||||
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
|
||||
/(yandex(?:(?:mobile)?(?:accessibility|additional|com|renderresources|screenshot|sprav)?bot(?!.+mirror)|image(?:s|resizer)|adnet|blogs|favicons|market|media|metrika|news|ontodb(?:api)?|partner|rca|tracker|turbo|verti(?:cal)?s|webmaster|video(?:parser)?))\/([\w\.]+)/i,
|
||||
|
||||
// Yeti (Naver)
|
||||
/(yeti)\/([\w\.]+)/i,
|
||||
|
||||
// aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot
|
||||
/((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|startpageprivateimageproxy|webzio-extended|(?:chatglm-|line|screaming frog seo |yisou)spider)\/?([\w\.]*)/i
|
||||
// aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
|
||||
// Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/
|
||||
// Freespoke - https://docs.freespoke.com/search/bot/
|
||||
/((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
|
||||
],
|
||||
|
||||
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||
|
||||
[
|
||||
// YandexBot MirrorDetector
|
||||
/(yandexbot\/([\w\.]+); mirrordetector)/i
|
||||
],
|
||||
[[NAME, /\/.+;/ig, ''], VERSION, [TYPE, CRAWLER]],
|
||||
|
||||
[
|
||||
// Google Bots
|
||||
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
|
||||
|
||||
// AI2Bot - https://allenai.org/crawler
|
||||
// Bytespider
|
||||
// DataForSeoBot - https://dataforseo.com/dataforseo-bot
|
||||
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
|
||||
// ImagesiftBot - https://imagesift.com/about
|
||||
// Qihoo 360Spider
|
||||
// Siteimprove - https://help.siteimprove.com/support/solutions/articles/80000448553
|
||||
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
|
||||
// v0bot - https://vercel.com/docs/bot-management
|
||||
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
|
||||
/\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i
|
||||
// Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
|
||||
/\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
|
||||
],
|
||||
[NAME, [TYPE, CRAWLER]]
|
||||
]
|
||||
@ -234,16 +256,17 @@ const Emails = Object.freeze({
|
||||
const Fetchers = Object.freeze({
|
||||
browser : [
|
||||
[
|
||||
// Asana / Bitlybot / Better Uptime / BingPreview / Blueno / Cohere-AI / HubSpot Page Fetcher / kakaotalk-scrap / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
|
||||
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
|
||||
// Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
|
||||
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
|
||||
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
|
||||
// Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
|
||||
// Google Site Verifier / Meta / Yahoo! Japan
|
||||
// Iframely - https://iframely.com/docs/about
|
||||
// Perplexity-User - https://docs.perplexity.ai/guides/bots
|
||||
// MistralAI-User - https://docs.mistral.ai/robots/
|
||||
// Yandex Bots - https://yandex.com/bots
|
||||
/(ahrefssiteaudit|(?:bing|microsoft)preview|(?:chatgpt|mistralai|perplexity)-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|iframely|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
|
||||
/(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
|
||||
|
||||
// Bluesky
|
||||
/(bluesky) cardyb\/([\w\.]+)/i,
|
||||
@ -260,8 +283,8 @@ const Fetchers = Object.freeze({
|
||||
[NAME, VERSION, [TYPE, FETCHER]],
|
||||
|
||||
[
|
||||
// Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots
|
||||
/((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i
|
||||
// Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / Vercelbot / Yandex Bots
|
||||
/((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
|
||||
],
|
||||
[NAME, [TYPE, FETCHER]],
|
||||
],
|
||||
@ -404,8 +427,8 @@ const Vehicles = Object.freeze({
|
||||
const Bots = Object.freeze({
|
||||
browser : [
|
||||
...CLIs.browser,
|
||||
...Crawlers.browser,
|
||||
...Fetchers.browser,
|
||||
...Crawlers.browser,
|
||||
...Libraries.browser
|
||||
],
|
||||
os : [
|
||||
|
@ -3,10 +3,10 @@
|
||||
// Source: /src/extensions/ua-parser-extensions.js
|
||||
|
||||
///////////////////////////////////////////////
|
||||
/* Extensions for UAParser.js v2.0.4
|
||||
/* Extensions for UAParser.js v2.0.5
|
||||
https://github.com/faisalman/ua-parser-js
|
||||
Author: Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License */
|
||||
AGPLv3 License */
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
@ -47,20 +47,31 @@ const Crawlers = Object.freeze({
|
||||
// AhrefsBot - https://ahrefs.com/robot
|
||||
// Amazonbot - https://developer.amazon.com/amazonbot
|
||||
// Bingbot / AdIdxBot - https://www.bing.com/webmasters/help/which-crawlers-does-bing-use-8c184ec0
|
||||
// Bravebot - https://search.brave.com/help/brave-search-crawler
|
||||
// CCBot - https://commoncrawl.org/faq
|
||||
// contxbot - https://affiliate-program.amazon.com/help/node/topic/GT98G5PPRERNVZ2C
|
||||
// Coveobot - https://connect.coveo.com/s/article/19648
|
||||
// CriteoBot - https://www.criteo.com/criteo-crawler/
|
||||
// Dotbot - https://moz.com/help/moz-procedures/crawlers/dotbot
|
||||
// DuckDuckBot - http://duckduckgo.com/duckduckbot.html
|
||||
// FacebookBot - https://developers.facebook.com/docs/sharing/bot/
|
||||
// GPTBot - https://platform.openai.com/docs/gptbot
|
||||
// iAskBot - https://iask.ai
|
||||
// Kagibot - https://kagi.com/bot
|
||||
// Kangaroo Bot - https://kangaroollm.com.au/kangaroo-bot/
|
||||
// LinkedInBot - http://www.linkedin.com
|
||||
// MJ12bot - https://mj12bot.com/
|
||||
// MojeekBot - https://www.mojeek.com/bot.html
|
||||
// Onespot - https://www.onespot.com/identifying-traffic.html
|
||||
// OpenAI's SearchGPT - https://platform.openai.com/docs/bots
|
||||
// PerplexityBot - https://perplexity.ai/perplexitybot
|
||||
// SBIntuitionsBot - https://www.sbintuitions.co.jp/bot/
|
||||
// SeznamBot - http://napoveda.seznam.cz/seznambot-intro
|
||||
/((?:adidx|ahrefs|amazon|bing|cc|dot|duckduck|exa|facebook|gpt|iask|linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|semrush|seznam)bot)\/([\w\.-]+)/i,
|
||||
// YepBot - https://yep.com/yepbot/
|
||||
/((?:adidx|ahrefs|amazon|bing|brave|cc|contx|coveo|criteo|dot|duckduck(?:go-favicons-)?|exa|facebook|gpt|iask|kagi|kangaroo |linkedin|mj12|mojeek|oai-search|onespot-scraper|perplexity|sbintuitions|semrush|seznam|yep)bot)\/([\w\.-]+)/i,
|
||||
|
||||
// Algolia Crawler
|
||||
/(algolia crawler(?: renderscript)?)\/?([\w\.]*)/i,
|
||||
|
||||
// Applebot - http://apple.com/go/applebot
|
||||
/(applebot(?:-extended)?)\/?([\w\.]*)/i,
|
||||
@ -69,7 +80,7 @@ const Crawlers = Object.freeze({
|
||||
/(baiduspider[-imagevdonwsfcpr]{0,7})\/?([\w\.]*)/i,
|
||||
|
||||
// ClaudeBot (Anthropic)
|
||||
/(claude(?:bot|-web)|anthropic-ai)\/?([\w\.]*)/i,
|
||||
/(claude(?:bot|-searchbot|-web)|anthropic-ai)\/?([\w\.]*)/i,
|
||||
|
||||
// Coc Coc Bot - https://help.coccoc.com/en/search-engine
|
||||
/(coccocbot-(?:image|web))\/([\w\.]+)/i,
|
||||
@ -87,6 +98,9 @@ const Crawlers = Object.freeze({
|
||||
// Internet Archive (archive.org)
|
||||
/(ia_archiver|archive\.org_bot)\/?([\w\.]*)/i,
|
||||
|
||||
// OnCrawl
|
||||
/(oncrawl) mobile\/([\w\.]+)/i,
|
||||
|
||||
// Qwantbot - https://help.qwant.com/bot
|
||||
/(qwantbot)[-\w]*\/?([\w\.]*)/i,
|
||||
|
||||
@ -100,30 +114,38 @@ const Crawlers = Object.freeze({
|
||||
/(y!?j-(?:asr|br[uw]|dscv|mmp|vsidx|wsc))\/([\w\.]+)/i,
|
||||
|
||||
// Yandex Bots - https://yandex.com/bots
|
||||
/(yandex(?:(?:mobile)?(?:accessibility|additional|renderresources|screenshot|sprav)?bot|image(?:s|resizer)|video(?:parser)?|blogs|adnet|favicons|fordomain|market|media|metrika|news|ontodb(?:api)?|pagechecker|partner|rca|tracker|turbo|vertis|webmaster|antivirus))\/([\w\.]+)/i,
|
||||
/(yandex(?:(?:mobile)?(?:accessibility|additional|com|renderresources|screenshot|sprav)?bot(?!.+mirror)|image(?:s|resizer)|adnet|blogs|favicons|market|media|metrika|news|ontodb(?:api)?|partner|rca|tracker|turbo|verti(?:cal)?s|webmaster|video(?:parser)?))\/([\w\.]+)/i,
|
||||
|
||||
// Yeti (Naver)
|
||||
/(yeti)\/([\w\.]+)/i,
|
||||
|
||||
// aiHitBot / Diffbot / Linespider / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / VelenPublicWebCrawler / YisouSpider / YouBot
|
||||
/((?:aihit|diff|timpi|you)bot|omgili(?:bot)?|openai image downloader|(?:magpie-|velenpublicweb)crawler|startpageprivateimageproxy|webzio-extended|(?:chatglm-|line|screaming frog seo |yisou)spider)\/?([\w\.]*)/i
|
||||
// aiHitBot / Algolia Crawler / BLEXBot / Diffbot / FirecrawlAgent / HuggingFace-Bot / Linespider / MSNBot / Magpie-Crawler / Omgilibot / OpenAI Image Downloader / PanguBot / Replicate-Bot / RunPod-Bot / Webzio-Extended / Screaming Frog SEO Spider / Startpage / Timpibot / Together-Bot / VelenPublicWebCrawler / xAI-Bot / YisouSpider / YouBot / ZumBot
|
||||
// Cotoyogi - https://ds.rois.ac.jp/en_center8/en_crawler/
|
||||
// Freespoke - https://docs.freespoke.com/search/bot/
|
||||
/((?:aihit|blex|diff|huggingface-|msn|pangu|replicate-|runpod-|timpi|together-|xai-|you|zum)bot|(?:magpie-|velenpublicweb)crawler|(?:chatglm-|line|screaming frog seo |yisou)spider|cotoyogi|firecrawlagent|freespoke|omgili(?:bot)?|openai image downloader|startpageprivateimageproxy|twinagent|webzio-extended)\/?([\w\.]*)/i
|
||||
],
|
||||
|
||||
[NAME, VERSION, [TYPE, CRAWLER]],
|
||||
|
||||
[
|
||||
// YandexBot MirrorDetector
|
||||
/(yandexbot\/([\w\.]+); mirrordetector)/i
|
||||
],
|
||||
[[NAME, /\/.+;/ig, ''], VERSION, [TYPE, CRAWLER]],
|
||||
|
||||
[
|
||||
// Google Bots
|
||||
/((?:adsbot|apis|mediapartners)-google(?:-mobile)?|google-?(?:other|cloudvertexbot|extended|safety))/i,
|
||||
|
||||
// AI2Bot - https://allenai.org/crawler
|
||||
// Bytespider
|
||||
// DataForSeoBot - https://dataforseo.com/dataforseo-bot
|
||||
// Huawei AspiegelBot / PetalBot https://aspiegel.com/petalbot
|
||||
// ImagesiftBot - https://imagesift.com/about
|
||||
// Qihoo 360Spider
|
||||
// Siteimprove - https://help.siteimprove.com/support/solutions/articles/80000448553
|
||||
// TurnitinBot - https://www.turnitin.com/robot/crawlerinfo.html
|
||||
// v0bot - https://vercel.com/docs/bot-management
|
||||
// Yahoo! Slurp - http://help.yahoo.com/help/us/ysearch/slurp
|
||||
/\b(360spider-?(?:image|video)?|bytespider|(?:ai2|aspiegel|dataforseo|imagesift|petal|turnitin)bot|teoma|yahoo! slurp)/i
|
||||
// Botify / Bytespider / DeepSeekBot / Qihoo 360Spider / SeekportBot / TikTokSpider
|
||||
/\b((ai2|aspiegel|dataforseo|deepseek|imagesift|petal|seekport|turnitin|v0)bot|360spider-?(image|video)?|baidu-ads|botify|(byte|tiktok)spider|cohere-training-data-crawler|elastic(?=\/s)|marginalia|siteimprove(?=bot|\.com)|teoma|webzio|yahoo! slurp)/i
|
||||
],
|
||||
[NAME, [TYPE, CRAWLER]]
|
||||
]
|
||||
@ -238,16 +260,17 @@ const Emails = Object.freeze({
|
||||
const Fetchers = Object.freeze({
|
||||
browser : [
|
||||
[
|
||||
// Asana / Bitlybot / Better Uptime / BingPreview / Blueno / Cohere-AI / HubSpot Page Fetcher / kakaotalk-scrap / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
|
||||
// AhrefsSiteAudit - https://ahrefs.com/robot/site-audit
|
||||
// Buffer Link Preview Bot - https://scraper.buffer.com/about/bots/link-preview-bot
|
||||
// ChatGPT-User - https://platform.openai.com/docs/plugins/bot
|
||||
// DuckAssistBot - https://duckduckgo.com/duckassistbot/
|
||||
// Better Uptime / BingPreview / Mastodon / MicrosoftPreview / Pinterestbot / Redditbot / Rogerbot / SiteAuditBot / Telegrambot / Twitterbot / UptimeRobot
|
||||
// Google Site Verifier / Meta / Yahoo! Japan
|
||||
// Iframely - https://iframely.com/docs/about
|
||||
// Perplexity-User - https://docs.perplexity.ai/guides/bots
|
||||
// MistralAI-User - https://docs.mistral.ai/robots/
|
||||
// Yandex Bots - https://yandex.com/bots
|
||||
/(ahrefssiteaudit|(?:bing|microsoft)preview|(?:chatgpt|mistralai|perplexity)-user|mastodon|(?:discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero)bot|google-site-verification|iframely|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
|
||||
/(asana|ahrefssiteaudit|(?:bing|microsoft)preview|blueno|(?:chatgpt|claude|mistralai|perplexity)-user|cohere-ai|hubspot page fetcher|mastodon|(?:bitly|bufferlinkpreview|discord|duckassist|linkedin|pinterest|reddit|roger|siteaudit|twitter|uptimero|zoom)bot|google-site-verification|iframely|kakaotalk-scrap|meta-externalfetcher|y!?j-dlc|yandex(?:calendar|direct(?:dyn)?|fordomain|pagechecker|searchshop)|yadirectfetcher)\/([\w\.]+)/i,
|
||||
|
||||
// Bluesky
|
||||
/(bluesky) cardyb\/([\w\.]+)/i,
|
||||
@ -264,8 +287,8 @@ const Fetchers = Object.freeze({
|
||||
[NAME, VERSION, [TYPE, FETCHER]],
|
||||
|
||||
[
|
||||
// Google Bots / Cohere / Snapchat / Vercelbot / Yandex Bots
|
||||
/((?:better uptime |telegram|vercel)bot|cohere-ai|feedfetcher-google|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|yandex(?:sitelinks|userproxy))/i
|
||||
// Google Bots / Chrome-Lighthouse / Gemini-Deep-Research / Snapchat / Vercelbot / Yandex Bots
|
||||
/((?:better uptime |telegram|vercel)bot|chrome-lighthouse|feedfetcher-google|gemini-deep-research|google(?:imageproxy|-read-aloud|-pagerenderer|producer)|snap url preview|vercel(flags|tracing|-(favicon|screenshot)-bot)|yandex(?:sitelinks|userproxy))/i
|
||||
],
|
||||
[NAME, [TYPE, FETCHER]],
|
||||
],
|
||||
@ -408,8 +431,8 @@ const Vehicles = Object.freeze({
|
||||
const Bots = Object.freeze({
|
||||
browser : [
|
||||
...CLIs.browser,
|
||||
...Crawlers.browser,
|
||||
...Fetchers.browser,
|
||||
...Crawlers.browser,
|
||||
...Libraries.browser
|
||||
],
|
||||
os : [
|
||||
|
32
src/helpers/ua-parser-helpers.d.ts
vendored
32
src/helpers/ua-parser-helpers.d.ts
vendored
@ -1,27 +1,15 @@
|
||||
// Type definitions for Helpers submodule of UAParser.js v2.0.4
|
||||
// Type definitions for Helpers submodule of UAParser.js v2.0.5
|
||||
// Project: https://github.com/faisalman/ua-parser-js
|
||||
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
||||
|
||||
import type { IResult } from "../main/ua-parser";
|
||||
|
||||
declare function getDeviceVendor(model: string): string | undefined;
|
||||
declare function isAppleSilicon(resultOrUA: IResult | string): boolean;
|
||||
declare function isAIBot(resultOrUA: IResult | string): boolean;
|
||||
declare function isBot(resultOrUA: IResult | string): boolean;
|
||||
declare function isChromeFamily(resultOrUA: IResult | string): boolean;
|
||||
declare function isElectron(): boolean;
|
||||
declare function isFromEU(): boolean;
|
||||
declare function isFrozenUA(ua: string): boolean;
|
||||
declare function isStandalonePWA(): boolean;
|
||||
|
||||
export {
|
||||
getDeviceVendor,
|
||||
isAppleSilicon,
|
||||
isAIBot,
|
||||
isBot,
|
||||
isChromeFamily,
|
||||
isElectron,
|
||||
isFromEU,
|
||||
isFrozenUA,
|
||||
isStandalonePWA
|
||||
}
|
||||
export function getDeviceVendor(model: string): string | undefined;
|
||||
export function isAppleSilicon(resultOrUA: IResult | string): boolean;
|
||||
export function isAIBot(resultOrUA: IResult | string): boolean;
|
||||
export function isBot(resultOrUA: IResult | string): boolean;
|
||||
export function isChromeFamily(resultOrUA: IResult | string): boolean;
|
||||
export function isElectron(): boolean;
|
||||
export function isFromEU(): boolean;
|
||||
export function isFrozenUA(ua: string): boolean;
|
||||
export function isStandalonePWA(): boolean;
|
||||
|
@ -1,18 +1,19 @@
|
||||
///////////////////////////////////////////////
|
||||
/* Helpers for UAParser.js v2.0.4
|
||||
/* Helpers for UAParser.js v2.0.5
|
||||
https://github.com/faisalman/ua-parser-js
|
||||
Author: Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License */
|
||||
AGPLv3 License */
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
|
||||
const { UAParser } = require('../main/ua-parser');
|
||||
const { CPU, OS, Engine } = require('../enums/ua-parser-enums');
|
||||
const { Bots } = require('../extensions/ua-parser-extensions');
|
||||
const { CPUArch, OSName, EngineName, Extension, BrowserType } = require('../enums/ua-parser-enums');
|
||||
const { Bots, Crawlers } = require('../extensions/ua-parser-extensions');
|
||||
const { isFromEU } = require('detect-europe-js');
|
||||
const { isFrozenUA } = require('ua-is-frozen');
|
||||
const { isStandalonePWA } = require('is-standalone-pwa');
|
||||
const { Crawler } = Extension.BrowserName;
|
||||
|
||||
const toResult = (value, head, ext) => typeof value === 'string' ? UAParser(value, head, ext) : value;
|
||||
|
||||
@ -20,8 +21,8 @@ const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${m
|
||||
|
||||
const isAppleSilicon = (resultOrUA) => {
|
||||
const res = toResult(resultOrUA);
|
||||
if (res.os.is(OS.MACOS)) {
|
||||
if (res.cpu.is(CPU.ARM)) {
|
||||
if (res.os.is(OSName.MACOS)) {
|
||||
if (res.cpu.is(CPUArch.ARM)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') {
|
||||
@ -44,88 +45,129 @@ const isAppleSilicon = (resultOrUA) => {
|
||||
const isAIBot = (resultOrUA) => [
|
||||
|
||||
// AI2
|
||||
'ai2bot',
|
||||
Crawler.AI2_BOT,
|
||||
|
||||
// Amazon
|
||||
'amazonbot',
|
||||
Crawler.AMAZON_BOT,
|
||||
|
||||
// Anthropic
|
||||
'anthropic-ai',
|
||||
'claude-web',
|
||||
'claudebot',
|
||||
Crawler.ANTHROPIC_AI,
|
||||
Crawler.ANTHROPIC_CLAUDE_BOT,
|
||||
Crawler.ANTHROPIC_CLAUDE_SEARCHBOT,
|
||||
Crawler.ANTHROPIC_CLAUDE_WEB,
|
||||
|
||||
// Apple
|
||||
'applebot',
|
||||
'applebot-extended',
|
||||
Crawler.APPLE_BOT,
|
||||
Crawler.APPLE_BOT_EXTENDED,
|
||||
|
||||
// Brave
|
||||
Crawler.BRAVE_BOT,
|
||||
|
||||
// ByteDance
|
||||
'bytespider',
|
||||
Crawler.BYTEDANCE_BYTESPIDER,
|
||||
Crawler.BYTEDANCE_TIKTOKSPIDER,
|
||||
|
||||
// Cohere
|
||||
Crawler.COHERE_TRAINING_DATA_CRAWLER,
|
||||
|
||||
// Common Crawl
|
||||
'ccbot',
|
||||
Crawler.COMMON_CRAWL_CCBOT,
|
||||
|
||||
// Coveo
|
||||
Crawler.COVEO_BOT,
|
||||
|
||||
// DataForSeo
|
||||
'dataforseobot',
|
||||
Crawler.DATAFORSEO_BOT,
|
||||
|
||||
// DeepSeek
|
||||
Crawler.DEEPSEEK_BOT,
|
||||
|
||||
// Diffbot
|
||||
'diffbot',
|
||||
Crawler.DIFFBOT,
|
||||
|
||||
// Google
|
||||
'googleother',
|
||||
'googleother-image',
|
||||
'googleother-video',
|
||||
'google-extended',
|
||||
Crawler.GOOGLE_EXTENDED,
|
||||
Crawler.GOOGLE_OTHER,
|
||||
Crawler.GOOGLE_OTHER_IMAGE,
|
||||
Crawler.GOOGLE_OTHER_VIDEO,
|
||||
Crawler.GOOGLE_CLOUDVERTEXBOT,
|
||||
|
||||
// Hive AI
|
||||
'imagesiftbot',
|
||||
Crawler.HIVE_IMAGESIFTBOT,
|
||||
|
||||
// Huawei
|
||||
'petalbot',
|
||||
Crawler.HUAWEI_PETALBOT,
|
||||
Crawler.HUAWEI_PANGUBOT,
|
||||
|
||||
// Hugging Face
|
||||
Crawler.HUGGINGFACE_BOT,
|
||||
|
||||
// Kangaroo
|
||||
Crawler.KANGAROO_BOT,
|
||||
|
||||
// Mendable.ai
|
||||
Crawler.FIRECRAWL_AGENT,
|
||||
|
||||
// Meta
|
||||
'facebookbot',
|
||||
'meta-externalagent',
|
||||
Crawler.META_FACEBOOKBOT,
|
||||
Crawler.META_EXTERNALAGENT,
|
||||
|
||||
// OpenAI
|
||||
'gptbot',
|
||||
'oai-searchbot',
|
||||
Crawler.OPENAI_GPTBOT,
|
||||
Crawler.OPENAI_SEARCH_BOT,
|
||||
|
||||
// Perplexity
|
||||
'perplexitybot',
|
||||
Crawler.PERPLEXITY_BOT,
|
||||
|
||||
// Replicate
|
||||
Crawler.REPLICATE_BOT,
|
||||
|
||||
// Runpod
|
||||
Crawler.RUNPOD_BOT,
|
||||
|
||||
// SB Intuitions
|
||||
Crawler.SB_INTUITIONS_BOT,
|
||||
|
||||
// Semrush
|
||||
'semrushbot-ocob',
|
||||
Crawler.SEMRUSH_BOT_CONTENTSHAKE,
|
||||
|
||||
// Timpi
|
||||
'timpibot',
|
||||
Crawler.TIMPI_BOT,
|
||||
|
||||
// Together AI
|
||||
Crawler.TOGETHER_BOT,
|
||||
|
||||
// Velen.io
|
||||
'velenpublicwebcrawler',
|
||||
Crawler.HUNTER_VELENPUBLICWEBCRAWLER,
|
||||
|
||||
// Vercel
|
||||
Crawler.VERCEL_V0BOT,
|
||||
|
||||
// Webz.io
|
||||
'omgili',
|
||||
'omgilibot',
|
||||
'webzio-extended',
|
||||
Crawler.WEBZIO_OMGILI,
|
||||
Crawler.WEBZIO_OMGILI_BOT,
|
||||
Crawler.WEBZIO_EXTENDED,
|
||||
|
||||
// X
|
||||
Crawler.XAI_BOT,
|
||||
|
||||
// You.com
|
||||
'youbot',
|
||||
Crawler.YOU_BOT,
|
||||
|
||||
// Zhipu AI
|
||||
'chatglm-spider',
|
||||
|
||||
// Zyte
|
||||
'scrapy'
|
||||
|
||||
].includes(String(toResult(resultOrUA, Bots).browser.name).toLowerCase());
|
||||
Crawler.ZHIPU_CHATGLM_SPIDER
|
||||
]
|
||||
.map((s) => s.toLowerCase())
|
||||
.includes(String(toResult(resultOrUA, Crawlers).browser.name).toLowerCase());
|
||||
|
||||
const isBot = (resultOrUA) => [
|
||||
'cli',
|
||||
'crawler',
|
||||
'fetcher',
|
||||
'library'
|
||||
BrowserType.CLI,
|
||||
BrowserType.CRAWLER,
|
||||
BrowserType.FETCHER,
|
||||
BrowserType.LIBRARY
|
||||
].includes(toResult(resultOrUA, Bots).browser.type);
|
||||
|
||||
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(Engine.BLINK);
|
||||
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(EngineName.BLINK);
|
||||
|
||||
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
|
||||
/ electron\//i.test(navigator?.userAgent)); // browser
|
||||
|
@ -3,20 +3,21 @@
|
||||
// Source: /src/helpers/ua-parser-helpers.js
|
||||
|
||||
///////////////////////////////////////////////
|
||||
/* Helpers for UAParser.js v2.0.4
|
||||
/* Helpers for UAParser.js v2.0.5
|
||||
https://github.com/faisalman/ua-parser-js
|
||||
Author: Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License */
|
||||
AGPLv3 License */
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/*jshint esversion: 6 */
|
||||
|
||||
import { UAParser } from '../main/ua-parser.mjs';
|
||||
import { CPU, OS, Engine } from '../enums/ua-parser-enums.mjs';
|
||||
import { Bots } from '../extensions/ua-parser-extensions.mjs';
|
||||
import { CPUArch, OSName, EngineName, Extension, BrowserType } from '../enums/ua-parser-enums.mjs';
|
||||
import { Bots, Crawlers } from '../extensions/ua-parser-extensions.mjs';
|
||||
import { isFromEU } from 'detect-europe-js';
|
||||
import { isFrozenUA } from 'ua-is-frozen';
|
||||
import { isStandalonePWA } from 'is-standalone-pwa';
|
||||
const { Crawler } = Extension.BrowserName;
|
||||
|
||||
const toResult = (value, head, ext) => typeof value === 'string' ? UAParser(value, head, ext) : value;
|
||||
|
||||
@ -24,8 +25,8 @@ const getDeviceVendor = (model) => UAParser(`Mozilla/5.0 (Linux; Android 10; ${m
|
||||
|
||||
const isAppleSilicon = (resultOrUA) => {
|
||||
const res = toResult(resultOrUA);
|
||||
if (res.os.is(OS.MACOS)) {
|
||||
if (res.cpu.is(CPU.ARM)) {
|
||||
if (res.os.is(OSName.MACOS)) {
|
||||
if (res.cpu.is(CPUArch.ARM)) {
|
||||
return true;
|
||||
}
|
||||
if (typeof resultOrUA !== 'string' && typeof window !== 'undefined') {
|
||||
@ -48,88 +49,129 @@ const isAppleSilicon = (resultOrUA) => {
|
||||
const isAIBot = (resultOrUA) => [
|
||||
|
||||
// AI2
|
||||
'ai2bot',
|
||||
Crawler.AI2_BOT,
|
||||
|
||||
// Amazon
|
||||
'amazonbot',
|
||||
Crawler.AMAZON_BOT,
|
||||
|
||||
// Anthropic
|
||||
'anthropic-ai',
|
||||
'claude-web',
|
||||
'claudebot',
|
||||
Crawler.ANTHROPIC_AI,
|
||||
Crawler.ANTHROPIC_CLAUDE_BOT,
|
||||
Crawler.ANTHROPIC_CLAUDE_SEARCHBOT,
|
||||
Crawler.ANTHROPIC_CLAUDE_WEB,
|
||||
|
||||
// Apple
|
||||
'applebot',
|
||||
'applebot-extended',
|
||||
Crawler.APPLE_BOT,
|
||||
Crawler.APPLE_BOT_EXTENDED,
|
||||
|
||||
// Brave
|
||||
Crawler.BRAVE_BOT,
|
||||
|
||||
// ByteDance
|
||||
'bytespider',
|
||||
Crawler.BYTEDANCE_BYTESPIDER,
|
||||
Crawler.BYTEDANCE_TIKTOKSPIDER,
|
||||
|
||||
// Cohere
|
||||
Crawler.COHERE_TRAINING_DATA_CRAWLER,
|
||||
|
||||
// Common Crawl
|
||||
'ccbot',
|
||||
Crawler.COMMON_CRAWL_CCBOT,
|
||||
|
||||
// Coveo
|
||||
Crawler.COVEO_BOT,
|
||||
|
||||
// DataForSeo
|
||||
'dataforseobot',
|
||||
Crawler.DATAFORSEO_BOT,
|
||||
|
||||
// DeepSeek
|
||||
Crawler.DEEPSEEK_BOT,
|
||||
|
||||
// Diffbot
|
||||
'diffbot',
|
||||
Crawler.DIFFBOT,
|
||||
|
||||
// Google
|
||||
'googleother',
|
||||
'googleother-image',
|
||||
'googleother-video',
|
||||
'google-extended',
|
||||
Crawler.GOOGLE_EXTENDED,
|
||||
Crawler.GOOGLE_OTHER,
|
||||
Crawler.GOOGLE_OTHER_IMAGE,
|
||||
Crawler.GOOGLE_OTHER_VIDEO,
|
||||
Crawler.GOOGLE_CLOUDVERTEXBOT,
|
||||
|
||||
// Hive AI
|
||||
'imagesiftbot',
|
||||
Crawler.HIVE_IMAGESIFTBOT,
|
||||
|
||||
// Huawei
|
||||
'petalbot',
|
||||
Crawler.HUAWEI_PETALBOT,
|
||||
Crawler.HUAWEI_PANGUBOT,
|
||||
|
||||
// Hugging Face
|
||||
Crawler.HUGGINGFACE_BOT,
|
||||
|
||||
// Kangaroo
|
||||
Crawler.KANGAROO_BOT,
|
||||
|
||||
// Mendable.ai
|
||||
Crawler.FIRECRAWL_AGENT,
|
||||
|
||||
// Meta
|
||||
'facebookbot',
|
||||
'meta-externalagent',
|
||||
Crawler.META_FACEBOOKBOT,
|
||||
Crawler.META_EXTERNALAGENT,
|
||||
|
||||
// OpenAI
|
||||
'gptbot',
|
||||
'oai-searchbot',
|
||||
Crawler.OPENAI_GPTBOT,
|
||||
Crawler.OPENAI_SEARCH_BOT,
|
||||
|
||||
// Perplexity
|
||||
'perplexitybot',
|
||||
Crawler.PERPLEXITY_BOT,
|
||||
|
||||
// Replicate
|
||||
Crawler.REPLICATE_BOT,
|
||||
|
||||
// Runpod
|
||||
Crawler.RUNPOD_BOT,
|
||||
|
||||
// SB Intuitions
|
||||
Crawler.SB_INTUITIONS_BOT,
|
||||
|
||||
// Semrush
|
||||
'semrushbot-ocob',
|
||||
Crawler.SEMRUSH_BOT_CONTENTSHAKE,
|
||||
|
||||
// Timpi
|
||||
'timpibot',
|
||||
Crawler.TIMPI_BOT,
|
||||
|
||||
// Together AI
|
||||
Crawler.TOGETHER_BOT,
|
||||
|
||||
// Velen.io
|
||||
'velenpublicwebcrawler',
|
||||
Crawler.HUNTER_VELENPUBLICWEBCRAWLER,
|
||||
|
||||
// Vercel
|
||||
Crawler.VERCEL_V0BOT,
|
||||
|
||||
// Webz.io
|
||||
'omgili',
|
||||
'omgilibot',
|
||||
'webzio-extended',
|
||||
Crawler.WEBZIO_OMGILI,
|
||||
Crawler.WEBZIO_OMGILI_BOT,
|
||||
Crawler.WEBZIO_EXTENDED,
|
||||
|
||||
// X
|
||||
Crawler.XAI_BOT,
|
||||
|
||||
// You.com
|
||||
'youbot',
|
||||
Crawler.YOU_BOT,
|
||||
|
||||
// Zhipu AI
|
||||
'chatglm-spider',
|
||||
|
||||
// Zyte
|
||||
'scrapy'
|
||||
|
||||
].includes(String(toResult(resultOrUA, Bots).browser.name).toLowerCase());
|
||||
Crawler.ZHIPU_CHATGLM_SPIDER
|
||||
]
|
||||
.map((s) => s.toLowerCase())
|
||||
.includes(String(toResult(resultOrUA, Crawlers).browser.name).toLowerCase());
|
||||
|
||||
const isBot = (resultOrUA) => [
|
||||
'cli',
|
||||
'crawler',
|
||||
'fetcher',
|
||||
'library'
|
||||
BrowserType.CLI,
|
||||
BrowserType.CRAWLER,
|
||||
BrowserType.FETCHER,
|
||||
BrowserType.LIBRARY
|
||||
].includes(toResult(resultOrUA, Bots).browser.type);
|
||||
|
||||
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(Engine.BLINK);
|
||||
const isChromeFamily = (resultOrUA) => toResult(resultOrUA).engine.is(EngineName.BLINK);
|
||||
|
||||
const isElectron = () => !!(process?.versions?.hasOwnProperty('electron') || // node.js
|
||||
/ electron\//i.test(navigator?.userAgent)); // browser
|
||||
|
16
src/main/ua-parser.d.ts
vendored
16
src/main/ua-parser.d.ts
vendored
@ -1,9 +1,9 @@
|
||||
// Type definitions for UAParser.js v2.0.4
|
||||
// Type definitions for UAParser.js v2.0.5
|
||||
// Project: https://github.com/faisalman/ua-parser-js
|
||||
// Definitions by: Faisal Salman <https://github.com/faisalman>
|
||||
|
||||
import type { IncomingHttpHeaders } from 'http';
|
||||
import type { Headers as FetchAPIHeaders } from 'node-fetch';
|
||||
import type { Headers } from "undici";
|
||||
import { BrowserType, CPUArch, DeviceType, EngineName } from "../enums/ua-parser-enums";
|
||||
|
||||
declare namespace UAParser {
|
||||
|
||||
@ -18,21 +18,21 @@ declare namespace UAParser {
|
||||
name?: string;
|
||||
version?: string;
|
||||
major?: string;
|
||||
type?: 'crawler' | 'cli' | 'email' | 'fetcher' | 'inapp' | 'mediaplayer' | 'library';
|
||||
type?: typeof BrowserType[keyof typeof BrowserType];
|
||||
}
|
||||
|
||||
interface ICPU extends IData<ICPU> {
|
||||
architecture?: 'ia32' | 'ia64' | 'amd64' | 'arm' | 'arm64' | 'armhf' | 'avr' | 'avr32' | 'irix' | 'irix64' | 'mips' | 'mips64' | '68k' | 'pa-risc' | 'ppc' | 'sparc' | 'sparc64';
|
||||
architecture?: typeof CPUArch[keyof typeof CPUArch];
|
||||
}
|
||||
|
||||
interface IDevice extends IData<IDevice> {
|
||||
type?: 'mobile' | 'tablet' | 'console' | 'smarttv' | 'wearable' | 'xr' | 'embedded';
|
||||
type?: typeof DeviceType[keyof typeof DeviceType];
|
||||
vendor?: string;
|
||||
model?: string;
|
||||
}
|
||||
|
||||
interface IEngine extends IData<IEngine> {
|
||||
name?: 'Amaya' | 'ArkWeb' | 'Blink' | 'EdgeHTML' | 'Flow' | 'Gecko' | 'Goanna' | 'iCab' | 'KHTML' | 'LibWeb' | 'Links' | 'Lynx' | 'NetFront' | 'NetSurf' | 'Presto' | 'Servo' | 'Tasman' | 'Trident' | 'w3m' | 'WebKit';
|
||||
name?: typeof EngineName[keyof typeof EngineName];
|
||||
version?: string;
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ declare namespace UAParser {
|
||||
type RegexMap = ((RegExp | string | (string | RegExp | Function)[])[])[];
|
||||
type UAParserProps = 'browser' | 'cpu' | 'device' | 'engine' | 'os';
|
||||
type UAParserExt = Partial<Record<UAParserProps, RegexMap>> | Partial<Record<UAParserProps, RegexMap>>[];
|
||||
type UAParserHeaders = Record<string, string> | IncomingHttpHeaders | FetchAPIHeaders;
|
||||
export type UAParserHeaders = Record<string, string | string[] | undefined> | Headers;
|
||||
|
||||
export function UAParser(uastring?: string, extensions?: UAParserExt, headers?: UAParserHeaders): IResult;
|
||||
export function UAParser(uastring?: string, headers?: UAParserHeaders): IResult;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/* UAParser.js v2.0.4
|
||||
/* UAParser.js v2.0.5
|
||||
Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License *//*
|
||||
AGPLv3 License *//*
|
||||
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
||||
Supports browser & node.js environment.
|
||||
Demo : https://uaparser.dev
|
||||
@ -19,7 +19,7 @@
|
||||
// Constants
|
||||
/////////////
|
||||
|
||||
var LIBVERSION = '2.0.4',
|
||||
var LIBVERSION = '2.0.5',
|
||||
UA_MAX_LENGTH = 500,
|
||||
USER_AGENT = 'user-agent',
|
||||
EMPTY = '',
|
||||
@ -188,6 +188,8 @@
|
||||
},
|
||||
setProps = function (arr) {
|
||||
for (var i in arr) {
|
||||
if (!arr.hasOwnProperty(i)) continue;
|
||||
|
||||
var propName = arr[i];
|
||||
if (typeof propName == OBJ_TYPE && propName.length == 2) {
|
||||
this[propName[0]] = propName[1];
|
||||
@ -455,6 +457,8 @@
|
||||
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
|
||||
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
||||
], [NAME, [TYPE, INAPP]], [
|
||||
/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
|
||||
], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
|
||||
|
||||
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
|
||||
], [NAME, VERSION], [
|
||||
@ -536,15 +540,15 @@
|
||||
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
|
||||
], [[ARCHITECTURE, 'arm']], [
|
||||
|
||||
/((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
|
||||
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
||||
|
||||
/ sun4\w[;\)]/i // SPARC
|
||||
], [[ARCHITECTURE, 'sparc']], [
|
||||
|
||||
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
|
||||
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
|
||||
], [[ARCHITECTURE, lowerize]]
|
||||
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
|
||||
/((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
|
||||
/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
|
||||
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
||||
/winnt.+\[axp/i
|
||||
], [[ARCHITECTURE, 'alpha']]
|
||||
],
|
||||
|
||||
device : [[
|
||||
@ -768,7 +772,8 @@
|
||||
/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL
|
||||
/(hp) ([\w ]+\w)/i, // HP iPAQ
|
||||
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
|
||||
/(oppo) ?([\w ]+) bui/i // OPPO
|
||||
/(oppo) ?([\w ]+) bui/i, // OPPO
|
||||
/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i // Philips
|
||||
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
||||
|
||||
/(kobo)\s(ereader|touch)/i, // Kobo
|
||||
@ -795,6 +800,7 @@
|
||||
// SMARTTVS
|
||||
///////////////////
|
||||
|
||||
/(philips)[\w ]+tv/i, // Philips
|
||||
/smart-tv.+(samsung)/i // Samsung
|
||||
], [VENDOR, [TYPE, SMARTTV]], [
|
||||
/hbbtv.+maple;(\d+)/i
|
||||
@ -832,11 +838,6 @@
|
||||
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
|
||||
/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
|
||||
], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
|
||||
// SmartTV from Unidentified Vendors
|
||||
/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i
|
||||
], [MODEL, [TYPE, SMARTTV]], [
|
||||
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i
|
||||
], [[TYPE, SMARTTV]], [
|
||||
|
||||
///////////////////
|
||||
// CONSOLES
|
||||
@ -883,7 +884,7 @@
|
||||
|
||||
/droid.+; (glass) \d/i // Google Glass
|
||||
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
||||
/(pico) (4|neo3(?: link|pro)?)/i // Pico
|
||||
/(pico) ([\w ]+) os\d/i // Pico
|
||||
], [VENDOR, MODEL, [TYPE, XR]], [
|
||||
/(quest( \d| pro)?s?).+vr/i // Meta Quest
|
||||
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
||||
@ -907,6 +908,10 @@
|
||||
// MIXED (GENERIC)
|
||||
///////////////////
|
||||
|
||||
/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i // Unidentifiable SmartTV
|
||||
], [MODEL, [TYPE, SMARTTV]], [
|
||||
/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
|
||||
], [[TYPE, SMARTTV]], [
|
||||
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i
|
||||
], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
|
||||
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
|
||||
@ -1263,7 +1268,7 @@
|
||||
case UA_ENGINE:
|
||||
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
|
||||
if (brands) {
|
||||
for (var i in brands) {
|
||||
for (var i=0; i<brands.length; i++) {
|
||||
var brandName = brands[i].brand || brands[i],
|
||||
brandVersion = brands[i].version;
|
||||
if (this.itemType == UA_BROWSER &&
|
||||
@ -1385,11 +1390,22 @@
|
||||
extensions = undefined;
|
||||
}
|
||||
|
||||
// Convert Headers object into a plain object
|
||||
if (headers && typeof headers.append === FUNC_TYPE) {
|
||||
var kv = {};
|
||||
headers.forEach(function (v, k) { kv[k] = v; });
|
||||
headers = kv;
|
||||
if (headers) {
|
||||
if (typeof headers.append === FUNC_TYPE) {
|
||||
// Convert Headers object into a plain object
|
||||
var kv = {};
|
||||
headers.forEach(function (v, k) { kv[String(k).toLowerCase()] = v; });
|
||||
headers = kv;
|
||||
} else {
|
||||
// Normalize headers field name into lowercase
|
||||
var normalized = {};
|
||||
for (var header in headers) {
|
||||
if (headers.hasOwnProperty(header)) {
|
||||
normalized[String(header).toLowerCase()] = headers[header];
|
||||
}
|
||||
}
|
||||
headers = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(this instanceof UAParser)) {
|
||||
|
@ -3,9 +3,9 @@
|
||||
// Source: /src/main/ua-parser.js
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
/* UAParser.js v2.0.4
|
||||
/* UAParser.js v2.0.5
|
||||
Copyright © 2012-2025 Faisal Salman <f@faisalman.com>
|
||||
UAParser.js PRO Personal License *//*
|
||||
AGPLv3 License *//*
|
||||
Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.
|
||||
Supports browser & node.js environment.
|
||||
Demo : https://uaparser.dev
|
||||
@ -21,7 +21,7 @@
|
||||
// Constants
|
||||
/////////////
|
||||
|
||||
var LIBVERSION = '2.0.4',
|
||||
var LIBVERSION = '2.0.5',
|
||||
UA_MAX_LENGTH = 500,
|
||||
USER_AGENT = 'user-agent',
|
||||
EMPTY = '',
|
||||
@ -190,6 +190,8 @@
|
||||
},
|
||||
setProps = function (arr) {
|
||||
for (var i in arr) {
|
||||
if (!arr.hasOwnProperty(i)) continue;
|
||||
|
||||
var propName = arr[i];
|
||||
if (typeof propName == OBJ_TYPE && propName.length == 2) {
|
||||
this[propName[0]] = propName[1];
|
||||
@ -457,6 +459,8 @@
|
||||
], [VERSION, [NAME, 'TikTok'], [TYPE, INAPP]], [
|
||||
/\[(linkedin)app\]/i // LinkedIn App for iOS & Android
|
||||
], [NAME, [TYPE, INAPP]], [
|
||||
/(zalo(?:app)?)[\/\sa-z]*([\w\.-]+)/i // Zalo
|
||||
], [[NAME, /(.+)/, 'Zalo'], VERSION, [TYPE, INAPP]], [
|
||||
|
||||
/(chromium)[\/ ]([-\w\.]+)/i // Chromium
|
||||
], [NAME, VERSION], [
|
||||
@ -538,15 +542,15 @@
|
||||
/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i
|
||||
], [[ARCHITECTURE, 'arm']], [
|
||||
|
||||
/((ppc|powerpc)(64)?)( mac|;|\))/i // PowerPC
|
||||
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
||||
|
||||
/ sun4\w[;\)]/i // SPARC
|
||||
], [[ARCHITECTURE, 'sparc']], [
|
||||
|
||||
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i
|
||||
// IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC
|
||||
], [[ARCHITECTURE, lowerize]]
|
||||
/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i,
|
||||
/((ppc|powerpc)(64)?)( mac|;|\))/i, // PowerPC
|
||||
/(?:osf1|[freopnt]{3,4}bsd) (alpha)/i // Alpha
|
||||
], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [
|
||||
/winnt.+\[axp/i
|
||||
], [[ARCHITECTURE, 'alpha']]
|
||||
],
|
||||
|
||||
device : [[
|
||||
@ -770,7 +774,8 @@
|
||||
/; (blu|hmd|imo|infinix|lava|oneplus|tcl)[_ ]([\w\+ ]+?)(?: bui|\)|; r)/i, // BLU/HMD/IMO/Infinix/Lava/OnePlus/TCL
|
||||
/(hp) ([\w ]+\w)/i, // HP iPAQ
|
||||
/(microsoft); (lumia[\w ]+)/i, // Microsoft Lumia
|
||||
/(oppo) ?([\w ]+) bui/i // OPPO
|
||||
/(oppo) ?([\w ]+) bui/i, // OPPO
|
||||
/droid[^;]+; (philips)[_ ]([sv-x][\d]{3,4}[xz]?)/i // Philips
|
||||
], [VENDOR, MODEL, [TYPE, MOBILE]], [
|
||||
|
||||
/(kobo)\s(ereader|touch)/i, // Kobo
|
||||
@ -797,6 +802,7 @@
|
||||
// SMARTTVS
|
||||
///////////////////
|
||||
|
||||
/(philips)[\w ]+tv/i, // Philips
|
||||
/smart-tv.+(samsung)/i // Samsung
|
||||
], [VENDOR, [TYPE, SMARTTV]], [
|
||||
/hbbtv.+maple;(\d+)/i
|
||||
@ -834,11 +840,6 @@
|
||||
/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, // Roku
|
||||
/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i // HbbTV devices
|
||||
], [[VENDOR, /.+\/(\w+)/, '$1', strMapper, {'LG':'lge'}], [MODEL, trim], [TYPE, SMARTTV]], [
|
||||
// SmartTV from Unidentified Vendors
|
||||
/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i
|
||||
], [MODEL, [TYPE, SMARTTV]], [
|
||||
/\b(android tv|smart[- ]?tv|opera tv|tv; rv:|large screen[\w ]+safari)\b/i
|
||||
], [[TYPE, SMARTTV]], [
|
||||
|
||||
///////////////////
|
||||
// CONSOLES
|
||||
@ -885,7 +886,7 @@
|
||||
|
||||
/droid.+; (glass) \d/i // Google Glass
|
||||
], [MODEL, [VENDOR, GOOGLE], [TYPE, XR]], [
|
||||
/(pico) (4|neo3(?: link|pro)?)/i // Pico
|
||||
/(pico) ([\w ]+) os\d/i // Pico
|
||||
], [VENDOR, MODEL, [TYPE, XR]], [
|
||||
/(quest( \d| pro)?s?).+vr/i // Meta Quest
|
||||
], [MODEL, [VENDOR, FACEBOOK], [TYPE, XR]], [
|
||||
@ -909,6 +910,10 @@
|
||||
// MIXED (GENERIC)
|
||||
///////////////////
|
||||
|
||||
/droid.+; ([\w- ]+) (4k|android|smart|google)[- ]?tv/i // Unidentifiable SmartTV
|
||||
], [MODEL, [TYPE, SMARTTV]], [
|
||||
/\b((4k|android|smart|opera)[- ]?tv|tv; rv:|large screen[\w ]+safari)\b/i
|
||||
], [[TYPE, SMARTTV]], [
|
||||
/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+?(mobile|vr|\d) safari/i
|
||||
], [MODEL, [TYPE, strMapper, { 'mobile' : 'Mobile', 'xr' : 'VR', '*' : TABLET }]], [
|
||||
/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i // Unidentifiable Tablet
|
||||
@ -1265,7 +1270,7 @@
|
||||
case UA_ENGINE:
|
||||
var brands = uaCH[FULLVERLIST] || uaCH[BRANDS], prevName;
|
||||
if (brands) {
|
||||
for (var i in brands) {
|
||||
for (var i=0; i<brands.length; i++) {
|
||||
var brandName = brands[i].brand || brands[i],
|
||||
brandVersion = brands[i].version;
|
||||
if (this.itemType == UA_BROWSER &&
|
||||
@ -1387,11 +1392,22 @@
|
||||
extensions = undefined;
|
||||
}
|
||||
|
||||
// Convert Headers object into a plain object
|
||||
if (headers && typeof headers.append === FUNC_TYPE) {
|
||||
var kv = {};
|
||||
headers.forEach(function (v, k) { kv[k] = v; });
|
||||
headers = kv;
|
||||
if (headers) {
|
||||
if (typeof headers.append === FUNC_TYPE) {
|
||||
// Convert Headers object into a plain object
|
||||
var kv = {};
|
||||
headers.forEach(function (v, k) { kv[String(k).toLowerCase()] = v; });
|
||||
headers = kv;
|
||||
} else {
|
||||
// Normalize headers field name into lowercase
|
||||
var normalized = {};
|
||||
for (var header in headers) {
|
||||
if (headers.hasOwnProperty(header)) {
|
||||
normalized[String(header).toLowerCase()] = headers[header];
|
||||
}
|
||||
}
|
||||
headers = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(this instanceof UAParser)) {
|
||||
|
242
test/data/ua-ch/headers.js
Normal file
242
test/data/ua-ch/headers.js
Normal file
@ -0,0 +1,242 @@
|
||||
const UACHTests = [
|
||||
{
|
||||
desc: 'Avast Secure Browser',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Avast Secure Browser";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Avast Secure Browser',
|
||||
version : '131',
|
||||
major : '131',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Brave',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Brave',
|
||||
version : '132',
|
||||
major : '132',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Chrome',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Chrome',
|
||||
version : '111',
|
||||
major : '111',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Chrome Headless',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Chrome Headless',
|
||||
version : '124',
|
||||
major : '124',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Chrome WebView',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Chrome WebView',
|
||||
version : '123',
|
||||
major : '123',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'DuckDuckGo',
|
||||
headers : {
|
||||
'sec-ch-ua': '"DuckDuckGo";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
|
||||
},
|
||||
expect : {
|
||||
browser : {
|
||||
name : 'DuckDuckGo',
|
||||
version : '131',
|
||||
major : '131',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Edge',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Edge',
|
||||
version : '120',
|
||||
major : '120',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Edge WebView2',
|
||||
headers : {
|
||||
'sec-ch-ua': '" Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103", "Microsoft Edge WebView2";v="104"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Edge WebView2',
|
||||
version : '104',
|
||||
major : '104',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Huawei Browser',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "HuaweiBrowser";v="114"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Huawei Browser',
|
||||
version : '114',
|
||||
major : '114',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'MIUI Browser',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Miui Browser";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'MIUI Browser',
|
||||
version : '123',
|
||||
major : '123',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Oculus Browser',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="130", "Oculus Browser";v="36", "Not?A_Brand";v="99"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Oculus Browser',
|
||||
version : '36',
|
||||
major : '36',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Opera',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Opera";v="116", "Chromium";v="131", "Not_A Brand";v="24"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera',
|
||||
version : '116',
|
||||
major : '116',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Opera GX',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Opera GX";v="114"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera GX',
|
||||
version : '114',
|
||||
major : '114',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Opera Mobi',
|
||||
headers : {
|
||||
'sec-ch-ua': '"OperaMobile";v="86", ";Not A Brand";v="99", "Opera";v="115", "Chromium";v="130"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera Mobi',
|
||||
version : '86',
|
||||
major : '86',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Opera Mobi',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="132", "OperaMobile";v="87", "Opera";v="117", " Not A;Brand";v="99"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera Mobi',
|
||||
version : '87',
|
||||
major : '87',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Samsung Internet',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="125", "Not.A/Brand";v="24", "Samsung Internet";v="27.0"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Samsung Internet',
|
||||
version : '27.0',
|
||||
major : '27',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
desc: 'Yandex',
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="130", "YaBrowser";v="24.12", "Not?A_Brand";v="99", "Yowser";v="2.5"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Yandex',
|
||||
version : '24.12',
|
||||
major : '24',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
module.exports = UACHTests;
|
@ -2695,5 +2695,27 @@
|
||||
"major" : "10",
|
||||
"type" : "inapp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Zalo on iOS",
|
||||
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Zalo/20.05.01 Mobile/15E148",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Zalo",
|
||||
"version" : "20.05.01",
|
||||
"major" : "20",
|
||||
"type" : "inapp"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Zalo on Android",
|
||||
"ua" : "Mozilla/5.0 (Linux; Android 10; Vsmart Live Build/QKQ1.190918.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.108 Mobile Safari/537.36 Zalo/20.04.02.r1",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Zalo",
|
||||
"version" : "20.04.02.r1",
|
||||
"major" : "20",
|
||||
"type" : "inapp"
|
||||
}
|
||||
}
|
||||
]
|
@ -87,6 +87,22 @@
|
||||
"architecture" : "amd64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Alpha",
|
||||
"ua" : "Mozilla/3.01 (WinNT; I) [AXP]",
|
||||
"expect" :
|
||||
{
|
||||
"architecture" : "alpha"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Alpha",
|
||||
"ua" : "Mozilla/5.0 (X11; OpenBSD alpha; rv:78.0) Gecko/20100101 Firefox/78.0",
|
||||
"expect" :
|
||||
{
|
||||
"architecture" : "alpha"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "ARM",
|
||||
"ua" : "Mozilla/5.0 (Mobile; Windows Phone 8.1; Android 4.0; ARM; Trident/7.0; Touch; rv:11.0; IEMobile/11.0; NOKIA; Lumia 635) like iPhone OS 7_0_3 Mac OS X AppleWebKit/537 (KHTML, like Gecko) Mobile Safari/537",
|
||||
|
@ -122,42 +122,6 @@
|
||||
"type": "undefined"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips SmartTV",
|
||||
"ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips 32PFL6606K/02 SmartTV (2011)",
|
||||
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips 32PFL6606K/02 SmartTV (2013)",
|
||||
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips 32PHS5301/12 SmartTV (2016)",
|
||||
"ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "32PHS5301/12",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Samsung SmartTV",
|
||||
"ua": "Mozilla/5.0 (SMART-TV; X11; Linux armv7l) AppleWebkit/537.42 (KHTML, like Gecko) Safari/537.42",
|
||||
|
83
test/data/ua/device/philips.json
Normal file
83
test/data/ua/device/philips.json
Normal file
@ -0,0 +1,83 @@
|
||||
[
|
||||
{
|
||||
"desc": "Philips S616",
|
||||
"ua": "Mozilla/5.0 (Linux; Android 5.1; Philips S616 Build/LMY47D) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.109 Mobile Safari/537.36",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "S616",
|
||||
"type": "mobile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips W8510",
|
||||
"ua": "Mozilla/5.0 (Linux; Android 4.2.2; Philips W8510 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.68 Mobile Safari/537.36",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "W8510",
|
||||
"type": "mobile"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips SmartTV",
|
||||
"ua": "Mozilla/5.0 (Linux; Android 11; PHILIPS 4k TV Build/RTXC.231010.082.A1; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/126.0.6478.71 Mobile Safari/537.36",
|
||||
"expect": {
|
||||
"vendor": "PHILIPS",
|
||||
"model": "undefined",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips SmartTV",
|
||||
"ua": "Opera/9.80 HbbTV/1.1.1 (; Philips; ; ; ; ) NETTV/4.0.2; en) Version/11.60",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips 32PFL6606K/02 SmartTV (2011)",
|
||||
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips 32PFL6606K/02 SmartTV (2013)",
|
||||
"ua": "Opera/9.80 (Linux mips ; U; HbbTV/1.1.1 (; Philips; ; ; ; ) CE-HTML/1.0 NETTV/3.1.0; en) Presto/2.6.33 Version/10.70",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips 32PHS5301/12 SmartTV (2016)",
|
||||
"ua": "Mozilla/5.0 (Linux armv7l) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36 OPR/29.0.1803.0 OMI/4.5.23.37.MOT2.13 HbbTV/1.2.1 (;Philips;32PHS5301/12;;_TV_MT5800;) Firmware/TPM161E_012.002.045.001 en",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "32PHS5301/12",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips PH0M_EA_T32",
|
||||
"ua": "Mozilla/5.0 (Linux; Android 10; Philips FHD Android TV Build/QTG3.201102.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/125.0.6422.186 Mobile Safari/537.36",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "undefined",
|
||||
"type": "smarttv"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Philips PH3M_AL_T32",
|
||||
"ua": "Mozilla/5.0 (Linux; Android 11; Philips Google TV TA7 Build/RTM5.220609.199; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/111.0.5563.58 Mobile Safari/537.36",
|
||||
"expect": {
|
||||
"vendor": "Philips",
|
||||
"model": "undefined",
|
||||
"type": "smarttv"
|
||||
}
|
||||
}
|
||||
]
|
@ -25,5 +25,23 @@
|
||||
"model": "Neo3 Link",
|
||||
"type": "xr"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Pico Neo 3",
|
||||
"ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo 3 OS5.12.2 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.48 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0",
|
||||
"expect": {
|
||||
"vendor": "Pico",
|
||||
"model": "Neo 3",
|
||||
"type": "xr"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc": "Pico Neo 3 Pro",
|
||||
"ua": "Mozilla/5.0 (X11; Linux x86_64; Pico Neo 3 Pro OS5.9.9.0 like Quest) AppleWebKit/537.36 (KHTML, like Gecko) PicoBrowser/3.3.46 Chrome/105.0.5195.68 VR Safari/537.36 OculusBrowser/7.0",
|
||||
"expect": {
|
||||
"vendor": "Pico",
|
||||
"model": "Neo 3 Pro",
|
||||
"type": "xr"
|
||||
}
|
||||
}
|
||||
]
|
@ -79,6 +79,26 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Algolia Crawler",
|
||||
"ua" : "Algolia Crawler/v2.183.0",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Algolia Crawler",
|
||||
"version" : "v2.183.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Algolia Crawler Renderscript",
|
||||
"ua" : "Algolia Crawler Renderscript",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Algolia Crawler Renderscript",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Applebot",
|
||||
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B410 Safari/600.1.4 (Applebot/0.1;+http://www.apple.com/go/applebot)",
|
||||
@ -139,6 +159,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Baidu ADS",
|
||||
"ua" : "Baidu-ADS",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Baidu-ADS",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Baiduspider",
|
||||
"ua" : "Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)",
|
||||
@ -229,6 +259,36 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "BLEXBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup-crawler.com/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "BLEXBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "botify",
|
||||
"ua" : "Desktop: Mozilla/5.0 (compatible; botify; http://botify.com)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "botify",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Bravebot",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Bravebot/1.0; +https://search.brave.com/help/brave-search-crawler) Chrome/W.X.Y.Z Safari/537.36",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Bravebot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Bytespider",
|
||||
"ua" : "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.1511.1269 Mobile Safari/537.36; Bytespider",
|
||||
@ -269,6 +329,26 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Claude-SearchBot",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Claude-SearchBot/1.0; +Claude-SearchBot@anthropic.com)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Claude-SearchBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "ClaudeWeb",
|
||||
"ua" : "Claude-Web/1.0 (web crawler; +https://www.anthropic.com/; bots@anthropic.com)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Claude-Web",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Coc Coc Bot (web)",
|
||||
"ua" : "Mozilla/5.0 (compatible; coccocbot-web/1.0; +http://help.coccoc.com/searchengine)",
|
||||
@ -290,15 +370,55 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "ClaudeWeb",
|
||||
"ua" : "Claude-Web/1.0 (web crawler; +https://www.anthropic.com/; bots@anthropic.com)",
|
||||
"desc" : "cohere-training-data-crawler",
|
||||
"ua" : "cohere-training-data-crawler (+crawler@cohere.ai)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Claude-Web",
|
||||
"name" : "cohere-training-data-crawler",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "contxbot",
|
||||
"ua" : "Mozilla/5.0 (compatible;contxbot/1.0)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "contxbot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Cotoyogi",
|
||||
"ua" : "Mozilla/5.0 (compatible; Cotoyogi/4.0; +https://ds.rois.ac.jp/center8/crawler/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Cotoyogi",
|
||||
"version" : "4.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Coveobot",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) (compatible; Coveobot/2.0;+http://www.coveo.com/bot.html)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Coveobot",
|
||||
"version" : "2.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "CriteoBot",
|
||||
"ua" : "CriteoBot/0.1 (+https://www.criteo.com/criteo-crawler/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "CriteoBot",
|
||||
"version" : "0.1",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "DataForSEO",
|
||||
"ua" : "Mozilla/5.0 (compatible; DataForSeoBot; +https://dataforseo.com/dataforseo-bot)",
|
||||
@ -339,6 +459,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "DeepSeekBot",
|
||||
"ua" : "DeepSeekBot",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "DeepSeekBot",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Diffbot",
|
||||
"ua" : "Diffbot/0.1",
|
||||
@ -369,6 +499,26 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "DuckDuckGo-Favicons-Bot",
|
||||
"ua" : "DuckDuckGo-Favicons-Bot/1.0",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "DuckDuckGo-Favicons-Bot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Elastic",
|
||||
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/124.0.6367.29 Safari/537.36 Elastic/Synthetics",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Elastic",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Exabot",
|
||||
"ua" : "Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)",
|
||||
@ -409,6 +559,36 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "FirecrawlAgent",
|
||||
"ua" : "Mozilla/5.0 (compatible; FirecrawlAgent/1.0)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "FirecrawlAgent",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Freespoke",
|
||||
"ua" : "Mozilla/5.0 (compatible; Freespoke/2.0; +https://docs.freespoke.com/search/bot)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Freespoke",
|
||||
"version" : "2.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "APIs-Google",
|
||||
"ua" : "APIs-Google (+https://developers.google.com/webmasters/APIs-Google.html)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "APIs-Google",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Googlebot-Video",
|
||||
"ua" : "Googlebot-Video/1.0",
|
||||
@ -509,6 +689,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Google-CloudVertexBot",
|
||||
"ua" : "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.7204.183 Mobile Safari/537.36 (compatible; Google-CloudVertexBot; +https://cloud.google.com/enterprise-search)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Google-CloudVertexBot",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Google-Safety",
|
||||
"ua" : "Google-Safety",
|
||||
@ -529,6 +719,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "HuggingFace-Bot",
|
||||
"ua" : "Mozilla/5.0 (compatible; HuggingFace-Bot/1.0; +https://huggingface.co/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "HuggingFace-Bot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "iAskBot",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/605.1.15 (KHTML, like Gecko; compatible; iAskBot/1.0; +https://iask.ai/) Chrome/120.0.6099.119 Safari/605.1.15",
|
||||
@ -549,6 +749,26 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Kagibot",
|
||||
"ua" : "Mozilla/5.0 (compatible; Kagibot/1.0; +https://kagi.com/bot)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Kagibot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Kangaroo Bot",
|
||||
"ua" : "Mozilla/5.0 (compatible; Kangaroo Bot/1.0)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Kangaroo Bot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Linespider",
|
||||
"ua" : "Mozilla/5.0 (compatible; Linespider/1.1; +https://lin.ee/4dwXkTH)",
|
||||
@ -579,6 +799,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Marginalia Search",
|
||||
"ua" : "search.marginalia.nu",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "marginalia",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Meta-ExternalAgent",
|
||||
"ua" : "meta-externalagent/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)",
|
||||
@ -610,6 +840,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "msnbot",
|
||||
"ua" : "msnbot/2.0b (+http://search.msn.com/msnbot.htm)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "msnbot",
|
||||
"version" : "2.0b",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Omgili",
|
||||
"ua" : "omgili/0.5 +https://omgili.com",
|
||||
@ -630,6 +870,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "OnCrawl",
|
||||
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4 (compatible; OnCrawl Mobile/1.0; +http://www.oncrawl.com/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "OnCrawl",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Onespot",
|
||||
"ua" : "Mozilla/5.0 (compatible; Onespot-ScraperBot/1.0; +https://www.onespot.com/identifying-traffic.html)",
|
||||
@ -650,6 +900,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "PanguBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; PanguBot/1.0)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "PanguBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "PerplexityBot",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)",
|
||||
@ -710,6 +970,46 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Replicate-Bot",
|
||||
"ua" : "Mozilla/5.0 (compatible; Replicate-Bot/1.0; +https://replicate.com/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Replicate-Bot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "RunPod-Bot",
|
||||
"ua" : "Mozilla/5.0 (compatible; RunPod-Bot/1.0; +https://runpod.io/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "RunPod-Bot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "SBIntuitionsBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; SBIntuitionsBot/0.1;+https://www.sbintuitions.co.jp/bot/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "SBIntuitionsBot",
|
||||
"version" : "0.1",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "SeekportBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; SeekportBot; +https://bot.seekport.com)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "SeekportBot",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "SemrushBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; SemrushBot/7~bl; +http://www.semrush.com/bot.html)",
|
||||
@ -761,7 +1061,27 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Sogou",
|
||||
"desc" : "Siteimprove",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; SiteCheck-sitecrawl by Siteimprove.com; +https://siteimprove.com/bots) Chrome/[VERSION] Safari/537.36",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Siteimprove",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Sogou Pic Spider",
|
||||
"ua" : "Sogou Pic Spider/3.0( http://www.sogou.com/docs/help/webmasters.htm#07)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Sogou Pic Spider",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Sogou web spider",
|
||||
"ua" : "Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)",
|
||||
"expect" :
|
||||
{
|
||||
@ -790,6 +1110,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "TikTokSpider",
|
||||
"ua" : "Mozilla/5.0 (Linux; Android 5.0) AppleWebKit/537.36 (KHTML, like Gecko) Mobile Safari/537.36 (compatible; TikTokSpider; ttspider-feedback@tiktok.com)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "TikTokSpider",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Timpibot",
|
||||
"ua" : "Timpibot/0.8 (+http://www.timpi.io)",
|
||||
@ -800,6 +1130,16 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Together-Bot",
|
||||
"ua" : "Mozilla/5.0 (compatible; Together-Bot/1.0; +https://together.ai/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Together-Bot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "TurnitinBot",
|
||||
"ua" : "TurnitinBot (https://turnitin.com/robot/crawlerinfo.html)",
|
||||
@ -810,6 +1150,26 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "TwinAgent",
|
||||
"ua" : "TwinAgent/1.0",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "TwinAgent",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "xAI-Bot",
|
||||
"ua" : "Mozilla/5.0 (compatible; xAI-Bot/1.0; +https://x.ai/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "xAI-Bot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "VelenPublicWebCrawler",
|
||||
"ua" : "Mozilla/5.0 (compatible; VelenPublicWebCrawler/1.0; +https://velen.io)",
|
||||
@ -820,6 +1180,36 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "v0bot",
|
||||
"ua" : "v0bot",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "v0bot",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "webzio",
|
||||
"ua" : "webzio (+https://webz.io/bot.html)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "webzio",
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Webzio-Extended",
|
||||
"ua" : "Mozilla/5.0 (compatible; Webzio-Extended/1.0; +https://www.webzio.com/bot.html)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Webzio-Extended",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Yahoo! Japan",
|
||||
"ua" : "Y!J-BRW/1.0 (https://www.yahoo-help.jp/app/answers/detail/p/595/a_id/42716)",
|
||||
@ -840,6 +1230,46 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexAccessibilityBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexAccessibilityBot/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexAccessibilityBot",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexAdditionalBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexAdditionalBot/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexAdditionalBot",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexAdNet",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexAdNet/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexAdNet",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexBlogs",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexBlogs/0.99; robot; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexBlogs",
|
||||
"version" : "0.99",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)",
|
||||
@ -850,6 +1280,256 @@
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexBot MirrorDetector",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexBot/3.0; MirrorDetector; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexBot MirrorDetector",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexComBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexComBot/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexComBot",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexFavicons",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexFavicons/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexFavicons",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexImageResizer",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexImageResizer/2.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexImageResizer",
|
||||
"version" : "2.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexImages",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexImages",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexMarket",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexMarket/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexMarket",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexMetrika",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexMetrika/2.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexMetrika",
|
||||
"version" : "2.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexMedia",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexMedia/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexMedia",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexMobileBot",
|
||||
"ua" : "Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B411 Safari/600.1.4 (compatible; YandexMobileBot/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexMobileBot",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexMobileScreenShotBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexMobileScreenShotBot/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexMobileScreenShotBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexNews",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexNews/4.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexNews",
|
||||
"version" : "4.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexOntoDB",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexOntoDB/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexOntoDB",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexOntoDBAPI",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexOntoDBAPI/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexOntoDBAPI",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexPartner",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexPartner/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexPartner",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexRCA",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexRCA/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexRCA",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexRenderResourcesBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexRenderResourcesBot/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexRenderResourcesBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexScreenshotBot",
|
||||
"ua" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.96 Safari/537.36 (compatible; YandexScreenshotBot/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexScreenshotBot",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexSpravBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexSpravBot/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexSpravBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexTracker",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexTracker/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexTracker",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexVertis",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexVertis/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexVertis",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexVerticals",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexVerticals/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexVerticals",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexVideo",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexVideo/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexVideo",
|
||||
"version" : "3.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexVideoParser",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexVideoParser/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexVideoParser",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexWebmaster",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexWebmaster/2.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexWebmaster",
|
||||
"version" : "2.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YepBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; YepBot/1.0; +http://yep.com/yepbot/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YepBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Yeti",
|
||||
"ua" : "Mozilla/5.0 (compatible; Yeti/1.1; +http://naver.me/spd)",
|
||||
@ -889,5 +1569,15 @@
|
||||
"version" : "undefined",
|
||||
"type" : "crawler"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "ZumBot",
|
||||
"ua" : "Mozilla/5.0 (compatible; ZumBot/1.0; http://help.zum.com/inquiry)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "ZumBot",
|
||||
"version" : "1.0",
|
||||
"type" : "crawler"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -9,6 +9,16 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Asana",
|
||||
"ua" : "Asana/1.4.0 WebsiteMetadataRetriever",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Asana",
|
||||
"version" : "1.4.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Better Uptime Bot",
|
||||
"ua" : "Better Uptime Bot Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36",
|
||||
@ -29,6 +39,26 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Bit.ly",
|
||||
"ua" : "bitlybot/3.0 (+http://bit.ly/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "bitlybot",
|
||||
"version" : "3.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Blueno",
|
||||
"ua" : "acebookexternalhit/1.1 (compatible; Blueno/1.0; +http://naver.me/scrap)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Blueno",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Bluesky",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app) Chrome/100.0.0.0 Safari/537.36",
|
||||
@ -39,6 +69,16 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "BufferLinkPreviewBot",
|
||||
"ua" : "BufferLinkPreviewBot/1.0 (+https://scraper.buffer.com/about/bots/link-preview-bot)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "BufferLinkPreviewBot",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "ChatGPT-User",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ChatGPT-User/1.0; +https://openai.com/bot",
|
||||
@ -49,6 +89,36 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Chrome-Lighthouse",
|
||||
"ua" : "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4590.2 Mobile Safari/537.36 Chrome-Lighthouse",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Chrome-Lighthouse",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Claude-User",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Claude-User/1.0; +Claude-User@anthropic.com)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Claude-User",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Cohere-AI",
|
||||
"ua" : "Mozilla/5.0 (compatible; Cohere-AI/1.0; +https://cohere.com/)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Cohere-AI",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "DuckAssistBot",
|
||||
"ua" : "DuckAssistBot/1.2; (+http://duckduckgo.com/duckassistbot.html)",
|
||||
@ -59,6 +129,16 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Gemini-Deep-Research",
|
||||
"ua" : "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; Gemini-Deep-Research; +https://gemini.google/overview/deep-research/) Chrome/135.0.0.0 Safari/537.36",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Gemini-Deep-Research",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Google FeedFetcher",
|
||||
"ua" : "FeedFetcher-Google; (+http://www.google.com/feedfetcher.html)",
|
||||
@ -129,6 +209,16 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "HubSpot Page Fetcher",
|
||||
"ua" : "HubSpot Page Fetcher/1.0 http://www.hubspot.com/ web-crawlers@hubspot.com",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "HubSpot Page Fetcher",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Iframely",
|
||||
"ua" : "Iframely/1.3.1 (+https://iframely.com/docs/about)",
|
||||
@ -139,6 +229,16 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "kakaotalk-scrap",
|
||||
"ua" : "facebookexternalhit/1.1; kakaotalk-scrap/1.0; +https://devtalk.kakao.com/t/scrap/33984",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "kakaotalk-scrap",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Meta-ExternalFetcher",
|
||||
"ua" : "meta-externalfetcher/1.1 (+https://developers.facebook.com/docs/sharing/webmasters/crawler)",
|
||||
@ -249,6 +349,26 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "vercel-favicon-bot",
|
||||
"ua" : "vercel-favicon-bot",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "vercel-favicon-bot",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "vercel-screenshot-bot",
|
||||
"ua" : "vercel-screenshot-bot",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "vercel-screenshot-bot",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Vercelbot",
|
||||
"ua" : "Vercelbot (+https://vercel.com)",
|
||||
@ -259,6 +379,26 @@
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "vercelflags",
|
||||
"ua" : "vercelflags",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "vercelflags",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "verceltracing",
|
||||
"ua" : "verceltracing",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "verceltracing",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "WhatsApp",
|
||||
"ua" : "WhatsApp/2.23.20.0",
|
||||
@ -268,5 +408,105 @@
|
||||
"version" : "2.23.20.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YaDirectFetcher",
|
||||
"ua" : "Mozilla/5.0 (compatible; YaDirectFetcher/1.0; Dyatel; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YaDirectFetcher",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexCalendar",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexCalendar/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexCalendar",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexDirect",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexDirect/3.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexDirect",
|
||||
"version" : "3.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexDirectDyn",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexDirectDyn/1.0; +http://yandex.com/bots",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexDirectDyn",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexForDomain",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexForDomain/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexForDomain",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexPagechecker",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexPagechecker/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexPagechecker",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexSearchShop",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexSearchShop/1.0; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexSearchShop",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexSitelinks",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexSitelinks; Dyatel; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexSitelinks",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "YandexUserproxy",
|
||||
"ua" : "Mozilla/5.0 (compatible; YandexUserproxy; robot; +http://yandex.com/bots)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "YandexUserproxy",
|
||||
"version" : "undefined",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
},
|
||||
{
|
||||
"desc" : "Zoombot",
|
||||
"ua" : "Mozilla/5.0 (compatible; Zoombot/1.0; +https://zoom.us; crawler@domain.com)",
|
||||
"expect" :
|
||||
{
|
||||
"name" : "Zoombot",
|
||||
"version" : "1.0",
|
||||
"type" : "fetcher"
|
||||
}
|
||||
}
|
||||
]
|
@ -1,5 +1,5 @@
|
||||
import { UAParser } from '../../src/main/ua-parser.mjs';
|
||||
import { CPU, Device, Engine } from '../../src/enums/ua-parser-enums.mjs';
|
||||
import { CPUArch, DeviceType, EngineName } from '../../src/enums/ua-parser-enums.mjs';
|
||||
import * as assert from 'assert';
|
||||
|
||||
describe('Returns', () => {
|
||||
@ -19,8 +19,8 @@ describe('Returns', () => {
|
||||
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);
|
||||
assert.strictEqual(cpu.is(CPUArch.ARM), true);
|
||||
assert.strictEqual(device.is(DeviceType.MOBILE), true);
|
||||
assert.strictEqual(engine.is(EngineName.GECKO), true);
|
||||
});
|
||||
});
|
@ -5,6 +5,8 @@ const traverse = require('@babel/traverse').default;
|
||||
const safe = require('safe-regex');
|
||||
const { UAParser } = require('../../src/main/ua-parser');
|
||||
const { Bots, CLIs, Crawlers, Emails, Fetchers, InApps, Libraries, Vehicles } = require('../../src/extensions/ua-parser-extensions');
|
||||
const { BrowserType, OSName, Extension } = require('../../src/enums/ua-parser-enums');
|
||||
const { CLI, Crawler, Email, Fetcher, Library } = Extension.BrowserName;
|
||||
|
||||
describe('Extensions', () => {
|
||||
[
|
||||
@ -42,29 +44,29 @@ describe('Extensions', () => {
|
||||
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)';
|
||||
|
||||
assert.equal(UAParser(scrapy, Bots).browser.name, 'Scrapy');
|
||||
assert.equal(UAParser(scrapy, Bots).browser.name, Library.SCRAPY);
|
||||
|
||||
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"});
|
||||
assert.deepEqual(emailParser.setUA(outlook).getBrowser(), {name: Email.MICROSOFT_OUTLOOK, version: "16.0.9126", major: "16", type: BrowserType.EMAIL});
|
||||
assert.deepEqual(emailParser.setUA(thunderbird).getBrowser(), {name: Email.THUNDERBIRD, version: "78.13.0", major: "78", type: BrowserType.EMAIL});
|
||||
|
||||
const libraryParser = new UAParser(Libraries);
|
||||
assert.deepEqual(libraryParser.setUA(axios).getBrowser(), {name: "axios", version: "1.3.5", major: "1", type: "library"});
|
||||
assert.deepEqual(libraryParser.setUA(jsdom).getBrowser(), {name: "jsdom", version: "20.0.3", major: "20", type: "library"});
|
||||
assert.deepEqual(libraryParser.setUA(scrapy).getBrowser(), {name: "Scrapy", version: "1.5.0", major: "1", type: "library"});
|
||||
assert.deepEqual(libraryParser.setUA(axios).getBrowser(), {name: Library.AXIOS, version: "1.3.5", major: "1", type: BrowserType.LIBRARY});
|
||||
assert.deepEqual(libraryParser.setUA(jsdom).getBrowser(), {name: Library.JSDOM, version: "20.0.3", major: "20", type: BrowserType.LIBRARY});
|
||||
assert.deepEqual(libraryParser.setUA(scrapy).getBrowser(), {name: Library.SCRAPY, version: "1.5.0", major: "1", type: BrowserType.LIBRARY});
|
||||
|
||||
// Bluesky
|
||||
const bluesky = 'Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)';
|
||||
assert.deepEqual(new UAParser(bluesky, Bots).getBrowser(), {
|
||||
name: 'Bluesky',
|
||||
name: Fetcher.BLUESKY,
|
||||
version: '1.1',
|
||||
major: '1',
|
||||
type: 'fetcher'
|
||||
type: BrowserType.FETCHER
|
||||
});
|
||||
|
||||
const whatsapp = "WhatsApp/2.0 A";
|
||||
assert.deepEqual(new UAParser(whatsapp, Fetchers).getOS(), {
|
||||
name : 'Android',
|
||||
name : OSName.ANDROID,
|
||||
version : undefined
|
||||
});
|
||||
});
|
||||
@ -77,14 +79,14 @@ describe('Merge', () => {
|
||||
// try merging crawlers & CLIs
|
||||
const crawlersAndCLIs = { browser : [...Crawlers.browser, ...CLIs.browser]};
|
||||
const crawlersAndCLIsParser = new UAParser(crawlersAndCLIs);
|
||||
assert.deepEqual(crawlersAndCLIsParser.setUA(wget).getBrowser(), {name: "Wget", version: "1.21.1", major: "1", type:"cli"});
|
||||
assert.deepEqual(crawlersAndCLIsParser.setUA(facebookBot).getBrowser(), {name: "FacebookBot", version: "1.0", major: "1", type:"crawler"});
|
||||
assert.deepEqual(crawlersAndCLIsParser.setUA(wget).getBrowser(), {name: CLI.WGET, version: "1.21.1", major: "1", type: BrowserType.CLI});
|
||||
assert.deepEqual(crawlersAndCLIsParser.setUA(facebookBot).getBrowser(), {name: Crawler.META_FACEBOOKBOT, version: "1.0", major: "1", type: BrowserType.CRAWLER});
|
||||
|
||||
// alternative merge options
|
||||
const crawlersAndCLIsParser2 = new UAParser([Crawlers, CLIs]);
|
||||
const crawlersAndCLIsParser3 = new UAParser(facebookBot, [Crawlers, CLIs]);
|
||||
assert.deepEqual(crawlersAndCLIsParser2.setUA(wget).getBrowser(), {name: "Wget", version: "1.21.1", major: "1", type:"cli"});
|
||||
assert.deepEqual(crawlersAndCLIsParser3.getBrowser(), {name: "FacebookBot", version: "1.0", major: "1", type:"crawler"});
|
||||
assert.deepEqual(crawlersAndCLIsParser2.setUA(wget).getBrowser(), {name: CLI.WGET, version: "1.21.1", major: "1", type: BrowserType.CLI});
|
||||
assert.deepEqual(crawlersAndCLIsParser3.getBrowser(), {name: Crawler.META_FACEBOOKBOT, version: "1.0", major: "1", type: BrowserType.CRAWLER});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -2,6 +2,7 @@ const assert = require('assert');
|
||||
const { UAParser } = require('../../src/main/ua-parser');
|
||||
const { getDeviceVendor, isAppleSilicon, isAIBot, isBot, isChromeFamily } = require('../../src/helpers/ua-parser-helpers');
|
||||
const { Bots, Emails } = require('../../src/extensions/ua-parser-extensions');
|
||||
const { DeviceVendor } = require('../../src/enums/ua-parser-enums');
|
||||
|
||||
describe('getDeviceVendor', () => {
|
||||
it('Can guess the device vendor from a model name', () => {
|
||||
@ -11,10 +12,10 @@ describe('getDeviceVendor', () => {
|
||||
const modelNexus = 'Nexus 6P';
|
||||
const modelAquos = 'AQUOS-TVX19B';
|
||||
|
||||
assert.equal(getDeviceVendor(modelSM), 'Samsung');
|
||||
assert.equal(getDeviceVendor(modelRedmi), 'Xiaomi');
|
||||
assert.equal(getDeviceVendor(modelNexus), 'Huawei');
|
||||
assert.equal(getDeviceVendor(modelAquos), 'Sharp');
|
||||
assert.equal(getDeviceVendor(modelSM), DeviceVendor.SAMSUNG);
|
||||
assert.equal(getDeviceVendor(modelRedmi), DeviceVendor.XIAOMI);
|
||||
assert.equal(getDeviceVendor(modelNexus), DeviceVendor.HUAWEI);
|
||||
assert.equal(getDeviceVendor(modelAquos), DeviceVendor.SHARP);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -10,7 +10,7 @@ var cpus = require('../data/ua/cpu/cpu-all.json');
|
||||
var devices = readJsonFiles('test/data/ua/device');
|
||||
var engines = require('../data/ua/engine/engine-all.json');
|
||||
var os = readJsonFiles('test/data/ua/os');
|
||||
var { Headers } = require('node-fetch');
|
||||
var { Headers } = require('undici');
|
||||
|
||||
function readJsonFiles(dir) {
|
||||
var list = [];
|
||||
@ -91,6 +91,34 @@ describe('Returns', function () {
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
it('works even when Array.prototype has been mangled', function(done) {
|
||||
const result = withMangledArrayProto(() => new UAParser('').getResult());
|
||||
|
||||
function withMangledArrayProto(fn, key = 'isEmpty', value = function() { return this.length === 0; }) {
|
||||
const originalValue = Array.prototype[key];
|
||||
const restore = Object.hasOwnProperty.call(Array.prototype, key)
|
||||
? () => Array.prototype[key] = originalValue
|
||||
: () => delete Array.prototype[key];
|
||||
|
||||
Array.prototype[key] = value;
|
||||
const result = fn();
|
||||
restore();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
assert.deepEqual(result,
|
||||
{
|
||||
ua : '',
|
||||
browser: { name: undefined, version: undefined, major: undefined, type: undefined },
|
||||
cpu: { architecture: undefined },
|
||||
device: { vendor: undefined, model: undefined, type: undefined },
|
||||
engine: { name: undefined, version: undefined},
|
||||
os: { name: undefined, version: undefined }
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Extending Regex', function () {
|
||||
@ -353,4 +381,18 @@ describe('Read user-agent data from req.headers', function () {
|
||||
const { browser } = UAParser(reqHeaders);
|
||||
assert.strictEqual(browser.is('Midori'), true);
|
||||
});
|
||||
});
|
||||
|
||||
it('Headers field name should be case insensitive', function () {
|
||||
const hEaDeRs = {
|
||||
'uSeR-aGenT' : 'Midori/0.2.2 (X11; Linux i686; U; en-us) WebKit/531.2+'
|
||||
};
|
||||
const { browser } = UAParser(hEaDeRs);
|
||||
assert.strictEqual(browser.toString(), "Midori 0.2.2");
|
||||
});
|
||||
|
||||
it('Empty headers should not raise any error', function () {
|
||||
const emptyHeaders = {};
|
||||
const { browser } = UAParser(emptyHeaders);
|
||||
assert.strictEqual(browser.toString(), "undefined");
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,7 @@
|
||||
const assert = require('assert');
|
||||
const { UAParser } = require('../../src/main/ua-parser');
|
||||
const { BrowserName, CPUArch, DeviceType, DeviceVendor, EngineName, OSName } = require('../../src/enums/ua-parser-enums');
|
||||
const UACHTests = require('../data/ua-ch/headers');
|
||||
|
||||
describe('Map UA-CH headers', () => {
|
||||
|
||||
@ -25,27 +27,27 @@ describe('Map UA-CH headers', () => {
|
||||
it('Can read from client-hints headers using `withClientHints()`', () => {
|
||||
|
||||
assert.strictEqual(uap.ua, "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36");
|
||||
assert.strictEqual(uap.browser.name, "Chrome");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(uap.browser.version, "93.0.1.2");
|
||||
assert.strictEqual(uap.browser.major, "93");
|
||||
assert.strictEqual(browser.name, "Chrome");
|
||||
assert.strictEqual(browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(browser.version, "93.0.1.2");
|
||||
assert.strictEqual(browser.major, "93");
|
||||
assert.strictEqual(uap.cpu.architecture, "arm64");
|
||||
assert.strictEqual(cpu.architecture, "arm64");
|
||||
assert.strictEqual(uap.device.type, "mobile");
|
||||
assert.strictEqual(uap.cpu.architecture, CPUArch.ARM_64);
|
||||
assert.strictEqual(cpu.architecture, CPUArch.ARM_64);
|
||||
assert.strictEqual(uap.device.type, DeviceType.MOBILE);
|
||||
assert.strictEqual(uap.device.model, "Pixel 99");
|
||||
assert.strictEqual(uap.device.vendor, "Google");
|
||||
assert.strictEqual(device.type, "mobile");
|
||||
assert.strictEqual(uap.device.vendor, DeviceVendor.GOOGLE);
|
||||
assert.strictEqual(device.type, DeviceType.MOBILE);
|
||||
assert.strictEqual(device.model, "Pixel 99");
|
||||
assert.strictEqual(device.vendor, "Google");
|
||||
assert.strictEqual(uap.engine.name, 'Blink');
|
||||
assert.strictEqual(device.vendor, DeviceVendor.GOOGLE);
|
||||
assert.strictEqual(uap.engine.name, EngineName.BLINK);
|
||||
assert.strictEqual(uap.engine.version, '93.0.1.2');
|
||||
assert.strictEqual(engine.name, 'Blink');
|
||||
assert.strictEqual(engine.name, EngineName.BLINK);
|
||||
assert.strictEqual(engine.version, '93.0.1.2');
|
||||
assert.strictEqual(uap.os.name, "Windows");
|
||||
assert.strictEqual(uap.os.name, OSName.WINDOWS);
|
||||
assert.strictEqual(uap.os.version, "11");
|
||||
assert.strictEqual(os.name, "Windows");
|
||||
assert.strictEqual(os.name, OSName.WINDOWS);
|
||||
assert.strictEqual(os.version, "11");
|
||||
});
|
||||
|
||||
@ -58,16 +60,16 @@ describe('Map UA-CH headers', () => {
|
||||
engine = new UAParser(headers).getEngine();
|
||||
os = new UAParser(headers).getOS();
|
||||
|
||||
assert.strictEqual(uap.browser.name, "Chrome");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(uap.browser.version, "110.0.0.0");
|
||||
assert.strictEqual(uap.browser.major, "110");
|
||||
assert.strictEqual(uap.cpu.architecture, "amd64");
|
||||
assert.strictEqual(uap.cpu.architecture, CPUArch.X86_64);
|
||||
assert.strictEqual(uap.device.type, undefined);
|
||||
assert.strictEqual(uap.device.model, undefined);
|
||||
assert.strictEqual(uap.device.vendor, undefined);
|
||||
assert.strictEqual(uap.engine.name, 'Blink');
|
||||
assert.strictEqual(uap.engine.name, EngineName.BLINK);
|
||||
assert.strictEqual(uap.engine.version, '110.0.0.0');
|
||||
assert.strictEqual(uap.os.name, "Linux");
|
||||
assert.strictEqual(uap.os.name, OSName.LINUX);
|
||||
assert.strictEqual(uap.os.version, undefined);
|
||||
});
|
||||
|
||||
@ -80,16 +82,16 @@ describe('Map UA-CH headers', () => {
|
||||
|
||||
uap = UAParser(headers2).withClientHints();
|
||||
|
||||
assert.strictEqual(uap.browser.name, "Chrome");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(uap.browser.version, "110.0.0.0");
|
||||
assert.strictEqual(uap.browser.major, "110");
|
||||
assert.strictEqual(uap.cpu.architecture, "amd64");
|
||||
assert.strictEqual(uap.device.type, "mobile");
|
||||
assert.strictEqual(uap.cpu.architecture, CPUArch.X86_64);
|
||||
assert.strictEqual(uap.device.type, DeviceType.MOBILE);
|
||||
assert.strictEqual(uap.device.model, undefined);
|
||||
assert.strictEqual(uap.device.vendor, undefined);
|
||||
assert.strictEqual(uap.engine.name, 'Blink');
|
||||
assert.strictEqual(uap.engine.name, EngineName.BLINK);
|
||||
assert.strictEqual(uap.engine.version, '110.0.0.0');
|
||||
assert.strictEqual(uap.os.name, "Linux");
|
||||
assert.strictEqual(uap.os.name, OSName.LINUX);
|
||||
assert.strictEqual(uap.os.version, undefined);
|
||||
});
|
||||
|
||||
@ -116,10 +118,10 @@ describe('Map UA-CH headers', () => {
|
||||
}
|
||||
*/
|
||||
|
||||
assert.strictEqual(ua.os.is("macOS"), true);
|
||||
assert.strictEqual(ua.cpu.is("arm"), true);
|
||||
assert.strictEqual(ua.device.is("mobile"), false);
|
||||
assert.strictEqual(ua.device.is("tablet"), false);
|
||||
assert.strictEqual(ua.os.is(OSName.MACOS), true);
|
||||
assert.strictEqual(ua.cpu.is(CPUArch.ARM), true);
|
||||
assert.strictEqual(ua.device.is(DeviceType.MOBILE), false);
|
||||
assert.strictEqual(ua.device.is(DeviceType.TABLET), false);
|
||||
});
|
||||
});
|
||||
|
||||
@ -138,11 +140,11 @@ describe('Map UA-CH headers', () => {
|
||||
};
|
||||
|
||||
UAParser(FFVR).withClientHints().then(ua => {
|
||||
assert.strictEqual(ua.device.type, 'xr');
|
||||
assert.strictEqual(ua.device.type, DeviceType.XR);
|
||||
});
|
||||
|
||||
UAParser(FFEInk).withClientHints().then(ua => {
|
||||
assert.strictEqual(ua.device.type, 'tablet');
|
||||
assert.strictEqual(ua.device.type, DeviceType.TABLET);
|
||||
});
|
||||
|
||||
|
||||
@ -168,7 +170,7 @@ describe('Map UA-CH headers', () => {
|
||||
|
||||
uap = UAParser(headers2).withClientHints();
|
||||
|
||||
assert.strictEqual(uap.browser.name, "Chrome");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(uap.browser.version, undefined);
|
||||
assert.strictEqual(uap.browser.major, undefined);
|
||||
});
|
||||
@ -195,258 +197,37 @@ describe('Map UA-CH headers', () => {
|
||||
};
|
||||
|
||||
uap = UAParser(headers3a).withClientHints();
|
||||
assert.strictEqual(uap.browser.name, "Chrome");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(uap.browser.version, "120.0.6099.132");
|
||||
|
||||
uap = UAParser(headers3b).withClientHints();
|
||||
assert.strictEqual(uap.browser.name, "Chrome");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(uap.browser.version, "120.0.6099.132");
|
||||
|
||||
uap = UAParser(headers3c).withClientHints();
|
||||
assert.strictEqual(uap.browser.name, "Chrome");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.CHROME);
|
||||
assert.strictEqual(uap.browser.version, "120.0.6099.132");
|
||||
|
||||
uap = UAParser(headers3d).withClientHints();
|
||||
assert.strictEqual(uap.browser.name, "Edge");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.EDGE);
|
||||
assert.strictEqual(uap.browser.version, "120.0.6099.133");
|
||||
|
||||
uap = UAParser(headers3e).withClientHints();
|
||||
assert.strictEqual(uap.browser.name, "Edge");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.EDGE);
|
||||
assert.strictEqual(uap.browser.version, "120.0.6099.133");
|
||||
|
||||
uap = UAParser(headers3f).withClientHints();
|
||||
assert.strictEqual(uap.browser.name, "Edge");
|
||||
assert.strictEqual(uap.browser.name, BrowserName.EDGE);
|
||||
assert.strictEqual(uap.browser.version, "120.0.6099.133");
|
||||
});
|
||||
});
|
||||
|
||||
describe('UA-CH Headers tests', () => {
|
||||
[
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Avast Secure Browser";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Avast Secure Browser',
|
||||
version : '131',
|
||||
major : '131',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Not A(Brand";v="8", "Chromium";v="132", "Brave";v="132"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Brave',
|
||||
version : '132',
|
||||
major : '132',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Google Chrome";v="111", "Not(A:Brand";v="8", "Chromium";v="111"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Chrome',
|
||||
version : '111',
|
||||
major : '111',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="124", "HeadlessChrome";v="124", "Not-A.Brand";v="99"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Chrome Headless',
|
||||
version : '124',
|
||||
major : '124',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Android WebView";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Chrome WebView',
|
||||
version : '123',
|
||||
major : '123',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"DuckDuckGo";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
|
||||
},
|
||||
expect : {
|
||||
browser : {
|
||||
name : 'DuckDuckGo',
|
||||
version : '131',
|
||||
major : '131',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Edge',
|
||||
version : '120',
|
||||
major : '120',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '" Not;A Brand";v="99", "Microsoft Edge";v="103", "Chromium";v="103", "Microsoft Edge WebView2";v="104"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Edge WebView2',
|
||||
version : '104',
|
||||
major : '104',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "HuaweiBrowser";v="114"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Huawei Browser',
|
||||
version : '114',
|
||||
major : '114',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Miui Browser";v="123", "Not:A-Brand";v="8", "Chromium";v="123"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'MIUI Browser',
|
||||
version : '123',
|
||||
major : '123',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="130", "Oculus Browser";v="36", "Not?A_Brand";v="99"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Oculus Browser',
|
||||
version : '36',
|
||||
major : '36',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Opera";v="116", "Chromium";v="131", "Not_A Brand";v="24"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera',
|
||||
version : '116',
|
||||
major : '116',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="128", "Not;A=Brand";v="24", "Opera GX";v="114"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera GX',
|
||||
version : '114',
|
||||
major : '114',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"OperaMobile";v="86", ";Not A Brand";v="99", "Opera";v="115", "Chromium";v="130"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera Mobi',
|
||||
version : '86',
|
||||
major : '86',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="132", "OperaMobile";v="87", "Opera";v="117", " Not A;Brand";v="99"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Opera Mobi',
|
||||
version : '87',
|
||||
major : '87',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="125", "Not.A/Brand";v="24", "Samsung Internet";v="27.0"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Samsung Internet',
|
||||
version : '27.0',
|
||||
major : '27',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
headers : {
|
||||
'sec-ch-ua': '"Chromium";v="130", "YaBrowser";v="24.12", "Not?A_Brand";v="99", "Yowser";v="2.5"'
|
||||
},
|
||||
expect: {
|
||||
browser : {
|
||||
name : 'Yandex',
|
||||
version : '24.12',
|
||||
major : '24',
|
||||
type : undefined
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
.forEach(test => {
|
||||
const { browser } = UAParser(test.headers).withClientHints();
|
||||
assert.deepEqual(browser, test.expect.browser);
|
||||
UACHTests.forEach(test => {
|
||||
it(`Test for ${test.desc}`, () => {
|
||||
const { browser } = UAParser(test.headers).withClientHints();
|
||||
assert.deepEqual(browser, test.expect.browser);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -455,169 +236,169 @@ describe('Identify vendor & type of device from given model name', () => {
|
||||
{
|
||||
model: '220733SG',
|
||||
expect: {
|
||||
vendor : 'Xiaomi',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.XIAOMI,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: '5087Z',
|
||||
expect: {
|
||||
vendor : 'TCL',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.TCL,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: '9137W',
|
||||
expect: {
|
||||
vendor : 'TCL',
|
||||
type : 'tablet'
|
||||
vendor : DeviceVendor.TCL,
|
||||
type : DeviceType.TABLET
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'BE2015',
|
||||
expect: {
|
||||
vendor : 'OnePlus',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.ONEPLUS,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'CPH2389',
|
||||
expect: {
|
||||
vendor : 'OnePlus',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.ONEPLUS,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'Infinix X669C',
|
||||
expect: {
|
||||
vendor : 'Infinix',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.INFINIX,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'itel L6502',
|
||||
expect: {
|
||||
vendor : 'itel',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.ITEL,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'Lenovo TB-X606F',
|
||||
expect: {
|
||||
vendor : 'Lenovo',
|
||||
type : 'tablet'
|
||||
vendor : DeviceVendor.LENOVO,
|
||||
type : DeviceType.TABLET
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'LM-Q720',
|
||||
expect: {
|
||||
vendor : 'LG',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.LG,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'M2003J15SC',
|
||||
expect: {
|
||||
vendor : 'Xiaomi',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.XIAOMI,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'MAR-LX1A',
|
||||
expect: {
|
||||
vendor : 'Huawei',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.HUAWEI,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'moto g(20)',
|
||||
expect: {
|
||||
vendor : 'Motorola',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.MOTOROLA,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'Nokia C210',
|
||||
expect: {
|
||||
vendor : 'Nokia',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.NOKIA,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'Pixel 8',
|
||||
expect: {
|
||||
vendor : 'Google',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.GOOGLE,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'Redmi Note 9S',
|
||||
expect: {
|
||||
vendor : 'Xiaomi',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.XIAOMI,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'RMX3830',
|
||||
expect: {
|
||||
vendor : 'Realme',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.REALME,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'SM-S536DL',
|
||||
expect: {
|
||||
vendor : 'Samsung',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.SAMSUNG,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'SM-S546VL',
|
||||
expect: {
|
||||
vendor : 'Samsung',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.SAMSUNG,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'SM-T875',
|
||||
expect: {
|
||||
vendor : 'Samsung',
|
||||
type : 'tablet'
|
||||
vendor : DeviceVendor.SAMSUNG,
|
||||
type : DeviceType.TABLET
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'STK-L21',
|
||||
expect: {
|
||||
vendor : 'Huawei',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.HUAWEI,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'T430W',
|
||||
expect: {
|
||||
vendor : 'TCL',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.TCL,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'TECNO KI5k',
|
||||
expect: {
|
||||
vendor : 'TECNO',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.TECNO,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'vivo 1820',
|
||||
expect: {
|
||||
vendor : 'Vivo',
|
||||
type : 'mobile'
|
||||
vendor : DeviceVendor.VIVO,
|
||||
type : DeviceType.MOBILE
|
||||
}
|
||||
},
|
||||
{
|
||||
model: 'Xbox',
|
||||
expect: {
|
||||
vendor : 'Microsoft',
|
||||
type : 'console'
|
||||
vendor : DeviceVendor.MICROSOFT,
|
||||
type : DeviceType.CONSOLE
|
||||
}
|
||||
}
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user