venue-js 1.4.0-next.19 → 1.4.0-next.20

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/dist/index.js CHANGED
@@ -69,6 +69,7 @@ __export(index_exports, {
69
69
  getLocationByFeature: () => getLocationByFeature,
70
70
  getLocationByOccupant: () => getLocationByOccupant,
71
71
  getLocationIdByFeature: () => getLocationIdByFeature,
72
+ getNavigateClient: () => getNavigateClient,
72
73
  getOrdinalByLocationId: () => getOrdinalByLocationId,
73
74
  getRelatedLocationIdsByFeature: () => getRelatedLocationIdsByFeature,
74
75
  getRelatedLocationsByAmenity: () => getRelatedLocationsByAmenity,
@@ -238,6 +239,119 @@ var defaultFeatureQueryOptionsMap = {
238
239
  model3d: {}
239
240
  };
240
241
 
242
+ // src/data/utils/geometry-validator.ts
243
+ var isValidCoordinate = (point2) => {
244
+ return point2.length === 2 && point2.every((coord) => typeof coord === "number");
245
+ };
246
+ function isValidLinearRingCoordinates(ring) {
247
+ if (ring.length < 4) {
248
+ return false;
249
+ }
250
+ return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
251
+ }
252
+ var isValidPolygonCoordinates = (polygon2) => {
253
+ if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
254
+ return isValidLinearRingCoordinates(polygon2);
255
+ }
256
+ if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
257
+ if (!isValidLinearRingCoordinates(polygon2[0])) {
258
+ return false;
259
+ }
260
+ for (let i = 1; i < polygon2.length; i++) {
261
+ if (!isValidLinearRingCoordinates(polygon2[i])) {
262
+ return false;
263
+ }
264
+ }
265
+ return true;
266
+ }
267
+ return false;
268
+ };
269
+ var isValidMultiPolygonCoordinates = (multipolygon) => {
270
+ return multipolygon.every(isValidPolygonCoordinates);
271
+ };
272
+ var isValidLineStringCoordinates = (lineString2) => {
273
+ if (!Array.isArray(lineString2) || lineString2.length < 2) {
274
+ return false;
275
+ }
276
+ const firstPoint = lineString2[0];
277
+ const lastPoint = lineString2[lineString2.length - 1];
278
+ if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
279
+ return false;
280
+ }
281
+ return lineString2.every(isValidCoordinate);
282
+ };
283
+ var isValidMultiPolygon = (geometry) => {
284
+ const { type, coordinates } = geometry;
285
+ return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
286
+ };
287
+ var isValidPolygon = (geometry) => {
288
+ const { type, coordinates } = geometry;
289
+ return type === "Polygon" && isValidPolygonCoordinates(coordinates);
290
+ };
291
+ var isValidLineString = (geometry) => {
292
+ const { type, coordinates } = geometry;
293
+ return type === "LineString" && isValidLineStringCoordinates(coordinates);
294
+ };
295
+ var isValidPoint = (geometry) => {
296
+ const { type, coordinates } = geometry;
297
+ return type === "Point" && isValidCoordinate(coordinates);
298
+ };
299
+
300
+ // src/data/utils/match-filters.ts
301
+ function isInFilter(filter) {
302
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
303
+ }
304
+ var someIntersect = (a, b) => a.some((v) => b.includes(v));
305
+ function matchFilter(value, filter) {
306
+ if (Array.isArray(value)) {
307
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
308
+ return value.includes(filter);
309
+ } else {
310
+ if (isInFilter(filter)) return filter.$in.includes(value);
311
+ return value === filter;
312
+ }
313
+ }
314
+ function matchFilters(item, filters) {
315
+ return Object.entries(filters).every(([key, filter]) => {
316
+ return matchFilter(item.properties[key], filter);
317
+ });
318
+ }
319
+
320
+ // src/data/utils/occupant-helper.ts
321
+ var occupant_helper_exports = {};
322
+ __export(occupant_helper_exports, {
323
+ getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
324
+ getOccupantMainLocation: () => getOccupantMainLocation,
325
+ getOccupantMarkerLocations: () => getOccupantMarkerLocations
326
+ });
327
+
328
+ // src/data/utils/lodash/compact.ts
329
+ var compact = (arr) => arr.filter((item) => Boolean(item));
330
+
331
+ // src/data/utils/occupant-helper.ts
332
+ var getOccupantMainLocation = (occupant) => {
333
+ return occupant.properties.kiosk || occupant.properties.unit;
334
+ };
335
+ var getOccupantCorrelatedLocations = (occupant) => {
336
+ const allCorrelatedLocations = [
337
+ ...occupant.properties.units,
338
+ ...occupant.properties.kiosks
339
+ ];
340
+ return compact(allCorrelatedLocations);
341
+ };
342
+ var getOccupantMarkerLocations = (occupant, options) => {
343
+ const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
344
+ const mainLocation = getOccupantMainLocation(occupant);
345
+ const mainLocationLevel = mainLocation?.properties?.level_id;
346
+ const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
347
+ if (placementType === "ALL_LOCATIONS") {
348
+ return compact([mainLocation, ...allCorrelatedLocations]);
349
+ }
350
+ const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
351
+ const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
352
+ return compact([mainLocation, ...onePerLevelLocations]);
353
+ };
354
+
241
355
  // src/data/api/delivery-project.ts
