gtfs-to-html 2.6.11 → 2.7.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/CHANGELOG.md +20 -0
- package/app/index.js +14 -9
- package/lib/file-utils.js +11 -16
- package/lib/formatters.js +2 -43
- package/lib/gtfs-to-html.js +2 -2
- package/lib/utils.js +0 -2
- package/package.json +5 -5
- package/{public → views/default}/css/overview_styles.css +92 -137
- package/views/default/css/timetable_styles.css +447 -0
- package/views/default/formatting_functions.pug +21 -5
- package/{public → views/default}/js/system-map.js +33 -23
- package/{public → views/default}/js/timetable-map.js +32 -27
- package/views/default/overview.pug +12 -12
- package/views/default/timetable_continuation_as.pug +3 -9
- package/views/default/timetable_continuation_from.pug +4 -10
- package/views/default/timetable_horizontal.pug +1 -1
- package/views/default/timetable_hourly.pug +5 -5
- package/views/default/timetable_menu.pug +46 -47
- package/views/default/timetable_stop_name.pug +1 -1
- package/views/default/timetable_vertical.pug +4 -4
- package/views/default/timetablepage.pug +55 -55
- package/www/docs/configuration.md +2 -2
- package/www/docs/custom-templates.md +1 -3
- package/www/docs/timetables.md +2 -2
- package/public/css/timetable_styles.css +0 -497
- /package/{public → views/default}/css/timetable_pdf_styles.css +0 -0
- /package/{public → views/default}/js/timetable-menu.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.7.0] - 2024-07-27
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- Fixes for horizontal orientation labels
|
|
12
|
+
|
|
13
|
+
### Updated
|
|
14
|
+
- Better date format documentation
|
|
15
|
+
- Better default for timetable_page_label
|
|
16
|
+
- Larger map on desktop
|
|
17
|
+
- Improved button styles
|
|
18
|
+
- Serve static assets from templatePath
|
|
19
|
+
- Move static js and css to views/default
|
|
20
|
+
- Dependency updates
|
|
21
|
+
|
|
22
|
+
## [2.6.12] - 2024-07-26
|
|
23
|
+
|
|
24
|
+
### Updated
|
|
25
|
+
- Dependency updates
|
|
26
|
+
- Improved styles for default template
|
|
27
|
+
|
|
8
28
|
## [2.6.11] - 2024-07-24
|
|
9
29
|
|
|
10
30
|
### Updated
|
package/app/index.js
CHANGED
|
@@ -4,9 +4,9 @@ import { readFileSync } from 'node:fs';
|
|
|
4
4
|
import { map } from 'lodash-es';
|
|
5
5
|
import yargs from 'yargs';
|
|
6
6
|
import { openDb } from 'gtfs';
|
|
7
|
-
|
|
8
7
|
import express from 'express';
|
|
9
8
|
import logger from 'morgan';
|
|
9
|
+
import untildify from 'untildify';
|
|
10
10
|
|
|
11
11
|
import { formatTimetableLabel } from '../lib/formatters.js';
|
|
12
12
|
import {
|
|
@@ -44,7 +44,7 @@ try {
|
|
|
44
44
|
} catch (error) {
|
|
45
45
|
if (error instanceof Error && error.code === 'SQLITE_CANTOPEN') {
|
|
46
46
|
config.logError(
|
|
47
|
-
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json
|
|
47
|
+
`Unable to open sqlite database "${config.sqlitePath}" defined as \`sqlitePath\` config.json. Ensure the parent directory exists or remove \`sqlitePath\` from config.json.`,
|
|
48
48
|
);
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -59,14 +59,14 @@ router.get('/', async (request, response, next) => {
|
|
|
59
59
|
const timetablePages = [];
|
|
60
60
|
const timetablePageIds = map(
|
|
61
61
|
getTimetablePagesForAgency(config),
|
|
62
|
-
'timetable_page_id'
|
|
62
|
+
'timetable_page_id',
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
for (const timetablePageId of timetablePageIds) {
|
|
66
66
|
// eslint-disable-next-line no-await-in-loop
|
|
67
67
|
const timetablePage = await getFormattedTimetablePage(
|
|
68
68
|
timetablePageId,
|
|
69
|
-
config
|
|
69
|
+
config,
|
|
70
70
|
);
|
|
71
71
|
|
|
72
72
|
if (
|
|
@@ -74,7 +74,7 @@ router.get('/', async (request, response, next) => {
|
|
|
74
74
|
timetablePage.consolidatedTimetables.length === 0
|
|
75
75
|
) {
|
|
76
76
|
console.error(
|
|
77
|
-
`No timetables found for timetable_page_id=${timetablePage.timetable_page_id}
|
|
77
|
+
`No timetables found for timetable_page_id=${timetablePage.timetable_page_id}`,
|
|
78
78
|
);
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -107,7 +107,7 @@ router.get('/timetables/:timetablePageId', async (request, response, next) => {
|
|
|
107
107
|
try {
|
|
108
108
|
const timetablePage = await getFormattedTimetablePage(
|
|
109
109
|
timetablePageId,
|
|
110
|
-
config
|
|
110
|
+
config,
|
|
111
111
|
);
|
|
112
112
|
|
|
113
113
|
const html = await generateTimetableHTML(timetablePage, config);
|
|
@@ -121,9 +121,14 @@ app.set('views', path.join(fileURLToPath(import.meta.url), '../../views'));
|
|
|
121
121
|
app.set('view engine', 'pug');
|
|
122
122
|
|
|
123
123
|
app.use(logger('dev'));
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
124
|
+
|
|
125
|
+
// Serve static assets
|
|
126
|
+
const staticAssetPath =
|
|
127
|
+
config.templatePath === undefined
|
|
128
|
+
? path.join(fileURLToPath(import.meta.url), '../../views/default')
|
|
129
|
+
: untildify(config.templatePath);
|
|
130
|
+
|
|
131
|
+
app.use(express.static(staticAssetPath));
|
|
127
132
|
|
|
128
133
|
app.use('/', router);
|
|
129
134
|
app.set('port', process.env.PORT || 3000);
|
package/lib/file-utils.js
CHANGED
|
@@ -66,18 +66,12 @@ function getTemplatePath(templateFileName, config) {
|
|
|
66
66
|
fullTemplateFileName += '_full';
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
);
|
|
74
|
-
}
|
|
69
|
+
const templatePath =
|
|
70
|
+
config.templatePath === undefined
|
|
71
|
+
? path.join(fileURLToPath(import.meta.url), '../../views/default')
|
|
72
|
+
: untildify(config.templatePath);
|
|
75
73
|
|
|
76
|
-
return path.join(
|
|
77
|
-
fileURLToPath(import.meta.url),
|
|
78
|
-
'../../views/default',
|
|
79
|
-
`${fullTemplateFileName}.pug`,
|
|
80
|
-
);
|
|
74
|
+
return path.join(templatePath, `${fullTemplateFileName}.pug`);
|
|
81
75
|
}
|
|
82
76
|
|
|
83
77
|
/*
|
|
@@ -101,11 +95,12 @@ export async function prepDirectory(exportPath) {
|
|
|
101
95
|
/*
|
|
102
96
|
* Copy needed CSS and JS to export path.
|
|
103
97
|
*/
|
|
104
|
-
export function copyStaticAssets(exportPath) {
|
|
105
|
-
const staticAssetPath =
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
export function copyStaticAssets(config, exportPath) {
|
|
99
|
+
const staticAssetPath =
|
|
100
|
+
config.templatePath === undefined
|
|
101
|
+
? path.join(fileURLToPath(import.meta.url), '../../views/default')
|
|
102
|
+
: untildify(config.templatePath);
|
|
103
|
+
|
|
109
104
|
copydir.sync(path.join(staticAssetPath, 'css'), path.join(exportPath, 'css'));
|
|
110
105
|
copydir.sync(path.join(staticAssetPath, 'js'), path.join(exportPath, 'js'));
|
|
111
106
|
}
|
package/lib/formatters.js
CHANGED
|
@@ -247,20 +247,6 @@ export function formatTrip(trip, timetable, calendars, config) {
|
|
|
247
247
|
return trip;
|
|
248
248
|
}
|
|
249
249
|
|
|
250
|
-
/*
|
|
251
|
-
* Format a route name.
|
|
252
|
-
*/
|
|
253
|
-
export function formatRouteName(route) {
|
|
254
|
-
let routeName = 'Route ';
|
|
255
|
-
if (!isNullOrEmpty(route.route_short_name)) {
|
|
256
|
-
routeName += route.route_short_name;
|
|
257
|
-
} else if (!isNullOrEmpty(route.route_long_name)) {
|
|
258
|
-
routeName += route.route_long_name;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return routeName;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
250
|
/*
|
|
265
251
|
* Format a frequency.
|
|
266
252
|
*/
|
|
@@ -384,7 +370,7 @@ export function formatStopName(stop) {
|
|
|
384
370
|
}
|
|
385
371
|
|
|
386
372
|
/*
|
|
387
|
-
* Formats trip "
|
|
373
|
+
* Formats trip "Continues from".
|
|
388
374
|
*/
|
|
389
375
|
export function formatTripContinuesFrom(trip) {
|
|
390
376
|
return trip.continues_from_route
|
|
@@ -393,7 +379,7 @@ export function formatTripContinuesFrom(trip) {
|
|
|
393
379
|
}
|
|
394
380
|
|
|
395
381
|
/*
|
|
396
|
-
* Formats trip "
|
|
382
|
+
* Formats trip "Continues as".
|
|
397
383
|
*/
|
|
398
384
|
export function formatTripContinuesAs(trip) {
|
|
399
385
|
return trip.continues_as_route
|
|
@@ -500,33 +486,6 @@ export function formatTimetableLabel(timetable) {
|
|
|
500
486
|
return timetableLabel;
|
|
501
487
|
}
|
|
502
488
|
|
|
503
|
-
/*
|
|
504
|
-
* Format a label for a timetable page.
|
|
505
|
-
*/
|
|
506
|
-
export function formatTimetablePageLabel(timetablePage) {
|
|
507
|
-
if (!isNullOrEmpty(timetablePage.timetable_page_label)) {
|
|
508
|
-
return timetablePage.timetable_page_label;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
if (
|
|
512
|
-
timetablePage.consolidatedTimetables &&
|
|
513
|
-
timetablePage.consolidatedTimetables.length > 0
|
|
514
|
-
) {
|
|
515
|
-
// Use route names from all timetables
|
|
516
|
-
const routes = uniqBy(
|
|
517
|
-
flatMap(
|
|
518
|
-
timetablePage.consolidatedTimetables,
|
|
519
|
-
(timetable) => timetable.routes,
|
|
520
|
-
),
|
|
521
|
-
'route_id',
|
|
522
|
-
);
|
|
523
|
-
|
|
524
|
-
return routes.map((route) => formatRouteName(route)).join(' and ');
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
return 'Unknown';
|
|
528
|
-
}
|
|
529
|
-
|
|
530
489
|
/*
|
|
531
490
|
* Merge timetables with same `timetable_id`.
|
|
532
491
|
*/
|
package/lib/gtfs-to-html.js
CHANGED
|
@@ -89,7 +89,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
89
89
|
await prepDirectory(exportPath);
|
|
90
90
|
|
|
91
91
|
if (config.noHead !== true && ['html', 'pdf'].includes(config.outputFormat)) {
|
|
92
|
-
copyStaticAssets(exportPath);
|
|
92
|
+
copyStaticAssets(config, exportPath);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
const bar = progressBar(
|
|
@@ -134,7 +134,7 @@ const gtfsToHtml = async (initialConfig) => {
|
|
|
134
134
|
);
|
|
135
135
|
|
|
136
136
|
if (config.outputFormat === 'csv') {
|
|
137
|
-
for (const timetable of timetablePage.
|
|
137
|
+
for (const timetable of timetablePage.consolidatedTimetables) {
|
|
138
138
|
const csv = await generateTimetableCSV(timetable);
|
|
139
139
|
const csvPath = path.join(
|
|
140
140
|
exportPath,
|
package/lib/utils.js
CHANGED
|
@@ -58,7 +58,6 @@ import {
|
|
|
58
58
|
formatStops,
|
|
59
59
|
formatTimetableId,
|
|
60
60
|
formatTimetableLabel,
|
|
61
|
-
formatTimetablePageLabel,
|
|
62
61
|
formatTrip,
|
|
63
62
|
formatTripContinuesAs,
|
|
64
63
|
formatTripContinuesFrom,
|
|
@@ -1505,7 +1504,6 @@ export function getFormattedTimetablePage(timetablePageId, config) {
|
|
|
1505
1504
|
timetablePage.timetables,
|
|
1506
1505
|
config,
|
|
1507
1506
|
);
|
|
1508
|
-
timetablePage.timetable_page_label = formatTimetablePageLabel(timetablePage);
|
|
1509
1507
|
timetablePage.dayList = formatDays(
|
|
1510
1508
|
getDaysFromCalendars(timetablePage.consolidatedTimetables),
|
|
1511
1509
|
config,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gtfs-to-html",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Build human readable transit timetables as HTML, PDF or CSV from GTFS",
|
|
6
6
|
"keywords": [
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"archiver": "^7.0.1",
|
|
41
41
|
"cli-table": "^0.3.11",
|
|
42
42
|
"copy-dir": "^1.3.0",
|
|
43
|
-
"csv-stringify": "^6.5.
|
|
43
|
+
"csv-stringify": "^6.5.1",
|
|
44
44
|
"express": "^4.19.2",
|
|
45
|
-
"gtfs": "^4.13.
|
|
45
|
+
"gtfs": "^4.13.2",
|
|
46
46
|
"insane": "^2.6.2",
|
|
47
47
|
"js-beautify": "^1.15.1",
|
|
48
48
|
"lodash-es": "^4.17.21",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"morgan": "^1.10.0",
|
|
52
52
|
"pretty-error": "^4.0.0",
|
|
53
53
|
"pug": "^3.0.3",
|
|
54
|
-
"puppeteer": "^22.
|
|
54
|
+
"puppeteer": "^22.14.0",
|
|
55
55
|
"sanitize-filename": "^1.6.3",
|
|
56
56
|
"sqlstring": "^2.3.3",
|
|
57
57
|
"timer-machine": "^1.1.0",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"yoctocolors": "^2.1.1"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"husky": "^9.1.
|
|
64
|
+
"husky": "^9.1.3",
|
|
65
65
|
"lint-staged": "^15.2.7",
|
|
66
66
|
"prettier": "^3.3.3"
|
|
67
67
|
},
|
|
@@ -36,7 +36,59 @@ a:hover {
|
|
|
36
36
|
|
|
37
37
|
/* Overview styles */
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
|
|
40
|
+
.timetable-overview {
|
|
41
|
+
height: 100vh;
|
|
42
|
+
align-items: stretch;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@media (min-width: 768px) {
|
|
46
|
+
.timetable-overview {
|
|
47
|
+
display: flex;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.timetable-overview h1 {
|
|
52
|
+
font-size: 1.5rem;
|
|
53
|
+
line-height: 2rem;
|
|
54
|
+
margin-left: 1rem;
|
|
55
|
+
margin-right: 1rem;
|
|
56
|
+
padding-top: 0.75rem;
|
|
57
|
+
padding-bottom: 0.75rem;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.timetable-overview .overview-list {
|
|
61
|
+
flex: none;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@media (min-width: 768px) {
|
|
65
|
+
.timetable-overview .overview-list {
|
|
66
|
+
max-width: 24rem;
|
|
67
|
+
overflow-y: scroll;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.timetable-overview a.timetable-page-link {
|
|
72
|
+
display: flex;
|
|
73
|
+
align-items: center;
|
|
74
|
+
gap: 0.5rem;
|
|
75
|
+
border-bottom: 1px solid rgb(226 232 240);
|
|
76
|
+
text-decoration: none;
|
|
77
|
+
padding: 0.5rem;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.timetable-overview a.timetable-page-link:hover {
|
|
81
|
+
background-color: rgb(241 245 249);
|
|
82
|
+
text-decoration: none;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.timetable-overview a.timetable-page-link .timetable-page-label {
|
|
86
|
+
font-size: 1.25rem;
|
|
87
|
+
line-height: 1;
|
|
88
|
+
color: rgb(30 41 59)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.timetable-overview .route-color-swatch {
|
|
40
92
|
min-width: 34px;
|
|
41
93
|
height: 34px;
|
|
42
94
|
border-radius: 17px;
|
|
@@ -45,9 +97,11 @@ a:hover {
|
|
|
45
97
|
font-size: 14px;
|
|
46
98
|
letter-spacing: -0.5px;
|
|
47
99
|
padding: 0 5px;
|
|
100
|
+
flex: none;
|
|
101
|
+
flex-shrink: 0;
|
|
48
102
|
}
|
|
49
103
|
|
|
50
|
-
.route-color-swatch-large {
|
|
104
|
+
.timetable-overview .route-color-swatch-large {
|
|
51
105
|
min-width: 46px;
|
|
52
106
|
height: 46px;
|
|
53
107
|
border-radius: 23px;
|
|
@@ -57,11 +111,13 @@ a:hover {
|
|
|
57
111
|
font-weight: bold;
|
|
58
112
|
letter-spacing: -1px;
|
|
59
113
|
padding: 0 6px;
|
|
114
|
+
flex: none;
|
|
115
|
+
flex-shrink: 0;
|
|
60
116
|
}
|
|
61
117
|
|
|
62
|
-
.btn-blue {
|
|
118
|
+
.timetable-overview .btn-blue {
|
|
63
119
|
color: rgb(255 255 255);
|
|
64
|
-
padding: 0.75rem
|
|
120
|
+
padding: 0.75rem 1.5rem;
|
|
65
121
|
background-color: rgb(37 99 235);
|
|
66
122
|
border-radius: 0.375rem;
|
|
67
123
|
justify-content: center;
|
|
@@ -71,172 +127,71 @@ a:hover {
|
|
|
71
127
|
text-decoration: none;
|
|
72
128
|
}
|
|
73
129
|
|
|
74
|
-
.btn-blue:hover {
|
|
130
|
+
.timetable-overview .btn-blue:hover {
|
|
75
131
|
background-color: rgb(29 78 216);
|
|
76
132
|
text-decoration: none;
|
|
77
133
|
}
|
|
78
134
|
|
|
79
|
-
.btn-sm {
|
|
135
|
+
.timetable-overview .btn-sm {
|
|
80
136
|
padding: 0.25rem 1rem;
|
|
81
137
|
border-radius: 0.25rem;
|
|
82
138
|
}
|
|
83
139
|
|
|
84
|
-
.
|
|
85
|
-
margin-right: 0.25rem;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.mx-4 {
|
|
89
|
-
margin-left: 1rem;
|
|
90
|
-
margin-right: 1rem;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
.mb-2 {
|
|
94
|
-
margin-bottom: 0.5rem;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.block {
|
|
98
|
-
display: block;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
.flex {
|
|
102
|
-
display: flex;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.inline-flex {
|
|
140
|
+
.timetable-overview .badge-gray {
|
|
106
141
|
display: inline-flex;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
.h-full {
|
|
110
|
-
height: 100%;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.h-screen {
|
|
114
|
-
height: 100vh;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
.w-full {
|
|
118
|
-
width: 100%;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
.flex-none {
|
|
122
|
-
flex: none;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.items-center {
|
|
126
142
|
align-items: center;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
.items-stretch {
|
|
130
|
-
align-items: stretch;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.justify-center {
|
|
134
143
|
justify-content: center;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
.gap-2 {
|
|
138
|
-
gap: 0.5rem;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.rounded-full {
|
|
142
|
-
border-radius: 9999px;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.border-b {
|
|
146
|
-
border-bottom-width: 1px;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.border-slate-200 {
|
|
150
|
-
border-color: rgb(226 232 240);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.bg-slate-200 {
|
|
154
|
-
background-color: rgb(226 232 240);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
.p-2 {
|
|
158
|
-
padding: 0.5rem;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.px-2 {
|
|
162
144
|
padding-left: 0.5rem;
|
|
163
145
|
padding-right: 0.5rem;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
.py-1 {
|
|
167
146
|
padding-top: 0.25rem;
|
|
168
147
|
padding-bottom: 0.25rem;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.py-3 {
|
|
172
|
-
padding-top: 0.75rem;
|
|
173
|
-
padding-bottom: 0.75rem;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
.text-2xl {
|
|
177
|
-
font-size: 1.5rem;
|
|
178
|
-
line-height: 2rem;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
.text-xl {
|
|
182
|
-
font-size: 1.25rem;
|
|
183
|
-
line-height: 1.75rem;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
.text-xs {
|
|
187
148
|
font-size: 0.75rem;
|
|
188
|
-
line-height: 1rem;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
.font-bold {
|
|
192
|
-
font-weight: 700;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
.leading-none {
|
|
196
149
|
line-height: 1;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
.text-slate-800 {
|
|
150
|
+
font-weight: 700;
|
|
200
151
|
color: rgb(30 41 59);
|
|
152
|
+
background-color: rgb(226 232 240);
|
|
153
|
+
border-radius: 9999px;
|
|
201
154
|
}
|
|
202
155
|
|
|
203
|
-
|
|
204
|
-
background-color: rgb(241 245 249);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
.hover\:no-underline:hover {
|
|
208
|
-
text-decoration-line: none;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
@media (min-width: 768px) {
|
|
212
|
-
.md\:flex {
|
|
213
|
-
display: flex;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
.md\:max-w-96 {
|
|
217
|
-
max-width: 24rem;
|
|
218
|
-
}
|
|
156
|
+
/* Map Styles */
|
|
219
157
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
158
|
+
.overview-map {
|
|
159
|
+
height: 100%;
|
|
160
|
+
width: 100%;
|
|
223
161
|
}
|
|
224
162
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
.map .mapboxgl-popup-content .popup-title {
|
|
163
|
+
.overview-map .mapboxgl-popup-content .popup-title {
|
|
228
164
|
margin: 0 20px 5px 0;
|
|
229
165
|
font-size: 16px;
|
|
230
166
|
font-weight: bold;
|
|
231
167
|
}
|
|
232
168
|
|
|
233
|
-
.map .mapboxgl-popup-content .
|
|
169
|
+
.overview-map .mapboxgl-popup-content .popup-label {
|
|
170
|
+
margin-right: 0.25rem;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.overview-map .mapboxgl-popup-content .route-list {
|
|
174
|
+
margin-bottom: 0.5rem;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.overview-map .mapboxgl-popup-content .map-route-item {
|
|
234
178
|
display: flex;
|
|
235
179
|
align-items: center;
|
|
180
|
+
font-size: 0.75rem;
|
|
236
181
|
line-height: 1;
|
|
182
|
+
margin-bottom: 0.5rem;
|
|
183
|
+
gap: 0.5rem;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.overview-map .mapboxgl-popup-content .map-route-item:hover {
|
|
187
|
+
text-decoration: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.overview-map .mapboxgl-popup-content a.map-route-item .underline-hover:hover {
|
|
191
|
+
text-decoration: underline;
|
|
237
192
|
}
|
|
238
193
|
|
|
239
|
-
.map .mapboxgl-popup-content .mapboxgl-popup-close-button {
|
|
194
|
+
.overview-map .mapboxgl-popup-content .mapboxgl-popup-close-button {
|
|
240
195
|
padding: 0 5px;
|
|
241
196
|
}
|
|
242
197
|
|