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