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