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.
@@ -41,6 +41,7 @@ __export(data_exports, {
41
41
  fetchDeliveryApi: () => fetchDeliveryApi,
42
42
  fetchPreviewApi: () => fetchPreviewApi,
43
43
  getDataClient: () => getDataClient,
44
+ getNavigateClient: () => getNavigateClient,
44
45
  getSearchClient: () => getSearchClient,
45
46
  isValidCoordinate: () => isValidCoordinate,
46
47
  isValidLineString: () => isValidLineString,
@@ -200,6 +201,119 @@ var defaultFeatureQueryOptionsMap = {
200
201
  model3d: {}
201
202
  };
202
203
 
204
+ // src/data/utils/geometry-validator.ts
205
+ var isValidCoordinate = (point2) => {
206
+ return point2.length === 2 && point2.every((coord) => typeof coord === "number");
207
+ };
208
+ function isValidLinearRingCoordinates(ring) {
209
+ if (ring.length < 4) {
210
+ return false;
211
+ }
212
+ return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
213
+ }
214
+ var isValidPolygonCoordinates = (polygon2) => {
215
+ if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
216
+ return isValidLinearRingCoordinates(polygon2);
217
+ }
218
+ if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
219
+ if (!isValidLinearRingCoordinates(polygon2[0])) {
220
+ return false;
221
+ }
222
+ for (let i = 1; i < polygon2.length; i++) {
223
+ if (!isValidLinearRingCoordinates(polygon2[i])) {
224
+ return false;
225
+ }
226
+ }
227
+ return true;
228
+ }
229
+ return false;
230
+ };
231
+ var isValidMultiPolygonCoordinates = (multipolygon) => {
232
+ return multipolygon.every(isValidPolygonCoordinates);
233
+ };
234
+ var isValidLineStringCoordinates = (lineString2) => {
235
+ if (!Array.isArray(lineString2) || lineString2.length < 2) {
236
+ return false;
237
+ }
238
+ const firstPoint = lineString2[0];
239
+ const lastPoint = lineString2[lineString2.length - 1];
240
+ if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
241
+ return false;
242
+ }
243
+ return lineString2.every(isValidCoordinate);
244
+ };
245
+ var isValidMultiPolygon = (geometry) => {
246
+ const { type, coordinates } = geometry;
247
+ return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
248
+ };
249
+ var isValidPolygon = (geometry) => {
250
+ const { type, coordinates } = geometry;
251
+ return type === "Polygon" && isValidPolygonCoordinates(coordinates);
252
+ };
253
+ var isValidLineString = (geometry) => {
254
+ const { type, coordinates } = geometry;
255
+ return type === "LineString" && isValidLineStringCoordinates(coordinates);
256
+ };
257
+ var isValidPoint = (geometry) => {
258
+ const { type, coordinates } = geometry;
259
+ return type === "Point" && isValidCoordinate(coordinates);
260
+ };
261
+
262
+ // src/data/utils/match-filters.ts
263
+ function isInFilter(filter) {
264
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
265
+ }
266
+ var someIntersect = (a, b) => a.some((v) => b.includes(v));
267
+ function matchFilter(value, filter) {
268
+ if (Array.isArray(value)) {
269
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
270
+ return value.includes(filter);
271
+ } else {
272
+ if (isInFilter(filter)) return filter.$in.includes(value);
273
+ return value === filter;
274
+ }
275
+ }
276
+ function matchFilters(item, filters) {
277
+ return Object.entries(filters).every(([key, filter]) => {
278
+ return matchFilter(item.properties[key], filter);
279
+ });
280
+ }
281
+
282
+ // src/data/utils/occupant-helper.ts
283
+ var occupant_helper_exports = {};
284
+ __export(occupant_helper_exports, {
285
+ getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
286
+ getOccupantMainLocation: () => getOccupantMainLocation,
287
+ getOccupantMarkerLocations: () => getOccupantMarkerLocations
288
+ });
289
+
290
+ // src/data/utils/lodash/compact.ts
291
+ var compact = (arr) => arr.filter((item) => Boolean(item));
292
+
293
+ // src/data/utils/occupant-helper.ts
294
+ var getOccupantMainLocation = (occupant) => {
295
+ return occupant.properties.kiosk || occupant.properties.unit;
296
+ };
297
+ var getOccupantCorrelatedLocations = (occupant) => {
298
+ const allCorrelatedLocations = [
299
+ ...occupant.properties.units,
300
+ ...occupant.properties.kiosks
301
+ ];
302
+ return compact(allCorrelatedLocations);
303
+ };
304
+ var getOccupantMarkerLocations = (occupant, options) => {
305
+ const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
306
+ const mainLocation = getOccupantMainLocation(occupant);
307
+ const mainLocationLevel = mainLocation?.properties?.level_id;
308
+ const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
309
+ if (placementType === "ALL_LOCATIONS") {
310
+ return compact([mainLocation, ...allCorrelatedLocations]);
311
+ }
312
+ const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
313
+ const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
314
+ return compact([mainLocation, ...onePerLevelLocations]);
315
+ };
316
+
203
317
  // src/data/api/delivery-project.ts
