@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/core.js CHANGED
@@ -1,7 +1,7 @@
1
- 'use strict';var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function f(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),l=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),l=i*(Math.PI/180),p=t*(Math.PI/180),a=Math.asin(Math.sin(l)*Math.cos(r)+Math.cos(l)*Math.sin(r)*Math.cos(s));return [((p+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(l),Math.cos(r)-Math.sin(l)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(l,p)*(180/Math.PI);return a=(a+360)%360,a}function v(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function S(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(l,p)*180/Math.PI+360)%360}function Y(i,t,e){let n=(r,s,l)=>r+(s-r)*l;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function A(i,t,e){let[n,r]=i,[s,l]=t,[p,a]=e,d=p-s,u=a-l,o=d*d+u*u;if(o===0)return t;let c=((n-s)*d+(r-l)*u)/o;return c=Math.max(0,Math.min(1,c)),[s+c*d,l+c*u]}function J(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+f(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function q(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+f(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,l=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let p=l*Math.max(1,n/5),a=i.P/(i.P+p),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var x=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,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 B={};$(B,{ARRIVAL_THRESHOLD_METERS:()=>Ct,BASE_CORRIDOR_METERS:()=>z,BEARING_ALIGNMENT_THRESHOLD:()=>rt,BEARING_MIN_SPEED_MPS:()=>ot,BEARING_MISMATCH_PENALTY:()=>V,BEARING_MISMATCH_THRESHOLD:()=>F,BEARING_SMOOTHING_ALPHA:()=>nt,BETA_CORRECTION:()=>mt,DETOUR_COMMIT_MS:()=>pt,DR_MAX_AGE_MS:()=>it,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>dt,GPS_STALE_MS:()=>ut,INERTIA_PENALTY:()=>U,INERTIA_SEGMENT_DIST:()=>W,LOOK_AHEAD_SECONDS:()=>yt,MANEUVER_TRIGGER_DIST:()=>ht,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>gt,MAX_SNAP_DISTANCE:()=>k,MIN_LOOK_AHEAD_METERS:()=>ft,OFF_ROUTE_CONFIRM_MS:()=>st,REJOIN_CONFIRM_MS:()=>at,REJOIN_COOLDOWN_MS:()=>ct,SNAP_WINDOW_SIZE:()=>et,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>lt});var z=25,Q=60,Z=1.2,tt=.5,k=80,F=90,V=500,U=200,W=5,et=25,nt=.3,ot=1.5,rt=55,it=5e3,st=2e3,at=1500,ct=12e3,lt=3e3,pt=4e3,ut=3e3,dt=10,ht=25,mt=.15,yt=3,ft=20,gt=100,Ct=30;var bt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},E=class{constructor(t){this.options={...bt,...t};}snap(t,e,n,r,s,l,p,a=null,d=null){let u=e.length,o=p,c=1/0,h=1/0,w=e[p]??[0,0];for(let C=0;C<=r;C++){let m=n+C;if(m>u-2)if(s&&l>u*.7)m=m%(u-1);else break;if(m<0||m>=u-1)continue;let T=e[m],N=e[m+1],b=A(t,T,N),R=f(t[1],t[0],b[1],b[0]);if(R>this.options.maxSnapDistance*2)continue;let g=R;if(this.options.useBearingPenalty&&a!==null){let G=S(T,N);Math.abs(v(a-G))>90&&(g+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(m-d)>=5&&(g+=200),g<c&&(c=g,h=R,o=m,w=b);}return {idx:o,dist:h,proj:w}}};var P=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",l=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,p=await fetch(l);if(!p.ok)throw new Error(`[OSRM] HTTP ${p.status}: ${p.statusText}`);let a=await p.json();if(a.code!=="Ok"||!a.routes?.length)throw new Error(`[OSRM] No route found: ${a.code}`);let d=a.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(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var _=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(c=>({lon:c[0],lat:c[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),l={"Content-Type":"application/json","User-Agent":"NavCoreSDK/1.0.0 (React Native; Expo; bab-bou-jeloud-demo)"};this.config.apiKey&&(l.api_key=this.config.apiKey);let p=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:l,body:s});if(!p.ok){let c=await p.text();throw new Error(`[Valhalla] HTTP ${p.status}: ${c}`)}let a=await p.json(),d=this.decodePolyline(a.trip?.legs?.[0]?.shape??""),u=a.trip?.summary??{},o=(a.trip?.legs??[]).map(c=>({distance:(c.summary?.length??0)*1e3,duration:c.summary?.time??0,steps:(c.maneuvers??[]).map(h=>({distance:(h.length??0)*1e3,duration:h.time??0,geometry:[],maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:h.begin_heading??0,bearingAfter:h.end_heading??0,instruction:h.instruction},name:h.street_names?.[0]}))}));return {geometry:d,distance:(u.length??0)*1e3,duration:u.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,l=0,p=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;l+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let c=(d&1)!==0?~(d>>1):d>>1;p+=c,r.push([p/n,l/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var Rt="https://api.openrouteservice.org/v2/directions";var D=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??Rt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let l=await s.json(),p=l.features?.[0];if(!p)throw new Error("[ORS] No route returned");let a=p.properties?.summary??{},u=(p.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(c=>({distance:c.distance??0,duration:c.duration??0,geometry:[],maneuver:{type:c.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:c.instruction},name:c.name}))}));return {geometry:p.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:l}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var vt=0;function K(){return `wp_${Date.now()}_${++vt}`}var M=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=K();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=K();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(p=>p.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),l=[];for(let p=0;p<n.length;p+=s){let a=n.slice(p,p+e);if(l.push(a),p+e>=n.length)break}return l}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
1
+ 'use strict';var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function g(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),p=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(p),Math.sqrt(1-p)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),p=i*(Math.PI/180),c=t*(Math.PI/180),a=Math.asin(Math.sin(p)*Math.cos(r)+Math.cos(p)*Math.sin(r)*Math.cos(s));return [((c+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(p),Math.cos(r)-Math.sin(p)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),p=Math.sin(s-n)*Math.cos(r),c=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(p,c)*(180/Math.PI);return a=(a+360)%360,a}function S(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function _(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),p=Math.sin(s-n)*Math.cos(r),c=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(p,c)*180/Math.PI+360)%360}function q(i,t,e){let n=(r,s,p)=>r+(s-r)*p;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function E(i,t,e){let[n,r]=i,[s,p]=t,[c,a]=e,d=c-s,u=a-p,o=d*d+u*u;if(o===0)return t;let l=((n-s)*d+(r-p)*u)/o;return l=Math.max(0,Math.min(1,l)),[s+l*d,p+l*u]}function z(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+g(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function Y(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+g(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,p=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let c=p*Math.max(1,n/5),a=i.P/(i.P+c),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var D=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,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 G={};$(G,{ARRIVAL_THRESHOLD_METERS:()=>bt,BASE_CORRIDOR_METERS:()=>J,BEARING_ALIGNMENT_THRESHOLD:()=>st,BEARING_MIN_SPEED_MPS:()=>it,BEARING_MISMATCH_PENALTY:()=>U,BEARING_MISMATCH_THRESHOLD:()=>k,BEARING_SMOOTHING_ALPHA:()=>rt,BETA_CORRECTION:()=>yt,DETOUR_COMMIT_MS:()=>dt,DR_MAX_AGE_MS:()=>at,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>mt,GPS_STALE_MS:()=>ht,INERTIA_PENALTY:()=>K,INERTIA_SEGMENT_DIST:()=>B,LOOK_AHEAD_SECONDS:()=>gt,MANEUVER_TRIGGER_DIST:()=>ft,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>Rt,MAX_SNAP_DISTANCE:()=>F,MIN_LOOK_AHEAD_METERS:()=>Ct,OFF_ROUTE_CONFIRM_MS:()=>ct,REJOIN_CONFIRM_MS:()=>pt,REJOIN_COOLDOWN_MS:()=>lt,SNAP_WINDOW_SIZE:()=>ot,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>ut,TURN_CORRIDOR_MULTIPLIER:()=>nt,TURN_LOOKAHEAD_DISTANCE_METERS:()=>et});var J=25,Q=60,Z=1.2,tt=.5,et=40,nt=1.4,F=80,k=90,U=500,K=200,B=5,ot=25,rt=.3,it=1.5,st=55,at=5e3,ct=2e3,pt=1500,lt=12e3,ut=3e3,dt=4e3,ht=3e3,mt=10,ft=25,yt=.15,gt=3,Ct=20,Rt=100,bt=30;var xt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},M=class{constructor(t){this.options={...xt,...t};}snap(t,e,n,r,s,p,c,a=null,d=null){let u=e.length,o=c,l=1/0,m=1/0,b=e[c]??[0,0];for(let f=0;f<=r;f++){let h=n+f;if(h>u-2)if(s&&p>u*.7)h=h%(u-1);else break;if(h<0||h>=u-1)continue;let y=e[h],x=e[h+1],C=E(t,y,x),R=g(t[1],t[0],C[1],C[0]);if(R>this.options.maxSnapDistance*2)continue;let P=R;if(this.options.useBearingPenalty&&a!==null){let V=_(y,x);Math.abs(S(a-V))>90&&(P+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(h-d)>=5&&(P+=200),P<l&&(l=P,m=R,o=h,b=C);}return {idx:o,dist:m,proj:b}}};var O=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",p=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,c=await fetch(p);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 d=a.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(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let l=t.slice(o,o+r);if(l.length<2||(s.push(l),o+r>=t.length))break}let p=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),c=[],a=0,d=0,u=[];for(let o=0;o<p.length;o++){let l=p[o];c.push(...o===0?l.geometry:l.geometry.slice(1)),a+=l.distance,d+=l.duration,u.push(...l.legs);}return {geometry:c,distance:a,duration:d,legs:u,raw:p.map(o=>o.raw)}}};var v=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(m=>({lon:m[0],lat:m[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),p={"Content-Type":"application/json"};this.config.apiKey&&(p.api_key=this.config.apiKey);let c=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:p,body:s});if(!c.ok){let m=await c.text();throw new Error(`[Valhalla] HTTP ${c.status}: ${m}`)}let a=await c.json(),d=a.trip?.summary??{},u=[],o=(a.trip?.legs??[]).map((m,b)=>{let f=this.decodePolyline(m.shape??"");return b===0?u.push(...f):f.length>0&&u.push(...f.slice(1)),{distance:(m.summary?.length??0)*1e3,duration:m.summary?.time??0,steps:(m.maneuvers??[]).map(h=>{let y=typeof h.begin_shape_index=="number"?h.begin_shape_index:0,x=typeof h.end_shape_index=="number"?h.end_shape_index:y,C=f.slice(y,x+1),R=f[y]??t[0];return {distance:(h.length??0)*1e3,duration:h.time??0,geometry:C,maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:R,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(a.trip?.legs?.[0]?.shape??""),distance:(d.length??0)*1e3,duration:d.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,p=0,c=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;p+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let l=(d&1)!==0?~(d>>1):d>>1;c+=l,r.push([c/n,p/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let l=t.slice(o,o+r);if(l.length<2||(s.push(l),o+r>=t.length))break}let p=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),c=[],a=0,d=0,u=[];for(let o=0;o<p.length;o++){let l=p[o];c.push(...o===0?l.geometry:l.geometry.slice(1)),a+=l.distance,d+=l.duration,u.push(...l.legs);}return {geometry:c,distance:a,duration:d,legs:u,raw:p.map(o=>o.raw)}}};var Pt="https://api.openrouteservice.org/v2/directions";var I=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??Pt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let p=await s.json(),c=p.features?.[0];if(!c)throw new Error("[ORS] No route returned");let a=c.properties?.summary??{},u=(c.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(l=>({distance:l.distance??0,duration:l.duration??0,geometry:[],maneuver:{type:l.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:l.instruction},name:l.name}))}));return {geometry:c.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:p}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let l=t.slice(o,o+r);if(l.length<2||(s.push(l),o+r>=t.length))break}let p=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),c=[],a=0,d=0,u=[];for(let o=0;o<p.length;o++){let l=p[o];c.push(...o===0?l.geometry:l.geometry.slice(1)),a+=l.distance,d+=l.duration,u.push(...l.legs);}return {geometry:c,distance:a,duration:d,legs:u,raw:p.map(o=>o.raw)}}};var At=0;function W(){return `wp_${Date.now()}_${++At}`}var T=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=W();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=W();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(c=>c.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),p=[];for(let c=0;c<n.length;c+=s){let a=n.slice(c,c+e);if(p.push(a),c+e>=n.length)break}return p}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
2
2
  <gpx version="1.1" creator="NavCore SDK">
3
3
  ${this.waypoints.map(e=>` <wpt lat="${e.coord[1]}" lon="${e.coord[0]}">`+(e.options?.name?`
4
4
  <name>${e.options.name}</name>`:"")+`
5
5
  </wpt>`).join(`
6
6
  `)}
7
- </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var O={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 y=class y{constructor(t){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;t&&(this.tryValidateSync(t)||this.validate(t)),this.promoteToActive();}static getActive(){return y.activeManager}static clearActive(){y.activeManager=null;}promoteToActive(){let t=y.activeManager;(t===null||t.status!=="VALID"||this.status==="VALID")&&(y.activeManager=this);}tryValidateSync(t){return t==="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(t){if(this.tryValidateSync(t))return this.status;try{let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,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 t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(O.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),l=Uint8Array.from(atob(y.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),p=await crypto.subtle.importKey("spki",l,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},p,s,r)}catch{return false}}};y.activeManager=null,y.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var I=y;exports.Constants=B;exports.CustomRouteBuilder=M;exports.FEATURES=O;exports.KalmanFilter2D=x;exports.LicenseManager=I;exports.OSRMDirectionsProvider=P;exports.OpenRouteServiceProvider=D;exports.RouteSnapper=E;exports.ValhallaDirectionsProvider=_;exports.buildForwardCumulativeDistances=J;exports.buildReverseCumulativeDistances=q;exports.destinationPoint=X;exports.geoGetBearing=j;exports.getBearingBetweenPoints=S;exports.haversineDistance=f;exports.interpolatePoint=Y;exports.kalmanUpdate2D=L;exports.normalizeAngle=v;exports.projectPointOnSegment=A;
7
+ </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var w={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 A=class A{constructor(t,e){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;this.isDev=false;this.isDev=e??false,t&&this.validate(t);}async validate(t){try{if(this.status==="VALID"&&this.payload?.bid==="dev.bypass")return "VALID";let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,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 t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.isDev?true:this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(w.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),p=Uint8Array.from(atob(A.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),c=await crypto.subtle.importKey("spki",p,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},c,s,r)}catch{return false}}};A.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var N=A;exports.Constants=G;exports.CustomRouteBuilder=T;exports.FEATURES=w;exports.KalmanFilter2D=D;exports.LicenseManager=N;exports.OSRMDirectionsProvider=O;exports.OpenRouteServiceProvider=I;exports.RouteSnapper=M;exports.ValhallaDirectionsProvider=v;exports.buildForwardCumulativeDistances=z;exports.buildReverseCumulativeDistances=Y;exports.destinationPoint=X;exports.geoGetBearing=j;exports.getBearingBetweenPoints=_;exports.haversineDistance=g;exports.interpolatePoint=q;exports.kalmanUpdate2D=L;exports.normalizeAngle=S;exports.projectPointOnSegment=E;
package/dist/core.mjs CHANGED
@@ -1,7 +1,7 @@
1
- var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function f(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),l=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(l),Math.sqrt(1-l)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),l=i*(Math.PI/180),p=t*(Math.PI/180),a=Math.asin(Math.sin(l)*Math.cos(r)+Math.cos(l)*Math.sin(r)*Math.cos(s));return [((p+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(l),Math.cos(r)-Math.sin(l)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(l,p)*(180/Math.PI);return a=(a+360)%360,a}function v(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function S(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),l=Math.sin(s-n)*Math.cos(r),p=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(l,p)*180/Math.PI+360)%360}function Y(i,t,e){let n=(r,s,l)=>r+(s-r)*l;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function A(i,t,e){let[n,r]=i,[s,l]=t,[p,a]=e,d=p-s,u=a-l,o=d*d+u*u;if(o===0)return t;let c=((n-s)*d+(r-l)*u)/o;return c=Math.max(0,Math.min(1,c)),[s+c*d,l+c*u]}function J(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+f(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function q(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+f(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,l=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let p=l*Math.max(1,n/5),a=i.P/(i.P+p),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var x=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,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 B={};$(B,{ARRIVAL_THRESHOLD_METERS:()=>Ct,BASE_CORRIDOR_METERS:()=>z,BEARING_ALIGNMENT_THRESHOLD:()=>rt,BEARING_MIN_SPEED_MPS:()=>ot,BEARING_MISMATCH_PENALTY:()=>V,BEARING_MISMATCH_THRESHOLD:()=>F,BEARING_SMOOTHING_ALPHA:()=>nt,BETA_CORRECTION:()=>mt,DETOUR_COMMIT_MS:()=>pt,DR_MAX_AGE_MS:()=>it,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>dt,GPS_STALE_MS:()=>ut,INERTIA_PENALTY:()=>U,INERTIA_SEGMENT_DIST:()=>W,LOOK_AHEAD_SECONDS:()=>yt,MANEUVER_TRIGGER_DIST:()=>ht,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>gt,MAX_SNAP_DISTANCE:()=>k,MIN_LOOK_AHEAD_METERS:()=>ft,OFF_ROUTE_CONFIRM_MS:()=>st,REJOIN_CONFIRM_MS:()=>at,REJOIN_COOLDOWN_MS:()=>ct,SNAP_WINDOW_SIZE:()=>et,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>lt});var z=25,Q=60,Z=1.2,tt=.5,k=80,F=90,V=500,U=200,W=5,et=25,nt=.3,ot=1.5,rt=55,it=5e3,st=2e3,at=1500,ct=12e3,lt=3e3,pt=4e3,ut=3e3,dt=10,ht=25,mt=.15,yt=3,ft=20,gt=100,Ct=30;var bt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},E=class{constructor(t){this.options={...bt,...t};}snap(t,e,n,r,s,l,p,a=null,d=null){let u=e.length,o=p,c=1/0,h=1/0,w=e[p]??[0,0];for(let C=0;C<=r;C++){let m=n+C;if(m>u-2)if(s&&l>u*.7)m=m%(u-1);else break;if(m<0||m>=u-1)continue;let T=e[m],N=e[m+1],b=A(t,T,N),R=f(t[1],t[0],b[1],b[0]);if(R>this.options.maxSnapDistance*2)continue;let g=R;if(this.options.useBearingPenalty&&a!==null){let G=S(T,N);Math.abs(v(a-G))>90&&(g+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(m-d)>=5&&(g+=200),g<c&&(c=g,h=R,o=m,w=b);}return {idx:o,dist:h,proj:w}}};var P=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",l=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,p=await fetch(l);if(!p.ok)throw new Error(`[OSRM] HTTP ${p.status}: ${p.statusText}`);let a=await p.json();if(a.code!=="Ok"||!a.routes?.length)throw new Error(`[OSRM] No route found: ${a.code}`);let d=a.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(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var _=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(c=>({lon:c[0],lat:c[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),l={"Content-Type":"application/json","User-Agent":"NavCoreSDK/1.0.0 (React Native; Expo; bab-bou-jeloud-demo)"};this.config.apiKey&&(l.api_key=this.config.apiKey);let p=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:l,body:s});if(!p.ok){let c=await p.text();throw new Error(`[Valhalla] HTTP ${p.status}: ${c}`)}let a=await p.json(),d=this.decodePolyline(a.trip?.legs?.[0]?.shape??""),u=a.trip?.summary??{},o=(a.trip?.legs??[]).map(c=>({distance:(c.summary?.length??0)*1e3,duration:c.summary?.time??0,steps:(c.maneuvers??[]).map(h=>({distance:(h.length??0)*1e3,duration:h.time??0,geometry:[],maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:h.begin_heading??0,bearingAfter:h.end_heading??0,instruction:h.instruction},name:h.street_names?.[0]}))}));return {geometry:d,distance:(u.length??0)*1e3,duration:u.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,l=0,p=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;l+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let c=(d&1)!==0?~(d>>1):d>>1;p+=c,r.push([p/n,l/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var Rt="https://api.openrouteservice.org/v2/directions";var D=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??Rt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let l=await s.json(),p=l.features?.[0];if(!p)throw new Error("[ORS] No route returned");let a=p.properties?.summary??{},u=(p.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(c=>({distance:c.distance??0,duration:c.duration??0,geometry:[],maneuver:{type:c.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:c.instruction},name:c.name}))}));return {geometry:p.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:l}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let c=t.slice(o,o+r);if(c.length<2||(s.push(c),o+r>=t.length))break}let l=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),p=[],a=0,d=0,u=[];for(let o=0;o<l.length;o++){let c=l[o];p.push(...o===0?c.geometry:c.geometry.slice(1)),a+=c.distance,d+=c.duration,u.push(...c.legs);}return {geometry:p,distance:a,duration:d,legs:u,raw:l.map(o=>o.raw)}}};var vt=0;function K(){return `wp_${Date.now()}_${++vt}`}var M=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=K();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=K();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(p=>p.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),l=[];for(let p=0;p<n.length;p+=s){let a=n.slice(p,p+e);if(l.push(a),p+e>=n.length)break}return l}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
1
+ var H=Object.defineProperty;var $=(i,t)=>{for(var e in t)H(i,e,{get:t[e],enumerable:true});};function g(i,t,e,n){let r=(e-i)*(Math.PI/180),s=(n-t)*(Math.PI/180),p=Math.sin(r/2)*Math.sin(r/2)+Math.cos(i*(Math.PI/180))*Math.cos(e*(Math.PI/180))*Math.sin(s/2)*Math.sin(s/2);return 6371e3*(2*Math.atan2(Math.sqrt(p),Math.sqrt(1-p)))}function X(i,t,e,n){let r=n/6371e3,s=e*(Math.PI/180),p=i*(Math.PI/180),c=t*(Math.PI/180),a=Math.asin(Math.sin(p)*Math.cos(r)+Math.cos(p)*Math.sin(r)*Math.cos(s));return [((c+Math.atan2(Math.sin(s)*Math.sin(r)*Math.cos(p),Math.cos(r)-Math.sin(p)*Math.sin(a)))*180/Math.PI+540)%360-180,a*180/Math.PI]}function j(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),p=Math.sin(s-n)*Math.cos(r),c=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n),a=Math.atan2(p,c)*(180/Math.PI);return a=(a+360)%360,a}function S(i){let t=i%360;return t>180?t-360:t<-180?t+360:t}function _(i,t){let e=i[1]*(Math.PI/180),n=i[0]*(Math.PI/180),r=t[1]*(Math.PI/180),s=t[0]*(Math.PI/180),p=Math.sin(s-n)*Math.cos(r),c=Math.cos(e)*Math.sin(r)-Math.sin(e)*Math.cos(r)*Math.cos(s-n);return (Math.atan2(p,c)*180/Math.PI+360)%360}function q(i,t,e){let n=(r,s,p)=>r+(s-r)*p;return [n(i[0],t[0],e),n(i[1],t[1],e)]}function E(i,t,e){let[n,r]=i,[s,p]=t,[c,a]=e,d=c-s,u=a-p,o=d*d+u*u;if(o===0)return t;let l=((n-s)*d+(r-p)*u)/o;return l=Math.max(0,Math.min(1,l)),[s+l*d,p+l*u]}function z(i){let t=new Float64Array(i.length);for(let e=1;e<i.length;e++)t[e]=t[e-1]+g(i[e-1][1],i[e-1][0],i[e][1],i[e][0]);return t}function Y(i){let t=new Float64Array(i.length);for(let e=i.length-2;e>=0;e--)t[e]=t[e+1]+g(i[e][1],i[e][0],i[e+1][1],i[e+1][0]);return t}function L(i,t,e,n,r,s=1e-5,p=5e-5){i.x+=i.vx*r,i.y+=i.vy*r,i.P+=s;let c=p*Math.max(1,n/5),a=i.P/(i.P+c),d=t-i.x,u=e-i.y;return i.x+=a*d,i.y+=a*u,r>0&&(i.vx=d/r*a,i.vy=u/r*a),i.P=(1-a)*i.P,i}var D=class{constructor(t=1e-5,e=5e-5){this.lastTimestamp=0;this.Q=t,this.rBase=e,this.state={x:0,y:0,vx:0,vy:0,P:1};}init(t,e,n){this.state={x:t,y:e,vx:0,vy:0,P:1},this.lastTimestamp=n;}update(t,e,n,r){if(this.lastTimestamp===0)return this.init(t,e,r),[t,e];let s=Math.max(.001,(r-this.lastTimestamp)/1e3);return this.lastTimestamp=r,L(this.state,t,e,n,s,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 G={};$(G,{ARRIVAL_THRESHOLD_METERS:()=>bt,BASE_CORRIDOR_METERS:()=>J,BEARING_ALIGNMENT_THRESHOLD:()=>st,BEARING_MIN_SPEED_MPS:()=>it,BEARING_MISMATCH_PENALTY:()=>U,BEARING_MISMATCH_THRESHOLD:()=>k,BEARING_SMOOTHING_ALPHA:()=>rt,BETA_CORRECTION:()=>yt,DETOUR_COMMIT_MS:()=>dt,DR_MAX_AGE_MS:()=>at,GPS_ACCURACY_FACTOR:()=>tt,GPS_AGE_CAP_SECONDS:()=>mt,GPS_STALE_MS:()=>ht,INERTIA_PENALTY:()=>K,INERTIA_SEGMENT_DIST:()=>B,LOOK_AHEAD_SECONDS:()=>gt,MANEUVER_TRIGGER_DIST:()=>ft,MAX_CORRIDOR_METERS:()=>Q,MAX_LOOK_AHEAD_METERS:()=>Rt,MAX_SNAP_DISTANCE:()=>F,MIN_LOOK_AHEAD_METERS:()=>Ct,OFF_ROUTE_CONFIRM_MS:()=>ct,REJOIN_CONFIRM_MS:()=>pt,REJOIN_COOLDOWN_MS:()=>lt,SNAP_WINDOW_SIZE:()=>ot,SPEED_CORRIDOR_FACTOR:()=>Z,STARTUP_GRACE_MS:()=>ut,TURN_CORRIDOR_MULTIPLIER:()=>nt,TURN_LOOKAHEAD_DISTANCE_METERS:()=>et});var J=25,Q=60,Z=1.2,tt=.5,et=40,nt=1.4,F=80,k=90,U=500,K=200,B=5,ot=25,rt=.3,it=1.5,st=55,at=5e3,ct=2e3,pt=1500,lt=12e3,ut=3e3,dt=4e3,ht=3e3,mt=10,ft=25,yt=.15,gt=3,Ct=20,Rt=100,bt=30;var xt={useBearingPenalty:true,useInertiaPenalty:true,maxSnapDistance:80},M=class{constructor(t){this.options={...xt,...t};}snap(t,e,n,r,s,p,c,a=null,d=null){let u=e.length,o=c,l=1/0,m=1/0,b=e[c]??[0,0];for(let f=0;f<=r;f++){let h=n+f;if(h>u-2)if(s&&p>u*.7)h=h%(u-1);else break;if(h<0||h>=u-1)continue;let y=e[h],x=e[h+1],C=E(t,y,x),R=g(t[1],t[0],C[1],C[0]);if(R>this.options.maxSnapDistance*2)continue;let P=R;if(this.options.useBearingPenalty&&a!==null){let V=_(y,x);Math.abs(S(a-V))>90&&(P+=500);}this.options.useInertiaPenalty&&d!==null&&Math.abs(h-d)>=5&&(P+=200),P<l&&(l=P,m=R,o=h,b=C);}return {idx:o,dist:m,proj:b}}};var O=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),profile:t.profile??"driving",maxWaypointsPerChunk:t.maxWaypointsPerChunk??100};}async getRoute(t,e){if(t.length<2)throw new Error("[OSRM] At least 2 waypoints required");let n=e?.profile??this.config.profile;return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}async fetchRoute(t,e,n){let r=t.map(u=>`${u[0]},${u[1]}`).join(";"),s=n?.steps!==false?"true":"false",p=`${this.config.baseUrl}/route/v1/${e}/${r}?overview=full&geometries=geojson&steps=${s}&annotations=false`,c=await fetch(p);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 d=a.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(o=>({distance:o.distance,duration:o.duration,geometry:o.geometry?.coordinates??[],maneuver:{type:o.maneuver?.type??"unknown",modifier:o.maneuver?.modifier,location:o.maneuver?.location??[0,0],bearingBefore:o.maneuver?.bearing_before??0,bearingAfter:o.maneuver?.bearing_after??0,instruction:o.name??void 0},name:o.name}))})),raw:a}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let l=t.slice(o,o+r);if(l.length<2||(s.push(l),o+r>=t.length))break}let p=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),c=[],a=0,d=0,u=[];for(let o=0;o<p.length;o++){let l=p[o];c.push(...o===0?l.geometry:l.geometry.slice(1)),a+=l.distance,d+=l.duration,u.push(...l.legs);}return {geometry:c,distance:a,duration:d,legs:u,raw:p.map(o=>o.raw)}}};var v=class{constructor(t){this.config={baseUrl:t.baseUrl.replace(/\/$/,""),costing:t.costing??"auto",apiKey:t.apiKey??"",maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[Valhalla] At least 2 waypoints required");let n=this.profileToCosting(e?.profile);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileToCosting(t){switch(t){case "cycling":return "bicycle";case "walking":return "pedestrian";default:return this.config.costing}}async fetchRoute(t,e,n){let r=t.map(m=>({lon:m[0],lat:m[1],type:"break"})),s=JSON.stringify({locations:r,costing:e,directions_options:{units:"kilometers"}}),p={"Content-Type":"application/json"};this.config.apiKey&&(p.api_key=this.config.apiKey);let c=await fetch(`${this.config.baseUrl}/route`,{method:"POST",headers:p,body:s});if(!c.ok){let m=await c.text();throw new Error(`[Valhalla] HTTP ${c.status}: ${m}`)}let a=await c.json(),d=a.trip?.summary??{},u=[],o=(a.trip?.legs??[]).map((m,b)=>{let f=this.decodePolyline(m.shape??"");return b===0?u.push(...f):f.length>0&&u.push(...f.slice(1)),{distance:(m.summary?.length??0)*1e3,duration:m.summary?.time??0,steps:(m.maneuvers??[]).map(h=>{let y=typeof h.begin_shape_index=="number"?h.begin_shape_index:0,x=typeof h.end_shape_index=="number"?h.end_shape_index:y,C=f.slice(y,x+1),R=f[y]??t[0];return {distance:(h.length??0)*1e3,duration:h.time??0,geometry:C,maneuver:{type:h.type?.toString()??"unknown",modifier:void 0,location:R,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(a.trip?.legs?.[0]?.shape??""),distance:(d.length??0)*1e3,duration:d.time??0,legs:o,raw:a}}decodePolyline(t,e=6){let n=Math.pow(10,e),r=[],s=0,p=0,c=0;for(;s<t.length;){let a=0,d=0,u;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let o=(d&1)!==0?~(d>>1):d>>1;p+=o,a=0,d=0;do u=t.charCodeAt(s++)-63,d|=(u&31)<<a,a+=5;while(u>=32);let l=(d&1)!==0?~(d>>1):d>>1;c+=l,r.push([c/n,p/n]);}return r}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let l=t.slice(o,o+r);if(l.length<2||(s.push(l),o+r>=t.length))break}let p=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),c=[],a=0,d=0,u=[];for(let o=0;o<p.length;o++){let l=p[o];c.push(...o===0?l.geometry:l.geometry.slice(1)),a+=l.distance,d+=l.duration,u.push(...l.legs);}return {geometry:c,distance:a,duration:d,legs:u,raw:p.map(o=>o.raw)}}};var Pt="https://api.openrouteservice.org/v2/directions";var I=class{constructor(t){this.config={apiKey:t.apiKey,profile:t.profile??"driving-car",baseUrl:t.baseUrl??Pt,maxWaypointsPerChunk:t.maxWaypointsPerChunk??50};}async getRoute(t,e){if(t.length<2)throw new Error("[ORS] At least 2 waypoints required");let n=this.profileFromOptions(e);return t.length<=this.config.maxWaypointsPerChunk?this.fetchRoute(t,n,e):this.fetchChunked(t,n,e)}profileFromOptions(t){switch(t?.profile){case "cycling":return "cycling-regular";case "walking":return "foot-walking";default:return this.config.profile}}async fetchRoute(t,e,n){let r=JSON.stringify({coordinates:t,instructions:n?.steps!==false,language:n?.language??"en"}),s=await fetch(`${this.config.baseUrl}/${e}/geojson`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:this.config.apiKey},body:r});if(!s.ok){let o=await s.text();throw new Error(`[ORS] HTTP ${s.status}: ${o}`)}let p=await s.json(),c=p.features?.[0];if(!c)throw new Error("[ORS] No route returned");let a=c.properties?.summary??{},u=(c.properties?.segments??[]).map(o=>({distance:o.distance??0,duration:o.duration??0,steps:(o.steps??[]).map(l=>({distance:l.distance??0,duration:l.duration??0,geometry:[],maneuver:{type:l.type?.toString()??"unknown",modifier:void 0,location:t[0],bearingBefore:0,bearingAfter:0,instruction:l.instruction},name:l.name}))}));return {geometry:c.geometry?.coordinates??[],distance:a.distance??0,duration:a.duration??0,legs:u,raw:p}}async fetchChunked(t,e,n){let r=this.config.maxWaypointsPerChunk,s=[];for(let o=0;o<t.length;o+=r-1){let l=t.slice(o,o+r);if(l.length<2||(s.push(l),o+r>=t.length))break}let p=await Promise.all(s.map(o=>this.fetchRoute(o,e,n))),c=[],a=0,d=0,u=[];for(let o=0;o<p.length;o++){let l=p[o];c.push(...o===0?l.geometry:l.geometry.slice(1)),a+=l.distance,d+=l.duration,u.push(...l.legs);}return {geometry:c,distance:a,duration:d,legs:u,raw:p.map(o=>o.raw)}}};var At=0;function W(){return `wp_${Date.now()}_${++At}`}var T=class{constructor(){this.waypoints=[];}addWaypoint(t,e){let n=W();return this.waypoints.push({id:n,coord:t,options:e}),n}insertWaypoint(t,e){let n=this.waypoints.findIndex(s=>s.id===e);if(n===-1)throw new Error(`Waypoint ${e} not found`);let r=W();return this.waypoints.splice(n+1,0,{id:r,coord:t,options:void 0}),r}removeWaypoint(t){let e=this.waypoints.findIndex(n=>n.id===t);if(e===-1)throw new Error(`Waypoint ${t} not found`);this.waypoints.splice(e,1);}moveWaypoint(t,e){let n=this.waypoints.find(r=>r.id===t);if(!n)throw new Error(`Waypoint ${t} not found`);n.coord=e;}getWaypoints(){return this.waypoints}get size(){return this.waypoints.length}chunk(t="OVERLAP_1",e=25){let n=this.waypoints.map(c=>c.coord);if(n.length<=e)return [n];let s=e-(t==="OVERLAP_2"?2:1),p=[];for(let c=0;c<n.length;c+=s){let a=n.slice(c,c+e);if(p.push(a),c+e>=n.length)break}return p}buildStraightLine(){return {geometry:this.waypoints.map(t=>t.coord),waypoints:[...this.waypoints]}}fromGPX(t){this.waypoints=[];let e=/<(?:trkpt|wpt|rtept)\s+lat="([^"]+)"\s+lon="([^"]+)"/g,n;for(;(n=e.exec(t))!==null;){let r=parseFloat(n[1]),s=parseFloat(n[2]);isFinite(r)&&isFinite(s)&&this.addWaypoint([s,r]);}}toGPX(){return `<?xml version="1.0" encoding="UTF-8"?>
2
2
  <gpx version="1.1" creator="NavCore SDK">
3
3
  ${this.waypoints.map(e=>` <wpt lat="${e.coord[1]}" lon="${e.coord[0]}">`+(e.options?.name?`
4
4
  <name>${e.options.name}</name>`:"")+`
5
5
  </wpt>`).join(`
6
6
  `)}
7
- </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var O={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 y=class y{constructor(t){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;t&&(this.tryValidateSync(t)||this.validate(t)),this.promoteToActive();}static getActive(){return y.activeManager}static clearActive(){y.activeManager=null;}promoteToActive(){let t=y.activeManager;(t===null||t.status!=="VALID"||this.status==="VALID")&&(y.activeManager=this);}tryValidateSync(t){return t==="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(t){if(this.tryValidateSync(t))return this.status;try{let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,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 t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(O.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),l=Uint8Array.from(atob(y.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),p=await crypto.subtle.importKey("spki",l,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},p,s,r)}catch{return false}}};y.activeManager=null,y.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var I=y;export{B as Constants,M as CustomRouteBuilder,O as FEATURES,x as KalmanFilter2D,I as LicenseManager,P as OSRMDirectionsProvider,D as OpenRouteServiceProvider,E as RouteSnapper,_ as ValhallaDirectionsProvider,J as buildForwardCumulativeDistances,q as buildReverseCumulativeDistances,X as destinationPoint,j as geoGetBearing,S as getBearingBetweenPoints,f as haversineDistance,Y as interpolatePoint,L as kalmanUpdate2D,v as normalizeAngle,A as projectPointOnSegment};
7
+ </gpx>`}fromGeoJSON(t){if(this.waypoints=[],t.type==="FeatureCollection"&&t.features){for(let e of t.features)if(e.geometry.type==="Point"){let n=e.geometry.coordinates;this.addWaypoint(n);}else if(e.geometry.type==="LineString"){let n=e.geometry.coordinates;for(let r of n)this.addWaypoint(r);}}}toGeoJSON(){let t=this.waypoints.map((n,r)=>({type:"Feature",geometry:{type:"Point",coordinates:n.coord},properties:{id:n.id,order:r,name:n.options?.name??null,silent:n.options?.silent??false}})),e={type:"Feature",geometry:{type:"LineString",coordinates:this.waypoints.map(n=>n.coord)},properties:{type:"route"}};return {type:"FeatureCollection",features:[...t,e]}}clear(){this.waypoints=[];}};var w={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 A=class A{constructor(t,e){this.status="MISSING";this.payload=null;this.enabledFeatures=new Set;this.warnedFeatures=new Set;this.isDev=false;this.isDev=e??false,t&&this.validate(t);}async validate(t){try{if(this.status==="VALID"&&this.payload?.bid==="dev.bypass")return "VALID";let[e,n]=t.split(".");if(!e||!n)return this.status="INVALID",this.status;let r=atob(e);if(this.payload=JSON.parse(r),!this.payload||this.payload.exp<Date.now())return this.status="EXPIRED",this.status;if(!await this.verifySignature(e,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 t of this.payload.f)this.enabledFeatures.add(t);this.payload.t==="pro"&&this.enabledFeatures.add("*");}}hasFeature(t){return this.isDev?true:this.status!=="VALID"?false:this.enabledFeatures.has("*")?true:this.enabledFeatures.has(t)}warnOnce(t){this.warnedFeatures.has(t)||(console.warn(`[NavCore] Feature '${t}' requires a Pro license`),this.warnedFeatures.add(t));}isProEnabled(){return this.hasFeature("*")}isAIEnabled(){return this.hasFeature(w.NAV_AI)}getStatus(){return this.status}getPayload(){return this.payload}getEnabledFeatures(){return Array.from(this.enabledFeatures)}async verifySignature(t,e){try{if(typeof crypto>"u"||!crypto.subtle)return !1;let r=new TextEncoder().encode(t),s=Uint8Array.from(atob(e),a=>a.charCodeAt(0)),p=Uint8Array.from(atob(A.PUBLIC_KEY_SPKI),a=>a.charCodeAt(0)),c=await crypto.subtle.importKey("spki",p,{name:"ECDSA",namedCurve:"P-256"},!0,["verify"]);return await crypto.subtle.verify({name:"ECDSA",hash:{name:"SHA-256"}},c,s,r)}catch{return false}}};A.PUBLIC_KEY_SPKI="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk6onJmJkWtRFusiSS69dcdONX4xL2Snm4AZO+dYjSynfJiL4x7trEy80MImLftknBWT/qI0z7ox4Q7VNL3te6A==";var N=A;export{G as Constants,T as CustomRouteBuilder,w as FEATURES,D as KalmanFilter2D,N as LicenseManager,O as OSRMDirectionsProvider,I as OpenRouteServiceProvider,M as RouteSnapper,v as ValhallaDirectionsProvider,z as buildForwardCumulativeDistances,Y as buildReverseCumulativeDistances,X as destinationPoint,j as geoGetBearing,_ as getBearingBetweenPoints,g as haversineDistance,q as interpolatePoint,L as kalmanUpdate2D,S as normalizeAngle,E as projectPointOnSegment};
package/dist/index.d.mts CHANGED
@@ -1,66 +1,3 @@
1
- import { C as Coordinate } from './NavCore.d-BuXR5DO7.mjs';
2
- export { F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, d as LifecycleContext, e as LifecycleEvent, N as NavCore, f as NavCoreOptions, g as NavCoreState, h as NavGpsUpdate, i as NavInstruction, j as NavLifecycleState, k as NavigationFSM, O as OffRouteContext, l as OffRouteEvent, m as OffRouteFSM, n as OffRouteState, R as RejoinTarget, T as TempRoute, o as destinationPoint, p as geoGetBearing, q as haversineDistance, r as resolveNextInstruction } from './NavCore.d-BuXR5DO7.mjs';
1
+ export { C as Coordinate, F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, d as LifecycleContext, e as LifecycleEvent, N as NavCore, f as NavCoreOptions, g as NavCoreState, h as NavGpsUpdate, i as NavInstruction, j as NavLifecycleState, k as NavigationFSM, O as OffRouteContext, l as OffRouteEvent, m as OffRouteFSM, n as OffRouteState, R as RejoinTarget, T as TempRoute, o as destinationPoint, p as geoGetBearing, q as haversineDistance, r as resolveNextInstruction } from './NavCore-qf5_0qsR.mjs';
3
2
  export { BuildOptions, CameraOptions, Constants, CustomRouteBuilder, CustomWaypoint, DirectionsLeg, DirectionsManeuver, DirectionsOptions, DirectionsProvider, DirectionsResult, DirectionsStep, Kalman2DState, KalmanFilter2D, MapRendererAdapter, ORSConfig, ORSProfile, OSRMConfig, OSRMDirectionsProvider, OpenRouteServiceProvider, RouteSnapper, RouteStyle, SnapResult, SnapperOptions, ValhallaConfig, ValhallaCostingModel, ValhallaDirectionsProvider, VehicleStyle, WaypointOptions, buildForwardCumulativeDistances, buildReverseCumulativeDistances, getBearingBetweenPoints, interpolatePoint, kalmanUpdate2D, normalizeAngle, projectPointOnSegment } from './core.mjs';
4
- export { DeadReckoningEngine, DeviationDetector, ETAEngine, ETAOptions, ETAResult, GeofenceEvent, GeofenceEventType, GeofenceType, GeofencingEngine, GeofencingOptions, InstructionEditor, InstructionType, ParallelRoadResolver, ParallelRoadResolverOptions, ResolvedCandidate, RichInstruction, SnapCandidate, VoiceCue, VoicePriority, VoiceTriggerEngine, VoiceTriggerOptions, ZoneDefinition, calculateDynamicCorridor, computeDeadReckoningOnRoute } from './pro.mjs';
5
-
6
- /**
7
- * Module 5: BearingEngine
8
- * Speed-adaptive IIR bearing smoothing.
9
- */
10
-
11
- /**
12
- * Calculate speed-adaptive smoothing factor.
13
- * Higher speed → less smoothing (alpha closer to 1).
14
- * Lower speed → more smoothing (alpha closer to base value).
15
- */
16
- declare function getSpeedAdaptiveAlpha(speedMps: number, baseAlpha?: number): number;
17
- /**
18
- * Compute bearing from the route geometry at the current segment.
19
- */
20
- declare function calculateRobustBearing(route: Coordinate[], currentIdx: number, lookAhead?: number): number;
21
- /**
22
- * Blend two bearings using the shortest angular path.
23
- */
24
- declare function blendBearing(current: number, target: number, alpha: number): number;
25
- /**
26
- * Full bearing smoothing pipeline: route bearing → IIR blend → output.
27
- */
28
- declare function applyBearingSmoothing(currentBearing: number, route: Coordinate[], routeIdx: number, speedMps: number, gpsBearing: number | null, baseAlpha?: number): number;
29
-
30
- /**
31
- * Module 6: ProgressTracker
32
- * Monotonic route progress tracking with anti-jitter.
33
- */
34
-
35
- /**
36
- * Validate a progress update: ensures monotonic forward progress with jitter tolerance.
37
- *
38
- * @returns The new progress index (may be the same as current if update is rejected)
39
- */
40
- declare function validateProgressUpdate(currentIdx: number, candidateIdx: number, route: Coordinate[], distToRoute: number, maxSnapDistance: number): number;
41
-
42
- /**
43
- * Module 8: RouteOffsetPredictor
44
- * Linear distance-based position predictor for smooth rendering between GPS fixes.
45
- */
46
-
47
- /**
48
- * Advance the predictor's offset by speed * dt.
49
- */
50
- declare function advancePredictor(currentOffset: number, speedMps: number, dtSec: number): number;
51
- /**
52
- * Correct the predictor when a new GPS fix arrives.
53
- * Blend towards the actual measured offset using betaCorrection.
54
- */
55
- declare function applyGpsCorrection(predictedOffset: number, measuredOffset: number, betaCorrection?: number): number;
56
- /**
57
- * Given a linear offset (metres from route start), find the [lng, lat] on the route.
58
- *
59
- * @param offset Linear distance from route start in metres
60
- * @param cumulativeDistances Forward cumulative distance array
61
- * @param route Route coordinates
62
- * @returns Interpolated coordinate on the route
63
- */
64
- declare function pointAtOffset(offset: number, cumulativeDistances: Float64Array, route: Coordinate[]): Coordinate;
65
-
66
- export { Coordinate, advancePredictor, applyBearingSmoothing, applyGpsCorrection, blendBearing, calculateRobustBearing, getSpeedAdaptiveAlpha, pointAtOffset, validateProgressUpdate };
3
+ export { D as DeadReckoningEngine, a as DeviationDetector, E as ETAEngine, b as ETAOptions, c as ETAResult, G as GeofenceEvent, d as GeofenceEventType, e as GeofenceType, f as GeofencingEngine, g as GeofencingOptions, I as InstructionEditor, h as InstructionType, P as ParallelRoadResolver, i as ParallelRoadResolverOptions, R as ResolvedCandidate, j as RichInstruction, S as SnapCandidate, V as VoiceCue, k as VoicePriority, l as VoiceTriggerEngine, m as VoiceTriggerOptions, Z as ZoneDefinition, n as advancePredictor, o as applyBearingSmoothing, p as applyGpsCorrection, q as blendBearing, r as calculateDynamicCorridor, s as calculateRobustBearing, t as computeDeadReckoningOnRoute, u as getSpeedAdaptiveAlpha, v as pointAtOffset, w as validateProgressUpdate } from './index.pro-Cg6394f_.mjs';
package/dist/index.d.ts CHANGED
@@ -1,66 +1,3 @@
1
- import { C as Coordinate } from './NavCore.d-BuXR5DO7.js';
2
- export { F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, d as LifecycleContext, e as LifecycleEvent, N as NavCore, f as NavCoreOptions, g as NavCoreState, h as NavGpsUpdate, i as NavInstruction, j as NavLifecycleState, k as NavigationFSM, O as OffRouteContext, l as OffRouteEvent, m as OffRouteFSM, n as OffRouteState, R as RejoinTarget, T as TempRoute, o as destinationPoint, p as geoGetBearing, q as haversineDistance, r as resolveNextInstruction } from './NavCore.d-BuXR5DO7.js';
1
+ export { C as Coordinate, F as FEATURES, a as FeatureKey, L as LicenseManager, b as LicensePayload, c as LicenseStatus, d as LifecycleContext, e as LifecycleEvent, N as NavCore, f as NavCoreOptions, g as NavCoreState, h as NavGpsUpdate, i as NavInstruction, j as NavLifecycleState, k as NavigationFSM, O as OffRouteContext, l as OffRouteEvent, m as OffRouteFSM, n as OffRouteState, R as RejoinTarget, T as TempRoute, o as destinationPoint, p as geoGetBearing, q as haversineDistance, r as resolveNextInstruction } from './NavCore-qf5_0qsR.js';
3
2
  export { BuildOptions, CameraOptions, Constants, CustomRouteBuilder, CustomWaypoint, DirectionsLeg, DirectionsManeuver, DirectionsOptions, DirectionsProvider, DirectionsResult, DirectionsStep, Kalman2DState, KalmanFilter2D, MapRendererAdapter, ORSConfig, ORSProfile, OSRMConfig, OSRMDirectionsProvider, OpenRouteServiceProvider, RouteSnapper, RouteStyle, SnapResult, SnapperOptions, ValhallaConfig, ValhallaCostingModel, ValhallaDirectionsProvider, VehicleStyle, WaypointOptions, buildForwardCumulativeDistances, buildReverseCumulativeDistances, getBearingBetweenPoints, interpolatePoint, kalmanUpdate2D, normalizeAngle, projectPointOnSegment } from './core.js';
4
- export { DeadReckoningEngine, DeviationDetector, ETAEngine, ETAOptions, ETAResult, GeofenceEvent, GeofenceEventType, GeofenceType, GeofencingEngine, GeofencingOptions, InstructionEditor, InstructionType, ParallelRoadResolver, ParallelRoadResolverOptions, ResolvedCandidate, RichInstruction, SnapCandidate, VoiceCue, VoicePriority, VoiceTriggerEngine, VoiceTriggerOptions, ZoneDefinition, calculateDynamicCorridor, computeDeadReckoningOnRoute } from './pro.js';
5
-
6
- /**
7
- * Module 5: BearingEngine
8
- * Speed-adaptive IIR bearing smoothing.
9
- */
10
-
11
- /**
12
- * Calculate speed-adaptive smoothing factor.
13
- * Higher speed → less smoothing (alpha closer to 1).
14
- * Lower speed → more smoothing (alpha closer to base value).
15
- */
16
- declare function getSpeedAdaptiveAlpha(speedMps: number, baseAlpha?: number): number;
17
- /**
18
- * Compute bearing from the route geometry at the current segment.
19
- */
20
- declare function calculateRobustBearing(route: Coordinate[], currentIdx: number, lookAhead?: number): number;
21
- /**
22
- * Blend two bearings using the shortest angular path.
23
- */
24
- declare function blendBearing(current: number, target: number, alpha: number): number;
25
- /**
26
- * Full bearing smoothing pipeline: route bearing → IIR blend → output.
27
- */
28
- declare function applyBearingSmoothing(currentBearing: number, route: Coordinate[], routeIdx: number, speedMps: number, gpsBearing: number | null, baseAlpha?: number): number;
29
-
30
- /**
31
- * Module 6: ProgressTracker
32
- * Monotonic route progress tracking with anti-jitter.
33
- */
34
-
35
- /**
36
- * Validate a progress update: ensures monotonic forward progress with jitter tolerance.
37
- *
38
- * @returns The new progress index (may be the same as current if update is rejected)
39
- */
40
- declare function validateProgressUpdate(currentIdx: number, candidateIdx: number, route: Coordinate[], distToRoute: number, maxSnapDistance: number): number;
41
-
42
- /**
43
- * Module 8: RouteOffsetPredictor
44
- * Linear distance-based position predictor for smooth rendering between GPS fixes.
45
- */
46
-
47
- /**
48
- * Advance the predictor's offset by speed * dt.
49
- */
50
- declare function advancePredictor(currentOffset: number, speedMps: number, dtSec: number): number;
51
- /**
52
- * Correct the predictor when a new GPS fix arrives.
53
- * Blend towards the actual measured offset using betaCorrection.
54
- */
55
- declare function applyGpsCorrection(predictedOffset: number, measuredOffset: number, betaCorrection?: number): number;
56
- /**
57
- * Given a linear offset (metres from route start), find the [lng, lat] on the route.
58
- *
59
- * @param offset Linear distance from route start in metres
60
- * @param cumulativeDistances Forward cumulative distance array
61
- * @param route Route coordinates
62
- * @returns Interpolated coordinate on the route
63
- */
64
- declare function pointAtOffset(offset: number, cumulativeDistances: Float64Array, route: Coordinate[]): Coordinate;
65
-
66
- export { Coordinate, advancePredictor, applyBearingSmoothing, applyGpsCorrection, blendBearing, calculateRobustBearing, getSpeedAdaptiveAlpha, pointAtOffset, validateProgressUpdate };
3
+ export { D as DeadReckoningEngine, a as DeviationDetector, E as ETAEngine, b as ETAOptions, c as ETAResult, G as GeofenceEvent, d as GeofenceEventType, e as GeofenceType, f as GeofencingEngine, g as GeofencingOptions, I as InstructionEditor, h as InstructionType, P as ParallelRoadResolver, i as ParallelRoadResolverOptions, R as ResolvedCandidate, j as RichInstruction, S as SnapCandidate, V as VoiceCue, k as VoicePriority, l as VoiceTriggerEngine, m as VoiceTriggerOptions, Z as ZoneDefinition, n as advancePredictor, o as applyBearingSmoothing, p as applyGpsCorrection, q as blendBearing, r as calculateDynamicCorridor, s as calculateRobustBearing, t as computeDeadReckoningOnRoute, u as getSpeedAdaptiveAlpha, v as pointAtOffset, w as validateProgressUpdate } from './index.pro-C5J1xlzt.js';
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- 'use strict';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
+ 'use strict';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
- exports.Constants=Se;exports.CustomRouteBuilder=se;exports.DeadReckoningEngine=P;exports.DeviationDetector=w;exports.ETAEngine=de;exports.FEATURES=h;exports.GeofencingEngine=pe;exports.InstructionEditor=ie;exports.KalmanFilter2D=D;exports.LicenseManager=m;exports.NavCore=he;exports.NavigationFSM=G;exports.OSRMDirectionsProvider=ae;exports.OffRouteFSM=L;exports.OpenRouteServiceProvider=le;exports.ParallelRoadResolver=Q;exports.RouteSnapper=N;exports.ValhallaDirectionsProvider=ce;exports.VoiceTriggerEngine=ue;exports.advancePredictor=re;exports.applyBearingSmoothing=ee;exports.applyGpsCorrection=oe;exports.blendBearing=V;exports.buildForwardCumulativeDistances=K;exports.buildReverseCumulativeDistances=j;exports.calculateDynamicCorridor=Z;exports.calculateRobustBearing=Me;exports.computeDeadReckoningOnRoute=Ae;exports.destinationPoint=B;exports.geoGetBearing=we;exports.getBearingBetweenPoints=R;exports.getSpeedAdaptiveAlpha=_e;exports.haversineDistance=y;exports.interpolatePoint=W;exports.kalmanUpdate2D=me;exports.normalizeAngle=E;exports.pointAtOffset=ze;exports.projectPointOnSegment=H;exports.resolveNextInstruction=ne;exports.validateProgressUpdate=te;
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
+ exports.Constants=_e;exports.CustomRouteBuilder=ce;exports.DeadReckoningEngine=D;exports.DeviationDetector=N;exports.ETAEngine=he;exports.FEATURES=_;exports.GeofencingEngine=me;exports.InstructionEditor=oe;exports.KalmanFilter2D=M;exports.LicenseManager=G;exports.NavCore=fe;exports.NavigationFSM=F;exports.OSRMDirectionsProvider=le;exports.OffRouteFSM=w;exports.OpenRouteServiceProvider=de;exports.ParallelRoadResolver=ee;exports.RouteSnapper=T;exports.ValhallaDirectionsProvider=ue;exports.VoiceTriggerEngine=pe;exports.advancePredictor=se;exports.applyBearingSmoothing=ne;exports.applyGpsCorrection=ae;exports.blendBearing=k;exports.buildForwardCumulativeDistances=K;exports.buildReverseCumulativeDistances=W;exports.calculateDynamicCorridor=te;exports.calculateRobustBearing=De;exports.computeDeadReckoningOnRoute=Ae;exports.destinationPoint=B;exports.geoGetBearing=Le;exports.getBearingBetweenPoints=g;exports.getSpeedAdaptiveAlpha=Te;exports.haversineDistance=f;exports.interpolatePoint=H;exports.kalmanUpdate2D=ge;exports.normalizeAngle=E;exports.pointAtOffset=Ze;exports.projectPointOnSegment=j;exports.resolveNextInstruction=re;exports.validateProgressUpdate=ie;