ahoy_matey 2.2.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7b0851dfc7538c6768d6f694d7e8356f0aef3e3ff66ba361447e000a2db5bac
4
- data.tar.gz: c28eb30ab780037d83550d359a36d6790e3a16f60b314b5d0be170d11b3c427b
3
+ metadata.gz: 1da649f5c85699714bff1777f3226b232f555e79ec2ece218280541bbb1264d5
4
+ data.tar.gz: '0180556a4ad007b5d9df07faa327a6d53e9a2cfe1bf810cb78e9d24d6cdc060b'
5
5
  SHA512:
6
- metadata.gz: 85fb407054564104efc83ae3d425c6253db7495d6f6d4156c741156f64fcd7fe048035f78e4563bf9ec92c69c7e6dfef41e29f7d1031174705b17c595ef96572
7
- data.tar.gz: ff03757afbb0deca1a11dc4ece02310bbd8a03f644f675c2eee32c1bf7711013f0cd38eb0fd009541b97b3a5b914a756279e88dbe0cbc8a8bd14ed064d648089
6
+ metadata.gz: e7cd93d376c86d34123c964fceb7f84ef33dc0513bfb66ac1e9da1b5654a7bed69041eb0d99477b50f87c77b5bf8e4c396e4dc8bf99b10db2699ef09fb11ecf8
7
+ data.tar.gz: f11f02dbd35f36982d932d12a905d060770d9f01f4b0bdfe572002dd5a10feaa07b79b1d3eb0e2df3376f00c6fbe67bbcc29549498599bd9634e164ff04d4184
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 3.0.0
2
+
3
+ - Made Device Detector the default user agent parser
4
+ - Made v2 the default bot detection version
5
+ - Removed a large number of dependencies
6
+ - Removed search keyword detection (most search engines today prevent this)
7
+ - Removed support for Rails < 5
8
+
1
9
  ## 2.2.1
2
10
 
3
11
  - Updated Ahoy.js to 0.3.4
data/README.md CHANGED
@@ -31,12 +31,12 @@ Restart your web server, open a page in your browser, and a visit will be create
31
31
  Track your first event from a controller with:
32
32
 
33
33
  ```ruby
34
- ahoy.track "My first event", {language: "Ruby"}
34
+ ahoy.track "My first event", language: "Ruby"
35
35
  ```
36
36
 
37
37
  ### JavaScript, Native Apps, & AMP
38
38
 
39
- First, enable the API in `config/initializers/ahoy.rb`:
39
+ Enable the API in `config/initializers/ahoy.rb`:
40
40
 
41
41
  ```ruby
42
42
  Ahoy.api = true
@@ -44,7 +44,9 @@ Ahoy.api = true
44
44
 
45
45
  And restart your web server.
46
46
 
47
- For JavaScript and Rails 6 / Webpacker, run:
47
+ ### JavaScript
48
+
49
+ For Rails 6 / Webpacker, run:
48
50
 
49
51
  ```sh
50
52
  yarn add ahoy.js
@@ -56,7 +58,7 @@ And add to `app/javascript/packs/application.js`:
56
58
  import ahoy from "ahoy.js";
57
59
  ```
58
60
 
59
- For JavaScript and Rails 5 / Sprockets, add to `app/assets/javascripts/application.js`:
61
+ For Rails 5 / Sprockets, add to `app/assets/javascripts/application.js`:
60
62
 
61
63
  ```javascript
62
64
  //= require ahoy
@@ -68,14 +70,6 @@ Track an event with:
68
70
  ahoy.track("My second event", {language: "JavaScript"});
