@idm-plugin/vessel 1.7.2 → 1.7.4

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.
@@ -1 +1 @@
1
- (function(x,F){typeof exports=="object"&&typeof module<"u"?F(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],F):(x=typeof globalThis<"u"?globalThis:x||self,F(x["idm-plugin-rabbitmq"]={},x.got,x["@log4js-node/log4js-api"],x.moment,x["@idm-plugin/geo2"],x["@idm-plugin/meteo2"],x["@idm-plugin/meteo"]))})(this,function(x,F,_,g,E,nt,ot){"use strict";var vt=Object.defineProperty;var wt=(x,F,_)=>F in x?vt(x,F,{enumerable:!0,configurable:!0,writable:!0,value:_}):x[F]=_;var K=(x,F,_)=>(wt(x,typeof F!="symbol"?F+"":F,_),_);let p;try{p=_.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class mt extends G{constructor(t,o){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await F.post(o,i).json();p==null||p.info("[%s] fetch access token from: %s - %j",t.requestId,o,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:g().utc().format()})}async realTimePosition(t,o={}){var u,y,h;(!this.token||g().diff(g(this.token.issuedAt),"seconds")>((u=this.token)==null?void 0:u.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(y=this.token)==null?void 0:y.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:{mmsi:t}};p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const a=await F.get(i,n).json();if(a.code)return p==null||p.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:a.message,status:a.status,code:a.code}),a;const s=a.data;for(const M in s)!isNaN(s[M])&&Number(s[M])!==1/0&&(s[M]=Number(s[M]));const d=g(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName,imo:s.imo,callSign:s.callsign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?g.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,n,a=!0,s={}){(!this.token||g().diff(g(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(t,s),c=g(o),u=g(i),y=[];for(;u.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(t,c,c.clone().add(30,"day"),d,n,y,s),c.add(30,"day");return await this.trajectoryIn30Day(t,c,u,d,n,y,s),y}async trajectoryIn30Day(t,o,i,n,a,s,d={}){var m,k,H,v,w;const c="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(k=this.token)==null?void 0:k.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",d.requestId,c,u);const y=await F.post(c,u).json();if(y.code)return p==null||p.warn("[%s] fetch trajectory failed: %j",d.requestId,c,{message:y.message,status:y.status,code:y.code}),y;let h=-1;const M=g(`${(v=(H=y.data)==null?void 0:H[0])==null?void 0:v.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(w=y.data)==null||w.forEach(r=>{for(const A in r)!isNaN(r[A])&&Number(r[A])!==1/0&&(r[A]=Number(r[A]));const l=g(`${r.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),b=r.status,{labelCn:f,labelEn:Y}=this.parseStatus(b),j={mmsi:r.mmsi,imo:n==null?void 0:n.imo,lat:r.lat,lng:r.lon,sog:r.sog,cog:r.cog,hdg:r.hdg,draught:r.draught,status:b,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(r.eta)?g(`${r.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:r.dest,positionTime:l.unix(),labelCn:f,labelEn:Y,method:"trajectory",vendor:"myVessel",utc:l.utc().format()},O=Math.floor(l.diff(M,"minute",!0)/(a||1));O!==h&&(h=O,s.push(j))}),s}}class yt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},a=await F.post(i,n).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const s=a==null?void 0:a.list;if(!s)return p==null||p.warn("[%s] fetch realtime position failed: %j",o.requestId,i,a),a;for(const M in s)!isNaN(s[M])&&Number(s[M])!==1/0&&(s[M]=Number(s[M]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:c,labelEn:u}=this.parseStatus(d),y=g(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?g.utc(s.eta).format():void 0,destination:s.destination,positionTime:y.unix(),utc:y.utc().format(),status:d,labelCn:c,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,o={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await F.post(i,n).json();p==null||p.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]);for(const d in a)!isNaN(a[d])&&Number(a[d])!==1/0&&(a[d]=Number(a[d]));const s={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr,type:a.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await F.post(i,n).json(),p==null||p.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]),a&&(s.deadweight=Number(a.dwt)),s}async suggest(t,o={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},a=await F.post(i,n).json();p==null||p.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,n);const s=[];for(const d of a)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,c)=>c.score-d.score),s}async trajectory(t,o,i,n,a=!0,s={}){var r,l,b;const d=await this.realTimePosition(t,s);let c=g(o);const u=g(i),y=g();if(a){let f=u.diff(c,"d",!0);f<0?c=u.clone().subtract(40,"d"):f<30?c.subtract(10,"d"):f<60?c.subtract(5,"d"):c=u.clone().subtract(80,"d"),f=y.diff(u,"d",!0),u.add(f>10?240:f*24,"h")}const h={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:c.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},M="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",m=await F.get(M,h).json();p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,M,h);let k;m&&(k=((l=(r=m.ships)==null?void 0:r.offors)==null?void 0:l.ship)||[],k.length||p==null||p.warn("[%s] fetch trajectory failed: %j",s.requestId,m));const H=[];let v=-1;const w=g(`${(b=k==null?void 0:k[0])==null?void 0:b.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const f of k){for(const S in f)!isNaN(f[S])&&Number(f[S])!==1/0&&(f[S]=Number(f[S]));const Y=g(`${f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");f.status=f.sp>4?0:1;const{labelEn:j,labelCn:O}=this.parseStatus(f.status),A={mmsi:f.m,name:f.n,imo:d==null?void 0:d.imo,lat:f.la,lng:f.lo,draught:f.draught,sog:f.sp,cog:f.co,hdg:f.hdg,positionTime:Y.unix(),utc:Y.utc().format(),status:f.status,labelCn:O,labelEn:j,method:"trajectory",vendor:"hifleet"},T=Math.floor(Y.diff(w,"minute",!0)/(n||1));T!==v&&(v=T,H.push(A))}return H}}class Mt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",a=await F.get(n,i).json();if(p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,n,i),(a==null?void 0:a.status)!==0)return a;const s=a.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:c}=await this.parseStatus(s.navistat),u=g.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:c,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,n,a=!0,s={}){var w;const d=await this.realTimePosition(t,s),c=g(o),u=g(i),y="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:c.unix(),etm:u.unix()}},M=await F.get(y,h).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,y,h),(M==null?void 0:M.status)!==0)return M;const m=M==null?void 0:M.points,k=[],H=g.unix((w=m[0])==null?void 0:w.utc);let v=-1;for(const r of m){const l=g.unix(r.utc),b={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(r.sog*3600/1e3/1852*100)/100,cog:Math.round(r.cog/100*100)/100,lat:Math.round(r.lat/1e6*1e5)/1e5,lng:Math.round(r.lon/1e6*1e5)/1e5,positionTime:l.unix(),utc:l.utc().format(),method:"trajectory",vendor:"shipxy"},f=Math.floor(l.diff(H,"minute",!0)/(n||1));f!==v&&(v=f,k.push(b))}return k}}class pt extends G{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await F.post(n,i).json();return p==null||p.info("[%s] fetch ship id from: %s - %j",o.requestId,n,i),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",a=await F.post(n,i).json();if(p==null||p.info("[%s] fetch ship info from: %s - %j",o.requestId,n,i),a.code!=="0")return a;const s=a.data;let d=s.imo;return t==="407170"&&(d="9198379",p==null||p.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),n=await this.getShipInfo(i,o),a={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await F.post(s,a).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,a);const c=d.data[0];for(const m in c)!isNaN(c[m])&&Number(c[m])!==1/0&&(c[m]=Number(c[m]));const{labelCn:u,labelEn:y}=await this.parseStatus(c.aisNavStatus),h=g.unix(c.posTime);return{...n,mmsi:t,lat:Math.round(c.lat/1e4/60*1e5)/1e5,lng:Math.round(c.lon/1e4/60*1e5)/1e5,sog:Math.round(c.sog/10*100)/100,cog:Math.round(c.cog/10*100)/100,hdg:Math.round(c.heading*100)/100,rot:Math.round(c.rot*100)/100,positionTime:c.posTime,utc:h.utc().format(),status:c.aisNavStatus,labelEn:y,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,o,i,n,a=!0,s={}){const d=g(o),c=g(i),u=await this.getShipId(t),y=await this.getShipInfo(u),h=[];for(;c.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(u,d.unix(),d.add(30,"day").unix(),y,t,n,h);return await this.trajectoryIn30Day(u,d.unix(),c.unix(),y,t,n,h),h}async trajectoryIn30Day(t,o,i,n,a,s,d,c={}){var H;const u={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},y="https://api3.myships.com/sp/ships/position/history",h=await F.post(y,u).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",c.requestId,y,u),h.code!=="0")return p==null||p.warn("[%s] invoke myship trajectory failed: %j",c.requestId,h),h;const M=h.data;for(const v in M)!isNaN(M[v])&&Number(M[v])!==1/0&&(M[v]=Number(M[v]));const m=g.unix((H=M[0])==null?void 0:H.posTime);let k=-1;for(const v of M){const w=g.unix(v.posTime),r={imo:n==null?void 0:n.imo,mmsi:a,lat:Math.round(v.lat/1e4/60*1e5)/1e5,lng:Math.round(v.lon/1e4/60*1e5)/1e5,sog:Math.round(v.sog/10*100)/100,cog:Math.round(v.cog/10*100)/100,hdg:Math.round(v.heading*100)/100,rot:Math.round(v.rot*100)/100,positionTime:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"myship"},l=Math.floor(w.diff(m,"minute",!0)/(s||1));l!==k&&(k=l,d.push(r))}return d}}let B;try{B=_.getLogger("vessel")}catch{}finally{}var it=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(it||{});class ct{parsePrinciple(e,t={}){var s,d,c;B==null||B.info("[%s] parse rule: %s",t.requestId,e);const o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const a={};for(let u=0;u<(n==null?void 0:n.length);u++){const y=(c=(d=n[u].match(o))==null?void 0:d[0])==null?void 0:c.split("],");if(u===0&&!y)a.scope=n[0];else if(y)for(let h=0,M=y.length;h<M;h++){const m=this.parseRule(y[h]);m&&(a[m.level]?m.key?a[m.level][m==null?void 0:m.key]=m:a[m.level]=m:m.key?a[m.level]={[m==null?void 0:m.key]:m}:a[m.level]=m)}}return a}parseRule(e,t={}){var a;B==null||B.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(a=e==null?void 0:e.match(o))==null?void 0:a[0],n=i==null?void 0:i.split(",");if(n)return{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:Number(n[3]),key:n[4]}}checkWeather(e,t,o={}){var m,k,H,v,w,r,l,b,f,Y,j,O,A,T,S;let i=0,n=0,a=0,s=0;const d=Math.round(((k=(m=t==null?void 0:t.SEVERE)==null?void 0:m.sigWave)==null?void 0:k.number)*1.6*100)/100,c=(v=(H=t==null?void 0:t.SEVERE)==null?void 0:H.sigWave)==null?void 0:v.number,u=(r=(w=t==null?void 0:t.HEAVY)==null?void 0:w.sigWave)==null?void 0:r.number,y=Math.round((((b=(l=t==null?void 0:t.SEVERE)==null?void 0:l.wind)==null?void 0:b.number)+2)*100)/100,h=(Y=(f=t==null?void 0:t.SEVERE)==null?void 0:f.wind)==null?void 0:Y.number,M=(O=(j=t==null?void 0:t.HEAVY)==null?void 0:j.wind)==null?void 0:O.number;for(let V=0;V<(e==null?void 0:e.length);V++){const C=e[V],q=(T=(A=C==null?void 0:C.meteo)==null?void 0:A.wave)==null?void 0:T.sig,J=(S=C==null?void 0:C.meteo)==null?void 0:S.wind,Z=V?g(C.eta).diff(g(e[V-1].eta),"hour",!0):0;s=Z>s?Z:s,B==null||B.info("[%s] check sig.wave: %j",o.requestId,{...q,dgThd4Wv:d,svThd4Wv:c,hvThd4Wv:u}),(q==null?void 0:q.height)>=d?C.isDangerous=!0:(q==null?void 0:q.height)>=c?C.isSevere=!0:(q==null?void 0:q.height)>=u&&(C.isHeavy=!0),B==null||B.info("[%s] check wind: %j",o.requestId,{...J,dgThd4Wd:y,svThd4Wd:h,hvThd4Wd:M}),(J==null?void 0:J.scale)>=y?(C.isDangerous=!0,delete C.isSevere,delete C.isHeavy):(J==null?void 0:J.scale)>h?(C.isDangerous||(C.isSevere=!0),delete C.isHeavy):(J==null?void 0:J.scale)===M&&!C.isDangerous&&!C.isSevere&&(C.isHeavy=!0),i+=C.isDangerous?Z:0,n+=C.isSevere?Z:0,a+=C.isHeavy?Z:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,a=Math.round(a*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:n,heavy:a,step:s<3?3:s,wind:{dgThd4Wd:y,svThd4Wd:h,hvThd4Wd:M},sig:{dgThd4Wv:d,svThd4Wv:c,hvThd4Wv:u}}}}const bt=new ct;let I;try{I=_.getLogger("vessel")}catch{}finally{}const gt=new nt.MeteoHelper2("",!0);var rt=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(rt||{}),dt=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(dt||{}),ut=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ut||{});class P{static blockCoefficient(e,t,o,i){let n=Math.round(e/(t*o*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const a=[.55,.6,.65,.7,.75,.8,.85],s=a.map(d=>Math.abs(d-n));return a[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(a=i[e]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let n;return o==="container"?n=.7*i+Math.pow(i,6.5)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)):n=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,a=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,c=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:c.indexOf("container")>-1?"container":c.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:a,breadthMoulded:s,displacement:Math.round((d/1.025+a*s*n*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",n=2,a=!0,s=!1,d={}){let c;if(t.velocity&&s&&(e.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let u;if(d.meteo2)try{const m=await gt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[k]=ot.Meteo2Assist.pickHourly(m,o);u=ot.Meteo2Assist.toLegacy(k)}catch(m){I.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},m)}else u=await nt.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const y=P.weatherFactor(e,u),h=P.currentFactor(e.bearing,u==null?void 0:u.current,n),M=Math.round((e.speed*1.943844+y+h)*100)/100;c={meteo:{...u},wxFactor:y,cFactor:h,speed:t.velocity&&s?t.velocity:M<0?1:M,eta:o.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:o.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else c={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round((e.speed*1.943844+0+0)*100)/100,eta:o.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:o.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...c,...t}}static async speedLoseInHoursStep(e,t,o,i,n,a,s="",d=!0,c=!1,u={}){t.utc();const y=t.clone().add(14,"days"),h=[],M=[];let m=0,k=0,H,v;for(let w=0;w<a.length-1;w++){let r=a[w];r.distanceFromStart=Math.round((n+k)*1e4)/1e4;const l=a[w+1];if(e.bearing=E.LaneHelper.calculateBearing(r,l,!l.gcToPrevious),r.bearing=e.bearing,r.suspend&&c){r.eta=r.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),r.elapsed=r.elapsed??0;const Y=r.suspend-r.elapsed;if(i-m>Y)i=i-m-Y,t.add(Y,"hour"),r.elapsed=r.suspend;else{const j=i-m;r.elapsed+=j,t.add(j,"hour"),i=0}if(I==null||I.info(`[%s] suspend ${r.elapsed} hours at %j, and remain ${i} hours need to go...`,u.requestId,r),i===0)return r.distanceFromPrevious=k,{etd:t,from:v||r,to:r,next:a.filter(j=>j),wps:h,days:M}}else r.suspend=0;d=t.isAfter(y)?!1:d,r=await P.speedLoseAt(e,r,t,s,0,d,c,u),v=v||r,r.important&&h.push(r),t.isSameOrAfter(o)&&(M.push(r),o.add(24,"hour"));const b=E.LaneHelper.calculateDistance(r,l,!l.gcToPrevious);let f=Math.ceil(b/v.speed*1e4)/1e4;if(m+f<i){if(m+=f,t.add(f,"hour"),delete a[w],I==null||I.debug(`[%s] go to %j from %j with ${b}nm, and cost ${f} hours`,u.requestId,{lat:l.lat,lng:l.lng},{lat:v.lat,lng:v.lng,etd:v.etd}),k+=b,a.filter(Y=>Y).length<=1){H=l,H.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),H.distanceFromPrevious=b,H.distanceFromStart=Math.round((n+k)*1e4)/1e4,h.push(H),delete a[w+1];break}}else{f=i-m,t.add(f,"hour");const Y=E.LngLatHelper.roundPrecision(v.speed*f,4);H=E.LaneHelper.calculateCoordinate(r,e.bearing,Y,"nauticalmiles",!l.gcToPrevious),H.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),a[w]=H,I==null||I.debug(`[%s] go to %j from %j with ${Y}nm, and cost ${f} hours`,u.requestId,{lat:H.lat,lng:H.lng},{lat:r.lat,lng:r.lng,etd:r.etd}),k+=Y,H.distanceFromPrevious=Math.round(k*1e4)/1e4,H.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:v,to:H,next:a.filter(w=>w),wps:h,days:M}}static currentFactor(e,t,o=0){const i=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return o&2?n=Math.ceil(n*100)/100:o&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t){var y,h,M,m,k,H,v;I==null||I.debug("calculate weather factor via: %j",{...e,...t});const o=P.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=P.froudeNumber(e.speed,e.lbp),n=P.amendFactor(o,i,e.loadCondition);let a=Math.abs(e.bearing%360-(((y=t==null?void 0:t.wind)==null?void 0:y.degree)%360||0));a=a>180?360-a:a;const s=P.directionFactor(a,(h=t==null?void 0:t.wind)==null?void 0:h.scale),d=P.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(M=t==null?void 0:t.wind)==null?void 0:M.scale);let c=s*n*d/100*e.speed;c=Math.round(c*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),I==null||I.debug("wind wx factor = %d",c),a=Math.abs(e.bearing%360-(((k=(m=t==null?void 0:t.wave)==null?void 0:m.sig)==null?void 0:k.degree)%360||0));const u=P.waveHeightFactor(((v=(H=t==null?void 0:t.wave)==null?void 0:H.sig)==null?void 0:v.height)??1,a);return I==null||I.debug("wave wx factor = %d",u),c=c*.4+u,I==null||I.debug("weather factor = %d",c),c=Math.abs(c)>4?4*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-4)*.1:c,Math.round((c||0)*100)/100}static async analyseInstant(e,t,o,i,n,a="",s=0,d=!0,c=!1,u={}){var z,U,Q,X,$;const y=g().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:M}=n.points,m=E.LaneHelper.calculateSubRoute(e,h);if(((z=m[0])==null?void 0:z.length)<=1)return;const{v0:k,label:H}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},v=P.assembleProperties(o,i.loadCondition,k,0),w=M.length?E.LaneHelper.calculateSubWaypoints(e,M):[];w.forEach(L=>L.important=!0);const r={from:{...e},route:m,waypoints:w,v0:k,label:H},l={hours:[],days:[],wps:[]};s||(E.LaneHelper.calculateRouteDistance(m)/i.speed<=72?s=3:s=6);let b=E.LaneHelper.simplifyRouteToCoordinates(m,w,0),f=0,Y=0,j=0,O=0;t=g(t).utc();const A=t.clone();for(;b.length>0;){const L=s-t.hour()%s,R=Math.ceil(t.clone().add(L,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,N=await P.speedLoseInHoursStep(v,t,A,R,f,b,a,d,c,u);(U=N.from)!=null&&U.speed&&(l.hours.push(N.from),l.wps.push(...N.wps),l.days.push(...N.days)),b=N==null?void 0:N.next,b.length||l.hours.push(N==null?void 0:N.to),f+=Math.round((((Q=N==null?void 0:N.to)==null?void 0:Q.distanceFromPrevious)??0)*1e4)/1e4}const T=l.hours;for(let L=0;L<T.length-1;L++){const R=g(T[L+1].eta).diff(T[L].etd,"hour",!0)||1;Y+=(T[L].wxFactor||0)*R,j+=(T[L].cFactor||0)*R,O+=R}(X=l.wps)==null||X.forEach((L,R)=>{if(L.positionTime=g.utc(L.etd||L.eta).unix(),R){const N=l.wps[R-1],W=L.distanceFromStart-N.distanceFromStart,ht=g(L.eta).diff(g(N.etd),"h",!0);if(ht<1)L.avgSpd=N.speed;else{L.avgSpd=Math.round(W/ht*100)/100;const ft=Math.round((N.speed+L.speed)/2*100)/100;L.avgSpd=L.avgSpd>ft?ft:L.avgSpd}}}),r.sample=l;const S=l.hours.at(0),V=l.hours.at(-1);r.distance=Math.round(V.distanceFromStart*1e4)/1e4,r.etd=g(S.eta).utc().format(),r.eta=g(V.eta).utc().format(),r.wxFactor=Math.round(Y/O*1e4)/1e4,r.cFactor=Math.round(j/O*1e4)/1e4,r.avgSpeed=Math.round(V.distanceFromStart/O*1e4)/1e4,r.totalHrs=Math.round(O*1e4)/1e4;const{distanceInECA:C,hoursInECA:q,totalDgoConsInECA:J,eca:Z}=await this.calculateECA(r,i,u),et=E.LngLatHelper.roundPrecision(i.fo/24*(O-q),3),st=E.LngLatHelper.roundPrecision(i.dgo/24*O,3);r.extend={eca:Z,distanceInECA:C,hoursInECA:q,totalDgoConsInECA:J},r.totalFoCons=et,r.totalDgoCons=st;const tt=g().valueOf()-y,at=(($=l==null?void 0:l.hours)==null?void 0:$.length)||1;return I==null||I.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,tt,at,Math.round(tt/at*1e3)/1e3),r}static async analyseInstantWithThreshed(e,t,o,i,n,a,s,d="",c=3,u=!0,y=!1,h={}){var Q,X,$,L;const M=g().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{v0:m,label:k}=e.sog?{v0:e.sog,label:"Other"}:{v0:n.speed,label:"CP"},H=P.assembleProperties(i,n.loadCondition,m,0),v=E.LaneHelper.calculateSubRoute(e,a);if(((Q=v[0])==null?void 0:Q.length)<=1)return;const w=s.length?E.LaneHelper.calculateSubWaypoints(e,s):[];w.forEach(R=>R.important=!0);let r=E.LaneHelper.simplifyRouteToCoordinates(v,w,0),l=0,b=0,f=0,Y=0;const j={hours:[],wps:[],days:[]};t=g(t).utc();const O=t.clone();for(;r.length>0;){const R=c-t.hour()%c;let N=Math.ceil(t.clone().add(R,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;N=t.clone().add(N,"h").isSameOrAfter(o)?o.diff(t,"h",!0)*1e4/1e4:N;const W=await P.speedLoseInHoursStep(H,t,O,N,l,r,d,u,y,h);if((X=W.from)!=null&&X.speed&&(j.hours.push(W.from),W!=null&&W.wps&&j.wps.push(...W.wps),j.days.push(...W.days)),r=W==null?void 0:W.next,r.length||j.hours.push(W==null?void 0:W.to),l+=Math.round(((($=W==null?void 0:W.to)==null?void 0:$.distanceFromPrevious)??0)*1e4)/1e4,!N)break}const A=j.hours;for(let R=0;R<A.length-1;R++){const N=g(A[R+1].eta).diff(A[R].etd,"hour",!0);b+=A[R].wxFactor*N,f+=A[R].cFactor*N,Y+=N}const T=j.hours.at(0),S=j.hours.at(-1),V=await E.LaneHelper.calculateRangeRoute(T,S,v),C=await E.LaneHelper.calculateRangeWaypoints(T,S,v,w),q={sample:j,distance:Math.round(((S==null?void 0:S.distanceFromStart)||0)*1e4)/1e4,etd:g(T.eta).utc().format(),eta:g(S==null?void 0:S.eta).utc().format(),wxFactor:Math.round(b/Y*1e4)/1e4,cFactor:Math.round(f/Y*1e4)/1e4,avgSpeed:Math.round(((S==null?void 0:S.distanceFromStart)||0)/Y*1e4)/1e4,totalHrs:Math.round(Y*1e4)/1e4,from:T,to:S,route:V,waypoints:C,v0:m,label:k},{distanceInECA:J,hoursInECA:Z,totalDgoConsInECA:et,eca:st}=await this.calculateECA(q,n,h),lt=E.LngLatHelper.roundPrecision(n.fo/24*(Y-Z),3),tt=E.LngLatHelper.roundPrecision(n.dgo/24*Y,3);q.extend={eca:st,distanceInECA:J,hoursInECA:Z,totalDgoConsInECA:et},q.totalDgoCons=tt,q.totalFoCons=lt;const z=g().valueOf()-M,U=((L=j==null?void 0:j.hours)==null?void 0:L.length)||1;return I==null||I.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,z,U,Math.round(z/U*1e3)/1e3),q}static async analyseCost(e,t,o,i,n={}){var v,w;const a=g().valueOf(),s=[];n.meteo2=n.meteo2||!0,e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const d=E.LaneHelper.calculateRouteDistance(i.route);let c=0;o.forEach(r=>{const l=Math.ceil(d/r.speed/24);c=c<l?l:c}),c=c*1.3;const u=g.utc(e.etd).add(c??14,"day");let y=1;for(const r of o){const l=JSON.parse(JSON.stringify(i.route)),b=JSON.parse(JSON.stringify(i.waypoints)),f=await P.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,r,l,b,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);f&&(await P.calculateCost(f,r,e,n),s.push(f),I==null||I.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,y,e.etd,u.format(),{cost:f.cost.total,distance:f.distance,hours:f.totalHrs,cp:`${r.speed}/${r.fo}/${r.dgo}`})),y++}s.sort((r,l)=>r.cost.total-l.cost.total);const h=s.at(0),M=s.at(1),m=[];if(m.push({combined:!1,speeds:[h],cost:(v=h.cost)==null?void 0:v.total}),M){const r=h.cost.cp,l=M.cost.cp,b=g(h.eta),f=g(h.etd),Y=b.diff(f,"days",!0);let j=Math.ceil(Y/2);j=j>7?7:j<e.alterStep?e.alterStep:j;let O=2,A={combined:!1,speeds:[M],cost:(w=M.cost)==null?void 0:w.total},T;for(;j>=e.alterStep;){const S=await P.combinedAnalyse(e,t,u,[r,l],i,j,{...n,level:O});if(A.cost>S.cost?T?(T==null?void 0:T.cost)>S.cost&&(T=S):(T=A,A=S):(!T||(T==null?void 0:T.cost)>S.cost)&&(T=S),j<=e.alterStep)break;j=Math.ceil(j/2),O+=1}m.push(A),T&&m.push(T)}const H=g().valueOf()-a;return I==null||I.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,H),m.sort((r,l)=>r.cost-l.cost)}static async combinedAnalyse(e,t,o,i,n,a,s={}){s.counter=1,I==null||I.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,a);const d=await P.alternateAnalyse(e,t,o,i,0,n,a,s),c=d.reduce((h,M)=>h+M.cost.total,0);I==null||I.info("[%s][L%d] cost with cpa/cpb turn: %d",s.requestId,s.level,c);const u=await P.alternateAnalyse(e,t,o,i,1,n,a,s),y=u.reduce((h,M)=>h+M.cost.total,0);return I==null||I.info("[%s][L%d] cost with cpb/cpa turn: %d",s.requestId,s.level,y),c<y?{combined:!0,cost:Math.round(c*1e3)/1e3,speeds:d,step:a}:{combined:!0,cost:Math.round(y*1e3)/1e3,speeds:u,step:a}}static async alternateAnalyse(e,t,o,i,n,a,s,d={}){var h,M;let c=g.utc(e.etd);const u={lat:e.lat,lng:e.lng},y=[];for(;c.isBefore(o);){const m=c.clone().utc().add(s,"day"),k=JSON.parse(JSON.stringify(a.route)),H=JSON.parse(JSON.stringify(a.waypoints)),v=i[n],w=await P.analyseInstantWithThreshed(u,c.format(),m,t,v,k,H,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,d);w&&(await P.calculateCost(w,v,e,d),I==null||I.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,c.utc().format(),m.utc().format(),{cost:w.cost.total,distance:w.distance,hours:w.totalHrs,cp:`${v.speed}/${v.fo}/${v.dgo}`})),d.counter=d.counter+1;const r=(M=(h=w==null?void 0:w.sample)==null?void 0:h.hours)==null?void 0:M.at(-1);if(r)u.lat=r.lat,u.lng=r.lng,c=g(r.eta),y.push(w),n=n?0:1;else break}return y}static async calculateCost(e,t,o,i={}){var n;if(e){const a=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,s=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,d=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((a+s+d)*1e3)/1e3,hire:a,bunker:Math.round((s+d)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,o={}){var d,c;const i=await E.LaneHelper.intersectInECA(e.route);let n=0,a=0,s=0;e.sample.wps.forEach(u=>{u.positionTime=g.utc(u.etd||u.eta).unix()});for(const u of i){n+=u.distance;const y=await E.LaneHelper.deadReckoningTime((d=u.waypoints)==null?void 0:d.at(0),e.sample.wps),h=await E.LaneHelper.deadReckoningTime((c=u.waypoints)==null?void 0:c.at(-1),e.sample.wps);u.in=y,u.out=h,u.totalHrs=E.LngLatHelper.roundPrecision((h.positionTime-y.positionTime)/3600,2),u.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*u.totalHrs,3),a+=u.totalHrs,s+=u.totalDgoCons}return n=E.LngLatHelper.roundPrecision(n,3),a=E.LngLatHelper.roundPrecision(a,3),s=E.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:a,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(e,t={}){var w,r;const o={hours:[],wps:[],days:[]},i=e.reduce((l,b)=>l+b.distance,0),n=e.reduce((l,b)=>{var f;return l+(((f=b.extend)==null?void 0:f.distanceInECA)||0)},0),a=e.reduce((l,b)=>l+b.totalHrs,0),s=e.reduce((l,b)=>{var f;return l+(((f=b.extend)==null?void 0:f.hoursInECA)||0)},0),d=e.reduce((l,b)=>{var f;return l+(((f=b.extend)==null?void 0:f.totalDgoConsInECA)||0)},0),c=e.reduce((l,b)=>l+b.wxFactor*b.totalHrs/a,0),u=e.reduce((l,b)=>l+b.cFactor*b.totalHrs/a,0),y=e.reduce((l,b)=>l+b.totalFoCons,0),h=e.reduce((l,b)=>l+b.totalDgoCons,0),M=e.reduce((l,b)=>l+b.cost.total,0),m=e.reduce((l,b)=>l+b.cost.hire,0),k=e.reduce((l,b)=>l+b.cost.bunker,0),H=[],v=[];for(const l of e){v.push(...((w=l.extend)==null?void 0:w.eca)||[]);const b=l.sample.hours,f=b.at(0);f.cp=l.cost.cp;const Y=[l.etd,l.eta],j=H.findIndex(S=>S.id===f.cp.id);j===-1?(f.cp.segment=[Y],H.push(f.cp)):H[j].segment.push(Y);const O=l.sample.wps,A=l.sample.days;b.forEach(S=>{var C;((C=o.hours)==null?void 0:C.findIndex(q=>q.eta===S.eta))===-1&&o.hours.push(S)}),O.forEach(S=>{var C;((C=o.wps)==null?void 0:C.findIndex(q=>q.eta===S.eta))===-1&&o.wps.push(S)}),A.forEach(S=>{var C;((C=o==null?void 0:o.days)==null?void 0:C.findIndex(q=>q.eta===S.eta))===-1&&o.days.push(S)});const T=(r=o.wps)==null?void 0:r.findIndex(S=>S.eta===f.eta);T===-1?o.wps.push(f):o.wps[T]=f}return o.wps.sort((l,b)=>{g(l.etd).unix()-g(b.etd).unix()}),{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(i/a*1e3)/1e3,wxFactor:Math.round(c/a*1e3)/1e3,cFactor:Math.round(u/a*1e3)/1e3,totalFoCons:Math.round(y*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(M*1e3)/1e3,hire:Math.round(m*1e3)/1e3,bunker:Math.round(k*1e3)/1e3},extend:{cps:H,eca:v,distanceInECA:Math.round(n*1e4)/1e4,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3}}}}x.AISImpl=G,x.AlertHelper=ct,x.AlertLevel=it,x.HifleetImpl=yt,x.LoadCondition=dt,x.MyShipImpl=pt,x.MyVesselImpl=mt,x.ShipxyImpl=Mt,x.SpeedHelper=P,x.SpeedLabel=ut,x.VesselTag=rt,x.alertHelper=bt,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"})});
1
+ (function(D,Y){typeof exports=="object"&&typeof module<"u"?Y(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],Y):(D=typeof globalThis<"u"?globalThis:D||self,Y(D["idm-plugin-rabbitmq"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,Y,G,v,q,ot,it){"use strict";var wt=Object.defineProperty;var It=(D,Y,G)=>Y in D?wt(D,Y,{enumerable:!0,configurable:!0,writable:!0,value:G}):D[Y]=G;var z=(D,Y,G)=>(It(D,typeof Y!="symbol"?Y+"":Y,G),G);let p;try{p=G.getLogger("vessel")}catch{}finally{}class U{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class mt extends U{constructor(t,o){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await Y.post(o,i).json();p==null||p.info("[%s] fetch access token from: %s - %j",t.requestId,o,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async realTimePosition(t,o={}){var l,m,h;(!this.token||v().diff(v(this.token.issuedAt),"seconds")>((l=this.token)==null?void 0:l.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:{mmsi:t}};p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const a=await Y.get(i,n).json();if(a.code)return p==null||p.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:a.message,status:a.status,code:a.code}),a;const s=a.data;for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const d=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName,imo:s.imo,callSign:s.callsign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,n,a=!0,s={}){(!this.token||v().diff(v(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(t,s),r=v(o),l=v(i),m=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,n,m,s),r.add(30,"day");return await this.trajectoryIn30Day(t,r,l,d,n,m,s),m}async trajectoryIn30Day(t,o,i,n,a,s,d={}){var f,j,k,g,b;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,l);const m=await Y.post(r,l).json();if(m.code)return p==null||p.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:m.message,status:m.status,code:m.code}),m;let h=-1;const y=v(`${(g=(k=m.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(b=m.data)==null||b.forEach(c=>{for(const P in c)!isNaN(c[P])&&Number(c[P])!==1/0&&(c[P]=Number(c[P]));const w=v(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),M=c.status,{labelCn:u,labelEn:I}=this.parseStatus(M),F={mmsi:c.mmsi,imo:n==null?void 0:n.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:M,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?v(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:w.unix(),labelCn:u,labelEn:I,method:"trajectory",vendor:"myVessel",utc:w.utc().format()},N=Math.floor(w.diff(y,"minute",!0)/(a||1));N!==h&&(h=N,s.push(F))}),s}}class yt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},a=await Y.post(i,n).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const s=a==null?void 0:a.list;if(!s)return p==null||p.warn("[%s] fetch realtime position failed: %j",o.requestId,i,a),a;for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:l}=this.parseStatus(d),m=v(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.destination,positionTime:m.unix(),utc:m.utc().format(),status:d,labelCn:r,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,o={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await Y.post(i,n).json();p==null||p.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]);for(const d in a)!isNaN(a[d])&&Number(a[d])!==1/0&&(a[d]=Number(a[d]));const s={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr,type:a.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await Y.post(i,n).json(),p==null||p.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]),a&&(s.deadweight=Number(a.dwt)),s}async suggest(t,o={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},a=await Y.post(i,n).json();p==null||p.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,n);const s=[];for(const d of a)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(t,o,i,n,a=!0,s={}){var c,w,M;const d=await this.realTimePosition(t,s);let r=v(o);const l=v(i),m=v();if(a){let u=l.diff(r,"d",!0);u<0?r=l.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=l.clone().subtract(80,"d"),u=m.diff(l,"d",!0),l.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},y="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await Y.get(y,h).json();p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,y,h);let j;f&&(j=((w=(c=f.ships)==null?void 0:c.offors)==null?void 0:w.ship)||[],j.length||p==null||p.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const k=[];let g=-1;const b=v(`${(M=j==null?void 0:j[0])==null?void 0:M.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of j){for(const T in u)!isNaN(u[T])&&Number(u[T])!==1/0&&(u[T]=Number(u[T]));const I=v(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:N}=this.parseStatus(u.status),P={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:I.unix(),utc:I.utc().format(),status:u.status,labelCn:N,labelEn:F,method:"trajectory",vendor:"hifleet"},H=Math.floor(I.diff(b,"minute",!0)/(n||1));H!==g&&(g=H,k.push(P))}return k}}class Mt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",a=await Y.get(n,i).json();if(p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,n,i),(a==null?void 0:a.status)!==0)return a;const s=a.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),l=v.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:l.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,n,a=!0,s={}){var b;const d=await this.realTimePosition(t,s),r=v(o),l=v(i),m="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:l.unix()}},y=await Y.get(m,h).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,m,h),(y==null?void 0:y.status)!==0)return y;const f=y==null?void 0:y.points,j=[],k=v.unix((b=f[0])==null?void 0:b.utc);let g=-1;for(const c of f){const w=v.unix(c.utc),M={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(c.sog*3600/1e3/1852*100)/100,cog:Math.round(c.cog/100*100)/100,lat:Math.round(c.lat/1e6*1e5)/1e5,lng:Math.round(c.lon/1e6*1e5)/1e5,positionTime:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(w.diff(k,"minute",!0)/(n||1));u!==g&&(g=u,j.push(M))}return j}}class pt extends U{constructor(t){super();z(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await Y.post(n,i).json();return p==null||p.info("[%s] fetch ship id from: %s - %j",o.requestId,n,i),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",a=await Y.post(n,i).json();if(p==null||p.info("[%s] fetch ship info from: %s - %j",o.requestId,n,i),a.code!=="0")return a;const s=a.data;let d=s.imo;return t==="407170"&&(d="9198379",p==null||p.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),n=await this.getShipInfo(i,o),a={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await Y.post(s,a).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,a);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:l,labelEn:m}=await this.parseStatus(r.aisNavStatus),h=v.unix(r.posTime);return{...n,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:h.utc().format(),status:r.aisNavStatus,labelEn:m,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,o,i,n,a=!0,s={}){const d=v(o),r=v(i),l=await this.getShipId(t),m=await this.getShipInfo(l),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(l,d.unix(),d.add(30,"day").unix(),m,t,n,h);return await this.trajectoryIn30Day(l,d.unix(),r.unix(),m,t,n,h),h}async trajectoryIn30Day(t,o,i,n,a,s,d,r={}){var k;const l={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},m="https://api3.myships.com/sp/ships/position/history",h=await Y.post(m,l).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",r.requestId,m,l),h.code!=="0")return p==null||p.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const y=h.data;for(const g in y)!isNaN(y[g])&&Number(y[g])!==1/0&&(y[g]=Number(y[g]));const f=v.unix((k=y[0])==null?void 0:k.posTime);let j=-1;for(const g of y){const b=v.unix(g.posTime),c={imo:n==null?void 0:n.imo,mmsi:a,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"myship"},w=Math.floor(b.diff(f,"minute",!0)/(s||1));w!==j&&(j=w,d.push(c))}return d}}let B;try{B=G.getLogger("vessel")}catch{}finally{}var rt=(L=>(L.NOTICE="NOTICE",L.WARN="WARN",L.HEAVY="HEAVY",L.SEVERE="SEVERE",L.ERROR="ERROR",L.FATAL="FATAL",L))(rt||{});class ct{parsePrinciple(e,t={}){var s,d,r;B==null||B.info("[%s] parse rule: %s",t.requestId,e);const o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const a={};for(let l=0;l<(n==null?void 0:n.length);l++){const m=(r=(d=n[l].match(o))==null?void 0:d[0])==null?void 0:r.split("],");if(l===0&&!m)a.scope=n[0];else if(m)for(let h=0,y=m.length;h<y;h++){const f=this.parseRule(m[h]);f&&(a[f.level]?f.key?a[f.level][f==null?void 0:f.key]=f:a[f.level]=f:f.key?a[f.level]={[f==null?void 0:f.key]:f}:a[f.level]=f)}}return a}parseRule(e,t={}){var a;B==null||B.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(a=e==null?void 0:e.match(o))==null?void 0:a[0],n=i==null?void 0:i.split(",");if(n)return{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:Number(n[3]),key:n[4]}}checkWeather(e,t,o={}){var f,j,k,g,b,c,w,M,u,I,F,N,P,H,T;let i=0,n=0,a=0,s=0;const d=Math.round(((j=(f=t==null?void 0:t.SEVERE)==null?void 0:f.sigWave)==null?void 0:j.number)*1.6*100)/100,r=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,l=(c=(b=t==null?void 0:t.HEAVY)==null?void 0:b.sigWave)==null?void 0:c.number,m=Math.round((((M=(w=t==null?void 0:t.SEVERE)==null?void 0:w.wind)==null?void 0:M.number)+2)*100)/100,h=(I=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:I.number,y=(N=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:N.number;for(let E=0;E<(e==null?void 0:e.length);E++){const C=e[E],A=(H=(P=C==null?void 0:C.meteo)==null?void 0:P.wave)==null?void 0:H.sig,V=(T=C==null?void 0:C.meteo)==null?void 0:T.wind,K=E?v(C.eta).diff(v(e[E-1].eta),"hour",!0):0;s=K>s?K:s,B==null||B.info("[%s] check sig.wave: %j",o.requestId,{...A,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}),(A==null?void 0:A.height)>=d?C.isDangerous=!0:(A==null?void 0:A.height)>=r?C.isSevere=!0:(A==null?void 0:A.height)>=l&&(C.isHeavy=!0),B==null||B.info("[%s] check wind: %j",o.requestId,{...V,dgThd4Wd:m,svThd4Wd:h,hvThd4Wd:y}),(V==null?void 0:V.scale)>=m?(C.isDangerous=!0,delete C.isSevere,delete C.isHeavy):(V==null?void 0:V.scale)>h?(C.isDangerous||(C.isSevere=!0),delete C.isHeavy):(V==null?void 0:V.scale)===y&&!C.isDangerous&&!C.isSevere&&(C.isHeavy=!0),i+=C.isDangerous?K:0,n+=C.isSevere?K:0,a+=C.isHeavy?K:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,a=Math.round(a*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:n,heavy:a,step:s<3?3:s,wind:{dgThd4Wd:m,svThd4Wd:h,hvThd4Wd:y},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}}}}const vt=new ct;let S;try{S=G.getLogger("vessel")}catch{}finally{}const bt=new ot.MeteoHelper2("",!0);var dt=(L=>(L.common="common",L.container="container",L.tugs="tugs",L))(dt||{}),ut=(L=>(L.Ballast="Ballast",L.Laden="Laden",L))(ut||{}),lt=(L=>(L.Cp="CP",L.Perf="Basis",L.Instruct="Other",L))(lt||{});class R{static blockCoefficient(e,t,o,i){let n=Math.round(e/(t*o*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const a=[.55,.6,.65,.7,.75,.8,.85],s=a.map(d=>Math.abs(d-n));return a[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(a=i[e]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let n;return o==="container"?n=.7*i+Math.pow(i,6.5)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)):n=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,a=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,r=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:a,breadthMoulded:s,displacement:Math.round((d/1.025+a*s*n*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",n=2,a=!0,s=!1,d={}){let r;if(t.velocity&&s&&(e.speed=q.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let l;if(d.meteo2)try{const f=await bt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[j]=it.Meteo2Assist.pickHourly(f,o);l=it.Meteo2Assist.toLegacy(j)}catch(f){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},f)}else l=await ot.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const m=R.weatherFactor(e,l),h=R.currentFactor(e.bearing,l==null?void 0:l.current,n),y=Math.round((e.speed*1.943844+m+h)*100)/100;r={meteo:{...l},wxFactor:m,cFactor:h,speed:t.velocity&&s?t.velocity:y<0?1:y,eta:o.utc().format(),etd:o.utc().format()}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round((e.speed*1.943844+0+0)*100)/100,eta:o.utc().format(),etd:o.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(e,t,o,i,n,a,s="",d=!0,r=!1,l={}){t.utc();const m=t.clone().add(14,"days"),h=[],y=[];let f=0,j=0,k,g;for(let b=0;b<a.length-1;b++){let c=a[b];c.distanceFromStart=Math.round((n+j)*1e4)/1e4;const w=a[b+1];if(e.bearing=q.LaneHelper.calculateBearing(c,w,!w.gcToPrevious),c.bearing=e.bearing,c.suspend&&r){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const I=c.suspend-c.elapsed;if(i-f>I)i=i-f-I,t.add(I,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,t.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=j,{etd:t,from:g||c,to:c,next:a.filter(F=>F),wps:h,days:y}}else c.suspend=0;d=t.isAfter(m)?!1:d,c=await R.speedLoseAt(e,c,t,s,0,d,r,l),g=g||c,c.important&&h.push(c),t.isSameOrAfter(o)&&(y.push(c),o.add(24,"hour"));const M=q.LaneHelper.calculateDistance(c,w,!w.gcToPrevious);let u=Math.round(M/g.speed*1e5)/1e5;if(f+u<i){if(f+=u,t.add(u,"hour"),delete a[b],S==null||S.debug(`[%s] go to %j from %j with ${M}nm, and cost ${u} hours`,l.requestId,{lat:w.lat,lng:w.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),j+=M,a.filter(I=>I).length<=1){k=w,k.eta=t.utc().format(),k.distanceFromPrevious=M,k.distanceFromStart=Math.round((n+j)*1e4)/1e4,h.push(k),delete a[b+1];break}}else{u=i-f,t.add(u,"hour");const I=q.LngLatHelper.roundPrecision(g.speed*u,5);k=q.LaneHelper.calculateCoordinate(c,e.bearing,I,"nauticalmiles",!w.gcToPrevious),k.eta=t.utc().format(),a[b]=k,S==null||S.debug(`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,l.requestId,{lat:k.lat,lng:k.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),j+=I,k.distanceFromPrevious=Math.round(j*1e4)/1e4,k.distanceFromStart=Math.round((n+j)*1e4)/1e4;break}}return{etd:t,from:g,to:k,next:a.filter(b=>b),wps:h,days:y}}static currentFactor(e,t,o=0){const i=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return o&2?n=Math.ceil(n*100)/100:o&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t){var m,h,y,f,j,k,g;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=R.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=R.froudeNumber(e.speed,e.lbp),n=R.amendFactor(o,i,e.loadCondition);let a=Math.abs(e.bearing%360-(((m=t==null?void 0:t.wind)==null?void 0:m.degree)%360||0));a=a>180?360-a:a;const s=R.directionFactor(a,(h=t==null?void 0:t.wind)==null?void 0:h.scale),d=R.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(y=t==null?void 0:t.wind)==null?void 0:y.scale);let r=s*n*d/100*e.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),a=Math.abs(e.bearing%360-(((j=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:j.degree)%360||0));const l=R.waveHeightFactor(((g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.height)??1,a);return S==null||S.debug("wave wx factor = %d",l),r=r*.4+l,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(e,t,o,i,n,a="",s=0,d=!0,r=!1,l={}){var Q,X,Z,$,tt;const m=v().valueOf();e.lng=q.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:y}=n.points,f=q.LaneHelper.calculateSubRoute(e,h);if(((Q=f[0])==null?void 0:Q.length)<=1)return;const{v0:j,label:k}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},g=R.assembleProperties(o,i.loadCondition,j,0),b=y.length?q.LaneHelper.calculateSubWaypoints(e,y):[];b.forEach(W=>W.important=!0);const c={from:{...e},route:f,waypoints:b,v0:j,label:k},w={hours:[],days:[],wps:[]};s||(q.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let M=q.LaneHelper.simplifyRouteToCoordinates(f,b,0),u=0,I=0,F=0,N=0;t=v(t).utc();const P=t.clone();for(;M.length>0;){const W=s-t.hour()%s,_=Math.ceil(t.clone().add(W,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,x=await R.speedLoseInHoursStep(g,t,P,_,u,M,a,d,r,l);(X=x.from)!=null&&X.speed&&(w.hours.push(x.from),w.wps.push(...x.wps),w.days.push(...x.days)),M=x==null?void 0:x.next,M.length||w.hours.push(x==null?void 0:x.to),u+=Math.round((((Z=x==null?void 0:x.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const H=w.hours;for(let W=0;W<H.length-1;W++){const _=v(H[W+1].eta).diff(H[W].etd,"hour",!0)||1;I+=(H[W].wxFactor||0)*_,F+=(H[W].cFactor||0)*_,N+=_}($=w.wps)==null||$.forEach((W,_)=>{if(W.positionTime=v.utc(W.etd||W.eta).unix(),_){const x=w.wps[_-1],J=W.distanceFromStart-x.distanceFromStart,O=v(W.eta).diff(v(x.etd),"h",!0);O<.5?W.avgSpd=x.speed:W.avgSpd=Math.round(J/O*100)/100}}),c.sample=w;const T=w.hours.at(0),E=w.hours.at(-1);c.distance=Math.round(E.distanceFromStart*1e4)/1e4,c.etd=v(T.eta).utc().format(),c.eta=v(E.eta).utc().format(),c.wxFactor=Math.round(I/N*1e4)/1e4,c.cFactor=Math.round(F/N*1e4)/1e4,c.avgSpeed=Math.round(E.distanceFromStart/N*1e4)/1e4,c.totalHrs=Math.round(N*1e4)/1e4;const{distanceInECA:C,hoursInECA:A,totalDgoConsInECA:V,eca:K}=await this.calculateECA(c,i,l),st=q.LngLatHelper.roundPrecision(i.fo/24*(N-A),3),at=q.LngLatHelper.roundPrecision(i.dgo/24*N,3);c.extend={eca:K,distanceInECA:C,hoursInECA:A,totalDgoConsInECA:V},c.totalFoCons=st,c.totalDgoCons=at;const et=v().valueOf()-m,nt=((tt=w==null?void 0:w.hours)==null?void 0:tt.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,et,nt,Math.round(et/nt*1e3)/1e3),c}static async analyseInstantWithThreshed(e,t,o,i,n,a,s,d="",r=3,l=!0,m=!1,h={}){var Z,$,tt,W,_;const y=v().valueOf();e.lng=q.LngLatHelper.convertToStdLng(e.lng);const{v0:f,label:j}=e.sog?{v0:e.sog,label:"Other"}:{v0:n.speed,label:"CP"},k=R.assembleProperties(i,n.loadCondition,f,0),g=q.LaneHelper.calculateSubRoute(e,a);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const b=s.length?q.LaneHelper.calculateSubWaypoints(e,s):[];b.forEach(x=>x.important=!0);let c=q.LaneHelper.simplifyRouteToCoordinates(g,b,0),w=0,M=0,u=0,I=0;const F={hours:[],wps:[],days:[]};t=v(t).utc();const N=t.clone();for(;c.length>0;){const x=r-t.hour()%r;let J=Math.ceil(t.clone().add(x,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;J=t.clone().add(J,"h").isSameOrAfter(o)?o.diff(t,"h",!0)*1e4/1e4:J;const O=await R.speedLoseInHoursStep(k,t,N,J,w,c,d,l,m,h);if(($=O.from)!=null&&$.speed&&(F.hours.push(O.from),O!=null&&O.wps&&F.wps.push(...O.wps),F.days.push(...O.days)),c=O==null?void 0:O.next,c.length||F.hours.push(O==null?void 0:O.to),w+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!J)break}(W=F.wps)==null||W.forEach((x,J)=>{if(J){const O=F.wps[J-1],gt=x.distanceFromStart-O.distanceFromStart,ft=v(x.eta).diff(v(O.etd),"h",!0);ft<.5?x.avgSpd=O.speed:x.avgSpd=Math.round(gt/ft*100)/100}});const P=F.hours;for(let x=0;x<P.length-1;x++){const J=v(P[x+1].eta).diff(P[x].etd,"hour",!0);M+=P[x].wxFactor*J,u+=P[x].cFactor*J,I+=J}const H=F.hours.at(0),T=F.hours.at(-1),E=await q.LaneHelper.calculateRangeRoute(H,T,g),C=await q.LaneHelper.calculateRangeWaypoints(H,T,g,b),A={sample:F,distance:Math.round(((T==null?void 0:T.distanceFromStart)||0)*1e4)/1e4,etd:v(H.eta).utc().format(),eta:v(T==null?void 0:T.eta).utc().format(),wxFactor:Math.round(M/I*1e4)/1e4,cFactor:Math.round(u/I*1e4)/1e4,avgSpeed:Math.round(((T==null?void 0:T.distanceFromStart)||0)/I*1e4)/1e4,totalHrs:Math.round(I*1e4)/1e4,from:H,to:T,route:E,waypoints:C,v0:f,label:j},{distanceInECA:V,hoursInECA:K,totalDgoConsInECA:st,eca:at}=await this.calculateECA(A,n,h),ht=q.LngLatHelper.roundPrecision(n.fo/24*(I-K),3),et=q.LngLatHelper.roundPrecision(n.dgo/24*I,3);A.extend={eca:at,distanceInECA:V,hoursInECA:K,totalDgoConsInECA:st},A.totalDgoCons=et,A.totalFoCons=ht;const Q=v().valueOf()-y,X=((_=F==null?void 0:F.hours)==null?void 0:_.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,Q,X,Math.round(Q/X*1e3)/1e3),A}static async analyseCost(e,t,o,i,n={}){var g,b;const a=v().valueOf(),s=[];n.meteo2=n.meteo2||!0,e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const d=q.LaneHelper.calculateRouteDistance(i.route);let r=0;o.forEach(c=>{const w=Math.ceil(d/c.speed/24);r=r<w?w:r}),r=r*1.3;const l=v.utc(e.etd).add(r??14,"day");let m=1;for(const c of o){const w=JSON.parse(JSON.stringify(i.route)),M=JSON.parse(JSON.stringify(i.waypoints)),u=await R.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,l,t,c,w,M,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);u&&(await R.calculateCost(u,c,e,n),s.push(u),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,m,e.etd,l.format(),{cost:u.cost.total,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),m++}s.sort((c,w)=>c.cost.total-w.cost.total);const h=s.at(0),y=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(g=h.cost)==null?void 0:g.total}),y){const c=h.cost.cp,w=y.cost.cp,M=v(h.eta),u=v(h.etd),I=M.diff(u,"days",!0);let F=Math.ceil(I/2);F=F>7?7:F<e.alterStep?e.alterStep:F;let N=2,P={combined:!1,speeds:[y],cost:(b=y.cost)==null?void 0:b.total},H;for(;F>=e.alterStep;){const T=await R.combinedAnalyse(e,t,l,[c,w],i,F,{...n,level:N});if(P.cost>T.cost?H?(H==null?void 0:H.cost)>T.cost&&(H=T):(H=P,P=T):(!H||(H==null?void 0:H.cost)>T.cost)&&(H=T),F<=e.alterStep)break;F=Math.ceil(F/2),N+=1}f.push(P),H&&f.push(H)}const k=v().valueOf()-a;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),f.sort((c,w)=>c.cost-w.cost)}static async combinedAnalyse(e,t,o,i,n,a,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,a);const d=await R.alternateAnalyse(e,t,o,i,0,n,a,s),r=d.reduce((h,y)=>h+y.cost.total,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %d",s.requestId,s.level,r);const l=await R.alternateAnalyse(e,t,o,i,1,n,a,s),m=l.reduce((h,y)=>h+y.cost.total,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %d",s.requestId,s.level,m),r<m?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:a}:{combined:!0,cost:Math.round(m*1e3)/1e3,speeds:l,step:a}}static async alternateAnalyse(e,t,o,i,n,a,s,d={}){var h,y;let r=v.utc(e.etd);const l={lat:e.lat,lng:e.lng},m=[];for(;r.isBefore(o);){const f=r.clone().utc().add(s,"day"),j=JSON.parse(JSON.stringify(a.route)),k=JSON.parse(JSON.stringify(a.waypoints)),g=i[n],b=await R.analyseInstantWithThreshed(l,r.utc().format(),f,t,g,j,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,d);b&&(await R.calculateCost(b,g,e,d),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,r.utc().format(),f.utc().format(),{cost:b.cost.total,distance:b.distance,hours:b.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),d.counter=d.counter+1;const c=(y=(h=b==null?void 0:b.sample)==null?void 0:h.hours)==null?void 0:y.at(-1);if(c)l.lat=c.lat,l.lng=c.lng,r=v(c.eta),m.push(b),n=n?0:1;else break}return m}static async calculateCost(e,t,o,i={}){var n;if(e){const a=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,s=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,d=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((a+s+d)*1e3)/1e3,hire:a,bunker:Math.round((s+d)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,o={}){var d,r;const i=await q.LaneHelper.intersectInECA(e.route);let n=0,a=0,s=0;e.sample.wps.forEach(l=>{l.positionTime=v.utc(l.etd||l.eta).unix()});for(const l of i){n+=l.distance;const m=await q.LaneHelper.deadReckoningTime((d=l.waypoints)==null?void 0:d.at(0),e.sample.wps),h=await q.LaneHelper.deadReckoningTime((r=l.waypoints)==null?void 0:r.at(-1),e.sample.wps);l.in=m,l.out=h,l.totalHrs=q.LngLatHelper.roundPrecision((h.positionTime-m.positionTime)/3600,2),l.totalDgoCons=q.LngLatHelper.roundPrecision(t.fo/24*l.totalHrs,3),a+=l.totalHrs,s+=l.totalDgoCons}return n=q.LngLatHelper.roundPrecision(n,3),a=q.LngLatHelper.roundPrecision(a,3),s=q.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:a,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(e,t={}){var c,w;const o={hours:[],wps:[],days:[]},i=e.reduce((M,u)=>M+u.distance,0),n=e.reduce((M,u)=>{var I;return M+(((I=u.extend)==null?void 0:I.distanceInECA)||0)},0),a=e.reduce((M,u)=>M+u.totalHrs,0),s=e.reduce((M,u)=>{var I;return M+(((I=u.extend)==null?void 0:I.hoursInECA)||0)},0),d=e.reduce((M,u)=>{var I;return M+(((I=u.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),r=e.reduce((M,u)=>M+u.wxFactor*u.totalHrs/a,0),l=e.reduce((M,u)=>M+u.cFactor*u.totalHrs/a,0),m=e.reduce((M,u)=>M+u.totalFoCons,0),h=e.reduce((M,u)=>M+u.totalDgoCons,0),y=e.reduce((M,u)=>M+u.cost.total,0),f=e.reduce((M,u)=>M+u.cost.hire,0),j=e.reduce((M,u)=>M+u.cost.bunker,0),k=[],g=[];let b;for(const M of e){g.push(...((c=M.extend)==null?void 0:c.eca)||[]);const u=M.sample.hours,I=M.sample.wps,F=M.sample.days,N=u.at(0);b&&(N.distanceFromPrevious=b.distanceFromPrevious,N.distanceFromStart=b.distanceFromStart,u.forEach((E,C)=>{C&&(E.distanceFromStart=E.distanceFromStart+b.distanceFromStart)}),I.at(0).distanceFromPrevious=b.distanceFromPrevious,I.at(0).distanceFromStart=b.distanceFromStart,I.forEach((E,C)=>{C&&(E.distanceFromStart=E.distanceFromStart+b.distanceFromStart)}),F.at(0).distanceFromPrevious=b.distanceFromPrevious,F.at(0).distanceFromStart=b.distanceFromStart,F.forEach((E,C)=>{C&&(E.distanceFromStart=E.distanceFromStart+b.distanceFromStart)})),N.cp=M.cost.cp;const P=[M.etd,M.eta],H=k.findIndex(E=>E.id===N.cp.id);H===-1?(N.cp.segment=[P],k.push(N.cp)):k[H].segment.push(P),u.forEach(E=>{var A;((A=o.hours)==null?void 0:A.findIndex(V=>V.eta===E.eta))===-1&&o.hours.push(E)}),I.forEach(E=>{var A;((A=o.wps)==null?void 0:A.findIndex(V=>V.eta===E.eta))===-1&&o.wps.push(E)}),F.forEach(E=>{var A;((A=o==null?void 0:o.days)==null?void 0:A.findIndex(V=>V.eta===E.eta))===-1&&o.days.push(E)});const T=(w=o.wps)==null?void 0:w.findIndex(E=>E.eta===N.eta);T===-1?o.wps.push(N):o.wps[T]=N,b=u.at(-1)}return o.wps.sort((M,u)=>{v(M.etd).unix()-v(u.etd).unix()}),o.wps.forEach((M,u)=>{if(!M.avgSpd){let I;if(u===0?I=o.wps.at(1):I=o.wps.at(u+1),I){const F=I.distanceFromStart-(M.distanceFromStart||0),N=v(I.etd||I.eta).diff(v(M.etd||I.eta),"hour",!0),P=Math.round(F/N*100)/100;M.avgSpd=P}}}),{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(i/a*1e3)/1e3,wxFactor:Math.round(r/a*1e3)/1e3,cFactor:Math.round(l/a*1e3)/1e3,totalFoCons:Math.round(m*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(y*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e4)/1e4,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:e}}}}D.AISImpl=U,D.AlertHelper=ct,D.AlertLevel=rt,D.HifleetImpl=yt,D.LoadCondition=ut,D.MyShipImpl=pt,D.MyVesselImpl=mt,D.ShipxyImpl=Mt,D.SpeedHelper=R,D.SpeedLabel=lt,D.VesselTag=dt,D.alertHelper=vt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
@@ -356,6 +356,7 @@ export declare class SpeedHelper {
356
356
  distanceInECA: number;
357
357
  hoursInECA: number;
358
358
  totalDgoConsInECA: number;
359
+ speeds: any[];
359
360
  };
360
361
  }>;
361
362
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "1.7.2",
4
+ "version": "1.7.4",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [