zakuro 0.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 +7 -0
- data/.editorconfig +9 -0
- data/.gitignore +69 -0
- data/.rspec +3 -0
- data/.rubocop.yml +14 -0
- data/.travis.yml +6 -0
- data/Gemfile +19 -0
- data/LICENSE.txt +21 -0
- data/README.md +44 -0
- data/Rakefile +20 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/images/12/346/234/210/344/273/245/351/231/215/343/201/256/345/205/245/345/256/232/346/260/227.png +0 -0
- data/images/12/346/234/210/344/273/245/351/231/215/343/201/256/346/234/210/343/201/256/351/200/262/351/200/200.png +0 -0
- data/images/source/description.numbers +0 -0
- data/images//345/205/245/345/256/232/346/260/227/343/201/256/350/265/267/347/256/227.png +0 -0
- data/images//345/220/204/346/234/210/343/201/256/346/261/202/343/202/201/346/226/271.png +0 -0
- data/images//345/244/252/351/231/275/343/201/250/346/234/210.png +0 -0
- data/lib/zakuro.rb +9 -0
- data/lib/zakuro/condition.rb +239 -0
- data/lib/zakuro/cycle/abstract_remainder.rb +457 -0
- data/lib/zakuro/cycle/zodiac.rb +103 -0
- data/lib/zakuro/era/gengou/set-001-until-south.yaml +375 -0
- data/lib/zakuro/era/gengou/set-002-from-north.yaml +166 -0
- data/lib/zakuro/era/gengou/set-003-modern.yaml +12 -0
- data/lib/zakuro/era/japan.rb +630 -0
- data/lib/zakuro/era/western.rb +412 -0
- data/lib/zakuro/merchant.rb +57 -0
- data/lib/zakuro/output/error.rb +10 -0
- data/lib/zakuro/output/logger.rb +64 -0
- data/lib/zakuro/output/response.rb +170 -0
- data/lib/zakuro/output/result.rb +219 -0
- data/lib/zakuro/output/stringifier.rb +62 -0
- data/lib/zakuro/version.rb +7 -0
- data/lib/zakuro/version/abstract_version.rb +29 -0
- data/lib/zakuro/version/genka/genka.rb +19 -0
- data/lib/zakuro/version/gihou/gihou.rb +19 -0
- data/lib/zakuro/version/gregorio/gregorio.rb +19 -0
- data/lib/zakuro/version/houryaku/houryaku.rb +19 -0
- data/lib/zakuro/version/joukyou/joukyou.rb +19 -0
- data/lib/zakuro/version/kansei/kansei.rb +19 -0
- data/lib/zakuro/version/senmyou/README.md +586 -0
- data/lib/zakuro/version/senmyou/base/era.rb +81 -0
- data/lib/zakuro/version/senmyou/base/gengou.rb +210 -0
- data/lib/zakuro/version/senmyou/base/remainder.rb +60 -0
- data/lib/zakuro/version/senmyou/base/solar_term.rb +66 -0
- data/lib/zakuro/version/senmyou/base/year.rb +58 -0
- data/lib/zakuro/version/senmyou/monthly/lunar_phase.rb +220 -0
- data/lib/zakuro/version/senmyou/monthly/month.rb +112 -0
- data/lib/zakuro/version/senmyou/senmyou.rb +34 -0
- data/lib/zakuro/version/senmyou/stella/lunar_orbit.rb +332 -0
- data/lib/zakuro/version/senmyou/stella/solar_average.rb +192 -0
- data/lib/zakuro/version/senmyou/stella/solar_orbit.rb +398 -0
- data/lib/zakuro/version/senmyou/stella/winter_solstice.rb +106 -0
- data/lib/zakuro/version/senmyou/summary/annual_data.rb +186 -0
- data/lib/zakuro/version/senmyou/summary/gengou_data.rb +294 -0
- data/lib/zakuro/version/taien/taien.rb +19 -0
- data/lib/zakuro/version/tenpou/tenpou.rb +19 -0
- data/lib/zakuro/version_factory.rb +59 -0
- data/zakuro.gemspec +31 -0
- metadata +106 -0
@@ -0,0 +1,412 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
# :nodoc:
|
6
|
+
module Zakuro
|
7
|
+
#
|
8
|
+
# Western 西暦
|
9
|
+
#
|
10
|
+
module Western
|
11
|
+
#
|
12
|
+
# Type 日付種別
|
13
|
+
#
|
14
|
+
module Type
|
15
|
+
# @return [Symbol] ユリウス暦
|
16
|
+
JULIAN = :julian
|
17
|
+
# @return [Symbol] グレゴリオ暦
|
18
|
+
GREGORIAN = :gregorian
|
19
|
+
# @return [Symbol] ユリウス暦/グレゴリオ暦
|
20
|
+
DEFAULT = :default
|
21
|
+
end
|
22
|
+
|
23
|
+
# @return [Hash<Symbol, Integer>] グレゴリオ暦の開始日(ユリウス日)
|
24
|
+
DATE_START = {
|
25
|
+
# 通年ユリウス暦
|
26
|
+
Type::JULIAN => Date::JULIAN,
|
27
|
+
# 通年グレゴリオ暦
|
28
|
+
Type::GREGORIAN => Date::GREGORIAN,
|
29
|
+
# ユリウス暦/グレゴリオ暦
|
30
|
+
#
|
31
|
+
# Date::ITALY は以下引用の通りにユリウス暦/グレゴリオ暦の改暦が行われるため矛盾はない
|
32
|
+
#
|
33
|
+
# ユリウス暦で1582年10月4日(わが天正10年9月18日)の翌日を10月15日としてグレゴリオ暦に改暦した。
|
34
|
+
# 9月朔まではユリウス暦日に対応させるべきであるが、計算の都合でこの頁からグレゴリオ暦に対応させてある。
|
35
|
+
# 念のため相当するユリウス暦日を記すと、天正10年正月朔は1月24日、2月朔は2月23日、3月朔は3月24日、
|
36
|
+
# 4月朔は4月23日、5月朔は5月22日、6月朔は6月20日、7月朔は7月20日、8月朔は8月18日、9月朔は9月17日である。
|
37
|
+
# 以下必要ならグレゴリオ暦日の10日前を求めればよい。(暦法編第3章のix : 第30表参照)
|
38
|
+
# p.393
|
39
|
+
#
|
40
|
+
# Date::ITALY は改暦による存在しない日付(1582-10-05 ~ 1852-10-14)でエラーが発生する
|
41
|
+
#
|
42
|
+
# ref: https://github.com/ruby/ruby/blob/487d96c6b1cd7f5d415dba27a9684b30dfa9afed/ext/date/date_core.c#L9237-L9249
|
43
|
+
#
|
44
|
+
# * A Date object can be created with an optional argument,
|
45
|
+
# * the day of calendar reform as a Julian day number, which
|
46
|
+
# * should be 2298874 to 2426355 or negative/positive infinity.
|
47
|
+
# * The default value is +Date::ITALY+ (2299161=1582-10-15).
|
48
|
+
# * See also sample/cal.rb.
|
49
|
+
# *
|
50
|
+
# * $ ruby sample/cal.rb -c it 10 1582
|
51
|
+
# * October 1582
|
52
|
+
# * S M Tu W Th F S
|
53
|
+
# * 1 2 3 4 15 16
|
54
|
+
# * 17 18 19 20 21 22 23
|
55
|
+
# * 24 25 26 27 28 29 30
|
56
|
+
# * 31
|
57
|
+
#
|
58
|
+
Type::DEFAULT => Date::ITALY
|
59
|
+
}.freeze
|
60
|
+
|
61
|
+
#
|
62
|
+
# 日付種別からRuby標準のグレゴリオ暦開始日を引き当てる
|
63
|
+
#
|
64
|
+
# @param [Symbol] type 日付種別
|
65
|
+
#
|
66
|
+
# @return [Integer] Ruby標準のグレゴリオ暦開始日
|
67
|
+
#
|
68
|
+
def self.to_native_start(type:)
|
69
|
+
DATE_START.fetch(type, DATE_START[Type::DEFAULT])
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# Ruby標準のグレゴリオ暦開始日から日付種別を引き当てる
|
74
|
+
#
|
75
|
+
# @param [Integer] start Ruby標準のグレゴリオ暦開始日
|
76
|
+
#
|
77
|
+
# @return [Symbol] 日付種別
|
78
|
+
#
|
79
|
+
def self.to_type(start:)
|
80
|
+
DATE_START.invert.fetch(start, Type::DEFAULT)
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Parameter 初期化引数
|
85
|
+
#
|
86
|
+
class Parameter
|
87
|
+
# @return [Integer] 年
|
88
|
+
attr_reader :year
|
89
|
+
# @return [Integer] 月
|
90
|
+
attr_reader :month
|
91
|
+
# @return [Integer] 日
|
92
|
+
attr_reader :day
|
93
|
+
# @return [Integer] Ruby標準のグレゴリオ暦開始日
|
94
|
+
attr_reader :start
|
95
|
+
|
96
|
+
#
|
97
|
+
# 初期化
|
98
|
+
#
|
99
|
+
# @param [Integer] year 年
|
100
|
+
# @param [Integer] month 月
|
101
|
+
# @param [Integer] day 日
|
102
|
+
# @param [Integer] start Ruby標準のグレゴリオ暦開始日
|
103
|
+
#
|
104
|
+
def initialize(year:, month:, day:, start:)
|
105
|
+
@year = year
|
106
|
+
@month = month
|
107
|
+
@day = day
|
108
|
+
@start = start
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# :reek:TooManyMethods { max_methods: 17 }
|
113
|
+
|
114
|
+
#
|
115
|
+
# Calendar 年月日情報(西暦)
|
116
|
+
#
|
117
|
+
# このクラスでは以下の機能が求められる。
|
118
|
+
# 1. グレゴリオ暦(yyyy, mm, dd) -> 日付オブジェクト
|
119
|
+
# 2. ユリウス暦(yyyy, mm, dd) -> 日付オブジェクト
|
120
|
+
# 3. 指定なし(yyyy, mm, dd) -> 日付オブジェクト
|
121
|
+
# 4. 日付オブジェクト(グレゴリオ暦) -> グレゴリオ暦(yyyy, mm, dd)
|
122
|
+
# 5. 日付オブジェクト(ユリウス暦) -> ユリウス暦(yyyy, mm, dd)
|
123
|
+
# 6. 日付オブジェクト(指定なし) -> ユリウス暦/グレゴリオ暦(yyyy, mm, dd)
|
124
|
+
#
|
125
|
+
# * 3の "指定なし" とは、グレゴリオ暦開始日からを1、それ以前を2とする方式である
|
126
|
+
# * 6もまた上記に準じて日付を求める
|
127
|
+
# * それぞれ日付オブジェクトに変換する目的は、日付の加減算と比較のためである
|
128
|
+
#
|
129
|
+
# これらの機能はRubyの標準機能であり、特別な実装を要しない
|
130
|
+
#
|
131
|
+
# 定数 DATE_START のバリエーションで日付オブジェクトを初期化するだけで良い
|
132
|
+
#
|
133
|
+
class Calendar # rubocop:disable Metrics/ClassLength
|
134
|
+
attr_reader :param, :date
|
135
|
+
|
136
|
+
def validate
|
137
|
+
failed = valid_type
|
138
|
+
|
139
|
+
return failed unless failed.size.zero?
|
140
|
+
|
141
|
+
valid_date
|
142
|
+
end
|
143
|
+
|
144
|
+
# :reek:TooManyStatements { max_statements: 8 }
|
145
|
+
|
146
|
+
#
|
147
|
+
# データ型を検証する
|
148
|
+
#
|
149
|
+
# @return [Array<String>] 不正メッセージ
|
150
|
+
#
|
151
|
+
def valid_type
|
152
|
+
failed = []
|
153
|
+
year = @param.year
|
154
|
+
month = @param.month
|
155
|
+
day = @param.day
|
156
|
+
failed.push("wrong type. year: #{year}") unless year.is_a?(Integer)
|
157
|
+
failed.push("wrong type. month: #{month}") unless month.is_a?(Integer)
|
158
|
+
failed.push("wrong type. day: #{day}") unless day.is_a?(Integer)
|
159
|
+
failed
|
160
|
+
end
|
161
|
+
|
162
|
+
# :reek:TooManyStatements { max_statements: 7 }
|
163
|
+
|
164
|
+
#
|
165
|
+
# 日付データとして検証する
|
166
|
+
#
|
167
|
+
# @return [Array<String>] 不正メッセージ
|
168
|
+
#
|
169
|
+
def valid_date
|
170
|
+
failed = []
|
171
|
+
|
172
|
+
year = @param.year
|
173
|
+
month = @param.month
|
174
|
+
day = @param.day
|
175
|
+
start = @param.start
|
176
|
+
unless Date.valid_date?(year, month, day, start)
|
177
|
+
failed.push("year: #{year}, month: #{month}, " \
|
178
|
+
"day: #{day}, start: #{start}")
|
179
|
+
end
|
180
|
+
failed
|
181
|
+
end
|
182
|
+
|
183
|
+
#
|
184
|
+
# 初期化
|
185
|
+
#
|
186
|
+
# @param [Integer] year 年
|
187
|
+
# @param [Integer] month 月
|
188
|
+
# @param [Integer] day 日
|
189
|
+
# @param [Symbol] type 日付種別
|
190
|
+
#
|
191
|
+
def initialize(year: -4712, month: 1, day: 1, type: Type::DEFAULT)
|
192
|
+
start = Western.to_native_start(type: type)
|
193
|
+
@param = Parameter.new(year: year, month: month, day: day, start: start)
|
194
|
+
|
195
|
+
failed = validate
|
196
|
+
raise ArgumentError, failed.join('\n') unless failed.size.zero?
|
197
|
+
|
198
|
+
@date = Date.new(year, month, day, start)
|
199
|
+
end
|
200
|
+
|
201
|
+
#
|
202
|
+
# 初期化時の日付とは異なる種別に切り替える
|
203
|
+
#
|
204
|
+
# @example Ruby標準の start_with に相当する
|
205
|
+
# > date = Date.new(1582, 10, 15)
|
206
|
+
# => #<Date: 1582-10-15 ((2299161j,0s,0n),+0s,2299161j)>
|
207
|
+
# > date.new_start(Date::JULIAN)
|
208
|
+
# => #<Date: 1582-10-05 ((2299161j,0s,0n),+0s,Infj)>
|
209
|
+
#
|
210
|
+
# @param [Symbol] type 日付種別
|
211
|
+
#
|
212
|
+
# @return [Calendar] 年月日情報(西暦)
|
213
|
+
#
|
214
|
+
def redate(type: Type::DEFAULT)
|
215
|
+
start = DATE_START.fetch(type, DATE_START[Type::DEFAULT])
|
216
|
+
@date = @date.new_start(start)
|
217
|
+
self
|
218
|
+
end
|
219
|
+
|
220
|
+
#
|
221
|
+
# 加算する
|
222
|
+
#
|
223
|
+
# @param [Calendar,Integer] other 年月日情報(西暦),日数
|
224
|
+
#
|
225
|
+
# @return [Calendar] 年月日情報(西暦)
|
226
|
+
#
|
227
|
+
def +(other)
|
228
|
+
return @date.jd + other.date.jd if other.is_a?(Western::Calendar)
|
229
|
+
|
230
|
+
@date += other
|
231
|
+
self
|
232
|
+
end
|
233
|
+
|
234
|
+
#
|
235
|
+
# 減算する
|
236
|
+
#
|
237
|
+
# @param [Calendar,Integer] other 年月日情報(西暦),日数
|
238
|
+
#
|
239
|
+
# @return [Calendar] 年月日情報(西暦)
|
240
|
+
#
|
241
|
+
def -(other)
|
242
|
+
return @date.jd - other.date.jd if other.is_a?(Western::Calendar)
|
243
|
+
|
244
|
+
@date -= other
|
245
|
+
self
|
246
|
+
end
|
247
|
+
|
248
|
+
#
|
249
|
+
# 大小比較する(>)
|
250
|
+
#
|
251
|
+
# @param [Calendar] other 年月日情報(西暦)
|
252
|
+
#
|
253
|
+
# @return [True] より大きい(未来日である)
|
254
|
+
# @return [False] 以下(現在日/過去日である)
|
255
|
+
#
|
256
|
+
def >(other)
|
257
|
+
@date > other.date
|
258
|
+
end
|
259
|
+
|
260
|
+
#
|
261
|
+
# 大小比較する(>=)
|
262
|
+
#
|
263
|
+
# @param [Calendar] other 年月日情報(西暦)
|
264
|
+
#
|
265
|
+
# @return [True] 以上(現在日/未来日である)
|
266
|
+
# @return [False] より小さい(過去日である)
|
267
|
+
#
|
268
|
+
def >=(other)
|
269
|
+
@date >= other.date
|
270
|
+
end
|
271
|
+
|
272
|
+
#
|
273
|
+
# 大小比較する(<)
|
274
|
+
#
|
275
|
+
# @param [Calendar] other 年月日情報(西暦)
|
276
|
+
#
|
277
|
+
# @return [True] より小さい(過去日である)
|
278
|
+
# @return [False] 以上(現在日/未来日である)
|
279
|
+
#
|
280
|
+
def <(other)
|
281
|
+
@date < other.date
|
282
|
+
end
|
283
|
+
|
284
|
+
#
|
285
|
+
# 大小比較する(<=)
|
286
|
+
#
|
287
|
+
# @param [Calendar] other 年月日情報(西暦)
|
288
|
+
#
|
289
|
+
# @return [True] 以下(過去日/現在日である)
|
290
|
+
# @return [False] より大きい(未来日である)
|
291
|
+
#
|
292
|
+
def <=(other)
|
293
|
+
@date <= other.date
|
294
|
+
end
|
295
|
+
|
296
|
+
#
|
297
|
+
# 大小比較する(==)
|
298
|
+
#
|
299
|
+
# @param [Calendar] other 年月日情報(西暦)
|
300
|
+
#
|
301
|
+
# @return [True] 等しい(現在日である)
|
302
|
+
# @return [False] 等しくない(過去日/未来日である)
|
303
|
+
#
|
304
|
+
def ==(other)
|
305
|
+
@date == other.date
|
306
|
+
end
|
307
|
+
|
308
|
+
#
|
309
|
+
# 年を取得する
|
310
|
+
#
|
311
|
+
# @return [Integer] 年
|
312
|
+
#
|
313
|
+
def year
|
314
|
+
@date.year
|
315
|
+
end
|
316
|
+
|
317
|
+
#
|
318
|
+
# 月を取得する
|
319
|
+
#
|
320
|
+
# @return [Integer] 月
|
321
|
+
#
|
322
|
+
def month
|
323
|
+
@date.month
|
324
|
+
end
|
325
|
+
|
326
|
+
#
|
327
|
+
# 日を取得する
|
328
|
+
#
|
329
|
+
# @return [Integer] 日
|
330
|
+
#
|
331
|
+
def day
|
332
|
+
@date.day
|
333
|
+
end
|
334
|
+
|
335
|
+
#
|
336
|
+
# 次年にする
|
337
|
+
#
|
338
|
+
# @param [Integer] num 年数
|
339
|
+
#
|
340
|
+
# @return [Calendar] 年月日情報(西暦)
|
341
|
+
#
|
342
|
+
def next_year(num: 1)
|
343
|
+
@date = @date.next_year(num)
|
344
|
+
self
|
345
|
+
end
|
346
|
+
|
347
|
+
#
|
348
|
+
# 年月日をフォーマット化する
|
349
|
+
#
|
350
|
+
# @param [String] form フォーマット
|
351
|
+
#
|
352
|
+
# @return [String] 年月日情報
|
353
|
+
#
|
354
|
+
def format(form: '%Y-%m-%d')
|
355
|
+
@date.strftime(form)
|
356
|
+
end
|
357
|
+
|
358
|
+
#
|
359
|
+
# 年月日情報(西暦)を生成する
|
360
|
+
#
|
361
|
+
# @param [Date] date Ruby標準日付
|
362
|
+
#
|
363
|
+
# @return [Calendar] 年月日情報(西暦)
|
364
|
+
#
|
365
|
+
def self.create(date: Date.new)
|
366
|
+
type = Western.to_type(start: date.start)
|
367
|
+
Calendar.new(year: date.year, month: date.month,
|
368
|
+
day: date.day, type: type)
|
369
|
+
end
|
370
|
+
|
371
|
+
#
|
372
|
+
# 年月日情報(西暦)を生成する
|
373
|
+
#
|
374
|
+
# @param [String] str 日付文字列
|
375
|
+
# @param [Symbol] type 日付種別
|
376
|
+
#
|
377
|
+
# @return [Calendar] 年月日情報(西暦)
|
378
|
+
#
|
379
|
+
def self.parse(str: '', type: Type::DEFAULT)
|
380
|
+
unless Calendar.valid_date_string(str: str, type: type)
|
381
|
+
raise ArgumentError, "invalid date string: #{str}"
|
382
|
+
end
|
383
|
+
|
384
|
+
start = DATE_START.fetch(type, DATE_START[Type::DEFAULT])
|
385
|
+
date = Date.parse(str, start)
|
386
|
+
|
387
|
+
Calendar.new(
|
388
|
+
year: date.year, month: date.month, day: date.day, type: type
|
389
|
+
)
|
390
|
+
end
|
391
|
+
|
392
|
+
#
|
393
|
+
# 日付文字列を検証する
|
394
|
+
#
|
395
|
+
# @param [String] str 日付文字列
|
396
|
+
# @param [Symbol] type 日付種別
|
397
|
+
#
|
398
|
+
# @return [True] 正しい
|
399
|
+
# @return [True] 正しくない
|
400
|
+
#
|
401
|
+
def self.valid_date_string(str: '', type: Type::DEFAULT)
|
402
|
+
start = DATE_START.fetch(type, DATE_START[Type::DEFAULT])
|
403
|
+
begin
|
404
|
+
Date.parse(str, start)
|
405
|
+
rescue ArgumentError => _e
|
406
|
+
false
|
407
|
+
end
|
408
|
+
true
|
409
|
+
end
|
410
|
+
end
|
411
|
+
end
|
412
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative './version_factory'
|
4
|
+
require_relative './condition'
|
5
|
+
|
6
|
+
# :nodoc:
|
7
|
+
module Zakuro
|
8
|
+
#
|
9
|
+
# Merchant ざくろ商人
|
10
|
+
# 東西の暦を取引する
|
11
|
+
#
|
12
|
+
class Merchant
|
13
|
+
# @return [Hash<Symbol, Object>] 条件
|
14
|
+
attr_reader :condition
|
15
|
+
|
16
|
+
#
|
17
|
+
# 初期化
|
18
|
+
#
|
19
|
+
# @param [Hash<Symbol, Object>] condition 条件
|
20
|
+
#
|
21
|
+
def initialize(condition: {})
|
22
|
+
failed = Condition.validate(hash: condition)
|
23
|
+
raise ZakuroError, failed.join('\n') unless failed.empty?
|
24
|
+
|
25
|
+
@condition = Condition.new(hash: condition)
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# 条件提示する
|
30
|
+
#
|
31
|
+
# @param [Hash<Symbol, Object>] condition 条件
|
32
|
+
#
|
33
|
+
# @return [Merchant] 自インスタンス
|
34
|
+
#
|
35
|
+
def offer(condition: {})
|
36
|
+
failed = Condition.validate(hash: condition)
|
37
|
+
raise ZakuroError, failed.join('\n') unless failed.empty?
|
38
|
+
|
39
|
+
@condition.rewrite(hash: condition)
|
40
|
+
|
41
|
+
self
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# 承諾する
|
46
|
+
#
|
47
|
+
# @return [Result::SingleDay] 和暦日
|
48
|
+
#
|
49
|
+
def commit
|
50
|
+
date = condition.date
|
51
|
+
return VersionFactory.to_japan_date(western_date: date) if date
|
52
|
+
|
53
|
+
# TODO: does not have no patterns now
|
54
|
+
{}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|