@hyperwatch/useragent 3.9.3 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,14 @@
1
+ // Installs the Git hooks (npm's prepare script), except where Husky isn't
2
+ // wanted (production, CI) or isn't installed (npm install --omit=dev)
3
+ if (process.env.NODE_ENV === 'production' || process.env.CI === 'true') {
4
+ process.exit(0);
5
+ }
6
+
7
+ try {
8
+ const { default: husky } = await import('husky');
9
+ console.log(husky());
10
+ } catch (error) {
11
+ if (error.code !== 'ERR_MODULE_NOT_FOUND') {
12
+ throw error;
13
+ }
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperwatch/useragent",
3
- "version": "3.9.3",
3
+ "version": "4.0.0",
4
4
  "description": "User Agent parser",
5
5
  "license": "Apache-2.0",
6
6
  "author": "François Hodierne <francois@hodierne.net>",
@@ -9,46 +9,52 @@
9
9
  "url": "https://github.com/hyperwatch/useragent.git"
10
10
  },
11
11
  "main": "src/useragent.js",
12
+ "files": [
13
+ ".husky/install.mjs",
14
+ "regexes/*.json",
15
+ "regexes/index.js",
16
+ "src"
17
+ ],
12
18
  "scripts": {
13
19
  "depcheck": "depcheck",
14
- "lint": "eslint '**/*.js'",
15
- "lint:fix": "eslint '**/*.js' --fix",
16
- "test": "mocha --recursive",
20
+ "lint": "eslint",
21
+ "lint:fix": "eslint --fix",
22
+ "prepare": "node .husky/install.mjs",
17
23
  "prettier": "prettier \"**/*.@(js|json|md|yml)\"",
18
24
  "prettier:check": "npm run prettier -- --list-different",
19
25
  "prettier:write": "npm run prettier -- --write",
26
+ "test": "mocha --recursive",
20
27
  "update": "node scripts/update && npm run prettier:write"
21
28
  },
22
29
  "dependencies": {
23
- "debug": "^4.3.4",
24
- "lodash": "^4.17.21"
30
+ "debug": "^4.4.3",
31
+ "lodash": "^4.18.1"
25
32
  },
26
33
  "devDependencies": {
27
- "depcheck": "^1.4.3",
28
- "eslint": "^8.25.0",
29
- "eslint-plugin-import": "^2.26.0",
30
- "eslint-plugin-node": "^11.1.0",
31
- "husky": "^4.3.0",
32
- "lint-staged": "^11.1.1",
33
- "mocha": "^10.0.0",
34
- "node-fetch": "^2.6.7",
35
- "prettier": "^2.7.1",
36
- "prettier-package-json": "^2.7.0",
34
+ "@eslint/js": "^10.0.1",
35
+ "depcheck": "^1.4.7",
36
+ "eslint": "^10.12.0",
37
+ "eslint-plugin-import-x": "^4.17.1",
38
+ "eslint-plugin-n": "^18.4.1",
39
+ "globals": "^17.13.0",
40
+ "husky": "^9.1.7",
41
+ "lint-staged": "^17.6.0",
42
+ "mocha": "^12.0.3",
43
+ "prettier": "^3.9.9",
44
+ "prettier-package-json": "^2.8.0",
37
45
  "yamlparser": "0.0.2"
38
46
  },
39
47
  "engines": {
40
- "node": ">=12.0"
48
+ "node": ">=24"
49
+ },
50
+ "allowScripts": {
51
+ "unrs-resolver": false
41
52
  },
42
53
  "depcheck": {
43
54
  "ignores": [
44
55
  "prettier-package-json"
45
56
  ]
46
57
  },
47
- "husky": {
48
- "hooks": {
49
- "pre-commit": "lint-staged"
50
- }
51
- },
52
58
  "lint-staged": {
53
59
  "*.{js,json,md,yml}": [
54
60
  "prettier --write"
package/regexes/core.json CHANGED
@@ -209,9 +209,15 @@
209
209
  {
210
210
  "regex": "(\\w+[\\w \\-\\.]{0,50})\\/(\\d+)?\\.?(\\d+)?\\.?(\\d+)?[\\w~\\-\\+\\. ]*; ?\\+?https?:\\/\\/[A-Za-z0-9\\-\\.\\/]{0,50}"
211
211
  },
212
+ {
213
+ "regex": "^(\\w+[\\w\\-\\.]{0,50})/[A-Za-z]{1,10}\\-(\\d+)\\.(\\d+)\\.?(\\d+)?"
214
+ },
212
215
  {
213
216
  "regex": "^(\\w+[\\w \\-\\.:\\w]{0,50})\\/v?(\\d+)\\.?(\\d+)?\\.?(\\d+)?\\.?(\\d+)?"
214
217
  },
218
+ {
219
+ "regex": "^(\\w+[\\w\\-\\.]{0,50}?)\\-(?:(?=\\d*[a-f])[0-9a-f]{8}|[0-9a-f]{8}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{4}\\-[0-9a-f]{12})$"
220
+ },
215
221
  {
216
222
  "regex": "^(\\w+[\\w \\-\\.:\\w]{0,50})\\-v?(\\d+)\\.?(\\d+)?\\.?(\\d+)?\\.?(\\d+)?"
217
223
  },
@@ -281,6 +287,9 @@
281
287
  }
282
288
  ],
