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.
Files changed (84) hide show
  1. package/package.json +21 -8
  2. package/.eslintrc.json +0 -28
  3. package/.husky/pre-commit +0 -4
  4. package/CHANGELOG.md +0 -1018
  5. package/app/index.js +0 -138
  6. package/bin/gtfs-to-html.js +0 -48
  7. package/config-sample.json +0 -59
  8. package/docker/Dockerfile +0 -14
  9. package/docker/README.md +0 -5
  10. package/docker/docker-compose.yml +0 -10
  11. package/examples/stop_attributes.txt +0 -6
  12. package/examples/timetable_notes.txt +0 -8
  13. package/examples/timetable_notes_references.txt +0 -8
  14. package/examples/timetable_pages.txt +0 -3
  15. package/examples/timetable_stop_order.txt +0 -16
  16. package/examples/timetables.txt +0 -9
  17. package/index.js +0 -1
  18. package/lib/file-utils.js +0 -202
  19. package/lib/formatters.js +0 -518
  20. package/lib/geojson-utils.js +0 -96
  21. package/lib/gtfs-to-html.js +0 -214
  22. package/lib/log-utils.js +0 -215
  23. package/lib/template-functions.js +0 -192
  24. package/lib/time-utils.js +0 -90
  25. package/lib/utils.js +0 -1702
  26. package/views/default/css/overview_styles.css +0 -197
  27. package/views/default/css/timetable_pdf_styles.css +0 -7
  28. package/views/default/css/timetable_styles.css +0 -447
  29. package/views/default/formatting_functions.pug +0 -113
  30. package/views/default/js/system-map.js +0 -594
  31. package/views/default/js/timetable-map.js +0 -358
  32. package/views/default/js/timetable-menu.js +0 -63
  33. package/views/default/layout.pug +0 -11
  34. package/views/default/overview.pug +0 -27
  35. package/views/default/overview_full.pug +0 -16
  36. package/views/default/timetable_continuation_as.pug +0 -7
  37. package/views/default/timetable_continuation_from.pug +0 -7
  38. package/views/default/timetable_horizontal.pug +0 -42
  39. package/views/default/timetable_hourly.pug +0 -30
  40. package/views/default/timetable_menu.pug +0 -48
  41. package/views/default/timetable_note_symbol.pug +0 -5
  42. package/views/default/timetable_stop_name.pug +0 -13
  43. package/views/default/timetable_stoptime.pug +0 -17
  44. package/views/default/timetable_vertical.pug +0 -67
  45. package/views/default/timetablepage.pug +0 -66
  46. package/views/default/timetablepage_full.pug +0 -22
  47. package/www/README.md +0 -33
  48. package/www/babel.config.js +0 -3
  49. package/www/blog/2020-07-07-New-Documentation.md +0 -12
  50. package/www/blog/2020-08-20-Version-1.0.0.md +0 -29
  51. package/www/blog/2021-11-06-CSV-Export.md +0 -26
  52. package/www/docs/additional-files.md +0 -24
  53. package/www/docs/configuration.md +0 -568
  54. package/www/docs/current-usage.md +0 -48
  55. package/www/docs/custom-templates.md +0 -13
  56. package/www/docs/introduction.md +0 -39
  57. package/www/docs/logging-sql-queries.md +0 -12
  58. package/www/docs/previewing-html-output.md +0 -24
  59. package/www/docs/processing-large-gtfs.md +0 -10
  60. package/www/docs/quick-start.md +0 -136
  61. package/www/docs/related-libraries.md +0 -54
  62. package/www/docs/reviewing-changes.md +0 -29
  63. package/www/docs/stop-attributes.md +0 -30
  64. package/www/docs/support.md +0 -12
  65. package/www/docs/timetable-notes-references.md +0 -44
  66. package/www/docs/timetable-notes.md +0 -33
  67. package/www/docs/timetable-pages.md +0 -37
  68. package/www/docs/timetable-stop-order.md +0 -63
  69. package/www/docs/timetables.md +0 -64
  70. package/www/docusaurus.config.js +0 -104
  71. package/www/package.json +0 -21
  72. package/www/sidebars.js +0 -10
  73. package/www/src/css/custom.css +0 -25
  74. package/www/src/pages/index.js +0 -270
  75. package/www/src/pages/styles.module.css +0 -53
  76. package/www/static/.nojekyll +0 -0
  77. package/www/static/img/favicon.ico +0 -0
  78. package/www/static/img/gtfs-to-html-logo.svg +0 -18
  79. package/www/static/img/overview-example.jpg +0 -0
  80. package/www/static/img/timetable-example.jpg +0 -0
  81. package/www/static/img/undraw_happy_music.svg +0 -1
  82. package/www/static/img/undraw_proud_coder.svg +0 -1
  83. package/www/static/img/undraw_spreadsheets.svg +0 -1
  84. 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
- });
@@ -1,11 +0,0 @@
1
- doctype html
2
- html
3
- head
4
- title= title
5
- meta(charset="utf-8")
6
- meta(name="viewport" content="initial-scale=1.0, width=device-width")
7
-
8
- block extraHeader
9
-
10
- body
11
- block content
@@ -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 &nbsp;|&nbsp;
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,5 +0,0 @@
1
- a(href=`#note-${timetable.timetable_id}-${note.note_id}` class=`timetable-note-${note.note_id}`).symbol
2
- if timetable.routes.length <= 1 && timetable.orientation === 'vertical'
3
- span= note.symbol
4
- else
5
- sup= note.symbol
@@ -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