69
71
  ```
70
72
 
71
- For Android, check out [Ahoy Android](https://github.com/instacart/ahoy-android). For other platforms, see the [API spec](#api-spec).
72
-
73
- For AMP, track an event with:
74
-
75
- ```erb
76
- <%= amp_event "My third event", language: "AMP" %>
77
- ```
78
-
79
73
  ### GDPR Compliance
80
74
 
81
75
  Ahoy provides a number of options to help with GDPR compliance. See the [GDPR section](#gdpr-compliance-1) for more info.
@@ -86,9 +80,9 @@ Ahoy provides a number of options to help with GDPR compliance. See the [GDPR se
86
80
 
87
81
  When someone visits your website, Ahoy creates a visit with lots of useful information.
88
82
 
89
- - **traffic source** - referrer, referring domain, landing page, search keyword
90
- - **location** - country, region, and city
91
- - **technology** - browser, OS, and device type
83
+ - **traffic source** - referrer, referring domain, landing page
84
+ - **location** - country, region, city, latitude, longitude
85
+ - **technology** - browser, OS, device type
92
86
  - **utm parameters** - source, medium, term, content, campaign
93
87
 
94
88
  Use the `current_visit` method to access it.
@@ -113,23 +107,7 @@ Ahoy.server_side_visits = :when_needed
113
107
 
114
108
  ### Events
115
109
 
116
- Each event has a `name` and `properties`.
117
-
118
- There are several ways to track events.
119
-
120
- #### JavaScript
121
-
122
- ```javascript
123
- ahoy.track("Viewed book", {title: "The World is Flat"});
124
- ```
125
-
126
- or track events automatically with:
127
-
128
- ```javascript
129
- ahoy.trackAll();
130
- ```
131
-
132
- See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features.
110
+ Each event has a `name` and `properties`. There are several ways to track events.
133
111
 
134
112
  #### Ruby
135
113
 
@@ -137,7 +115,7 @@ See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features
137
115
  ahoy.track "Viewed book", title: "Hot, Flat, and Crowded"
138
116
  ```
139
117
 
140
- or track actions automatically with:
118
+ Track actions automatically with:
141
119
 
142
120
  ```ruby
143
121
  class ApplicationController < ActionController::Base
@@ -151,6 +129,20 @@ class ApplicationController < ActionController::Base
151
129
  end
152
130
  ```
153
131
 
