calcpace 1.8.0 → 1.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb37c0c8cf8bb5944459915e43549229d6db504b77538729cea721fa041f7266
4
- data.tar.gz: d6900ff2d3cd7e2a821d4637d96beafa69cd8e656a31f2251b68d9e7a818cefb
3
+ metadata.gz: f8e3c9a491b95568c00e5fabb1a9ba33be46c07035f72a24e51155b60bd6ecaa
4
+ data.tar.gz: 7c644cc582c27f1204a98bf86238c45b5a236520350c97786d04d119698a2840
5
5
  SHA512:
6
- metadata.gz: 683f9af0342d287411cc79fd6b2acbf3ebae0d2bf408a282f2309b36a6f62e7478d51983d9ab86bb9c5b524ffe55ab0b445ac9c6b212bd628466adba84e0e249
7
- data.tar.gz: 95286680a44cceede252bb0b9429ba321be66a895246986339dd261af30c0547f8f95726d36bfc85fc2da1e8333fad9141d3836f2659b0237ef39a56ea8f1f6a
6
+ metadata.gz: a503fad2dcb76fc61459315f9f6d866dc47cad64fff8459c5ea94ba3b82f22664e2b04a2e7a105de4130e169661de7c01b7b6dc54950bdf2b5179279d30e75d4
7
+ data.tar.gz: 28e0d2c909e0a7c811d0f992a397b63de2be086ed76a64e29839884a5597d6f1ce161dca9b3092a308947fb49c0bf7d7aca4fdfb351c51fe56253a5096e92efa
@@ -8,12 +8,24 @@ on:
8
8
  branches: [ "main" ]
9
9
 
10
10
  jobs:
11
+ lint:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - name: Checkout code
15
+ uses: actions/checkout@v4
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: .ruby-version
20
+ bundler-cache: true
21
+ - name: Run RuboCop
22
+ run: bundle exec rubocop
11
23
  test:
12
24
  runs-on: ubuntu-latest
13
25
  strategy:
14
26
  fail-fast: false
15
27
  matrix:
16
- ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', '3.4']
28
+ ruby: ['3.2', '3.3', '3.4', '4.0']
17
29
  steps:
18
30
  - name: Checkout code
19
31
  uses: actions/checkout@v4
data/.gitignore CHANGED
@@ -1,3 +1,5 @@
1
+ coverage/
2
+
1
3
  calcpace-*.gem
2
4
  !calcpace.gemspec
3
5
  improvements_plan.md
data/.rubocop.yml CHANGED
@@ -4,7 +4,7 @@
4
4
  # Following Ruby best practices and style guidelines
5
5
 
6
6
  AllCops:
7
- TargetRubyVersion: 2.7
7
+ TargetRubyVersion: 3.2
8
8
  NewCops: enable
9
9
  Exclude:
10
10
  - 'vendor/**/*'
@@ -55,6 +55,14 @@ Metrics/BlockLength:
55
55
  - 'test/**/*'
56
56
  - '*.gemspec'
57
57
 
58
+ Metrics/ClassLength:
59
+ Exclude:
60
+ - 'test/**/*'
61
+
62
+ Metrics/ModuleLength:
63
+ Exclude:
64
+ - 'lib/calcpace/race_splits.rb'
65
+
58
66
  # Allow both single and double quotes for strings
59
67
  Style/StringLiteralsInInterpolation:
60
68
  Enabled: false
data/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.8.1] - 2026-03-06
9
+
10
+ ### Added
11
+ - SimpleCov integration for code coverage measurement
12
+ - RuboCop lint job to CI pipeline
13
+ - YARD documentation for all previously undocumented public methods in `Calculator` (`checked_velocity`, `clock_velocity`, `checked_pace`, `clock_pace`, `time`, `checked_time`, `clock_time`, `distance`, `checked_distance`)
14
+
15
+ ### Changed
16
+ - Minimum required Ruby version bumped from 2.7 to 3.2
17
+ - CI matrix updated: removed EOL Ruby versions (2.7, 3.0, 3.1), added Ruby 4.0
18
+ - CI lint job uses `.ruby-version` file instead of a hardcoded version
19
+ - Bundler updated to 4.0.6
20
+ - `Rakefile.rb` renamed to `Rakefile` (standard convention)
21
+ - `PaceConverter` constants `MI_TO_KM` and `KM_TO_MI` consolidated into `Converter::Distance`
22
+ - Negative and positive split calculations refactored to share common logic
23
+ - Test files refactored to inherit from shared `CalcpaceTest` base class
24
+
8
25
  ## [1.8.0] - 2026-02-14
