@opentripplanner/core-utils 4.11.6-alpha.1 → 5.0.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/esm/deprecated-with-types.js +47 -0
- package/esm/deprecated-with-types.js.map +1 -0
- package/esm/index.js +0 -4
- package/esm/index.js.map +1 -1
- package/esm/itinerary.js +1 -1
- package/esm/itinerary.js.map +1 -1
- package/esm/map.js +4 -9
- package/esm/map.js.map +1 -1
- package/esm/route.js +5 -3
- package/esm/route.js.map +1 -1
- package/esm/storage.js +1 -0
- package/esm/storage.js.map +1 -1
- package/esm/time.js +6 -36
- package/esm/time.js.map +1 -1
- package/esm/ui.js +1 -1
- package/esm/ui.js.map +1 -1
- package/lib/deprecated-with-types.d.ts +23 -0
- package/lib/deprecated-with-types.d.ts.map +1 -0
- package/lib/deprecated-with-types.js +61 -0
- package/lib/deprecated-with-types.js.map +1 -0
- package/lib/index.d.ts +19 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +0 -6
- package/lib/index.js.map +1 -1
- package/lib/itinerary.d.ts +113 -0
- package/lib/itinerary.d.ts.map +1 -0
- package/lib/itinerary.js +2 -1
- package/lib/itinerary.js.map +1 -1
- package/lib/map.d.ts +30 -0
- package/lib/map.d.ts.map +1 -0
- package/lib/map.js +3 -8
- package/lib/map.js.map +1 -1
- package/lib/route.d.ts +98 -0
- package/lib/route.d.ts.map +1 -0
- package/lib/route.js +5 -3
- package/lib/route.js.map +1 -1
- package/lib/storage.d.ts +19 -0
- package/lib/storage.d.ts.map +1 -0
- package/lib/storage.js +2 -0
- package/lib/storage.js.map +1 -1
- package/lib/time.d.ts +65 -0
- package/lib/time.d.ts.map +1 -0
- package/lib/time.js +22 -39
- package/lib/time.js.map +1 -1
- package/lib/ui.d.ts +13 -0
- package/lib/ui.d.ts.map +1 -0
- package/lib/ui.js +1 -1
- package/lib/ui.js.map +1 -1
- package/package.json +4 -1
- package/src/__tests__/__snapshots__/route.js.snap +30 -30
- package/src/deprecated-with-types.ts +62 -0
- package/src/{index.js → index.ts} +0 -4
- package/src/{itinerary.js → itinerary.ts} +70 -36
- package/src/{map.js → map.ts} +43 -31
- package/src/{route.js → route.ts} +52 -28
- package/src/{storage.js → storage.ts} +6 -5
- package/src/{time.js → time.ts} +28 -46
- package/src/{ui.js → ui.ts} +8 -8
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +4921 -0
- package/esm/messages.js +0 -25
- package/esm/messages.js.map +0 -1
- package/esm/types.js +0 -560
- package/esm/types.js.map +0 -1
- package/lib/messages.js +0 -29
- package/lib/messages.js.map +0 -1
- package/lib/types.js +0 -661
- package/lib/types.js.map +0 -1
- package/src/messages.js +0 -20
- package/src/types.js +0 -605
package/lib/time.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/time.js"],"names":["OTP_API_DATE_FORMAT","OTP_API_DATE_FORMAT_DATE_FNS","OTP_API_TIME_FORMAT","formatDurationLikeMoment","seconds","showSeconds","localize","enabled","code","hours","Math","floor","minutes","secondsLeftOver","specLookup","xHours","xMinutes","xSeconds","locale","formatDistance","spec","val","undefined","format","toHoursMinutesSeconds","getTimeFormat","config","dateTime","timeFormat","getDateFormat","dateFormat","getLongDateFormat","longDateFormat","formatDuration","formatDurationWithSeconds","region","offsetTime","ms","options","offset","formatTime","formatSecondsAfterMidnight","time","Date","getUserTimezone","fallbackTimezone","process","env","NODE_ENV","TZ","Intl","DateTimeFormat","resolvedOptions","timeZone","getCurrentTime","timezone","now","getCurrentDate"],"mappings":"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","sourcesContent":["import {\n startOfDay,\n add,\n format,\n formatDuration as dateFnsFormatDuration\n} from \"date-fns\";\nimport { utcToZonedTime } from \"date-fns-tz\";\n\n// special constants for making sure the following date format is always sent to\n// OTP regardless of whatever the user has configured as the display format\nexport const OTP_API_DATE_FORMAT = \"YYYY-MM-DD\";\n// Date-Fns uses a different string format than moment.js\n// see https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\nexport const OTP_API_DATE_FORMAT_DATE_FNS = \"yyyy-MM-dd\";\nexport const OTP_API_TIME_FORMAT = \"HH:mm\";\n\n/**\n * To ease the transition away from moment.js, this method uses date-fns to format durations\n * the way moment.js did.\n * @param {number} seconds The number of seconds to format\n * @param {boolean} showSeconds Whether to render seconds or not\n * @param {boolean} localize If true, will create output like moment.js using date-fns locale.\n * Otherwise, uses date-fns default\n * @returns Formatted duration\n */\nfunction formatDurationLikeMoment(\n seconds,\n showSeconds,\n localize = { enabled: true, code: \"en-US\" }\n) {\n // date-fns doesn't do this automatically\n if ((!showSeconds && seconds < 60) || seconds === 0) {\n return \"0 min\";\n }\n\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds - hours * 3600) / 60);\n const secondsLeftOver = showSeconds\n ? seconds - hours * 3600 - minutes * 60\n : 0;\n const specLookup = {\n xHours: \"hr\",\n xMinutes: \"min\",\n xSeconds: \"sec\"\n };\n const locale = localize\n ? {\n // Maintain backwards compatibility when called with localize=true\n code: localize?.code || \"en-US\",\n formatDistance: (spec, val) => {\n return `${val} ${specLookup[spec]}`;\n }\n }\n : undefined;\n\n return dateFnsFormatDuration(\n {\n hours,\n minutes,\n seconds: secondsLeftOver\n },\n {\n format: [\"hours\", \"minutes\", \"seconds\"],\n locale\n }\n );\n}\n\n/**\n * Breaks up a duration in seconds into hours, minutes, and seconds.\n * @param {number} seconds The number of seconds to break up\n * @returns an object with fields with the corresponding, hours, minutes, seconds.\n */\nexport function toHoursMinutesSeconds(seconds) {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds - hours * 3600) / 60);\n return {\n hours,\n minutes,\n seconds: seconds - hours * 3600 - minutes * 60\n };\n}\n\n/**\n * @param {[type]} config the OTP config object found in store\n * @return {string} the config-defined time formatter or HH:mm (24-hr time)\n */\nexport function getTimeFormat(config) {\n return config?.dateTime?.timeFormat || OTP_API_TIME_FORMAT;\n}\n\nexport function getDateFormat(config) {\n return config?.dateTime?.dateFormat || OTP_API_DATE_FORMAT;\n}\n\nexport function getLongDateFormat(config) {\n return config?.dateTime?.longDateFormat || \"D MMMM YYYY\";\n}\n\n/**\n * Formats an elapsed time duration for display in narrative.\n * TODO: internationalization\n * @param {number} seconds duration in seconds\n * @returns {string} formatted text representation\n */\nexport function formatDuration(seconds) {\n return formatDurationLikeMoment(seconds, false);\n}\n\n/**\n * Formats an elapsed time in seconds, minutes, hours duration for display in narrative\n * @param {number} seconds duration in seconds\n * @param {object} region an object that allows internationalization of the time\n * @returns {string} formatted text representation\n */\nexport function formatDurationWithSeconds(seconds, region) {\n return formatDurationLikeMoment(seconds, { enabled: true, code: region });\n}\n\n/**\n * Offsets a time according to the provided time options\n * and returns the result.\n */\nexport function offsetTime(ms, options) {\n return ms + (options?.offset || 0);\n}\n\n/**\n * Formats a time value for display in narrative\n * TODO: internationalization/timezone\n * @param {number} ms epoch time value in milliseconds\n * @returns {string} formatted text representation\n */\nexport function formatTime(ms, options) {\n return format(\n offsetTime(ms, options),\n options?.format || OTP_API_TIME_FORMAT\n );\n}\n\n/**\n * Formats a seconds after midnight value for display in narrative\n * @param {number} seconds time since midnight in seconds\n * @param {string} timeFormat A valid date-fns time format\n * @return {string} formatted text representation\n */\nexport function formatSecondsAfterMidnight(seconds, timeFormat) {\n const time = add(startOfDay(new Date()), { seconds });\n return format(time, timeFormat);\n}\n\n/**\n * Uses Intl.DateTimeFormat() api to get the user's time zone. In a test\n * environment, pulls timezone information from an env variable. Default to\n * GMT+0 if the Intl API is unavailable.\n */\nexport function getUserTimezone(fallbackTimezone = \"Etc/Greenwich\") {\n if (process.env.NODE_ENV === \"test\") return process.env.TZ;\n return Intl?.DateTimeFormat().resolvedOptions().timeZone || fallbackTimezone;\n}\n\n/**\n * Formats current time for use in OTP query\n * The conversion to the user's timezone is needed for testing purposes.\n */\nexport function getCurrentTime(timezone = getUserTimezone()) {\n return format(utcToZonedTime(Date.now(), timezone), OTP_API_TIME_FORMAT);\n}\n\n/**\n * Formats current date for use in OTP query\n * The conversion to the user's timezone is needed for testing purposes.\n */\nexport function getCurrentDate(timezone = getUserTimezone()) {\n return format(\n utcToZonedTime(Date.now(), timezone),\n OTP_API_DATE_FORMAT_DATE_FNS\n );\n}\n"],"file":"time.js"}
|
|
1
|
+
{"version":3,"sources":["../src/time.ts"],"names":["OTP_API_DATE_FORMAT","OTP_API_DATE_FORMAT_DATE_FNS","OTP_API_TIME_FORMAT","formatDurationLikeMoment","seconds","showSeconds","localize","enabled","code","hours","Math","floor","minutes","secondsLeftOver","specLookup","xHours","xMinutes","xSeconds","locale","formatDistance","spec","val","undefined","format","toHoursMinutesSeconds","getTimeFormat","config","dateTime","timeFormat","getDateFormat","dateFormat","getLongDateFormat","longDateFormat","offsetTime","ms","options","offset","formatSecondsAfterMidnight","time","Date","getUserTimezone","fallbackTimezone","process","env","NODE_ENV","TZ","Intl","DateTimeFormat","resolvedOptions","timeZone","getCurrentTime","timezone","now","getCurrentDate"],"mappings":"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","sourcesContent":["import { Config } from \"@opentripplanner/types\";\nimport {\n startOfDay,\n add,\n format,\n formatDuration as dateFnsFormatDuration\n} from \"date-fns\";\nimport { utcToZonedTime } from \"date-fns-tz\";\n\n/* eslint-disable import/no-cycle */\nimport {\n formatTime,\n formatDurationWithSeconds,\n formatDuration\n} from \"./deprecated-with-types\";\n\nexport { formatTime, formatDuration, formatDurationWithSeconds };\n\n// special constants for making sure the following date format is always sent to\n// OTP regardless of whatever the user has configured as the display format\nexport const OTP_API_DATE_FORMAT = \"YYYY-MM-DD\";\n// Date-Fns uses a different string format than moment.js\n// see https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\nexport const OTP_API_DATE_FORMAT_DATE_FNS = \"yyyy-MM-dd\";\nexport const OTP_API_TIME_FORMAT = \"HH:mm\";\n\n/**\n * To ease the transition away from moment.js, this method uses date-fns to format durations\n * the way moment.js did.\n * @param {number} seconds The number of seconds to format\n * @param {boolean} showSeconds Whether to render seconds or not\n * @param {boolean} localize If true, will create output like moment.js using date-fns locale.\n * Otherwise, uses date-fns default\n * @returns Formatted duration\n */\nexport function formatDurationLikeMoment(\n seconds: number,\n showSeconds: boolean,\n localize: { enabled: boolean; code: string } = {\n enabled: true,\n code: \"en-US\"\n }\n): string {\n // date-fns doesn't do this automatically\n if ((!showSeconds && seconds < 60) || seconds === 0) {\n return \"0 min\";\n }\n\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds - hours * 3600) / 60);\n const secondsLeftOver = showSeconds\n ? seconds - hours * 3600 - minutes * 60\n : 0;\n const specLookup = {\n xHours: \"hr\",\n xMinutes: \"min\",\n xSeconds: \"sec\"\n };\n const locale = localize\n ? {\n // Maintain backwards compatibility when called with localize=true\n code: localize?.code || \"en-US\",\n formatDistance: (spec, val) => {\n return `${val} ${specLookup[spec]}`;\n }\n }\n : undefined;\n\n return dateFnsFormatDuration(\n {\n hours,\n minutes,\n seconds: secondsLeftOver\n },\n {\n format: [\"hours\", \"minutes\", \"seconds\"],\n locale\n }\n );\n}\n\n/**\n * Breaks up a duration in seconds into hours, minutes, and seconds.\n * @param {number} seconds The number of seconds to break up\n * @returns an object with fields with the corresponding, hours, minutes, seconds.\n */\nexport function toHoursMinutesSeconds(seconds) {\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.floor((seconds - hours * 3600) / 60);\n return {\n hours,\n minutes,\n seconds: seconds - hours * 3600 - minutes * 60\n };\n}\n\n/**\n * @param {[type]} config the OTP config object found in store\n * @return {string} the config-defined time formatter or HH:mm (24-hr time)\n */\nexport function getTimeFormat(config: Config): string {\n return config?.dateTime?.timeFormat || OTP_API_TIME_FORMAT;\n}\n\nexport function getDateFormat(config: Config): string {\n return config?.dateTime?.dateFormat || OTP_API_DATE_FORMAT;\n}\n\nexport function getLongDateFormat(config: Config): string {\n return config?.dateTime?.longDateFormat || \"D MMMM YYYY\";\n}\n/**\n * Offsets a time according to the provided time options\n * and returns the result.\n */\nexport function offsetTime(ms, options) {\n return ms + (options?.offset || 0);\n}\n\n/**\n * Formats a seconds after midnight value for display in narrative\n * @param {number} seconds time since midnight in seconds\n * @param {string} timeFormat A valid date-fns time format\n * @return {string} formatted text representation\n */\nexport function formatSecondsAfterMidnight(\n seconds: number,\n timeFormat: string\n): string {\n const time = add(startOfDay(new Date()), { seconds });\n return format(time, timeFormat);\n}\n\n/**\n * Uses Intl.DateTimeFormat() api to get the user's time zone. In a test\n * environment, pulls timezone information from an env variable. Default to\n * GMT+0 if the Intl API is unavailable.\n */\nexport function getUserTimezone(fallbackTimezone = \"Etc/Greenwich\"): string {\n if (process.env.NODE_ENV === \"test\") return process.env.TZ;\n return Intl?.DateTimeFormat().resolvedOptions().timeZone || fallbackTimezone;\n}\n\n/**\n * Formats current time for use in OTP query\n * The conversion to the user's timezone is needed for testing purposes.\n */\nexport function getCurrentTime(timezone = getUserTimezone()): string {\n return format(utcToZonedTime(Date.now(), timezone), OTP_API_TIME_FORMAT);\n}\n\n/**\n * Formats current date for use in OTP query\n * The conversion to the user's timezone is needed for testing purposes.\n */\nexport function getCurrentDate(timezone = getUserTimezone()): string {\n return format(\n utcToZonedTime(Date.now(), timezone),\n OTP_API_DATE_FORMAT_DATE_FNS\n );\n}\n"],"file":"time.js"}
|
package/lib/ui.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function isMobile(): boolean;
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the user is using a [redacted] browser
|
|
4
|
+
*/
|
|
5
|
+
export declare function isIE(): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Enables scrolling for a specified selector, while disabling scrolling for all
|
|
8
|
+
* other targets. This is adapted from https://stackoverflow.com/a/41601290/915811
|
|
9
|
+
* and intended to fix issues with iOS elastic scrolling, e.g.,
|
|
10
|
+
* https://github.com/conveyal/trimet-mod-otp/issues/92.
|
|
11
|
+
*/
|
|
12
|
+
export declare function enableScrollForSelector(selector: string): void;
|
|
13
|
+
//# sourceMappingURL=ui.d.ts.map
|
package/lib/ui.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,IAAI,OAAO,CAKlC;AAED;;GAEG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAE9B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CA4C9D"}
|
package/lib/ui.js
CHANGED
|
@@ -21,7 +21,7 @@ function isMobile() {
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
function isIE() {
|
|
24
|
-
return _bowser.default.
|
|
24
|
+
return _bowser.default.parse(navigator.userAgent).browser === "Internet Explorer";
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Enables scrolling for a specified selector, while disabling scrolling for all
|
package/lib/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ui.
|
|
1
|
+
{"version":3,"sources":["../src/ui.ts"],"names":["isMobile","test","navigator","userAgent","isIE","bowser","parse","browser","enableScrollForSelector","selector","overlay","document","querySelector","clientY","isOverlayTotallyScrolled","scrollHeight","scrollTop","clientHeight","disableRubberBand","event","clientYDelta","targetTouches","preventDefault","addEventListener","length"],"mappings":";;;;;;;;;;;AAAA;;AAEO,SAASA,QAAT,GAA6B;AAClC;AACA,SAAO,iEAAiEC,IAAjE,CACLC,SAAS,CAACC,SADL,CAAP;AAGD;AAED;AACA;AACA;;;AACO,SAASC,IAAT,GAAyB;AAC9B,SAAOC,gBAAOC,KAAP,CAAaJ,SAAS,CAACC,SAAvB,EAAkCI,OAAlC,KAA8C,mBAArD;AACD;AAED;AACA;AACA;AACA;AACA;AACA;;;AACO,SAASC,uBAAT,CAAiCC,QAAjC,EAAyD;AAC9D,QAAMC,OAAO,GAAGC,QAAQ,CAACC,aAAT,CAAuBH,QAAvB,CAAhB;AACA,MAAII,OAAO,GAAG,IAAd,CAF8D,CAE1C;;AAEpB,WAASC,wBAAT,GAA6C;AAC3C;AACA,WAAOJ,OAAO,CAACK,YAAR,GAAuBL,OAAO,CAACM,SAA/B,IAA4CN,OAAO,CAACO,YAA3D;AACD;;AAED,WAASC,iBAAT,CAA2BC,KAA3B,EAA8C;AAC5C,UAAMC,YAAY,GAAGD,KAAK,CAACE,aAAN,CAAoB,CAApB,EAAuBR,OAAvB,GAAiCA,OAAtD;;AAEA,QAAIH,OAAO,CAACM,SAAR,KAAsB,CAAtB,IAA2BI,YAAY,GAAG,CAA9C,EAAiD;AAC/C;AACAD,MAAAA,KAAK,CAACG,cAAN;AACD;;AAED,QAAIR,wBAAwB,MAAMM,YAAY,GAAG,CAAjD,EAAoD;AAClD;AACAD,MAAAA,KAAK,CAACG,cAAN;AACD;AACF;;AAEDZ,EAAAA,OAAO,CAACa,gBAAR,CACE,YADF,EAEE,UAASJ,KAAT,EAA4B;AAC1B,QAAIA,KAAK,CAACE,aAAN,CAAoBG,MAApB,KAA+B,CAAnC,EAAsC;AACpC;AACAX,MAAAA,OAAO,GAAGM,KAAK,CAACE,aAAN,CAAoB,CAApB,EAAuBR,OAAjC;AACD;AACF,GAPH,EAQE,KARF;AAWAH,EAAAA,OAAO,CAACa,gBAAR,CACE,WADF,EAEE,UAASJ,KAAT,EAA4B;AAC1B,QAAIA,KAAK,CAACE,aAAN,CAAoBG,MAApB,KAA+B,CAAnC,EAAsC;AACpC;AACAN,MAAAA,iBAAiB,CAACC,KAAD,CAAjB;AACD;AACF,GAPH,EAQE,KARF;AAUD","sourcesContent":["import bowser from \"bowser\";\n\nexport function isMobile(): boolean {\n // TODO: consider using 3rd-party library?\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(\n navigator.userAgent\n );\n}\n\n/**\n * Returns true if the user is using a [redacted] browser\n */\nexport function isIE(): boolean {\n return bowser.parse(navigator.userAgent).browser === \"Internet Explorer\";\n}\n\n/**\n * Enables scrolling for a specified selector, while disabling scrolling for all\n * other targets. This is adapted from https://stackoverflow.com/a/41601290/915811\n * and intended to fix issues with iOS elastic scrolling, e.g.,\n * https://github.com/conveyal/trimet-mod-otp/issues/92.\n */\nexport function enableScrollForSelector(selector: string): void {\n const overlay = document.querySelector(selector);\n let clientY = null; // remember Y position on touch start\n\n function isOverlayTotallyScrolled(): boolean {\n // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight#Problems_and_solutions\n return overlay.scrollHeight - overlay.scrollTop <= overlay.clientHeight;\n }\n\n function disableRubberBand(event: TouchEvent) {\n const clientYDelta = event.targetTouches[0].clientY - clientY;\n\n if (overlay.scrollTop === 0 && clientYDelta > 0) {\n // element is at the top of its scroll\n event.preventDefault();\n }\n\n if (isOverlayTotallyScrolled() && clientYDelta < 0) {\n // element is at the top of its scroll\n event.preventDefault();\n }\n }\n\n overlay.addEventListener(\n \"touchstart\",\n function(event: TouchEvent) {\n if (event.targetTouches.length === 1) {\n // detect single touch\n clientY = event.targetTouches[0].clientY;\n }\n },\n false\n );\n\n overlay.addEventListener(\n \"touchmove\",\n function(event: TouchEvent) {\n if (event.targetTouches.length === 1) {\n // detect single touch\n disableRubberBand(event);\n }\n },\n false\n );\n}\n"],"file":"ui.js"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentripplanner/core-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Core functionality that is shared among numerous UI components",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=13"
|
|
@@ -26,5 +26,8 @@
|
|
|
26
26
|
"qs": "^6.9.1"
|
|
27
27
|
},
|
|
28
28
|
"gitHead": "0af1b7cda60bd4252b219dcf893e01c2acb2ed5d",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"tsc": "tsc"
|
|
31
|
+
},
|
|
29
32
|
"devDependencies": {}
|
|
30
33
|
}
|
|
@@ -35,18 +35,18 @@ Array [
|
|
|
35
35
|
|
|
36
36
|
exports[`util > route routeComparator should prioritize routes with valid sortOrder 1`] = `
|
|
37
37
|
Array [
|
|
38
|
-
Object {
|
|
39
|
-
"longName": "Around town",
|
|
40
|
-
"mode": "BUS",
|
|
41
|
-
"shortName": "20",
|
|
42
|
-
"sortOrder": 2,
|
|
43
|
-
},
|
|
44
38
|
Object {
|
|
45
39
|
"longName": "Around another town",
|
|
46
40
|
"shortName": "3",
|
|
47
41
|
"sortOrder": -999,
|
|
48
42
|
"type": 3,
|
|
49
43
|
},
|
|
44
|
+
Object {
|
|
45
|
+
"longName": "Around town",
|
|
46
|
+
"mode": "BUS",
|
|
47
|
+
"shortName": "20",
|
|
48
|
+
"sortOrder": 2,
|
|
49
|
+
},
|
|
50
50
|
]
|
|
51
51
|
`;
|
|
52
52
|
|
|
@@ -191,6 +191,30 @@ Array [
|
|
|
191
191
|
"shortName": "IC",
|
|
192
192
|
"sortOrder": 2,
|
|
193
193
|
},
|
|
194
|
+
Object {
|
|
195
|
+
"longName": "A-line",
|
|
196
|
+
"mode": "BUS",
|
|
197
|
+
"shortName": "A",
|
|
198
|
+
"sortOrder": -999,
|
|
199
|
+
},
|
|
200
|
+
Object {
|
|
201
|
+
"longName": "B-line",
|
|
202
|
+
"mode": "BUS",
|
|
203
|
+
"shortName": "B",
|
|
204
|
+
"sortOrder": -999,
|
|
205
|
+
},
|
|
206
|
+
Object {
|
|
207
|
+
"longName": "Loop route",
|
|
208
|
+
"mode": "BUS",
|
|
209
|
+
"shortName": "2",
|
|
210
|
+
"sortOrder": -999,
|
|
211
|
+
},
|
|
212
|
+
Object {
|
|
213
|
+
"longName": "Around another town",
|
|
214
|
+
"shortName": "3",
|
|
215
|
+
"sortOrder": -999,
|
|
216
|
+
"type": 3,
|
|
217
|
+
},
|
|
194
218
|
Object {
|
|
195
219
|
"longName": "Local route",
|
|
196
220
|
"mode": "BUS",
|
|
@@ -239,30 +263,6 @@ Array [
|
|
|
239
263
|
"shortName": "10",
|
|
240
264
|
"sortOrder": 10,
|
|
241
265
|
},
|
|
242
|
-
Object {
|
|
243
|
-
"longName": "A-line",
|
|
244
|
-
"mode": "BUS",
|
|
245
|
-
"shortName": "A",
|
|
246
|
-
"sortOrder": -999,
|
|
247
|
-
},
|
|
248
|
-
Object {
|
|
249
|
-
"longName": "B-line",
|
|
250
|
-
"mode": "BUS",
|
|
251
|
-
"shortName": "B",
|
|
252
|
-
"sortOrder": -999,
|
|
253
|
-
},
|
|
254
|
-
Object {
|
|
255
|
-
"longName": "Loop route",
|
|
256
|
-
"mode": "BUS",
|
|
257
|
-
"shortName": "2",
|
|
258
|
-
"sortOrder": -999,
|
|
259
|
-
},
|
|
260
|
-
Object {
|
|
261
|
-
"longName": "Around another town",
|
|
262
|
-
"shortName": "3",
|
|
263
|
-
"sortOrder": -999,
|
|
264
|
-
"type": 3,
|
|
265
|
-
},
|
|
266
266
|
Object {
|
|
267
267
|
"longName": "A meandering route",
|
|
268
268
|
"mode": "BUS",
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/* eslint-disable import/no-cycle */
|
|
2
|
+
import { TimeOptions } from "@opentripplanner/types";
|
|
3
|
+
import { format } from "date-fns";
|
|
4
|
+
|
|
5
|
+
import { logDeprecationWarning } from "./deprecated";
|
|
6
|
+
import {
|
|
7
|
+
formatDurationLikeMoment,
|
|
8
|
+
offsetTime,
|
|
9
|
+
OTP_API_TIME_FORMAT
|
|
10
|
+
} from "./time";
|
|
11
|
+
|
|
12
|
+
// time.ts
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Formats a time value for display in narrative
|
|
16
|
+
* TODO: internationalization/timezone
|
|
17
|
+
* @param {number} ms epoch time value in milliseconds
|
|
18
|
+
* @returns {string} formatted text representation
|
|
19
|
+
*/
|
|
20
|
+
export function formatTime(ms: number, options: TimeOptions): string {
|
|
21
|
+
logDeprecationWarning("formatTime", "formatjs");
|
|
22
|
+
|
|
23
|
+
return format(
|
|
24
|
+
offsetTime(ms, options),
|
|
25
|
+
options?.format || OTP_API_TIME_FORMAT
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Formats an elapsed time duration for display in narrative.
|
|
31
|
+
* TODO: internationalization
|
|
32
|
+
* @param {number} seconds duration in seconds
|
|
33
|
+
* @returns {string} formatted text representation
|
|
34
|
+
*/
|
|
35
|
+
// TS TODO: region as type?
|
|
36
|
+
export function formatDuration(seconds: number, region: string): string {
|
|
37
|
+
logDeprecationWarning("formatDuration", "formatjs");
|
|
38
|
+
|
|
39
|
+
return formatDurationLikeMoment(seconds, false, {
|
|
40
|
+
enabled: true,
|
|
41
|
+
code: region
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Formats an elapsed time in seconds, minutes, hours duration for display in narrative
|
|
47
|
+
* @param {number} seconds duration in seconds
|
|
48
|
+
* @param {object} region an object that allows internationalization of the time
|
|
49
|
+
* @returns {string} formatted text representation
|
|
50
|
+
*/
|
|
51
|
+
// TS TODO: region as type?
|
|
52
|
+
export function formatDurationWithSeconds(
|
|
53
|
+
seconds: number,
|
|
54
|
+
region: string
|
|
55
|
+
): string {
|
|
56
|
+
logDeprecationWarning("formatDurationWithSeconds", "formatjs");
|
|
57
|
+
|
|
58
|
+
return formatDurationLikeMoment(seconds, true, {
|
|
59
|
+
enabled: true,
|
|
60
|
+
code: region
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -1,26 +1,22 @@
|
|
|
1
1
|
import * as itinerary from "./itinerary";
|
|
2
2
|
import * as map from "./map";
|
|
3
|
-
import * as messages from "./messages";
|
|
4
3
|
import * as profile from "./profile";
|
|
5
4
|
import * as query from "./query";
|
|
6
5
|
import * as queryParams from "./query-params";
|
|
7
6
|
import * as route from "./route";
|
|
8
7
|
import * as storage from "./storage";
|
|
9
8
|
import * as time from "./time";
|
|
10
|
-
import * as types from "./types";
|
|
11
9
|
import * as ui from "./ui";
|
|
12
10
|
|
|
13
11
|
const core = {
|
|
14
12
|
itinerary,
|
|
15
13
|
map,
|
|
16
|
-
messages,
|
|
17
14
|
profile,
|
|
18
15
|
query,
|
|
19
16
|
queryParams,
|
|
20
17
|
route,
|
|
21
18
|
storage,
|
|
22
19
|
time,
|
|
23
|
-
types,
|
|
24
20
|
ui
|
|
25
21
|
};
|
|
26
22
|
|
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
import polyline from "@mapbox/polyline";
|
|
2
|
+
import {
|
|
3
|
+
Company,
|
|
4
|
+
Config,
|
|
5
|
+
ElevationProfile,
|
|
6
|
+
FlexBookingInfo,
|
|
7
|
+
Itinerary,
|
|
8
|
+
LatLngArray,
|
|
9
|
+
Leg,
|
|
10
|
+
Step
|
|
11
|
+
} from "@opentripplanner/types";
|
|
2
12
|
import turfAlong from "@turf/along";
|
|
3
13
|
|
|
4
14
|
import {
|
|
@@ -40,13 +50,16 @@ export const transitModes = [
|
|
|
40
50
|
* @return {Array} List of all transit modes defined in config; otherwise default mode list
|
|
41
51
|
*/
|
|
42
52
|
|
|
43
|
-
export function getTransitModes(config) {
|
|
53
|
+
export function getTransitModes(config: Config): string[] {
|
|
44
54
|
if (!config || !config.modes || !config.modes.transitModes)
|
|
45
55
|
return transitModes;
|
|
46
|
-
|
|
56
|
+
|
|
57
|
+
return config.modes.transitModes.map(tm =>
|
|
58
|
+
typeof tm !== "string" ? tm.mode : tm
|
|
59
|
+
);
|
|
47
60
|
}
|
|
48
61
|
|
|
49
|
-
export function isTransit(mode) {
|
|
62
|
+
export function isTransit(mode: string): boolean {
|
|
50
63
|
return transitModes.includes(mode) || mode === "TRANSIT";
|
|
51
64
|
}
|
|
52
65
|
|
|
@@ -55,7 +68,7 @@ export function isTransit(mode) {
|
|
|
55
68
|
* calling ahead for the service to run. "mustPhone" is the only
|
|
56
69
|
* property of boardRule which encodes this info.
|
|
57
70
|
*/
|
|
58
|
-
export function isReservationRequired(leg) {
|
|
71
|
+
export function isReservationRequired(leg: Leg): boolean {
|
|
59
72
|
return leg.boardRule === "mustPhone";
|
|
60
73
|
}
|
|
61
74
|
/**
|
|
@@ -63,53 +76,53 @@ export function isReservationRequired(leg) {
|
|
|
63
76
|
* asking the driver to let the user off. "coordinateWithDriver" is the only
|
|
64
77
|
* property of alightRule which encodes this info.
|
|
65
78
|
*/
|
|
66
|
-
export function isContinuousDropoff(leg) {
|
|
79
|
+
export function isContinuousDropoff(leg: Leg): boolean {
|
|
67
80
|
return leg.alightRule === "coordinateWithDriver";
|
|
68
81
|
}
|
|
69
82
|
/**
|
|
70
83
|
* The two rules checked by the above two functions are the only values
|
|
71
84
|
* returned by OTP when a leg is a flex leg.
|
|
72
85
|
*/
|
|
73
|
-
export function isFlex(leg) {
|
|
86
|
+
export function isFlex(leg: Leg): boolean {
|
|
74
87
|
return isReservationRequired(leg) || isContinuousDropoff(leg);
|
|
75
88
|
}
|
|
76
89
|
|
|
77
|
-
export function isAdvanceBookingRequired(info) {
|
|
90
|
+
export function isAdvanceBookingRequired(info: FlexBookingInfo): boolean {
|
|
78
91
|
return info?.latestBookingTime?.daysPrior > 0;
|
|
79
92
|
}
|
|
80
|
-
export function legDropoffRequiresAdvanceBooking(leg) {
|
|
93
|
+
export function legDropoffRequiresAdvanceBooking(leg: Leg): boolean {
|
|
81
94
|
return isAdvanceBookingRequired(leg.dropOffBookingInfo);
|
|
82
95
|
}
|
|
83
96
|
|
|
84
|
-
export function isWalk(mode) {
|
|
97
|
+
export function isWalk(mode: string): boolean {
|
|
85
98
|
if (!mode) return false;
|
|
86
99
|
|
|
87
100
|
return mode === "WALK";
|
|
88
101
|
}
|
|
89
102
|
|
|
90
|
-
export function isBicycle(mode) {
|
|
103
|
+
export function isBicycle(mode: string): boolean {
|
|
91
104
|
if (!mode) return false;
|
|
92
105
|
|
|
93
106
|
return mode === "BICYCLE";
|
|
94
107
|
}
|
|
95
108
|
|
|
96
|
-
export function isBicycleRent(mode) {
|
|
109
|
+
export function isBicycleRent(mode: string): boolean {
|
|
97
110
|
if (!mode) return false;
|
|
98
111
|
|
|
99
112
|
return mode === "BICYCLE_RENT";
|
|
100
113
|
}
|
|
101
114
|
|
|
102
|
-
export function isCar(mode) {
|
|
115
|
+
export function isCar(mode: string): boolean {
|
|
103
116
|
if (!mode) return false;
|
|
104
117
|
return mode.startsWith("CAR");
|
|
105
118
|
}
|
|
106
119
|
|
|
107
|
-
export function isMicromobility(mode) {
|
|
120
|
+
export function isMicromobility(mode: string): boolean {
|
|
108
121
|
if (!mode) return false;
|
|
109
122
|
return mode.startsWith("MICROMOBILITY") || mode.startsWith("SCOOTER");
|
|
110
123
|
}
|
|
111
124
|
|
|
112
|
-
export function isAccessMode(mode) {
|
|
125
|
+
export function isAccessMode(mode: string): boolean {
|
|
113
126
|
return (
|
|
114
127
|
isWalk(mode) ||
|
|
115
128
|
isBicycle(mode) ||
|
|
@@ -123,7 +136,7 @@ export function isAccessMode(mode) {
|
|
|
123
136
|
* @param {string} modesStr a comma-separated list of OTP modes
|
|
124
137
|
* @return {boolean} whether any of the modes are transit modes
|
|
125
138
|
*/
|
|
126
|
-
export function hasTransit(modesStr) {
|
|
139
|
+
export function hasTransit(modesStr: string): boolean {
|
|
127
140
|
return modesStr.split(",").some(mode => isTransit(mode));
|
|
128
141
|
}
|
|
129
142
|
|
|
@@ -131,7 +144,7 @@ export function hasTransit(modesStr) {
|
|
|
131
144
|
* @param {string} modesStr a comma-separated list of OTP modes
|
|
132
145
|
* @return {boolean} whether any of the modes are car-based modes
|
|
133
146
|
*/
|
|
134
|
-
export function hasCar(modesStr) {
|
|
147
|
+
export function hasCar(modesStr: string): boolean {
|
|
135
148
|
return modesStr.split(",").some(mode => isCar(mode));
|
|
136
149
|
}
|
|
137
150
|
|
|
@@ -139,7 +152,7 @@ export function hasCar(modesStr) {
|
|
|
139
152
|
* @param {string} modesStr a comma-separated list of OTP modes
|
|
140
153
|
* @return {boolean} whether any of the modes are bicycle-based modes
|
|
141
154
|
*/
|
|
142
|
-
export function hasBike(modesStr) {
|
|
155
|
+
export function hasBike(modesStr: string): boolean {
|
|
143
156
|
return modesStr
|
|
144
157
|
.split(",")
|
|
145
158
|
.some(mode => isBicycle(mode) || isBicycleRent(mode));
|
|
@@ -149,7 +162,7 @@ export function hasBike(modesStr) {
|
|
|
149
162
|
* @param {string} modesStr a comma-separated list of OTP modes
|
|
150
163
|
* @return {boolean} whether any of the modes are micromobility-based modes
|
|
151
164
|
*/
|
|
152
|
-
export function hasMicromobility(modesStr) {
|
|
165
|
+
export function hasMicromobility(modesStr: string): boolean {
|
|
153
166
|
return modesStr.split(",").some(mode => isMicromobility(mode));
|
|
154
167
|
}
|
|
155
168
|
|
|
@@ -157,7 +170,7 @@ export function hasMicromobility(modesStr) {
|
|
|
157
170
|
* @param {string} modesStr a comma-separated list of OTP modes
|
|
158
171
|
* @return {boolean} whether any of the modes is a hailing mode
|
|
159
172
|
*/
|
|
160
|
-
export function hasHail(modesStr) {
|
|
173
|
+
export function hasHail(modesStr: string): boolean {
|
|
161
174
|
return modesStr.split(",").some(mode => mode.indexOf("_HAIL") > -1);
|
|
162
175
|
}
|
|
163
176
|
|
|
@@ -165,11 +178,11 @@ export function hasHail(modesStr) {
|
|
|
165
178
|
* @param {string} modesStr a comma-separated list of OTP modes
|
|
166
179
|
* @return {boolean} whether any of the modes is a rental mode
|
|
167
180
|
*/
|
|
168
|
-
export function hasRental(modesStr) {
|
|
181
|
+
export function hasRental(modesStr: string): boolean {
|
|
169
182
|
return modesStr.split(",").some(mode => mode.indexOf("_RENT") > -1);
|
|
170
183
|
}
|
|
171
184
|
|
|
172
|
-
export function getMapColor(mode) {
|
|
185
|
+
export function getMapColor(mode: string): string {
|
|
173
186
|
mode = mode || this.get("mode");
|
|
174
187
|
if (mode === "WALK") return "#444";
|
|
175
188
|
if (mode === "BICYCLE") return "#0073e5";
|
|
@@ -183,7 +196,7 @@ export function getMapColor(mode) {
|
|
|
183
196
|
return "#aaa";
|
|
184
197
|
}
|
|
185
198
|
|
|
186
|
-
export function toSentenceCase(str) {
|
|
199
|
+
export function toSentenceCase(str: string): string {
|
|
187
200
|
if (str == null) {
|
|
188
201
|
return "";
|
|
189
202
|
}
|
|
@@ -194,7 +207,7 @@ export function toSentenceCase(str) {
|
|
|
194
207
|
/**
|
|
195
208
|
* Derive the company string based on mode and network associated with leg.
|
|
196
209
|
*/
|
|
197
|
-
export function getCompanyFromLeg(leg) {
|
|
210
|
+
export function getCompanyFromLeg(leg: Leg): string {
|
|
198
211
|
if (!leg) return null;
|
|
199
212
|
const { from, mode, rentedBike, rentedCar, rentedVehicle, tncData } = leg;
|
|
200
213
|
if (mode === "CAR" && rentedCar) {
|
|
@@ -216,12 +229,12 @@ export function getCompanyFromLeg(leg) {
|
|
|
216
229
|
return null;
|
|
217
230
|
}
|
|
218
231
|
|
|
219
|
-
export function getItineraryBounds(itinerary) {
|
|
232
|
+
export function getItineraryBounds(itinerary: Itinerary): LatLngArray[] {
|
|
220
233
|
let coords = [];
|
|
221
234
|
itinerary.legs.forEach(leg => {
|
|
222
235
|
const legCoords = polyline
|
|
223
236
|
.toGeoJSON(leg.legGeometry.points)
|
|
224
|
-
.coordinates.map(c => [c[1], c[0]]);
|
|
237
|
+
.coordinates.map((c: number[]) => [c[1], c[0]]);
|
|
225
238
|
coords = [...coords, ...legCoords];
|
|
226
239
|
});
|
|
227
240
|
return coords;
|
|
@@ -230,7 +243,7 @@ export function getItineraryBounds(itinerary) {
|
|
|
230
243
|
/**
|
|
231
244
|
* Return a coords object that encloses the given leg's geometry.
|
|
232
245
|
*/
|
|
233
|
-
export function getLegBounds(leg) {
|
|
246
|
+
export function getLegBounds(leg: Leg): number[] {
|
|
234
247
|
const coords = polyline
|
|
235
248
|
.toGeoJSON(leg.legGeometry.points)
|
|
236
249
|
.coordinates.map(c => [c[1], c[0]]);
|
|
@@ -246,7 +259,7 @@ export function getLegBounds(leg) {
|
|
|
246
259
|
|
|
247
260
|
/* Returns an interpolated lat-lon at a specified distance along a leg */
|
|
248
261
|
|
|
249
|
-
export function legLocationAtDistance(leg, distance) {
|
|
262
|
+
export function legLocationAtDistance(leg: Leg, distance: number): number[] {
|
|
250
263
|
if (!leg.legGeometry) return null;
|
|
251
264
|
|
|
252
265
|
try {
|
|
@@ -264,7 +277,10 @@ export function legLocationAtDistance(leg, distance) {
|
|
|
264
277
|
|
|
265
278
|
/* Returns an interpolated elevation at a specified distance along a leg */
|
|
266
279
|
|
|
267
|
-
export function legElevationAtDistance(
|
|
280
|
+
export function legElevationAtDistance(
|
|
281
|
+
points: number[][],
|
|
282
|
+
distance: number
|
|
283
|
+
): number {
|
|
268
284
|
// Iterate through the combined elevation profile
|
|
269
285
|
let traversed = 0;
|
|
270
286
|
// If first point distance is not zero, insert starting point at zero with
|
|
@@ -302,7 +318,10 @@ export function legElevationAtDistance(points, distance) {
|
|
|
302
318
|
|
|
303
319
|
// Iterate through the steps, building the array of elevation points and
|
|
304
320
|
// keeping track of the minimum and maximum elevations reached
|
|
305
|
-
export function getElevationProfile(
|
|
321
|
+
export function getElevationProfile(
|
|
322
|
+
steps: Step[],
|
|
323
|
+
unitConversion = 1
|
|
324
|
+
): ElevationProfile {
|
|
306
325
|
let minElev = 100000;
|
|
307
326
|
let maxElev = -100000;
|
|
308
327
|
let traversed = 0;
|
|
@@ -349,11 +368,14 @@ export function getElevationProfile(steps, unitConversion = 1) {
|
|
|
349
368
|
*
|
|
350
369
|
* @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
|
|
351
370
|
*/
|
|
352
|
-
export function getTextWidth(text, font = "22px Arial") {
|
|
371
|
+
export function getTextWidth(text: string, font = "22px Arial"): number {
|
|
372
|
+
// Create custom type for function including re-used canvas object
|
|
373
|
+
type GetTextWidth = typeof getTextWidth & { canvas: HTMLCanvasElement };
|
|
374
|
+
|
|
353
375
|
// re-use canvas object for better performance
|
|
354
376
|
const canvas =
|
|
355
|
-
getTextWidth.canvas ||
|
|
356
|
-
(getTextWidth.canvas = document.createElement("canvas"));
|
|
377
|
+
(getTextWidth as GetTextWidth).canvas ||
|
|
378
|
+
((getTextWidth as GetTextWidth).canvas = document.createElement("canvas"));
|
|
357
379
|
const context = canvas.getContext("2d");
|
|
358
380
|
context.font = font;
|
|
359
381
|
const metrics = context.measureText(text);
|
|
@@ -364,7 +386,10 @@ export function getTextWidth(text, font = "22px Arial") {
|
|
|
364
386
|
* Get the configured company object for the given network string if the company
|
|
365
387
|
* has been defined in the provided companies array config.
|
|
366
388
|
*/
|
|
367
|
-
export function getCompanyForNetwork(
|
|
389
|
+
export function getCompanyForNetwork(
|
|
390
|
+
networkString: string,
|
|
391
|
+
companies: Company[] = []
|
|
392
|
+
): Company {
|
|
368
393
|
const company = companies.find(co => co.id === networkString);
|
|
369
394
|
if (!company) {
|
|
370
395
|
console.warn(
|
|
@@ -382,7 +407,10 @@ export function getCompanyForNetwork(networkString, companies = []) {
|
|
|
382
407
|
* @param {Array<object>} [companies=[]] An optional list of the companies config.
|
|
383
408
|
* @return {string} A label for use in presentation on a website.
|
|
384
409
|
*/
|
|
385
|
-
export function getCompaniesLabelFromNetworks(
|
|
410
|
+
export function getCompaniesLabelFromNetworks(
|
|
411
|
+
networks: string[],
|
|
412
|
+
companies: Company[] = []
|
|
413
|
+
): string {
|
|
386
414
|
return networks
|
|
387
415
|
.map(network => getCompanyForNetwork(network, companies))
|
|
388
416
|
.filter(co => !!co)
|
|
@@ -390,12 +418,18 @@ export function getCompaniesLabelFromNetworks(networks, companies = []) {
|
|
|
390
418
|
.join("/");
|
|
391
419
|
}
|
|
392
420
|
|
|
393
|
-
export function getTNCLocation(leg, type) {
|
|
421
|
+
export function getTNCLocation(leg: Leg, type: string): string {
|
|
394
422
|
const location = leg[type];
|
|
395
423
|
return `${location.lat.toFixed(5)},${location.lon.toFixed(5)}`;
|
|
396
424
|
}
|
|
397
425
|
|
|
398
|
-
export function calculatePhysicalActivity(
|
|
426
|
+
export function calculatePhysicalActivity(
|
|
427
|
+
itinerary: Itinerary
|
|
428
|
+
): {
|
|
429
|
+
bikeDuration: number;
|
|
430
|
+
caloriesBurned: number;
|
|
431
|
+
walkDuration: number;
|
|
432
|
+
} {
|
|
399
433
|
let walkDuration = 0;
|
|
400
434
|
let bikeDuration = 0;
|
|
401
435
|
itinerary.legs.forEach(leg => {
|