device_detector 1.1.0 → 1.1.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +4 -4
- data/lib/device_detector/browser.rb +6 -0
- data/lib/device_detector/client_hint.rb +22 -7
- data/lib/device_detector/device.rb +231 -1
- data/lib/device_detector/parser.rb +25 -3
- data/lib/device_detector/vendor_fragment.rb +25 -0
- data/lib/device_detector/version.rb +1 -1
- data/lib/device_detector.rb +33 -2
- data/regexes/bots.yml +172 -10
- data/regexes/client/browsers.yml +35 -18
- data/regexes/client/hints/browsers.yml +5 -0
- data/regexes/client/libraries.yml +1 -1
- data/regexes/client/mobile_apps.yml +76 -2
- data/regexes/device/car_browsers.yml +1 -1
- data/regexes/device/consoles.yml +2 -2
- data/regexes/device/mobiles.yml +4333 -1090
- data/regexes/device/portable_media_player.yml +7 -1
- data/regexes/device/shell_tv.yml +5 -0
- data/regexes/oss.yml +71 -22
- metadata +4 -3
@@ -58,7 +58,29 @@ class DeviceDetector
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def load_regexes(file_paths)
|
61
|
-
file_paths.map
|
61
|
+
file_paths.map do |path, full_path|
|
62
|
+
object = YAML.load_file(full_path)
|
63
|
+
object = rewrite_device_object!(object) if is_device_yml_file?(full_path)
|
64
|
+
object = rewrite_vendor_object!(object) if is_vendor_yml_file?(full_path)
|
65
|
+
|
66
|
+
[path, symbolize_keys!(object)]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def is_device_yml_file?(file_path)
|
71
|
+
file_path.include?('/regexes/device/')
|
72
|
+
end
|
73
|
+
|
74
|
+
def is_vendor_yml_file?(file_path)
|
75
|
+
file_path.include?('/regexes/vendorfragments')
|
76
|
+
end
|
77
|
+
|
78
|
+
def rewrite_vendor_object!(object)
|
79
|
+
object.map { |key, values| values.map { |v| { 'regex_name' => key, 'regex' => v } } }.flatten
|
80
|
+
end
|
81
|
+
|
82
|
+
def rewrite_device_object!(object)
|
83
|
+
object.map { |key, value| [key, { 'regex_name' => key }.merge!(value)] }.to_h
|
62
84
|
end
|
63
85
|
|
64
86
|
def symbolize_keys!(object)
|
@@ -88,8 +110,8 @@ class DeviceDetector
|
|
88
110
|
Regexp.new('(?:^|[^A-Z0-9\-_]|[^A-Z0-9\-]_|sprd-|MZ-)(?:' + src + ')', Regexp::IGNORECASE)
|
89
111
|
end
|
90
112
|
|
91
|
-
def from_cache(key)
|
92
|
-
DeviceDetector.cache.get_or_set(key)
|
113
|
+
def from_cache(key, &block)
|
114
|
+
DeviceDetector.cache.get_or_set(key, &block)
|
93
115
|
end
|
94
116
|
end
|
95
117
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
|
5
|
+
class DeviceDetector
|
6
|
+
class VendorFragment < Parser
|
7
|
+
def name
|
8
|
+
vendor_fragment_info
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def vendor_fragment_info
|
14
|
+
from_cache(['vendor_fragment', self.class.name, user_agent]) do
|
15
|
+
return if regex_meta.nil? || regex_meta.empty?
|
16
|
+
|
17
|
+
regex_meta[:regex_name]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def filenames
|
22
|
+
['vendorfragments.yml']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/device_detector.rb
CHANGED
@@ -15,13 +15,34 @@ require 'device_detector/device'
|
|
15
15
|
require 'device_detector/os'
|
16
16
|
require 'device_detector/browser'
|
17
17
|
require 'device_detector/client_hint'
|
18
|
+
require 'device_detector/vendor_fragment'
|
18
19
|
|
19
20
|
class DeviceDetector
|
20
21
|
attr_reader :client_hint, :user_agent
|
21
22
|
|
22
23
|
def initialize(user_agent, headers = nil)
|
23
24
|
@client_hint = ClientHint.new(headers)
|
24
|
-
|
25
|
+
utf8_user_agent = encode_user_agent_if_needed(user_agent)
|
26
|
+
@user_agent = set_user_agent(utf8_user_agent)
|
27
|
+
end
|
28
|
+
|
29
|
+
# https://github.com/matomo-org/device-detector/blob/c235832dba13961ab0f71b681616baf1aa48de23/Parser/Device/AbstractDeviceParser.php#L1873
|
30
|
+
def set_user_agent(user_agent)
|
31
|
+
return user_agent if client_hint.model.nil?
|
32
|
+
|
33
|
+
regex = build_regex('Android 10[.\d]*; K(?: Build/|[;)])')
|
34
|
+
return user_agent unless user_agent =~ regex
|
35
|
+
|
36
|
+
version = client_hint.os_version || '10'
|
37
|
+
|
38
|
+
user_agent.gsub(regex, "Android #{version}, #{client_hint.model}")
|
39
|
+
end
|
40
|
+
|
41
|
+
def encode_user_agent_if_needed(user_agent)
|
42
|
+
return if user_agent.nil?
|
43
|
+
return user_agent if user_agent.encoding.name == 'UTF-8'
|
44
|
+
|
45
|
+
user_agent.encode('utf-8', 'binary', undef: :replace)
|
25
46
|
end
|
26
47
|
|
27
48
|
def name
|
@@ -53,13 +74,18 @@ class DeviceDetector
|
|
53
74
|
end
|
54
75
|
|
55
76
|
def device_name
|
77
|
+
return if fake_ua?
|
78
|
+
|
56
79
|
device.name || client_hint.model || fix_for_x_music
|
57
80
|
end
|
58
81
|
|
59
82
|
def device_brand
|
83
|
+
return if fake_ua?
|
84
|
+
|
60
85
|
# Assume all devices running iOS / Mac OS are from Apple
|
61
86
|
brand = device.brand
|
62
87
|
brand = 'Apple' if brand.nil? && ['Apple TV', 'iOS', 'Mac'].include?(os_name)
|
88
|
+
|
63
89
|
brand
|
64
90
|
end
|
65
91
|
|
@@ -206,6 +232,11 @@ class DeviceDetector
|
|
206
232
|
@os ||= OS.new(user_agent)
|
207
233
|
end
|
208
234
|
|
235
|
+
# https://github.com/matomo-org/device-detector/blob/827a3fab7e38c3274c18d2f5f5bc2a78b7ef4a3a/DeviceDetector.php#L921C5-L921C5
|
236
|
+
def fake_ua?
|
237
|
+
os_name == 'Android' && device.brand == 'Apple'
|
238
|
+
end
|
239
|
+
|
209
240
|
# https://github.com/matomo-org/device-detector/blob/be1c9ef486c247dc4886668da5ed0b1c49d90ba8/Parser/Client/Browser.php#L772
|
210
241
|
# Fix mobile browser names e.g. Chrome => Chrome Mobile
|
211
242
|
def mobile_fix?
|
@@ -218,7 +249,7 @@ class DeviceDetector
|
|
218
249
|
|
219
250
|
# Related to issue mentionned in device.rb#1562
|
220
251
|
def fix_for_x_music
|
221
|
-
user_agent
|
252
|
+
user_agent&.include?('X-music Ⅲ') ? 'X-Music III' : nil
|
222
253
|
end
|
223
254
|
|
224
255
|
def skip_os_version?
|
data/regexes/bots.yml
CHANGED
@@ -13,6 +13,14 @@
|
|
13
13
|
name: 'Plesk International GmbH'
|
14
14
|
url: 'https://www.plesk.com'
|
15
15
|
|
16
|
+
- regex: 'Cloudflare-Healthchecks'
|
17
|
+
name: 'Cloudflare Health Checks'
|
18
|
+
category: 'Service Agent'
|
19
|
+
url: 'https://developers.cloudflare.com/health-checks/'
|
20
|
+
producer:
|
21
|
+
name: 'CloudFlare'
|
22
|
+
url: 'http://www.cloudflare.com'
|
23
|
+
|
16
24
|
- regex: '360Spider'
|
17
25
|
name: '360Spider'
|
18
26
|
category: 'Search bot'
|
@@ -704,7 +712,7 @@
|
|
704
712
|
name: 'Visual Meta'
|
705
713
|
url: 'https://www.shopalike.cz/'
|
706
714
|
|
707
|
-
- regex: 'AdsBot-Google|Adwords-(DisplayAds|Express|Instant)|Google Web Preview|Google[ -]Publisher[ -]Plugin|Google-(Ads-Conversions|Ads-Qualify|Adwords|AMPHTML|Assess|HotelAdsVerifier|Read-Aloud|Shopping-Quality|Site-Verification|speakr|Stale-Content-Probe|Test|Youtube-Links)|(APIs|DuplexWeb|Feedfetcher|Mediapartners)-Google|Googlebot|Google(?:AdSenseInfeed|AssociationService|Producer)|Google.*/\+/web/snippet'
|
715
|
+
- regex: 'AdsBot-Google|Adwords-(DisplayAds|Express|Instant)|Google Web Preview|Google[ -]Publisher[ -]Plugin|Google-(Ads-Conversions|Ads-Qualify|Adwords|AMPHTML|Assess|HotelAdsVerifier|Read-Aloud|Shopping-Quality|Site-Verification|speakr|Stale-Content-Probe|Test|Youtube-Links)|(APIs|DuplexWeb|Feedfetcher|Mediapartners)-Google|Googlebot|Google(?:AdSenseInfeed|AssociationService|Prober|Producer)|Google.*/\+/web/snippet'
|
708
716
|
name: 'Googlebot'
|
709
717
|
category: 'Search bot'
|
710
718
|
url: 'http://www.google.com/bot.html'
|
@@ -727,6 +735,11 @@
|
|
727
735
|
name: 'HubSpot Inc.'
|
728
736
|
url: 'https://www.hubspot.com'
|
729
737
|
|
738
|
+
- regex: 'vuhuvBot'
|
739
|
+
name: 'Vuhuv Bot'
|
740
|
+
category: 'Crawler'
|
741
|
+
url: 'http://vuhuv.com/bot.html'
|
742
|
+
|
730
743
|
- regex: 'HTTPMon'
|
731
744
|
name: 'HTTPMon'
|
732
745
|
category: 'Site Monitor'
|
@@ -1020,6 +1033,14 @@
|
|
1020
1033
|
- regex: 'Octopus [0-9]'
|
1021
1034
|
name: 'Octopus'
|
1022
1035
|
|
1036
|
+
- regex: 'OnlineOrNot.com_bot'
|
1037
|
+
name: 'OnlineOrNot Bot'
|
1038
|
+
category: 'Site Monitor'
|
1039
|
+
url: 'https://onlineornot.com/website-monitoring'
|
1040
|
+
producer:
|
1041
|
+
name: 'OnlineOrNot'
|
1042
|
+
url: 'https://onlineornot.com'
|
1043
|
+
|
1023
1044
|
- regex: 'omgili'
|
1024
1045
|
name: 'Omgili bot'
|
1025
1046
|
category: 'Search bot'
|
@@ -2025,7 +2046,15 @@
|
|
2025
2046
|
name: 'WooRank sprl'
|
2026
2047
|
url: 'https://www.woorank.com/'
|
2027
2048
|
|
2028
|
-
- regex: '
|
2049
|
+
- regex: 'by Siteimprove\.com'
|
2050
|
+
name: 'Siteimprove'
|
2051
|
+
category: 'Search bot'
|
2052
|
+
url: 'https://siteimprove.com/'
|
2053
|
+
producer:
|
2054
|
+
name: 'Siteimprove GmbH'
|
2055
|
+
url: 'https://siteimprove.com/'
|
2056
|
+
|
2057
|
+
- regex: 'Image size by Siteimprove\.com'
|
2029
2058
|
name: 'Siteimprove'
|
2030
2059
|
category: 'Search bot'
|
2031
2060
|
url: 'https://siteimprove.com/'
|
@@ -2153,6 +2182,14 @@
|
|
2153
2182
|
name: 'Startpagina B.V.'
|
2154
2183
|
url: 'https://www.startpagina.nl/'
|
2155
2184
|
|
2185
|
+
- regex: 'MoodleBot-Linkchecker'
|
2186
|
+
name: 'MoodleBot Linkchecker'
|
2187
|
+
category: 'Search bot'
|
2188
|
+
url: 'hhttps://docs.moodle.org/en/Usage'
|
2189
|
+
producer:
|
2190
|
+
name: 'Moodle Pty Ltd'
|
2191
|
+
url: 'https://moodle.org/'
|
2192
|
+
|
2156
2193
|
- regex: 'GTmetrix'
|
2157
2194
|
name: 'GTmetrix'
|
2158
2195
|
category: 'Crawler'
|
@@ -2412,6 +2449,13 @@
|
|
2412
2449
|
producer:
|
2413
2450
|
name: 'Hatena Co., Ltd.'
|
2414
2451
|
url: 'https://www.hatena.ne.jp'
|
2452
|
+
- regex: 'Hatena-?Bookmark'
|
2453
|
+
name: 'Hatena Bookmark'
|
2454
|
+
category: 'Crawler'
|
2455
|
+
url: 'https://www.hatena.ne.jp/faq/'
|
2456
|
+
producer:
|
2457
|
+
name: 'Hatena Co., Ltd.'
|
2458
|
+
url: 'https://www.hatena.ne.jp'
|
2415
2459
|
|
2416
2460
|
- regex: 'RyowlEngine/(\d+)'
|
2417
2461
|
name: 'Ryowl'
|
@@ -2556,6 +2600,14 @@
|
|
2556
2600
|
category: 'Security Checker'
|
2557
2601
|
url: 'https://github.com/LeakIX/l9explore'
|
2558
2602
|
|
2603
|
+
- regex: 'l9scan/|^Lkx-(.*)/([\d+.]+)'
|
2604
|
+
name: 'LeakIX'
|
2605
|
+
category: 'Security Checker'
|
2606
|
+
url: 'https://leakix.net/'
|
2607
|
+
producer:
|
2608
|
+
name: 'BaDaaS SRL'
|
2609
|
+
url: 'https://leakix.net/'
|
2610
|
+
|
2559
2611
|
- regex: 'MegaIndex.ru/([\d+\.])'
|
2560
2612
|
name: 'MegaIndex'
|
2561
2613
|
category: 'Crawler'
|
@@ -3047,14 +3099,6 @@
|
|
3047
3099
|
name: 'New Work SE'
|
3048
3100
|
url: 'https://www.xing.com/'
|
3049
3101
|
|
3050
|
-
- regex: '^Lkx-(.*)/([\d+.]+)'
|
3051
|
-
name: 'LeakIX'
|
3052
|
-
category: 'Security Checker'
|
3053
|
-
url: 'https://leakix.net/'
|
3054
|
-
producer:
|
3055
|
-
name: 'BaDaaS SRL'
|
3056
|
-
url: 'https://leakix.net/'
|
3057
|
-
|
3058
3102
|
- regex: 'RepoLookoutBot/([\d+.]+)'
|
3059
3103
|
name: 'Repo Lookout'
|
3060
3104
|
category: 'Security Checker'
|
@@ -3217,6 +3261,124 @@
|
|
3217
3261
|
category: 'Crawler'
|
3218
3262
|
url: 'https://reqbin.com/curl'
|
3219
3263
|
|
3264
|
+
- regex: 'XoviBot/([\d+.]+)'
|
3265
|
+
name: 'XoviBot'
|
3266
|
+
category: 'Crawler'
|
3267
|
+
url: 'https://www.xovibot.net'
|
3268
|
+
producer:
|
3269
|
+
name: 'Xovi GmbH'
|
3270
|
+
url: 'http://www.xovi.de'
|
3271
|
+
|
3272
|
+
- regex: 'Overcast/([\d+.]+) Podcast Sync'
|
3273
|
+
name: 'Overcast Podcast Sync'
|
3274
|
+
category: 'Service Agent'
|
3275
|
+
url: 'https://overcast.fm/podcasterinfo'
|
3276
|
+
|
3277
|
+
- regex: '^Verity/([\d+.]+)'
|
3278
|
+
name: 'GumGum Verity'
|
3279
|
+
category: 'Service Agent'
|
3280
|
+
url: 'https://gumgum.com/verity'
|
3281
|
+
|
3282
|
+
- regex: 'hackermention'
|
3283
|
+
name: 'hackermention'
|
3284
|
+
category: 'Feed Reader'
|
3285
|
+
url: 'https://github.com/snarfed/hackermention'
|
3286
|
+
|
3287
|
+
- regex: 'BitSightBot/([\d+.]+)'
|
3288
|
+
name: 'BitSight'
|
3289
|
+
category: 'Security Checker'
|
3290
|
+
url: 'https://www.bitsight.com/'
|
3291
|
+
producer:
|
3292
|
+
name: 'BitSight Technologies, Inc.'
|
3293
|
+
url: 'https://www.bitsight.com/'
|
3294
|
+
|
3295
|
+
- regex: 'Ezgif/([\d+.]+)'
|
3296
|
+
name: 'Ezgif'
|
3297
|
+
category: 'Service Agent'
|
3298
|
+
url: 'https://ezgif.com/about'
|
3299
|
+
|
3300
|
+
- regex: 'intelx.io_bot'
|
3301
|
+
name: 'Intelligence X'
|
3302
|
+
category: 'Crawler'
|
3303
|
+
url: 'https://intelx.io/'
|
3304
|
+
producer:
|
3305
|
+
name: 'Kleissner Investments s.r.o.'
|
3306
|
+
url: 'https://intelx.io/'
|
3307
|
+
|
3308
|
+
- regex: 'FemtosearchBot/([\d+.]+)'
|
3309
|
+
name: 'Femtosearch'
|
3310
|
+
category: 'Crawler'
|
3311
|
+
url: 'http://femtosearch.com/'
|
3312
|
+
producer:
|
3313
|
+
name: 'Grier Forensics, LLC'
|
3314
|
+
url: 'https://www.grierforensics.com/'
|
3315
|
+
|
3316
|
+
- regex: 'AdsTxtCrawler/([\d+.]+)'
|
3317
|
+
name: 'AdsTxtCrawler'
|
3318
|
+
category: 'Crawler'
|
3319
|
+
url: 'https://github.com/InteractiveAdvertisingBureau/adstxtcrawler'
|
3320
|
+
producer:
|
3321
|
+
name: 'IAB Technology Laboratory, Inc.'
|
3322
|
+
url: 'https://iabtechlab.com/'
|
3323
|
+
|
3324
|
+
- regex: 'Morningscore'
|
3325
|
+
name: 'Morningscore Bot'
|
3326
|
+
category: 'Crawler'
|
3327
|
+
url: 'https://morningscore.io/'
|
3328
|
+
producer:
|
3329
|
+
name: 'Morningscore'
|
3330
|
+
url: 'https://morningscore.io/'
|
3331
|
+
|
3332
|
+
- regex: 'Uptime-Kuma/([\d+.]+)'
|
3333
|
+
name: 'Uptime-Kuma'
|
3334
|
+
category: 'Site Monitor'
|
3335
|
+
url: 'https://github.com/louislam/uptime-kuma'
|
3336
|
+
|
3337
|
+
- regex: 'ChatGPT-User'
|
3338
|
+
name: 'ChatGPT'
|
3339
|
+
category: 'Crawler'
|
3340
|
+
url: 'https://platform.openai.com/docs/plugins/bot'
|
3341
|
+
producer:
|
3342
|
+
name: 'OpenAI OpCo, LLC'
|
3343
|
+
url: 'https://openai.com/'
|
3344
|
+
|
3345
|
+
- regex: 'BrightEdge Crawler/([\d+.]+)'
|
3346
|
+
name: 'BrightEdge'
|
3347
|
+
category: 'Crawler'
|
3348
|
+
url: 'https://www.brightedge.com/'
|
3349
|
+
producer:
|
3350
|
+
name: 'BrightEdge Technologies, Inc'
|
3351
|
+
url: 'https://www.brightedge.com/'
|
3352
|
+
|
3353
|
+
- regex: 'sfFeedReader/([\d+.]+)'
|
3354
|
+
name: 'sfFeedReader'
|
3355
|
+
url: 'https://github.com/diem-project/sfFeed2Plugin'
|
3356
|
+
category: 'Feed Fetcher'
|
3357
|
+
|
3358
|
+
- regex: 'cyberscan.io'
|
3359
|
+
name: 'Cyberscan'
|
3360
|
+
category: 'Security Checker'
|
3361
|
+
url: 'https://www.cyberscan.io/'
|
3362
|
+
producer:
|
3363
|
+
name: 'DGC Verwaltungs GmbH'
|
3364
|
+
url: 'https://dgc.org/'
|
3365
|
+
|
3366
|
+
- regex: 'deepcrawl\.com'
|
3367
|
+
name: 'Lumar'
|
3368
|
+
category: 'Crawler'
|
3369
|
+
url: 'https://deepcrawl.com/bot'
|
3370
|
+
producer:
|
3371
|
+
name: 'Lumar'
|
3372
|
+
url: 'https://www.lumar.io/'
|
3373
|
+
|
3374
|
+
- regex: 'RepoLookoutBot'
|
3375
|
+
name: 'Repo Lookout'
|
3376
|
+
category: 'Crawler'
|
3377
|
+
url: 'https://www.repo-lookout.org/'
|
3378
|
+
producer:
|
3379
|
+
name: 'Crissy Field GmbH'
|
3380
|
+
url: 'https://www.crissyfield.de/'
|
3381
|
+
|
3220
3382
|
# Generic detections
|
3221
3383
|
- regex: '[a-z0-9\-_]*((?<!cu|power[ _]|m[ _])bot(?![ _]TAB|[ _]?5[0-9]|[ _]Senior|[ _]Junior)|crawler|crawl|checker|archiver|transcoder|spider)([^a-z]|$)'
|
3222
3384
|
name: 'Generic Bot'
|
data/regexes/client/browsers.yml
CHANGED
@@ -319,7 +319,7 @@
|
|
319
319
|
default: 'Blink'
|
320
320
|
|
321
321
|
# Chromium GOST (https://github.com/deemru/chromium-gost)
|
322
|
-
- regex: 'Chrome/(\d
|
322
|
+
- regex: 'Chrome/(\d+\.[\.\d]+) .*\(Chromium GOST\)'
|
323
323
|
name: 'Chromium GOST'
|
324
324
|
version: '$1'
|
325
325
|
engine:
|
@@ -349,7 +349,7 @@
|
|
349
349
|
default: 'Gecko'
|
350
350
|
|
351
351
|
# CoolBrowser (https://play.google.com/store/apps/details?id=com.easybrowser.browser.coolbrowser)
|
352
|
-
- regex: 'Chrome/(\d
|
352
|
+
- regex: 'Chrome/(\d+\.[\.\d]+) .*AgentWeb.+UCBrowser'
|
353
353
|
name: 'CoolBrowser'
|
354
354
|
version: '$1'
|
355
355
|
engine:
|
@@ -387,7 +387,7 @@
|
|
387
387
|
default: 'Blink'
|
388
388
|
|
389
389
|
# Qutebrowser (https://qutebrowser.org/)
|
390
|
-
- regex: 'qutebrowser/(\d
|
390
|
+
- regex: 'qutebrowser/(\d+\.[\.\d]+) .*Chrome'
|
391
391
|
name: 'Qutebrowser'
|
392
392
|
version: '$1'
|
393
393
|
engine:
|
@@ -791,6 +791,13 @@
|
|
791
791
|
engine:
|
792
792
|
default: 'Blink'
|
793
793
|
|
794
|
+
# Wolvic VR Browser
|
795
|
+
- regex: 'Wolvic/(\d+\.[.\d]+)'
|
796
|
+
name: 'Wolvic'
|
797
|
+
version: '$1'
|
798
|
+
engine:
|
799
|
+
default: 'Gecko'
|
800
|
+
|
794
801
|
# Firefox Reality (https://mixedreality.mozilla.org/firefox-reality/)
|
795
802
|
- regex: 'Mobile VR.+Firefox'
|
796
803
|
name: 'Firefox Reality'
|
@@ -1168,7 +1175,7 @@
|
|
1168
1175
|
version: '$1'
|
1169
1176
|
engine:
|
1170
1177
|
default: 'Blink'
|
1171
|
-
- regex: 'AlohaBrowser(?:/(\d+[\.\d]+))?'
|
1178
|
+
- regex: 'AlohaBrowser(?:App)?(?:/(\d+[\.\d]+))?'
|
1172
1179
|
name: 'Aloha Browser'
|
1173
1180
|
version: '$1'
|
1174
1181
|
- regex: 'Aloha/'
|
@@ -1232,7 +1239,7 @@
|
|
1232
1239
|
version: '$1'
|
1233
1240
|
|
1234
1241
|
#Amigo
|
1235
|
-
- regex: 'Chrome/(\d
|
1242
|
+
- regex: 'Chrome/(\d+\.[\.\d]+) .*MRCHROME'
|
1236
1243
|
name: 'Amigo'
|
1237
1244
|
version: '$1'
|
1238
1245
|
engine:
|
@@ -1395,7 +1402,7 @@
|
|
1395
1402
|
default: 'Gecko'
|
1396
1403
|
|
1397
1404
|
#Swiftfox
|
1398
|
-
- regex: 'Firefox/(\d
|
1405
|
+
- regex: 'Firefox/(\d+\.[\.\d]+) .*\(Swiftfox\)'
|
1399
1406
|
name: 'Swiftfox'
|
1400
1407
|
version: '$1'
|
1401
1408
|
engine:
|
@@ -1581,7 +1588,7 @@
|
|
1581
1588
|
version: '$1'
|
1582
1589
|
engine:
|
1583
1590
|
default: 'Blink'
|
1584
|
-
- regex: 'Opera/(\d
|
1591
|
+
- regex: 'Opera/(\d+\.[\.\d]+) .*Opera Mobi'
|
1585
1592
|
name: 'Opera Mobile'
|
1586
1593
|
version: '$1'
|
1587
1594
|
engine:
|
@@ -1616,7 +1623,7 @@
|
|
1616
1623
|
default: 'Presto'
|
1617
1624
|
versions:
|
1618
1625
|
15: 'Blink'
|
1619
|
-
- regex: '(?:Opera|OPR)[/ ](?:9.80.*Version/)?(\d
|
1626
|
+
- regex: '(?:Opera|OPR)[/ ](?:9.80.*Version/)?(\d+\.[\.\d]+) .*Edition Next'
|
1620
1627
|
name: 'Opera Next'
|
1621
1628
|
version: '$1'
|
1622
1629
|
engine:
|
@@ -1699,7 +1706,17 @@
|
|
1699
1706
|
name: 'Baidu Spark'
|
1700
1707
|
version: '$1'
|
1701
1708
|
|
1702
|
-
# Yandex Browser
|
1709
|
+
# Yandex Browser
|
1710
|
+
- regex: 'YaBrowser(?:/(\d+[\.\d]*)) YaApp_iOS'
|
1711
|
+
name: 'Yandex Browser'
|
1712
|
+
version: '$1'
|
1713
|
+
engine:
|
1714
|
+
default: 'WebKit'
|
1715
|
+
- regex: 'iP(?:hone|ad);.+YaBrowser(?:/(\d+[\.\d]*)) Mobile'
|
1716
|
+
name: 'Yandex Browser'
|
1717
|
+
version: '$1'
|
1718
|
+
engine:
|
1719
|
+
default: 'WebKit'
|
1703
1720
|
- regex: 'YaBrowser(?:/(\d+[\.\d]*)) \(lite\)?'
|
1704
1721
|
name: 'Yandex Browser Lite'
|
1705
1722
|
version: '$1'
|
@@ -1789,7 +1806,7 @@
|
|
1789
1806
|
default: 'Blink'
|
1790
1807
|
|
1791
1808
|
# Iron
|
1792
|
-
- regex: 'Chrome(?:/(\d
|
1809
|
+
- regex: 'Chrome(?:/(\d+\.[\.\d]+) )?.*Iron'
|
1793
1810
|
name: 'Iron'
|
1794
1811
|
version: '$1'
|
1795
1812
|
engine:
|
@@ -1869,7 +1886,7 @@
|
|
1869
1886
|
versions:
|
1870
1887
|
28: 'Blink'
|
1871
1888
|
|
1872
|
-
- regex: '(?:DDG-Android-|DuckDuckGo/)(\d+[\.\d]*)'
|
1889
|
+
- regex: '(?:DDG-Android-|DuckDuckGo/|ddg_android/)(\d+[\.\d]*)'
|
1873
1890
|
name: 'DuckDuckGo Privacy Browser'
|
1874
1891
|
version: '$1'
|
1875
1892
|
engine:
|
@@ -1957,7 +1974,7 @@
|
|
1957
1974
|
default: 'Blink'
|
1958
1975
|
|
1959
1976
|
# Web Explorer
|
1960
|
-
- regex: 'Web Explorer/(\d
|
1977
|
+
- regex: 'Web Explorer/(\d+\.[\.\d]+) .*Chrome'
|
1961
1978
|
name: 'Web Explorer'
|
1962
1979
|
version: '$1'
|
1963
1980
|
engine:
|
@@ -2244,7 +2261,7 @@
|
|
2244
2261
|
- regex: '(?:Tizen|SLP) ?Browser(?:/(\d+[\.\d]+))?'
|
2245
2262
|
name: 'Tizen Browser'
|
2246
2263
|
version: '$1'
|
2247
|
-
- regex: 'Tizen (?:\d
|
2264
|
+
- regex: 'Tizen (?:\d+\.[\.\d]+)[^\.\d].* Version/(\d+[\.\d]+) (?:TV|Mobile|like)'
|
2248
2265
|
name: 'Tizen Browser'
|
2249
2266
|
version: '$1'
|
2250
2267
|
engine:
|
@@ -2413,7 +2430,7 @@
|
|
2413
2430
|
version: '$1'
|
2414
2431
|
engine:
|
2415
2432
|
default: 'WebKit'
|
2416
|
-
- regex: 'GoogleEarth/(\d
|
2433
|
+
- regex: 'GoogleEarth/(\d+\.[\.\d]+)[^\.\d].*client:(?:Plus|Pro)'
|
2417
2434
|
name: 'Google Earth Pro'
|
2418
2435
|
version: '$1'
|
2419
2436
|
engine:
|
@@ -2460,7 +2477,7 @@
|
|
2460
2477
|
version: '$1'
|
2461
2478
|
engine:
|
2462
2479
|
default: 'Trident'
|
2463
|
-
- regex: 'MSIE (\d
|
2480
|
+
- regex: 'MSIE (\d+\.[\.\d]+)[^\.\d].*XBLWP7'
|
2464
2481
|
name: 'IE Mobile'
|
2465
2482
|
version: '$1'
|
2466
2483
|
engine:
|
@@ -2663,7 +2680,7 @@
|
|
2663
2680
|
version: '$1'
|
2664
2681
|
engine:
|
2665
2682
|
default: 'WebKit'
|
2666
|
-
- regex: '(?:Version/(\d
|
2683
|
+
- regex: '(?:Version/(\d+\.[\.\d]+) .*)?Mobile.*Safari/'
|
2667
2684
|
name: 'Mobile Safari'
|
2668
2685
|
version: '$1'
|
2669
2686
|
engine:
|
@@ -2673,14 +2690,14 @@
|
|
2673
2690
|
version: ''
|
2674
2691
|
engine:
|
2675
2692
|
default: 'WebKit'
|
2676
|
-
- regex: 'Version/(\d
|
2693
|
+
- regex: 'Version/(\d+\.[\.\d]+) .*Safari/|(?:Safari|Safari(?:%20)?%E6%B5%8F%E8%A7%88%E5%99%A8)/?\d+'
|
2677
2694
|
name: 'Safari'
|
2678
2695
|
version: '$1'
|
2679
2696
|
engine:
|
2680
2697
|
default: 'WebKit'
|
2681
2698
|
|
2682
2699
|
# Dorado
|
2683
|
-
- regex: 'Dorado WAP-Browser(?:[/ ](\d+[\.\d]+))?'
|
2700
|
+
- regex: '(?:\w{1,5}[_ ])?Dorado WAP-Browser(?:[/ ](\d+[\.\d]+))?'
|
2684
2701
|
name: 'Dorado'
|
2685
2702
|
version: '$1'
|
2686
2703
|
|
@@ -86,6 +86,7 @@
|
|
86
86
|
'com.hideitpro.vbrowser': 'vBrowser'
|
87
87
|
'com.cgbrowser.rn': 'CG Browser'
|
88
88
|
'com.azka.browser.anti.blokir': 'Azka Browser'
|
89
|
+
'com.azka.browser': 'Azka Browser'
|
89
90
|
'com.micromaxinfo.browser': 'Mmx Browser'
|
90
91
|
'com.zeesitech.bitchutebrowser': 'Bitchute Browser'
|
91
92
|
'nova.all.video.downloader': 'Nova Video Downloader Pro'
|
@@ -188,3 +189,7 @@
|
|
188
189
|
'com.microsoft.emmx': 'Microsoft Edge'
|
189
190
|
'com.explore.web.browser': 'Web Browser & Explorer'
|
190
191
|
'privacy.explorer.fast.safe.browser': 'Privacy Explorer Fast Safe'
|
192
|
+
'app.soundy.browser': 'Soundy Browser'
|
193
|
+
'com.ivvi.browser': 'IVVI Browser'
|
194
|
+
'com.nomone.vrbrowser': 'NOMone VR Browser'
|
195
|
+
'com.opus.browser': 'Opus Browser'
|