9
26
 
10
27
  ### Added
data/Gemfile CHANGED
@@ -7,3 +7,4 @@ gem 'rake', '~> 13.2'
7
7
  gem 'rake-compiler', '~> 1.0'
8
8
  gem 'rdoc', '~> 6.2'
9
9
  gem 'rubocop', '~> 1.69'
10
+ gem 'simplecov', '~> 0.22', require: false
data/Gemfile.lock CHANGED
@@ -1,45 +1,68 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- ast (2.4.2)
5
- date (3.4.1)
6
- json (2.10.2)
7
- language_server-protocol (3.17.0.4)
4
+ addressable (2.8.9)
5
+ public_suffix (>= 2.0.2, < 8.0)
6
+ ast (2.4.3)
7
+ bigdecimal (4.0.1)
8
+ date (3.5.1)
9
+ docile (1.4.1)
10
+ erb (6.0.2)
11
+ json (2.19.0)
12
+ json-schema (6.2.0)
13
+ addressable (~> 2.8)
14
+ bigdecimal (>= 3.1, < 5)
15
+ language_server-protocol (3.17.0.5)
8
16
  lint_roller (1.1.0)
9
- minitest (5.25.4)
10
- parallel (1.26.3)
11
- parser (3.3.7.1)
17
+ mcp (0.8.0)
18
+ json-schema (>= 4.1)
19
+ minitest (5.27.0)
20
+ parallel (1.27.0)
21
+ parser (3.3.10.2)
12
22
  ast (~> 2.4.1)
13
23
  racc
14
- psych (5.2.3)
24
+ prism (1.9.0)
25
+ psych (5.3.1)
15
26
  date
16
27
  stringio
28
+ public_suffix (7.0.5)
17
29
  racc (1.8.1)
18
30
  rainbow (3.1.1)
19
- rake (13.2.1)
20
- rake-compiler (1.2.9)
31
+ rake (13.3.1)
32
+ rake-compiler (1.3.1)
21
33
  rake
22
- rdoc (6.12.0)
34
+ rdoc (6.17.0)
35
+ erb
23
36
  psych (>= 4.0.0)
24
- regexp_parser (2.10.0)
25
- rubocop (1.73.2)
37
+ tsort
38
+ regexp_parser (2.11.3)
39
+ rubocop (1.85.1)
26
40
  json (~> 2.3)
27
41
  language_server-protocol (~> 3.17.0.2)
28
42
  lint_roller (~> 1.1.0)
43
+ mcp (~> 0.6)
29
44
  parallel (~> 1.10)
30
45
  parser (>= 3.3.0.2)
31
46
  rainbow (>= 2.2.2, < 4.0)
32
47
  regexp_parser (>= 2.9.3, < 3.0)
33
- rubocop-ast (>= 1.38.0, < 2.0)
48
+ rubocop-ast (>= 1.49.0, < 2.0)
34
49
  ruby-progressbar (~> 1.7)
35
50
  unicode-display_width (>= 2.4.0, < 4.0)
36
- rubocop-ast (1.38.1)
37
- parser (>= 3.3.1.0)
51
+ rubocop-ast (1.49.0)
52
+ parser (>= 3.3.7.2)
53
+ prism (~> 1.7)
38
54
  ruby-progressbar (1.13.0)
