calendarium-romanum 0.2.1 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/calendariumrom +4 -1
- data/config/locales/cs.yml +54 -2
- data/config/locales/en.yml +64 -14
- data/config/locales/es.yml +90 -0
- data/config/locales/fr.yml +90 -0
- data/config/locales/it.yml +54 -4
- data/config/locales/la.yml +52 -2
- data/data/README.md +105 -5
- data/data/czech-brno-cs.txt +11 -5
- data/data/czech-budejovice-cs.txt +11 -5
- data/data/czech-cechy-cs.txt +11 -5
- data/data/czech-cs.txt +243 -234
- data/data/czech-hradec-cs.txt +10 -4
- data/data/czech-litomerice-cs.txt +12 -6
- data/data/czech-morava-cs.txt +11 -5
- data/data/czech-olomouc-cs.txt +9 -3
- data/data/czech-ostrava-cs.txt +10 -4
- data/data/czech-plzen-cs.txt +10 -4
- data/data/czech-praha-cs.txt +10 -3
- data/data/universal-en.txt +218 -212
- data/data/universal-es.txt +243 -0
- data/data/universal-fr.txt +243 -0
- data/data/universal-it.txt +218 -212
- data/data/universal-la.txt +218 -211
- data/lib/calendarium-romanum.rb +30 -18
- data/lib/calendarium-romanum/abstract_date.rb +12 -0
- data/lib/calendarium-romanum/calendar.rb +210 -48
- data/lib/calendarium-romanum/cli.rb +101 -52
- data/lib/calendarium-romanum/cr.rb +16 -0
- data/lib/calendarium-romanum/data.rb +46 -18
- data/lib/calendarium-romanum/day.rb +200 -21
- data/lib/calendarium-romanum/enum.rb +24 -5
- data/lib/calendarium-romanum/enums.rb +123 -37
- data/lib/calendarium-romanum/errors.rb +4 -0
- data/lib/calendarium-romanum/ordinalizer.rb +61 -0
- data/lib/calendarium-romanum/perpetual_calendar.rb +97 -0
- data/lib/calendarium-romanum/rank.rb +43 -6
- data/lib/calendarium-romanum/sanctorale.rb +142 -22
- data/lib/calendarium-romanum/sanctorale_factory.rb +74 -3
- data/lib/calendarium-romanum/sanctorale_loader.rb +176 -0
- data/lib/calendarium-romanum/temporale.rb +296 -251
- data/lib/calendarium-romanum/temporale/celebration_factory.rb +106 -0
- data/lib/calendarium-romanum/temporale/dates.rb +232 -0
- data/lib/calendarium-romanum/temporale/extensions/christ_eternal_priest.rb +37 -0
- data/lib/calendarium-romanum/transfers.rb +43 -6
- data/lib/calendarium-romanum/util.rb +36 -3
- data/lib/calendarium-romanum/version.rb +5 -1
- data/spec/abstract_date_spec.rb +11 -3
- data/spec/calendar_spec.rb +645 -188
- data/spec/celebration_factory_spec.rb +40 -0
- data/spec/celebration_spec.rb +67 -0
- data/spec/cli_spec.rb +154 -11
- data/spec/colour_spec.rb +22 -0
- data/spec/data_spec.rb +26 -3
- data/spec/date_parser_spec.rb +68 -0
- data/spec/date_spec.rb +8 -8
- data/spec/dates_spec.rb +73 -0
- data/spec/day_spec.rb +151 -0
- data/spec/i18n_spec.rb +11 -2
- data/spec/ordinalizer_spec.rb +44 -0
- data/spec/perpetual_calendar_spec.rb +125 -0
- data/spec/rank_spec.rb +42 -7
- data/spec/readme_spec.rb +18 -10
- data/spec/sanctorale_factory_spec.rb +113 -9
- data/spec/sanctorale_loader_spec.rb +229 -0
- data/spec/sanctorale_spec.rb +176 -62
- data/spec/season_spec.rb +22 -0
- data/spec/spec_helper.rb +27 -1
- data/spec/temporale_spec.rb +473 -154
- data/spec/year_spec.rb +25 -0
- metadata +42 -7
- data/lib/calendarium-romanum/sanctoraleloader.rb +0 -104
- data/spec/sanctoraleloader_spec.rb +0 -171
@@ -0,0 +1,106 @@
|
|
1
|
+
module CalendariumRomanum
|
2
|
+
class Temporale
|
3
|
+
# Provides factory methods building {Celebration}s
|
4
|
+
# for temporale feasts
|
5
|
+
class CelebrationFactory
|
6
|
+
class << self
|
7
|
+
# @yield [Symbol]
|
8
|
+
# @return [void, Enumerator]
|
9
|
+
def each
|
10
|
+
return to_enum(__method__) unless block_given?
|
11
|
+
|
12
|
+
celebrations.each do |symbol|
|
13
|
+
yield public_send(symbol)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Celebration]
|
18
|
+
def first_advent_sunday
|
19
|
+
Temporale.create_celebration(
|
20
|
+
I18n.t('temporale.advent.sunday', week: Ordinalizer.ordinal(1)),
|
21
|
+
Ranks::PRIMARY,
|
22
|
+
Colours::VIOLET
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def celebrations
|
29
|
+
@celebrations ||= [:first_advent_sunday]
|
30
|
+
end
|
31
|
+
|
32
|
+
def celebration(symbol, rank, colour = Colours::WHITE, fixed_date: false)
|
33
|
+
define_singleton_method(symbol) do
|
34
|
+
Temporale.create_celebration(
|
35
|
+
proc { I18n.t("temporale.solemnity.#{symbol}") },
|
36
|
+
rank,
|
37
|
+
colour,
|
38
|
+
symbol: symbol,
|
39
|
+
date: fixed_date
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
celebrations << symbol
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Celebration]
|
48
|
+
# @!scope class
|
49
|
+
celebration(:nativity, Ranks::PRIMARY, fixed_date: AbstractDate.new(12, 25))
|
50
|
+
# @return [Celebration]
|
51
|
+
# @!scope class
|
52
|
+
celebration(:holy_family, Ranks::FEAST_LORD_GENERAL)
|
53
|
+
# @return [Celebration]
|
54
|
+
# @!scope class
|
55
|
+
celebration(:mother_of_god, Ranks::SOLEMNITY_GENERAL, fixed_date: AbstractDate.new(1, 1))
|
56
|
+
# @return [Celebration]
|
57
|
+
# @!scope class
|
58
|
+
celebration(:epiphany, Ranks::PRIMARY)
|
59
|
+
# @return [Celebration]
|
60
|
+
# @!scope class
|
61
|
+
celebration(:baptism_of_lord, Ranks::FEAST_LORD_GENERAL)
|
62
|
+
# @return [Celebration]
|
63
|
+
# @!scope class
|
64
|
+
celebration(:ash_wednesday, Ranks::PRIMARY, Colours::VIOLET)
|
65
|
+
# @return [Celebration]
|
66
|
+
# @!scope class
|
67
|
+
celebration(:good_friday, Ranks::TRIDUUM, Colours::RED)
|
68
|
+
# @return [Celebration]
|
69
|
+
# @!scope class
|
70
|
+
celebration(:holy_saturday, Ranks::TRIDUUM, Colours::VIOLET)
|
71
|
+
# @return [Celebration]
|
72
|
+
# @!scope class
|
73
|
+
celebration(:palm_sunday, Ranks::PRIMARY, Colours::RED)
|
74
|
+
# @return [Celebration]
|
75
|
+
# @!scope class
|
76
|
+
celebration(:easter_sunday, Ranks::TRIDUUM)
|
77
|
+
# @return [Celebration]
|
78
|
+
# @!scope class
|
79
|
+
celebration(:ascension, Ranks::PRIMARY)
|
80
|
+
# @return [Celebration]
|
81
|
+
# @!scope class
|
82
|
+
celebration(:pentecost, Ranks::PRIMARY, Colours::RED)
|
83
|
+
# @return [Celebration]
|
84
|
+
# @!scope class
|
85
|
+
celebration(:holy_trinity, Ranks::SOLEMNITY_GENERAL)
|
86
|
+
# @return [Celebration]
|
87
|
+
# @!scope class
|
88
|
+
celebration(:corpus_christi, Ranks::SOLEMNITY_GENERAL)
|
89
|
+
# @return [Celebration]
|
90
|
+
# @!scope class
|
91
|
+
celebration(:sacred_heart, Ranks::SOLEMNITY_GENERAL)
|
92
|
+
# @return [Celebration]
|
93
|
+
# @!scope class
|
94
|
+
celebration(:christ_king, Ranks::SOLEMNITY_GENERAL)
|
95
|
+
# @return [Celebration]
|
96
|
+
# @!scope class
|
97
|
+
celebration(:mother_of_church, Ranks::MEMORIAL_GENERAL)
|
98
|
+
# @return [Celebration]
|
99
|
+
# @!scope class
|
100
|
+
celebration(:immaculate_heart, Ranks::MEMORIAL_GENERAL)
|
101
|
+
# @return [Celebration]
|
102
|
+
# @!scope class
|
103
|
+
celebration(:saturday_memorial_bvm, Ranks::MEMORIAL_OPTIONAL)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,232 @@
|
|
1
|
+
module CalendariumRomanum
|
2
|
+
class Temporale
|
3
|
+
# Provides methods computing dates of movable feasts
|
4
|
+
# and utilities for common computations of relative dates
|
5
|
+
module Dates
|
6
|
+
# (see .nativity)
|
7
|
+
def self.first_advent_sunday(year)
|
8
|
+
sunday_before(nativity(year)) - 3 * WEEK
|
9
|
+
end
|
10
|
+
|
11
|
+
# @param year [Fixnum] liturgical year
|
12
|
+
# @return [Date]
|
13
|
+
def self.nativity(year)
|
14
|
+
Date.new(year, 12, 25)
|
15
|
+
end
|
16
|
+
|
17
|
+
# (see .nativity)
|
18
|
+
def self.holy_family(year)
|
19
|
+
xmas = nativity(year)
|
20
|
+
if xmas.sunday?
|
21
|
+
return Date.new(year, 12, 30)
|
22
|
+
else
|
23
|
+
sunday_after(xmas)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# (see .nativity)
|
28
|
+
def self.mother_of_god(year)
|
29
|
+
octave_of(nativity(year))
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param year [Fixnum] liturgical year
|
33
|
+
# @param sunday [Boolean] transfer to Sunday?
|
34
|
+
# @return [Date]
|
35
|
+
def self.epiphany(year, sunday: false)
|
36
|
+
if sunday
|
37
|
+
# GNLYC 7 a)
|
38
|
+
return sunday_after(Date.new(year + 1, 1, 1))
|
39
|
+
end
|
40
|
+
|
41
|
+
Date.new(year + 1, 1, 6)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param year [Fixnum] liturgical year
|
45
|
+
# @param epiphany_on_sunday [Boolean] was Epiphany transferred to Sunday?
|
46
|
+
# @return [Date]
|
47
|
+
def self.baptism_of_lord(year, epiphany_on_sunday: false)
|
48
|
+
e = epiphany(year, sunday: epiphany_on_sunday)
|
49
|
+
if epiphany_on_sunday
|
50
|
+
e + 1
|
51
|
+
else
|
52
|
+
sunday_after e
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# (see .nativity)
|
57
|
+
def self.ash_wednesday(year)
|
58
|
+
easter_sunday(year) - (6 * WEEK + 4)
|
59
|
+
end
|
60
|
+
|
61
|
+
# (see .nativity)
|
62
|
+
def self.easter_sunday(year)
|
63
|
+
year += 1
|
64
|
+
|
65
|
+
# algorithm below taken from the 'easter' gem:
|
66
|
+
# https://github.com/jrobertson/easter
|
67
|
+
|
68
|
+
golden_number = (year % 19) + 1
|
69
|
+
dominical_number = (year + (year / 4) - (year / 100) + (year / 400)) % 7
|
70
|
+
solar_correction = (year - 1600) / 100 - (year - 1600) / 400
|
71
|
+
lunar_correction = (((year - 1400) / 100) * 8) / 25
|
72
|
+
paschal_full_moon = (3 - 11 * golden_number + solar_correction - lunar_correction) % 30
|
73
|
+
dominical_number += 7 until dominical_number > 0
|
74
|
+
paschal_full_moon += 30 until paschal_full_moon > 0
|
75
|
+
paschal_full_moon -= 1 if (paschal_full_moon == 29) || ((paschal_full_moon == 28) && golden_number > 11)
|
76
|
+
difference = (4 - paschal_full_moon - dominical_number) % 7
|
77
|
+
difference += 7 if difference < 0
|
78
|
+
day_easter = paschal_full_moon + difference + 1
|
79
|
+
if day_easter < 11
|
80
|
+
# Easter occurs in March.
|
81
|
+
return Date.new(year, 3, day_easter + 21)
|
82
|
+
else
|
83
|
+
# Easter occurs in April.
|
84
|
+
return Date.new(year, 4, day_easter - 10)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# (see .nativity)
|
89
|
+
def self.palm_sunday(year)
|
90
|
+
easter_sunday(year) - 7
|
91
|
+
end
|
92
|
+
|
93
|
+
# (see .nativity)
|
94
|
+
def self.good_friday(year)
|
95
|
+
easter_sunday(year) - 2
|
96
|
+
end
|
97
|
+
|
98
|
+
# (see .nativity)
|
99
|
+
def self.holy_saturday(year)
|
100
|
+
easter_sunday(year) - 1
|
101
|
+
end
|
102
|
+
|
103
|
+
# (see .epiphany)
|
104
|
+
def self.ascension(year, sunday: false)
|
105
|
+
if sunday
|
106
|
+
# GNLYC 7 b)
|
107
|
+
return easter_sunday(year) + 6 * WEEK
|
108
|
+
end
|
109
|
+
|
110
|
+
pentecost(year) - 10
|
111
|
+
end
|
112
|
+
|
113
|
+
# (see .nativity)
|
114
|
+
def self.pentecost(year)
|
115
|
+
easter_sunday(year) + 7 * WEEK
|
116
|
+
end
|
117
|
+
|
118
|
+
# (see .nativity)
|
119
|
+
def self.holy_trinity(year)
|
120
|
+
octave_of(pentecost(year))
|
121
|
+
end
|
122
|
+
|
123
|
+
# (see .epiphany)
|
124
|
+
def self.corpus_christi(year, sunday: false)
|
125
|
+
if sunday
|
126
|
+
# GNLYC 7 c)
|
127
|
+
return holy_trinity(year) + WEEK
|
128
|
+
end
|
129
|
+
|
130
|
+
holy_trinity(year) + 4
|
131
|
+
end
|
132
|
+
|
133
|
+
# (see .nativity)
|
134
|
+
def self.sacred_heart(year)
|
135
|
+
corpus_christi(year) + 8
|
136
|
+
end
|
137
|
+
|
138
|
+
# (see .nativity)
|
139
|
+
def self.mother_of_church(year)
|
140
|
+
pentecost(year) + 1
|
141
|
+
end
|
142
|
+
|
143
|
+
# (see .nativity)
|
144
|
+
def self.immaculate_heart(year)
|
145
|
+
pentecost(year) + 20
|
146
|
+
end
|
147
|
+
|
148
|
+
# (see .nativity)
|
149
|
+
def self.christ_king(year)
|
150
|
+
first_advent_sunday(year + 1) - 7
|
151
|
+
end
|
152
|
+
|
153
|
+
# utility methods
|
154
|
+
|
155
|
+
# @param weekday [Fixnum]
|
156
|
+
# @param date [Date]
|
157
|
+
# @return [Date]
|
158
|
+
def self.weekday_before(weekday, date)
|
159
|
+
if date.wday == weekday
|
160
|
+
date - WEEK
|
161
|
+
elsif weekday < date.wday
|
162
|
+
date - (date.wday - weekday)
|
163
|
+
else
|
164
|
+
date - (date.wday + WEEK - weekday)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# (see .weekday_before)
|
169
|
+
def self.weekday_after(weekday, date)
|
170
|
+
if date.wday == weekday
|
171
|
+
date + WEEK
|
172
|
+
elsif weekday > date.wday
|
173
|
+
date + (weekday - date.wday)
|
174
|
+
else
|
175
|
+
date + (WEEK - date.wday + weekday)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# @param date [Date]
|
180
|
+
# @return [Date]
|
181
|
+
def self.octave_of(date)
|
182
|
+
date + WEEK
|
183
|
+
end
|
184
|
+
|
185
|
+
class << self
|
186
|
+
# @!method sunday_before(date)
|
187
|
+
# @param date [Date]
|
188
|
+
# @return [Date]
|
189
|
+
# @!method monday_before(date)
|
190
|
+
# (see .sunday_before)
|
191
|
+
# @!method tuesday_before(date)
|
192
|
+
# (see .sunday_before)
|
193
|
+
# @!method wednesday_before(date)
|
194
|
+
# (see .sunday_before)
|
195
|
+
# @!method thursday_before(date)
|
196
|
+
# (see .sunday_before)
|
197
|
+
# @!method friday_before(date)
|
198
|
+
# (see .sunday_before)
|
199
|
+
# @!method saturday_before(date)
|
200
|
+
# (see .sunday_before)
|
201
|
+
|
202
|
+
# @!method sunday_after(date)
|
203
|
+
# @param date [Date]
|
204
|
+
# @return [Date]
|
205
|
+
# @!method monday_after(date)
|
206
|
+
# (see .sunday_after)
|
207
|
+
# @!method tuesday_after(date)
|
208
|
+
# (see .sunday_after)
|
209
|
+
# @!method wednesday_after(date)
|
210
|
+
# (see .sunday_after)
|
211
|
+
# @!method thursday_after(date)
|
212
|
+
# (see .sunday_after)
|
213
|
+
# @!method friday_after(date)
|
214
|
+
# (see .sunday_after)
|
215
|
+
# @!method saturday_after(date)
|
216
|
+
# (see .sunday_after)
|
217
|
+
|
218
|
+
# @api private
|
219
|
+
WEEKDAYS = %w(sunday monday tuesday wednesday thursday friday saturday).freeze
|
220
|
+
WEEKDAYS.each_with_index do |weekday, weekday_i|
|
221
|
+
define_method "#{weekday}_before" do |date|
|
222
|
+
send('weekday_before', weekday_i, date)
|
223
|
+
end
|
224
|
+
|
225
|
+
define_method "#{weekday}_after" do |date|
|
226
|
+
send('weekday_after', weekday_i, date)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module CalendariumRomanum
|
2
|
+
class Temporale
|
3
|
+
module Extensions
|
4
|
+
# {Temporale} extension adding the movable feast
|
5
|
+
# of "Christ Eternal Priests",
|
6
|
+
# included in some local calendars
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# temporale = Temporale.new(2015, extensions: [
|
10
|
+
# Temporale::Extensions::ChristEternalPriest
|
11
|
+
# ])
|
12
|
+
module ChristEternalPriest
|
13
|
+
# @yield [Symbol, Celebration]
|
14
|
+
# @return [void]
|
15
|
+
def self.each_celebration
|
16
|
+
yield(
|
17
|
+
# symbol refers to the date-computing method
|
18
|
+
:christ_eternal_priest,
|
19
|
+
Celebration.new(
|
20
|
+
proc { I18n.t('temporale.extension.christ_eternal_priest') },
|
21
|
+
Ranks::FEAST_PROPER,
|
22
|
+
Colours::WHITE
|
23
|
+
)
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
# Computes the feast's date
|
28
|
+
#
|
29
|
+
# @param year [Fixnum] liturgical year
|
30
|
+
# @return [Date]
|
31
|
+
def self.christ_eternal_priest(year)
|
32
|
+
Dates.pentecost(year) + 4
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,12 +1,29 @@
|
|
1
1
|
module CalendariumRomanum
|
2
2
|
|
3
|
-
#
|
3
|
+
# Internal {Calendar} component.
|
4
|
+
# Resolves transfers of conflicting solemnities.
|
5
|
+
#
|
6
|
+
# For any day {Temporale} has a {Celebration}.
|
7
|
+
# Often {Sanctorale} has one (or more), too.
|
8
|
+
# {Calendar} handles these conflicts, in most cases
|
9
|
+
# by throwing away all the proposed {Celebration}s except
|
10
|
+
# of the one of highest rank.
|
11
|
+
# But when there are two conflicting _solemnities_,
|
12
|
+
# one is celebrated on the given day and the less lucky one
|
13
|
+
# must be transferred to another day.
|
14
|
+
# However, not all days are valid as targets of solemnity transfer.
|
15
|
+
#
|
16
|
+
# @api private
|
4
17
|
class Transfers
|
18
|
+
# @param temporale [Temporale]
|
19
|
+
# @param sanctorale [Sanctorale]
|
5
20
|
def initialize(temporale, sanctorale)
|
6
21
|
@transferred = {}
|
22
|
+
@temporale = temporale
|
23
|
+
@sanctorale = sanctorale
|
7
24
|
|
8
25
|
dates = sanctorale.solemnities.keys.collect do |abstract_date|
|
9
|
-
|
26
|
+
concretize_abstract_date abstract_date
|
10
27
|
end.sort
|
11
28
|
|
12
29
|
dates.each do |date|
|
@@ -21,24 +38,44 @@ module CalendariumRomanum
|
|
21
38
|
transfer_to = date
|
22
39
|
begin
|
23
40
|
transfer_to = transfer_to.succ
|
24
|
-
end until valid_destination?(transfer_to
|
41
|
+
end until valid_destination?(transfer_to)
|
25
42
|
@transferred[transfer_to] = loser
|
26
43
|
end
|
27
44
|
end
|
28
45
|
|
46
|
+
# Retrieve solemnity for the specified day
|
47
|
+
#
|
48
|
+
# @param date [Date]
|
49
|
+
# @return [Celebration, nil]
|
29
50
|
def get(date)
|
30
51
|
@transferred[date]
|
31
52
|
end
|
32
53
|
|
33
54
|
private
|
34
55
|
|
35
|
-
def valid_destination?(day
|
36
|
-
return false if temporale.get(day).rank >= Ranks::FEAST_PROPER
|
56
|
+
def valid_destination?(day)
|
57
|
+
return false if @temporale.get(day).rank >= Ranks::FEAST_PROPER
|
37
58
|
|
38
|
-
sc = sanctorale.get(day)
|
59
|
+
sc = @sanctorale.get(day)
|
39
60
|
return false if sc.size > 0 && sc.first.rank >= Ranks::FEAST_PROPER
|
40
61
|
|
41
62
|
true
|
42
63
|
end
|
64
|
+
|
65
|
+
# Converts an AbstractDate to a Date in the given
|
66
|
+
# liturgical year.
|
67
|
+
# It isn't guaranteed to work well (and probably doesn't work well)
|
68
|
+
# for the grey zone of dates between earliest and latest
|
69
|
+
# possible date of the first Advent Sunday, but that's no problem
|
70
|
+
# as long as there are no sanctorale solemnities in this
|
71
|
+
# date range.
|
72
|
+
def concretize_abstract_date(abstract_date)
|
73
|
+
d = abstract_date.concretize(@temporale.year + 1)
|
74
|
+
if @temporale.date_range.include? d
|
75
|
+
d
|
76
|
+
else
|
77
|
+
abstract_date.concretize(@temporale.year)
|
78
|
+
end
|
79
|
+
end
|
43
80
|
end
|
44
81
|
end
|