283
289
  "mozilla5": [
290
+ {
291
+ "regex": "^Mozilla/5\\.0 \\([^()]{1,100}\\) (\\w+[\\w\\-\\.]{0,50})/(\\d+)\\.?(\\d+)?\\.?(\\d+)?$"
292
+ },
284
293
  {
285
294
  "regex": "Mozilla/5.0 ([\\w]+[\\w \\-\\.[\\w]+]{0,50})\\/?(\\d+)?\\.?(\\d+)?"
286
295
  },
@@ -112,6 +112,10 @@
112
112
  "regex": "(PingdomTMS)/(\\d+)\\.(\\d+)\\.(\\d+)",
113
113
  "family_replacement": "PingdomBot"
114
114
  },
115
+ {
116
+ "regex": "(PingdomPageSpeed)/(\\d+)\\.(\\d+)",
117
+ "family_replacement": "PingdomBot"
118
+ },
115
119
  {
116
120
  "regex": " (PTST)/(\\d+)(?:\\.(\\d+)|)$",
117
121
  "family_replacement": "WebPageTest.org bot"
@@ -123,6 +127,10 @@
123
127
  "regex": "(NewRelicPinger)/(\\d+)\\.(\\d+)",
124
128
  "family_replacement": "NewRelicPingerBot"
125
129
  },
130
+ {
131
+ "regex": "(RuxitSynthetic)/(\\d+)\\.(\\d+)",
132
+ "family_replacement": "Ruxit Synthetic"
133
+ },
126
134
  {
127
135
  "regex": "(Tableau)/(\\d+)\\.(\\d+)",
128
136
  "family_replacement": "Tableau"
@@ -179,10 +187,10 @@
179
187
  "family_replacement": "Pinterestbot"
180
188
  },
181
189
  {
182
- "regex": "(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\\/\\$BotVersion|123metaspider-Bot|1470\\.net crawler|50\\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\\b\\w{0,30}favicon\\w{0,30}\\b|\\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\\(S\\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|OgScrper|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PHPCrawl|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\\.ru|Tiny Tiny RSS|Twitterbot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\\.almaden\\.ibm\\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\\.ze\\.bz|ZooShot|ZyBorg|ArcGIS Hub Indexer)(?:[ /]v?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)|)"
190
+ "regex": "(CSimpleSpider|Cityreview Robot|CrawlDaddy|CrawlFire|Finderbots|Index crawler|Job Roboter|KiwiStatus Spider|Lijit Crawler|QuerySeekerSpider|ScollSpider|Trends Crawler|USyd-NLP-Spider|SiteCat Webbot|BotName\\/\\$BotVersion|123metaspider-Bot|1470\\.net crawler|50\\.nu|8bo Crawler Bot|Aboundex|Accoona-[A-z]{1,30}-Agent|AdsBot-Google(?:-[a-z]{1,30}|)|altavista|AppEngine-Google|archive.{0,30}\\.org_bot|archiver|Ask Jeeves|[Bb]ai[Dd]u[Ss]pider(?:-[A-Za-z]{1,30})(?:-[A-Za-z]{1,30}|)|bingbot|BingPreview|blitzbot|BlogBridge|Bloglovin|BoardReader Blog Indexer|BoardReader Favicon Fetcher|boitho.com-dc|BotSeer|BUbiNG|\\b\\w{0,30}favicon\\w{0,30}\\b|\\bYeti(?:-[a-z]{1,30}|)|Catchpoint(?: bot|)|[Cc]harlotte|Checklinks|clumboot|Comodo HTTP\\(S\\) Crawler|Comodo-Webinspector-Crawler|ConveraCrawler|CRAWL-E|CrawlConvera|Daumoa(?:-feedfetcher|)|Feed Seeker Bot|Feedbin|findlinks|Flamingo_SearchEngine|FollowSite Bot|furlbot|Genieo|gigabot|GomezAgent|gonzo1|(?:[a-zA-Z]{1,30}-|)Googlebot(?:-[a-zA-Z]{1,30}|)|GoogleOther|Google SketchUp|grub-client|gsa-crawler|heritrix|HiddenMarket|holmes|HooWWWer|htdig|ia_archiver|ICC-Crawler|Icarus6j|ichiro(?:/mobile|)|IconSurf|IlTrovatore(?:-Setaccio|)|InfuzApp|Innovazion Crawler|InternetArchive|IP2[a-z]{1,30}Bot|jbot\\b|KaloogaBot|Kraken|Kurzor|larbin|LEIA|LesnikBot|Linguee Bot|LinkAider|LinkedInBot|Lite Bot|Llaut|lycos|Mail\\.RU_Bot|masscan|masidani_bot|Mediapartners-Google|Microsoft .{0,30} Bot|mogimogi|mozDex|MJ12bot|msnbot(?:-media {0,2}|)|msrbot|Mtps Feed Aggregation System|netresearch|Netvibes|NewsGator[^/]{0,30}|^NING|Nutch[^/]{0,30}|Nymesis|ObjectsSearch|OgScrper|Orbiter|OOZBOT|PagePeeker|PagesInventory|PaxleFramework|Peeplo Screenshot Bot|PHPCrawl|PlantyNet_WebRobot|Pompos|Qwantify|Read%20Later|Reaper|RedCarpet|Retreiver|Riddler|Rival IQ|scooter|Scrapy|Scrubby|searchsight|seekbot|semanticdiscovery|SemrushBot|Simpy|SimplePie|SEOstats|SimpleRSS|SiteCon|Slackbot-LinkExpanding|Slack-ImgProxy|Slurp|snappy|Speedy Spider|Squrl Java|Stringer|TheUsefulbot|ThumbShotsBot|Thumbshots\\.ru|Tiny Tiny RSS|Twitterbot|WhatsApp|URL2PNG|Vagabondo|VoilaBot|^vortex|Votay bot|^voyager|WASALive.Bot|Web-sniffer|WebThumb|WeSEE:[A-z]{1,30}|WhatWeb|WIRE|WordPress|Wotbox|www\\.almaden\\.ibm\\.com|Xenu(?:.s|) Link Sleuth|Xerka [A-z]{1,30}Bot|yacy(?:bot|)|YahooSeeker|Yahoo! Slurp|Yandex\\w{1,30}|YodaoBot(?:-[A-z]{1,30}|)|YottaaMonitor|Yowedo|^Zao|^Zao-Crawler|ZeBot_www\\.ze\\.bz|ZooShot|ZyBorg|ArcGIS Hub Indexer|GPTBot|Google-InspectionTool)(?:[ /]v?(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)|)"
183
191
  },
