browserino 0.2.0 → 0.3.2
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/.travis.yml +4 -0
- data/README.md +5 -1
- data/bin/console +4 -7
- data/browserino.gemspec +1 -0
- data/lib/browserino/agent.rb +58 -0
- data/lib/browserino/agent_manipulator.rb +28 -0
- data/lib/browserino/browser.rb +3 -11
- data/lib/browserino/engine.rb +4 -2
- data/lib/browserino/maps/android.rb +30 -0
- data/lib/browserino/maps/ios.rb +11 -0
- data/lib/browserino/maps/osx.rb +21 -0
- data/lib/browserino/maps/windows.rb +19 -0
- data/lib/browserino/match_extractor.rb +14 -0
- data/lib/browserino/operating_system.rb +6 -3
- data/lib/browserino/patterns.rb +15 -22
- data/lib/browserino/version.rb +1 -1
- data/lib/browserino.rb +27 -4
- metadata +24 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ad35d09a1a6278e60f23ce734ea23ecc5625656b
|
|
4
|
+
data.tar.gz: 3a422fd663f391581b0189d2ca792c72611deb74
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0a39500512bebd5272265e678252498ad8a514ec7883dbedf8a7cd200774a354cee423970b6715418847a8c2753f272f4fb39034ce7963c0ab03988b43c9ce75
|
|
7
|
+
data.tar.gz: b7c75865e23b990c115fc93376bd5089599e00185701b84b2794ca6244a7d72362e509fc7eba646cfa2c8a22294255141657271b62657b55342432663b288b6a
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
|
@@ -10,7 +10,7 @@ This gem aims to provide information about the browser that your visitor is usin
|
|
|
10
10
|
Hey there everone, my name is Sidney Liebrand and I aim to become a contributor to various open source projects as I gain experience in working with the community.
|
|
11
11
|
For now All I'm going to say is that I'm not that experienced with git yet or how things go so bear with me should I make any mistake.
|
|
12
12
|
|
|
13
|
-
If anyone ofcourse desires to manage
|
|
13
|
+
If anyone ofcourse desires to manage this project with me feel free to add me on skype: *sidney.liebrand*
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
@@ -43,6 +43,10 @@ Or install it yourself as:
|
|
|
43
43
|
* version
|
|
44
44
|
* architecture
|
|
45
45
|
|
|
46
|
+
## Development
|
|
47
|
+
|
|
48
|
+
*Should you want to contribute to the project the instructions for it will be here when version 1 releases*
|
|
49
|
+
|
|
46
50
|
## Contributing
|
|
47
51
|
|
|
48
52
|
Bug reports and pull requests are welcome on GitHub at https://github.com/SidOfc/browserino. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
data/bin/console
CHANGED
|
@@ -2,13 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require "bundler/setup"
|
|
4
4
|
require "browserino"
|
|
5
|
+
require "pry"
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
# with your gem easier. You can also use a different console, if you like.
|
|
7
|
+
@agent = Browserino::parse('Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25')
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
# require "pry"
|
|
11
|
-
# Pry.start
|
|
9
|
+
puts @agent
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
IRB.start
|
|
11
|
+
Pry.start
|
data/browserino.gemspec
CHANGED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Browserino
|
|
2
|
+
class Agent
|
|
3
|
+
attr_accessor :info
|
|
4
|
+
|
|
5
|
+
def initialize(hash)
|
|
6
|
+
@info = hash
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def browser_name
|
|
10
|
+
@info[:browser_name]
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def browser_version
|
|
14
|
+
@info[:browser_version].gsub('_', '.')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def engine_name
|
|
18
|
+
@info[:engine_name]
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def engine_version
|
|
22
|
+
@info[:engine_version].gsub('_', '.')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def system_name(opts = {})
|
|
26
|
+
opts = {full: false}.merge(opts)
|
|
27
|
+
name = @info[:system_name]
|
|
28
|
+
if opts[:full]
|
|
29
|
+
[name, fetch_system_version_name(name)]
|
|
30
|
+
else
|
|
31
|
+
name
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def system_version
|
|
36
|
+
@info[:system_version].gsub('_', '.')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def system_architecture
|
|
40
|
+
@info[:system_architecture]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def fetch_system_version_name(name)
|
|
46
|
+
codename = Browserino::Mapping.const_get(name.upcase)
|
|
47
|
+
name.downcase!
|
|
48
|
+
if name.match(/mac|ios/i)
|
|
49
|
+
version = system_version.split('.').first(2).join.to_i
|
|
50
|
+
elsif name.start_with?('win') || name.start_with?('android')
|
|
51
|
+
version = system_version.gsub('.', '').to_i
|
|
52
|
+
end
|
|
53
|
+
if version
|
|
54
|
+
codename.select { |k, v| v if k.include?(version) }.values.first
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Browserino
|
|
2
|
+
@ua = nil
|
|
3
|
+
|
|
4
|
+
class AgentManipulator
|
|
5
|
+
def initialize(ua)
|
|
6
|
+
@ua = ua
|
|
7
|
+
standardize_ios!
|
|
8
|
+
strip_legacy_mozilla!
|
|
9
|
+
strip_fake_opera_version!
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def standardize_ios!
|
|
13
|
+
@ua = @ua.gsub(/ip((a|o)d|hone)/i, 'ios')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def strip_legacy_mozilla!
|
|
17
|
+
@ua = @ua.gsub(/(Mozilla\/[\d\.]+)/i, '')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def strip_fake_opera_version!
|
|
21
|
+
@ua = @ua.gsub(/ope?ra?(\/|\s)?[\d\.]+/i, '')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def ua
|
|
25
|
+
@ua
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/lib/browserino/browser.rb
CHANGED
|
@@ -1,16 +1,8 @@
|
|
|
1
1
|
module Browserino
|
|
2
2
|
module Browser
|
|
3
|
-
def self.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
until browsers.empty? || !name.nil?
|
|
7
|
-
subject = browsers.shift
|
|
8
|
-
name = subject if (ua.match(Browserino::PATTERNS[:browser][subject][:name]))
|
|
9
|
-
end
|
|
10
|
-
name ||= :unknown
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def self.version
|
|
3
|
+
def self.version(ua, patterns)
|
|
4
|
+
out = MatchExtractor::extract(ua.match(patterns[:version]), :version).to_s.downcase unless patterns.nil?
|
|
5
|
+
out ||= ''
|
|
14
6
|
end
|
|
15
7
|
end
|
|
16
8
|
end
|
data/lib/browserino/engine.rb
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
module Browserino
|
|
2
2
|
module Engine
|
|
3
|
-
def self.name
|
|
3
|
+
def self.name(ua)
|
|
4
|
+
MatchExtractor::extract(ua.match(Browserino::PATTERNS[:engine][:name]), :name).to_s.downcase
|
|
4
5
|
end
|
|
5
6
|
|
|
6
|
-
def self.version
|
|
7
|
+
def self.version(ua)
|
|
8
|
+
MatchExtractor::extract(ua.match(Browserino::PATTERNS[:engine][:version]), :version).to_s.downcase
|
|
7
9
|
end
|
|
8
10
|
end
|
|
9
11
|
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Taken from https://en.wikipedia.org/wiki/Android_version_history
|
|
2
|
+
# 15 - 09 - 2015
|
|
3
|
+
|
|
4
|
+
module Browserino
|
|
5
|
+
module Mapping
|
|
6
|
+
ANDROID = {
|
|
7
|
+
[10] => '1.0',
|
|
8
|
+
[11] => '1.1',
|
|
9
|
+
[15] => 'Cupcake 3',
|
|
10
|
+
[16] => 'Cupcake 4',
|
|
11
|
+
[20] => 'Eclair 5',
|
|
12
|
+
[201] => 'Eclair 6',
|
|
13
|
+
[21] => 'Eclair 7',
|
|
14
|
+
[22, 221, 222, 223] => 'Froyo 8',
|
|
15
|
+
[23, 231, 232] => 'Gingerbread 9',
|
|
16
|
+
[233, 234, 235, 236, 237] => 'Gingerbread 10',
|
|
17
|
+
[30] => 'Honeycomb 11',
|
|
18
|
+
[31] => 'honeycomb 12',
|
|
19
|
+
[32, 321, 322, 323, 324, 325, 326] => 'Honeycomb 13',
|
|
20
|
+
[40, 401, 402] => 'Ice Cream Sandwich 14',
|
|
21
|
+
[403, 404] => 'Ice Cream Sandwich 15',
|
|
22
|
+
[41, 411, 412] => 'Jelly Bean 16',
|
|
23
|
+
[42, 421, 422] => 'Jelly Bean 17',
|
|
24
|
+
[43, 431] => 'Jelly Bean 18',
|
|
25
|
+
[44, 441, 442, 443, 444] => 'KitKat 19',
|
|
26
|
+
[50, 501, 502] => 'Lollipop 21',
|
|
27
|
+
[51, 511] => 'Lollipop 22',
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Taken from http://www.thinkybits.com/blog/iOS-versions/
|
|
2
|
+
# 15 - 09 - 2015
|
|
3
|
+
|
|
4
|
+
module Browserino
|
|
5
|
+
module Mapping
|
|
6
|
+
IOS = {
|
|
7
|
+
[20, 21, 22, 30, 31] => 'iPhone OS',
|
|
8
|
+
[40, 41, 42, 43, 50, 51, 60, 61, 70, 71, 80, 81, 82, 83, 84, 90, 91] => 'iOS'
|
|
9
|
+
}
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Taken from https://nl.wikipedia.org/wiki/OS_X
|
|
2
|
+
# 15 - 09 - 2015
|
|
3
|
+
|
|
4
|
+
module Browserino
|
|
5
|
+
module Mapping
|
|
6
|
+
MACINTOSH = {
|
|
7
|
+
[100] => 'Cheetah',
|
|
8
|
+
[101] => 'Puma',
|
|
9
|
+
[102] => 'Jaguar',
|
|
10
|
+
[103] => 'Panther',
|
|
11
|
+
[104] => 'Tiger',
|
|
12
|
+
[105] => 'Leopard',
|
|
13
|
+
[106] => 'Snow Leopard',
|
|
14
|
+
[107] => 'Lion',
|
|
15
|
+
[108] => 'Mountain Lion',
|
|
16
|
+
[109] => 'Mavericks',
|
|
17
|
+
[1010] => 'Yosemite',
|
|
18
|
+
[1011] => 'El Capitan'
|
|
19
|
+
}
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Taken from https://nl.wikipedia.org/wiki/Windows_NT
|
|
2
|
+
# 15 - 09 - 2015
|
|
3
|
+
|
|
4
|
+
module Browserino
|
|
5
|
+
module Mapping
|
|
6
|
+
WINDOWS = {
|
|
7
|
+
[35] => '3.5',
|
|
8
|
+
[40] => '4',
|
|
9
|
+
[50] => '2000',
|
|
10
|
+
[51] => 'XP',
|
|
11
|
+
[52] => 'XP',
|
|
12
|
+
[60] => 'Vista',
|
|
13
|
+
[61] => '7',
|
|
14
|
+
[62] => '8',
|
|
15
|
+
[63] => '8.1',
|
|
16
|
+
[100] => '10'
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
module Browserino
|
|
2
2
|
module OperatingSystem
|
|
3
|
-
def self.name
|
|
3
|
+
def self.name(ua)
|
|
4
|
+
MatchExtractor::extract(ua.match(Browserino::PATTERNS[:operating_system][:name]), :name).to_s.downcase
|
|
4
5
|
end
|
|
5
6
|
|
|
6
|
-
def self.version
|
|
7
|
+
def self.version(ua)
|
|
8
|
+
MatchExtractor::extract(ua.match(Browserino::PATTERNS[:operating_system][:version]), :version).to_s.downcase
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
def self.architecture
|
|
11
|
+
def self.architecture(ua)
|
|
12
|
+
MatchExtractor::extract(ua.match(Browserino::PATTERNS[:operating_system][:architecture]), :architecture).to_s.downcase
|
|
10
13
|
end
|
|
11
14
|
end
|
|
12
15
|
end
|
data/lib/browserino/patterns.rb
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
# See this as a giant CSS selector.
|
|
2
|
-
# It will iterate through hashes recursively.
|
|
3
|
-
# If the :name is set in e.g. :browser then it will be global for all browsers.
|
|
4
|
-
# However if in :browser there is a hash called :opera with a :name
|
|
5
|
-
# then that will override the global setting.
|
|
6
|
-
# This basically follows the 'Cascading Style Sheet' flow
|
|
7
|
-
|
|
8
1
|
module Browserino
|
|
9
2
|
PATTERNS = {
|
|
10
3
|
browser: {
|
|
@@ -14,40 +7,40 @@ module Browserino
|
|
|
14
7
|
},
|
|
15
8
|
|
|
16
9
|
maxthon: {
|
|
17
|
-
name: /(?<name>
|
|
18
|
-
version: /maxthon(\s|\/)(?<version>
|
|
10
|
+
name: /(?<name>maxthon)/i,
|
|
11
|
+
version: /maxthon(\s|\/)(?<version>[\d\.]+)/i
|
|
19
12
|
},
|
|
20
13
|
|
|
21
14
|
ie: {
|
|
22
|
-
name: /(?<name>
|
|
23
|
-
version: /(
|
|
15
|
+
name: /(?<name>msie|trident)/i,
|
|
16
|
+
version: /((ms)?ie\s|rv\:)(?<version>[\d\.b]+)/i
|
|
24
17
|
},
|
|
25
18
|
|
|
26
19
|
firefox: {
|
|
27
|
-
name: /(?<name>
|
|
28
|
-
version: /(fire|water)(fox|bird)|ice(weasel|cat)|netscape(?<version>
|
|
20
|
+
name: /(?<name>(fire|water)(fox|bird)|ice(weasel|cat)|netscape)/i,
|
|
21
|
+
version: /((fire|water)(fox|bird)|ice(weasel|cat)|netscape)[\/]?(?<version>[\d\.]+)/i
|
|
29
22
|
},
|
|
30
23
|
|
|
31
24
|
chrome: {
|
|
32
|
-
name: /(?<name>
|
|
33
|
-
version: /chrome?(ium|plus)?\/(?<version>
|
|
25
|
+
name: /(?<name>chrome?(ium|plus)?)/i,
|
|
26
|
+
version: /chrome?(ium|plus)?\/(?<version>[\d\.]+)/i
|
|
34
27
|
},
|
|
35
28
|
|
|
36
29
|
safari: {
|
|
37
|
-
name: /(?<name>
|
|
38
|
-
version: /(version|safari)\/(?<version>
|
|
30
|
+
name: /(?<name>safari)/i,
|
|
31
|
+
version: /(version|safari)\/(?<version>[\d\.]+)/i
|
|
39
32
|
}
|
|
40
33
|
},
|
|
41
34
|
|
|
42
35
|
engine: {
|
|
43
|
-
name: /(?<name>
|
|
44
|
-
version: /((apple)?webkit|
|
|
36
|
+
name: /(?<name>((apple)?webkit|gecko|trident|presto))/i,
|
|
37
|
+
version: /((apple)?webkit|rv:|trident|presto)[\/\s]?(?<version>[\d\.]+)/i
|
|
45
38
|
},
|
|
46
39
|
|
|
47
40
|
operating_system: {
|
|
48
|
-
name: /(?<name>
|
|
49
|
-
version: /(nt|mac\sos\sx)\s(?<version>
|
|
50
|
-
architecture: /(?<architecture>
|
|
41
|
+
name: /(?<name>windows|macintosh|android|ios)/i,
|
|
42
|
+
version: /(nt|mac\sos\sx|android|(cpu\s|i)os)\s(?<version>[\d\._]+)/i,
|
|
43
|
+
architecture: /(?<architecture>(x?(86_)?64)|i(3|6)86)/i
|
|
51
44
|
}
|
|
52
45
|
}
|
|
53
46
|
end
|
data/lib/browserino/version.rb
CHANGED
data/lib/browserino.rb
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
require "browserino/maps/osx"
|
|
2
|
+
require "browserino/maps/ios"
|
|
3
|
+
require "browserino/maps/android"
|
|
4
|
+
require "browserino/maps/windows"
|
|
5
|
+
|
|
6
|
+
require "browserino/agent_manipulator"
|
|
7
|
+
require "browserino/agent"
|
|
1
8
|
require "browserino/version"
|
|
9
|
+
require "browserino/match_extractor"
|
|
2
10
|
require "browserino/patterns"
|
|
3
11
|
require "browserino/browser"
|
|
4
12
|
require "browserino/engine"
|
|
@@ -6,13 +14,28 @@ require "browserino/operating_system"
|
|
|
6
14
|
|
|
7
15
|
module Browserino
|
|
8
16
|
def self.parse ua
|
|
9
|
-
ua =
|
|
10
|
-
|
|
17
|
+
ua = AgentManipulator.new(ua).ua
|
|
18
|
+
name = find_browser_name(ua)
|
|
19
|
+
Agent.new({
|
|
20
|
+
browser_name: name,
|
|
21
|
+
browser_version: Browser::version(ua, PATTERNS[:browser][name]),
|
|
22
|
+
engine_name: Engine::name(ua),
|
|
23
|
+
engine_version: Engine::version(ua),
|
|
24
|
+
system_name: OperatingSystem::name(ua),
|
|
25
|
+
system_version: OperatingSystem::version(ua),
|
|
26
|
+
system_architecture: OperatingSystem::architecture(ua)
|
|
27
|
+
})
|
|
11
28
|
end
|
|
12
29
|
|
|
13
30
|
private
|
|
14
31
|
|
|
15
|
-
def self.
|
|
16
|
-
|
|
32
|
+
def self.find_browser_name ua
|
|
33
|
+
name = nil
|
|
34
|
+
browsers = PATTERNS[:browser].keys
|
|
35
|
+
until browsers.empty? || !name.nil?
|
|
36
|
+
tmp = browsers.shift
|
|
37
|
+
name = tmp if (ua.match(PATTERNS[:browser][tmp][:name]))
|
|
38
|
+
end
|
|
39
|
+
name ||= :unknown
|
|
17
40
|
end
|
|
18
41
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: browserino
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sidney Liebrand
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-09-
|
|
11
|
+
date: 2015-09-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -94,6 +94,20 @@ dependencies:
|
|
|
94
94
|
- - ">="
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
96
|
version: '0'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: pry
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - ">="
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '0'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
97
111
|
description:
|
|
98
112
|
email:
|
|
99
113
|
- sidneyliebrand@gmail.com
|
|
@@ -115,8 +129,15 @@ files:
|
|
|
115
129
|
- bin/setup
|
|
116
130
|
- browserino.gemspec
|
|
117
131
|
- lib/browserino.rb
|
|
132
|
+
- lib/browserino/agent.rb
|
|
133
|
+
- lib/browserino/agent_manipulator.rb
|
|
118
134
|
- lib/browserino/browser.rb
|
|
119
135
|
- lib/browserino/engine.rb
|
|
136
|
+
- lib/browserino/maps/android.rb
|
|
137
|
+
- lib/browserino/maps/ios.rb
|
|
138
|
+
- lib/browserino/maps/osx.rb
|
|
139
|
+
- lib/browserino/maps/windows.rb
|
|
140
|
+
- lib/browserino/match_extractor.rb
|
|
120
141
|
- lib/browserino/operating_system.rb
|
|
121
142
|
- lib/browserino/patterns.rb
|
|
122
143
|
- lib/browserino/version.rb
|
|
@@ -140,7 +161,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
140
161
|
version: '0'
|
|
141
162
|
requirements: []
|
|
142
163
|
rubyforge_project:
|
|
143
|
-
rubygems_version: 2.4.
|
|
164
|
+
rubygems_version: 2.4.6
|
|
144
165
|
signing_key:
|
|
145
166
|
specification_version: 4
|
|
146
167
|
summary: A browser identification gem
|