ua-parser-js 2.0.0-alpha.2 → 2.0.0-alpha.3

Sign up to get free protection for your applications and to get access to all the features.
package/readme.md CHANGED
@@ -3,11 +3,14 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- <a href="https://travis-ci.org/faisalman/ua-parser-js"><img src="https://travis-ci.org/faisalman/ua-parser-js.svg?branch=master"></a>
7
- <a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/v/ua-parser-js.svg"></a>
8
- <a href="https://www.npmjs.com/package/ua-parser-js"><img src="https://img.shields.io/npm/dw/ua-parser-js.svg"></a>
9
- <a href="https://www.jsdelivr.com/package/npm/ua-parser-js"><img src="https://data.jsdelivr.com/v1/package/npm/ua-parser-js/badge"></a>
10
- <a href="https://cdnjs.com/libraries/UAParser.js"><img src="https://img.shields.io/cdnjs/v/UAParser.js.svg"></a>
6
+ <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>
7
+ <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>
8
+ <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>
9
+ <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>
10
+ <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>
11
+ <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>
12
+ <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>
13
+ <img src="https://img.shields.io/ossf-scorecard/github.com/faisalman/ua-parser-js?label=openssf%20scorecard&style=for-the-badge">
11
14
  </p>
12
15
 
13
16
  # UAParser.js
@@ -17,6 +20,9 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro
17
20
  * Author : Faisal Salman <<f@faisalman.com>>
18
21
  * Demo : https://faisalman.github.io/ua-parser-js
19
22
  * Source : https://github.com/faisalman/ua-parser-js
23
+ * Documentation :
24
+ * v1 : https://github.com/faisalman/ua-parser-js/tree/1.0.35#documentation
25
+ * v2 : https://faisalman.github.io/ua-parser-js-docs/v2
20
26
 
21
27
  ***
22
28
 
@@ -26,14 +32,6 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro
26
32
  </thead>
27
33
  <tbody>
28
34
  <tr>
29
- <td align="center" width="200px" rowspan="2"><a href="https://www.npmjs.com/package/@51degrees/ua-parser-js"><img src="images/51degrees.svg" alt="51degrees" width="75%" height="75%" ></a></td>
30
- <td align="left" width="400px"><a href="https://www.npmjs.com/package/@51degrees/ua-parser-js">↗ @51degrees/ua-parser-js</a></td>
31
- </tr>
32
- <tr>
33
- <td><br/><p>UAParser.js has been upgraded to detect comprehensive device data based on the User-Agent and User-Agent Client Hints.</p><p>This package supports all device types including Apple and Android devices and can be used either in a browser (client-side) or Node.js environment (server-side).</p><p>Visit <a href="https://www.npmjs.com/package/@51degrees/ua-parser-js">↗ 51Degrees <u>UAParser</u></a> to get started.</p>
34
- </td>
35
- </tr>
36
- <tr>
37
35
  <td colspan="2">
38
36
  <a href="https://opencollective.com/ua-parser-js">↗ Become a sponsor</a>
39
37
  </td>
@@ -47,39 +45,47 @@ JavaScript library to detect Browser, Engine, OS, CPU, and Device type/model fro
47
45
  What's new & breaking, please read [CHANGELOG](changelog.md) before upgrading.
48
46
 
49
47
  # Documentation
50
- ### UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)])
51
-
52
- In the browser environment you dont need to pass the user-agent string to the function, you can just call the funtion and it should automatically get the string from the `window.navigator.userAgent`, but that is not the case in nodejs. The user-agent string must be passed in' nodejs for the function to work. Usually you can find the user agent in: `request.headers["user-agent"]`.
48
+ ### `UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)]):IData`
53
49
 
50
+ In browser environment you don't need to pass the user-agent string to the function, as it should automatically get the string from the `window.navigator.userAgent`. Whereas in nodejs environment, the user-agent string must be passed in order for the function to work (usually you can find the user-agent in: `request.headers["user-agent"]`).
54
51
 
55
52
  ## Constructor
53
+
54
+ #### * `new UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)]):UAParser`
55
+
56
56
  When you call `UAParser` with the `new` keyword, `UAParser` will return a new instance with an empty result object, you have to call one of the available methods to get the information from the user-agent string.
57
57
  Like so:
58
- * `new UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)])`
58
+
59
59
  ```js
60
60
  let parser = new UAParser("your user-agent here"); // you need to pass the user-agent for nodejs
61
61
  console.log(parser); // {}
62
62
  let parserResults = parser.getResult();
63
63
  console.log(parserResults);
64
- /** {
65
- "ua" : "",
66
- "browser" : {},
67
- "engine" : {},
68
- "os" : {},
69
- "device" : {},
70
- "cpu" : {}
71
- } */
64
+ /*
65
+ {
66
+ ua : "",
67
+ browser : {},
68
+ engine : {},
69
+ os : {},
70
+ device : {},
71
+ cpu : {}
72
+ }
73
+ */
72
74
  ```
73
75
 
74
- When you call UAParser without the `new` keyword, it will automatically call `getResult()` function and return the parsed results.
75
- * `UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)])`
76
- * returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`
76
+ #### * `UAParser([user-agent:string][,extensions:object][,headers:object(since@2.0)]):IData`
77
77
 
78
- ## Methods
78
+ When you call `UAParser` without the `new` keyword, it will automatically call `getResult()` function and return the parsed results.
79
+
80
+ ```sh
81
+ returns result object `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`
82
+ ```
83
+
84
+ ## `UAParser`:
79
85
 
80
86
  #### Methods table
81
87
  The methods are self explanatory, here's a small overview on all the available methods:
82
- * `getResult()` - returns all function object calls, user-agent string, browser info, cpu, device, engine, os:
88
+ * `getResult()` - returns all function object calls, user-agent string, browser info, cpu, device, engine, os:
83
89
  `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`.
84
90
 
85
91
  * `getBrowser()` - returns the browser name and version.
@@ -88,17 +94,21 @@ The methods are self explanatory, here's a small overview on all the available m
88
94
  * `getOS()` - returns the running operating system name and version.
89
95
  * `getCPU()` - returns CPU architectural design name.
90
96
  * `getUA()` - returns the user-agent string.
91
- * `setUA(user-agent)` - set a custom user-agent to be parsed.
97
+ * `setUA(ua)` - set a custom user-agent to be parsed.
92
98
 
93
99
  ---
94
100
 
95
- * `getResult()`
96
- * returns `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`
101
+ #### * `getResult():IData`
102
+
103
+ ```sh
104
+ returns `{ ua: '', browser: {}, cpu: {}, device: {}, engine: {}, os: {} }`
105
+ ```
97
106
 
98
- * `getBrowser()`
99
- * returns `{ name: '', version: '' }`
107
+ #### * `getBrowser():IData`
100
108
 
101
109
  ```sh
110
+ returns `{ name: '', version: '' }`
111
+
102
112
  # Possible 'browser.name':
103
113
  2345Explorer, 360 Browser, Amaya, Android Browser, Arora, Avant, Avast, AVG,
104
114
  BIDUBrowser, Baidu, Basilisk, Blazer, Bolt, Brave, Bowser, Camino, Chimera,
@@ -113,16 +123,18 @@ NetSurf, Netfront, Netscape, NokiaBrowser, Obigo, Oculus Browser, OmniWeb,
113
123
  Opera Coast, Opera [Mini/Mobi/Tablet], PaleMoon, PhantomJS, Phoenix, Polaris,
114
124
  Puffin, QQ, QQBrowser, QQBrowserLite, Quark, QupZilla, RockMelt, [Mobile] Safari,
115
125
  Sailfish Browser, Samsung Browser, SeaMonkey, Silk, Skyfire, Sleipnir, Slim,
116
- SlimBrowser, Swiftfox, Tesla, TikTok, Tizen Browser, UCBrowser, UP.Browser, Viera,
117
- Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m, Whale Browser, ...
126
+ SlimBrowser, Snapchat, Swiftfox, Tesla, TikTok, Tizen Browser, UCBrowser,
127
+ UP.Browser, Viera, Vivaldi, Waterfox, WeChat, Weibo, Yandex, baidu, iCab, w3m,
128
+ Whale Browser, ...
118
129
 
119
130
  # 'browser.version' determined dynamically