184
192
  {
185
- "regex": "\\b(Boto3?|JetS3t|aws-(?:cli|sdk-(?:cpp|go|java|nodejs|ruby2?|dotnet-(?:\\d{1,2}|core)))|s3fs)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
193
+ "regex": "\\b(Boto3?|JetS3t|aws-(?:cli|sdk-(?:cpp|go|go-v\\d|java|nodejs|ruby2?|dotnet-(?:\\d{1,2}|core)))|s3fs)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
186
194
  },
187
195
  {
188
196
  "regex": "(FME)\\/(\\d+\\.\\d+)\\.(\\d+)\\.(\\d+)"
@@ -208,6 +216,9 @@
208
216
  "regex": "\\[FB.{0,300};",
209
217
  "family_replacement": "Facebook"
210
218
  },
219
+ {
220
+ "regex": "(RecipeRadar)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
221
+ },
211
222
  {
212
223
  "regex": "^.{0,200}?(?:\\/[A-Za-z0-9\\.]{0,50}|) {0,2}([A-Za-z0-9 \\-_\\!\\[\\]:]{0,50}(?:[Aa]rchiver|[Ii]ndexer|[Ss]craper|[Bb]ot|[Ss]pider|[Cc]rawl[a-z]{0,50}))[/ ](\\d+)(?:\\.(\\d+)(?:\\.(\\d+)|)|)"
213
224
  },
@@ -236,6 +247,9 @@
236
247
  {
237
248
  "regex": "Mozilla.{1,200}Mobile.{1,100}(Instagram).(\\d+)\\.(\\d+)\\.(\\d+)"
238
249
  },
250
+ {
251
+ "regex": "(Instagram) (\\d+)\\.(\\d+)\\.(\\d+)"
252
+ },
239
253
  {
240
254
  "regex": "Mozilla.{1,200}Mobile.{1,100}(Flipboard).(\\d+)\\.(\\d+)\\.(\\d+)"
241
255
  },
@@ -253,15 +267,35 @@
253
267
  "family_replacement": "Twitter"
254
268
  },
255
269
  {
256
- "regex": "Mozilla.{1,200}Mobile.{1,100}(Phantom\\/ios|android).(\\d+)\\.(\\d+)\\.(\\d+)",
270
+ "regex": "(musical_ly) app_version\\/(\\d+)\\.(\\d+)\\.(\\d+)",
271
+ "family_replacement": "TikTok"
272
+ },
273
+ {
274
+ "regex": "(musical_ly_)(\\d+)\\.(\\d+)\\.(\\d+)",
275
+ "family_replacement": "TikTok"
276
+ },
277
+ {
278
+ "regex": "(BytedanceWebview)\\/[a-z0-9]+",
279
+ "family_replacement": "TikTok"
280
+ },
281
+ {
282
+ "regex": "Mozilla.{1,200}Mobile.{1,100}(KAKAOTALK)/(\\d+)\\.(\\d+)\\.(\\d+)",
283
+ "family_replacement": "KakaoTalk"
284
+ },
285
+ {
286
+ "regex": "(Telegram-Android)/(\\d+)\\.(\\d+)\\.(\\d+)",
287
+ "family_replacement": "Telegram"
288
+ },
289
+ {
290
+ "regex": "Mozilla.{1,200}Mobile.{1,100}(Phantom\\/ios|Phantom\\/android).(\\d+)\\.(\\d+)\\.(\\d+)",
257
291
  "family_replacement": "Phantom"
258
292
  },
259
293
  {
260
- "regex": "Mozilla.{1,100}Mobile.{1,100}AspiegelBot",
294
+ "regex": "Mozilla.{1,100}Mobile.{1,100}(AspiegelBot|PetalBot)",
261
295
  "family_replacement": "Spider"
262
296
  },
263
297
  {
264
- "regex": "AspiegelBot",
298
+ "regex": "AspiegelBot|PetalBot",
265
299
  "family_replacement": "Spider"
266
300
  },
267
301
  {
@@ -272,6 +306,9 @@
272
306
  "regex": "(PaleMoon)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
273
307
  "family_replacement": "Pale Moon"
274
308
  },
309
+ {
310
+ "regex": "(Camoufox) Camoufox (\\d+)\\.(\\d+)"
311
+ },
275
312
  {
276
313
  "regex": "(Fennec)/(\\d+)\\.(\\d+)\\.?([ab]?\\d+[a-z]*)",
277
314
  "family_replacement": "Firefox Mobile"
@@ -346,7 +383,7 @@
346
383
  "family_replacement": "My Internet Browser"
347
384
  },
348
385
  {
349
- "regex": "(UC? ?Browser|UCWEB|U3)[ /]?(\\d+)\\.(\\d+)\\.(\\d+)",
386
+ "regex": "(UC? ?Browser|UCWEB|UCMobile|U3)[ /]?(\\d+)\\.(\\d+)\\.(\\d+)",
350
387
  "family_replacement": "UC Browser"
351
388
  },
352
389
  {
@@ -382,6 +419,14 @@
382
419
  "regex": "(?:Chrome).{1,300}(OPR)/(\\d+)\\.(\\d+)\\.(\\d+)",
383
420
  "family_replacement": "Opera"
384
421
  },
422
+ {
423
+ "regex": "(OPX)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
424
+ "family_replacement": "Opera GX"
425
+ },
426
+ {
427
+ "regex": "(OPT)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
428
+ "family_replacement": "Opera Touch"
429
+ },
385
430
  {
386
431
  "regex": "(Coast)/(\\d+).(\\d+).(\\d+)",
387
432
  "family_replacement": "Opera Coast"
@@ -466,6 +511,33 @@
466
511
  "regex": "(Nintendo 3DS)",
467
512
  "family_replacement": "NetFront NX"
468
513
  },
514
+ {
515
+ "regex": "(HuaweiBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.\\d+",
516
+ "family_replacement": "Huawei Browser"
517
+ },
518
+ {
519
+ "regex": "(AVG)/(\\d+)\\.(\\d+)\\.(\\d+)\\.\\d+",
520
+ "family_replacement": "AVG"
521
+ },
522
+ {
523
+ "regex": "(AvastSecureBrowser|Avast)/(\\d+)\\.(\\d+)\\.(\\d+)",
524
+ "family_replacement": "Avast Secure Browser"
525
+ },
526
+ {
527
+ "regex": "(Instabridge)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"
528
+ },
529
+ {
530
+ "regex": "(AlohaBrowser|ABB)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
531
+ "family_replacement": "Aloha Browser"
532
+ },
533
+ {
534
+ "regex": "((?:B|b)rave(?:\\sChrome)?)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
535
+ "family_replacement": "Brave"
536
+ },
537
+ {
538
+ "regex": "(?:\\()?Brave(?:\\))?\\s*$",
539
+ "family_replacement": "Brave"
540
+ },
469
541
  {
470
542
  "regex": "(Silk)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+)|)",
471
543
  "family_replacement": "Amazon Silk"
@@ -478,9 +550,13 @@
478
550
  "family_replacement": "Edge Mobile"
479
551
  },
