@opentripplanner/core-utils 13.0.0-alpha.1 → 13.0.0-alpha.2

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 (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/esm/graphql.d.js.map +1 -1
  4. package/esm/index.js.map +1 -1
  5. package/esm/itinerary.js +78 -115
  6. package/esm/itinerary.js.map +1 -1
  7. package/esm/map.js +3 -3
  8. package/esm/map.js.map +1 -1
  9. package/esm/profile.js +17 -18
  10. package/esm/profile.js.map +1 -1
  11. package/esm/query-gen.js +35 -45
  12. package/esm/query-gen.js.map +1 -1
  13. package/esm/query.js +135 -191
  14. package/esm/query.js.map +1 -1
  15. package/esm/route.js +74 -97
  16. package/esm/route.js.map +1 -1
  17. package/esm/storage.js +4 -5
  18. package/esm/storage.js.map +1 -1
  19. package/esm/suspense.js +1 -3
  20. package/esm/suspense.js.map +1 -1
  21. package/esm/time.js +13 -17
  22. package/esm/time.js.map +1 -1
  23. package/esm/ui.js +0 -5
  24. package/esm/ui.js.map +1 -1
  25. package/lib/graphql.d.js.map +1 -1
  26. package/lib/index.js +3 -19
  27. package/lib/index.js.map +1 -1
  28. package/lib/itinerary.js +152 -249
  29. package/lib/itinerary.js.map +1 -1
  30. package/lib/map.d.ts +1 -1
  31. package/lib/map.d.ts.map +1 -1
  32. package/lib/map.js +9 -20
  33. package/lib/map.js.map +1 -1
  34. package/lib/profile.js +18 -20
  35. package/lib/profile.js.map +1 -1
  36. package/lib/query-gen.d.ts +4 -4
  37. package/lib/query-gen.d.ts.map +1 -1
  38. package/lib/query-gen.js +35 -47
  39. package/lib/query-gen.js.map +1 -1
  40. package/lib/query-params.jsx +893 -0
  41. package/lib/query.js +68 -122
  42. package/lib/query.js.map +1 -1
  43. package/lib/route.js +73 -101
  44. package/lib/route.js.map +1 -1
  45. package/lib/storage.js +6 -11
  46. package/lib/storage.js.map +1 -1
  47. package/lib/suspense.d.ts +1 -1
  48. package/lib/suspense.d.ts.map +1 -1
  49. package/lib/suspense.js +3 -9
  50. package/lib/suspense.js.map +1 -1
  51. package/lib/time.js +21 -44
  52. package/lib/time.js.map +1 -1
  53. package/lib/ui.js +1 -8
  54. package/lib/ui.js.map +1 -1
  55. package/package.json +7 -8
  56. package/src/query-params.jsx +893 -0
  57. package/tsconfig.tsbuildinfo +1 -1
  58. package/esm/query-params.js +0 -786
  59. package/esm/query-params.js.map +0 -1
  60. package/lib/query-params.js +0 -756
  61. package/lib/query-params.js.map +0 -1
  62. /package/{src/query-params.js → esm/query-params.jsx} +0 -0
package/lib/itinerary.js CHANGED
@@ -1,229 +1,195 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
- exports.getTransitModes = getTransitModes;
9
- exports.isTransitLeg = isTransitLeg;
10
- exports.isTransit = isTransit;
11
- exports.isReservationRequired = isReservationRequired;
12
- exports.isCoordinationRequired = isCoordinationRequired;
7
+ exports.calculateEmissions = calculateEmissions;
8
+ exports.calculatePhysicalActivity = calculatePhysicalActivity;
9
+ exports.calculateTncFares = calculateTncFares;
13
10
  exports.containsGeometry = containsGeometry;
11
+ exports.convertGraphQLResponseToLegacy = void 0;
14
12
  exports.endsWithGeometry = endsWithGeometry;
15
- exports.startsWithGeometry = startsWithGeometry;
16
- exports.legContainsGeometry = legContainsGeometry;
13
+ exports.getCompaniesLabelFromNetworks = getCompaniesLabelFromNetworks;
14
+ exports.getCompanyForNetwork = getCompanyForNetwork;
15
+ exports.getCompanyFromLeg = getCompanyFromLeg;
16
+ exports.getDisplayedStopId = getDisplayedStopId;
17
+ exports.getElevationProfile = getElevationProfile;
18
+ exports.getItineraryBounds = getItineraryBounds;
19
+ exports.getItineraryCost = getItineraryCost;
20
+ exports.getLegBounds = getLegBounds;
21
+ exports.getLegCost = getLegCost;
22
+ exports.getLegRouteShortName = exports.getLegRouteName = exports.getLegRouteLongName = void 0;
23
+ exports.getMapColor = getMapColor;
24
+ exports.getTNCLocation = getTNCLocation;
25
+ exports.getTextWidth = getTextWidth;
26
+ exports.getTransitModes = getTransitModes;
27
+ exports.hasBike = hasBike;
28
+ exports.hasCar = hasCar;
29
+ exports.hasHail = hasHail;
30
+ exports.hasMicromobility = hasMicromobility;
31
+ exports.hasRental = hasRental;
32
+ exports.hasTransit = hasTransit;
33
+ exports.isAccessMode = isAccessMode;
17
34
  exports.isAdvanceBookingRequired = isAdvanceBookingRequired;
18
- exports.legDropoffRequiresAdvanceBooking = legDropoffRequiresAdvanceBooking;
19
- exports.isFlex = isFlex;
20
- exports.isRideshareLeg = isRideshareLeg;
21
- exports.isWalk = isWalk;
22
35
  exports.isBicycle = isBicycle;
23
36
  exports.isBicycleRent = isBicycleRent;
24
37
  exports.isCar = isCar;
38
+ exports.isCoordinationRequired = isCoordinationRequired;
39
+ exports.isFlex = isFlex;
25
40
  exports.isMicromobility = isMicromobility;
26
- exports.isAccessMode = isAccessMode;
27
- exports.hasTransit = hasTransit;
28
- exports.hasCar = hasCar;
29
- exports.hasBike = hasBike;
30
- exports.hasMicromobility = hasMicromobility;
31
- exports.hasHail = hasHail;
32
- exports.hasRental = hasRental;
33
- exports.getMapColor = getMapColor;
34
- exports.toSentenceCase = toSentenceCase;
35
- exports.getCompanyFromLeg = getCompanyFromLeg;
36
- exports.getItineraryBounds = getItineraryBounds;
37
- exports.getLegBounds = getLegBounds;
38
- exports.legLocationAtDistance = legLocationAtDistance;
41
+ exports.isReservationRequired = isReservationRequired;
42
+ exports.isRideshareLeg = isRideshareLeg;
43
+ exports.isTransit = isTransit;
44
+ exports.isTransitLeg = isTransitLeg;
45
+ exports.isWalk = isWalk;
46
+ exports.legContainsGeometry = legContainsGeometry;
47
+ exports.legDropoffRequiresAdvanceBooking = legDropoffRequiresAdvanceBooking;
39
48
  exports.legElevationAtDistance = legElevationAtDistance;
49
+ exports.legLocationAtDistance = legLocationAtDistance;
40
50
  exports.mapOldElevationComponentToNew = mapOldElevationComponentToNew;
41
- exports.getElevationProfile = getElevationProfile;
42
- exports.getTextWidth = getTextWidth;
43
- exports.getCompanyForNetwork = getCompanyForNetwork;
44
- exports.getCompaniesLabelFromNetworks = getCompaniesLabelFromNetworks;
45
- exports.getTNCLocation = getTNCLocation;
46
- exports.calculatePhysicalActivity = calculatePhysicalActivity;
47
- exports.calculateTncFares = calculateTncFares;
48
- exports.calculateEmissions = calculateEmissions;
49
- exports.getDisplayedStopId = getDisplayedStopId;
50
- exports.getLegCost = getLegCost;
51
- exports.getItineraryCost = getItineraryCost;
52
- exports.getLegRouteName = exports.getLegRouteLongName = exports.getLegRouteShortName = exports.convertGraphQLResponseToLegacy = exports.transitModes = void 0;
53
-
51
+ exports.startsWithGeometry = startsWithGeometry;
52
+ exports.toSentenceCase = toSentenceCase;
53
+ exports.transitModes = void 0;
54
54
  var _polyline = _interopRequireDefault(require("@mapbox/polyline"));
55
-
56
55
  var _along = _interopRequireDefault(require("@turf/along"));
57
-
58
56
  // All OTP transit modes
59
- const transitModes = ["TRAM", "TROLLEYBUS", "BUS", "SUBWAY", "FERRY", "RAIL", "GONDOLA"];
57
+ const transitModes = exports.transitModes = ["TRAM", "TROLLEYBUS", "BUS", "SUBWAY", "FERRY", "RAIL", "GONDOLA"];
58
+
60
59
  /**
61
60
  * @param {config} config OTP-RR configuration object
62
61
  * @return {Array} List of all transit modes defined in config; otherwise default mode list
63
62
  */
64
63
 
65
- exports.transitModes = transitModes;
66
-
67
64
  function getTransitModes(config) {
68
65
  if (!config || !config.modes || !config.modes.transitModes) return transitModes;
69
66
  return config.modes.transitModes.map(tm => typeof tm !== "string" ? tm.mode : tm);
70
67
  }
71
-
72
68
  function isTransitLeg(leg) {
73
69
  return leg.transitLeg;
74
70
  }
75
-
76
71
  function isTransit(mode) {
77
72
  return transitModes.includes(mode) || mode === "TRANSIT";
78
73
  }
74
+
79
75
  /**
80
76
  * Returns true if the leg pickup rules enabled which require
81
77
  * calling ahead for the service to run. "mustPhone" is the only
82
78
  * property which encodes this info.
83
79
  */
84
-
85
-
86
80
  function isReservationRequired(leg) {
87
- return (leg === null || leg === void 0 ? void 0 : leg.boardRule) === "mustPhone" || (leg === null || leg === void 0 ? void 0 : leg.alightRule) === "mustPhone";
81
+ return leg?.boardRule === "mustPhone" || leg?.alightRule === "mustPhone";
88
82
  }
89
83
  /**
90
84
  * Returns true if a user must ask the driver to let the user off
91
85
  * or if the user must flag the driver down for pickup.
92
86
  * "coordinateWithDriver" in board/alight rule encodes this info.
93
87
  */
94
-
95
-
96
88
  function isCoordinationRequired(leg) {
97
- return (leg === null || leg === void 0 ? void 0 : leg.boardRule) === "coordinateWithDriver" || (leg === null || leg === void 0 ? void 0 : leg.alightRule) === "coordinateWithDriver";
89
+ return leg?.boardRule === "coordinateWithDriver" || leg?.alightRule === "coordinateWithDriver";
98
90
  }
99
-
100
91
  function containsGeometry(place) {
101
- var _place$stop, _place$stop2;
102
-
103
- return (place === null || place === void 0 ? void 0 : (_place$stop = place.stop) === null || _place$stop === void 0 ? void 0 : _place$stop.geometries) !== null && (place === null || place === void 0 ? void 0 : (_place$stop2 = place.stop) === null || _place$stop2 === void 0 ? void 0 : _place$stop2.geometries) !== undefined;
92
+ return place?.stop?.geometries !== null && place?.stop?.geometries !== undefined;
104
93
  }
105
-
106
94
  function endsWithGeometry(leg) {
107
- return containsGeometry(leg === null || leg === void 0 ? void 0 : leg.to);
95
+ return containsGeometry(leg?.to);
108
96
  }
109
-
110
97
  function startsWithGeometry(leg) {
111
- return containsGeometry(leg === null || leg === void 0 ? void 0 : leg.from);
98
+ return containsGeometry(leg?.from);
112
99
  }
113
-
114
100
  function legContainsGeometry(leg) {
115
101
  return endsWithGeometry(leg) || startsWithGeometry(leg);
116
102
  }
117
-
118
103
  function isAdvanceBookingRequired(info) {
119
- var _info$latestBookingTi;
120
-
121
- return (info === null || info === void 0 ? void 0 : (_info$latestBookingTi = info.latestBookingTime) === null || _info$latestBookingTi === void 0 ? void 0 : _info$latestBookingTi.daysPrior) > 0;
104
+ return info?.latestBookingTime?.daysPrior > 0;
122
105
  }
123
-
124
106
  function legDropoffRequiresAdvanceBooking(leg) {
125
- return isAdvanceBookingRequired(leg === null || leg === void 0 ? void 0 : leg.dropOffBookingInfo);
107
+ return isAdvanceBookingRequired(leg?.dropOffBookingInfo);
126
108
  }
109
+
127
110
  /**
128
111
  * The two rules checked by the above two functions are the only values
129
112
  * returned by OTP when a leg is a flex leg.
130
113
  */
131
-
132
-
133
114
  function isFlex(leg) {
134
- return isReservationRequired(leg) || isCoordinationRequired(leg) || legDropoffRequiresAdvanceBooking(leg) || isAdvanceBookingRequired(leg === null || leg === void 0 ? void 0 : leg.pickupBookingInfo) || legContainsGeometry(leg);
135
- } // alpha-only comment
136
-
115
+ return isReservationRequired(leg) || isCoordinationRequired(leg) || legDropoffRequiresAdvanceBooking(leg) || isAdvanceBookingRequired(leg?.pickupBookingInfo) || legContainsGeometry(leg);
116
+ }
137
117
 
