gps-plus-slam-app-framework 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +222 -0
  3. package/dist/alignment-lerper-D9BeDwZX.d.ts +29 -0
  4. package/dist/app-selectors-DyMzxCEC.d.ts +140 -0
  5. package/dist/ar/camera-blit-capture.d.ts +2 -0
  6. package/dist/ar/camera-blit-capture.js +253 -0
  7. package/dist/ar/capture-failure-tracker.d.ts +2 -0
  8. package/dist/ar/capture-failure-tracker.js +45 -0
  9. package/dist/ar/chromium-camera-access-workaround.d.ts +2 -0
  10. package/dist/ar/chromium-camera-access-workaround.js +32 -0
  11. package/dist/ar/depth-sampler.d.ts +3 -0
  12. package/dist/ar/depth-sampler.js +147 -0
  13. package/dist/ar/image-capture.d.ts +2 -0
  14. package/dist/ar/image-capture.js +152 -0
  15. package/dist/ar/index.d.ts +12 -0
  16. package/dist/ar/index.js +12 -0
  17. package/dist/ar/replay-scene.d.ts +2 -0
  18. package/dist/ar/replay-scene.js +325 -0
  19. package/dist/ar/scene-node-names.d.ts +2 -0
  20. package/dist/ar/scene-node-names.js +16 -0
  21. package/dist/ar/tracking-state.d.ts +2 -0
  22. package/dist/ar/tracking-state.js +164 -0
  23. package/dist/ar/webxr-session.d.ts +4 -0
  24. package/dist/ar/webxr-session.js +890 -0
  25. package/dist/ar/xr-camera-texture.d.ts +2 -0
  26. package/dist/ar/xr-camera-texture.js +39 -0
  27. package/dist/ar/xr-error-handler.d.ts +2 -0
  28. package/dist/ar/xr-error-handler.js +37 -0
  29. package/dist/ar-types-B-ORgk6Z.d.ts +82 -0
  30. package/dist/camera-blit-capture-DHuyrrxr.d.ts +108 -0
  31. package/dist/camera-follower-BMqPddxx.d.ts +29 -0
  32. package/dist/capture-failure-tracker-2Q6oI2uQ.d.ts +52 -0
  33. package/dist/chromium-camera-access-workaround-CU5zSKNr.d.ts +61 -0
  34. package/dist/community-license-key-ChZLCJyO.d.ts +21 -0
  35. package/dist/concurrency-p6gB30fT.d.ts +24 -0
  36. package/dist/css3d-renderer-manager-rgLMVAvd.d.ts +23 -0
  37. package/dist/depth-sampler-BNCtnEoP.d.ts +108 -0
  38. package/dist/failure-tracker-1sQ_Cgyw.d.ts +49 -0
  39. package/dist/file-system-BsQgYCU3.d.ts +128 -0
  40. package/dist/file-system-utils-5cWO8Xyv.d.ts +24 -0
  41. package/dist/format-file-size-onGq0k1Q.d.ts +24 -0
  42. package/dist/fused-path-DtqCSqJh.d.ts +25 -0
  43. package/dist/geo-types-Xx-LVcnw.d.ts +29 -0
  44. package/dist/gps-Ddzr2KlX.d.ts +54 -0
  45. package/dist/gps-compass-cubes-C-6JEnpR.d.ts +22 -0
  46. package/dist/gps-error-handler-VPuNOuf8.d.ts +40 -0
  47. package/dist/gps-event-markers-DpEy2qRd.d.ts +67 -0
  48. package/dist/h3-ref-point-CFhayNSZ.d.ts +59 -0
  49. package/dist/image-capture-2pKjYUS6.d.ts +130 -0
  50. package/dist/index.d.ts +56 -0
  51. package/dist/index.js +61 -0
  52. package/dist/leaflet-map-overlay-CvfQXTye.d.ts +114 -0
  53. package/dist/lerp-utils-87NWjUOD.d.ts +20 -0
  54. package/dist/licensing/community-license-key.d.ts +2 -0
  55. package/dist/licensing/community-license-key.js +21 -0
  56. package/dist/licensing/index.d.ts +2 -0
  57. package/dist/licensing/index.js +2 -0
  58. package/dist/list-formatter-DKQQVLcl.d.ts +14 -0
  59. package/dist/logger-B81iwxx0.d.ts +74 -0
  60. package/dist/map-overlay-DuiZuCTx.d.ts +153 -0
  61. package/dist/null-storage-backend-CsWvQwN8.d.ts +11 -0
  62. package/dist/opfs-storage-ChOzF_Wp.d.ts +181 -0
  63. package/dist/opfs-storage-backend-CVcmfJHN.d.ts +11 -0
  64. package/dist/permission-checker-jO2ziCWC.d.ts +146 -0
  65. package/dist/persistence-middleware-DrptY02i.d.ts +31 -0
  66. package/dist/recorder-slice-fcwAXrsh.d.ts +35 -0
  67. package/dist/recording-coordinator-DzflP07_.d.ts +81 -0
  68. package/dist/recording-options-BYUFX8iU.d.ts +166 -0
  69. package/dist/recording-replayer-oOzPITrd.d.ts +32 -0
  70. package/dist/ref-point-importer-B_wn5ABk.d.ts +62 -0
  71. package/dist/ref-point-loader-Pt1smgHS.d.ts +117 -0
  72. package/dist/ref-points/h3-ref-point.d.ts +2 -0
  73. package/dist/ref-points/h3-ref-point.js +74 -0
  74. package/dist/ref-points/index.d.ts +2 -0
  75. package/dist/ref-points/index.js +2 -0
  76. package/dist/ref-points-slice-tC-Wd6XJ.d.ts +48 -0
  77. package/dist/reference-points-CFWy8_wj.d.ts +68 -0
  78. package/dist/replay-engine-DuX316ae.d.ts +103 -0
  79. package/dist/replay-scene-DtUm6bsr.d.ts +109 -0
  80. package/dist/routing-slice-BlHTM8eh.d.ts +23 -0
  81. package/dist/scene-node-names-DPsaE2z3.d.ts +14 -0
  82. package/dist/sensors/gps-error-handler.d.ts +2 -0
  83. package/dist/sensors/gps-error-handler.js +53 -0
  84. package/dist/sensors/gps.d.ts +2 -0
  85. package/dist/sensors/gps.js +93 -0
  86. package/dist/sensors/index.d.ts +4 -0
  87. package/dist/sensors/index.js +4 -0
  88. package/dist/sensors/permission-checker.d.ts +2 -0
  89. package/dist/sensors/permission-checker.js +397 -0
  90. package/dist/state/app-selectors.d.ts +2 -0
  91. package/dist/state/app-selectors.js +35 -0
  92. package/dist/state/index.d.ts +17 -0
  93. package/dist/state/index.js +13 -0
  94. package/dist/state/persistence-middleware.d.ts +2 -0
  95. package/dist/state/persistence-middleware.js +71 -0
  96. package/dist/state/recorder-slice.d.ts +2 -0
  97. package/dist/state/recorder-slice.js +47 -0
  98. package/dist/state/recording-coordinator.d.ts +2 -0
  99. package/dist/state/recording-coordinator.js +150 -0
  100. package/dist/state/recording-options.d.ts +2 -0
  101. package/dist/state/recording-options.js +192 -0
  102. package/dist/state/recording-replayer.d.ts +2 -0
  103. package/dist/state/recording-replayer.js +39 -0
  104. package/dist/state/ref-points-slice.d.ts +2 -0
  105. package/dist/state/ref-points-slice.js +44 -0
  106. package/dist/state/replay-engine.d.ts +2 -0
  107. package/dist/state/replay-engine.js +230 -0
  108. package/dist/state/routing-slice.d.ts +2 -0
  109. package/dist/state/routing-slice.js +13 -0
  110. package/dist/state/store-subscribers.d.ts +3 -0
  111. package/dist/state/store-subscribers.js +97 -0
  112. package/dist/state/store.d.ts +9 -0
  113. package/dist/state/store.js +71 -0
  114. package/dist/state/subscribe-to-selector.d.ts +2 -0
  115. package/dist/state/subscribe-to-selector.js +26 -0
  116. package/dist/storage/file-system-utils.d.ts +2 -0
  117. package/dist/storage/file-system-utils.js +31 -0
  118. package/dist/storage/file-system.d.ts +2 -0
  119. package/dist/storage/file-system.js +229 -0
  120. package/dist/storage/index.d.ts +11 -0
  121. package/dist/storage/index.js +10 -0
  122. package/dist/storage/null-storage-backend.d.ts +2 -0
  123. package/dist/storage/null-storage-backend.js +8 -0
  124. package/dist/storage/opfs-storage-backend.d.ts +2 -0
  125. package/dist/storage/opfs-storage-backend.js +15 -0
  126. package/dist/storage/opfs-storage.d.ts +2 -0
  127. package/dist/storage/opfs-storage.js +242 -0
  128. package/dist/storage/ref-point-importer.d.ts +2 -0
  129. package/dist/storage/ref-point-importer.js +163 -0
  130. package/dist/storage/ref-point-loader.d.ts +2 -0
  131. package/dist/storage/ref-point-loader.js +248 -0
  132. package/dist/storage/ref-point-recovery.d.ts +28 -0
  133. package/dist/storage/ref-point-recovery.js +159 -0
  134. package/dist/storage/storage-backend.d.ts +2 -0
  135. package/dist/storage/storage-backend.js +1 -0
  136. package/dist/storage/zip-export.d.ts +2 -0
  137. package/dist/storage/zip-export.js +214 -0
  138. package/dist/storage/zip-reader.d.ts +2 -0
  139. package/dist/storage/zip-reader.js +190 -0
  140. package/dist/storage-backend-BcEItnFr.d.ts +20 -0
  141. package/dist/store-C7PKOj8S.d.ts +96 -0
  142. package/dist/store-subscribers-CuoIzB5T.d.ts +77 -0
  143. package/dist/subscribe-to-selector-UTZ0KkAc.d.ts +26 -0
  144. package/dist/test-utils/browser-mocks.d.ts +294 -0
  145. package/dist/test-utils/browser-mocks.js +568 -0
  146. package/dist/test-utils/zip-round-trip-helpers.d.ts +60 -0
  147. package/dist/test-utils/zip-round-trip-helpers.js +207 -0
  148. package/dist/three-dispose-CCBHjE_a.d.ts +30 -0
  149. package/dist/tracking-state-B9QfuZCg.d.ts +101 -0
  150. package/dist/types/ar-types.d.ts +2 -0
  151. package/dist/types/ar-types.js +1 -0
  152. package/dist/types/geo-types.d.ts +2 -0
  153. package/dist/types/geo-types.js +1 -0
  154. package/dist/types/index.d.ts +3 -0
  155. package/dist/types/index.js +1 -0
  156. package/dist/utils/concurrency.d.ts +2 -0
  157. package/dist/utils/concurrency.js +40 -0
  158. package/dist/utils/failure-tracker.d.ts +2 -0
  159. package/dist/utils/failure-tracker.js +48 -0
  160. package/dist/utils/format-file-size.d.ts +2 -0
  161. package/dist/utils/format-file-size.js +41 -0
  162. package/dist/utils/fused-path.d.ts +2 -0
  163. package/dist/utils/fused-path.js +44 -0
  164. package/dist/utils/index.d.ts +7 -0
  165. package/dist/utils/index.js +7 -0
  166. package/dist/utils/list-formatter.d.ts +2 -0
  167. package/dist/utils/list-formatter.js +17 -0
  168. package/dist/utils/logger.d.ts +2 -0
  169. package/dist/utils/logger.js +226 -0
  170. package/dist/vis-colors-Qi2vlRGt.d.ts +63 -0
  171. package/dist/visualization/alignment-lerper.d.ts +2 -0
  172. package/dist/visualization/alignment-lerper.js +68 -0
  173. package/dist/visualization/camera-follower.d.ts +2 -0
  174. package/dist/visualization/camera-follower.js +51 -0
  175. package/dist/visualization/css3d-renderer-manager.d.ts +2 -0
  176. package/dist/visualization/css3d-renderer-manager.js +41 -0
  177. package/dist/visualization/gps-compass-cubes.d.ts +2 -0
  178. package/dist/visualization/gps-compass-cubes.js +129 -0
  179. package/dist/visualization/gps-event-markers.d.ts +2 -0
  180. package/dist/visualization/gps-event-markers.js +159 -0
  181. package/dist/visualization/index.d.ts +12 -0
  182. package/dist/visualization/index.js +12 -0
  183. package/dist/visualization/leaflet-map-overlay.d.ts +2 -0
  184. package/dist/visualization/leaflet-map-overlay.js +313 -0
  185. package/dist/visualization/lerp-utils.d.ts +2 -0
  186. package/dist/visualization/lerp-utils.js +22 -0
  187. package/dist/visualization/map-overlay.d.ts +2 -0
  188. package/dist/visualization/map-overlay.js +241 -0
  189. package/dist/visualization/reference-points.d.ts +2 -0
  190. package/dist/visualization/reference-points.js +160 -0
  191. package/dist/visualization/three-dispose.d.ts +2 -0
  192. package/dist/visualization/three-dispose.js +55 -0
  193. package/dist/visualization/vis-colors.d.ts +2 -0
  194. package/dist/visualization/vis-colors.js +74 -0
  195. package/dist/webxr-session-COlSrXdL.d.ts +316 -0
  196. package/dist/xr-camera-texture-BbukNE79.d.ts +53 -0
  197. package/dist/xr-error-handler-DTHfmvrl.d.ts +24 -0
  198. package/dist/zip-export-Rtpi75JJ.d.ts +87 -0
  199. package/dist/zip-reader-D7pkpX8K.d.ts +97 -0
  200. package/package.json +104 -0
