runeterra_cards 0.1.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 +7 -0
- data/LICENSE.txt +21 -0
- data/lib/runeterra_cards.rb +14 -0
- data/lib/runeterra_cards/card_and_count.rb +41 -0
- data/lib/runeterra_cards/card_metadata.rb +63 -0
- data/lib/runeterra_cards/card_set.rb +98 -0
- data/lib/runeterra_cards/errors.rb +59 -0
- data/lib/runeterra_cards/factions.rb +23 -0
- data/lib/runeterra_cards/metadata.rb +61 -0
- data/lib/runeterra_cards/version.rb +6 -0
- metadata +220 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 275e8ca4e8362b65da7022dc3042e9fbe3b0970f52443e652476757be52125f1
|
4
|
+
data.tar.gz: ab803e005acf47f9499aad38aaad76d0e1c59c275dc4457bc8735208f08baace
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f406aad97cd4b6b57b356f08ff665661d3edecd608467b0a04b2c76d434927bc406cd01fec7f02aa171701f0a0f89fd2e322de7cbc871d18cb58993c9ae4d9e3
|
7
|
+
data.tar.gz: 96023313de8c2868fbf551185224a9441a13e30ddb297f9766b69b07481f4d21c1a56b78052ec09ba3a5aa22878c39f1c94ef196a235838b5cc447bb08255d96
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2020 James 'zofrex' Sanderson
|
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.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'runeterra_cards/version'
|
4
|
+
require 'runeterra_cards/errors'
|
5
|
+
require 'runeterra_cards/factions'
|
6
|
+
require 'runeterra_cards/card_and_count'
|
7
|
+
require 'runeterra_cards/card_metadata'
|
8
|
+
require 'runeterra_cards/metadata'
|
9
|
+
require 'runeterra_cards/card_set'
|
10
|
+
|
11
|
+
module RuneterraCards
|
12
|
+
# The version of deck encoding supported
|
13
|
+
SUPPORTED_VERSION = 2
|
14
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuneterraCards
|
4
|
+
# Represents a card and how many of that card are in a collection.
|
5
|
+
# @deprecated
|
6
|
+
class CardAndCount
|
7
|
+
# The card code, for example "01DE123"
|
8
|
+
# @return [String]
|
9
|
+
attr_reader :code
|
10
|
+
|
11
|
+
# How many of this card are in a collection (between 1-3).
|
12
|
+
# @return [Fixnum]
|
13
|
+
attr_reader :count
|
14
|
+
|
15
|
+
# @param set [Fixnum]
|
16
|
+
# @param faction_number [Fixnum]
|
17
|
+
# @param card_number [Fixnum]
|
18
|
+
# @param count [Fixnum]
|
19
|
+
def initialize(code: nil, count:, set: nil, faction_number: nil, card_number: nil)
|
20
|
+
if code
|
21
|
+
raise if set || faction_number || card_number
|
22
|
+
|
23
|
+
@code = code
|
24
|
+
else
|
25
|
+
padded_set = format('%<i>02d', i: set)
|
26
|
+
faction = FACTION_IDENTIFIERS_FROM_INT.fetch(faction_number)
|
27
|
+
padded_card_number = format('%<i>03d', i: card_number)
|
28
|
+
@code = "#{padded_set}#{faction}#{padded_card_number}"
|
29
|
+
end
|
30
|
+
@count = count
|
31
|
+
end
|
32
|
+
|
33
|
+
def eql?(other)
|
34
|
+
code.eql?(other.code) && count.equal?(other.count)
|
35
|
+
end
|
36
|
+
|
37
|
+
def hash
|
38
|
+
[code, count].hash
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuneterraCards
|
4
|
+
# Represents metadata for a single card. Metadata is all meaning the game imbues upon a card code, including things
|
5
|
+
# like cost, health, etc and also localised information such as name and description.
|
6
|
+
#
|
7
|
+
# Currently this class only represents a thin sliver of metadata as required by its downstream consumers.
|
8
|
+
#
|
9
|
+
# @see CardAndCount
|
10
|
+
class CardMetadata
|
11
|
+
RARITIES = {
|
12
|
+
'None' => :none,
|
13
|
+
'Common' => :common,
|
14
|
+
'Rare' => :rare,
|
15
|
+
'Epic' => :epic,
|
16
|
+
'Champion' => :champion,
|
17
|
+
}.freeze
|
18
|
+
private_constant :RARITIES
|
19
|
+
|
20
|
+
# Returns the name attribute. The name is the localised name that the card would have in game.
|
21
|
+
# For example: "House Spider".
|
22
|
+
# @return [String]
|
23
|
+
attr_reader :name
|
24
|
+
|
25
|
+
# Returns the card_code attribute. For example: "01NX055".
|
26
|
+
# @return [String]
|
27
|
+
attr_reader :card_code
|
28
|
+
|
29
|
+
# Returns the card's rarity as a symbol. Can be one of: +:none+, +:common+, +:rare+, +:epic+, or +:champion+
|
30
|
+
# @return [Symbol]
|
31
|
+
attr_reader :rarity
|
32
|
+
|
33
|
+
# Creates a single {CardMetadata} Object from the supplied Hash of data.
|
34
|
+
# This is intended for use with the data files from Legends of Runeterra Data Dragon, and it expects a Hash
|
35
|
+
# representing a single card from the parsed JSON data files from Data Dragon.
|
36
|
+
#
|
37
|
+
# @param hash [Hash] Card data from Legends of Runeterra Data Dragon
|
38
|
+
# @option hash [String] name
|
39
|
+
# @option hash [String] cardCode
|
40
|
+
# @option hash [Boolean] collectible
|
41
|
+
#
|
42
|
+
# @raise [MissingCardDataError] if any of the expected hash parameters are missing, or if +rarityRef+ contains an
|
43
|
+
# unexpected value.
|
44
|
+
def initialize(hash)
|
45
|
+
begin
|
46
|
+
@name, @card_code, @collectible, rarity_ref = hash.fetch_values('name', 'cardCode', 'collectible', 'rarityRef')
|
47
|
+
rescue KeyError => e
|
48
|
+
raise MetadataLoadError.new(hash['name'] || hash['cardCode'], "Missing expected key: #{e.key}")
|
49
|
+
end
|
50
|
+
|
51
|
+
@rarity = RARITIES[rarity_ref]
|
52
|
+
return unless rarity.nil?
|
53
|
+
|
54
|
+
raise MetadataLoadError.new(name, "Invalid value for rarityRef, got: #{rarity_ref}, "\
|
55
|
+
"expected one of: #{RARITIES.keys.join ', '}")
|
56
|
+
end
|
57
|
+
|
58
|
+
# Whether or not the card is collectible.
|
59
|
+
def collectible?
|
60
|
+
@collectible
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'base32'
|
4
|
+
|
5
|
+
module RuneterraCards
|
6
|
+
# Represents a collection of cards.
|
7
|
+
#
|
8
|
+
# @todo The API to this class is very unstable and will change a lot in a coming release.
|
9
|
+
class CardSet
|
10
|
+
attr_reader :cards
|
11
|
+
|
12
|
+
def initialize(cards)
|
13
|
+
@cards = cards
|
14
|
+
end
|
15
|
+
|
16
|
+
# @deprecated
|
17
|
+
def self.from_card_and_counts(set)
|
18
|
+
new(Hash[set.map { |cac| [cac.code, cac.count] }])
|
19
|
+
end
|
20
|
+
|
21
|
+
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
|
26
|
+
|
27
|
+
CardSet.new(remaining_cards)
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return Enumerator<CardAndCount>
|
31
|
+
# @deprecated
|
32
|
+
def as_card_and_counts
|
33
|
+
cards.map { |code, count| CardAndCount.new(code: code, count: count) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def count_for_card_code(code)
|
37
|
+
cards[code] || 0
|
38
|
+
end
|
39
|
+
|
40
|
+
# @param deck_code [String]
|
41
|
+
# @raise [Base32Error] if the deck code cannot be Base32 decoded.
|
42
|
+
# @raise [UnrecognizedVersionError] if the deck code's version is not supported by this library
|
43
|
+
# (see {SUPPORTED_VERSION}).
|
44
|
+
# @raise [EmptyInputError] if the deck code is an empty string.
|
45
|
+
def self.from_deck_code(deck_code)
|
46
|
+
binary_data = decode_base32(deck_code)
|
47
|
+
format, version = decode_format_and_version(binary_data[0])
|
48
|
+
|
49
|
+
raise UnrecognizedVersionError.new(SUPPORTED_VERSION, version) unless version <= SUPPORTED_VERSION
|
50
|
+
|
51
|
+
raise unless format.equal? 1
|
52
|
+
|
53
|
+
int_array = binary_data[1..].unpack('w*')
|
54
|
+
cards = assemble_card_list(int_array)
|
55
|
+
from_card_and_counts(cards)
|
56
|
+
end
|
57
|
+
|
58
|
+
# @param string [String] base32-encoded string
|
59
|
+
# @return [String] binary data
|
60
|
+
def self.decode_base32(string)
|
61
|
+
raise EmptyInputError if string.empty?
|
62
|
+
|
63
|
+
begin
|
64
|
+
Base32.decode(string)
|
65
|
+
rescue StandardError
|
66
|
+
raise Base32Error
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private_class_method :decode_base32
|
71
|
+
|
72
|
+
# @param byte [String] a single byte
|
73
|
+
# @return [FixNum] format and version, in that order
|
74
|
+
def self.decode_format_and_version(byte)
|
75
|
+
format_and_version = byte.unpack1('C')
|
76
|
+
format = format_and_version >> 4
|
77
|
+
version = format_and_version & 0xF
|
78
|
+
[format, version]
|
79
|
+
end
|
80
|
+
|
81
|
+
private_class_method :decode_format_and_version
|
82
|
+
|
83
|
+
def self.assemble_card_list(array)
|
84
|
+
3.downto(1).flat_map do |number_of_copies|
|
85
|
+
set_faction_combination_count = array.shift
|
86
|
+
set_faction_combination_count.times.flat_map do
|
87
|
+
number_of_cards, set, faction = array.shift(3)
|
88
|
+
|
89
|
+
array.shift(number_of_cards).map do |card_number|
|
90
|
+
CardAndCount.new(set: set, faction_number: faction, card_number: card_number, count: number_of_copies)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private_class_method :assemble_card_list
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuneterraCards
|
4
|
+
# The base exception for errors that occur when decoding a deck code
|
5
|
+
class DeckCodeParseError < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
# This exception is raised if the deck code cannot be Base32-decoded. This probably means it isn't a deck code, or
|
9
|
+
# got malformed somehow.
|
10
|
+
class Base32Error < DeckCodeParseError
|
11
|
+
def initialize
|
12
|
+
super('Encountered an error while Base32 decoding deck code.' \
|
13
|
+
' Probably an invalid deck code, or possibly a bug in the Base32 handling.')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# This exception is raised if the deck code is an empty string.
|
18
|
+
class EmptyInputError < DeckCodeParseError
|
19
|
+
def initialize
|
20
|
+
super('The input was an empty string')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# This exception is raised if the deck code version number in the deck code is not one we can handle. This could mean
|
25
|
+
# this isn't a deck code (especially if the version number is very different to the one expected), or it could mean
|
26
|
+
# Riot has updated the deck code version and you need to update this library.
|
27
|
+
#
|
28
|
+
# If updating this library fails to resolve the issue, and you are sure this is a deck code, check GitHub for an
|
29
|
+
# issue relating to this. If none exists, then file one!
|
30
|
+
# @see SUPPORTED_VERSION
|
31
|
+
class UnrecognizedVersionError < DeckCodeParseError
|
32
|
+
def initialize(expected, got)
|
33
|
+
super("Unrecognized deck code version number: #{got}, was expecting: #{expected}. \
|
34
|
+
Possibly an invalid deck code, possibly you need to update the deck code library version.")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# This exception is raised if you try to parse data from Runeterra Data Dragon that is not in the expected form.
|
39
|
+
# The message will tell you what data was not right, and the {#card} attribute will tell you which card had issues,
|
40
|
+
# if possible.
|
41
|
+
#
|
42
|
+
# @see CardMetadata#initialize
|
43
|
+
class MetadataLoadError < StandardError
|
44
|
+
# Return the name or card code of the card that was missing an expected attribute.
|
45
|
+
# @return [String] name if the name was present
|
46
|
+
# @return [String] card code if the name was not present
|
47
|
+
# @return [nil] if neither name nor card code were present
|
48
|
+
attr_reader :card
|
49
|
+
|
50
|
+
def initialize(card, problem)
|
51
|
+
if card.nil?
|
52
|
+
super("Error loading data for unknown card (no code or name): #{problem}")
|
53
|
+
else
|
54
|
+
super("Error loading data for card #{card}: #{problem}")
|
55
|
+
end
|
56
|
+
@card = card
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuneterraCards
|
4
|
+
# An array of the two-letter Faction identifiers, indexed by their integer identifiers
|
5
|
+
# @example
|
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
|
9
|
+
|
10
|
+
# A map from two-letter Faction identifiers to their integer identifiers
|
11
|
+
# @example
|
12
|
+
# FACTION_INTS_FROM_IDENTIFIER["IO"] #=> 2
|
13
|
+
# @return [Hash<String,Fixnum>]
|
14
|
+
FACTION_INTS_FROM_IDENTIFIER = {
|
15
|
+
'DE' => 0,
|
16
|
+
'FR' => 1,
|
17
|
+
'IO' => 2,
|
18
|
+
'NX' => 3,
|
19
|
+
'PZ' => 4,
|
20
|
+
'SI' => 5,
|
21
|
+
'BW' => 6,
|
22
|
+
}.freeze
|
23
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module RuneterraCards
|
6
|
+
# Loads, stores, and retrieves data for cards from Legends of Runeterra Data Dragon set files.
|
7
|
+
# N.B. this does not ship with any metadata of its own, you must provide set files yourself and load them before
|
8
|
+
# this class will do anything.
|
9
|
+
#
|
10
|
+
# @example Load data and retrieve data for a card
|
11
|
+
# m = RuneterraCards::Metadata.new
|
12
|
+
# m.add_set_file('./set1-en_us.json')
|
13
|
+
# m.lookup_card('01DE031') #=> CardMetadata
|
14
|
+
#
|
15
|
+
# @example Load data from multiple sets
|
16
|
+
# m = RuneterraCards::Metadata.new
|
17
|
+
# m.add_set_file('./set1-en_us.json')
|
18
|
+
# m.add_set_file('./set2-en_us.json')
|
19
|
+
#
|
20
|
+
# @note This class cannot yet handle metadata for multiple locales at the same time. You will need multiple instances
|
21
|
+
# of this class, one for each locale, if you wish to handle multiple locales at this time.
|
22
|
+
class Metadata
|
23
|
+
def initialize
|
24
|
+
@cards = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
# Load card data from a Legends of Runeterra Data Dragon set file, e.g. "set1-en_us.json"
|
28
|
+
# @param file_path [String] The path to the metadata file to read
|
29
|
+
# @todo document and test exceptions that can be thrown here
|
30
|
+
def add_set_file(file_path)
|
31
|
+
file = File.read(file_path)
|
32
|
+
data = JSON.parse(file)
|
33
|
+
data.each do |card_data|
|
34
|
+
card = CardMetadata.new(card_data)
|
35
|
+
@cards[card.card_code] = card
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Fetch card metadata for a card via its card code
|
40
|
+
# @param card_code [String] card code, e.g. 01DE031
|
41
|
+
# @return [CardMetadata]
|
42
|
+
# @todo document errors if card_code doesn't exist
|
43
|
+
def lookup_card(card_code)
|
44
|
+
@cards.fetch(card_code)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns all cards in the metadata set that are collectible
|
48
|
+
# @return [Hash<String,CardMetadata>]
|
49
|
+
# @see CardMetadata#collectible?
|
50
|
+
def all_collectible
|
51
|
+
@cards.select { |_, card| card.collectible? }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Returns a [CardSet] that represents a complete card collection.
|
55
|
+
# That is: 3x of every card that is collectible.
|
56
|
+
# @return [CardSet]
|
57
|
+
def full_set
|
58
|
+
CardSet.new(all_collectible.keys.each_with_object({}) { |code, result| result[code] = 3 })
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,220 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: runeterra_cards
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- zofrex
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-08-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: base32
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.3.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.3.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: deep-cover
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.7'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.7'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.14'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.14'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest-reporters
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.4.2
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.4.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: mutant-minitest
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
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: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 13.0.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 13.0.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.89.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.89.1
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-minitest
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.10.1
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.10.1
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: rubocop-packaging
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 0.3.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 0.3.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop-performance
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '1.7'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1.7'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: yard
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: 0.9.25
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: 0.9.25
|
181
|
+
description: Legends of Runeterra deck encoder/decoder and general purpose card info
|
182
|
+
email:
|
183
|
+
- zofrex@gmail.com
|
184
|
+
executables: []
|
185
|
+
extensions: []
|
186
|
+
extra_rdoc_files: []
|
187
|
+
files:
|
188
|
+
- LICENSE.txt
|
189
|
+
- lib/runeterra_cards.rb
|
190
|
+
- lib/runeterra_cards/card_and_count.rb
|
191
|
+
- lib/runeterra_cards/card_metadata.rb
|
192
|
+
- lib/runeterra_cards/card_set.rb
|
193
|
+
- lib/runeterra_cards/errors.rb
|
194
|
+
- lib/runeterra_cards/factions.rb
|
195
|
+
- lib/runeterra_cards/metadata.rb
|
196
|
+
- lib/runeterra_cards/version.rb
|
197
|
+
homepage:
|
198
|
+
licenses:
|
199
|
+
- MIT
|
200
|
+
metadata: {}
|
201
|
+
post_install_message:
|
202
|
+
rdoc_options: []
|
203
|
+
require_paths:
|
204
|
+
- lib
|
205
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
+
requirements:
|
207
|
+
- - ">="
|
208
|
+
- !ruby/object:Gem::Version
|
209
|
+
version: '2.6'
|
210
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
211
|
+
requirements:
|
212
|
+
- - ">="
|
213
|
+
- !ruby/object:Gem::Version
|
214
|
+
version: '0'
|
215
|
+
requirements: []
|
216
|
+
rubygems_version: 3.1.4
|
217
|
+
signing_key:
|
218
|
+
specification_version: 4
|
219
|
+
summary: Legends of Runeterra deck encoder/decoder and general purpose card info
|
220
|
+
test_files: []
|