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.
@@ -150,6 +150,119 @@ var defaultFeatureQueryOptionsMap = {
150
150
  model3d: {}
151
151
  };
152
152
 
153
+ // src/data/utils/geometry-validator.ts
154
+ var isValidCoordinate = (point2) => {
155
+ return point2.length === 2 && point2.every((coord) => typeof coord === "number");
156
+ };
157
+ function isValidLinearRingCoordinates(ring) {
158
+ if (ring.length < 4) {
159
+ return false;
160
+ }
161
+ return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
162
+ }
163
+ var isValidPolygonCoordinates = (polygon2) => {
164
+ if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
165
+ return isValidLinearRingCoordinates(polygon2);
166
+ }
167
+ if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
168
+ if (!isValidLinearRingCoordinates(polygon2[0])) {
169
+ return false;
170
+ }
171
+ for (let i = 1; i < polygon2.length; i++) {
172
+ if (!isValidLinearRingCoordinates(polygon2[i])) {
173
+ return false;
174
+ }
175
+ }
176
+ return true;
177
+ }
178
+ return false;
179
+ };
180
+ var isValidMultiPolygonCoordinates = (multipolygon) => {
181
+ return multipolygon.every(isValidPolygonCoordinates);
182
+ };
183
+ var isValidLineStringCoordinates = (lineString2) => {
184
+ if (!Array.isArray(lineString2) || lineString2.length < 2) {
185
+ return false;
186
+ }
187
+ const firstPoint = lineString2[0];
188
+ const lastPoint = lineString2[lineString2.length - 1];
189
+ if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
190
+ return false;
191
+ }
192
+ return lineString2.every(isValidCoordinate);
193
+ };
194
+ var isValidMultiPolygon = (geometry) => {
195
+ const { type, coordinates } = geometry;
196
+ return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
197
+ };
198
+ var isValidPolygon = (geometry) => {
199
+ const { type, coordinates } = geometry;
200
+ return type === "Polygon" && isValidPolygonCoordinates(coordinates);
201
+ };
202
+ var isValidLineString = (geometry) => {
203
+ const { type, coordinates } = geometry;
204
+ return type === "LineString" && isValidLineStringCoordinates(coordinates);
205
+ };
206
+ var isValidPoint = (geometry) => {
207
+ const { type, coordinates } = geometry;
208
+ return type === "Point" && isValidCoordinate(coordinates);
209
+ };
210
+
211
+ // src/data/utils/match-filters.ts
212
+ function isInFilter(filter) {
213
+ return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
214
+ }
215
+ var someIntersect = (a, b) => a.some((v) => b.includes(v));
216
+ function matchFilter(value, filter) {
217
+ if (Array.isArray(value)) {
218
+ if (isInFilter(filter)) return someIntersect(value, filter.$in);
219
+ return value.includes(filter);
220
+ } else {
221
+ if (isInFilter(filter)) return filter.$in.includes(value);
222
+ return value === filter;
223
+ }
224
+ }
225
+ function matchFilters(item, filters) {
226
+ return Object.entries(filters).every(([key, filter]) => {
227
+ return matchFilter(item.properties[key], filter);
228
+ });
229
+ }
230
+
231
+ // src/data/utils/occupant-helper.ts
232
+ var occupant_helper_exports = {};
233
+ __export(occupant_helper_exports, {
234
+ getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
235
+ getOccupantMainLocation: () => getOccupantMainLocation,
236
+ getOccupantMarkerLocations: () => getOccupantMarkerLocations
237
+ });
238
+
239
+ // src/data/utils/lodash/compact.ts
240
+ var compact = (arr) => arr.filter((item) => Boolean(item));
241
+
242
+ // src/data/utils/occupant-helper.ts
243
+ var getOccupantMainLocation = (occupant) => {
244
+ return occupant.properties.kiosk || occupant.properties.unit;
245
+ };
246
+ var getOccupantCorrelatedLocations = (occupant) => {
247
+ const allCorrelatedLocations = [
248
+ ...occupant.properties.units,
249
+ ...occupant.properties.kiosks
250
+ ];
251
+ return compact(allCorrelatedLocations);
252
+ };
253
+ var getOccupantMarkerLocations = (occupant, options) => {
254
+ const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
255
+ const mainLocation = getOccupantMainLocation(occupant);
256
+ const mainLocationLevel = mainLocation?.properties?.level_id;
257
+ const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
258
+ if (placementType === "ALL_LOCATIONS") {
259
+ return compact([mainLocation, ...allCorrelatedLocations]);
260
+ }
261
+ const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
262
+ const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
263
+ return compact([mainLocation, ...onePerLevelLocations]);
264
+ };
265
+
153
266
  // src/data/api/delivery-project.ts