242
356
  async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
243
357
  switch (featureType) {
@@ -359,119 +473,6 @@ var safeFetchFeature = async (featureType, params) => {
359
473
  }
360
474
  };
361
475
 
362
- // src/data/utils/geometry-validator.ts
363
- var isValidCoordinate = (point2) => {
364
- return point2.length === 2 && point2.every((coord) => typeof coord === "number");
365
- };
366
- function isValidLinearRingCoordinates(ring) {
367
- if (ring.length < 4) {
368
- return false;
369
- }
370
- return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
371
- }
372
- var isValidPolygonCoordinates = (polygon2) => {
373
- if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
374
- return isValidLinearRingCoordinates(polygon2);
375
- }
376
- if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
377
- if (!isValidLinearRingCoordinates(polygon2[0])) {
378
- return false;
379
- }
380
- for (let i = 1; i < polygon2.length; i++) {
381
- if (!isValidLinearRingCoordinates(polygon2[i])) {
382
- return false;
383
- }
384
- }
385
- return true;
386
- }
387
- return false;
388
- };
389
- var isValidMultiPolygonCoordinates = (multipolygon) => {
390
- return multipolygon.every(isValidPolygonCoordinates);
391
- };
392
- var isValidLineStringCoordinates = (lineString2) => {
393
- if (!Array.isArray(lineString2) || lineString2.length < 2) {
394
- return false;
395
- }
396
- const firstPoint = lineString2[0];
397
- const lastPoint = lineString2[lineString2.length - 1];
398
- if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
399
- return false;
400
- }
401
- return lineString2.every(isValidCoordinate);
402
- };
403
- var isValidMultiPolygon = (geometry) => {
404
- const { type, coordinates } = geometry;
405
- return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
406
- };
407
- var isValidPolygon = (geometry) => {
408
- const { type, coordinates } = geometry;
409
- return type === "Polygon" && isValidPolygonCoordinates(coordinates);
410
- };
411
- var isValidLineString = (geometry) => {
412
- const { type, coordinates } = geometry;
413
- return type === "LineString" && isValidLineStringCoordinates(coordinates);
414
- };
415
- var isValidPoint = (geometry) => {
416
- const { type, coordinates } = geometry;
417
- return type === "Point" && isValidCoordinate(coordinates);
418
- };
419
-
420
- // src/data/utils/match-filters.ts
421
- function isInFilter(filter) {
422
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
423
- }
424
- var someIntersect = (a, b) => a.some((v) => b.includes(v));
425
- function matchFilter(value, filter) {
426
- if (Array.isArray(value)) {
427
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
428
- return value.includes(filter);
429
- } else {
430
- if (isInFilter(filter)) return filter.$in.includes(value);
431
- return value === filter;
432
- }
433
- }
434
- function matchFilters(item, filters) {
435
- return Object.entries(filters).every(([key, filter]) => {
436
- return matchFilter(item.properties[key], filter);
437
- });
438
- }
439
-
440
- // src/data/utils/occupant-helper.ts
441
- var occupant_helper_exports = {};
442
- __export(occupant_helper_exports, {
443
- getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
444
- getOccupantMainLocation: () => getOccupantMainLocation,
445
- getOccupantMarkerLocations: () => getOccupantMarkerLocations
446
- });
447
-
448
- // src/data/utils/lodash/compact.ts
449
- var compact = (arr) => arr.filter((item) => Boolean(item));
450
-
451
- // src/data/utils/occupant-helper.ts
452
- var getOccupantMainLocation = (occupant) => {
453
- return occupant.properties.kiosk || occupant.properties.unit;
454
- };
455
- var getOccupantCorrelatedLocations = (occupant) => {
456
- const allCorrelatedLocations = [
457
- ...occupant.properties.units,
458
- ...occupant.properties.kiosks
459
- ];
460
- return compact(allCorrelatedLocations);
461
- };
462
- var getOccupantMarkerLocations = (occupant, options) => {
463
- const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
464
- const mainLocation = getOccupantMainLocation(occupant);
465
- const mainLocationLevel = mainLocation?.properties?.level_id;
466
- const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
467
- if (placementType === "ALL_LOCATIONS") {
468
- return compact([mainLocation, ...allCorrelatedLocations]);
469
- }
470
- const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
471
- const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
472
- return compact([mainLocation, ...onePerLevelLocations]);
473
- };
474
-
475
476
  // src/data/getDataClient.ts