@@ -0,0 +1,62 @@
1
+ //#region ../src/storage/ref-point-importer.d.ts
2
+ /**
3
+ * Reference Point Importer Module
4
+ *
5
+ * Extracts reference points from ZIP files in a folder, enabling reuse of
6
+ * ref points from previous recording sessions.
7
+ *
8
+ * This module:
9
+ * 1. Enumerates all *.zip files in a folder
10
+ * 2. Opens each ZIP and looks for refPoints/*.json files
11
+ * 3. Parses and validates each ref point definition
12
+ * 4. Merges and deduplicates ref points by ID
13
+ *
14
+ * Uses @zip.js/zip.js for ZIP reading (same library as zip-export.ts).
15
+ */
16
+ /**
17
+ * Simplified reference point for import/suggestion purposes.
18
+ * Contains only the essential data needed for ref point suggestions and display.
19
+ * The `lat`/`lon` are kept for "nearby ref point" proximity suggestions.
20
+ */
21
+ interface ImportedRefPoint {
22
+ /** Unique identifier — H3 hex index since the March 2026 H3 migration */
23
+ readonly id: string;
24
+ /** Human-readable display name entered by the user (e.g., "Bench Corner") */
25
+ readonly name: string;
26
+ /** Latitude from first observation (for future proximity-based suggestions) */
27
+ readonly lat: number;
28
+ /** Longitude from first observation */
29
+ readonly lon: number;
30
+ /** Optional altitude */
31
+ readonly alt?: number;
32
+ /** Source ZIP file name for debugging/tracking */
33
+ readonly sourceZipName: string;
34
+ }
35
+ /**
36
+ * Result from importing reference points from a folder.
37
+ */
38
+ interface RefPointImportResult {
39
+ /** Whether the import completed (even with some errors) */
40
+ readonly success: boolean;
41
+ /** Merged, deduplicated reference points from all ZIPs */
42
+ readonly refPoints: ImportedRefPoint[];
43
+ /** Number of ZIP files successfully scanned */
44
+ readonly zipFilesScanned: number;
45
+ /** Error messages from failed ZIPs or malformed ref points */
46
+ readonly errors: string[];
47
+ }
48
+ /**
49
+ * Import reference points from all ZIP files in a folder.
50
+ *
51
+ * Enumerates all *.zip files in the folder, extracts refPoints/*.json from each,
52
+ * and merges them into a deduplicated list.
53
+ *
54
+ * Deduplication: If the same ref point ID appears in multiple ZIPs, the first
55
+ * occurrence is kept (based on iteration order).
56
+ *
57
+ * @param folderHandle - Read-only directory handle from showDirectoryPicker
58
+ * @returns Result containing merged ref points, scan count, and errors
59
+ */
60
+ declare function importRefPointsFromFolder(folderHandle: FileSystemDirectoryHandle): Promise<RefPointImportResult>;
61
+ //#endregion
62
+ export { RefPointImportResult as n, importRefPointsFromFolder as r, ImportedRefPoint as t };
@@ -0,0 +1,117 @@
1
+ import { n as ArPoseTuples } from "./ar-types-B-ORgk6Z.js";
2
+ import { GpsPoint, LatLongAlt, Quaternion, Vector3 } from "gps-plus-slam-js";
3
+
4
+ //#region ../src/storage/ref-point-loader.d.ts
5
+ /**
6
+ * A single observation of a reference point in one session.
7
+ */
8
+ interface RefPointObservation {
9
+ /** Session ID (e.g., "recording-2025-02-28_14-30-11utc") */
10
+ readonly sessionId: string;
11
+ /** When this observation was made */
12
+ readonly timestamp: number;
13
+ /** AR pose at the moment of marking */
14
+ readonly arPose: ArPoseTuples;
15
+ /** Full GPS point from library (includes lat/lon, accuracy, etc.) */
16
+ readonly gpsPoint: GpsPoint;
17
+ /** Fused GPS from aligned VIO path at mark time (absent in legacy data) */
18
+ readonly fusedGpsPoint?: {
19
+ latitude: number;
20
+ longitude: number;
21
+ altitude?: number;
22
+ };
23
+ }
24
+ /**
25
+ * Complete definition of a reference point with all observations.
26
+ */
27
+ interface RefPointDefinition {
28
+ /** Unique identifier (e.g., "pointA", "benchCorner") */
29
+ id: string;
30
+ /** Human-readable name */
31
+ name: string;
32
+ /** Timestamp of first observation */
33
+ createdAt: number;
34
+ /** All observations across sessions */
35
+ observations: RefPointObservation[];
36
+ }
37
+ /**
38
+ * Load all reference point definitions from the scenario's refPoints/ directory.
39
+ *
40
+ * @param scenarioHandle - File system handle for the scenario folder
41
+ * @returns Array of all reference point definitions
42
+ */
43
+ declare function loadAllRefPoints(scenarioHandle: FileSystemDirectoryHandle): Promise<RefPointDefinition[]>;
44
+ /**
45
+ * Load a specific reference point by ID.
46
+ *
47
+ * @param scenarioHandle - File system handle for the scenario folder
48
+ * @param pointId - Reference point ID
49
+ * @returns Reference point definition or null if not found
50
+ */
51
+ declare function loadRefPoint(scenarioHandle: FileSystemDirectoryHandle, pointId: string): Promise<RefPointDefinition | null>;
52
+ /**
53
+ * Save or update a reference point observation.
54
+ * Creates the refPoints/ directory if it doesn't exist.
55
+ * If the reference point exists, appends the new observation.
56
+ * If it doesn't exist, creates a new reference point file.
57
+ *
58
+ * @param scenarioHandle - File system handle for the scenario folder
59
+ * @param pointId - Reference point ID
60
+ * @param pointName - Human-readable name for the reference point
61
+ * @param observation - New observation to add
62
+ */
63
+ declare function saveRefPointObservation(scenarioHandle: FileSystemDirectoryHandle, pointId: string, pointName: string, observation: RefPointObservation): Promise<void>;
64
+ /**
65
+ * Write a complete RefPointDefinition to OPFS.
66
+ * Creates the refPoints/ directory if it doesn't exist.
67
+ * Used by the recovery flow to restore definitions extracted from ZIPs.
68
+ *
69
+ * @param scenarioHandle - File system handle for the scenario folder
70
+ * @param definition - Complete ref point definition to write
71
+ */
72
+ declare function writeRefPointDefinition(scenarioHandle: FileSystemDirectoryHandle, definition: RefPointDefinition): Promise<void>;
73
+ /**
74
+ * Get list of all reference point IDs in the scenario.
75
+ * Useful for autocomplete/suggestions.
76
+ *
77
+ * @param scenarioHandle - File system handle for the scenario folder
78
+ * @returns Array of reference point IDs
79
+ */
80
+ declare function listRefPointIds(scenarioHandle: FileSystemDirectoryHandle): Promise<string[]>;
81
+ /**
82
+ * Marker type representing a single observation suitable for visualization.
83
+ * Position/rotation use odometry frame; gpsPosition provides world coordinates.
84
+ */
85
+ interface RefPointMark {
86
+ id: string;
87
+ /** Odometry position at the moment of marking */
88
+ odomPosition: Vector3;
89
+ /** Odometry rotation at the moment of marking */
90
+ odomRotation: Quaternion;
91
+ /** GPS position if available */
92
+ gpsPosition?: LatLongAlt;
93
+ timestamp: number;
94
+ }
95
+ /**
96
+ * Flatten an array of RefPointDefinition objects into individual RefPointMark
97
+ * observations suitable for visualization.
98
+ *
99
+ * @param refPointDefs - Array of reference point definitions with observations
100
+ * @returns Flat array of individual marks (one per observation)
101
+ */
102
+ declare function flattenRefPointsToMarks(refPointDefs: RefPointDefinition[]): RefPointMark[];
103
+ /**
104
+ * Compute one averaged GPS position per reference point ID.
105
+ * For each observation, prefers `fusedGpsPoint` (sub-meter accuracy) when
106
+ * available, falling back to raw `gpsPoint`. Returns the centroid (mean
107
+ * lat/lon) across all observations.
108
+ */
109
+ declare function averageGpsPerRefPoint(refPointDefs: RefPointDefinition[]): Array<{
110
+ id: string;
111
+ name: string;
112
+ lat: number;
113
+ lon: number;
114
+ alt?: number;
115
+ }>;
116
+ //#endregion
117
+ export { flattenRefPointsToMarks as a, loadRefPoint as c, averageGpsPerRefPoint as i, saveRefPointObservation as l, RefPointMark as n, listRefPointIds as o, RefPointObservation as r, loadAllRefPoints as s, RefPointDefinition as t, writeRefPointDefinition as u };
@@ -0,0 +1,2 @@
1
+ import { a as gpsToH3, i as findNearbyRefPoint, n as KnownRefPoint, o as h3RefsMatch, r as approxDistanceMetres, s as isH3Index, t as H3_RESOLUTION } from "../h3-ref-point-CFhayNSZ.js";
2
+ export { H3_RESOLUTION, KnownRefPoint, approxDistanceMetres, findNearbyRefPoint, gpsToH3, h3RefsMatch, isH3Index };
@@ -0,0 +1,74 @@
1
+ import { gridDisk, latLngToCell } from "h3-js";
2
+ //#region ../src/ref-points/h3-ref-point.ts
3
+ /**
4
+ * H3 Reference Point Matching
5
+ *
6
+ * Utility for matching GPS positions to known reference points using
7
+ * H3 hexagonal grid indices. Uses gridDisk(cell, 1) to create a ~65m
8
+ * safe zone that absorbs GPS jitter of 3-10m.
9
+ *
10
+ * @see docs/2026-03-08-ref-point-naming-investigation.md §6
11
+ */
12
+ /** H3 resolution 11: ~25m edge, ~65m gridDisk safe zone */
13
+ const H3_RESOLUTION = 11;
14
+ /**
15
+ * Compute the H3 resolution-11 index for a GPS position.
16
+ */
17
+ function gpsToH3(lat, lng) {
18
+ return latLngToCell(lat, lng, 11);
19
+ }
20
+ /**
21
+ * Approximate distance in metres using equirectangular projection.
22
+ * Accurate to < 0.1% for distances under 1 km at mid-latitudes,
23
+ * which is sufficient for ranking ref point candidates within a
24
+ * gridDisk safe zone (~65–130 m).
25
+ */
26
+ function approxDistanceMetres(lat1, lon1, lat2, lon2) {
27
+ const R = 6371e3;
28
+ const dLat = (lat2 - lat1) * Math.PI / 180;
29
+ let dLonDeg = lon2 - lon1;
30
+ dLonDeg -= 360 * Math.floor((dLonDeg + 180) / 360);
31
+ const x = dLonDeg * Math.PI / 180 * Math.cos((lat1 + lat2) / 2 * Math.PI / 180);
32
+ return R * Math.sqrt(dLat * dLat + x * x);
33
+ }
34
+ /**
35
+ * Find the known reference point closest to the given GPS position,
36
+ * provided it falls within the gridDisk safe zone.
37
+ *
38
+ * The safe zone is the center cell plus its 6 neighbors (~65m radius),
39
+ * which absorbs GPS jitter of 3-10m while keeping ref points >130m apart
40
+ * distinguishable.
41
+ *
42
+ * When multiple ref points have overlapping safe zones (65–130 m apart),
43
+ * the closest one by equirectangular distance is returned.
44
+ */
45
+ function findNearbyRefPoint(lat, lng, knownRefPoints) {
46
+ if (knownRefPoints.length === 0) return;
47
+ const safeZone = gridDisk(latLngToCell(lat, lng, 11), 1);
48
+ const candidates = knownRefPoints.filter((rp) => safeZone.includes(rp.h3Index));
49
+ if (candidates.length === 0) return void 0;
50
+ if (candidates.length === 1) return candidates[0];
51
+ return candidates.reduce((closest, rp) => {
52
+ return approxDistanceMetres(lat, lng, rp.lat, rp.lon) < approxDistanceMetres(lat, lng, closest.lat, closest.lon) ? rp : closest;
53
+ });
54
+ }
55
+ /**
56
+ * Check whether two H3 indices refer to the same physical location
57
+ * (i.e., one falls within the other's gridDisk safe zone).
58
+ * This is the canonical cross-session matching check.
59
+ */
60
+ function h3RefsMatch(h3a, h3b) {
61
+ if (h3a === h3b) return true;
62
+ return gridDisk(h3a, 1).includes(h3b);
63
+ }
64
+ /** H3 resolution-11 indices are 15-character lowercase hex strings. */
65
+ const H3_INDEX_PATTERN = /^[0-9a-f]{15}$/;
66
+ /**
67
+ * Check whether a string looks like a valid H3 resolution-11 index.
68
+ * Used to distinguish H3 IDs from legacy user-typed string IDs.
69
+ */
70
+ function isH3Index(id) {
71
+ return H3_INDEX_PATTERN.test(id);
72
+ }
73
+ //#endregion
74
+ export { H3_RESOLUTION, approxDistanceMetres, findNearbyRefPoint, gpsToH3, h3RefsMatch, isH3Index };
@@ -0,0 +1,2 @@
1
+ import { a as gpsToH3, i as findNearbyRefPoint, n as KnownRefPoint, o as h3RefsMatch, r as approxDistanceMetres, s as isH3Index, t as H3_RESOLUTION } from "../h3-ref-point-CFhayNSZ.js";
2
+ export { H3_RESOLUTION, type KnownRefPoint, approxDistanceMetres, findNearbyRefPoint, gpsToH3, h3RefsMatch, isH3Index };
@@ -0,0 +1,2 @@
1
+ import { H3_RESOLUTION, approxDistanceMetres, findNearbyRefPoint, gpsToH3, h3RefsMatch, isH3Index } from "./h3-ref-point.js";
2
+ export { H3_RESOLUTION, approxDistanceMetres, findNearbyRefPoint, gpsToH3, h3RefsMatch, isH3Index };
@@ -0,0 +1,48 @@
1
+ import { n as KnownRefPoint } from "./h3-ref-point-CFhayNSZ.js";
2
+ import { t as ImportedRefPoint } from "./ref-point-importer-B_wn5ABk.js";
3
+ import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
4
+
5
+ //#region ../src/state/ref-points-slice.d.ts
6
+ interface RefPointsState {
7
+ /** Prior ref points loaded from previous session ZIPs. */
8
+ importedRefPoints: ImportedRefPoint[];
9
+ /**
10
+ * Tracks how many times each ref point was marked in the current session.
11
+ * Keyed by ref-point ID (H3 index). Plain object for Redux serializability
12
+ * (replaces the Map<string, number> that lived in the closure).
13
+ */
14
+ sessionRefPointUsage: Record<string, number>;
15
+ }
16
+ declare const setImportedRefPoints: _$_reduxjs_toolkit0.ActionCreatorWithPayload<ImportedRefPoint[], "refPoints/setImportedRefPoints">, incrementRefPointUsage: _$_reduxjs_toolkit0.ActionCreatorWithPayload<string, "refPoints/incrementRefPointUsage">, clearSessionRefPointUsage: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"refPoints/clearSessionRefPointUsage">, resetRefPointsState: _$_reduxjs_toolkit0.ActionCreatorWithoutPayload<"refPoints/resetRefPointsState">;
17
+ declare const refPointsReducer: _$_reduxjs_toolkit0.Reducer<RefPointsState>;
18
+ /**
19
+ * Memoized selector that derives KnownRefPoint[] (with H3 indices) from
20
+ * importedRefPoints. Replaces the closure-based `recomputeKnownRefPoints()`
21
+ * in ref-point-handlers.ts.
22
+ *
23
+ * Uses createSelector (reselect) for standard RTK memoization — recomputes
24
+ * only when the importedRefPoints array reference changes.
25
+ */
26
+ declare const selectCachedKnownRefPoints: ((state: RefPointsState) => KnownRefPoint[]) & {
27
+ clearCache: () => void;
28
+ resultsCount: () => number;
29
+ resetResultsCount: () => void;
30
+ } & {
31
+ resultFunc: (resultFuncArgs_0: ImportedRefPoint[]) => KnownRefPoint[];
32
+ memoizedResultFunc: ((resultFuncArgs_0: ImportedRefPoint[]) => KnownRefPoint[]) & {
33
+ clearCache: () => void;
34
+ resultsCount: () => number;
35
+ resetResultsCount: () => void;
36
+ };
37
+ lastResult: () => KnownRefPoint[];
38
+ dependencies: [(state: RefPointsState) => ImportedRefPoint[]];
39
+ recomputations: () => number;
40
+ resetRecomputations: () => void;
41
+ dependencyRecomputations: () => number;
42
+ resetDependencyRecomputations: () => void;
43
+ } & {
44
+ memoize: typeof _$_reduxjs_toolkit0.weakMapMemoize;
45
+ argsMemoize: typeof _$_reduxjs_toolkit0.weakMapMemoize;
46
+ };
47
+ //#endregion
48
+ export { resetRefPointsState as a, refPointsReducer as i, clearSessionRefPointUsage as n, selectCachedKnownRefPoints as o, incrementRefPointUsage as r, setImportedRefPoints as s, RefPointsState as t };
@@ -0,0 +1,68 @@
1
+ import { n as RefPointMark } from "./ref-point-loader-Pt1smgHS.js";
2
+ import { LatLong } from "gps-plus-slam-js";
3
+
4
+ //#region ../src/visualization/reference-points.d.ts
5
+ /**
6
+ * Manager for reference point visualization
7
+ */
8
+ declare class RefPointVisualizer {
9
+ private priorRefMeshes;
10
+ private currentRefMeshes;
11
+ private zeroRef;
12
+ /** Shared geometry for prior-session ref point meshes (lazy-created) */
13
+ private priorRefGeometry;
14
+ /** Shared material for prior-session ref point meshes (lazy-created) */
15
+ private priorRefMaterial;
16
+ /** Shared geometry for current-session ref point meshes (lazy-created) */
17
+ private currentRefGeometry;
18
+ /**
19
+ * Set the GPS zero reference (origin for coordinate conversion).
20
+ * Must be called before displaying reference points.
21
+ *
22
+ * @param zero - GPS coordinates of the origin
23
+ */
24
+ setZeroRef(zero: LatLong): void;
25
+ /**
26
+ * Get the current zero reference
27
+ */
28
+ getZeroRef(): LatLong | null;
29
+ /**
30
+ * Display reference points from prior sessions.
31
+ * Clears any existing prior ref points first.
32
+ *
33
+ * @param refPoints - Array of reference point marks to visualize
34
+ */
35
+ displayPriorRefPoints(refPoints: RefPointMark[]): void;
36
+ /**
37
+ * Add a reference point from the current session.
38
+ *
39
+ * @param refPoint - Reference point mark to visualize
40
+ */
41
+ addCurrentRefPoint(refPoint: RefPointMark): void;
42
+ /**
43
+ * Clear all prior reference point meshes from the scene.
44
+ */
45
+ clearPriorRefPoints(): void;
46
+ /**
47
+ * Clear current session reference point meshes from the scene.
48
+ */
49
+ clearCurrentRefPoints(): void;
50
+ /**
51
+ * Clear all visualizations and reset state.
52
+ */
53
+ clearAll(): void;
54
+ /**
55
+ * Get count of visible reference points.
56
+ */
57
+ getCounts(): {
58
+ prior: number;
59
+ current: number;
60
+ };
61
+ }
62
+ /**
63
+ * Singleton instance for global use.
64
+ * Import this to visualize reference points.
65
+ */
66
+ declare const refPointVisualizer: RefPointVisualizer;
67
+ //#endregion
68
+ export { refPointVisualizer as n, RefPointVisualizer as t };
@@ -0,0 +1,103 @@
1
+ import { l as RecorderStore } from "./store-C7PKOj8S.js";
2
+
3
+ //#region ../src/state/replay-engine.d.ts
4
+ /** Default maximum delay between actions in ms (30 seconds real-time) */
5
+ declare const DEFAULT_MAX_DELAY_MS = 30000;
6
+ type ReplayState = 'idle' | 'playing' | 'paused' | 'completed';
7
+ type ProgressCallback = (current: number, total: number) => void;
8
+ type CompleteCallback = () => void;
9
+ type ErrorCallback = (actionIndex: number, error: Error) => void;
10
+ /** Minimal action shape for replay — just needs type and optional payload */
11
+ interface ReplayAction {
12
+ type: string;
13
+ payload?: unknown;
14
+ }
15
+ /**
16
+ * Extract an absolute epoch-ms timestamp from a Redux action, or null
17
+ * if the action type doesn't carry one.
18
+ *
19
+ * IMPORTANT: depthSample uses performance.now() (relative to page load),
20
+ * NOT epoch ms. Returning it here would mix clock domains and produce
21
+ * garbage delays. It must return null. (Risk R4)
22
+ *
23
+ * @param action - A Redux action with type and optional payload
24
+ * @returns Epoch milliseconds, or null if unavailable/unreliable
25
+ */
26
+ declare function extractActionTimestamp(action: ReplayAction): number | null;
27
+ /**
28
+ * Compute the delay in ms between two consecutive actions for replay.
29
+ *
30
+ * @param currentTs - Epoch ms of the current (just-dispatched) action, or null
31
+ * @param nextTs - Epoch ms of the next action, or null
32
+ * @param speedFactor - Playback speed multiplier (1 = real-time)
33
+ * @param maxDelay - Maximum delay in ms (default: DEFAULT_MAX_DELAY_MS)
34
+ * @returns Delay in ms, clamped to [0, maxDelay]
35
+ */
36
+ declare function computeInterActionDelay(currentTs: number | null, nextTs: number | null, speedFactor: number, maxDelay?: number): number;
37
+ /**
38
+ * Async controller that dispatches recorded actions with timed delays.
39
+ *
40
+ * Uses AbortController for pause/cancel:
41
+ * - play() starts the async loop
42
+ * - pause() aborts the current controller → loop exits
43
+ * - resume() creates a new controller and restarts from current index
44
+ * - setSpeed() updates a closure variable, picked up on next delay calc
45
+ * - dispose() stops everything and resets state
46
+ */
47
+ declare class ReplayEngine {
48
+ private state;
49
+ private currentIndex;
50
+ private actions;
51
+ private store;
52
+ private speedFactor;
53
+ private abortController;
54
+ private progressCallbacks;
55
+ private completeCallbacks;
56
+ private errorCallbacks;
57
+ private currentPlayPromise;
58
+ /** Get the current engine state */
59
+ getState(): ReplayState;
60
+ /** Get the current action index (1-based after dispatch, 0 before play) */
61
+ getCurrentActionIndex(): number;
62
+ /** Register a progress callback: (currentIndex, totalCount) */
63
+ onProgress(callback: ProgressCallback): void;
64
+ /** Register a completion callback */
65
+ onComplete(callback: CompleteCallback): void;
66
+ /**
67
+ * Register an error callback: (actionIndex, error).
68
+ * Called when a dispatch throws. Replay continues past the error.
69
+ * After MAX_CONSECUTIVE_ERRORS consecutive failures, engine auto-pauses (R7).
70
+ */
71
+ onError(callback: ErrorCallback): void;
72
+ /** Update playback speed (takes effect on next delay calculation) */
73
+ setSpeed(factor: number): void;
74
+ /**
75
+ * Start replaying actions with timed delays.
76
+ *
77
+ * @param actions - Array of Redux actions to dispatch
78
+ * @param store - RecorderStore to dispatch into
79
+ * @param speedFactor - Initial playback speed (1 = real-time)
80
+ * @returns Promise that resolves when replay completes or is paused
81
+ */
82
+ play(actions: ReplayAction[], store: RecorderStore, speedFactor: number): Promise<void>;
83
+ /** Pause the replay. Can be resumed later with resume(). */
84
+ pause(): void;
85
+ /**
86
+ * Resume from the current action index after a pause.
87
+ * @returns Promise that resolves when replay completes or is paused again
88
+ */
89
+ resume(): Promise<void>;
90
+ /** Stop playback and reset to idle. */
91
+ dispose(): void;
92
+ private runLoop;
93
+ /**
94
+ * Promise-based delay that resolves on timeout or rejects on abort.
95
+ * Returns true if aborted, false if delay completed normally.
96
+ */
97
+ private abortableDelay;
98
+ private notifyProgress;
99
+ private notifyComplete;
100
+ private notifyError;
101
+ }
102
+ //#endregion
103
+ export { ReplayAction as a, computeInterActionDelay as c, ProgressCallback as i, extractActionTimestamp as l, DEFAULT_MAX_DELAY_MS as n, ReplayEngine as o, ErrorCallback as r, ReplayState as s, CompleteCallback as t };
@@ -0,0 +1,109 @@
1
+ import { t as CameraFollower } from "./camera-follower-BMqPddxx.js";
2
+ import { t as AlignmentLerper } from "./alignment-lerper-D9BeDwZX.js";
3
+ import { t as Css3dRendererManager } from "./css3d-renderer-manager-rgLMVAvd.js";
4
+ import * as THREE from "three";
5
+ import { OrbitControls } from "three/addons/controls/OrbitControls.js";
6
+
7
+ //#region ../src/ar/replay-scene.d.ts
8
+ type CameraMode = 'orbit' | 'fps';
9
+ interface ReplaySceneState {
10
+ scene: THREE.Scene;
11
+ arWorldGroup: THREE.Group;
12
+ camera: THREE.PerspectiveCamera;
13
+ renderer: THREE.WebGLRenderer;
14
+ orbitControls: OrbitControls;
15
+ cameraMode: CameraMode;
16
+ rAFId: number;
17
+ container: HTMLElement;
18
+ cameraFollower: CameraFollower;
19
+ alignmentLerper: AlignmentLerper;
20
+ css3dManager: Css3dRendererManager;
21
+ }
22
+ /**
23
+ * Initialize the replay scene with a standard Three.js renderer.
24
+ *
25
+ * - Creates the scene hierarchy via createSceneHierarchy()
26
+ * - Reparents camera from arWorldGroup to scene root (Risk R5)
27
+ * - Creates a WebGLRenderer WITHOUT WebXR
28
+ * - Registers scene with module-global getters (Risk R1)
29
+ * - Inserts canvas into the provided container
30
+ * - Starts a requestAnimationFrame render loop
31
+ * - Sets up OrbitControls as default camera mode
32
+ *
33
+ * @param container - DOM element to insert the canvas into
34
+ * @returns Scene state object for downstream use
35
+ * @throws If already initialized (call disposeReplayScene first)
36
+ */
37
+ declare function initReplayScene(container: HTMLElement): {
38
+ scene: THREE.Scene;
39
+ arWorldGroup: THREE.Group;
40
+ camera: THREE.PerspectiveCamera;
41
+ renderer: THREE.WebGLRenderer;
42
+ };
43
+ /**
44
+ * Dispose the replay scene, cleaning up all resources.
45
+ *
46
+ * - Cancels the rAF render loop
47
+ * - Disposes renderer (frees GPU resources)
48
+ * - Disposes camera controls
49
+ * - Removes canvas from DOM
50
+ * - Clears module-global scene references
51
+ *
52
+ * Safe to call multiple times (idempotent).
53
+ */
54
+ declare function disposeReplayScene(): void;
55
+ /**
56
+ * Get the current replay scene state, or null if not initialized.
57
+ */
58
+ declare function getReplayState(): ReplaySceneState | null;
59
+ /**
60
+ * Update the OrbitControls target position and translate the camera
61
+ * by the same delta so the orbit viewing relationship is preserved.
62
+ *
63
+ * OrbitControls.update() does NOT automatically move the camera when
64
+ * the target changes — it recomputes offset = camera.position - target
65
+ * each frame, which is a no-op without user input. Without explicit
66
+ * camera translation, the camera would sit still while the trajectory
67
+ * moves away. Moving the camera by the target delta keeps the viewing
68
+ * angle and distance constant as the trajectory progresses.
69
+ *
70
+ * Call this as new odom poses are replayed so the orbit camera
71
+ * auto-follows the recorded trajectory.
72
+ *
73
+ * No-op if not initialized.
74
+ */
75
+ declare function updateOrbitTarget(position: THREE.Vector3): void;
76
+ /**
77
+ * Get the current camera control mode.
78
+ * Returns 'orbit' if not initialized.
79
+ */
80
+ declare function getCameraMode(): CameraMode;
81
+ /**
82
+ * Get the camera follower's Object3D, or null if the replay scene
83
+ * is not initialized. Use this to attach children (e.g., map mesh)
84
+ * that should track the camera's position but stay GPS-aligned.
85
+ */
86
+ declare function getCameraFollower(): THREE.Object3D | null;
87
+ /**
88
+ * Get the alignment lerper, or null if not initialized.
89
+ * Used by replay-mode to route store-subscriber alignment updates
90
+ * through the lerper instead of applying them directly.
91
+ */
92
+ declare function getAlignmentLerper(): AlignmentLerper | null;
93
+ /**
94
+ * Get the CSS3D renderer manager, or null if not initialized.
95
+ * Used for external resize handling or to verify the CSS3D layer exists.
96
+ */
97
+ declare function getCss3dManager(): Css3dRendererManager | null;
98
+ /**
99
+ * Toggle between orbit and FPS camera modes.
100
+ *
101
+ * - orbit → fps: Disables OrbitControls, creates and enables
102
+ * PointerLockControls + WASD keyboard handler
103
+ * - fps → orbit: Disables PointerLockControls, re-enables OrbitControls
104
+ *
105
+ * No-op if not initialized.
106
+ */
107
+ declare function toggleCameraMode(): void;
108
+ //#endregion
109
+ export { getCameraFollower as a, getReplayState as c, updateOrbitTarget as d, getAlignmentLerper as i, initReplayScene as l, ReplaySceneState as n, getCameraMode as o, disposeReplayScene as r, getCss3dManager as s, CameraMode as t, toggleCameraMode as u };
@@ -0,0 +1,23 @@
1
+ import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
2
+
3
+ //#region ../src/state/routing-slice.d.ts
4
+ /**
5
+ * Routing Slice — Redux state for current application screen.
6
+ *
7
+ * Bug 2 fix (SPA architecture audit): Moves `currentScreen` from a
8
+ * module-level variable in navigation.ts into Redux, making it the
9
+ * single source of truth for screen state. This enables time-travel
10
+ * debugging and prevents desync between navigation state and Redux.
11
+ *
12
+ * @see docs/2026-04-06-spa-architecture-audit.md — Bug 2
13
+ * @see docs_guides/spa-architecture-best-practices.md — §4 State-Driven Routing
14
+ */
15
+ /** Application screen states for history-based navigation. */
16
+ type AppScreen = 'setup' | 'ar' | 'recording' | 'summary';
17
+ interface RoutingState {
18
+ currentScreen: AppScreen;
19
+ }
20
+ declare const navigateTo: _$_reduxjs_toolkit0.ActionCreatorWithPayload<AppScreen, "routing/navigateTo">;
21
+ declare const routingReducer: _$_reduxjs_toolkit0.Reducer<RoutingState>;
22
+ //#endregion
23
+ export { routingReducer as i, RoutingState as n, navigateTo as r, AppScreen as t };
@@ -0,0 +1,14 @@
1
+ //#region ../src/ar/scene-node-names.d.ts
2
+ /**
3
+ * Scene-graph node name constants.
4
+ *
5
+ * Used in .name assignments and getObjectByName() lookups.
6
+ * Centralised here (R4) so a rename is a single-point change
7
+ * with compile-time safety instead of grep-and-replace.
8
+ */
9
+ declare const SCENE_NODE: {
10
+ /** Basis-change node (WebXR → NUE coordinate system) */readonly BASIS_CHANGE: "webxr-to-nue"; /** Camera follower node (GPS-world-aligned, tracks camera position) */
11
+ readonly CAMERA_FOLLOWER: "camera-follower";
12
+ };
13
+ //#endregion
14
+ export { SCENE_NODE as t };
@@ -0,0 +1,2 @@
1
+ import { a as getGpsErrorMessage, i as createGpsErrorHandler, n as GPS_ERROR_MESSAGES, r as GPS_ERROR_MESSAGE_UNKNOWN, t as GPS_ERROR_CODES } from "../gps-error-handler-VPuNOuf8.js";
2
+ export { GPS_ERROR_CODES, GPS_ERROR_MESSAGES, GPS_ERROR_MESSAGE_UNKNOWN, createGpsErrorHandler, getGpsErrorMessage };