line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Travel::Status::DE::IRIS::Result; |
2
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
57
|
use strict; |
|
7
|
|
|
|
|
24
|
|
|
7
|
|
|
|
|
242
|
|
4
|
7
|
|
|
7
|
|
54
|
use warnings; |
|
7
|
|
|
|
|
38
|
|
|
7
|
|
|
|
|
178
|
|
5
|
7
|
|
|
7
|
|
190
|
use 5.014; |
|
7
|
|
|
|
|
32
|
|
6
|
7
|
|
|
7
|
|
50
|
use utf8; |
|
7
|
|
|
|
|
16
|
|
|
7
|
|
|
|
|
71
|
|
7
|
|
|
|
|
|
|
|
8
|
7
|
|
|
7
|
|
275
|
no if $] >= 5.018, warnings => 'experimental::smartmatch'; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
68
|
|
9
|
|
|
|
|
|
|
|
10
|
7
|
|
|
7
|
|
585
|
use parent 'Class::Accessor'; |
|
7
|
|
|
|
|
48
|
|
|
7
|
|
|
|
|
81
|
|
11
|
7
|
|
|
7
|
|
18917
|
use Carp qw(cluck); |
|
7
|
|
|
|
|
38
|
|
|
7
|
|
|
|
|
422
|
|
12
|
7
|
|
|
7
|
|
66
|
use DateTime; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
250
|
|
13
|
7
|
|
|
7
|
|
47
|
use DateTime::Format::Strptime; |
|
7
|
|
|
|
|
15
|
|
|
7
|
|
|
|
|
81
|
|
14
|
7
|
|
|
7
|
|
7149
|
use List::Compare; |
|
7
|
|
|
|
|
169130
|
|
|
7
|
|
|
|
|
314
|
|
15
|
7
|
|
|
7
|
|
74
|
use List::MoreUtils qw(none uniq lastval); |
|
7
|
|
|
|
|
97
|
|
|
7
|
|
|
|
|
86
|
|
16
|
7
|
|
|
7
|
|
6477
|
use Scalar::Util qw(weaken); |
|
7
|
|
|
|
|
17
|
|
|
7
|
|
|
|
|
39632
|
|
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
our $VERSION = '1.90'; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
Travel::Status::DE::IRIS::Result->mk_ro_accessors( |
21
|
|
|
|
|
|
|
qw(arrival arrival_delay arrival_has_realtime arrival_is_additional arrival_is_cancelled arrival_hidden |
22
|
|
|
|
|
|
|
date datetime delay |
23
|
|
|
|
|
|
|
departure departure_delay departure_has_realtime departure_is_additional departure_is_cancelled departure_hidden |
24
|
|
|
|
|
|
|
ds100 has_realtime is_transfer is_unscheduled is_wing |
25
|
|
|
|
|
|
|
line_no old_train_id old_train_no operator platform raw_id |
26
|
|
|
|
|
|
|
realtime_xml route_start route_end |
27
|
|
|
|
|
|
|
sched_arrival sched_departure sched_platform sched_route_start |
28
|
|
|
|
|
|
|
sched_route_end start |
29
|
|
|
|
|
|
|
station station_uic |
30
|
|
|
|
|
|
|
stop_no time train_id train_no transfer type |
31
|
|
|
|
|
|
|
unknown_t unknown_o wing_id wing_of) |
32
|
|
|
|
|
|
|
); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
# {{{ Data (message codes, station fixups) |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
my %translation = ( |
37
|
|
|
|
|
|
|
1 => 'Nähere Informationen in Kürze', |
38
|
|
|
|
|
|
|
2 => 'Polizeieinsatz', |
39
|
|
|
|
|
|
|
3 => 'Feuerwehreinsatz auf der Strecke', |
40
|
|
|
|
|
|
|
4 => 'Kurzfristiger Personalausfall', # xlsx: missing |
41
|
|
|
|
|
|
|
5 => 'Ärztliche Versorgung eines Fahrgastes', |
42
|
|
|
|
|
|
|
6 => 'Betätigen der Notbremse', # xlsx: "Unbefugtes Ziehen der Notbremse" |
43
|
|
|
|
|
|
|
7 => 'Unbefugte Personen auf der Strecke', |
44
|
|
|
|
|
|
|
8 => 'Notarzteinsatz auf der Strecke', |
45
|
|
|
|
|
|
|
9 => 'Streikauswirkungen', |
46
|
|
|
|
|
|
|
10 => 'Tiere auf der Strecke', |
47
|
|
|
|
|
|
|
11 => 'Unwetter', |
48
|
|
|
|
|
|
|
12 => 'Warten auf ein verspätetes Schiff', |
49
|
|
|
|
|
|
|
13 => 'Pass- und Zollkontrolle', |
50
|
|
|
|
|
|
|
14 => 'Defekt am Bahnhof', # xlsx: "Technischer Defekt am Bahnhof" |
51
|
|
|
|
|
|
|
15 => 'Beeinträchtigung durch Vandalismus', |
52
|
|
|
|
|
|
|
16 => 'Entschärfung einer Fliegerbombe', |
53
|
|
|
|
|
|
|
17 => 'Beschädigung einer Brücke', |
54
|
|
|
|
|
|
|
18 => 'Umgestürzter Baum auf der Strecke', |
55
|
|
|
|
|
|
|
19 => 'Unfall an einem Bahnübergang', |
56
|
|
|
|
|
|
|
20 => 'Tiere im Gleis', # xlsx: missing |
57
|
|
|
|
|
|
|
21 => 'Warten auf Anschlussreisende', |
58
|
|
|
|
|
|
|
22 => 'Witterungsbedingte Beeinträchtigung', |
59
|
|
|
|
|
|
|
23 => 'Feuerwehreinsatz auf Bahngelände', # xlsx: missing |
60
|
|
|
|
|
|
|
24 => 'Verspätung im Ausland', |
61
|
|
|
|
|
|
|
25 => 'Bereitstellung weiterer Wagen', |
62
|
|
|
|
|
|
|
26 => 'Abhängen von Wagen', |
63
|
|
|
|
|
|
|
28 => 'Gegenstände auf der Strecke', |
64
|
|
|
|
|
|
|
29 => 'Ersatzverkehr mit Bus ist eingerichtet', |
65
|
|
|
|
|
|
|
31 => 'Bauarbeiten', |
66
|
|
|
|
|
|
|
32 => 'Verzögerung beim Ein-/Ausstieg' |
67
|
|
|
|
|
|
|
, # xlsx: "Unterstützung beim Ein- und Ausstieg" |
68
|
|
|
|
|
|
|
33 => 'Defekt an der Oberleitung', # xlsx: "Reparatur an der Oberleitung" |
69
|
|
|
|
|
|
|
34 => 'Defekt an einem Signal', # xlsx: "Reparatur an einem Signal" |
70
|
|
|
|
|
|
|
35 => 'Streckensperrung', |
71
|
|
|
|
|
|
|
36 => 'Defekt am Zug', # xlsx: "Reparatur am Zug" |
72
|
|
|
|
|
|
|
37 => 'Defekt am Wagen', # xlsx: missing |
73
|
|
|
|
|
|
|
38 => 'Defekt an der Strecke', # xlsx: "Reparatur an der Strecke" |
74
|
|
|
|
|
|
|
39 => 'Anhängen von zusätzlichen Wagen', # xlsx: missing |
75
|
|
|
|
|
|
|
40 => 'Defektes Stellwerk', |
76
|
|
|
|
|
|
|
41 => 'Defekt an einem Bahnübergang' |
77
|
|
|
|
|
|
|
, # xlsx: "Technischer Defekt an einem Bahnüburgang" |
78
|
|
|
|
|
|
|
42 => 'Außerplanmäßige Geschwindigkeitsbeschränkung' |
79
|
|
|
|
|
|
|
, # xlsx: "Vorübergehend verminderte Geschwindigkeit auf der Strecke" |
80
|
|
|
|
|
|
|
43 => 'Verspätung eines vorausfahrenden Zuges', |
81
|
|
|
|
|
|
|
44 => 'Warten auf einen entgegenkommenden Zug', |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
# TODO for Oct 2021: switch 45, 46 to "Vorfahrt eines anderen Zuges" |
84
|
|
|
|
|
|
|
45 => 'Überholung durch anderen Zug', # xlsx: "Vorfahrt eines anderen Zuges" |
85
|
|
|
|
|
|
|
46 => 'Warten auf freie Einfahrt', # xlsx: "Vorfahrt eines anderen Zuges" |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
47 => |
88
|
|
|
|
|
|
|
'Verspätete Bereitstellung', # xlsx: "Verspätete Bereitstellung des Zuges" |
89
|
|
|
|
|
|
|
48 => 'Verspätung aus vorheriger Fahrt', |
90
|
|
|
|
|
|
|
49 => 'Kurzfristiger Personalausfall', |
91
|
|
|
|
|
|
|
50 => 'Kurzfristige Erkrankung von Personal', |
92
|
|
|
|
|
|
|
51 => 'Verspätetes Personal aus vorheriger Fahrt', |
93
|
|
|
|
|
|
|
52 => 'Streik', |
94
|
|
|
|
|
|
|
53 => 'Unwetterauswirkungen', |
95
|
|
|
|
|
|
|
54 => 'Verfügbarkeit der Gleise derzeit eingeschränkt', |
96
|
|
|
|
|
|
|
55 => 'Defekt an einem anderen Zug', |
97
|
|
|
|
|
|
|
56 => 'Warten auf Anschlussreisende', # aus einem Bus |
98
|
|
|
|
|
|
|
57 => 'Zusätzlicher Halt', # xslx: "Zusätzlicher Halt zum Ein- und Ausstieg" |
99
|
|
|
|
|
|
|
58 => 'Umleitung', # xlsx: "Umleitung des Zuges" |
100
|
|
|
|
|
|
|
59 => 'Schnee und Eis', |
101
|
|
|
|
|
|
|
60 => 'Witterungsbedingt verminderte Geschwindigkeit', |
102
|
|
|
|
|
|
|
61 => 'Defekte Tür', |
103
|
|
|
|
|
|
|
62 => 'Behobener Defekt am Zug', # r 36 |
104
|
|
|
|
|
|
|
63 => 'Technische Untersuchung am Zug', |
105
|
|
|
|
|
|
|
64 => 'Defekt an einer Weiche', # xlsx: "Reparatur an der Weiche" |
106
|
|
|
|
|
|
|
65 => 'Erdrutsch', |
107
|
|
|
|
|
|
|
66 => 'Hochwasser', |
108
|
|
|
|
|
|
|
67 => 'Behördliche Maßnahme', |
109
|
|
|
|
|
|
|
68 => 'Hohes Fahrgastaufkommen' |
110
|
|
|
|
|
|
|
, # xlsx: "Hohes Fahrgastaufkommen verlängert Ein- und Ausstieg" |
111
|
|
|
|
|
|
|
69 => 'Zug verkehrt mit verminderter Geschwindigeit', |
112
|
|
|
|
|
|
|
70 => 'WLAN nicht verfügbar', |
113
|
|
|
|
|
|
|
71 => 'WLAN in einzelnen Wagen nicht verfügbar', |
114
|
|
|
|
|
|
|
72 => 'Info/Entertainment nicht verfügbar', |
115
|
|
|
|
|
|
|
73 => 'Heute: Mehrzweckabteil vorne', # r 74 |
116
|
|
|
|
|
|
|
74 => 'Heute: Mehrzweckabteil hinten', # r 73 |
117
|
|
|
|
|
|
|
75 => 'Heute: 1. Klasse vorne', # r 76 |
118
|
|
|
|
|
|
|
76 => 'Heute: 1. Klasse hinten', # r 75 |
119
|
|
|
|
|
|
|
77 => '1. Klasse fehlt', |
120
|
|
|
|
|
|
|
78 => 'Ersatzverkehr mit Bus ist eingerichtet', |
121
|
|
|
|
|
|
|
79 => 'Mehrzweckabteil fehlt', |
122
|
|
|
|
|
|
|
80 => 'Abweichende Wagenreihung', |
123
|
|
|
|
|
|
|
81 => 'Fahrzeugtausch', |
124
|
|
|
|
|
|
|
82 => 'Mehrere Wagen fehlen', |
125
|
|
|
|
|
|
|
83 => 'Defekte fahrzeuggebundene Einstiegshilfe', |
126
|
|
|
|
|
|
|
84 => 'Zug verkehrt richtig gereiht', # r 80 82 85 |
127
|
|
|
|
|
|
|
85 => 'Ein Wagen fehlt', |
128
|
|
|
|
|
|
|
86 => 'Gesamter Zug ohne Reservierung', |
129
|
|
|
|
|
|
|
87 => 'Einzelne Wagen ohne Reservierung', |
130
|
|
|
|
|
|
|
88 => 'Keine Qualitätsmängel', # r 80 82 83 85 86 87 90 91 92 93 96 97 98 |
131
|
|
|
|
|
|
|
89 => 'Reservierungen sind wieder vorhanden', # -> 86 87 |
132
|
|
|
|
|
|
|
90 => 'Kein gastronomisches Angebot', |
133
|
|
|
|
|
|
|
91 => 'Fahrradmitnahme nicht möglich', |
134
|
|
|
|
|
|
|
92 => 'Eingeschränkte Fahrradbeförderung', |
135
|
|
|
|
|
|
|
93 => 'Behindertengerechte Einrichtung fehlt', |
136
|
|
|
|
|
|
|
94 => 'Ersatzbewirtschaftung', |
137
|
|
|
|
|
|
|
95 => 'Universal-WC fehlt', |
138
|
|
|
|
|
|
|
96 => 'Der Zug ist stark überbesetzt', # r 97 |
139
|
|
|
|
|
|
|
97 => 'Der Zug ist überbesetzt', # r 96 |
140
|
|
|
|
|
|
|
98 => 'Sonstige Qualitätsmängel', |
141
|
|
|
|
|
|
|
99 => 'Verzögerungen im Betriebsablauf', |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
# Occasionally, there's a message with ID 900. In all cases observed so far, |
144
|
|
|
|
|
|
|
# it was used for "Anschlussbus wartet". However, as we don't know which bus |
145
|
|
|
|
|
|
|
# it refers to, we don't show it to users. |
146
|
|
|
|
|
|
|
); |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# IRIS may return "Betriebsstelle nicht bekannt" for some recently added |
149
|
|
|
|
|
|
|
# stations. Fix those manually. |
150
|
|
|
|
|
|
|
my %fixup = ( |
151
|
|
|
|
|
|
|
8002795 => 'Herten(Westf)', |
152
|
|
|
|
|
|
|
8003983 => 'Merklingen - Schwäbische Alb', |
153
|
|
|
|
|
|
|
8005493 => 'Schwetzingen-Hirschacker', |
154
|
|
|
|
|
|
|
8070678 => 'Metzingen-Neuhausen', |
155
|
|
|
|
|
|
|
); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
# }}} |
158
|
|
|
|
|
|
|
# {{{ Constructor |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
sub new { |
161
|
1140
|
|
|
1140
|
1
|
9774
|
my ( $obj, %opt ) = @_; |
162
|
|
|
|
|
|
|
|
163
|
1140
|
|
|
|
|
2488
|
my $ref = \%opt; |
164
|
|
|
|
|
|
|
|
165
|
1140
|
|
|
|
|
8995
|
my ( $train_id, $start_ts, $stop_no ) = split( /.\K-/, $opt{raw_id} ); |
166
|
|
|
|
|
|
|
|
167
|
1140
|
|
|
|
|
2874
|
bless( $ref, $obj ); |
168
|
|
|
|
|
|
|
|
169
|
1140
|
|
33
|
|
|
3056
|
$ref->{strptime_obj} //= DateTime::Format::Strptime->new( |
170
|
|
|
|
|
|
|
pattern => '%y%m%d%H%M', |
171
|
|
|
|
|
|
|
time_zone => 'Europe/Berlin', |
172
|
|
|
|
|
|
|
); |
173
|
|
|
|
|
|
|
|
174
|
1140
|
|
|
|
|
3972
|
$ref->{wing_id} = "${train_id}-${start_ts}"; |
175
|
1140
|
|
|
|
|
2351
|
$ref->{is_wing} = 0; |
176
|
1140
|
|
|
|
|
3639
|
$train_id =~ s{^-}{}; |
177
|
|
|
|
|
|
|
|
178
|
1140
|
|
|
|
|
3113
|
$ref->{start} = $ref->parse_ts($start_ts); |
179
|
|
|
|
|
|
|
|
180
|
1140
|
|
|
|
|
1044680
|
$ref->{train_id} = $train_id; |
181
|
1140
|
|
|
|
|
2694
|
$ref->{stop_no} = $stop_no; |
182
|
|
|
|
|
|
|
|
183
|
1140
|
100
|
|
|
|
2881
|
if ( $opt{transfer} ) { |
184
|
24
|
|
|
|
|
160
|
my ($transfer) = split( /.\K-/, $opt{transfer} ); |
185
|
24
|
|
|
|
|
97
|
$transfer =~ s{^-}{}; |
186
|
24
|
|
|
|
|
50
|
$ref->{transfer} = $transfer; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
my $ar = $ref->{arrival} = $ref->{sched_arrival} |
190
|
1140
|
|
|
|
|
3036
|
= $ref->parse_ts( $opt{arrival_ts} ); |
191
|
|
|
|
|
|
|
my $dp = $ref->{departure} = $ref->{sched_departure} |
192
|
1140
|
|
|
|
|
878625
|
= $ref->parse_ts( $opt{departure_ts} ); |
193
|
|
|
|
|
|
|
|
194
|
1140
|
50
|
66
|
|
|
836401
|
if ( not( defined $ar or defined $dp ) ) { |
195
|
|
|
|
|
|
|
cluck( |
196
|
|
|
|
|
|
|
sprintf( |
197
|
|
|
|
|
|
|
"Neither arrival '%s' nor departure '%s' are valid " |
198
|
|
|
|
|
|
|
. "timestamps - can't handle this train", |
199
|
|
|
|
|
|
|
$opt{arrival_ts}, $opt{departure_ts} |
200
|
|
|
|
|
|
|
) |
201
|
0
|
|
|
|
|
0
|
); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
1140
|
|
66
|
|
|
4056
|
my $dt = $ref->{datetime} = $dp // $ar; |
205
|
|
|
|
|
|
|
|
206
|
1140
|
|
|
|
|
6573
|
$ref->{date} = $dt->strftime('%d.%m.%Y'); |
207
|
1140
|
|
|
|
|
65333
|
$ref->{time} = $dt->strftime('%H:%M'); |
208
|
1140
|
|
|
|
|
40286
|
$ref->{epoch} = $dt->epoch; |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
$ref->{route_pre} = $ref->{sched_route_pre} |
211
|
1140
|
|
100
|
|
|
23356
|
= [ split( qr{[|]}, $ref->{route_pre} // q{} ) ]; |
212
|
|
|
|
|
|
|
$ref->{route_post} = $ref->{sched_route_post} |
213
|
1140
|
|
100
|
|
|
13617
|
= [ split( qr{[|]}, $ref->{route_post} // q{} ) ]; |
214
|
|
|
|
|
|
|
|
215
|
1140
|
|
|
|
|
4899
|
$ref->fixup_route( $ref->{route_pre} ); |
216
|
1140
|
|
|
|
|
3012
|
$ref->fixup_route( $ref->{route_post} ); |
217
|
|
|
|
|
|
|
|
218
|
1140
|
100
|
|
|
|
3044
|
$ref->{route_pre_incomplete} = $ref->{route_end} ? 1 : 0; |
219
|
1140
|
50
|
|
|
|
2711
|
$ref->{route_post_incomplete} = $ref->{route_post} ? 1 : 0; |
220
|
|
|
|
|
|
|
|
221
|
1140
|
|
|
|
|
2364
|
$ref->{sched_platform} = $ref->{platform}; |
222
|
|
|
|
|
|
|
$ref->{route_end} |
223
|
|
|
|
|
|
|
= $ref->{sched_route_end} |
224
|
|
|
|
|
|
|
= $ref->{route_end} |
225
|
|
|
|
|
|
|
|| $ref->{route_post}[-1] |
226
|
1140
|
|
66
|
|
|
5775
|
|| $ref->{station}; |
227
|
|
|
|
|
|
|
$ref->{route_start} |
228
|
|
|
|
|
|
|
= $ref->{sched_route_start} |
229
|
|
|
|
|
|
|
= $ref->{route_start} |
230
|
|
|
|
|
|
|
|| $ref->{route_pre}[0] |
231
|
1140
|
|
66
|
|
|
4868
|
|| $ref->{station}; |
232
|
|
|
|
|
|
|
|
233
|
1140
|
|
|
|
|
4158
|
return $ref; |
234
|
|
|
|
|
|
|
} |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
# }}} |
237
|
|
|
|
|
|
|
# {{{ Internal Helpers |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub fixup_route { |
240
|
3012
|
|
|
3012
|
0
|
5687
|
my ( $self, $route ) = @_; |
241
|
3012
|
|
|
|
|
4292
|
for my $stop ( @{$route} ) { |
|
3012
|
|
|
|
|
6320
|
|
242
|
27180
|
50
|
|
|
|
48767
|
if ( $stop =~ m{^Betriebsstelle nicht bekannt (\d+)$} ) { |
243
|
0
|
0
|
|
|
|
0
|
if ( $fixup{$1} ) { |
244
|
0
|
|
|
|
|
0
|
$stop = $fixup{$1}; |
245
|
|
|
|
|
|
|
} |
246
|
|
|
|
|
|
|
} |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
} |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub parse_ts { |
251
|
5011
|
|
|
5011
|
0
|
10833
|
my ( $self, $string ) = @_; |
252
|
|
|
|
|
|
|
|
253
|
5011
|
100
|
|
|
|
11176
|
if ( defined $string ) { |
254
|
4655
|
|
|
|
|
15021
|
return $self->{strptime_obj}->parse_datetime($string); |
255
|
|
|
|
|
|
|
} |
256
|
356
|
|
|
|
|
970
|
return; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
# List::Compare does not keep the order of its arguments (even with unsorted). |
260
|
|
|
|
|
|
|
# So we need to re-sort all stops to maintain their original order. |
261
|
|
|
|
|
|
|
sub sorted_sublist { |
262
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $list, $sublist ) = @_; |
263
|
0
|
|
|
|
|
0
|
my %pos; |
264
|
|
|
|
|
|
|
|
265
|
0
|
0
|
0
|
|
|
0
|
if ( not $sublist or not @{$sublist} ) { |
|
0
|
|
|
|
|
0
|
|
266
|
0
|
|
|
|
|
0
|
return; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
|
269
|
0
|
|
|
|
|
0
|
for my $i ( 0 .. $#{$list} ) { |
|
0
|
|
|
|
|
0
|
|
270
|
0
|
|
|
|
|
0
|
$pos{ $list->[$i] } = $i; |
271
|
|
|
|
|
|
|
} |
272
|
|
|
|
|
|
|
|
273
|
0
|
|
|
|
|
0
|
my @sorted = sort { $pos{$a} <=> $pos{$b} } @{$sublist}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
274
|
|
|
|
|
|
|
|
275
|
0
|
|
|
|
|
0
|
return @sorted; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub superseded_messages { |
279
|
3
|
|
|
3
|
0
|
9
|
my ( $self, $msg ) = @_; |
280
|
3
|
|
|
|
|
30
|
my %superseded = ( |
281
|
|
|
|
|
|
|
62 => [36], |
282
|
|
|
|
|
|
|
73 => [74], |
283
|
|
|
|
|
|
|
74 => [73], |
284
|
|
|
|
|
|
|
75 => [76], |
285
|
|
|
|
|
|
|
76 => [75], |
286
|
|
|
|
|
|
|
84 => [ 80, 82, 85 ], |
287
|
|
|
|
|
|
|
88 => [ 80, 82, 83, 85, 86, 87, 90, 91, 92, 93, 96, 97, 98 ], |
288
|
|
|
|
|
|
|
89 => [ 86, 87 ], |
289
|
|
|
|
|
|
|
96 => [97], |
290
|
|
|
|
|
|
|
97 => [96], |
291
|
|
|
|
|
|
|
); |
292
|
|
|
|
|
|
|
|
293
|
3
|
|
50
|
|
|
7
|
return @{ $superseded{$msg} // [] }; |
|
3
|
|
|
|
|
30
|
|
294
|
|
|
|
|
|
|
} |
295
|
|
|
|
|
|
|
|
296
|
|
|
|
|
|
|
# }}} |
297
|
|
|
|
|
|
|
# {{{ Internal Setters for IRIS.pm |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
sub set_ar { |
300
|
760
|
|
|
760
|
0
|
40300
|
my ( $self, %attrib ) = @_; |
301
|
|
|
|
|
|
|
|
302
|
760
|
100
|
100
|
|
|
3407
|
if ( $attrib{status} and $attrib{status} eq 'c' ) { |
|
|
50
|
66
|
|
|
|
|
303
|
54
|
|
|
|
|
216
|
$self->{has_realtime} = $self->{arrival_has_realtime} = 1; |
304
|
54
|
|
|
|
|
133
|
$self->{arrival_is_cancelled} = 1; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
elsif ( $attrib{status} and $attrib{status} eq 'a' ) { |
307
|
0
|
|
|
|
|
0
|
$self->{arrival_is_additional} = 1; |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
else { |
310
|
706
|
|
|
|
|
1684
|
$self->{arrival_is_additional} = 0; |
311
|
706
|
|
|
|
|
1464
|
$self->{arrival_is_cancelled} = 0; |
312
|
|
|
|
|
|
|
} |
313
|
|
|
|
|
|
|
|
314
|
760
|
50
|
|
|
|
1534
|
if ( $attrib{arrival_hidden} ) { |
315
|
0
|
|
|
|
|
0
|
$self->{arrival_hidden} = $attrib{arrival_hidden}; |
316
|
|
|
|
|
|
|
} |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# unscheduled arrivals may not appear in the plan, but we do need to |
319
|
|
|
|
|
|
|
# know their planned arrival time |
320
|
760
|
100
|
|
|
|
1513
|
if ( $attrib{plan_arrival_ts} ) { |
321
|
|
|
|
|
|
|
$self->{sched_arrival} |
322
|
184
|
|
|
|
|
527
|
= $self->parse_ts( $attrib{plan_arrival_ts} ); |
323
|
|
|
|
|
|
|
} |
324
|
|
|
|
|
|
|
|
325
|
760
|
100
|
|
|
|
170456
|
if ( $attrib{arrival_ts} ) { |
326
|
648
|
|
|
|
|
1879
|
$self->{has_realtime} = $self->{arrival_has_realtime} = 1; |
327
|
648
|
|
|
|
|
1636
|
$self->{arrival} = $self->parse_ts( $attrib{arrival_ts} ); |
328
|
648
|
100
|
|
|
|
595085
|
if ( not $self->{arrival_is_cancelled} ) { |
329
|
|
|
|
|
|
|
$self->{delay} = $self->{arrival_delay} |
330
|
640
|
|
|
|
|
2210
|
= $self->arrival->subtract_datetime( $self->sched_arrival ) |
331
|
|
|
|
|
|
|
->in_units('minutes'); |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
else { |
335
|
112
|
|
|
|
|
516
|
$self->{arrival} = $self->{sched_arrival}; |
336
|
112
|
|
50
|
|
|
559
|
$self->{arrival_delay} //= 0; |
337
|
112
|
|
50
|
|
|
397
|
$self->{delay} //= 0; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
760
|
100
|
|
|
|
326996
|
if ( $attrib{platform} ) { |
341
|
14
|
|
|
|
|
73
|
$self->{platform} = $attrib{platform}; |
342
|
|
|
|
|
|
|
} |
343
|
|
|
|
|
|
|
else { |
344
|
746
|
|
|
|
|
3471
|
$self->{platform} = $self->{sched_platform}; |
345
|
|
|
|
|
|
|
} |
346
|
|
|
|
|
|
|
|
347
|
760
|
100
|
|
|
|
1672
|
if ( defined $attrib{route_pre} ) { |
348
|
190
|
|
50
|
|
|
2551
|
$self->{route_pre} = [ split( qr{[|]}, $attrib{route_pre} // q{} ) ]; |
349
|
190
|
|
|
|
|
891
|
$self->fixup_route( $self->{route_pre} ); |
350
|
190
|
100
|
|
|
|
342
|
if ( @{ $self->{route_pre} } ) { |
|
190
|
|
|
|
|
506
|
|
351
|
144
|
|
|
|
|
518
|
$self->{route_start} = $self->{route_pre}[0]; |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
else { |
355
|
570
|
|
|
|
|
1430
|
$self->{route_pre} = $self->{sched_route_pre}; |
356
|
570
|
|
|
|
|
1521
|
$self->{route_start} = $self->{sched_route_start}; |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
|
|
|
|
|
|
# also only for unscheduled arrivals |
360
|
760
|
100
|
|
|
|
1795
|
if ( $attrib{sched_route_pre} ) { |
361
|
|
|
|
|
|
|
$self->{sched_route_pre} |
362
|
184
|
|
50
|
|
|
2604
|
= [ split( qr{[|]}, $attrib{sched_route_pre} // q{} ) ]; |
363
|
184
|
|
|
|
|
877
|
$self->fixup_route( $self->{sched_route_pre} ); |
364
|
184
|
|
|
|
|
468
|
$self->{sched_route_start} = $self->{sched_route_pre}[0]; |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
760
|
|
|
|
|
2771
|
return $self; |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
sub set_dp { |
371
|
686
|
|
|
686
|
0
|
33878
|
my ( $self, %attrib ) = @_; |
372
|
|
|
|
|
|
|
|
373
|
686
|
100
|
100
|
|
|
2914
|
if ( $attrib{status} and $attrib{status} eq 'c' ) { |
|
|
50
|
66
|
|
|
|
|
374
|
53
|
|
|
|
|
147
|
$self->{has_realtime} = $self->{arrival_has_realtime} = 1; |
375
|
53
|
|
|
|
|
136
|
$self->{departure_is_cancelled} = 1; |
376
|
|
|
|
|
|
|
} |
377
|
|
|
|
|
|
|
elsif ( $attrib{status} and $attrib{status} eq 'a' ) { |
378
|
0
|
|
|
|
|
0
|
$self->{departure_is_additional} = 1; |
379
|
|
|
|
|
|
|
} |
380
|
|
|
|
|
|
|
else { |
381
|
633
|
|
|
|
|
1218
|
$self->{departure_is_additional} = 0; |
382
|
633
|
|
|
|
|
1205
|
$self->{departure_is_cancelled} = 0; |
383
|
|
|
|
|
|
|
} |
384
|
|
|
|
|
|
|
|
385
|
686
|
50
|
|
|
|
1363
|
if ( $attrib{departure_hidden} ) { |
386
|
0
|
|
|
|
|
0
|
$self->{departure_hidden} = $attrib{departure_hidden}; |
387
|
|
|
|
|
|
|
} |
388
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
# unscheduled arrivals may not appear in the plan, but we do need to |
390
|
|
|
|
|
|
|
# know their planned arrival time |
391
|
686
|
100
|
|
|
|
1369
|
if ( $attrib{plan_departure_ts} ) { |
392
|
|
|
|
|
|
|
$self->{sched_departure} |
393
|
176
|
|
|
|
|
500
|
= $self->parse_ts( $attrib{plan_departure_ts} ); |
394
|
|
|
|
|
|
|
} |
395
|
|
|
|
|
|
|
|
396
|
686
|
100
|
|
|
|
159365
|
if ( $attrib{departure_ts} ) { |
397
|
572
|
|
|
|
|
1288
|
$self->{has_realtime} = $self->{departure_has_realtime} = 1; |
398
|
572
|
|
|
|
|
1588
|
$self->{departure} = $self->parse_ts( $attrib{departure_ts} ); |
399
|
572
|
100
|
|
|
|
515030
|
if ( not $self->{departure_is_cancelled} ) { |
400
|
|
|
|
|
|
|
$self->{delay} = $self->{departure_delay} |
401
|
564
|
|
|
|
|
2003
|
= $self->departure->subtract_datetime( $self->sched_departure ) |
402
|
|
|
|
|
|
|
->in_units('minutes'); |
403
|
|
|
|
|
|
|
} |
404
|
|
|
|
|
|
|
} |
405
|
|
|
|
|
|
|
else { |
406
|
114
|
|
|
|
|
379
|
$self->{departure} = $self->{sched_departure}; |
407
|
114
|
|
100
|
|
|
350
|
$self->{delay} //= 0; |
408
|
114
|
|
50
|
|
|
517
|
$self->{departure_delay} //= 0; |
409
|
|
|
|
|
|
|
} |
410
|
|
|
|
|
|
|
|
411
|
686
|
100
|
|
|
|
286070
|
if ( $attrib{platform} ) { |
412
|
7
|
|
|
|
|
50
|
$self->{platform} = $attrib{platform}; |
413
|
|
|
|
|
|
|
} |
414
|
|
|
|
|
|
|
else { |
415
|
679
|
|
|
|
|
1696
|
$self->{platform} = $self->{sched_platform}; |
416
|
|
|
|
|
|
|
} |
417
|
|
|
|
|
|
|
|
418
|
686
|
100
|
|
|
|
1476
|
if ( defined $attrib{route_post} ) { |
419
|
182
|
|
50
|
|
|
2221
|
$self->{route_post} = [ split( qr{[|]}, $attrib{route_post} // q{} ) ]; |
420
|
182
|
|
|
|
|
840
|
$self->fixup_route( $self->{route_post} ); |
421
|
182
|
100
|
|
|
|
314
|
if ( @{ $self->{route_post} } ) { |
|
182
|
|
|
|
|
533
|
|
422
|
137
|
|
|
|
|
392
|
$self->{route_end} = $self->{route_post}[-1]; |
423
|
|
|
|
|
|
|
} |
424
|
|
|
|
|
|
|
} |
425
|
|
|
|
|
|
|
else { |
426
|
504
|
|
|
|
|
1561
|
$self->{route_post} = $self->{sched_route_post}; |
427
|
504
|
|
|
|
|
1372
|
$self->{route_end} = $self->{sched_route_end}; |
428
|
|
|
|
|
|
|
} |
429
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
# also only for unscheduled departures |
431
|
686
|
100
|
|
|
|
1588
|
if ( $attrib{sched_route_post} ) { |
432
|
|
|
|
|
|
|
$self->{sched_route_post} |
433
|
176
|
|
50
|
|
|
2385
|
= [ split( qr{[|]}, $attrib{sched_route_post} // q{} ) ]; |
434
|
176
|
|
|
|
|
865
|
$self->fixup_route( $self->{sched_route_post} ); |
435
|
176
|
|
|
|
|
429
|
$self->{sched_route_end} = $self->{sched_route_post}[-1]; |
436
|
|
|
|
|
|
|
} |
437
|
|
|
|
|
|
|
|
438
|
686
|
|
|
|
|
4263
|
return $self; |
439
|
|
|
|
|
|
|
} |
440
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
sub set_messages { |
442
|
827
|
|
|
827
|
0
|
2710
|
my ( $self, %messages ) = @_; |
443
|
|
|
|
|
|
|
|
444
|
827
|
|
|
|
|
2299
|
$self->{messages} = \%messages; |
445
|
|
|
|
|
|
|
|
446
|
827
|
|
|
|
|
1837
|
return $self; |
447
|
|
|
|
|
|
|
} |
448
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
sub set_realtime { |
450
|
827
|
|
|
827
|
0
|
1629
|
my ( $self, $xmlobj ) = @_; |
451
|
|
|
|
|
|
|
|
452
|
827
|
|
|
|
|
2172
|
$self->{realtime_xml} = $xmlobj; |
453
|
|
|
|
|
|
|
|
454
|
827
|
|
|
|
|
1703
|
return $self; |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
sub add_raw_ref { |
458
|
1
|
|
|
1
|
0
|
40
|
my ( $self, %attrib ) = @_; |
459
|
|
|
|
|
|
|
|
460
|
1
|
|
|
|
|
3
|
push( @{ $self->{refs} }, \%attrib ); |
|
1
|
|
|
|
|
17
|
|
461
|
|
|
|
|
|
|
|
462
|
1
|
|
|
|
|
7
|
return $self; |
463
|
|
|
|
|
|
|
} |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
sub set_unscheduled { |
466
|
121
|
|
|
121
|
0
|
274
|
my ( $self, $unscheduled ) = @_; |
467
|
|
|
|
|
|
|
|
468
|
121
|
|
|
|
|
270
|
$self->{is_unscheduled} = $unscheduled; |
469
|
|
|
|
|
|
|
|
470
|
121
|
|
|
|
|
268
|
return $self; |
471
|
|
|
|
|
|
|
} |
472
|
|
|
|
|
|
|
|
473
|
|
|
|
|
|
|
sub add_arrival_wingref { |
474
|
14
|
|
|
14
|
0
|
45
|
my ( $self, $ref ) = @_; |
475
|
|
|
|
|
|
|
|
476
|
14
|
|
|
|
|
37
|
my $backref = $self; |
477
|
|
|
|
|
|
|
|
478
|
14
|
|
|
|
|
76
|
weaken($ref); |
479
|
14
|
|
|
|
|
50
|
weaken($backref); |
480
|
14
|
|
|
|
|
41
|
$ref->{is_wing} = 1; |
481
|
14
|
|
|
|
|
43
|
$ref->{wing_of} = $backref; |
482
|
14
|
|
|
|
|
44
|
push( @{ $self->{arrival_wings} }, $ref ); |
|
14
|
|
|
|
|
66
|
|
483
|
14
|
|
|
|
|
103
|
return $self; |
484
|
|
|
|
|
|
|
} |
485
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
sub add_departure_wingref { |
487
|
8
|
|
|
8
|
0
|
21
|
my ( $self, $ref ) = @_; |
488
|
|
|
|
|
|
|
|
489
|
8
|
|
|
|
|
18
|
my $backref = $self; |
490
|
|
|
|
|
|
|
|
491
|
8
|
|
|
|
|
68
|
weaken($ref); |
492
|
8
|
|
|
|
|
41
|
weaken($backref); |
493
|
8
|
|
|
|
|
24
|
$ref->{is_wing} = 1; |
494
|
8
|
|
|
|
|
22
|
$ref->{wing_of} = $backref; |
495
|
8
|
|
|
|
|
13
|
push( @{ $self->{departure_wings} }, $ref ); |
|
8
|
|
|
|
|
35
|
|
496
|
8
|
|
|
|
|
30
|
return $self; |
497
|
|
|
|
|
|
|
} |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
sub add_reference { |
500
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $ref ) = @_; |
501
|
|
|
|
|
|
|
|
502
|
0
|
|
|
|
|
0
|
$ref->add_inverse_reference($self); |
503
|
0
|
|
|
|
|
0
|
weaken($ref); |
504
|
0
|
|
|
|
|
0
|
push( @{ $self->{replacement_for} }, $ref ); |
|
0
|
|
|
|
|
0
|
|
505
|
0
|
|
|
|
|
0
|
return $self; |
506
|
|
|
|
|
|
|
} |
507
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
sub merge_with_departure { |
509
|
10
|
|
|
10
|
0
|
24
|
my ( $self, $result ) = @_; |
510
|
|
|
|
|
|
|
|
511
|
|
|
|
|
|
|
# result must be departure-only |
512
|
|
|
|
|
|
|
|
513
|
10
|
|
|
|
|
19
|
$self->{is_transfer} = 1; |
514
|
|
|
|
|
|
|
|
515
|
10
|
|
|
|
|
60
|
$self->{old_train_id} = $self->{train_id}; |
516
|
10
|
|
|
|
|
33
|
$self->{old_train_no} = $self->{train_no}; |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
# departure is preferred over arrival, so overwrite default values |
519
|
10
|
|
|
|
|
28
|
$self->{date} = $result->{date}; |
520
|
10
|
|
|
|
|
32
|
$self->{time} = $result->{time}; |
521
|
10
|
|
|
|
|
33
|
$self->{epoch} = $result->{epoch}; |
522
|
10
|
|
|
|
|
20
|
$self->{datetime} = $result->{datetime}; |
523
|
10
|
|
|
|
|
15
|
$self->{train_id} = $result->{train_id}; |
524
|
10
|
|
|
|
|
23
|
$self->{train_no} = $result->{train_no}; |
525
|
|
|
|
|
|
|
|
526
|
10
|
|
|
|
|
17
|
$self->{departure} = $result->{departure}; |
527
|
10
|
|
|
|
|
17
|
$self->{departure_wings} = $result->{departure_wings}; |
528
|
10
|
|
|
|
|
31
|
$self->{route_end} = $result->{route_end}; |
529
|
10
|
|
|
|
|
26
|
$self->{route_post} = $result->{route_post}; |
530
|
10
|
|
|
|
|
20
|
$self->{sched_departure} = $result->{sched_departure}; |
531
|
10
|
|
|
|
|
23
|
$self->{sched_route_post} = $result->{sched_route_post}; |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
# update realtime info only if applicable |
534
|
10
|
|
33
|
|
|
37
|
$self->{is_cancelled} ||= $result->{is_cancelled}; |
535
|
|
|
|
|
|
|
|
536
|
10
|
|
|
|
|
26
|
return $self; |
537
|
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
sub add_inverse_reference { |
540
|
0
|
|
|
0
|
0
|
0
|
my ( $self, $ref ) = @_; |
541
|
|
|
|
|
|
|
|
542
|
0
|
|
|
|
|
0
|
weaken($ref); |
543
|
0
|
|
|
|
|
0
|
push( @{ $self->{replaced_by} }, $ref ); |
|
0
|
|
|
|
|
0
|
|
544
|
0
|
|
|
|
|
0
|
return $self; |
545
|
|
|
|
|
|
|
} |
546
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
# }}} |
548
|
|
|
|
|
|
|
# {{{ Public Accessors |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
sub is_additional { |
551
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
552
|
|
|
|
|
|
|
|
553
|
0
|
0
|
0
|
|
|
0
|
if ( $self->{arrival_is_additional} and $self->{departure_is_additional} ) { |
554
|
0
|
|
|
|
|
0
|
return 1; |
555
|
|
|
|
|
|
|
} |
556
|
0
|
0
|
0
|
|
|
0
|
if ( $self->{arrival_is_additional} |
557
|
|
|
|
|
|
|
and not defined $self->{departure_is_additional} ) |
558
|
|
|
|
|
|
|
{ |
559
|
0
|
|
|
|
|
0
|
return 1; |
560
|
|
|
|
|
|
|
} |
561
|
0
|
0
|
0
|
|
|
0
|
if ( not defined $self->{arrival_is_additional} |
562
|
|
|
|
|
|
|
and $self->{departure_is_additional} ) |
563
|
|
|
|
|
|
|
{ |
564
|
0
|
|
|
|
|
0
|
return 1; |
565
|
|
|
|
|
|
|
} |
566
|
0
|
|
|
|
|
0
|
return 0; |
567
|
|
|
|
|
|
|
} |
568
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
sub is_cancelled { |
570
|
2
|
|
|
2
|
1
|
2706
|
my ($self) = @_; |
571
|
|
|
|
|
|
|
|
572
|
2
|
50
|
66
|
|
|
17
|
if ( $self->{arrival_is_cancelled} and $self->{departure_is_cancelled} ) { |
573
|
1
|
|
|
|
|
6
|
return 1; |
574
|
|
|
|
|
|
|
} |
575
|
1
|
50
|
33
|
|
|
5
|
if ( $self->{arrival_is_cancelled} |
576
|
|
|
|
|
|
|
and not defined $self->{departure_is_cancelled} ) |
577
|
|
|
|
|
|
|
{ |
578
|
0
|
|
|
|
|
0
|
return 1; |
579
|
|
|
|
|
|
|
} |
580
|
1
|
0
|
33
|
|
|
5
|
if ( not defined $self->{arrival_is_cancelled} |
581
|
|
|
|
|
|
|
and $self->{departure_is_cancelled} ) |
582
|
|
|
|
|
|
|
{ |
583
|
0
|
|
|
|
|
0
|
return 1; |
584
|
|
|
|
|
|
|
} |
585
|
1
|
|
|
|
|
6
|
return 0; |
586
|
|
|
|
|
|
|
} |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
sub additional_stops { |
589
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
590
|
|
|
|
|
|
|
|
591
|
|
|
|
|
|
|
$self->{comparator} //= List::Compare->new( |
592
|
|
|
|
|
|
|
{ |
593
|
0
|
|
0
|
|
|
0
|
lists => [ $self->{sched_route_post}, $self->{route_post} ], |
594
|
|
|
|
|
|
|
unsorted => 1, |
595
|
|
|
|
|
|
|
} |
596
|
|
|
|
|
|
|
); |
597
|
|
|
|
|
|
|
|
598
|
|
|
|
|
|
|
return $self->sorted_sublist( $self->{route_post}, |
599
|
0
|
|
|
|
|
0
|
[ $self->{comparator}->get_complement ] ); |
600
|
|
|
|
|
|
|
} |
601
|
|
|
|
|
|
|
|
602
|
|
|
|
|
|
|
sub canceled_stops { |
603
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
604
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
$self->{comparator} //= List::Compare->new( |
606
|
|
|
|
|
|
|
{ |
607
|
0
|
|
0
|
|
|
0
|
lists => [ $self->{sched_route_post}, $self->{route_post} ], |
608
|
|
|
|
|
|
|
unsorted => 1, |
609
|
|
|
|
|
|
|
} |
610
|
|
|
|
|
|
|
); |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
return $self->sorted_sublist( $self->{sched_route_post}, |
613
|
0
|
|
|
|
|
0
|
[ $self->{comparator}->get_unique ] ); |
614
|
|
|
|
|
|
|
} |
615
|
|
|
|
|
|
|
|
616
|
|
|
|
|
|
|
sub classes { |
617
|
1
|
|
|
1
|
1
|
4404
|
my ($self) = @_; |
618
|
|
|
|
|
|
|
|
619
|
1
|
|
50
|
|
|
11
|
my @classes = split( //, $self->{classes} // q{} ); |
620
|
|
|
|
|
|
|
|
621
|
1
|
|
|
|
|
9
|
return @classes; |
622
|
|
|
|
|
|
|
} |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
sub origin { |
625
|
134
|
|
|
134
|
1
|
89556
|
my ($self) = @_; |
626
|
|
|
|
|
|
|
|
627
|
134
|
|
|
|
|
426
|
return $self->route_start; |
628
|
|
|
|
|
|
|
} |
629
|
|
|
|
|
|
|
|
630
|
|
|
|
|
|
|
sub destination { |
631
|
134
|
|
|
134
|
1
|
94373
|
my ($self) = @_; |
632
|
|
|
|
|
|
|
|
633
|
134
|
|
|
|
|
475
|
return $self->route_end; |
634
|
|
|
|
|
|
|
} |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
sub delay_messages { |
637
|
1
|
|
|
1
|
1
|
6
|
my ($self) = @_; |
638
|
|
|
|
|
|
|
|
639
|
1
|
|
|
|
|
4
|
my @keys = sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
10
|
|
640
|
1
|
|
|
|
|
6
|
my @msgs = grep { $_->[1] eq 'd' } map { $self->{messages}{$_} } @keys; |
|
8
|
|
|
|
|
24
|
|
|
8
|
|
|
|
|
18
|
|
641
|
1
|
|
|
|
|
8
|
my @msgids = uniq( map { $_->[2] } @msgs ); |
|
7
|
|
|
|
|
33
|
|
642
|
1
|
|
|
|
|
5
|
my @ret; |
643
|
|
|
|
|
|
|
|
644
|
1
|
|
|
|
|
4
|
for my $id (@msgids) { |
645
|
2
|
50
|
|
|
|
8
|
if ( my @superseded = $self->superseded_messages($id) ) { |
646
|
0
|
|
|
|
|
0
|
@ret = grep { not( $_->[2] ~~ \@superseded ) } @ret; |
|
0
|
|
|
|
|
0
|
|
647
|
|
|
|
|
|
|
} |
648
|
2
|
|
|
3
|
|
17
|
my $msg = lastval { $_->[2] == $id } @msgs; |
|
3
|
|
|
|
|
7
|
|
649
|
2
|
|
|
|
|
8
|
push( @ret, $msg ); |
650
|
|
|
|
|
|
|
} |
651
|
|
|
|
|
|
|
|
652
|
|
|
|
|
|
|
@ret = reverse |
653
|
1
|
|
|
|
|
12
|
map { [ $self->parse_ts( $_->[0] ), $self->translate_msg( $_->[2] ) ] } |
|
2
|
|
|
|
|
9
|
|
654
|
|
|
|
|
|
|
@ret; |
655
|
|
|
|
|
|
|
|
656
|
1
|
|
|
|
|
11
|
return @ret; |
657
|
|
|
|
|
|
|
} |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
sub arrival_wings { |
660
|
4
|
|
|
4
|
1
|
5201
|
my ($self) = @_; |
661
|
|
|
|
|
|
|
|
662
|
4
|
100
|
|
|
|
15
|
if ( $self->{arrival_wings} ) { |
663
|
2
|
|
|
|
|
3
|
return @{ $self->{arrival_wings} }; |
|
2
|
|
|
|
|
12
|
|
664
|
|
|
|
|
|
|
} |
665
|
2
|
|
|
|
|
55
|
return; |
666
|
|
|
|
|
|
|
} |
667
|
|
|
|
|
|
|
|
668
|
|
|
|
|
|
|
sub departure_wings { |
669
|
6
|
|
|
6
|
1
|
18
|
my ($self) = @_; |
670
|
|
|
|
|
|
|
|
671
|
6
|
100
|
|
|
|
18
|
if ( $self->{departure_wings} ) { |
672
|
4
|
|
|
|
|
12
|
return @{ $self->{departure_wings} }; |
|
4
|
|
|
|
|
29
|
|
673
|
|
|
|
|
|
|
} |
674
|
2
|
|
|
|
|
11
|
return; |
675
|
|
|
|
|
|
|
} |
676
|
|
|
|
|
|
|
|
677
|
|
|
|
|
|
|
sub replaced_by { |
678
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
679
|
|
|
|
|
|
|
|
680
|
0
|
0
|
|
|
|
0
|
if ( $self->{replaced_by} ) { |
681
|
0
|
|
|
|
|
0
|
return @{ $self->{replaced_by} }; |
|
0
|
|
|
|
|
0
|
|
682
|
|
|
|
|
|
|
} |
683
|
0
|
|
|
|
|
0
|
return; |
684
|
|
|
|
|
|
|
} |
685
|
|
|
|
|
|
|
|
686
|
|
|
|
|
|
|
sub replacement_for { |
687
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
688
|
|
|
|
|
|
|
|
689
|
0
|
0
|
|
|
|
0
|
if ( $self->{replacement_for} ) { |
690
|
0
|
|
|
|
|
0
|
return @{ $self->{replacement_for} }; |
|
0
|
|
|
|
|
0
|
|
691
|
|
|
|
|
|
|
} |
692
|
0
|
|
|
|
|
0
|
return; |
693
|
|
|
|
|
|
|
} |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
sub qos_messages { |
696
|
1
|
|
|
1
|
1
|
5
|
my ($self) = @_; |
697
|
|
|
|
|
|
|
|
698
|
1
|
|
|
|
|
47
|
my @keys = sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
19
|
|
699
|
|
|
|
|
|
|
my @msgs |
700
|
1
|
|
|
|
|
8
|
= grep { $_->[1] ~~ [qw[f q]] } map { $self->{messages}{$_} } @keys; |
|
8
|
|
|
|
|
29
|
|
|
8
|
|
|
|
|
19
|
|
701
|
1
|
|
|
|
|
3
|
my @ret; |
702
|
|
|
|
|
|
|
|
703
|
1
|
|
|
|
|
3
|
for my $msg (@msgs) { |
704
|
1
|
50
|
|
|
|
5
|
if ( my @superseded = $self->superseded_messages( $msg->[2] ) ) { |
705
|
0
|
|
|
|
|
0
|
@ret = grep { not( $_->[2] ~~ \@superseded ) } @ret; |
|
0
|
|
|
|
|
0
|
|
706
|
|
|
|
|
|
|
} |
707
|
1
|
|
|
|
|
5
|
@ret = grep { $_->[2] != $msg->[2] } @ret; |
|
0
|
|
|
|
|
0
|
|
708
|
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
# 88 is "no qos shortcomings" and only required to cancel previous qos |
710
|
|
|
|
|
|
|
# messages. Same for 84 ("correct wagon order") and 89 ("reservations |
711
|
|
|
|
|
|
|
# display is working again"). |
712
|
1
|
50
|
33
|
|
|
14
|
if ( $msg->[2] != 84 and $msg->[2] != 88 and $msg->[2] != 89 ) { |
|
|
|
33
|
|
|
|
|
713
|
1
|
|
|
|
|
3
|
push( @ret, $msg ); |
714
|
|
|
|
|
|
|
} |
715
|
|
|
|
|
|
|
} |
716
|
|
|
|
|
|
|
|
717
|
|
|
|
|
|
|
@ret |
718
|
1
|
|
|
|
|
7
|
= map { [ $self->parse_ts( $_->[0] ), $self->translate_msg( $_->[2] ) ] } |
|
1
|
|
|
|
|
6
|
|
719
|
|
|
|
|
|
|
reverse @ret; |
720
|
|
|
|
|
|
|
|
721
|
1
|
|
|
|
|
9
|
return @ret; |
722
|
|
|
|
|
|
|
} |
723
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
sub raw_messages { |
725
|
0
|
|
|
0
|
0
|
0
|
my ($self) = @_; |
726
|
|
|
|
|
|
|
|
727
|
0
|
|
|
|
|
0
|
my @messages = reverse sort keys %{ $self->{messages} }; |
|
0
|
|
|
|
|
0
|
|
728
|
|
|
|
|
|
|
my @ret = map { |
729
|
0
|
|
|
|
|
0
|
[ |
730
|
|
|
|
|
|
|
$self->parse_ts( $self->{messages}->{$_}->[0] ), |
731
|
0
|
|
|
|
|
0
|
$self->{messages}->{$_}->[2] |
732
|
|
|
|
|
|
|
] |
733
|
|
|
|
|
|
|
} @messages; |
734
|
|
|
|
|
|
|
|
735
|
0
|
|
|
|
|
0
|
return @ret; |
736
|
|
|
|
|
|
|
} |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
sub messages { |
739
|
1
|
|
|
1
|
1
|
6
|
my ($self) = @_; |
740
|
|
|
|
|
|
|
|
741
|
1
|
|
|
|
|
2
|
my @messages = reverse sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
12
|
|
742
|
|
|
|
|
|
|
my @ret = map { |
743
|
1
|
|
|
|
|
4
|
[ |
744
|
|
|
|
|
|
|
$self->parse_ts( $self->{messages}->{$_}->[0] ), |
745
|
8
|
|
|
|
|
30
|
$self->translate_msg( $self->{messages}->{$_}->[2] ) |
746
|
|
|
|
|
|
|
] |
747
|
|
|
|
|
|
|
} @messages; |
748
|
|
|
|
|
|
|
|
749
|
1
|
|
|
|
|
24
|
return @ret; |
750
|
|
|
|
|
|
|
} |
751
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
sub info { |
753
|
1
|
|
|
1
|
1
|
17
|
my ($self) = @_; |
754
|
|
|
|
|
|
|
|
755
|
1
|
|
|
|
|
2
|
my @messages = sort keys %{ $self->{messages} }; |
|
1
|
|
|
|
|
14
|
|
756
|
1
|
|
|
|
|
4
|
my @ids = uniq( map { $self->{messages}{$_}->[2] } @messages ); |
|
8
|
|
|
|
|
36
|
|
757
|
|
|
|
|
|
|
|
758
|
1
|
|
|
|
|
6
|
my @info = map { $self->translate_msg($_) } @ids; |
|
3
|
|
|
|
|
10
|
|
759
|
|
|
|
|
|
|
|
760
|
1
|
|
|
|
|
13
|
return @info; |
761
|
|
|
|
|
|
|
} |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
sub line { |
764
|
268
|
|
|
268
|
1
|
504
|
my ($self) = @_; |
765
|
|
|
|
|
|
|
|
766
|
|
|
|
|
|
|
return sprintf( '%s %s', |
767
|
|
|
|
|
|
|
$self->{type} // 'Zug', |
768
|
268
|
|
50
|
|
|
2911
|
$self->{line_no} // $self->{train_no} // '-' ); |
|
|
|
33
|
|
|
|
|
|
|
|
50
|
|
|
|
|
769
|
|
|
|
|
|
|
} |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
sub route_pre { |
772
|
4
|
|
|
4
|
1
|
13
|
my ($self) = @_; |
773
|
|
|
|
|
|
|
|
774
|
4
|
|
|
|
|
9
|
return @{ $self->{route_pre} }; |
|
4
|
|
|
|
|
30
|
|
775
|
|
|
|
|
|
|
} |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
sub route_post { |
778
|
8
|
|
|
8
|
1
|
18
|
my ($self) = @_; |
779
|
|
|
|
|
|
|
|
780
|
8
|
|
|
|
|
13
|
return @{ $self->{route_post} }; |
|
8
|
|
|
|
|
102
|
|
781
|
|
|
|
|
|
|
} |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
sub route { |
784
|
2
|
|
|
2
|
1
|
18
|
my ($self) = @_; |
785
|
|
|
|
|
|
|
|
786
|
2
|
|
|
|
|
8
|
return ( $self->route_pre, $self->{station}, $self->route_post ); |
787
|
|
|
|
|
|
|
} |
788
|
|
|
|
|
|
|
|
789
|
|
|
|
|
|
|
sub train { |
790
|
134
|
|
|
134
|
1
|
97344
|
my ($self) = @_; |
791
|
|
|
|
|
|
|
|
792
|
134
|
|
|
|
|
388
|
return $self->line; |
793
|
|
|
|
|
|
|
} |
794
|
|
|
|
|
|
|
|
795
|
|
|
|
|
|
|
sub route_interesting { |
796
|
4
|
|
|
4
|
1
|
14
|
my ( $self, $max_parts ) = @_; |
797
|
|
|
|
|
|
|
|
798
|
4
|
|
|
|
|
14
|
my @via = $self->route_post; |
799
|
4
|
|
|
|
|
9
|
my ( @via_main, @via_show, $last_stop ); |
800
|
4
|
|
50
|
|
|
25
|
$max_parts //= 3; |
801
|
|
|
|
|
|
|
|
802
|
|
|
|
|
|
|
# Centraal: dutch main station (Hbf in .nl) |
803
|
|
|
|
|
|
|
# HB: swiss main station (Hbf in .ch) |
804
|
|
|
|
|
|
|
# hl.n.: czech main station (Hbf in .cz) |
805
|
4
|
|
|
|
|
8
|
for my $stop (@via) { |
806
|
16
|
100
|
|
|
|
70
|
if ( $stop =~ m{ HB $ | hl\.n\. $ | Hbf | Centraal | Flughafen }x ) { |
807
|
9
|
|
|
|
|
18
|
push( @via_main, $stop ); |
808
|
|
|
|
|
|
|
} |
809
|
|
|
|
|
|
|
} |
810
|
|
|
|
|
|
|
$last_stop |
811
|
4
|
50
|
|
|
|
32
|
= $self->{route_post_incomplete} ? $self->{route_end} : pop(@via); |
812
|
|
|
|
|
|
|
|
813
|
4
|
100
|
100
|
|
|
19
|
if ( @via_main and $via_main[-1] eq $last_stop ) { |
814
|
2
|
|
|
|
|
3
|
pop(@via_main); |
815
|
|
|
|
|
|
|
} |
816
|
4
|
100
|
66
|
|
|
23
|
if ( @via and $via[-1] eq $last_stop ) { |
817
|
3
|
|
|
|
|
7
|
pop(@via); |
818
|
|
|
|
|
|
|
} |
819
|
|
|
|
|
|
|
|
820
|
4
|
100
|
66
|
|
|
17
|
if ( @via_main and @via and $via[0] eq $via_main[0] ) { |
|
|
|
100
|
|
|
|
|
821
|
1
|
|
|
|
|
2
|
shift(@via_main); |
822
|
|
|
|
|
|
|
} |
823
|
|
|
|
|
|
|
|
824
|
4
|
100
|
|
|
|
11
|
if ( @via < $max_parts ) { |
825
|
2
|
|
|
|
|
5
|
@via_show = @via; |
826
|
|
|
|
|
|
|
} |
827
|
|
|
|
|
|
|
else { |
828
|
2
|
100
|
|
|
|
6
|
if ( @via_main >= $max_parts ) { |
829
|
1
|
|
|
|
|
4
|
@via_show = ( $via[0] ); |
830
|
|
|
|
|
|
|
} |
831
|
|
|
|
|
|
|
else { |
832
|
1
|
|
|
|
|
9
|
@via_show = splice( @via, 0, $max_parts - @via_main ); |
833
|
|
|
|
|
|
|
} |
834
|
|
|
|
|
|
|
|
835
|
2
|
|
66
|
|
|
11
|
while ( @via_show < $max_parts and @via_main ) { |
836
|
4
|
|
|
|
|
8
|
my $stop = shift(@via_main); |
837
|
4
|
50
|
33
|
|
|
19
|
if ( $stop ~~ \@via_show or $stop eq $last_stop ) { |
838
|
0
|
|
|
|
|
0
|
next; |
839
|
|
|
|
|
|
|
} |
840
|
4
|
|
|
|
|
16
|
push( @via_show, $stop ); |
841
|
|
|
|
|
|
|
} |
842
|
|
|
|
|
|
|
} |
843
|
|
|
|
|
|
|
|
844
|
4
|
|
|
|
|
23
|
for (@via_show) { |
845
|
6
|
|
|
|
|
42
|
s{ \s? Hbf .* }{}x; |
846
|
|
|
|
|
|
|
} |
847
|
|
|
|
|
|
|
|
848
|
4
|
|
|
|
|
46
|
return @via_show; |
849
|
|
|
|
|
|
|
|
850
|
|
|
|
|
|
|
} |
851
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
sub sched_route_pre { |
853
|
2
|
|
|
2
|
1
|
66
|
my ($self) = @_; |
854
|
|
|
|
|
|
|
|
855
|
2
|
|
|
|
|
6
|
return @{ $self->{sched_route_pre} }; |
|
2
|
|
|
|
|
18
|
|
856
|
|
|
|
|
|
|
} |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
sub sched_route_post { |
859
|
2
|
|
|
2
|
1
|
5
|
my ($self) = @_; |
860
|
|
|
|
|
|
|
|
861
|
2
|
|
|
|
|
4
|
return @{ $self->{sched_route_post} }; |
|
2
|
|
|
|
|
23
|
|
862
|
|
|
|
|
|
|
} |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
sub sched_route { |
865
|
1
|
|
|
1
|
1
|
4
|
my ($self) = @_; |
866
|
|
|
|
|
|
|
|
867
|
|
|
|
|
|
|
return ( $self->sched_route_pre, $self->{station}, |
868
|
1
|
|
|
|
|
23
|
$self->sched_route_post ); |
869
|
|
|
|
|
|
|
} |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
sub translate_msg { |
872
|
14
|
|
|
14
|
0
|
9971
|
my ( $self, $msg ) = @_; |
873
|
|
|
|
|
|
|
|
874
|
14
|
|
33
|
|
|
92
|
return $translation{$msg} // "?($msg)"; |
875
|
|
|
|
|
|
|
} |
876
|
|
|
|
|
|
|
|
877
|
|
|
|
|
|
|
sub TO_JSON { |
878
|
0
|
|
|
0
|
0
|
|
my ($self) = @_; |
879
|
|
|
|
|
|
|
|
880
|
0
|
|
|
|
|
|
my %copy = %{$self}; |
|
0
|
|
|
|
|
|
|
881
|
0
|
|
|
|
|
|
delete $copy{realtime_xml}; |
882
|
0
|
|
|
|
|
|
delete $copy{strptime_obj}; |
883
|
|
|
|
|
|
|
|
884
|
0
|
|
|
|
|
|
for my $ref_key ( |
885
|
|
|
|
|
|
|
qw(arrival_wings departure_wings replaced_by replacement_for)) |
886
|
|
|
|
|
|
|
{ |
887
|
0
|
|
|
|
|
|
delete $copy{$ref_key}; |
888
|
0
|
|
0
|
|
|
|
for my $train_ref ( @{ $self->{$ref_key} // [] } ) { |
|
0
|
|
|
|
|
|
|
889
|
|
|
|
|
|
|
push( |
890
|
0
|
|
|
|
|
|
@{ $copy{$ref_key} }, |
|
0
|
|
|
|
|
|
|
891
|
|
|
|
|
|
|
{ |
892
|
|
|
|
|
|
|
raw_id => $train_ref->raw_id, |
893
|
|
|
|
|
|
|
train => $train_ref->train, |
894
|
|
|
|
|
|
|
train_no => $train_ref->train_no, |
895
|
|
|
|
|
|
|
type => $train_ref->type, |
896
|
|
|
|
|
|
|
} |
897
|
|
|
|
|
|
|
); |
898
|
|
|
|
|
|
|
} |
899
|
|
|
|
|
|
|
} |
900
|
|
|
|
|
|
|
|
901
|
0
|
|
|
|
|
|
delete $copy{wing_of}; |
902
|
0
|
0
|
|
|
|
|
if ( my $train_ref = $self->wing_of ) { |
903
|
|
|
|
|
|
|
$copy{wing_of} = { |
904
|
0
|
|
|
|
|
|
raw_id => $train_ref->raw_id, |
905
|
|
|
|
|
|
|
train => $train_ref->train, |
906
|
|
|
|
|
|
|
train_no => $train_ref->train_no, |
907
|
|
|
|
|
|
|
type => $train_ref->type, |
908
|
|
|
|
|
|
|
}; |
909
|
|
|
|
|
|
|
} |
910
|
|
|
|
|
|
|
|
911
|
0
|
|
|
|
|
|
for my $datetime_key ( |
912
|
|
|
|
|
|
|
qw(arrival departure sched_arrival sched_departure start datetime)) |
913
|
|
|
|
|
|
|
{ |
914
|
0
|
0
|
|
|
|
|
if ( defined $copy{$datetime_key} ) { |
915
|
0
|
|
|
|
|
|
$copy{$datetime_key} = $copy{$datetime_key}->epoch; |
916
|
|
|
|
|
|
|
} |
917
|
|
|
|
|
|
|
} |
918
|
|
|
|
|
|
|
|
919
|
0
|
|
|
|
|
|
return {%copy}; |
920
|
|
|
|
|
|
|
} |
921
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
# }}} |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
1; |
925
|
|
|
|
|
|
|
|
926
|
|
|
|
|
|
|
__END__ |
927
|
|
|
|
|
|
|
|
928
|
|
|
|
|
|
|
=head1 NAME |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
Travel::Status::DE::IRIS::Result - Information about a single |
931
|
|
|
|
|
|
|
arrival/departure received by Travel::Status::DE::IRIS |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
=head1 SYNOPSIS |
934
|
|
|
|
|
|
|
|
935
|
|
|
|
|
|
|
for my $result ($status->results) { |
936
|
|
|
|
|
|
|
printf( |
937
|
|
|
|
|
|
|
"At %s: %s to %s from platform %s\n", |
938
|
|
|
|
|
|
|
$result->time, |
939
|
|
|
|
|
|
|
$result->line, |
940
|
|
|
|
|
|
|
$result->destination, |
941
|
|
|
|
|
|
|
$result->platform, |
942
|
|
|
|
|
|
|
); |
943
|
|
|
|
|
|
|
} |
944
|
|
|
|
|
|
|
|
945
|
|
|
|
|
|
|
=head1 VERSION |
946
|
|
|
|
|
|
|
|
947
|
|
|
|
|
|
|
version 1.90 |
948
|
|
|
|
|
|
|
|
949
|
|
|
|
|
|
|
=head1 DESCRIPTION |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
Travel::Status::DE::IRIs::Result describes a single arrival/departure |
952
|
|
|
|
|
|
|
as obtained by Travel::Status::DE::IRIS. It contains information about |
953
|
|
|
|
|
|
|
the platform, time, route and more. |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
=head1 METHODS |
956
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
=head2 ACCESSORS |
958
|
|
|
|
|
|
|
|
959
|
|
|
|
|
|
|
=over |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=item $result->additional_stops |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
Returns served stops which are not part of the schedule. I.e., this is the |
964
|
|
|
|
|
|
|
set of actual stops (B<route_post>) minus the set of scheduled stops |
965
|
|
|
|
|
|
|
(B<sched_route_post>). |
966
|
|
|
|
|
|
|
|
967
|
|
|
|
|
|
|
=item $result->arrival |
968
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
DateTime(3pm) object for the arrival date and time. undef if the |
970
|
|
|
|
|
|
|
train starts here. Contains realtime data if available. |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
=item $result->arrival_delay |
973
|
|
|
|
|
|
|
|
974
|
|
|
|
|
|
|
Estimated arrival delay in minutes (integer number). undef if no realtime |
975
|
|
|
|
|
|
|
data is available, the train starts at the specified station, or there is |
976
|
|
|
|
|
|
|
no scheduled arrival time (e.g. due to diversions). May be negative. |
977
|
|
|
|
|
|
|
|
978
|
|
|
|
|
|
|
=item $result->arrival_has_realtime |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
True if "arrival" is based on real-time data. |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
=item $result->arrival_hidden |
983
|
|
|
|
|
|
|
|
984
|
|
|
|
|
|
|
True if arrival should not be displayed to customers. |
985
|
|
|
|
|
|
|
This often indicates an entry-only stop near the beginning of a train's journey. |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
=item $result->arrival_is_additional |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
True if the arrival at this stop is an additional (unscheduled) event, i.e., |
990
|
|
|
|
|
|
|
if the train started its journey earlier than planned. |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
=item $result->arrival_is_cancelled |
993
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
True if the arrival at this stop has been cancelled. |
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
=item $result->arrival_wings |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
Returns a list of weakened references to Travel::Status::DE::IRIS::Result(3pm) |
999
|
|
|
|
|
|
|
objects which are coupled to this train on arrival. Returns nothing (false / |
1000
|
|
|
|
|
|
|
empty list) otherwise. |
1001
|
|
|
|
|
|
|
|
1002
|
|
|
|
|
|
|
=item $result->canceled_stops |
1003
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
Returns stops which are scheduled, but will not be served by this train. |
1005
|
|
|
|
|
|
|
I.e., this is the set of scheduled stops (B<sched_route_post>) minus the set of |
1006
|
|
|
|
|
|
|
actual stops (B<route_post>). |
1007
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
=item $result->classes |
1009
|
|
|
|
|
|
|
|
1010
|
|
|
|
|
|
|
List of characters indicating the class(es) of this train, may be empty. This |
1011
|
|
|
|
|
|
|
is slighty related to B<type>, but more generic. At this time, the following |
1012
|
|
|
|
|
|
|
classes are known: |
1013
|
|
|
|
|
|
|
|
1014
|
|
|
|
|
|
|
D Non-DB train. Usually local transport |
1015
|
|
|
|
|
|
|
D,F Non-DB train, long distance transport |
1016
|
|
|
|
|
|
|
F "Fernverkehr", long-distance transport |
1017
|
|
|
|
|
|
|
N "Nahverkehr", local and regional transport |
1018
|
|
|
|
|
|
|
S S-Bahn, rather slow local/regional transport |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
=item $result->date |
1021
|
|
|
|
|
|
|
|
1022
|
|
|
|
|
|
|
Scheduled departure date if available, arrival date otherwise (e.g. if the |
1023
|
|
|
|
|
|
|
train ends here). String in dd.mm.YYYY format. Does not contain realtime data. |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
=item $result->datetime |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
DateTime(3pm) object for departure if available, arrival otherwise. Does not |
1028
|
|
|
|
|
|
|
contain realtime data. |
1029
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
=item $result->delay |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
Estimated delay in minutes (integer number). Defaults to the departure delay, |
1033
|
|
|
|
|
|
|
except for trains which terminate at the specifed station. Similar to |
1034
|
|
|
|
|
|
|
C<< $result->departure_delay // $result->arrival_delay >>. undef if |
1035
|
|
|
|
|
|
|
no realtime data is available. May be negative. |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
=item $result->delay_messages |
1038
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
Get all delay messages entered for this train. Returns a list of [datetime, |
1040
|
|
|
|
|
|
|
string] listrefs sorted by newest first. The datetime part is a DateTime(3pm) |
1041
|
|
|
|
|
|
|
object corresponding to the point in time when the message was entered, the |
1042
|
|
|
|
|
|
|
string is the message. If a delay reason was entered more than once, only its |
1043
|
|
|
|
|
|
|
most recent record will be returned. |
1044
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
=item $result->departure |
1046
|
|
|
|
|
|
|
|
1047
|
|
|
|
|
|
|
DateTime(3pm) object for the departure date and time. undef if the train ends |
1048
|
|
|
|
|
|
|
here. Contains realtime data if available. |
1049
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
=item $result->departure_delay |
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
Estimated departure delay in minutes (integer number). undef if no realtime |
1053
|
|
|
|
|
|
|
data is available, the train terminates at the specified station, or there is |
1054
|
|
|
|
|
|
|
no scheduled departure time (e.g. due to diversions). May be negative. |
1055
|
|
|
|
|
|
|
|
1056
|
|
|
|
|
|
|
=item $result->departure_has_realtime |
1057
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
True if "departure" is based on real-time data. |
1059
|
|
|
|
|
|
|
|
1060
|
|
|
|
|
|
|
=item $result->departure_hidden |
1061
|
|
|
|
|
|
|
|
1062
|
|
|
|
|
|
|
True if departure should not be displayed to customers. |
1063
|
|
|
|
|
|
|
This often indicates an exit-only stop near the end of a train's journey. |
1064
|
|
|
|
|
|
|
|
1065
|
|
|
|
|
|
|
=item $result->departure_is_additional |
1066
|
|
|
|
|
|
|
|
1067
|
|
|
|
|
|
|
True if the train's departure at this stop is unscheduled (additional), i.e., |
1068
|
|
|
|
|
|
|
the route has been extended past its scheduled terminal stop. |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
=item $result->departure_is_cancelled |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
True if the train's departure at this stop has been cancelled, i.e., the train |
1073
|
|
|
|
|
|
|
terminates here and does not continue its scheduled journey. |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
=item $result->departure_wings |
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
Returns a list of weakened references to Travel::Status::DE::IRIS::Result(3pm) |
1078
|
|
|
|
|
|
|
objects which are coupled to this train on departure. Returns nothing (false / |
1079
|
|
|
|
|
|
|
empty list) otherwise. |
1080
|
|
|
|
|
|
|
|
1081
|
|
|
|
|
|
|
=item $result->destination |
1082
|
|
|
|
|
|
|
|
1083
|
|
|
|
|
|
|
Alias for route_end. |
1084
|
|
|
|
|
|
|
|
1085
|
|
|
|
|
|
|
=item $result->has_realtime |
1086
|
|
|
|
|
|
|
|
1087
|
|
|
|
|
|
|
True if arrival or departure time are based on real-time data. Note that this |
1088
|
|
|
|
|
|
|
is different from C<< defined($esult->delay) >>. If delay is defined, some kind |
1089
|
|
|
|
|
|
|
of realtime information for the train is available, but not necessarily its |
1090
|
|
|
|
|
|
|
arrival/departure time. If has_realtime is true, arrival/departure time are |
1091
|
|
|
|
|
|
|
available. This behaviour may change in the future. |
1092
|
|
|
|
|
|
|
|
1093
|
|
|
|
|
|
|
=item $result->info |
1094
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
List of information strings. Contains both reasons for delays (which may or |
1096
|
|
|
|
|
|
|
may not be up-to-date) and generic information such as missing carriages or |
1097
|
|
|
|
|
|
|
broken toilets. |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
=item $result->is_additional |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
True if the train's arrival and departure at the stop are unscheduled |
1102
|
|
|
|
|
|
|
additional stops, false otherwise. |
1103
|
|
|
|
|
|
|
|
1104
|
|
|
|
|
|
|
=item $result->is_cancelled |
1105
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
True if the train was cancelled, false otherwise. Note that this does not |
1107
|
|
|
|
|
|
|
contain information about replacement trains or route diversions. |
1108
|
|
|
|
|
|
|
|
1109
|
|
|
|
|
|
|
=item $result->is_transfer |
1110
|
|
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
True if the train changes its ID at the current station, false otherwise. |
1112
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
An ID change means: There are two results in the system (e.g. RE 10228 |
1114
|
|
|
|
|
|
|
ME<uuml>nster -> Duisburg, RE 30028 Duisburg -> DE<uuml>sseldorf), but they are |
1115
|
|
|
|
|
|
|
the same train (RE line 2 from ME<uuml>nster to DE<uuml>sseldorf in this case) |
1116
|
|
|
|
|
|
|
and should be treated as such. In this case, Travel::Status::DE::IRIS merges |
1117
|
|
|
|
|
|
|
the results and indicates it by setting B<is_transfer> to a true value. |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
In case of a transfer, B<train_id> and B<train_no> are set to the "new" |
1120
|
|
|
|
|
|
|
value, the old ones are available in B<old_train_id> and B<old_train_no>. |
1121
|
|
|
|
|
|
|
|
1122
|
|
|
|
|
|
|
=item $result->is_unscheduled |
1123
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
True if the train does not appear in the requested plans. This can happen |
1125
|
|
|
|
|
|
|
because of two reasons: Either the scheduled time and the actual time are so |
1126
|
|
|
|
|
|
|
far apart that it should've arrived/departed long ago, or it really is an |
1127
|
|
|
|
|
|
|
unscheduled train. In that case, it can be a replacement or an additional |
1128
|
|
|
|
|
|
|
train. There is no logic to distinguish these cases yet. |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
=item $result->is_wing |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
Returns true if this result is a wing, false otherwise. |
1133
|
|
|
|
|
|
|
A wing is a train which has its own ID and destination, but is currently |
1134
|
|
|
|
|
|
|
coupled to another train and shares all or some of its route. |
1135
|
|
|
|
|
|
|
|
1136
|
|
|
|
|
|
|
=item $result->line |
1137
|
|
|
|
|
|
|
|
1138
|
|
|
|
|
|
|
Train type with line (such as C<< S 1 >>) if available, type with number |
1139
|
|
|
|
|
|
|
(suc as C<< RE 10126 >>) otherwise. |
1140
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
=item $result->line_no |
1142
|
|
|
|
|
|
|
|
1143
|
|
|
|
|
|
|
Number of the line, undef if unknown. Seems to be set only for S-Bahn and |
1144
|
|
|
|
|
|
|
regional trains. Note that some regional and most long-distance trains do |
1145
|
|
|
|
|
|
|
not have this field set, even if they have a common line number. |
1146
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
Example: For the line C<< S 1 >>, line_no will return C<< 1 >>. |
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
=item $result->messages |
1150
|
|
|
|
|
|
|
|
1151
|
|
|
|
|
|
|
Get all qos and delay messages ever entered for this train. Returns a list of |
1152
|
|
|
|
|
|
|
[datetime, string] listrefs sorted by newest first. The datetime part is a |
1153
|
|
|
|
|
|
|
DateTime(3pm) object corresponding to the point in time when the message was |
1154
|
|
|
|
|
|
|
entered, the string is the message. Note that neither duplicates nor superseded |
1155
|
|
|
|
|
|
|
messages are filtered from this list. |
1156
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
=item $result->old_train_id |
1158
|
|
|
|
|
|
|
|
1159
|
|
|
|
|
|
|
Numeric ID of the pre-transfer train. Seems to be unique for a year and |
1160
|
|
|
|
|
|
|
trackable across stations. Only defined if a transfer took place, |
1161
|
|
|
|
|
|
|
see also B<is_transfer>. |
1162
|
|
|
|
|
|
|
|
1163
|
|
|
|
|
|
|
=item $result->old_train_no |
1164
|
|
|
|
|
|
|
|
1165
|
|
|
|
|
|
|
Number of the pre-tarnsfer train, unique per day. E.g. C<< 2225 >> for |
1166
|
|
|
|
|
|
|
C<< IC 2225 >>. Only defined if a transfer took |
1167
|
|
|
|
|
|
|
place, see also B<is_transfer>. |
1168
|
|
|
|
|
|
|
|
1169
|
|
|
|
|
|
|
=item $result->origin |
1170
|
|
|
|
|
|
|
|
1171
|
|
|
|
|
|
|
Alias for route_start. |
1172
|
|
|
|
|
|
|
|
1173
|
|
|
|
|
|
|
=item $result->qos_messages |
1174
|
|
|
|
|
|
|
|
1175
|
|
|
|
|
|
|
Get all current qos messages for this train. Returns a list of [datetime, |
1176
|
|
|
|
|
|
|
string] listrefs sorted by newest first. The datetime part is a DateTime(3pm) |
1177
|
|
|
|
|
|
|
object corresponding to the point in time when the message was entered, the |
1178
|
|
|
|
|
|
|
string is the message. Contains neither superseded messages nor duplicates (in |
1179
|
|
|
|
|
|
|
case of a duplicate, only the most recent message is present) |
1180
|
|
|
|
|
|
|
|
1181
|
|
|
|
|
|
|
=item $result->platform |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
Arrival/departure platform as string, undef if unknown. Note that this is |
1184
|
|
|
|
|
|
|
not neccessarily a number, platform sections may be included (e.g. |
1185
|
|
|
|
|
|
|
C<< 3a/b >>). |
1186
|
|
|
|
|
|
|
|
1187
|
|
|
|
|
|
|
=item $result->raw_id |
1188
|
|
|
|
|
|
|
|
1189
|
|
|
|
|
|
|
Raw ID of the departure, e.g. C<< -4642102742373784975-1401031322-6 >>. |
1190
|
|
|
|
|
|
|
The first part appears to be this train's UUID (can be tracked across |
1191
|
|
|
|
|
|
|
multiple stations), the second the YYmmddHHMM departure timestamp at its |
1192
|
|
|
|
|
|
|
start station, and the third the count of this station in the train's schedule |
1193
|
|
|
|
|
|
|
(in this case, it's the sixth from thestart station). |
1194
|
|
|
|
|
|
|
|
1195
|
|
|
|
|
|
|
About half of all departure IDs do not contain the leading minus (C<< - >>) |
1196
|
|
|
|
|
|
|
seen in this example. The reason for this is unknown. |
1197
|
|
|
|
|
|
|
|
1198
|
|
|
|
|
|
|
This is a developer option. It may be removed without prior warning. |
1199
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
=item $result->realtime_xml |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
XML::LibXML::Node(3pm) object containing all realtime data. undef if none is |
1203
|
|
|
|
|
|
|
available. |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
This is a developer option. It may be removed without prior warning. |
1206
|
|
|
|
|
|
|
|
1207
|
|
|
|
|
|
|
=item $result->replaced_by |
1208
|
|
|
|
|
|
|
|
1209
|
|
|
|
|
|
|
Returns a list of weakened references to Travel::Status::DE::IRIS::Result(3pm) |
1210
|
|
|
|
|
|
|
objects which replace the (usually cancelled) arrival/departure of this train. |
1211
|
|
|
|
|
|
|
Returns nothing (false / empty list) otherwise. |
1212
|
|
|
|
|
|
|
|
1213
|
|
|
|
|
|
|
=item $result->replacement_for |
1214
|
|
|
|
|
|
|
|
1215
|
|
|
|
|
|
|
Returns a list of weakened references to Travel::Status::DE::IRIS::Result(3pm) |
1216
|
|
|
|
|
|
|
objects which this (usually unplanned) train is meant to replace. Returns |
1217
|
|
|
|
|
|
|
nothing (false / empty list) otherwise. |
1218
|
|
|
|
|
|
|
|
1219
|
|
|
|
|
|
|
=item $result->route |
1220
|
|
|
|
|
|
|
|
1221
|
|
|
|
|
|
|
List of all stations served by this train, according to its schedule. Does |
1222
|
|
|
|
|
|
|
not contain realtime data. |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
=item $result->route_end |
1225
|
|
|
|
|
|
|
|
1226
|
|
|
|
|
|
|
Name of the last station served by this train. |
1227
|
|
|
|
|
|
|
|
1228
|
|
|
|
|
|
|
=item $result->route_interesting |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
List of up to three "interesting" stations served by this train, subset of |
1231
|
|
|
|
|
|
|
route_post. Usually contains the next stop and one or two major stations after |
1232
|
|
|
|
|
|
|
that. Does not contain realtime data. |
1233
|
|
|
|
|
|
|
|
1234
|
|
|
|
|
|
|
=item $result->route_pre |
1235
|
|
|
|
|
|
|
|
1236
|
|
|
|
|
|
|
List of station names the train passed (or will have passed) before this stop. |
1237
|
|
|
|
|
|
|
|
1238
|
|
|
|
|
|
|
=item $result->route_post |
1239
|
|
|
|
|
|
|
|
1240
|
|
|
|
|
|
|
List of station names the train will pass after this stop. |
1241
|
|
|
|
|
|
|
|
1242
|
|
|
|
|
|
|
=item $result->route_start |
1243
|
|
|
|
|
|
|
|
1244
|
|
|
|
|
|
|
Name of the first station served by this train. |
1245
|
|
|
|
|
|
|
|
1246
|
|
|
|
|
|
|
=item $result->sched_arrival |
1247
|
|
|
|
|
|
|
|
1248
|
|
|
|
|
|
|
DateTime(3pm) object for the scheduled arrival date and time. undef if the |
1249
|
|
|
|
|
|
|
train starts here. |
1250
|
|
|
|
|
|
|
|
1251
|
|
|
|
|
|
|
=item $result->sched_departure |
1252
|
|
|
|
|
|
|
|
1253
|
|
|
|
|
|
|
DateTime(3pm) object for the scehduled departure date and time. undef if the |
1254
|
|
|
|
|
|
|
train ends here. |
1255
|
|
|
|
|
|
|
|
1256
|
|
|
|
|
|
|
=item $result->sched_platform |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
Scheduled Arrival/departure platform as string, undef if unknown. Note that |
1259
|
|
|
|
|
|
|
this is not neccessarily a number, platform sections may be included (e.g. C<< |
1260
|
|
|
|
|
|
|
3a/b >>). |
1261
|
|
|
|
|
|
|
|
1262
|
|
|
|
|
|
|
=item $result->sched_route |
1263
|
|
|
|
|
|
|
|
1264
|
|
|
|
|
|
|
List of all stations served by this train, according to its schedule. Does |
1265
|
|
|
|
|
|
|
not contain realtime data. |
1266
|
|
|
|
|
|
|
|
1267
|
|
|
|
|
|
|
=item $result->sched_route_end |
1268
|
|
|
|
|
|
|
|
1269
|
|
|
|
|
|
|
Name of the last station served by this train according to its schedule. |
1270
|
|
|
|
|
|
|
|
1271
|
|
|
|
|
|
|
=item $result->sched_route_pre |
1272
|
|
|
|
|
|
|
|
1273
|
|
|
|
|
|
|
List of station names the train is scheduled to pass before this stop. |
1274
|
|
|
|
|
|
|
|
1275
|
|
|
|
|
|
|
=item $result->sched_route_post |
1276
|
|
|
|
|
|
|
|
1277
|
|
|
|
|
|
|
List of station names the train is scheduled to pass after this stop. |
1278
|
|
|
|
|
|
|
|
1279
|
|
|
|
|
|
|
=item $result->sched_route_start |
1280
|
|
|
|
|
|
|
|
1281
|
|
|
|
|
|
|
Name of the first station served by this train according to its schedule. |
1282
|
|
|
|
|
|
|
|
1283
|
|
|
|
|
|
|
=item $result->start |
1284
|
|
|
|
|
|
|
|
1285
|
|
|
|
|
|
|
DateTime(3pm) object for the scheduled start of the train on its route |
1286
|
|
|
|
|
|
|
(i.e. the departure time at its first station). |
1287
|
|
|
|
|
|
|
|
1288
|
|
|
|
|
|
|
=item $result->station |
1289
|
|
|
|
|
|
|
|
1290
|
|
|
|
|
|
|
Name of the station this train result belongs to. |
1291
|
|
|
|
|
|
|
|
1292
|
|
|
|
|
|
|
=item $result->station_uic |
1293
|
|
|
|
|
|
|
|
1294
|
|
|
|
|
|
|
EVA number of the station this train result belongs to. |
1295
|
|
|
|
|
|
|
This is often, but not always, identical with the UIC station number. |
1296
|
|
|
|
|
|
|
|
1297
|
|
|
|
|
|
|
=item $result->stop_no |
1298
|
|
|
|
|
|
|
|
1299
|
|
|
|
|
|
|
Number of this stop on the train's route. 1 if it's the start station, 2 |
1300
|
|
|
|
|
|
|
for the stop after that, and so on. |
1301
|
|
|
|
|
|
|
|
1302
|
|
|
|
|
|
|
=item $result->time |
1303
|
|
|
|
|
|
|
|
1304
|
|
|
|
|
|
|
Scheduled departure time if available, arrival time otherwise (e.g. if the |
1305
|
|
|
|
|
|
|
train ends here). String in HH:MM format. Does not contain realtime data. |
1306
|
|
|
|
|
|
|
|
1307
|
|
|
|
|
|
|
=item $result->train |
1308
|
|
|
|
|
|
|
|
1309
|
|
|
|
|
|
|
Alias for line. |
1310
|
|
|
|
|
|
|
|
1311
|
|
|
|
|
|
|
=item $result->train_id |
1312
|
|
|
|
|
|
|
|
1313
|
|
|
|
|
|
|
Numeric ID of this train, trackable across stations and days. For instance, the |
1314
|
|
|
|
|
|
|
S 31128 (S1) to Solingen, starting in Dortmund on 19:23, has the ID |
1315
|
|
|
|
|
|
|
2404170432985554630 on each station it passes and (usually) on every day of the |
1316
|
|
|
|
|
|
|
year. Note that it may change during the yearly itinerary update in december. |
1317
|
|
|
|
|
|
|
|
1318
|
|
|
|
|
|
|
=item $result->train_no |
1319
|
|
|
|
|
|
|
|
1320
|
|
|
|
|
|
|
Number of this train, unique per day. E.g. C<< 2225 >> for C<< IC 2225 >>. |
1321
|
|
|
|
|
|
|
|
1322
|
|
|
|
|
|
|
=item $result->type |
1323
|
|
|
|
|
|
|
|
1324
|
|
|
|
|
|
|
Type of this train, e.g. C<< S >> for S-Bahn, C<< RE >> for Regional-Express, |
1325
|
|
|
|
|
|
|
C<< ICE >> for InterCity-Express. |
1326
|
|
|
|
|
|
|
|
1327
|
|
|
|
|
|
|
=item $result->wing_of |
1328
|
|
|
|
|
|
|
|
1329
|
|
|
|
|
|
|
If B<is_wing> is true, returns a weakened reference to the |
1330
|
|
|
|
|
|
|
Travel::Status::DE::IRIS::Result(3pm) object which this train is a wing of. So |
1331
|
|
|
|
|
|
|
far, it seems that a train is either not a wing or a wing of exactly one other |
1332
|
|
|
|
|
|
|
train. Returns undef if B<is_wing> is false. |
1333
|
|
|
|
|
|
|
|
1334
|
|
|
|
|
|
|
=back |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
=head2 INTERNAL |
1337
|
|
|
|
|
|
|
|
1338
|
|
|
|
|
|
|
=over |
1339
|
|
|
|
|
|
|
|
1340
|
|
|
|
|
|
|
=item $result = Travel::Status::DE::IRIS::Result->new(I<%data>) |
1341
|
|
|
|
|
|
|
|
1342
|
|
|
|
|
|
|
Returns a new Travel::Status::DE::IRIS::Result object. |
1343
|
|
|
|
|
|
|
You usually do not need to call this. |
1344
|
|
|
|
|
|
|
|
1345
|
|
|
|
|
|
|
=back |
1346
|
|
|
|
|
|
|
|
1347
|
|
|
|
|
|
|
=head1 MESSAGES |
1348
|
|
|
|
|
|
|
|
1349
|
|
|
|
|
|
|
A dump of all messages entered for the result is available. Each message |
1350
|
|
|
|
|
|
|
consists of a timestamp (when it was entered), a type (d for delay reasons, |
1351
|
|
|
|
|
|
|
q for other train-related information) and a value (numeric ID). |
1352
|
|
|
|
|
|
|
|
1353
|
|
|
|
|
|
|
At the time of this writing, the following messages are known: |
1354
|
|
|
|
|
|
|
|
1355
|
|
|
|
|
|
|
=over |
1356
|
|
|
|
|
|
|
|
1357
|
|
|
|
|
|
|
=item d 2 : "Polizeiliche Ermittlung" |
1358
|
|
|
|
|
|
|
|
1359
|
|
|
|
|
|
|
=item d 3 : "Feuerwehreinsatz neben der Strecke" |
1360
|
|
|
|
|
|
|
|
1361
|
|
|
|
|
|
|
=item d 5 : "E<Auml>rztliche Versorgung eines Fahrgastes" |
1362
|
|
|
|
|
|
|
|
1363
|
|
|
|
|
|
|
=item d 6 : "BetE<auml>tigen der Notbremse" |
1364
|
|
|
|
|
|
|
|
1365
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1366
|
|
|
|
|
|
|
|
1367
|
|
|
|
|
|
|
=item d 7 : "Personen im Gleis" |
1368
|
|
|
|
|
|
|
|
1369
|
|
|
|
|
|
|
=item d 8 : "Notarzteinsatz am Gleis" |
1370
|
|
|
|
|
|
|
|
1371
|
|
|
|
|
|
|
=item d 9 : "Streikauswirkungen" |
1372
|
|
|
|
|
|
|
|
1373
|
|
|
|
|
|
|
=item d 10 : "Ausgebrochene Tiere im Gleis" |
1374
|
|
|
|
|
|
|
|
1375
|
|
|
|
|
|
|
=item d 11 : "Unwetter" |
1376
|
|
|
|
|
|
|
|
1377
|
|
|
|
|
|
|
=item d 13 : "Pass- und Zollkontrolle" |
1378
|
|
|
|
|
|
|
|
1379
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1380
|
|
|
|
|
|
|
|
1381
|
|
|
|
|
|
|
=item d 15 : "BeeintrE<auml>chtigung durch Vandalismus" |
1382
|
|
|
|
|
|
|
|
1383
|
|
|
|
|
|
|
=item d 16 : "EntschE<auml>rfung einer Fliegerbombe" |
1384
|
|
|
|
|
|
|
|
1385
|
|
|
|
|
|
|
=item d 17 : "BeschE<auml>digung einer BrE<uuml>cke" |
1386
|
|
|
|
|
|
|
|
1387
|
|
|
|
|
|
|
=item d 18 : "UmgestE<uuml>rzter Baum im Gleis" |
1388
|
|
|
|
|
|
|
|
1389
|
|
|
|
|
|
|
=item d 19 : "Unfall an einem BahnE<uuml>bergang" |
1390
|
|
|
|
|
|
|
|
1391
|
|
|
|
|
|
|
=item d 20 : "Tiere im Gleis" |
1392
|
|
|
|
|
|
|
|
1393
|
|
|
|
|
|
|
=item d 21 : "Warten auf weitere Reisende" |
1394
|
|
|
|
|
|
|
|
1395
|
|
|
|
|
|
|
=item d 22 : "Witterungsbedingte StE<ouml>rung" |
1396
|
|
|
|
|
|
|
|
1397
|
|
|
|
|
|
|
=item d 23 : "Feuerwehreinsatz auf BahngelE<auml>nde" |
1398
|
|
|
|
|
|
|
|
1399
|
|
|
|
|
|
|
=item d 24 : "VerspE<auml>tung aus dem Ausland" |
1400
|
|
|
|
|
|
|
|
1401
|
|
|
|
|
|
|
=item d 25 : "Warten auf verspE<auml>tete Zugteile" |
1402
|
|
|
|
|
|
|
|
1403
|
|
|
|
|
|
|
=item d 28 : "GegenstE<auml>nde im Gleis" |
1404
|
|
|
|
|
|
|
|
1405
|
|
|
|
|
|
|
=item d 29 : "Ersatzverkehr mit Bus ist eingerichtet" |
1406
|
|
|
|
|
|
|
|
1407
|
|
|
|
|
|
|
=item d 31 : "Bauarbeiten" |
1408
|
|
|
|
|
|
|
|
1409
|
|
|
|
|
|
|
=item d 32 : "VerzE<ouml>gerung beim Ein-/Ausstieg" |
1410
|
|
|
|
|
|
|
|
1411
|
|
|
|
|
|
|
=item d 33 : "OberleitungsstE<ouml>rung" |
1412
|
|
|
|
|
|
|
|
1413
|
|
|
|
|
|
|
=item d 34 : "SignalstE<ouml>rung" |
1414
|
|
|
|
|
|
|
|
1415
|
|
|
|
|
|
|
=item d 35 : "Streckensperrung" |
1416
|
|
|
|
|
|
|
|
1417
|
|
|
|
|
|
|
=item d 36 : "Technische StE<ouml>rung am Zug" |
1418
|
|
|
|
|
|
|
|
1419
|
|
|
|
|
|
|
=item d 37 : "Technische StE<ouml>rung am Wagen" |
1420
|
|
|
|
|
|
|
|
1421
|
|
|
|
|
|
|
=item d 38 : "Technische StE<ouml>rung an der Strecke" |
1422
|
|
|
|
|
|
|
|
1423
|
|
|
|
|
|
|
=item d 39 : "AnhE<auml>ngen von zusE<auml>tzlichen Wagen" |
1424
|
|
|
|
|
|
|
|
1425
|
|
|
|
|
|
|
=item d 40 : "StellwerksstE<ouml>rung/-ausfall" |
1426
|
|
|
|
|
|
|
|
1427
|
|
|
|
|
|
|
=item d 41 : "StE<ouml>rung an einem BahnE<uuml>bergang" |
1428
|
|
|
|
|
|
|
|
1429
|
|
|
|
|
|
|
=item d 42 : "AuE<szlig>erplanmE<auml>E<szlig>ige GeschwindigkeitsbeschrE<auml>nkung" |
1430
|
|
|
|
|
|
|
|
1431
|
|
|
|
|
|
|
=item d 43 : "VerspE<auml>tung eines vorausfahrenden Zuges" |
1432
|
|
|
|
|
|
|
|
1433
|
|
|
|
|
|
|
=item d 44 : "Warten auf einen entgegenkommenden Zug" |
1434
|
|
|
|
|
|
|
|
1435
|
|
|
|
|
|
|
=item d 45 : "E<Uuml>berholung durch anderen Zug" |
1436
|
|
|
|
|
|
|
|
1437
|
|
|
|
|
|
|
=item d 46 : "Warten auf freie Einfahrt" |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
=item d 47 : "VerspE<auml>tete Bereitstellung" |
1440
|
|
|
|
|
|
|
|
1441
|
|
|
|
|
|
|
=item d 48 : "VerspE<auml>tung aus vorheriger Fahrt" |
1442
|
|
|
|
|
|
|
|
1443
|
|
|
|
|
|
|
=item d 55 : "Technische StE<ouml>rung an einem anderen Zug" |
1444
|
|
|
|
|
|
|
|
1445
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1446
|
|
|
|
|
|
|
|
1447
|
|
|
|
|
|
|
=item d 56 : "Warten auf FahrgE<auml>ste aus einem Bus" |
1448
|
|
|
|
|
|
|
|
1449
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1450
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
=item d 57 : "ZusE<auml>tzlicher Halt" |
1452
|
|
|
|
|
|
|
|
1453
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1454
|
|
|
|
|
|
|
|
1455
|
|
|
|
|
|
|
=item d 58 : "Umleitung" |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). Several entries, related |
1458
|
|
|
|
|
|
|
to "Notarzteinsatz am Gleis". |
1459
|
|
|
|
|
|
|
|
1460
|
|
|
|
|
|
|
=item d 59 : "Schnee und Eis" |
1461
|
|
|
|
|
|
|
|
1462
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1463
|
|
|
|
|
|
|
|
1464
|
|
|
|
|
|
|
=item d 60 : "Reduzierte Geschwindigkeit wegen Sturm" |
1465
|
|
|
|
|
|
|
|
1466
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1467
|
|
|
|
|
|
|
|
1468
|
|
|
|
|
|
|
=item d 61 : "TE<uuml>rstE<ouml>rung" |
1469
|
|
|
|
|
|
|
|
1470
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1471
|
|
|
|
|
|
|
|
1472
|
|
|
|
|
|
|
=item d 62 : "Behobene technische StE<ouml>rung am Zug" |
1473
|
|
|
|
|
|
|
|
1474
|
|
|
|
|
|
|
Source: Correlation between IRIS and DB RIS (bahn.de). |
1475
|
|
|
|
|
|
|
|
1476
|
|
|
|
|
|
|
=item d 63 : "Technische Untersuchung am Zug" |
1477
|
|
|
|
|
|
|
|
1478
|
|
|
|
|
|
|
=item d 64 : "WeichenstE<ouml>rung" |
1479
|
|
|
|
|
|
|
|
1480
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1481
|
|
|
|
|
|
|
|
1482
|
|
|
|
|
|
|
=item d 65 : "Erdrutsch" |
1483
|
|
|
|
|
|
|
|
1484
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1485
|
|
|
|
|
|
|
|
1486
|
|
|
|
|
|
|
=item d 66 : "Hochwasser" |
1487
|
|
|
|
|
|
|
|
1488
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1489
|
|
|
|
|
|
|
|
1490
|
|
|
|
|
|
|
=item f 67 : "BehE<ouml>rdliche Anordnung" |
1491
|
|
|
|
|
|
|
|
1492
|
|
|
|
|
|
|
Source: L<https://twitter.com/DodoMedia/status/1238816272240070659>. |
1493
|
|
|
|
|
|
|
|
1494
|
|
|
|
|
|
|
=item q 70 : "WLAN nicht verfE<uuml>gbar" |
1495
|
|
|
|
|
|
|
|
1496
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1497
|
|
|
|
|
|
|
|
1498
|
|
|
|
|
|
|
=item q 71 : "WLAN in einzelnen Wagen nicht verfE<uuml>gbar" |
1499
|
|
|
|
|
|
|
|
1500
|
|
|
|
|
|
|
=item q 72 : "Info/Entertainment nicht verfE<uuml>gbar" |
1501
|
|
|
|
|
|
|
|
1502
|
|
|
|
|
|
|
=item q 73 : "Mehrzweckabteil vorne" |
1503
|
|
|
|
|
|
|
|
1504
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1505
|
|
|
|
|
|
|
|
1506
|
|
|
|
|
|
|
=item q 74 : "Mehrzweckabteil hinten" |
1507
|
|
|
|
|
|
|
|
1508
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1509
|
|
|
|
|
|
|
|
1510
|
|
|
|
|
|
|
=item q 75 : "1. Klasse vorne" |
1511
|
|
|
|
|
|
|
|
1512
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1513
|
|
|
|
|
|
|
|
1514
|
|
|
|
|
|
|
=item q 76 : "1. Klasse hinten" |
1515
|
|
|
|
|
|
|
|
1516
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1517
|
|
|
|
|
|
|
|
1518
|
|
|
|
|
|
|
=item q 77 : "Ohne 1. Klasse" |
1519
|
|
|
|
|
|
|
|
1520
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1521
|
|
|
|
|
|
|
|
1522
|
|
|
|
|
|
|
=item q 78 : "Ersatzverkehr mit Bus ist eingerichtet" |
1523
|
|
|
|
|
|
|
|
1524
|
|
|
|
|
|
|
=item q 79 : "Ohne Mehrzweckabteil" |
1525
|
|
|
|
|
|
|
|
1526
|
|
|
|
|
|
|
Source: correlation between IRIS and DB RIS (bahn.de). |
1527
|
|
|
|
|
|
|
|
1528
|
|
|
|
|
|
|
=item q 80 : "Abweichende Wagenreihung" |
1529
|
|
|
|
|
|
|
|
1530
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1531
|
|
|
|
|
|
|
|
1532
|
|
|
|
|
|
|
=item q 81 : "Fahrzeugtausch" |
1533
|
|
|
|
|
|
|
|
1534
|
|
|
|
|
|
|
=item q 82 : "Mehrere Wagen fehlen" |
1535
|
|
|
|
|
|
|
|
1536
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1537
|
|
|
|
|
|
|
|
1538
|
|
|
|
|
|
|
=item q 83 : "StE<ouml>rung der fahrzeuggebundenen Einstiegshilfe" |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
=item q 84 : "Zug verkehrt richtig gereiht" |
1541
|
|
|
|
|
|
|
|
1542
|
|
|
|
|
|
|
Obsoletes messages 80, 82, 85. |
1543
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1544
|
|
|
|
|
|
|
|
1545
|
|
|
|
|
|
|
=item q 85 : "Ein Wagen fehlt" |
1546
|
|
|
|
|
|
|
|
1547
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1548
|
|
|
|
|
|
|
|
1549
|
|
|
|
|
|
|
=item q 86 : "Keine Reservierungsanzeige" |
1550
|
|
|
|
|
|
|
|
1551
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1552
|
|
|
|
|
|
|
|
1553
|
|
|
|
|
|
|
=item q 87 : "Einzelne Wagen ohne Reservierungsanzeige" |
1554
|
|
|
|
|
|
|
|
1555
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1556
|
|
|
|
|
|
|
|
1557
|
|
|
|
|
|
|
=item q 88 : "Keine QualitE<auml>tsmE<auml>ngel" |
1558
|
|
|
|
|
|
|
|
1559
|
|
|
|
|
|
|
Obsoletes messages 80, 82, 83, 85, 86, 87, 90, 91, 92, 93, 96, 97, 98. |
1560
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1561
|
|
|
|
|
|
|
|
1562
|
|
|
|
|
|
|
=item q 89 : "Reservierungen sind wieder vorhanden" |
1563
|
|
|
|
|
|
|
|
1564
|
|
|
|
|
|
|
Obsoletes messages 86, 87. |
1565
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1566
|
|
|
|
|
|
|
|
1567
|
|
|
|
|
|
|
=item q 90 : "Kein gastronomisches Angebot" |
1568
|
|
|
|
|
|
|
|
1569
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1570
|
|
|
|
|
|
|
|
1571
|
|
|
|
|
|
|
=item q 91 : "EingeschrE<auml>nkte FahrradbefE<ouml>rderung" |
1572
|
|
|
|
|
|
|
|
1573
|
|
|
|
|
|
|
=item q 92 : "Keine FahrradbefE<ouml>rderung" |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
=item q 93 : "Fehlende oder gestE<ouml>rte behindertengerechte Einrichtung" |
1576
|
|
|
|
|
|
|
|
1577
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1578
|
|
|
|
|
|
|
Might also mean "Kein rollstuhlgerechtes WC" (source: frubi). |
1579
|
|
|
|
|
|
|
|
1580
|
|
|
|
|
|
|
=item q 94 : "Ersatzbewirtschaftung" |
1581
|
|
|
|
|
|
|
|
1582
|
|
|
|
|
|
|
Estimated from a comparison with bahn.de/ris messages. Needs to be verified. |
1583
|
|
|
|
|
|
|
|
1584
|
|
|
|
|
|
|
=item q 95 : "Ohne behindertengerechtes WC" |
1585
|
|
|
|
|
|
|
|
1586
|
|
|
|
|
|
|
Estimated from a comparison with bahn.de/iris messages. |
1587
|
|
|
|
|
|
|
|
1588
|
|
|
|
|
|
|
=item q 96 : "Der Zug ist stark E<uuml>berbesetzt" |
1589
|
|
|
|
|
|
|
|
1590
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1591
|
|
|
|
|
|
|
|
1592
|
|
|
|
|
|
|
=item q 97 : "Der Zug ist E<uuml>berbesetzt" |
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1595
|
|
|
|
|
|
|
|
1596
|
|
|
|
|
|
|
=item q 98 : "Sonstige QualitE<auml>tsmE<auml>ngel" |
1597
|
|
|
|
|
|
|
|
1598
|
|
|
|
|
|
|
Verified by L<https://iris.noncd.db.de/irisWebclient/Configuration>. |
1599
|
|
|
|
|
|
|
Might also mean "Kein rollstuhlgerechter Wagen" (source: frubi). |
1600
|
|
|
|
|
|
|
|
1601
|
|
|
|
|
|
|
=item d 99 : "VerzE<ouml>gerungen im Betriebsablauf" |
1602
|
|
|
|
|
|
|
|
1603
|
|
|
|
|
|
|
=back |
1604
|
|
|
|
|
|
|
|
1605
|
|
|
|
|
|
|
=head1 DIAGNOSTICS |
1606
|
|
|
|
|
|
|
|
1607
|
|
|
|
|
|
|
None. |
1608
|
|
|
|
|
|
|
|
1609
|
|
|
|
|
|
|
=head1 DEPENDENCIES |
1610
|
|
|
|
|
|
|
|
1611
|
|
|
|
|
|
|
=over |
1612
|
|
|
|
|
|
|
|
1613
|
|
|
|
|
|
|
=item Class::Accessor(3pm) |
1614
|
|
|
|
|
|
|
|
1615
|
|
|
|
|
|
|
=back |
1616
|
|
|
|
|
|
|
|
1617
|
|
|
|
|
|
|
=head1 BUGS AND LIMITATIONS |
1618
|
|
|
|
|
|
|
|
1619
|
|
|
|
|
|
|
Unknown. |
1620
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
=head1 SEE ALSO |
1622
|
|
|
|
|
|
|
|
1623
|
|
|
|
|
|
|
Travel::Status::DE::IRIS(3pm). |
1624
|
|
|
|
|
|
|
|
1625
|
|
|
|
|
|
|
=head1 AUTHOR |
1626
|
|
|
|
|
|
|
|
1627
|
|
|
|
|
|
|
Copyright (C) 2013-2023 by Birte Kristina Friesel E<lt>derf@finalrewind.orgE<gt> |
1628
|
|
|
|
|
|
|
|
1629
|
|
|
|
|
|
|
=head1 LICENSE |
1630
|
|
|
|
|
|
|
|
1631
|
|
|
|
|
|
|
This module is licensed under the same terms as Perl itself. |