118
+ // alpha-only comment
138
119
  function isRideshareLeg(leg) {
139
- var _leg$rideHailingEstim, _leg$rideHailingEstim2;
140
-
141
- return !!((_leg$rideHailingEstim = leg.rideHailingEstimate) !== null && _leg$rideHailingEstim !== void 0 && (_leg$rideHailingEstim2 = _leg$rideHailingEstim.provider) !== null && _leg$rideHailingEstim2 !== void 0 && _leg$rideHailingEstim2.id);
120
+ return !!leg.rideHailingEstimate?.provider?.id;
142
121
  }
143
-
144
122
  function isWalk(mode) {
145
123
  if (!mode) return false;
146
124
  return mode === "WALK";
147
125
  }
148
-
149
126
  function isBicycle(mode) {
150
127
  if (!mode) return false;
151
128
  return mode === "BICYCLE";
152
129
  }
153
-
154
130
  function isBicycleRent(mode) {
155
131
  if (!mode) return false;
156
132
  return mode === "BICYCLE_RENT";
157
133
  }
158
-
159
134
  function isCar(mode) {
160
135
  if (!mode) return false;
161
136
  return mode.startsWith("CAR");
162
137
  }
163
-
164
138
  function isMicromobility(mode) {
165
139
  if (!mode) return false;
166
140
  return mode.startsWith("MICROMOBILITY") || mode.startsWith("SCOOTER");
167
141
  }
