@idm-plugin/vessel 3.5.1 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -240,13 +240,9 @@ class jt extends at {
240
240
  var k, b, S;
241
241
  const r = w();
242
242
  await this.checkToken(s);
243
- const l = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", u = {
244
- endPoint: {
245
- lon: a.lng,
246
- lat: a.lat
247
- },
243
+ const l = "https://market.myvessel.cn/sdc/v1/mkt/routes/plan", u = {
248
244
  maxDraught: s.draught || 10,
249
- useAIModel: s.useAIModel || !1,
245
+ useAIModel: s.useAIModel ?? !0,
250
246
  withECA: s.withECA || !1,
251
247
  withSpecialRegion: s.withSpecial || !1
252
248
  };
@@ -1 +1 @@
1
- (function(D,x){typeof exports=="object"&&typeof module<"u"?x(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"],x):(D=typeof globalThis<"u"?globalThis:D||self,x(D["idm-plugin-vessel"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,x,U,v,F,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(D,x,U)=>x in D?Ct(D,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):D[x]=U;var _=(D,x,U)=>(St(D,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,a,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 checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const d=r.data;if(d)return{mmsi:d.mmsi,imo:Number.isNaN(d.imo)?null:Number(d.imo),callSign:d.callsign,name:d.nameEn,nameCn:d.nameCn,type:d.vesselTypeNameEn,flagName:d.flagCtry,clasz:d.classSociety,dateOfBuild:d.buildYearMonth,deadweight:d.dwt,grossTonnage:d.grt,netTonnage:d.net,teu:d.teu,length:d.length,breadth:d.width,height:d.height,draught:d.draught,speed:d.speed,passengerCapacity:d.passengercapacity,vendor:"myvessel",raw:d}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,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:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,T;const r=v();await this.checkToken(s);const l="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",u={endPoint:{lon:a.lng,lat:a.lat},maxDraught:s.draught||10,useAIModel:s.useAIModel||!1,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const d={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,d);const y=await x.post(l,d).json();if(y.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:y.message,status:y.status,code:y.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:w,tracks:f,specialRegions:c,ecaLength:h}=y.data;k.nodes=g==null?void 0:g.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=w==null?void 0:w.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),c==null||c.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=f==null?void 0:f.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(T=k.waypoints)!=null&&T.length&&(k.waypoints=F.LaneHelper.simplifyCoordinates(k.waypoints),k.route=F.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=F.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=h);const C=v().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,d,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,d,s),d}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,T,k,g,w;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const d=await x.post(l,u).json();if(d.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const I=v(`${(g=(k=d.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(w=d.data)==null||w.forEach(f=>{for(const q in f)!isNaN(f[q])&&Number(f[q])!==1/0&&(f[q]=Number(f[q]));const c=v(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=f.status,{labelCn:m,labelEn:C}=this.parseStatus(h),p={mmsi:f.mmsi,imo:n==null?void 0:n.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:h,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?v(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:c.unix(),labelCn:m,labelEn:C,method:"trajectory",vendor:"myVessel",utc:c.utc().format()},L=Math.floor(c.diff(I,"minute",!0)/(i||1));L!==y&&(y=L,s.push(p))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),d=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,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="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 i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="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"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var f,c,h;const r=await this.realTimePosition(t,s);let l=v(a);const u=v(o),d=v();if(i){let m=u.diff(l,"d",!0);m<0?l=u.clone().subtract(40,"d"):m<30?l.subtract(10,"d"):m<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),m=d.diff(u,"d",!0),u.add(m>10?240:m*24,"h")}const y={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,y).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,y);let T;b&&(T=((c=(f=b.ships)==null?void 0:f.offors)==null?void 0:c.ship)||[],T.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let g=-1;const w=v(`${(h=T==null?void 0:T[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const m of T){for(const R in m)!isNaN(m[R])&&Number(m[R])!==1/0&&(m[R]=Number(m[R]));const C=v(`${m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");m.status=m.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(m.status),q={mmsi:m.m,name:m.n,imo:r==null?void 0:r.imo,lat:m.la,lng:m.lo,draught:m.draught,sog:m.sp,cog:m.co,hdg:m.hdg,positionTime:C.unix(),utc:C.utc().format(),status:m.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(w,"minute",!0)/(n||1));N!==g&&(g=N,k.push(q))}return k}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=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:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var w;const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(d,y).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,d,y),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,T=[],k=v.unix((w=b[0])==null?void 0:w.utc);let g=-1;for(const f of b){const c=v.unix(f.utc),h={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"shipxy"},m=Math.floor(c.diff(k,"minute",!0)/(n||1));m!==g&&(g=m,T.push(h))}return T}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:d}=await this.parseStatus(l.aisNavStatus),y=v.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:y.utc().format(),status:l.aisNavStatus,labelEn:d,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=v(a),l=v(o),u=await this.getShipId(t),d=await this.getShipInfo(u),y=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},d="https://api3.myships.com/sp/ships/position/history",y=await x.post(d,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,u),y.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,y),y;const I=y.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const b=v.unix((k=I[0])==null?void 0:k.posTime);let T=-1;for(const g of I){const w=v.unix(g.posTime),f={imo:n==null?void 0:n.imo,mmsi:i,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:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"myship"},c=Math.floor(w.diff(b,"minute",!0)/(s||1));c!==T&&(T=c,r.push(f))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const d=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!d)i.scope=n[0];else if(d)for(let y=0,I=d.length;y<I;y++){const b=this.parseRule(d[y]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,T,k,g,w,f,c,h,m,C,p,L,q,N,R;let o=0,n=0,i=0,s=0;const r=Math.round(((T=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:T.number)*1.6*100)/100,l=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,u=(f=(w=t==null?void 0:t.HEAVY)==null?void 0:w.sigWave)==null?void 0:f.number,d=Math.round((((h=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:h.number)+2)*100)/100,y=(C=(m=t==null?void 0:t.SEVERE)==null?void 0:m.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(q=H==null?void 0:H.meteo)==null?void 0:q.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?v(H.eta).diff(v(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=u&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I}),(B==null?void 0:B.scale)>=d?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>y?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===I&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const vt=new lt;let S;try{S=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ht||{}),ft=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(ft||{}),mt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.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 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.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var y;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((y=e==null?void 0:e.type)==null?void 0:y.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=F.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:b,marineModels:T}=await ot.Meteo2Assist.autoPickMeteoModel(o),k=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:b,marineModels:T}),[g]=ot.Meteo2Assist.pickHourly(k,a);u=ot.Meteo2Assist.toLegacy(g)}catch(b){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},b)}const d=O.currentFactor(e.bearing,u==null?void 0:u.current,n),y=O.weatherFactor(e,u,d),I=Math.round((e.speed*1.943844+y+d)*100)/100;l={meteo:{...u},wxFactor:y,cFactor:d,speed:t.velocity&&s?t.velocity:I<0?1:I,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const d=t.clone().add(14,"days"),y=[],I=[],b=[];let T=0,k=0,g,w;for(let f=0;f<i.length-1;f++){let c=i[f];c.distanceFromStart=Math.round((n+k)*1e3)/1e3;const h=i[f+1];if(e.bearing=F.LaneHelper.calculateBearing(c,h,!h.gcToPrevious),c.bearing=e.bearing,c.suspend&&l){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const p=c.suspend-c.elapsed;if(o-T>p)o=o-T-p,t.add(p,"hour"),c.elapsed=c.suspend;else{const L=o-T;c.elapsed+=L,t.add(L,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,c),o===0)return c.distanceFromPrevious=k,{etd:t,from:w||c,to:c,next:i.filter(L=>L),wps:y,days:I,all:b}}else c.suspend=0;r=t.isAfter(d)?!1:r,c=await O.speedLoseAt(e,c,t,s,0,r,l,u),b.push(c),w=w||c,c.important&&y.push(c),t.isSameOrAfter(a)&&(I.push(c),a.add(24,"hour"));const m=F.LaneHelper.calculateDistance(c,h,!h.gcToPrevious);let C=Math.round(m/w.speed*1e5)/1e5;if(T+C<o){if(T+=C,t.add(C,"hour"),delete i[f],S==null||S.debug(`[%s] go to %j from %j with ${m}nm, and cost ${C} hours`,u.requestId,{lat:h.lat,lng:h.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),k+=m,i.filter(p=>p).length<=1){g=h,g.eta=t.utc().format(),g.distanceFromPrevious=m,g.distanceFromStart=Math.round((n+k)*1e4)/1e4,y.push(g),b.push(g),delete i[f+1];break}}else{C=o-T,t.add(C,"hour");const p=F.LngLatHelper.roundPrecision(w.speed*C,5);g=F.LaneHelper.calculateCoordinate(c,e.bearing,p,"nauticalmiles",!h.gcToPrevious),g.eta=t.utc().format(),i[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),k+=p,g.distanceFromPrevious=Math.round(k*1e4)/1e4,g.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:w,to:g,next:i.filter(f=>f),wps:y,days:I,all:b}}static currentFactor(e,t,a=0){const o=F.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var I,b,T,k,g,w,f;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=F.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=F.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(T=t==null?void 0:t.wind)==null?void 0:T.kts);let d=l*s*u/100*(e.speed-n);d=Math.round(d*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(d)>1&&(d=d/(Math.abs(Math.round(d))+1)),S==null||S.debug("wind wx factor = %d",d),r=F.LaneHelper.includedAngle(e.bearing,(g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.degree);const y=O.waveHeightFactor(((f=(w=t==null?void 0:t.wave)==null?void 0:w.sig)==null?void 0:f.height)??1,r);return S==null||S.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.7,S==null||S.debug("weather factor = %d",d),d=Math.abs(d)>3?3*(Math.abs(d)/d)+Math.abs(d)/d*(Math.abs(d)-2)*.1:d,Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=v.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(v(n.etd).unix()/t)===Math.floor(v(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const d=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:I}=n.points,b=F.LaneHelper.calculateSubRoute(e,y);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:T,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(a,o.loadCondition,T,0),w=I.length?F.LaneHelper.calculateSubWaypoints(e,I):[];w.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:w,v0:T,label:k},c={hours:[],days:[],wps:[],all:[]};s||(F.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let h=F.LaneHelper.simplifyRouteToCoordinates(b,w,0),m=0,C=0,p=0,L=0;t=v(t).utc();const q=t.clone();for(;h.length>0;){const P=s-t.hour()%s,z=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,q,z,m,h,i,r,l,u);if(c.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(c.hours.push(j.from),c.wps.push(...j.wps),c.days.push(...j.days)),h=j==null?void 0:j.next,!h.length){const W=await O.speedLoseAt(g,j.to,v(j.to.eta),i,0,r,l,u);W.bearing=g.bearing,c.hours.push(W),c.all.push(W)}m+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=c.hours;for(let P=0;P<N.length-1;P++){const z=v(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;C+=(N[P].wxFactor||0)*z,p+=(N[P].cFactor||0)*z,L+=z}const R=N.reduce((P,z)=>P+(z.suspend||0),0);($=c.wps)==null||$.forEach((P,z)=>{P.positionTime=v.utc(P.etd||P.eta).unix();const j=c.wps[z-1];if(j){const W=P.distanceFromStart-j.distanceFromStart,Y=v(P.eta||P.etd).diff(v(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(W/Y*100)/100,j.bearing=F.LaneHelper.calculateBearing(j,P)}}),c.wps=await O.reduceWPS(c.wps),c.days=await O.reduceDays(c.days),c.all=(tt=c.all)==null?void 0:tt.reduce((P,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(z.positionTime/60))||P.push(z),P),[]),f.sample=c;const E=c.hours.at(0),H=c.hours.at(-1);f.distance=Math.round(H.distanceFromStart*1e3)/1e3,f.etd=v(E.eta).utc().format(),f.eta=v(H.eta).utc().format(),f.wxFactor=Math.round(C/L*1e3)/1e3,f.cFactor=Math.round(p/L*1e3)/1e3,f.avgSpeed=Math.round(H.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(R*1e3)/1e3;const V=F.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(f,o,u),at=F.LngLatHelper.roundPrecision(o.fo/24*(L-K),3),rt=F.LngLatHelper.roundPrecision(o.dgo/24*L+V,3);f.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},f.totalFoCons=at<0?0:at,f.totalDgoCons=rt;const nt=v().valueOf()-d,dt=((et=c==null?void 0:c.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,d=!1,y={}){var Z,$,tt,et,P,z;const I=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),g=F.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const w=s.length?F.LaneHelper.calculateSubWaypoints(e,s):[];w.forEach(j=>j.important=!0);let f=F.LaneHelper.simplifyRouteToCoordinates(g,w,0),c=0,h=0,m=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const L=t.clone();for(;f.length>0;){const j=l-t.hour()%l;let W=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(k,t,L,W,c,f,r,u,d,y);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||p.hours.push(Y==null?void 0:Y.to),c+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,W)=>(W.positionTime=v.utc(W.etd||W.eta).unix(),j.some(Y=>Math.round(v(Y.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||j.push(W),j),[]),(P=p.wps)==null||P.forEach((j,W)=>{const Y=p.wps[W-1];if(Y){const It=j.distanceFromStart-Y.distanceFromStart,kt=v(j.eta||j.etd).diff(v(Y.etd||Y.eta),"h",!0);Y.bearing=F.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const q=p.hours;for(let j=0;j<q.length-1;j++){const W=v(q[j+1].eta).diff(q[j].etd,"hour",!0);h+=q[j].wxFactor*W,m+=q[j].cFactor*W,C+=W}const N=q.reduce((j,W)=>j+(W.suspend||0),0),R=p.hours.at(0),E=p.hours.at(-1),H=await F.LaneHelper.calculateRangeRoute(R,E,g),V=await F.LaneHelper.calculateRangeWaypoints(R,E,g,w),B={sample:p,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(h/C*1e3)/1e3,cFactor:Math.round(m/C*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:b,label:T},K=F.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=F.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=F.LngLatHelper.roundPrecision(n.dgo/24*C+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=v().valueOf()-I,Q=((z=p==null?void 0:p.hours)==null?void 0:z.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",y==null?void 0:y.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var g,w;const i=v().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=F.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(f=>{const c=Math.ceil(r/f.speed/24);l=l<c?c:l}),l=l*1.3;const u=v.utc(e.etd).add(l??14,"day");let d=1;for(const f of a){const c=JSON.parse(JSON.stringify(o.route)),h=JSON.parse(JSON.stringify(o.waypoints)),m=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,c,h,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);m&&(await O.calculateCost(m,f,e,n),s.push(m),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,u.format(),{cost:m.cost.total,hire:m.cost.hire,bunker:m.cost.bunker,distance:m.distance,hours:m.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),d++}s.sort((f,c)=>f.cost.total-c.cost.total);const y=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[y],cost:(g=y.cost)==null?void 0:g.total}),I){const f=y.cost.cp,c=I.cost.cp,h=v(y.eta),m=v(y.etd),C=h.diff(m,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,q={combined:!1,speeds:[I],cost:(w=I.cost)==null?void 0:w.total},N;for(;p>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[f,c],o,p,{...n,level:L});if(q.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=q,q=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(q),N&&b.push(N)}const k=v().valueOf()-i;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((f,c)=>f.cost-c.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((c,h)=>c+h.cost.total,0),u=r.reduce((c,h)=>c+h.cost.hire,0),d=r.reduce((c,h)=>c+h.cost.bunker,0),y=r.reduce((c,h)=>c+h.distance,0),I=r.reduce((c,h)=>c+h.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:d,distance:y,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),T=b.reduce((c,h)=>c+h.cost.total,0),k=b.reduce((c,h)=>c+h.cost.hire,0),g=b.reduce((c,h)=>c+h.cost.bunker,0),w=b.reduce((c,h)=>c+h.distance,0),f=b.reduce((c,h)=>c+h.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:T,hire:k,bunker:g,distance:w,hours:f}),l<T?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var y,I;let l=v.utc(e.etd);const u={lat:e.lat,lng:e.lng},d=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),T=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],w=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,T,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);w&&(await O.calculateCost(w,g,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:w.cost.total,hire:w.cost.hire,bunker:w.cost.bunker,distance:w.distance,hours:w.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const f=(I=(y=w==null?void 0:w.sample)==null?void 0:y.hours)==null?void 0:I.at(-1);if(f)u.lat=f.lat,u.lng=f.lng,l=v(f.eta),d.push(w),n=n?0:1;else break}return d}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,d;const o=await F.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(y=>{y.positionTime=v.utc(y.etd||y.eta).unix()});for(const y of o){n+=y.distance;const I=await F.LaneHelper.deadReckoningTime((u=y.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await F.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),e.sample.all||e.sample.wps);y.in=I,y.out=b,y.totalHrs=F.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),y.totalDgoCons=F.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),i+=y.totalHrs,s+=y.totalDgoCons}return n=F.LngLatHelper.roundPrecision(n,3),i=F.LngLatHelper.roundPrecision(i,3),s=F.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var f,c;const a={hours:[],wps:[],days:[]},o=e.reduce((h,m)=>h+m.distance,0),n=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((h,m)=>h+m.totalHrs,0),s=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((h,m)=>h+m.wxFactor*m.totalHrs/i,0),u=e.reduce((h,m)=>h+m.cFactor*m.totalHrs/i,0),d=e.reduce((h,m)=>h+m.totalFoCons,0),y=e.reduce((h,m)=>h+m.totalDgoCons,0),I=e.reduce((h,m)=>h+m.cost.total,0),b=e.reduce((h,m)=>h+m.cost.hire,0),T=e.reduce((h,m)=>h+m.cost.bunker,0),k=[],g=[];let w;for(const h of e){g.push(...((f=h.extend)==null?void 0:f.eca)||[]);const m=h.sample.hours,C=h.sample.wps,p=h.sample.days,L=m.at(0);w&&(L.distanceFromPrevious=w.distanceFromPrevious,L.distanceFromStart=w.distanceFromStart,m.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),C.at(0).distanceFromPrevious=w.distanceFromPrevious,C.at(0).distanceFromStart=w.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),p.at(0).distanceFromPrevious=w.distanceFromPrevious,p.at(0).distanceFromStart=w.distanceFromStart,p.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)})),L.cp=h.cost.cp;const q=[h.etd,h.eta],N=k.findIndex(E=>E.id===L.cp.id);N===-1?(L.cp.segment=[q],k.push(L.cp)):k[N].segment.push(q),m.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),C.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),p.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(c=a.wps)==null?void 0:c.findIndex(E=>E.eta===L.eta);R===-1?a.wps.push(L):a.wps[R]=L,w=m.at(-1)}return a.wps.sort((h,m)=>v(h.etd).unix()-v(m.etd).unix()),a.wps.forEach((h,m)=>{const C=a.wps[m-1];if(C){const p=h.distanceFromStart-(C.distanceFromStart||0),L=v(h.eta||h.etd).diff(v(C.etd||C.eta),"hour",!0),q=Math.round(p/L*100)/100;h.avgSpd=q;const N=F.LaneHelper.calculateBearing(C,h);C.bearing=N}}),{sample:a,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(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(T*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}D.AISImpl=G,D.AlertHelper=lt,D.AlertLevel=ut,D.HifleetImpl=Mt,D.LoadCondition=ft,D.MyShipImpl=gt,D.MyVesselImpl=pt,D.ShipxyImpl=bt,D.SpeedHelper=O,D.SpeedLabel=mt,D.VesselTag=ht,D.alertHelper=vt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
1
+ (function(D,x){typeof exports=="object"&&typeof module<"u"?x(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"],x):(D=typeof globalThis<"u"?globalThis:D||self,x(D["idm-plugin-vessel"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,x,U,v,F,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(D,x,U)=>x in D?Ct(D,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):D[x]=U;var _=(D,x,U)=>(St(D,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,a,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 checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const d=r.data;if(d)return{mmsi:d.mmsi,imo:Number.isNaN(d.imo)?null:Number(d.imo),callSign:d.callsign,name:d.nameEn,nameCn:d.nameCn,type:d.vesselTypeNameEn,flagName:d.flagCtry,clasz:d.classSociety,dateOfBuild:d.buildYearMonth,deadweight:d.dwt,grossTonnage:d.grt,netTonnage:d.net,teu:d.teu,length:d.length,breadth:d.width,height:d.height,draught:d.draught,speed:d.speed,passengerCapacity:d.passengercapacity,vendor:"myvessel",raw:d}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,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:u.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,T;const r=v();await this.checkToken(s);const l="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",u={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const d={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,d);const y=await x.post(l,d).json();if(y.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:y.message,status:y.status,code:y.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:w,tracks:f,specialRegions:c,ecaLength:h}=y.data;k.nodes=g==null?void 0:g.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=w==null?void 0:w.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),c==null||c.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=f==null?void 0:f.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(T=k.waypoints)!=null&&T.length&&(k.waypoints=F.LaneHelper.simplifyCoordinates(k.waypoints),k.route=F.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=F.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=h);const C=v().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,d,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,d,s),d}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,T,k,g,w;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const d=await x.post(l,u).json();if(d.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const I=v(`${(g=(k=d.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(w=d.data)==null||w.forEach(f=>{for(const q in f)!isNaN(f[q])&&Number(f[q])!==1/0&&(f[q]=Number(f[q]));const c=v(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=f.status,{labelCn:m,labelEn:C}=this.parseStatus(h),p={mmsi:f.mmsi,imo:n==null?void 0:n.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:h,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?v(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:c.unix(),labelCn:m,labelEn:C,method:"trajectory",vendor:"myVessel",utc:c.utc().format()},L=Math.floor(c.diff(I,"minute",!0)/(i||1));L!==y&&(y=L,s.push(p))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:u}=this.parseStatus(r),d=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,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="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 i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="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"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var f,c,h;const r=await this.realTimePosition(t,s);let l=v(a);const u=v(o),d=v();if(i){let m=u.diff(l,"d",!0);m<0?l=u.clone().subtract(40,"d"):m<30?l.subtract(10,"d"):m<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),m=d.diff(u,"d",!0),u.add(m>10?240:m*24,"h")}const y={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,y).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,y);let T;b&&(T=((c=(f=b.ships)==null?void 0:f.offors)==null?void 0:c.ship)||[],T.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let g=-1;const w=v(`${(h=T==null?void 0:T[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const m of T){for(const R in m)!isNaN(m[R])&&Number(m[R])!==1/0&&(m[R]=Number(m[R]));const C=v(`${m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");m.status=m.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(m.status),q={mmsi:m.m,name:m.n,imo:r==null?void 0:r.imo,lat:m.la,lng:m.lo,draught:m.draught,sog:m.sp,cog:m.co,hdg:m.hdg,positionTime:C.unix(),utc:C.utc().format(),status:m.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(w,"minute",!0)/(n||1));N!==g&&(g=N,k.push(q))}return k}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=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:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var w;const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(d,y).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,d,y),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,T=[],k=v.unix((w=b[0])==null?void 0:w.utc);let g=-1;for(const f of b){const c=v.unix(f.utc),h={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"shipxy"},m=Math.floor(c.diff(k,"minute",!0)/(n||1));m!==g&&(g=m,T.push(h))}return T}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:d}=await this.parseStatus(l.aisNavStatus),y=v.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:y.utc().format(),status:l.aisNavStatus,labelEn:d,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=v(a),l=v(o),u=await this.getShipId(t),d=await this.getShipInfo(u),y=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},d="https://api3.myships.com/sp/ships/position/history",y=await x.post(d,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,u),y.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,y),y;const I=y.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const b=v.unix((k=I[0])==null?void 0:k.posTime);let T=-1;for(const g of I){const w=v.unix(g.posTime),f={imo:n==null?void 0:n.imo,mmsi:i,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:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"myship"},c=Math.floor(w.diff(b,"minute",!0)/(s||1));c!==T&&(T=c,r.push(f))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const d=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!d)i.scope=n[0];else if(d)for(let y=0,I=d.length;y<I;y++){const b=this.parseRule(d[y]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,T,k,g,w,f,c,h,m,C,p,L,q,N,R;let o=0,n=0,i=0,s=0;const r=Math.round(((T=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:T.number)*1.6*100)/100,l=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,u=(f=(w=t==null?void 0:t.HEAVY)==null?void 0:w.sigWave)==null?void 0:f.number,d=Math.round((((h=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:h.number)+2)*100)/100,y=(C=(m=t==null?void 0:t.SEVERE)==null?void 0:m.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(q=H==null?void 0:H.meteo)==null?void 0:q.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?v(H.eta).diff(v(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=u&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I}),(B==null?void 0:B.scale)>=d?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>y?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===I&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const vt=new lt;let S;try{S=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ht||{}),ft=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(ft||{}),mt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.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 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.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var y;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((y=e==null?void 0:e.type)==null?void 0:y.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=F.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:b,marineModels:T}=await ot.Meteo2Assist.autoPickMeteoModel(o),k=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:b,marineModels:T}),[g]=ot.Meteo2Assist.pickHourly(k,a);u=ot.Meteo2Assist.toLegacy(g)}catch(b){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},b)}const d=O.currentFactor(e.bearing,u==null?void 0:u.current,n),y=O.weatherFactor(e,u,d),I=Math.round((e.speed*1.943844+y+d)*100)/100;l={meteo:{...u},wxFactor:y,cFactor:d,speed:t.velocity&&s?t.velocity:I<0?1:I,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const d=t.clone().add(14,"days"),y=[],I=[],b=[];let T=0,k=0,g,w;for(let f=0;f<i.length-1;f++){let c=i[f];c.distanceFromStart=Math.round((n+k)*1e3)/1e3;const h=i[f+1];if(e.bearing=F.LaneHelper.calculateBearing(c,h,!h.gcToPrevious),c.bearing=e.bearing,c.suspend&&l){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const p=c.suspend-c.elapsed;if(o-T>p)o=o-T-p,t.add(p,"hour"),c.elapsed=c.suspend;else{const L=o-T;c.elapsed+=L,t.add(L,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,c),o===0)return c.distanceFromPrevious=k,{etd:t,from:w||c,to:c,next:i.filter(L=>L),wps:y,days:I,all:b}}else c.suspend=0;r=t.isAfter(d)?!1:r,c=await O.speedLoseAt(e,c,t,s,0,r,l,u),b.push(c),w=w||c,c.important&&y.push(c),t.isSameOrAfter(a)&&(I.push(c),a.add(24,"hour"));const m=F.LaneHelper.calculateDistance(c,h,!h.gcToPrevious);let C=Math.round(m/w.speed*1e5)/1e5;if(T+C<o){if(T+=C,t.add(C,"hour"),delete i[f],S==null||S.debug(`[%s] go to %j from %j with ${m}nm, and cost ${C} hours`,u.requestId,{lat:h.lat,lng:h.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),k+=m,i.filter(p=>p).length<=1){g=h,g.eta=t.utc().format(),g.distanceFromPrevious=m,g.distanceFromStart=Math.round((n+k)*1e4)/1e4,y.push(g),b.push(g),delete i[f+1];break}}else{C=o-T,t.add(C,"hour");const p=F.LngLatHelper.roundPrecision(w.speed*C,5);g=F.LaneHelper.calculateCoordinate(c,e.bearing,p,"nauticalmiles",!h.gcToPrevious),g.eta=t.utc().format(),i[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),k+=p,g.distanceFromPrevious=Math.round(k*1e4)/1e4,g.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:w,to:g,next:i.filter(f=>f),wps:y,days:I,all:b}}static currentFactor(e,t,a=0){const o=F.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var I,b,T,k,g,w,f;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=F.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=F.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(T=t==null?void 0:t.wind)==null?void 0:T.kts);let d=l*s*u/100*(e.speed-n);d=Math.round(d*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(d)>1&&(d=d/(Math.abs(Math.round(d))+1)),S==null||S.debug("wind wx factor = %d",d),r=F.LaneHelper.includedAngle(e.bearing,(g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.degree);const y=O.waveHeightFactor(((f=(w=t==null?void 0:t.wave)==null?void 0:w.sig)==null?void 0:f.height)??1,r);return S==null||S.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.7,S==null||S.debug("weather factor = %d",d),d=Math.abs(d)>3?3*(Math.abs(d)/d)+Math.abs(d)/d*(Math.abs(d)-2)*.1:d,Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=v.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(v(n.etd).unix()/t)===Math.floor(v(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const d=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:I}=n.points,b=F.LaneHelper.calculateSubRoute(e,y);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:T,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(a,o.loadCondition,T,0),w=I.length?F.LaneHelper.calculateSubWaypoints(e,I):[];w.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:w,v0:T,label:k},c={hours:[],days:[],wps:[],all:[]};s||(F.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let h=F.LaneHelper.simplifyRouteToCoordinates(b,w,0),m=0,C=0,p=0,L=0;t=v(t).utc();const q=t.clone();for(;h.length>0;){const P=s-t.hour()%s,z=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,q,z,m,h,i,r,l,u);if(c.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(c.hours.push(j.from),c.wps.push(...j.wps),c.days.push(...j.days)),h=j==null?void 0:j.next,!h.length){const W=await O.speedLoseAt(g,j.to,v(j.to.eta),i,0,r,l,u);W.bearing=g.bearing,c.hours.push(W),c.all.push(W)}m+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=c.hours;for(let P=0;P<N.length-1;P++){const z=v(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;C+=(N[P].wxFactor||0)*z,p+=(N[P].cFactor||0)*z,L+=z}const R=N.reduce((P,z)=>P+(z.suspend||0),0);($=c.wps)==null||$.forEach((P,z)=>{P.positionTime=v.utc(P.etd||P.eta).unix();const j=c.wps[z-1];if(j){const W=P.distanceFromStart-j.distanceFromStart,Y=v(P.eta||P.etd).diff(v(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(W/Y*100)/100,j.bearing=F.LaneHelper.calculateBearing(j,P)}}),c.wps=await O.reduceWPS(c.wps),c.days=await O.reduceDays(c.days),c.all=(tt=c.all)==null?void 0:tt.reduce((P,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(z.positionTime/60))||P.push(z),P),[]),f.sample=c;const E=c.hours.at(0),H=c.hours.at(-1);f.distance=Math.round(H.distanceFromStart*1e3)/1e3,f.etd=v(E.eta).utc().format(),f.eta=v(H.eta).utc().format(),f.wxFactor=Math.round(C/L*1e3)/1e3,f.cFactor=Math.round(p/L*1e3)/1e3,f.avgSpeed=Math.round(H.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(R*1e3)/1e3;const V=F.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(f,o,u),at=F.LngLatHelper.roundPrecision(o.fo/24*(L-K),3),rt=F.LngLatHelper.roundPrecision(o.dgo/24*L+V,3);f.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},f.totalFoCons=at<0?0:at,f.totalDgoCons=rt;const nt=v().valueOf()-d,dt=((et=c==null?void 0:c.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,d=!1,y={}){var Z,$,tt,et,P,z;const I=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),g=F.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const w=s.length?F.LaneHelper.calculateSubWaypoints(e,s):[];w.forEach(j=>j.important=!0);let f=F.LaneHelper.simplifyRouteToCoordinates(g,w,0),c=0,h=0,m=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const L=t.clone();for(;f.length>0;){const j=l-t.hour()%l;let W=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(k,t,L,W,c,f,r,u,d,y);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||p.hours.push(Y==null?void 0:Y.to),c+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,W)=>(W.positionTime=v.utc(W.etd||W.eta).unix(),j.some(Y=>Math.round(v(Y.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||j.push(W),j),[]),(P=p.wps)==null||P.forEach((j,W)=>{const Y=p.wps[W-1];if(Y){const It=j.distanceFromStart-Y.distanceFromStart,kt=v(j.eta||j.etd).diff(v(Y.etd||Y.eta),"h",!0);Y.bearing=F.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const q=p.hours;for(let j=0;j<q.length-1;j++){const W=v(q[j+1].eta).diff(q[j].etd,"hour",!0);h+=q[j].wxFactor*W,m+=q[j].cFactor*W,C+=W}const N=q.reduce((j,W)=>j+(W.suspend||0),0),R=p.hours.at(0),E=p.hours.at(-1),H=await F.LaneHelper.calculateRangeRoute(R,E,g),V=await F.LaneHelper.calculateRangeWaypoints(R,E,g,w),B={sample:p,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(h/C*1e3)/1e3,cFactor:Math.round(m/C*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:b,label:T},K=F.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=F.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=F.LngLatHelper.roundPrecision(n.dgo/24*C+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=v().valueOf()-I,Q=((z=p==null?void 0:p.hours)==null?void 0:z.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",y==null?void 0:y.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var g,w;const i=v().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=F.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(f=>{const c=Math.ceil(r/f.speed/24);l=l<c?c:l}),l=l*1.3;const u=v.utc(e.etd).add(l??14,"day");let d=1;for(const f of a){const c=JSON.parse(JSON.stringify(o.route)),h=JSON.parse(JSON.stringify(o.waypoints)),m=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,c,h,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);m&&(await O.calculateCost(m,f,e,n),s.push(m),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,u.format(),{cost:m.cost.total,hire:m.cost.hire,bunker:m.cost.bunker,distance:m.distance,hours:m.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),d++}s.sort((f,c)=>f.cost.total-c.cost.total);const y=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[y],cost:(g=y.cost)==null?void 0:g.total}),I){const f=y.cost.cp,c=I.cost.cp,h=v(y.eta),m=v(y.etd),C=h.diff(m,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,q={combined:!1,speeds:[I],cost:(w=I.cost)==null?void 0:w.total},N;for(;p>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[f,c],o,p,{...n,level:L});if(q.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=q,q=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(q),N&&b.push(N)}const k=v().valueOf()-i;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((f,c)=>f.cost-c.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((c,h)=>c+h.cost.total,0),u=r.reduce((c,h)=>c+h.cost.hire,0),d=r.reduce((c,h)=>c+h.cost.bunker,0),y=r.reduce((c,h)=>c+h.distance,0),I=r.reduce((c,h)=>c+h.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:d,distance:y,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),T=b.reduce((c,h)=>c+h.cost.total,0),k=b.reduce((c,h)=>c+h.cost.hire,0),g=b.reduce((c,h)=>c+h.cost.bunker,0),w=b.reduce((c,h)=>c+h.distance,0),f=b.reduce((c,h)=>c+h.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:T,hire:k,bunker:g,distance:w,hours:f}),l<T?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var y,I;let l=v.utc(e.etd);const u={lat:e.lat,lng:e.lng},d=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),T=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],w=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,T,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);w&&(await O.calculateCost(w,g,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:w.cost.total,hire:w.cost.hire,bunker:w.cost.bunker,distance:w.distance,hours:w.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const f=(I=(y=w==null?void 0:w.sample)==null?void 0:y.hours)==null?void 0:I.at(-1);if(f)u.lat=f.lat,u.lng=f.lng,l=v(f.eta),d.push(w),n=n?0:1;else break}return d}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,d;const o=await F.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(y=>{y.positionTime=v.utc(y.etd||y.eta).unix()});for(const y of o){n+=y.distance;const I=await F.LaneHelper.deadReckoningTime((u=y.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await F.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),e.sample.all||e.sample.wps);y.in=I,y.out=b,y.totalHrs=F.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),y.totalDgoCons=F.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),i+=y.totalHrs,s+=y.totalDgoCons}return n=F.LngLatHelper.roundPrecision(n,3),i=F.LngLatHelper.roundPrecision(i,3),s=F.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var f,c;const a={hours:[],wps:[],days:[]},o=e.reduce((h,m)=>h+m.distance,0),n=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((h,m)=>h+m.totalHrs,0),s=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((h,m)=>h+m.wxFactor*m.totalHrs/i,0),u=e.reduce((h,m)=>h+m.cFactor*m.totalHrs/i,0),d=e.reduce((h,m)=>h+m.totalFoCons,0),y=e.reduce((h,m)=>h+m.totalDgoCons,0),I=e.reduce((h,m)=>h+m.cost.total,0),b=e.reduce((h,m)=>h+m.cost.hire,0),T=e.reduce((h,m)=>h+m.cost.bunker,0),k=[],g=[];let w;for(const h of e){g.push(...((f=h.extend)==null?void 0:f.eca)||[]);const m=h.sample.hours,C=h.sample.wps,p=h.sample.days,L=m.at(0);w&&(L.distanceFromPrevious=w.distanceFromPrevious,L.distanceFromStart=w.distanceFromStart,m.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),C.at(0).distanceFromPrevious=w.distanceFromPrevious,C.at(0).distanceFromStart=w.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),p.at(0).distanceFromPrevious=w.distanceFromPrevious,p.at(0).distanceFromStart=w.distanceFromStart,p.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)})),L.cp=h.cost.cp;const q=[h.etd,h.eta],N=k.findIndex(E=>E.id===L.cp.id);N===-1?(L.cp.segment=[q],k.push(L.cp)):k[N].segment.push(q),m.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),C.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),p.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(c=a.wps)==null?void 0:c.findIndex(E=>E.eta===L.eta);R===-1?a.wps.push(L):a.wps[R]=L,w=m.at(-1)}return a.wps.sort((h,m)=>v(h.etd).unix()-v(m.etd).unix()),a.wps.forEach((h,m)=>{const C=a.wps[m-1];if(C){const p=h.distanceFromStart-(C.distanceFromStart||0),L=v(h.eta||h.etd).diff(v(C.etd||C.eta),"hour",!0),q=Math.round(p/L*100)/100;h.avgSpd=q;const N=F.LaneHelper.calculateBearing(C,h);C.bearing=N}}),{sample:a,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(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(T*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}D.AISImpl=G,D.AlertHelper=lt,D.AlertLevel=ut,D.HifleetImpl=Mt,D.LoadCondition=ft,D.MyShipImpl=gt,D.MyVesselImpl=pt,D.ShipxyImpl=bt,D.SpeedHelper=O,D.SpeedLabel=mt,D.VesselTag=ht,D.alertHelper=vt,Object.defineProperty(D,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": "3.5.1",
4
+ "version": "3.5.2",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [