gtfs-to-html 2.7.2 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +21 -8
- package/.eslintrc.json +0 -28
- package/.husky/pre-commit +0 -4
- package/CHANGELOG.md +0 -1018
- package/app/index.js +0 -138
- package/bin/gtfs-to-html.js +0 -48
- package/config-sample.json +0 -59
- package/docker/Dockerfile +0 -14
- package/docker/README.md +0 -5
- package/docker/docker-compose.yml +0 -10
- package/examples/stop_attributes.txt +0 -6
- package/examples/timetable_notes.txt +0 -8
- package/examples/timetable_notes_references.txt +0 -8
- package/examples/timetable_pages.txt +0 -3
- package/examples/timetable_stop_order.txt +0 -16
- package/examples/timetables.txt +0 -9
- package/index.js +0 -1
- package/lib/file-utils.js +0 -202
- package/lib/formatters.js +0 -518
- package/lib/geojson-utils.js +0 -96
- package/lib/gtfs-to-html.js +0 -214
- package/lib/log-utils.js +0 -215
- package/lib/template-functions.js +0 -192
- package/lib/time-utils.js +0 -90
- package/lib/utils.js +0 -1702
- package/views/default/css/overview_styles.css +0 -197
- package/views/default/css/timetable_pdf_styles.css +0 -7
- package/views/default/css/timetable_styles.css +0 -447
- package/views/default/formatting_functions.pug +0 -113
- package/views/default/js/system-map.js +0 -594
- package/views/default/js/timetable-map.js +0 -358
- package/views/default/js/timetable-menu.js +0 -63
- package/views/default/layout.pug +0 -11
- package/views/default/overview.pug +0 -27
- package/views/default/overview_full.pug +0 -16
- package/views/default/timetable_continuation_as.pug +0 -7
- package/views/default/timetable_continuation_from.pug +0 -7
- package/views/default/timetable_horizontal.pug +0 -42
- package/views/default/timetable_hourly.pug +0 -30
- package/views/default/timetable_menu.pug +0 -48
- package/views/default/timetable_note_symbol.pug +0 -5
- package/views/default/timetable_stop_name.pug +0 -13
- package/views/default/timetable_stoptime.pug +0 -17
- package/views/default/timetable_vertical.pug +0 -67
- package/views/default/timetablepage.pug +0 -66
- package/views/default/timetablepage_full.pug +0 -22
- package/www/README.md +0 -33
- package/www/babel.config.js +0 -3
- package/www/blog/2020-07-07-New-Documentation.md +0 -12
- package/www/blog/2020-08-20-Version-1.0.0.md +0 -29
- package/www/blog/2021-11-06-CSV-Export.md +0 -26
- package/www/docs/additional-files.md +0 -24
- package/www/docs/configuration.md +0 -568
- package/www/docs/current-usage.md +0 -48
- package/www/docs/custom-templates.md +0 -13
- package/www/docs/introduction.md +0 -39
- package/www/docs/logging-sql-queries.md +0 -12
- package/www/docs/previewing-html-output.md +0 -24
- package/www/docs/processing-large-gtfs.md +0 -10
- package/www/docs/quick-start.md +0 -136
- package/www/docs/related-libraries.md +0 -54
- package/www/docs/reviewing-changes.md +0 -29
- package/www/docs/stop-attributes.md +0 -30
- package/www/docs/support.md +0 -12
- package/www/docs/timetable-notes-references.md +0 -44
- package/www/docs/timetable-notes.md +0 -33
- package/www/docs/timetable-pages.md +0 -37
- package/www/docs/timetable-stop-order.md +0 -63
- package/www/docs/timetables.md +0 -64
- package/www/docusaurus.config.js +0 -104
- package/www/package.json +0 -21
- package/www/sidebars.js +0 -10
- package/www/src/css/custom.css +0 -25
- package/www/src/pages/index.js +0 -270
- package/www/src/pages/styles.module.css +0 -53
- package/www/static/.nojekyll +0 -0
- package/www/static/img/favicon.ico +0 -0
- package/www/static/img/gtfs-to-html-logo.svg +0 -18
- package/www/static/img/overview-example.jpg +0 -0
- package/www/static/img/timetable-example.jpg +0 -0
- package/www/static/img/undraw_happy_music.svg +0 -1
- package/www/static/img/undraw_proud_coder.svg +0 -1
- package/www/static/img/undraw_spreadsheets.svg +0 -1
- package/www/yarn.lock +0 -8351
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
/* global window, document, $, mapboxgl */
|
|
2
|
-
/* eslint no-var: "off", prefer-arrow-callback: "off", no-unused-vars: "off" */
|
|
3
|
-
|
|
4
|
-
const maps = {};
|
|
5
|
-
|
|
6
|
-
function formatRouteColor(route) {
|
|
7
|
-
return route.route_color || '#000000';
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function formatRouteTextColor(route) {
|
|
11
|
-
return route.route_text_color || '#FFFFFF';
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function formatRoute(route) {
|
|
15
|
-
const html = route.route_url
|
|
16
|
-
? $('<a>').attr('href', route.route_url)
|
|
17
|
-
: $('<div>');
|
|
18
|
-
|
|
19
|
-
html.addClass('map-route-item');
|
|
20
|
-
|
|
21
|
-
// Only add color swatch if route has a color
|
|
22
|
-
const routeItemDivs = [];
|
|
23
|
-
|
|
24
|
-
if (route.route_color) {
|
|
25
|
-
routeItemDivs.push(
|
|
26
|
-
$('<div>')
|
|
27
|
-
.addClass('route-color-swatch')
|
|
28
|
-
.css('backgroundColor', formatRouteColor(route))
|
|
29
|
-
.css('color', formatRouteTextColor(route))
|
|
30
|
-
.text(route.route_short_name ?? ''),
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
routeItemDivs.push(
|
|
34
|
-
$('<div>')
|
|
35
|
-
.addClass('underline-hover')
|
|
36
|
-
.text(route.route_long_name ?? `Route ${route.route_short_name}`),
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
html.append(routeItemDivs);
|
|
40
|
-
|
|
41
|
-
return html.prop('outerHTML');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function formatStopPopup(feature, routes) {
|
|
45
|
-
const routeIds = JSON.parse(feature.properties.routes);
|
|
46
|
-
const html = $('<div>');
|
|
47
|
-
|
|
48
|
-
$('<div>')
|
|
49
|
-
.addClass('popup-title')
|
|
50
|
-
.text(feature.properties.stop_name)
|
|
51
|
-
.appendTo(html);
|
|
52
|
-
|
|
53
|
-
if (feature.properties.stop_code ?? false) {
|
|
54
|
-
$('<div>')
|
|
55
|
-
.html([
|
|
56
|
-
$('<label>').addClass('popup-label').text('Stop Code:'),
|
|
57
|
-
$('<strong>').text(feature.properties.stop_code),
|
|
58
|
-
])
|
|
59
|
-
.appendTo(html);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
$('<label>').text('Routes Served:').appendTo(html);
|
|
63
|
-
|
|
64
|
-
$(html).append(
|
|
65
|
-
$('<div>')
|
|
66
|
-
.addClass('route-list')
|
|
67
|
-
.html(routeIds.map((routeId) => formatRoute(routes[routeId]))),
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
$('<a>')
|
|
71
|
-
.addClass('btn-blue btn-sm')
|
|
72
|
-
.prop(
|
|
73
|
-
'href',
|
|
74
|
-
`https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=${feature.geometry.coordinates[1]},${feature.geometry.coordinates[0]}&heading=0&pitch=0&fov=90`,
|
|
75
|
-
)
|
|
76
|
-
.prop('target', '_blank')
|
|
77
|
-
.prop('rel', 'noopener noreferrer')
|
|
78
|
-
.html('View on Streetview')
|
|
79
|
-
.appendTo(html);
|
|
80
|
-
|
|
81
|
-
return html.prop('outerHTML');
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function getBounds(geojson) {
|
|
85
|
-
const bounds = new mapboxgl.LngLatBounds();
|
|
86
|
-
for (const feature of geojson.features) {
|
|
87
|
-
if (feature.geometry.type.toLowerCase() === 'point') {
|
|
88
|
-
bounds.extend(feature.geometry.coordinates);
|
|
89
|
-
} else if (feature.geometry.type.toLowerCase() === 'linestring') {
|
|
90
|
-
for (const coordinate of feature.geometry.coordinates) {
|
|
91
|
-
bounds.extend(coordinate);
|
|
92
|
-
}
|
|
93
|
-
} else if (feature.geometry.type.toLowerCase() === 'multilinestring') {
|
|
94
|
-
for (const linestring of feature.geometry.coordinates) {
|
|
95
|
-
for (const coordinate of linestring) {
|
|
96
|
-
bounds.extend(coordinate);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return bounds;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function createMap(id, geojson, routes) {
|
|
106
|
-
const defaultRouteColor = '#000000';
|
|
107
|
-
const lineLayout = {
|
|
108
|
-
'line-join': 'round',
|
|
109
|
-
'line-cap': 'round',
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
if (!geojson || geojson.features.length === 0) {
|
|
113
|
-
$('#map_' + id).hide();
|
|
114
|
-
return false;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const bounds = getBounds(geojson);
|
|
118
|
-
const map = new mapboxgl.Map({
|
|
119
|
-
container: 'map_' + id,
|
|
120
|
-
style: 'mapbox://styles/mapbox/light-v10',
|
|
121
|
-
center: bounds.getCenter(),
|
|
122
|
-
zoom: 12,
|
|
123
|
-
preserveDrawingBuffer: true,
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
map.initialize = () =>
|
|
127
|
-
map.fitBounds(bounds, {
|
|
128
|
-
padding: {
|
|
129
|
-
top: 40,
|
|
130
|
-
bottom: 40,
|
|
131
|
-
left: 20,
|
|
132
|
-
right: 40,
|
|
133
|
-
},
|
|
134
|
-
duration: 0,
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
map.scrollZoom.disable();
|
|
138
|
-
map.addControl(new mapboxgl.NavigationControl());
|
|
139
|
-
|
|
140
|
-
map.on('load', () => {
|
|
141
|
-
map.fitBounds(bounds, {
|
|
142
|
-
padding: {
|
|
143
|
-
top: 40,
|
|
144
|
-
bottom: 40,
|
|
145
|
-
left: 20,
|
|
146
|
-
right: 40,
|
|
147
|
-
},
|
|
148
|
-
duration: 0,
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// Turn off Points of Interest labels
|
|
152
|
-
map.setLayoutProperty('poi-label', 'visibility', 'none');
|
|
153
|
-
|
|
154
|
-
// Find the index of the first symbol layer in the map style to put the route lines underneath
|
|
155
|
-
let firstSymbolId;
|
|
156
|
-
for (const layer of map.getStyle().layers) {
|
|
157
|
-
if (layer.type === 'symbol') {
|
|
158
|
-
firstSymbolId = layer.id;
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Add route drop shadow outline first
|
|
164
|
-
map.addLayer(
|
|
165
|
-
{
|
|
166
|
-
id: 'route-line-shadow',
|
|
167
|
-
type: 'line',
|
|
168
|
-
source: {
|
|
169
|
-
type: 'geojson',
|
|
170
|
-
data: geojson,
|
|
171
|
-
},
|
|
172
|
-
paint: {
|
|
173
|
-
'line-color': '#000000',
|
|
174
|
-
'line-opacity': 0.3,
|
|
175
|
-
'line-width': {
|
|
176
|
-
base: 12,
|
|
177
|
-
stops: [
|
|
178
|
-
[14, 20],
|
|
179
|
-
[18, 42],
|
|
180
|
-
],
|
|
181
|
-
},
|
|
182
|
-
'line-blur': {
|
|
183
|
-
base: 12,
|
|
184
|
-
stops: [
|
|
185
|
-
[14, 20],
|
|
186
|
-
[18, 42],
|
|
187
|
-
],
|
|
188
|
-
},
|
|
189
|
-
},
|
|
190
|
-
layout: lineLayout,
|
|
191
|
-
filter: ['!has', 'stop_id'],
|
|
192
|
-
},
|
|
193
|
-
firstSymbolId,
|
|
194
|
-
);
|
|
195
|
-
|
|
196
|
-
// Add route line outline
|
|
197
|
-
map.addLayer(
|
|
198
|
-
{
|
|
199
|
-
id: 'route-line-outline',
|
|
200
|
-
type: 'line',
|
|
201
|
-
source: {
|
|
202
|
-
type: 'geojson',
|
|
203
|
-
data: geojson,
|
|
204
|
-
},
|
|
205
|
-
paint: {
|
|
206
|
-
'line-color': '#FFFFFF',
|
|
207
|
-
'line-opacity': 1,
|
|
208
|
-
'line-width': {
|
|
209
|
-
base: 8,
|
|
210
|
-
stops: [
|
|
211
|
-
[14, 12],
|
|
212
|
-
[18, 32],
|
|
213
|
-
],
|
|
214
|
-
},
|
|
215
|
-
},
|
|
216
|
-
layout: lineLayout,
|
|
217
|
-
filter: ['!has', 'stop_id'],
|
|
218
|
-
},
|
|
219
|
-
firstSymbolId,
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
// Add route line
|
|
223
|
-
map.addLayer(
|
|
224
|
-
{
|
|
225
|
-
id: 'route-line',
|
|
226
|
-
type: 'line',
|
|
227
|
-
source: {
|
|
228
|
-
type: 'geojson',
|
|
229
|
-
data: geojson,
|
|
230
|
-
},
|
|
231
|
-
paint: {
|
|
232
|
-
'line-color': ['to-color', ['get', 'route_color'], defaultRouteColor],
|
|
233
|
-
'line-opacity': 1,
|
|
234
|
-
'line-width': {
|
|
235
|
-
base: 4,
|
|
236
|
-
stops: [
|
|
237
|
-
[14, 6],
|
|
238
|
-
[18, 16],
|
|
239
|
-
],
|
|
240
|
-
},
|
|
241
|
-
},
|
|
242
|
-
layout: lineLayout,
|
|
243
|
-
filter: ['!has', 'stop_id'],
|
|
244
|
-
},
|
|
245
|
-
firstSymbolId,
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
// Add stops
|
|
249
|
-
map.addLayer({
|
|
250
|
-
id: 'stops',
|
|
251
|
-
type: 'circle',
|
|
252
|
-
source: {
|
|
253
|
-
type: 'geojson',
|
|
254
|
-
data: geojson,
|
|
255
|
-
},
|
|
256
|
-
paint: {
|
|
257
|
-
'circle-color': '#fff',
|
|
258
|
-
'circle-radius': {
|
|
259
|
-
base: 1.75,
|
|
260
|
-
stops: [
|
|
261
|
-
[12, 4],
|
|
262
|
-
[22, 100],
|
|
263
|
-
],
|
|
264
|
-
},
|
|
265
|
-
'circle-stroke-color': '#3f4a5c',
|
|
266
|
-
'circle-stroke-width': 2,
|
|
267
|
-
},
|
|
268
|
-
filter: ['has', 'stop_id'],
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
// Layer for highlighted stops
|
|
272
|
-
map.addLayer({
|
|
273
|
-
id: 'stops-highlighted',
|
|
274
|
-
type: 'circle',
|
|
275
|
-
source: {
|
|
276
|
-
type: 'geojson',
|
|
277
|
-
data: geojson,
|
|
278
|
-
},
|
|
279
|
-
paint: {
|
|
280
|
-
'circle-color': '#fff',
|
|
281
|
-
'circle-radius': {
|
|
282
|
-
base: 1.75,
|
|
283
|
-
stops: [
|
|
284
|
-
[12, 5],
|
|
285
|
-
[22, 125],
|
|
286
|
-
],
|
|
287
|
-
},
|
|
288
|
-
'circle-stroke-width': 2,
|
|
289
|
-
'circle-stroke-color': '#3f4a5c',
|
|
290
|
-
},
|
|
291
|
-
filter: ['==', 'stop_id', ''],
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
map.on('mousemove', (event) => {
|
|
295
|
-
const features = map.queryRenderedFeatures(event.point, {
|
|
296
|
-
layers: ['stops'],
|
|
297
|
-
});
|
|
298
|
-
if (features.length > 0) {
|
|
299
|
-
map.getCanvas().style.cursor = 'pointer';
|
|
300
|
-
highlightStop(features[0].properties.stop_id);
|
|
301
|
-
} else {
|
|
302
|
-
map.getCanvas().style.cursor = '';
|
|
303
|
-
unHighlightStop();
|
|
304
|
-
}
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
map.on('click', (event) => {
|
|
308
|
-
// Set bbox as 5px rectangle area around clicked point
|
|
309
|
-
const bbox = [
|
|
310
|
-
[event.point.x - 5, event.point.y - 5],
|
|
311
|
-
[event.point.x + 5, event.point.y + 5],
|
|
312
|
-
];
|
|
313
|
-
const features = map.queryRenderedFeatures(bbox, {
|
|
314
|
-
layers: ['stops-highlighted', 'stops'],
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
if (!features || features.length === 0) {
|
|
318
|
-
return;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Get the first feature and show popup
|
|
322
|
-
const feature = features[0];
|
|
323
|
-
|
|
324
|
-
new mapboxgl.Popup()
|
|
325
|
-
.setLngLat(feature.geometry.coordinates)
|
|
326
|
-
.setHTML(formatStopPopup(feature, routes))
|
|
327
|
-
.addTo(map);
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
function highlightStop(stopId) {
|
|
331
|
-
map.setFilter('stops-highlighted', ['==', 'stop_id', stopId]);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
function unHighlightStop() {
|
|
335
|
-
map.setFilter('stops-highlighted', ['==', 'stop_id', '']);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// On table hover, highlight stop on map
|
|
339
|
-
$('th, td', $('#' + id + ' table')).hover((event) => {
|
|
340
|
-
let stopId;
|
|
341
|
-
const table = $(event.target).parents('table');
|
|
342
|
-
if (table.data('orientation') === 'vertical') {
|
|
343
|
-
var index = $(event.target).index();
|
|
344
|
-
stopId = $('colgroup col', table).eq(index).data('stop-id');
|
|
345
|
-
} else {
|
|
346
|
-
stopId = $(event.target).parents('tr').data('stop-id');
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (stopId === undefined) {
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
highlightStop(stopId.toString());
|
|
354
|
-
}, unHighlightStop);
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
maps[id] = map;
|
|
358
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/* global window, document, $, maps */
|
|
2
|
-
/* eslint no-unused-vars: "off" */
|
|
3
|
-
|
|
4
|
-
$(() => {
|
|
5
|
-
showSelectedTimetable();
|
|
6
|
-
|
|
7
|
-
$('#day_list_selector input[name="dayList"]').change(() => {
|
|
8
|
-
showSelectedTimetable();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
$('#direction_name_selector input[name="directionName"]').change(() => {
|
|
12
|
-
showSelectedTimetable();
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
function showSelectedTimetable() {
|
|
16
|
-
if ($('.timetable').length === 1) {
|
|
17
|
-
showTimetable($('.timetable').attr('id'));
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
$('#day_list_selector input[name="dayList"]').each((index, element) => {
|
|
22
|
-
$(element)
|
|
23
|
-
.parents('label')
|
|
24
|
-
.toggleClass('btn-blue', $(element).is(':checked'));
|
|
25
|
-
$(element)
|
|
26
|
-
.parents('label')
|
|
27
|
-
.toggleClass('btn-gray', $(element).is(':not(:checked)'));
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
$('#direction_name_selector input[name="directionName"]').each(
|
|
31
|
-
(index, element) => {
|
|
32
|
-
$(element)
|
|
33
|
-
.parents('label')
|
|
34
|
-
.toggleClass('btn-blue', $(element).is(':checked'));
|
|
35
|
-
$(element)
|
|
36
|
-
.parents('label')
|
|
37
|
-
.toggleClass('btn-gray', $(element).is(':not(:checked)'));
|
|
38
|
-
},
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
const dayList = $('#day_list_selector input[name="dayList"]:checked').val();
|
|
42
|
-
const directionName = $(
|
|
43
|
-
'#direction_name_selector input[name="directionName"]:checked',
|
|
44
|
-
).val();
|
|
45
|
-
|
|
46
|
-
$('.timetable').hide();
|
|
47
|
-
const id = $(
|
|
48
|
-
'.timetable[data-day-list="' +
|
|
49
|
-
dayList +
|
|
50
|
-
'"][data-direction-name="' +
|
|
51
|
-
directionName +
|
|
52
|
-
'"]',
|
|
53
|
-
).attr('id');
|
|
54
|
-
showTimetable(id);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function showTimetable(id) {
|
|
58
|
-
$('#' + id).show();
|
|
59
|
-
if (typeof maps !== 'undefined' && maps[id]) {
|
|
60
|
-
maps[id].resize();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
});
|
package/views/default/layout.pug
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
include formatting_functions.pug
|
|
2
|
-
|
|
3
|
-
.timetable-overview
|
|
4
|
-
if !timetablePages || !timetablePages.length
|
|
5
|
-
h1 No timetables found
|
|
6
|
-
else
|
|
7
|
-
.overview-list
|
|
8
|
-
each timetablePageGroup in getAgencyTimetableGroups(timetablePages, agencies)
|
|
9
|
-
h1= `${formatAgencyName(timetablePageGroup.agency)} Routes`
|
|
10
|
-
each timetablePage in timetablePageGroup.timetablePages
|
|
11
|
-
if config.allowEmptyTimetables || timetablePage.consolidatedTimetables.length > 0
|
|
12
|
-
a.timetable-page-link(href=`${timetablePage.relativePath}` data-route-ids=`${timetablePage.route_ids ? timetablePage.route_ids.join(',') : ''}`)
|
|
13
|
-
- const timetableRouteList = _.uniqBy(_.flatMap(timetablePage.consolidatedTimetables, timetable => timetable.routes), 'route_id')
|
|
14
|
-
each route in timetableRouteList
|
|
15
|
-
.route-color-swatch-large(style=`background-color: ${formatRouteColor(route)}; color: ${formatRouteTextColor(route)};`)= route.route_short_name || ''
|
|
16
|
-
div
|
|
17
|
-
.timetable-page-label= timetablePage.timetable_page_label || timetableRouteList.map(route => formatRouteName(route)).join(' and ')
|
|
18
|
-
.badge-gray= timetablePage.dayList
|
|
19
|
-
if config.showMap
|
|
20
|
-
#system_map.overview-map
|
|
21
|
-
|
|
22
|
-
//- Use !{variable} format to inject values from pug to client side js
|
|
23
|
-
script.
|
|
24
|
-
(function() {
|
|
25
|
-
const geojson = !{JSON.stringify(geojson) || '\'\''};
|
|
26
|
-
createSystemMap('system_map', geojson);
|
|
27
|
-
})();
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
extends layout
|
|
2
|
-
block content
|
|
3
|
-
include overview.pug
|
|
4
|
-
|
|
5
|
-
block extraHeader
|
|
6
|
-
if config.showMap
|
|
7
|
-
script(src="https://unpkg.com/jquery@3.7.1/dist/jquery.min.js" crossorigin="anonymous")
|
|
8
|
-
script(src="https://unpkg.com/lodash@4.17.21/lodash.min.js" crossorigin="anonymous")
|
|
9
|
-
script(src="https://api.mapbox.com/mapbox-gl-js/v3.5.1/mapbox-gl.js")
|
|
10
|
-
script.
|
|
11
|
-
mapboxgl.accessToken = '#{config.mapboxAccessToken}';
|
|
12
|
-
script(src=`${config.assetPath}js/system-map.js`)
|
|
13
|
-
|
|
14
|
-
link(href="https://api.mapbox.com/mapbox-gl-js/v3.5.1/mapbox-gl.css" rel="stylesheet")
|
|
15
|
-
|
|
16
|
-
link(rel="stylesheet" href=`${config.assetPath}css/overview_styles.css`)
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
- const routeColorCss = trip.continues_as_route ? getRouteColorsAsCss(trip.continues_as_route.route) : ''
|
|
2
|
-
td.run-footer(style=routeColorCss)
|
|
3
|
-
if trip.continues_as_route
|
|
4
|
-
if trip.continues_as_route.route.route_url
|
|
5
|
-
a.continues-as-route(href=`${trip.continues_as_route.route.route_url}` style=routeColorCss data-trip-id=trip.continues_as_route.trip_id)= trip.continues_as_route.route.route_short_name
|
|
6
|
-
else
|
|
7
|
-
.continues-as-route(data-trip-id=trip.continues_as_route.trip_id)= trip.continues_as_route.route.route_short_name
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
- const routeColorCss = trip.continues_from_route ? getRouteColorsAsCss(trip.continues_from_route.route) : ''
|
|
2
|
-
td.run-footer(style=routeColorCss)
|
|
3
|
-
if trip.continues_from_route
|
|
4
|
-
if trip.continues_from_route.route.route_url
|
|
5
|
-
a.continues-from-route(href=`${trip.continues_from_route.route.route_url}` style=routeColorCss data-trip-id=trip.continues_from_route.trip_id)= trip.continues_from_route.route.route_short_name
|
|
6
|
-
else
|
|
7
|
-
.continues-from-route(data-trip-id=trip.continues_from_route.trip_id)= trip.continues_from_route.route.route_short_name
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
.table-container
|
|
2
|
-
table.table-horizontal(summary= getTimetableSummary(timetable) data-orientation="horizontal")
|
|
3
|
-
caption.sr-only= `${timetable.timetable_label} | ${timetable.dayList}`
|
|
4
|
-
colgroup
|
|
5
|
-
col
|
|
6
|
-
each trip, idx in timetable.orderedTrips
|
|
7
|
-
col(id=`trip_id_${formatHtmlId(trip.trip_id)}` class=`run_${idx} ${(trip.trip_short_name) ? 'trip_short_name_' + trip.trip_short_name : ''}`)
|
|
8
|
-
thead
|
|
9
|
-
tr
|
|
10
|
-
th.stop-header(scope="col") Stop
|
|
11
|
-
each trip, idx in timetable.orderedTrips
|
|
12
|
-
th.run-header(scope="col")= formatTripName(trip, idx, timetable)
|
|
13
|
-
each note in getNotesForTrip(timetable.notes, trip)
|
|
14
|
-
include timetable_note_symbol.pug
|
|
15
|
-
if timetable.frequencies && !timetable.frequencyExactTimes
|
|
16
|
-
tr.trip-row
|
|
17
|
-
td.trip-frequency(colspan=`${timetable.orderedTrips.length + 1}`)!= formatFrequencyWarning(timetable.frequencies)
|
|
18
|
-
tbody
|
|
19
|
-
if timetable.has_continues_from_route
|
|
20
|
-
tr.continues-from-row
|
|
21
|
-
th Continues from route
|
|
22
|
-
each trip in timetable.orderedTrips
|
|
23
|
-
include timetable_continuation_from.pug
|
|
24
|
-
- let previousCity = null;
|
|
25
|
-
each stop in timetable.stops
|
|
26
|
-
if stop.stop_city !== '' && previousCity !== stop.stop_city && config.showStopCity
|
|
27
|
-
tr.city-row
|
|
28
|
-
th(scope="row" colspan=`${stop.trips.length + 1}`)= stop.stop_city
|
|
29
|
-
- previousCity = stop.stop_city
|
|
30
|
-
|
|
31
|
-
tr.stop-row(id=`stop_id_${formatHtmlId(stop.stop_id)}` data-stop-id=`${stop.stop_id}` data-is-timepoint=`${stop.is_timepoint}`)
|
|
32
|
-
th.stop-name-container(scope="row")
|
|
33
|
-
include timetable_stop_name.pug
|
|
34
|
-
|
|
35
|
-
each stoptime in stop.trips
|
|
36
|
-
include timetable_stoptime.pug
|
|
37
|
-
|
|
38
|
-
if timetable.has_continues_as_route
|
|
39
|
-
tr.continues-as-row
|
|
40
|
-
th Continues as route
|
|
41
|
-
each trip in timetable.orderedTrips
|
|
42
|
-
include timetable_continuation_as.pug
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
.table-container
|
|
2
|
-
table.table-hourly(summary= getTimetableSummary(timetable) data-orientation="hourly")
|
|
3
|
-
caption.sr-only= `${timetable.timetable_label} | ${timetable.dayList}`
|
|
4
|
-
thead
|
|
5
|
-
tr
|
|
6
|
-
th.stop-header(scope="col") Stop
|
|
7
|
-
th(scope="col") Minutes after the hour
|
|
8
|
-
|
|
9
|
-
tbody
|
|
10
|
-
if timetable.frequencies && !timetable.frequencyExactTimes
|
|
11
|
-
tr.trip-row
|
|
12
|
-
td.trip-frequency(colspan="2")!= formatFrequencyWarning(timetable.frequencies)
|
|
13
|
-
- let previousCity
|
|
14
|
-
each stop in timetable.stops
|
|
15
|
-
if previousCity !== stop.stop_city && config.showStopCity
|
|
16
|
-
tr.city-row
|
|
17
|
-
th(scope="row" colspan="2")= stop.stop_city
|
|
18
|
-
- previousCity = stop.stop_city
|
|
19
|
-
|
|
20
|
-
tr.stop-row(id=`stop_id_${formatHtmlId(stop.stop_id)}` data-stop-id=`${stop.stop_id}`)
|
|
21
|
-
th.stop-name-container(scope="row")
|
|
22
|
-
include timetable_stop_name.pug
|
|
23
|
-
|
|
24
|
-
td.stop-time= stop.hourlyTimes.join(', ')
|
|
25
|
-
|
|
26
|
-
- const firstStop = timetable.stops[0]
|
|
27
|
-
- const firstTripStartTime = firstStop.trips[0]
|
|
28
|
-
- const lastStop = timetable.stops[timetable.stops.length - 1]
|
|
29
|
-
- const lastTripEndTime = lastStop.trips[lastStop.trips.length - 1]
|
|
30
|
-
.table-hourly-notes!= `Service begins at ${firstStop.stop_name} at ${firstTripStartTime.formatted_time} and ends at ${lastStop.stop_name} at ${lastTripEndTime.formatted_time}.`
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
if timetablePage.consolidatedTimetables.length > 1
|
|
2
|
-
if config.menuType === 'simple'
|
|
3
|
-
ul.timetable-simple-menu
|
|
4
|
-
- const showTimetableLabel = timetablePageHasDifferentLabels(timetablePage);
|
|
5
|
-
- const showDayList = timetablePageHasDifferentDays(timetablePage);
|
|
6
|
-
each timetable in timetablePage.consolidatedTimetables
|
|
7
|
-
li
|
|
8
|
-
a(href=`#timetable_id_${timetable.timetable_id}`)
|
|
9
|
-
if showTimetableLabel
|
|
10
|
-
span= timetable.timetable_label
|
|
11
|
-
if showTimetableLabel && showDayList
|
|
12
|
-
span |
|
|
13
|
-
if showDayList
|
|
14
|
-
span= timetable.dayListLong
|
|
15
|
-
|
|
16
|
-
if config.menuType === 'jump'
|
|
17
|
-
-
|
|
18
|
-
const groupedTimetables = timetablePage.consolidatedTimetables.reduce((memo, timetable) => {
|
|
19
|
-
if (!memo.hasOwnProperty(timetable.dayList)) {
|
|
20
|
-
memo[timetable.dayList] = []
|
|
21
|
-
}
|
|
22
|
-
memo[timetable.dayList].push(timetable);
|
|
23
|
-
return memo;
|
|
24
|
-
}, {});
|
|
25
|
-
.timetable-jump-menu
|
|
26
|
-
each group, dayList in groupedTimetables
|
|
27
|
-
div
|
|
28
|
-
h3= dayList
|
|
29
|
-
each timetable in group
|
|
30
|
-
a.btn-blue(href=`#timetable_id_${timetable.timetable_id}`)= timetable.timetable_label
|
|
31
|
-
|
|
32
|
-
if config.menuType === 'radio'
|
|
33
|
-
.timetable-radio-menu
|
|
34
|
-
-const directionNames = _.uniq(timetablePage.consolidatedTimetables.map(timetable => timetable.direction_name));
|
|
35
|
-
div(hidden=directionNames.length <= 1)
|
|
36
|
-
#direction_name_selector
|
|
37
|
-
h3 Service Direction
|
|
38
|
-
each directionName, idx in directionNames
|
|
39
|
-
label(class=idx === 0 ? 'btn-blue' : 'btn-gray')
|
|
40
|
-
input.hidden(type="radio" name="directionName" autocomplete="off" value=directionName checked=(idx === 0))
|
|
41
|
-
span= directionName
|
|
42
|
-
div(hidden=timetablePage.dayLists.length <= 1)
|
|
43
|
-
#day_list_selector
|
|
44
|
-
h3 Day of Week
|
|
45
|
-
each dayList, idx in timetablePage.dayLists
|
|
46
|
-
label(class=idx === 0 ? 'btn-blue' : 'btn-gray')
|
|
47
|
-
input.hidden(type="radio" name="dayList" autocomplete="off" value=dayList checked=(idx === 0))
|
|
48
|
-
span= dayList
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
- const stopName = `${stop.stop_name}${stop.type === 'arrival' ? ' (Arrival)' : stop.type === 'departure' ? ' (Departure)' : ''}`;
|
|
2
|
-
|
|
3
|
-
if config.linkStopUrls && stop.stop_url
|
|
4
|
-
a.stop-name(href=`${stop.stop_url}`)= stopName
|
|
5
|
-
each note in getNotesForStop(timetable.notes, stop)
|
|
6
|
-
include timetable_note_symbol.pug
|
|
7
|
-
else
|
|
8
|
-
.stop-name= stopName
|
|
9
|
-
each note in getNotesForStop(timetable.notes, stop)
|
|
10
|
-
include timetable_note_symbol.pug
|
|
11
|
-
.stop-code= stop.stop_code
|
|
12
|
-
if config.showStopDescription
|
|
13
|
-
.stop-description= stop.stop_desc
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
td.stop-time(class=`${stoptime.classes.join(' ')}`)
|
|
2
|
-
if config.showStoptimesForRequestStops || (!stoptime.requestDropoff && !stoptime.requestPickup)
|
|
3
|
-
span.stop-time-text!= stoptime.formatted_time
|
|
4
|
-
if stoptime.skipped && timetable.noServiceSymbol !== null
|
|
5
|
-
a(href=`#note-${timetable.timetable_id}-no-service`).symbol= timetable.noServiceSymbol
|
|
6
|
-
if stoptime.interpolated && timetable.interpolatedStopSymbol !== null
|
|
7
|
-
a(href=`#note-${timetable.timetable_id}-interpolated-stop`).symbol= timetable.interpolatedStopSymbol
|
|
8
|
-
if stoptime.requestPickup && timetable.requestPickupSymbol !== null
|
|
9
|
-
a(href=`#note-${timetable.timetable_id}-request-pickup`).symbol= timetable.requestPickupSymbol
|
|
10
|
-
if stoptime.noPickup && timetable.noPickupSymbol !== null
|
|
11
|
-
a(href=`#note-${timetable.timetable_id}-no-pickup`).symbol= timetable.noPickupSymbol
|
|
12
|
-
if stoptime.requestDropoff && timetable.requestDropoffSymbol !== null
|
|
13
|
-
a(href=`#note-${timetable.timetable_id}-request-dropoff`).symbol= timetable.requestDropoffSymbol
|
|
14
|
-
if stoptime.noDropoff && timetable.noDropoffSymbol !== null
|
|
15
|
-
a(href=`#note-${timetable.timetable_id}-no-dropoff`).symbol= timetable.noDropoffSymbol
|
|
16
|
-
each note in getNotesForStoptime(timetable.notes, stoptime)
|
|
17
|
-
include timetable_note_symbol.pug
|