480
552
  {
481
- "regex": "(EdgiOS|EdgA)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
553
+ "regex": "(EdgiOS|EdgA)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
482
554
  "family_replacement": "Edge Mobile"
483
555
  },
556
+ {
557
+ "regex": "(OculusBrowser)/(\\d+)\\.(\\d+)(?:\\.([0-9\\-]+)|)",
558
+ "family_replacement": "Oculus Browser"
559
+ },
484
560
  {
485
561
  "regex": "(SamsungBrowser)/(\\d+)\\.(\\d+)",
486
562
  "family_replacement": "Samsung Internet"
@@ -493,14 +569,6 @@
493
569
  "regex": "(coc_coc_browser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
494
570
  "family_replacement": "Coc Coc"
495
571
  },
496
- {
497
- "regex": "(baidubrowser)[/\\s](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
498
- "family_replacement": "Baidu Browser"
499
- },
500
- {
501
- "regex": "(FlyFlow)/(\\d+)\\.(\\d+)",
502
- "family_replacement": "Baidu Explorer"
503
- },
504
572
  {
505
573
  "regex": "(MxBrowser)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
506
574
  "family_replacement": "Maxthon"
@@ -528,6 +596,14 @@
528
596
  "regex": "Mozilla.{1,200}Android.{1,200}(GSA)/(\\d+)\\.(\\d+)\\.(\\d+)",
529
597
  "family_replacement": "Google"
530
598
  },
599
+ {
600
+ "regex": "(baidubrowser)[/\\s](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
601
+ "family_replacement": "Baidu Browser"
602
+ },
603
+ {
604
+ "regex": "(FlyFlow|flyflow|baiduboxapp)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
605
+ "family_replacement": "Baidu Explorer"
606
+ },
531
607
  {
532
608
  "regex": "(MQQBrowser/Mini)(?:(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)",
533
609
  "family_replacement": "QQ Browser Mini"
@@ -541,13 +617,64 @@
541
617
  "family_replacement": "QQ Browser"
542
618
  },
543
619
  {
544
- "regex": "Mobile.{0,200}(DuckDuckGo)/(\\d+)",
620
+ "regex": "Mozilla.{1,200}Mobile.{1,100}(DuckDuckGo)/(\\d+)",
621
+ "family_replacement": "DuckDuckGo Mobile"
622
+ },
623
+ {
624
+ "regex": "Mozilla.{1,200}(DuckDuckGo)/(\\d+)",
625
+ "family_replacement": "DuckDuckGo"
626
+ },
627
+ {
628
+ "regex": "Mozilla.{1,200}Mobile.{1,100}(Ddg)/(\\d+)(?:\\.(\\d+)|)",
545
629
  "family_replacement": "DuckDuckGo Mobile"
546
630
  },
631
+ {
632
+ "regex": "Mozilla.{1,200}(Ddg)/(\\d+)(?:\\.(\\d+)|)",
633
+ "family_replacement": "DuckDuckGo"
634
+ },
547
635
  {
548
636
  "regex": "(Tenta/)(\\d+)\\.(\\d+)\\.(\\d+)",
549
637
  "family_replacement": "Tenta Browser"
550
638
  },
639
+ {
640
+ "regex": "(Ecosia) ios@(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
641
+ "family_replacement": "Ecosia iOS"
642
+ },
643
+ {
644
+ "regex": "(Ecosia) android@(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
645
+ "family_replacement": "Ecosia Android"
646
+ },
647
+ {
648
+ "regex": "(VivoBrowser)\\/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
649
+ },
650
+ {
651
+ "regex": "(H[Ii]Browser)\\/v(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
652
+ "family_replacement": "HiBrowser"
653
+ },
654
+ {
655
+ "regex": "(HonorBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
656
+ "family_replacement": "Honor Browser"
657
+ },
658
+ {
659
+ "regex": "(bdhonorbrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
660
+ "family_replacement": "Honor Browser"
661
+ },
662
+ {
663
+ "regex": "(HeyTapBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
664
+ "family_replacement": "HeyTap Browser"
665
+ },
666
+ {
667
+ "regex": "(weibo)__(\\d+)\\.(\\d+)\\.(\\d+)",
668
+ "family_replacement": "Weibo"
669
+ },
670
+ {
671
+ "regex": "(WeiboliteiOS|WeiboIntliOS)",
672
+ "family_replacement": "Weibo"
673
+ },
674
+ {
675
+ "regex": "(PHX)/(\\d+)\\.(\\d+)",
676
+ "family_replacement": "Phoenix Browser"
677
+ },
551
678
  {
552
679
  "regex": "Version/.{1,300}(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
553
680
  "family_replacement": "Chrome Mobile WebView"
@@ -561,7 +688,7 @@
561
688
  "family_replacement": "Chrome Mobile"
562
689
  },
563
690
  {
564
- "regex": "(CriOS)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
691
+ "regex": "(CriOS)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
565
692
  "family_replacement": "Chrome Mobile iOS"
566
693
  },
