rate_center 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.release-please-manifest.json +3 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +26 -0
  5. data/.tool-versions +1 -0
  6. data/CHANGELOG.md +17 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +102 -0
  9. data/Rakefile +12 -0
  10. data/data/cities/us/ak.yml +6420 -0
  11. data/data/cities/us/al.yml +10684 -0
  12. data/data/cities/us/ar.yml +11308 -0
  13. data/data/cities/us/az.yml +8396 -0
  14. data/data/cities/us/ca.yml +30626 -0
  15. data/data/cities/us/co.yml +9787 -0
  16. data/data/cities/us/ct.yml +3388 -0
  17. data/data/cities/us/dc.yml +12 -0
  18. data/data/cities/us/de.yml +1424 -0
  19. data/data/cities/us/fl.yml +17198 -0
  20. data/data/cities/us/ga.yml +12062 -0
  21. data/data/cities/us/hi.yml +2846 -0
  22. data/data/cities/us/ia.yml +18822 -0
  23. data/data/cities/us/id.yml +4324 -0
  24. data/data/cities/us/il.yml +27206 -0
  25. data/data/cities/us/in.yml +17594 -0
  26. data/data/cities/us/ks.yml +13626 -0
  27. data/data/cities/us/ky.yml +9958 -0
  28. data/data/cities/us/la.yml +8786 -0
  29. data/data/cities/us/ma.yml +2288 -0
  30. data/data/cities/us/md.yml +10738 -0
  31. data/data/cities/us/me.yml +1194 -0
  32. data/data/cities/us/mi.yml +13662 -0
  33. data/data/cities/us/mn.yml +16378 -0
  34. data/data/cities/us/mo.yml +21572 -0
  35. data/data/cities/us/ms.yml +7762 -0
  36. data/data/cities/us/mt.yml +9032 -0
  37. data/data/cities/us/nc.yml +14140 -0
  38. data/data/cities/us/nd.yml +7300 -0
  39. data/data/cities/us/ne.yml +10622 -0
  40. data/data/cities/us/nh.yml +740 -0
  41. data/data/cities/us/nj.yml +11848 -0
  42. data/data/cities/us/nm.yml +9352 -0
  43. data/data/cities/us/nv.yml +2652 -0
  44. data/data/cities/us/ny.yml +17946 -0
  45. data/data/cities/us/oh.yml +22704 -0
  46. data/data/cities/us/ok.yml +15154 -0
  47. data/data/cities/us/or.yml +7680 -0
  48. data/data/cities/us/pa.yml +32546 -0
  49. data/data/cities/us/pr.yml +5121 -0
  50. data/data/cities/us/ri.yml +560 -0
  51. data/data/cities/us/sc.yml +8768 -0
  52. data/data/cities/us/sd.yml +8768 -0
  53. data/data/cities/us/tn.yml +9404 -0
  54. data/data/cities/us/tx.yml +36996 -0
  55. data/data/cities/us/ut.yml +6308 -0
  56. data/data/cities/us/va.yml +12194 -0
  57. data/data/cities/us/vt.yml +1910 -0
  58. data/data/cities/us/wa.yml +11900 -0
  59. data/data/cities/us/wi.yml +14564 -0
  60. data/data/cities/us/wv.yml +7984 -0
  61. data/data/cities/us/wy.yml +3674 -0
  62. data/data/rate_centers/us/.keep +0 -0
  63. data/data/rate_centers/us/ak.yml +4584 -0
  64. data/data/rate_centers/us/al.yml +9798 -0
  65. data/data/rate_centers/us/ar.yml +15882 -0
  66. data/data/rate_centers/us/as.yml +119 -0
  67. data/data/rate_centers/us/az.yml +4159 -0
  68. data/data/rate_centers/us/ca.yml +21059 -0
  69. data/data/rate_centers/us/co.yml +6502 -0
  70. data/data/rate_centers/us/ct.yml +4086 -0
  71. data/data/rate_centers/us/dc.yml +16 -0
  72. data/data/rate_centers/us/de.yml +1133 -0
  73. data/data/rate_centers/us/fl.yml +10773 -0
  74. data/data/rate_centers/us/ga.yml +10143 -0
  75. data/data/rate_centers/us/gu.yml +218 -0
  76. data/data/rate_centers/us/hi.yml +1130 -0
  77. data/data/rate_centers/us/ia.yml +15438 -0
  78. data/data/rate_centers/us/id.yml +4357 -0
  79. data/data/rate_centers/us/il.yml +25322 -0
  80. data/data/rate_centers/us/in.yml +13924 -0
  81. data/data/rate_centers/us/ks.yml +12312 -0
  82. data/data/rate_centers/us/ky.yml +18629 -0
  83. data/data/rate_centers/us/la.yml +7785 -0
  84. data/data/rate_centers/us/ma.yml +7947 -0
  85. data/data/rate_centers/us/md.yml +6956 -0
  86. data/data/rate_centers/us/me.yml +9213 -0
  87. data/data/rate_centers/us/mi.yml +15653 -0
  88. data/data/rate_centers/us/mn.yml +15195 -0
  89. data/data/rate_centers/us/mo.yml +18238 -0
  90. data/data/rate_centers/us/mp.yml +29 -0
  91. data/data/rate_centers/us/ms.yml +7913 -0
  92. data/data/rate_centers/us/mt.yml +5659 -0
  93. data/data/rate_centers/us/nc.yml +11641 -0
  94. data/data/rate_centers/us/nd.yml +7341 -0
  95. data/data/rate_centers/us/ne.yml +8727 -0
  96. data/data/rate_centers/us/nh.yml +4499 -0
  97. data/data/rate_centers/us/nj.yml +13710 -0
  98. data/data/rate_centers/us/nm.yml +4636 -0
  99. data/data/rate_centers/us/nv.yml +2629 -0
  100. data/data/rate_centers/us/ny.yml +34576 -0
  101. data/data/rate_centers/us/oh.yml +20184 -0
  102. data/data/rate_centers/us/ok.yml +9970 -0
  103. data/data/rate_centers/us/or.yml +6867 -0
  104. data/data/rate_centers/us/pa.yml +40360 -0
  105. data/data/rate_centers/us/pr.yml +1899 -0
  106. data/data/rate_centers/us/ri.yml +1225 -0
  107. data/data/rate_centers/us/sc.yml +6251 -0
  108. data/data/rate_centers/us/sd.yml +6256 -0
  109. data/data/rate_centers/us/tn.yml +9289 -0
  110. data/data/rate_centers/us/tx.yml +27690 -0
  111. data/data/rate_centers/us/ut.yml +4712 -0
  112. data/data/rate_centers/us/va.yml +17679 -0
  113. data/data/rate_centers/us/vi.yml +146 -0
  114. data/data/rate_centers/us/vt.yml +4667 -0
  115. data/data/rate_centers/us/wa.yml +8151 -0
  116. data/data/rate_centers/us/wi.yml +12872 -0
  117. data/data/rate_centers/us/wv.yml +14818 -0
  118. data/data/rate_centers/us/wy.yml +2852 -0
  119. data/lib/rate_center/city.rb +33 -0
  120. data/lib/rate_center/collection.rb +23 -0
  121. data/lib/rate_center/data_loader.rb +75 -0
  122. data/lib/rate_center/data_prep.rb +121 -0
  123. data/lib/rate_center/data_source/local_calling_guide.rb +107 -0
  124. data/lib/rate_center/data_source/simple_maps.rb +93 -0
  125. data/lib/rate_center/distance.rb +3 -0
  126. data/lib/rate_center/errors.rb +6 -0
  127. data/lib/rate_center/rate_center.rb +34 -0
  128. data/lib/rate_center/vector.rb +3 -0
  129. data/lib/rate_center/version.rb +5 -0
  130. data/lib/rate_center.rb +21 -0
  131. data/release-please-config.json +15 -0
  132. metadata +400 -0
