gps-plus-slam-js 1.0.6 → 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.
- package/README.md +16 -0
- package/dist/index.d.ts +10 -37
- package/dist/index.js +1 -1
- package/dist/licensing/community-license-key.d.ts +1 -1
- package/dist/licensing/community-license-key.js +1 -1
- package/package.json +17 -17
package/README.md
CHANGED
|
@@ -150,10 +150,26 @@ Source: [github.com/cs-util-com/location-based-webxr](https://github.com/cs-util
|
|
|
150
150
|
To prepare a new release version for npm, use the automated release preparation script from the repository root. It bumps the core package, updates the dependency range in the companion `GpsPlusSlamJs_AppFramework`, and prints a step-by-step checklist for the two PRs that follow.
|
|
151
151
|
|
|
152
152
|
1. Run the preparation script for the desired bump (`patch`, `minor`, or `major`):
|
|
153
|
+
|
|
153
154
|
```bash
|
|
155
|
+
# Core-only release (gps-plus-slam-js):
|
|
154
156
|
pnpm run prep_new_releases --core patch
|
|
157
|
+
|
|
158
|
+
# Framework-only release (gps-plus-slam-app-framework):
|
|
159
|
+
pnpm run prep_new_releases --framework patch
|
|
160
|
+
|
|
161
|
+
# Coordinated release — bump BOTH packages together. The two
|
|
162
|
+
# versions are independent SoTs; if you want them to move in
|
|
163
|
+
# lockstep you must pass both flags explicitly. A core-only
|
|
164
|
+
# bump leaves the framework's package.json#version unchanged,
|
|
165
|
+
# which will fail the publish workflow's tag-vs-version check
|
|
166
|
+
# (e.g. "Release tag app-framework@1.0.6 does not match
|
|
167
|
+
# package.json version app-framework@1.0.4").
|
|
168
|
+
pnpm run prep_new_releases --core patch --framework patch
|
|
155
169
|
```
|
|
170
|
+
|
|
156
171
|
The public-repo `pnpm install` step is **expected** to fail with `ERR_PNPM_NO_MATCHING_VERSION` because the new version is not on npm yet — the script treats this as accepted-red and continues.
|
|
172
|
+
|
|
157
173
|
2. **Private repo (`gps-plus-slam`):** follow the script's checklist to commit the core bump, open a PR, merge it, and draft a GitHub Release with the new `vX.Y.Z` tag. The release workflow re-signs the community license key and publishes `gps-plus-slam-js` to npm.
|
|
158
174
|
3. **Wait** until the new version is resolvable on npm.
|
|
159
175
|
4. **Public repo (`location-based-webxr`):** follow the script's checklist to push the AppFramework dep-range bump, run `pnpm install` to refresh the lockfile, open a PR, and merge it.
|
package/dist/index.d.ts
CHANGED
|
@@ -257,37 +257,15 @@ interface ArImageCapture {
|
|
|
257
257
|
screenRotation: number;
|
|
258
258
|
/** Epoch milliseconds (Date.now() / new Date().getTime()) */
|
|
259
259
|
capturedAt?: number;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
|
|
269
|
-
/** AR pose when the reference point was marked */
|
|
270
|
-
position: Vector3;
|
|
271
|
-
rotation: Quaternion;
|
|
272
|
-
/** GPS data at the moment of marking */
|
|
273
|
-
gpsPoint: GpsPoint;
|
|
274
|
-
/** Epoch milliseconds (Date.now() / new Date().getTime()) */
|
|
275
|
-
timestamp: number;
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* Payload for the markReferencePoint action.
|
|
279
|
-
*/
|
|
280
|
-
interface MarkReferencePointPayload {
|
|
281
|
-
/** Unique identifier for this reference point */
|
|
282
|
-
id: string;
|
|
283
|
-
/** AR pose position when marking */
|
|
284
|
-
position: Vector3;
|
|
285
|
-
/** AR pose rotation when marking */
|
|
286
|
-
rotation: Quaternion;
|
|
287
|
-
/** Raw GPS point data at the moment of marking */
|
|
288
|
-
rawGpsPoint: RawGpsPoint;
|
|
289
|
-
/** Optional timestamp (defaults to Date.now() if not provided) */
|
|
290
|
-
timestamp?: number;
|
|
260
|
+
/**
|
|
261
|
+
* Captured JPEG width in pixels. Pose-invariant metadata persisted so
|
|
262
|
+
* consumers (e.g. the 3D frame-tile visualizer) can render the frame at
|
|
263
|
+
* its true aspect ratio instead of assuming square. `undefined` for legacy
|
|
264
|
+
* recordings captured before the field existed — consumers must fall back.
|
|
265
|
+
*/
|
|
266
|
+
width?: number;
|
|
267
|
+
/** Captured JPEG height in pixels. See {@link ArImageCapture.width}. */
|
|
268
|
+
height?: number;
|
|
291
269
|
}
|
|
292
270
|
interface OdometryPath {
|
|
293
271
|
points: ArImageCapture[];
|
|
@@ -334,8 +312,6 @@ interface GpsModel {
|
|
|
334
312
|
zero: LatLong;
|
|
335
313
|
gpsEvents: GpsEventsType;
|
|
336
314
|
odometryPath: OdometryPath;
|
|
337
|
-
/** User-defined reference points for ground truth validation */
|
|
338
|
-
referencePoints: ReferencePoint[];
|
|
339
315
|
}
|
|
340
316
|
interface GpsSlamState {
|
|
341
317
|
gpsData: GpsModel | null;
|
|
@@ -453,7 +429,6 @@ declare const recordGpsEvent: _$_reduxjs_toolkit0.ActionCreatorWithPayload<Recor
|
|
|
453
429
|
declare const odometryTrackingRestarted: _$_reduxjs_toolkit0.ActionCreatorWithPayload<OdometryTrackingRestartedPayload, "gpsData/odometryTrackingRestarted">;
|
|
454
430
|
declare const arLoopClosureDetected: _$_reduxjs_toolkit0.ActionCreatorWithPayload<ArLoopClosureDetectedPayload, "gpsData/arLoopClosureDetected">;
|
|
455
431
|
declare const add2dImage: _$_reduxjs_toolkit0.ActionCreatorWithPayload<ArImageCapture, "gpsData/add2dImage">;
|
|
456
|
-
declare const markReferencePoint: _$_reduxjs_toolkit0.ActionCreatorWithPayload<MarkReferencePointPayload, "gpsData/markReferencePoint">;
|
|
457
432
|
declare const gpsDataReducer: (state: GpsModel | null | undefined, action: _$redux.UnknownAction) => GpsModel | null;
|
|
458
433
|
//#endregion
|
|
459
434
|
//#region ../src/state/gpsElementsSlice.d.ts
|
|
@@ -531,8 +506,6 @@ declare const getOdometryPositions: (state: GpsSlamState) => readonly Vector3[];
|
|
|
531
506
|
declare const getOdometryRotations: (state: GpsSlamState) => readonly Quaternion[];
|
|
532
507
|
/** Returns the recorded GPS positions with metadata. */
|
|
533
508
|
declare const getGpsPositions: (state: GpsSlamState) => readonly GpsPoint[];
|
|
534
|
-
/** Returns the user-defined reference points. */
|
|
535
|
-
declare const getReferencePoints: (state: GpsSlamState) => readonly ReferencePoint[];
|
|
536
509
|
/** Returns the GPS zero reference (origin for coordinate conversion), or null. */
|
|
537
510
|
declare const getZeroReference: (state: GpsSlamState) => LatLong | null;
|
|
538
511
|
/** Returns median and mean GPS accuracy statistics, or null values if unavailable. */
|
|
@@ -561,4 +534,4 @@ declare function validateLicenseKey(key: string): LicenseValidationResult;
|
|
|
561
534
|
//#region ../src/index.d.ts
|
|
562
535
|
declare const LIB_VERSION = "1.0.0";
|
|
563
536
|
//#endregion
|
|
564
|
-
export { type Add2dImagePayload, type ArElementsState, type ArImageCapture, type ArLoopClosureDetectedPayload, type AreaPolygon, type CreateGpsSlamStoreOptions, type DetectedArPlane, type EventArea, type FloorDetection, type GpsElementsState, type GpsLine, type GpsMarker, type GpsModel, type GpsPoint, type GpsSlamDispatch, type GpsSlamState, type GpsSlamStore, type HeatArea, type HeatMapTile, IDENTITY_MATRIX4, IDENTITY_QUATERNION, LIB_VERSION, type LatLong, type LatLongAlt, type LicenseValidationResult, type
|
|
537
|
+
export { type Add2dImagePayload, type ArElementsState, type ArImageCapture, type ArLoopClosureDetectedPayload, type AreaPolygon, type CreateGpsSlamStoreOptions, type DetectedArPlane, type EventArea, type FloorDetection, type GpsElementsState, type GpsLine, type GpsMarker, type GpsModel, type GpsPoint, type GpsSlamDispatch, type GpsSlamState, type GpsSlamStore, type HeatArea, type HeatMapTile, IDENTITY_MATRIX4, IDENTITY_QUATERNION, LIB_VERSION, type LatLong, type LatLongAlt, type LicenseValidationResult, type Matrix4, type OdometryPath, type OdometryTrackingRestartedPayload, type Quaternion, type RawDeviceOrientation, type RawGpsPoint, type RecordGpsEventPayload, type RootState, type Vector3, type Vector4, ZERO_VECTOR3, add2dImage, addArea, addCornerToEventArea, addHeatMapArea, addLine, addMarker, addOrUpdateArPlane, addToHeatMaps, anchorEventAreaInWorldSpace, arElementsReducer, arLoopClosureDetected, calcGeoHash, calcGpsCoords, calcQuadKey, calcRelativeCoordsInMeters, cloneMatrix4, cloneQuaternion, cloneVector3, correctArDriftForEventArea, createGpsSlamStore, distanceInMeters, distanceInMetersRelative, enuQuaternionToNUE, eulerToQuaternion, finishEventArea, fromMatrix4, fromQuaternion, fromVector3, fusedGpsFromOdom, geoHashToLatLong, getAlignmentMatrix, getAlignmentRotation, getGoogleMapsDirectionsLink, getGoogleMapsLink, getGpsAccuracyStats, getGpsPositions, getOdometryPositions, getOdometryRotations, getOpenStreetMapLink, getZeroReference, gpsDataReducer, gpsElementsReducer, invertQuaternion, isIdentityMatrix4, isIdentityQuaternion, isNearIdentityQuaternion, multiplyQuaternions, normalizeQuaternion, nueQuaternionToENU, nueQuaternionToWebXR, nueToWebXR, odometryTrackingRestarted, quadKeyToLatLong, quaternionMagnitude, quaternionsEquivalent, recordGpsEvent, recordPhoneHeight, resetArElements, resetGpsElements, sanitizeForDevTools, setZeroPos, startEventArea, toEarthCenteredCoordinates, toMatrix4, toQuaternion, toVector3, validateLicenseKey, webxrQuaternionToNUE, webxrToNUE };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! gps-plus-slam-js | (c) 2026 cs-util-com | UNLICENSED — see EULA.md */
|
|
2
|
-
import{configureStore as e,createSlice as t}from"@reduxjs/toolkit";import{ed25519 as n}from"@noble/curves/ed25519.js";import{hexToBytes as r}from"@noble/curves/utils.js";import{mat4 as i,quat as a,vec3 as o,vec4 as s}from"gl-matrix";import{castDraft as c}from"immer";let l=!1;function u(){l=!0}function d(){if(!l)throw Error(`gps-plus-slam-js: license not activated. Construct your store via createRecorderStore() from gps-plus-slam-app-framework, or pass a valid licenseKey to createGpsSlamStore(). See EULA §3.`)}function f(e){return((...t)=>(d(),e(...t)))}function p(e){let t=((...t)=>(d(),e(...t)));return Object.assign(t,e),t.toString=()=>e.type,t}function m(e){return(t,n)=>(d(),e(t,n))}function h(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=`=`.repeat((4-t.length%4)%4),r=atob(t+n);return Uint8Array.from(r,e=>e.charCodeAt(0))}function g(e){let t=new Date,i=e.indexOf(`.`);if(i<=0||i>=e.length-1)throw Error(`Invalid license key format: expected "payload.signature" with base64url-encoded parts.`);let a,o;try{a=h(e.substring(0,i)),o=h(e.substring(i+1))}catch{throw Error(`Invalid license key format: base64url decoding failed.`)}let s=r(`dfe5c62120b7a0ce962b17907a15b27cf1b056e6619bf6ce55e6e094b322a470`);if(!n.verify(o,a,s))throw Error(`Invalid license key: signature verification failed.`);let c=JSON.parse(new TextDecoder().decode(a));if(typeof c!=`object`||!c)throw Error(`Invalid license key: payload must be a JSON object.`);let{type:l,exp:d}=c;if(l!==`community`)throw Error(`Invalid license key: "type" must be "community".`);if(typeof d!=`number`||!Number.isFinite(d))throw Error(`Invalid license key: "exp" must be a finite number (Unix timestamp in seconds).`);if(d<Math.floor(t.getTime()/1e3)){let e=new Date(d*1e3);throw Error(`License key expired on ${e.toISOString()}. Update to the latest version for a renewed community key.`)}return u(),{type:l,expiresAt:new Date(d*1e3)}}const _=180/Math.PI,v=e=>{let t=e[0],n=e[1],r=e[2],i=e[3],a=2*(i*t+n*r),o=1-2*(t*t+n*n),s=Math.atan2(a,o)*_,c=2*(i*n-r*t),l=Math.abs(c)>=1?Math.sign(c)*90:Math.asin(c)*_,u=2*(i*r+t*n),d=1-2*(n*n+r*r);return{pitch:l,yaw:Math.atan2(u,d)*_,roll:s}},y=1/298.257223563,b=y*(2-y),x=40075016.6856/360,S=39940652.7422/360,C=Math.PI/180,w=180/Math.PI,T=`0123456789bcdefghjkmnpqrstuvwxyz`,E=[16,8,4,2,1],D=(e,t,n)=>Math.min(Math.max(e,t),n),ee=e=>D(e,-180,180),O=e=>e*C,te=e=>e*w,ne=e=>{if(!Number.isFinite(e))throw RangeError(`Coordinate values must be finite numbers`);return String(e)},re=e=>({lat:ne(e.lat),lon:ne(e.lon)}),ie=(e,t=0)=>{let n=O(e.lat),r=O(e.lon),i=Math.sin(n),a=Math.cos(n),s=Math.sin(r),c=Math.cos(r),l=6378137/Math.sqrt(1-b*i*i),u=(l+t)*a*c,d=(l+t)*a*s,f=(l*(1-b)+t)*i;return o.fromValues(u,d,f)},ae=f((e,t)=>{if(t<1||t>23)throw RangeError(`levelOfDetail must be between 1 and 23 (inclusive)`);let n=D(e.lat,-85.05112878,85.05112878),r=ee(e.lon),i=Math.sin(O(n)),a=256*2**t,o=(r+180)/360*a,s=(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*a,c=2**t-1,l=D(Math.floor(o/256),0,c),u=D(Math.floor(s/256),0,c),d=``;for(let e=t;e>0;--e){let t=0,n=1<<e-1;(l&n)!==0&&(t+=1),(u&n)!==0&&(t+=2),d+=t.toString()}return d}),oe=f(e=>{if(!/^[0-3]+$/.test(e))throw Error(`QuadKey must consist of digits 0-3`);let t=e.length;if(t===0)throw Error(`QuadKey must not be empty`);let n=0,r=0;for(let i=0;i<t;i+=1){let a=Number.parseInt(e[i],10),o=1<<t-i-1;a&1&&(n+=o),a&2&&(r+=o)}let i=256*2**t,a=(n+.5)*256,o=(r+.5)*256,s=a/i,c=o/i,l=s*360-180;return{lat:te(Math.atan(Math.sinh(Math.PI*(1-2*c)))),lon:l}}),se=f((e,t)=>{if(t<=0)throw RangeError(`precision must be greater than 0`);let n=-90,r=90,i=-180,a=180,o=``,s=0,c=0,l=!0;for(;o.length<t;){if(l){let t=(i+a)/2;e.lon>=t?(c|=E[s],i=t):a=t}else{let t=(n+r)/2;e.lat>=t?(c|=E[s],n=t):r=t}l=!l,s<4?s+=1:(o+=T[c],s=0,c=0)}return o}),ce=f(e=>{if(e.length===0)throw Error(`geoHash must not be empty`);let t=-90,n=90,r=-180,i=180,a=!0;for(let o of e){let e=T.indexOf(o);if(e===-1)throw Error(`Invalid geohash character: ${o}`);for(let o of E){if(a){let t=(r+i)/2;(e&o)===0?i=t:r=t}else{let r=(t+n)/2;(e&o)===0?n=r:t=r}a=!a}}return{lat:(t+n)/2,lon:(r+i)/2}}),le=f((e,t)=>{let n=O(e.lat),r=O(t.lat),i=r-n,a=O(t.lon-e.lon),o=Math.sin(i/2),s=Math.sin(a/2),c=o*o+Math.cos(n)*Math.cos(r)*s*s,l=Math.min(1,Math.max(0,c));return 6371008.8*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}),ue=f((e,t)=>{let n=de(e,t);return Math.hypot(n[0],n[2])}),de=f((e,t,n=0,r=0)=>{let i=(t.lon-e.lon)*x*Math.cos(O(e.lat)),a=(t.lat-e.lat)*S,s=n-r;return o.fromValues(a,s,i)}),fe=f((e,t)=>{let n=t[0],r=t[2];return{lat:n/S+e.lat,lon:r/(x*Math.cos(O(e.lat)))+e.lon}}),pe=f((e,t=0)=>ie(e,t)),me=e=>{let{lat:t,lon:n}=re(e);return`${t}%2C${n}`},he=f(e=>`https://www.google.com/maps/search/?api=1&query=${me(e)}`),ge=f((e,t)=>`https://www.google.com/maps/dir/?api=1&origin=${me(t)}&destination=${me(e)}`),_e=f((e,t=19)=>{let{lat:n,lon:r}=re(e);return`https://www.openstreetmap.org/query?lat=${n}&lon=${r}#map=${t}/${n}/${r}`}),ve=f((e,t,n)=>{let r=i.fromValues(...e),a=o.fromValues(t[0],t[1],t[2]),s=o.create();o.transformMat4(s,a,r);let{lat:c,lon:l}=fe(n,s);return{lat:c,lon:l,altitude:s[1]}}),ye=()=>({points:[]}),k=()=>({gpsMarkers:[],gpsLines:[],areas:[],heatMap:{},heatAreas:{}}),A=()=>({arPlanes:{},floorDetections:[],eventAreas:[],currentEventAreaId:null,currentEventAreaPoints:[]}),j=e=>o.fromValues(e[0],e[1],e[2]),M=e=>a.fromValues(e[0],e[1],e[2],e[3]),be=e=>i.fromValues(...e),N=e=>[e[0],e[1],e[2]],P=e=>[e[0],e[1],e[2],e[3]],F=e=>[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]],I=e=>[e[0],e[1],e[2]],xe=e=>[e[0],e[1],e[2],e[3]],Se=e=>[...e],L=Object.freeze([0,0,0,1]),R=Object.freeze([0,0,0]),z=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),B=e=>{let t=we(e);if(t===0)return L;let n=1/t;return[e[0]*n,e[1]*n,e[2]*n,e[3]*n]},Ce=e=>{for(let t=0;t<16;t++)if(e[t]!==z[t])return!1;return!0},we=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]+e[3]*e[3]),Te=e=>e[0]===0&&e[1]===0&&e[2]===0&&e[3]===1,Ee=(e,t)=>Math.abs(e[0])<t&&Math.abs(e[1])<t&&Math.abs(e[2])<t&&Math.abs(e[3]-1)<t,De=(e,t,n=1e-10)=>{let r=Math.abs(e[0]-t[0])<n&&Math.abs(e[1]-t[1])<n&&Math.abs(e[2]-t[2])<n&&Math.abs(e[3]-t[3])<n,i=Math.abs(e[0]+t[0])<n&&Math.abs(e[1]+t[1])<n&&Math.abs(e[2]+t[2])<n&&Math.abs(e[3]+t[3])<n;return r||i},Oe=(e,t)=>{let n=a.create();return a.multiply(n,e,t),[n[0],n[1],n[2],n[3]]},ke=e=>{let t=a.create();return a.invert(t,e),[t[0],t[1],t[2],t[3]]},V=e=>[-e[2],e[1],e[0]],Ae=e=>[e[2],e[1],-e[0]],H=e=>[-e[2],e[1],e[0],e[3]],je=e=>[e[2],e[1],-e[0],e[3]],U=e=>[e[1],e[2],e[0],e[3]],Me=e=>[e[2],e[0],e[1],e[3]],W=(e,t,n)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n))throw Error(`eulerToQuaternion: non-finite input (alpha=${e}, beta=${t}, gamma=${n})`);let r=e*Math.PI/180,i=t*Math.PI/180,o=n*Math.PI/180,s=a.create(),c=a.create(),l=a.create();a.setAxisAngle(s,[0,0,1],r),a.setAxisAngle(c,[1,0,0],i),a.setAxisAngle(l,[0,1,0],o);let u=a.create();return a.multiply(u,s,c),a.multiply(u,u,l),[u[0],u[1],u[2],u[3]]},Ne=t({name:`arElements`,initialState:A(),reducers:{recordPhoneHeight:(e,t)=>{e.floorDetections.push(t.payload)},addOrUpdateArPlane:(e,t)=>{let n=t.payload;if(n.parentPlaneId){delete e.arPlanes[n.planeId];return}e.arPlanes[n.planeId]=c(n)},startEventArea:(e,t)=>{e.currentEventAreaId=t.payload.id,e.currentEventAreaPoints=[]},addCornerToEventArea:(e,t)=>{e.currentEventAreaId&&e.currentEventAreaPoints.push(c(I(t.payload.position)))},correctArDriftForEventArea:(e,t)=>{let n=t.payload.drift;for(let t of e.currentEventAreaPoints)t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]},finishEventArea:(e,t)=>{e.currentEventAreaId&&(e.eventAreas.push({id:e.currentEventAreaId,label:t.payload.label,polygon:[],isInArSpace:!0,arPoints:e.currentEventAreaPoints}),e.currentEventAreaId=null,e.currentEventAreaPoints=[])},anchorEventAreaInWorldSpace:(e,t)=>{let{areaId:n,alignmentMatrix:r,zeroRef:i}=t.payload,a=e.eventAreas.findIndex(e=>e.id===n);if(a===-1)return;let s=e.eventAreas[a];if(!s.isInArSpace||!s.arPoints)throw Error(`The area ${s.id} is already anchored in world space`);let c=be(r),l=s.arPoints.map(e=>{let t=j(e);return fe(i,o.transformMat4(o.create(),t,c))});e.eventAreas[a]={...s,isInArSpace:!1,polygon:l,arPoints:void 0}},resetArElements:()=>A()}}),{recordPhoneHeight:Pe,addOrUpdateArPlane:Fe,startEventArea:Ie,addCornerToEventArea:Le,correctArDriftForEventArea:Re,finishEventArea:ze,anchorEventAreaInWorldSpace:Be,resetArElements:Ve}=Ne.actions,He=p(Pe),Ue=p(Fe),We=p(Ie),Ge=p(Le),Ke=p(Re),qe=p(ze),Je=p(Be),Ye=p(Ve),Xe=m(Ne.reducer);function Ze(e,t,n,r){let{inCentroid:i,refCentroid:a,refVec:s,tmp:c}=r;o.set(i,0,0,0),o.set(a,0,0,0);let l=0;for(let n=0;n<e.length;n++){let r=t[n][3];o.scaleAndAdd(i,i,e[n],r),G(s,t[n]),o.scaleAndAdd(a,a,s,r),l+=r}if(l===0)throw Error(`Weights must not sum to zero when solving Kabsch`);let u=1/l;if(o.scale(i,i,u),o.scale(a,a,u),!n)return{inCentroid:i,refCentroid:a,scaleRatio:1};let d=0,f=0;for(let n=0;n<e.length;n++)o.subtract(c,e[n],i),d+=o.length(c),G(s,t[n]),o.subtract(c,s,a),f+=o.length(c);return{inCentroid:i,refCentroid:a,scaleRatio:d===0?1:f/d}}function Qe(e,t,n,r,a,s,c){let{negCentroid:l,scaleVec:u}=c;return i.fromRotationTranslation(e,r,n),s&&(o.set(u,a,a,a),i.scale(e,e,u)),o.negate(l,t),i.translate(e,e,l),e}function $e(e,t,n={}){let r=e.length;if(r!==t.length)throw Error(`Length of the point lists was not equal: ${r} vs ${t.length}`);if(r===0)return i.create();let s=n.solveRotation??!0,c=n.solveScale??!1,l=n.ignoreYAxisForRotation??!1,u=n.rotationIterations??9,{inCentroid:d,refCentroid:f,scaleRatio:p}=Ze(e,t,c,{inCentroid:o.create(),refCentroid:o.create(),refVec:o.create(),tmp:o.create()}),m=a.create();s?new et(l).solve(e,t,d,f,m,u):a.identity(m);let h={negCentroid:o.create(),scaleVec:o.create()};return Qe(i.create(),d,f,m,p,c,h)}var et=class e{static twoPi=Math.PI*2;static basisX=o.fromValues(1,0,0);static basisY=o.fromValues(0,1,0);static basisZ=o.fromValues(0,0,1);constructor(e){this.ignoreYAxis=e}solve(t,n,r,i,o,s){let c=this.transposeMultSubtract(t,n,r,i);if(this.ignoreYAxis){let t=c[0][0],n=c[0][2],r=c[2][0],i=c[2][2],s=Math.atan2(r-n,t+i);a.setAxisAngle(o,e.basisY,s)}else this.extractRotation(c,o,s)}transposeMultSubtract(e,t,n,r){let i=[o.create(),o.create(),o.create()],a=o.clone(n),s=o.clone(r);this.ignoreYAxis&&(a[1]=0,s[1]=0);let c=o.create(),l=o.create(),u=o.create();for(let n=0;n<e.length;n++){o.copy(c,e[n]),G(u,t[n]),this.ignoreYAxis&&(c[1]=0,u[1]=0);let r=t[n][3];o.subtract(c,c,a),o.scale(c,c,r),o.subtract(l,u,s),i[0][0]+=c[0]*l[0],i[1][0]+=c[1]*l[0],i[2][0]+=c[2]*l[0],i[0][1]+=c[0]*l[1],i[1][1]+=c[1]*l[1],i[2][1]+=c[2]*l[1],i[0][2]+=c[0]*l[2],i[1][2]+=c[1]*l[2],i[2][2]+=c[2]*l[2]}return i}extractRotation(t,n,r){let i=[o.create(),o.create(),o.create()],s=o.create(),c=o.create(),l=o.create();for(let u=0;u<r;u++){this.fillMatrixFromQuaternion(n,i),o.cross(s,i[0],t[0]),o.cross(l,i[1],t[1]),o.add(s,s,l),o.cross(l,i[2],t[2]),o.add(s,s,l);let r=o.dot(i[0],t[0])+o.dot(i[1],t[1])+o.dot(i[2],t[2])+1e-9;r=Math.abs(r),o.scale(s,s,1/r);let u=o.length(s);if(u<1e-9)break;o.scale(c,s,1/u);let d=u%e.twoPi,f=a.create();a.setAxisAngle(f,c,d),a.multiply(n,f,n),a.normalize(n,n)}}fillMatrixFromQuaternion(t,n){o.transformQuat(n[0],e.basisX,t),o.transformQuat(n[1],e.basisY,t),o.transformQuat(n[2],e.basisZ,t)}};const G=(e,t)=>(e[0]=t[0],e[1]=t[1],e[2]=t[2],e);function tt(e,t,n,r,i,a,o=Math.random){let s=Array.from(e);if(n>s.length)throw RangeError(`minSampleSize must be smaller than the number of elements: minSampleSize=${n}, elements=${s.length}`);return it(s,nt(s,t,n,r,i,a,o),i,a)}function nt(e,t,n,r,i,a,o){let s=null,c=Array(n),l=new Uint8Array(e.length);for(let u=0;u<r;u+=1){at(e,n,o,c,l);let{inliers:r,outliers:u}=rt(e,l,i(c),a);if(s===null||n+r.length>=t){let e=[...c,...r],t=i(e),n=K(t,`createModel must assign totalModelError for comparison during RANSAC`);(s===null||n<s.error)&&(t.inliers=e,t.outliers=u,s={model:t,error:n})}}return s?.model??null}function rt(e,t,n,r){let i=[],a=[];for(let o=0;o<e.length;o+=1){if(t?.[o])continue;let s=e[o];(r(n,s)?i:a).push(s)}return{inliers:i,outliers:a}}function it(e,t,n,r){let i=t??n(e);K(i,`RANSAC failed to produce a model with totalModelError`);let{inliers:a,outliers:o}=rt(e,null,i,r);return a.length>0&&(i=n(a),K(i,`createModel must assign totalModelError for final RANSAC model`)),i.inliers=a,i.outliers=o,i}function K(e,t){let{totalModelError:n}=e;if(n==null)throw Error(t);return n}function at(e,t,n,r,i){i.fill(0);let a=0;for(;a<t;){let t=Math.floor(n()*e.length);i[t]||(i[t]=1,r[a]=e[t],a+=1)}}const ot={useOnlyRecentData:!1,recentSeconds:180,includeTimeWeight:!0,weightByTimeFactor:800,ignoreYAxisForRotation:!0,useRansac:!1,ransacInlierRatio:.95,ransacSampleRatio:.3,ransacMaxIterations:230,ransacErrorTolerance:1,geohashPrecision:8,geohashWindowSize:10,gpsAccuracyExponent:.1,altitudeAlignmentMode:`separate1D`,altitudeAggregator:`mean`,altitudeSampleSet:`all`,gpsVerticalAccuracyExponent:5},st=e=>e.map(e=>I(e)),ct=e=>e.map(e=>B(e)),lt=e=>e.map(Q),ut=e=>e.map(e=>[e[0],e[1],e[2],e[3]]),q=e=>Array.isArray(e)?e:N(e),J=e=>Array.isArray(e)?e:P(e),dt=(e,t,n,r)=>({odometryPosOffset:I(q(e)),odometryRotOffset:B(J(t)),latestLoopClosureFixPointPos:n?I(q(n)):null,latestLoopClosureFixPointRot:r?B(J(r)):null}),ft=(e,t,n,r)=>({odometryPositions:[],odometryRotations:[],gpsPositions:[],gpsPositionsVec4:[],alignmentMatrix:[...z],alignmentRotation:[...L],alignmentTranslation:[...R],alignmentRotationInDegree:[...R],...dt(e,t,n,r),gpsAccuracyMedian:null,gpsAccuracyMean:null,currentGpsPosGeoHash:null}),pt=()=>ft(R,L,null,null),mt=(e,t,n,r)=>{let i=e.map(e=>q(e)),a=t.map(e=>B(J(e))),o=n.map(Q),s=r.gpsAccuracyExponent;for(let e of o)e.weight=Y(e.latLongAccuracy,s);let c=o.map(Mt),l=r.includeTimeWeight?Ot(c,o,r.weightByTimeFactor):c,u=r.useOnlyRecentData?Et(o,r.recentSeconds):0,d=i.slice(u).map(j),f=o.slice(u);return{allPositionTuples:i,allRotationTuples:a,allGpsPoints:o,allVec4Tuples:l,solverPositionsTyped:d,solverGpsPoints:f,solverWeightedVec4Tuples:l.slice(u),solverVerticalWeights:Dt(f,r)}},ht=e=>{let{odometryPositions:t,odometryRotations:n,gpsPoints:r,odometryPosOffset:i=R,odometryRotOffset:s=L,latestLoopClosureFixPointPos:c=null,latestLoopClosureFixPointRot:l=null,alignmentConfig:u,random:d}=e;if(t.length!==n.length||t.length!==r.length)throw Error(`GpsEvents requires odometry positions, rotations, and gps points to have identical lengths`);let f={...ot,...u??{}};if(t.length===0)return ft(i,s,c,l);let{allPositionTuples:p,allRotationTuples:m,allGpsPoints:h,allVec4Tuples:g,solverPositionsTyped:_,solverGpsPoints:v,solverWeightedVec4Tuples:y,solverVerticalWeights:b}=mt(t,n,r,f),x=yt(_,y,b,f,d??Math.random),S=a.create(),C=o.create(),w=o.create();_t(x.matrix,S,C,w);let{mean:T,median:E}=At(h),D=kt(r,f.geohashPrecision,f.geohashWindowSize);return{odometryPositions:st(p),odometryRotations:ct(m),gpsPositions:lt(h),gpsPositionsVec4:ut(g),alignmentMatrix:F(x.matrix),alignmentRotation:P(S),alignmentTranslation:N(C),alignmentRotationInDegree:N(w),...dt(i,s,c,l),gpsAccuracyMedian:E,gpsAccuracyMean:T,currentGpsPosGeoHash:D}},Y=(e,t)=>e!=null&&e>0?1/Math.max(e,1)**+t:1,gt=(e,t,n,r,i,s)=>{let c=e.odometryPositions,l=e.odometryRotations,u=e.gpsPositions,d=e.gpsPositionsVec4;c.push(q(t)),l.push(B(J(n)));let f=Q(r);u.push(f);let p={...ot,...i??{}};f.weight=Y(f.latLongAccuracy,p.gpsAccuracyExponent);let m=Mt(f);if(p.includeTimeWeight){d.push(m);let e=Ot(d,u,p.weightByTimeFactor);for(let t=0;t<e.length;t++)d[t]=e[t]}else d.push(m);let h=0;p.useOnlyRecentData&&(h=Et(u,p.recentSeconds));let g=yt(c.slice(h).map(j),d.slice(h),Dt(u.slice(h),p),p,s??Math.random);e.alignmentMatrix=F(g.matrix);let _=a.create(),v=o.create(),y=o.create();_t(g.matrix,_,v,y),e.alignmentRotation=P(_),e.alignmentTranslation=N(v),e.alignmentRotationInDegree=N(y);let{mean:b,median:x}=At(u);e.gpsAccuracyMean=b,e.gpsAccuracyMedian=x,e.currentGpsPosGeoHash=kt(u,p.geohashPrecision,p.geohashWindowSize)},_t=(e,t,n,r)=>{i.getRotation(t,e),a.normalize(t,t),i.getTranslation(n,e),jt(t,r)},X=o.create(),vt=o.create(),yt=(e,t,n,r,a)=>{if(e.length===0)return{matrix:i.create(),meanError:0};let o=e.length,c=[];for(let r=0;r<o;r+=1){let i=t[r];c.push({odom:e[r],ref:s.fromValues(i[0],i[1],i[2],i[3]),verticalWeight:n[r]??1})}let l,u,d;if(r.useRansac&&c.length>=3){let e=c.length,t=Math.max(3,Math.min(e,Math.ceil(e*r.ransacSampleRatio))),n=tt(c,Math.max(t,Math.min(e,Math.ceil(e*r.ransacInlierRatio))),t,r.ransacMaxIterations,e=>Ct(e,r.ignoreYAxisForRotation),(e,t)=>wt(e,t)<e.meanAlignmentError+r.ransacErrorTolerance,a);l=n.alignmentMatrix,u=n.meanAlignmentError,n.inliers!==void 0&&(d=Array.from(n.inliers))}else{let e=Ct(c,r.ignoreYAxisForRotation);l=e.alignmentMatrix,u=e.meanAlignmentError}return r.altitudeAlignmentMode===`separate1D`&&bt(l,c,d,r),{matrix:l,meanError:u}},bt=(e,t,n,r)=>{let i=r.altitudeSampleSet===`horizontalInliers`&&n!==void 0&&n.length>0?n:t;if(i.length===0)return;let a=Array(i.length),o=Array(i.length);for(let e=0;e<i.length;e+=1){let t=i[e];a[e]=t.ref[1]-t.odom[1];let n=t.verticalWeight;o[e]=n>0&&Number.isFinite(n)?n:0}e[13]=r.altitudeAggregator===`median`?St(a,o):xt(a,o)},xt=(e,t)=>{let n=0,r=0;for(let i=0;i<e.length;i+=1)n+=e[i]*t[i],r+=t[i];if(r>0&&Number.isFinite(r))return n/r;let i=0;for(let t=0;t<e.length;t+=1)i+=e[t];return e.length===0?0:i/e.length},St=(e,t)=>{if(e.length===0)return 0;if(e.length===1)return e[0];let n=e.map((e,t)=>t);n.sort((t,n)=>e[t]-e[n]);let r=0;for(let e=0;e<t.length;e+=1)r+=t[e];if(!(r>0)||!Number.isFinite(r)){let t=n.map(t=>e[t]);return t[Math.floor((t.length-1)/2)]}let i=r/2,a=0;for(let r=0;r<n.length;r+=1)if(a+=t[n[r]],a>=i)return e[n[r]];return e[n[n.length-1]]},Ct=(e,t)=>{let n=Array.from(e),r=n.length,i=Array(r),a=Array(r);for(let e=0;e<r;e+=1)i[e]=n[e].odom,a[e]=n[e].ref;let s=$e(i,a,{ignoreYAxisForRotation:t}),c=0;for(let e=0;e<r;e+=1)o.transformMat4(X,i[e],s),c+=Tt(X,n[e].ref);return{alignmentMatrix:s,meanAlignmentError:r===0?0:c/r,totalModelError:c}},wt=(e,t)=>(o.transformMat4(X,t.odom,e.alignmentMatrix),Tt(X,t.ref)),Tt=(e,t)=>(o.set(vt,t[0],t[1],t[2]),o.squaredDistance(e,vt)),Et=(e,t)=>{if(e.length===0||t<=0)return 0;let n=e[e.length-1].timestamp-t*1e3;for(let t=0;t<e.length;t+=1)if(e[t].timestamp>=n)return t;return 0},Dt=(e,t)=>{let n=t.gpsVerticalAccuracyExponent,r=e.map(e=>{let t=e.altitudeAccuracy;return Y(t!=null&&Number.isFinite(t)&&t>0?t:e.latLongAccuracy,n)});if(!t.includeTimeWeight||e.length<2)return r;let i=e[e.length-1].timestamp,a=e[0].timestamp,o=Math.max(1,i-a),s=t.weightByTimeFactor;return r.map((t,n)=>{if(!(t>0&&Number.isFinite(t)))return 0;let r=s*((i-e[n].timestamp)/o)+1;return 1/(1/t+r)})},Ot=(e,t,n)=>{if(e.length<2)return e.map(e=>[e[0],e[1],e[2],e[3]]);let r=t[t.length-1].timestamp,i=t[0].timestamp,a=Math.max(1,r-i);return e.map((e,i)=>{let o=n*((r-t[i].timestamp)/a)+1,s=t[i].weight;if(!(s>0&&Number.isFinite(s)))return[e[0],e[1],e[2],0];let c=1/(1/s+o);return[e[0],e[1],e[2],c]})},Z=new Map,kt=(e,t,n)=>{if(e.length===0)return null;let r=Math.max(0,e.length-n);Z.clear();for(let n=r;n<e.length;n+=1){let r=e[n],i=se(Nt(r),t),a=Z.get(i);a?(a.count+=1,a.index=n):Z.set(i,{count:1,index:n})}let i=null,a=-1,o=-1;for(let[e,{count:t,index:n}]of Z)(t>a||t===a&&n>o)&&(i=e,a=t,o=n);return i},At=e=>{let t=e.map(e=>e.latLongAccuracy).filter(e=>typeof e==`number`&&Number.isFinite(e));if(t.length===0)return{mean:null,median:null};let n=t.reduce((e,t)=>e+t,0)/t.length,r=t.slice().sort((e,t)=>e-t),i=Math.floor(r.length/2);return{mean:n,median:r.length%2==0?(r[i-1]+r[i])/2:r[i]}},jt=(e,t)=>{let n=e[0],r=e[1],i=e[2],a=e[3],s=2*(a*n+r*i),c=1-2*(n*n+r*r),l=Math.atan2(s,c),u=2*(a*r-i*n),d;d=Math.abs(u)>=1?Math.PI/2*Math.sign(u):Math.asin(u);let f=2*(a*i+n*r),p=1-2*(r*r+i*i),m=Math.atan2(f,p),h=180/Math.PI,g=t??o.create();return g[0]=l*h,g[1]=d*h,g[2]=m*h,g},Mt=e=>[e.coordinates[0],e.coordinates[1],e.coordinates[2],e.weight>0&&Number.isFinite(e.weight)?e.weight:1],Nt=e=>({lat:e.latitude,lon:e.longitude}),Q=e=>({...e,zeroRef:{lat:e.zeroRef.lat,lon:e.zeroRef.lon},coordinates:[e.coordinates[0],e.coordinates[1],e.coordinates[2]],timestamp:e.timestamp,deviceRotation:e.deviceRotation?B(J(e.deviceRotation)):void 0}),Pt=({lat:e,lon:t})=>{if(!Number.isFinite(e))throw Error(`Invalid latitude value: ${e}`);if(!Number.isFinite(t))throw Error(`Invalid longitude value: ${t}`);if(e<-90||e>90)throw Error(`Invalid latitude range: ${e}`);if(t<-180||t>180)throw Error(`Invalid longitude range: ${t}`)},Ft=o.fromValues(1,1,1),It=(e,t)=>[e[0]+t[0],e[1]+t[1],e[2]+t[2]],Lt=(e,t,n)=>{let r=de(t,{lat:e.latitude,lon:e.longitude},e.altitude??0,0),i=n?.alpha!=null&&n?.beta!=null&&n?.gamma!=null?U(W(n.alpha,n.beta,n.gamma)):void 0;return{...e,zeroRef:t,coordinates:N(r),weight:1,deviceRotation:i}},Rt=(e,t,n)=>{if(e)return W(e.alpha,e.beta,e.gamma);if(t)return t;throw Error(`Sensor rotation missing for ${n}: neither raw orientation nor legacy quaternion provided`)},zt=e=>{let t=a.invert(a.create(),e);if(!t)throw Error(`Encountered non-invertible quaternion`);return t},Bt=e=>{let t=zt(a.normalize(a.create(),M(e.lastSensorRot))),n=a.normalize(a.create(),M(e.lastValidOdomRot)),r=a.multiply(a.create(),t,n),i=a.normalize(a.create(),M(e.newSensorRot)),o=a.multiply(a.create(),i,r),s=a.normalize(a.create(),M(e.newOdomRot)),c=a.multiply(a.create(),o,s);return a.normalize(c,c),P(c)},Vt=(e,t)=>{let n=i.create();return i.fromRotationTranslationScale(n,a.normalize(a.create(),M(t)),j(e),Ft),n},Ht=(e,t,n)=>{let r=o.create(),s=o.create(),c=a.create(),l=a.create();i.getTranslation(r,e),i.getTranslation(s,t),i.getRotation(c,e),i.getRotation(l,t);let u=o.create();o.lerp(u,r,s,n);let d=a.create();return a.slerp(d,c,l,n),i.fromRotationTranslation(i.create(),d,u)},Ut=(e,t)=>{if(e.length===0)return[];let n=e[e.length-1],r=i.invert(i.create(),n);if(!r)throw Error(`End pose matrix is not invertible`);let a=i.multiply(i.create(),t,r),o=i.create(),s=e.length-1;return e.map((e,t)=>{let n=Ht(o,a,s<=0?1:t/s);return i.multiply(i.create(),n,e)})},Wt=(e,t,n)=>{for(let r=e.length-1;r>=0;--r)if(n(e[r],t))return r;return-1},Gt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2],Kt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3],qt=t({name:`gpsData`,initialState:null,reducers:{setZeroPos:{reducer:(e,t)=>e===null?{zero:t.payload,gpsEvents:pt(),odometryPath:ye(),referencePoints:[]}:e,prepare:e=>(Pt(e),{payload:e})},recordGpsEvent:(e,t)=>{if(!e)return e;let{odomPosition:n,odomRotation:r,rawGpsPoint:i,rawDeviceOrientation:a}=t.payload,o=Lt(i,e.zero,a);gt(e.gpsEvents,V(n),H(r),o)},odometryTrackingRestarted:(e,t)=>{if(!e)return e;let n=It(e.gpsEvents.odometryPosOffset,V(t.payload.lastValidOdomPos)),r=Rt(t.payload.lastSensorOrientation,t.payload.lastSensorRot,`lastSensor`),i=Rt(t.payload.newSensorOrientation,t.payload.newSensorRot,`newSensor`);e.gpsEvents=c(ht({odometryPositions:[],odometryRotations:[],gpsPoints:[],odometryPosOffset:n,odometryRotOffset:Bt({...t.payload,lastValidOdomRot:H(t.payload.lastValidOdomRot),newOdomRot:H(t.payload.newOdomRot),lastSensorRot:U(r),newSensorRot:U(i)}),latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null}))},arLoopClosureDetected:(e,t)=>{if(!e)return e;let n=e.gpsEvents;if(n.odometryPositions.length===0)return e;let r=n.latestLoopClosureFixPointPos?Wt(n.odometryPositions,n.latestLoopClosureFixPointPos,Gt):0,s=n.latestLoopClosureFixPointRot?Wt(n.odometryRotations,n.latestLoopClosureFixPointRot,Kt):0;if(r<0||s<0)throw Error(`Loop closure fix point could not be located in history`);if(r!==s)throw Error(`Loop closure fix point indices for position and rotation diverged`);let l=n.odometryPositions.slice(0,r).map(e=>I(e)),u=n.odometryRotations.slice(0,r).map(e=>B(e)),d=n.odometryPositions.slice(r).map(e=>I(e)),f=n.odometryRotations.slice(r).map(e=>B(e)),p=d.map((e,t)=>Vt(e,f[t])),m=Vt(V(t.payload.lastPos),B(H(t.payload.lastRot)));p.push(m);let h=Ut(p,Vt(V(t.payload.newPos),B(H(t.payload.newRot)))),g=[],_=[],v=o.create();for(let e=0;e<h.length-1;e+=1){let t=h[e],n=o.create();i.getTranslation(n,t);let r=a.create();if(i.getRotation(r,t),a.normalize(r,r),i.getScaling(v,t),Math.hypot(v[0]-1,v[1]-1,v[2]-1)>.05)throw Error(`Unexpected scale drift encountered during loop closure correction`);g.push(N(n)),_.push(P(r))}e.gpsEvents=c(ht({odometryPositions:l.concat(g),odometryRotations:u.concat(_),gpsPoints:n.gpsPositions,odometryPosOffset:n.odometryPosOffset,odometryRotOffset:n.odometryRotOffset,latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null}))},add2dImage:(e,t)=>{if(!e)return e;e.odometryPath.points.push(c({imageFile:t.payload.imageFile,screenRotation:t.payload.screenRotation,position:V(t.payload.position),rotation:B(H(t.payload.rotation)),capturedAt:t.payload.capturedAt}))},markReferencePoint:(e,t)=>{if(!e)return e;let{id:n,position:r,rotation:i,rawGpsPoint:a,timestamp:o}=t.payload,s=Lt(a,e.zero);e.referencePoints.push(c({id:n,position:V(r),rotation:B(H(i)),gpsPoint:Q(s),timestamp:o??Date.now()}))}}}),{setZeroPos:Jt,recordGpsEvent:Yt,odometryTrackingRestarted:Xt,arLoopClosureDetected:Zt,add2dImage:Qt,markReferencePoint:$t}=qt.actions,en=p(Jt),tn=p(Yt),nn=p(Xt),rn=p(Zt),an=p(Qt),on=p($t),sn=m(qt.reducer),cn=t({name:`gpsElements`,initialState:k(),reducers:{addMarker:(e,t)=>{e.gpsMarkers.push(t.payload)},addLine:(e,t)=>{e.gpsLines.push(t.payload)},addArea:(e,t)=>{e.areas.push(t.payload)},addToHeatMaps:(e,t)=>{let{category:n,tiles:r}=t.payload,i=e.heatMap[n]??{};e.heatMap[n]={...i,...r}},addHeatMapArea:(e,t)=>{let n=t.payload,r=n.category;if(e.heatAreas[r]||(e.heatAreas[r]={}),e.heatAreas[r][n.geoHash])throw Error(`HeatArea collision detected for GeoHash: ${n.geoHash}`);e.heatAreas[r][n.geoHash]=n},resetGpsElements:()=>k()}}),{addMarker:ln,addLine:un,addArea:dn,addToHeatMaps:fn,addHeatMapArea:pn,resetGpsElements:mn}=cn.actions,hn=p(ln),gn=p(un),_n=p(dn),vn=p(fn),yn=p(pn),bn=p(mn),xn=m(cn.reducer),Sn=()=>({gpsData:null,gpsElements:k(),arElements:A()}),Cn=e=>{let t=Array.from({length:Math.min(e.length,4)},(t,n)=>e[n].toFixed(2));e.length>4&&t.push(`…`);let n=`[${t.join(`, `)}]`;if(e.length===4){let{pitch:t,yaw:r,roll:i}=v(e);return`${n} (pitch=${t.toFixed(0)}°, yaw=${r.toFixed(0)}°, roll=${i.toFixed(0)}°)`}return n},wn=e=>(e.length===3||e.length===4||e.length===16)&&e.every(e=>typeof e==`number`),$=(e,t=0)=>{if(t>10||e==null)return e;if(Array.isArray(e))return wn(e)?Cn(e):e.map(e=>$(e,t+1));if(typeof e==`object`){let n={};for(let[r,i]of Object.entries(e))n[r]=$(i,t+1);return n}return e},Tn=(t={})=>{let{preloadedState:n,enableDevToolsSanitizers:r=!0,enableDevChecks:i=!0,licenseKey:a}=t;if(a==null)throw Error(`License key required. Pass options.licenseKey or use createRecorderStore() from gps-plus-slam-app-framework. See EULA §3.`);g(a);let o=Sn(),s=n?{gpsData:n.gpsData??o.gpsData,gpsElements:n.gpsElements??o.gpsElements,arElements:n.arElements??o.arElements}:void 0;return e({reducer:{gpsData:sn,gpsElements:xn,arElements:Xe},preloadedState:s,middleware:e=>e({serializableCheck:i,immutableCheck:i}),devTools:r?{actionSanitizer:$,stateSanitizer:$}:!0})},En=[],Dn=[],On=[],kn=[],An={median:null,mean:null},jn=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentMatrix}),Mn=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentRotation}),Nn=f(function(e){return e.gpsData?.gpsEvents?.odometryPositions??En}),Pn=f(function(e){return e.gpsData?.gpsEvents?.odometryRotations??Dn}),Fn=f(function(e){return e.gpsData?.gpsEvents?.gpsPositions??On}),In=f(function(e){return e.gpsData?.referencePoints??kn}),Ln=f(function(e){return e.gpsData?.zero??null}),Rn=f(function(e){let t=e.gpsData?.gpsEvents?.gpsAccuracyMedian??null,n=e.gpsData?.gpsEvents?.gpsAccuracyMean??null;return t===null&&n===null?An:{median:t,mean:n}}),zn=`1.0.0`;export{z as IDENTITY_MATRIX4,L as IDENTITY_QUATERNION,zn as LIB_VERSION,R as ZERO_VECTOR3,an as add2dImage,_n as addArea,Ge as addCornerToEventArea,yn as addHeatMapArea,gn as addLine,hn as addMarker,Ue as addOrUpdateArPlane,vn as addToHeatMaps,Je as anchorEventAreaInWorldSpace,Xe as arElementsReducer,rn as arLoopClosureDetected,se as calcGeoHash,fe as calcGpsCoords,ae as calcQuadKey,de as calcRelativeCoordsInMeters,Se as cloneMatrix4,xe as cloneQuaternion,I as cloneVector3,Ke as correctArDriftForEventArea,Tn as createGpsSlamStore,le as distanceInMeters,ue as distanceInMetersRelative,U as enuQuaternionToNUE,W as eulerToQuaternion,qe as finishEventArea,be as fromMatrix4,M as fromQuaternion,j as fromVector3,ve as fusedGpsFromOdom,ce as geoHashToLatLong,jn as getAlignmentMatrix,Mn as getAlignmentRotation,ge as getGoogleMapsDirectionsLink,he as getGoogleMapsLink,Rn as getGpsAccuracyStats,Fn as getGpsPositions,Nn as getOdometryPositions,Pn as getOdometryRotations,_e as getOpenStreetMapLink,In as getReferencePoints,Ln as getZeroReference,sn as gpsDataReducer,xn as gpsElementsReducer,ke as invertQuaternion,Ce as isIdentityMatrix4,Te as isIdentityQuaternion,Ee as isNearIdentityQuaternion,on as markReferencePoint,Oe as multiplyQuaternions,B as normalizeQuaternion,Me as nueQuaternionToENU,je as nueQuaternionToWebXR,Ae as nueToWebXR,nn as odometryTrackingRestarted,oe as quadKeyToLatLong,we as quaternionMagnitude,De as quaternionsEquivalent,tn as recordGpsEvent,He as recordPhoneHeight,Ye as resetArElements,bn as resetGpsElements,$ as sanitizeForDevTools,en as setZeroPos,We as startEventArea,pe as toEarthCenteredCoordinates,F as toMatrix4,P as toQuaternion,N as toVector3,g as validateLicenseKey,H as webxrQuaternionToNUE,V as webxrToNUE};
|
|
2
|
+
import{configureStore as e,createSlice as t}from"@reduxjs/toolkit";import{ed25519 as n}from"@noble/curves/ed25519.js";import{hexToBytes as r}from"@noble/curves/utils.js";import{mat4 as i,quat as a,vec3 as o,vec4 as s}from"gl-matrix";import{castDraft as c}from"immer";let l=!1;function u(){l=!0}function d(){if(!l)throw Error(`gps-plus-slam-js: license not activated. Construct your store via createRecorderStore() from gps-plus-slam-app-framework, or pass a valid licenseKey to createGpsSlamStore(). See EULA §3.`)}function f(e){return((...t)=>(d(),e(...t)))}function p(e){let t=((...t)=>(d(),e(...t)));return Object.assign(t,e),t.toString=()=>e.type,t}function m(e){return(t,n)=>(d(),e(t,n))}function h(e){let t=e.replace(/-/g,`+`).replace(/_/g,`/`),n=`=`.repeat((4-t.length%4)%4),r=atob(t+n);return Uint8Array.from(r,e=>e.charCodeAt(0))}function g(e){let t=new Date,i=e.indexOf(`.`);if(i<=0||i>=e.length-1)throw Error(`Invalid license key format: expected "payload.signature" with base64url-encoded parts.`);let a,o;try{a=h(e.substring(0,i)),o=h(e.substring(i+1))}catch{throw Error(`Invalid license key format: base64url decoding failed.`)}let s=r(`dfe5c62120b7a0ce962b17907a15b27cf1b056e6619bf6ce55e6e094b322a470`);if(!n.verify(o,a,s))throw Error(`Invalid license key: signature verification failed.`);let c=JSON.parse(new TextDecoder().decode(a));if(typeof c!=`object`||!c)throw Error(`Invalid license key: payload must be a JSON object.`);let{type:l,exp:d}=c;if(l!==`community`)throw Error(`Invalid license key: "type" must be "community".`);if(typeof d!=`number`||!Number.isFinite(d))throw Error(`Invalid license key: "exp" must be a finite number (Unix timestamp in seconds).`);if(d<Math.floor(t.getTime()/1e3)){let e=new Date(d*1e3);throw Error(`License key expired on ${e.toISOString()}. Update to the latest version for a renewed community key.`)}return u(),{type:l,expiresAt:new Date(d*1e3)}}const _=180/Math.PI,v=e=>{let t=e[0],n=e[1],r=e[2],i=e[3],a=2*(i*t+n*r),o=1-2*(t*t+n*n),s=Math.atan2(a,o)*_,c=2*(i*n-r*t),l=Math.abs(c)>=1?Math.sign(c)*90:Math.asin(c)*_,u=2*(i*r+t*n),d=1-2*(n*n+r*r);return{pitch:l,yaw:Math.atan2(u,d)*_,roll:s}},y=1/298.257223563,b=y*(2-y),x=40075016.6856/360,S=39940652.7422/360,ee=Math.PI/180,C=180/Math.PI,w=`0123456789bcdefghjkmnpqrstuvwxyz`,T=[16,8,4,2,1],E=(e,t,n)=>Math.min(Math.max(e,t),n),te=e=>E(e,-180,180),D=e=>e*ee,ne=e=>e*C,re=e=>{if(!Number.isFinite(e))throw RangeError(`Coordinate values must be finite numbers`);return String(e)},ie=e=>({lat:re(e.lat),lon:re(e.lon)}),ae=(e,t=0)=>{let n=D(e.lat),r=D(e.lon),i=Math.sin(n),a=Math.cos(n),s=Math.sin(r),c=Math.cos(r),l=6378137/Math.sqrt(1-b*i*i),u=(l+t)*a*c,d=(l+t)*a*s,f=(l*(1-b)+t)*i;return o.fromValues(u,d,f)},oe=f((e,t)=>{if(t<1||t>23)throw RangeError(`levelOfDetail must be between 1 and 23 (inclusive)`);let n=E(e.lat,-85.05112878,85.05112878),r=te(e.lon),i=Math.sin(D(n)),a=256*2**t,o=(r+180)/360*a,s=(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*a,c=2**t-1,l=E(Math.floor(o/256),0,c),u=E(Math.floor(s/256),0,c),d=``;for(let e=t;e>0;--e){let t=0,n=1<<e-1;(l&n)!==0&&(t+=1),(u&n)!==0&&(t+=2),d+=t.toString()}return d}),se=f(e=>{if(!/^[0-3]+$/.test(e))throw Error(`QuadKey must consist of digits 0-3`);let t=e.length;if(t===0)throw Error(`QuadKey must not be empty`);let n=0,r=0;for(let i=0;i<t;i+=1){let a=Number.parseInt(e[i],10),o=1<<t-i-1;a&1&&(n+=o),a&2&&(r+=o)}let i=256*2**t,a=(n+.5)*256,o=(r+.5)*256,s=a/i,c=o/i,l=s*360-180;return{lat:ne(Math.atan(Math.sinh(Math.PI*(1-2*c)))),lon:l}}),ce=f((e,t)=>{if(t<=0)throw RangeError(`precision must be greater than 0`);let n=-90,r=90,i=-180,a=180,o=``,s=0,c=0,l=!0;for(;o.length<t;){if(l){let t=(i+a)/2;e.lon>=t?(c|=T[s],i=t):a=t}else{let t=(n+r)/2;e.lat>=t?(c|=T[s],n=t):r=t}l=!l,s<4?s+=1:(o+=w[c],s=0,c=0)}return o}),le=f(e=>{if(e.length===0)throw Error(`geoHash must not be empty`);let t=-90,n=90,r=-180,i=180,a=!0;for(let o of e){let e=w.indexOf(o);if(e===-1)throw Error(`Invalid geohash character: ${o}`);for(let o of T){if(a){let t=(r+i)/2;(e&o)===0?i=t:r=t}else{let r=(t+n)/2;(e&o)===0?n=r:t=r}a=!a}}return{lat:(t+n)/2,lon:(r+i)/2}}),ue=f((e,t)=>{let n=D(e.lat),r=D(t.lat),i=r-n,a=D(t.lon-e.lon),o=Math.sin(i/2),s=Math.sin(a/2),c=o*o+Math.cos(n)*Math.cos(r)*s*s,l=Math.min(1,Math.max(0,c));return 6371008.8*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}),de=f((e,t)=>{let n=O(e,t);return Math.hypot(n[0],n[2])}),O=f((e,t,n=0,r=0)=>{let i=(t.lon-e.lon)*x*Math.cos(D(e.lat)),a=(t.lat-e.lat)*S,s=n-r;return o.fromValues(a,s,i)}),k=f((e,t)=>{let n=t[0],r=t[2];return{lat:n/S+e.lat,lon:r/(x*Math.cos(D(e.lat)))+e.lon}}),fe=f((e,t=0)=>ae(e,t)),A=e=>{let{lat:t,lon:n}=ie(e);return`${t}%2C${n}`},pe=f(e=>`https://www.google.com/maps/search/?api=1&query=${A(e)}`),me=f((e,t)=>`https://www.google.com/maps/dir/?api=1&origin=${A(t)}&destination=${A(e)}`),he=f((e,t=19)=>{let{lat:n,lon:r}=ie(e);return`https://www.openstreetmap.org/query?lat=${n}&lon=${r}#map=${t}/${n}/${r}`}),ge=f((e,t,n)=>{let r=i.fromValues(...e),a=o.fromValues(t[0],t[1],t[2]),s=o.create();o.transformMat4(s,a,r);let{lat:c,lon:l}=k(n,s);return{lat:c,lon:l,altitude:s[1]}}),_e=()=>({points:[]}),ve=()=>({gpsMarkers:[],gpsLines:[],areas:[],heatMap:{},heatAreas:{}}),j=()=>({arPlanes:{},floorDetections:[],eventAreas:[],currentEventAreaId:null,currentEventAreaPoints:[]}),M=e=>o.fromValues(e[0],e[1],e[2]),N=e=>a.fromValues(e[0],e[1],e[2],e[3]),ye=e=>i.fromValues(...e),P=e=>[e[0],e[1],e[2]],F=e=>[e[0],e[1],e[2],e[3]],I=e=>[e[0],e[1],e[2],e[3],e[4],e[5],e[6],e[7],e[8],e[9],e[10],e[11],e[12],e[13],e[14],e[15]],L=e=>[e[0],e[1],e[2]],be=e=>[e[0],e[1],e[2],e[3]],xe=e=>[...e],R=Object.freeze([0,0,0,1]),z=Object.freeze([0,0,0]),B=Object.freeze([1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]),V=e=>{let t=Ce(e);if(t===0)return R;let n=1/t;return[e[0]*n,e[1]*n,e[2]*n,e[3]*n]},Se=e=>{for(let t=0;t<16;t++)if(e[t]!==B[t])return!1;return!0},Ce=e=>Math.sqrt(e[0]*e[0]+e[1]*e[1]+e[2]*e[2]+e[3]*e[3]),we=e=>e[0]===0&&e[1]===0&&e[2]===0&&e[3]===1,Te=(e,t)=>Math.abs(e[0])<t&&Math.abs(e[1])<t&&Math.abs(e[2])<t&&Math.abs(e[3]-1)<t,Ee=(e,t,n=1e-10)=>{let r=Math.abs(e[0]-t[0])<n&&Math.abs(e[1]-t[1])<n&&Math.abs(e[2]-t[2])<n&&Math.abs(e[3]-t[3])<n,i=Math.abs(e[0]+t[0])<n&&Math.abs(e[1]+t[1])<n&&Math.abs(e[2]+t[2])<n&&Math.abs(e[3]+t[3])<n;return r||i},De=(e,t)=>{let n=a.create();return a.multiply(n,e,t),[n[0],n[1],n[2],n[3]]},Oe=e=>{let t=a.create();return a.invert(t,e),[t[0],t[1],t[2],t[3]]},H=e=>[-e[2],e[1],e[0]],ke=e=>[e[2],e[1],-e[0]],U=e=>[-e[2],e[1],e[0],e[3]],Ae=e=>[e[2],e[1],-e[0],e[3]],W=e=>[e[1],e[2],e[0],e[3]],je=e=>[e[2],e[0],e[1],e[3]],G=(e,t,n)=>{if(!Number.isFinite(e)||!Number.isFinite(t)||!Number.isFinite(n))throw Error(`eulerToQuaternion: non-finite input (alpha=${e}, beta=${t}, gamma=${n})`);let r=e*Math.PI/180,i=t*Math.PI/180,o=n*Math.PI/180,s=a.create(),c=a.create(),l=a.create();a.setAxisAngle(s,[0,0,1],r),a.setAxisAngle(c,[1,0,0],i),a.setAxisAngle(l,[0,1,0],o);let u=a.create();return a.multiply(u,s,c),a.multiply(u,u,l),[u[0],u[1],u[2],u[3]]},Me=t({name:`arElements`,initialState:j(),reducers:{recordPhoneHeight:(e,t)=>{e.floorDetections.push(t.payload)},addOrUpdateArPlane:(e,t)=>{let n=t.payload;if(n.parentPlaneId){delete e.arPlanes[n.planeId];return}e.arPlanes[n.planeId]=c(n)},startEventArea:(e,t)=>{e.currentEventAreaId=t.payload.id,e.currentEventAreaPoints=[]},addCornerToEventArea:(e,t)=>{e.currentEventAreaId&&e.currentEventAreaPoints.push(c(L(t.payload.position)))},correctArDriftForEventArea:(e,t)=>{let n=t.payload.drift;for(let t of e.currentEventAreaPoints)t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]},finishEventArea:(e,t)=>{e.currentEventAreaId&&(e.eventAreas.push({id:e.currentEventAreaId,label:t.payload.label,polygon:[],isInArSpace:!0,arPoints:e.currentEventAreaPoints}),e.currentEventAreaId=null,e.currentEventAreaPoints=[])},anchorEventAreaInWorldSpace:(e,t)=>{let{areaId:n,alignmentMatrix:r,zeroRef:i}=t.payload,a=e.eventAreas.findIndex(e=>e.id===n);if(a===-1)return;let s=e.eventAreas[a];if(!s.isInArSpace||!s.arPoints)throw Error(`The area ${s.id} is already anchored in world space`);let c=ye(r),l=s.arPoints.map(e=>{let t=M(e);return k(i,o.transformMat4(o.create(),t,c))});e.eventAreas[a]={...s,isInArSpace:!1,polygon:l,arPoints:void 0}},resetArElements:()=>j()}}),{recordPhoneHeight:Ne,addOrUpdateArPlane:Pe,startEventArea:Fe,addCornerToEventArea:Ie,correctArDriftForEventArea:Le,finishEventArea:Re,anchorEventAreaInWorldSpace:ze,resetArElements:Be}=Me.actions,Ve=p(Ne),He=p(Pe),Ue=p(Fe),We=p(Ie),Ge=p(Le),Ke=p(Re),qe=p(ze),Je=p(Be),Ye=m(Me.reducer);function Xe(e,t,n,r){let{inCentroid:i,refCentroid:a,refVec:s,tmp:c}=r;o.set(i,0,0,0),o.set(a,0,0,0);let l=0;for(let n=0;n<e.length;n++){let r=t[n][3];o.scaleAndAdd(i,i,e[n],r),K(s,t[n]),o.scaleAndAdd(a,a,s,r),l+=r}if(l===0)throw Error(`Weights must not sum to zero when solving Kabsch`);let u=1/l;if(o.scale(i,i,u),o.scale(a,a,u),!n)return{inCentroid:i,refCentroid:a,scaleRatio:1};let d=0,f=0;for(let n=0;n<e.length;n++)o.subtract(c,e[n],i),d+=o.length(c),K(s,t[n]),o.subtract(c,s,a),f+=o.length(c);return{inCentroid:i,refCentroid:a,scaleRatio:d===0?1:f/d}}function Ze(e,t,n,r,a,s,c){let{negCentroid:l,scaleVec:u}=c;return i.fromRotationTranslation(e,r,n),s&&(o.set(u,a,a,a),i.scale(e,e,u)),o.negate(l,t),i.translate(e,e,l),e}function Qe(e,t,n={}){let r=e.length;if(r!==t.length)throw Error(`Length of the point lists was not equal: ${r} vs ${t.length}`);if(r===0)return i.create();let s=n.solveRotation??!0,c=n.solveScale??!1,l=n.ignoreYAxisForRotation??!1,u=n.rotationIterations??9,{inCentroid:d,refCentroid:f,scaleRatio:p}=Xe(e,t,c,{inCentroid:o.create(),refCentroid:o.create(),refVec:o.create(),tmp:o.create()}),m=a.create();s?new $e(l).solve(e,t,d,f,m,u):a.identity(m);let h={negCentroid:o.create(),scaleVec:o.create()};return Ze(i.create(),d,f,m,p,c,h)}var $e=class e{ignoreYAxis;static twoPi=Math.PI*2;static basisX=o.fromValues(1,0,0);static basisY=o.fromValues(0,1,0);static basisZ=o.fromValues(0,0,1);constructor(e){this.ignoreYAxis=e}solve(t,n,r,i,o,s){let c=this.transposeMultSubtract(t,n,r,i);if(this.ignoreYAxis){let t=c[0][0],n=c[0][2],r=c[2][0],i=c[2][2],s=Math.atan2(r-n,t+i);a.setAxisAngle(o,e.basisY,s)}else this.extractRotation(c,o,s)}transposeMultSubtract(e,t,n,r){let i=[o.create(),o.create(),o.create()],a=o.clone(n),s=o.clone(r);this.ignoreYAxis&&(a[1]=0,s[1]=0);let c=o.create(),l=o.create(),u=o.create();for(let n=0;n<e.length;n++){o.copy(c,e[n]),K(u,t[n]),this.ignoreYAxis&&(c[1]=0,u[1]=0);let r=t[n][3];o.subtract(c,c,a),o.scale(c,c,r),o.subtract(l,u,s),i[0][0]+=c[0]*l[0],i[1][0]+=c[1]*l[0],i[2][0]+=c[2]*l[0],i[0][1]+=c[0]*l[1],i[1][1]+=c[1]*l[1],i[2][1]+=c[2]*l[1],i[0][2]+=c[0]*l[2],i[1][2]+=c[1]*l[2],i[2][2]+=c[2]*l[2]}return i}extractRotation(t,n,r){let i=[o.create(),o.create(),o.create()],s=o.create(),c=o.create(),l=o.create();for(let u=0;u<r;u++){this.fillMatrixFromQuaternion(n,i),o.cross(s,i[0],t[0]),o.cross(l,i[1],t[1]),o.add(s,s,l),o.cross(l,i[2],t[2]),o.add(s,s,l);let r=o.dot(i[0],t[0])+o.dot(i[1],t[1])+o.dot(i[2],t[2])+1e-9;r=Math.abs(r),o.scale(s,s,1/r);let u=o.length(s);if(u<1e-9)break;o.scale(c,s,1/u);let d=u%e.twoPi,f=a.create();a.setAxisAngle(f,c,d),a.multiply(n,f,n),a.normalize(n,n)}}fillMatrixFromQuaternion(t,n){o.transformQuat(n[0],e.basisX,t),o.transformQuat(n[1],e.basisY,t),o.transformQuat(n[2],e.basisZ,t)}};const K=(e,t)=>(e[0]=t[0],e[1]=t[1],e[2]=t[2],e);function et(e,t,n,r,i,a,o=Math.random){let s=Array.from(e);if(n>s.length)throw RangeError(`minSampleSize must be smaller than the number of elements: minSampleSize=${n}, elements=${s.length}`);return rt(s,tt(s,t,n,r,i,a,o),i,a)}function tt(e,t,n,r,i,a,o){let s=null,c=Array(n),l=new Uint8Array(e.length);for(let u=0;u<r;u+=1){it(e,n,o,c,l);let{inliers:r,outliers:u}=nt(e,l,i(c),a);if(s===null||n+r.length>=t){let e=[...c,...r],t=i(e),n=q(t,`createModel must assign totalModelError for comparison during RANSAC`);(s===null||n<s.error)&&(t.inliers=e,t.outliers=u,s={model:t,error:n})}}return s?.model??null}function nt(e,t,n,r){let i=[],a=[];for(let o=0;o<e.length;o+=1){if(t?.[o])continue;let s=e[o];(r(n,s)?i:a).push(s)}return{inliers:i,outliers:a}}function rt(e,t,n,r){let i=t??n(e);q(i,`RANSAC failed to produce a model with totalModelError`);let{inliers:a,outliers:o}=nt(e,null,i,r);return a.length>0&&(i=n(a),q(i,`createModel must assign totalModelError for final RANSAC model`)),i.inliers=a,i.outliers=o,i}function q(e,t){let{totalModelError:n}=e;if(n==null)throw Error(t);return n}function it(e,t,n,r,i){i.fill(0);let a=0;for(;a<t;){let t=Math.floor(n()*e.length);i[t]||(i[t]=1,r[a]=e[t],a+=1)}}const at={useOnlyRecentData:!1,recentSeconds:180,includeTimeWeight:!0,weightByTimeFactor:2500,ignoreYAxisForRotation:!0,useRansac:!1,ransacInlierRatio:.95,ransacSampleRatio:.3,ransacMaxIterations:230,ransacErrorTolerance:1,geohashPrecision:8,geohashWindowSize:10,gpsAccuracyExponent:.1,altitudeAlignmentMode:`separate1D`,altitudeAggregator:`mean`,altitudeSampleSet:`all`,gpsVerticalAccuracyExponent:5},ot=e=>e.map(e=>L(e)),st=e=>e.map(e=>V(e)),ct=e=>e.map(Nt),lt=e=>e.map(e=>[e[0],e[1],e[2],e[3]]),J=e=>Array.isArray(e)?e:P(e),Y=e=>Array.isArray(e)?e:F(e),ut=(e,t,n,r)=>({odometryPosOffset:L(J(e)),odometryRotOffset:V(Y(t)),latestLoopClosureFixPointPos:n?L(J(n)):null,latestLoopClosureFixPointRot:r?V(Y(r)):null}),dt=(e,t,n,r)=>({odometryPositions:[],odometryRotations:[],gpsPositions:[],gpsPositionsVec4:[],alignmentMatrix:[...B],alignmentRotation:[...R],alignmentTranslation:[...z],alignmentRotationInDegree:[...z],...ut(e,t,n,r),gpsAccuracyMedian:null,gpsAccuracyMean:null,currentGpsPosGeoHash:null}),ft=()=>dt(z,R,null,null),pt=(e,t,n,r)=>{let i=e.map(e=>J(e)),a=t.map(e=>V(Y(e))),o=n.map(Nt),s=r.gpsAccuracyExponent;for(let e of o)e.weight=X(e.latLongAccuracy,s);let c=o.map(jt),l=r.includeTimeWeight?Dt(c,o,r.weightByTimeFactor):c,u=r.useOnlyRecentData?Tt(o,r.recentSeconds):0,d=i.slice(u).map(M),f=o.slice(u);return{allPositionTuples:i,allRotationTuples:a,allGpsPoints:o,allVec4Tuples:l,solverPositionsTyped:d,solverGpsPoints:f,solverWeightedVec4Tuples:l.slice(u),solverVerticalWeights:Et(f,r)}},mt=e=>{let{odometryPositions:t,odometryRotations:n,gpsPoints:r,odometryPosOffset:i=z,odometryRotOffset:s=R,latestLoopClosureFixPointPos:c=null,latestLoopClosureFixPointRot:l=null,alignmentConfig:u,random:d}=e;if(t.length!==n.length||t.length!==r.length)throw Error(`GpsEvents requires odometry positions, rotations, and gps points to have identical lengths`);let f={...at,...u??{}};if(t.length===0)return dt(i,s,c,l);let{allPositionTuples:p,allRotationTuples:m,allGpsPoints:h,allVec4Tuples:g,solverPositionsTyped:_,solverGpsPoints:v,solverWeightedVec4Tuples:y,solverVerticalWeights:b}=pt(t,n,r,f),x=vt(_,y,b,f,d??Math.random),S=a.create(),ee=o.create(),C=o.create();gt(x.matrix,S,ee,C);let{mean:w,median:T}=kt(h),E=Ot(r,f.geohashPrecision,f.geohashWindowSize);return{odometryPositions:ot(p),odometryRotations:st(m),gpsPositions:ct(h),gpsPositionsVec4:lt(g),alignmentMatrix:I(x.matrix),alignmentRotation:F(S),alignmentTranslation:P(ee),alignmentRotationInDegree:P(C),...ut(i,s,c,l),gpsAccuracyMedian:T,gpsAccuracyMean:w,currentGpsPosGeoHash:E}},X=(e,t)=>e!=null&&e>0?1/Math.max(e,1)**+t:1,ht=(e,t,n,r,i,s)=>{let c=e.odometryPositions,l=e.odometryRotations,u=e.gpsPositions,d=e.gpsPositionsVec4;c.push(J(t)),l.push(V(Y(n)));let f=Nt(r);u.push(f);let p={...at,...i??{}};f.weight=X(f.latLongAccuracy,p.gpsAccuracyExponent);let m=jt(f);if(p.includeTimeWeight){d.push(m);let e=Dt(d,u,p.weightByTimeFactor);for(let t=0;t<e.length;t++)d[t]=e[t]}else d.push(m);let h=0;p.useOnlyRecentData&&(h=Tt(u,p.recentSeconds));let g=vt(c.slice(h).map(M),d.slice(h),Et(u.slice(h),p),p,s??Math.random);e.alignmentMatrix=I(g.matrix);let _=a.create(),v=o.create(),y=o.create();gt(g.matrix,_,v,y),e.alignmentRotation=F(_),e.alignmentTranslation=P(v),e.alignmentRotationInDegree=P(y);let{mean:b,median:x}=kt(u);e.gpsAccuracyMean=b,e.gpsAccuracyMedian=x,e.currentGpsPosGeoHash=Ot(u,p.geohashPrecision,p.geohashWindowSize)},gt=(e,t,n,r)=>{i.getRotation(t,e),a.normalize(t,t),i.getTranslation(n,e),At(t,r)},Z=o.create(),_t=o.create(),vt=(e,t,n,r,a)=>{if(e.length===0)return{matrix:i.create(),meanError:0};let o=e.length,c=[];for(let r=0;r<o;r+=1){let i=t[r];c.push({odom:e[r],ref:s.fromValues(i[0],i[1],i[2],i[3]),verticalWeight:n[r]??1})}let l,u,d;if(r.useRansac&&c.length>=3){let e=c.length,t=Math.max(3,Math.min(e,Math.ceil(e*r.ransacSampleRatio))),n=et(c,Math.max(t,Math.min(e,Math.ceil(e*r.ransacInlierRatio))),t,r.ransacMaxIterations,e=>St(e,r.ignoreYAxisForRotation),(e,t)=>Ct(e,t)<e.meanAlignmentError+r.ransacErrorTolerance,a);l=n.alignmentMatrix,u=n.meanAlignmentError,n.inliers!==void 0&&(d=Array.from(n.inliers))}else{let e=St(c,r.ignoreYAxisForRotation);l=e.alignmentMatrix,u=e.meanAlignmentError}return r.altitudeAlignmentMode===`separate1D`&&yt(l,c,d,r),{matrix:l,meanError:u}},yt=(e,t,n,r)=>{let i=r.altitudeSampleSet===`horizontalInliers`&&n!==void 0&&n.length>0?n:t;if(i.length===0)return;let a=Array(i.length),o=Array(i.length);for(let e=0;e<i.length;e+=1){let t=i[e];a[e]=t.ref[1]-t.odom[1];let n=t.verticalWeight;o[e]=n>0&&Number.isFinite(n)?n:0}e[13]=r.altitudeAggregator===`median`?xt(a,o):bt(a,o)},bt=(e,t)=>{let n=0,r=0;for(let i=0;i<e.length;i+=1)n+=e[i]*t[i],r+=t[i];if(r>0&&Number.isFinite(r))return n/r;let i=0;for(let t=0;t<e.length;t+=1)i+=e[t];return e.length===0?0:i/e.length},xt=(e,t)=>{if(e.length===0)return 0;if(e.length===1)return e[0];let n=e.map((e,t)=>t);n.sort((t,n)=>e[t]-e[n]);let r=0;for(let e=0;e<t.length;e+=1)r+=t[e];if(!(r>0)||!Number.isFinite(r)){let t=n.map(t=>e[t]);return t[Math.floor((t.length-1)/2)]}let i=r/2,a=0;for(let r=0;r<n.length;r+=1)if(a+=t[n[r]],a>=i)return e[n[r]];return e[n[n.length-1]]},St=(e,t)=>{let n=Array.from(e),r=n.length,i=Array(r),a=Array(r);for(let e=0;e<r;e+=1)i[e]=n[e].odom,a[e]=n[e].ref;let s=Qe(i,a,{ignoreYAxisForRotation:t}),c=0;for(let e=0;e<r;e+=1)o.transformMat4(Z,i[e],s),c+=wt(Z,n[e].ref);return{alignmentMatrix:s,meanAlignmentError:r===0?0:c/r,totalModelError:c}},Ct=(e,t)=>(o.transformMat4(Z,t.odom,e.alignmentMatrix),wt(Z,t.ref)),wt=(e,t)=>(o.set(_t,t[0],t[1],t[2]),o.squaredDistance(e,_t)),Tt=(e,t)=>{if(e.length===0||t<=0)return 0;let n=e[e.length-1].timestamp-t*1e3;for(let t=0;t<e.length;t+=1)if(e[t].timestamp>=n)return t;return 0},Et=(e,t)=>{let n=t.gpsVerticalAccuracyExponent,r=e.map(e=>{let t=e.altitudeAccuracy;return X(t!=null&&Number.isFinite(t)&&t>0?t:e.latLongAccuracy,n)});if(!t.includeTimeWeight||e.length<2)return r;let i=e[e.length-1].timestamp,a=e[0].timestamp,o=Math.max(1,i-a),s=t.weightByTimeFactor;return r.map((t,n)=>{if(!(t>0&&Number.isFinite(t)))return 0;let r=s*((i-e[n].timestamp)/o)+1;return 1/(1/t+r)})},Dt=(e,t,n)=>{if(e.length<2)return e.map(e=>[e[0],e[1],e[2],e[3]]);let r=t[t.length-1].timestamp,i=t[0].timestamp,a=Math.max(1,r-i);return e.map((e,i)=>{let o=n*((r-t[i].timestamp)/a)+1,s=t[i].weight;if(!(s>0&&Number.isFinite(s)))return[e[0],e[1],e[2],0];let c=1/(1/s+o);return[e[0],e[1],e[2],c]})},Q=new Map,Ot=(e,t,n)=>{if(e.length===0)return null;let r=Math.max(0,e.length-n);Q.clear();for(let n=r;n<e.length;n+=1){let r=e[n],i=ce(Mt(r),t),a=Q.get(i);a?(a.count+=1,a.index=n):Q.set(i,{count:1,index:n})}let i=null,a=-1,o=-1;for(let[e,{count:t,index:n}]of Q)(t>a||t===a&&n>o)&&(i=e,a=t,o=n);return i},kt=e=>{let t=e.map(e=>e.latLongAccuracy).filter(e=>typeof e==`number`&&Number.isFinite(e));if(t.length===0)return{mean:null,median:null};let n=t.reduce((e,t)=>e+t,0)/t.length,r=t.slice().sort((e,t)=>e-t),i=Math.floor(r.length/2);return{mean:n,median:r.length%2==0?(r[i-1]+r[i])/2:r[i]}},At=(e,t)=>{let n=e[0],r=e[1],i=e[2],a=e[3],s=2*(a*n+r*i),c=1-2*(n*n+r*r),l=Math.atan2(s,c),u=2*(a*r-i*n),d;d=Math.abs(u)>=1?Math.PI/2*Math.sign(u):Math.asin(u);let f=2*(a*i+n*r),p=1-2*(r*r+i*i),m=Math.atan2(f,p),h=180/Math.PI,g=t??o.create();return g[0]=l*h,g[1]=d*h,g[2]=m*h,g},jt=e=>[e.coordinates[0],e.coordinates[1],e.coordinates[2],e.weight>0&&Number.isFinite(e.weight)?e.weight:1],Mt=e=>({lat:e.latitude,lon:e.longitude}),Nt=e=>({...e,zeroRef:{lat:e.zeroRef.lat,lon:e.zeroRef.lon},coordinates:[e.coordinates[0],e.coordinates[1],e.coordinates[2]],timestamp:e.timestamp,deviceRotation:e.deviceRotation?V(Y(e.deviceRotation)):void 0}),Pt=({lat:e,lon:t})=>{if(!Number.isFinite(e))throw Error(`Invalid latitude value: ${e}`);if(!Number.isFinite(t))throw Error(`Invalid longitude value: ${t}`);if(e<-90||e>90)throw Error(`Invalid latitude range: ${e}`);if(t<-180||t>180)throw Error(`Invalid longitude range: ${t}`)},Ft=o.fromValues(1,1,1),It=(e,t)=>[e[0]+t[0],e[1]+t[1],e[2]+t[2]],Lt=(e,t,n)=>{let r=O(t,{lat:e.latitude,lon:e.longitude},e.altitude??0,0),i=n?.alpha!=null&&n?.beta!=null&&n?.gamma!=null?W(G(n.alpha,n.beta,n.gamma)):void 0;return{...e,zeroRef:t,coordinates:P(r),weight:1,deviceRotation:i}},Rt=(e,t,n)=>{if(e)return G(e.alpha,e.beta,e.gamma);if(t)return t;throw Error(`Sensor rotation missing for ${n}: neither raw orientation nor legacy quaternion provided`)},zt=e=>{let t=a.invert(a.create(),e);if(!t)throw Error(`Encountered non-invertible quaternion`);return t},Bt=e=>{let t=zt(a.normalize(a.create(),N(e.lastSensorRot))),n=a.normalize(a.create(),N(e.lastValidOdomRot)),r=a.multiply(a.create(),t,n),i=a.normalize(a.create(),N(e.newSensorRot)),o=a.multiply(a.create(),i,r),s=a.normalize(a.create(),N(e.newOdomRot)),c=a.multiply(a.create(),o,s);return a.normalize(c,c),F(c)},Vt=(e,t)=>{let n=i.create();return i.fromRotationTranslationScale(n,a.normalize(a.create(),N(t)),M(e),Ft),n},Ht=(e,t,n)=>{let r=o.create(),s=o.create(),c=a.create(),l=a.create();i.getTranslation(r,e),i.getTranslation(s,t),i.getRotation(c,e),i.getRotation(l,t);let u=o.create();o.lerp(u,r,s,n);let d=a.create();return a.slerp(d,c,l,n),i.fromRotationTranslation(i.create(),d,u)},Ut=(e,t)=>{if(e.length===0)return[];let n=e[e.length-1],r=i.invert(i.create(),n);if(!r)throw Error(`End pose matrix is not invertible`);let a=i.multiply(i.create(),t,r),o=i.create(),s=e.length-1;return e.map((e,t)=>{let n=Ht(o,a,s<=0?1:t/s);return i.multiply(i.create(),n,e)})},Wt=(e,t,n)=>{for(let r=e.length-1;r>=0;--r)if(n(e[r],t))return r;return-1},Gt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2],Kt=(e,t)=>e[0]===t[0]&&e[1]===t[1]&&e[2]===t[2]&&e[3]===t[3],qt=t({name:`gpsData`,initialState:null,reducers:{setZeroPos:{reducer:(e,t)=>e===null?{zero:t.payload,gpsEvents:ft(),odometryPath:_e()}:e,prepare:e=>(Pt(e),{payload:e})},recordGpsEvent:(e,t)=>{if(!e)return e;let{odomPosition:n,odomRotation:r,rawGpsPoint:i,rawDeviceOrientation:a}=t.payload,o=Lt(i,e.zero,a);ht(e.gpsEvents,H(n),U(r),o)},odometryTrackingRestarted:(e,t)=>{if(!e)return e;let n=It(e.gpsEvents.odometryPosOffset,H(t.payload.lastValidOdomPos)),r=Rt(t.payload.lastSensorOrientation,t.payload.lastSensorRot,`lastSensor`),i=Rt(t.payload.newSensorOrientation,t.payload.newSensorRot,`newSensor`);e.gpsEvents=c(mt({odometryPositions:[],odometryRotations:[],gpsPoints:[],odometryPosOffset:n,odometryRotOffset:Bt({...t.payload,lastValidOdomRot:U(t.payload.lastValidOdomRot),newOdomRot:U(t.payload.newOdomRot),lastSensorRot:W(r),newSensorRot:W(i)}),latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null}))},arLoopClosureDetected:(e,t)=>{if(!e)return e;let n=e.gpsEvents;if(n.odometryPositions.length===0)return e;let r=n.latestLoopClosureFixPointPos?Wt(n.odometryPositions,n.latestLoopClosureFixPointPos,Gt):0,s=n.latestLoopClosureFixPointRot?Wt(n.odometryRotations,n.latestLoopClosureFixPointRot,Kt):0;if(r<0||s<0)throw Error(`Loop closure fix point could not be located in history`);if(r!==s)throw Error(`Loop closure fix point indices for position and rotation diverged`);let l=n.odometryPositions.slice(0,r).map(e=>L(e)),u=n.odometryRotations.slice(0,r).map(e=>V(e)),d=n.odometryPositions.slice(r).map(e=>L(e)),f=n.odometryRotations.slice(r).map(e=>V(e)),p=d.map((e,t)=>Vt(e,f[t])),m=Vt(H(t.payload.lastPos),V(U(t.payload.lastRot)));p.push(m);let h=Ut(p,Vt(H(t.payload.newPos),V(U(t.payload.newRot)))),g=[],_=[],v=o.create();for(let e=0;e<h.length-1;e+=1){let t=h[e],n=o.create();i.getTranslation(n,t);let r=a.create();if(i.getRotation(r,t),a.normalize(r,r),i.getScaling(v,t),Math.hypot(v[0]-1,v[1]-1,v[2]-1)>.05)throw Error(`Unexpected scale drift encountered during loop closure correction`);g.push(P(n)),_.push(F(r))}e.gpsEvents=c(mt({odometryPositions:l.concat(g),odometryRotations:u.concat(_),gpsPoints:n.gpsPositions,odometryPosOffset:n.odometryPosOffset,odometryRotOffset:n.odometryRotOffset,latestLoopClosureFixPointPos:null,latestLoopClosureFixPointRot:null}))},add2dImage:(e,t)=>{if(!e)return e;e.odometryPath.points.push(c({imageFile:t.payload.imageFile,screenRotation:t.payload.screenRotation,position:H(t.payload.position),rotation:V(U(t.payload.rotation)),capturedAt:t.payload.capturedAt,width:t.payload.width,height:t.payload.height}))}}}),{setZeroPos:Jt,recordGpsEvent:Yt,odometryTrackingRestarted:Xt,arLoopClosureDetected:Zt,add2dImage:Qt}=qt.actions,$t=p(Jt),en=p(Yt),tn=p(Xt),nn=p(Zt),rn=p(Qt),an=m(qt.reducer),on=t({name:`gpsElements`,initialState:ve(),reducers:{addMarker:(e,t)=>{e.gpsMarkers.push(t.payload)},addLine:(e,t)=>{e.gpsLines.push(t.payload)},addArea:(e,t)=>{e.areas.push(t.payload)},addToHeatMaps:(e,t)=>{let{category:n,tiles:r}=t.payload,i=e.heatMap[n]??{};e.heatMap[n]={...i,...r}},addHeatMapArea:(e,t)=>{let n=t.payload,r=n.category;if(e.heatAreas[r]||(e.heatAreas[r]={}),e.heatAreas[r][n.geoHash])throw Error(`HeatArea collision detected for GeoHash: ${n.geoHash}`);e.heatAreas[r][n.geoHash]=n},resetGpsElements:()=>ve()}}),{addMarker:sn,addLine:cn,addArea:ln,addToHeatMaps:un,addHeatMapArea:dn,resetGpsElements:fn}=on.actions,pn=p(sn),mn=p(cn),hn=p(ln),gn=p(un),_n=p(dn),vn=p(fn),yn=m(on.reducer),bn=()=>({gpsData:null,gpsElements:ve(),arElements:j()}),xn=e=>{let t=Array.from({length:Math.min(e.length,4)},(t,n)=>e[n].toFixed(2));e.length>4&&t.push(`…`);let n=`[${t.join(`, `)}]`;if(e.length===4){let{pitch:t,yaw:r,roll:i}=v(e);return`${n} (pitch=${t.toFixed(0)}°, yaw=${r.toFixed(0)}°, roll=${i.toFixed(0)}°)`}return n},Sn=e=>(e.length===3||e.length===4||e.length===16)&&e.every(e=>typeof e==`number`),$=(e,t=0)=>{if(t>10||e==null)return e;if(Array.isArray(e))return Sn(e)?xn(e):e.map(e=>$(e,t+1));if(typeof e==`object`){let n={};for(let[r,i]of Object.entries(e))n[r]=$(i,t+1);return n}return e},Cn=(t={})=>{let{preloadedState:n,enableDevToolsSanitizers:r=!0,enableDevChecks:i=!0,licenseKey:a}=t;if(a==null)throw Error(`License key required. Pass options.licenseKey or use createRecorderStore() from gps-plus-slam-app-framework. See EULA §3.`);g(a);let o=bn(),s=n?{gpsData:n.gpsData??o.gpsData,gpsElements:n.gpsElements??o.gpsElements,arElements:n.arElements??o.arElements}:void 0;return e({reducer:{gpsData:an,gpsElements:yn,arElements:Ye},preloadedState:s,middleware:e=>e({serializableCheck:i,immutableCheck:i}),devTools:r?{actionSanitizer:$,stateSanitizer:$}:!0})},wn=[],Tn=[],En=[],Dn={median:null,mean:null},On=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentMatrix}),kn=f(function(e){let t=e.gpsData?.gpsEvents;return!t||t.gpsPositions.length===0?null:t.alignmentRotation}),An=f(function(e){return e.gpsData?.gpsEvents?.odometryPositions??wn}),jn=f(function(e){return e.gpsData?.gpsEvents?.odometryRotations??Tn}),Mn=f(function(e){return e.gpsData?.gpsEvents?.gpsPositions??En}),Nn=f(function(e){return e.gpsData?.zero??null}),Pn=f(function(e){let t=e.gpsData?.gpsEvents?.gpsAccuracyMedian??null,n=e.gpsData?.gpsEvents?.gpsAccuracyMean??null;return t===null&&n===null?Dn:{median:t,mean:n}}),Fn=`1.0.0`;export{B as IDENTITY_MATRIX4,R as IDENTITY_QUATERNION,Fn as LIB_VERSION,z as ZERO_VECTOR3,rn as add2dImage,hn as addArea,We as addCornerToEventArea,_n as addHeatMapArea,mn as addLine,pn as addMarker,He as addOrUpdateArPlane,gn as addToHeatMaps,qe as anchorEventAreaInWorldSpace,Ye as arElementsReducer,nn as arLoopClosureDetected,ce as calcGeoHash,k as calcGpsCoords,oe as calcQuadKey,O as calcRelativeCoordsInMeters,xe as cloneMatrix4,be as cloneQuaternion,L as cloneVector3,Ge as correctArDriftForEventArea,Cn as createGpsSlamStore,ue as distanceInMeters,de as distanceInMetersRelative,W as enuQuaternionToNUE,G as eulerToQuaternion,Ke as finishEventArea,ye as fromMatrix4,N as fromQuaternion,M as fromVector3,ge as fusedGpsFromOdom,le as geoHashToLatLong,On as getAlignmentMatrix,kn as getAlignmentRotation,me as getGoogleMapsDirectionsLink,pe as getGoogleMapsLink,Pn as getGpsAccuracyStats,Mn as getGpsPositions,An as getOdometryPositions,jn as getOdometryRotations,he as getOpenStreetMapLink,Nn as getZeroReference,an as gpsDataReducer,yn as gpsElementsReducer,Oe as invertQuaternion,Se as isIdentityMatrix4,we as isIdentityQuaternion,Te as isNearIdentityQuaternion,De as multiplyQuaternions,V as normalizeQuaternion,je as nueQuaternionToENU,Ae as nueQuaternionToWebXR,ke as nueToWebXR,tn as odometryTrackingRestarted,se as quadKeyToLatLong,Ce as quaternionMagnitude,Ee as quaternionsEquivalent,en as recordGpsEvent,Ve as recordPhoneHeight,Je as resetArElements,vn as resetGpsElements,$ as sanitizeForDevTools,$t as setZeroPos,Ue as startEventArea,fe as toEarthCenteredCoordinates,I as toMatrix4,F as toQuaternion,P as toVector3,g as validateLicenseKey,U as webxrQuaternionToNUE,H as webxrToNUE};
|
|
@@ -35,6 +35,6 @@
|
|
|
35
35
|
* @see docs/2026-04-25-private-key-security-plan.md — secret-backed renewal
|
|
36
36
|
* @see ../../GpsPlusSlamJs_Docs/docs/2026-05-01-community-key-resign-cross-repo-issue.md
|
|
37
37
|
*/
|
|
38
|
-
declare const COMMUNITY_LICENSE_KEY = "
|
|
38
|
+
declare const COMMUNITY_LICENSE_KEY = "eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODEyOTEyMTg2fQ.eRcW8Abz6alOWXkRQGyA4w3s_n9lMkO_cjbmHBB0fx18675sCPDom2DL4Vu17k7Mgk9sn5T3HTHoo5BwIs_IBQ";
|
|
39
39
|
//#endregion
|
|
40
40
|
export { COMMUNITY_LICENSE_KEY };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! gps-plus-slam-js | (c) 2026 cs-util-com | UNLICENSED — see EULA.md */
|
|
2
|
-
const e=`
|
|
2
|
+
const e=`eyJ0eXBlIjoiY29tbXVuaXR5IiwiZXhwIjoxODEyOTEyMTg2fQ.eRcW8Abz6alOWXkRQGyA4w3s_n9lMkO_cjbmHBB0fx18675sCPDom2DL4Vu17k7Mgk9sn5T3HTHoo5BwIs_IBQ`;export{e as COMMUNITY_LICENSE_KEY};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gps-plus-slam-js",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "TypeScript library for real-time GPS + AR odometry alignment.",
|
|
5
5
|
"author": "cs-util-com",
|
|
6
6
|
"keywords": [
|
|
@@ -42,35 +42,35 @@
|
|
|
42
42
|
"@noble/curves": "^2.2.0",
|
|
43
43
|
"@reduxjs/toolkit": "^2.11.2",
|
|
44
44
|
"gl-matrix": "3.4.4",
|
|
45
|
-
"immer": "^11.1.
|
|
45
|
+
"immer": "^11.1.8",
|
|
46
46
|
"redux": "^5.0.1",
|
|
47
47
|
"redux-thunk": "^3.1.0"
|
|
48
48
|
},
|
|
49
49
|
"license": "UNLICENSED",
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@eslint/js": "^10.0.1",
|
|
52
|
-
"@playwright/test": "^1.
|
|
52
|
+
"@playwright/test": "^1.60.0",
|
|
53
53
|
"@stryker-mutator/core": "^9.6.1",
|
|
54
54
|
"@stryker-mutator/typescript-checker": "^9.6.1",
|
|
55
55
|
"@stryker-mutator/vitest-runner": "^9.6.1",
|
|
56
|
-
"@types/node": "^25.
|
|
57
|
-
"@vitest/coverage-v8": "^4.1.
|
|
58
|
-
"@vitest/eslint-plugin": "^1.6.
|
|
59
|
-
"dependency-cruiser": "^17.
|
|
60
|
-
"dpdm": "^4.0
|
|
61
|
-
"eslint": "^10.
|
|
56
|
+
"@types/node": "^25.7.0",
|
|
57
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
58
|
+
"@vitest/eslint-plugin": "^1.6.17",
|
|
59
|
+
"dependency-cruiser": "^17.4.0",
|
|
60
|
+
"dpdm": "^4.2.0",
|
|
61
|
+
"eslint": "^10.3.0",
|
|
62
62
|
"eslint-config-prettier": "^10.1.8",
|
|
63
|
-
"fast-check": "^4.
|
|
64
|
-
"globals": "^17.
|
|
65
|
-
"jscpd": "^4.
|
|
66
|
-
"knip": "^6.
|
|
63
|
+
"fast-check": "^4.8.0",
|
|
64
|
+
"globals": "^17.6.0",
|
|
65
|
+
"jscpd": "^4.1.1",
|
|
66
|
+
"knip": "^6.13.1",
|
|
67
67
|
"prettier": "^3.8.3",
|
|
68
68
|
"serve": "^14.2.6",
|
|
69
|
-
"tailwindcss": "^4.
|
|
70
|
-
"tsdown": "^0.
|
|
69
|
+
"tailwindcss": "^4.3.0",
|
|
70
|
+
"tsdown": "^0.22.0",
|
|
71
71
|
"typescript": "^6.0.3",
|
|
72
|
-
"typescript-eslint": "^8.59.
|
|
73
|
-
"vitest": "^4.1.
|
|
72
|
+
"typescript-eslint": "^8.59.3",
|
|
73
|
+
"vitest": "^4.1.6"
|
|
74
74
|
},
|
|
75
75
|
"scripts": {
|
|
76
76
|
"generate-keys": "node scripts/generate-keys.mjs",
|