567
694
  {
@@ -598,6 +725,10 @@
598
725
  "regex": "(YaBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)",
599
726
  "family_replacement": "Yandex Browser"
600
727
  },
728
+ {
729
+ "regex": "(YaSearchBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)",
730
+ "family_replacement": "Yandex Browser"
731
+ },
601
732
  {
602
733
  "regex": "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+).{0,100} MRCHROME",
603
734
  "family_replacement": "Mail.ru Chromium Browser"
@@ -632,6 +763,131 @@
632
763
  "regex": "^(surveyon)/(\\d+)\\.(\\d+)\\.(\\d+)",
633
764
  "family_replacement": "Surveyon"
634
765
  },
766
+ {
767
+ "regex": "(115Browser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
768
+ "family_replacement": "115 Browser"
769
+ },
770
+ {
771
+ "regex": "(Avira)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
772
+ "family_replacement": "Avira"
773
+ },
774
+ {
775
+ "regex": "(CCleaner)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
776
+ "family_replacement": "CCleaner"
777
+ },
778
+ {
779
+ "regex": "(Norton)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
780
+ "family_replacement": "Norton"
781
+ },
782
+ {
783
+ "regex": "(Quark)/(\\d+)\\.(\\d+)\\.(\\d+)",
784
+ "family_replacement": "Quark"
785
+ },
786
+ {
787
+ "regex": "(QuarkPC)/(\\d+)\\.(\\d+)\\.(\\d+)",
788
+ "family_replacement": "Quark PC"
789
+ },
790
+ {
791
+ "regex": "(SLBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)",
792
+ "family_replacement": "Smart Lenovo Browser"
793
+ },
794
+ {
795
+ "regex": "(Atom)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
796
+ "family_replacement": "Atom Browser"
797
+ },
798
+ {
799
+ "regex": "(Chrome)/\\d+\\.\\d+\\.\\d+\\.\\d+ .* QIHU 360(?:SEi18n|ENT)",
800
+ "family_replacement": "360 Secure Browser"
801
+ },
802
+ {
803
+ "regex": "(Decentr)",
804
+ "family_replacement": "Decentr Web3 Browser"
805
+ },
806
+ {
807
+ "regex": "(Sparrow)",
808
+ "family_replacement": "Sparrow Browser"
809
+ },
810
+ {
811
+ "regex": "(Chromium GOST)",
812
+ "family_replacement": "Chromium GOST Browser"
813
+ },
814
+ {
815
+ "regex": "(AOLShield)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
816
+ "family_replacement": "AOL Shield Browser"
817
+ },
818
+ {
819
+ "regex": "(Hola)/(\\d+)\\.(\\d+)\\.(\\d+)",
820
+ "family_replacement": "Hola Browser"
821
+ },
822
+ {
823
+ "regex": "(CravingExplorer)/(\\d+)\\.(\\d+)\\.(\\d+)",
824
+ "family_replacement": "Craving Explorer Browser"
825
+ },
826
+ {
827
+ "regex": "(Talon)",
828
+ "family_replacement": "Talon Cyber Security Browser"
829
+ },
830
+ {
831
+ "regex": "(Qaxbrowser)",
832
+ "family_replacement": "QAX Browser"
833
+ },
834
+ {
835
+ "regex": "(ADG)/(\\d+)\\.(\\d+)\\.(\\d+)",
836
+ "family_replacement": "AOL Desktop Gold Browser"
837
+ },
838
+ {
839
+ "regex": "(SberBrowser)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
840
+ "family_replacement": "Sber Browser"
841
+ },
842
+ {
843
+ "regex": "(JiSu)/(\\d+)\\.(\\d+)\\.(\\d+)",
844
+ "family_replacement": "JiSu Browser"
845
+ },
846
+ {
847
+ "regex": "(Wolvic)/(\\d+)\\.(\\d+)\\.(\\d+)",
848
+ "family_replacement": "Wolvic Browser"
849
+ },
850
+ {
851
+ "regex": "(Thano)/(\\d+)\\.(\\d+)",
852
+ "family_replacement": "SmartTV WebBrowser"
853
+ },
854
+ {
855
+ "regex": "(MicroMessenger)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)",
856
+ "family_replacement": "WeChat Browser"
857
+ },
858
+ {
859
+ "regex": "(Odin)/(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)",
860
+ "family_replacement": "Odin"
861
+ },
862
+ {
863
+ "regex": "(Colt)/(\\d+)\\.(\\d+)",
864
+ "family_replacement": "NetCast Smart TV"
865
+ },
866
+ {
867
+ "regex": "(Lite Browser)/(\\d+)\\.(\\d+)",
868
+ "family_replacement": "Lite Browser"
869
+ },
870
+ {
871
+ "regex": "(OMI)/(\\d+)\\.(\\d+)\\.(\\d+)",
872
+ "family_replacement": "Vewd Browser"
873
+ },
874
+ {
875
+ "regex": "(Mypal)/(\\d+)\\.(\\d+)\\.(\\d+)",
876
+ "family_replacement": "Mypal Browser"
877
+ },
878
+ {
879
+ "regex": "(Chesscom-Android)/(\\d+)\\.(\\d+)\\.(\\d+)"
880
+ },
881
+ {
882
+ "regex": "(RobloxApp)/(\\d+)\\.(\\d+)\\.(\\d+)",
883
+ "family_replacement": "Roblox App"
884
+ },
885
+ {
886
+ "regex": "(Roadrunner)/IOS/\\d+/(\\d+)\\.(\\d+)\\.(\\d+)"
887
+ },
888
+ {
889
+ "regex": "(AncestryAndroid)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
890
+ },
635
891
  {
636
892
  "regex": "(Slack_SSB)/(\\d+)\\.(\\d+)\\.(\\d+)",
637
893
  "family_replacement": "Slack Desktop Client"
@@ -694,15 +950,15 @@
694
950
  "family_replacement": "Superhuman"
695
951
  },