476
477
  var import_query_core = require("@tanstack/query-core");
477
478
 
@@ -876,7 +877,7 @@ var getDistanceOptions = (options, category) => {
876
877
 
877
878
  // src/data/utils/trace.ts
878
879
  var trace = (namespace, text, ms, color) => {
879
- console.log(`[${namespace}] %c${text.padEnd(90)} ${ms !== void 0 ? `${ms.toFixed(1).padStart(6)} ms` : ``}`, color ? `color: ${color}` : void 0);
880
+ if (process.env.NODE_ENV !== "test") console.log(`[${namespace}] %c${text.padEnd(90)} ${ms !== void 0 ? `${ms.toFixed(1).padStart(6)} ms` : ``}`, color ? `color: ${color}` : void 0);
880
881
  };
881
882
 
882
883
  // src/data/navigate/graph/nodemap/createTraversalNodeMap.ts
@@ -1287,7 +1288,6 @@ var prepareGraph = (options) => {
1287
1288
  // src/data/navigate/steps/createStepUtils.ts
1288
1289
  var import_lodash12 = require("lodash");
1289
1290
  var import_intersectionBy = __toESM(require("lodash/intersectionBy"));
1290
- var import_center9 = require("@turf/center");
1291
1291
 
1292
1292
  // src/data/navigate/description/describe.ts
1293
1293
  var t = (template, locale, options) => {
@@ -1686,7 +1686,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1686
1686
  if (path.length <= 2) return path;
1687
1687
  const out = [path[0]];
1688
1688
  for (let i = 1; i < path.length - 1; i++) {
1689
- const a = out[out.length - 1];
1689
+ const a = out.at(-1);
1690
1690
  const b = path[i];
1691
1691
  const c = path[i + 1];
1692
1692
  const abx = b[0] - a[0], aby = b[1] - a[1];
@@ -1697,7 +1697,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1697
1697
  const angle = Math.acos(dot / (ab * bc)) * 180 / Math.PI;
1698
1698
  if (angle > minDeg) out.push(b);
1699
1699
  }
1700
- out.push(path[path.length - 1]);
1700
+ out.push(path.at(-1));
1701
1701
  return out;
1702
1702
  }
1703
1703
 
@@ -1705,7 +1705,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1705
1705
  function pruneShortSegments(path, minLen = 5) {
1706
1706
  const out = [path[0]];
1707
1707
  for (let i = 1; i < path.length; i++) {
1708
- const [x0, y0] = out[out.length - 1];
1708
+ const [x0, y0] = out.at(-1);
1709
1709
  const [x1, y1] = path[i];
1710
1710
  if (Math.hypot(x1 - x0, y1 - y0) >= minLen) {
1711
1711
  out.push(path[i]);
@@ -1907,7 +1907,7 @@ var shortestPath_default = shortestPath;
1907
1907
  // src/data/navigate/steps/path/index.ts
1908
1908
  var createStepPathUtils = (options) => {
1909
1909
  const resolution = options.resolution ?? 88e-5;
1910
- const { units, kiosks, fixtures } = options.data;
1910
+ const { units = [], kiosks = [], fixtures = [] } = options.data;
1911
1911
  const possibleObstacleFeatures = [...units, ...kiosks, ...fixtures];
1912
1912
  const filterObstaclesByOrdinal = (levelId) => {
1913
1913
  return possibleObstacleFeatures.filter(({ feature_type, properties, geometry }) => {
@@ -1973,181 +1973,6 @@ var createStepPathUtils = (options) => {
1973
1973
  };
1974
1974
  };
1975
1975
 
1976
- // src/data/navigate/landmark/createLandmarkUtils.ts
1977
- var import_center6 = require("@turf/center");
1978
- var import_distance5 = __toESM(require("@turf/distance"));
1979
- var NEARBY_DISTANCE = 30;
1980
- var createLandmarkUtils = (options) => {
1981
- const { data, findByIdSync } = options;
1982
- const { occupants } = data;
1983
- const occupantToLandmark = (occupant) => {
1984
- const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
1985
- const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
1986
- const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
1987
- const level = findByIdSync(location.properties.level_id);
1988
- return {
1989
- name: occupant.properties.name,
1990
- point: (0, import_center6.center)(location.geometry).geometry.coordinates,
1991
- level_id: location.properties.level_id,
1992
- is_priority: occupant.properties.is_landmark,
1993
- ordinal: level.properties.ordinal
1994
- };
1995
- };
1996
- const landmarks = [
1997
- ...occupants.map(occupantToLandmark)
1998
- ];
1999
- const findNearbyLandmarks = (point2, levelId) => {
2000
- if (point2 === null || levelId === null) return [];
2001
- return landmarks.map((landmark) => {
2002
- const landmarkAndDistance = {
2003
- landmark,
2004
- d: (0, import_distance5.default)(point2, landmark.point, { units: "meters" })
2005
- };
2006
- return landmarkAndDistance;
2007
- }).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
2008
- const aPriority = a.landmark.is_priority ? 0 : 1;
2009
- const bPriority = b.landmark.is_priority ? 0 : 1;
2010
- if (aPriority !== bPriority) return aPriority - bPriority;
2011
- return a.d - b.d;
2012
- }).map(({ landmark }) => landmark);
2013
- };
2014
- const findNearestLandmark = (point2, levelId) => {
2015
- const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
2016
- const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
2017
- return nearestLandmark;
2018
- };
2019
- return { findNearbyLandmarks, findNearestLandmark };
2020
- };
2021
-
2022
- // src/data/navigate/steps/utils/extractStartPoint.ts
2023
- var import_center7 = require("@turf/center");
2024
-
2025
- // src/data/navigate/steps/utils/featureIdGuard.ts
2026
- var isOccupant = (id) => !!id && id.startsWith("occupant-");
2027
- var isUnit = (id) => !!id && id.startsWith("unit-");
2028
- var isKiosk = (id) => !!id && id.startsWith("kiosk-");
2029
- var isOpening = (id) => !!id && id.startsWith("opening-");
2030
-
2031
- // src/data/navigate/type-guard.ts
2032
- function isCoordinateOrdinalString(id) {
2033
- return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
2034
- }
2035
-
2036
- // src/data/navigate/steps/utils/extractStartPoint.ts
2037
- var extractStartPoint = (path, options) => {
2038
- const { findByIdSync } = options;
2039
- const [a, b, c] = path;
2040
- if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2041
- const occ = findByIdSync(a);
2042
- const opening = findByIdSync(c);
2043
- const level = findByIdSync(opening.properties.level_id);
2044
- return [
2045
- {
2046
- id: occ.id,
2047
- type: "start",
2048
- name: occ.properties.name,
2049
- point: (0, import_center7.center)(opening).geometry.coordinates,
2050
- levelId: opening.properties.level_id,
2051
- ordinal: level.properties.ordinal,
2052
- source: { type: "opening", id: opening.id }
2053
- },
2054
- path.slice(3)
2055
- ];
2056
- }
2057
- if (isOccupant(a) && isKiosk(b)) {
2058
- const occ = findByIdSync(a);
2059
- const kiosk = findByIdSync(c);
2060
- const level = findByIdSync(kiosk.properties.level_id);
2061
- return [
2062
- {
2063
- id: occ.id,
2064
- type: "start",
2065
- name: occ.properties.name,
2066
- point: (0, import_center7.center)(kiosk).geometry.coordinates,
2067
- levelId: kiosk.properties.level_id,
2068
- ordinal: level.properties.ordinal,
2069
- source: { type: "kiosk", id: kiosk.id }
2070
- },
2071
- path.slice(2)
2072
- ];
2073
- }
2074
- if (isCoordinateOrdinalString(a) && isOpening(b)) {
2075
- const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2076
- const opening = findByIdSync(b);
2077
- return [
2078
- {
2079
- id: a,
2080
- type: "start",
2081
- name: { en: `Your location` },
2082
- point: [lng, lat],
2083
- levelId: opening.properties.level_id,
2084
- ordinal,
2085
- source: { type: "opening", id: opening.id }
2086
- },
2087
- path.slice(1)
2088
- ];
2089
- }
2090
- return [null, path];
2091
- };
2092
-
2093
- // src/data/navigate/steps/utils/extractEndPint.ts
2094
- var import_center8 = require("@turf/center");
2095
- var extractEndPoint = (path, options) => {
2096
- const { findByIdSync } = options;
2097
- const [c, b, a] = path.slice(-3);
2098
- if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2099
- const occ = findByIdSync(a);
2100
- const opening = findByIdSync(c);
2101
- const level = findByIdSync(opening.properties.level_id);
2102
- return [
2103
- {
2104
- id: occ.id,
2105
- type: "end",
2106
- name: occ.properties.name,
2107
- point: (0, import_center8.center)(opening).geometry.coordinates,
2108
- levelId: opening.properties.level_id,
2109
- ordinal: level.properties.ordinal,
2110
- source: { type: "opening", id: opening.id }
2111
- },
2112
- path.slice(0, -3)
2113
- ];
2114
- }
2115
- if (isOccupant(a) && isKiosk(b)) {
2116
- const occ = findByIdSync(a);
2117
- const kiosk = findByIdSync(c);
2118
- const level = findByIdSync(kiosk.properties.level_id);
2119
- return [
2120
- {
2121
- id: occ.id,
2122
- type: "end",
2123
- name: occ.properties.name,
2124
- point: (0, import_center8.center)(kiosk).geometry.coordinates,
2125
- levelId: kiosk.properties.level_id,
2126
- ordinal: level.properties.ordinal,
2127
- source: { type: "kiosk", id: kiosk.id }
2128
- },
2129
- path.slice(0, -2)
2130
- ];
2131
- }
2132
- if (isCoordinateOrdinalString(a)) {
2133
- const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2134
- const opening = findByIdSync(b);
2135
- return [
2136
- {
2137
- id: a,
2138
- type: "end",
2139
- name: { en: `Your location` },
2140
- point: [lng, lat],
2141
- levelId: opening.properties.level_id,
2142
- ordinal,
2143
- source: { type: "opening", id: opening.id }
2144
- },
2145
- path.slice(0, -2)
2146
- ];
2147
- }
2148
- return [null, path];
2149
- };
2150
-
2151
1976
  // src/data/navigate/steps/utils/combineWalkwaySteps.ts
2152
1977
  var import_uniq = __toESM(require("lodash/uniq"));
2153
1978
  var combineWalkwaySteps = (steps) => {
@@ -2160,7 +1985,6 @@ var combineWalkwaySteps = (steps) => {
2160
1985
  }
2161
1986
  const nextStep = steps[i + 1];
2162
1987
  if (thisStep.intermediaryCategory === "walkway" && nextStep.intermediaryCategory === "walkway" && thisStep.from.source.type === "opening" && nextStep.from.source.type === "opening") {
2163
- console.log({ i, len: steps.length, thisStep, nextStep });
2164
1988
  result.push({
2165
1989
  from: thisStep.from,
2166
1990
  to: nextStep.to,
@@ -2184,15 +2008,14 @@ var combineWalkwaySteps = (steps) => {
2184
2008
  // src/data/navigate/steps/createStepUtils.ts
2185
2009
  var createStepUtils = (options) => {
2186
2010
  const { data: { units, relationships }, findByIdSync } = options;
2187
- const landmarkUtils = createLandmarkUtils(options);
2188
2011
  const stepPathUtils = createStepPathUtils({ ...options, resolution: 88e-5 });
2189
2012
  const findUnitBetweenOpenings = (originId, destinationId) => {
2190
2013
  const origin = findByIdSync(originId);
2191
2014
  const destination = findByIdSync(destinationId);
2192
2015
  const matchedOne = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(origin.id));
2193
- const matchOneUnits = [matchedOne.properties.origin, matchedOne.properties.destination];
2016
+ const matchOneUnits = matchedOne ? [matchedOne.properties.origin, matchedOne.properties.destination] : [];
2194
2017
  const matchedTwo = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(destination.id));
2195
- const matchTwoUnits = [matchedTwo.properties.origin, matchedTwo.properties.destination];
2018
+ const matchTwoUnits = matchedTwo ? [matchedTwo.properties.origin, matchedTwo.properties.destination] : [];
2196
2019
  const unitIds = (0, import_intersectionBy.default)(matchOneUnits, matchTwoUnits, "id");
2197
2020
  return unitIds.map(({ id }) => findByIdSync(id));
2198
2021
  };
@@ -2219,7 +2042,7 @@ var createStepUtils = (options) => {
2219
2042
  const formatCategoryLabel = (category) => {
2220
2043
  return (0, import_lodash12.capitalize)(category);
2221
2044
  };
2222
- const getToward = (from, to, intermediary) => {
2045
+ const getNextStepIntermediary = (from, to, intermediary) => {
2223
2046
  if (to.type === "end") return to.name;
2224
2047
  const intermediaryIds = intermediary.map((int) => int.id);
2225
2048
  const relationship = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(to.source.id));
@@ -2230,32 +2053,11 @@ var createStepUtils = (options) => {
2230
2053
  const nextUnit = findByIdSync(nextUnitId);
2231
2054
  return { en: formatCategoryLabel(`${nextUnit.properties.category}`) };
2232
2055
  };
2233
- const toWaypoints = (path) => {
2234
- const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
2235
- const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
2236
- const waypoints = middlePoints.map((openingId) => {
2237
- const opening = findByIdSync(openingId);
2238
- const level = findByIdSync(opening.properties.level_id);
2239
- const coordinates = (0, import_center9.center)(opening).geometry.coordinates;
2240
- const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
2241
- return {
2242
- id: `${opening.properties.level_id}:${openingId}`,
2243
- type: "between",
2244
- point: coordinates,
2245
- name: null,
2246
- levelId: opening.properties.level_id,
2247
- ordinal: level.properties.ordinal,
2248
- hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
2249
- source: { type: "opening", id: opening.id }
2250
- };
2251
- });
2252
- return [startPoint, ...waypoints, endPoint];
2253
- };
2254
2056
  const createHorizontalStep = (from, to) => {
2255
2057
  const intermediary = findHorizontalIntermediary(from, to);
2256
2058
  const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
2257
2059
  const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
2258
- const toward = getToward(from, to, intermediary);
2060
+ const toward = getNextStepIntermediary(from, to, intermediary);
2259
2061
  const landmark = to.hint?.kind === "landmark" ? to.hint.name : null;
2260
2062
  const path = stepPathUtils.findStepPath(from.point, to.point, intermediary);
2261
2063
  const step = {
@@ -2312,8 +2114,6 @@ var createStepUtils = (options) => {
2312
2114
  return simplifySteps;
2313
2115
  };
2314
2116
  return {
2315
- // createSteps,
2316
- toWaypoints,
2317
2117
  toSteps
2318
2118
  };
2319
2119
  };
@@ -2334,6 +2134,11 @@ var calculateRoundedDistance = (distance5) => {
2334
2134
  return Math.round(distance5 - distance5 % 25);
2335
2135
  };
2336
2136
 
2137
+ // src/data/navigate/type-guard.ts
2138
+ function isCoordinateOrdinalString(id) {
2139
+ return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
2140
+ }
2141
+
2337
2142
  // src/data/navigate/utils/createFindByIdSync.ts
2338
2143
  var createFindByIdSync = (data) => {
2339
2144
  const { amenities = [], anchors = [], fixtures = [], levels = [], kiosks = [], relationships = [], occupants = [], openings = [], units } = data;
@@ -2356,6 +2161,207 @@ var createFindByIdSync = (data) => {
2356
2161
  return { findByIdSync };
2357
2162
  };
2358
2163
 
2164
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2165
+ var import_center9 = require("@turf/center");
2166
+
2167
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2168
+ var import_center6 = require("@turf/center");
2169
+
2170
+ // src/data/navigate/waypoint/featureIdGuard.ts
2171
+ var isOccupant = (id) => !!id && id.startsWith("occupant-");
2172
+ var isUnit = (id) => !!id && id.startsWith("unit-");
2173
+ var isKiosk = (id) => !!id && id.startsWith("kiosk-");
2174
+ var isOpening = (id) => !!id && id.startsWith("opening-");
2175
+
2176
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2177
+ var extractEndPoint = (path, options) => {
2178
+ const { findByIdSync } = options;
2179
+ const [c, b, a] = path.slice(-3);
2180
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2181
+ const occ = findByIdSync(a);
2182
+ const opening = findByIdSync(c);
2183
+ const level = findByIdSync(opening.properties.level_id);
2184
+ return [
2185
+ {
2186
+ id: occ.id,
2187
+ type: "end",
2188
+ name: occ.properties.name,
2189
+ point: (0, import_center6.center)(opening).geometry.coordinates,
2190
+ levelId: opening.properties.level_id,
2191
+ ordinal: level.properties.ordinal,
2192
+ source: { type: "opening", id: opening.id }
2193
+ },
2194
+ path.slice(0, -3)
2195
+ ];
2196
+ }
2197
+ if (isOccupant(a) && isKiosk(b)) {
2198
+ const occ = findByIdSync(a);
2199
+ const kiosk = findByIdSync(b);
2200
+ const level = findByIdSync(kiosk.properties.level_id);
2201
+ return [
2202
+ {
2203
+ id: occ.id,
2204
+ type: "end",
2205
+ name: occ.properties.name,
2206
+ point: (0, import_center6.center)(kiosk).geometry.coordinates,
2207
+ levelId: kiosk.properties.level_id,
2208
+ ordinal: level.properties.ordinal,
2209
+ source: { type: "kiosk", id: kiosk.id }
2210
+ },
2211
+ path.slice(0, -2)
2212
+ ];
2213
+ }
2214
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2215
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2216
+ const opening = findByIdSync(b);
2217
+ return [
2218
+ {
2219
+ id: a,
2220
+ type: "end",
2221
+ name: { en: a },
2222
+ point: [lng, lat],
2223
+ levelId: opening.properties.level_id,
2224
+ ordinal,
2225
+ source: { type: "coordinate", raw: a }
2226
+ },
2227
+ path.slice(0, -1)
2228
+ ];
2229
+ }
2230
+ return [null, path];
2231
+ };
2232
+
2233
+ // src/data/navigate/waypoint/extractStartWaypoint.ts
2234
+ var import_center7 = require("@turf/center");
2235
+ var extractStartPoint = (path, options) => {
2236
+ const { findByIdSync } = options;
2237
+ const [a, b, c] = path;
2238
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2239
+ const occ = findByIdSync(a);
2240
+ const opening = findByIdSync(c);
2241
+ const level = findByIdSync(opening.properties.level_id);
2242
+ return [
2243
+ {
2244
+ id: occ.id,
2245
+ type: "start",
2246
+ name: occ.properties.name,
2247
+ point: (0, import_center7.center)(opening).geometry.coordinates,
2248
+ levelId: opening.properties.level_id,
2249
+ ordinal: level.properties.ordinal,
2250
+ source: { type: "opening", id: opening.id }
2251
+ },
2252
+ path.slice(3)
2253
+ ];
2254
+ }
2255
+ if (isOccupant(a) && isKiosk(b)) {
2256
+ const occ = findByIdSync(a);
2257
+ const kiosk = findByIdSync(b);
2258
+ const level = findByIdSync(kiosk.properties.level_id);
2259
+ return [
2260
+ {
2261
+ id: occ.id,
2262
+ type: "start",
2263
+ name: occ.properties.name,
2264
+ point: (0, import_center7.center)(kiosk).geometry.coordinates,
2265
+ levelId: kiosk.properties.level_id,
2266
+ ordinal: level.properties.ordinal,
2267
+ source: { type: "kiosk", id: kiosk.id }
2268
+ },
2269
+ path.slice(2)
2270
+ ];
2271
+ }
2272
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2273
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2274
+ const opening = findByIdSync(b);
2275
+ return [
2276
+ {
2277
+ id: a,
2278
+ type: "start",
2279
+ name: { en: a },
2280
+ point: [lng, lat],
2281
+ levelId: opening.properties.level_id,
2282
+ ordinal,
2283
+ source: { type: "coordinate", raw: a }
2284
+ },
2285
+ path.slice(1)
2286
+ ];
2287
+ }
2288
+ return [null, path];
2289
+ };
2290
+
2291
+ // src/data/navigate/landmark/createLandmarkUtils.ts
2292
+ var import_center8 = require("@turf/center");
2293
+ var import_distance5 = __toESM(require("@turf/distance"));
2294
+ var NEARBY_DISTANCE = 30;
2295
+ var createLandmarkUtils = (options) => {
2296
+ const { data, findByIdSync } = options;
2297
+ const { occupants = [] } = data;
2298
+ const occupantToLandmark = (occupant) => {
2299
+ const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
2300
+ const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
2301
+ const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
2302
+ const level = findByIdSync(location.properties.level_id);
2303
+ return {
2304
+ name: occupant.properties.name,
2305
+ point: (0, import_center8.center)(location.geometry).geometry.coordinates,
2306
+ level_id: location.properties.level_id,
2307
+ is_priority: occupant.properties.is_landmark,
2308
+ ordinal: level.properties.ordinal
2309
+ };
2310
+ };
2311
+ const landmarks = [
2312
+ ...occupants.map(occupantToLandmark)
2313
+ ];
2314
+ const findNearbyLandmarks = (point2, levelId) => {
2315
+ if (point2 === null || levelId === null) return [];
2316
+ return landmarks.map((landmark) => {
2317
+ const landmarkAndDistance = {
2318
+ landmark,
2319
+ d: (0, import_distance5.default)(point2, landmark.point, { units: "meters" })
2320
+ };
2321
+ return landmarkAndDistance;
2322
+ }).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
2323
+ const aPriority = a.landmark.is_priority ? 0 : 1;
2324
+ const bPriority = b.landmark.is_priority ? 0 : 1;
2325
+ if (aPriority !== bPriority) return aPriority - bPriority;
2326
+ return a.d - b.d;
2327
+ }).map(({ landmark }) => landmark);
2328
+ };
2329
+ const findNearestLandmark = (point2, levelId) => {
2330
+ const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
2331
+ const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
2332
+ return nearestLandmark;
2333
+ };
2334
+ return { findNearbyLandmarks, findNearestLandmark };
2335
+ };
2336
+
2337
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2338
+ var createWaypointUtils = (options) => {
2339
+ const { findByIdSync } = options;
2340
+ const landmarkUtils = createLandmarkUtils(options);
2341
+ const toWaypoints = (path) => {
2342
+ const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
2343
+ const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
2344
+ const waypoints = middlePoints.map((openingId) => {
2345
+ const opening = findByIdSync(openingId);
2346
+ const level = findByIdSync(opening.properties.level_id);
2347
+ const coordinates = (0, import_center9.center)(opening).geometry.coordinates;
2348
+ const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
2349
+ return {
2350
+ id: `${opening.properties.level_id}:${openingId}`,
2351
+ type: "between",
2352
+ point: coordinates,
2353
+ name: null,
2354
+ levelId: opening.properties.level_id,
2355
+ ordinal: level.properties.ordinal,
2356
+ hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
2357
+ source: { type: "opening", id: opening.id }
2358
+ };
2359
+ });
2360
+ return [startPoint, ...waypoints, endPoint];
2361
+ };
2362
+ return { toWaypoints };
2363
+ };
2364
+
2359
2365
  // src/data/navigate/getNavigateClient.ts
2360
2366
  var getNavigateClient = (options) => {
2361
2367
  const { data } = options;
@@ -2377,6 +2383,7 @@ var getNavigateClient = (options) => {
2377
2383
  return unit;
2378
2384
  };
2379
2385
  const stepUtils = createStepUtils({ ...options, findByIdSync });
2386
+ const waypointUtils = createWaypointUtils({ ...options, findByIdSync });
2380
2387
  const findRoute = async (routeOriginParam, routeDestinationParam, options2) => {
2381
2388
  if (!routeOriginParam || !routeDestinationParam) return null;
2382
2389
  const graph = options2?.mode === "accessible" ? accessibleGraph : defaultGraph;
@@ -2394,8 +2401,7 @@ var getNavigateClient = (options) => {
2394
2401
  const path = graph.path(routeOriginParam, routeDestinationParam);
2395
2402
  const t12 = performance.now();
2396
2403
  trace("nav", " \u251C\u2500 path (dijkstra)", t12 - t02);
2397
- const waypoints = stepUtils.toWaypoints(path);
2398
- console.log({ waypoints });
2404
+ const waypoints = waypointUtils.toWaypoints(path);
2399
2405
  const t22 = performance.now();
2400
2406
  trace("nav", " \u251C\u2500 toWaypoints", t22 - t12);
2401
2407
  trace("nav", " \u251C\u2500 toSteps", 0);
@@ -2407,9 +2413,6 @@ var getNavigateClient = (options) => {
2407
2413
  const t4 = performance.now();
2408
2414
  trace("nav", " \u2514\u2500 postProcess", t4 - t32);
2409
2415
  return {
2410
- // origin: routeOrigin,
2411
- // destination: routeDestination,
2412
- description: null,
2413
2416
  distance: roundedDistance,
2414
2417
  duration,
2415
2418
  steps
@@ -6616,6 +6619,7 @@ var IndoorMap = class extends EventTarget {
6616
6619
  getLocationByFeature,
6617
6620
  getLocationByOccupant,
6618
6621
  getLocationIdByFeature,
6622
+ getNavigateClient,
6619
6623
  getOrdinalByLocationId,
6620
6624
  getRelatedLocationIdsByFeature,
6621
6625
  getRelatedLocationsByAmenity,