168
-
169
142
  function isAccessMode(mode) {
170
143
  return isWalk(mode) || isBicycle(mode) || isBicycleRent(mode) || isCar(mode) || isMicromobility(mode);
171
144
  }
145
+
172
146
  /**
173
147
  * @param {string} modesStr a comma-separated list of OTP modes
174
148
  * @return {boolean} whether any of the modes are transit modes
175
149
  */
176
-
177
-
178
150
  function hasTransit(modesStr) {
179
151
  return modesStr.split(",").some(mode => isTransit(mode));
180
152
  }
153
+
181
154
  /**
182
155
  * @param {string} modesStr a comma-separated list of OTP modes
183
156
  * @return {boolean} whether any of the modes are car-based modes
184
157
  */
185
-
186
-
187
158
  function hasCar(modesStr) {
188
159
  return modesStr.split(",").some(mode => isCar(mode));
189
160
  }
161
+
190
162
  /**
191
163
  * @param {string} modesStr a comma-separated list of OTP modes
192
164
  * @return {boolean} whether any of the modes are bicycle-based modes
193
165
  */
194
-
195
-
196
166
  function hasBike(modesStr) {
197
167
  return modesStr.split(",").some(mode => isBicycle(mode) || isBicycleRent(mode));
198
168
  }
169
+
199
170
  /**
200
171
  * @param {string} modesStr a comma-separated list of OTP modes
201
172
  * @return {boolean} whether any of the modes are micromobility-based modes
202
173
  */
203
-
204
-
205
174
  function hasMicromobility(modesStr) {
206
175
  return modesStr.split(",").some(mode => isMicromobility(mode));
207
176
  }
177
+
208
178
  /**
209
179
  * @param {string} modesStr a comma-separated list of OTP modes
210
180
  * @return {boolean} whether any of the modes is a hailing mode
211
181
  */
212
-
213
-
214
182
  function hasHail(modesStr) {
215
183
  return modesStr.split(",").some(mode => mode.indexOf("_HAIL") > -1);
216
184
  }