120
131
  ```
121
132
 
122
- * `getDevice()`
123
- * returns `{ model: '', type: '', vendor: '' }`
133
+ #### * `getDevice():IData`
124
134
 
125
135
  ```sh
136
+ returns `{ model: '', type: '', vendor: '' }`
137
+
126
138
  # Possible 'device.type':
127
139
  console, mobile, tablet, smarttv, wearable, embedded
128
140
 
@@ -135,18 +147,20 @@ console, mobile, tablet, smarttv, wearable, embedded
135
147
 
136
148
  # Possible 'device.vendor':
137
149
  Acer, Alcatel, Amazon, Apple, Archos, ASUS, AT&T, BenQ, BlackBerry, Dell,
138
- Essential, Facebook, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Jolla, Kobo,
139
- Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia, OnePlus,
140
- OPPO, Ouya, Palm, Panasonic, Pebble, Polytron, Realme, RIM, Roku, Samsung, Sharp,
141
- Siemens, Sony[Ericsson], Sprint, Tesla, Vivo, Vodafone, Xbox, Xiaomi, Zebra, ZTE, ...
150
+ Essential, Facebook, Fairphone, GeeksPhone, Google, HP, HTC, Huawei, Infinix, Jolla,
151
+ Kobo, Lenovo, LG, Meizu, Microsoft, Motorola, Nexian, Nintendo, Nokia, Nvidia,
152
+ OnePlus, OPPO, Ouya, Palm, Panasonic, Pebble, Polytron, Realme, RIM, Roku, Samsung,
153
+ Sharp, Siemens, Sony[Ericsson], Sprint, Tecno, Tesla, Vivo, Vodafone, Xbox, Xiaomi,
154
+ Zebra, ZTE, ...
142
155
 
143
156
  # 'device.model' determined dynamically
144
157
  ```
145
158
 
146
- * `getEngine()`
147
- * returns `{ name: '', version: '' }`
159
+ #### * `getEngine():IData`
148
160
 
149
161
  ```sh
162
+ returns `{ name: '', version: '' }`
163
+
150
164
  # Possible 'engine.name'
151
165
  Amaya, Blink, EdgeHTML, Flow, Gecko, Goanna, iCab, KHTML, LibWeb, Links, Lynx,
152
166
  NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit
@@ -154,10 +168,11 @@ NetFront, NetSurf, Presto, Tasman, Trident, w3m, WebKit
154
168
  # 'engine.version' determined dynamically
155
169
  ```
156
170
 
157
- * `getOS()`
158
- * returns `{ name: '', version: '' }`
171
+ #### * `getOS():IData`
159
172
 
160
173
  ```sh
174
+ returns `{ name: '', version: '' }`
175
+
161
176
  # Possible 'os.name'
162
177
  AIX, Amiga OS, Android[-x86], Arch, Bada, BeOS, BlackBerry, CentOS, Chromium OS,
163
178
  Contiki, Fedora, Firefox OS, FreeBSD, Debian, Deepin, DragonFly, elementary OS,
@@ -172,22 +187,42 @@ Zenwalk, ...
172
187
  # 'os.version' determined dynamically
173
188
  ```
174
189
 
175
- * `getCPU()`
176
- * returns `{ architecture: '' }`
190
+ #### * `getCPU():IData`
177
191
 
178
192
  ```sh
193
+ returns `{ architecture: '' }`
194
+
179
195
  # Possible 'cpu.architecture'
180
196
  68k, amd64, arm[64/hf], avr, ia[32/64], irix[64], mips[64], pa-risc, ppc, sparc[64]
181
197
  ```
182
198
 
183
- * `getUA()`
184
- * returns UA string of current instance
199
+ #### * `getUA():string`
200
+
201
+ ```sh
202
+ returns user-agent string of current instance
203
+ ```
185
204
 
186
- * `setUA(uastring)`
187
- * set UA string to be parsed
188
- * returns current instance
205
+ #### * `setUA(ua:string):UAParser`
189
206
 
190
- #### * `is():boolean` utility `since@2.0`
207
+ ```sh
208
+ set user-agent string to be parsed
209
+ returns current instance
210
+ ```
211
+
212
+ ---
213
+
214
+ ## `IData`: `since@2.0`
215
+
216
+ #### Methods table
217
+ The methods are self explanatory, here's a small overview on all the available methods:
218
+ * `is(value)` - returns `true` if the passed value matches a value of current object, `false` otherwise
219
+ * `toString()` - returns the full-name values of current object as a string
220
+ * `withClientHints()` - returns an object with re-updated data from client hints
221
+ * `withFeatureCheck()` - returns an object with re-updated data from feature detection
222
+
223
+ ---
224
+
225
+ #### * `is(value:string):boolean`
191
226
 
192
227
  ```js