132
+ #### JavaScript
133
+
134
+ ```javascript
135
+ ahoy.track("Viewed book", {title: "The World is Flat"});
136
+ ```
137
+
138
+ Track events automatically with:
139
+
140
+ ```javascript
141
+ ahoy.trackAll();
142
+ ```
143
+
144
+ See [Ahoy.js](https://github.com/ankane/ahoy.js) for a complete list of features.
145
+
154
146
  #### Native Apps
155
147
 
156
148
  For Android, check out [Ahoy Android](https://github.com/instacart/ahoy-android). For other platforms, see the [API spec](#api-spec).
@@ -415,6 +407,8 @@ Ahoy can mask IPs with the same approach [Google Analytics uses for IP anonymiza
415
407
  Ahoy.mask_ips = true
416
408
  ```
417
409
 
410
+ IPs are masked before geolocation is performed.
411
+
418
412
  To mask previously collected IPs, use:
419
413
 
420
414
  ```ruby
@@ -507,7 +501,7 @@ end
507
501
 
508
502
  Two useful methods you can use are `request` and `controller`.
509
503
 
510
- You can pass additional visit data from JavaScript with: [master]
504
+ You can pass additional visit data from JavaScript with:
511
505
 
512
506
  ```javascript
513
507
  ahoy.configure({visitParams: {referral_code: 123}});
@@ -631,6 +625,21 @@ Send a `POST` request to `/ahoy/events` with `Content-Type: application/json` an
631
625
 
632
626
  ## Upgrading
633
627
 
628
+ ### 3.0
629
+
630
+ If you installed Ahoy before 2.1 and want to keep legacy user agent parsing and bot detection, add to your Gemfile:
631
+
632
+ ```ruby
633
+ gem "browser", "~> 2.0"
634
+ gem "user_agent_parser"
635
+ ```
636
+
637
+ And add to `config/initializers/ahoy.rb`:
638
+
639
+ ```ruby
640
+ Ahoy.user_agent_parser = :legacy
641
+ ```
642
+
634
643
  ### 2.2
635
644
 
636
645
  Ahoy now ships with better bot detection if you use Device Detector. This should be more accurate but can significantly reduce the number of visits recorded. For existing installs, it’s opt-in to start. To use it, add to `config/initializers/ahoy.rb`:
@@ -1,13 +1,10 @@
1
1
  module Ahoy
2
2
  class BaseController < ApplicationController
3
3
  filters = _process_action_callbacks.map(&:filter) - Ahoy.preserve_callbacks
4
- if Rails::VERSION::MAJOR >= 5
5
- skip_before_action(*filters, raise: false)
6
- skip_after_action(*filters, raise: false)
7
- skip_around_action(*filters, raise: false)
8
- else
9
- skip_action_callback(*filters)
10
- end
4
+ skip_before_action(*filters, raise: false)
5
+ skip_after_action(*filters, raise: false)
6
+ skip_around_action(*filters, raise: false)
7
+
11
8
  before_action :verify_request_size
12
9
  before_action :renew_cookies
13
10
 
@@ -31,7 +28,7 @@ module Ahoy
31
28
  def verify_request_size
32
29
  if request.content_length > Ahoy.max_content_length
33
30
  logger.info "[ahoy] Payload too large"
34
- render text: "Payload too large\n", status: 413
31
+ render plain: "Payload too large\n", status: 413
35
32
  end
36
33
  end
37
34
  end
data/lib/ahoy.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  require "ipaddr"
2
2
 
3
+ # dependencies
3
4
  require "active_support"
4
5
  require "active_support/core_ext"
5
- require "addressable/uri"
6
6
  require "geocoder"
7
7
  require "safely/core"
8
8
 
9
+ # modules
9
10
  require "ahoy/utils"
10
11
  require "ahoy/base_store"
11
12
  require "ahoy/controller"
@@ -72,7 +73,7 @@ module Ahoy
72
73
  self.track_bots = false
73
74
 
74
75
  mattr_accessor :bot_detection_version
75
- self.bot_detection_version = 1
76
+ self.bot_detection_version = 2
76
77
 
77
78
  mattr_accessor :token_generator
78
79
  self.token_generator = -> { SecureRandom.uuid }
@@ -81,10 +82,12 @@ module Ahoy
81
82
  self.mask_ips = false
82
83
 
83
84
  mattr_accessor :user_agent_parser
84
- self.user_agent_parser = :legacy
85
+ self.user_agent_parser = :device_detector
86
+
87
+ mattr_accessor :logger
85
88
 
86
89
  def self.log(message)
87
- Rails.logger.info { "[ahoy] #{message}" }
90
+ logger.info { "[ahoy] #{message}" } if logger
88
91
  end
89
92
 
90
93
  def self.mask_ip(ip)
@@ -52,11 +52,13 @@ module Ahoy
52
52
  if Ahoy.user_agent_parser == :device_detector
53
53
  detector = DeviceDetector.new(request.user_agent)
54
54
  if Ahoy.bot_detection_version == 2
55
- detector.bot? || detector.device_type.nil?
55
+ detector.bot? || (detector.device_type.nil? && detector.os_name.nil?)
56
56
  else
57
57
  detector.bot?
58
58
  end
59
59
  else
60
+ # no need to throw friendly error if browser isn't defined
61
+ # since will error in visit_properties
60
62
  Browser.new(request.user_agent).bot?
61
63
  end
62
64
  else
@@ -1,5 +1,3 @@
1
- require "request_store"
2
-
3
1
  module Ahoy
4
2
  module Controller
5
3
  def self.included(base)
@@ -9,7 +7,7 @@ module Ahoy
9
7
  end
10
8
  base.before_action :set_ahoy_cookies, unless: -> { Ahoy.api_only }
11
9
  base.before_action :track_ahoy_visit, unless: -> { Ahoy.api_only }
12
- base.before_action :set_ahoy_request_store
10
+ base.around_action :set_ahoy_request_store
13
11
  end
14
12
 
15
13
  def ahoy
@@ -41,7 +39,13 @@ module Ahoy
41
39
  end
42
40
 
43
41
  def set_ahoy_request_store
44
- RequestStore.store[:ahoy] ||= ahoy
42
+ previous_value = Thread.current[:ahoy]
43
+ begin
44
+ Thread.current[:ahoy] = ahoy
45
+ yield
46
+ ensure
47
+ Thread.current[:ahoy] = previous_value
48
+ end
45
49
  end
46
50
  end
47
51
  end
@@ -34,7 +34,7 @@ module Ahoy
34
34
  # upsert since visit might not be found due to eventual consistency
35
35
  visit_model.where(visit_token: visit_token).find_one_and_update({"$set": data}, {upsert: true})
36
36
  elsif visit
37
- visit.update_attributes(data)
37
+ visit.update!(data)
38
38
  else
39
39
  Ahoy.log "Visit for geocode not found: #{visit_token}"
40
40
  end
data/lib/ahoy/engine.rb CHANGED
@@ -1,6 +1,8 @@
1
1
  module Ahoy
2
2
  class Engine < ::Rails::Engine
3
3
  initializer "ahoy", after: "sprockets.environment" do
4
+ Ahoy.logger ||= Rails.logger
5
+
4
6
  # allow Devise to be loaded after Ahoy
5
7
  require "ahoy/warden" if defined?(Warden)
6
8
 
data/lib/ahoy/model.rb CHANGED
@@ -2,14 +2,12 @@ module Ahoy
2
2
  module Model
3
3
  def visitable(name = :visit, **options)
4
4
  class_eval do
5
- safe_options = options.dup
6
- safe_options[:optional] = true if Rails::VERSION::MAJOR >= 5
7
- belongs_to(name, class_name: "Ahoy::Visit", **safe_options)
5
+ belongs_to(name, class_name: "Ahoy::Visit", optional: true, **options)
8
6
  before_create :set_ahoy_visit
9
7
  end
10
8
  class_eval %{
11
9
  def set_ahoy_visit
12
- self.#{name} ||= RequestStore.store[:ahoy].try(:visit_or_create)
10
+ self.#{name} ||= Thread.current[:ahoy].try(:visit_or_create)
13
11
  end
14
12
  }
15
13
  end
data/lib/ahoy/tracker.rb CHANGED
@@ -127,7 +127,6 @@ module Ahoy
127
127
  @user ||= @store.user
128
128
  end
129
129
 
130
- # TODO better name
131
130
  def visit_properties
132
131
  @visit_properties ||= Ahoy::VisitProperties.new(request, api: api?).generate
133
132
  end
@@ -186,7 +185,7 @@ module Ahoy
186
185
 
187
186
  def trusted_time(time = nil)
188
187
  if !time || (api? && !(1.minute.ago..Time.now).cover?(time))
189
- Time.zone.now
188
+ Time.current
190
189
  else
191
190
  time
192
191
  end
@@ -197,7 +196,7 @@ module Ahoy
197
196
  end
198
197
 
199
198
  def report_exception(e)
200
- raise e if Rails.env.development? || Rails.env.test?
199
+ raise e if !defined?(Rails) || Rails.env.development? || Rails.env.test?
201
200
  Safely.report_exception(e)
202
201
  end
203
202
 
data/lib/ahoy/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ahoy
2
- VERSION = "2.2.1"
2
+ VERSION = "3.0.0"
3
3
  end
@@ -1,7 +1,6 @@
1
- require "browser"
1
+ require "cgi"
2
2
  require "device_detector"
3
- require "referer-parser"
4
- require "user_agent_parser"
3
+ require "uri"
5
4
 
6
5
  module Ahoy
7
6
  class VisitProperties
@@ -21,23 +20,26 @@ module Ahoy
21
20
  private
22
21
 
23
22
  def utm_properties
24
- landing_uri = Addressable::URI.parse(landing_page) rescue nil
25
- landing_params = (landing_uri && landing_uri.query_values) || {}
23
+ landing_params = {}
24
+ begin
25
+ landing_uri = URI.parse(landing_page)
26
+ # could also use Rack::Utils.parse_nested_query
27
+ landing_params = CGI.parse(landing_uri.query) if landing_uri
28
+ rescue
29
+ # do nothing
30
+ end
26
31
 
27
32
  props = {}
28
33
  %w(utm_source utm_medium utm_term utm_content utm_campaign).each do |name|
29
- props[name.to_sym] = params[name] || landing_params[name]
34
+ props[name.to_sym] = params[name] || landing_params[name].try(:first)
30
35
  end
31
36
  props
32
37
  end
33
38
 
34
39
  def traffic_properties
35
- # cache for performance
36
- @@referrer_parser ||= RefererParser::Parser.new
37
-
40
+ uri = URI.parse(referrer) rescue nil
38
41
  {
39
- referring_domain: (Addressable::URI.parse(referrer).host.first(255) rescue nil),
40
- search_keyword: (@@referrer_parser.parse(@referrer)[:term].first(255) rescue nil).presence
42
+ referring_domain: uri.try(:host).try(:first, 255)
41
43
  }
42
44
  end
43
45
 
@@ -60,6 +62,9 @@ module Ahoy
60
62
  device_type: device_type
61
63
  }
62
64
  else
65
+ raise "Add browser to your Gemfile to use legacy user agent parsing" unless defined?(Browser)
66
+ raise "Add user_agent_parser to your Gemfile to use legacy user agent parsing" unless defined?(UserAgentParser)
67
+
63
68
  # cache for performance
64
69
  @@user_agent_parser ||= UserAgentParser::Parser.new
65
70
 
@@ -27,8 +27,7 @@ module Ahoy
27
27
  template "active_record_visit_model.rb", "app/models/ahoy/visit.rb"
28
28
  template "active_record_event_model.rb", "app/models/ahoy/event.rb"
29
29
  migration_template "active_record_migration.rb", "db/migrate/create_ahoy_visits_and_events.rb", migration_version: migration_version
30
- migrate_command = rails5? ? "rails" : "rake"
31
- puts "\nAlmost set! Last, run:\n\n #{migrate_command} db:migrate"
30
+ puts "\nAlmost set! Last, run:\n\n rails db:migrate"
32
31
  end
33
32
 
34
33
  def properties_type
@@ -44,14 +43,12 @@ module Ahoy
44
43
  end
45
44
  end
46
45
 
47
- def rails5?
48
- Rails::VERSION::MAJOR >= 5
46
+ def rails52?
47
+ ActiveRecord::VERSION::STRING >= "5.2"
49
48
  end
50
49
 
51
50
  def migration_version
52
- if rails5?
53
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
54
- end
51
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
55
52
  end
56
53
  end
57
54
  end
@@ -11,10 +11,6 @@ module Ahoy
11
11
  template "mongoid_event_model.rb", "app/models/ahoy/event.rb"
12
12
  puts "\nAlmost set! Last, run:\n\n rake db:mongoid:create_indexes"
13
13
  end
14
-
15
- def rails5?
16
- Rails::VERSION::MAJOR >= 5
17
- end
18
14
  end
19
15
  end
20
16
  end
@@ -1,10 +1,10 @@
1
- class Ahoy::Event < <%= rails5? ? "ApplicationRecord" : "ActiveRecord::Base" %>
1
+ class Ahoy::Event < ApplicationRecord
2
2
  include Ahoy::QueryMethods
3
3
 
4
4
  self.table_name = "ahoy_events"
5
5
 
6
6
  belongs_to :visit
7
- belongs_to :user<%= rails5? ? ", optional: true" : nil %><% if properties_type == "text" %>
7
+ belongs_to :user, optional: true<% if properties_type == "text" %>
8
8
 
9
9
  serialize :properties, JSON<% end %>
10
10
  end
@@ -26,8 +26,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
26
26
  t.string :country
27
27
  t.string :region
28
28
  t.string :city
29
- t.decimal :latitude, precision: 10, scale: 8
30
- t.decimal :longitude, precision: 11, scale: 8
29
+ t.float :latitude
30
+ t.float :longitude
31
31
 
32
32
  # utm parameters
33
33
  t.string :utm_source
@@ -55,7 +55,8 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
55
55
  t.timestamp :time
56
56
  end
57
57
 
58
- add_index :ahoy_events, [:name, :time]<% if properties_type == "jsonb" && rails5? %>
59
- add_index :ahoy_events, "properties jsonb_path_ops", using: "gin"<% end %>
58
+ add_index :ahoy_events, [:name, :time]<% if properties_type == "jsonb" %><% if rails52? %>
59
+ add_index :ahoy_events, :properties, using: :gin, opclass: :jsonb_path_ops<% else %>
60
+ add_index :ahoy_events, "properties jsonb_path_ops", using: "gin"<% end %><% end %>
60
61
  end
61
62
  end
@@ -1,6 +1,6 @@
1
- class Ahoy::Visit < <%= rails5? ? "ApplicationRecord" : "ActiveRecord::Base" %>
1
+ class Ahoy::Visit < ApplicationRecord
2
2
  self.table_name = "ahoy_visits"
3
3
 
4
4
  has_many :events, class_name: "Ahoy::Event"
5
- belongs_to :user<%= rails5? ? ", optional: true" : nil %>
5
+ belongs_to :user, optional: true
6
6
  end
@@ -18,9 +18,3 @@ end
18
18
 
19
19
  # set to true for JavaScript tracking
20
20
  Ahoy.api = false
21
-
22
- # better user agent parsing
23
- Ahoy.user_agent_parser = :device_detector
24
-
25
- # better bot detection
26
- Ahoy.bot_detection_version = 2
@@ -3,9 +3,3 @@ end
3
3
 
4
4
  # set to true for JavaScript tracking
5
5
  Ahoy.api = false
6
-
7
- # better user agent parsing
8
- Ahoy.user_agent_parser = :device_detector
9
-
10
- # better bot detection
11
- Ahoy.bot_detection_version = 2
@@ -3,7 +3,7 @@ class Ahoy::Event
3
3
 
4
4
  # associations
5
5
  belongs_to :visit, index: true
6
- belongs_to :user, index: true<%= rails5? ? ", optional: true" : nil %>
6
+ belongs_to :user, index: true, optional: true
7
7
 
8
8
  # fields
9
9
  field :name, type: String
@@ -3,7 +3,7 @@ class Ahoy::Visit
3
3
 
4
4
  # associations
5
5
  has_many :events, class_name: "Ahoy::Event"
6
- belongs_to :user, index: true<%= rails5? ? ", optional: true" : nil %>
6
+ belongs_to :user, index: true, optional: true
7
7
 
8
8
  # required
9
9
  field :visit_token, type: String
metadata CHANGED
@@ -1,43 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_matey
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-27 00:00:00.000000000 Z
11
+ date: 2019-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: railties
14
+ name: activesupport
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '5'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
27
- - !ruby/object:Gem::Dependency
28
- name: addressable
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
26
+ version: '5'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: geocoder
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -52,62 +38,6 @@ dependencies:
52
38
  - - ">="
53
39
  - !ruby/object:Gem::Version
54
40
  version: 1.4.5
55
- - !ruby/object:Gem::Dependency
56
- name: browser
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '2.0'
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.0'
69
- - !ruby/object:Gem::Dependency
70
- name: referer-parser
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0.3'
76
- type: :runtime
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0.3'
83
- - !ruby/object:Gem::Dependency
84
- name: user_agent_parser
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :runtime
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: request_store
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
41
  - !ruby/object:Gem::Dependency
112
42
  name: safely_block
113
43
  requirement: !ruby/object:Gem::Requirement
@@ -288,7 +218,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
288
218
  requirements:
289
219
  - - ">="
290
220
  - !ruby/object:Gem::Version
291
- version: '2.2'
221
+ version: '2.4'
292
222
  required_rubygems_version: !ruby/object:Gem::Requirement
293
223
  requirements:
294
224
  - - ">="