minting 1.9.6 → 2.0.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 +4 -4
- data/README.md +244 -121
- data/Rakefile +17 -26
- data/bin/bench_check +2 -2
- data/doc/agents/api_review-2026-06-15.md +1 -1
- data/doc/agents/copilot-instructions.md +5 -5
- data/doc/agents/expired/copilot-instructions.md +2 -2
- data/doc/agents/expired/gemini_gem_evaluation.md +2 -2
- data/lib/minting/aliases.rb +22 -0
- data/lib/minting/currency/currency.rb +87 -12
- data/lib/minting/data/crypto-currencies.yaml +126 -0
- data/lib/minting/data/world-currencies.yaml +75 -23
- data/lib/minting/mint/i18n.rb +79 -29
- data/lib/minting/mint/mint.rb +1 -26
- data/lib/minting/mint/registry/crypto.rb +59 -0
- data/lib/minting/mint/registry/registration.rb +1 -2
- data/lib/minting/mint/registry/symbols.rb +37 -30
- data/lib/minting/mint/rounding.rb +10 -7
- data/lib/minting/mint.rb +1 -2
- data/lib/minting/money/allocation/allocation.rb +2 -2
- data/lib/minting/money/allocation/split.rb +1 -1
- data/lib/minting/money/arithmetics/operators.rb +10 -13
- data/lib/minting/money/clamp.rb +6 -6
- data/lib/minting/money/coercion.rb +1 -1
- data/lib/minting/money/comparable.rb +3 -3
- data/lib/minting/money/constructors.rb +3 -42
- data/lib/minting/money/conversion.rb +23 -18
- data/lib/minting/money/format/format.rb +100 -0
- data/lib/minting/money/format/formatter.rb +102 -0
- data/lib/minting/money/format/to_s.rb +34 -99
- data/lib/minting/money/format/validator.rb +34 -0
- data/lib/minting/money/money.rb +25 -13
- data/lib/minting/money/parse.rb +127 -0
- data/lib/minting/money/rounding.rb +27 -0
- data/lib/minting/version.rb +1 -1
- data/lib/minting.rb +17 -8
- metadata +9 -28
- data/doc/Mint/Currency.html +0 -1943
- data/doc/Mint/CurrencyRegistry.html +0 -511
- data/doc/Mint/Money.html +0 -4607
- data/doc/Mint/RangeStepPatch.html +0 -277
- data/doc/Mint/Registry.html +0 -863
- data/doc/Mint/Rounding.html +0 -506
- data/doc/Mint/UnknownCurrency.html +0 -136
- data/doc/Mint.html +0 -1004
- data/doc/Minting.html +0 -142
- data/doc/_index.html +0 -180
- data/doc/class_list.html +0 -54
- data/doc/css/common.css +0 -1
- data/doc/css/full_list.css +0 -206
- data/doc/css/style.css +0 -1089
- data/doc/file.README.html +0 -277
- data/doc/file_list.html +0 -59
- data/doc/frames.html +0 -22
- data/doc/index.html +0 -277
- data/doc/js/app.js +0 -801
- data/doc/js/full_list.js +0 -334
- data/doc/js/jquery.js +0 -4
- data/doc/method_list.html +0 -686
- data/doc/top-level-namespace.html +0 -151
- data/lib/minting/mint/aliases.rb +0 -16
- data/lib/minting/mint/parser/parser.rb +0 -97
- data/lib/minting/mint/parser/separators.rb +0 -41
- data/lib/minting/money/format/formatting.rb +0 -97
|
@@ -2,9 +2,9 @@ Repository overview
|
|
|
2
2
|
|
|
3
3
|
- Language: Ruby gem (minting)
|
|
4
4
|
- Location of main code: lib/minting and its subfolders (mint/, money/)
|
|
5
|
-
- Public API surface: Mint (factory/helpers), Mint::Money,
|
|
5
|
+
- Public API surface: Mint (factory/helpers), Mint::Money, Money::Currency
|
|
6
6
|
- Data: built-in currencies in lib/minting/data/currencies.yaml
|
|
7
|
-
- Tests: Minitest (unit) + performance benchmarks under
|
|
7
|
+
- Tests: Minitest (unit) + performance benchmarks under bench/
|
|
8
8
|
|
|
9
9
|
Build, test and lint commands
|
|
10
10
|
|
|
@@ -43,7 +43,7 @@ High-level architecture (big picture)
|
|
|
43
43
|
- Currency: lightweight value object (code, subunit, symbol, priority, minimum_amount).
|
|
44
44
|
- Money: immutable value object stored as Rational and rounded to currency.subunit. Core concerns split across lib/minting/money/* (arithmetics, formatting, conversion, coercion, allocation, parsing, comparable).
|
|
45
45
|
- Refinements: Numeric/String/Refinements in lib/minting/mint/refinements.rb expose helpers like 10.dollars, 4.to_money('USD'), and require `using Mint` in scope.
|
|
46
|
-
- Performance tests: separate bench tasks under Rake;
|
|
46
|
+
- Performance tests: separate bench tasks under Rake; bench/ holds benchmark suites.
|
|
47
47
|
|
|
48
48
|
Key conventions and repo-specific rules
|
|
49
49
|
|
|
@@ -59,7 +59,7 @@ Files and places to check first during edits
|
|
|
59
59
|
- lib/minting/money - core behavior and arithmetic
|
|
60
60
|
- lib/minting/mint - currency registry, refinements, and factory API
|
|
61
61
|
- lib/minting/data/currencies.yaml - canonical currency definitions
|
|
62
|
-
- test/ - unit tests;
|
|
62
|
+
- test/ - unit tests; bench/ - benchmark suites
|
|
63
63
|
|
|
64
64
|
Notes for Copilot sessions
|
|
65
65
|
|
|
@@ -67,4 +67,4 @@ Notes for Copilot sessions
|
|
|
67
67
|
- When changing numeric/rounding behavior, run both unit tests and relevant performance benchmarks.
|
|
68
68
|
- Respect zero-equality semantics and currency code validation when modifying equality/hash logic.
|
|
69
69
|
|
|
70
|
-
If you want, update this file with project-specific conventions to capture workflow choices (e.g., backport policy, DI patterns).
|
|
70
|
+
If you want, update this file with project-specific conventions to capture workflow choices (e.g., backport policy, DI patterns).
|
|
@@ -2,7 +2,7 @@ Repository overview
|
|
|
2
2
|
|
|
3
3
|
- Language: Ruby gem (minting)
|
|
4
4
|
- Location of main code: lib/minting and its subfolders (mint/, money/)
|
|
5
|
-
- Public API surface: Mint (factory/helpers), Mint::Money,
|
|
5
|
+
- Public API surface: Mint (factory/helpers), Mint::Money, Money::Currency
|
|
6
6
|
- Data: built-in currencies in lib/minting/data/currencies.yaml
|
|
7
7
|
- Tests: Minitest (unit) + performance benchmarks under test/performance
|
|
8
8
|
|
|
@@ -72,4 +72,4 @@ Notes for Copilot sessions
|
|
|
72
72
|
- When changing numeric/rounding behavior, run both unit tests and relevant performance benchmarks.
|
|
73
73
|
- Respect zero-equality semantics and currency code validation when modifying equality/hash logic.
|
|
74
74
|
|
|
75
|
-
If you want, update this file with project-specific conventions to capture workflow choices (e.g., backport policy, DI patterns).
|
|
75
|
+
If you want, update this file with project-specific conventions to capture workflow choices (e.g., backport policy, DI patterns).
|
|
@@ -29,7 +29,7 @@ lib/
|
|
|
29
29
|
│ ├── data/
|
|
30
30
|
│ │ └── currencies.yaml # built-in ISO 4217 database
|
|
31
31
|
│ ├── mint/
|
|
32
|
-
│ │ ├── currency.rb #
|
|
32
|
+
│ │ ├── currency.rb # Money::Currency model
|
|
33
33
|
│ │ ├── refinements.rb # Scoped Numeric/String refinements
|
|
34
34
|
│ │ └── registry.rb # Global lookup & registration
|
|
35
35
|
│ ├── money/
|
|
@@ -70,7 +70,7 @@ lib/
|
|
|
70
70
|
|
|
71
71
|
The gem exhibits top-tier Ruby development practices:
|
|
72
72
|
|
|
73
|
-
- **Immutability & Safety**: Both `
|
|
73
|
+
- **Immutability & Safety**: Both `Money::Currency` and `Mint::Money` objects are frozen upon initialization:
|
|
74
74
|
```ruby
|
|
75
75
|
def initialize(amount, currency)
|
|
76
76
|
# ...
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# @!parse
|
|
4
|
+
# # Top-level alias for {Money::Currency}, opt-in via +require 'minting/aliases'+.
|
|
5
|
+
# Currency = Money::Currency
|
|
6
|
+
|
|
7
|
+
# Top-level alias for {Money::Currency}, opt-in via +require 'minting/aliases'+.
|
|
8
|
+
#
|
|
9
|
+
# {::Currency} is **not** auto-bound by `require 'minting'` because
|
|
10
|
+
# application domain models are commonly named +Currency+ (e.g. a Rails
|
|
11
|
+
# model). Load this file explicitly to opt in.
|
|
12
|
+
#
|
|
13
|
+
# If {::Currency} is already defined, a warning is emitted and the existing
|
|
14
|
+
# constant is preserved — use {Money::Currency} explicitly in that case.
|
|
15
|
+
#
|
|
16
|
+
# @see Money::Currency
|
|
17
|
+
|
|
18
|
+
Currency = Money::Currency unless defined?(Currency)
|
|
19
|
+
|
|
20
|
+
if Currency != Money::Currency
|
|
21
|
+
warn "minting: top-level Currency was already defined (#{Currency}); skipping alias. Use Money::Currency"
|
|
22
|
+
end
|
|
@@ -15,20 +15,25 @@ module Mint
|
|
|
15
15
|
# @attr_reader name [String, nil] Currency name
|
|
16
16
|
# @attr_reader fractional_multiplier [Integer] 10^subunit, used for fractional conversions
|
|
17
17
|
# @attr_reader minimum_amount [Rational] Smallest representable amount (1/fractional_multiplier)
|
|
18
|
+
# @attr_reader disambiguate_symbol [String, nil] A longer, code-prefixed variant to distinguish
|
|
19
|
+
# currencies that share the same primary symbol (e.g. "US$" for USD, "C$" for CAD).
|
|
18
20
|
Currency = Data.define(:code, :subunit, :symbol, :priority, :country, :name,
|
|
19
|
-
:fractional_multiplier) do
|
|
21
|
+
:fractional_multiplier, :disambiguate_symbol) do
|
|
20
22
|
# @param code [String] ISO 4217 currency code
|
|
21
23
|
# @param symbol [String] Display symbol
|
|
22
24
|
# @param subunit [Integer] Number of decimal places (default 0)
|
|
23
25
|
# @param priority [Integer] Parser precedence for symbol detection (default 0)
|
|
24
26
|
# @param country [String, nil] Associated country code (default nil)
|
|
25
27
|
# @param name [String, nil] Currency name (default nil)
|
|
26
|
-
def initialize(code:, symbol:, subunit: 0, priority: 0, country: nil, name: nil
|
|
28
|
+
def initialize(code:, symbol:, subunit: 0, priority: 0, country: nil, name: nil,
|
|
29
|
+
disambiguate_symbol: nil)
|
|
27
30
|
subunit = subunit.to_i
|
|
28
31
|
priority = priority.to_i
|
|
29
32
|
fractional_multiplier = 10**subunit
|
|
33
|
+
symbol = nil if symbol && symbol.empty?
|
|
34
|
+
disambiguate_symbol = nil if [code, symbol].include? disambiguate_symbol
|
|
30
35
|
super(code:, subunit:, symbol:, priority:, country:, name:,
|
|
31
|
-
fractional_multiplier:)
|
|
36
|
+
fractional_multiplier:, disambiguate_symbol:)
|
|
32
37
|
end
|
|
33
38
|
|
|
34
39
|
# @return [String] debug representation
|
|
@@ -37,17 +42,29 @@ module Mint
|
|
|
37
42
|
# @return [Rational] smallest representable amount (1/fractional_multiplier)
|
|
38
43
|
def minimum_amount = Rational(1, fractional_multiplier)
|
|
39
44
|
|
|
40
|
-
# Normalizes numeric
|
|
41
|
-
#
|
|
42
|
-
#
|
|
45
|
+
# Normalizes a numeric amount for this currency.
|
|
46
|
+
#
|
|
47
|
+
# @param amount [Numeric] the monetary amount to normalize
|
|
48
|
+
# @return [Rational] the amount converted to +Rational+ and rounded to
|
|
49
|
+
# the currency's subunit precision (half-up by default)
|
|
50
|
+
# @example
|
|
51
|
+
# usd = Money::Currency.for_code('USD')
|
|
52
|
+
# usd.normalize_amount(10.567) #=> (10567/1000)
|
|
53
|
+
# usd.normalize_amount("5.25") #=> (21/4)
|
|
54
|
+
#
|
|
55
|
+
# @see Mint::Rounding.apply Custom rounding modes via {Money.with_rounding}
|
|
43
56
|
def normalize_amount(amount) = amount.to_r.round(subunit)
|
|
44
57
|
|
|
45
58
|
# Returns the cached frozen zero-Money for this currency.
|
|
46
59
|
#
|
|
47
60
|
# @return [Money] a frozen zero-Money instance
|
|
48
61
|
# @example
|
|
49
|
-
#
|
|
62
|
+
# Money::Currency.for_code('USD').zero #=> [USD 0.00]
|
|
50
63
|
def zero = Registry.zero_for(self)
|
|
64
|
+
|
|
65
|
+
def dsymbol
|
|
66
|
+
disambiguate_symbol || (Registry.symbol_shared?(symbol) ? code : symbol)
|
|
67
|
+
end
|
|
51
68
|
end
|
|
52
69
|
|
|
53
70
|
# Registers a new currency, raising a KeyError if already registered.
|
|
@@ -65,20 +82,37 @@ module Mint
|
|
|
65
82
|
|
|
66
83
|
# Resolves an object into a {Currency}, returning +nil+ when it can't.
|
|
67
84
|
#
|
|
68
|
-
# Accepts +nil+, +String+, {Currency},
|
|
69
|
-
#
|
|
85
|
+
# Accepts +nil+, +String+, {Currency}, {Money}, or any object implementing
|
|
86
|
+
# +#to_currency+ (must return {Currency}) or +#currency_code+ (must return +String+).
|
|
70
87
|
#
|
|
71
|
-
# @param object [String, Currency, Money, nil
|
|
88
|
+
# @param object [String, Currency, Money, nil, #to_currency, #currency_code]
|
|
89
|
+
# a currency code, object, or +nil+
|
|
72
90
|
# @return [Currency, nil] the resolved Currency, or +nil+ if +object+ is +nil+
|
|
73
91
|
# or the code is not registered
|
|
74
|
-
# @raise [ArgumentError] if +object+ is an unsupported type
|
|
92
|
+
# @raise [ArgumentError] if +object+ is an unsupported type, or if the method
|
|
93
|
+
# used to resolve it returns a value of the wrong type
|
|
75
94
|
def Currency.resolve(object)
|
|
76
95
|
case object
|
|
77
96
|
when NilClass then nil
|
|
78
97
|
when Currency then object
|
|
79
98
|
when Money then object.currency
|
|
80
99
|
when String then Currency.for_code object
|
|
81
|
-
else
|
|
100
|
+
else
|
|
101
|
+
if object.respond_to?(:to_currency)
|
|
102
|
+
result = object.to_currency
|
|
103
|
+
unless result.is_a?(Currency)
|
|
104
|
+
raise ArgumentError, "#to_currency must return a [Money::Currency], got #{result.class}"
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
result
|
|
108
|
+
elsif object.respond_to?(:currency_code)
|
|
109
|
+
result = object.currency_code
|
|
110
|
+
raise ArgumentError, "#currency_code must return a [String], got #{result.class}" unless result.is_a?(String)
|
|
111
|
+
|
|
112
|
+
Currency.for_code result
|
|
113
|
+
else
|
|
114
|
+
raise ArgumentError, "currency must be [Money::Currency], [Money], [String] or nil (#{object})"
|
|
115
|
+
end
|
|
82
116
|
end
|
|
83
117
|
end
|
|
84
118
|
|
|
@@ -95,6 +129,15 @@ module Mint
|
|
|
95
129
|
resolve(object) or raise Mint::UnknownCurrency, "Could not resolve (#{object}) into a currency"
|
|
96
130
|
end
|
|
97
131
|
|
|
132
|
+
# Returns all registered currencies as a frozen hash keyed by ISO code.
|
|
133
|
+
#
|
|
134
|
+
# @return [Hash{String => Currency}] frozen hash of all registered currencies
|
|
135
|
+
# @example Iterate over registered currencies
|
|
136
|
+
# Currency.registered_currencies.each { |code, currency| puts "#{code}: #{currency.name}" }
|
|
137
|
+
# @example Count of registered currencies
|
|
138
|
+
# Currency.registered_currencies.size #=> 154
|
|
139
|
+
def Currency.registered_currencies = Registry.currencies
|
|
140
|
+
|
|
98
141
|
# Looks up a registered currency by its alpha code.
|
|
99
142
|
#
|
|
100
143
|
# @param code [String] the currency code
|
|
@@ -118,4 +161,36 @@ module Mint
|
|
|
118
161
|
# @return [Money] a frozen zero-Money
|
|
119
162
|
# @raise [Mint::UnknownCurrency] if the currency can't be resolved
|
|
120
163
|
def Currency.zero(currency) = Registry.zero_for(Currency.resolve!(currency))
|
|
164
|
+
|
|
165
|
+
# Returns the frozen hash of all built-in ISO 4217 world currencies.
|
|
166
|
+
#
|
|
167
|
+
# @return [Hash{String => Currency}] ISO-4217 world currencies mapped by code
|
|
168
|
+
# @api private
|
|
169
|
+
def Currency.world_currencies = Registry.world_currencies
|
|
170
|
+
|
|
171
|
+
# Returns the list of built-in crypto currency definitions.
|
|
172
|
+
#
|
|
173
|
+
# These are not registered by default — call {.register_crypto} to opt in.
|
|
174
|
+
#
|
|
175
|
+
# @return [Array<Currency>] frozen array of crypto currency definitions
|
|
176
|
+
def Currency.crypto_currencies = Registry.crypto_currencies
|
|
177
|
+
|
|
178
|
+
# Registers one or more crypto currencies into the shared currency registry.
|
|
179
|
+
#
|
|
180
|
+
# Raises on duplicate registration or unknown code — use +rescue+ if
|
|
181
|
+
# idempotent bulk registration is needed.
|
|
182
|
+
#
|
|
183
|
+
# @param codes [Array<String>] one or more crypto currency codes
|
|
184
|
+
# @raise [ArgumentError] if a code is not a known crypto currency
|
|
185
|
+
# @raise [KeyError] if the currency code is already registered
|
|
186
|
+
# @return [Array<Currency>] the newly registered Currency objects
|
|
187
|
+
def Currency.register_crypto(...) = Registry.register_crypto(...)
|
|
188
|
+
|
|
189
|
+
# Registers all built-in crypto currencies at once.
|
|
190
|
+
#
|
|
191
|
+
# Raises on the first duplicate — call +rescue+ if idempotency is needed.
|
|
192
|
+
#
|
|
193
|
+
# @raise [KeyError] if any currency code is already registered
|
|
194
|
+
# @return [Array<Currency>] the newly registered Currency objects
|
|
195
|
+
def Currency.register_all_crypto = Registry.register_all_crypto
|
|
121
196
|
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
- code: BTC
|
|
3
|
+
subunit: 8
|
|
4
|
+
symbol: "₿"
|
|
5
|
+
priority: 1000
|
|
6
|
+
name: Bitcoin
|
|
7
|
+
- code: ETH
|
|
8
|
+
subunit: 18
|
|
9
|
+
symbol: "Ξ"
|
|
10
|
+
priority: 950
|
|
11
|
+
name: Ethereum
|
|
12
|
+
- code: USDT
|
|
13
|
+
subunit: 6
|
|
14
|
+
symbol: "$"
|
|
15
|
+
priority: 900
|
|
16
|
+
name: Tether
|
|
17
|
+
- code: SOL
|
|
18
|
+
subunit: 9
|
|
19
|
+
symbol: "◎"
|
|
20
|
+
priority: 850
|
|
21
|
+
name: Solana
|
|
22
|
+
- code: XRP
|
|
23
|
+
subunit: 6
|
|
24
|
+
symbol: "✕"
|
|
25
|
+
priority: 800
|
|
26
|
+
name: XRP
|
|
27
|
+
- code: BNB
|
|
28
|
+
subunit: 8
|
|
29
|
+
symbol: ""
|
|
30
|
+
priority: 750
|
|
31
|
+
name: BNB
|
|
32
|
+
- code: USDC
|
|
33
|
+
subunit: 6
|
|
34
|
+
symbol: "$"
|
|
35
|
+
priority: 740
|
|
36
|
+
name: USD Coin
|
|
37
|
+
- code: DOGE
|
|
38
|
+
subunit: 8
|
|
39
|
+
symbol: "Ð"
|
|
40
|
+
priority: 730
|
|
41
|
+
name: Dogecoin
|
|
42
|
+
- code: ADA
|
|
43
|
+
subunit: 6
|
|
44
|
+
symbol: "₳"
|
|
45
|
+
priority: 720
|
|
46
|
+
name: Cardano
|
|
47
|
+
- code: TRX
|
|
48
|
+
subunit: 6
|
|
49
|
+
symbol: ""
|
|
50
|
+
priority: 710
|
|
51
|
+
name: TRON
|
|
52
|
+
- code: AVAX
|
|
53
|
+
subunit: 9
|
|
54
|
+
symbol: ""
|
|
55
|
+
priority: 700
|
|
56
|
+
name: Avalanche
|
|
57
|
+
- code: DOT
|
|
58
|
+
subunit: 10
|
|
59
|
+
symbol: ""
|
|
60
|
+
priority: 680
|
|
61
|
+
name: Polkadot
|
|
62
|
+
- code: LINK
|
|
63
|
+
subunit: 8
|
|
64
|
+
symbol: ""
|
|
65
|
+
priority: 660
|
|
66
|
+
name: Chainlink
|
|
67
|
+
- code: MATIC
|
|
68
|
+
subunit: 6
|
|
69
|
+
symbol: "⧫"
|
|
70
|
+
priority: 640
|
|
71
|
+
name: Polygon
|
|
72
|
+
- code: SHIB
|
|
73
|
+
subunit: 8
|
|
74
|
+
symbol: ""
|
|
75
|
+
priority: 620
|
|
76
|
+
name: Shiba Inu
|
|
77
|
+
- code: UNI
|
|
78
|
+
subunit: 8
|
|
79
|
+
symbol: ""
|
|
80
|
+
priority: 600
|
|
81
|
+
name: Uniswap
|
|
82
|
+
- code: ATOM
|
|
83
|
+
subunit: 6
|
|
84
|
+
symbol: ""
|
|
85
|
+
priority: 580
|
|
86
|
+
name: Cosmos
|
|
87
|
+
- code: LTC
|
|
88
|
+
subunit: 8
|
|
89
|
+
symbol: "Ł"
|
|
90
|
+
priority: 560
|
|
91
|
+
name: Litecoin
|
|
92
|
+
- code: BCH
|
|
93
|
+
subunit: 8
|
|
94
|
+
symbol: ""
|
|
95
|
+
priority: 540
|
|
96
|
+
name: Bitcoin Cash
|
|
97
|
+
- code: FIL
|
|
98
|
+
subunit: 9
|
|
99
|
+
symbol: ""
|
|
100
|
+
priority: 520
|
|
101
|
+
name: Filecoin
|
|
102
|
+
- code: APT
|
|
103
|
+
subunit: 8
|
|
104
|
+
symbol: ""
|
|
105
|
+
priority: 500
|
|
106
|
+
name: Aptos
|
|
107
|
+
- code: SUI
|
|
108
|
+
subunit: 9
|
|
109
|
+
symbol: ""
|
|
110
|
+
priority: 480
|
|
111
|
+
name: Sui
|
|
112
|
+
- code: TON
|
|
113
|
+
subunit: 9
|
|
114
|
+
symbol: ""
|
|
115
|
+
priority: 460
|
|
116
|
+
name: Toncoin
|
|
117
|
+
- code: PEPE
|
|
118
|
+
subunit: 8
|
|
119
|
+
symbol: ""
|
|
120
|
+
priority: 440
|
|
121
|
+
name: Pepe
|
|
122
|
+
- code: STX
|
|
123
|
+
subunit: 6
|
|
124
|
+
symbol: ""
|
|
125
|
+
priority: 420
|
|
126
|
+
name: Stacks
|