204
318
  async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
205
319
  switch (featureType) {
@@ -321,119 +435,6 @@ var safeFetchFeature = async (featureType, params) => {
321
435
  }
322
436
  };
323
437
 
324
- // src/data/utils/geometry-validator.ts
325
- var isValidCoordinate = (point2) => {
326
- return point2.length === 2 && point2.every((coord) => typeof coord === "number");
327
- };
328
- function isValidLinearRingCoordinates(ring) {
329
- if (ring.length < 4) {
330
- return false;
331
- }
332
- return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
333
- }
334
- var isValidPolygonCoordinates = (polygon2) => {
335
- if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
336
- return isValidLinearRingCoordinates(polygon2);
337
- }
338
- if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
339
- if (!isValidLinearRingCoordinates(polygon2[0])) {
340
- return false;
341
- }
342
- for (let i = 1; i < polygon2.length; i++) {
343
- if (!isValidLinearRingCoordinates(polygon2[i])) {
344
- return false;
345
- }
346
- }
347
- return true;
348
- }
349
- return false;
350
- };
351
- var isValidMultiPolygonCoordinates = (multipolygon) => {
352
- return multipolygon.every(isValidPolygonCoordinates);
353
- };
354
- var isValidLineStringCoordinates = (lineString2) => {
355
- if (!Array.isArray(lineString2) || lineString2.length < 2) {
356
- return false;
357
- }
358
- const firstPoint = lineString2[0];
359
- const lastPoint = lineString2[lineString2.length - 1];
360
- if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
361
- return false;
362
- }
363
- return lineString2.every(isValidCoordinate);
364
- };
365
- var isValidMultiPolygon = (geometry) => {
366
- const { type, coordinates } = geometry;
367
- return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
368
- };
369
- var isValidPolygon = (geometry) => {
370
- const { type, coordinates } = geometry;
371
- return type === "Polygon" && isValidPolygonCoordinates(coordinates);
372
- };
373
- var isValidLineString = (geometry) => {
374
- const { type, coordinates } = geometry;
375
- return type === "LineString" && isValidLineStringCoordinates(coordinates);
376
- };
377
- var isValidPoint = (geometry) => {
378
- const { type, coordinates } = geometry;
379
- return type === "Point" && isValidCoordinate(coordinates);
380
- };
381
-
382
- // src/data/utils/match-filters.ts
383
- function isInFilter(filter) {
384
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
385
- }
386
- var someIntersect = (a, b) => a.some((v) => b.includes(v));
387
- function matchFilter(value, filter) {
388
- if (Array.isArray(value)) {
389
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
390
- return value.includes(filter);
391
- } else {
392
- if (isInFilter(filter)) return filter.$in.includes(value);
393
- return value === filter;
394
- }
395
- }
396
- function matchFilters(item, filters) {
397
- return Object.entries(filters).every(([key, filter]) => {
398
- return matchFilter(item.properties[key], filter);
399
- });
400
- }
401
-
402
- // src/data/utils/occupant-helper.ts
403
- var occupant_helper_exports = {};
404
- __export(occupant_helper_exports, {
405
- getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
406
- getOccupantMainLocation: () => getOccupantMainLocation,
407
- getOccupantMarkerLocations: () => getOccupantMarkerLocations
408
- });
409
-
410
- // src/data/utils/lodash/compact.ts
411
- var compact = (arr) => arr.filter((item) => Boolean(item));
412
-
413
- // src/data/utils/occupant-helper.ts
414
- var getOccupantMainLocation = (occupant) => {
415
- return occupant.properties.kiosk || occupant.properties.unit;
416
- };
417
- var getOccupantCorrelatedLocations = (occupant) => {
418
- const allCorrelatedLocations = [
419
- ...occupant.properties.units,
420
- ...occupant.properties.kiosks
421
- ];
422
- return compact(allCorrelatedLocations);
423
- };
424
- var getOccupantMarkerLocations = (occupant, options) => {
425
- const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
426
- const mainLocation = getOccupantMainLocation(occupant);
427
- const mainLocationLevel = mainLocation?.properties?.level_id;
428
- const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
429
- if (placementType === "ALL_LOCATIONS") {
430
- return compact([mainLocation, ...allCorrelatedLocations]);
431
- }
432
- const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
433
- const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
434
- return compact([mainLocation, ...onePerLevelLocations]);
435
- };
436
-
437
438
  // src/data/getDataClient.ts