39
- stringio (3.1.5)
40
- unicode-display_width (3.1.4)
41
- unicode-emoji (~> 4.0, >= 4.0.4)
42
- unicode-emoji (4.0.4)
55
+ simplecov (0.22.0)
56
+ docile (~> 1.1)
57
+ simplecov-html (~> 0.11)
58
+ simplecov_json_formatter (~> 0.1)
59
+ simplecov-html (0.13.2)
60
+ simplecov_json_formatter (0.1.4)
61
+ stringio (3.2.0)
62
+ tsort (0.2.0)
63
+ unicode-display_width (3.2.0)
64
+ unicode-emoji (~> 4.1)
65
+ unicode-emoji (4.2.0)
43
66
 
44
67
  PLATFORMS
45
68
  ruby
@@ -50,6 +73,7 @@ DEPENDENCIES
50
73
  rake-compiler (~> 1.0)
51
74
  rdoc (~> 6.2)
52
75
  rubocop (~> 1.69)
76
+ simplecov (~> 0.22)
53
77
 
54
78
  BUNDLED WITH
55
- 2.4.22
79
+ 4.0.6
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Calcpace [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&r=r&ts=1683906897&type=6e&v=1.8.0&x2=0)](https://badge.fury.io/rb/calcpace)
1
+ # Calcpace [![Gem Version](https://d25lcipzij17d.cloudfront.net/badge.svg?id=rb&r=r&ts=1683906897&type=6e&v=1.8.1&x2=0)](https://badge.fury.io/rb/calcpace)
2
2
 
3
3
  Calcpace is a Ruby gem designed for calculations and conversions related to distance and time. It can calculate velocity, pace, total time, and distance, accepting time in various formats, including HH:MM:SS. The gem supports conversion to 42 different units, including kilometers, miles, meters, and feet. It also provides methods to validate input.
4
4
 
@@ -7,7 +7,7 @@ Calcpace is a Ruby gem designed for calculations and conversions related to dist
7
7
  ### Add to your Gemfile
8
8
 
9
9
  ```ruby
10
- gem 'calcpace', '~> 1.8.0'
10
+ gem 'calcpace', '~> 1.8.1'
11
11
  ```
12
12
 
13
13
  Then run:
data/calcpace.gemspec CHANGED
@@ -9,11 +9,11 @@ Gem::Specification.new do |spec|
9
9
  spec.email = ['joaogilberto@tuta.io']
10
10
 
11
11
  spec.summary = 'A Ruby gem for pace, distance, and time calculations.'
12
- spec.description = 'Calcpace provides methods to calculate and convert values related to pace, distance, time, and speed. It supports various time formats and unit conversions.'
12
+ spec.description = 'Ruby gem for pace, distance, time, and speed calculations. Supports multiple units and formats.'
13
13
  spec.homepage = 'https://github.com/0jonjo/calcpace'
14
14
  spec.metadata['source_code_uri'] = spec.homepage
15
15
  spec.license = 'MIT'
16
- spec.required_ruby_version = '>= 2.7.0'
16
+ spec.required_ruby_version = '>= 3.2.0'
17
17
 
18
18
  spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
19
19
  spec.metadata['rubygems_mfa_required'] = 'true'
@@ -21,11 +21,31 @@ module Calculator
21
21
  distance.to_f / time
22
22
  end
23
23
 
24
+ # Calculates velocity from a time string
25
+ #
26
+ # @param time [String] time in HH:MM:SS or MM:SS format
27
+ # @param distance [Numeric] distance in any unit (e.g., meters, kilometers)
28
+ # @return [Float] velocity (distance/time)
29
+ # @raise [Calcpace::InvalidTimeFormatError] if time string is invalid
30
+ # @raise [Calcpace::NonPositiveInputError] if distance is not positive
31
+ #
32
+ # @example
33
+ # checked_velocity('01:00:00', 10_000) #=> 2.778 (10000 meters / 3600 seconds)
24
34
  def checked_velocity(time, distance)
25
35
  seconds = convert_to_seconds(validate_time(time))
26
36
  velocity(seconds, distance)
27
37
  end
28
38
 
39
+ # Calculates velocity from a time string and returns result as a clock time string
40
+ #
41
+ # @param time [String] time in HH:MM:SS or MM:SS format
42
+ # @param distance [Numeric] distance in any unit
43
+ # @return [String] velocity in HH:MM:SS format
44
+ # @raise [Calcpace::InvalidTimeFormatError] if time string is invalid
45
+ # @raise [Calcpace::NonPositiveInputError] if distance is not positive
46
+ #
47
+ # @example
48
+ # clock_velocity('01:00:00', 10_000) #=> '00:00:00'
29
49
  def clock_velocity(time, distance)
30
50
  convert_to_clocktime(checked_velocity(time, distance))
31
51
  end
@@ -44,34 +64,101 @@ module Calculator
44
64
  time.to_f / distance
45
65
  end
46
66
 
67
+ # Calculates pace from a time string
68
+ #
69
+ # @param time [String] time in HH:MM:SS or MM:SS format
70
+ # @param distance [Numeric] distance in any unit (e.g., kilometers, miles)
71
+ # @return [Float] pace (time/distance) in seconds
72
+ # @raise [Calcpace::InvalidTimeFormatError] if time string is invalid
73
+ # @raise [Calcpace::NonPositiveInputError] if distance is not positive
74
+ #
75
+ # @example
76
+ # checked_pace('00:50:00', 10) #=> 300.0 (300 seconds/km = 5:00/km)
47
77
  def checked_pace(time, distance)
48
78
  seconds = convert_to_seconds(validate_time(time))
49
79
  pace(seconds, distance)
50
80
  end
51
81
 
82
+ # Calculates pace from a time string and returns result as a clock time string
83
+ #
84
+ # @param time [String] time in HH:MM:SS or MM:SS format
85
+ # @param distance [Numeric] distance in any unit
86
+ # @return [String] pace in HH:MM:SS format
87
+ # @raise [Calcpace::InvalidTimeFormatError] if time string is invalid
88
+ # @raise [Calcpace::NonPositiveInputError] if distance is not positive
89
+ #
90
+ # @example
91
+ # clock_pace('00:50:00', 10) #=> '00:05:00'
52
92
  def clock_pace(time, distance)
53
93
  convert_to_clocktime(checked_pace(time, distance))
54
94
  end
55
95
 
96
+ # Calculates time given velocity and distance
97
+ #
98
+ # @param velocity [Numeric] velocity in any unit
99
+ # @param distance [Numeric] distance in any unit
100
+ # @return [Float] time (velocity * distance)
101
+ # @raise [Calcpace::NonPositiveInputError] if velocity or distance is not positive
102
+ #
103
+ # @example
104
+ # time(300, 10) #=> 3000.0 (300 s/km * 10 km = 3000 seconds)
56
105
  def time(velocity, distance)
57
106
  validate_positive({ velocity: velocity, distance: distance })
58
107
  velocity * distance
59
108
  end
60
109
 
110
+ # Calculates time from a velocity string and distance
111
+ #
112
+ # @param velocity [String] velocity in HH:MM:SS or MM:SS format
113
+ # @param distance [Numeric] distance in any unit
114
+ # @return [Float] time in seconds
115
+ # @raise [Calcpace::InvalidTimeFormatError] if velocity string is invalid
116
+ # @raise [Calcpace::NonPositiveInputError] if distance is not positive
117
+ #
118
+ # @example
119
+ # checked_time('05:00', 10) #=> 3000.0 (5:00/km * 10 km = 3000 seconds)
61
120
  def checked_time(velocity, distance)
62
121
  velocity_seconds = convert_to_seconds(validate_time(velocity))
63
122
  time(velocity_seconds, distance)
64
123
  end
65
124
 
125
+ # Calculates time from a velocity string and returns result as a clock time string
126
+ #
127
+ # @param velocity [String] velocity in HH:MM:SS or MM:SS format
128
+ # @param distance [Numeric] distance in any unit
129
+ # @return [String] time in HH:MM:SS format
130
+ # @raise [Calcpace::InvalidTimeFormatError] if velocity string is invalid
131
+ # @raise [Calcpace::NonPositiveInputError] if distance is not positive
132
+ #
133
+ # @example
134
+ # clock_time('05:00', 10) #=> '00:50:00'
66
135
  def clock_time(velocity, distance)
67
136
  convert_to_clocktime(checked_time(velocity, distance))
68
137
  end
69
138
 
139
+ # Calculates distance given time and velocity
140
+ #
141
+ # @param time [Numeric] time in any unit
142
+ # @param velocity [Numeric] velocity in any unit
143
+ # @return [Float] distance (time/velocity)
144
+ # @raise [Calcpace::NonPositiveInputError] if time or velocity is not positive
145
+ #
146
+ # @example
147
+ # distance(3000, 300) #=> 10.0 (3000 seconds / 300 s/km = 10 km)
70
148
  def distance(time, velocity)
71
149
  validate_positive({ time: time, velocity: velocity })
72
150
  time.to_f / velocity
73
151
  end
74
152
 
153
+ # Calculates distance from time and velocity strings
154
+ #
155
+ # @param time [String] time in HH:MM:SS or MM:SS format
156
+ # @param velocity [String] velocity in HH:MM:SS or MM:SS format
157
+ # @return [Float] distance
158
+ # @raise [Calcpace::InvalidTimeFormatError] if any string is invalid
159
+ #
160
+ # @example
161
+ # checked_distance('00:50:00', '05:00') #=> 10.0 (50 min / 5:00/km = 10 km)
75
162
  def checked_distance(time, velocity)
76
163
  time_seconds = convert_to_seconds(validate_time(time))
77
164
  velocity_seconds = convert_to_seconds(validate_time(velocity))
@@ -39,7 +39,7 @@ module ConverterChain
39
39
  def convert_chain_with_description(value, conversions)
40
40
  initial_value = value
41
41
  result = convert_chain(value, conversions)
42
- conversion_names = conversions.map(&:to_s).join(' → ')
42
+ conversion_names = conversions.join(' → ')
43
43
  description = "#{initial_value} → #{conversion_names} → #{result.round(4)}"
44
44
 
45
45
  { result: result, description: description }
@@ -5,10 +5,6 @@
5
5
  # This module provides methods to convert running pace between kilometers
6
6
  # and miles, maintaining the time per distance unit format.
7
7
  module PaceConverter
8
- # Conversion factor: 1 mile = 1.60934 kilometers
9
- MI_TO_KM = 1.60934
10
- KM_TO_MI = 0.621371
11
-
12
8
  # Converts pace from one unit to another
13
9
  #
14
10
  # @param pace [Numeric, String] pace in seconds per unit or time string (MM:SS)
@@ -87,10 +83,10 @@ module PaceConverter
87
83
  case conversion_type
88
84
  when :km_to_mi
89
85
  # If running at X seconds per km, pace per mile = X * (miles to km ratio)
90
- pace_seconds * MI_TO_KM
86
+ pace_seconds * Converter::Distance::MI_TO_KM
91
87
  when :mi_to_km
92
88
  # If running at X seconds per mile, pace per km = X / (miles to km ratio)
93
- pace_seconds * KM_TO_MI
89
+ pace_seconds * Converter::Distance::KM_TO_MI
94
90
  end
95
91
  end
96
92
  end
@@ -136,35 +136,7 @@ module RaceSplits
136
136
  # @param split_km [Float] split distance in kilometers
137
137
  # @return [Array<String>] array of cumulative split times
138
138
  def calculate_negative_splits(total_distance, target_seconds, split_km)
139
- half_distance = total_distance / 2.0
140
- avg_pace = target_seconds / total_distance
141
-
142
- # First half: 4% slower, second half: 4% faster
143
- first_half_pace = avg_pace * 1.04
144
- second_half_pace = avg_pace * 0.96
145
-
146
- splits = []
147
- distance_covered = 0.0
148
- cumulative_time = 0.0
149
-
150
- while distance_covered < total_distance - 0.001
151
- distance_covered += split_km
152
- distance_covered = total_distance if distance_covered > total_distance
153
-
154
- if distance_covered <= half_distance
155
- # First half
156
- cumulative_time = distance_covered * first_half_pace
157
- else
158
- # Second half
159
- time_at_halfway = half_distance * first_half_pace
160
- distance_in_second_half = distance_covered - half_distance
161
- cumulative_time = time_at_halfway + (distance_in_second_half * second_half_pace)
162
- end
163
-
164
- splits << convert_to_clocktime(cumulative_time.round)
165
- end
166
-
167
- splits
139
+ calculate_variable_splits(total_distance, target_seconds, split_km, first_factor: 1.04, second_factor: 0.96)
168
140
  end
169
141
 
170
142
  # Calculates positive splits (first half faster than second half)
@@ -175,12 +147,22 @@ module RaceSplits
175
147
  # @param split_km [Float] split distance in kilometers
176
148
  # @return [Array<String>] array of cumulative split times
177
149
  def calculate_positive_splits(total_distance, target_seconds, split_km)
150
+ calculate_variable_splits(total_distance, target_seconds, split_km, first_factor: 0.96, second_factor: 1.04)
151
+ end
152
+
153
+ # Shared logic for variable pace split strategies
154
+ #
155
+ # @param total_distance [Float] total race distance in kilometers
156
+ # @param target_seconds [Float] target finish time in seconds
157
+ # @param split_km [Float] split distance in kilometers
158
+ # @param first_factor [Float] pace multiplier for the first half
159
+ # @param second_factor [Float] pace multiplier for the second half
160
+ # @return [Array<String>] array of cumulative split times
161
+ def calculate_variable_splits(total_distance, target_seconds, split_km, first_factor:, second_factor:)
178
162
  half_distance = total_distance / 2.0
179
163
  avg_pace = target_seconds / total_distance
180
-
181
- # First half: 4% faster, second half: 4% slower
182
- first_half_pace = avg_pace * 0.96
183
- second_half_pace = avg_pace * 1.04
164
+ first_half_pace = avg_pace * first_factor
165
+ second_half_pace = avg_pace * second_factor
184
166
 
185
167
  splits = []
186
168
  distance_covered = 0.0
@@ -191,10 +173,8 @@ module RaceSplits
191
173
  distance_covered = total_distance if distance_covered > total_distance
192
174
 
193
175
  if distance_covered <= half_distance
194
- # First half
195
176
  cumulative_time = distance_covered * first_half_pace
196
177
  else
197
- # Second half
198
178
  time_at_halfway = half_distance * first_half_pace
199
179
  distance_in_second_half = distance_covered - half_distance
200
180
  cumulative_time = time_at_halfway + (distance_in_second_half * second_half_pace)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Calcpace
4
- VERSION = '1.8.0'
4
+ VERSION = '1.8.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: calcpace
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.0
4
+ version: 1.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - João Gilberto Saraiva
@@ -9,8 +9,8 @@ bindir: exe
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
- description: Calcpace provides methods to calculate and convert values related to
13
- pace, distance, time, and speed. It supports various time formats and unit conversions.
12
+ description: Ruby gem for pace, distance, time, and speed calculations. Supports multiple
13
+ units and formats.
14
14
  email:
15
15
  - joaogilberto@tuta.io
16
16
  executables: []
@@ -26,7 +26,7 @@ files:
26
26
  - Gemfile
27
27
  - Gemfile.lock
28
28
  - README.md
29
- - Rakefile.rb
29
+ - Rakefile
30
30
  - calcpace.gemspec
31
31
  - lib/calcpace.rb
32
32
  - lib/calcpace/calculator.rb
@@ -53,14 +53,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
53
53
  requirements:
54
54
  - - ">="
55
55
  - !ruby/object:Gem::Version
56
- version: 2.7.0
56
+ version: 3.2.0
57
57
  required_rubygems_version: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  requirements: []
63
- rubygems_version: 3.6.7
63
+ rubygems_version: 4.0.6
64
64
  specification_version: 4
65
65
  summary: A Ruby gem for pace, distance, and time calculations.
66
66
  test_files: []
File without changes