line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package DateTime::Calendar::Hebrew; |
2
|
12
|
|
|
12
|
|
33207
|
use DateTime; |
|
12
|
|
|
|
|
3789017
|
|
|
12
|
|
|
|
|
645
|
|
3
|
12
|
|
|
12
|
|
136
|
use Params::Validate qw/validate SCALAR OBJECT CODEREF/; |
|
12
|
|
|
|
|
25
|
|
|
12
|
|
|
|
|
1002
|
|
4
|
|
|
|
|
|
|
|
5
|
12
|
|
|
12
|
|
68
|
use vars qw($VERSION); |
|
12
|
|
|
|
|
25
|
|
|
12
|
|
|
|
|
634
|
|
6
|
|
|
|
|
|
|
$VERSION = '0.05'; |
7
|
12
|
|
|
12
|
|
319
|
use 5.010_000; |
|
12
|
|
|
|
|
45
|
|
|
12
|
|
|
|
|
389
|
|
8
|
|
|
|
|
|
|
|
9
|
12
|
|
|
12
|
|
61
|
use strict; |
|
12
|
|
|
|
|
18
|
|
|
12
|
|
|
|
|
373
|
|
10
|
12
|
|
|
12
|
|
54
|
no strict 'refs'; |
|
12
|
|
|
|
|
22
|
|
|
12
|
|
|
|
|
353
|
|
11
|
|
|
|
|
|
|
|
12
|
12
|
|
|
12
|
|
59
|
use constant HEBREW_EPOCH => -1373429; |
|
12
|
|
|
|
|
19
|
|
|
12
|
|
|
|
|
1014
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use overload |
15
|
12
|
|
|
|
|
104
|
fallback => 1, |
16
|
|
|
|
|
|
|
'<=>' => '_compare_overload', |
17
|
|
|
|
|
|
|
'cmp' => '_compare_overload', |
18
|
|
|
|
|
|
|
'+' => '_add_overload', |
19
|
12
|
|
|
12
|
|
82
|
'-' => '_subtract_overload'; |
|
12
|
|
|
|
|
22
|
|
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub new { |
22
|
12
|
|
|
12
|
1
|
2317
|
my $class = shift; |
23
|
|
|
|
|
|
|
my %p = validate( @_, |
24
|
|
|
|
|
|
|
{ year => { type => SCALAR }, |
25
|
|
|
|
|
|
|
month => { type => SCALAR, default => 1, |
26
|
|
|
|
|
|
|
callbacks => { |
27
|
|
|
|
|
|
|
'is between 1 and 13' => |
28
|
12
|
50
|
|
12
|
|
320
|
sub { $_[0] >= 1 && $_[0] <= 13 } |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
}, |
31
|
|
|
|
|
|
|
day => { type => SCALAR, default => 1, |
32
|
|
|
|
|
|
|
callbacks => { |
33
|
|
|
|
|
|
|
'is between 1 and 30' => |
34
|
12
|
50
|
|
12
|
|
212
|
sub { $_[0] >= 1 && $_[0] <= 30 } |
35
|
|
|
|
|
|
|
} |
36
|
|
|
|
|
|
|
}, |
37
|
|
|
|
|
|
|
hour => { type => SCALAR, default => 0, |
38
|
|
|
|
|
|
|
callbacks => { |
39
|
|
|
|
|
|
|
'is between 0 and 23' => |
40
|
8
|
50
|
|
8
|
|
134
|
sub { $_[0] >= 0 && $_[0] <= 23 } |
41
|
|
|
|
|
|
|
} |
42
|
|
|
|
|
|
|
}, |
43
|
|
|
|
|
|
|
minute => { type => SCALAR, default => 0, |
44
|
|
|
|
|
|
|
callbacks => { |
45
|
|
|
|
|
|
|
'is between 0 and 59' => |
46
|
8
|
50
|
|
8
|
|
111
|
sub { $_[0] >= 0 && $_[0] <= 59 } |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
}, |
49
|
|
|
|
|
|
|
second => { type => SCALAR, default => 0, |
50
|
|
|
|
|
|
|
callbacks => { |
51
|
|
|
|
|
|
|
'is between 0 and 59' => |
52
|
5
|
50
|
|
5
|
|
99
|
sub { $_[0] >= 0 && $_[0] <= 59 } |
53
|
|
|
|
|
|
|
} |
54
|
|
|
|
|
|
|
}, |
55
|
|
|
|
|
|
|
nanosecond => { type => SCALAR, default => 0, |
56
|
|
|
|
|
|
|
callbacks => { |
57
|
|
|
|
|
|
|
'is between 0 and 999999999' => |
58
|
4
|
50
|
|
4
|
|
69
|
sub { $_[0] >= 0 && $_[0] <= 999999999 } |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
}, |
61
|
12
|
|
|
|
|
1040
|
sunset => { type => OBJECT, optional => 1 }, |
62
|
|
|
|
|
|
|
time_zone => { type => SCALAR, optional => 1 }, |
63
|
|
|
|
|
|
|
} ); |
64
|
|
|
|
|
|
|
|
65
|
12
|
|
|
|
|
285
|
my $self = bless \%p, $class; |
66
|
|
|
|
|
|
|
|
67
|
12
|
|
|
|
|
70
|
$self->{rd_days} = &_to_rd(@p{ qw(year month day) }); |
68
|
12
|
|
|
|
|
59
|
$self->{rd_secs} = $p{hour} * 60 * 60 + $p{minute} * 60 + $p{second}; |
69
|
12
|
100
|
|
|
|
62
|
if($self->{nanosecond}) { $self->{rd_nanosecs} = delete $self->{nanosecond}; } |
|
1
|
|
|
|
|
3
|
|
70
|
|
|
|
|
|
|
|
71
|
12
|
100
|
66
|
|
|
92
|
if($self->{sunset} and $self->{time_zone}) { |
72
|
2
|
|
|
|
|
15
|
my $DT_Event_Sunrise = $self->{sunset}; |
73
|
2
|
|
|
|
|
4
|
my $time_zone = $self->{time_zone}; |
74
|
2
|
|
|
|
|
20
|
my $DT = DateTime->from_object(object => $self); |
75
|
|
|
|
|
|
|
|
76
|
2
|
|
|
|
|
292
|
my $sunset = $DT_Event_Sunrise->next($DT->clone->truncate(to => 'day')); |
77
|
2
|
|
|
|
|
4620
|
$sunset->set_time_zone($time_zone); |
78
|
|
|
|
|
|
|
|
79
|
2
|
50
|
|
|
|
60914
|
if($DT > $sunset) { |
80
|
2
|
|
|
|
|
774
|
$self->{after_sunset} = 1; |
81
|
2
|
|
|
|
|
19
|
@{$self}{qw/year month day/} = &_from_rd($self->{rd_days} + 1); |
|
2
|
|
|
|
|
22
|
|
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
12
|
|
|
|
|
81
|
return $self; |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
sub from_object { |
89
|
3
|
|
|
3
|
1
|
425
|
my ( $class ) = shift; |
90
|
3
|
|
|
|
|
61
|
my %p = validate( @_, { |
91
|
|
|
|
|
|
|
object => { |
92
|
|
|
|
|
|
|
type => OBJECT, |
93
|
|
|
|
|
|
|
can => 'utc_rd_values', |
94
|
|
|
|
|
|
|
}, |
95
|
|
|
|
|
|
|
}); |
96
|
|
|
|
|
|
|
|
97
|
3
|
|
|
|
|
179
|
my $object = $p{object}->clone(); |
98
|
3
|
50
|
|
|
|
64
|
$object->set_time_zone('floating') if $object->can( 'set_time_zone' ); |
99
|
|
|
|
|
|
|
|
100
|
3
|
|
|
|
|
434
|
my ($rd_days, $rd_secs, $rd_nanosecs) = $object->utc_rd_values(); |
101
|
3
|
|
50
|
|
|
45
|
$rd_nanosecs ||= 0; |
102
|
|
|
|
|
|
|
|
103
|
3
|
|
|
|
|
60
|
my %args; |
104
|
3
|
|
|
|
|
16
|
@args{ qw( year month day ) } = &_from_rd($rd_days); |
105
|
|
|
|
|
|
|
|
106
|
3
|
|
|
|
|
6
|
my($h, $m, $s); |
107
|
3
|
|
|
|
|
6
|
$s = $rd_secs % 60; |
108
|
3
|
|
|
|
|
10
|
$m = int($rd_secs / 60); |
109
|
3
|
|
|
|
|
7
|
$h = int($m / 60); |
110
|
3
|
|
|
|
|
4
|
$m %= 60; |
111
|
3
|
|
|
|
|
13
|
@args{ qw(hour minute second) } = ($h, $m, $s); |
112
|
|
|
|
|
|
|
|
113
|
3
|
|
50
|
|
|
21
|
$args{nanosecond} = $rd_nanosecs || 0; |
114
|
|
|
|
|
|
|
|
115
|
3
|
|
|
|
|
25
|
my $new_object = $class->new(%args); |
116
|
|
|
|
|
|
|
|
117
|
3
|
|
|
|
|
44
|
return $new_object; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
sub set { |
121
|
1
|
|
|
1
|
1
|
9
|
my $self = shift; |
122
|
|
|
|
|
|
|
my %p = validate( @_, |
123
|
|
|
|
|
|
|
{ year => { type => SCALAR, optional => 1 }, |
124
|
|
|
|
|
|
|
month => { type => SCALAR, optional => 1, |
125
|
|
|
|
|
|
|
callbacks => { |
126
|
|
|
|
|
|
|
'is between 1 and 13' => |
127
|
1
|
50
|
|
1
|
|
11
|
sub { $_[0] >= 1 && $_[0] <= 13 } |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
}, |
130
|
|
|
|
|
|
|
day => { type => SCALAR, optional => 1, |
131
|
|
|
|
|
|
|
callbacks => { |
132
|
|
|
|
|
|
|
'is between 1 and 30' => |
133
|
1
|
50
|
|
1
|
|
20
|
sub { $_[0] >= 1 && $_[0] <= 30 } |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
}, |
136
|
|
|
|
|
|
|
hour => { type => SCALAR, optional => 1, |
137
|
|
|
|
|
|
|
callbacks => { |
138
|
|
|
|
|
|
|
'is between 0 and 23' => |
139
|
1
|
50
|
|
1
|
|
18
|
sub { $_[0] >= 0 && $_[0] <= 23 } |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
}, |
142
|
|
|
|
|
|
|
minute => { type => SCALAR, optional => 1, |
143
|
|
|
|
|
|
|
callbacks => { |
144
|
|
|
|
|
|
|
'is between 0 and 59' => |
145
|
1
|
50
|
|
1
|
|
17
|
sub { $_[0] >= 0 && $_[0] <= 59 } |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
}, |
148
|
|
|
|
|
|
|
second => { type => SCALAR, optional => 1, |
149
|
|
|
|
|
|
|
callbacks => { |
150
|
|
|
|
|
|
|
'is between 0 and 59' => |
151
|
1
|
50
|
|
1
|
|
15
|
sub { $_[0] >= 0 && $_[0] <= 59 } |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
}, |
154
|
|
|
|
|
|
|
nanosecond => { type => SCALAR, optional => 1, |
155
|
|
|
|
|
|
|
callbacks => { |
156
|
|
|
|
|
|
|
'is between 0 and 999999999' => |
157
|
0
|
0
|
|
0
|
|
0
|
sub { $_[0] >= 0 && $_[0] <= 999999999 } |
158
|
|
|
|
|
|
|
} |
159
|
|
|
|
|
|
|
}, |
160
|
1
|
|
|
|
|
70
|
sunset => { type => OBJECT, optional => 1 }, |
161
|
|
|
|
|
|
|
time_zone => { type => SCALAR, optional => 1 }, |
162
|
|
|
|
|
|
|
} ); |
163
|
|
|
|
|
|
|
|
164
|
1
|
|
|
|
|
27
|
$self->{$_} = $p{$_} for keys %p; |
165
|
|
|
|
|
|
|
|
166
|
1
|
|
|
|
|
6
|
$self->{rd_days} = &_to_rd($self->{year}, $self->{month}, $self->{day}); |
167
|
1
|
|
|
|
|
5
|
$self->{rd_secs} = $self->{hour} * 60 * 60 + $self->{minute} * 60 + $self->{second}; |
168
|
1
|
50
|
|
|
|
4
|
if($self->{nanosecond}) { $self->{rd_nanosecs} = delete $self->{nanosecond}; } |
|
0
|
|
|
|
|
0
|
|
169
|
|
|
|
|
|
|
|
170
|
1
|
50
|
33
|
|
|
4
|
if($self->{sunset} and $self->{time_zone}) { |
171
|
0
|
|
|
|
|
0
|
my $DT_Event_Sunrise = $self->{sunset}; |
172
|
0
|
|
|
|
|
0
|
my $time_zone = $self->{time_zone}; |
173
|
0
|
|
|
|
|
0
|
my $DT = DateTime->from_object(object => $self); |
174
|
|
|
|
|
|
|
|
175
|
0
|
|
|
|
|
0
|
my $sunset = $DT_Event_Sunrise->next($DT->clone->truncate(to => 'day')); |
176
|
0
|
|
|
|
|
0
|
$sunset->set_time_zone($time_zone); |
177
|
|
|
|
|
|
|
|
178
|
0
|
0
|
|
|
|
0
|
if($DT > $sunset) { |
179
|
0
|
|
|
|
|
0
|
$self->{after_sunset} = 1; |
180
|
0
|
|
|
|
|
0
|
@{$self}{qw/year month day/} = &_from_rd($self->{rd_days} + 1); |
|
0
|
|
|
|
|
0
|
|
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
|
184
|
1
|
|
|
|
|
5
|
return $self; |
185
|
|
|
|
|
|
|
} |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub utc_rd_values { |
188
|
15
|
|
|
15
|
1
|
163
|
my $self = shift; |
189
|
15
|
|
|
|
|
30
|
my @res = @{$self}{ qw/rd_days rd_secs rd_nanosecs/ }; |
|
15
|
|
|
|
|
50
|
|
190
|
|
|
|
|
|
|
# Protect against undef |
191
|
15
|
|
100
|
|
|
82
|
$res[2] ||= 0; |
192
|
15
|
|
|
|
|
53
|
return @res; |
193
|
|
|
|
|
|
|
} |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
sub utc_rd_as_seconds { |
196
|
2
|
|
|
2
|
1
|
9
|
my $self = shift; |
197
|
2
|
|
|
|
|
5
|
my ($rd_days, $rd_secs, $rd_nanosecs) = $self->utc_rd_values; |
198
|
|
|
|
|
|
|
|
199
|
2
|
|
|
|
|
7
|
return $rd_days*24*60*60 + $rd_secs; |
200
|
|
|
|
|
|
|
} |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
sub clone { |
203
|
9
|
|
|
9
|
1
|
397
|
my $self = shift; |
204
|
9
|
|
|
|
|
73
|
my $clone = {%$self}; |
205
|
9
|
|
|
|
|
33
|
bless $clone, ref $self; |
206
|
9
|
|
|
|
|
39
|
return $clone; |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
sub _compare_overload { |
210
|
4
|
50
|
|
4
|
|
63
|
return $_[2] ? - $_[0]->_compare($_[1]) : $_[0]->_compare($_[1]); |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub _compare { |
214
|
4
|
|
|
4
|
|
9
|
my($a, $b) = @_; |
215
|
|
|
|
|
|
|
|
216
|
4
|
50
|
|
|
|
12
|
return undef unless defined $b; |
217
|
|
|
|
|
|
|
|
218
|
4
|
50
|
33
|
|
|
57
|
unless($a->can('utc_rd_values') and $b->can('utc_rd_values')) { |
219
|
0
|
|
|
|
|
0
|
die "Cannot compare a datetime to a regular scalar"; |
220
|
|
|
|
|
|
|
} |
221
|
|
|
|
|
|
|
|
222
|
4
|
|
|
|
|
15
|
my @a = $a->utc_rd_values; |
223
|
4
|
|
|
|
|
12
|
my @b = $b->utc_rd_values; |
224
|
|
|
|
|
|
|
|
225
|
4
|
|
|
|
|
14
|
foreach my $i (0..2) { |
226
|
12
|
50
|
|
|
|
34
|
return ($a[$i] <=> $b[$i]) if($a[$i] != $b[$i]); |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
|
229
|
4
|
|
|
|
|
15
|
return 0; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub _add_overload { |
233
|
2
|
|
|
2
|
|
5
|
my($dt, $dur, $reversed) = @_; |
234
|
2
|
50
|
|
|
|
7
|
($dur,$dt) = ($dt,$dur) if $reversed; |
235
|
2
|
|
|
|
|
7
|
return $dt->clone->add_duration($dur); |
236
|
|
|
|
|
|
|
} |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
sub _subtract_overload { |
239
|
2
|
|
|
2
|
|
5
|
my($dt, $dur, $reversed) = @_; |
240
|
2
|
50
|
|
|
|
8
|
($dur,$dt) = ($dt,$dur) if $reversed; |
241
|
2
|
|
|
|
|
5
|
return $dt->clone->subtract_duration($dur); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub add_duration { |
245
|
8
|
|
|
8
|
1
|
511
|
my ($self, $dur) = @_; |
246
|
8
|
|
|
|
|
31
|
my %deltas = $dur->deltas; |
247
|
|
|
|
|
|
|
|
248
|
8
|
50
|
|
|
|
141
|
if($deltas{days}) { $self->{rd_days} += $deltas{days}; } |
|
8
|
|
|
|
|
24
|
|
249
|
8
|
50
|
|
|
|
23
|
if($deltas{hours}) { $self->{rd_secs} += $deltas{hours} * 60 * 60; } |
|
0
|
|
|
|
|
0
|
|
250
|
8
|
50
|
|
|
|
21
|
if($deltas{minutes}) { $self->{rd_secs} += $deltas{minutes} * 60; } |
|
8
|
|
|
|
|
15
|
|
251
|
8
|
50
|
|
|
|
26
|
if($deltas{seconds}) { $self->{rd_secs} += $deltas{seconds}; } |
|
8
|
|
|
|
|
14
|
|
252
|
8
|
50
|
|
|
|
20
|
if($deltas{nanoseconds}) { $self->{rd_nanosecs} += $deltas{nanoseconds}; } |
|
0
|
|
|
|
|
0
|
|
253
|
|
|
|
|
|
|
|
254
|
8
|
|
|
|
|
22
|
while($self->{rd_secs} < 0) { |
255
|
8
|
|
|
|
|
10
|
$self->{rd_days}--; |
256
|
8
|
|
|
|
|
19
|
$self->{rd_secs} += (24 * 60 * 60); |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
8
|
|
|
|
|
22
|
return $self->_normalize; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
sub subtract_duration { |
263
|
4
|
|
|
4
|
1
|
7
|
my ($self, $dur) = @_; |
264
|
4
|
|
|
|
|
18
|
return $self->add_duration($dur->inverse); |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
sub _normalize { |
268
|
8
|
|
|
8
|
|
16
|
my($self) = shift; |
269
|
|
|
|
|
|
|
|
270
|
8
|
|
|
|
|
9
|
my($h, $m, $s, $d); |
271
|
8
|
|
|
|
|
13
|
$s = $self->{rd_secs} % 60; |
272
|
8
|
|
|
|
|
16
|
$m = int($self->{rd_secs} / 60); |
273
|
8
|
|
|
|
|
12
|
$h = int($m / 60); |
274
|
8
|
|
|
|
|
10
|
$m %= 60; |
275
|
8
|
|
|
|
|
11
|
$d = int($h / 24); |
276
|
8
|
|
|
|
|
10
|
$h %= 24; |
277
|
|
|
|
|
|
|
|
278
|
8
|
|
|
|
|
12
|
$self->{rd_days} += $d; |
279
|
8
|
|
|
|
|
16
|
$self->{rd_secs} = ($h * 60 * 60) + ($m * 60) + $s; |
280
|
|
|
|
|
|
|
|
281
|
8
|
|
|
|
|
21
|
@{$self}{qw/year month day/} = &_from_rd($self->{rd_days}); |
|
8
|
|
|
|
|
32
|
|
282
|
8
|
|
|
|
|
15
|
@{$self}{qw/hour minute second/} = ($h, $m, $s); |
|
8
|
|
|
|
|
27
|
|
283
|
|
|
|
|
|
|
|
284
|
8
|
|
|
|
|
70
|
return $self; |
285
|
|
|
|
|
|
|
} |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
sub now { |
288
|
1
|
|
|
1
|
1
|
22
|
my $class = shift; |
289
|
1
|
|
33
|
|
|
10
|
$class = ref($class) || $class; |
290
|
|
|
|
|
|
|
|
291
|
1
|
|
|
|
|
9
|
my $dt = DateTime->now; |
292
|
1
|
|
|
|
|
482
|
my $ht = $class->from_object(object => $dt); |
293
|
1
|
|
|
|
|
9
|
return($ht); |
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
sub today { |
297
|
1
|
|
|
1
|
1
|
39
|
my $class = shift; |
298
|
1
|
|
33
|
|
|
10
|
$class = ref($class) || $class; |
299
|
|
|
|
|
|
|
|
300
|
1
|
|
|
|
|
10
|
my $dt = DateTime->today; |
301
|
1
|
|
|
|
|
851
|
my $ht = $class->from_object(object => $dt); |
302
|
1
|
|
|
|
|
8
|
return($ht); |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
sub _from_rd { |
306
|
13
|
|
|
13
|
|
25
|
my $rd = shift; |
307
|
|
|
|
|
|
|
|
308
|
13
|
|
|
|
|
19
|
my ($year, $month, $day); |
309
|
13
|
|
|
|
|
52
|
$year = int(($rd - HEBREW_EPOCH) / 366); |
310
|
13
|
|
|
|
|
46
|
while ($rd >= &_to_rd($year + 1, 7, 1)) { $year++; } |
|
120
|
|
|
|
|
260
|
|
311
|
13
|
100
|
|
|
|
41
|
if ($rd < &_to_rd($year, 1, 1)) { $month = 7; } |
|
4
|
|
|
|
|
8
|
|
312
|
9
|
|
|
|
|
17
|
else { $month = 1; } |
313
|
13
|
|
|
|
|
36
|
while ($rd > &_to_rd($year, $month, (&_LastDayOfMonth($year, $month)))) { $month++; } |
|
31
|
|
|
|
|
63
|
|
314
|
13
|
|
|
|
|
38
|
$day = $rd - &_to_rd($year, $month, 1) + 1; |
315
|
|
|
|
|
|
|
|
316
|
13
|
|
|
|
|
45
|
return $year, $month, $day; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
sub _to_rd { |
320
|
219
|
|
|
219
|
|
350
|
my ($year, $month, $day) = @_; |
321
|
219
|
50
|
|
|
|
470
|
if(scalar @_) { |
322
|
219
|
|
|
|
|
452
|
($year, $month, $day) = @_; |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
219
|
|
|
|
|
253
|
my($m, $DayInYear); |
326
|
|
|
|
|
|
|
|
327
|
219
|
|
|
|
|
366
|
$DayInYear = $day; |
328
|
219
|
100
|
|
|
|
375
|
if ($month < 7) { |
329
|
73
|
|
|
|
|
93
|
$m = 7; |
330
|
73
|
|
|
|
|
155
|
while ($m <= (&_LastMonthOfYear($year))) { |
331
|
505
|
|
|
|
|
994
|
$DayInYear += &_LastDayOfMonth($year, $m++); |
332
|
|
|
|
|
|
|
} |
333
|
73
|
|
|
|
|
103
|
$m = 1; |
334
|
73
|
|
|
|
|
192
|
while ($m < $month) { |
335
|
131
|
|
|
|
|
231
|
$DayInYear += &_LastDayOfMonth($year, $m); |
336
|
131
|
|
|
|
|
276
|
$m++; |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
else { |
340
|
146
|
|
|
|
|
171
|
$m = 7; |
341
|
146
|
|
|
|
|
344
|
while ($m < $month) { |
342
|
12
|
|
|
|
|
20
|
$DayInYear += &_LastDayOfMonth($year, $m); |
343
|
12
|
|
|
|
|
27
|
$m++; |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
219
|
|
|
|
|
415
|
return($DayInYear + (&_CalendarElapsedDays($year) + HEBREW_EPOCH)); |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
sub _leap_year { |
351
|
756
|
|
|
756
|
|
788
|
my $year = shift; |
352
|
|
|
|
|
|
|
|
353
|
756
|
100
|
|
|
|
1439
|
if ((((7 * $year) + 1) % 19) < 7) { return 1; } |
|
702
|
|
|
|
|
1808
|
|
354
|
54
|
|
|
|
|
135
|
else { return 0; } |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
sub _LastMonthOfYear { |
358
|
578
|
|
|
578
|
|
719
|
my $year = shift; |
359
|
|
|
|
|
|
|
|
360
|
578
|
100
|
|
|
|
834
|
if (&_leap_year($year)) { return 13; } |
|
536
|
|
|
|
|
1173
|
|
361
|
42
|
|
|
|
|
95
|
else { return 12; } |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
sub _CalendarElapsedDays { |
365
|
529
|
|
|
529
|
|
595
|
my $year = shift; |
366
|
|
|
|
|
|
|
|
367
|
529
|
|
|
|
|
545
|
my($MonthsElapsed, $PartsElapsed, $HoursElapsed, $ConjunctionDay, $ConjunctionParts); |
368
|
0
|
|
|
|
|
0
|
my($AlternativeDay); |
369
|
|
|
|
|
|
|
|
370
|
529
|
|
|
|
|
1260
|
$MonthsElapsed = (235 * int(($year - 1) / 19)) + (12 * (($year - 1) % 19)) + int((7 * (($year - 1) % 19) + 1) / 19); |
371
|
529
|
|
|
|
|
598
|
$PartsElapsed = 204 + 793 * ($MonthsElapsed % 1080); |
372
|
529
|
|
|
|
|
992
|
$HoursElapsed = 5 + 12 * $MonthsElapsed + 793 * int($MonthsElapsed / 1080) + int($PartsElapsed / 1080); |
373
|
529
|
|
|
|
|
615
|
$ConjunctionDay = 1 + 29 * $MonthsElapsed + int($HoursElapsed / 24); |
374
|
529
|
|
|
|
|
634
|
$ConjunctionParts = 1080 * ($HoursElapsed % 24) + $PartsElapsed % 1080; |
375
|
|
|
|
|
|
|
|
376
|
529
|
|
|
|
|
548
|
$AlternativeDay = 0; |
377
|
529
|
100
|
100
|
|
|
3089
|
if (($ConjunctionParts >= 19440) || |
|
|
|
66
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
33
|
|
|
|
|
378
|
|
|
|
|
|
|
((($ConjunctionDay % 7) == 2) |
379
|
|
|
|
|
|
|
&& ($ConjunctionParts >= 9924) |
380
|
|
|
|
|
|
|
&& (!&_leap_year($year))) || |
381
|
|
|
|
|
|
|
((($ConjunctionDay % 7) == 1) |
382
|
|
|
|
|
|
|
&& ($ConjunctionParts >= 16789) |
383
|
|
|
|
|
|
|
&& (&_leap_year($year - 1)))) |
384
|
271
|
|
|
|
|
302
|
{ $AlternativeDay = $ConjunctionDay + 1; } |
385
|
258
|
|
|
|
|
298
|
else { $AlternativeDay = $ConjunctionDay; } |
386
|
|
|
|
|
|
|
|
387
|
529
|
100
|
100
|
|
|
2734
|
if ((($AlternativeDay % 7) == 0) || |
|
|
|
100
|
|
|
|
|
388
|
|
|
|
|
|
|
(($AlternativeDay % 7) == 3) || |
389
|
|
|
|
|
|
|
(($AlternativeDay % 7) == 5)) |
390
|
245
|
|
|
|
|
1038
|
{ return (1 + $AlternativeDay); } |
391
|
284
|
|
|
|
|
1175
|
else { return $AlternativeDay; } |
392
|
|
|
|
|
|
|
} |
393
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
sub _DaysInYear { |
395
|
155
|
|
|
155
|
|
166
|
my $year = shift; |
396
|
155
|
|
|
|
|
318
|
return ((&_CalendarElapsedDays($year + 1)) - (&_CalendarElapsedDays($year))); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
sub _LongCheshvan { |
400
|
78
|
|
|
78
|
|
107
|
my $year = shift; |
401
|
78
|
100
|
|
|
|
148
|
if ((&_DaysInYear($year) % 10) == 5) { return 1; } |
|
27
|
|
|
|
|
290
|
|
402
|
51
|
|
|
|
|
225
|
else { return 0; } |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub _ShortKislev { |
406
|
77
|
|
|
77
|
|
90
|
my $year = shift; |
407
|
77
|
100
|
|
|
|
158
|
if ((&_DaysInYear($year) % 10) == 3) { return 1; } |
|
43
|
|
|
|
|
179
|
|
408
|
34
|
|
|
|
|
307
|
else { return 0; } |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub _LastDayOfMonth { |
412
|
707
|
|
|
707
|
|
874
|
my ($year, $month) = @_; |
413
|
|
|
|
|
|
|
|
414
|
707
|
100
|
100
|
|
|
8199
|
if (($month == 2) || |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
415
|
|
|
|
|
|
|
($month == 4) || |
416
|
|
|
|
|
|
|
($month == 6) || |
417
|
|
|
|
|
|
|
(($month == 8) && (! &_LongCheshvan($year))) || |
418
|
|
|
|
|
|
|
(($month == 9) && &_ShortKislev($year)) || |
419
|
|
|
|
|
|
|
($month == 10) || |
420
|
|
|
|
|
|
|
(($month == 12) && (!&_leap_year($year))) || |
421
|
317
|
|
|
|
|
691
|
($month == 13)) { return 29; } |
422
|
390
|
|
|
|
|
927
|
else { return 30; } |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
sub month_name { |
426
|
2
|
|
|
2
|
1
|
8
|
my $self = shift; |
427
|
2
|
|
|
|
|
9
|
my $month = $self->month; |
428
|
2
|
50
|
|
|
|
10
|
if(@_) { $month = shift; } |
|
0
|
|
|
|
|
0
|
|
429
|
|
|
|
|
|
|
|
430
|
2
|
|
|
|
|
10
|
return (qw/Nissan Iyar Sivan Tamuz Av Elul Tishrei Cheshvan Kislev Tevet Shevat AdarI AdarII/)[$month-1]; |
431
|
|
|
|
|
|
|
} |
432
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
sub day_name { |
434
|
2
|
|
|
2
|
1
|
10
|
my $self = shift; |
435
|
2
|
|
|
|
|
9
|
my $day = $self->day_of_week; |
436
|
2
|
50
|
|
|
|
14
|
if(@_) { $day = shift; } |
|
0
|
|
|
|
|
0
|
|
437
|
|
|
|
|
|
|
|
438
|
2
|
|
|
|
|
9
|
return (qw/Sunday Monday Tuesday Wednesday Thursday Friday Shabbos/)[$day - 1]; |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
12
|
|
|
12
|
|
38436
|
use DateTime::TimeZone::Floating qw( ); |
|
12
|
|
|
|
|
40
|
|
|
12
|
|
|
|
|
21634
|
|
442
|
6
|
|
|
6
|
0
|
1246
|
sub time_zone { DateTime::TimeZone::Floating->new() } |
443
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
|
445
|
11
|
|
|
11
|
1
|
48
|
sub year { $_[0]->{year} } |
446
|
|
|
|
|
|
|
|
447
|
10
|
|
|
10
|
1
|
35
|
sub month { $_[0]->{month} } |
448
|
|
|
|
|
|
|
*mon = \&month; |
449
|
|
|
|
|
|
|
|
450
|
1
|
|
|
1
|
0
|
7
|
sub month_0 { $_[0]->month - 1 } |
451
|
|
|
|
|
|
|
*mon_0 = \&month_0; |
452
|
|
|
|
|
|
|
|
453
|
9
|
|
|
9
|
1
|
58
|
sub day_of_month { $_[0]->{day} } |
454
|
|
|
|
|
|
|
*day = \&day_of_month; |
455
|
|
|
|
|
|
|
*mday = \&day_of_month; |
456
|
|
|
|
|
|
|
|
457
|
1
|
|
|
1
|
1
|
6
|
sub day_of_month_0 { $_[0]->day - 1 } |
458
|
|
|
|
|
|
|
*day_0 = \&day_of_month_0; |
459
|
|
|
|
|
|
|
*mday_0 = \&day_of_month_0; |
460
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
sub day_of_week { |
462
|
3
|
|
|
3
|
1
|
12
|
my $rd_days = $_[0]->{rd_days}; |
463
|
3
|
50
|
|
|
|
12
|
if($_[0]->{after_sunset}) { $rd_days++; } |
|
0
|
|
|
|
|
0
|
|
464
|
3
|
|
|
|
|
7
|
return $rd_days % 7 + 1; |
465
|
|
|
|
|
|
|
} |
466
|
|
|
|
|
|
|
*wday = \&day_of_week; |
467
|
|
|
|
|
|
|
*dow = \&day_of_week; |
468
|
|
|
|
|
|
|
|
469
|
|
|
|
|
|
|
sub day_of_week_0 { |
470
|
4
|
|
|
4
|
1
|
14
|
my $rd_days = $_[0]->{rd_days}; |
471
|
4
|
50
|
|
|
|
11
|
if($_[0]->{after_sunset}) { $rd_days++; } |
|
0
|
|
|
|
|
0
|
|
472
|
4
|
|
|
|
|
19
|
return $rd_days % 7; |
473
|
|
|
|
|
|
|
} |
474
|
|
|
|
|
|
|
*wday_0 = \&day_of_week_0; |
475
|
|
|
|
|
|
|
*dow_0 = \&day_of_week_0; |
476
|
|
|
|
|
|
|
|
477
|
1
|
|
|
1
|
1
|
8
|
sub hour { $_[0]->{hour} } |
478
|
|
|
|
|
|
|
*hr = \&hour; |
479
|
|
|
|
|
|
|
|
480
|
1
|
|
|
1
|
1
|
8
|
sub minute { $_[0]->{minute} } |
481
|
|
|
|
|
|
|
*min = \&minute; |
482
|
|
|
|
|
|
|
|
483
|
1
|
|
|
1
|
1
|
6
|
sub second { $_[0]->{second} } |
484
|
|
|
|
|
|
|
*sec = \&second; |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
sub day_of_year { |
487
|
6
|
|
|
6
|
1
|
14
|
my $self = shift; |
488
|
6
|
|
|
|
|
8
|
my ($year, $month, $day) = @{$self}{qw/year month day/}; |
|
6
|
|
|
|
|
18
|
|
489
|
|
|
|
|
|
|
|
490
|
6
|
|
|
|
|
8
|
my $m = 1; |
491
|
6
|
|
|
|
|
14
|
while ($m < $month) { |
492
|
15
|
|
|
|
|
27
|
$day += &_LastDayOfMonth($year, $m); |
493
|
15
|
|
|
|
|
35
|
$m++; |
494
|
|
|
|
|
|
|
} |
495
|
6
|
|
|
|
|
16
|
return $day; |
496
|
|
|
|
|
|
|
} |
497
|
|
|
|
|
|
|
*doy = \&day_of_year; |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub week_number { |
500
|
3
|
|
|
3
|
0
|
12
|
my $self = shift; |
501
|
|
|
|
|
|
|
|
502
|
3
|
|
|
|
|
14
|
my $day_of_year = $self->day_of_year; |
503
|
3
|
|
|
|
|
9
|
my $start_of_year = &_to_rd($self->year, 1, 1); |
504
|
3
|
|
|
|
|
8
|
my $first_week_started_on = $start_of_year % 7 + 1; |
505
|
|
|
|
|
|
|
|
506
|
3
|
|
|
|
|
10
|
return (($day_of_year + (7 - $first_week_started_on)) / 7) + 1; |
507
|
|
|
|
|
|
|
} |
508
|
|
|
|
|
|
|
|
509
|
1
|
|
|
1
|
1
|
10
|
sub day_of_year_0 { $_[0]->day_of_year - 1; } |
510
|
|
|
|
|
|
|
*doy_0 = \&day_of_year_0; |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
sub hms { |
513
|
0
|
|
|
0
|
1
|
0
|
my ($self, $sep) = @_; |
514
|
0
|
0
|
|
|
|
0
|
$sep = ':' unless defined $sep; |
515
|
|
|
|
|
|
|
|
516
|
0
|
|
|
|
|
0
|
return sprintf( "%02d%s%02d%s%02d", |
517
|
|
|
|
|
|
|
$self->hour, $sep, |
518
|
|
|
|
|
|
|
$self->minute, $sep, |
519
|
|
|
|
|
|
|
$self->second ); |
520
|
|
|
|
|
|
|
} |
521
|
|
|
|
|
|
|
*time = \&hms; |
522
|
|
|
|
|
|
|
|
523
|
|
|
|
|
|
|
sub hm { |
524
|
0
|
|
|
0
|
1
|
0
|
my ($self, $sep) = @_; |
525
|
0
|
0
|
|
|
|
0
|
$sep = ':' unless defined $sep; |
526
|
|
|
|
|
|
|
|
527
|
0
|
|
|
|
|
0
|
return sprintf( "%02d%s%02d", |
528
|
|
|
|
|
|
|
$self->hour, $sep, |
529
|
|
|
|
|
|
|
$self->minute ); |
530
|
|
|
|
|
|
|
} |
531
|
|
|
|
|
|
|
|
532
|
|
|
|
|
|
|
sub ymd { |
533
|
2
|
|
|
2
|
1
|
20
|
my ($self, $sep) = @_; |
534
|
2
|
100
|
|
|
|
10
|
$sep = '-' unless defined $sep; |
535
|
|
|
|
|
|
|
|
536
|
2
|
|
|
|
|
6
|
return sprintf( "%04d%s%02d%s%02d", |
537
|
|
|
|
|
|
|
$self->year, $sep, |
538
|
|
|
|
|
|
|
$self->month, $sep, |
539
|
|
|
|
|
|
|
$self->day ); |
540
|
|
|
|
|
|
|
} |
541
|
|
|
|
|
|
|
*date = \&ymd; |
542
|
|
|
|
|
|
|
|
543
|
|
|
|
|
|
|
sub mdy { |
544
|
1
|
|
|
1
|
1
|
8
|
my ($self, $sep) = @_; |
545
|
1
|
50
|
|
|
|
3
|
$sep = '-' unless defined $sep; |
546
|
|
|
|
|
|
|
|
547
|
1
|
|
|
|
|
3
|
return sprintf( "%02d%s%02d%s%04d", |
548
|
|
|
|
|
|
|
$self->month, $sep, |
549
|
|
|
|
|
|
|
$self->day, $sep, |
550
|
|
|
|
|
|
|
$self->year ); |
551
|
|
|
|
|
|
|
} |
552
|
|
|
|
|
|
|
|
553
|
|
|
|
|
|
|
sub dmy { |
554
|
1
|
|
|
1
|
1
|
7
|
my ($self, $sep) = @_; |
555
|
1
|
50
|
|
|
|
3
|
$sep = '-' unless defined $sep; |
556
|
|
|
|
|
|
|
|
557
|
1
|
|
|
|
|
8
|
return sprintf( "%02d%s%02d%s%04d", |
558
|
|
|
|
|
|
|
$self->day, $sep, |
559
|
|
|
|
|
|
|
$self->month, $sep, |
560
|
|
|
|
|
|
|
$self->year ); |
561
|
|
|
|
|
|
|
} |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
sub datetime { |
564
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
565
|
0
|
|
|
|
|
0
|
return ($self->ymd('-') . "T" . $self->hms); |
566
|
|
|
|
|
|
|
} |
567
|
|
|
|
|
|
|
|
568
|
|
|
|
|
|
|
my %formats = ( |
569
|
|
|
|
|
|
|
'A' => sub { $_[0]->day_name }, |
570
|
|
|
|
|
|
|
'a' => sub { my $a = $_[0]->day_of_week_0; (qw/Sun Mon Tue Wed Thu Fri Shabbat/)[$a] }, |
571
|
|
|
|
|
|
|
'B' => sub { $_[0]->month_name }, |
572
|
|
|
|
|
|
|
'd' => sub { sprintf( '%02d', $_[0]->day) }, |
573
|
|
|
|
|
|
|
'D' => sub { $_[0]->strftime( '%m/%d/%Y') }, |
574
|
|
|
|
|
|
|
'e' => sub { sprintf( '%2d', $_[0]->day) }, |
575
|
|
|
|
|
|
|
'F' => sub { $_[0]->ymd('-') }, |
576
|
|
|
|
|
|
|
'j' => sub { sprintf('%03d', $_[0]->day_of_year) }, |
577
|
|
|
|
|
|
|
'H' => sub { sprintf('%02d', $_[0]->hour) }, |
578
|
|
|
|
|
|
|
'I' => sub { ($_[0]->hour == 12) ? '12' : sprintf('%02d', ($_[0]->hour % 12)) }, |
579
|
|
|
|
|
|
|
'k' => sub { sprintf('%2d', $_[0]->hour) }, |
580
|
|
|
|
|
|
|
'l' => sub { ($_[0]->hour == 12) ? '12' : sprintf('%2d', ($_[0]->hour % 12)) }, |
581
|
|
|
|
|
|
|
'M' => sub { sprintf('%02d', $_[0]->minute) }, |
582
|
|
|
|
|
|
|
'm' => sub { sprintf('%02d', $_[0]->month) }, |
583
|
|
|
|
|
|
|
'n' => sub { "\n" }, |
584
|
|
|
|
|
|
|
'P' => sub { ($_[0]->hour >= 12) ? "PM" : "AM" }, |
585
|
|
|
|
|
|
|
'p' => sub { ($_[0]->hour >= 12) ? "pm" : "am" }, |
586
|
|
|
|
|
|
|
'r' => sub { $_[0]->strftime( '%I:%M:%S %p') }, |
587
|
|
|
|
|
|
|
'R' => sub { $_[0]->strftime( '%H:%M') }, |
588
|
|
|
|
|
|
|
'S' => sub { sprintf('%02d', $_[0]->second) }, |
589
|
|
|
|
|
|
|
'T' => sub { $_[0]->strftime( '%H:%M:%S') }, |
590
|
|
|
|
|
|
|
't' => sub { "\t" }, |
591
|
|
|
|
|
|
|
'u' => sub { my $u = $_[0]->day_of_week_0; $u == 0 ? 7 : $u }, |
592
|
|
|
|
|
|
|
'U' => sub { my $w = $_[0]->week_number; defined $w ? sprintf('%02d', $w) : ' ' }, |
593
|
|
|
|
|
|
|
'w' => sub { $_[0]->day_of_week_0 }, |
594
|
|
|
|
|
|
|
'W' => sub { sprintf('%02d', $_[0]->week_number) }, |
595
|
|
|
|
|
|
|
'y' => sub { sprintf('%02d', substr($_[0]->year, -2)) }, |
596
|
|
|
|
|
|
|
'Y' => sub { return $_[0]->year }, |
597
|
|
|
|
|
|
|
'%' => sub { '%' }, |
598
|
|
|
|
|
|
|
); |
599
|
|
|
|
|
|
|
$formats{W} = $formats{V} = $formats{U}; |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
sub strftime { |
602
|
16
|
|
|
16
|
1
|
139
|
my ($self, @r) = @_; |
603
|
|
|
|
|
|
|
|
604
|
16
|
|
|
|
|
27
|
foreach (@r) { |
605
|
16
|
50
|
|
|
|
63
|
s/%([%*A-Za-z])/ $formats{$1} ? $formats{$1}->($self) : $1 /ge; |
|
18
|
|
|
|
|
76
|
|
606
|
16
|
50
|
|
|
|
75
|
return $_ unless wantarray; |
607
|
|
|
|
|
|
|
} |
608
|
0
|
|
|
|
|
|
return @r; |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
|
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
|
613
|
|
|
|
|
|
|
1; |
614
|
|
|
|
|
|
|
__END__ |