runeterra_cards 0.1.0 → 0.3.0

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: 275e8ca4e8362b65da7022dc3042e9fbe3b0970f52443e652476757be52125f1
4
- data.tar.gz: ab803e005acf47f9499aad38aaad76d0e1c59c275dc4457bc8735208f08baace
3
+ metadata.gz: 5e7902d9b185d9d9230fefa7917c9ebf6cfcc7342dedb80e2388594538d940e5
4
+ data.tar.gz: 7412372ff827c53911e6a16430979a80f8f9bb12ce4e0901e1e95ca60673409a
5
5
  SHA512:
6
- metadata.gz: f406aad97cd4b6b57b356f08ff665661d3edecd608467b0a04b2c76d434927bc406cd01fec7f02aa171701f0a0f89fd2e322de7cbc871d18cb58993c9ae4d9e3
7
- data.tar.gz: 96023313de8c2868fbf551185224a9441a13e30ddb297f9766b69b07481f4d21c1a56b78052ec09ba3a5aa22878c39f1c94ef196a235838b5cc447bb08255d96
6
+ metadata.gz: 5f5caa2b4ebe93ce457b5806fea9add1da1aaf0486cf8f6983846b1564adc3ee920331397f0a3b054affce1f8e6464f9e8eb355456ce58366308599c57f9e9af
7
+ data.tar.gz: f613c1bdd35331fcb7ceac4846a252630f3e68556b0d577500e655a0dbc60e5c6406f1ecbe423e73ff9c0d2c0313622b821d7254cf421714d1c28647c8f5e6b4
@@ -0,0 +1,4 @@
1
+ --output-dir yard
2
+ --readme doc/README.md
3
+ -
4
+ doc/*
@@ -0,0 +1,36 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.3.0] - 2020-08-31
8
+ ### Added
9
+ - `Cost` class to represent crafting cost as wildcards & shards.
10
+ - `Metadata#cost_of` to get the cost of crafting a `CardSet`.
11
+ - Documented everything that is public & non-deprecated
12
+
13
+ ## [0.2.3] - 2020-08-31
14
+ ### Fixed
15
+ - Fixed issue with documentation not rendering on rubydoc.info.
16
+
17
+ ## [0.2.2] - 2020-08-30
18
+ ### Fixed
19
+ - Included .yardopts in the Gem so README and CHANGELOG get included in documentation generated from the Gem.
20
+
21
+ ## [0.2.1] - 2020-08-29
22
+ ### Fixed
23
+ - Correctly packaged README and CHANGELOG in the Gem.
24
+
25
+ ## [0.2.0] - 2020-08-29
26
+ ### Added
27
+ - Added support for the Mount Targon faction
28
+ - UnrecognizedVersionError#version returns the version number that wasn't recognized.
29
+ - UnrecognizedFactionError, which is raised by CardAndCount#new (and by extension, CardSet#from_deck_code) if an unrecognized faction number is encountered.
30
+
31
+ ### Changed
32
+ - FACTION_IDENTIFIERS_FROM_INT is now a Hash instead of an Array. The API for looking up a faction identifier by integer should remain unchanged in most cases.
33
+
34
+ ## [0.1.0] - 2020-08-28
35
+ ### Added
36
+ - Initial public release, with support for loading deck codes (Bilgewater and earlier) and loading metadata from Legends of Runeterra Data Dragon.
@@ -0,0 +1,64 @@
1
+ <!-- This is the README file for the Gem documentation / online documentation. It should be thorough and authoritative for using the Gem, but not discuss development concerns, which belong in the Github README. -->
2
+
3
+ ## Description
4
+
5
+ This library makes it easy to decode Legends of Runeterra deck codes, load Data Dragon metadata for cards, and perform operations on the data.
6
+
7
+ ## Installation
8
+
9
+ Add the following to your `Gemfile`:
10
+
11
+ ```
12
+ gem 'runeterra_cards', '~> 0.3.0'
13
+ ```
14
+
15
+ Or, if you're building a Gem, your `.gemspec`:
16
+
17
+ ```
18
+ spec.add_dependency 'runeterra_cards', '~> 0.3.0'
19
+ ```
20
+
21
+ ## Updates & Versioning
22
+
23
+ This library will conform to [semantic versioning](https://semver.org/) once it hits 1.0. In the meantime, you can rely on the minor version (Y in x.Y.z) being bumped for backwards-incompatible changes.
24
+
25
+ All changes are documented in the {file:doc/CHANGELOG.md}.
26
+
27
+ ## Main Concepts
28
+
29
+ Your typical main entry points to this library will be {RuneterraCards::CardSet} for manipulating deck codes and/or {RuneterraCards::Metadata} for handling Data Dragon card data.
30
+
31
+ ## Examples
32
+
33
+ Load a deck code:
34
+
35
+ ```
36
+ require 'runeterra_cards'
37
+
38
+ deck_code = 'CEBAOAQGC4OSKJZJF44ACAQFBIBAIAQGAEPCYNIBAICQOAYCAECSOMADAIDAKGRWAEBAKAY'
39
+ deck = RuneterraCards::CardSet.from_deck_code(deck_code)
40
+
41
+ deck.count_for_card_code('02BW053') #=> 2
42
+
43
+ deck.cards.each do |card, count|
44
+ puts "#{card} x#{count}"
45
+ end
46
+ ```
47
+
48
+ Load metadata from Legends of Runeterra Data Dragon:
49
+
50
+ ```
51
+ require 'runeterra_cards'
52
+
53
+ metadata = RuneterraCards::Metadata.new
54
+
55
+ metadata.add_set_file 'set1-en_us.json'
56
+ metadata.add_set_file 'set2-en_us.json'
57
+
58
+ card = metadata.lookup_card '02BW053'
59
+ card.name #=> "Nautilus"
60
+ ```
61
+
62
+ ## Development & Contributing
63
+
64
+ See the [Github project](https://github.com/zofrex/runeterra_cards) for more details.
@@ -7,8 +7,15 @@ require 'runeterra_cards/card_and_count'
7
7
  require 'runeterra_cards/card_metadata'
8
8
  require 'runeterra_cards/metadata'
9
9
  require 'runeterra_cards/card_set'
10
+ require 'runeterra_cards/cost'
10
11
 
12
+ # The top-level module for +runeterra_cards+.
13
+ #
14
+ # Some of the most useful classes are {CardSet} and {Metadata}.
15
+ #
16
+ # You might also want to check out the {file:doc/README.md} and the {file:doc/CHANGELOG.md}.
11
17
  module RuneterraCards
12
18
  # The version of deck encoding supported
13
19
  SUPPORTED_VERSION = 2
20
+ public_constant :SUPPORTED_VERSION
14
21
  end
@@ -23,17 +23,19 @@ module RuneterraCards
23
23
  @code = code
24
24
  else
25
25
  padded_set = format('%<i>02d', i: set)
26
- faction = FACTION_IDENTIFIERS_FROM_INT.fetch(faction_number)
26
+ faction = FACTION_IDENTIFIERS_FROM_INT.fetch(faction_number) { |key| raise UnrecognizedFactionError, key }
27
27
  padded_card_number = format('%<i>03d', i: card_number)
28
28
  @code = "#{padded_set}#{faction}#{padded_card_number}"
29
29
  end
30
30
  @count = count
31
31
  end
32
32
 
33
+ #:nodoc:
33
34
  def eql?(other)
34
35
  code.eql?(other.code) && count.equal?(other.count)
35
36
  end
36
37
 
38
+ #:nodoc:
37
39
  def hash
38
40
  [code, count].hash
39
41
  end
@@ -51,8 +51,7 @@ module RuneterraCards
51
51
  @rarity = RARITIES[rarity_ref]
52
52
  return unless rarity.nil?
53
53
 
54
- raise MetadataLoadError.new(name, "Invalid value for rarityRef, got: #{rarity_ref}, "\
55
- "expected one of: #{RARITIES.keys.join ', '}")
54
+ raise MetadataLoadError.invalid_rarity(name, rarity_ref, RARITIES.keys)
56
55
  end
57
56
 
58
57
  # Whether or not the card is collectible.
@@ -7,8 +7,10 @@ module RuneterraCards
7
7
  #
8
8
  # @todo The API to this class is very unstable and will change a lot in a coming release.
9
9
  class CardSet
10
+ # @return [Hash<String,Fixnum>]
10
11
  attr_reader :cards
11
12
 
13
+ # @param [Hash<String,Fixnum>] cards A Hash of card codes mapping to card counts
12
14
  def initialize(cards)
13
15
  @cards = cards
14
16
  end
@@ -18,30 +20,40 @@ module RuneterraCards
18
20
  new(Hash[set.map { |cac| [cac.code, cac.count] }])
19
21
  end
20
22
 
23
+ # Subtract another {CardSet CardSet} from this one. Items with count 0 are not represented in the returned
24
+ # {CardSet CardSet}, they are removed altogether.
25
+ # @param [CardSet] other An object that responds to {#count_for_card_code}
26
+ # @return [CardSet]
21
27
  def -(other)
22
- remaining_cards = cards.each_with_object({}) do |(code, count), result|
23
- new_count = count - other.count_for_card_code(code)
24
- result[code] = new_count unless new_count.equal?(0)
25
- end
28
+ remaining_cards =
29
+ cards.each_with_object({}) do |(code, count), result|
30
+ new_count = count - other.count_for_card_code(code)
31
+ result[code] = new_count unless new_count.equal?(0)
32
+ end
26
33
 
27
34
  CardSet.new(remaining_cards)
28
35
  end
29
36
 
30
- # @return Enumerator<CardAndCount>
37
+ # @return [Enumerator<CardAndCount>]
31
38
  # @deprecated
32
39
  def as_card_and_counts
33
40
  cards.map { |code, count| CardAndCount.new(code: code, count: count) }
34
41
  end
35
42
 
43
+ # Returns how many of the given card are in this CardSet.
44
+ # @param [String] code Card code, e.g. "01DE031"
45
+ # @return [Fixnum] How many of the card are in this CardSet, or 0 if it isn't present.
36
46
  def count_for_card_code(code)
37
47
  cards[code] || 0
38
48
  end
39
49
 
50
+ # Parse a Deck Code.
40
51
  # @param deck_code [String]
41
52
  # @raise [Base32Error] if the deck code cannot be Base32 decoded.
42
53
  # @raise [UnrecognizedVersionError] if the deck code's version is not supported by this library
43
54
  # (see {SUPPORTED_VERSION}).
44
55
  # @raise [EmptyInputError] if the deck code is an empty string.
56
+ # @return [CardSet]
45
57
  def self.from_deck_code(deck_code)
46
58
  binary_data = decode_base32(deck_code)
47
59
  format, version = decode_format_and_version(binary_data[0])
@@ -80,6 +92,8 @@ module RuneterraCards
80
92
 
81
93
  private_class_method :decode_format_and_version
82
94
 
95
+ # @param [Array<Fixnum>] array
96
+ # @return [Array<CardAndCount>]
83
97
  def self.assemble_card_list(array)
84
98
  3.downto(1).flat_map do |number_of_copies|
85
99
  set_faction_combination_count = array.shift
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuneterraCards
4
+ # Represents the cost of a {CardSet}, as wildcards or shards.
5
+ # To get the cost of a {CardSet} you need to call {Metadata#cost_of}, as rarity (and therefore cost) is a property
6
+ # of metadata.
7
+ #
8
+ # A {Cost} object tells you how many wildcards would be needed to craft a {CardSet}, or alternatively how many
9
+ # shards would be needed. You can figure out the cost of a mixture of wildcards and shards by creating a new {Cost}
10
+ # object representing the wildcards to be spent, and subtracting that from the original {Cost} object.
11
+ #
12
+ # @example Getting the shard cost for a {CardSet}
13
+ # cost = metadata.cost_of(card_set)
14
+ # cost.shards #=> 3000
15
+ #
16
+ # @example Getting wildcard costs for a {CardSet}
17
+ # cost = metadata.cost_of(card_set)
18
+ # cost.common #=> 3
19
+ # cost.rare #=> 1
20
+ # # etc
21
+ #
22
+ # @example Getting remaining cost after spending some wildcards
23
+ # cost = metadata.cost_of(card_set)
24
+ # cost.dust #=> 11500
25
+ #
26
+ # wildcards_in_hand = Cost.new(10, 5, 3, 1)
27
+ # remaining_cost = cost - wildcards_in_hand
28
+ # remaining_cost.dust #=> 5100
29
+ class Cost
30
+ # The number of Common wildcards needed
31
+ # @return [Fixnum] count
32
+ attr_reader :common
33
+
34
+ # The number of Rare wildcards needed
35
+ # @return [Fixnum] count
36
+ attr_reader :rare
37
+
38
+ # The number of Epic wildcards needed
39
+ # @return [Fixnum] count
40
+ attr_reader :epic
41
+
42
+ # The number of Champion wildcards needed
43
+ # @return [Fixnum] count
44
+ attr_reader :champion
45
+
46
+ # @param [Fixnum] common
47
+ # @param [Fixnum] rare
48
+ # @param [Fixnum] epic
49
+ # @param [Fixnum] champion
50
+ def initialize(common, rare, epic, champion)
51
+ @common, @rare, @epic, @champion = common, rare, epic, champion
52
+ end
53
+
54
+ # The number of shards needed. I.e. the equivalent amount of shards for all these wildcards.
55
+ # @return [Fixnum] shards
56
+ def shards
57
+ common * 100 +
58
+ rare * 300 +
59
+ epic * 1200 +
60
+ champion * 3000
61
+ end
62
+
63
+ # Whether this Cost is equal to another. Equality means exactly the same number of each wildcard, not just the
64
+ # same shard count.
65
+ # @param [Cost] other an object that response to {#common}, {#rare}, {#epic}, and {#champion}.
66
+ # @return [Boolean] equal?
67
+ def ==(other)
68
+ common.equal?(other.common) &&
69
+ rare.equal?(other.rare) &&
70
+ epic.equal?(other.epic) &&
71
+ champion.equal?(other.champion)
72
+ end
73
+
74
+ # Subtracts another Cost from this one. Subtraction is performed by subtracting each wildcard type individually,
75
+ # not by operating on the shard count. The minimum value any wildcard will have is zero, so +5 - 7 = 0+ for
76
+ # example.
77
+ # @note This will not return negative values.
78
+ # @param [Cost] other an object that response to {#common}, {#rare}, {#epic}, and {#champion}.
79
+ # @return [Cost] The remaining cost, with a floor of 0.
80
+ # @example
81
+ # minuend = Cost.new(9, 8, 5, 2)
82
+ # subtrahend = Cost.new(7, 8, 2, 3)
83
+ # result = minuend - subtrahend
84
+ # result #=> Cost.new(2, 0, 3, 0)
85
+ def -(other)
86
+ Cost.new(
87
+ [common - other.common, 0].max,
88
+ [rare - other.rare, 0].max,
89
+ [epic - other.epic, 0].max,
90
+ [champion - other.champion, 0].max
91
+ )
92
+ end
93
+ end
94
+ end
@@ -8,6 +8,7 @@ module RuneterraCards
8
8
  # This exception is raised if the deck code cannot be Base32-decoded. This probably means it isn't a deck code, or
9
9
  # got malformed somehow.
10
10
  class Base32Error < DeckCodeParseError
11
+ # Returns a new instance of Base32Error with a helpful error message preloaded.
11
12
  def initialize
12
13
  super('Encountered an error while Base32 decoding deck code.' \
13
14
  ' Probably an invalid deck code, or possibly a bug in the Base32 handling.')
@@ -16,6 +17,7 @@ module RuneterraCards
16
17
 
17
18
  # This exception is raised if the deck code is an empty string.
18
19
  class EmptyInputError < DeckCodeParseError
20
+ # Returns a new instance of EmptyInputError with a helpful error message preloaded.
19
21
  def initialize
20
22
  super('The input was an empty string')
21
23
  end
@@ -29,9 +31,34 @@ module RuneterraCards
29
31
  # issue relating to this. If none exists, then file one!
30
32
  # @see SUPPORTED_VERSION
31
33
  class UnrecognizedVersionError < DeckCodeParseError
34
+ # @return [Fixnum] the version number encountered in the deck code
35
+ attr_accessor :version
36
+
37
+ # @param [Fixnum] expected The version number we were expecting to see in the deck code.
38
+ # @param [Fixnum] got The version number we actually got.
32
39
  def initialize(expected, got)
33
40
  super("Unrecognized deck code version number: #{got}, was expecting: #{expected}. \
34
41
  Possibly an invalid deck code, possibly you need to update the deck code library version.")
42
+ @version = got
43
+ end
44
+ end
45
+
46
+ # This exception is raised if the deck code contains an unexpected faction number. (see the table at
47
+ # {https://github.com/RiotGames/LoRDeckCodes} for what 'faction number' means.) This most likely means that
48
+ # Legends of Runeterra has a new faction and you need to update to a newer version of this library to handle it.
49
+ #
50
+ # Check that the {#faction_number} causing issues is listed in {https://github.com/RiotGames/LoRDeckCodes
51
+ # the table on Github}. If it isn't then something else has gone wrong. If it is, and updating this library doesn't
52
+ # fix the issue, then the library needs updating - {https://github.com/zofrex/runeterra_cards/issues file an issue}.
53
+ class UnrecognizedFactionError < DeckCodeParseError
54
+ # @return [Fixnum] the faction number that was unrecognized
55
+ attr_reader :faction_number
56
+
57
+ # @param [Fixnum] faction_number The faction number we encountered and did not recognise.
58
+ def initialize(faction_number)
59
+ super("Unrecognized faction number '#{faction_number}'."\
60
+ ' Possibly you need to update this library to a newer version')
61
+ @faction_number = faction_number
35
62
  end
36
63
  end
37
64
 
@@ -39,7 +66,7 @@ Possibly an invalid deck code, possibly you need to update the deck code library
39
66
  # The message will tell you what data was not right, and the {#card} attribute will tell you which card had issues,
40
67
  # if possible.
41
68
  #
42
- # @see CardMetadata#initialize
69
+ # @see CardMetadata#initialize CardMetadata#initialize for details on when this error is raised.
43
70
  class MetadataLoadError < StandardError
44
71
  # Return the name or card code of the card that was missing an expected attribute.
45
72
  # @return [String] name if the name was present
@@ -47,6 +74,8 @@ Possibly an invalid deck code, possibly you need to update the deck code library
47
74
  # @return [nil] if neither name nor card code were present
48
75
  attr_reader :card
49
76
 
77
+ # @param [String] card The card's name or cardCode.
78
+ # @param [String] problem Details on the problem encountered loading the card.
50
79
  def initialize(card, problem)
51
80
  if card.nil?
52
81
  super("Error loading data for unknown card (no code or name): #{problem}")
@@ -55,5 +84,15 @@ Possibly an invalid deck code, possibly you need to update the deck code library
55
84
  end
56
85
  @card = card
57
86
  end
87
+
88
+ # Create a {MetadataLoadError MetadataLoadError} with a helpful message regarding an invalid value for rarityRef.
89
+ # @param [String] card The card name that had an invalid rarityRef value.
90
+ #
91
+ # @param [String] given The value that rarityRef had.
92
+ # @param [Enumerable<String>] expected A list of values that would have been valid.
93
+ # @return [MetadataLoadError]
94
+ def self.invalid_rarity(card, given, expected)
95
+ new(card, "Invalid value for rarityRef, got: #{given}, expected one of: #{expected.join ', '}")
96
+ end
58
97
  end
59
98
  end
@@ -1,11 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RuneterraCards
4
- # An array of the two-letter Faction identifiers, indexed by their integer identifiers
4
+ # An map from integer faction identifiers to their two-letter identifiers
5
5
  # @example
6
6
  # FACTION_IDENTIFIERS_FROM_INT[2] #=> "IO"
7
- # @return [Array<String>]
8
- FACTION_IDENTIFIERS_FROM_INT = %w[DE FR IO NX PZ SI BW].freeze
7
+ # @return [Hash<Fixnum,String>]
8
+ FACTION_IDENTIFIERS_FROM_INT = {
9
+ 0 => 'DE',
10
+ 1 => 'FR',
11
+ 2 => 'IO',
12
+ 3 => 'NX',
13
+ 4 => 'PZ',
14
+ 5 => 'SI',
15
+ 6 => 'BW',
16
+ 9 => 'MT',
17
+ }.freeze
18
+ public_constant :FACTION_IDENTIFIERS_FROM_INT
9
19
 
10
20
  # A map from two-letter Faction identifiers to their integer identifiers
11
21
  # @example
@@ -19,5 +29,7 @@ module RuneterraCards
19
29
  'PZ' => 4,
20
30
  'SI' => 5,
21
31
  'BW' => 6,
32
+ 'MT' => 9,
22
33
  }.freeze
34
+ public_constant :FACTION_INTS_FROM_IDENTIFIER
23
35
  end
@@ -20,6 +20,7 @@ module RuneterraCards
20
20
  # @note This class cannot yet handle metadata for multiple locales at the same time. You will need multiple instances
21
21
  # of this class, one for each locale, if you wish to handle multiple locales at this time.
22
22
  class Metadata
23
+ # Create a new, empty, metadata repository.
23
24
  def initialize
24
25
  @cards = {}
25
26
  end
@@ -57,5 +58,15 @@ module RuneterraCards
57
58
  def full_set
58
59
  CardSet.new(all_collectible.keys.each_with_object({}) { |code, result| result[code] = 3 })
59
60
  end
61
+
62
+ # @param [CardSet] card_set
63
+ # @return [Cost] the cost of crafting all the cards in the supplied CardSet
64
+ def cost_of(card_set)
65
+ rarity_and_count = card_set.cards.map { |card, count| [lookup_card(card).rarity, count] }
66
+ total = { common: 0, rare: 0, epic: 0, champion: 0 }
67
+ rarity_and_count.each { |(rarity, count)| total[rarity] += count }
68
+
69
+ Cost.new(total.fetch(:common), total.fetch(:rare), total.fetch(:epic), total.fetch(:champion))
70
+ end
60
71
  end
61
72
  end
@@ -2,5 +2,6 @@
2
2
 
3
3
  module RuneterraCards
4
4
  # The version of this library
5
- VERSION = '0.1.0'
5
+ VERSION = '0.3.0'
6
+ public_constant :VERSION
6
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runeterra_cards
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
- - zofrex
7
+ - James "zofrex" Sanderson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-28 00:00:00.000000000 Z
11
+ date: 2020-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base32
@@ -178,18 +178,22 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: 0.9.25
181
- description: Legends of Runeterra deck encoder/decoder and general purpose card info
181
+ description: Legends of Runeterra deck code decoder & Data Dragon card data loader.
182
182
  email:
183
183
  - zofrex@gmail.com
184
184
  executables: []
185
185
  extensions: []
186
186
  extra_rdoc_files: []
187
187
  files:
188
+ - ".yardopts"
188
189
  - LICENSE.txt
190
+ - doc/CHANGELOG.md
191
+ - doc/README.md
189
192
  - lib/runeterra_cards.rb
190
193
  - lib/runeterra_cards/card_and_count.rb
191
194
  - lib/runeterra_cards/card_metadata.rb
192
195
  - lib/runeterra_cards/card_set.rb
196
+ - lib/runeterra_cards/cost.rb
193
197
  - lib/runeterra_cards/errors.rb
194
198
  - lib/runeterra_cards/factions.rb
195
199
  - lib/runeterra_cards/metadata.rb
@@ -197,7 +201,10 @@ files:
197
201
  homepage:
198
202
  licenses:
199
203
  - MIT
200
- metadata: {}
204
+ metadata:
205
+ bug_tracker_uri: https://github.com/zofrex/runeterra_cards/issues
206
+ changelog_uri: https://www.rubydoc.info/gems/runeterra_cards/doc/CHANGELOG.md
207
+ source_code_uri: https://github.com/zofrex/runeterra_cards
201
208
  post_install_message:
202
209
  rdoc_options: []
203
210
  require_paths:
@@ -216,5 +223,5 @@ requirements: []
216
223
  rubygems_version: 3.1.4
217
224
  signing_key:
218
225
  specification_version: 4
219
- summary: Legends of Runeterra deck encoder/decoder and general purpose card info
226
+ summary: Legends of Runeterra deck code decoder & Data Dragon card data loader.
220
227
  test_files: []