193
228
  // Is just a shorthand comparison to check whether the value of specified item equals one of its properties (in a case-insensitive way)
@@ -246,7 +281,7 @@ let engine = uap.getEngine();
246
281
  engine.is("Blink"); // true
247
282
  ```
248
283
 
249
- #### * `toString():string` utility `since@2.0`
284
+ #### * `toString():string`
250
285
 
251
286
  ```js
252
287
  // Retrieve full-name values as a string
@@ -287,7 +322,7 @@ engine.version; // "28.0.1500.95"
287
322
  engine.toString(); // "Blink 28.0.1500.95"
288
323
  ```
289
324
 
290
- #### * `withClientHints():Promise<object>|Thenable<object>|object` `since@2.0`
325
+ #### * `withClientHints():Promise<IData>|Thenable<IData>|IData`
291
326
 
292
327
  Recently, Chrome limits the information exposed through user-agent and introduces a new experimental set of data called "client-hints". In browser-environment, obtaining the client-hints data via JavaScript must be done in an asynchronous way. In `UAParser` you can chain the result object from `get*` method with `withClientHints()` to also read the client-hints data from the browser and return the updated data as a `Promise`.
293
328
 
@@ -346,6 +381,21 @@ new UAParser(request.headers)
346
381
  });
347
382
  ```
348
383
 
384
+ #### * `withFeatureCheck():IData`
385
+
386
+ This method allows us to examine other features beyond `navigator.userAgent` to further improve detection of the following:
387
+ - browser : Brave (check for `navigator.isBrave`)
388
+ - device : iPad (check for `navigator.standalone` & `navigator.maxTouchPoints`)
389
+
390
+ ```js
391
+ // suppose this code runs on iPad
392
+ const withoutFeatureCheck = UAParser();
393
+ const withFeatureCheck = UAParser().withFeatureCheck();
394
+
395
+ console.log(withoutFeatureCheck.device); // { vendor : "Apple", model : "Macintosh", type : undefined }
396
+ console.log(withFeatureCheck.device); // { vendor : "Apple", model : "iPad", type : "tablet" }
397
+ ```
398
+
349
399
  ## Extending Regex
350
400
 
351
401
  If you want to detect something that's not currently provided by UAParser.js (eg: `bots`, specific apps, etc), you can pass a list of regexes to extend internal UAParser.js regexes with your own.
@@ -1,10 +1,12 @@
1
1
  ///////////////////////////////////////////////
2
- /* Enums for UAParser.js v2.0.0-alpha.2
2
+ /* Enums for UAParser.js v2.0.0-alpha.3
3
3
  https://github.com/faisalman/ua-parser-js
4
4
  Author: Faisal Salman <f@faisalman.com>
5
5
  MIT License */
6
6
  //////////////////////////////////////////////
7
7
 