696
952
  {
697
- "regex": "(Vivaldi)/(\\d+)\\.(\\d+)\\.(\\d+)"
953
+ "regex": "(Vivaldi)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"
698
954
  },
699
955
  {
700
- "regex": "(Edge?)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
701
- "family_replacement": "Edge"
956
+ "regex": ".{0,200}(Teams)/(\\d+)\\.(\\d+)\\.(\\d+)",
957
+ "family_replacement": "Microsoft Teams"
702
958
  },
703
959
  {
704
- "regex": "(brave)/(\\d+)\\.(\\d+)\\.(\\d+) Chrome",
705
- "family_replacement": "Brave"
960
+ "regex": "(Edge?)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)(?:\\.(\\d+)|)",
961
+ "family_replacement": "Edge"
706
962
  },
707
963
  {
708
964
  "regex": "(Chrome)/(\\d+)\\.(\\d+)\\.(\\d+)[\\d.]{0,100} Iron[^/]",
@@ -723,6 +979,67 @@
723
979
  {
724
980
  "regex": "(bingbot|Bolt|AdobeAIR|Jasmine|IceCat|Skyfire|Midori|Maxthon|Lynx|Arora|IBrowse|Dillo|Camino|Shiira|Fennec|Phoenix|Flock|Netscape|Lunascape|Epiphany|WebPilot|Opera Mini|Opera|NetFront|Netfront|Konqueror|Googlebot|SeaMonkey|Kazehakase|Vienna|Iceape|Iceweasel|IceWeasel|Iron|K-Meleon|Sleipnir|Galeon|GranParadiso|iCab|iTunes|MacAppStore|NetNewsWire|Space Bison|Stainless|Orca|Dolfin|BOLT|Minimo|Tizen Browser|Polaris|Abrowser|Planetweb|ICE Browser|mDolphin|qutebrowser|Otter|QupZilla|MailBar|kmail2|YahooMobileMail|ExchangeWebServices|ExchangeServicesClient|Dragon|Outlook-iOS-Android)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
725
981
  },
982
+ {
983
+ "regex": "(QtWebEngine)/(\\d+)\\.(\\d+)\\.(\\d+)",
984
+ "family_replacement": "Qt Web Engine"
985
+ },
986
+ {
987
+ "regex": "(OpenWave)/(\\d+)\\.(\\d+)\\.(\\d+)",
988
+ "family_replacement": "Open Wave"
989
+ },
990
+ {
991
+ "regex": "(AtContent)/(\\d+)\\.(\\d+)\\.(\\d+)"
992
+ },
993
+ {
994
+ "regex": "(Trailer)/(\\d+)\\.(\\d+)\\.(\\d+)"
995
+ },
996
+ {
997
+ "regex": "(Agency)/(\\d+)\\.(\\d+)\\.(\\d+)"
998
+ },
999
+ {
1000
+ "regex": "(Herring)/(\\d+)\\.(\\d+)\\.(\\d+)"
1001
+ },
1002
+ {
1003
+ "regex": "(Config)/(\\d+)\\.(\\d+)\\.(\\d+)"
1004
+ },
1005
+ {
1006
+ "regex": "(Viewer)/(\\d+)\\.(\\d+)\\.(\\d+)"
1007
+ },
1008
+ {
1009
+ "regex": "(LikeWise)/(\\d+)\\.(\\d+)\\.(\\d+)"
1010
+ },
1011
+ {
1012
+ "regex": "(Unique)/(\\d+)\\.(\\d+)\\.(\\d+)"
1013
+ },
1014
+ {
1015
+ "regex": "(CitizenFX)/(\\d+)\\.(\\d+)\\.(\\d+)"
1016
+ },
1017
+ {
1018
+ "regex": "(R2Client)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
1019
+ },
1020
+ {
1021
+ "regex": "(OBS)/(\\d+)\\.(\\d+)\\.(\\d+)",
1022
+ "family_replacement": "OBS Studio"
1023
+ },
1024
+ {
1025
+ "regex": "(AdobeCEP)/(\\d+)\\.(\\d+)\\.(\\d+)",
1026
+ "family_replacement": "Adobe CEP"
1027
+ },
1028
+ {
1029
+ "regex": "Valve Steam (GameOverlay).{1,200}Chrome/(\\d+)\\.(\\d+)\\.(\\d+)",
1030
+ "family_replacement": "Steam GameOverlay"
1031
+ },
1032
+ {
1033
+ "regex": "Valve Steam (Gamepad)/Steam Deck.{1,200}Chrome/(\\d+)\\.(\\d+)\\.(\\d+)",
1034
+ "family_replacement": "Steam Deck"
1035
+ },
1036
+ {
1037
+ "regex": "(Valve(?: Steam|) Client).{1,200}Chrome/(\\d+)\\.(\\d+)\\.(\\d+)",
1038
+ "family_replacement": "Steam Client"
1039
+ },
1040
+ {
1041
+ "regex": "(Ladybird)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)"
1042
+ },
726
1043
  {
727
1044
  "regex": "(Chromium|Chrome)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"
728
1045
  },
@@ -1151,7 +1468,7 @@
1151
1468
  "family_replacement": "Apple Mail"
1152
1469
  },