154
267
  async function fetchDeliveryApi(projectId, apiKey, featureType, baseUrl = DEFAULT_BASE_URL) {
155
268
  switch (featureType) {
@@ -271,119 +384,6 @@ var safeFetchFeature = async (featureType, params) => {
271
384
  }
272
385
  };
273
386
 
274
- // src/data/utils/geometry-validator.ts
275
- var isValidCoordinate = (point2) => {
276
- return point2.length === 2 && point2.every((coord) => typeof coord === "number");
277
- };
278
- function isValidLinearRingCoordinates(ring) {
279
- if (ring.length < 4) {
280
- return false;
281
- }
282
- return ring.every(isValidCoordinate) && ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1];
283
- }
284
- var isValidPolygonCoordinates = (polygon2) => {
285
- if (Array.isArray(polygon2[0]) && (polygon2[0].length === 0 || typeof polygon2[0][0] === "number")) {
286
- return isValidLinearRingCoordinates(polygon2);
287
- }
288
- if (Array.isArray(polygon2) && polygon2.length > 0 && Array.isArray(polygon2[0])) {
289
- if (!isValidLinearRingCoordinates(polygon2[0])) {
290
- return false;
291
- }
292
- for (let i = 1; i < polygon2.length; i++) {
293
- if (!isValidLinearRingCoordinates(polygon2[i])) {
294
- return false;
295
- }
296
- }
297
- return true;
298
- }
299
- return false;
300
- };
301
- var isValidMultiPolygonCoordinates = (multipolygon) => {
302
- return multipolygon.every(isValidPolygonCoordinates);
303
- };
304
- var isValidLineStringCoordinates = (lineString2) => {
305
- if (!Array.isArray(lineString2) || lineString2.length < 2) {
306
- return false;
307
- }
308
- const firstPoint = lineString2[0];
309
- const lastPoint = lineString2[lineString2.length - 1];
310
- if (firstPoint[0] === lastPoint[0] && firstPoint[1] === lastPoint[1]) {
311
- return false;
312
- }
313
- return lineString2.every(isValidCoordinate);
314
- };
315
- var isValidMultiPolygon = (geometry) => {
316
- const { type, coordinates } = geometry;
317
- return type === "MultiPolygon" && isValidMultiPolygonCoordinates(coordinates);
318
- };
319
- var isValidPolygon = (geometry) => {
320
- const { type, coordinates } = geometry;
321
- return type === "Polygon" && isValidPolygonCoordinates(coordinates);
322
- };
323
- var isValidLineString = (geometry) => {
324
- const { type, coordinates } = geometry;
325
- return type === "LineString" && isValidLineStringCoordinates(coordinates);
326
- };
327
- var isValidPoint = (geometry) => {
328
- const { type, coordinates } = geometry;
329
- return type === "Point" && isValidCoordinate(coordinates);
330
- };
331
-
332
- // src/data/utils/match-filters.ts
333
- function isInFilter(filter) {
334
- return typeof filter === "object" && filter !== null && "$in" in filter && Array.isArray(filter.$in);
335
- }
336
- var someIntersect = (a, b) => a.some((v) => b.includes(v));
337
- function matchFilter(value, filter) {
338
- if (Array.isArray(value)) {
339
- if (isInFilter(filter)) return someIntersect(value, filter.$in);
340
- return value.includes(filter);
341
- } else {
342
- if (isInFilter(filter)) return filter.$in.includes(value);
343
- return value === filter;
344
- }
345
- }
346
- function matchFilters(item, filters) {
347
- return Object.entries(filters).every(([key, filter]) => {
348
- return matchFilter(item.properties[key], filter);
349
- });
350
- }
351
-
352
- // src/data/utils/occupant-helper.ts
353
- var occupant_helper_exports = {};
354
- __export(occupant_helper_exports, {
355
- getOccupantCorrelatedLocations: () => getOccupantCorrelatedLocations,
356
- getOccupantMainLocation: () => getOccupantMainLocation,
357
- getOccupantMarkerLocations: () => getOccupantMarkerLocations
358
- });
359
-
360
- // src/data/utils/lodash/compact.ts
361
- var compact = (arr) => arr.filter((item) => Boolean(item));
362
-
363
- // src/data/utils/occupant-helper.ts
364
- var getOccupantMainLocation = (occupant) => {
365
- return occupant.properties.kiosk || occupant.properties.unit;
366
- };
367
- var getOccupantCorrelatedLocations = (occupant) => {
368
- const allCorrelatedLocations = [
369
- ...occupant.properties.units,
370
- ...occupant.properties.kiosks
371
- ];
372
- return compact(allCorrelatedLocations);
373
- };
374
- var getOccupantMarkerLocations = (occupant, options) => {
375
- const placementType = options?.type ? options.type : occupant.properties.show_name_on_all_units ? "ALL_LOCATIONS" : "ONCE_PER_LEVEL";
376
- const mainLocation = getOccupantMainLocation(occupant);
377
- const mainLocationLevel = mainLocation?.properties?.level_id;
378
- const allCorrelatedLocations = getOccupantCorrelatedLocations(occupant);
379
- if (placementType === "ALL_LOCATIONS") {
380
- return compact([mainLocation, ...allCorrelatedLocations]);
381
- }
382
- const otherLevelLocations = allCorrelatedLocations.filter((f) => f.properties.level_id !== mainLocationLevel);
383
- const onePerLevelLocations = [...new Map(otherLevelLocations.map((loc) => [loc.properties.level_id, loc])).values()];
384
- return compact([mainLocation, ...onePerLevelLocations]);
385
- };
386
-
387
387
  // src/data/getDataClient.ts