8
+ /*jshint esversion: 6 */
9
+
8
10
  const BrowserName = Object.freeze({
9
11
  CHROME : 'Chrome',
10
12
  EDGE : 'Edge',
@@ -98,4 +100,4 @@ module.exports = {
98
100
  DeviceVendor,
99
101
  EngineName,
100
102
  OSName
101
- }
103
+ };
@@ -1,14 +1,16 @@
1
1
  // Generated ESM version of UAParser.js enums
2
2
  // DO NOT EDIT THIS FILE!
3
- // Source: /src/enum/ua-parser-enum.js
3
+ // Source: /src/enums/ua-parser-enums.js
4
4
 
5
5
  ///////////////////////////////////////////////
6
- /* Enums for UAParser.js v2.0.0-alpha.2
6
+ /* Enums for UAParser.js v2.0.0-alpha.3
7
7
  https://github.com/faisalman/ua-parser-js
8
8
  Author: Faisal Salman <f@faisalman.com>
9
9
  MIT License */
10
10
  //////////////////////////////////////////////
11
11
 
12
+ /*jshint esversion: 6 */
13
+
12
14
  const BrowserName = Object.freeze({
13
15
  CHROME : 'Chrome',
14
16
  EDGE : 'Edge',
@@ -102,4 +104,4 @@ export {
102
104
  DeviceVendor,
103
105
  EngineName,
104
106
  OSName
105
- }
107
+ };
@@ -0,0 +1,248 @@
1
+ ///////////////////////////////////////////////
2
+ /* Extensions for UAParser.js v2.0.0-alpha.3
3
+ https://github.com/faisalman/ua-parser-js
4
+ Author: Faisal Salman <f@faisalman.com>
5
+ MIT License */
6
+ //////////////////////////////////////////////
7
+
8
+ /*jshint esversion: 6 */
9
+
10
+ const MODEL = 'model';
11
+ const NAME = 'name';
12
+ const TYPE = 'type';
13
+ const VENDOR = 'vendor';
14
+ const VERSION = 'version';
15
+ const MOBILE = 'mobile';
16
+ const TABLET = 'tablet';
17
+
18
+ const Apps = Object.freeze({
19
+ browser : [
20
+ [/chatlyio\/([\d\.]+)/i], [VERSION, 'Slack', [TYPE, 'app']]
21
+ ]
22
+ });
23
+
24
+ const Bots = Object.freeze({
25
+ browser : [
26
+ // Googlebot / BingBot / MSNBot / FacebookBot
27
+ [/((?:google|bing|msn|facebook)bot(?:[\-imagevdo]{0,6})|bingpreview)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']],
28
+
29
+ // GPTBot - https://platform.openai.com/docs/gptbot
30
+ [/(gptbot)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']],
31
+
32
+ // Slackbot - https://api.slack.com/robots
33
+ [/(slack(?:bot)?(?:-imgproxy|-linkexpanding)?) ([\w\.]+)/i], [NAME, VERSION, [TYPE, 'bot']]
34
+ ]
35
+ });
36
+
37
+ const CLIs = Object.freeze({
38
+ browser : [
39
+ // wget / curl / lynx
40
+ [/(wget|curl|lynx)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'cli']]
41
+ ]
42
+ });
43
+
44
+ const ExtraDevices = Object.freeze({
45
+ device : [[
46
+ /(nook)[\w ]+build\/(\w+)/i, // Nook
47
+ /(dell) (strea[kpr\d ]*[\dko])/i, // Dell Streak
48
+ /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, // Le Pan Tablets
49
+ /(trinity)[- ]*(t\d{3}) bui/i, // Trinity Tablets
50
+ /(gigaset)[- ]+(q\w{1,9}) bui/i, // Gigaset Tablets
51
+ /(vodafone) ([\w ]+)(?:\)| bui)/i // Vodafone
52
+ ], [VENDOR, MODEL, [TYPE, TABLET]], [
53
+
54
+ /(u304aa)/i // AT&T
55
+ ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [
56
+
57
+ /\bsie-(\w*)/i // Siemens
58
+ ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [
59
+
60
+ /\b(rct\w+) b/i // RCA Tablets
61
+ ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [
62
+
63
+ /\b(venue[\d ]{2,7}) b/i // Dell Venue Tablets
64
+ ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [
65
+
66
+ /\b(q(?:mv|ta)\w+) b/i // Verizon Tablet
67
+ ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [
68
+
69
+ /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i // Barnes & Noble Tablet
70
+ ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [
71
+
72
+ /\b(tm\d{3}\w+) b/i
73
+ ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [
74
+
75
+ /\b(k88) b/i // ZTE K Series Tablet
76
+ ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [
77
+
78
+ /\b(nx\d{3}j) b/i // ZTE Nubia
79
+ ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [
80
+
81
+ /\b(gen\d{3}) b.+49h/i // Swiss GEN Mobile
82
+ ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [
83
+
84
+ /\b(zur\d{3}) b/i // Swiss ZUR Tablet
85
+ ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [
86
+
87
+ /\b((zeki)?tb.*\b) b/i // Zeki Tablets
88
+ ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [
89
+
90
+ /\b([yr]\d{2}) b/i,
91
+ /\b(?:dragon[- ]+touch |dt)(\w{5}) b/i // Dragon Touch Tablet
92
+ ], [MODEL, [VENDOR, 'Dragon Touch'], [TYPE, TABLET]], [
93
+
94
+ /\b(ns-?\w{0,9}) b/i // Insignia Tablets
95
+ ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [
96
+
97
+ /\b((nxa|next)-?\w{0,9}) b/i // NextBook Tablets
98
+ ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [
99
+
100
+ /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones
101
+ ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [
102
+
103
+ /\b(lvtel\-)?(v1[12]) b/i // LvTel Phones
104
+ ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [
105
+
106
+ /\b(ph-1) /i // Essential PH-1
107
+ ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [
108
+
109
+ /\b(v(100md|700na|7011|917g).*\b) b/i // Envizen Tablets
110
+ ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [
111
+
112
+ /\b(trio[-\w\. ]+) b/i // MachSpeed Tablets
113
+ ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [
114
+
115
+ /\btu_(1491) b/i // Rotor Tablets
116
+ ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]]
117
+ ]
118
+ });
119
+
120
+ const Emails = Object.freeze({
121
+ browser : [
122
+ // Microsoft Outlook / Thunderbird
123
+ [/(microsoft outlook|thunderbird)[\s\/]([\w\.]+)/i], [NAME, VERSION, [TYPE, 'email']]
124
+ ]
125
+ });
126
+
127
+ const MediaPlayers = Object.freeze({
128
+ browser : [[
129
+
130
+ /(apple(?:coremedia|))\/([\w\._]+)/i, // Generic Apple CoreMedia
131
+ /(coremedia) v([\w\._]+)/i
132
+ ], [NAME, VERSION], [
133
+
134
+ /(aqualung|lyssna|bsplayer)\/([\w\.-]+)/i // Aqualung/Lyssna/BSPlayer
135
+ ], [NAME, VERSION], [
136
+
137
+ /(ares|ossproxy)\s([\w\.-]+)/i // Ares/OSSProxy
138
+ ], [NAME, VERSION], [
139
+
140
+ /(audacious|audimusicstream|amarok|bass|core|dalvik|gnomemplayer|music on console|nsplayer|psp-internetradioplayer|videos)\/([\w\.-]+)/i,
141
+ // Audacious/AudiMusicStream/Amarok/BASS/OpenCORE/Dalvik/GnomeMplayer/MoC
142
+ // NSPlayer/PSP-InternetRadioPlayer/Videos
143
+ /(clementine|music player daemon)\s([\w\.-]+)/i, // Clementine/MPD
144
+ /(lg player|nexplayer)\s([\d\.]+)/i,
145
+ /player\/(nexplayer|lg player)\s([\w\.-]+)/i // NexPlayer/LG Player
146
+ ], [NAME, VERSION], [
147
+ /(nexplayer)\s([\w\.-]+)/i // Nexplayer
148
+ ], [NAME, VERSION], [
149
+
150
+ /(flrp)\/([\w\.-]+)/i // Flip Player
151
+ ], [[NAME, 'Flip Player'], VERSION], [
152
+
153
+ /(fstream|nativehost|queryseekspider|ia-archiver|facebookexternalhit)/i
154
+ // FStream/NativeHost/QuerySeekSpider/IA Archiver/facebookexternalhit
155
+ ], [NAME], [
156
+
157
+ /(gstreamer) souphttpsrc.+libsoup\/([\w\.-]+)/i
158
+ // Gstreamer
159
+ ], [NAME, VERSION], [
160
+
161
+ /(htc streaming player)\s[\w_]+\s\/\s([\d\.]+)/i, // HTC Streaming Player
162
+ /(java|python-urllib|python-requests|wget|libcurl)\/([\w\.-_]+)/i,
163
+ // Java/urllib/requests/wget/cURL
164
+ /(lavf)([\d\.]+)/i // Lavf (FFMPEG)
165
+ ], [NAME, VERSION], [
166
+
167
+ /(htc_one_s)\/([\d\.]+)/i, // HTC One S
168
+ ], [[NAME, /_/g, ' '], VERSION], [
169
+
170
+ /(mplayer)(?:\s|\/)(?:(?:sherpya-){0,1}svn)(?:-|\s)(r\d+(?:-\d+[\w\.-]+))/i,
171
+ // MPlayer SVN
172
+ ], [NAME, VERSION], [
173
+
174
+ /(mplayer)(?:\s|\/)([\w\.-]+)/i, // MPlayer
175
+ /(mplayer) unknown-([\w\.\-]+)/i // MPlayer UNKNOWN
176
+ ], [NAME, VERSION], [
177
+
178
+ /(mplayer)/i, // MPlayer (no other info)
179
+ /(yourmuze)/i, // YourMuze
180
+ /(media player classic|nero showtime)/i // Media Player Classic/Nero ShowTime
181
+ ], [NAME], [
182
+
183
+ /(nero (?:home|scout))\/([\w\.-]+)/i // Nero Home/Nero Scout
184
+ ], [NAME, VERSION], [
185
+
186
+ /(nokia\d+)\/([\w\.-]+)/i // Nokia
187
+ ], [NAME, VERSION], [
188
+
189
+ /\s(songbird)\/([\w\.-]+)/i // Songbird/Philips-Songbird
190
+ ], [NAME, VERSION], [
191
+
192
+ /(winamp)3 version ([\w\.-]+)/i, // Winamp
193
+ /(winamp)\s([\w\.-]+)/i,
194
+ /(winamp)mpeg\/([\w\.-]+)/i
195
+ ], [NAME, VERSION], [
196
+
197
+ /(ocms-bot|tapinradio|tunein radio|unknown|winamp|inlight radio)/i // OCMS-bot/tap in radio/tunein/unknown/winamp (no other info)
198
+ // inlight radio
199
+ ], [NAME], [
200
+
201
+ /(quicktime|rma|radioapp|radioclientapplication|soundtap|totem|stagefright|streamium)\/([\w\.-]+)/i
202
+ // QuickTime/RealMedia/RadioApp/RadioClientApplication/
203
+ // SoundTap/Totem/Stagefright/Streamium
204
+ ], [NAME, VERSION], [
205
+
206
+ /(smp)([\d\.]+)/i // SMP
207
+ ], [NAME, VERSION], [
208
+
209
+ /(vlc) media player - version ([\w\.]+)/i, // VLC Videolan
210
+ /(vlc)\/([\w\.-]+)/i,
211
+ /(xbmc|gvfs|xine|xmms|irapp)\/([\w\.-]+)/i, // XBMC/gvfs/Xine/XMMS/irapp
212
+ /(foobar2000)\/([\d\.]+)/i, // Foobar2000
213
+ /(itunes)\/([\d\.]+)/i // iTunes
214
+ ], [NAME, VERSION], [
215
+
216
+ /(wmplayer)\/([\w\.-]+)/i, // Windows Media Player
217
+ /(windows-media-player)\/([\w\.-]+)/i
218
+ ], [[NAME, /-/g, ' '], VERSION], [
219
+
220
+ /windows\/([\w\.-]+) upnp\/[\d\.]+ dlnadoc\/[\d\.]+ (home media server)/i,
221
+ // Windows Media Server
222
+ ], [VERSION, [NAME, 'Windows']], [
223
+
224
+ /(com\.riseupradioalarm)\/([\d\.]*)/i // RiseUP Radio Alarm
225
+ ], [NAME, VERSION], [
226
+
227
+ /(rad.io)\s([\d\.]+)/i, // Rad.io
228
+ /(radio.(?:de|at|fr))\s([\d\.]+)/i
229
+ ], [[NAME, 'rad.io'], VERSION]
230
+ ]
231
+ });
232
+
233
+ const Modules = Object.freeze({
234
+ browser : [
235
+ // Axios/jsdom/Scrapy
236
+ [/\b(axios|jsdom|scrapy)\/([\w\.]+)/i], [NAME, VERSION, [TYPE, 'module']]
237
+ ]
238
+ });
239
+
240
+ module.exports = {
241
+ Apps,
242
+ Bots,
243
+ CLIs,
244
+ ExtraDevices,
245
+ Emails,
246
+ MediaPlayers,
247
+ Modules
248
+ };