@idm-plugin/vessel 1.9.5 → 1.9.6

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