ast-tdl 0.0.1 → 0.0.4

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: 2f857804cef121dd1c5f2a8e41ab0d27098517e03ee15c8316bc0e62d7707093
4
- data.tar.gz: 2235c16bf905edf99c00693477e5b9c0f037b084c39ca541bec49f00031f9cdb
3
+ metadata.gz: 757763f7548180daaeaf4e4d427a9837584d0f3b68ef8b08fc2cefffab8b293e
4
+ data.tar.gz: 4518d44a21c598c06872b1b5c60d13cd62816fd192e550c80a7e45f9617c4306
5
5
  SHA512:
6
- metadata.gz: 62436ef8167db994e207f1309c7a41a9b022ceae7ca85f82f57b9f630134965859ceb845953b99c5858a3a16613961ba04507451252a27597da9702e86458655
7
- data.tar.gz: 10e94fd67a4301721b0b600b4786fe73d5527493a3c192d85e1f7d8c290fe376a79f4e3ebab62f63eba8748b7af025fbf59cd1d4203b608634e5f0ae31f644b5
6
+ metadata.gz: cf4a6d62f36951fcf352b6c93d31d4ba2a170169b1a82e7beb493b3283c7df5f1eecef2f62bdd94a18f86437e647665a8d2f5c5af357e82925b1ea199a10d642
7
+ data.tar.gz: d594576289625b607ebb359fbbe5e22623fafd0f9dcf904d33cc088b479dbfdba1c6b9c022c65e2534891cd7ae7295d770ee93d3bea322464d65f243dea30b3b
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Iztok Fister Jr.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,33 +1,61 @@
1
1
  # Training Description Language (TDL) for Artificial Sport Trainer (AST)
2
2
 
3
- AST-DSL is a very small domain-specific language
3
+ ## Motivation
4
+ ast-dsl is intended to be a small DSL for practical definition and description of sports training that can be automatically or manually defined and used in conjunction with Artificial Sport Trainer.
4
5
 
5
- ## Objective
6
+ ## Feature diagram
7
+ ![scheme](https://user-images.githubusercontent.com/73126820/175337865-77344476-b7c8-45d4-bda2-0aca82aebefd.png)
6
8
 
7
9
  ## Installation
8
-
9
10
  $ gem install ast-tdl
10
11
 
11
12
  ## Language description
13
+ Training Description Language (TDL) is implemented in Ruby. Currently, the description of sports training sessions and intervals is now supported. Those contain various data, such as duration, average heart rate, sport type, and many more.
12
14
 
13
15
  ## Examples
16
+ ```ruby
17
+ EasyTraining = Ast.build :Monday do
18
+ session("Short swimming session today") {
19
+ sport :"swim"
20
+ info :"Very easy training"
21
+ average_heart_rate :"130"
22
+ total_duration :"30"
23
+ }
24
+
25
+ session("Bike ride") {
26
+ sport :"bike"
27
+ info :"Endurance ride with intervals"
28
+ average_heart_rate :"140"
29
+ total_duration :"250"
30
+ }
31
+
32
+ interval("Number 1") {
33
+ sport :"swim"
34
+ info :"Moderate"
35
+ average_heart_rate :"160"
36
+ total_duration :"5"
37
+ average_heart_rate_rest :"90"
38
+ total_duration_rest :"2"
39
+ }
40
+ end
41
+ ```
14
42
 
15
43
  ### Session
16
-
17
44
  ```ruby
18
45
  session("Short swimming session today") {
19
- sport :"swim"
20
- info :"Very easy training"
21
- avhr :"130"
22
- td :"30"
46
+ sport :"swim"
47
+ info :"Very easy training"
48
+ average_heart_rate :"130"
49
+ total_duration :"30"
23
50
  }
24
51
  ```
25
- ## License
26
52
 
53
+ ## License
27
54
  This package is distributed under the MIT License. This license can be found online at <http://www.opensource.org/licenses/MIT>.
28
55
 
29
56
  ## Disclaimer
30
-
31
57
  This framework is provided as-is, and there are no guarantees that it fits your purposes or that it is bug-free. Use it at your own risk!
32
58
 
59
+ ## References
33
60
 
61
+ Fister Jr, I., Fister, I., Iglesias, A., Galvez, A., Deb, S., & Fister, D. (2021). On deploying the Artificial Sport Trainer into practice. arXiv preprint [arXiv:2109.13334](https://arxiv.org/abs/2109.13334).
data/lib/ast-tdl.rb CHANGED
@@ -1 +1,3 @@
1
- require 'ast'
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './ast'
data/lib/ast.rb CHANGED
@@ -1,53 +1,85 @@
1
- require 'json'
1
+ # frozen_string_literal: true
2
2
 
3
+ require 'json'
3
4
  require_relative 'classes'
4
5
  require_relative 'interval'
5
6
  require_relative 'session'
6
7
 
7
-
8
+ ##
9
+ # This module is intended to be used for building trainings
10
+ # from the domain specific language AST-TDL.
8
11
  module Ast
9
- def self.build(name, &block)
10
- training = Training.new(name)
11
- training.instance_eval(&block)
12
- return training
13
- end
14
-
15
- class Training
16
- def initialize(name)
17
- @name = name
18
- @session = []
19
- @interval = []
20
- end
21
-
22
- def session(name, &block)
23
- training_type = Session.new(name)
24
- training_type.instance_eval(&block)
25
- @session << training_type
26
- end
27
-
28
- def interval(name, &block)
29
- interval_data = Interval.new(name)
30
- interval_data.instance_eval(&block)
31
- @interval << interval_data
32
- end
33
-
34
- def to_s
35
- str = "#{@name} #{@session[0]}"
36
- end
37
-
38
- def json
39
- training_json = {
40
- name: @name,
41
- session: @session.collect { |x| x.to_hash },
42
- interval: @interval.collect { |x| x.to_hash },
43
- }
44
- training_json.to_json
45
- end
46
-
47
- def save_to_file(filename)
48
- f = File.open(filename, "w")
49
- f.puts(json)
50
- f.close
51
- end
52
- end
12
+ ##
13
+ # Building a new training from the domain specific language.
14
+ # Params:
15
+ # +name+:: the name of the training
16
+ # +block+:: training data
17
+ def self.build(name, &block)
18
+ training = Training.new(name)
19
+ training.instance_eval(&block)
20
+ training
21
+ end
22
+
23
+ ##
24
+ # This class represents a training with a name, sessions and intervals.
25
+ class Training
26
+ ##
27
+ # Initialization method for the +Training+ class.
28
+ # Params:
29
+ # +name+:: the name of the training
30
+ def initialize(name)
31
+ @name = name
32
+ @session = []
33
+ @interval = []
34
+ end
35
+
36
+ ##
37
+ # Building a new session from the domain specific language.
38
+ # Params:
39
+ # +name+:: the name of the session
40
+ # +block+:: session data
41
+ def session(name, &block)
42
+ training_type = Session.new(name)
43
+ training_type.instance_eval(&block)
44
+ @session << training_type
45
+ end
46
+
47
+ ##
48
+ # Building a new interval from the domain specific language.
49
+ # Params:
50
+ # +name+:: the name of the interval
51
+ # +block+:: interval data
52
+ def interval(name, &block)
53
+ interval_data = Interval.new(name)
54
+ interval_data.instance_eval(&block)
55
+ @interval << interval_data
56
+ end
57
+
58
+ ##
59
+ # Converting a training to a string.
60
+ def to_s
61
+ "#{@name} #{@session[0]}"
62
+ end
63
+
64
+ ##
65
+ # Converting a training to a JSON-ized string.
66
+ def json
67
+ training_json = {
68
+ name: @name,
69
+ session: @session.collect(&:to_hash),
70
+ interval: @interval.collect(&:to_hash)
71
+ }
72
+ training_json.to_json
73
+ end
74
+
75
+ ##
76
+ # Saving a training to a JSON file.
77
+ # Params:
78
+ # +filename+:: the desired name of the file
79
+ def save_to_file(filename)
80
+ f = File.open(filename, 'w')
81
+ f.puts(json)
82
+ f.close
83
+ end
84
+ end
53
85
  end
data/lib/classes.rb CHANGED
@@ -1,86 +1,148 @@
1
- require 'json'
1
+ # frozen_string_literal: true
2
2
 
3
+ require 'json'
3
4
 
5
+ ##
6
+ # This class represents a sport with a type.
4
7
  class Sport
5
- attr_reader :type
6
-
7
- def initialize(type)
8
- @type = type
9
- end
10
-
11
- def to_hash
12
- sport_json = {
13
- type: @type
14
- }
15
- end
8
+ # The type of a sport.
9
+ attr_reader :type
10
+
11
+ ##
12
+ # Initialization method for the +Sport+ class.
13
+ # Params:
14
+ # +type+:: the type of the sport
15
+ def initialize(type)
16
+ @type = type
17
+ end
18
+
19
+ ##
20
+ # Converting +Sport+ class to a hash.
21
+ def to_hash
22
+ {
23
+ type: @type
24
+ }
25
+ end
16
26
  end
17
27
 
28
+ ##
29
+ # This class represents information with a message.
18
30
  class Info
19
- attr_reader :message
20
-
21
- def initialize(message)
22
- @message = message
23
- end
24
-
25
- def to_hash
26
- info_json = {
27
- message: @message
28
- }
29
- end
31
+ # The info message.
32
+ attr_reader :message
33
+
34
+ ##
35
+ # Initialization method for the +Info+ class.
36
+ # Params:
37
+ # +message+:: the info message
38
+ def initialize(message)
39
+ @message = message
40
+ end
41
+
42
+ ##
43
+ # Converting +Info+ class to a hash.
44
+ def to_hash
45
+ {
46
+ message: @message
47
+ }
48
+ end
30
49
  end
31
50
 
32
- class Avhr
33
- attr_reader :heart_rate
34
-
35
- def initialize(heart_rate)
36
- @heart_rate = heart_rate
37
- end
38
-
39
- def to_hash
40
- info_json = {
41
- average_hr: @heart_rate
42
- }
43
- end
51
+ ##
52
+ # This class represents an average heart rate.
53
+ class AverageHeartRate
54
+ # An average heart rate.
55
+ attr_reader :heart_rate
56
+
57
+ ##
58
+ # Initialization method for the +AverageHeartRate+ class.
59
+ # Params:
60
+ # +heart_rate+:: the average heart rate
61
+ def initialize(heart_rate)
62
+ heart_rate = heart_rate.to_s.to_i
63
+ raise ArgumentError, 'Maximum heart rate is 220.' if heart_rate > 220
64
+
65
+ @heart_rate = heart_rate
66
+ end
67
+
68
+ ##
69
+ # Converting +AverageHeartRate+ class to a hash.
70
+ def to_hash
71
+ {
72
+ average_hr: @heart_rate
73
+ }
74
+ end
44
75
  end
45
76
 
46
- class Td
47
- attr_reader :duration
48
-
49
- def initialize(duration)
50
- @duration = duration
51
- end
52
-
53
- def to_hash
54
- td_json = {
55
- duration: @duration
56
- }
57
- end
77
+ ##
78
+ # This class represents a total duration of a session or an interval.
79
+ class TotalDuration
80
+ # The total duration in seconds.
81
+ attr_reader :duration
82
+
83
+ ##
84
+ # Initialization method for the +TotalDuration+ class.
85
+ # Params:
86
+ # +duration+:: the total duration
87
+ def initialize(duration)
88
+ @duration = duration
89
+ end
90
+
91
+ ##
92
+ # Converting +TotalDuration+ class to a hash.
93
+ def to_hash
94
+ {
95
+ duration: @duration
96
+ }
97
+ end
58
98
  end
59
99
 
60
- class AvhrRest
61
- attr_reader :avhr_rest
62
-
63
- def initialize(avhr_rest)
64
- @avhr_rest = avhr_rest
65
- end
66
-
67
- def to_hash
68
- avhr_json = {
69
- average_hr_rest: @avhr_rest
70
- }
71
- end
100
+ ##
101
+ # This class represents an average heart rate in the resting period.
102
+ class AverageHeartRateRest
103
+ # The average rest heart rate.
104
+ attr_reader :average_heart_rate_rest
105
+
106
+ ##
107
+ # Initialization method for the +AverageHeartRateRest+ class.
108
+ # Params:
109
+ # +average_heart_rate_rest+:: the average heart rate
110
+ def initialize(average_heart_rate_rest)
111
+ average_heart_rate_rest = average_heart_rate_rest.to_s.to_i
112
+ raise ArgumentError, 'Maximum heart rate is 220.' if average_heart_rate_rest > 220
113
+
114
+ @average_heart_rate_rest = average_heart_rate_rest
115
+ end
116
+
117
+ ##
118
+ # Converting +AverageHeartRateRest+ class to a hash.
119
+ def to_hash
120
+ {
121
+ average_heart_rate_rest: @average_heart_rate_rest
122
+ }
123
+ end
72
124
  end
73
125
 
74
- class TdRest
75
- attr_reader :td_rest
76
-
77
- def initialize(td_rest)
78
- @td_rest = td_rest
79
- end
80
-
81
- def to_hash
82
- td_json = {
83
- duration_rest: @td_rest
84
- }
85
- end
126
+ ##
127
+ # This class represents a total duration of a session or an
128
+ # interval in the resting period.
129
+ class TotalDurationRest
130
+ # The total duration in seconds.
131
+ attr_reader :total_duration_rest
132
+
133
+ ##
134
+ # Initialization method for the +TotalDurationRest+ class.
135
+ # Params:
136
+ # +total_duration_rest+:: the total rest duration
137
+ def initialize(total_duration_rest)
138
+ @total_duration_rest = total_duration_rest
139
+ end
140
+
141
+ ##
142
+ # Converting +TotalDurationRest+ class to a hash.
143
+ def to_hash
144
+ {
145
+ total_duration_rest: @total_duration_rest
146
+ }
147
+ end
86
148
  end
data/lib/interval.rb CHANGED
@@ -1,51 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # This class represents an interval.
1
5
  class Interval
2
- def initialize(name)
3
- @name = []
4
- @sport = []
5
- @info = []
6
- @avhr = []
7
- @td = []
8
- @avhr_rest = []
9
- @td_rest = []
10
- end
11
-
12
- def sport(type)
13
- @sport << Sport.new(type)
14
- end
15
-
16
- def info(message)
17
- @info << Info.new(message)
18
- end
19
-
20
- def avhr(heart_rate)
21
- @avhr << Avhr.new(heart_rate)
22
- end
23
-
24
- def td(duration)
25
- @td << Td.new(duration)
26
- end
27
-
28
- def avhr_rest(heart_rate_rest)
29
- @avhr_rest << AvhrRest.new(heart_rate_rest)
30
- end
31
-
32
- def td_rest(duration_rest)
33
- @td_rest << TdRest.new(duration_rest)
34
- end
35
-
36
- def to_s
37
- str = "#{@sport[0].type} #{@info[0].message}"
38
- end
39
-
40
- def to_hash
41
- interval_json = {
42
- name: @name.collect { |x| x.to_hash },
43
- sport: @sport.collect { |x| x.to_hash },
44
- info: @info.collect { |x| x.to_hash },
45
- average_hr: @avhr.collect { |x| x.to_hash },
46
- duration: @td.collect { |x| x.to_hash },
47
- average_hr_rest: @avhr_rest.collect { |x| x.to_hash },
48
- duration_rest: @td_rest.collect { |x| x.to_hash },
49
- }
50
- end
51
- end
6
+ ##
7
+ # Initialization method for the +Interval+ class.
8
+ # Params:
9
+ # +name+:: the name of the interval
10
+ def initialize(_name)
11
+ @name = []
12
+ @sport = []
13
+ @info = []
14
+ @average_heart_rate = []
15
+ @total_duration = []
16
+ @average_heart_rate_rest = []
17
+ @total_duration_rest = []
18
+ end
19
+
20
+ ##
21
+ # Building a new Sport object.
22
+ # Params:
23
+ # +type+:: the type of the sport
24
+ def sport(type)
25
+ @sport << Sport.new(type)
26
+ end
27
+
28
+ ##
29
+ # Building a new Info object.
30
+ # Params:
31
+ # +message+:: the info message
32
+ def info(message)
33
+ @info << Info.new(message)
34
+ end
35
+
36
+ ##
37
+ # Building a new AverageHeartRate object.
38
+ # Params:
39
+ # +heart_rate+:: the average heart rate in bpm
40
+ def average_heart_rate(heart_rate)
41
+ @average_heart_rate << AverageHeartRate.new(heart_rate)
42
+ end
43
+
44
+ ##
45
+ # Building a new TotalDuration object.
46
+ # Params:
47
+ # +duration+:: the duration in seconds
48
+ def total_duration(duration)
49
+ @total_duration << TotalDuration.new(duration)
50
+ end
51
+
52
+ ##
53
+ # Building a new AverageHeartRateRest object.
54
+ # Params:
55
+ # +heart_rate_rest+:: the average rest heart rate in bpm
56
+ def average_heart_rate_rest(heart_rate_rest)
57
+ @average_heart_rate_rest << AverageHeartRateRest.new(heart_rate_rest)
58
+ end
59
+
60
+ ##
61
+ # Building a new TotalDurationRest object.
62
+ # Params:
63
+ # +duration rest+:: the rest duration in seconds
64
+ def total_duration_rest(duration_rest)
65
+ @total_duration_rest << TotalDurationRest.new(duration_rest)
66
+ end
67
+
68
+ ##
69
+ # Converting an interval to a string.
70
+ def to_s
71
+ "#{@sport[0].type} #{@info[0].message}"
72
+ end
73
+
74
+ ##
75
+ # Converting an interval to a JSON-ized string.
76
+ def to_hash
77
+ {
78
+ name: @name.collect(&:to_hash),
79
+ sport: @sport.collect(&:to_hash),
80
+ info: @info.collect(&:to_hash),
81
+ average_heart_rate: @average_heart_rate.collect(&:to_hash),
82
+ total_duration: @total_duration.collect(&:to_hash),
83
+ average_heart_rate_rest: @average_heart_rate_rest.collect(&:to_hash),
84
+ total_duration_rest: @total_duration_rest.collect(&:to_hash),
85
+ }
86
+ end
87
+ end
data/lib/session.rb CHANGED
@@ -1,42 +1,67 @@
1
- require 'json'
2
-
1
+ # frozen_string_literal: true
3
2
 
3
+ ##
4
+ # This class represents a session.
4
5
  class Session
5
- def initialize(name)
6
- @name = []
7
- @sport = []
8
- @info = []
9
- @avhr = []
10
- @td = []
11
- end
6
+ ##
7
+ # Initialization method for the +Session+ class.
8
+ # Params:
9
+ # +name+:: the name of the session
10
+ def initialize(_name)
11
+ @name = []
12
+ @sport = []
13
+ @info = []
14
+ @average_heart_rate = []
15
+ @total_duration = []
16
+ end
12
17
 
13
- def sport(type)
14
- @sport << Sport.new(type)
15
- end
18
+ ##
19
+ # Building a new Sport object.
20
+ # Params:
21
+ # +type+:: the type of the sport
22
+ def sport(type)
23
+ @sport << Sport.new(type)
24
+ end
16
25
 
17
- def info(message)
18
- @info << Info.new(message)
19
- end
26
+ ##
27
+ # Building a new Info object.
28
+ # Params:
29
+ # +message+:: the info message
30
+ def info(message)
31
+ @info << Info.new(message)
32
+ end
20
33
 
21
- def avhr(heart_rate)
22
- @avhr << Avhr.new(heart_rate)
23
- end
34
+ ##
35
+ # Building a new AverageHeartRate object.
36
+ # Params:
37
+ # +heart_rate+:: the average heart rate in bpm
38
+ def average_heart_rate(heart_rate)
39
+ @average_heart_rate << AverageHeartRate.new(heart_rate)
40
+ end
24
41
 
25
- def td(duration)
26
- @td << Td.new(duration)
27
- end
42
+ ##
43
+ # Building a new TotalDuration object.
44
+ # Params:
45
+ # +duration+:: the duration in seconds
46
+ def total_duration(duration)
47
+ @total_duration << TotalDuration.new(duration)
48
+ end
28
49
 
29
- def to_s
30
- str = "#{@sport[0].type} #{@info[0].message}"
31
- end
50
+ ##
51
+ # Converting a session to a string.
52
+ def to_s
53
+ "#{@sport[0].type} #{@info[0].message}"
54
+ end
32
55
 
33
- def to_hash
34
- session_json = {
35
- name: @name.collect { |x| x.to_hash },
36
- sport: @sport.collect { |x| x.to_hash },
37
- info: @info.collect { |x| x.to_hash },
38
- average_hr: @avhr.collect { |x| x.to_hash },
39
- duration: @td.collect { |x| x.to_hash },
40
- }
41
- end
42
- end
56
+ ##
57
+ # Converting a session to a JSON-ized string.
58
+ def to_hash
59
+ {
60
+ name: @name.collect(&:to_hash),
61
+ sport: @sport.collect(&:to_hash),
62
+ info: @info.collect(&:to_hash),
63
+ average_heart_rate: @average_heart_rate.collect(&:to_hash),
64
+ total_duration: @total_duration.collect(&:to_hash),
65
+ }
66
+ end
67
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ast-tdl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - firefly-cpp
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-06-14 00:00:00.000000000 Z
12
+ date: 2022-06-28 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email:
@@ -19,18 +19,20 @@ executables: []
19
19
  extensions: []
20
20
  extra_rdoc_files: []
21
21
  files:
22
+ - LICENSE
22
23
  - README.md
23
24
  - lib/ast-tdl.rb
24
25
  - lib/ast.rb
25
26
  - lib/classes.rb
26
27
  - lib/interval.rb
27
28
  - lib/session.rb
28
- homepage: https://github.com/firefly-cpp/AST-DSL
29
- licenses: []
29
+ homepage: https://github.com/firefly-cpp/ast-tdl
30
+ licenses:
31
+ - MIT
30
32
  metadata:
31
- homepage_uri: https://github.com/firefly-cpp/AST-DSL
32
- source_code_uri: https://github.com/firefly-cpp/AST-DSL
33
- changelog_uri: https://github.com/firefly-cpp/AST-DSL
33
+ homepage_uri: https://github.com/firefly-cpp/ast-tdl
34
+ source_code_uri: https://github.com/firefly-cpp/ast-tdl
35
+ changelog_uri: https://github.com/firefly-cpp/ast-tdl
34
36
  post_install_message:
35
37
  rdoc_options: []
36
38
  require_paths:
@@ -39,7 +41,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
39
41
  requirements:
40
42
  - - ">="
41
43
  - !ruby/object:Gem::Version
42
- version: 2.4.0
44
+ version: 2.6.0
43
45
  required_rubygems_version: !ruby/object:Gem::Requirement
44
46
  requirements:
45
47
  - - ">="