1153
1470
  {
1154
- "regex": "(Firefox)/(\\d+)\\.(\\d+)\\.(\\d+)"
1471
+ "regex": "(Firefox)/(\\d+)\\.(\\d+)(?:\\.(\\d+)|$)"
1155
1472
  },
1156
1473
  {
1157
1474
  "regex": "(Firefox)/(\\d+)\\.(\\d+)(pre|[ab]\\d+[a-z]*|)"
@@ -1165,7 +1482,7 @@
1165
1482
  "family_replacement": "Python Requests"
1166
1483
  },
1167
1484
  {
1168
- "regex": "\\b(Windows-Update-Agent|WindowsPowerShell|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|wget2|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia|fetch libfetch|akka-http|got|CloudCockpitBackend|ReactorNetty|axios|Jersey|Vert.x-WebClient|Apache-CXF|Go-CF-client|go-resty|AHC)(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"
1485
+ "regex": "\\b(Windows-Update-Agent|WindowsPowerShell|Microsoft-CryptoAPI|SophosUpdateManager|SophosAgent|Debian APT-HTTP|Ubuntu APT-HTTP|libcurl-agent|libwww-perl|urlgrabber|curl|PycURL|Wget|wget2|aria2|Axel|OpenBSD ftp|lftp|jupdate|insomnia|fetch libfetch|akka-http|got|CloudCockpitBackend|ReactorNetty|axios|Jersey|Vert.x-WebClient|Apache-CXF|Go-CF-client|go-resty|AHC|HTTPie)(?:[ /](\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)|)"
1169
1486
  },
1170
1487
  {
1171
1488
  "regex": "^(cf)\\/(\\d+)\\.(\\d+)\\.(\\S+)",
@@ -1195,7 +1512,10 @@
1195
1512
  "family_replacement": "Python aiohttp"
1196
1513
  },
1197
1514
  {
1198
- "regex": "(Java)[/ ]?\\d+\\.(\\d+)\\.(\\d+)[_-]*([a-zA-Z0-9]+|)"
1515
+ "regex": "(Java)[/ ]?\\d{1}\\.(\\d+)\\.(\\d+)[_-]*([a-zA-Z0-9]+|)"
1516
+ },
1517
+ {
1518
+ "regex": "(Java)[/ ]?(\\d+)\\.(\\d+)\\.(\\d+)"
1199
1519
  },
1200
1520
  {
1201
1521
  "regex": "(minio-go)/v(\\d+)\\.(\\d+)\\.(\\d+)"
@@ -1254,7 +1574,9 @@
1254
1574
  "regex": "\\b(HTTrack) (\\d+)\\.(\\d+)(?:[\\.\\-](\\d+)|)"
1255
1575
  },
1256
1576
  {
1257
- "regex": "SerenityOS",
1258
- "family_replacement": "SerenityOS Browser"
1577
+ "regex": "(Ladybird)\\/(\\d+)\\.(\\d+)"
1578
+ },
1579
+ {
1580
+ "regex": "(MullvadBrowser)/(\\d+)(?:\\.(\\d+)|)(?:\\.(\\d+)|)"
1259
1581
  }
1260
1582
  ]