line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
1
|
|
|
1
|
|
35560
|
use 5.16.0; |
|
1
|
|
|
|
|
3
|
|
2
|
1
|
|
|
1
|
|
479
|
use Map::Metro::Standard; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
8
|
|
3
|
1
|
|
|
1
|
|
12920
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
22
|
|
4
|
1
|
|
|
1
|
|
4
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
61
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
package Map::Metro { |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
our $VERSION = '0.2300'; # VERSION |
9
|
|
|
|
|
|
|
# ABSTRACT: Public transport graphing |
10
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
938
|
use Moose; |
|
1
|
|
|
|
|
463025
|
|
|
1
|
|
|
|
|
6
|
|
12
|
1
|
|
|
1
|
|
7773
|
use Module::Pluggable search_path => ['Map::Metro::Plugin::Map'], require => 1, sub_name => 'system_maps'; |
|
1
|
|
|
|
|
9185
|
|
|
1
|
|
|
|
|
9
|
|
13
|
1
|
|
|
1
|
|
955
|
use MooseX::AttributeShortcuts; |
|
1
|
|
|
|
|
403393
|
|
|
1
|
|
|
|
|
6
|
|
14
|
1
|
|
|
1
|
|
37380
|
use Types::Standard -types; |
|
1
|
|
|
|
|
65731
|
|
|
1
|
|
|
|
|
14
|
|
15
|
1
|
|
|
1
|
|
5135
|
use Types::Path::Tiny -types; |
|
1
|
|
|
|
|
22796
|
|
|
1
|
|
|
|
|
12
|
|
16
|
1
|
|
|
1
|
|
933
|
use List::Util 1.33 'any'; |
|
1
|
|
|
|
|
23
|
|
|
1
|
|
|
|
|
60
|
|
17
|
|
|
|
|
|
|
|
18
|
1
|
|
|
1
|
|
880
|
use Map::Metro::Graph; |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
1331
|
|
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
has map => ( |
21
|
|
|
|
|
|
|
is => 'ro', |
22
|
|
|
|
|
|
|
traits => ['Array'], |
23
|
|
|
|
|
|
|
isa => ArrayRef, |
24
|
|
|
|
|
|
|
predicate => 1, |
25
|
|
|
|
|
|
|
handles => { |
26
|
|
|
|
|
|
|
get_map => 'get', |
27
|
|
|
|
|
|
|
}, |
28
|
|
|
|
|
|
|
); |
29
|
|
|
|
|
|
|
has mapclasses => ( |
30
|
|
|
|
|
|
|
is => 'ro', |
31
|
|
|
|
|
|
|
traits => ['Array'], |
32
|
|
|
|
|
|
|
isa => ArrayRef, |
33
|
|
|
|
|
|
|
default => sub { [] }, |
34
|
|
|
|
|
|
|
handles => { |
35
|
|
|
|
|
|
|
add_mapclass => 'push', |
36
|
|
|
|
|
|
|
get_mapclass => 'get', |
37
|
|
|
|
|
|
|
}, |
38
|
|
|
|
|
|
|
); |
39
|
|
|
|
|
|
|
has hooks => ( |
40
|
|
|
|
|
|
|
is => 'ro', |
41
|
|
|
|
|
|
|
isa => ArrayRef[ Str ], |
42
|
|
|
|
|
|
|
traits => ['Array'], |
43
|
|
|
|
|
|
|
default => sub { [] }, |
44
|
|
|
|
|
|
|
handles => { |
45
|
|
|
|
|
|
|
all_hooks => 'elements', |
46
|
|
|
|
|
|
|
hook_count => 'count', |
47
|
|
|
|
|
|
|
}, |
48
|
|
|
|
|
|
|
); |
49
|
|
|
|
|
|
|
has _plugin_ns => ( |
50
|
|
|
|
|
|
|
is => 'ro', |
51
|
|
|
|
|
|
|
isa => Str, |
52
|
|
|
|
|
|
|
default => 'Plugin::Map', |
53
|
|
|
|
|
|
|
init_arg => undef, |
54
|
|
|
|
|
|
|
); |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
around BUILDARGS => sub { |
57
|
|
|
|
|
|
|
my ($orig, $class, @args) = @_; |
58
|
|
|
|
|
|
|
my %args; |
59
|
|
|
|
|
|
|
if(scalar @args == 1) { |
60
|
|
|
|
|
|
|
$args{'map'} = shift @args; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
elsif(scalar @args % 2 != 0) { |
63
|
|
|
|
|
|
|
my $map = shift @args; |
64
|
|
|
|
|
|
|
%args = @args; |
65
|
|
|
|
|
|
|
$args{'map'} = $map; |
66
|
|
|
|
|
|
|
} |
67
|
|
|
|
|
|
|
else { |
68
|
|
|
|
|
|
|
%args = @args; |
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
if(exists $args{'map'} && !ArrayRef->check($args{'map'})) { |
72
|
|
|
|
|
|
|
$args{'map'} = [$args{'map'}]; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
if(exists $args{'hooks'} && !ArrayRef->check($args{'hooks'})) { |
75
|
|
|
|
|
|
|
$args{'hooks'} = [$args{'hooks'}]; |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
return $class->$orig(%args); |
79
|
|
|
|
|
|
|
}; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub BUILD { |
82
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
83
|
0
|
|
|
|
|
|
my @args = @_; |
84
|
|
|
|
|
|
|
|
85
|
0
|
0
|
|
|
|
|
if($self->has_map) { |
86
|
0
|
|
|
|
|
|
my @system_maps = map { s{^Map::Metro::Plugin::Map::}{}; $_ } $self->system_maps; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
87
|
0
|
0
|
|
0
|
|
|
if(any { $_ eq $self->get_map(0) } @system_maps) { |
|
0
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
|
my $mapclass = 'Map::Metro::Plugin::Map::'.$self->get_map(0); |
89
|
0
|
|
|
|
|
|
my $mapobj = $mapclass->new(hooks => $self->hooks); |
90
|
0
|
|
|
|
|
|
$self->add_mapclass($mapobj); |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
# Borrowed from Mojo::Util |
96
|
|
|
|
|
|
|
sub decamelize { |
97
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
98
|
0
|
|
|
|
|
|
my $string = shift; |
99
|
|
|
|
|
|
|
|
100
|
0
|
0
|
|
|
|
|
return $string if $string !~ m{[A-Z]}; |
101
|
|
|
|
|
|
|
return join '_' => map { |
102
|
0
|
|
|
|
|
|
join ('_' => map { lc } grep { length } split m{([A-Z]{1}[^A-Z]*)}) |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
} split '::' => $string; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub parse { |
107
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
108
|
0
|
|
|
|
|
|
my %args = @_; |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
return Map::Metro::Graph->new(filepath => $self->get_mapclass(0)->maplocation, |
111
|
|
|
|
|
|
|
do_undiacritic => $self->get_mapclass(0)->do_undiacritic, |
112
|
|
|
|
|
|
|
wanted_hook_plugins => [$self->all_hooks], |
113
|
0
|
0
|
|
|
|
|
exists $args{'override_line_change_weight'} ? (override_line_change_weight => $args{'override_line_change_weight'}) : (), |
114
|
|
|
|
|
|
|
)->parse; |
115
|
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub available_maps { |
118
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
119
|
0
|
|
|
|
|
|
return sort $self->system_maps; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
1; |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
__END__ |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=pod |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=encoding utf-8 |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=head1 NAME |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
Map::Metro - Public transport graphing |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
|
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=begin HTML |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
<p><img src="https://img.shields.io/badge/perl-5.16+-brightgreen.svg" alt="Requires Perl 5.16+" /> <a href="https://travis-ci.org/Csson/p5-Map-Metro"><img src="https://api.travis-ci.org/Csson/p5-Map-Metro.svg?branch=master" alt="Travis status" /></a></p> |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=end HTML |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=begin markdown |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
![Requires Perl 5.16+](https://img.shields.io/badge/perl-5.16+-brightgreen.svg) [![Travis status](https://api.travis-ci.org/Csson/p5-Map-Metro.svg?branch=master)](https://travis-ci.org/Csson/p5-Map-Metro) |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=end markdown |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=head1 VERSION |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
Version 0.2300, released 2016-01-14. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=head1 SYNOPSIS |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
# Install a map |
157
|
|
|
|
|
|
|
$ cpanm Map::Metro::Plugin::Map::Stockholm |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# And then |
160
|
|
|
|
|
|
|
my $graph = Map::Metro->new('Stockholm', hooks => ['PrettyPrinter'])->parse; |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
my $routing = $graph->routing_for('Universitetet', 'Kista'); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# or in a terminal |
165
|
|
|
|
|
|
|
$ map-metro.pl route Stockholm Universitetet Kista |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
prints |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
From Universitetet to Kista |
170
|
|
|
|
|
|
|
=========================== |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
-- Route 1 (cost 15) ---------- |
173
|
|
|
|
|
|
|
[ T14 ] Universitetet |
174
|
|
|
|
|
|
|
[ T14 ] Tekniska högskolan |
175
|
|
|
|
|
|
|
[ T14 ] Stadion |
176
|
|
|
|
|
|
|
[ T14 ] Ãstermalmstorg |
177
|
|
|
|
|
|
|
[ T14 ] T-Centralen |
178
|
|
|
|
|
|
|
[ * T11 ] T-Centralen |
179
|
|
|
|
|
|
|
[ T11 ] RÃ¥dhuset |
180
|
|
|
|
|
|
|
[ T11 ] Fridhemsplan |
181
|
|
|
|
|
|
|
[ T11 ] Stadshagen |
182
|
|
|
|
|
|
|
[ T11 ] Västra skogen |
183
|
|
|
|
|
|
|
[ T11 ] Solna centrum |
184
|
|
|
|
|
|
|
[ T11 ] Näckrosen |
185
|
|
|
|
|
|
|
[ T11 ] Hallonbergen |
186
|
|
|
|
|
|
|
[ T11 ] Kista |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
T11 Blue line |
189
|
|
|
|
|
|
|
T14 Red line |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
*: Transfer to other line |
192
|
|
|
|
|
|
|
+: Transfer to other station |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=head1 DESCRIPTION |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
The purpose of this distribution is to find the shortest L<unique|/"What is a unique path?"> route/routes between two stations in a transport network. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
See L<Task::MapMetro::Maps> for a list of released maps. |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
=head2 Methods |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=head3 new($city, hooks => []) |
203
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
B<C<$city>> |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
The name of the city you want to search connections in. Mandatory, unless you are only going to call L</"available_maps">. |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
B<C<$hooks>> |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
Array reference of L<Hooks|Map::Metro::Hook> that listens for events. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=head3 parse() |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
Returns a L<Map::Metro::Graph> object containing the entire graph. |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
=head3 available_maps() |
217
|
|
|
|
|
|
|
|
218
|
|
|
|
|
|
|
Returns an array reference containing the names of all Map::Metro maps installed on the system. |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=head2 What is a unique path? |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
The following rules are a guideline: |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
If the starting station and finishing station... |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
...is on the same line there will be no transfers to other lines. |
227
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
...shares multiple lines (e.g., both stations are on both line 2 and 4), each line constitutes a route. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
...are on different lines a transfer will take place at a shared station. No matter how many shared stations there are, there will only be one route returned (but which transfer station is used can differ between queries). |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
...has no shared stations, the shortest route/routes will be returned. |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=head1 MORE INFORMATION |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
L<Map::Metro::Graph> - How to use graph object. |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
L<Map::Metro::Plugin::Map> - How to make your own maps. |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
L<Map::Metro::Hook> - How to extend Map::Metro via hooks/events. |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
L<Map::Metro::Cmd> - A guide to the command line application. |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
L<Map::Metro::Graph::Connection> - Defines a MMG::Connection. |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
L<Map::Metro::Graph::Line> - Defines a MMG::Line. |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
L<Map::Metro::Graph::LineStation> - Defines a MMG::LineStation. |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
L<Map::Metro::Graph::Route> - Defines a MMG::Route. |
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
L<Map::Metro::Graph::Routing> - Defines a MMG::Routing. |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
L<Map::Metro::Graph::Segment> - Defines a MMG::Segment. |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
L<Map::Metro::Graph::Station> - Defines a MMG::Station. |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
L<Map::Metro::Graph::Step> - Defines a MMG::Step. |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
L<Map::Metro::Graph::Transfer> - Defines a MMG::Transfer. |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
=head2 Hierarchy |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
The following is a conceptual overview of the various parts of a graph: |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
At first, the map file is parsed. The four types of blocks (stations, transfers, lines and segments) are translated |
267
|
|
|
|
|
|
|
into their respective object. |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
Next, lines and stations are put together into L<LineStations|Map::Metro::Graph::LineStation>. Every two adjacent LineStations |
270
|
|
|
|
|
|
|
are put into two L<Connections|Map::Metro::Graph::Connection> (one for each direction). |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
Now the network is complete, and it is time to start traversing it. |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
Once a request to search for paths between two stations is given, we first search for the starting L<Station|Map::Metro::Graph::Station> given either a |
275
|
|
|
|
|
|
|
station id or station name. Then we find all L<LineStations|Map::Metro::Graph::LineStation> for that station. |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
Then we do the same for the destination station. |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
And then we walk through the network, from L<LineStation|Map::Metro::Graph::LineStation> to L<LineStation|Map::Metro::Graph::LineStation>, finding their L<Connections|Map::Metro::Graph::Connection> |
280
|
|
|
|
|
|
|
and turning them into L<Steps|Map::Metro::Graph::Step>, which we then add to the L<Route|Map::Metro::Graph::Route>. |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
All L<Routes|Map::Metro::Graph::Route> between the two L<Stations|Map::Metro::Graph::Station> are then put into a L<Routing|Map::Metro::Graph::Routing>, which is returned to the user. |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
=head1 PERFORMANCE |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
Since 0.2200 performance is less than an issue than it used to be, but it can still be improved. Prior to this version the entire network was analyzed up-front. This is unnecessary when searching one (or a few) routes. For long-running applications it is still possible to pre-calculate all paths, see L<asps|Map::Metro::Graph/"asps()">. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=head1 STATUS |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
This is somewhat experimental. I don't expect that the map file format will I<break>, but it might be |
291
|
|
|
|
|
|
|
extended. Only the documented api should be relied on, though breaking changes might occur. |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
For all maps in the Map::Metro::Plugin::Map namespace (unless noted): |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
* These maps are not an official source. Use accordingly. |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
* There should be a note regarding what routes the map covers. |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=head1 COMPATIBILITY |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
Currently requires Perl 5.16. |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=head1 Map::Metro or Map::Tube? |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
L<Map::Tube> is the main alternative to C<Map::Metro>. They both have their strong and weak points. |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
* Map::Tube is faster. |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
* Map::Tube is more stable: It has been on Cpan for a long time, and is under active development. |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
* Map::Metro has (in my opinion) a better map format. |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
* Map::Metro supports eg. transfers between stations. |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
* See L<Task::MapMetro::Maps> and L<Task::Map::Tube> for available maps. |
316
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
* It is possible to convert Map::Metro maps into Map::Tube maps using L<map-metro.pl|Map::Metro::Cmd/"map-metro.pl metro_to_tube $city">. |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
=head1 SEE ALSO |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
L<Map::Tube> |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
=head1 SOURCE |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
L<https://github.com/Csson/p5-Map-Metro> |
326
|
|
|
|
|
|
|
|
327
|
|
|
|
|
|
|
=head1 HOMEPAGE |
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
L<https://metacpan.org/release/Map-Metro> |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
=head1 AUTHOR |
332
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
Erik Carlsson <info@code301.com> |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
336
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
This software is copyright (c) 2016 by Erik Carlsson. |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
340
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
=cut |