388
388
  import {
389
389
  QueryClient,
@@ -791,7 +791,7 @@ var getDistanceOptions = (options, category) => {
791
791
 
792
792
  // src/data/utils/trace.ts
793
793
  var trace = (namespace, text, ms, color) => {
794
- console.log(`[${namespace}] %c${text.padEnd(90)} ${ms !== void 0 ? `${ms.toFixed(1).padStart(6)} ms` : ``}`, color ? `color: ${color}` : void 0);
794
+ 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);
795
795
  };
796
796
 
797
797
  // src/data/navigate/graph/nodemap/createTraversalNodeMap.ts
@@ -1202,7 +1202,6 @@ var prepareGraph = (options) => {
1202
1202
  // src/data/navigate/steps/createStepUtils.ts
1203
1203
  import { capitalize } from "lodash";
1204
1204
  import _intersectionBy from "lodash/intersectionBy";
1205
- import { center as center6 } from "@turf/center";
1206
1205
 
1207
1206
  // src/data/navigate/description/describe.ts
1208
1207
  var t = (template, locale, options) => {
@@ -1594,7 +1593,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1594
1593
  if (path.length <= 2) return path;
1595
1594
  const out = [path[0]];
1596
1595
  for (let i = 1; i < path.length - 1; i++) {
1597
- const a = out[out.length - 1];
1596
+ const a = out.at(-1);
1598
1597
  const b = path[i];
1599
1598
  const c = path[i + 1];
1600
1599
  const abx = b[0] - a[0], aby = b[1] - a[1];
@@ -1605,7 +1604,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1605
1604
  const angle = Math.acos(dot / (ab * bc)) * 180 / Math.PI;
1606
1605
  if (angle > minDeg) out.push(b);
1607
1606
  }
1608
- out.push(path[path.length - 1]);
1607
+ out.push(path.at(-1));
1609
1608
  return out;
1610
1609
  }
1611
1610
 
@@ -1613,7 +1612,7 @@ function pruneSmallAngles(path, minDeg = 10) {
1613
1612
  function pruneShortSegments(path, minLen = 5) {
1614
1613
  const out = [path[0]];
1615
1614
  for (let i = 1; i < path.length; i++) {
1616
- const [x0, y0] = out[out.length - 1];
1615
+ const [x0, y0] = out.at(-1);
1617
1616
  const [x1, y1] = path[i];
1618
1617
  if (Math.hypot(x1 - x0, y1 - y0) >= minLen) {
1619
1618
  out.push(path[i]);
@@ -1815,7 +1814,7 @@ var shortestPath_default = shortestPath;
1815
1814
  // src/data/navigate/steps/path/index.ts
1816
1815
  var createStepPathUtils = (options) => {
1817
1816
  const resolution = options.resolution ?? 88e-5;
1818
- const { units, kiosks, fixtures } = options.data;
1817
+ const { units = [], kiosks = [], fixtures = [] } = options.data;
1819
1818
  const possibleObstacleFeatures = [...units, ...kiosks, ...fixtures];
1820
1819
  const filterObstaclesByOrdinal = (levelId) => {
1821
1820
  return possibleObstacleFeatures.filter(({ feature_type, properties, geometry }) => {
@@ -1881,181 +1880,6 @@ var createStepPathUtils = (options) => {
1881
1880
  };
1882
1881
  };
1883
1882
 
1884
- // src/data/navigate/landmark/createLandmarkUtils.ts
1885
- import { center as center3 } from "@turf/center";
1886
- import distance4 from "@turf/distance";
1887
- var NEARBY_DISTANCE = 30;
1888
- var createLandmarkUtils = (options) => {
1889
- const { data, findByIdSync } = options;
1890
- const { occupants } = data;
1891
- const occupantToLandmark = (occupant) => {
1892
- const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
1893
- const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
1894
- const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
1895
- const level = findByIdSync(location.properties.level_id);
1896
- return {
1897
- name: occupant.properties.name,
1898
- point: center3(location.geometry).geometry.coordinates,
1899
- level_id: location.properties.level_id,
1900
- is_priority: occupant.properties.is_landmark,
1901
- ordinal: level.properties.ordinal
1902
- };
1903
- };
1904
- const landmarks = [
1905
- ...occupants.map(occupantToLandmark)
1906
- ];
1907
- const findNearbyLandmarks = (point2, levelId) => {
1908
- if (point2 === null || levelId === null) return [];
1909
- return landmarks.map((landmark) => {
1910
- const landmarkAndDistance = {
1911
- landmark,
1912
- d: distance4(point2, landmark.point, { units: "meters" })
1913
- };
1914
- return landmarkAndDistance;
1915
- }).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
1916
- const aPriority = a.landmark.is_priority ? 0 : 1;
1917
- const bPriority = b.landmark.is_priority ? 0 : 1;
1918
- if (aPriority !== bPriority) return aPriority - bPriority;
1919
- return a.d - b.d;
1920
- }).map(({ landmark }) => landmark);
1921
- };
1922
- const findNearestLandmark = (point2, levelId) => {
1923
- const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
1924
- const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
1925
- return nearestLandmark;
1926
- };
1927
- return { findNearbyLandmarks, findNearestLandmark };
1928
- };
1929
-
1930
- // src/data/navigate/steps/utils/extractStartPoint.ts
1931
- import { center as center4 } from "@turf/center";
1932
-
1933
- // src/data/navigate/steps/utils/featureIdGuard.ts
1934
- var isOccupant = (id) => !!id && id.startsWith("occupant-");
1935
- var isUnit = (id) => !!id && id.startsWith("unit-");
1936
- var isKiosk = (id) => !!id && id.startsWith("kiosk-");
1937
- var isOpening = (id) => !!id && id.startsWith("opening-");
1938
-
1939
- // src/data/navigate/type-guard.ts
1940
- function isCoordinateOrdinalString(id) {
1941
- return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
1942
- }
1943
-
1944
- // src/data/navigate/steps/utils/extractStartPoint.ts
1945
- var extractStartPoint = (path, options) => {
1946
- const { findByIdSync } = options;
1947
- const [a, b, c] = path;
1948
- if (isOccupant(a) && isUnit(b) && isOpening(c)) {
1949
- const occ = findByIdSync(a);
1950
- const opening = findByIdSync(c);
1951
- const level = findByIdSync(opening.properties.level_id);
1952
- return [
1953
- {
1954
- id: occ.id,
1955
- type: "start",
1956
- name: occ.properties.name,
1957
- point: center4(opening).geometry.coordinates,
1958
- levelId: opening.properties.level_id,
1959
- ordinal: level.properties.ordinal,
1960
- source: { type: "opening", id: opening.id }
1961
- },
1962
- path.slice(3)
1963
- ];
1964
- }
1965
- if (isOccupant(a) && isKiosk(b)) {
1966
- const occ = findByIdSync(a);
1967
- const kiosk = findByIdSync(c);
1968
- const level = findByIdSync(kiosk.properties.level_id);
1969
- return [
1970
- {
1971
- id: occ.id,
1972
- type: "start",
1973
- name: occ.properties.name,
1974
- point: center4(kiosk).geometry.coordinates,
1975
- levelId: kiosk.properties.level_id,
1976
- ordinal: level.properties.ordinal,
1977
- source: { type: "kiosk", id: kiosk.id }
1978
- },
1979
- path.slice(2)
1980
- ];
1981
- }
1982
- if (isCoordinateOrdinalString(a) && isOpening(b)) {
1983
- const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
1984
- const opening = findByIdSync(b);
1985
- return [
1986
- {
1987
- id: a,
1988
- type: "start",
1989
- name: { en: `Your location` },
1990
- point: [lng, lat],
1991
- levelId: opening.properties.level_id,
1992
- ordinal,
1993
- source: { type: "opening", id: opening.id }
1994
- },
1995
- path.slice(1)
1996
- ];
1997
- }
1998
- return [null, path];
1999
- };
2000
-
2001
- // src/data/navigate/steps/utils/extractEndPint.ts
2002
- import { center as center5 } from "@turf/center";
2003
- var extractEndPoint = (path, options) => {
2004
- const { findByIdSync } = options;
2005
- const [c, b, a] = path.slice(-3);
2006
- if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2007
- const occ = findByIdSync(a);
2008
- const opening = findByIdSync(c);
2009
- const level = findByIdSync(opening.properties.level_id);
2010
- return [
2011
- {
2012
- id: occ.id,
2013
- type: "end",
2014
- name: occ.properties.name,
2015
- point: center5(opening).geometry.coordinates,
2016
- levelId: opening.properties.level_id,
2017
- ordinal: level.properties.ordinal,
2018
- source: { type: "opening", id: opening.id }
2019
- },
2020
- path.slice(0, -3)
2021
- ];
2022
- }
2023
- if (isOccupant(a) && isKiosk(b)) {
2024
- const occ = findByIdSync(a);
2025
- const kiosk = findByIdSync(c);
2026
- const level = findByIdSync(kiosk.properties.level_id);
2027
- return [
2028
- {
2029
- id: occ.id,
2030
- type: "end",
2031
- name: occ.properties.name,
2032
- point: center5(kiosk).geometry.coordinates,
2033
- levelId: kiosk.properties.level_id,
2034
- ordinal: level.properties.ordinal,
2035
- source: { type: "kiosk", id: kiosk.id }
2036
- },
2037
- path.slice(0, -2)
2038
- ];
2039
- }
2040
- if (isCoordinateOrdinalString(a)) {
2041
- const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2042
- const opening = findByIdSync(b);
2043
- return [
2044
- {
2045
- id: a,
2046
- type: "end",
2047
- name: { en: `Your location` },
2048
- point: [lng, lat],
2049
- levelId: opening.properties.level_id,
2050
- ordinal,
2051
- source: { type: "opening", id: opening.id }
2052
- },
2053
- path.slice(0, -2)
2054
- ];
2055
- }
2056
- return [null, path];
2057
- };
2058
-
2059
1883
  // src/data/navigate/steps/utils/combineWalkwaySteps.ts
2060
1884
  import uniq from "lodash/uniq";
2061
1885
  var combineWalkwaySteps = (steps) => {
@@ -2068,7 +1892,6 @@ var combineWalkwaySteps = (steps) => {
2068
1892
  }
2069
1893
  const nextStep = steps[i + 1];
2070
1894
  if (thisStep.intermediaryCategory === "walkway" && nextStep.intermediaryCategory === "walkway" && thisStep.from.source.type === "opening" && nextStep.from.source.type === "opening") {
2071
- console.log({ i, len: steps.length, thisStep, nextStep });
2072
1895
  result.push({
2073
1896
  from: thisStep.from,
2074
1897
  to: nextStep.to,
@@ -2092,15 +1915,14 @@ var combineWalkwaySteps = (steps) => {
2092
1915
  // src/data/navigate/steps/createStepUtils.ts
2093
1916
  var createStepUtils = (options) => {
2094
1917
  const { data: { units, relationships }, findByIdSync } = options;
2095
- const landmarkUtils = createLandmarkUtils(options);
2096
1918
  const stepPathUtils = createStepPathUtils({ ...options, resolution: 88e-5 });
2097
1919
  const findUnitBetweenOpenings = (originId, destinationId) => {
2098
1920
  const origin = findByIdSync(originId);
2099
1921
  const destination = findByIdSync(destinationId);
2100
1922
  const matchedOne = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(origin.id));
2101
- const matchOneUnits = [matchedOne.properties.origin, matchedOne.properties.destination];
1923
+ const matchOneUnits = matchedOne ? [matchedOne.properties.origin, matchedOne.properties.destination] : [];
2102
1924
  const matchedTwo = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(destination.id));
2103
- const matchTwoUnits = [matchedTwo.properties.origin, matchedTwo.properties.destination];
1925
+ const matchTwoUnits = matchedTwo ? [matchedTwo.properties.origin, matchedTwo.properties.destination] : [];
2104
1926
  const unitIds = _intersectionBy(matchOneUnits, matchTwoUnits, "id");
2105
1927
  return unitIds.map(({ id }) => findByIdSync(id));
2106
1928
  };
@@ -2127,7 +1949,7 @@ var createStepUtils = (options) => {
2127
1949
  const formatCategoryLabel = (category) => {
2128
1950
  return capitalize(category);
2129
1951
  };
2130
- const getToward = (from, to, intermediary) => {
1952
+ const getNextStepIntermediary = (from, to, intermediary) => {
2131
1953
  if (to.type === "end") return to.name;
2132
1954
  const intermediaryIds = intermediary.map((int) => int.id);
2133
1955
  const relationship = relationships.find((rel) => rel.properties.intermediary.map((int) => int.id).includes(to.source.id));
@@ -2138,32 +1960,11 @@ var createStepUtils = (options) => {
2138
1960
  const nextUnit = findByIdSync(nextUnitId);
2139
1961
  return { en: formatCategoryLabel(`${nextUnit.properties.category}`) };
2140
1962
  };
2141
- const toWaypoints = (path) => {
2142
- const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
2143
- const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
2144
- const waypoints = middlePoints.map((openingId) => {
2145
- const opening = findByIdSync(openingId);
2146
- const level = findByIdSync(opening.properties.level_id);
2147
- const coordinates = center6(opening).geometry.coordinates;
2148
- const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
2149
- return {
2150
- id: `${opening.properties.level_id}:${openingId}`,
2151
- type: "between",
2152
- point: coordinates,
2153
- name: null,
2154
- levelId: opening.properties.level_id,
2155
- ordinal: level.properties.ordinal,
2156
- hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
2157
- source: { type: "opening", id: opening.id }
2158
- };
2159
- });
2160
- return [startPoint, ...waypoints, endPoint];
2161
- };
2162
1963
  const createHorizontalStep = (from, to) => {
2163
1964
  const intermediary = findHorizontalIntermediary(from, to);
2164
1965
  const intermediaryCategories = intermediary.map((unit) => unit.properties.category);
2165
1966
  const intermediaryCategory = intermediaryCategories.length > 0 ? intermediaryCategories[0] : "unspecified";
2166
- const toward = getToward(from, to, intermediary);
1967
+ const toward = getNextStepIntermediary(from, to, intermediary);
2167
1968
  const landmark = to.hint?.kind === "landmark" ? to.hint.name : null;
2168
1969
  const path = stepPathUtils.findStepPath(from.point, to.point, intermediary);
2169
1970
  const step = {
@@ -2220,8 +2021,6 @@ var createStepUtils = (options) => {
2220
2021
  return simplifySteps;
2221
2022
  };
2222
2023
  return {
2223
- // createSteps,
2224
- toWaypoints,
2225
2024
  toSteps
2226
2025
  };
2227
2026
  };
@@ -2242,6 +2041,11 @@ var calculateRoundedDistance = (distance5) => {
2242
2041
  return Math.round(distance5 - distance5 % 25);
2243
2042
  };
2244
2043
 
2044
+ // src/data/navigate/type-guard.ts
2045
+ function isCoordinateOrdinalString(id) {
2046
+ return /^-?\d+(\.\d+)?,-?\d+(\.\d+)?,-?\d+(\.\d+)?o$/.test(id);
2047
+ }
2048
+
2245
2049
  // src/data/navigate/utils/createFindByIdSync.ts
2246
2050
  var createFindByIdSync = (data) => {
2247
2051
  const { amenities = [], anchors = [], fixtures = [], levels = [], kiosks = [], relationships = [], occupants = [], openings = [], units } = data;
@@ -2264,6 +2068,207 @@ var createFindByIdSync = (data) => {
2264
2068
  return { findByIdSync };
2265
2069
  };
2266
2070
 
2071
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2072
+ import { center as center6 } from "@turf/center";
2073
+
2074
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2075
+ import { center as center3 } from "@turf/center";
2076
+
2077
+ // src/data/navigate/waypoint/featureIdGuard.ts
2078
+ var isOccupant = (id) => !!id && id.startsWith("occupant-");
2079
+ var isUnit = (id) => !!id && id.startsWith("unit-");
2080
+ var isKiosk = (id) => !!id && id.startsWith("kiosk-");
2081
+ var isOpening = (id) => !!id && id.startsWith("opening-");
2082
+
2083
+ // src/data/navigate/waypoint/extractEndWaypoint.ts
2084
+ var extractEndPoint = (path, options) => {
2085
+ const { findByIdSync } = options;
2086
+ const [c, b, a] = path.slice(-3);
2087
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2088
+ const occ = findByIdSync(a);
2089
+ const opening = findByIdSync(c);
2090
+ const level = findByIdSync(opening.properties.level_id);
2091
+ return [
2092
+ {
2093
+ id: occ.id,
2094
+ type: "end",
2095
+ name: occ.properties.name,
2096
+ point: center3(opening).geometry.coordinates,
2097
+ levelId: opening.properties.level_id,
2098
+ ordinal: level.properties.ordinal,
2099
+ source: { type: "opening", id: opening.id }
2100
+ },
2101
+ path.slice(0, -3)
2102
+ ];
2103
+ }
2104
+ if (isOccupant(a) && isKiosk(b)) {
2105
+ const occ = findByIdSync(a);
2106
+ const kiosk = findByIdSync(b);
2107
+ const level = findByIdSync(kiosk.properties.level_id);
2108
+ return [
2109
+ {
2110
+ id: occ.id,
2111
+ type: "end",
2112
+ name: occ.properties.name,
2113
+ point: center3(kiosk).geometry.coordinates,
2114
+ levelId: kiosk.properties.level_id,
2115
+ ordinal: level.properties.ordinal,
2116
+ source: { type: "kiosk", id: kiosk.id }
2117
+ },
2118
+ path.slice(0, -2)
2119
+ ];
2120
+ }
2121
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2122
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2123
+ const opening = findByIdSync(b);
2124
+ return [
2125
+ {
2126
+ id: a,
2127
+ type: "end",
2128
+ name: { en: a },
2129
+ point: [lng, lat],
2130
+ levelId: opening.properties.level_id,
2131
+ ordinal,
2132
+ source: { type: "coordinate", raw: a }
2133
+ },
2134
+ path.slice(0, -1)
2135
+ ];
2136
+ }
2137
+ return [null, path];
2138
+ };
2139
+
2140
+ // src/data/navigate/waypoint/extractStartWaypoint.ts
2141
+ import { center as center4 } from "@turf/center";
2142
+ var extractStartPoint = (path, options) => {
2143
+ const { findByIdSync } = options;
2144
+ const [a, b, c] = path;
2145
+ if (isOccupant(a) && isUnit(b) && isOpening(c)) {
2146
+ const occ = findByIdSync(a);
2147
+ const opening = findByIdSync(c);
2148
+ const level = findByIdSync(opening.properties.level_id);
2149
+ return [
2150
+ {
2151
+ id: occ.id,
2152
+ type: "start",
2153
+ name: occ.properties.name,
2154
+ point: center4(opening).geometry.coordinates,
2155
+ levelId: opening.properties.level_id,
2156
+ ordinal: level.properties.ordinal,
2157
+ source: { type: "opening", id: opening.id }
2158
+ },
2159
+ path.slice(3)
2160
+ ];
2161
+ }
2162
+ if (isOccupant(a) && isKiosk(b)) {
2163
+ const occ = findByIdSync(a);
2164
+ const kiosk = findByIdSync(b);
2165
+ const level = findByIdSync(kiosk.properties.level_id);
2166
+ return [
2167
+ {
2168
+ id: occ.id,
2169
+ type: "start",
2170
+ name: occ.properties.name,
2171
+ point: center4(kiosk).geometry.coordinates,
2172
+ levelId: kiosk.properties.level_id,
2173
+ ordinal: level.properties.ordinal,
2174
+ source: { type: "kiosk", id: kiosk.id }
2175
+ },
2176
+ path.slice(2)
2177
+ ];
2178
+ }
2179
+ if (isCoordinateOrdinalString(a) && isOpening(b)) {
2180
+ const [lat, lng, ordinal] = parseOrdinalCoordinate(a);
2181
+ const opening = findByIdSync(b);
2182
+ return [
2183
+ {
2184
+ id: a,
2185
+ type: "start",
2186
+ name: { en: a },
2187
+ point: [lng, lat],
2188
+ levelId: opening.properties.level_id,
2189
+ ordinal,
2190
+ source: { type: "coordinate", raw: a }
2191
+ },
2192
+ path.slice(1)
2193
+ ];
2194
+ }
2195
+ return [null, path];
2196
+ };
2197
+
2198
+ // src/data/navigate/landmark/createLandmarkUtils.ts
2199
+ import { center as center5 } from "@turf/center";
2200
+ import distance4 from "@turf/distance";
2201
+ var NEARBY_DISTANCE = 30;
2202
+ var createLandmarkUtils = (options) => {
2203
+ const { data, findByIdSync } = options;
2204
+ const { occupants = [] } = data;
2205
+ const occupantToLandmark = (occupant) => {
2206
+ const locationType = occupant.properties.unit_id ? "unit" : "kiosk";
2207
+ const locationId = locationType === "unit" ? occupant.properties.unit_id : occupant.properties.kiosk_id;
2208
+ const location = locationType === "unit" ? findByIdSync(locationId) : findByIdSync(locationId);
2209
+ const level = findByIdSync(location.properties.level_id);
2210
+ return {
2211
+ name: occupant.properties.name,
2212
+ point: center5(location.geometry).geometry.coordinates,
2213
+ level_id: location.properties.level_id,
2214
+ is_priority: occupant.properties.is_landmark,
2215
+ ordinal: level.properties.ordinal
2216
+ };
2217
+ };
2218
+ const landmarks = [
2219
+ ...occupants.map(occupantToLandmark)
2220
+ ];
2221
+ const findNearbyLandmarks = (point2, levelId) => {
2222
+ if (point2 === null || levelId === null) return [];
2223
+ return landmarks.map((landmark) => {
2224
+ const landmarkAndDistance = {
2225
+ landmark,
2226
+ d: distance4(point2, landmark.point, { units: "meters" })
2227
+ };
2228
+ return landmarkAndDistance;
2229
+ }).filter(({ landmark, d }) => d <= NEARBY_DISTANCE && landmark.level_id === levelId).sort((a, b) => {
2230
+ const aPriority = a.landmark.is_priority ? 0 : 1;
2231
+ const bPriority = b.landmark.is_priority ? 0 : 1;
2232
+ if (aPriority !== bPriority) return aPriority - bPriority;
2233
+ return a.d - b.d;
2234
+ }).map(({ landmark }) => landmark);
2235
+ };
2236
+ const findNearestLandmark = (point2, levelId) => {
2237
+ const nearbyLandmarks = findNearbyLandmarks(point2, levelId);
2238
+ const nearestLandmark = nearbyLandmarks.length > 0 ? nearbyLandmarks[0] : null;
2239
+ return nearestLandmark;
2240
+ };
2241
+ return { findNearbyLandmarks, findNearestLandmark };
2242
+ };
2243
+
2244
+ // src/data/navigate/waypoint/createWaypointUtils.ts
2245
+ var createWaypointUtils = (options) => {
2246
+ const { findByIdSync } = options;
2247
+ const landmarkUtils = createLandmarkUtils(options);
2248
+ const toWaypoints = (path) => {
2249
+ const [startPoint, middleAndEndPoints] = extractStartPoint(path, options);
2250
+ const [endPoint, middlePoints] = extractEndPoint(middleAndEndPoints, options);
2251
+ const waypoints = middlePoints.map((openingId) => {
2252
+ const opening = findByIdSync(openingId);
2253
+ const level = findByIdSync(opening.properties.level_id);
2254
+ const coordinates = center6(opening).geometry.coordinates;
2255
+ const landmark = landmarkUtils.findNearestLandmark(coordinates, opening.properties.level_id);
2256
+ return {
2257
+ id: `${opening.properties.level_id}:${openingId}`,
2258
+ type: "between",
2259
+ point: coordinates,
2260
+ name: null,
2261
+ levelId: opening.properties.level_id,
2262
+ ordinal: level.properties.ordinal,
2263
+ hint: landmark ? { kind: "landmark", name: landmark.name } : void 0,
2264
+ source: { type: "opening", id: opening.id }
2265
+ };
2266
+ });
2267
+ return [startPoint, ...waypoints, endPoint];
2268
+ };
2269
+ return { toWaypoints };
2270
+ };
2271
+
2267
2272
  // src/data/navigate/getNavigateClient.ts
2268
2273
  var getNavigateClient = (options) => {
2269
2274
  const { data } = options;
@@ -2285,6 +2290,7 @@ var getNavigateClient = (options) => {
2285
2290
  return unit;
2286
2291
  };
2287
2292
  const stepUtils = createStepUtils({ ...options, findByIdSync });
2293
+ const waypointUtils = createWaypointUtils({ ...options, findByIdSync });
2288
2294
  const findRoute = async (routeOriginParam, routeDestinationParam, options2) => {
2289
2295
  if (!routeOriginParam || !routeDestinationParam) return null;
2290
2296
  const graph = options2?.mode === "accessible" ? accessibleGraph : defaultGraph;
@@ -2302,8 +2308,7 @@ var getNavigateClient = (options) => {
2302
2308
  const path = graph.path(routeOriginParam, routeDestinationParam);
2303
2309
  const t12 = performance.now();
2304
2310
  trace("nav", " \u251C\u2500 path (dijkstra)", t12 - t02);
2305
- const waypoints = stepUtils.toWaypoints(path);
2306
- console.log({ waypoints });
2311
+ const waypoints = waypointUtils.toWaypoints(path);
2307
2312
  const t22 = performance.now();
2308
2313
  trace("nav", " \u251C\u2500 toWaypoints", t22 - t12);
2309
2314
  trace("nav", " \u251C\u2500 toSteps", 0);
@@ -2315,9 +2320,6 @@ var getNavigateClient = (options) => {
2315
2320
  const t4 = performance.now();
2316
2321
  trace("nav", " \u2514\u2500 postProcess", t4 - t32);
2317
2322
  return {
2318
- // origin: routeOrigin,
2319
- // destination: routeDestination,
2320
- description: null,
2321
2323
  distance: roundedDistance,
2322
2324
  duration,
2323
2325
  steps
@@ -2505,6 +2507,7 @@ export {
2505
2507
  fetchDeliveryApi,
2506
2508
  fetchPreviewApi,
2507
2509
  getDataClient,
2510
+ getNavigateClient,
2508
2511
  getSearchClient,
2509
2512
  isValidCoordinate,
2510
2513
  isValidLineString,