@@ -0,0 +1,33 @@
1
+
2
+ require "ostruct"
3
+ require_relative "collection"
4
+ require_relative "vector"
5
+ require_relative "distance"
6
+
7
+ module RateCenter
8
+ class City < OpenStruct
9
+ extend Collection
10
+
11
+ class << self
12
+ private
13
+
14
+ def data
15
+ ::RateCenter.data_loader.cities
16
+ end
17
+
18
+ def load_collection
19
+ data.map do |data|
20
+ city = new(**data)
21
+ city.nearby_rate_centers = Array(data["nearby_rate_centers"]).map do |rate_center|
22
+ distance = rate_center.fetch("distance")
23
+ Vector.new(
24
+ name: rate_center.fetch("name"),
25
+ distance: Distance.new(value: distance.fetch("value"), units: distance.fetch("units"))
26
+ )
27
+ end
28
+ city
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ module RateCenter
2
+ module Collection
3
+ def collection
4
+ raise Errors::DataNotLoadedError.new("No data loaded. Load data with RateCenter.load before calling this method") if data.nil?
5
+
6
+ @collection ||= load_collection
7
+ end
8
+
9
+ def all
10
+ collection
11
+ end
12
+
13
+ def find_by(attributes)
14
+ collection.find do |region|
15
+ attributes.all? { |key, value| region[key] == value }
16
+ end
17
+ end
18
+
19
+ def find_by!(*)
20
+ find_by(*) || raise(Errors::NotFoundError.new)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,75 @@
1
+ require "yaml"
2
+
3
+ module RateCenter
4
+ class DataLoader
5
+ attr_reader :data_directory, :cities, :rate_centers
6
+
7
+ def initialize(**options)
8
+ @data_directory = options.fetch(:data_directory) { Pathname(File.expand_path("../../data/", __dir__)) }
9
+ end
10
+
11
+ def load(type, ...)
12
+ case type.to_sym
13
+ when :all
14
+ @cities = load_data("cities", :all)
15
+ @rate_centers = load_data("rate_centers", :all)
16
+ when :cities
17
+ @cities = load_data("cities", ...)
18
+ when :rate_centers
19
+ @rate_centers = load_data("rate_centers", ...)
20
+ else
21
+ raise ArgumentError, "Invalid type: #{type}"
22
+ end
23
+
24
+ nil
25
+ end
26
+
27
+ private
28
+
29
+ def load_data(type, all = nil, **options)
30
+ if all
31
+ load_data_from(data_directory.join(type).glob("**/*.yml"), type:)
32
+ else
33
+ load_data_with_filter(options.fetch(:only), type:)
34
+ end
35
+ end
36
+
37
+ def load_data_with_filter(filter, type:)
38
+ unless filter.is_a?(Hash)
39
+ return Array(filter).each_with_object([]) do |country, result|
40
+ result.concat(load_country_data(type:, country:))
41
+ end
42
+ end
43
+
44
+ filter.each_with_object([]) do |(country, regions), result|
45
+ if regions.is_a?(Hash)
46
+ regions.each do |region, keys|
47
+ data = load_region_data(type:, country:, region:)
48
+ result.concat(data.select { |d| Array(keys).include?(d.fetch("name")) })
49
+ end
50
+ else
51
+ Array(regions).each do |region|
52
+ result.concat(load_region_data(type:, country:, region:))
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def load_data_from(files, type:)
59
+ Array(files).each_with_object([]) do |file, result|
60
+ result.concat(YAML.load(file.read).fetch(type))
61
+ end
62
+ end
63
+
64
+ def load_country_data(type:, country:)
65
+ load_data_from(data_directory.join(type.to_s, country.to_s.downcase).glob("**/*.yml"), type:)
66
+ end
67
+
68
+ def load_region_data(type:, country:, region:)
69
+ load_data_from(
70
+ data_directory.join(type.to_s, country.to_s.downcase, "#{region.to_s.downcase}.yml"),
71
+ type:
72
+ )
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,121 @@
1
+ require "yaml"
2
+ require "geocoder"
3
+
4
+ module RateCenter
5
+ class DataPrep
6
+ attr_reader :data_directory, :logger
7
+
8
+ def initialize(**options)
9
+ @data_directory = options.fetch(:data_directory)
10
+ end
11
+
12
+ def call
13
+ update_rate_centers_with_closest_city
14
+ update_cities_with_nearby_rate_centers
15
+ end
16
+
17
+ private
18
+
19
+ def update_rate_centers_with_closest_city
20
+ rate_center_data.each do |region, rate_centers|
21
+ rate_centers.each do |rate_center|
22
+ next if rate_center["lat"].nil? || rate_center["long"].nil?
23
+
24
+ closest_city = find_closest(
25
+ lat: rate_center.fetch("lat"),
26
+ long: rate_center.fetch("long"),
27
+ data: city_data[region],
28
+ key: ->(data) { data.fetch("name") }
29
+ ).first
30
+
31
+ next if closest_city.nil?
32
+
33
+ rate_center["closest_city"] = {
34
+ "name" => closest_city.name,
35
+ "distance" => {
36
+ "value" => closest_city.distance.round(2),
37
+ "units" => "km"
38
+ }
39
+ }
40
+ end
41
+ end
42
+
43
+ write_data("rate_centers", "us", rate_center_data)
44
+ end
45
+
46
+ def update_cities_with_nearby_rate_centers
47
+ city_data.each do |region, cities|
48
+ candidates = Array(rate_center_data[region]).reject { |data| data["lat"].nil? }
49
+
50
+ cities.each do |city|
51
+ candidate_distances = find_closest(
52
+ lat: city.fetch("lat"),
53
+ long: city.fetch("long"),
54
+ data: candidates,
55
+ key: ->(data) { data.fetch("name") }
56
+ )
57
+
58
+ candidates_by_distance = candidate_distances.each_with_object(Hash.new { |h, k| h[k] = [] }) do |rate_center, result|
59
+ result[rate_center.distance] << rate_center
60
+ end
61
+
62
+ nearby_rate_centers = candidates_by_distance.keys.first(3).each_with_object([]) do |distance, result|
63
+ result.concat(candidates_by_distance.fetch(distance))
64
+ end
65
+
66
+ city["nearby_rate_centers"] = nearby_rate_centers.map do |rate_center|
67
+ {
68
+ "name" => rate_center.name,
69
+ "distance" => {
70
+ "value" => rate_center.distance.round(2),
71
+ "units" => "km"
72
+ }
73
+ }
74
+ end
75
+ end
76
+ end
77
+
78
+ write_data("cities", "us", city_data)
79
+ end
80
+
81
+ def find_closest(lat:, long:, data:, key:)
82
+ distance_to = Class.new(Struct.new(:name, :distance, keyword_init: true))
83
+
84
+ distances_to = Array(data).map do |d|
85
+ distance_to.new(
86
+ name: key.call(d),
87
+ distance: Geocoder::Calculations.distance_between(
88
+ [ lat, long ],
89
+ [ d.fetch("lat"), d.fetch("long") ],
90
+ units: :km
91
+ )
92
+ )
93
+ end
94
+
95
+ distances_to.sort_by(&:distance)
96
+ end
97
+
98
+ def write_data(type, country, data)
99
+ data.each do |state, state_data|
100
+ state_file = data_directory.join(type, country, "#{state.downcase}.yml")
101
+ state_file.write({ type => state_data }.to_yaml)
102
+ end
103
+ end
104
+
105
+ def city_data
106
+ @city_data ||= load_data("cities", "us")
107
+ end
108
+
109
+ def rate_center_data
110
+ @rate_center_data ||= load_data("rate_centers", "us")
111
+ end
112
+
113
+ def load_data(type, country)
114
+ data_directory.join(type, country).glob("**/*.yml").each_with_object({}) do |state_file, result|
115
+ data = YAML.load(state_file.read)
116
+ state = state_file.basename(".yml").to_s
117
+ result[state.upcase] = data.fetch(type.to_s)
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,107 @@
1
+ require "faraday"
2
+ require "multi_xml"
3
+ require "rack"
4
+ require "yaml"
5
+ require "countries"
6
+ require "ostruct"
7
+
8
+ module RateCenter
9
+ module DataSource
10
+ class LocalCallingGuide
11
+ attr_reader :client, :data_directory
12
+
13
+ def initialize(**options)
14
+ @client = options.fetch(:client) { Client.new }
15
+ end
16
+
17
+ class ResponseParser
18
+ Response = Struct.new(:rate_centers, keyword_init: true)
19
+
20
+ attr_reader :parser
21
+
22
+ def initialize(**options)
23
+ @parser = options.fetch(:parser) { MultiXml }
24
+ end
25
+
26
+ def parse(xml)
27
+ data = parser.parse(xml)
28
+ rc_data = data.dig("root", "rcdata")
29
+
30
+ return Response.new(rate_centers: []) if rc_data.nil?
31
+
32
+ rc_data = rc_data.is_a?(Array) ? rc_data : Array([ rc_data ])
33
+ rate_centers = rc_data.map do |d|
34
+ OpenStruct.new(d.transform_values { |v| v.strip unless v.strip.empty? })
35
+ end
36
+
37
+ Response.new(rate_centers: rate_centers)
38
+ end
39
+ end
40
+
41
+ class Client
42
+ HOST = "https://localcallingguide.com/".freeze
43
+
44
+ attr_reader :host, :http_client, :response_parser
45
+
46
+ def initialize(**options)
47
+ @host = options.fetch(:host, HOST)
48
+ @http_client = options.fetch(:http_client) { default_http_client }
49
+ @response_parser = options.fetch(:response_parser) { ResponseParser.new }
50
+ end
51
+
52
+ def fetch_rate_center_data(params)
53
+ uri = URI("/xmlrc.php")
54
+ uri.query = Rack::Utils.build_query(params)
55
+ response = http_client.get(uri)
56
+ response_parser.parse(response.body)
57
+ end
58
+
59
+ private
60
+
61
+ def default_http_client
62
+ Faraday.new(url: host) do |builder|
63
+ builder.headers["Accept"] = "application/xml"
64
+ builder.headers["Content-Type"] = "application/xml"
65
+
66
+ builder.response :raise_error
67
+ end
68
+ end
69
+ end
70
+
71
+ def load_data!(**options)
72
+ data_directory = options.fetch(:data_directory)
73
+ FileUtils.mkdir_p(data_directory)
74
+
75
+ us_regions = Array(regions_for("US"))
76
+
77
+ Array(us_regions).each do |region, _|
78
+ data_file = data_directory.join("#{region.downcase}.yml")
79
+ rate_centers = client.fetch_rate_center_data(region:).rate_centers
80
+ next if rate_centers.empty?
81
+
82
+ data = rate_centers.sort_by(&:rc).map do |rate_center|
83
+ {
84
+ "country" => "US",
85
+ "region" => region,
86
+ "exchange" => rate_center.exch,
87
+ "name" => rate_center.rcshort || rate_center.rc,
88
+ "full_name" => rate_center.rc,
89
+ "lata" => rate_center.lata,
90
+ "ilec_name" => rate_center.ilec_name,
91
+ "lat" => rate_center.rc_lat,
92
+ "long" => rate_center.rc_lon
93
+ }
94
+ end
95
+
96
+ data_file.write({ "rate_centers" => data }.to_yaml)
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ def regions_for(country_code)
103
+ ISO3166::Country.new(country_code).subdivisions
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,93 @@
1
+ require "faraday"
2
+ require "zip"
3
+ require "csv"
4
+ require "yaml"
5
+ require "ostruct"
6
+
7
+ module RateCenter
8
+ module DataSource
9
+ class SimpleMaps
10
+ class ResponseParser
11
+ DATABASE_FILENAME = "uscities.csv".freeze
12
+
13
+ def parse(response)
14
+ database_file = extract_zipped_file(response, filename: DATABASE_FILENAME)
15
+
16
+ CSV.parse(database_file.read, headers: true).each_with_object([]) do |row_data, result|
17
+ result << OpenStruct.new(row_data.to_h)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def extract_zipped_file(zip_data, filename:)
24
+ Zip::InputStream.open(StringIO.new(zip_data)) do |zip_stream|
25
+ while (entry = zip_stream.get_next_entry)
26
+ return entry.get_input_stream if entry.name == filename
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ class Client
33
+ HOST = "https://simplemaps.com/".freeze
34
+ DEFAULT_DOWNLOAD_PATH = "static/data/us-cities/1.79/basic/simplemaps_uscities_basicv1.79.zip"
35
+
36
+ attr_reader :host, :http_client, :response_parser
37
+
38
+ def initialize(**options)
39
+ @host = options.fetch(:host, HOST)
40
+ @http_client = options.fetch(:http_client) { default_http_client }
41
+ @response_parser = options.fetch(:response_parser) { ResponseParser.new }
42
+ end
43
+
44
+ def fetch_data(**options)
45
+ uri = URI(options.fetch(:path, DEFAULT_DOWNLOAD_PATH))
46
+ response = http_client.get(uri)
47
+ response_parser.parse(response.body)
48
+ end
49
+
50
+ private
51
+
52
+ def default_http_client
53
+ Faraday.new(url: host) do |builder|
54
+ builder.response :raise_error
55
+ end
56
+ end
57
+ end
58
+
59
+ attr_reader :client, :data_directory
60
+
61
+ def initialize(**options)
62
+ @client = options.fetch(:client) { Client.new }
63
+ end
64
+
65
+ def load_data!(**options)
66
+ data_directory = options.fetch(:data_directory)
67
+ FileUtils.mkdir_p(data_directory)
68
+
69
+ data = client.fetch_data
70
+
71
+ cities_by_state = data.each_with_object(Hash.new { |h, k| h[k] = [] }) do |city, result|
72
+ result[city.state_id] << city
73
+ end
74
+
75
+ cities_by_state.each do |state, cities|
76
+ data_file = data_directory.join("#{state.downcase}.yml")
77
+
78
+ data = cities.sort_by(&:city).map do |city|
79
+ {
80
+ "country" => "US",
81
+ "region" => city.state_id,
82
+ "name" => city.city,
83
+ "lat" => city.lat,
84
+ "long" => city.lng
85
+ }
86
+ end
87
+
88
+ data_file.write({ "cities" => data }.to_yaml)
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module RateCenter
2
+ Distance = Struct.new(:value, :units, keyword_init: true)
3
+ end
@@ -0,0 +1,6 @@
1
+ module RateCenter
2
+ module Errors
3
+ class NotFoundError < StandardError; end
4
+ class DataNotLoadedError < StandardError; end
5
+ end
6
+ end
@@ -0,0 +1,34 @@
1
+ require "ostruct"
2
+ require_relative "collection"
3
+ require_relative "vector"
4
+ require_relative "distance"
5
+
6
+ module RateCenter
7
+ class RateCenter < OpenStruct
8
+ extend Collection
9
+
10
+ class << self
11
+ private
12
+
13
+ def data
14
+ ::RateCenter.data_loader.rate_centers
15
+ end
16
+
17
+ def load_collection
18
+ data.map do |data|
19
+ rate_center = new(**data)
20
+ closest_city = data["closest_city"]
21
+ next rate_center if closest_city.nil?
22
+
23
+ distance = closest_city.fetch("distance")
24
+ rate_center.closest_city = Vector.new(
25
+ name: closest_city.fetch("name"),
26
+ distance: Distance.new(value: distance.fetch("value"), units: distance.fetch("units"))
27
+ )
28
+
29
+ rate_center
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module RateCenter
2
+ Vector = Struct.new(:name, :distance, keyword_init: true)
3
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RateCenter
4
+ VERSION = "0.1.2"
5
+ end
@@ -0,0 +1,21 @@
1
+ module RateCenter
2
+ class << self
3
+ def load(...)
4
+ data_loader.load(...)
5
+ end
6
+
7
+ def unload
8
+ @data_loader = nil
9
+ end
10
+
11
+ def data_loader
12
+ @data_loader ||= DataLoader.new
13
+ end
14
+ end
15
+ end
16
+
17
+ require_relative "rate_center/errors"
18
+ require_relative "rate_center/data_loader"
19
+ require_relative "rate_center/city"
20
+ require_relative "rate_center/rate_center"
21
+ require_relative "rate_center/version"
@@ -0,0 +1,15 @@
1
+ {
2
+ "include-component-in-tag": false,
3
+ "version-file": "lib/rate_center/version.rb",
4
+ "packages": {
5
+ ".": {
6
+ "changelog-path": "CHANGELOG.md",
7
+ "release-type": "ruby",
8
+ "bump-minor-pre-major": true,
9
+ "bump-patch-for-minor-pre-major": false,
10
+ "draft": false,
11
+ "prerelease": false
12
+ }
13
+ },
14
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json"
15
+ }