438
439
  var import_query_core = require("@tanstack/query-core");
439
440
 
@@ -838,7 +839,7 @@ var getDistanceOptions = (options, category) => {
838
839
 
839
840
  // src/data/utils/trace.ts
840
841
  var trace = (namespace, text, ms, color) => {
841
- console.log(`[${namespace}] %c${text.padEnd(90)} ${ms !== void 0 ? `${ms.toFixed(1).padStart(6)} ms` : ``}`, color ? `color: ${color}` : void 0);
842
+ 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);
842
843
  };
843
844
 
844
845
  // src/data/navigate/graph/nodemap/createTraversalNodeMap.ts
@@ -1249,7 +1250,6 @@ var prepareGraph = (options) => {
1249
1250
  // src/data/navigate/steps/createStepUtils.ts
1250
1251
  var import_lodash12 = require("lodash");
1251
1252
  var import_intersectionBy = __toESM(require("lodash/intersectionBy"));
1252
- var import_center9 = require("@turf/center");
1253
1253
 
1254
1254
  // src/data/navigate/description/describe.ts
1255
1255
  var t = (template, locale, options) => {
@@ -1641,7 +1641,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1641
1641
  if (path.length <= 2) return path;
1642
1642
  const out = [path[0]];
1643
1643
  for (let i = 1; i < path.length - 1; i++) {
1644
- const a = out[out.length - 1];
1644
+ const a = out.at(-1);
1645
1645
  const b = path[i];
1646
1646
  const c = path[i + 1];
1647
1647
  const abx = b[0] - a[0], aby = b[1] - a[1];
@@ -1652,7 +1652,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1652
1652
  const angle = Math.acos(dot / (ab * bc)) * 180 / Math.PI;
1653
1653
  if (angle > minDeg) out.push(b);
1654
1654
  }
1655
- out.push(path[path.length - 1]);
1655
+ out.push(path.at(-1));
1656
1656
  return out;
1657
1657
  }
1658
1658
 
@@ -1660,7 +1660,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1660
1660
  function pruneShortSegments(path, minLen = 5) {
1661
1661
  const out = [path[0]];
1662
1662
  for (let i = 1; i < path.length; i++) {
1663
- const [x0, y0] = out[out.length - 1];
1663
+ const [x0, y0] = out.at(-1);
1664
1664
  const [x1, y1] = path[i];
1665
1665
  if (Math.hypot(x1 - x0, y1 - y0) >= minLen) {
1666
1666
  out.push(path[i]);
@@ -1862,7 +1862,7 @@ var shortestPath_default = shortestPath;
1862
1862
  // src/data/navigate/steps/path/index.ts
1863
1863
  var createStepPathUtils = (options) => {
1864
1864
  const resolution = options.resolution ?? 88e-5;
1865
- const { units, kiosks, fixtures } = options.data;
1865
+ const { units = [], kiosks = [], fixtures = [] } = options.data;
1866
1866
  const possibleObstacleFeatures = [...units, ...kiosks, ...fixtures];
1867
1867
  const filterObstaclesByOrdinal = (levelId) => {
1868
1868
  return possibleObstacleFeatures.filter(({ feature_type, properties, geometry }) => {
@@ -1928,181 +1928,6 @@ var createStepPathUtils = (options) => {
1928
1928
  };
1929
1929
  };
1930
1930
 
1931
- // src/data/navigate/landmark/createLandmarkUtils.ts
1932
- var import_center6 = require("@turf/center");
1933
- var import_distance5 = __toESM(require("@turf/distance"));
1934
- var NEARBY_DISTANCE = 30;
1935
- var createLandmarkUtils = (options) => {
1936
- const { data, findByIdSync } = options;
1937
- const { occupants } = data;
1938
- const occupantToLandmark = (occupant) => {
1939
- const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
1940
- const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
1941
- const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
1942
- const level = findByIdSync(location.properties.level_id);
1943
- return {
1944
- name: occupant.properties.name,
1945
- point: (0, import_center6.center)(location.geometry).geometry.coordinates,
1946
- level_id: location.properties.level_id,
1947
- is_priority: occupant.properties.is_landmark,
1948
- ordinal: level.properties.ordinal
1949
- };
1950
- };
1951
- const landmarks = [
1952
- ...occupants.map(occupantToLandmark)
1953
- ];
1954
- const findNearbyLandmarks = (point2, levelId) => {
1955
- if (point2 === null || levelId === null) return [];
1956
- return landmarks.map((landmark) => {
1957
- const landmarkAndDistance = {
1958
- landmark,
1959
- d: (0, import_distance5.default)(point2, landmark.point, { units: "meters" })
1960
- };
1961
- return landmarkAndDistance;
1962
- }).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
1963
- const aPriority = a.landmark.is_priority ? 0 : 1;
1964
- const bPriority = b.landmark.is_priority ? 0 : 1;
1965
- if (aPriority !== bPriority) return aPriority - bPriority;
1966
- return a.d - b.d;
1967
- }).map(({ landmark }) => landmark);
1968
- };
1969
- const findNearestLandmark = (point2, levelId) => {
1970
- const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
1971
- const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
1972
- return nearestLandmark;
1973
- };
1974
- return { findNearbyLandmarks, findNearestLandmark };
1975
- };
1976
-
1977
- // src/data/navigate/steps/utils/extractStartPoint.ts
1978
- var import_center7 = require("@turf/center");
1979
-
1980
- // src/data/navigate/steps/utils/featureIdGuard.ts
1981
- var isOccupant = (id) => !!id && id.startsWith("occupant-");
1982
- var isUnit = (id) => !!id && id.startsWith("unit-");
1983
- var isKiosk = (id) => !!id && id.startsWith("kiosk-");
1984
- var isOpening = (id) => !!id && id.startsWith("opening-");
1985
-
1986
- // src/data/navigate/type-guard.ts
1987
- function isCoordinateOrdinalString(id) {
1988
- return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
1989
- }
1990
-
1991
- // src/data/navigate/steps/utils/extractStartPoint.ts
1992
- var extractStartPoint = (path, options) => {
1993
- const { findByIdSync } = options;
1994
- const [a, b, c] = path;
1995
- if (isOccupant(a) && isUnit(b) && isOpening(c)) {
1996
- const occ = findByIdSync(a);
1997
- const opening = findByIdSync(c);
1998
- const level = findByIdSync(opening.properties.level_id);
1999
- return [
2000
- {
2001
- id: occ.id,
2002
- type: "start",
2003
- name: occ.properties.name,
2004
- point: (0, import_center7.center)(opening).geometry.coordinates,
2005
- levelId: opening.properties.level_id,
2006
- ordinal: level.properties.ordinal,
2007
- source: { type: "opening", id: opening.id }
2008
- },
2009
- path.slice(3)
2010
- ];
2011
- }
2012
- if (isOccupant(a) && isKiosk(b)) {
2013
- const occ = findByIdSync(a);
2014
- const kiosk = findByIdSync(c);
2015
- const level = findByIdSync(kiosk.properties.level_id);
2016
- return [
2017
- {
2018
- id: occ.id,
2019
- type: "start",
2020
- name: occ.properties.name,
2021
- point: (0, import_center7.center)(kiosk).geometry.coordinates,
2022
- levelId: kiosk.properties.level_id,
2023
- ordinal: level.properties.ordinal,
2024
- source: { type: "kiosk", id: kiosk.id }
2025
- },
2026
- path.slice(2)
2027
- ];
2028
- }
2029
- if (isCoordinateOrdinalString(a) && isOpening(b)) {
2030
- const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2031
- const opening = findByIdSync(b);
2032
- return [
2033
- {
2034
- id: a,
2035
- type: "start",
2036
- name: { en: `Your location` },
2037
- point: [lng, lat],
2038
- levelId: opening.properties.level_id,
2039
- ordinal,
2040
- source: { type: "opening", id: opening.id }
2041
- },
2042
- path.slice(1)
2043
- ];
2044
- }
2045
- return [null, path];
2046
- };
2047
-
2048
- // src/data/navigate/steps/utils/extractEndPint.ts
2049
- var import_center8 = require("@turf/center");
2050
- var extractEndPoint = (path, options) => {
2051
- const { findByIdSync } = options;
2052
- const [c, b, a] = path.slice(-3);
2053
- if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2054
- const occ = findByIdSync(a);
2055
- const opening = findByIdSync(c);
2056
- const level = findByIdSync(opening.properties.level_id);
2057
- return [
2058
- {
2059
- id: occ.id,
2060
- type: "end",
2061
- name: occ.properties.name,
2062
- point: (0, import_center8.center)(opening).geometry.coordinates,
2063
- levelId: opening.properties.level_id,
2064
- ordinal: level.properties.ordinal,
2065
- source: { type: "opening", id: opening.id }
2066
- },
2067
- path.slice(0, -3)
2068
- ];
2069
- }
2070
- if (isOccupant(a) && isKiosk(b)) {
2071
- const occ = findByIdSync(a);
2072
- const kiosk = findByIdSync(c);
2073
- const level = findByIdSync(kiosk.properties.level_id);
2074
- return [
2075
- {
2076
- id: occ.id,
2077
- type: "end",
2078
- name: occ.properties.name,
2079
- point: (0, import_center8.center)(kiosk).geometry.coordinates,
2080
- levelId: kiosk.properties.level_id,
2081
- ordinal: level.properties.ordinal,
2082
- source: { type: "kiosk", id: kiosk.id }
2083
- },
2084
- path.slice(0, -2)
2085
- ];
2086
- }
2087
- if (isCoordinateOrdinalString(a)) {
2088
- const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2089
- const opening = findByIdSync(b);
2090
- return [
2091
- {
2092
- id: a,
2093
- type: "end",
2094
- name: { en: `Your location` },
2095
- point: [lng, lat],
2096
- levelId: opening.properties.level_id,
2097
- ordinal,
2098
- source: { type: "opening", id: opening.id }
2099
- },
2100
- path.slice(0, -2)
2101
- ];
2102
- }
2103
- return [null, path];
2104
- };
2105
-
2106
1931
  // src/data/navigate/steps/utils/combineWalkwaySteps.ts
2107
1932
  var import_uniq = __toESM(require("lodash/uniq"));
2108
1933
  var combineWalkwaySteps = (steps) => {
@@ -2115,7 +1940,6 @@ var combineWalkwaySteps = (steps) => {
2115
1940
  }
2116
1941
  const nextStep = steps[i + 1];
2117
1942
  if (thisStep.intermediaryCategory === "walkway" && nextStep.intermediaryCategory === "walkway" && thisStep.from.source.type === "opening" && nextStep.from.source.type === "opening") {
2118
- console.log({ i, len: steps.length, thisStep, nextStep });
2119
1943
  result.push({
2120
1944
  from: thisStep.from,
2121
1945
  to: nextStep.to,
@@ -2139,15 +1963,14 @@ var combineWalkwaySteps = (steps) => {
2139
1963
  // src/data/navigate/steps/createStepUtils.ts
2140
1964
  var createStepUtils = (options) => {
2141
1965
  const { data: { units, relationships }, findByIdSync } = options;
2142
- const landmarkUtils = createLandmarkUtils(options);
2143
1966
  const stepPathUtils = createStepPathUtils({ ...options, resolution: 88e-5 });
2144
1967
  const findUnitBetweenOpenings = (originId, destinationId) => {
2145
1968
  const origin = findByIdSync(originId);
2146
1969
  const destination = findByIdSync(destinationId);
2147
1970
  const matchedOne = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(origin.id));
2148
- const matchOneUnits = [matchedOne.properties.origin, matchedOne.properties.destination];
1971
+ const matchOneUnits = matchedOne ? [matchedOne.properties.origin, matchedOne.properties.destination] : [];
2149
1972
  const matchedTwo = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(destination.id));
2150
- const matchTwoUnits = [matchedTwo.properties.origin, matchedTwo.properties.destination];
1973
+ const matchTwoUnits = matchedTwo ? [matchedTwo.properties.origin, matchedTwo.properties.destination] : [];
2151
1974
  const unitIds = (0, import_intersectionBy.default)(matchOneUnits, matchTwoUnits, "id");
2152
1975
  return unitIds.map(({ id }) => findByIdSync(id));
2153
1976
  };
@@ -2174,7 +1997,7 @@ var createStepUtils = (options) => {
2174
1997
  const formatCategoryLabel = (category) => {
2175
1998
  return (0, import_lodash12.capitalize)(category);
2176
1999
  };
2177
- const getToward = (from, to, intermediary) => {
2000
+ const getNextStepIntermediary = (from, to, intermediary) => {
2178
2001
  if (to.type === "end") return to.name;
2179
2002
  const intermediaryIds = intermediary.map((int) => int.id);
2180
2003
  const relationship = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(to.source.id));
@@ -2185,32 +2008,11 @@ var createStepUtils = (options) => {
2185
2008
  const nextUnit = findByIdSync(nextUnitId);
2186
2009
  return { en: formatCategoryLabel(`${nextUnit.properties.category}`) };
2187
2010
  };
2188
- const toWaypoints = (path) => {
2189
- const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
2190
- const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
2191
- const waypoints = middlePoints.map((openingId) => {
2192
- const opening = findByIdSync(openingId);
2193
- const level = findByIdSync(opening.properties.level_id);
2194
- const coordinates = (0, import_center9.center)(opening).geometry.coordinates;
2195
- const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
2196
- return {
2197
- id: `${opening.properties.level_id}:${openingId}`,
2198
- type: "between",
2199
- point: coordinates,
2200
- name: null,
2201
- levelId: opening.properties.level_id,
2202
- ordinal: level.properties.ordinal,
2203
- hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
2204
- source: { type: "opening", id: opening.id }
2205
- };
2206
- });
2207
- return [startPoint, ...waypoints, endPoint];
2208
- };
2209
2011
  const createHorizontalStep = (from, to) => {
2210
2012
  const intermediary = findHorizontalIntermediary(from, to);
2211
2013
  const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
2212
2014
  const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
2213
- const toward = getToward(from, to, intermediary);
2015
+ const toward = getNextStepIntermediary(from, to, intermediary);
2214
2016
  const landmark = to.hint?.kind === "landmark" ? to.hint.name : null;
2215
2017
  const path = stepPathUtils.findStepPath(from.point, to.point, intermediary);
2216
2018
  const step = {
@@ -2267,8 +2069,6 @@ var createStepUtils = (options) => {
2267
2069
  return simplifySteps;
2268
2070
  };
2269
2071
  return {
2270
- // createSteps,
2271
- toWaypoints,
2272
2072
  toSteps
2273
2073
  };
2274
2074
  };
@@ -2289,6 +2089,11 @@ var calculateRoundedDistance = (distance5) => {
2289
2089
  return Math.round(distance5 - distance5 % 25);
2290
2090
  };
2291
2091
 
2092
+ // src/data/navigate/type-guard.ts
2093
+ function isCoordinateOrdinalString(id) {
2094
+ return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
2095
+ }
2096
+
2292
2097
  // src/data/navigate/utils/createFindByIdSync.ts
2293
2098
  var createFindByIdSync = (data) => {
2294
2099
  const { amenities = [], anchors = [], fixtures = [], levels = [], kiosks = [], relationships = [], occupants = [], openings = [], units } = data;
@@ -2311,6 +2116,207 @@ var createFindByIdSync = (data) => {
2311
2116
  return { findByIdSync };
2312
2117
  };
2313
2118
 
2119
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2120
+ var import_center9 = require("@turf/center");
2121
+
2122
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2123
+ var import_center6 = require("@turf/center");
2124
+
2125
+ // src/data/navigate/waypoint/featureIdGuard.ts
2126
+ var isOccupant = (id) => !!id && id.startsWith("occupant-");
2127
+ var isUnit = (id) => !!id && id.startsWith("unit-");
2128
+ var isKiosk = (id) => !!id && id.startsWith("kiosk-");
2129
+ var isOpening = (id) => !!id && id.startsWith("opening-");
2130
+
2131
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2132
+ var extractEndPoint = (path, options) => {
2133
+ const { findByIdSync } = options;
2134
+ const [c, b, a] = path.slice(-3);
2135
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2136
+ const occ = findByIdSync(a);
2137
+ const opening = findByIdSync(c);
2138
+ const level = findByIdSync(opening.properties.level_id);
2139
+ return [
2140
+ {
2141
+ id: occ.id,
2142
+ type: "end",
2143
+ name: occ.properties.name,
2144
+ point: (0, import_center6.center)(opening).geometry.coordinates,
2145
+ levelId: opening.properties.level_id,
2146
+ ordinal: level.properties.ordinal,
2147
+ source: { type: "opening", id: opening.id }
2148
+ },
2149
+ path.slice(0, -3)
2150
+ ];
2151
+ }
2152
+ if (isOccupant(a) && isKiosk(b)) {
2153
+ const occ = findByIdSync(a);
2154
+ const kiosk = findByIdSync(b);
2155
+ const level = findByIdSync(kiosk.properties.level_id);
2156
+ return [
2157
+ {
2158
+ id: occ.id,
2159
+ type: "end",
2160
+ name: occ.properties.name,
2161
+ point: (0, import_center6.center)(kiosk).geometry.coordinates,
2162
+ levelId: kiosk.properties.level_id,
2163
+ ordinal: level.properties.ordinal,
2164
+ source: { type: "kiosk", id: kiosk.id }
2165
+ },
2166
+ path.slice(0, -2)
2167
+ ];
2168
+ }
2169
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2170
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2171
+ const opening = findByIdSync(b);
2172
+ return [
2173
+ {
2174
+ id: a,
2175
+ type: "end",
2176
+ name: { en: a },
2177
+ point: [lng, lat],
2178
+ levelId: opening.properties.level_id,
2179
+ ordinal,
2180
+ source: { type: "coordinate", raw: a }
2181
+ },
2182
+ path.slice(0, -1)
2183
+ ];
2184
+ }
2185
+ return [null, path];
2186
+ };
2187
+
2188
+ // src/data/navigate/waypoint/extractStartWaypoint.ts
2189
+ var import_center7 = require("@turf/center");
2190
+ var extractStartPoint = (path, options) => {
2191
+ const { findByIdSync } = options;
2192
+ const [a, b, c] = path;
2193
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2194
+ const occ = findByIdSync(a);
2195
+ const opening = findByIdSync(c);
2196
+ const level = findByIdSync(opening.properties.level_id);
2197
+ return [
2198
+ {
2199
+ id: occ.id,
2200
+ type: "start",
2201
+ name: occ.properties.name,
2202
+ point: (0, import_center7.center)(opening).geometry.coordinates,
2203
+ levelId: opening.properties.level_id,
2204
+ ordinal: level.properties.ordinal,
2205
+ source: { type: "opening", id: opening.id }
2206
+ },
2207
+ path.slice(3)
2208
+ ];
2209
+ }
2210
+ if (isOccupant(a) && isKiosk(b)) {
2211
+ const occ = findByIdSync(a);
2212
+ const kiosk = findByIdSync(b);
2213
+ const level = findByIdSync(kiosk.properties.level_id);
2214
+ return [
2215
+ {
2216
+ id: occ.id,
2217
+ type: "start",
2218
+ name: occ.properties.name,
2219
+ point: (0, import_center7.center)(kiosk).geometry.coordinates,
2220
+ levelId: kiosk.properties.level_id,
2221
+ ordinal: level.properties.ordinal,
2222
+ source: { type: "kiosk", id: kiosk.id }
2223
+ },
2224
+ path.slice(2)
2225
+ ];
2226
+ }
2227
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2228
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2229
+ const opening = findByIdSync(b);
2230
+ return [
2231
+ {
2232
+ id: a,
2233
+ type: "start",
2234
+ name: { en: a },
2235
+ point: [lng, lat],
2236
+ levelId: opening.properties.level_id,
2237
+ ordinal,
2238
+ source: { type: "coordinate", raw: a }
2239
+ },
2240
+ path.slice(1)
2241
+ ];
2242
+ }
2243
+ return [null, path];
2244
+ };
2245
+
2246
+ // src/data/navigate/landmark/createLandmarkUtils.ts
2247
+ var import_center8 = require("@turf/center");
2248
+ var import_distance5 = __toESM(require("@turf/distance"));
2249
+ var NEARBY_DISTANCE = 30;
2250
+ var createLandmarkUtils = (options) => {
2251
+ const { data, findByIdSync } = options;
2252
+ const { occupants = [] } = data;
2253
+ const occupantToLandmark = (occupant) => {
2254
+ const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
2255
+ const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
2256
+ const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
2257
+ const level = findByIdSync(location.properties.level_id);
2258
+ return {
2259
+ name: occupant.properties.name,
2260
+ point: (0, import_center8.center)(location.geometry).geometry.coordinates,
2261
+ level_id: location.properties.level_id,
2262
+ is_priority: occupant.properties.is_landmark,
2263
+ ordinal: level.properties.ordinal
2264
+ };
2265
+ };
2266
+ const landmarks = [
2267
+ ...occupants.map(occupantToLandmark)
2268
+ ];
2269
+ const findNearbyLandmarks = (point2, levelId) => {
2270
+ if (point2 === null || levelId === null) return [];
2271
+ return landmarks.map((landmark) => {
2272
+ const landmarkAndDistance = {
2273
+ landmark,
2274
+ d: (0, import_distance5.default)(point2, landmark.point, { units: "meters" })
2275
+ };
2276
+ return landmarkAndDistance;
2277
+ }).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
2278
+ const aPriority = a.landmark.is_priority ? 0 : 1;
2279
+ const bPriority = b.landmark.is_priority ? 0 : 1;
2280
+ if (aPriority !== bPriority) return aPriority - bPriority;
2281
+ return a.d - b.d;
2282
+ }).map(({ landmark }) => landmark);
2283
+ };
2284
+ const findNearestLandmark = (point2, levelId) => {
2285
+ const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
2286
+ const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
2287
+ return nearestLandmark;
2288
+ };
2289
+ return { findNearbyLandmarks, findNearestLandmark };
2290
+ };
2291
+
2292
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2293
+ var createWaypointUtils = (options) => {
2294
+ const { findByIdSync } = options;
2295
+ const landmarkUtils = createLandmarkUtils(options);
2296
+ const toWaypoints = (path) => {
2297
+ const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
2298
+ const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
2299
+ const waypoints = middlePoints.map((openingId) => {
2300
+ const opening = findByIdSync(openingId);
2301
+ const level = findByIdSync(opening.properties.level_id);
2302
+ const coordinates = (0, import_center9.center)(opening).geometry.coordinates;
2303
+ const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
2304
+ return {
2305
+ id: `${opening.properties.level_id}:${openingId}`,
2306
+ type: "between",
2307
+ point: coordinates,
2308
+ name: null,
2309
+ levelId: opening.properties.level_id,
2310
+ ordinal: level.properties.ordinal,
2311
+ hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
2312
+ source: { type: "opening", id: opening.id }
2313
+ };
2314
+ });
2315
+ return [startPoint, ...waypoints, endPoint];
2316
+ };
2317
+ return { toWaypoints };
2318
+ };
2319
+
2314
2320
  // src/data/navigate/getNavigateClient.ts
2315
2321
  var getNavigateClient = (options) => {
2316
2322
  const { data } = options;
@@ -2332,6 +2338,7 @@ var getNavigateClient = (options) => {
2332
2338
  return unit;
2333
2339
  };
2334
2340
  const stepUtils = createStepUtils({ ...options, findByIdSync });
2341
+ const waypointUtils = createWaypointUtils({ ...options, findByIdSync });
2335
2342
  const findRoute = async (routeOriginParam, routeDestinationParam, options2) => {
2336
2343
  if (!routeOriginParam || !routeDestinationParam) return null;
2337
2344
  const graph = options2?.mode === "accessible" ? accessibleGraph : defaultGraph;
@@ -2349,8 +2356,7 @@ var getNavigateClient = (options) => {
2349
2356
  const path = graph.path(routeOriginParam, routeDestinationParam);
2350
2357
  const t12 = performance.now();
2351
2358
  trace("nav", " \u251C\u2500 path (dijkstra)", t12 - t02);
2352
- const waypoints = stepUtils.toWaypoints(path);
2353
- console.log({ waypoints });
2359
+ const waypoints = waypointUtils.toWaypoints(path);
2354
2360
  const t22 = performance.now();
2355
2361
  trace("nav", " \u251C\u2500 toWaypoints", t22 - t12);
2356
2362
  trace("nav", " \u251C\u2500 toSteps", 0);
@@ -2362,9 +2368,6 @@ var getNavigateClient = (options) => {
2362
2368
  const t4 = performance.now();
2363
2369
  trace("nav", " \u2514\u2500 postProcess", t4 - t32);
2364
2370
  return {
2365
- // origin: routeOrigin,
2366
- // destination: routeDestination,
2367
- description: null,
2368
2371
  distance: roundedDistance,
2369
2372
  duration,
2370
2373
  steps
@@ -2553,6 +2556,7 @@ var getDataClient = (options) => {
2553
2556
  fetchDeliveryApi,
2554
2557
  fetchPreviewApi,
2555
2558
  getDataClient,
2559
+ getNavigateClient,
2556
2560
  getSearchClient,
2557
2561
  isValidCoordinate,
2558
2562
  isValidLineString,