185
+
217
186
  /**
218
187
  * @param {string} modesStr a comma-separated list of OTP modes
219
188
  * @return {boolean} whether any of the modes is a rental mode
220
189
  */
221
-
222
-
223
190
  function hasRental(modesStr) {
224
191
  return modesStr.split(",").some(mode => mode.indexOf("_RENT") > -1);
225
192
  }
226
-
227
193
  function getMapColor(mode) {
228
194
  mode = mode || this.get("mode");
229
195
  if (mode === "WALK") return "#444";
@@ -238,20 +204,17 @@ function getMapColor(mode) {
238
204
  if (mode === "MICROMOBILITY" || mode === "SCOOTER") return "#f5a729";
239
205
  return "#aaa";
240
206
  }
241
-
242
207
  function toSentenceCase(str) {
243
208
  if (str == null) {
244
209
  return "";
245
210
  }
246
-
247
211
  str = String(str);
248
212
  return str.charAt(0).toUpperCase() + str.substr(1).toLowerCase();
249
213
  }
214
+
250
215
  /**
251
216
  * Derive the company string based on mode and network associated with leg.
252
217
  */
253
-
254
-
255
218
  function getCompanyFromLeg(leg) {
256
219
  if (!leg) return null;
257
220
  const {
@@ -262,93 +225,78 @@ function getCompanyFromLeg(leg) {
262
225
  rentedVehicle,
263
226
  rideHailingEstimate
264
227
  } = leg;
265
-
266
228
  if (mode === "CAR" && rentedCar) {
267
229
  return from.networks[0];
268
230
  }
269
-
270
231
  if (mode === "CAR" && rideHailingEstimate) {
271
232
  return rideHailingEstimate.provider.id;
272
233
  }
273
-
274
234
  if (mode === "BICYCLE" && rentedBike && from.networks) {
275
235
  return from.networks[0];
276
236
  }
277
-
278
237
  if (from.rentalVehicle) {
279
238
  return from.rentalVehicle.network;
280
239
  }
281
-
282
240
  if ((mode === "MICROMOBILITY" || mode === "SCOOTER") && rentedVehicle && from.networks) {
283
241
  return from.networks[0];
284
242
  }
285
-
286
243
  return null;
287
244
  }
288
-
289
245
  function getItineraryBounds(itinerary) {
290
246
  let coords = [];
291
247
  itinerary.legs.forEach(leg => {
292
248
  const legCoords = _polyline.default.toGeoJSON(leg.legGeometry.points).coordinates.map(c => [c[1], c[0]]);
293
-
294
249
  coords = [...coords, ...legCoords];
295
250
  });
296
251
  return coords;
297
252
  }
253
+
298
254
  /**
299
255
  * Return a coords object that encloses the given leg's geometry.
300
256
  */
301
-
302
-
303
257
  function getLegBounds(leg) {
304
- const coords = _polyline.default.toGeoJSON(leg.legGeometry.points).coordinates.map(c => [c[1], c[0]]); // in certain cases, there might be zero-length coordinates in the leg
258
+ const coords = _polyline.default.toGeoJSON(leg.legGeometry.points).coordinates.map(c => [c[1], c[0]]);
259
+
260
+ // in certain cases, there might be zero-length coordinates in the leg
305
261
  // geometry. In these cases, build us an array of coordinates using the from
306
262
  // and to data of the leg.
307
-
308
-
309
263
  if (coords.length === 0) {
310
264
  coords.push([leg.from.lat, leg.from.lon], [leg.to.lat, leg.to.lon]);
311
265
  }
312
-
313
266
  return coords;
314
267
  }
315
- /* Returns an interpolated lat-lon at a specified distance along a leg */
316
268
 
269
+ /* Returns an interpolated lat-lon at a specified distance along a leg */
317
270
 
318
271
  function legLocationAtDistance(leg, distance) {
319
272
  if (!leg.legGeometry) return null;
320
-
321
273
  try {
322
274
  const line = _polyline.default.toGeoJSON(leg.legGeometry.points);
323
-
324
275
  const pt = (0, _along.default)(line, distance, {
325
276
  units: "meters"
326
277
  });
327
-
328
278
  if (pt && pt.geometry && pt.geometry.coordinates) {
329
279
  return [pt.geometry.coordinates[1], pt.geometry.coordinates[0]];
330
280
  }
331
- } catch (e) {// FIXME handle error!
281
+ } catch (e) {
282
+ // FIXME handle error!
332
283
  }
333
-
334
284
  return null;
335
285
  }
336
- /* Returns an interpolated elevation at a specified distance along a leg */
337
286
 
287
+ /* Returns an interpolated elevation at a specified distance along a leg */
338
288
 
339
289
  function legElevationAtDistance(points, distance) {
340
290
  // Iterate through the combined elevation profile
341
- let traversed = 0; // If first point distance is not zero, insert starting point at zero with
291
+ let traversed = 0;
292
+ // If first point distance is not zero, insert starting point at zero with
342
293
  // null elevation. Encountering this value should trigger the warning below.
343
-
344
294
  if (points[0][0] > 0) {
345
295
  points.unshift([0, null]);
346
296
  }
347
-
348
297
  for (let i = 1; i < points.length; i++) {
349
298
  const start = points[i - 1];
350
299
  const elevDistanceSpan = points[i][0] - start[0];
351
-
352
300
  if (distance >= traversed && distance <= traversed + elevDistanceSpan) {
353
301
  // Distance falls within this point and the previous one;
354
302
  // compute & return interpolated elevation value
@@ -356,28 +304,24 @@ function legElevationAtDistance(points, distance) {
356
304
  console.warn("Elevation value does not exist for distance.", distance, traversed);
357
305
  return null;
358
306
  }
359
-
360
307
  const pct = (distance - traversed) / elevDistanceSpan;
361
308
  const elevSpan = points[i][1] - start[1];
362
309
  return start[1] + elevSpan * pct;
363
310
  }
364
-
365
311
  traversed += elevDistanceSpan;
366
312
  }
367
-
368
313
  console.warn("Elevation value does not exist for distance.", distance, traversed);
369
314
  return null;
370
315
  }
371
-
372
316
  function mapOldElevationComponentToNew(oldElev) {
373
317
  return {
374
318
  distance: oldElev.first,
375
319
  elevation: oldElev.second
376
320
  };
377
- } // Iterate through the steps, building the array of elevation points and
378
- // keeping track of the minimum and maximum elevations reached
379
-
321
+ }
380
322
 
323
+ // Iterate through the steps, building the array of elevation points and
324
+ // keeping track of the minimum and maximum elevations reached
381
325
  function getElevationProfile(steps, unitConversion = 1) {
382
326
  let minElev = 100000;
383
327
  let maxElev = -100000;
@@ -387,39 +331,32 @@ function getElevationProfile(steps, unitConversion = 1) {
387
331
  let previous = null;
388
332
  const points = [];
389
333
  steps.forEach(step => {
390
- var _step$elevation;
391
-
392
334
  // Support for old REST response data (in step.elevation)
393
- const stepElevationProfile = step.elevationProfile || Array.isArray(step.elevation) && ((_step$elevation = step.elevation) === null || _step$elevation === void 0 ? void 0 : _step$elevation.map(mapOldElevationComponentToNew));
394
-
335
+ const stepElevationProfile = step.elevationProfile || Array.isArray(step.elevation) && step.elevation?.map(mapOldElevationComponentToNew);
395
336
  if (!stepElevationProfile || stepElevationProfile.length === 0) {
396
337
  traversed += step.distance;
397
338
  return;
398
339
  }
399
-
400
340
  for (let i = 0; i < stepElevationProfile.length; i++) {
401
341
  const elev = stepElevationProfile[i];
402
-
403
342
  if (previous) {
404
343
  const diff = (elev.elevation - previous.elevation) * unitConversion;
405
344
  if (diff > 0) gain += diff;else loss += diff;
406
345
  }
407
-
408
- if (i === 0 && elev.distance !== 0) {// console.warn(`No elevation data available for step ${stepIndex}-${i} at beginning of segment`, elev)
346
+ if (i === 0 && elev.distance !== 0) {
347
+ // console.warn(`No elevation data available for step ${stepIndex}-${i} at beginning of segment`, elev)
409
348
  }
410
-
411
349
  const convertedElevation = elev.elevation * unitConversion;
412
350
  if (convertedElevation < minElev) minElev = convertedElevation;
413
351
  if (convertedElevation > maxElev) maxElev = convertedElevation;
414
- points.push([traversed + elev.distance, elev.elevation]); // Insert "filler" point if the last point in elevation profile does not
352
+ points.push([traversed + elev.distance, elev.elevation]);
353
+ // Insert "filler" point if the last point in elevation profile does not
415
354
  // reach the full distance of the step.
416
-
417
- if (i === stepElevationProfile.length - 1 && elev.distance !== step.distance) {// points.push([traversed + step.distance, elev.second])
355
+ if (i === stepElevationProfile.length - 1 && elev.distance !== step.distance) {
356
+ // points.push([traversed + step.distance, elev.second])
418
357
  }
419
-
420
358
  previous = elev;
421
359
  }
422
-
423
360
  traversed += step.distance;
424
361
  });
425
362
  return {
@@ -431,6 +368,7 @@ function getElevationProfile(steps, unitConversion = 1) {
431
368
  loss
432
369
  };
433
370
  }
371
+
434
372
  /**
435
373
  * Uses canvas.measureText to compute and return the width of the given text of given font in pixels.
436
374
  *
@@ -439,10 +377,9 @@ function getElevationProfile(steps, unitConversion = 1) {
439
377
  *
440
378
  * @see https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript/21015393#21015393
441
379
  */
442
-
443
-
444
380
  function getTextWidth(text, font = "22px Arial") {
445
381
  // Create custom type for function including reused canvas object
382
+
446
383
  // reuse canvas object for better performance
447
384
  const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
448
385
  const context = canvas.getContext("2d");
@@ -450,21 +387,19 @@ function getTextWidth(text, font = "22px Arial") {
450
387
  const metrics = context.measureText(text);
451
388
  return metrics.width;
452
389
  }
390
+
453
391
  /**
454
392
  * Get the configured company object for the given network string if the company
455
393
  * has been defined in the provided companies array config.
456
394
  */
457
-
458
-
459
395
  function getCompanyForNetwork(networkString, companies = []) {
460
396
  const company = companies.find(co => co.id === networkString);
461
-
462
397
  if (!company) {
463
398
  console.warn(`No company found in config.yml that matches rented vehicle network: ${networkString}`, companies);
464
399
  }
465
-
466
400
  return company;
467
401
  }
402
+
468
403
  /**
469
404
  * Get a string label to display from a list of vehicle rental networks.
470
405
  *
@@ -472,17 +407,13 @@ function getCompanyForNetwork(networkString, companies = []) {
472
407
  * @param {Array<object>} [companies=[]] An optional list of the companies config.
473
408
  * @return {string} A label for use in presentation on a website.
474
409
  */
475
-
476
-
477
410
  function getCompaniesLabelFromNetworks(networks, companies = []) {
478
411
  return (Array.isArray(networks) ? networks : [networks]).map(network => getCompanyForNetwork(network, companies)).filter(co => !!co).map(co => co.label).join("/");
479
412
  }
480
-
481
413
  function getTNCLocation(leg, type) {
482
414
  const location = leg[type];
483
415
  return `${location.lat.toFixed(5)},${location.lon.toFixed(5)}`;
484
416
  }
485
-
486
417
  function calculatePhysicalActivity(itinerary) {
487
418
  let walkDuration = 0;
488
419
  let bikeDuration = 0;
@@ -497,13 +428,12 @@ function calculatePhysicalActivity(itinerary) {
497
428
  walkDuration
498
429
  };
499
430
  }
431
+
500
432
  /**
501
433
  * For an itinerary, calculates the TNC fares and returns an object with
502
434
  * these values and currency info.
503
435
  * It is assumed that the same currency is used for all TNC legs.
504
436
  */
505
-
506
-
507
437
  function calculateTncFares(itinerary) {
508
438
  return itinerary.legs.filter(leg => leg.mode === "CAR" && leg.rideHailingEstimate).reduce(({
509
439
  maxTNCFare,
@@ -527,6 +457,7 @@ function calculateTncFares(itinerary) {
527
457
  minTNCFare: 0
528
458
  });
529
459
  }
460
+
530
461
  /**
531
462
  * Sources:
532
463
  * - https://www.itf-oecd.org/sites/default/files/docs/environmental-performance-new-mobility.pdf
@@ -534,8 +465,6 @@ function calculateTncFares(itinerary) {
534
465
  * - https://www.itf-oecd.org/sites/default/files/life-cycle-assessment-calculations-2020.xlsx
535
466
  * Other values extrapolated.
536
467
  */
537
-
538
-
539
468
  const CARBON_INTENSITY_DEFAULTS = {
540
469
  walk: 0.026,
541
470
  bicycle: 0.017,
@@ -554,55 +483,48 @@ const CARBON_INTENSITY_DEFAULTS = {
554
483
  airplane: 0.382,
555
484
  micromobility: 0.095
556
485
  };
486
+
557
487
  /**
558
488
  * @param {itinerary} itinerary OTP trip itinierary, only legs is required.
559
489
  * @param {carbonIntensity} carbonIntensity carbon intensity by mode in grams/meter
560
490
  * @param {units} units units to be used in return value
561
491
  * @return Amount of carbon in chosen unit
562
492
  */
563
-
564
- function calculateEmissions( // This type makes all the properties from Itinerary optional except legs.
493
+ function calculateEmissions(
494
+ // This type makes all the properties from Itinerary optional except legs.
565
495
  itinerary, carbonIntensity = {}, units) {
566
- var _itinerary$legs;
567
-
568
496
  // Apply defaults for any values that we don't have.
569
- const carbonIntensityWithDefaults = { ...CARBON_INTENSITY_DEFAULTS,
497
+ const carbonIntensityWithDefaults = {
498
+ ...CARBON_INTENSITY_DEFAULTS,
570
499
  ...carbonIntensity
571
- }; // Distance is in meters, totalCarbon is in grams
500
+ };
572
501
 
573
- const totalCarbon = (itinerary === null || itinerary === void 0 ? void 0 : (_itinerary$legs = itinerary.legs) === null || _itinerary$legs === void 0 ? void 0 : _itinerary$legs.reduce((total, leg) => {
502
+ // Distance is in meters, totalCarbon is in grams
503
+ const totalCarbon = itinerary?.legs?.reduce((total, leg) => {
574
504
  return (leg.distance * carbonIntensityWithDefaults[leg.mode.toLowerCase()] || 0) + total;
575
- }, 0)) || 0;
576
-
505
+ }, 0) || 0;
577
506
  switch (units) {
578
507
  case "ounce":
579
508
  return totalCarbon / 28.35;
580
-
581
509
  case "kilogram":
582
510
  return totalCarbon / 1000;
583
-
584
511
  case "pound":
585
512
  return totalCarbon / 454;
586
-
587
513
  case "gram":
588
514
  default:
589
515
  return totalCarbon;
590
516
  }
591
517
  }
518
+
592
519
  /**
593
520
  * Returns the user-facing stop id to display for a stop or place, using the following priority:
594
521
  * 1. stop code,
595
522
  * 2. stop id without the agency id portion, if stop id contains an agency portion,
596
523
  * 3. stop id, whether null or not (this is the fallback case).
597
524
  */
598
-
599
-
600
525
  function getDisplayedStopId(placeOrStop) {
601
- var _stopId;
602
-
603
526
  let stopId;
604
527
  let stopCode;
605
-
606
528
  if ("stopId" in placeOrStop) {
607
529
  ({
608
530
  stopCode,
@@ -614,9 +536,9 @@ function getDisplayedStopId(placeOrStop) {
614
536
  id: stopId
615
537
  } = placeOrStop);
616
538
  }
617
-
618
- return stopCode || ((_stopId = stopId) === null || _stopId === void 0 ? void 0 : _stopId.split(":")[1]) || stopId;
539
+ return stopCode || stopId?.split(":")[1] || stopId;
619
540
  }
541
+
620
542
  /**
621
543
  * Extracts useful data from the fare products on a leg, such as the leg cost and transfer info.
622
544
  * @param leg Leg with fare products (must have used getLegsWithFares)
@@ -624,8 +546,6 @@ function getDisplayedStopId(placeOrStop) {
624
546
  * @param container Fare container (cash, electronic)
625
547
  * @returns Object containing price as well as the transfer discount amount, if a transfer was used.
626
548
  */
627
-
628
-
629
549
  function getLegCost(leg, mediumId, riderCategoryId) {
630
550
  if (!leg.fareProducts) return {
631
551
  price: undefined
@@ -636,16 +556,18 @@ function getLegCost(leg, mediumId, riderCategoryId) {
636
556
  // riderCategory and medium can be specifically defined as null to handle
637
557
  // generic GTFS based fares from OTP when there is no fare model
638
558
  return (product.riderCategory === null ? null : product.riderCategory.id) === riderCategoryId && (product.medium === null ? null : product.medium.id) === mediumId;
639
- }); // Custom fare models return "rideCost", generic GTFS fares return "regular"
559
+ });
640
560
 
561
+ // Custom fare models return "rideCost", generic GTFS fares return "regular"
641
562
  const totalCostProduct = relevantFareProducts.find(fp => fp.product.name === "rideCost" || fp.product.name === "regular");
642
563
  const transferFareProduct = relevantFareProducts.find(fp => fp.product.name === "transfer");
643
564
  return {
644
- price: totalCostProduct === null || totalCostProduct === void 0 ? void 0 : totalCostProduct.product.price,
645
- transferAmount: transferFareProduct === null || transferFareProduct === void 0 ? void 0 : transferFareProduct.product.price,
646
- productUseId: totalCostProduct === null || totalCostProduct === void 0 ? void 0 : totalCostProduct.id
565
+ price: totalCostProduct?.product.price,
566
+ transferAmount: transferFareProduct?.product.price,
567
+ productUseId: totalCostProduct?.id
647
568
  };
648
569
  }
570
+
649
571
  /**
650
572
  * Returns the total itinerary cost for a given set of legs.
651
573
  * @param legs Itinerary legs with fare products (must have used getLegsWithFares)
@@ -653,16 +575,13 @@ function getLegCost(leg, mediumId, riderCategoryId) {
653
575
  * @param container Fare container (cash, electronic)
654
576
  * @returns Money object for the total itinerary cost.
655
577
  */
656
-
657
-
658
578
  function getItineraryCost(legs, mediumId, riderCategoryId) {
659
- const legCosts = legs // Only legs with fares (no walking legs)
660
- .filter(leg => {
661
- var _leg$fareProducts;
662
-
663
- return ((_leg$fareProducts = leg.fareProducts) === null || _leg$fareProducts === void 0 ? void 0 : _leg$fareProducts.length) > 0;
664
- }) // Get the leg cost object of each leg
665
- .map(leg => getLegCost(leg, mediumId, riderCategoryId)).filter(cost => cost.price !== undefined) // Filter out duplicate use IDs
579
+ const legCosts = legs
580
+ // Only legs with fares (no walking legs)
581
+ .filter(leg => leg.fareProducts?.length > 0)
582
+ // Get the leg cost object of each leg
583
+ .map(leg => getLegCost(leg, mediumId, riderCategoryId)).filter(cost => cost.price !== undefined)
584
+ // Filter out duplicate use IDs
666
585
  // One fare product can be used on multiple legs,
667
586
  // and we don't want to count it more than once.
668
587
  .reduce((prev, cur) => {
@@ -672,111 +591,95 @@ function getItineraryCost(legs, mediumId, riderCategoryId) {
672
591
  price: cur.price
673
592
  });
674
593
  }
675
-
676
594
  return prev;
677
595
  }, []).map(productUse => productUse.price);
678
- if (legCosts.length === 0) return undefined; // Calculate the total
679
-
596
+ if (legCosts.length === 0) return undefined;
597
+ // Calculate the total
680
598
  return legCosts.reduce((prev, cur) => {
681
599
  var _prev$currency;
682
-
683
600
  return {
684
- amount: prev.amount + (cur === null || cur === void 0 ? void 0 : cur.amount) || 0,
685
- currency: (_prev$currency = prev.currency) !== null && _prev$currency !== void 0 ? _prev$currency : cur === null || cur === void 0 ? void 0 : cur.currency
601
+ amount: prev.amount + cur?.amount || 0,
602
+ currency: (_prev$currency = prev.currency) !== null && _prev$currency !== void 0 ? _prev$currency : cur?.currency
686
603
  };
687
604
  }, {
688
605
  amount: 0,
689
606
  currency: null
690
607
  });
691
608
  }
692
-
693
609
  const pickupDropoffTypeToOtp1 = otp2Type => {
694
610
  switch (otp2Type) {
695
611
  case "COORDINATE_WITH_DRIVER":
696
612
  return "coordinateWithDriver";
697
-
698
613
  case "CALL_AGENCY":
699
614
  return "mustPhone";
700
-
701
615
  case "SCHEDULED":
702
616
  return "scheduled";
703
-
704
617
  case "NONE":
705
618
  return "none";
706
-
707
619
  default:
708
620
  return null;
709
621
  }
710
622
  };
623
+ const convertGraphQLResponseToLegacy = leg => ({
624
+ ...leg,
625
+ agencyBrandingUrl: leg.agency?.url,
626
+ agencyId: leg.agency?.id,
627
+ agencyName: leg.agency?.name,
628
+ agencyUrl: leg.agency?.url,
629
+ alightRule: pickupDropoffTypeToOtp1(leg.dropoffType),
630
+ boardRule: pickupDropoffTypeToOtp1(leg.pickupType),
631
+ dropOffBookingInfo: {
632
+ latestBookingTime: leg.dropOffBookingInfo
633
+ },
634
+ from: {
635
+ ...leg.from,
636
+ stopCode: leg.from.stop?.code,
637
+ stopId: leg.from.stop?.gtfsId
638
+ },
639
+ route: leg.route?.shortName,
640
+ routeColor: leg.route?.color,
641
+ routeId: leg.route?.gtfsId,
642
+ routeLongName: leg.route?.longName,
643
+ routeShortName: leg.route?.shortName,
644
+ routeTextColor: leg.route?.textColor,
645
+ to: {
646
+ ...leg.to,
647
+ stopCode: leg.to.stop?.code,
648
+ stopId: leg.to.stop?.gtfsId
649
+ },
650
+ tripHeadsign: leg.trip?.tripHeadsign,
651
+ tripId: leg.trip?.gtfsId
652
+ });
711
653
 
712
- const convertGraphQLResponseToLegacy = leg => {
713
- var _leg$agency, _leg$agency2, _leg$agency3, _leg$agency4, _leg$from$stop, _leg$from$stop2, _leg$route, _leg$route2, _leg$route3, _leg$route4, _leg$route5, _leg$route6, _leg$to$stop, _leg$to$stop2, _leg$trip, _leg$trip2;
714
-
715
- return { ...leg,
716
- agencyBrandingUrl: (_leg$agency = leg.agency) === null || _leg$agency === void 0 ? void 0 : _leg$agency.url,
717
- agencyId: (_leg$agency2 = leg.agency) === null || _leg$agency2 === void 0 ? void 0 : _leg$agency2.id,
718
- agencyName: (_leg$agency3 = leg.agency) === null || _leg$agency3 === void 0 ? void 0 : _leg$agency3.name,
719
- agencyUrl: (_leg$agency4 = leg.agency) === null || _leg$agency4 === void 0 ? void 0 : _leg$agency4.url,
720
- alightRule: pickupDropoffTypeToOtp1(leg.dropoffType),
721
- boardRule: pickupDropoffTypeToOtp1(leg.pickupType),
722
- dropOffBookingInfo: {
723
- latestBookingTime: leg.dropOffBookingInfo
724
- },
725
- from: { ...leg.from,
726
- stopCode: (_leg$from$stop = leg.from.stop) === null || _leg$from$stop === void 0 ? void 0 : _leg$from$stop.code,
727
- stopId: (_leg$from$stop2 = leg.from.stop) === null || _leg$from$stop2 === void 0 ? void 0 : _leg$from$stop2.gtfsId
728
- },
729
- route: (_leg$route = leg.route) === null || _leg$route === void 0 ? void 0 : _leg$route.shortName,
730
- routeColor: (_leg$route2 = leg.route) === null || _leg$route2 === void 0 ? void 0 : _leg$route2.color,
731
- routeId: (_leg$route3 = leg.route) === null || _leg$route3 === void 0 ? void 0 : _leg$route3.gtfsId,
732
- routeLongName: (_leg$route4 = leg.route) === null || _leg$route4 === void 0 ? void 0 : _leg$route4.longName,
733
- routeShortName: (_leg$route5 = leg.route) === null || _leg$route5 === void 0 ? void 0 : _leg$route5.shortName,
734
- routeTextColor: (_leg$route6 = leg.route) === null || _leg$route6 === void 0 ? void 0 : _leg$route6.textColor,
735
- to: { ...leg.to,
736
- stopCode: (_leg$to$stop = leg.to.stop) === null || _leg$to$stop === void 0 ? void 0 : _leg$to$stop.code,
737
- stopId: (_leg$to$stop2 = leg.to.stop) === null || _leg$to$stop2 === void 0 ? void 0 : _leg$to$stop2.gtfsId
738
- },
739
- tripHeadsign: (_leg$trip = leg.trip) === null || _leg$trip === void 0 ? void 0 : _leg$trip.tripHeadsign,
740
- tripId: (_leg$trip2 = leg.trip) === null || _leg$trip2 === void 0 ? void 0 : _leg$trip2.gtfsId
741
- };
742
- };
743
654
  /** Extracts the route number for a leg returned from OTP1 or OTP2. */
744
-
745
-
746
655
  exports.convertGraphQLResponseToLegacy = convertGraphQLResponseToLegacy;
747
-
748
656
  const getLegRouteShortName = leg => {
749
657
  const {
750
658
  route,
751
659
  routeShortName
752
- } = leg; // typeof route === "object" denotes newer OTP2 responses. routeShortName and route as string is OTP1.
753
-
754
- return typeof route === "object" ? route === null || route === void 0 ? void 0 : route.shortName : routeShortName || route;
660
+ } = leg;
661
+ // typeof route === "object" denotes newer OTP2 responses. routeShortName and route as string is OTP1.
662
+ return typeof route === "object" ? route?.shortName : routeShortName || route;
755
663
  };
756
- /** Extract the route long name for a leg returned from OTP1 or OTP2. */
757
-
758
664
 
665
+ /** Extract the route long name for a leg returned from OTP1 or OTP2. */
759
666
  exports.getLegRouteShortName = getLegRouteShortName;
760
-
761
667
  const getLegRouteLongName = leg => {
762
668
  const {
763
669
  route,
764
670
  routeLongName
765
- } = leg; // typeof route === "object" denotes newer OTP2 responses. routeLongName is OTP1.
766
-
767
- return typeof route === "object" ? route === null || route === void 0 ? void 0 : route.longName : routeLongName;
671
+ } = leg;
672
+ // typeof route === "object" denotes newer OTP2 responses. routeLongName is OTP1.
673
+ return typeof route === "object" ? route?.longName : routeLongName;
768
674
  };
675
+
769
676
  /**
770
677
  * Returns the route short name, or the route long name if no short name is provided.
771
678
  * This is happens with Seattle area streetcars and ferries.
772
679
  */
773
-
774
-
775
680
  exports.getLegRouteLongName = getLegRouteLongName;
776
-
777
681
  const getLegRouteName = leg => {
778
682
  return getLegRouteShortName(leg) || getLegRouteLongName(leg);
779
683
  };
780
-
781
684
  exports.getLegRouteName = getLegRouteName;
782
685
  //# sourceMappingURL=itinerary.js.map