@ingissa/navcore-core 1.0.3 → 1.0.5
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/dist/{NavCore.d-BuXR5DO7.d.mts → NavCore-qf5_0qsR.d.mts} +45 -45
- package/dist/{NavCore.d-BuXR5DO7.d.ts → NavCore-qf5_0qsR.d.ts} +45 -45
- package/dist/core.d.mts +36 -32
- package/dist/core.d.ts +36 -32
- package/dist/core.js +2 -2
- package/dist/core.mjs +2 -2
- package/dist/index.d.mts +2 -65
- package/dist/index.d.ts +2 -65
- package/dist/index.js +3 -3
- package/dist/index.mjs +3 -3
- package/dist/index.pro-C5J1xlzt.d.ts +535 -0
- package/dist/index.pro-Cg6394f_.d.mts +535 -0
- package/dist/pro.d.mts +2 -488
- package/dist/pro.d.ts +2 -488
- package/dist/pro.js +1 -1
- package/dist/pro.mjs +1 -1
- package/package.json +8 -8
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var Ne=Object.defineProperty;var Pe=(s,e)=>{for(var t in e)Ne(s,t,{get:e[t],enumerable:true});};function y(s,e,t,n){let i=(t-s)*(Math.PI/180),r=(n-e)*(Math.PI/180),o=Math.sin(i/2)*Math.sin(i/2)+Math.cos(s*(Math.PI/180))*Math.cos(t*(Math.PI/180))*Math.sin(r/2)*Math.sin(r/2);return 6371e3*(2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o)))}function B(s,e,t,n){let i=n/6371e3,r=t*(Math.PI/180),o=s*(Math.PI/180),c=e*(Math.PI/180),a=Math.asin(Math.sin(o)*Math.cos(i)+Math.cos(o)*Math.sin(i)*Math.cos(r));return [((c+Math.atan2(Math.sin(r)*Math.sin(i)*Math.cos(o),Math.cos(i)-Math.sin(o)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function we(s,e){let t=s[1]*(Math.PI/180),n=s[0]*(Math.PI/180),i=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),o=Math.sin(r-n)*Math.cos(i),c=Math.cos(t)*Math.sin(i)-Math.sin(t)*Math.cos(i)*Math.cos(r-n),a=Math.atan2(o,c)*(180/Math.PI);return a=(a+360)%360,a}function E(s){let e=s%360;return e>180?e-360:e<-180?e+360:e}function R(s,e){let t=s[1]*(Math.PI/180),n=s[0]*(Math.PI/180),i=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),o=Math.sin(r-n)*Math.cos(i),c=Math.cos(t)*Math.sin(i)-Math.sin(t)*Math.cos(i)*Math.cos(r-n);return (Math.atan2(o,c)*180/Math.PI+360)%360}function W(s,e,t){let n=(i,r,o)=>i+(r-i)*o;return [n(s[0],e[0],t),n(s[1],e[1],t)]}function H(s,e,t){let[n,i]=s,[r,o]=e,[c,a]=t,u=c-r,d=a-o,l=u*u+d*d;if(l===0)return e;let p=((n-r)*u+(i-o)*d)/l;return p=Math.max(0,Math.min(1,p)),[r+p*u,o+p*d]}function K(s){let e=new Float64Array(s.length);for(let t=1;t<s.length;t++)e[t]=e[t-1]+y(s[t-1][1],s[t-1][0],s[t][1],s[t][0]);return e}function j(s){let e=new Float64Array(s.length);for(let t=s.length-2;t>=0;t--)e[t]=e[t+1]+y(s[t][1],s[t][0],s[t+1][1],s[t+1][0]);return e}function me(s,e,t,n,i,r=1e-5,o=5e-5){s.x+=s.vx*i,s.y+=s.vy*i,s.P+=r;let c=o*Math.max(1,n/5),a=s.P/(s.P+c),u=e-s.x,d=t-s.y;return s.x+=a*u,s.y+=a*d,i>0&&(s.vx=u/i*a,s.vy=d/i*a),s.P=(1-a)*s.P,s}var D=class{constructor(e=1e-5,t=5e-5){this.lastTimestamp=0;this.Q=e,this.rBase=t,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(e,t,n){this.state={x:e,y:t,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(e,t,n,i){if(this.lastTimestamp===0)return this.init(e,t,i),[e,t];let r=Math.max(.001,(i-this.lastTimestamp)/1e3);return this.lastTimestamp=i,me(this.state,e,t,n,r,this.Q,this.rBase),[this.state.x,this.state.y]}getPosition(){return [this.state.x,this.state.y]}getState(){return {...this.state}}reset(){this.state={x:0,y:0,vx:0,vy:0,P:1},this.lastTimestamp=0;}};var Se={};Pe(Se,{ARRIVAL_THRESHOLD_METERS:()=>Ce,BASE_CORRIDOR_METERS:()=>k,BEARING_ALIGNMENT_THRESHOLD:()=>xe,BEARING_MIN_SPEED_MPS:()=>z,BEARING_MISMATCH_PENALTY:()=>ye,BEARING_MISMATCH_THRESHOLD:()=>J,BEARING_SMOOTHING_ALPHA:()=>U,BETA_CORRECTION:()=>be,DETOUR_COMMIT_MS:()=>Ue,DR_MAX_AGE_MS:()=>Y,GPS_ACCURACY_FACTOR:()=>ge,GPS_AGE_CAP_SECONDS:()=>ve,GPS_STALE_MS:()=>Ie,INERTIA_PENALTY:()=>Re,INERTIA_SEGMENT_DIST:()=>Ee,LOOK_AHEAD_SECONDS:()=>Be,MANEUVER_TRIGGER_DIST:()=>Ve,MAX_CORRIDOR_METERS:()=>$,MAX_LOOK_AHEAD_METERS:()=>He,MAX_SNAP_DISTANCE:()=>q,MIN_LOOK_AHEAD_METERS:()=>We,OFF_ROUTE_CONFIRM_MS:()=>Fe,REJOIN_CONFIRM_MS:()=>Ge,REJOIN_COOLDOWN_MS:()=>Le,SNAP_WINDOW_SIZE:()=>X,SPEED_CORRIDOR_FACTOR:()=>fe,STARTUP_GRACE_MS:()=>ke});var k=25,$=60,fe=1.2,ge=.5,q=80,J=90,ye=500,Re=200,Ee=5,X=25,U=.3,z=1.5,xe=55,Y=5e3,Fe=2e3,Ge=1500,Le=12e3,ke=3e3,Ue=4e3,Ie=3e3,ve=10,Ve=25,be=.15,Be=3,We=20,He=100,Ce=30;var Ke={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},N=class{constructor(e){this.options={...Ke,...e};}snap(e,t,n,i,r,o,c,a=null,u=null){let d=t.length,l=c,p=1/0,f=1/0,I=t[c]??[0,0];for(let v=0;v<=i;v++){let g=n+v;if(g>d-2)if(r&&o>d*.7)g=g%(d-1);else break;if(g<0||g>=d-1)continue;let b=t[g],x=t[g+1],S=H(e,b,x),O=y(e[1],e[0],S[1],S[0]);if(O>this.options.maxSnapDistance*2)continue;let C=O;if(this.options.useBearingPenalty&&a!==null){let T=R(b,x);Math.abs(E(a-T))>90&&(C+=500);}this.options.useInertiaPenalty&&u!==null&&Math.abs(g-u)>=5&&(C+=200),C<p&&(p=C,f=O,l=g,I=S);}return {idx:l,dist:f,proj:I}}};var h={GPS_SMOOTHING:"gps_smoothing",BASIC_SNAPPING:"basic_snapping",PROGRESS_TRACKING:"progress_tracking",ROUTE_OFFSET:"route_offset",DEAD_RECKONING:"dead_reckoning",ADVANCED_BEARING:"advanced_bearing",COMPOUND_DEVIATION:"compound_deviation",PARALLEL_ROAD_RESOLUTION:"parallel_road_resolution",U_TURN_PROTECTION:"u_turn_protection",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var A=class A{constructor(e){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;e&&(this.tryValidateSync(e)||this.validate(e)),this.promoteToActive();}static getActive(){return A.activeManager}static clearActive(){A.activeManager=null;}promoteToActive(){let e=A.activeManager;(e===null||e.status!=="VALID"||this.status==="VALID")&&(A.activeManager=this);}tryValidateSync(e){return e==="eyJ0IjoicHJvIiwiZXhwIjo0OTMyNzAzMTU2MDAwLCJiaWQiOiJkZXYuYnlwYXNzIiwiZiI6WyIqIl19.MEQCIH4E4QNu9PuVsXHSnYmcqpCLk4QitiIH9hhY0Zm+YO5gAiAE7X3c47YQLUj7WPSGKw9Y7W2kBUR5GCnOMBwdBsYGgg=="?typeof __DEV__<"u"&&__DEV__||typeof window<"u"&&(window.location?.hostname==="localhost"||window.location?.hostname==="127.0.0.1"||window.location?.hostname?.startsWith("192.168.")||window.location?.hostname?.endsWith(".local"))||typeof process<"u"&&(process.env?.NODE_ENV==="development"||process.env?.NODE_ENV==="test"||process.env?.VITEST==="true"||process.env?.JEST_WORKER_ID!==void 0)?(this.status="VALID",this.payload={t:"pro",exp:4932703156e3,bid:"dev.bypass",f:["*"]},this.extractFeatures(),console.log("\u{1F511} [NavCore] Development bypass key validated synchronously. Plan: pro"),true):(console.warn("[NavCore] Development bypass key is restricted to local development environments."),this.status="INVALID",this.payload=null,true):false}async validate(e){if(this.tryValidateSync(e))return this.status;try{let[t,n]=e.split(".");if(!t||!n)return this.status="INVALID",this.status;let i=atob(t);if(this.payload=JSON.parse(i),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(t,n))return this.status="INVALID",this.status;if(this.payload?.bid==="dev.bypass"&&!(typeof __DEV__<"u"&&__DEV__||typeof window<"u"&&(window.location?.hostname==="localhost"||window.location?.hostname==="127.0.0.1"||window.location?.hostname?.startsWith("192.168.")||window.location?.hostname?.endsWith(".local"))||typeof process<"u"&&(process.env?.NODE_ENV==="development"||process.env?.NODE_ENV==="test"||process.env?.VITEST==="true"||process.env?.JEST_WORKER_ID!==void 0)))return console.warn("[NavCore] Development bypass key is restricted to local development environments."),this.status="INVALID",this.payload=null,this.status;this.status="VALID",this.extractFeatures(),this.promoteToActive(),console.log(`\u{1F511} [NavCore] License validation complete. Plan: ${this.isProEnabled()?"pro":"core"}`);}catch{this.status="INVALID";}return this.status}extractFeatures(){if(this.enabledFeatures.clear(),!!this.payload){if(Array.isArray(this.payload.f))for(let e of this.payload.f)this.enabledFeatures.add(e);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(e){return this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(e)}warnOnce(e){this.warnedFeatures.has(e)||(console.warn(`[NavCore] Feature '${e}' requires a Pro license`),this.warnedFeatures.add(e));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(h.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(e,t){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let i=new TextEncoder().encode(e),r=Uint8Array.from(atob(t),a=>a.charCodeAt(0)),o=Uint8Array.from(atob(A.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),c=await crypto.subtle.importKey("spki",o,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},c,r,i)}catch{return false}}};A.activeManager=null,A.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var m=A;var je={bearingPenalty:80,bearingMismatchThresholdDeg:60,inertiaPenalty:40,inertiaSegmentDist:3},Q=class{constructor(e){this.warned=false;this.options={...je,...e};}resolve(e,t=null,n=null){let i=m.getActive();return (!i||!i.isProEnabled())&&(this.warned||(console.warn("[NavCore] ParallelRoadResolver and U-turn protection require a Pro license. Falling back to core distance snapping."),this.warned=true)),e.map(r=>this.score(r,t,n)).sort((r,o)=>r.score-o.score)}resolveBest(e,t=null,n=null){return e.length===0?null:this.resolve(e,t,n)[0]??null}score(e,t,n){let i=e.distanceMetres,r=null,o=false,c=m.getActive(),a=c&&c.isProEnabled();if(t!==null&&a){let u=R(e.segA,e.segB),d=Math.abs(E(t-u));r=d,d>this.options.bearingMismatchThresholdDeg&&(i+=this.options.bearingPenalty);}return n!==null&&a&&Math.abs(e.segmentIndex-n)>=this.options.inertiaSegmentDist&&(i+=this.options.inertiaPenalty,o=true),{...e,score:i,bearingDeltaDeg:r,inertiaPenaltyApplied:o}}isLikelyUTurn(e,t,n){let i=R(t,n);return Math.abs(E(e-i))>this.options.bearingMismatchThresholdDeg}};function Ae(s,e,t,n,i=5e3){if(!s||e<.5)return {predictedCoord:s?.coord??[0,0],isActive:false,ageMs:0};let r=n-s.ts;if(r>i||r<0)return {predictedCoord:s.coord,isActive:false,ageMs:r};let o=e*(r/1e3);return {predictedCoord:B(s.coord[1],s.coord[0],t,o),isActive:true,ageMs:r}}var P=class{constructor(e=5e3){this.anchor=null;this.warned=false;this.maxAgeMs=e;}setAnchor(e,t,n){this.anchor={coord:e,idx:t,ts:n};}predict(e,t,n){let i=m.getActive();return !i||!i.hasFeature(h.DEAD_RECKONING)?(this.warned||(i?i.warnOnce(h.DEAD_RECKONING):console.warn(`[NavCore] Feature '${h.DEAD_RECKONING}' requires a Pro license`),this.warned=true),{predictedCoord:this.anchor?.coord??[0,0],isActive:false,ageMs:0}):(this.warned=false,Ae(this.anchor,e,t,n,this.maxAgeMs))}clearAnchor(){this.anchor=null;}getAnchor(){return this.anchor}};function Oe(s,e,t,n,i=null){let r=Math.max(0,t),o=1/0,c=e[r]??[0,0],a=Math.min(t+n,e.length-1);for(let u=Math.max(0,t);u<a;u++){let d=e[u],l=e[u+1],[p,f]=s,[I,v]=d,[g,b]=l,x=g-I,S=b-v,O=x*x+S*S,C;if(O===0)C=d;else {let _=((p-I)*x+(f-v)*S)/O;_=Math.max(0,Math.min(1,_)),C=[I+_*x,v+_*S];}let T=y(s[1],s[0],C[1],C[0]);if(i!==null&&T<o*1.5){let _=R(d,l);if(Math.abs(E(i-_))>120)continue}T<o&&(o=T,r=u,c=C);}return {segmentIndex:r,distance:o,projection:c}}var w=class{constructor(){this.warned=false;}evaluate(e,t,n,i,r,o,c){let a=m.getActive();if(!a||!a.hasFeature(h.COMPOUND_DEVIATION))return this.warned||(a?a.warnOnce(h.COMPOUND_DEVIATION):console.warn(`[NavCore] Feature '${h.COMPOUND_DEVIATION}' requires a Pro license`),this.warned=true),{distanceToRoute:i.distance,outsideCorridor:false,bearingMismatch:false,movingAway:false,confirmed:false};this.warned=false;let u=i.distance>o,d=false;if(t!==null&&i.segmentIndex<r.length-1){let f=R(r[i.segmentIndex],r[i.segmentIndex+1]);d=Math.abs(E(t-f))>90;}let l=false;if(c!==null&&n>1.5){let f=r[Math.min(i.segmentIndex+2,r.length-1)];l=y(e[1],e[0],f[1],f[0])>c+5;}let p=u&&(d||l);return {distanceToRoute:i.distance,outsideCorridor:u,bearingMismatch:d,movingAway:l,confirmed:p}}};function Z(s,e=null,t=25,n=60,i=1.2,r=.5){let o=t+s*i;return e!==null&&e>0&&(o+=e*r),Math.min(o,n)}function _e(s,e=.3){return s<1.5?e*.5:s>20?Math.min(.9,e*2):e}function Me(s,e,t=3){let n=Math.min(e+t,s.length-1);return e>=s.length-1||e===n?e>0?R(s[e-1],s[e]):0:R(s[e],s[n])}function V(s,e,t){let n=E(e-s);return (s+t*n+360)%360}function ee(s,e,t,n,i,r=.3){let o=_e(n,r),c=Me(e,t);if(i!==null&&n>1.5){let a=V(s,i,o*.3);return V(a,c,o)}return V(s,c,o)}function te(s,e,t,n,i){return e<s||e>s+30||n>i?s:e}var $e=20,qe=60,Je=3;function ne(s,e,t,n,i,r,o,c=0){if(!e||e.length===0||t>=e.length)return {nextIdx:t,instruction:null,wasTriggered:false};let a=t;for(;a<e.length;){let g=e[a],b=s>g.geometryIndex+30,x=g.cumulativeOffset!==void 0&&o>g.cumulativeOffset+15;if(!b&&!x)break;a++;}if(a>=e.length)return {nextIdx:a,instruction:null,wasTriggered:false};let u=e[a],d=u.cumulativeOffset!==void 0?Math.max(0,u.cumulativeOffset-o):y(i[1],i[0],u.location[1],u.location[0]),l=Math.min(qe,Math.max($e,c*Je)),p=s<=u.geometryIndex+2,I=d<=l&&p,v=false;if(I){let g=true,b=u.bearingAfter??(u.geometryIndex<n.length-1?R(n[u.geometryIndex],n[u.geometryIndex+1]):null),x=u.bearingBefore??(u.geometryIndex>0?R(n[u.geometryIndex-1],n[u.geometryIndex]):null);x!==null&&b!==null&&r!==null&&Math.abs(E(b-x))>30&&Math.abs(E(r-b))>55&&(g=false),g&&(v=true);}return {nextIdx:a,instruction:u,wasTriggered:v}}var Xe=0;function F(){return `instr_${Date.now()}_${++Xe}`}var ie=class{constructor(){this.instructions=[];}addTurn(e,t,n,i){return this.instructions.push({id:F(),type:"turn",location:e,text:t,instruction:t,geometryIndex:n,silent:i?.silent,meta:i?.meta}),this}addExamPoint(e,t,n,i){return this.instructions.push({id:F(),type:"exam_point",location:e,text:t,instruction:t,geometryIndex:n,severity:i?.severity??"info",silent:i?.silent,meta:i?.meta}),this}addCheckpoint(e,t,n){return this.instructions.push({id:F(),type:"checkpoint",location:e,text:"",instruction:"",geometryIndex:t,silent:true,meta:n}),this}addDepart(e,t="Start navigation"){let n={id:F(),type:"depart",location:e,text:t,instruction:t,geometryIndex:0};return this.instructions.unshift(n),this}addArrive(e,t="You have arrived"){return this.instructions.push({id:F(),type:"arrive",location:e,text:t,instruction:t,geometryIndex:Number.MAX_SAFE_INTEGER}),this}update(e,t){let n=this.instructions.findIndex(i=>i.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions[n]={...this.instructions[n],...t},this}remove(e){let t=this.instructions.findIndex(n=>n.id===e);if(t===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions.splice(t,1),this}reorder(e,t){let n=this.instructions.findIndex(r=>r.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);let[i]=this.instructions.splice(n,1);return this.instructions.splice(Math.max(0,t),0,i),this}sort(){return this.instructions.sort((e,t)=>e.geometryIndex-t.geometryIndex),this}clear(){return this.instructions=[],this}attachToCumulative(e){let t=m.getActive();if(!t||!t.isProEnabled())return console.warn("[NavCore] InstructionEditor requires a Pro license. Fluent editing is disabled."),this;if(e.length<2)return this;let n=[0];for(let i=1;i<e.length;i++){let r=e[i-1],o=e[i];n.push(n[i-1]+y(r[1],r[0],o[1],o[0]));}for(let i of this.instructions){let r=Math.min(i.geometryIndex,e.length-1);i.cumulativeOffset=n[r]??0,r>0&&r<e.length-1&&(i.bearingBefore=R(e[r-1],e[r]),i.bearingAfter=R(e[r],e[r+1]));}return this}toArray(){let e=m.getActive();return !e||!e.isProEnabled()?(console.warn("[NavCore] InstructionEditor.toArray() requires a Pro license. Returning empty instruction set."),[]):this.instructions.map(({id:t,type:n,severity:i,meta:r,...o})=>o)}toRichArray(){return [...this.instructions]}get size(){return this.instructions.length}};function re(s,e,t){return s+e*t}function oe(s,e,t=.15){let n=e-s;return s+t*n}function ze(s,e,t){if(t.length===0)return [0,0];if(s<=0)return t[0];let n=e[e.length-1]??0;if(s>=n)return t[t.length-1];let i=0,r=e.length-1;for(;i<r-1;){let d=i+r>>1;e[d]<=s?i=d:r=d;}let o=e[i],a=e[r]-o;if(a===0)return t[i];let u=(s-o)/a;return W(t[i],t[r],u)}var G=class{constructor(){this._state="IDLE";this._context={resumeIndex:null};}get state(){return this._state}get context(){return {...this._context}}dispatch(e){switch(this._state){case "IDLE":e.type==="ROUTE_LOADED"&&(this._state="OVERVIEW"),e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "OVERVIEW":e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "APPROACHING_ROUTE":e.type==="ROUTE_JOINED"&&(this._state="ON_ROUTE",this._context.resumeIndex=e.data.index),e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE");break;case "ON_ROUTE":e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE"),e.type==="ROUTE_JOINED"&&(this._context.resumeIndex=e.data.index);break}return (e.type==="RESET"||e.type==="CANCEL_NAVIGATION")&&(this._state="IDLE",this._context={resumeIndex:null}),{state:this._state,context:{...this._context}}}reset(){this._state="IDLE",this._context={resumeIndex:null};}};var M={deviationSegmentIdx:null,deviationStartMs:null,tempRoute:null,rejoinTarget:null,lastRerouteMs:null,rejoinedAtMs:null,rejoinDwellFrames:0,failureReason:null},Te=2e3,Ye=3,L=class{constructor(){this._state="ON_ROUTE";this._context={...M};}get state(){return this._state}get context(){return {...this._context}}dispatch(e,t){let n=t??Date.now();switch(this._state){case "ON_ROUTE":e.type==="DEVIATION_SUSPECTED"&&(this._state="DEVIATING",this._context.deviationSegmentIdx=e.deviationSegmentIdx,this._context.deviationStartMs=n);break;case "DEVIATING":e.type==="DEVIATION_CONFIRMED"&&(this._context.deviationStartMs!==null?n-this._context.deviationStartMs:0)>=Te&&(this._state="OFF_ROUTE",this._context.deviationSegmentIdx=e.deviationSegmentIdx),(e.type==="RESUME"||e.type==="RESET")&&(this._state="ON_ROUTE",e.type==="RESET"?this._context={...M}:(this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null));break;case "OFF_ROUTE":e.type==="REROUTE_STARTED"&&(this._state="REROUTING",this._context.lastRerouteMs=n),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...M});break;case "REROUTING":e.type==="REROUTE_SUCCESS"&&(this._state="REJOINING",this._context.tempRoute=e.tempRoute,this._context.rejoinTarget=e.rejoinTarget),e.type==="REROUTE_FAILED"&&(this._state="FAILED",this._context.failureReason=e.reason);break;case "REJOINING":e.type==="REJOIN_DETECTED"&&this._context.rejoinDwellFrames++,(e.type==="REJOIN_CONFIRMED"||this._context.rejoinDwellFrames>=Ye)&&(this._state="REJOINED",this._context.rejoinedAtMs=n,this._context.rejoinDwellFrames=0),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...M});break;case "REJOINED":e.type==="RESUME"&&(this._state="ON_ROUTE",this._context.tempRoute=null,this._context.rejoinTarget=null,this._context.rejoinedAtMs=null,this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...M});break;case "FAILED":e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...M});break}return {state:this._state,context:{...this._context}}}reset(){this._state="ON_ROUTE",this._context={...M};}isDeviationConfirmed(e=Date.now()){return this._context.deviationStartMs?e-this._context.deviationStartMs>=Te:false}};var Qe=0;function De(){return `wp_${Date.now()}_${++Qe}`}var se=class{constructor(){this.waypoints=[];}addWaypoint(e,t){let n=De();return this.waypoints.push({id:n,coord:e,options:t}),n}insertWaypoint(e,t){let n=this.waypoints.findIndex(r=>r.id===t);if(n===-1)throw new Error(`Waypoint ${t} not found`);let i=De();return this.waypoints.splice(n+1,0,{id:i,coord:e,options:void 0}),i}removeWaypoint(e){let t=this.waypoints.findIndex(n=>n.id===e);if(t===-1)throw new Error(`Waypoint ${e} not found`);this.waypoints.splice(t,1);}moveWaypoint(e,t){let n=this.waypoints.find(i=>i.id===e);if(!n)throw new Error(`Waypoint ${e} not found`);n.coord=t;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(e="OVERLAP_1",t=25){let n=this.waypoints.map(c=>c.coord);if(n.length<=t)return [n];let r=t-(e==="OVERLAP_2"?2:1),o=[];for(let c=0;c<n.length;c+=r){let a=n.slice(c,c+t);if(o.push(a),c+t>=n.length)break}return o}buildStraightLine(){return {geometry:this.waypoints.map(e=>e.coord),waypoints:[...this.waypoints]}}fromGPX(e){this.waypoints=[];let t=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=t.exec(e))!==null;){let i=parseFloat(n[1]),r=parseFloat(n[2]);isFinite(i)&&isFinite(r)&&this.addWaypoint([r,i]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
|
|
1
|
+
var we=Object.defineProperty;var Ge=(s,e)=>{for(var t in e)we(s,t,{get:e[t],enumerable:true});};function f(s,e,t,n){let i=(t-s)*(Math.PI/180),r=(n-e)*(Math.PI/180),o=Math.sin(i/2)*Math.sin(i/2)+Math.cos(s*(Math.PI/180))*Math.cos(t*(Math.PI/180))*Math.sin(r/2)*Math.sin(r/2);return 6371e3*(2*Math.atan2(Math.sqrt(o),Math.sqrt(1-o)))}function B(s,e,t,n){let i=n/6371e3,r=t*(Math.PI/180),o=s*(Math.PI/180),l=e*(Math.PI/180),c=Math.asin(Math.sin(o)*Math.cos(i)+Math.cos(o)*Math.sin(i)*Math.cos(r));return [((l+Math.atan2(Math.sin(r)*Math.sin(i)*Math.cos(o),Math.cos(i)-Math.sin(o)*Math.sin(c)))*180/Math.PI+540)%360-180,c*180/Math.PI]}function Le(s,e){let t=s[1]*(Math.PI/180),n=s[0]*(Math.PI/180),i=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),o=Math.sin(r-n)*Math.cos(i),l=Math.cos(t)*Math.sin(i)-Math.sin(t)*Math.cos(i)*Math.cos(r-n),c=Math.atan2(o,l)*(180/Math.PI);return c=(c+360)%360,c}function E(s){let e=s%360;return e>180?e-360:e<-180?e+360:e}function g(s,e){let t=s[1]*(Math.PI/180),n=s[0]*(Math.PI/180),i=e[1]*(Math.PI/180),r=e[0]*(Math.PI/180),o=Math.sin(r-n)*Math.cos(i),l=Math.cos(t)*Math.sin(i)-Math.sin(t)*Math.cos(i)*Math.cos(r-n);return (Math.atan2(o,l)*180/Math.PI+360)%360}function H(s,e,t){let n=(i,r,o)=>i+(r-i)*o;return [n(s[0],e[0],t),n(s[1],e[1],t)]}function j(s,e,t){let[n,i]=s,[r,o]=e,[l,c]=t,d=l-r,u=c-o,a=d*d+u*u;if(a===0)return e;let p=((n-r)*d+(i-o)*u)/a;return p=Math.max(0,Math.min(1,p)),[r+p*d,o+p*u]}function K(s){let e=new Float64Array(s.length);for(let t=1;t<s.length;t++)e[t]=e[t-1]+f(s[t-1][1],s[t-1][0],s[t][1],s[t][0]);return e}function W(s){let e=new Float64Array(s.length);for(let t=s.length-2;t>=0;t--)e[t]=e[t+1]+f(s[t][1],s[t][0],s[t+1][1],s[t+1][0]);return e}function ge(s,e,t,n,i,r=1e-5,o=5e-5){s.x+=s.vx*i,s.y+=s.vy*i,s.P+=r;let l=o*Math.max(1,n/5),c=s.P/(s.P+l),d=e-s.x,u=t-s.y;return s.x+=c*d,s.y+=c*u,i>0&&(s.vx=d/i*c,s.vy=u/i*c),s.P=(1-c)*s.P,s}var M=class{constructor(e=1e-5,t=5e-5){this.lastTimestamp=0;this.Q=e,this.rBase=t,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(e,t,n){this.state={x:e,y:t,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(e,t,n,i){if(this.lastTimestamp===0)return this.init(e,t,i),[e,t];let r=Math.max(.001,(i-this.lastTimestamp)/1e3);return this.lastTimestamp=i,ge(this.state,e,t,n,r,this.Q,this.rBase),[this.state.x,this.state.y]}getPosition(){return [this.state.x,this.state.y]}getState(){return {...this.state}}reset(){this.state={x:0,y:0,vx:0,vy:0,P:1},this.lastTimestamp=0;}};var _e={};Ge(_e,{ARRIVAL_THRESHOLD_METERS:()=>ve,BASE_CORRIDOR_METERS:()=>L,BEARING_ALIGNMENT_THRESHOLD:()=>be,BEARING_MIN_SPEED_MPS:()=>Q,BEARING_MISMATCH_PENALTY:()=>xe,BEARING_MISMATCH_THRESHOLD:()=>q,BEARING_SMOOTHING_ALPHA:()=>U,BETA_CORRECTION:()=>Oe,DETOUR_COMMIT_MS:()=>He,DR_MAX_AGE_MS:()=>Z,GPS_ACCURACY_FACTOR:()=>z,GPS_AGE_CAP_SECONDS:()=>Se,GPS_STALE_MS:()=>Ce,INERTIA_PENALTY:()=>Ee,INERTIA_SEGMENT_DIST:()=>Ie,LOOK_AHEAD_SECONDS:()=>Ke,MANEUVER_TRIGGER_DIST:()=>je,MAX_CORRIDOR_METERS:()=>$,MAX_LOOK_AHEAD_METERS:()=>$e,MAX_SNAP_DISTANCE:()=>X,MIN_LOOK_AHEAD_METERS:()=>We,OFF_ROUTE_CONFIRM_MS:()=>Ue,REJOIN_CONFIRM_MS:()=>ke,REJOIN_COOLDOWN_MS:()=>Ve,SNAP_WINDOW_SIZE:()=>Y,SPEED_CORRIDOR_FACTOR:()=>J,STARTUP_GRACE_MS:()=>Be,TURN_CORRIDOR_MULTIPLIER:()=>ye,TURN_LOOKAHEAD_DISTANCE_METERS:()=>Re});var L=25,$=60,J=1.2,z=.5,Re=40,ye=1.4,X=80,q=90,xe=500,Ee=200,Ie=5,Y=25,U=.3,Q=1.5,be=55,Z=5e3,Ue=2e3,ke=1500,Ve=12e3,Be=3e3,He=4e3,Ce=3e3,Se=10,je=25,Oe=.15,Ke=3,We=20,$e=100,ve=30;var Je={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},T=class{constructor(e){this.options={...Je,...e};}snap(e,t,n,i,r,o,l,c=null,d=null){let u=t.length,a=l,p=1/0,m=1/0,C=t[l]??[0,0];for(let y=0;y<=i;y++){let h=n+y;if(h>u-2)if(r&&o>u*.7)h=h%(u-1);else break;if(h<0||h>=u-1)continue;let S=t[h],b=t[h+1],I=j(e,S,b),x=f(e[1],e[0],I[1],I[0]);if(x>this.options.maxSnapDistance*2)continue;let R=x;if(this.options.useBearingPenalty&&c!==null){let O=g(S,b);Math.abs(E(c-O))>90&&(R+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(h-d)>=5&&(R+=200),R<p&&(p=R,m=x,a=h,C=I);}return {idx:a,dist:m,proj:C}}};var ze={bearingPenalty:80,bearingMismatchThresholdDeg:60,inertiaPenalty:40,inertiaSegmentDist:3},ee=class{constructor(e){this.options={...ze,...e};}resolve(e,t=null,n=null){return e.map(i=>this.score(i,t,n)).sort((i,r)=>i.score-r.score)}resolveBest(e,t=null,n=null){return e.length===0?null:this.resolve(e,t,n)[0]??null}score(e,t,n){let i=e.distanceMetres,r=null,o=false;if(t!==null){let l=g(e.segA,e.segB),c=Math.abs(E(t-l));r=c,c>this.options.bearingMismatchThresholdDeg&&(i+=this.options.bearingPenalty);}return n!==null&&Math.abs(e.segmentIndex-n)>=this.options.inertiaSegmentDist&&(i+=this.options.inertiaPenalty,o=true),{...e,score:i,bearingDeltaDeg:r,inertiaPenaltyApplied:o}}isLikelyUTurn(e,t,n){let i=g(t,n);return Math.abs(E(e-i))>this.options.bearingMismatchThresholdDeg}};function Ae(s,e,t,n,i=5e3){if(!s||e<.5)return {predictedCoord:s?.coord??[0,0],isActive:false,ageMs:0};let r=n-s.ts;if(r>i||r<0)return {predictedCoord:s.coord,isActive:false,ageMs:r};let o=e*(r/1e3);return {predictedCoord:B(s.coord[1],s.coord[0],t,o),isActive:true,ageMs:r}}var D=class{constructor(e=5e3){this.anchor=null;this.maxAgeMs=e;}setAnchor(e,t,n){this.anchor={coord:e,idx:t,ts:n};}predict(e,t,n){return Ae(this.anchor,e,t,n,this.maxAgeMs)}clearAnchor(){this.anchor=null;}getAnchor(){return this.anchor}};function Me(s,e,t,n,i=null){let r=Math.max(0,t),o=1/0,l=e[r]??[0,0],c=Math.min(t+n,e.length-1);for(let d=Math.max(0,t);d<c;d++){let u=e[d],a=e[d+1],[p,m]=s,[C,y]=u,[h,S]=a,b=h-C,I=S-y,x=b*b+I*I,R;if(x===0)R=u;else {let v=((p-C)*b+(m-y)*I)/x;v=Math.max(0,Math.min(1,v)),R=[C+v*b,y+v*I];}let O=f(s[1],s[0],R[1],R[0]);if(i!==null&&O<o*1.5){let v=g(u,a);if(Math.abs(E(i-v))>120)continue}O<o&&(o=O,r=d,l=R);}return {segmentIndex:r,distance:o,projection:l}}var N=class{evaluate(e,t,n,i,r,o,l){let c=i.distance>o,d=false;if(t!==null&&i.segmentIndex<r.length-1){let p=g(r[i.segmentIndex],r[i.segmentIndex+1]);d=Math.abs(E(t-p))>90;}let u=false;if(l!==null&&n>1.5){let p=r[Math.min(i.segmentIndex+2,r.length-1)];u=f(e[1],e[0],p[1],p[0])>l+5;}let a=c&&(d||u);return {distanceToRoute:i.distance,outsideCorridor:c,bearingMismatch:d,movingAway:u,confirmed:a}}};function te(s,e=null,t=25,n=60,i=1.2,r=.5,o=null,l=1.4,c=40){let d=t+s*i;e!==null&&e>0&&(d+=e*r);let u=n;if(o!==null&&o>=0&&o<=c){let a=1-Math.max(0,o/c),p=1+(l-1)*a;d*=p,u=n*l;}return Math.min(d,u)}function Te(s,e=.3){return s<1.5?e*.5:s>20?Math.min(.9,e*2):e}function De(s,e,t=3){let n=Math.min(e+t,s.length-1);return e>=s.length-1||e===n?e>0?g(s[e-1],s[e]):0:g(s[e],s[n])}function k(s,e,t){let n=E(e-s);return (s+t*n+360)%360}function ne(s,e,t,n,i,r=.3){let o=Te(n,r),l=De(e,t);if(i!==null&&n>1.5){let c=k(s,i,o*.3);return k(c,l,o)}return k(s,l,o)}function ie(s,e,t,n,i){return e<s||e>s+30||n>i?s:e}var Xe=20,qe=60,Ye=3;function re(s,e,t,n,i,r,o,l=0,c=false){if(!e||e.length===0||t>=e.length)return {nextIdx:t,instruction:null,wasTriggered:false};let d=t;for(;d<e.length;){let x=e[d],R=s>x.geometryIndex+30,O=x.cumulativeOffset!==void 0&&o>x.cumulativeOffset+15;if(!R&&!O)break;d++;}if(d>=e.length)return {nextIdx:d,instruction:null,wasTriggered:false};let u=e[d],a=u.cumulativeOffset!==void 0?Math.max(0,u.cumulativeOffset-o):f(i[1],i[0],u.location[1],u.location[0]),p=Math.min(qe,Math.max(Xe,l*Ye)),m=s<=u.geometryIndex+2,C=u.geometryIndex>s+n.length*.15,y=a<=p,h=d===e.length-1,S=c&&h?s>n.length*.8:true,b=y&&m&&!C&&S,I=false;if(b){let x=true,R=u.bearingAfter??(u.geometryIndex<n.length-1?g(n[u.geometryIndex],n[u.geometryIndex+1]):null),O=u.bearingBefore??(u.geometryIndex>0?g(n[u.geometryIndex-1],n[u.geometryIndex]):null);O!==null&&R!==null&&r!==null&&Math.abs(E(R-O))>30&&Math.abs(E(r-R))>55&&(x=false),x&&(I=true);}return {nextIdx:d,instruction:u,wasTriggered:I}}var Qe=0;function P(){return `instr_${Date.now()}_${++Qe}`}var oe=class{constructor(){this.instructions=[];}addTurn(e,t,n,i){return this.instructions.push({id:P(),type:"turn",location:e,text:t,instruction:t,geometryIndex:n,silent:i?.silent,meta:i?.meta}),this}addExamPoint(e,t,n,i){return this.instructions.push({id:P(),type:"exam_point",location:e,text:t,instruction:t,geometryIndex:n,severity:i?.severity??"info",silent:i?.silent,meta:i?.meta}),this}addCheckpoint(e,t,n){return this.instructions.push({id:P(),type:"checkpoint",location:e,text:"",instruction:"",geometryIndex:t,silent:true,meta:n}),this}addDepart(e,t="Start navigation"){let n={id:P(),type:"depart",location:e,text:t,instruction:t,geometryIndex:0};return this.instructions.unshift(n),this}addArrive(e,t="You have arrived"){return this.instructions.push({id:P(),type:"arrive",location:e,text:t,instruction:t,geometryIndex:Number.MAX_SAFE_INTEGER}),this}update(e,t){let n=this.instructions.findIndex(i=>i.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions[n]={...this.instructions[n],...t},this}remove(e){let t=this.instructions.findIndex(n=>n.id===e);if(t===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);return this.instructions.splice(t,1),this}reorder(e,t){let n=this.instructions.findIndex(r=>r.id===e);if(n===-1)throw new Error(`[InstructionEditor] Instruction ${e} not found`);let[i]=this.instructions.splice(n,1);return this.instructions.splice(Math.max(0,t),0,i),this}sort(){return this.instructions.sort((e,t)=>e.geometryIndex-t.geometryIndex),this}clear(){return this.instructions=[],this}attachToCumulative(e){if(e.length<2)return this;let t=[0];for(let n=1;n<e.length;n++){let i=e[n-1],r=e[n];t.push(t[n-1]+f(i[1],i[0],r[1],r[0]));}for(let n of this.instructions){let i=Math.min(n.geometryIndex,e.length-1);n.cumulativeOffset=t[i]??0,i>0&&i<e.length-1&&(n.bearingBefore=g(e[i-1],e[i]),n.bearingAfter=g(e[i],e[i+1]));}return this}toArray(){return this.instructions.map(({id:e,type:t,severity:n,meta:i,...r})=>r)}toRichArray(){return [...this.instructions]}get size(){return this.instructions.length}};function se(s,e,t){return s+e*t}function ae(s,e,t=.15){let n=e-s;return s+t*n}function Ze(s,e,t){if(t.length===0)return [0,0];if(s<=0)return t[0];let n=e[e.length-1]??0;if(s>=n)return t[t.length-1];let i=0,r=e.length-1;for(;i<r-1;){let u=i+r>>1;e[u]<=s?i=u:r=u;}let o=e[i],c=e[r]-o;if(c===0)return t[i];let d=(s-o)/c;return H(t[i],t[r],d)}var F=class{constructor(){this._state="IDLE";this._context={resumeIndex:null};}get state(){return this._state}get context(){return {...this._context}}dispatch(e){switch(this._state){case "IDLE":e.type==="ROUTE_LOADED"&&(this._state="OVERVIEW"),e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "OVERVIEW":e.type==="USER_START_NAVIGATION"&&(this._state="APPROACHING_ROUTE");break;case "APPROACHING_ROUTE":e.type==="ROUTE_JOINED"&&(this._state="ON_ROUTE",this._context.resumeIndex=e.data.index),e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE");break;case "ON_ROUTE":e.type==="NAVIGATION_FINISHED"&&(this._state="IDLE"),e.type==="ROUTE_JOINED"&&(this._context.resumeIndex=e.data.index);break}return (e.type==="RESET"||e.type==="CANCEL_NAVIGATION")&&(this._state="IDLE",this._context={resumeIndex:null}),{state:this._state,context:{...this._context}}}reset(){this._state="IDLE",this._context={resumeIndex:null};}};var A={deviationSegmentIdx:null,deviationStartMs:null,tempRoute:null,rejoinTarget:null,lastRerouteMs:null,rejoinedAtMs:null,rejoinDwellFrames:0,failureReason:null},Ne=2e3,et=3,w=class{constructor(){this._state="ON_ROUTE";this._context={...A};}get state(){return this._state}get context(){return {...this._context}}dispatch(e,t){let n=t??Date.now();switch(this._state){case "ON_ROUTE":e.type==="DEVIATION_SUSPECTED"&&(this._state="DEVIATING",this._context.deviationSegmentIdx=e.deviationSegmentIdx,this._context.deviationStartMs=n);break;case "DEVIATING":e.type==="DEVIATION_CONFIRMED"&&(this._context.deviationStartMs!==null?n-this._context.deviationStartMs:0)>=Ne&&(this._state="OFF_ROUTE",this._context.deviationSegmentIdx=e.deviationSegmentIdx),(e.type==="RESUME"||e.type==="RESET")&&(this._state="ON_ROUTE",e.type==="RESET"?this._context={...A}:(this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null));break;case "OFF_ROUTE":e.type==="REROUTE_STARTED"&&(this._state="REROUTING",this._context.lastRerouteMs=n),e.type==="RESUME"&&(this._state="ON_ROUTE",this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...A});break;case "REROUTING":e.type==="REROUTE_SUCCESS"&&(this._state="REJOINING",this._context.tempRoute=e.tempRoute,this._context.rejoinTarget=e.rejoinTarget),e.type==="REROUTE_FAILED"&&(this._state="FAILED",this._context.failureReason=e.reason);break;case "REJOINING":e.type==="REJOIN_DETECTED"&&this._context.rejoinDwellFrames++,(e.type==="REJOIN_CONFIRMED"||this._context.rejoinDwellFrames>=et)&&(this._state="REJOINED",this._context.rejoinedAtMs=n,this._context.rejoinDwellFrames=0),e.type==="RESUME"&&(this._state="ON_ROUTE",this._context.tempRoute=null,this._context.rejoinTarget=null,this._context.rejoinedAtMs=null,this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null,this._context.rejoinDwellFrames=0),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...A});break;case "REJOINED":e.type==="RESUME"&&(this._state="ON_ROUTE",this._context.tempRoute=null,this._context.rejoinTarget=null,this._context.rejoinedAtMs=null,this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...A});break;case "FAILED":e.type==="RESUME"&&(this._state="ON_ROUTE",this._context.failureReason=null,this._context.deviationSegmentIdx=null,this._context.deviationStartMs=null),e.type==="RESET"&&(this._state="ON_ROUTE",this._context={...A});break}return {state:this._state,context:{...this._context}}}reset(){this._state="ON_ROUTE",this._context={...A};}isDeviationConfirmed(e=Date.now()){return this._context.deviationStartMs?e-this._context.deviationStartMs>=Ne:false}};var tt=0;function Pe(){return `wp_${Date.now()}_${++tt}`}var ce=class{constructor(){this.waypoints=[];}addWaypoint(e,t){let n=Pe();return this.waypoints.push({id:n,coord:e,options:t}),n}insertWaypoint(e,t){let n=this.waypoints.findIndex(r=>r.id===t);if(n===-1)throw new Error(`Waypoint ${t} not found`);let i=Pe();return this.waypoints.splice(n+1,0,{id:i,coord:e,options:void 0}),i}removeWaypoint(e){let t=this.waypoints.findIndex(n=>n.id===e);if(t===-1)throw new Error(`Waypoint ${e} not found`);this.waypoints.splice(t,1);}moveWaypoint(e,t){let n=this.waypoints.find(i=>i.id===e);if(!n)throw new Error(`Waypoint ${e} not found`);n.coord=t;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(e="OVERLAP_1",t=25){let n=this.waypoints.map(l=>l.coord);if(n.length<=t)return [n];let r=t-(e==="OVERLAP_2"?2:1),o=[];for(let l=0;l<n.length;l+=r){let c=n.slice(l,l+t);if(o.push(c),l+t>=n.length)break}return o}buildStraightLine(){return {geometry:this.waypoints.map(e=>e.coord),waypoints:[...this.waypoints]}}fromGPX(e){this.waypoints=[];let t=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=t.exec(e))!==null;){let i=parseFloat(n[1]),r=parseFloat(n[2]);isFinite(i)&&isFinite(r)&&this.addWaypoint([r,i]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
|
|
2
2
|
<gpx version="1.1" creator="NavCore SDK">
|
|
3
3
|
${this.waypoints.map(t=>` <wpt lat="${t.coord[1]}" lon="${t.coord[0]}">`+(t.options?.name?`
|
|
4
4
|
<name>${t.options.name}</name>`:"")+`
|
|
5
5
|
</wpt>`).join(`
|
|
6
6
|
`)}
|
|
7
|
-
</gpx>`}fromGeoJSON(e){if(this.waypoints=[],e.type==="FeatureCollection"&&e.features){for(let t of e.features)if(t.geometry.type==="Point"){let n=t.geometry.coordinates;this.addWaypoint(n);}else if(t.geometry.type==="LineString"){let n=t.geometry.coordinates;for(let i of n)this.addWaypoint(i);}}}toGeoJSON(){let e=this.waypoints.map((n,i)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:i,name:n.options?.name??null,silent:n.options?.silent??false}})),t={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...e,t]}}clear(){this.waypoints=[];}};var ae=class{constructor(e){this.config={baseUrl:e.baseUrl.replace(/\/$/,""),profile:e.profile??"driving",maxWaypointsPerChunk:e.maxWaypointsPerChunk??100};}async getRoute(e,t){if(e.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=t?.profile??this.config.profile;return e.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(e,n,t):this.fetchChunked(e,n,t)}async fetchRoute(e,t,n){let i=e.map(d=>`${d[0]},${d[1]}`).join(";"),r=n?.steps!==false?"true":"false",o=`${this.config.baseUrl}/route/v1/${t}/${i}?overview=full&geometries=geojson&steps=${r}&annotations=false`,c=await fetch(o);if(!c.ok)throw new Error(`[OSRM] HTTP ${c.status}: ${c.statusText}`);let a=await c.json();if(a.code!=="Ok"||!a.routes?.length)throw new Error(`[OSRM] No route found: ${a.code}`);let u=a.routes[0];return {geometry:u.geometry.coordinates,distance:u.distance,duration:u.duration,legs:(u.legs??[]).map(d=>({distance:d.distance,duration:d.duration,steps:(d.steps??[]).map(l=>({distance:l.distance,duration:l.duration,geometry:l.geometry?.coordinates??[],maneuver:{type:l.maneuver?.type??"unknown",modifier:l.maneuver?.modifier,location:l.maneuver?.location??[0,0],bearingBefore:l.maneuver?.bearing_before??0,bearingAfter:l.maneuver?.bearing_after??0,instruction:l.name??void 0},name:l.name}))})),raw:a}}async fetchChunked(e,t,n){let i=this.config.maxWaypointsPerChunk,r=[];for(let l=0;l<e.length;l+=i-1){let p=e.slice(l,l+i);if(p.length<2||(r.push(p),l+i>=e.length))break}let o=await Promise.all(r.map(l=>this.fetchRoute(l,t,n))),c=[],a=0,u=0,d=[];for(let l=0;l<o.length;l++){let p=o[l];c.push(...l===0?p.geometry:p.geometry.slice(1)),a+=p.distance,u+=p.duration,d.push(...p.legs);}return {geometry:c,distance:a,duration:u,legs:d,raw:o.map(l=>l.raw)}}};var ce=class{constructor(e){this.config={baseUrl:e.baseUrl.replace(/\/$/,""),costing:e.costing??"auto",apiKey:e.apiKey??"",maxWaypointsPerChunk:e.maxWaypointsPerChunk??50};}async getRoute(e,t){if(e.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(t?.profile);return e.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(e,n,t):this.fetchChunked(e,n,t)}profileToCosting(e){switch(e){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(e,t,n){let i=e.map(p=>({lon:p[0],lat:p[1],type:"break"})),r=JSON.stringify({locations:i,costing:t,directions_options:{units:"kilometers"}}),o={"Content-Type":"application/json","User-Agent":"NavCoreSDK/1.0.0 (React Native; Expo; bab-bou-jeloud-demo)"};this.config.apiKey&&(o.api_key=this.config.apiKey);let c=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:o,body:r});if(!c.ok){let p=await c.text();throw new Error(`[Valhalla] HTTP ${c.status}: ${p}`)}let a=await c.json(),u=this.decodePolyline(a.trip?.legs?.[0]?.shape??""),d=a.trip?.summary??{},l=(a.trip?.legs??[]).map(p=>({distance:(p.summary?.length??0)*1e3,duration:p.summary?.time??0,steps:(p.maneuvers??[]).map(f=>({distance:(f.length??0)*1e3,duration:f.time??0,geometry:[],maneuver:{type:f.type?.toString()??"unknown",modifier:void 0,location:e[0],bearingBefore:f.begin_heading??0,bearingAfter:f.end_heading??0,instruction:f.instruction},name:f.street_names?.[0]}))}));return {geometry:u,distance:(d.length??0)*1e3,duration:d.time??0,legs:l,raw:a}}decodePolyline(e,t=6){let n=Math.pow(10,t),i=[],r=0,o=0,c=0;for(;r<e.length;){let a=0,u=0,d;do d=e.charCodeAt(r++)-63,u|=(d&31)<<a,a+=5;while(d>=32);let l=(u&1)!==0?~(u>>1):u>>1;o+=l,a=0,u=0;do d=e.charCodeAt(r++)-63,u|=(d&31)<<a,a+=5;while(d>=32);let p=(u&1)!==0?~(u>>1):u>>1;c+=p,i.push([c/n,o/n]);}return i}async fetchChunked(e,t,n){let i=this.config.maxWaypointsPerChunk,r=[];for(let l=0;l<e.length;l+=i-1){let p=e.slice(l,l+i);if(p.length<2||(r.push(p),l+i>=e.length))break}let o=await Promise.all(r.map(l=>this.fetchRoute(l,t,n))),c=[],a=0,u=0,d=[];for(let l=0;l<o.length;l++){let p=o[l];c.push(...l===0?p.geometry:p.geometry.slice(1)),a+=p.distance,u+=p.duration,d.push(...p.legs);}return {geometry:c,distance:a,duration:u,legs:d,raw:o.map(l=>l.raw)}}};var Ze="https://api.openrouteservice.org/v2/directions";var le=class{constructor(e){this.config={apiKey:e.apiKey,profile:e.profile??"driving-car",baseUrl:e.baseUrl??Ze,maxWaypointsPerChunk:e.maxWaypointsPerChunk??50};}async getRoute(e,t){if(e.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(t);return e.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(e,n,t):this.fetchChunked(e,n,t)}profileFromOptions(e){switch(e?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(e,t,n){let i=JSON.stringify({coordinates:e,instructions:n?.steps!==false,language:n?.language??"en"}),r=await fetch(`${this.config.baseUrl}/${t}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:i});if(!r.ok){let l=await r.text();throw new Error(`[ORS] HTTP ${r.status}: ${l}`)}let o=await r.json(),c=o.features?.[0];if(!c)throw new Error("[ORS] No route returned");let a=c.properties?.summary??{},d=(c.properties?.segments??[]).map(l=>({distance:l.distance??0,duration:l.duration??0,steps:(l.steps??[]).map(p=>({distance:p.distance??0,duration:p.duration??0,geometry:[],maneuver:{type:p.type?.toString()??"unknown",modifier:void 0,location:e[0],bearingBefore:0,bearingAfter:0,instruction:p.instruction},name:p.name}))}));return {geometry:c.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:d,raw:o}}async fetchChunked(e,t,n){let i=this.config.maxWaypointsPerChunk,r=[];for(let l=0;l<e.length;l+=i-1){let p=e.slice(l,l+i);if(p.length<2||(r.push(p),l+i>=e.length))break}let o=await Promise.all(r.map(l=>this.fetchRoute(l,t,n))),c=[],a=0,u=0,d=[];for(let l=0;l<o.length;l++){let p=o[l];c.push(...l===0?p.geometry:p.geometry.slice(1)),a+=p.distance,u+=p.duration,d.push(...p.legs);}return {geometry:c,distance:a,duration:u,legs:d,raw:o.map(l=>l.raw)}}};var et={earlyTriggerMeters:120,lateTriggerMeters:20,reannounceMeters:300},ue=class{constructor(e){this.instructions=[];this.triggeredIds=new Set;this.reannouncedIds=new Set;this.options={...et,...e};}setInstructions(e){this.instructions=[...e],this.triggeredIds.clear(),this.reannouncedIds.clear();}update(e){let t=m.getActive();if(!t||!t.hasFeature(h.VOICE_TRIGGERS))return t?t.warnOnce(h.VOICE_TRIGGERS):console.warn(`[NavCore] Feature '${h.VOICE_TRIGGERS}' requires a Pro license`),null;let{distanceToNextInstruction:n,nextInstructionIndex:i}=e;if(i===null||n===null||i>=this.instructions.length)return null;let r=this.instructions[i],o=this.instrId(i),c=n;if(this.triggeredIds.has(o))return this.options.reannounceMeters>0&&!this.reannouncedIds.has(o)&&c<=this.options.reannounceMeters&&c>this.options.earlyTriggerMeters?(this.reannouncedIds.add(o),this.makeCue(r,c,"low")):null;if(c>this.options.earlyTriggerMeters)return null;if(c<-this.options.lateTriggerMeters)return this.triggeredIds.add(o),null;this.triggeredIds.add(o);let a=c<30?"urgent":c<60?"high":"normal";return this.makeCue(r,c,a)}onInstruction(e,t){let n=m.getActive();if(!n||!n.hasFeature(h.VOICE_TRIGGERS))return n?n.warnOnce(h.VOICE_TRIGGERS):console.warn(`[NavCore] Feature '${h.VOICE_TRIGGERS}' requires a Pro license`),{instruction:e,text:"",distanceMetres:0,priority:"normal",triggerId:"bypass"};let i=t.distanceToNextInstruction??0;return this.makeCue(e,i,"high")}reset(){this.triggeredIds.clear(),this.reannouncedIds.clear();}instrId(e){let t=this.instructions[e];return `${e}_${t?.geometryIndex??0}`}makeCue(e,t,n){return {instruction:e,text:e.text??e.instruction??"",distanceMetres:Math.max(0,t),priority:n,triggerId:`${e.geometryIndex}_${t.toFixed(0)}`}}};var tt={speedWindowSize:6,minimumSpeedMs:.5,fallbackSpeedMs:8.33},de=class{constructor(e){this.speedSamples=[];this.options={...tt,...e},this.lastReliableSpeed=this.options.fallbackSpeedMs;}update(e){let t=m.getActive();if(!t||!t.hasFeature(h.ETA))return t?t.warnOnce(h.ETA):console.warn(`[NavCore] Feature '${h.ETA}' requires a Pro license`),{etaSeconds:0,etaMs:0,distanceRemainingM:0,averageSpeedMs:0,isReliable:false};let n=e.distanceToDestination??0,i=e.currentSpeed??0;this.speedSamples.push(i),this.speedSamples.length>this.options.speedWindowSize&&this.speedSamples.shift();let r=this.rollingAverage();r>=this.options.minimumSpeedMs&&(this.lastReliableSpeed=r);let o=r>=this.options.minimumSpeedMs?r:this.lastReliableSpeed,c=this.speedSamples.length>=Math.ceil(this.options.speedWindowSize/2)&&o>0&&n>0,a=o>0?n/o:0;return {etaSeconds:Math.round(a),etaMs:Date.now()+a*1e3,distanceRemainingM:n,averageSpeedMs:r,isReliable:c}}reset(){this.speedSamples=[],this.lastReliableSpeed=this.options.fallbackSpeedMs;}rollingAverage(){return this.speedSamples.length===0?0:this.speedSamples.reduce((t,n)=>t+n,0)/this.speedSamples.length}};var nt={dwellThresholdMs:1e4},pe=class{constructor(e){this.fences=new Map;this.states=new Map;if(this.options={...nt,...e},this.options.zones)for(let t of this.options.zones)t.type==="circle"&&t.center&&t.radiusMeters?this.addCircle(t.id,t.name,t.center,t.radiusMeters,t.meta):t.type==="polygon"&&t.coords&&this.addPolygon(t.id,t.name,t.coords,t.meta);}addCircle(e,t,n,i,r){return this.fences.set(e,{kind:"circle",id:e,name:t,center:n,radiusM:i,meta:r}),this.states.set(e,{inside:false,enteredAtMs:null}),e}addPolygon(e,t,n,i){if(n.length<3)throw new Error("[Geofencing] Polygon requires at least 3 coordinates");return this.fences.set(e,{kind:"polygon",id:e,name:t,coords:n,meta:i}),this.states.set(e,{inside:false,enteredAtMs:null}),e}remove(e){this.fences.delete(e),this.states.delete(e);}clear(){this.fences.clear(),this.states.clear();}listIds(){return Array.from(this.fences.keys())}update(e){let t=m.getActive();if(!t||!t.hasFeature(h.GEOFENCING))return t?t.warnOnce(h.GEOFENCING):console.warn(`[NavCore] Feature '${h.GEOFENCING}' requires a Pro license`),[];if(!e)return [];let n=[],i=Date.now();for(let[r,o]of this.fences){let c=this.states.get(r),a=this.contains(o,e);if(!c.inside&&a){c.inside=true,c.enteredAtMs=i;let u={id:r,name:o.name,type:"enter",coord:e,meta:o.meta};n.push(u),this.options.onEvent?.(u);}else if(c.inside&&!a){c.inside=false;let u=c.enteredAtMs?i-c.enteredAtMs:0;c.enteredAtMs=null;let d={id:r,name:o.name,type:"exit",coord:e,dwellMs:u,meta:o.meta};n.push(d),this.options.onEvent?.(d);}else if(c.inside&&c.enteredAtMs!==null){let u=i-c.enteredAtMs;if(u>=this.options.dwellThresholdMs){let d={id:r,name:o.name,type:"dwell",coord:e,dwellMs:u,meta:o.meta};n.push(d),this.options.onEvent?.(d),c.enteredAtMs=i;}}}return n}isInside(e,t){let n=this.fences.get(e);return n?this.contains(n,t):false}contains(e,t){return e.kind==="circle"?y(t[1],t[0],e.center[1],e.center[0])<=e.radiusM:this.pointInPolygon(t,e.coords)}pointInPolygon(e,t){let[n,i]=e,r=false,o=t.length;for(let c=0,a=o-1;c<o;a=c++){let[u,d]=t[c],[l,p]=t[a];d>i!=p>i&&n<(l-u)*(i-d)/(p-d)+u&&(r=!r);}return r}};var he=class{constructor(e){this.route=[];this.instructions=[];this.forwardCum=new Float64Array(0);this.reverseCum=new Float64Array(0);this.snappedCoord=null;this.rawGpsCoord=null;this.bearing=0;this.rawGpsBearing=null;this.routeIndex=0;this.maxProgressIdx=0;this.prevSegment=null;this.distanceToRoute=0;this.corridor=25;this.prevDistToNext=null;this.currentSpeed=0;this.lastGpsTimestamp=0;this.instrIdx=0;this.linearOffset=0;this.hasArrived=false;this.listeners=new Map;this.options={licenseKey:e?.licenseKey??"",isCircuit:e?.isCircuit??false,kalmanQ:e?.kalmanQ??1e-5,kalmanRBase:e?.kalmanRBase??5e-5,baseCorridorMeters:e?.baseCorridorMeters??25,maxCorridorMeters:e?.maxCorridorMeters??60,arrivalThresholdMeters:e?.arrivalThresholdMeters??30,bearingSmoothingAlpha:e?.bearingSmoothingAlpha??.3},this.kalman=new D(this.options.kalmanQ,this.options.kalmanRBase),this.snapper=new N({useBearingPenalty:true,useInertiaPenalty:true}),this.deadReckoning=new P,this.deviationDetector=new w,this.lifecycleFSM=new G,this.offRouteFSM=new L,this.license=new m(this.options.licenseKey);}has(e){let t=this.license.hasFeature(e);return t||this.license.warnOnce(e),t}setRoute(e,t){this.route=e,this.instructions=t??[],this.forwardCum=K(e),this.reverseCum=j(e),this.routeIndex=0,this.maxProgressIdx=0,this.prevSegment=null,this.instrIdx=0,this.linearOffset=0,this.hasArrived=false,this.snappedCoord=null,this.prevDistToNext=null,this.lifecycleFSM.dispatch({type:"ROUTE_LOADED"}),this.emit("routeLoaded",{routeLength:e.length});}startNavigation(){this.lifecycleFSM.dispatch({type:"USER_START_NAVIGATION"}),this.emit("navigationStarted");}update(e){if(this.rawGpsCoord=e.coord,this.rawGpsBearing=e.bearing,this.currentSpeed=e.speed,this.lastGpsTimestamp=e.timestamp,this.route.length<2)return this.getState();let[t,n]=this.kalman.update(e.coord[0],e.coord[1],e.accuracy??10,e.timestamp),i=[t,n],r=Math.max(0,this.routeIndex-2),o=this.snapper.snap(i,this.route,r,25,this.options.isCircuit,this.maxProgressIdx,this.routeIndex,e.bearing,this.prevSegment);this.corridor=Z(e.speed,e.accuracy,this.options.baseCorridorMeters,this.options.maxCorridorMeters);let c=te(this.routeIndex,o.idx,this.route,o.dist,80);if(this.prevSegment=this.routeIndex,this.routeIndex=c,this.maxProgressIdx=Math.max(this.maxProgressIdx,c),this.snappedCoord=o.proj,this.distanceToRoute=o.dist,this.forwardCum.length>c){let a=this.forwardCum[c]??0;this.linearOffset=oe(this.linearOffset,a,.15);}if(this.has(h.ADVANCED_BEARING)?this.bearing=ee(this.bearing,this.route,this.routeIndex,e.speed,e.bearing,this.options.bearingSmoothingAlpha):e.bearing!==null&&(this.bearing=e.bearing),this.has(h.COMPOUND_DEVIATION)&&(this.offRouteFSM.state==="ON_ROUTE"||this.offRouteFSM.state==="DEVIATING")){let a=Oe(i,this.route,r,25),u=this.deviationDetector.evaluate(i,e.bearing,e.speed,a,this.route,this.corridor,this.prevDistToNext);if(a.segmentIndex<this.route.length-1){let d=this.route[Math.min(a.segmentIndex+2,this.route.length-1)];this.prevDistToNext=y(i[1],i[0],d[1],d[0]);}u.confirmed?this.offRouteFSM.state==="ON_ROUTE"?this.offRouteFSM.dispatch({type:"DEVIATION_SUSPECTED",deviationSegmentIdx:a.segmentIndex}):this.offRouteFSM.isDeviationConfirmed()&&(this.offRouteFSM.dispatch({type:"DEVIATION_CONFIRMED",deviationSegmentIdx:a.segmentIndex}),this.emit("deviation",{anchorIndex:a.segmentIndex,ghostCoord:o.proj})):this.offRouteFSM.state==="DEVIATING"&&this.offRouteFSM.dispatch({type:"RESUME"});}else this.has(h.COMPOUND_DEVIATION)||(o.dist>this.corridor&&this.offRouteFSM.state==="ON_ROUTE"?(this.offRouteFSM.dispatch({type:"DEVIATION_SUSPECTED",deviationSegmentIdx:o.idx}),this.emit("deviation",{anchorIndex:o.idx,ghostCoord:o.proj})):o.dist<=this.corridor&&this.offRouteFSM.state!=="ON_ROUTE"&&this.offRouteFSM.dispatch({type:"RESUME"}));if(this.lifecycleFSM.state==="APPROACHING_ROUTE"&&o.dist<this.corridor&&this.lifecycleFSM.dispatch({type:"ROUTE_JOINED",data:{index:o.idx}}),this.instructions.length>0){let a=ne(this.routeIndex,this.instructions,this.instrIdx,this.route,i,e.bearing,this.linearOffset,e.speed);a.nextIdx!==this.instrIdx&&(this.instrIdx=a.nextIdx),a.wasTriggered&&a.instruction&&(this.emit("instruction",a.instruction),this.instrIdx=a.nextIdx+1);}if(!this.hasArrived&&this.route.length>0){let a=this.route[this.route.length-1],u=y(i[1],i[0],a[1],a[0]),d=this.options.isCircuit?this.routeIndex>=this.route.length*.8:true;u<this.options.arrivalThresholdMeters&&d&&(this.hasArrived=true,this.lifecycleFSM.dispatch({type:"NAVIGATION_FINISHED"}),this.emit("arrival"));}return this.has(h.DEAD_RECKONING)&&this.deadReckoning.setAnchor(o.proj,o.idx,e.timestamp),this.getState()}tick(e){if(this.has(h.DEAD_RECKONING)){let t=this.deadReckoning.predict(this.currentSpeed,this.bearing,e);t.isActive&&(this.snappedCoord=t.predictedCoord);}if(this.lastGpsTimestamp>0){let t=(e-this.lastGpsTimestamp)/1e3;t>0&&t<10&&(this.linearOffset=re(this.linearOffset,this.currentSpeed,t));}return this.getState()}getState(){let e=this.route.length>0&&this.reverseCum.length>this.routeIndex?this.reverseCum[this.routeIndex]??null:null,t=this.instrIdx<this.instructions.length?(()=>{let i=this.instructions[this.instrIdx];return i.cumulativeOffset!==void 0?Math.max(0,i.cumulativeOffset-this.linearOffset):null})():null,n=this.lastGpsTimestamp>0?Date.now()-this.lastGpsTimestamp:0;return {snappedCoord:this.snappedCoord,rawGpsCoord:this.rawGpsCoord,bearing:this.bearing,rawGpsBearing:this.rawGpsBearing,routeIndex:this.routeIndex,distanceToRoute:this.distanceToRoute,corridor:this.corridor,isOffRoute:this.offRouteFSM.state!=="ON_ROUTE"&&this.offRouteFSM.state!=="DEVIATING",progressIndex:this.routeIndex,hasArrived:this.hasArrived,offRouteState:this.offRouteFSM.state,lifecycleState:this.lifecycleFSM.state,distanceToDestination:e,distanceToNextInstruction:t,nextInstructionIndex:this.instrIdx<this.instructions.length?this.instrIdx:null,currentSpeed:this.currentSpeed,isGpsStale:n>3e3,gpsAgeMs:n,licenseStatus:this.license.getStatus()}}destroy(){this.listeners.clear(),this.route=[],this.instructions=[],this.kalman.reset(),this.deadReckoning.clearAnchor(),this.lifecycleFSM.reset(),this.offRouteFSM.reset();}on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t);}off(e,t){let n=this.listeners.get(e);if(n){let i=n.indexOf(t);i>=0&&n.splice(i,1);}}emit(e,...t){let n=this.listeners.get(e);if(n)for(let i of n)i(...t);}getLicenseManager(){return this.license}getRoute(){return this.route}getInstructions(){return this.instructions}getOffRouteFSM(){return this.offRouteFSM}getLifecycleFSM(){return this.lifecycleFSM}};
|
|
8
|
-
export{
|
|
7
|
+
</gpx>`}fromGeoJSON(e){if(this.waypoints=[],e.type==="FeatureCollection"&&e.features){for(let t of e.features)if(t.geometry.type==="Point"){let n=t.geometry.coordinates;this.addWaypoint(n);}else if(t.geometry.type==="LineString"){let n=t.geometry.coordinates;for(let i of n)this.addWaypoint(i);}}}toGeoJSON(){let e=this.waypoints.map((n,i)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:i,name:n.options?.name??null,silent:n.options?.silent??false}})),t={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...e,t]}}clear(){this.waypoints=[];}};var le=class{constructor(e){this.config={baseUrl:e.baseUrl.replace(/\/$/,""),profile:e.profile??"driving",maxWaypointsPerChunk:e.maxWaypointsPerChunk??100};}async getRoute(e,t){if(e.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=t?.profile??this.config.profile;return e.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(e,n,t):this.fetchChunked(e,n,t)}async fetchRoute(e,t,n){let i=e.map(u=>`${u[0]},${u[1]}`).join(";"),r=n?.steps!==false?"true":"false",o=`${this.config.baseUrl}/route/v1/${t}/${i}?overview=full&geometries=geojson&steps=${r}&annotations=false`,l=await fetch(o);if(!l.ok)throw new Error(`[OSRM] HTTP ${l.status}: ${l.statusText}`);let c=await l.json();if(c.code!=="Ok"||!c.routes?.length)throw new Error(`[OSRM] No route found: ${c.code}`);let d=c.routes[0];return {geometry:d.geometry.coordinates,distance:d.distance,duration:d.duration,legs:(d.legs??[]).map(u=>({distance:u.distance,duration:u.duration,steps:(u.steps??[]).map(a=>({distance:a.distance,duration:a.duration,geometry:a.geometry?.coordinates??[],maneuver:{type:a.maneuver?.type??"unknown",modifier:a.maneuver?.modifier,location:a.maneuver?.location??[0,0],bearingBefore:a.maneuver?.bearing_before??0,bearingAfter:a.maneuver?.bearing_after??0,instruction:a.name??void 0},name:a.name}))})),raw:c}}async fetchChunked(e,t,n){let i=this.config.maxWaypointsPerChunk,r=[];for(let a=0;a<e.length;a+=i-1){let p=e.slice(a,a+i);if(p.length<2||(r.push(p),a+i>=e.length))break}let o=await Promise.all(r.map(a=>this.fetchRoute(a,t,n))),l=[],c=0,d=0,u=[];for(let a=0;a<o.length;a++){let p=o[a];l.push(...a===0?p.geometry:p.geometry.slice(1)),c+=p.distance,d+=p.duration,u.push(...p.legs);}return {geometry:l,distance:c,duration:d,legs:u,raw:o.map(a=>a.raw)}}};var ue=class{constructor(e){this.config={baseUrl:e.baseUrl.replace(/\/$/,""),costing:e.costing??"auto",apiKey:e.apiKey??"",maxWaypointsPerChunk:e.maxWaypointsPerChunk??50};}async getRoute(e,t){if(e.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(t?.profile);return e.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(e,n,t):this.fetchChunked(e,n,t)}profileToCosting(e){switch(e){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(e,t,n){let i=e.map(m=>({lon:m[0],lat:m[1],type:"break"})),r=JSON.stringify({locations:i,costing:t,directions_options:{units:"kilometers"}}),o={"Content-Type":"application/json"};this.config.apiKey&&(o.api_key=this.config.apiKey);let l=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:o,body:r});if(!l.ok){let m=await l.text();throw new Error(`[Valhalla] HTTP ${l.status}: ${m}`)}let c=await l.json(),d=c.trip?.summary??{},u=[],a=(c.trip?.legs??[]).map((m,C)=>{let y=this.decodePolyline(m.shape??"");return C===0?u.push(...y):y.length>0&&u.push(...y.slice(1)),{distance:(m.summary?.length??0)*1e3,duration:m.summary?.time??0,steps:(m.maneuvers??[]).map(h=>{let S=typeof h.begin_shape_index=="number"?h.begin_shape_index:0,b=typeof h.end_shape_index=="number"?h.end_shape_index:S,I=y.slice(S,b+1),x=y[S]??e[0];return {distance:(h.length??0)*1e3,duration:h.time??0,geometry:I,maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:x,bearingBefore:h.begin_heading??0,bearingAfter:h.end_heading??0,instruction:h.instruction},name:h.street_names?.[0]}})}});return {geometry:u.length>0?u:this.decodePolyline(c.trip?.legs?.[0]?.shape??""),distance:(d.length??0)*1e3,duration:d.time??0,legs:a,raw:c}}decodePolyline(e,t=6){let n=Math.pow(10,t),i=[],r=0,o=0,l=0;for(;r<e.length;){let c=0,d=0,u;do u=e.charCodeAt(r++)-63,d|=(u&31)<<c,c+=5;while(u>=32);let a=(d&1)!==0?~(d>>1):d>>1;o+=a,c=0,d=0;do u=e.charCodeAt(r++)-63,d|=(u&31)<<c,c+=5;while(u>=32);let p=(d&1)!==0?~(d>>1):d>>1;l+=p,i.push([l/n,o/n]);}return i}async fetchChunked(e,t,n){let i=this.config.maxWaypointsPerChunk,r=[];for(let a=0;a<e.length;a+=i-1){let p=e.slice(a,a+i);if(p.length<2||(r.push(p),a+i>=e.length))break}let o=await Promise.all(r.map(a=>this.fetchRoute(a,t,n))),l=[],c=0,d=0,u=[];for(let a=0;a<o.length;a++){let p=o[a];l.push(...a===0?p.geometry:p.geometry.slice(1)),c+=p.distance,d+=p.duration,u.push(...p.legs);}return {geometry:l,distance:c,duration:d,legs:u,raw:o.map(a=>a.raw)}}};var nt="https://api.openrouteservice.org/v2/directions";var de=class{constructor(e){this.config={apiKey:e.apiKey,profile:e.profile??"driving-car",baseUrl:e.baseUrl??nt,maxWaypointsPerChunk:e.maxWaypointsPerChunk??50};}async getRoute(e,t){if(e.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(t);return e.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(e,n,t):this.fetchChunked(e,n,t)}profileFromOptions(e){switch(e?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(e,t,n){let i=JSON.stringify({coordinates:e,instructions:n?.steps!==false,language:n?.language??"en"}),r=await fetch(`${this.config.baseUrl}/${t}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:i});if(!r.ok){let a=await r.text();throw new Error(`[ORS] HTTP ${r.status}: ${a}`)}let o=await r.json(),l=o.features?.[0];if(!l)throw new Error("[ORS] No route returned");let c=l.properties?.summary??{},u=(l.properties?.segments??[]).map(a=>({distance:a.distance??0,duration:a.duration??0,steps:(a.steps??[]).map(p=>({distance:p.distance??0,duration:p.duration??0,geometry:[],maneuver:{type:p.type?.toString()??"unknown",modifier:void 0,location:e[0],bearingBefore:0,bearingAfter:0,instruction:p.instruction},name:p.name}))}));return {geometry:l.geometry?.coordinates??[],distance:c.distance??0,duration:c.duration??0,legs:u,raw:o}}async fetchChunked(e,t,n){let i=this.config.maxWaypointsPerChunk,r=[];for(let a=0;a<e.length;a+=i-1){let p=e.slice(a,a+i);if(p.length<2||(r.push(p),a+i>=e.length))break}let o=await Promise.all(r.map(a=>this.fetchRoute(a,t,n))),l=[],c=0,d=0,u=[];for(let a=0;a<o.length;a++){let p=o[a];l.push(...a===0?p.geometry:p.geometry.slice(1)),c+=p.distance,d+=p.duration,u.push(...p.legs);}return {geometry:l,distance:c,duration:d,legs:u,raw:o.map(a=>a.raw)}}};var it={earlyTriggerMeters:120,lateTriggerMeters:20,reannounceMeters:300},pe=class{constructor(e){this.instructions=[];this.triggeredIds=new Set;this.reannouncedIds=new Set;this.options={...it,...e};}setInstructions(e){this.instructions=[...e],this.triggeredIds.clear(),this.reannouncedIds.clear();}update(e){let{distanceToNextInstruction:t,nextInstructionIndex:n}=e;if(n===null||t===null||n>=this.instructions.length)return null;let i=this.instructions[n],r=this.instrId(n),o=t;if(this.triggeredIds.has(r))return this.options.reannounceMeters>0&&!this.reannouncedIds.has(r)&&o<=this.options.reannounceMeters&&o>this.options.earlyTriggerMeters?(this.reannouncedIds.add(r),this.makeCue(i,o,"low")):null;if(o>this.options.earlyTriggerMeters)return null;if(o<-this.options.lateTriggerMeters)return this.triggeredIds.add(r),null;this.triggeredIds.add(r);let l=o<30?"urgent":o<60?"high":"normal";return this.makeCue(i,o,l)}onInstruction(e,t){let n=t.distanceToNextInstruction??0;return this.makeCue(e,n,"high")}reset(){this.triggeredIds.clear(),this.reannouncedIds.clear();}instrId(e){let t=this.instructions[e];return `${e}_${t?.geometryIndex??0}`}makeCue(e,t,n){return {instruction:e,text:e.text??e.instruction??"",distanceMetres:Math.max(0,t),priority:n,triggerId:`${e.geometryIndex}_${t.toFixed(0)}`}}};var rt={speedWindowSize:6,minimumSpeedMs:.5,fallbackSpeedMs:8.33},he=class{constructor(e){this.speedSamples=[];this.options={...rt,...e},this.lastReliableSpeed=this.options.fallbackSpeedMs;}update(e){let t=e.distanceToDestination??0,n=e.currentSpeed??0;this.speedSamples.push(n),this.speedSamples.length>this.options.speedWindowSize&&this.speedSamples.shift();let i=this.rollingAverage();i>=this.options.minimumSpeedMs&&(this.lastReliableSpeed=i);let r=i>=this.options.minimumSpeedMs?i:this.lastReliableSpeed,o=this.speedSamples.length>=Math.ceil(this.options.speedWindowSize/2)&&r>0&&t>0,l=r>0?t/r:0;return {etaSeconds:Math.round(l),etaMs:Date.now()+l*1e3,distanceRemainingM:t,averageSpeedMs:i,isReliable:o}}reset(){this.speedSamples=[],this.lastReliableSpeed=this.options.fallbackSpeedMs;}rollingAverage(){return this.speedSamples.length===0?0:this.speedSamples.reduce((t,n)=>t+n,0)/this.speedSamples.length}};var ot={dwellThresholdMs:1e4},me=class{constructor(e){this.fences=new Map;this.states=new Map;if(this.options={...ot,...e},this.options.zones)for(let t of this.options.zones)t.type==="circle"&&t.center&&t.radiusMeters?this.addCircle(t.id,t.name,t.center,t.radiusMeters,t.meta):t.type==="polygon"&&t.coords&&this.addPolygon(t.id,t.name,t.coords,t.meta);}addCircle(e,t,n,i,r){return this.fences.set(e,{kind:"circle",id:e,name:t,center:n,radiusM:i,meta:r}),this.states.set(e,{inside:false,enteredAtMs:null}),e}addPolygon(e,t,n,i){if(n.length<3)throw new Error("[Geofencing] Polygon requires at least 3 coordinates");return this.fences.set(e,{kind:"polygon",id:e,name:t,coords:n,meta:i}),this.states.set(e,{inside:false,enteredAtMs:null}),e}remove(e){this.fences.delete(e),this.states.delete(e);}clear(){this.fences.clear(),this.states.clear();}listIds(){return Array.from(this.fences.keys())}update(e){if(!e)return [];let t=[],n=Date.now();for(let[i,r]of this.fences){let o=this.states.get(i),l=this.contains(r,e);if(!o.inside&&l){o.inside=true,o.enteredAtMs=n;let c={id:i,name:r.name,type:"enter",coord:e,meta:r.meta};t.push(c),this.options.onEvent?.(c);}else if(o.inside&&!l){o.inside=false;let c=o.enteredAtMs?n-o.enteredAtMs:0;o.enteredAtMs=null;let d={id:i,name:r.name,type:"exit",coord:e,dwellMs:c,meta:r.meta};t.push(d),this.options.onEvent?.(d);}else if(o.inside&&o.enteredAtMs!==null){let c=n-o.enteredAtMs;if(c>=this.options.dwellThresholdMs){let d={id:i,name:r.name,type:"dwell",coord:e,dwellMs:c,meta:r.meta};t.push(d),this.options.onEvent?.(d),o.enteredAtMs=n;}}}return t}isInside(e,t){let n=this.fences.get(e);return n?this.contains(n,t):false}contains(e,t){return e.kind==="circle"?f(t[1],t[0],e.center[1],e.center[0])<=e.radiusM:this.pointInPolygon(t,e.coords)}pointInPolygon(e,t){let[n,i]=e,r=false,o=t.length;for(let l=0,c=o-1;l<o;c=l++){let[d,u]=t[l],[a,p]=t[c];u>i!=p>i&&n<(a-d)*(i-u)/(p-u)+d&&(r=!r);}return r}};var _={GPS_SMOOTHING:"gps_smoothing",BASIC_SNAPPING:"basic_snapping",ADVANCED_SNAPPING:"advanced_snapping",DEAD_RECKONING:"dead_reckoning",ROUTE_OFFSET:"route_offset",PROGRESS_TRACKING:"progress_tracking",ADVANCED_BEARING:"advanced_bearing",COMPOUND_DEVIATION:"compound_deviation",PARALLEL_ROAD_RESOLUTION:"parallel_road_resolution",U_TURN_PROTECTION:"u_turn_protection",VOICE_TRIGGERS:"voice_triggers",ETA:"eta",GEOFENCING:"geofencing",NAV_AI:"nav_ai"};var V=class V{constructor(e,t){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;this.isDev=false;this.isDev=t??false,e&&this.validate(e);}async validate(e){try{if(this.status==="VALID"&&this.payload?.bid==="dev.bypass")return "VALID";let[t,n]=e.split(".");if(!t||!n)return this.status="INVALID",this.status;let i=atob(t);if(this.payload=JSON.parse(i),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(t,n))return this.status="INVALID",this.status;this.status="VALID",this.extractFeatures(),console.log(`\u{1F511} [NavCore] License validation complete. Plan: ${this.isProEnabled()?"pro":"core"}`);}catch{this.status="INVALID";}return this.status}extractFeatures(){if(this.enabledFeatures.clear(),!!this.payload){if(Array.isArray(this.payload.f))for(let e of this.payload.f)this.enabledFeatures.add(e);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(e){return this.isDev?true:this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(e)}warnOnce(e){this.warnedFeatures.has(e)||(console.warn(`[NavCore] Feature '${e}' requires a Pro license`),this.warnedFeatures.add(e));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(_.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(e,t){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let i=new TextEncoder().encode(e),r=Uint8Array.from(atob(t),c=>c.charCodeAt(0)),o=Uint8Array.from(atob(V.PUBLIC_KEY_SPKI),c=>c.charCodeAt(0)),l=await crypto.subtle.importKey("spki",o,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},l,r,i)}catch{return false}}};V.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var G=V;var fe=class{constructor(e){this.route=[];this.instructions=[];this.forwardCum=new Float64Array(0);this.reverseCum=new Float64Array(0);this.snappedCoord=null;this.ghostCoord=null;this.rawGpsCoord=null;this.bearing=0;this.rawGpsBearing=null;this.routeIndex=0;this.maxProgressIdx=0;this.prevSegment=null;this.distanceToRoute=0;this.corridor=25;this.prevDistToNext=null;this.currentSpeed=0;this.lastGpsTimestamp=0;this.instrIdx=0;this.linearOffset=0;this.hasArrived=false;this.listeners=new Map;this.options={licenseKey:e?.licenseKey??"",isDev:e?.isDev??false,isCircuit:e?.isCircuit??false,kalmanQ:e?.kalmanQ??1e-5,kalmanRBase:e?.kalmanRBase??5e-5,baseCorridorMeters:e?.baseCorridorMeters??25,maxCorridorMeters:e?.maxCorridorMeters??60,arrivalThresholdMeters:e?.arrivalThresholdMeters??30,bearingSmoothingAlpha:e?.bearingSmoothingAlpha??.3},this.kalman=new M(this.options.kalmanQ,this.options.kalmanRBase),this.snapper=new T({useBearingPenalty:true,useInertiaPenalty:true}),this.deadReckoning=new D,this.deviationDetector=new N,this.lifecycleFSM=new F,this.offRouteFSM=new w,this.license=new G(this.options.licenseKey,this.options.isDev);}has(e){let t=this.license.hasFeature(e);return t||this.license.warnOnce(e),t}setRoute(e,t){this.route=e,this.instructions=t??[],this.forwardCum=K(e),this.reverseCum=W(e),this.routeIndex=0,this.maxProgressIdx=0,this.prevSegment=null,this.instrIdx=0,this.linearOffset=0,this.hasArrived=false,this.snappedCoord=null,this.prevDistToNext=null,this.lifecycleFSM.dispatch({type:"ROUTE_LOADED"});for(let n of this.instructions)n.cumulativeOffset===void 0&&n.geometryIndex<this.forwardCum.length&&(n.cumulativeOffset=this.forwardCum[n.geometryIndex]);this.emit("routeLoaded",{routeLength:e.length});}startNavigation(){this.lifecycleFSM.dispatch({type:"USER_START_NAVIGATION"}),this.emit("navigationStarted");}update(e){if(this.rawGpsCoord=e.coord,this.rawGpsBearing=e.bearing,this.currentSpeed=e.speed,this.lastGpsTimestamp=e.timestamp,this.route.length<2)return this.getState();let[t,n]=this.kalman.update(e.coord[0],e.coord[1],e.accuracy??10,e.timestamp),i=[t,n],r=Math.max(0,this.routeIndex-2),o=this.snapper.snap(i,this.route,r,25,this.options.isCircuit,this.maxProgressIdx,this.routeIndex,e.bearing,this.prevSegment);this.ghostCoord=o.proj;let l=null;if(this.instructions.length>0&&this.instrIdx<this.instructions.length){let a=this.instructions[this.instrIdx];l=a.cumulativeOffset!==void 0?Math.max(0,a.cumulativeOffset-this.linearOffset):f(i[1],i[0],a.location[1],a.location[0]);}this.corridor=te(e.speed,e.accuracy,this.options.baseCorridorMeters,this.options.maxCorridorMeters,1.2,.5,l);let c=ie(this.routeIndex,o.idx,this.route,o.dist,80);if(this.prevSegment=this.routeIndex,this.routeIndex=c,this.maxProgressIdx=Math.max(this.maxProgressIdx,c),this.snappedCoord=o.proj,this.distanceToRoute=o.dist,this.forwardCum.length>c){let a=this.forwardCum[c]??0;this.linearOffset=ae(this.linearOffset,a,.15);}this.has(_.ADVANCED_BEARING)?this.bearing=ne(this.bearing,this.route,this.routeIndex,e.speed,e.bearing,this.options.bearingSmoothingAlpha):e.bearing!==null&&(this.bearing=e.bearing);let d=this.has(_.COMPOUND_DEVIATION);if(this.offRouteFSM.state==="ON_ROUTE"||this.offRouteFSM.state==="DEVIATING")if(d){let a=Me(i,this.route,r,25),p=this.deviationDetector.evaluate(i,e.bearing,e.speed,a,this.route,this.corridor,this.prevDistToNext);if(a.segmentIndex<this.route.length-1){let m=this.route[Math.min(a.segmentIndex+2,this.route.length-1)];this.prevDistToNext=f(i[1],i[0],m[1],m[0]);}p.confirmed?this.offRouteFSM.state==="ON_ROUTE"?this.offRouteFSM.dispatch({type:"DEVIATION_SUSPECTED",deviationSegmentIdx:a.segmentIndex}):this.offRouteFSM.isDeviationConfirmed()&&(this.offRouteFSM.dispatch({type:"DEVIATION_CONFIRMED",deviationSegmentIdx:a.segmentIndex}),this.emit("deviation",{anchorIndex:a.segmentIndex,ghostCoord:o.proj})):this.offRouteFSM.state==="DEVIATING"&&this.offRouteFSM.dispatch({type:"RESUME"});}else o.dist>this.corridor&&this.offRouteFSM.state==="ON_ROUTE"?(this.offRouteFSM.dispatch({type:"DEVIATION_SUSPECTED",deviationSegmentIdx:o.idx}),this.emit("deviation",{anchorIndex:o.idx,ghostCoord:o.proj})):o.dist<=this.corridor&&this.offRouteFSM.state==="DEVIATING"&&this.offRouteFSM.dispatch({type:"RESUME"});else if(o.dist<=this.corridor){let a=this.offRouteFSM.state==="OFF_ROUTE"||this.offRouteFSM.state==="REJOINING"||this.offRouteFSM.state==="REJOINED";this.offRouteFSM.dispatch({type:"RESUME"}),a&&this.emit("rejoined",{resumeIndex:o.idx});}if(this.lifecycleFSM.state==="APPROACHING_ROUTE"&&o.dist<this.corridor&&this.lifecycleFSM.dispatch({type:"ROUTE_JOINED",data:{index:o.idx}}),this.instructions.length>0){let a=re(this.routeIndex,this.instructions,this.instrIdx,this.route,i,e.bearing,this.linearOffset,e.speed,this.options.isCircuit);a.nextIdx!==this.instrIdx&&(this.instrIdx=a.nextIdx),a.wasTriggered&&a.instruction&&(this.emit("instruction",a.instruction),this.instrIdx=a.nextIdx+1);}if(!this.hasArrived&&this.route.length>0){let a=this.route[this.route.length-1],p=f(i[1],i[0],a[1],a[0]),m=this.options.isCircuit?this.routeIndex>=this.route.length*.8:true;p<this.options.arrivalThresholdMeters&&m&&(this.hasArrived=true,this.lifecycleFSM.dispatch({type:"NAVIGATION_FINISHED"}),this.emit("arrival"));}this.has(_.DEAD_RECKONING)&&this.deadReckoning.setAnchor(o.proj,o.idx,e.timestamp);let u=this.getState();return this.emit("update",u),u}tick(e){if(this.has(_.DEAD_RECKONING)){let n=this.deadReckoning.predict(this.currentSpeed,this.bearing,e);n.isActive&&(this.snappedCoord=n.predictedCoord);}if(this.lastGpsTimestamp>0){let n=(e-this.lastGpsTimestamp)/1e3;n>0&&n<10&&(this.linearOffset=se(this.linearOffset,this.currentSpeed,n));}let t=this.getState();return this.emit("update",t),t}getState(){let e=this.route.length>0&&this.reverseCum.length>this.routeIndex?this.reverseCum[this.routeIndex]??null:null,t=this.instrIdx<this.instructions.length?(()=>{let p=this.instructions[this.instrIdx];return p.cumulativeOffset!==void 0?Math.max(0,p.cumulativeOffset-this.linearOffset):null})():null,n=this.lastGpsTimestamp>0?Date.now()-this.lastGpsTimestamp:0,i=Math.max(0,Math.min(1,1-this.distanceToRoute/Math.max(1,this.corridor))),r=this.offRouteFSM.state==="DEVIATING"?"DEVIATING":this.offRouteFSM.state==="OFF_ROUTE"||this.offRouteFSM.state==="REROUTING"?"RECALCULATING":this.offRouteFSM.state==="REJOINING"?"REJOINING":this.offRouteFSM.state==="REJOINED"?"REJOINED":"NONE",o=this.offRouteFSM.state!=="ON_ROUTE"&&this.offRouteFSM.state!=="DEVIATING",l=this.offRouteFSM.state==="OFF_ROUTE"||this.offRouteFSM.state==="REROUTING"?"FREE":"NONE",c=this.offRouteFSM.state==="OFF_ROUTE"?1:0,d=this.offRouteFSM.context.rejoinTarget?{coord:this.offRouteFSM.context.rejoinTarget.coordinates,index:this.offRouteFSM.context.rejoinTarget.index}:null,u=this.snappedCoord?{center:this.snappedCoord,bearing:this.bearing,angle:30,length:Math.max(10,Math.min(50,this.currentSpeed*3))}:null,a=this.instrIdx<this.instructions.length?this.instrIdx:null;return {snappedCoord:this.snappedCoord,ghostCoord:this.ghostCoord??this.snappedCoord,rawGpsCoord:this.rawGpsCoord,bearing:this.bearing,rawGpsBearing:this.rawGpsBearing,routeIndex:this.routeIndex,anchorRouteIndex:this.prevSegment??this.routeIndex,distanceToRoute:this.distanceToRoute,corridor:this.corridor,confidence:i,isOffRoute:o,navFsmState:this.lifecycleFSM.state,progressIndex:this.routeIndex,hasArrived:this.hasArrived,rejoinCandidate:d,confidenceCone:u,alertState:r,detourMode:l,detourCommitProgress:c,distanceToDestination:e,distanceToNextInstruction:t,nextInstrIdx:a,nextInstructionIndex:a,currentSpeed:this.currentSpeed,isGpsStale:n>3e3,gpsAgeMs:n,licenseStatus:this.license.getStatus(),offRouteState:this.offRouteFSM.state,lifecycleState:this.lifecycleFSM.state}}destroy(){this.listeners.clear(),this.route=[],this.instructions=[],this.snappedCoord=null,this.ghostCoord=null,this.rawGpsCoord=null,this.kalman.reset(),this.deadReckoning.clearAnchor(),this.lifecycleFSM.reset(),this.offRouteFSM.reset();}on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t);}off(e,t){let n=this.listeners.get(e);if(n){let i=n.indexOf(t);i>=0&&n.splice(i,1);}}emit(e,...t){let n=this.listeners.get(e);if(n)for(let i of n)i(...t);}getLicenseManager(){return this.license}getRoute(){return this.route}getInstructions(){return this.instructions}getOffRouteFSM(){return this.offRouteFSM}getLifecycleFSM(){return this.lifecycleFSM}};
|
|
8
|
+
export{_e as Constants,ce as CustomRouteBuilder,D as DeadReckoningEngine,N as DeviationDetector,he as ETAEngine,_ as FEATURES,me as GeofencingEngine,oe as InstructionEditor,M as KalmanFilter2D,G as LicenseManager,fe as NavCore,F as NavigationFSM,le as OSRMDirectionsProvider,w as OffRouteFSM,de as OpenRouteServiceProvider,ee as ParallelRoadResolver,T as RouteSnapper,ue as ValhallaDirectionsProvider,pe as VoiceTriggerEngine,se as advancePredictor,ne as applyBearingSmoothing,ae as applyGpsCorrection,k as blendBearing,K as buildForwardCumulativeDistances,W as buildReverseCumulativeDistances,te as calculateDynamicCorridor,De as calculateRobustBearing,Ae as computeDeadReckoningOnRoute,B as destinationPoint,Le as geoGetBearing,g as getBearingBetweenPoints,Te as getSpeedAdaptiveAlpha,f as haversineDistance,H as interpolatePoint,ge as kalmanUpdate2D,E as normalizeAngle,Ze as pointAtOffset,j as projectPointOnSegment,re as resolveNextInstruction,ie as validateProgressUpdate};
|