darthjee-core_ext 1.7.4 → 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/.circleci/config.yml +7 -1
- data/.gitignore +2 -0
- data/.reek.yml +3 -0
- data/ARRAY_README.md +72 -15
- data/CLASS_README.md +154 -0
- data/DATE_README.md +19 -9
- data/Dockerfile +2 -5
- data/ENUMERABLE_README.md +154 -4
- data/HASH_README.md +276 -135
- data/MATH_README.md +14 -10
- data/OBJECT_README.md +18 -35
- data/README.md +8 -4
- data/Rakefile +1 -0
- data/SYMBOL_README.md +13 -18
- data/config/rubycritc.rb +12 -0
- data/config/yardstick.yml +45 -3
- data/core_ext.gemspec +10 -8
- data/docker-compose.yml +15 -7
- data/lib/darthjee/core_ext/array.rb +17 -12
- data/lib/darthjee/core_ext/array/hash_builder.rb +20 -4
- data/lib/darthjee/core_ext/class.rb +28 -10
- data/lib/darthjee/core_ext/date.rb +1 -0
- data/lib/darthjee/core_ext/enumerable.rb +67 -30
- data/lib/darthjee/core_ext/hash.rb +4 -2
- data/lib/darthjee/core_ext/hash/cameliazable.rb +39 -8
- data/lib/darthjee/core_ext/hash/chain_fetcher.rb +17 -1
- data/lib/darthjee/core_ext/hash/changeable.rb +88 -0
- data/lib/darthjee/core_ext/hash/deep_hash_constructor.rb +127 -63
- data/lib/darthjee/core_ext/hash/deep_hash_constructor/setter.rb +112 -0
- data/lib/darthjee/core_ext/hash/key_changeable.rb +126 -54
- data/lib/darthjee/core_ext/hash/key_changer.rb +140 -40
- data/lib/darthjee/core_ext/hash/keys_sorter.rb +42 -6
- data/lib/darthjee/core_ext/hash/squasher.rb +131 -18
- data/lib/darthjee/core_ext/hash/transformable.rb +133 -41
- data/lib/darthjee/core_ext/hash/transposeable.rb +37 -8
- data/lib/darthjee/core_ext/hash/value_changer.rb +76 -36
- data/lib/darthjee/core_ext/math.rb +37 -6
- data/lib/darthjee/core_ext/numeric.rb +10 -0
- data/lib/darthjee/core_ext/object.rb +29 -0
- data/lib/darthjee/core_ext/symbol.rb +22 -2
- data/lib/darthjee/core_ext/version.rb +1 -1
- data/scripts/check_readme.sh +6 -0
- data/scripts/rubycritic.sh +10 -0
- data/spec/integration/readme/array_spec.rb +96 -0
- data/spec/integration/readme/class_spec.rb +123 -0
- data/spec/integration/readme/date_spec.rb +20 -0
- data/spec/integration/readme/enumerable_spec.rb +87 -0
- data/spec/integration/readme/hash_spec.rb +391 -0
- data/spec/integration/readme/math_spec.rb +31 -0
- data/spec/integration/readme/object_spec.rb +49 -0
- data/spec/integration/readme/symbol_spec.rb +29 -0
- data/spec/integration/yard/darthjee/core_ext/enumerable_spec.rb +24 -4
- data/spec/integration/yard/darthjee/core_ext/hash/cameliazable_spec.rb +11 -0
- data/spec/integration/yard/darthjee/core_ext/hash/changeable_spec.rb +68 -0
- data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +34 -0
- data/spec/integration/yard/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +65 -0
- data/spec/integration/yard/darthjee/core_ext/hash/key_changeable_spec.rb +8 -0
- data/spec/integration/yard/darthjee/core_ext/hash/key_changer_spec.rb +59 -0
- data/spec/integration/yard/darthjee/core_ext/hash/keys_sorter_spec.rb +25 -0
- data/spec/integration/yard/darthjee/core_ext/hash/squasher_spec.rb +60 -0
- data/spec/integration/yard/darthjee/core_ext/hash/transformable_spec.rb +66 -36
- data/spec/integration/yard/darthjee/core_ext/hash/transposeable_spec.rb +35 -0
- data/spec/integration/yard/darthjee/core_ext/hash_spec.rb +13 -2
- data/spec/integration/yard/darthjee/core_ext/math_spec.rb +28 -0
- data/spec/integration/yard/darthjee/core_ext/numeric_spec.rb +11 -0
- data/spec/integration/yard/darthjee/core_ext/object_spec.rb +47 -0
- data/spec/integration/yard/darthjee/core_ext/symbol_spec.rb +17 -0
- data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor/setter_spec.rb +64 -0
- data/spec/lib/darthjee/core_ext/hash/deep_hash_constructor_spec.rb +16 -156
- data/spec/lib/darthjee/core_ext/hash/keys_sorter_spec.rb +5 -4
- data/spec/lib/darthjee/core_ext/hash/squasher_spec.rb +8 -2
- data/spec/lib/darthjee/core_ext/hash/value_changer_spec.rb +4 -12
- data/spec/lib/hash_spec.rb +92 -146
- data/spec/lib/object_spec.rb +32 -0
- data/spec/support/models/client.rb +22 -0
- data/spec/support/shared_examples/hash/deep_hash.rb +166 -0
- data/spec/support/shared_examples/hash/hash_squasher.rb +54 -9
- data/spec/support/shared_examples/hash/keys_sorter.rb +266 -6
- metadata +70 -8
- data/lib/darthjee/core_ext/hash/to_hash_mapper.rb +0 -25
- data/spec/lib/darthjee/core_ext/hash/to_hash_mapper_spec.rb +0 -11
@@ -4,8 +4,7 @@ module Darthjee
|
|
4
4
|
module CoreExt
|
5
5
|
module Hash
|
6
6
|
module Transformable
|
7
|
-
#
|
8
|
-
# exist in the original hash
|
7
|
+
# Merge only common keys
|
9
8
|
#
|
10
9
|
# @param [::Hash] other other hash to be merged
|
11
10
|
#
|
@@ -15,14 +14,16 @@ module Darthjee
|
|
15
14
|
# hash = { a: 1, b: 2, c: 3 }
|
16
15
|
# other = { b: 4, 'c' => 5, e: 6 }
|
17
16
|
#
|
18
|
-
# hash.exclusive_merge(other) # returns {
|
19
|
-
#
|
17
|
+
# hash.exclusive_merge(other) # returns {
|
18
|
+
# # a: 1,
|
19
|
+
# # b: 4,
|
20
|
+
# # c: 3
|
21
|
+
# # }
|
20
22
|
def exclusive_merge(other)
|
21
23
|
dup.exclusive_merge!(other)
|
22
24
|
end
|
23
25
|
|
24
|
-
#
|
25
|
-
# exist in the original hash
|
26
|
+
# Merge only common keys
|
26
27
|
#
|
27
28
|
# @param [::Hash] other other hash to be merged
|
28
29
|
#
|
@@ -32,17 +33,23 @@ module Darthjee
|
|
32
33
|
# hash = { a: 1, b: 2, c: 3 }
|
33
34
|
# other = { b: 4, 'c' => 5, e: 6 }
|
34
35
|
#
|
35
|
-
# hash.exclusive_merge!(other) #
|
36
|
-
#
|
36
|
+
# hash.exclusive_merge!(other) # changes hash to {
|
37
|
+
# # a: 1,
|
38
|
+
# # b: 4,
|
39
|
+
# # c: 3
|
40
|
+
# # }
|
37
41
|
def exclusive_merge!(other)
|
38
42
|
merge!(other.slice(*keys))
|
39
43
|
end
|
40
44
|
|
45
|
+
# Map returning a hash keeping the original keys
|
46
|
+
#
|
41
47
|
# Run map block where each pair key, value is mapped
|
42
48
|
# to a new value to be assigned in the same key on the
|
43
49
|
# returned hash
|
44
50
|
#
|
45
|
-
# @return new Hash made with the pairs
|
51
|
+
# @return [::Hash] new Hash made with the pairs
|
52
|
+
# key => mapped_value
|
46
53
|
#
|
47
54
|
# @yield (key, value) block returning the new value
|
48
55
|
#
|
@@ -55,22 +62,33 @@ module Darthjee
|
|
55
62
|
# "#{key}->#{value.size}"
|
56
63
|
# end
|
57
64
|
#
|
58
|
-
# new_hash # returns {
|
59
|
-
|
60
|
-
|
65
|
+
# new_hash # returns {
|
66
|
+
# # a: 'a->4',
|
67
|
+
# # b: 'b->7',
|
68
|
+
# # c: 'c->1'
|
69
|
+
# # }
|
70
|
+
def map_to_hash
|
71
|
+
map do |key, value|
|
72
|
+
[key, yield(key, value)]
|
73
|
+
end.to_h
|
61
74
|
end
|
62
75
|
|
63
|
-
# Squash the hash
|
64
|
-
#
|
76
|
+
# Squash the hash returning a single level hash
|
77
|
+
#
|
78
|
+
# The squashing happens by merging the keys of
|
79
|
+
# outter and inner hashes
|
65
80
|
#
|
66
81
|
# This operation is the oposite of {#to_deep_hash}
|
67
82
|
#
|
68
|
-
# @
|
83
|
+
# @param joiner [::String] String to be used when
|
84
|
+
# joining keys
|
85
|
+
#
|
86
|
+
# @return [::Hash] A new hash
|
69
87
|
#
|
70
88
|
# @see Squash::Builder
|
71
89
|
# @see #to_deep_hash
|
72
90
|
#
|
73
|
-
# @example
|
91
|
+
# @example Simple Usage
|
74
92
|
# hash = { name: { first: 'John', last: 'Doe' } }
|
75
93
|
#
|
76
94
|
# hash.squash # returns {
|
@@ -80,21 +98,63 @@ module Darthjee
|
|
80
98
|
#
|
81
99
|
# @example Reverting a #to_deep_hash call
|
82
100
|
# person_data = {
|
83
|
-
#
|
84
|
-
#
|
101
|
+
# person: [{
|
102
|
+
# name: %w[John Wick],
|
103
|
+
# age: 22
|
104
|
+
# }, {
|
105
|
+
# name: %w[John Constantine],
|
106
|
+
# age: 25
|
107
|
+
# }]
|
85
108
|
# }
|
86
109
|
# person = person_data.to_deep_hash
|
87
110
|
#
|
88
111
|
# person.squash # returns {
|
89
|
-
# # 'person
|
90
|
-
# #
|
112
|
+
# # 'person' => [{
|
113
|
+
# # 'name' => %w[John Wick],
|
114
|
+
# # 'age' => 22
|
115
|
+
# # }, {
|
116
|
+
# # 'name' => %w[John Constantine],
|
117
|
+
# # 'age' => 25
|
118
|
+
# # }]
|
91
119
|
# # }
|
92
|
-
|
93
|
-
|
120
|
+
#
|
121
|
+
# @example Giving a custom joiner
|
122
|
+
# hash = {
|
123
|
+
# links: {
|
124
|
+
# home: '/',
|
125
|
+
# products: '/products'
|
126
|
+
# }
|
127
|
+
# }
|
128
|
+
#
|
129
|
+
# hash.squash('> ') # returns {
|
130
|
+
# # 'links> home' => '/',
|
131
|
+
# # 'links> products' => '/products'
|
132
|
+
# # }
|
133
|
+
def squash(joiner = '.')
|
134
|
+
Hash::Squasher.new(joiner).squash(deep_dup)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Squash the hash so that it becomes a single level hash
|
138
|
+
#
|
139
|
+
# The squashing happens by merging the keys of
|
140
|
+
# outter and inner hashes
|
141
|
+
#
|
142
|
+
# This operation is the oposite of {#to_deep_hash!}
|
143
|
+
#
|
144
|
+
# @param joiner [::String] String to be used when
|
145
|
+
# joining keys
|
146
|
+
#
|
147
|
+
# @return [::Hash] A new hash
|
148
|
+
#
|
149
|
+
# @see Squash::Builder
|
150
|
+
# @see #to_deep_hash!
|
151
|
+
#
|
152
|
+
# @example (see #squash)
|
153
|
+
def squash!(joiner = '.')
|
154
|
+
Hash::Squasher.new(joiner).squash(self)
|
94
155
|
end
|
95
156
|
|
96
|
-
# Creates a new hash of multiple levels
|
97
|
-
# hash
|
157
|
+
# Creates a new hash of multiple levels
|
98
158
|
#
|
99
159
|
# this operation is the oposite from {#squash}
|
100
160
|
#
|
@@ -103,32 +163,64 @@ module Darthjee
|
|
103
163
|
# @see Hash::DeepHashConstructor
|
104
164
|
# @see #squash
|
105
165
|
#
|
106
|
-
# @example
|
107
|
-
#
|
166
|
+
# @example With custom separator
|
167
|
+
# hash = {
|
168
|
+
# 'person[0]_name_first' => 'John',
|
169
|
+
# 'person[0]_name_last' => 'Doe',
|
170
|
+
# 'person[1]_name_first' => 'John',
|
171
|
+
# 'person[1]_name_last' => 'Wick'
|
172
|
+
# }
|
108
173
|
#
|
109
|
-
# hash.to_deep_hash # return {
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
174
|
+
# hash.to_deep_hash('_') # return {
|
175
|
+
# # 'person' => [{
|
176
|
+
# # 'name' => {
|
177
|
+
# # 'first' => 'John',
|
178
|
+
# # 'last' => 'Doe'
|
179
|
+
# # }, {
|
180
|
+
# # 'name' => {
|
181
|
+
# # 'first' => 'John',
|
182
|
+
# # 'last' => 'Wick'
|
183
|
+
# # }
|
184
|
+
# # }]
|
185
|
+
# # }
|
186
|
+
#
|
187
|
+
# @example Reverting the result of a squash
|
116
188
|
# person = {
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
# }
|
189
|
+
# person: [{
|
190
|
+
# name: ['John', 'Wick'],
|
191
|
+
# age: 23
|
192
|
+
# }, {
|
193
|
+
# name: %w[John Constantine],
|
194
|
+
# age: 25
|
195
|
+
# }]
|
121
196
|
# }
|
122
197
|
# person_data = person.squash
|
123
198
|
#
|
124
199
|
# person_data.to_deep_hash
|
125
200
|
# # returns {
|
126
|
-
# # 'person' => {
|
127
|
-
# # 'name' => 'John',
|
128
|
-
# # 'age'
|
129
|
-
# # }
|
201
|
+
# # 'person' => [{
|
202
|
+
# # 'name' => ['John', 'Wick'],
|
203
|
+
# # 'age' => 23
|
204
|
+
# # }, {
|
205
|
+
# # 'name' => %w[John Constantine],
|
206
|
+
# # 'age' => 25
|
207
|
+
# # }]
|
130
208
|
# # }
|
131
209
|
def to_deep_hash(separator = '.')
|
210
|
+
Hash::DeepHashConstructor.new(separator).deep_hash(deep_dup)
|
211
|
+
end
|
212
|
+
|
213
|
+
# Changes hash to be a multiple level hash
|
214
|
+
#
|
215
|
+
# this operation is the oposite from {#squash!}
|
216
|
+
#
|
217
|
+
# @return [::Hash] Self changed to be a multi-level hash
|
218
|
+
#
|
219
|
+
# @see Hash::DeepHashConstructor
|
220
|
+
# @see #squash
|
221
|
+
#
|
222
|
+
# @example (see #to_deep_hash)
|
223
|
+
def to_deep_hash!(separator = '.')
|
132
224
|
Hash::DeepHashConstructor.new(separator).deep_hash(self)
|
133
225
|
end
|
134
226
|
end
|
@@ -3,20 +3,49 @@
|
|
3
3
|
module Darthjee
|
4
4
|
module CoreExt
|
5
5
|
module Hash
|
6
|
+
# @author darthjee
|
7
|
+
#
|
8
|
+
# Collection of methods for transposing keys
|
9
|
+
# and values of hash
|
6
10
|
module Transposeable
|
11
|
+
# Transpose matrix swapping keys by values
|
12
|
+
#
|
13
|
+
# @return [::Hash]
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# hash = {
|
17
|
+
# key1: :value1,
|
18
|
+
# key2: :value2,
|
19
|
+
# }
|
20
|
+
#
|
21
|
+
# hash.transpose # returns {
|
22
|
+
# # value1: :key1,
|
23
|
+
# # value2: :key2
|
24
|
+
# # }
|
7
25
|
def transpose!
|
8
|
-
|
9
|
-
keys.each
|
10
|
-
|
11
|
-
self[v] = k
|
12
|
-
end
|
13
|
-
self
|
26
|
+
transposed = transpose
|
27
|
+
keys.each(&method(:delete))
|
28
|
+
merge!(transposed)
|
14
29
|
end
|
15
30
|
|
31
|
+
# Transpose matrix swapping keys by values
|
32
|
+
#
|
33
|
+
# @return [::Hash]
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# hash = {
|
37
|
+
# key1: :value1,
|
38
|
+
# key2: :value2,
|
39
|
+
# }
|
40
|
+
#
|
41
|
+
# hash.transpose # changes hash to {
|
42
|
+
# # value1: :key1,
|
43
|
+
# # value2: :key2
|
44
|
+
# # }
|
16
45
|
def transpose
|
17
46
|
{}.tap do |new_hash|
|
18
|
-
each do |
|
19
|
-
new_hash[
|
47
|
+
each do |key, value|
|
48
|
+
new_hash[value] = key
|
20
49
|
end
|
21
50
|
end
|
22
51
|
end
|
@@ -3,26 +3,27 @@
|
|
3
3
|
module Darthjee
|
4
4
|
module CoreExt
|
5
5
|
module Hash
|
6
|
+
# @api private
|
7
|
+
# @author darthjee
|
8
|
+
#
|
6
9
|
# Class responsible for changing values on a hash
|
7
10
|
#
|
8
|
-
# @attribute [
|
11
|
+
# @attribute [::TrueClass,::FalseClass] recursive
|
9
12
|
# flag telling to apply transformation recursively
|
10
|
-
# @attribute [
|
13
|
+
# @attribute [::TrueClass,::FalseClass] skip_inner
|
11
14
|
# flag telling to not apply change block call to inner hashes
|
12
15
|
# @attribute [::Proc] block
|
13
16
|
# block to be called when changing the values
|
14
17
|
#
|
15
18
|
# @example
|
16
|
-
# (see initialize)
|
19
|
+
# (see #initialize)
|
17
20
|
#
|
18
21
|
# @example
|
19
22
|
# (see #change)
|
20
23
|
class ValueChanger
|
21
|
-
|
22
|
-
|
23
|
-
# @param [Boolean] recursive
|
24
|
+
# @param [::TrueClass,::FalseClass] recursive
|
24
25
|
# flag telling to apply transformation recursively
|
25
|
-
# @param [
|
26
|
+
# @param [::TrueClass,::FalseClass] skip_inner
|
26
27
|
# flag telling to not apply change block call to inner hashes
|
27
28
|
# @param [::Proc] block
|
28
29
|
# block to be called when changing the values
|
@@ -108,61 +109,100 @@ module Darthjee
|
|
108
109
|
# # [{ e: 3 }]
|
109
110
|
# # ]
|
110
111
|
def change(object)
|
111
|
-
if object.
|
112
|
+
if object.is_a?(Hash)
|
112
113
|
change_hash(object)
|
113
|
-
elsif
|
114
|
+
elsif object.is_a?(Array)
|
114
115
|
change_array(object)
|
116
|
+
elsif iterable?(object)
|
117
|
+
change_iterator(object)
|
115
118
|
else
|
116
|
-
object
|
119
|
+
new_value(object)
|
117
120
|
end
|
118
121
|
end
|
119
122
|
|
120
123
|
private
|
121
124
|
|
125
|
+
attr_reader :recursive, :skip_inner, :block
|
126
|
+
|
127
|
+
# @private
|
128
|
+
#
|
122
129
|
# Apply change logic to hash object
|
123
130
|
#
|
124
|
-
# @
|
125
|
-
|
126
|
-
|
127
|
-
|
131
|
+
# @param hash [::Hash] hash to be changed
|
132
|
+
#
|
133
|
+
# @return [::Hash]
|
134
|
+
def change_hash(hash)
|
135
|
+
hash.tap do
|
136
|
+
hash.each do |key, value|
|
128
137
|
hash[key] = new_value(value)
|
129
138
|
end
|
130
139
|
end
|
131
140
|
end
|
132
141
|
|
142
|
+
# @private
|
143
|
+
#
|
133
144
|
# Apply change logic to iterator
|
134
145
|
#
|
135
|
-
# @
|
146
|
+
# @param array [::Array] array to be changed
|
147
|
+
#
|
148
|
+
# @return [::Array]
|
136
149
|
def change_array(array)
|
137
|
-
|
150
|
+
array.map!(&method(:change))
|
151
|
+
end
|
138
152
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
153
|
+
# @private
|
154
|
+
#
|
155
|
+
# Change value from iterator
|
156
|
+
#
|
157
|
+
# @param iterator [::Object] object responding to map
|
158
|
+
#
|
159
|
+
# @return [::Array]
|
160
|
+
def change_iterator(iterator)
|
161
|
+
iterator.map(&method(:change))
|
148
162
|
end
|
149
163
|
|
150
|
-
#
|
151
|
-
#
|
164
|
+
# @private
|
165
|
+
#
|
166
|
+
# Check wehether block should be called over value
|
152
167
|
#
|
153
168
|
# when the block is not iterable (not Array or Hash)
|
154
169
|
# or when skip_inner option is set to be false,
|
155
170
|
# then block should be called
|
156
171
|
#
|
157
|
-
# @
|
172
|
+
# @param value [::Object] value to be checked
|
173
|
+
#
|
174
|
+
# @return [::TrueClass,::FalseClass]
|
158
175
|
def change_value?(value)
|
159
176
|
!iterable?(value) || !skip_inner
|
160
177
|
end
|
161
178
|
|
179
|
+
# @private
|
180
|
+
#
|
181
|
+
# Checks if a value is iterable
|
182
|
+
#
|
183
|
+
# @param value [::Object] object to be checked
|
184
|
+
#
|
185
|
+
# @return [::TrueClass,::FalseClass]
|
162
186
|
def iterable?(value)
|
163
|
-
value.respond_to?(:
|
187
|
+
value.respond_to?(:map)
|
164
188
|
end
|
165
189
|
|
190
|
+
# @private
|
191
|
+
#
|
192
|
+
# Performs recursive transformation
|
193
|
+
#
|
194
|
+
# @overload new_value(hash)
|
195
|
+
# @param hash [::Hash] sub-hash to be processed recursively
|
196
|
+
# @return [::Hash]
|
197
|
+
#
|
198
|
+
# @overload new_value(array)
|
199
|
+
# @param array [::Array] array to be processed recursively
|
200
|
+
# @return [::Array]
|
201
|
+
#
|
202
|
+
# @overload new_value(value)
|
203
|
+
# @param value [::Object] value to be transformed
|
204
|
+
#
|
205
|
+
# @return [::Object]
|
166
206
|
def new_value(value)
|
167
207
|
value = block.call(value) if change_value?(value)
|
168
208
|
|
@@ -171,16 +211,16 @@ module Darthjee
|
|
171
211
|
change(value)
|
172
212
|
end
|
173
213
|
|
214
|
+
# @private
|
215
|
+
#
|
216
|
+
# Checks if recursion should be applied
|
217
|
+
#
|
218
|
+
# @param value [::Object]
|
219
|
+
#
|
220
|
+
# @return [::TrueClass,::FalseClass]
|
174
221
|
def apply_recursion?(value)
|
175
222
|
iterable?(value) && recursive
|
176
223
|
end
|
177
|
-
|
178
|
-
def options
|
179
|
-
@options ||= {
|
180
|
-
recursive: recursive,
|
181
|
-
skip_inner: skip_inner
|
182
|
-
}
|
183
|
-
end
|
184
224
|
end
|
185
225
|
end
|
186
226
|
end
|