gps-plus-slam-app-framework 1.2.0 → 1.3.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 (67) hide show
  1. package/dist/{app-selectors-CcZ5UV-8.d.ts → app-selectors-B8VQoMDY.d.ts} +1 -1
  2. package/dist/ar/camera-blit-capture.d.ts +1 -1
  3. package/dist/ar/camera-blit-capture.js +13 -0
  4. package/dist/ar/enable-gps-ar.d.ts +1 -1
  5. package/dist/ar/enable-gps-ar.js +1 -1
  6. package/dist/ar/image-capture.d.ts +2 -2
  7. package/dist/ar/image-capture.js +7 -5
  8. package/dist/ar/index.d.ts +4 -4
  9. package/dist/ar/index.js +1 -1
  10. package/dist/ar/replay-scene.js +1 -1
  11. package/dist/ar/webxr-session.d.ts +2 -2
  12. package/dist/ar/webxr-session.js +1 -1
  13. package/dist/{ar-world-group-alignment-ColHB_5A.d.ts → ar-world-group-alignment-C9lwwIyI.d.ts} +1 -1
  14. package/dist/{camera-blit-capture-D5_mNhla.d.ts → camera-blit-capture-CnxUDbKx.d.ts} +9 -0
  15. package/dist/{create-slam-app-store-qNXQ-tq5.d.ts → create-slam-app-store-BljusOua.d.ts} +2 -2
  16. package/dist/{enable-gps-ar-CapmADVN.d.ts → enable-gps-ar-BfUJOgpW.d.ts} +1 -1
  17. package/dist/{file-system-C_eqiEA8.d.ts → file-system-CwXTNHmB.d.ts} +1 -1
  18. package/dist/file-system-utils-CXIoL-DM.d.ts +40 -0
  19. package/dist/{gps-event-coordinator-BDIQde2x.d.ts → gps-event-coordinator-CWIDOk4U.d.ts} +1 -1
  20. package/dist/{image-capture-DZ4HFRgS.d.ts → image-capture-qAZ5Fh5X.d.ts} +29 -3
  21. package/dist/{index-KJq2amHF.d.ts → index-BYYUdf9v.d.ts} +1 -1
  22. package/dist/index.d.ts +19 -19
  23. package/dist/index.js +1 -1
  24. package/dist/{null-storage-backend-CxEjZHRW.d.ts → null-storage-backend-uKQE8tl7.d.ts} +2 -2
  25. package/dist/{opfs-storage-DYm8WHq7.d.ts → opfs-storage-D5zAn_lx.d.ts} +2 -2
  26. package/dist/{opfs-storage-backend-CjSAuqg_.d.ts → opfs-storage-backend-6aYMUZlJ.d.ts} +2 -2
  27. package/dist/{persistence-middleware-DwyzgfWr.d.ts → persistence-middleware-B9ei4Nhx.d.ts} +1 -1
  28. package/dist/{recording-replayer-BL-x-7k0.d.ts → recording-replayer-r0DZ9ALp.d.ts} +1 -1
  29. package/dist/{replay-engine-BRqszuQ9.d.ts → replay-engine-XpDa0dy1.d.ts} +1 -1
  30. package/dist/state/app-selectors.d.ts +1 -1
  31. package/dist/state/app-selectors.js +3 -1
  32. package/dist/state/combined-root-state.d.ts +1 -1
  33. package/dist/state/create-slam-app-store.d.ts +1 -1
  34. package/dist/state/gps-ar-pose-sampler.d.ts +1 -1
  35. package/dist/state/gps-event-coordinator.d.ts +1 -1
  36. package/dist/state/index.d.ts +11 -11
  37. package/dist/state/persistence-middleware.d.ts +1 -1
  38. package/dist/state/recording-replayer.d.ts +2 -2
  39. package/dist/state/replay-engine.d.ts +1 -1
  40. package/dist/state/store-subscribers.d.ts +2 -2
  41. package/dist/state/subscribe-to-selector.d.ts +1 -1
  42. package/dist/state/tracking-quality.d.ts +1 -1
  43. package/dist/storage/file-system-utils.d.ts +2 -2
  44. package/dist/storage/file-system-utils.js +17 -1
  45. package/dist/storage/file-system.d.ts +1 -1
  46. package/dist/storage/file-system.js +2 -2
  47. package/dist/storage/index.d.ts +7 -7
  48. package/dist/storage/null-storage-backend.d.ts +1 -1
  49. package/dist/storage/opfs-storage-backend.d.ts +1 -1
  50. package/dist/storage/opfs-storage.d.ts +1 -1
  51. package/dist/storage/opfs-storage.js +4 -4
  52. package/dist/storage/storage-backend.d.ts +1 -1
  53. package/dist/storage/zip-export.d.ts +1 -1
  54. package/dist/storage/zip-export.js +1 -1
  55. package/dist/storage/zip-reader.js +1 -1
  56. package/dist/{storage-backend-C9HLFtgz.d.ts → storage-backend-Do6YDpNo.d.ts} +1 -1
  57. package/dist/{store-subscribers-rrkLkFTt.d.ts → store-subscribers-0YWyOLvV.d.ts} +1 -1
  58. package/dist/{subscribe-to-selector-CP3BKSbF.d.ts → subscribe-to-selector-CZ6k1NFP.d.ts} +1 -1
  59. package/dist/test-utils/zip-round-trip-helpers.js +3 -2
  60. package/dist/visualization/ar-world-group-alignment.d.ts +1 -1
  61. package/dist/visualization/gps-event-markers.js +1 -1
  62. package/dist/visualization/index.d.ts +1 -1
  63. package/dist/{webxr-session-DtAG9srK.d.ts → webxr-session-GjZ2BIpS.d.ts} +1 -1
  64. package/dist/{webxr-session-QhcSSub5.js → webxr-session-TIaD883f.js} +17 -4
  65. package/dist/{zip-export-D_5HAvFz.d.ts → zip-export-G14hkSPG.d.ts} +1 -1
  66. package/package.json +2 -2
  67. package/dist/file-system-utils-DyAmcuvX.d.ts +0 -24
@@ -1,4 +1,4 @@
1
- import { L as CombinedRootState, r as SlamAppRootState } from "./create-slam-app-store-qNXQ-tq5.js";
1
+ import { L as CombinedRootState, r as SlamAppRootState } from "./create-slam-app-store-BljusOua.js";
2
2
  import * as _$gps_plus_slam_js0 from "gps-plus-slam-js";
3
3
  import { ArImageCapture, GpsPoint, LatLong, Matrix4, Quaternion, Vector3 } from "gps-plus-slam-js";
4
4
  import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
@@ -1,2 +1,2 @@
1
- import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "../camera-blit-capture-D5_mNhla.js";
1
+ import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "../camera-blit-capture-CnxUDbKx.js";
2
2
  export { CameraBlitCapture, CameraBlitCaptureConfig, DEFAULT_BLIT_CONFIG, computeCaptureSize };
@@ -267,6 +267,19 @@ var CameraBlitCapture = class {
267
267
  return true;
268
268
  }
269
269
  /**
270
+ * Current render-target width in pixels. This is exactly the width of the
271
+ * JPEG produced by {@link captureToBlob} (the encode canvas is sized to the
272
+ * render target), so callers can persist it as the captured image's true
273
+ * pixel width without decoding the blob.
274
+ */
275
+ getWidth() {
276
+ return this.width;
277
+ }
278
+ /** Current render-target height in pixels. See {@link getWidth}. */
279
+ getHeight() {
280
+ return this.height;
281
+ }
282
+ /**
270
283
  * Dispose GPU resources. Call when AR session ends.
271
284
  */
272
285
  dispose() {
@@ -1,2 +1,2 @@
1
- import { a as EnableGpsArState, i as EnableGpsArResult, n as EnableGpsArController, o as EnableGpsArStatus, r as EnableGpsArDeps, s as createEnableGpsArController, t as EnableGpsArConfig } from "../enable-gps-ar-CapmADVN.js";
1
+ import { a as EnableGpsArState, i as EnableGpsArResult, n as EnableGpsArController, o as EnableGpsArStatus, r as EnableGpsArDeps, s as createEnableGpsArController, t as EnableGpsArConfig } from "../enable-gps-ar-BfUJOgpW.js";
2
2
  export { EnableGpsArConfig, EnableGpsArController, EnableGpsArDeps, EnableGpsArResult, EnableGpsArState, EnableGpsArStatus, createEnableGpsArController };
@@ -1,7 +1,7 @@
1
1
  import { createLogger } from "../utils/logger.js";
2
2
  import { requestGeolocationPermission, requestOrientationPermission, requestWebXRWithDepthPermission } from "../sensors/permission-checker.js";
3
3
  import { startGpsWatch, startOrientationWatch, stopGpsWatch, stopOrientationWatch } from "../sensors/gps.js";
4
- import { _ as isWebXRSupported, g as initAR, i as endARSession } from "../webxr-session-QhcSSub5.js";
4
+ import { _ as isWebXRSupported, g as initAR, i as endARSession } from "../webxr-session-TIaD883f.js";
5
5
  //#region ../src/ar/enable-gps-ar.ts
6
6
  const log = createLogger("EnableGpsAr");
7
7
  const defaultDeps = {
@@ -1,2 +1,2 @@
1
- import { a as ImageCaptureManager, i as ImageCaptureConfig, n as DEFAULT_CAPTURE_CONFIG, o as MIN_VALID_IMAGE_BYTES, r as ImageCaptureCallbacks, t as CapturedImage } from "../image-capture-DZ4HFRgS.js";
2
- export { CapturedImage, DEFAULT_CAPTURE_CONFIG, ImageCaptureCallbacks, ImageCaptureConfig, ImageCaptureManager, MIN_VALID_IMAGE_BYTES };
1
+ import { a as ImageCaptureConfig, i as ImageCaptureCallbacks, n as CapturedImage, o as ImageCaptureManager, r as DEFAULT_CAPTURE_CONFIG, s as MIN_VALID_IMAGE_BYTES, t as CapturedFrame } from "../image-capture-qAZ5Fh5X.js";
2
+ export { CapturedFrame, CapturedImage, DEFAULT_CAPTURE_CONFIG, ImageCaptureCallbacks, ImageCaptureConfig, ImageCaptureManager, MIN_VALID_IMAGE_BYTES };
@@ -103,15 +103,15 @@ var ImageCaptureManager = class {
103
103
  this.captureTimeoutId = null;
104
104
  }
105
105
  }, this.config.captureTimeoutMs);
106
- if (this.callbacks.captureFrame) this.callbacks.captureFrame(this.config.quality).then((blob) => {
107
- this.handleCapturedBlob(blob, timestamp, frameIndex, pose, screenRotation);
106
+ if (this.callbacks.captureFrame) this.callbacks.captureFrame(this.config.quality).then((frame) => {
107
+ this.handleCapturedBlob(frame?.blob ?? null, frame?.width, frame?.height, timestamp, frameIndex, pose, screenRotation);
108
108
  }).catch(() => {
109
109
  this.clearCaptureTimeout();
110
110
  this.captureInProgress = false;
111
111
  this.callbacks.onCaptureFailed?.();
112
112
  });
113
113
  else this.canvas.toBlob((blob) => {
114
- this.handleCapturedBlob(blob, timestamp, frameIndex, pose, screenRotation);
114
+ this.handleCapturedBlob(blob, this.canvas.width, this.canvas.height, timestamp, frameIndex, pose, screenRotation);
115
115
  }, "image/jpeg", this.config.quality);
116
116
  }
117
117
  /**
@@ -128,7 +128,7 @@ var ImageCaptureManager = class {
128
128
  * Common handler for captured blobs (from either canvas.toBlob or captureFrame).
129
129
  * Handles null blobs, suspicious image detection, and dispatching onCaptured.
130
130
  */
131
- handleCapturedBlob(blob, timestamp, frameIndex, pose, screenRotation) {
131
+ handleCapturedBlob(blob, width, height, timestamp, frameIndex, pose, screenRotation) {
132
132
  this.clearCaptureTimeout();
133
133
  this.captureInProgress = false;
134
134
  if (!blob) {
@@ -145,7 +145,9 @@ var ImageCaptureManager = class {
145
145
  frameIndex,
146
146
  position: pose.position,
147
147
  rotation: pose.orientation,
148
- screenRotation
148
+ screenRotation,
149
+ ...width && width > 0 ? { width } : {},
150
+ ...height && height > 0 ? { height } : {}
149
151
  });
150
152
  }
151
153
  };
@@ -1,14 +1,14 @@
1
1
  import { r as bresenham3d, t as GridCell } from "../bresenham3d-CFfd7n6B.js";
2
- import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "../camera-blit-capture-D5_mNhla.js";
2
+ import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "../camera-blit-capture-CnxUDbKx.js";
3
3
  import { i as isFullySupported, n as CapabilitySupport, r as capabilityMessage, t as CapabilityMessageOptions } from "../capability-checker-CQXJHxXg.js";
4
4
  import { a as createCaptureFailureTracker, i as DEFAULT_CAPTURE_TRACKER_CONFIG, n as CaptureFailureTracker, r as CaptureFailureTrackerConfig, t as CAPTURE_FAILURE_WARNING } from "../capture-failure-tracker-CUeU3L_M.js";
5
5
  import { a as applyChromiumProjectionLayerWorkaround, i as ChromiumProjectionLayerWorkaroundResult, n as BASELAYER_WINDOW_MIN, o as needsBaseLayerPersistence, r as ChromeVersion, s as parseChromeVersion, t as BASELAYER_WINDOW_MAX } from "../chromium-camera-access-workaround-Jqbn0apH.js";
6
6
  import { a as wrapXRDepthInfo, i as DepthSamplerConfig, n as DepthSampler, r as DepthSamplerCallbacks, t as DepthInfo } from "../depth-sampler-Bhanfwla.js";
7
7
  import { n as createDepthUnprojector, r as unprojectDepthPoint, t as DepthUnprojector } from "../depth-unprojection-Y6i_mJuT.js";
8
- import { a as ImageCaptureManager, i as ImageCaptureConfig, n as DEFAULT_CAPTURE_CONFIG, o as MIN_VALID_IMAGE_BYTES, r as ImageCaptureCallbacks, t as CapturedImage } from "../image-capture-DZ4HFRgS.js";
8
+ import { a as ImageCaptureConfig, i as ImageCaptureCallbacks, n as CapturedImage, o as ImageCaptureManager, r as DEFAULT_CAPTURE_CONFIG, s as MIN_VALID_IMAGE_BYTES } from "../image-capture-qAZ5Fh5X.js";
9
9
  import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "../xr-camera-texture-DBwCaKTd.js";
10
- import { D as setDepthCaptureCallback, I as startDepthCapture, L as startImageCapture, M as setTrackingLostCallback, O as setFrameCallback, P as setTrackingStore, R as stopDepthCapture, d as getCamera, f as getCurrentArPose, g as getScene, h as getLiveCss3dManager, j as setTrackingCallbacks, k as setImageCaptureCallback, m as getImageCaptureFrameCount, o as endARSession, p as getDepthSampleCount, t as SessionFeatureOptions, u as getArWorldGroup, v as initAR, z as stopImageCapture } from "../webxr-session-DtAG9srK.js";
11
- import { a as EnableGpsArState, i as EnableGpsArResult, n as EnableGpsArController, o as EnableGpsArStatus, r as EnableGpsArDeps, s as createEnableGpsArController, t as EnableGpsArConfig } from "../enable-gps-ar-CapmADVN.js";
10
+ import { D as setDepthCaptureCallback, I as startDepthCapture, L as startImageCapture, M as setTrackingLostCallback, O as setFrameCallback, P as setTrackingStore, R as stopDepthCapture, d as getCamera, f as getCurrentArPose, g as getScene, h as getLiveCss3dManager, j as setTrackingCallbacks, k as setImageCaptureCallback, m as getImageCaptureFrameCount, o as endARSession, p as getDepthSampleCount, t as SessionFeatureOptions, u as getArWorldGroup, v as initAR, z as stopImageCapture } from "../webxr-session-GjZ2BIpS.js";
11
+ import { a as EnableGpsArState, i as EnableGpsArResult, n as EnableGpsArController, o as EnableGpsArStatus, r as EnableGpsArDeps, s as createEnableGpsArController, t as EnableGpsArConfig } from "../enable-gps-ar-BfUJOgpW.js";
12
12
  import { r as registerFrameUpdate, t as FrameUpdate } from "../frame-loop-CMewS8cY.js";
13
13
  import { n as OccupancyGridOptions, t as OccupancyGrid } from "../occupancy-grid-BRNRaPyT.js";
14
14
  import { i as registerXrFrameUpdate, n as XrFrameUpdate, t as XrFrameContext } from "../xr-frame-loop-BtYytZJg.js";
package/dist/ar/index.js CHANGED
@@ -10,7 +10,7 @@ import { registerFrameUpdate } from "./frame-loop.js";
10
10
  import { registerXrFrameUpdate } from "./xr-frame-loop.js";
11
11
  import { WEBXR_TO_NUE } from "./webxr-nue-basis.js";
12
12
  import { DEFAULT_CAPTURE_CONFIG, ImageCaptureManager, MIN_VALID_IMAGE_BYTES } from "./image-capture.js";
13
- import { A as setTrackingLostCallback, D as setImageCaptureCallback, E as setFrameCallback, F as startImageCapture, I as stopDepthCapture, L as stopImageCapture, M as setTrackingStore, P as startDepthCapture, T as setDepthCaptureCallback, c as getArWorldGroup, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, i as endARSession, k as setTrackingCallbacks, l as getCamera, m as getScene, p as getLiveCss3dManager, u as getCurrentArPose } from "../webxr-session-QhcSSub5.js";
13
+ import { A as setTrackingLostCallback, D as setImageCaptureCallback, E as setFrameCallback, F as startImageCapture, I as stopDepthCapture, L as stopImageCapture, M as setTrackingStore, P as startDepthCapture, T as setDepthCaptureCallback, c as getArWorldGroup, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, i as endARSession, k as setTrackingCallbacks, l as getCamera, m as getScene, p as getLiveCss3dManager, u as getCurrentArPose } from "../webxr-session-TIaD883f.js";
14
14
  import { acquireCameraTexture } from "./xr-camera-texture.js";
15
15
  import { SCENE_NODE } from "./scene-node-names.js";
16
16
  import { createEnableGpsArController } from "./enable-gps-ar.js";
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "../utils/logger.js";
2
- import { C as setArWorldGroup, O as setScene, S as setArPose, r as createSceneHierarchy, w as setCamera } from "../webxr-session-QhcSSub5.js";
2
+ import { C as setArWorldGroup, O as setScene, S as setArPose, r as createSceneHierarchy, w as setCamera } from "../webxr-session-TIaD883f.js";
3
3
  import { createCss3dRendererManager } from "../visualization/css3d-renderer-manager.js";
4
4
  import { createCameraFollower } from "../visualization/camera-follower.js";
5
5
  import { createAlignmentLerper } from "../visualization/alignment-lerper.js";
@@ -1,4 +1,4 @@
1
1
  import { i as DepthSample, t as ARPose } from "../ar-types-Dan1MVTi.js";
2
- import { t as CapturedImage } from "../image-capture-DZ4HFRgS.js";
3
- import { A as setScene, C as resetWebXRState, D as setDepthCaptureCallback, E as setCamera, F as shouldLogCameraAccessDiagnostic, I as startDepthCapture, L as startImageCapture, M as setTrackingLostCallback, N as setTrackingRecoveredCallback, O as setFrameCallback, P as setTrackingStore, R as stopDepthCapture, S as nueQuaternionToWebXR, T as setArWorldGroup, _ as getXrCameraFromPose, a as createSceneHierarchy, b as isXRCameraLike, c as extractResetTransformData, d as getCamera, f as getCurrentArPose, g as getScene, h as getLiveCss3dManager, i as buildSessionOptions, j as setTrackingCallbacks, k as setImageCaptureCallback, l as getArPose, m as getImageCaptureFrameCount, n as TrackingSubscribableStore, o as endARSession, p as getDepthSampleCount, r as applyAlignmentMatrix, s as extractPoseFromViewer, t as SessionFeatureOptions, u as getArWorldGroup, v as initAR, w as setArPose, x as nuePositionToWebXR, y as isWebXRSupported, z as stopImageCapture } from "../webxr-session-DtAG9srK.js";
2
+ import { n as CapturedImage } from "../image-capture-qAZ5Fh5X.js";
3
+ import { A as setScene, C as resetWebXRState, D as setDepthCaptureCallback, E as setCamera, F as shouldLogCameraAccessDiagnostic, I as startDepthCapture, L as startImageCapture, M as setTrackingLostCallback, N as setTrackingRecoveredCallback, O as setFrameCallback, P as setTrackingStore, R as stopDepthCapture, S as nueQuaternionToWebXR, T as setArWorldGroup, _ as getXrCameraFromPose, a as createSceneHierarchy, b as isXRCameraLike, c as extractResetTransformData, d as getCamera, f as getCurrentArPose, g as getScene, h as getLiveCss3dManager, i as buildSessionOptions, j as setTrackingCallbacks, k as setImageCaptureCallback, l as getArPose, m as getImageCaptureFrameCount, n as TrackingSubscribableStore, o as endARSession, p as getDepthSampleCount, r as applyAlignmentMatrix, s as extractPoseFromViewer, t as SessionFeatureOptions, u as getArWorldGroup, v as initAR, w as setArPose, x as nuePositionToWebXR, y as isWebXRSupported, z as stopImageCapture } from "../webxr-session-GjZ2BIpS.js";
4
4
  export { ARPose, CapturedImage, DepthSample, SessionFeatureOptions, TrackingSubscribableStore, applyAlignmentMatrix, buildSessionOptions, createSceneHierarchy, endARSession, extractPoseFromViewer, extractResetTransformData, getArPose, getArWorldGroup, getCamera, getCurrentArPose, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getScene, getXrCameraFromPose, initAR, isWebXRSupported, isXRCameraLike, nuePositionToWebXR, nueQuaternionToWebXR, resetWebXRState, setArPose, setArWorldGroup, setCamera, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setScene, setTrackingCallbacks, setTrackingLostCallback, setTrackingRecoveredCallback, setTrackingStore, shouldLogCameraAccessDiagnostic, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture };
@@ -1,2 +1,2 @@
1
- import { A as setTrackingLostCallback, C as setArWorldGroup, D as setImageCaptureCallback, E as setFrameCallback, F as startImageCapture, I as stopDepthCapture, L as stopImageCapture, M as setTrackingStore, N as shouldLogCameraAccessDiagnostic, O as setScene, P as startDepthCapture, S as setArPose, T as setDepthCaptureCallback, _ as isWebXRSupported, a as extractPoseFromViewer, b as nueQuaternionToWebXR, c as getArWorldGroup, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, h as getXrCameraFromPose, i as endARSession, j as setTrackingRecoveredCallback, k as setTrackingCallbacks, l as getCamera, m as getScene, n as buildSessionOptions, o as extractResetTransformData, p as getLiveCss3dManager, r as createSceneHierarchy, s as getArPose, t as applyAlignmentMatrix, u as getCurrentArPose, v as isXRCameraLike, w as setCamera, x as resetWebXRState, y as nuePositionToWebXR } from "../webxr-session-QhcSSub5.js";
1
+ import { A as setTrackingLostCallback, C as setArWorldGroup, D as setImageCaptureCallback, E as setFrameCallback, F as startImageCapture, I as stopDepthCapture, L as stopImageCapture, M as setTrackingStore, N as shouldLogCameraAccessDiagnostic, O as setScene, P as startDepthCapture, S as setArPose, T as setDepthCaptureCallback, _ as isWebXRSupported, a as extractPoseFromViewer, b as nueQuaternionToWebXR, c as getArWorldGroup, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, h as getXrCameraFromPose, i as endARSession, j as setTrackingRecoveredCallback, k as setTrackingCallbacks, l as getCamera, m as getScene, n as buildSessionOptions, o as extractResetTransformData, p as getLiveCss3dManager, r as createSceneHierarchy, s as getArPose, t as applyAlignmentMatrix, u as getCurrentArPose, v as isXRCameraLike, w as setCamera, x as resetWebXRState, y as nuePositionToWebXR } from "../webxr-session-TIaD883f.js";
2
2
  export { applyAlignmentMatrix, buildSessionOptions, createSceneHierarchy, endARSession, extractPoseFromViewer, extractResetTransformData, getArPose, getArWorldGroup, getCamera, getCurrentArPose, getDepthSampleCount, getImageCaptureFrameCount, getLiveCss3dManager, getScene, getXrCameraFromPose, initAR, isWebXRSupported, isXRCameraLike, nuePositionToWebXR, nueQuaternionToWebXR, resetWebXRState, setArPose, setArWorldGroup, setCamera, setDepthCaptureCallback, setFrameCallback, setImageCaptureCallback, setScene, setTrackingCallbacks, setTrackingLostCallback, setTrackingRecoveredCallback, setTrackingStore, shouldLogCameraAccessDiagnostic, startDepthCapture, startImageCapture, stopDepthCapture, stopImageCapture };
@@ -1,4 +1,4 @@
1
- import { t as SubscribableStore } from "./subscribe-to-selector-CP3BKSbF.js";
1
+ import { t as SubscribableStore } from "./subscribe-to-selector-CZ6k1NFP.js";
2
2
  import * as THREE from "three";
3
3
 
4
4
  //#region ../src/visualization/ar-world-group-alignment.d.ts
@@ -119,6 +119,15 @@ declare class CameraBlitCapture {
119
119
  * @returns true if resources were actually resized
120
120
  */
121
121
  resizeIfNeeded(newWidth: number, newHeight: number): boolean;
122
+ /**
123
+ * Current render-target width in pixels. This is exactly the width of the
124
+ * JPEG produced by {@link captureToBlob} (the encode canvas is sized to the
125
+ * render target), so callers can persist it as the captured image's true
126
+ * pixel width without decoding the blob.
127
+ */
128
+ getWidth(): number;
129
+ /** Current render-target height in pixels. See {@link getWidth}. */
130
+ getHeight(): number;
122
131
  /**
123
132
  * Dispose GPU resources. Call when AR session ends.
124
133
  */
@@ -1,8 +1,8 @@
1
1
  import { t as ARPose } from "./ar-types-Dan1MVTi.js";
2
2
  import { a as TrackingSliceState, t as DeviceOrientation } from "./tracking-slice-CdK8c-8P.js";
3
3
  import { t as RecordingState } from "./recording-slice-89O07ebs.js";
4
- import { n as SessionMetadata } from "./opfs-storage-DYm8WHq7.js";
5
- import { n as StorageBackend } from "./storage-backend-C9HLFtgz.js";
4
+ import { n as SessionMetadata } from "./opfs-storage-D5zAn_lx.js";
5
+ import { n as StorageBackend } from "./storage-backend-Do6YDpNo.js";
6
6
  import { GpsPoint, LatLong, Matrix4, RootState, Vector3 } from "gps-plus-slam-js";
7
7
  import * as _$_reduxjs_toolkit0 from "@reduxjs/toolkit";
8
8
  import { Middleware, Reducer, ReducersMapObject, configureStore } from "@reduxjs/toolkit";
@@ -1,7 +1,7 @@
1
1
  import { t as ArCrashIsolationOptions } from "./recording-options-DJBXuMxV.js";
2
2
  import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-VuezJWK3.js";
3
3
  import { n as PermissionStatus } from "./permission-checker-GpAiSCwd.js";
4
- import { t as SessionFeatureOptions } from "./webxr-session-DtAG9srK.js";
4
+ import { t as SessionFeatureOptions } from "./webxr-session-GjZ2BIpS.js";
5
5
 
6
6
  //#region ../src/ar/enable-gps-ar.d.ts
7
7
  /**
@@ -1,4 +1,4 @@
1
- import { n as SessionMetadata } from "./opfs-storage-DYm8WHq7.js";
1
+ import { n as SessionMetadata } from "./opfs-storage-D5zAn_lx.js";
2
2
 
3
3
  //#region ../src/storage/file-system.d.ts
4
4
  /**
@@ -0,0 +1,40 @@
1
+ //#region ../src/storage/file-system-utils.d.ts
2
+ /**
3
+ * File System Utilities - Pure Functions
4
+ *
5
+ * These are extracted from file-system.ts so they can be tested
6
+ * without mocking browser APIs.
7
+ */
8
+ /**
9
+ * Format a Date as a timestamp string for folder names
10
+ * @example "2025-02-28_14-30-11utc"
11
+ */
12
+ declare function formatTimestamp(date: Date): string;
13
+ /**
14
+ * Format an action file index as a zero-padded filename
15
+ * @example 42 -> "000042.json"
16
+ */
17
+ declare function formatActionFilename(index: number): string;
18
+ /**
19
+ * Format a frame index as a zero-padded filename
20
+ * @example 42 -> "frame-000042.jpg"
21
+ */
22
+ declare function formatFrameFilename(index: number): string;
23
+ /**
24
+ * Canonical session subdirectory for captured camera images, written by new
25
+ * recordings. Renamed from {@link LEGACY_SESSION_IMAGES_DIR} so an exported ZIP
26
+ * is a textbook COLMAP tree (`images/frame-NNNNNN.jpg` next to `sparse/0/`).
27
+ * Both the OPFS write path and the recorder's persisted `imageFile` value must
28
+ * use THIS constant so a recording stays self-consistent (COLMAP export plan
29
+ * Q5, gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-06-13-colmap-export-plan.md).
30
+ */
31
+ declare const SESSION_IMAGES_DIR = "images";
32
+ /**
33
+ * The pre-2026-06 session image subdirectory. Recordings made before the
34
+ * {@link SESSION_IMAGES_DIR} rename store frames under `frames/` (in both the
35
+ * on-disk dir and the persisted `imageFile`); readers fall back to this prefix
36
+ * so old recordings still replay.
37
+ */
38
+ declare const LEGACY_SESSION_IMAGES_DIR = "frames";
39
+ //#endregion
40
+ export { formatTimestamp as a, formatFrameFilename as i, SESSION_IMAGES_DIR as n, formatActionFilename as r, LEGACY_SESSION_IMAGES_DIR as t };
@@ -1,6 +1,6 @@
1
1
  import { t as ARPose } from "./ar-types-Dan1MVTi.js";
2
2
  import { n as RawDeviceOrientation, t as GpsPosition } from "./gps-VuezJWK3.js";
3
- import { i as SlamAppStore } from "./create-slam-app-store-qNXQ-tq5.js";
3
+ import { i as SlamAppStore } from "./create-slam-app-store-BljusOua.js";
4
4
  import { Quaternion, RawGpsPoint, RecordGpsEventPayload, Vector3, eulerToQuaternion } from "gps-plus-slam-js";
5
5
  import { ReducersMapObject } from "@reduxjs/toolkit";
6
6
 
@@ -54,6 +54,30 @@ interface CapturedImage {
54
54
  readonly rotation: WebXRQuaternion;
55
55
  /** Device screen orientation (0, 90, 180, 270) */
56
56
  readonly screenRotation: number;
57
+ /**
58
+ * Width of the encoded JPEG in pixels — the blit/canvas dimensions the blob
59
+ * was produced from, so it equals the decoded image's width. Persisted as
60
+ * `ArImageCapture.width` so consumers (the 3D frame-tile visualizer) can
61
+ * render each frame at its true aspect ratio. Always present from the
62
+ * capture pipeline; optional so the field can be threaded without forcing
63
+ * every test/caller to supply it.
64
+ */
65
+ readonly width?: number;
66
+ /** Height of the encoded JPEG in pixels. See {@link CapturedImage.width}. */
67
+ readonly height?: number;
68
+ }
69
+ /**
70
+ * A captured frame blob together with the pixel dimensions it was encoded at.
71
+ * Returned by the optional `captureFrame` (blit) callback so the pose-invariant
72
+ * image size can be persisted as first-class metadata (frame-tile aspect-ratio
73
+ * fix, D1 of 2026-06-13-frame-tile-rendering-bugs-user-feedback.md). The
74
+ * dimensions are the blit render-target size — identical to the JPEG's own
75
+ * width/height — so no decode is needed to learn the aspect ratio.
76
+ */
77
+ interface CapturedFrame {
78
+ readonly blob: Blob;
79
+ readonly width: number;
80
+ readonly height: number;
57
81
  }
58
82
  /**
59
83
  * Callbacks for image capture integration
@@ -80,10 +104,12 @@ interface ImageCaptureCallbacks {
80
104
  * be read directly via canvas.toBlob() (which returns black pixels).
81
105
  *
82
106
  * @param quality - JPEG quality 0.0-1.0
83
- * @returns Promise resolving to a JPEG Blob, or null if capture fails
107
+ * @returns Promise resolving to the JPEG blob plus the pixel dimensions it
108
+ * was encoded at, or null if capture fails. The dimensions flow into the
109
+ * persisted `ArImageCapture.width`/`height` for aspect-correct rendering.
84
110
  * @see docs/2026-02-06-bug-camera-frames-black.md
85
111
  */
86
- captureFrame?: (quality: number) => Promise<Blob | null>;
112
+ captureFrame?: (quality: number) => Promise<CapturedFrame | null>;
87
113
  }
88
114
  /**
89
115
  * Manages periodic image capture from a canvas.
@@ -140,4 +166,4 @@ declare class ImageCaptureManager {
140
166
  private handleCapturedBlob;
141
167
  }
142
168
  //#endregion
143
- export { ImageCaptureManager as a, ImageCaptureConfig as i, DEFAULT_CAPTURE_CONFIG as n, MIN_VALID_IMAGE_BYTES as o, ImageCaptureCallbacks as r, CapturedImage as t };
169
+ export { ImageCaptureConfig as a, ImageCaptureCallbacks as i, CapturedImage as n, ImageCaptureManager as o, DEFAULT_CAPTURE_CONFIG as r, MIN_VALID_IMAGE_BYTES as s, CapturedFrame as t };
@@ -1,4 +1,4 @@
1
- import { L as CombinedRootState, h as TrackingQualityReport } from "./create-slam-app-store-qNXQ-tq5.js";
1
+ import { L as CombinedRootState, h as TrackingQualityReport } from "./create-slam-app-store-BljusOua.js";
2
2
  import { Add2dImagePayload, GpsPoint as GpsPoint$1, LatLong as LatLong$1, RawDeviceOrientation, RawGpsPoint as RawGpsPoint$1, RecordGpsEventPayload as RecordGpsEventPayload$1, add2dImage, calcRelativeCoordsInMeters, recordGpsEvent as recordGpsEvent$1, setZeroPos as setZeroPos$1 } from "gps-plus-slam-js";
3
3
 
4
4
  //#region ../src/state/onboarding-guidance.d.ts
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { r as bresenham3d, t as GridCell } from "./bresenham3d-CFfd7n6B.js";
2
- import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "./camera-blit-capture-D5_mNhla.js";
2
+ import { i as computeCaptureSize, n as CameraBlitCaptureConfig, r as DEFAULT_BLIT_CONFIG, t as CameraBlitCapture } from "./camera-blit-capture-CnxUDbKx.js";
3
3
  import { i as isFullySupported, n as CapabilitySupport, r as capabilityMessage, t as CapabilityMessageOptions } from "./capability-checker-CQXJHxXg.js";
4
4
  import { a as createCaptureFailureTracker, i as DEFAULT_CAPTURE_TRACKER_CONFIG, n as CaptureFailureTracker, r as CaptureFailureTrackerConfig, t as CAPTURE_FAILURE_WARNING } from "./capture-failure-tracker-CUeU3L_M.js";
5
5
  import { a as applyChromiumProjectionLayerWorkaround, i as ChromiumProjectionLayerWorkaroundResult, n as BASELAYER_WINDOW_MIN, o as needsBaseLayerPersistence, r as ChromeVersion, s as parseChromeVersion, t as BASELAYER_WINDOW_MAX } from "./chromium-camera-access-workaround-Jqbn0apH.js";
@@ -9,12 +9,12 @@ import { n as createDepthUnprojector, r as unprojectDepthPoint, t as DepthUnproj
9
9
  import { _ as validateRecordingOptions, a as IMAGE_CONSTRAINTS, c as RecordingOptionsInput, d as loadRecordingOptions, f as resetRecordingOptions, g as validateImageOptions, h as validateDepthOptions, i as DepthCaptureOptions, l as STORAGE_KEY, n as DEFAULT_RECORDING_OPTIONS, o as ImageCaptureOptions, p as saveRecordingOptions, r as DEPTH_CONSTRAINTS, u as cloneRecordingOptions } from "./recording-options-DJBXuMxV.js";
10
10
  import { a as startOrientationWatch, i as startGpsWatch, n as RawDeviceOrientation, o as stopGpsWatch, r as requestOrientationPermission, s as stopOrientationWatch, t as GpsPosition } from "./gps-VuezJWK3.js";
11
11
  import { a as checkCameraPermission, c as checkOrientationPermission, d as requestCameraPermission, f as requestGeolocationPermission, g as setFileSystemState, h as resetFileSystemState, i as checkAllPermissions, l as checkWebXRSupport, m as requestWebXRWithDepthPermission, n as PermissionStatus, o as checkFileSystemPermission, p as requestOrientationPermission$1, s as checkGeolocationPermission, t as PermissionCheckResult, u as requestAllPermissions } from "./permission-checker-GpAiSCwd.js";
12
- import { a as ImageCaptureManager, i as ImageCaptureConfig, n as DEFAULT_CAPTURE_CONFIG, o as MIN_VALID_IMAGE_BYTES, r as ImageCaptureCallbacks, t as CapturedImage } from "./image-capture-DZ4HFRgS.js";
12
+ import { a as ImageCaptureConfig, i as ImageCaptureCallbacks, n as CapturedImage, o as ImageCaptureManager, r as DEFAULT_CAPTURE_CONFIG, s as MIN_VALID_IMAGE_BYTES } from "./image-capture-qAZ5Fh5X.js";
13
13
  import { a as TrackingSliceState, c as poseLost, d as selectLastRestartedPayload, f as selectLastSensorOrientation, g as trackingReducer, h as selectTrackingPhase, i as TrackingPhase, l as poseReceived, m as selectLostFrameCount, n as PoseReceivedPayload, o as clearLastRestartedPayload, p as selectLastValidPose, s as originReset, u as resetTracking } from "./tracking-slice-CdK8c-8P.js";
14
14
  import { n as createCss3dRendererManager, t as Css3dRendererManager } from "./css3d-renderer-manager-ptu_t3B3.js";
15
15
  import { i as acquireCameraTexture, n as RendererLike, r as XRCameraLike, t as CameraTextureResult } from "./xr-camera-texture-DBwCaKTd.js";
16
- import { D as setDepthCaptureCallback, I as startDepthCapture, L as startImageCapture, M as setTrackingLostCallback, O as setFrameCallback, P as setTrackingStore, R as stopDepthCapture, d as getCamera, f as getCurrentArPose, g as getScene, h as getLiveCss3dManager, j as setTrackingCallbacks, k as setImageCaptureCallback, m as getImageCaptureFrameCount, o as endARSession, p as getDepthSampleCount, t as SessionFeatureOptions, u as getArWorldGroup, v as initAR, z as stopImageCapture } from "./webxr-session-DtAG9srK.js";
17
- import { a as EnableGpsArState, i as EnableGpsArResult, n as EnableGpsArController, o as EnableGpsArStatus, r as EnableGpsArDeps, s as createEnableGpsArController, t as EnableGpsArConfig } from "./enable-gps-ar-CapmADVN.js";
16
+ import { D as setDepthCaptureCallback, I as startDepthCapture, L as startImageCapture, M as setTrackingLostCallback, O as setFrameCallback, P as setTrackingStore, R as stopDepthCapture, d as getCamera, f as getCurrentArPose, g as getScene, h as getLiveCss3dManager, j as setTrackingCallbacks, k as setImageCaptureCallback, m as getImageCaptureFrameCount, o as endARSession, p as getDepthSampleCount, t as SessionFeatureOptions, u as getArWorldGroup, v as initAR, z as stopImageCapture } from "./webxr-session-GjZ2BIpS.js";
17
+ import { a as EnableGpsArState, i as EnableGpsArResult, n as EnableGpsArController, o as EnableGpsArStatus, r as EnableGpsArDeps, s as createEnableGpsArController, t as EnableGpsArConfig } from "./enable-gps-ar-BfUJOgpW.js";
18
18
  import { r as registerFrameUpdate, t as FrameUpdate } from "./frame-loop-CMewS8cY.js";
19
19
  import { n as OccupancyGridOptions, t as OccupancyGrid } from "./occupancy-grid-BRNRaPyT.js";
20
20
  import { i as registerXrFrameUpdate, n as XrFrameUpdate, t as XrFrameContext } from "./xr-frame-loop-BtYytZJg.js";
@@ -34,23 +34,23 @@ import { t as mapWithConcurrencyLimit } from "./concurrency-CO1FQvs3.js";
34
34
  import { t as formatFileSize } from "./format-file-size-CLCZz3lC.js";
35
35
  import { t as listFormatter } from "./list-formatter-RRcBe8Vg.js";
36
36
  import { a as recordWriteFailure, i as recordDepthSample, o as recordingReducer, r as endSession, s as startSession, t as RecordingState } from "./recording-slice-89O07ebs.js";
37
- import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, i as createSession, l as listSessions, o as getSessionHandle, r as checkStorageQuota, s as getSessionsRootHandle, u as resetOpfsStorage } from "./opfs-storage-DYm8WHq7.js";
38
- import { n as StorageBackend, t as CreateSessionResult } from "./storage-backend-C9HLFtgz.js";
39
- import { A as resetTrackingQuality, C as computeResidualConsensus, D as firstAgreementReached, F as snapshotsTrimmed, I as trackingQualityReducer, M as selectRecentAlignments, N as selectTrackingQuality, O as matrixDelta, P as snapshotPushed, S as computeGpsVsFusedDivergence, T as createTrackingQualityListenerMiddleware, _ as TrackingQualityState, a as SlamAppStoreOptions, b as computeCoverage, d as DEFAULT_TRACKING_QUALITY_OPTIONS, g as TrackingQualitySliceState, h as TrackingQualityReport, i as SlamAppStore, j as selectFirstAgreementObservationIndex, k as reportUpdated, m as TrackingQualityOptions, n as SlamAppMiddleware, o as createSlamAppStore, r as SlamAppRootState, s as AlignmentSnapshot, t as SlamAppCombinedState, v as computeCompassAgreement, w as computeTrackingQualityReport, x as computeGpsAccuracy, y as computeConvergence } from "./create-slam-app-store-qNXQ-tq5.js";
40
- import { a as eulerToQuaternion, c as getLastDeviceOrientation, i as createGpsPositionHandler, l as resetCoordinatorState, n as buildRawGpsPoint, o as extractOdomPosition, r as buildRecordGpsEventPayload, s as extractOdomRotation, t as RecordingCoordinatorConfig, u as updateDeviceOrientation } from "./gps-event-coordinator-BDIQde2x.js";
37
+ import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, i as createSession, l as listSessions, o as getSessionHandle, r as checkStorageQuota, s as getSessionsRootHandle, u as resetOpfsStorage } from "./opfs-storage-D5zAn_lx.js";
38
+ import { n as StorageBackend, t as CreateSessionResult } from "./storage-backend-Do6YDpNo.js";
39
+ import { A as resetTrackingQuality, C as computeResidualConsensus, D as firstAgreementReached, F as snapshotsTrimmed, I as trackingQualityReducer, M as selectRecentAlignments, N as selectTrackingQuality, O as matrixDelta, P as snapshotPushed, S as computeGpsVsFusedDivergence, T as createTrackingQualityListenerMiddleware, _ as TrackingQualityState, a as SlamAppStoreOptions, b as computeCoverage, d as DEFAULT_TRACKING_QUALITY_OPTIONS, g as TrackingQualitySliceState, h as TrackingQualityReport, i as SlamAppStore, j as selectFirstAgreementObservationIndex, k as reportUpdated, m as TrackingQualityOptions, n as SlamAppMiddleware, o as createSlamAppStore, r as SlamAppRootState, s as AlignmentSnapshot, t as SlamAppCombinedState, v as computeCompassAgreement, w as computeTrackingQualityReport, x as computeGpsAccuracy, y as computeConvergence } from "./create-slam-app-store-BljusOua.js";
40
+ import { a as eulerToQuaternion, c as getLastDeviceOrientation, i as createGpsPositionHandler, l as resetCoordinatorState, n as buildRawGpsPoint, o as extractOdomPosition, r as buildRecordGpsEventPayload, s as extractOdomRotation, t as RecordingCoordinatorConfig, u as updateDeviceOrientation } from "./gps-event-coordinator-CWIDOk4U.js";
41
41
  import { a as ZipActionEntry, d as loadSessionMetadataFromBlob, f as readZipEntries, i as RecordedAction, l as loadGpsPathFromBlob, n as GpsPathCoord, r as MAX_ACTION_FILE_SIZE, s as loadActionsFromZip } from "./zip-reader-DSEXt7K6.js";
42
- import { n as replayRecording } from "./recording-replayer-BL-x-7k0.js";
43
- import { a as ReplayAction, c as computeInterActionDelay, i as ProgressCallback, l as extractActionTimestamp, n as DEFAULT_MAX_DELAY_MS, o as ReplayEngine, r as ErrorCallback, s as ReplayState, t as CompleteCallback } from "./replay-engine-BRqszuQ9.js";
42
+ import { n as replayRecording } from "./recording-replayer-r0DZ9ALp.js";
43
+ import { a as ReplayAction, c as computeInterActionDelay, i as ProgressCallback, l as extractActionTimestamp, n as DEFAULT_MAX_DELAY_MS, o as ReplayEngine, r as ErrorCallback, s as ReplayState, t as CompleteCallback } from "./replay-engine-XpDa0dy1.js";
44
44
  import { n as MapDataInput, r as buildMapData, t as MapData } from "./map-data-CkloBxIl.js";
45
- import { t as SubscribableStore } from "./subscribe-to-selector-CP3BKSbF.js";
46
- import { n as wireStoreSubscribers, t as StoreSubscriberDeps } from "./store-subscribers-rrkLkFTt.js";
47
- import { c as calcRelativeCoordsInMeters, d as OnboardingGuidance, f as OnboardingPhase, l as recordGpsEvent, m as selectOnboardingGuidance, p as computeOnboardingGuidance, s as add2dImage, u as setZeroPos } from "./index-KJq2amHF.js";
48
- import { t as NullStorageBackend } from "./null-storage-backend-CxEjZHRW.js";
49
- import { t as OpfsStorageBackend } from "./opfs-storage-backend-CjSAuqg_.js";
50
- import { c as resetForNewSession, d as startSession$1, f as verifyWriteAccess, l as resetStorageState, m as writeFrame, n as WriteAccessResult, o as initStorage, p as writeAction } from "./file-system-C_eqiEA8.js";
51
- import { n as formatFrameFilename, r as formatTimestamp, t as formatActionFilename } from "./file-system-utils-DyAmcuvX.js";
52
- import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportAndDownloadSession, r as ZipExportContributor, s as exportSessionAsZip, t as ExportSessionAsZipOptions } from "./zip-export-D_5HAvFz.js";
53
- import { n as ArWorldGroupAlignmentOptions, r as enableArWorldGroupAlignment, t as ArWorldGroupAlignmentHandle } from "./ar-world-group-alignment-ColHB_5A.js";
45
+ import { t as SubscribableStore } from "./subscribe-to-selector-CZ6k1NFP.js";
46
+ import { n as wireStoreSubscribers, t as StoreSubscriberDeps } from "./store-subscribers-0YWyOLvV.js";
47
+ import { c as calcRelativeCoordsInMeters, d as OnboardingGuidance, f as OnboardingPhase, l as recordGpsEvent, m as selectOnboardingGuidance, p as computeOnboardingGuidance, s as add2dImage, u as setZeroPos } from "./index-BYYUdf9v.js";
48
+ import { t as NullStorageBackend } from "./null-storage-backend-uKQE8tl7.js";
49
+ import { t as OpfsStorageBackend } from "./opfs-storage-backend-6aYMUZlJ.js";
50
+ import { c as resetForNewSession, d as startSession$1, f as verifyWriteAccess, l as resetStorageState, m as writeFrame, n as WriteAccessResult, o as initStorage, p as writeAction } from "./file-system-CwXTNHmB.js";
51
+ import { a as formatTimestamp, i as formatFrameFilename, r as formatActionFilename } from "./file-system-utils-CXIoL-DM.js";
52
+ import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportAndDownloadSession, r as ZipExportContributor, s as exportSessionAsZip, t as ExportSessionAsZipOptions } from "./zip-export-G14hkSPG.js";
53
+ import { n as ArWorldGroupAlignmentOptions, r as enableArWorldGroupAlignment, t as ArWorldGroupAlignmentHandle } from "./ar-world-group-alignment-C9lwwIyI.js";
54
54
  import { i as createGpsCompassCubes, n as COMPASS_CUBE_SIZE, r as GpsCompassCubes, t as COMPASS_CUBE_DISTANCE } from "./gps-compass-cubes-BM1uGiYV.js";
55
55
  import { i as isSphereInCameraFrustum, n as isObjectInCameraFrustum, r as isPointInCameraFrustum, t as buildCameraFrustum } from "./frustum-visibility-CmI96ESS.js";
56
56
  import { n as worldNueToGps, t as nueToArLocal } from "./frame-conversions-BfsafGWR.js";
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import { requestOrientationPermission, startGpsWatch, startOrientationWatch, sto
17
17
  import { WEBXR_TO_NUE } from "./ar/webxr-nue-basis.js";
18
18
  import { DEFAULT_CAPTURE_CONFIG, ImageCaptureManager, MIN_VALID_IMAGE_BYTES } from "./ar/image-capture.js";
19
19
  import { clearLastRestartedPayload, originReset, poseLost, poseReceived, resetTracking, selectLastRestartedPayload, selectLastSensorOrientation, selectLastValidPose, selectLostFrameCount, selectTrackingPhase, trackingReducer } from "./state/tracking-slice.js";
20
- import { A as setTrackingLostCallback, D as setImageCaptureCallback, E as setFrameCallback, F as startImageCapture, I as stopDepthCapture, L as stopImageCapture, M as setTrackingStore, P as startDepthCapture, T as setDepthCaptureCallback, c as getArWorldGroup, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, i as endARSession, k as setTrackingCallbacks, l as getCamera, m as getScene, p as getLiveCss3dManager, u as getCurrentArPose } from "./webxr-session-QhcSSub5.js";
20
+ import { A as setTrackingLostCallback, D as setImageCaptureCallback, E as setFrameCallback, F as startImageCapture, I as stopDepthCapture, L as stopImageCapture, M as setTrackingStore, P as startDepthCapture, T as setDepthCaptureCallback, c as getArWorldGroup, d as getDepthSampleCount, f as getImageCaptureFrameCount, g as initAR, i as endARSession, k as setTrackingCallbacks, l as getCamera, m as getScene, p as getLiveCss3dManager, u as getCurrentArPose } from "./webxr-session-TIaD883f.js";
21
21
  import { acquireCameraTexture } from "./ar/xr-camera-texture.js";
22
22
  import { DEFAULT_RECORDING_OPTIONS, DEPTH_CONSTRAINTS, IMAGE_CONSTRAINTS, STORAGE_KEY, cloneRecordingOptions, loadRecordingOptions, resetRecordingOptions, saveRecordingOptions, validateDepthOptions, validateImageOptions, validateRecordingOptions } from "./state/recording-options.js";
23
23
  import { SCENE_NODE } from "./ar/scene-node-names.js";
@@ -1,5 +1,5 @@
1
- import { n as SessionMetadata } from "./opfs-storage-DYm8WHq7.js";
2
- import { n as StorageBackend, t as CreateSessionResult } from "./storage-backend-C9HLFtgz.js";
1
+ import { n as SessionMetadata } from "./opfs-storage-D5zAn_lx.js";
2
+ import { n as StorageBackend, t as CreateSessionResult } from "./storage-backend-Do6YDpNo.js";
3
3
 
4
4
  //#region ../src/storage/null-storage-backend.d.ts
5
5
  declare class NullStorageBackend implements StorageBackend {
@@ -14,7 +14,7 @@
14
14
  * │ ├── actions/
15
15
  * │ │ ├── 000001.json
16
16
  * │ │ └── ...
17
- * │ └── frames/
17
+ * │ └── images/ (legacy recordings: frames/)
18
18
  * │ ├── frame-000001.jpg
19
19
  * │ └── ...
20
20
  * └── ...
@@ -117,7 +117,7 @@ declare function getAppRootHandle(): FileSystemDirectoryHandle | null;
117
117
  * Creates the directory structure:
118
118
  * - /gps-plus-slam/sessions/recording-{timestamp}/
119
119
  * - /gps-plus-slam/sessions/recording-{timestamp}/actions/
120
- * - /gps-plus-slam/sessions/recording-{timestamp}/frames/
120
+ * - /gps-plus-slam/sessions/recording-{timestamp}/images/ (legacy: frames/)
121
121
  *
122
122
  * @param timestamp - Session start time (used for folder naming)
123
123
  * @param _contextTag - Opaque tag; not used by the flat layout but accepted
@@ -1,5 +1,5 @@
1
- import { n as SessionMetadata } from "./opfs-storage-DYm8WHq7.js";
2
- import { n as StorageBackend, t as CreateSessionResult } from "./storage-backend-C9HLFtgz.js";
1
+ import { n as SessionMetadata } from "./opfs-storage-D5zAn_lx.js";
2
+ import { n as StorageBackend, t as CreateSessionResult } from "./storage-backend-Do6YDpNo.js";
3
3
 
4
4
  //#region ../src/storage/opfs-storage-backend.d.ts
5
5
  declare class OpfsStorageBackend implements StorageBackend {
@@ -1,4 +1,4 @@
1
- import { n as StorageBackend } from "./storage-backend-C9HLFtgz.js";
1
+ import { n as StorageBackend } from "./storage-backend-Do6YDpNo.js";
2
2
  import { Middleware } from "@reduxjs/toolkit";
3
3
 
4
4
  //#region ../src/state/persistence-middleware.d.ts
@@ -1,4 +1,4 @@
1
- import { L as CombinedRootState } from "./create-slam-app-store-qNXQ-tq5.js";
1
+ import { L as CombinedRootState } from "./create-slam-app-store-BljusOua.js";
2
2
  import { i as RecordedAction } from "./zip-reader-DSEXt7K6.js";
3
3
 
4
4
  //#region ../src/state/recording-replayer.d.ts
@@ -1,4 +1,4 @@
1
- import { i as SlamAppStore } from "./create-slam-app-store-qNXQ-tq5.js";
1
+ import { i as SlamAppStore } from "./create-slam-app-store-BljusOua.js";
2
2
  import { ReducersMapObject } from "@reduxjs/toolkit";
3
3
 
4
4
  //#region ../src/state/replay-engine.d.ts
@@ -1,2 +1,2 @@
1
- import { a as selectOdometryRotations, i as selectOdometryPositions, n as selectFrameTilesInWebXR, o as selectZeroReference, r as selectGpsPositions, t as selectAlignmentMatrix } from "../app-selectors-CcZ5UV-8.js";
1
+ import { a as selectOdometryRotations, i as selectOdometryPositions, n as selectFrameTilesInWebXR, o as selectZeroReference, r as selectGpsPositions, t as selectAlignmentMatrix } from "../app-selectors-B8VQoMDY.js";
2
2
  export { selectAlignmentMatrix, selectFrameTilesInWebXR, selectGpsPositions, selectOdometryPositions, selectOdometryRotations, selectZeroReference };
@@ -58,7 +58,9 @@ const selectFrameTilesInWebXR = createSelector([selectOdometryPathPoints], (poin
58
58
  position: nueToWebXR(p.position),
59
59
  rotation: nueQuaternionToWebXR(p.rotation),
60
60
  screenRotation: p.screenRotation,
61
- capturedAt: p.capturedAt
61
+ capturedAt: p.capturedAt,
62
+ width: p.width,
63
+ height: p.height
62
64
  }));
63
65
  });
64
66
  //#endregion
@@ -1,2 +1,2 @@
1
- import { L as CombinedRootState } from "../create-slam-app-store-qNXQ-tq5.js";
1
+ import { L as CombinedRootState } from "../create-slam-app-store-BljusOua.js";
2
2
  export { CombinedRootState };
@@ -1,2 +1,2 @@
1
- import { a as SlamAppStoreOptions, i as SlamAppStore, n as SlamAppMiddleware, o as createSlamAppStore, r as SlamAppRootState, t as SlamAppCombinedState } from "../create-slam-app-store-qNXQ-tq5.js";
1
+ import { a as SlamAppStoreOptions, i as SlamAppStore, n as SlamAppMiddleware, o as createSlamAppStore, r as SlamAppRootState, t as SlamAppCombinedState } from "../create-slam-app-store-BljusOua.js";
2
2
  export { SlamAppCombinedState, SlamAppMiddleware, SlamAppRootState, SlamAppStore, SlamAppStoreOptions, createSlamAppStore };
@@ -1,4 +1,4 @@
1
1
  import { t as ARPose } from "../ar-types-Dan1MVTi.js";
2
- import { o as extractOdomPosition, s as extractOdomRotation } from "../gps-event-coordinator-BDIQde2x.js";
2
+ import { o as extractOdomPosition, s as extractOdomRotation } from "../gps-event-coordinator-CWIDOk4U.js";
3
3
  import { i as captureGpsAnchorSample, n as GpsAnchorSample, r as GpsAnchorSampleGpsPoint, t as CaptureGpsAnchorSampleOptions } from "../gps-ar-pose-sampler-DVb96iOy.js";
4
4
  export { ARPose, CaptureGpsAnchorSampleOptions, GpsAnchorSample, GpsAnchorSampleGpsPoint, captureGpsAnchorSample, extractOdomPosition, extractOdomRotation };
@@ -1,2 +1,2 @@
1
- import { a as eulerToQuaternion, c as getLastDeviceOrientation, i as createGpsPositionHandler, l as resetCoordinatorState, n as buildRawGpsPoint, o as extractOdomPosition, r as buildRecordGpsEventPayload, s as extractOdomRotation, t as RecordingCoordinatorConfig, u as updateDeviceOrientation } from "../gps-event-coordinator-BDIQde2x.js";
1
+ import { a as eulerToQuaternion, c as getLastDeviceOrientation, i as createGpsPositionHandler, l as resetCoordinatorState, n as buildRawGpsPoint, o as extractOdomPosition, r as buildRecordGpsEventPayload, s as extractOdomRotation, t as RecordingCoordinatorConfig, u as updateDeviceOrientation } from "../gps-event-coordinator-CWIDOk4U.js";
2
2
  export { RecordingCoordinatorConfig, buildRawGpsPoint, buildRecordGpsEventPayload, createGpsPositionHandler, eulerToQuaternion, extractOdomPosition, extractOdomRotation, getLastDeviceOrientation, resetCoordinatorState, updateDeviceOrientation };
@@ -2,16 +2,16 @@ import { i as DepthSample, r as DepthPoint } from "../ar-types-Dan1MVTi.js";
2
2
  import { _ as validateRecordingOptions, a as IMAGE_CONSTRAINTS, c as RecordingOptionsInput, d as loadRecordingOptions, f as resetRecordingOptions, g as validateImageOptions, h as validateDepthOptions, i as DepthCaptureOptions, l as STORAGE_KEY, n as DEFAULT_RECORDING_OPTIONS, o as ImageCaptureOptions, p as saveRecordingOptions, r as DEPTH_CONSTRAINTS, u as cloneRecordingOptions } from "../recording-options-DJBXuMxV.js";
3
3
  import { a as TrackingSliceState, c as poseLost, d as selectLastRestartedPayload, f as selectLastSensorOrientation, g as trackingReducer, h as selectTrackingPhase, i as TrackingPhase, l as poseReceived, m as selectLostFrameCount, n as PoseReceivedPayload, o as clearLastRestartedPayload, p as selectLastValidPose, r as ResetTransformData, s as originReset, t as DeviceOrientation, u as resetTracking } from "../tracking-slice-CdK8c-8P.js";
4
4
  import { a as recordWriteFailure, i as recordDepthSample, n as SessionMetadata$1, o as recordingReducer, r as endSession, s as startSession, t as RecordingState } from "../recording-slice-89O07ebs.js";
5
- import { n as SessionMetadata } from "../opfs-storage-DYm8WHq7.js";
6
- import { n as StorageBackend } from "../storage-backend-C9HLFtgz.js";
7
- import { A as resetTrackingQuality, C as computeResidualConsensus, D as firstAgreementReached, E as degradedCountUpdated, F as snapshotsTrimmed, I as trackingQualityReducer, M as selectRecentAlignments, N as selectTrackingQuality, O as matrixDelta, P as snapshotPushed, S as computeGpsVsFusedDivergence, T as createTrackingQualityListenerMiddleware, _ as TrackingQualityState, a as SlamAppStoreOptions, b as computeCoverage, d as DEFAULT_TRACKING_QUALITY_OPTIONS, g as TrackingQualitySliceState, h as TrackingQualityReport, i as SlamAppStore, j as selectFirstAgreementObservationIndex, k as reportUpdated, m as TrackingQualityOptions, n as SlamAppMiddleware, o as createSlamAppStore, r as SlamAppRootState, s as AlignmentSnapshot, t as SlamAppCombinedState, v as computeCompassAgreement, w as computeTrackingQualityReport, x as computeGpsAccuracy, y as computeConvergence } from "../create-slam-app-store-qNXQ-tq5.js";
8
- import { a as eulerToQuaternion, c as getLastDeviceOrientation, i as createGpsPositionHandler, l as resetCoordinatorState, n as buildRawGpsPoint, o as extractOdomPosition, r as buildRecordGpsEventPayload, s as extractOdomRotation, t as RecordingCoordinatorConfig, u as updateDeviceOrientation } from "../gps-event-coordinator-BDIQde2x.js";
5
+ import { n as SessionMetadata } from "../opfs-storage-D5zAn_lx.js";
6
+ import { n as StorageBackend } from "../storage-backend-Do6YDpNo.js";
7
+ import { A as resetTrackingQuality, C as computeResidualConsensus, D as firstAgreementReached, E as degradedCountUpdated, F as snapshotsTrimmed, I as trackingQualityReducer, M as selectRecentAlignments, N as selectTrackingQuality, O as matrixDelta, P as snapshotPushed, S as computeGpsVsFusedDivergence, T as createTrackingQualityListenerMiddleware, _ as TrackingQualityState, a as SlamAppStoreOptions, b as computeCoverage, d as DEFAULT_TRACKING_QUALITY_OPTIONS, g as TrackingQualitySliceState, h as TrackingQualityReport, i as SlamAppStore, j as selectFirstAgreementObservationIndex, k as reportUpdated, m as TrackingQualityOptions, n as SlamAppMiddleware, o as createSlamAppStore, r as SlamAppRootState, s as AlignmentSnapshot, t as SlamAppCombinedState, v as computeCompassAgreement, w as computeTrackingQualityReport, x as computeGpsAccuracy, y as computeConvergence } from "../create-slam-app-store-BljusOua.js";
8
+ import { a as eulerToQuaternion, c as getLastDeviceOrientation, i as createGpsPositionHandler, l as resetCoordinatorState, n as buildRawGpsPoint, o as extractOdomPosition, r as buildRecordGpsEventPayload, s as extractOdomRotation, t as RecordingCoordinatorConfig, u as updateDeviceOrientation } from "../gps-event-coordinator-CWIDOk4U.js";
9
9
  import { i as captureGpsAnchorSample, n as GpsAnchorSample, r as GpsAnchorSampleGpsPoint, t as CaptureGpsAnchorSampleOptions } from "../gps-ar-pose-sampler-DVb96iOy.js";
10
- import { n as replayRecording, t as ReplayRecordingOptions } from "../recording-replayer-BL-x-7k0.js";
11
- import { n as createPersistenceMiddleware, r as slicePrefixOf, t as PersistenceMiddlewareOptions } from "../persistence-middleware-DwyzgfWr.js";
12
- import { a as ReplayAction, c as computeInterActionDelay, i as ProgressCallback, l as extractActionTimestamp, n as DEFAULT_MAX_DELAY_MS, o as ReplayEngine, r as ErrorCallback, s as ReplayState, t as CompleteCallback } from "../replay-engine-BRqszuQ9.js";
13
- import { n as subscribeToSelector, t as SubscribableStore } from "../subscribe-to-selector-CP3BKSbF.js";
14
- import { n as wireStoreSubscribers, t as StoreSubscriberDeps } from "../store-subscribers-rrkLkFTt.js";
15
- import { a as selectOdometryRotations, i as selectOdometryPositions, n as selectFrameTilesInWebXR, o as selectZeroReference, r as selectGpsPositions, t as selectAlignmentMatrix } from "../app-selectors-CcZ5UV-8.js";
16
- import { a as RawGpsPoint, c as calcRelativeCoordsInMeters, d as OnboardingGuidance, f as OnboardingPhase, i as RawDeviceOrientation, l as recordGpsEvent, m as selectOnboardingGuidance, n as GpsPoint, o as RecordGpsEventPayload, p as computeOnboardingGuidance, r as LatLong, s as add2dImage, t as Add2dImagePayload, u as setZeroPos } from "../index-KJq2amHF.js";
10
+ import { n as replayRecording, t as ReplayRecordingOptions } from "../recording-replayer-r0DZ9ALp.js";
11
+ import { n as createPersistenceMiddleware, r as slicePrefixOf, t as PersistenceMiddlewareOptions } from "../persistence-middleware-B9ei4Nhx.js";
12
+ import { a as ReplayAction, c as computeInterActionDelay, i as ProgressCallback, l as extractActionTimestamp, n as DEFAULT_MAX_DELAY_MS, o as ReplayEngine, r as ErrorCallback, s as ReplayState, t as CompleteCallback } from "../replay-engine-XpDa0dy1.js";
13
+ import { n as subscribeToSelector, t as SubscribableStore } from "../subscribe-to-selector-CZ6k1NFP.js";
14
+ import { n as wireStoreSubscribers, t as StoreSubscriberDeps } from "../store-subscribers-0YWyOLvV.js";
15
+ import { a as selectOdometryRotations, i as selectOdometryPositions, n as selectFrameTilesInWebXR, o as selectZeroReference, r as selectGpsPositions, t as selectAlignmentMatrix } from "../app-selectors-B8VQoMDY.js";
16
+ import { a as RawGpsPoint, c as calcRelativeCoordsInMeters, d as OnboardingGuidance, f as OnboardingPhase, i as RawDeviceOrientation, l as recordGpsEvent, m as selectOnboardingGuidance, n as GpsPoint, o as RecordGpsEventPayload, p as computeOnboardingGuidance, r as LatLong, s as add2dImage, t as Add2dImagePayload, u as setZeroPos } from "../index-BYYUdf9v.js";
17
17
  export { Add2dImagePayload, AlignmentSnapshot, CaptureGpsAnchorSampleOptions, CompleteCallback, DEFAULT_MAX_DELAY_MS, DEFAULT_RECORDING_OPTIONS, DEFAULT_TRACKING_QUALITY_OPTIONS, DEPTH_CONSTRAINTS, DepthCaptureOptions, DepthPoint, DepthSample, DeviceOrientation, ErrorCallback, GpsAnchorSample, GpsAnchorSampleGpsPoint, GpsPoint, IMAGE_CONSTRAINTS, ImageCaptureOptions, LatLong, OnboardingGuidance, OnboardingPhase, SessionMetadata as OpfsSessionMetadata, PersistenceMiddlewareOptions, PoseReceivedPayload, ProgressCallback, RawDeviceOrientation, RawGpsPoint, RecordGpsEventPayload, RecordingCoordinatorConfig, RecordingOptionsInput, RecordingState, ReplayAction, ReplayEngine, ReplayRecordingOptions, ReplayState, ResetTransformData, STORAGE_KEY, SessionMetadata$1 as SessionMetadata, SlamAppCombinedState, SlamAppMiddleware, SlamAppRootState, SlamAppStore, SlamAppStoreOptions, StorageBackend, StoreSubscriberDeps, SubscribableStore, TrackingPhase, TrackingQualityOptions, TrackingQualityReport, TrackingQualitySliceState, TrackingQualityState, TrackingSliceState, add2dImage, buildRawGpsPoint, buildRecordGpsEventPayload, calcRelativeCoordsInMeters, captureGpsAnchorSample, clearLastRestartedPayload, cloneRecordingOptions, computeCompassAgreement, computeConvergence, computeCoverage, computeGpsAccuracy, computeGpsVsFusedDivergence, computeInterActionDelay, computeOnboardingGuidance, computeResidualConsensus, computeTrackingQualityReport, createGpsPositionHandler, createPersistenceMiddleware, createSlamAppStore, createTrackingQualityListenerMiddleware, degradedCountUpdated, endSession, eulerToQuaternion, extractActionTimestamp, extractOdomPosition, extractOdomRotation, firstAgreementReached, getLastDeviceOrientation, loadRecordingOptions, matrixDelta, originReset, poseLost, poseReceived, recordDepthSample, recordGpsEvent, recordWriteFailure, recordingReducer, replayRecording, reportUpdated, resetCoordinatorState, resetRecordingOptions, resetTracking, resetTrackingQuality, saveRecordingOptions, selectAlignmentMatrix, selectFirstAgreementObservationIndex, selectFrameTilesInWebXR, selectGpsPositions, selectLastRestartedPayload, selectLastSensorOrientation, selectLastValidPose, selectLostFrameCount, selectOdometryPositions, selectOdometryRotations, selectOnboardingGuidance, selectRecentAlignments, selectTrackingPhase, selectTrackingQuality, selectZeroReference, setZeroPos, slicePrefixOf, snapshotPushed, snapshotsTrimmed, startSession, subscribeToSelector, trackingQualityReducer, trackingReducer, updateDeviceOrientation, validateDepthOptions, validateImageOptions, validateRecordingOptions, wireStoreSubscribers };
@@ -1,2 +1,2 @@
1
- import { n as createPersistenceMiddleware, r as slicePrefixOf, t as PersistenceMiddlewareOptions } from "../persistence-middleware-DwyzgfWr.js";
1
+ import { n as createPersistenceMiddleware, r as slicePrefixOf, t as PersistenceMiddlewareOptions } from "../persistence-middleware-B9ei4Nhx.js";
2
2
  export { PersistenceMiddlewareOptions, createPersistenceMiddleware, slicePrefixOf };
@@ -1,3 +1,3 @@
1
- import { L as CombinedRootState } from "../create-slam-app-store-qNXQ-tq5.js";
2
- import { n as replayRecording, t as ReplayRecordingOptions } from "../recording-replayer-BL-x-7k0.js";
1
+ import { L as CombinedRootState } from "../create-slam-app-store-BljusOua.js";
2
+ import { n as replayRecording, t as ReplayRecordingOptions } from "../recording-replayer-r0DZ9ALp.js";
3
3
  export { CombinedRootState, ReplayRecordingOptions, replayRecording };
@@ -1,2 +1,2 @@
1
- import { a as ReplayAction, c as computeInterActionDelay, i as ProgressCallback, l as extractActionTimestamp, n as DEFAULT_MAX_DELAY_MS, o as ReplayEngine, r as ErrorCallback, s as ReplayState, t as CompleteCallback } from "../replay-engine-BRqszuQ9.js";
1
+ import { a as ReplayAction, c as computeInterActionDelay, i as ProgressCallback, l as extractActionTimestamp, n as DEFAULT_MAX_DELAY_MS, o as ReplayEngine, r as ErrorCallback, s as ReplayState, t as CompleteCallback } from "../replay-engine-XpDa0dy1.js";
2
2
  export { CompleteCallback, DEFAULT_MAX_DELAY_MS, ErrorCallback, ProgressCallback, ReplayAction, ReplayEngine, ReplayState, computeInterActionDelay, extractActionTimestamp };
@@ -1,3 +1,3 @@
1
- import { t as SubscribableStore } from "../subscribe-to-selector-CP3BKSbF.js";
2
- import { n as wireStoreSubscribers, t as StoreSubscriberDeps } from "../store-subscribers-rrkLkFTt.js";
1
+ import { t as SubscribableStore } from "../subscribe-to-selector-CZ6k1NFP.js";
2
+ import { n as wireStoreSubscribers, t as StoreSubscriberDeps } from "../store-subscribers-0YWyOLvV.js";
3
3
  export { StoreSubscriberDeps, SubscribableStore, wireStoreSubscribers };
@@ -1,2 +1,2 @@
1
- import { n as subscribeToSelector, t as SubscribableStore } from "../subscribe-to-selector-CP3BKSbF.js";
1
+ import { n as subscribeToSelector, t as SubscribableStore } from "../subscribe-to-selector-CZ6k1NFP.js";
2
2
  export { SubscribableStore, subscribeToSelector };
@@ -1,2 +1,2 @@
1
- import { A as resetTrackingQuality, C as computeResidualConsensus, D as firstAgreementReached, E as degradedCountUpdated, F as snapshotsTrimmed, I as trackingQualityReducer, M as selectRecentAlignments, N as selectTrackingQuality, O as matrixDelta, P as snapshotPushed, S as computeGpsVsFusedDivergence, T as createTrackingQualityListenerMiddleware, _ as TrackingQualityState, b as computeCoverage, c as CompassAgreementResult, d as DEFAULT_TRACKING_QUALITY_OPTIONS, f as GpsAccuracyResult, g as TrackingQualitySliceState, h as TrackingQualityReport, j as selectFirstAgreementObservationIndex, k as reportUpdated, l as ConvergenceResult, m as TrackingQualityOptions, p as ResidualConsensusResult, s as AlignmentSnapshot, u as CoverageResult, v as computeCompassAgreement, w as computeTrackingQualityReport, x as computeGpsAccuracy, y as computeConvergence } from "../create-slam-app-store-qNXQ-tq5.js";
1
+ import { A as resetTrackingQuality, C as computeResidualConsensus, D as firstAgreementReached, E as degradedCountUpdated, F as snapshotsTrimmed, I as trackingQualityReducer, M as selectRecentAlignments, N as selectTrackingQuality, O as matrixDelta, P as snapshotPushed, S as computeGpsVsFusedDivergence, T as createTrackingQualityListenerMiddleware, _ as TrackingQualityState, b as computeCoverage, c as CompassAgreementResult, d as DEFAULT_TRACKING_QUALITY_OPTIONS, f as GpsAccuracyResult, g as TrackingQualitySliceState, h as TrackingQualityReport, j as selectFirstAgreementObservationIndex, k as reportUpdated, l as ConvergenceResult, m as TrackingQualityOptions, p as ResidualConsensusResult, s as AlignmentSnapshot, u as CoverageResult, v as computeCompassAgreement, w as computeTrackingQualityReport, x as computeGpsAccuracy, y as computeConvergence } from "../create-slam-app-store-BljusOua.js";
2
2
  export { AlignmentSnapshot, CompassAgreementResult, ConvergenceResult, CoverageResult, DEFAULT_TRACKING_QUALITY_OPTIONS, GpsAccuracyResult, ResidualConsensusResult, TrackingQualityOptions, TrackingQualityReport, TrackingQualitySliceState, TrackingQualityState, computeCompassAgreement, computeConvergence, computeCoverage, computeGpsAccuracy, computeGpsVsFusedDivergence, computeResidualConsensus, computeTrackingQualityReport, createTrackingQualityListenerMiddleware, degradedCountUpdated, firstAgreementReached, matrixDelta, reportUpdated, resetTrackingQuality, selectFirstAgreementObservationIndex, selectRecentAlignments, selectTrackingQuality, snapshotPushed, snapshotsTrimmed, trackingQualityReducer };
@@ -1,2 +1,2 @@
1
- import { n as formatFrameFilename, r as formatTimestamp, t as formatActionFilename } from "../file-system-utils-DyAmcuvX.js";
2
- export { formatActionFilename, formatFrameFilename, formatTimestamp };
1
+ import { a as formatTimestamp, i as formatFrameFilename, n as SESSION_IMAGES_DIR, r as formatActionFilename, t as LEGACY_SESSION_IMAGES_DIR } from "../file-system-utils-CXIoL-DM.js";
2
+ export { LEGACY_SESSION_IMAGES_DIR, SESSION_IMAGES_DIR, formatActionFilename, formatFrameFilename, formatTimestamp };
@@ -27,5 +27,21 @@ function formatActionFilename(index) {
27
27
  function formatFrameFilename(index) {
28
28
  return `frame-${String(index).padStart(6, "0")}.jpg`;
29
29
  }
30
+ /**
31
+ * Canonical session subdirectory for captured camera images, written by new
32
+ * recordings. Renamed from {@link LEGACY_SESSION_IMAGES_DIR} so an exported ZIP
33
+ * is a textbook COLMAP tree (`images/frame-NNNNNN.jpg` next to `sparse/0/`).
34
+ * Both the OPFS write path and the recorder's persisted `imageFile` value must
35
+ * use THIS constant so a recording stays self-consistent (COLMAP export plan
36
+ * Q5, gps-plus-slam/GpsPlusSlamJs_Docs/docs/2026-06-13-colmap-export-plan.md).
37
+ */
38
+ const SESSION_IMAGES_DIR = "images";
39
+ /**
40
+ * The pre-2026-06 session image subdirectory. Recordings made before the
41
+ * {@link SESSION_IMAGES_DIR} rename store frames under `frames/` (in both the
42
+ * on-disk dir and the persisted `imageFile`); readers fall back to this prefix
43
+ * so old recordings still replay.
44
+ */
45
+ const LEGACY_SESSION_IMAGES_DIR = "frames";
30
46
  //#endregion
31
- export { formatActionFilename, formatFrameFilename, formatTimestamp };
47
+ export { LEGACY_SESSION_IMAGES_DIR, SESSION_IMAGES_DIR, formatActionFilename, formatFrameFilename, formatTimestamp };
@@ -1,2 +1,2 @@
1
- import { a as getCurrentScenarioHandle, c as resetForNewSession, d as startSession, f as verifyWriteAccess, h as writeSessionMetadata, i as ensureScenarioDirectory, l as resetStorageState, m as writeFrame, n as WriteAccessResult, o as initStorage, p as writeAction, r as clearRefPointsCacheForAllScenarios, s as listSessions, t as ClearRefPointsCacheResult, u as setCurrentScenario } from "../file-system-C_eqiEA8.js";
1
+ import { a as getCurrentScenarioHandle, c as resetForNewSession, d as startSession, f as verifyWriteAccess, h as writeSessionMetadata, i as ensureScenarioDirectory, l as resetStorageState, m as writeFrame, n as WriteAccessResult, o as initStorage, p as writeAction, r as clearRefPointsCacheForAllScenarios, s as listSessions, t as ClearRefPointsCacheResult, u as setCurrentScenario } from "../file-system-CwXTNHmB.js";
2
2
  export { ClearRefPointsCacheResult, WriteAccessResult, clearRefPointsCacheForAllScenarios, ensureScenarioDirectory, getCurrentScenarioHandle, initStorage, listSessions, resetForNewSession, resetStorageState, setCurrentScenario, startSession, verifyWriteAccess, writeAction, writeFrame, writeSessionMetadata };
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from "../utils/logger.js";
2
2
  import { setFileSystemState } from "../sensors/permission-checker.js";
3
- import { formatTimestamp } from "./file-system-utils.js";
3
+ import { SESSION_IMAGES_DIR, formatTimestamp } from "./file-system-utils.js";
4
4
  import { createSession, getAppRootHandle, initOpfsStorage, listSessions as listSessions$1, resetOpfsStorage, resetSessionHandles, setSessionHandles, writeAction as writeAction$1, writeFrame as writeFrame$1, writeSessionMetadata as writeSessionMetadata$1 } from "./opfs-storage.js";
5
5
  //#region ../src/storage/file-system.ts
6
6
  /**
@@ -137,7 +137,7 @@ async function startSession(scenarioName) {
137
137
  currentScenarioHandle = scenarioHandle;
138
138
  const sessionName = `recording-${formatTimestamp(/* @__PURE__ */ new Date())}`;
139
139
  const sessionHandle = await scenarioHandle.getDirectoryHandle(sessionName, { create: true });
140
- setSessionHandles(sessionHandle, await sessionHandle.getDirectoryHandle("actions", { create: true }), await sessionHandle.getDirectoryHandle("frames", { create: true }));
140
+ setSessionHandles(sessionHandle, await sessionHandle.getDirectoryHandle("actions", { create: true }), await sessionHandle.getDirectoryHandle(SESSION_IMAGES_DIR, { create: true }));
141
141
  _currentScenarioName = scenarioName;
142
142
  log.info("Session started:", `${scenarioName}/${sessionName}`);
143
143
  return {
@@ -1,9 +1,9 @@
1
- import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, h as writeSessionMetadata$1, i as createSession, l as listSessions, n as SessionMetadata, o as getSessionHandle, r as checkStorageQuota, s as getSessionsRootHandle, u as resetOpfsStorage } from "../opfs-storage-DYm8WHq7.js";
2
- import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-C9HLFtgz.js";
1
+ import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, h as writeSessionMetadata$1, i as createSession, l as listSessions, n as SessionMetadata, o as getSessionHandle, r as checkStorageQuota, s as getSessionsRootHandle, u as resetOpfsStorage } from "../opfs-storage-D5zAn_lx.js";
2
+ import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-Do6YDpNo.js";
3
3
  import { a as ZipActionEntry, c as loadEntriesFromSubdir, d as loadSessionMetadataFromBlob, f as readZipEntries, i as RecordedAction, l as loadGpsPathFromBlob, n as GpsPathCoord, o as ZipSubdirEntry, r as MAX_ACTION_FILE_SIZE, s as loadActionsFromZip, t as Entry, u as loadSessionMetadata } from "../zip-reader-DSEXt7K6.js";
4
- import { t as NullStorageBackend } from "../null-storage-backend-CxEjZHRW.js";
5
- import { t as OpfsStorageBackend } from "../opfs-storage-backend-CjSAuqg_.js";
6
- import { a as getCurrentScenarioHandle, c as resetForNewSession, d as startSession, f as verifyWriteAccess, h as writeSessionMetadata, i as ensureScenarioDirectory, l as resetStorageState, m as writeFrame, n as WriteAccessResult, o as initStorage, p as writeAction, s as listSessions$1, u as setCurrentScenario } from "../file-system-C_eqiEA8.js";
7
- import { n as formatFrameFilename, r as formatTimestamp, t as formatActionFilename } from "../file-system-utils-DyAmcuvX.js";
8
- import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportAndDownloadSession, r as ZipExportContributor, s as exportSessionAsZip, t as ExportSessionAsZipOptions } from "../zip-export-D_5HAvFz.js";
4
+ import { t as NullStorageBackend } from "../null-storage-backend-uKQE8tl7.js";
5
+ import { t as OpfsStorageBackend } from "../opfs-storage-backend-6aYMUZlJ.js";
6
+ import { a as getCurrentScenarioHandle, c as resetForNewSession, d as startSession, f as verifyWriteAccess, h as writeSessionMetadata, i as ensureScenarioDirectory, l as resetStorageState, m as writeFrame, n as WriteAccessResult, o as initStorage, p as writeAction, s as listSessions$1, u as setCurrentScenario } from "../file-system-CwXTNHmB.js";
7
+ import { a as formatTimestamp, i as formatFrameFilename, r as formatActionFilename } from "../file-system-utils-CXIoL-DM.js";
8
+ import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportAndDownloadSession, r as ZipExportContributor, s as exportSessionAsZip, t as ExportSessionAsZipOptions } from "../zip-export-G14hkSPG.js";
9
9
  export { type CreateSessionResult, type Entry, type ExportSessionAsZipOptions, type GpsPathCoord, MAX_ACTION_FILE_SIZE, NullStorageBackend, OpfsStorageBackend, type RecordedAction, type SessionMetadata, type StorageBackend, type WriteAccessResult, type ZipActionEntry, type ZipContributorAddFile, type ZipExportContributor, type ZipExportResult, type ZipSubdirEntry, checkStorageQuota, createSession, downloadZip, ensureScenarioDirectory, exportAndDownloadSession, exportSessionAsZip, formatActionFilename, formatFrameFilename, formatTimestamp, getAppRootHandle, getCurrentScenarioHandle, getSessionHandle, getSessionsRootHandle, initOpfsStorage, initStorage, listSessions, listSessions$1 as listSessionsFromFileSystem, loadActionsFromZip, loadEntriesFromSubdir, loadGpsPathFromBlob, loadSessionMetadataFromBlob, loadSessionMetadata as loadSessionMetadataFromZip, readZipEntries, resetForNewSession, resetOpfsStorage, resetSessionHandles, resetStorageState, setCurrentScenario, startSession as startStorageSession, syncToExternalZip, verifyWriteAccess, writeAction, writeFrame, writeSessionMetadata as writeSessionMeta, writeSessionMetadata$1 as writeSessionMetadata };
@@ -1,2 +1,2 @@
1
- import { t as NullStorageBackend } from "../null-storage-backend-CxEjZHRW.js";
1
+ import { t as NullStorageBackend } from "../null-storage-backend-uKQE8tl7.js";
2
2
  export { NullStorageBackend };
@@ -1,2 +1,2 @@
1
- import { t as OpfsStorageBackend } from "../opfs-storage-backend-CjSAuqg_.js";
1
+ import { t as OpfsStorageBackend } from "../opfs-storage-backend-6aYMUZlJ.js";
2
2
  export { OpfsStorageBackend };
@@ -1,2 +1,2 @@
1
- import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, f as setSessionHandles, h as writeSessionMetadata, i as createSession, l as listSessions, m as writeFrame, n as SessionMetadata, o as getSessionHandle, p as writeAction, r as checkStorageQuota, s as getSessionsRootHandle, t as CreateSessionResult, u as resetOpfsStorage } from "../opfs-storage-DYm8WHq7.js";
1
+ import { a as getAppRootHandle, c as initOpfsStorage, d as resetSessionHandles, f as setSessionHandles, h as writeSessionMetadata, i as createSession, l as listSessions, m as writeFrame, n as SessionMetadata, o as getSessionHandle, p as writeAction, r as checkStorageQuota, s as getSessionsRootHandle, t as CreateSessionResult, u as resetOpfsStorage } from "../opfs-storage-D5zAn_lx.js";
2
2
  export { CreateSessionResult, SessionMetadata, checkStorageQuota, createSession, getAppRootHandle, getSessionHandle, getSessionsRootHandle, initOpfsStorage, listSessions, resetOpfsStorage, resetSessionHandles, setSessionHandles, writeAction, writeFrame, writeSessionMetadata };
@@ -1,5 +1,5 @@
1
1
  import { createLogger } from "../utils/logger.js";
2
- import { formatActionFilename, formatFrameFilename, formatTimestamp } from "./file-system-utils.js";
2
+ import { SESSION_IMAGES_DIR, formatActionFilename, formatFrameFilename, formatTimestamp } from "./file-system-utils.js";
3
3
  //#region ../src/storage/opfs-storage.ts
4
4
  /**
5
5
  * OPFS Storage Module
@@ -16,7 +16,7 @@ import { formatActionFilename, formatFrameFilename, formatTimestamp } from "./fi
16
16
  * │ ├── actions/
17
17
  * │ │ ├── 000001.json
18
18
  * │ │ └── ...
19
- * │ └── frames/
19
+ * │ └── images/ (legacy recordings: frames/)
20
20
  * │ ├── frame-000001.jpg
21
21
  * │ └── ...
22
22
  * └── ...
@@ -94,7 +94,7 @@ function getAppRootHandle() {
94
94
  * Creates the directory structure:
95
95
  * - /gps-plus-slam/sessions/recording-{timestamp}/
96
96
  * - /gps-plus-slam/sessions/recording-{timestamp}/actions/
97
- * - /gps-plus-slam/sessions/recording-{timestamp}/frames/
97
+ * - /gps-plus-slam/sessions/recording-{timestamp}/images/ (legacy: frames/)
98
98
  *
99
99
  * @param timestamp - Session start time (used for folder naming)
100
100
  * @param _contextTag - Opaque tag; not used by the flat layout but accepted
@@ -107,7 +107,7 @@ async function createSession(timestamp, _contextTag) {
107
107
  const sessionName = `recording-${formatTimestamp(timestamp)}`;
108
108
  currentSessionHandle = await sessionsDir.getDirectoryHandle(sessionName, { create: true });
109
109
  actionsHandle = await currentSessionHandle.getDirectoryHandle("actions", { create: true });
110
- framesHandle = await currentSessionHandle.getDirectoryHandle("frames", { create: true });
110
+ framesHandle = await currentSessionHandle.getDirectoryHandle(SESSION_IMAGES_DIR, { create: true });
111
111
  log.info("Session created:", sessionName);
112
112
  return { sessionName };
113
113
  }
@@ -1,2 +1,2 @@
1
- import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-C9HLFtgz.js";
1
+ import { n as StorageBackend, t as CreateSessionResult } from "../storage-backend-Do6YDpNo.js";
2
2
  export { CreateSessionResult, StorageBackend };
@@ -1,2 +1,2 @@
1
- import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportAndDownloadSession, r as ZipExportContributor, s as exportSessionAsZip, t as ExportSessionAsZipOptions } from "../zip-export-D_5HAvFz.js";
1
+ import { a as downloadZip, c as syncToExternalZip, i as ZipExportResult, n as ZipContributorAddFile, o as exportAndDownloadSession, r as ZipExportContributor, s as exportSessionAsZip, t as ExportSessionAsZipOptions } from "../zip-export-G14hkSPG.js";
2
2
  export { ExportSessionAsZipOptions, ZipContributorAddFile, ZipExportContributor, ZipExportResult, downloadZip, exportAndDownloadSession, exportSessionAsZip, syncToExternalZip };
@@ -61,7 +61,7 @@ async function streamDirectoryToZip(dirHandle, zipWriter, basePath = "") {
61
61
  * The ZIP structure mirrors the OPFS session structure:
62
62
  * - session.json (at root)
63
63
  * - actions/000001.json, actions/000002.json, ...
64
- * - frames/frame-000001.jpg, frames/frame-000002.jpg, ...
64
+ * - images/frame-000001.jpg, images/frame-000002.jpg, ... (legacy: frames/)
65
65
  * - refPoints/{h3}.json (only observations from this session, scenario layout only)
66
66
  *
67
67
  * Uses "store" mode (compression level 0) for fast packaging.
@@ -13,7 +13,7 @@ import { BlobReader, TextWriter, Uint8ArrayReader, ZipReader } from "@zip.js/zip
13
13
  * actions/000001.json — Redux action JSON files (1-based, zero-padded)
14
14
  * actions/000002.json
15
15
  * ...
16
- * frames/frame-000001.jpg — captured image frames (optional)
16
+ * images/frame-000001.jpg — captured image frames (optional; legacy: frames/)
17
17
  * session.json — session metadata (optional, see F1 bug)
18
18
  */
19
19
  const log = createLogger("ZipReader");
@@ -1,4 +1,4 @@
1
- import { n as SessionMetadata } from "./opfs-storage-DYm8WHq7.js";
1
+ import { n as SessionMetadata } from "./opfs-storage-D5zAn_lx.js";
2
2
 
3
3
  //#region ../src/storage/storage-backend.d.ts
4
4
  interface CreateSessionResult {
@@ -1,5 +1,5 @@
1
1
  import { t as MapData } from "./map-data-CkloBxIl.js";
2
- import { t as SubscribableStore } from "./subscribe-to-selector-CP3BKSbF.js";
2
+ import { t as SubscribableStore } from "./subscribe-to-selector-CZ6k1NFP.js";
3
3
  import { LatLong, Matrix4, Quaternion, Vector3 } from "gps-plus-slam-js";
4
4
 
5
5
  //#region ../src/state/store-subscribers.d.ts
@@ -1,4 +1,4 @@
1
- import { L as CombinedRootState } from "./create-slam-app-store-qNXQ-tq5.js";
1
+ import { L as CombinedRootState } from "./create-slam-app-store-BljusOua.js";
2
2
 
3
3
  //#region ../src/state/subscribe-to-selector.d.ts
4
4
  /**
@@ -1,3 +1,4 @@
1
+ import { SESSION_IMAGES_DIR } from "../storage/file-system-utils.js";
1
2
  import { createSession, initOpfsStorage, resetOpfsStorage, writeAction, writeFrame, writeSessionMetadata } from "../storage/opfs-storage.js";
2
3
  import { exportSessionAsZip } from "../storage/zip-export.js";
3
4
  import { installOPFSMocks } from "./browser-mocks.js";
@@ -86,7 +87,7 @@ async function produceTestZip(opts) {
86
87
  for (let i = 0; i < options.imagesBeforeSetZero; i++) await writeAndRecordAction({
87
88
  type: "gpsData/add2dImage",
88
89
  payload: {
89
- imageFile: `frames/frame-${String(actionIndex + 1).padStart(6, "0")}.jpg`,
90
+ imageFile: `${SESSION_IMAGES_DIR}/frame-${String(actionIndex + 1).padStart(6, "0")}.jpg`,
90
91
  position: [
91
92
  i * .5,
92
93
  0,
@@ -143,7 +144,7 @@ async function produceTestZip(opts) {
143
144
  await writeAndRecordAction({
144
145
  type: "gpsData/add2dImage",
145
146
  payload: {
146
- imageFile: `frames/frame-${String(imgIdx).padStart(6, "0")}.jpg`,
147
+ imageFile: `${SESSION_IMAGES_DIR}/frame-${String(imgIdx).padStart(6, "0")}.jpg`,
147
148
  position: [
148
149
  (i + 1) * 1,
149
150
  (i + 1) * .5,
@@ -1,2 +1,2 @@
1
- import { n as ArWorldGroupAlignmentOptions, r as enableArWorldGroupAlignment, t as ArWorldGroupAlignmentHandle } from "../ar-world-group-alignment-ColHB_5A.js";
1
+ import { n as ArWorldGroupAlignmentOptions, r as enableArWorldGroupAlignment, t as ArWorldGroupAlignmentHandle } from "../ar-world-group-alignment-C9lwwIyI.js";
2
2
  export { ArWorldGroupAlignmentHandle, ArWorldGroupAlignmentOptions, enableArWorldGroupAlignment };
@@ -1,6 +1,6 @@
1
1
  import { createLogger } from "../utils/logger.js";
2
2
  import { disposeMeshArray } from "./three-dispose.js";
3
- import { c as getArWorldGroup, m as getScene } from "../webxr-session-QhcSSub5.js";
3
+ import { c as getArWorldGroup, m as getScene } from "../webxr-session-TIaD883f.js";
4
4
  import { VIS_COLORS } from "./vis-colors.js";
5
5
  import * as THREE from "three";
6
6
  //#region ../src/visualization/gps-event-markers.ts
@@ -2,7 +2,7 @@ import { n as createCss3dRendererManager, t as Css3dRendererManager } from "../c
2
2
  import { n as createCameraFollower, t as CameraFollower } from "../camera-follower-C2mwEn7c.js";
3
3
  import { n as createAlignmentLerper, t as AlignmentLerper } from "../alignment-lerper-Dm9G7JJO.js";
4
4
  import { n as MapDataInput, r as buildMapData, t as MapData } from "../map-data-CkloBxIl.js";
5
- import { n as ArWorldGroupAlignmentOptions, r as enableArWorldGroupAlignment, t as ArWorldGroupAlignmentHandle } from "../ar-world-group-alignment-ColHB_5A.js";
5
+ import { n as ArWorldGroupAlignmentOptions, r as enableArWorldGroupAlignment, t as ArWorldGroupAlignmentHandle } from "../ar-world-group-alignment-C9lwwIyI.js";
6
6
  import { i as createGpsCompassCubes, n as COMPASS_CUBE_SIZE, r as GpsCompassCubes, t as COMPASS_CUBE_DISTANCE } from "../gps-compass-cubes-BM1uGiYV.js";
7
7
  import { i as isSphereInCameraFrustum, n as isObjectInCameraFrustum, r as isPointInCameraFrustum, t as buildCameraFrustum } from "../frustum-visibility-CmI96ESS.js";
8
8
  import { n as worldNueToGps, t as nueToArLocal } from "../frame-conversions-BfsafGWR.js";
@@ -1,7 +1,7 @@
1
1
  import { i as DepthSample, t as ARPose } from "./ar-types-Dan1MVTi.js";
2
2
  import { i as DepthSamplerConfig } from "./depth-sampler-Bhanfwla.js";
3
3
  import { t as ArCrashIsolationOptions } from "./recording-options-DJBXuMxV.js";
4
- import { i as ImageCaptureConfig, t as CapturedImage } from "./image-capture-DZ4HFRgS.js";
4
+ import { a as ImageCaptureConfig, n as CapturedImage } from "./image-capture-qAZ5Fh5X.js";
5
5
  import { a as TrackingSliceState, r as ResetTransformData } from "./tracking-slice-CdK8c-8P.js";
6
6
  import { t as Css3dRendererManager } from "./css3d-renderer-manager-ptu_t3B3.js";
7
7
  import { r as XRCameraLike } from "./xr-camera-texture-DBwCaKTd.js";
@@ -897,14 +897,27 @@ function startImageCapture(config) {
897
897
  const currentRenderer = renderer;
898
898
  const divisor = mergedConfig.resolutionDivisor;
899
899
  callbacks.captureFrame = async (quality) => {
900
- if (!blitCapture || !latestCameraTexture) return new Promise((resolve) => {
901
- currentRenderer.domElement.toBlob((blob) => resolve(blob), "image/jpeg", quality);
902
- });
900
+ if (!blitCapture || !latestCameraTexture) {
901
+ const canvas = currentRenderer.domElement;
902
+ return new Promise((resolve) => {
903
+ canvas.toBlob((blob) => resolve(blob ? {
904
+ blob,
905
+ width: canvas.width,
906
+ height: canvas.height
907
+ } : null), "image/jpeg", quality);
908
+ });
909
+ }
903
910
  if (latestCameraWidth > 0 && latestCameraHeight > 0) {
904
911
  const target = computeCaptureSize(latestCameraWidth, latestCameraHeight, divisor);
905
912
  blitCapture.resizeIfNeeded(target.width, target.height);
906
913
  }
907
- return blitCapture.captureToBlob(currentRenderer, latestCameraTexture, quality);
914
+ const blob = await blitCapture.captureToBlob(currentRenderer, latestCameraTexture, quality);
915
+ if (!blob) return null;
916
+ return {
917
+ blob,
918
+ width: blitCapture.getWidth(),
919
+ height: blitCapture.getHeight()
920
+ };
908
921
  };
909
922
  log.info(`Blit capture pipeline initialized (resolutionDivisor=${divisor})`);
910
923
  imageCaptureManager = new ImageCaptureManager(renderer.domElement, callbacks, mergedConfig);
@@ -83,7 +83,7 @@ interface ExportSessionAsZipOptions {
83
83
  * The ZIP structure mirrors the OPFS session structure:
84
84
  * - session.json (at root)
85
85
  * - actions/000001.json, actions/000002.json, ...
86
- * - frames/frame-000001.jpg, frames/frame-000002.jpg, ...
86
+ * - images/frame-000001.jpg, images/frame-000002.jpg, ... (legacy: frames/)
87
87
  * - refPoints/{h3}.json (only observations from this session, scenario layout only)
88
88
  *
89
89
  * Uses "store" mode (compression level 0) for fast packaging.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gps-plus-slam-app-framework",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Reusable AR+GPS app framework layer — WebXR session management, Three.js visualization, GPS sensors, storage abstractions, replay engine, and store wiring for gps-plus-slam-js.",
5
5
  "type": "module",
6
6
  "files": [
@@ -36,7 +36,7 @@
36
36
  "dependencies": {
37
37
  "@reduxjs/toolkit": "^2.11.2",
38
38
  "gl-matrix": "3.4.4",
39
- "gps-plus-slam-js": "^1.0.7"
39
+ "gps-plus-slam-js": "^1.3.0"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "@sentry/browser": ">=10.0.0",
@@ -1,24 +0,0 @@
1
- //#region ../src/storage/file-system-utils.d.ts
2
- /**
3
- * File System Utilities - Pure Functions
4
- *
5
- * These are extracted from file-system.ts so they can be tested
6
- * without mocking browser APIs.
7
- */
8
- /**
9
- * Format a Date as a timestamp string for folder names
10
- * @example "2025-02-28_14-30-11utc"
11
- */
12
- declare function formatTimestamp(date: Date): string;
13
- /**
14
- * Format an action file index as a zero-padded filename
15
- * @example 42 -> "000042.json"
16
- */
17
- declare function formatActionFilename(index: number): string;
18
- /**
19
- * Format a frame index as a zero-padded filename
20
- * @example 42 -> "frame-000042.jpg"
21
- */
22
- declare function formatFrameFilename(index: number): string;
23
- //#endregion
24
- export { formatFrameFilename as n, formatTimestamp as r, formatActionFilename as t };