@idm-plugin/vessel 1.6.1 → 1.6.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 +87 -87
- package/dist/index.umd.cjs +1 -1
- package/dist/speed/src/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var st = Object.defineProperty;
|
|
2
2
|
var at = (j, e, t) => e in j ? st(j, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : j[e] = t;
|
|
3
3
|
var Z = (j, e, t) => (at(j, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
|
-
import
|
|
4
|
+
import R from "got";
|
|
5
5
|
import Q from "@log4js-node/log4js-api";
|
|
6
6
|
import I from "moment";
|
|
7
7
|
import { LngLatHelper as z, LaneHelper as B } from "@idm-plugin/geo";
|
|
@@ -54,7 +54,7 @@ class U {
|
|
|
54
54
|
return { labelCn: t, labelEn: o };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class gt extends U {
|
|
58
58
|
constructor(t, o) {
|
|
59
59
|
super();
|
|
60
60
|
Z(this, "clientId");
|
|
@@ -69,7 +69,7 @@ class wt extends U {
|
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
}, a = await
|
|
72
|
+
}, a = await R.post(o, i).json();
|
|
73
73
|
b == null || b.info("[%s] fetch access token from: %s - %j", t.requestId, o, a), a.error || (this.token = {
|
|
74
74
|
accessToken: a.access_token,
|
|
75
75
|
tokenType: a.token_type,
|
|
@@ -89,7 +89,7 @@ class wt extends U {
|
|
|
89
89
|
searchParams: { mmsi: t }
|
|
90
90
|
};
|
|
91
91
|
b == null || b.info("[%s] fetch realtime position from: %s - %j", o.requestId, i, a);
|
|
92
|
-
const n = await
|
|
92
|
+
const n = await R.get(i, a).json();
|
|
93
93
|
if (n.code)
|
|
94
94
|
return b == null || b.warn("[%s] fetch realtime position failed: %j", o.requestId, i, { message: n.message, status: n.status, code: n.code }), n;
|
|
95
95
|
const s = n.data;
|
|
@@ -129,7 +129,7 @@ class wt extends U {
|
|
|
129
129
|
return await this.trajectoryIn30Day(t, r, l, d, a, m, s), m;
|
|
130
130
|
}
|
|
131
131
|
async trajectoryIn30Day(t, o, i, a, n, s, d = {}) {
|
|
132
|
-
var u, p, k, y,
|
|
132
|
+
var u, p, k, y, v;
|
|
133
133
|
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", l = {
|
|
134
134
|
headers: {
|
|
135
135
|
Authorization: `${(u = this.token) == null ? void 0 : u.tokenType} ${(p = this.token) == null ? void 0 : p.accessToken}`
|
|
@@ -141,12 +141,12 @@ class wt extends U {
|
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
143
|
b == null || b.info("[%s] fetch trajectory from: %s - %j", d.requestId, r, l);
|
|
144
|
-
const m = await
|
|
144
|
+
const m = await R.post(r, l).json();
|
|
145
145
|
if (m.code)
|
|
146
146
|
return b == null || b.warn("[%s] fetch trajectory failed: %j", d.requestId, r, { message: m.message, status: m.status, code: m.code }), m;
|
|
147
147
|
let f = -1;
|
|
148
148
|
const h = I(`${(y = (k = m.data) == null ? void 0 : k[0]) == null ? void 0 : y.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
149
|
-
return (
|
|
149
|
+
return (v = m.data) == null || v.forEach((c) => {
|
|
150
150
|
for (const C in c)
|
|
151
151
|
!isNaN(c[C]) && Number(c[C]) !== 1 / 0 && (c[C] = Number(c[C]));
|
|
152
152
|
const M = I(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), D = c.status, { labelCn: g, labelEn: Y } = this.parseStatus(D), S = {
|
|
@@ -172,7 +172,7 @@ class wt extends U {
|
|
|
172
172
|
}), s;
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
-
class
|
|
175
|
+
class wt extends U {
|
|
176
176
|
constructor(t) {
|
|
177
177
|
super();
|
|
178
178
|
Z(this, "token");
|
|
@@ -184,7 +184,7 @@ class gt extends U {
|
|
|
184
184
|
mmsi: t,
|
|
185
185
|
usertoken: this.token
|
|
186
186
|
}
|
|
187
|
-
}, n = await
|
|
187
|
+
}, n = await R.post(i, a).json();
|
|
188
188
|
b == null || b.info("[%s] fetch realtime position from: %s - %j", o.requestId, i, a);
|
|
189
189
|
const s = n == null ? void 0 : n.list;
|
|
190
190
|
if (!s)
|
|
@@ -230,7 +230,7 @@ class gt extends U {
|
|
|
230
230
|
Host: "www.hifleet.com"
|
|
231
231
|
}
|
|
232
232
|
};
|
|
233
|
-
let n = await
|
|
233
|
+
let n = await R.post(i, a).json();
|
|
234
234
|
b == null || b.info("[%s] fetch vessel props from: %s - %j", o.requestId, i, a), n instanceof Array && (n = n[0]);
|
|
235
235
|
for (const d in n)
|
|
236
236
|
!isNaN(n[d]) && Number(n[d]) !== 1 / 0 && (n[d] = Number(n[d]));
|
|
@@ -244,7 +244,7 @@ class gt extends U {
|
|
|
244
244
|
draught: n.dr,
|
|
245
245
|
type: n.t
|
|
246
246
|
};
|
|
247
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", n = await
|
|
247
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", n = await R.post(i, a).json(), b == null || b.info("[%s] search vessel dead weight from: %s - %j", o.requestId, i, a), n instanceof Array && (n = n[0]), n && (s.deadweight = Number(n.dwt)), s;
|
|
248
248
|
}
|
|
249
249
|
async suggest(t, o = {}) {
|
|
250
250
|
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", a = {
|
|
@@ -256,7 +256,7 @@ class gt extends U {
|
|
|
256
256
|
Origin: "https://www.hifleet.com",
|
|
257
257
|
Host: "www.hifleet.com"
|
|
258
258
|
}
|
|
259
|
-
}, n = await
|
|
259
|
+
}, n = await R.post(i, a).json();
|
|
260
260
|
b == null || b.info("[%s] suggest vessel props from: %s - %j", o.requestId, i, a);
|
|
261
261
|
const s = [];
|
|
262
262
|
for (const d of n)
|
|
@@ -285,13 +285,13 @@ class gt extends U {
|
|
|
285
285
|
mmsi: t,
|
|
286
286
|
usertoken: this.token
|
|
287
287
|
}
|
|
288
|
-
}, h = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", u = await
|
|
288
|
+
}, h = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", u = await R.get(h, f).json();
|
|
289
289
|
b == null || b.info("[%s] fetch trajectory from: %s - %j", s.requestId, h, f);
|
|
290
290
|
let p;
|
|
291
291
|
u && (p = ((M = (c = u.ships) == null ? void 0 : c.offors) == null ? void 0 : M.ship) || [], p.length || b == null || b.warn("[%s] fetch trajectory failed: %j", s.requestId, u));
|
|
292
292
|
const k = [];
|
|
293
293
|
let y = -1;
|
|
294
|
-
const
|
|
294
|
+
const v = I(`${(D = p == null ? void 0 : p[0]) == null ? void 0 : D.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
295
295
|
for (const g of p) {
|
|
296
296
|
for (const q in g)
|
|
297
297
|
!isNaN(g[q]) && Number(g[q]) !== 1 / 0 && (g[q] = Number(g[q]));
|
|
@@ -314,7 +314,7 @@ class gt extends U {
|
|
|
314
314
|
labelEn: S,
|
|
315
315
|
method: "trajectory",
|
|
316
316
|
vendor: "hifleet"
|
|
317
|
-
}, A = Math.floor(Y.diff(
|
|
317
|
+
}, A = Math.floor(Y.diff(v, "minute", !0) / (a || 1));
|
|
318
318
|
A !== y && (y = A, k.push(C));
|
|
319
319
|
}
|
|
320
320
|
return k;
|
|
@@ -333,7 +333,7 @@ class It extends U {
|
|
|
333
333
|
k: this.token,
|
|
334
334
|
enc: 1
|
|
335
335
|
}
|
|
336
|
-
}, a = "https://api.shipxy.com/apicall/GetSingleShip", n = await
|
|
336
|
+
}, a = "https://api.shipxy.com/apicall/GetSingleShip", n = await R.get(a, i).json();
|
|
337
337
|
if (b == null || b.info("[%s] fetch realtime position from: %s - %j", o.requestId, a, i), (n == null ? void 0 : n.status) !== 0)
|
|
338
338
|
return n;
|
|
339
339
|
const s = n.data[0];
|
|
@@ -364,7 +364,7 @@ class It extends U {
|
|
|
364
364
|
};
|
|
365
365
|
}
|
|
366
366
|
async trajectory(t, o, i, a, n = !0, s = {}) {
|
|
367
|
-
var
|
|
367
|
+
var v;
|
|
368
368
|
const d = await this.realTimePosition(t, s), r = I(o), l = I(i), m = "https://api.shipxy.com/apicall/GetShipTrack", f = {
|
|
369
369
|
searchParams: {
|
|
370
370
|
id: t,
|
|
@@ -374,10 +374,10 @@ class It extends U {
|
|
|
374
374
|
btm: r.unix(),
|
|
375
375
|
etm: l.unix()
|
|
376
376
|
}
|
|
377
|
-
}, h = await
|
|
377
|
+
}, h = await R.get(m, f).json();
|
|
378
378
|
if (b == null || b.info("[%s] fetch trajectory from: %s - %j", s.requestId, m, f), (h == null ? void 0 : h.status) !== 0)
|
|
379
379
|
return h;
|
|
380
|
-
const u = h == null ? void 0 : h.points, p = [], k = I.unix((
|
|
380
|
+
const u = h == null ? void 0 : h.points, p = [], k = I.unix((v = u[0]) == null ? void 0 : v.utc);
|
|
381
381
|
let y = -1;
|
|
382
382
|
for (const c of u) {
|
|
383
383
|
const M = I.unix(c.utc), D = {
|
|
@@ -411,7 +411,7 @@ class pt extends U {
|
|
|
411
411
|
json: {
|
|
412
412
|
mmsiList: t
|
|
413
413
|
}
|
|
414
|
-
}, a = "https://api3.myships.com/sp/ships/getShipIdByMMSI", n = await
|
|
414
|
+
}, a = "https://api3.myships.com/sp/ships/getShipIdByMMSI", n = await R.post(a, i).json();
|
|
415
415
|
return b == null || b.info("[%s] fetch ship id from: %s - %j", o.requestId, a, i), n.code !== "0" ? n : n.data[0].shipId;
|
|
416
416
|
}
|
|
417
417
|
async getShipInfo(t, o = {}) {
|
|
@@ -422,7 +422,7 @@ class pt extends U {
|
|
|
422
422
|
json: {
|
|
423
423
|
shipId: t
|
|
424
424
|
}
|
|
425
|
-
}, a = "https://api3.myships.com/sp/ships/aissta", n = await
|
|
425
|
+
}, a = "https://api3.myships.com/sp/ships/aissta", n = await R.post(a, i).json();
|
|
426
426
|
if (b == null || b.info("[%s] fetch ship info from: %s - %j", o.requestId, a, i), n.code !== "0")
|
|
427
427
|
return n;
|
|
428
428
|
const s = n.data;
|
|
@@ -445,7 +445,7 @@ class pt extends U {
|
|
|
445
445
|
json: {
|
|
446
446
|
shipId: i
|
|
447
447
|
}
|
|
448
|
-
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await
|
|
448
|
+
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await R.post(s, n).json();
|
|
449
449
|
b == null || b.info("[%s] fetch realtime position from: %s - %j", o.requestId, s, n);
|
|
450
450
|
const r = d.data[0];
|
|
451
451
|
for (const u in r)
|
|
@@ -486,7 +486,7 @@ class pt extends U {
|
|
|
486
486
|
startTime: o,
|
|
487
487
|
endTime: i
|
|
488
488
|
}
|
|
489
|
-
}, m = "https://api3.myships.com/sp/ships/position/history", f = await
|
|
489
|
+
}, m = "https://api3.myships.com/sp/ships/position/history", f = await R.post(m, l).json();
|
|
490
490
|
if (b == null || b.info("[%s] fetch trajectory from: %s - %j", r.requestId, m, l), f.code !== "0")
|
|
491
491
|
return b == null || b.warn("[%s] invoke myship trajectory failed: %j", r.requestId, f), f;
|
|
492
492
|
const h = f.data;
|
|
@@ -495,7 +495,7 @@ class pt extends U {
|
|
|
495
495
|
const u = I.unix((k = h[0]) == null ? void 0 : k.posTime);
|
|
496
496
|
let p = -1;
|
|
497
497
|
for (const y of h) {
|
|
498
|
-
const
|
|
498
|
+
const v = I.unix(y.posTime), c = {
|
|
499
499
|
imo: a == null ? void 0 : a.imo,
|
|
500
500
|
mmsi: n,
|
|
501
501
|
lat: Math.round(y.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
@@ -504,11 +504,11 @@ class pt extends U {
|
|
|
504
504
|
cog: Math.round(y.cog / 10 * 100) / 100,
|
|
505
505
|
hdg: Math.round(y.heading * 100) / 100,
|
|
506
506
|
rot: Math.round(y.rot * 100) / 100,
|
|
507
|
-
positionTime:
|
|
508
|
-
utc:
|
|
507
|
+
positionTime: v.unix(),
|
|
508
|
+
utc: v.utc().format(),
|
|
509
509
|
method: "trajectory",
|
|
510
510
|
vendor: "myship"
|
|
511
|
-
}, M = Math.floor(
|
|
511
|
+
}, M = Math.floor(v.diff(u, "minute", !0) / (s || 1));
|
|
512
512
|
M !== p && (p = M, d.push(c));
|
|
513
513
|
}
|
|
514
514
|
return d;
|
|
@@ -575,9 +575,9 @@ class rt {
|
|
|
575
575
|
* @param options
|
|
576
576
|
*/
|
|
577
577
|
checkWeather(e, t, o = {}) {
|
|
578
|
-
var u, p, k, y,
|
|
578
|
+
var u, p, k, y, v, c, M, D, g, Y, S, x, C, A, q;
|
|
579
579
|
let i = 0, a = 0, n = 0, s = 0;
|
|
580
|
-
const d = Math.round(((p = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.sigWave) == null ? void 0 : p.number) * 1.6 * 100) / 100, r = (y = (k = t == null ? void 0 : t.SEVERE) == null ? void 0 : k.sigWave) == null ? void 0 : y.number, l = (c = (
|
|
580
|
+
const d = Math.round(((p = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.sigWave) == null ? void 0 : p.number) * 1.6 * 100) / 100, r = (y = (k = t == null ? void 0 : t.SEVERE) == null ? void 0 : k.sigWave) == null ? void 0 : y.number, l = (c = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : c.number, m = Math.round((((D = (M = t == null ? void 0 : t.SEVERE) == null ? void 0 : M.wind) == null ? void 0 : D.number) + 2) * 100) / 100, f = (Y = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.wind) == null ? void 0 : Y.number, h = (x = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : x.number;
|
|
581
581
|
for (let V = 0; V < (e == null ? void 0 : e.length); V++) {
|
|
582
582
|
const T = e[V], O = (A = (C = T == null ? void 0 : T.meteo) == null ? void 0 : C.wave) == null ? void 0 : A.sig, P = (q = T == null ? void 0 : T.meteo) == null ? void 0 : q.wind, J = V ? I(T.eta).diff(I(e[V - 1].eta), "hour", !0) : 0;
|
|
583
583
|
s = J > s ? J : s, W == null || W.info("[%s] check sig.wave: %j", o.requestId, { ...O, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: l }), (O == null ? void 0 : O.height) >= d ? T.isDangerous = !0 : (O == null ? void 0 : O.height) >= r ? T.isSevere = !0 : (O == null ? void 0 : O.height) >= l && (T.isHeavy = !0), W == null || W.info("[%s] check wind: %j", o.requestId, { ...P, dgThd4Wd: m, svThd4Wd: f, hvThd4Wd: h }), (P == null ? void 0 : P.scale) >= m ? (T.isDangerous = !0, delete T.isSevere, delete T.isHeavy) : (P == null ? void 0 : P.scale) > f ? (T.isDangerous || (T.isSevere = !0), delete T.isHeavy) : (P == null ? void 0 : P.scale) === h && !T.isDangerous && !T.isSevere && (T.isHeavy = !0), i += T.isDangerous ? J : 0, a += T.isSevere ? J : 0, n += T.isHeavy ? J : 0;
|
|
@@ -586,9 +586,9 @@ class rt {
|
|
|
586
586
|
}
|
|
587
587
|
}
|
|
588
588
|
const kt = new rt();
|
|
589
|
-
let
|
|
589
|
+
let w;
|
|
590
590
|
try {
|
|
591
|
-
|
|
591
|
+
w = Q.getLogger("vessel");
|
|
592
592
|
} catch {
|
|
593
593
|
} finally {
|
|
594
594
|
}
|
|
@@ -741,7 +741,7 @@ class H {
|
|
|
741
741
|
const u = await ct.spotForecast(t.lat, t.lng, o.utc().format(), !1, !1, !0, d), [p] = tt.pickHourly(u, o);
|
|
742
742
|
l = tt.toLegacy(p);
|
|
743
743
|
} catch (u) {
|
|
744
|
-
|
|
744
|
+
w.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...t, eta: o.utc().format() }, u);
|
|
745
745
|
}
|
|
746
746
|
else
|
|
747
747
|
l = await nt.queryPointFactor(t.lng, t.lat, o.valueOf(), "wind,wave,current,watertemp", i, d);
|
|
@@ -781,10 +781,10 @@ class H {
|
|
|
781
781
|
t.utc();
|
|
782
782
|
const m = t.clone().add(14, "days"), f = [], h = [];
|
|
783
783
|
let u = 0, p = 0, k, y;
|
|
784
|
-
for (let
|
|
785
|
-
let c = n[
|
|
784
|
+
for (let v = 0; v < n.length - 1; v++) {
|
|
785
|
+
let c = n[v];
|
|
786
786
|
c.distanceFromStart = Math.round((a + p) * 1e4) / 1e4;
|
|
787
|
-
const M = n[
|
|
787
|
+
const M = n[v + 1];
|
|
788
788
|
if (e.bearing = B.calculateBearing(c, M, !M.gcToPrevious), c.bearing = e.bearing, c.suspend && r) {
|
|
789
789
|
c.eta = c.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), c.elapsed = c.elapsed ?? 0;
|
|
790
790
|
const Y = c.suspend - c.elapsed;
|
|
@@ -794,7 +794,7 @@ class H {
|
|
|
794
794
|
const S = i - u;
|
|
795
795
|
c.elapsed += S, t.add(S, "hour"), i = 0;
|
|
796
796
|
}
|
|
797
|
-
if (
|
|
797
|
+
if (w == null || w.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`, l.requestId, c), i === 0)
|
|
798
798
|
return c.distanceFromPrevious = p, { etd: t, from: y || c, to: c, next: n.filter((S) => S), wps: f, days: h };
|
|
799
799
|
} else
|
|
800
800
|
c.suspend = 0;
|
|
@@ -802,19 +802,19 @@ class H {
|
|
|
802
802
|
const D = B.calculateDistance(c, M, !M.gcToPrevious);
|
|
803
803
|
let g = Math.ceil(D / y.speed * 1e4) / 1e4;
|
|
804
804
|
if (u + g < i) {
|
|
805
|
-
if (u += g, t.add(g, "hour"), delete n[
|
|
805
|
+
if (u += g, t.add(g, "hour"), delete n[v], w == null || w.debug(
|
|
806
806
|
`[%s] go to %j from %j with ${D}nm, and cost ${g} hours`,
|
|
807
807
|
l.requestId,
|
|
808
808
|
{ lat: M.lat, lng: M.lng },
|
|
809
809
|
{ lat: y.lat, lng: y.lng, etd: y.etd }
|
|
810
810
|
), p += D, n.filter((Y) => Y).length <= 1) {
|
|
811
|
-
k = M, k.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), k.distanceFromPrevious = D, k.distanceFromStart = Math.round((a + p) * 1e4) / 1e4, f.push(k), delete n[
|
|
811
|
+
k = M, k.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), k.distanceFromPrevious = D, k.distanceFromStart = Math.round((a + p) * 1e4) / 1e4, f.push(k), delete n[v + 1];
|
|
812
812
|
break;
|
|
813
813
|
}
|
|
814
814
|
} else {
|
|
815
815
|
g = i - u, t.add(g, "hour");
|
|
816
816
|
const Y = z.roundPrecision(y.speed * g, 4);
|
|
817
|
-
k = B.calculateCoordinate(c, e.bearing, Y, "nauticalmiles", !M.gcToPrevious), k.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), n[
|
|
817
|
+
k = B.calculateCoordinate(c, e.bearing, Y, "nauticalmiles", !M.gcToPrevious), k.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), n[v] = k, w == null || w.debug(
|
|
818
818
|
`[%s] go to %j from %j with ${Y}nm, and cost ${g} hours`,
|
|
819
819
|
l.requestId,
|
|
820
820
|
{ lat: k.lat, lng: k.lng },
|
|
@@ -823,7 +823,7 @@ class H {
|
|
|
823
823
|
break;
|
|
824
824
|
}
|
|
825
825
|
}
|
|
826
|
-
return { etd: t, from: y, to: k, next: n.filter((
|
|
826
|
+
return { etd: t, from: y, to: k, next: n.filter((v) => v), wps: f, days: h };
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
829
829
|
* 洋流影响因子
|
|
@@ -845,15 +845,15 @@ class H {
|
|
|
845
845
|
*/
|
|
846
846
|
static weatherFactor(e, t) {
|
|
847
847
|
var m, f, h, u, p, k, y;
|
|
848
|
-
|
|
848
|
+
w == null || w.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
849
849
|
const o = H.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), i = H.froudeNumber(e.speed, e.lbp), a = H.amendFactor(o, i, e.loadCondition);
|
|
850
850
|
let n = Math.abs(e.bearing % 360 - (((m = t == null ? void 0 : t.wind) == null ? void 0 : m.degree) % 360 || 0));
|
|
851
851
|
n = n > 180 ? 360 - n : n;
|
|
852
852
|
const s = H.directionFactor(n, (f = t == null ? void 0 : t.wind) == null ? void 0 : f.scale), d = H.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (h = t == null ? void 0 : t.wind) == null ? void 0 : h.scale);
|
|
853
853
|
let r = s * a * d / 100 * e.speed;
|
|
854
|
-
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)),
|
|
854
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), w == null || w.debug("wind wx factor = %d", r), n = Math.abs(e.bearing % 360 - (((p = (u = t == null ? void 0 : t.wave) == null ? void 0 : u.sig) == null ? void 0 : p.degree) % 360 || 0));
|
|
855
855
|
const l = H.waveHeightFactor(((y = (k = t == null ? void 0 : t.wave) == null ? void 0 : k.sig) == null ? void 0 : y.height) ?? 1, n);
|
|
856
|
-
return
|
|
856
|
+
return w == null || w.debug("wave wx factor = %d", l), r = r * 0.4 + l, w == null || w.debug("weather factor = %d", r), r = Math.abs(r) > 4 ? 4 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 4) * 0.1 : r, Math.round((r || 0) * 100) / 100;
|
|
857
857
|
}
|
|
858
858
|
/**
|
|
859
859
|
* 全程失速分析(走完航程)
|
|
@@ -868,7 +868,7 @@ class H {
|
|
|
868
868
|
* @param useRouteParam
|
|
869
869
|
*/
|
|
870
870
|
static async analyseInstant(e, t, o, i, a, n = "", s = 0, d = !0, r = !1, l = {}) {
|
|
871
|
-
var J, K, _, G,
|
|
871
|
+
var J, K, _, G, L;
|
|
872
872
|
const m = I().valueOf();
|
|
873
873
|
e.lng = z.convertToStdLng(e.lng);
|
|
874
874
|
const { route: f, waypoints: h } = a.points, u = B.calculateSubRoute(e, f);
|
|
@@ -882,12 +882,12 @@ class H {
|
|
|
882
882
|
v0: i.speed,
|
|
883
883
|
label: "CP"
|
|
884
884
|
/* Cp */
|
|
885
|
-
}, y = H.assembleProperties(o, i.loadCondition, p, 0),
|
|
886
|
-
|
|
885
|
+
}, y = H.assembleProperties(o, i.loadCondition, p, 0), v = h.length ? B.calculateSubWaypoints(e, h) : [];
|
|
886
|
+
v.forEach((N) => N.important = !0);
|
|
887
887
|
const c = {
|
|
888
888
|
from: { ...e },
|
|
889
889
|
route: u,
|
|
890
|
-
waypoints:
|
|
890
|
+
waypoints: v,
|
|
891
891
|
v0: p,
|
|
892
892
|
label: k
|
|
893
893
|
}, M = {
|
|
@@ -896,7 +896,7 @@ class H {
|
|
|
896
896
|
wps: []
|
|
897
897
|
};
|
|
898
898
|
s || (B.calculateRouteDistance(u) / i.speed <= 72 ? s = 3 : s = 6);
|
|
899
|
-
let D = B.simplifyRouteToCoordinates(u,
|
|
899
|
+
let D = B.simplifyRouteToCoordinates(u, v, 0), g = 0, Y = 0, S = 0, x = 0;
|
|
900
900
|
t = I(t).utc();
|
|
901
901
|
const C = t.clone();
|
|
902
902
|
for (; D.length > 0; ) {
|
|
@@ -933,8 +933,8 @@ class H {
|
|
|
933
933
|
}), c.sample = M;
|
|
934
934
|
const q = M.hours.at(0), V = M.hours.at(-1);
|
|
935
935
|
c.distance = Math.round(V.distanceFromStart * 1e4) / 1e4, c.etd = I(q.eta).utc().format(), c.eta = I(V.eta).utc().format(), c.wxFactor = Math.round(Y / x * 1e4) / 1e4, c.cFactor = Math.round(S / x * 1e4) / 1e4, c.avgSpeed = Math.round(V.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;
|
|
936
|
-
const O = I().valueOf() - m, P = ((
|
|
937
|
-
return
|
|
936
|
+
const O = I().valueOf() - m, P = ((L = M == null ? void 0 : M.hours) == null ? void 0 : L.length) || 1;
|
|
937
|
+
return w == null || w.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, O, P, Math.round(O / P * 1e3) / 1e3), c;
|
|
938
938
|
}
|
|
939
939
|
/**
|
|
940
940
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -964,9 +964,9 @@ class H {
|
|
|
964
964
|
}, k = H.assembleProperties(i, a.loadCondition, u, 0), y = B.calculateSubRoute(e, n);
|
|
965
965
|
if (((J = y[0]) == null ? void 0 : J.length) <= 1)
|
|
966
966
|
return;
|
|
967
|
-
const
|
|
968
|
-
|
|
969
|
-
let c = B.simplifyRouteToCoordinates(y,
|
|
967
|
+
const v = s.length ? B.calculateSubWaypoints(e, s) : [];
|
|
968
|
+
v.forEach((L) => L.important = !0);
|
|
969
|
+
let c = B.simplifyRouteToCoordinates(y, v, 0), M = 0, D = 0, g = 0, Y = 0;
|
|
970
970
|
const S = {
|
|
971
971
|
hours: [],
|
|
972
972
|
wps: [],
|
|
@@ -975,8 +975,8 @@ class H {
|
|
|
975
975
|
t = I(t).utc();
|
|
976
976
|
const x = t.clone();
|
|
977
977
|
for (; c.length > 0; ) {
|
|
978
|
-
const
|
|
979
|
-
let N = Math.ceil(t.clone().add(
|
|
978
|
+
const L = r - t.hour() % r;
|
|
979
|
+
let N = Math.ceil(t.clone().add(L, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
980
980
|
if (N = t.clone().add(N, "h").isAfter(o) ? o.diff(t, "h", !0) * 1e4 / 1e4 : N, N) {
|
|
981
981
|
const F = await H.speedLoseInHoursStep(
|
|
982
982
|
k,
|
|
@@ -995,9 +995,9 @@ class H {
|
|
|
995
995
|
break;
|
|
996
996
|
}
|
|
997
997
|
const C = S.hours;
|
|
998
|
-
for (let
|
|
999
|
-
const N = I(C[
|
|
1000
|
-
D += C[
|
|
998
|
+
for (let L = 0; L < C.length - 1; L++) {
|
|
999
|
+
const N = I(C[L + 1].eta).diff(C[L].etd, "hour", !0);
|
|
1000
|
+
D += C[L].wxFactor * N, g += C[L].cFactor * N, Y += N;
|
|
1001
1001
|
}
|
|
1002
1002
|
const A = S.hours.at(0), q = S.hours.at(-1), V = {
|
|
1003
1003
|
sample: S,
|
|
@@ -1014,11 +1014,11 @@ class H {
|
|
|
1014
1014
|
from: A,
|
|
1015
1015
|
to: q,
|
|
1016
1016
|
route: y,
|
|
1017
|
-
waypoints:
|
|
1017
|
+
waypoints: v,
|
|
1018
1018
|
v0: u,
|
|
1019
1019
|
label: p
|
|
1020
1020
|
}, O = I().valueOf() - h, P = ((G = S == null ? void 0 : S.hours) == null ? void 0 : G.length) || 1;
|
|
1021
|
-
return
|
|
1021
|
+
return w == null || w.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", f == null ? void 0 : f.requestId, O, P, Math.round(O / P * 1e3) / 1e3), V;
|
|
1022
1022
|
}
|
|
1023
1023
|
/**
|
|
1024
1024
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1042,22 +1042,22 @@ class H {
|
|
|
1042
1042
|
const d = I.utc(e.etd).add(14, "day");
|
|
1043
1043
|
let r = 1;
|
|
1044
1044
|
for (const y of o) {
|
|
1045
|
-
|
|
1046
|
-
const
|
|
1045
|
+
w == null || w.info("[%s][L%d-%d] analyse from %s to %s", a.requestId, 1, r, e.etd, d.format());
|
|
1046
|
+
const v = JSON.parse(JSON.stringify(i.route)), c = JSON.parse(JSON.stringify(i.waypoints)), M = await H.analyseInstantWithThreshed(
|
|
1047
1047
|
{ lat: e.lat, lng: e.lng },
|
|
1048
1048
|
e.etd,
|
|
1049
1049
|
d,
|
|
1050
1050
|
t,
|
|
1051
1051
|
y,
|
|
1052
|
-
|
|
1052
|
+
v,
|
|
1053
1053
|
c,
|
|
1054
1054
|
e.meteoVendor,
|
|
1055
1055
|
e.speedStep,
|
|
1056
|
-
|
|
1056
|
+
e.useMeteo,
|
|
1057
1057
|
e.useRouteParam,
|
|
1058
1058
|
a
|
|
1059
1059
|
);
|
|
1060
|
-
M && (await H.calculateCost(M, y, e, a), s.push(M),
|
|
1060
|
+
M && (await H.calculateCost(M, y, e, a), s.push(M), w == null || w.info("[%s][L%d-%d] cost: %j", a.requestId, 1, r, {
|
|
1061
1061
|
distance: M.distance,
|
|
1062
1062
|
totalHrs: M.totalHrs,
|
|
1063
1063
|
totalFoCons: M.totalFoCons,
|
|
@@ -1067,14 +1067,14 @@ class H {
|
|
|
1067
1067
|
cost: M.cost
|
|
1068
1068
|
})), r++;
|
|
1069
1069
|
}
|
|
1070
|
-
s.sort((y,
|
|
1070
|
+
s.sort((y, v) => y.cost.total - v.cost.total);
|
|
1071
1071
|
const l = s.at(0), m = s.at(1), f = [];
|
|
1072
1072
|
if (f.push({ combined: !1, speeds: [l], cost: (p = l.cost) == null ? void 0 : p.total }), m) {
|
|
1073
|
-
const y = l.cost.cp,
|
|
1073
|
+
const y = l.cost.cp, v = m.cost.cp, c = I(l.eta), M = I(l.etd), D = c.diff(M, "days", !0);
|
|
1074
1074
|
let g = Math.ceil(D / 2);
|
|
1075
1075
|
g = g > 7 ? 7 : g;
|
|
1076
1076
|
let Y = 2, S = { combined: !1, speeds: [m], cost: (k = m.cost) == null ? void 0 : k.total }, x;
|
|
1077
|
-
for (; g >= 1 && (x = await H.combinedAnalyse(e, t, d, [y,
|
|
1077
|
+
for (; g >= 1 && (x = await H.combinedAnalyse(e, t, d, [y, v], i, g, { ...a, level: Y }), !(S.cost < x.cost)); ) {
|
|
1078
1078
|
const C = S;
|
|
1079
1079
|
if (S = x, g === 1) {
|
|
1080
1080
|
x = C;
|
|
@@ -1085,7 +1085,7 @@ class H {
|
|
|
1085
1085
|
f.push(S), x && f.push(x);
|
|
1086
1086
|
}
|
|
1087
1087
|
const u = I().valueOf() - n;
|
|
1088
|
-
return
|
|
1088
|
+
return w == null || w.info("[%s] analyse elapsed: %d ms", a == null ? void 0 : a.requestId, u), f.sort((y, v) => y.cost - v.cost);
|
|
1089
1089
|
}
|
|
1090
1090
|
/**
|
|
1091
1091
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1098,11 +1098,11 @@ class H {
|
|
|
1098
1098
|
* @param options
|
|
1099
1099
|
*/
|
|
1100
1100
|
static async combinedAnalyse(e, t, o, i, a, n, s = {}) {
|
|
1101
|
-
|
|
1101
|
+
w == null || w.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, n);
|
|
1102
1102
|
const d = await H.alternateAnalyse(e, t, o, i, 0, a, n, s), r = d.reduce((f, h) => f + h.cost.total, 0);
|
|
1103
|
-
|
|
1103
|
+
w == null || w.info("[%s][L%d] cost with alternate cp a first: %j", s.requestId, s.level, { cost: r });
|
|
1104
1104
|
const l = await H.alternateAnalyse(e, t, o, i, 1, a, n, s), m = l.reduce((f, h) => f + h.cost.total, 0);
|
|
1105
|
-
return
|
|
1105
|
+
return w == null || w.info("[%s][L%d] cost with alternate cp b first: %j", s.requestId, s.level, { cost: m }), r < m ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d } : { combined: !0, cost: Math.round(m * 1e3) / 1e3, speeds: l };
|
|
1106
1106
|
}
|
|
1107
1107
|
/**
|
|
1108
1108
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1121,8 +1121,8 @@ class H {
|
|
|
1121
1121
|
const m = { lat: e.lat, lng: e.lng }, f = [];
|
|
1122
1122
|
for (; r.isBefore(o); ) {
|
|
1123
1123
|
const p = r.clone().utc().add(s, "day");
|
|
1124
|
-
|
|
1125
|
-
const k = JSON.parse(JSON.stringify(n.route)), y = JSON.parse(JSON.stringify(n.waypoints)),
|
|
1124
|
+
w == null || w.info("[%s][L%d-%d] analyse from %s to %s", d.requestId, d.level, l, e.etd, p.format());
|
|
1125
|
+
const k = JSON.parse(JSON.stringify(n.route)), y = JSON.parse(JSON.stringify(n.waypoints)), v = await H.analyseInstantWithThreshed(
|
|
1126
1126
|
m,
|
|
1127
1127
|
r.format(),
|
|
1128
1128
|
p,
|
|
@@ -1132,22 +1132,22 @@ class H {
|
|
|
1132
1132
|
y,
|
|
1133
1133
|
e.meteoVendor,
|
|
1134
1134
|
e.speedStep,
|
|
1135
|
-
|
|
1135
|
+
e.useMeteo,
|
|
1136
1136
|
e.useRouteParam,
|
|
1137
1137
|
d
|
|
1138
1138
|
);
|
|
1139
|
-
|
|
1140
|
-
distance:
|
|
1141
|
-
totalHrs:
|
|
1142
|
-
totalFoCons:
|
|
1143
|
-
totalDgoCons:
|
|
1144
|
-
etd:
|
|
1145
|
-
eta:
|
|
1146
|
-
cost:
|
|
1139
|
+
v && (await H.calculateCost(v, i[a], e, d), w == null || w.info("[%s][L%d-%d] cost: %j", d.requestId, d.level, l, {
|
|
1140
|
+
distance: v.distance,
|
|
1141
|
+
totalHrs: v.totalHrs,
|
|
1142
|
+
totalFoCons: v.totalFoCons,
|
|
1143
|
+
totalDgoCons: v.totalDgoCons,
|
|
1144
|
+
etd: v.etd,
|
|
1145
|
+
eta: v.eta,
|
|
1146
|
+
cost: v.cost
|
|
1147
1147
|
}));
|
|
1148
|
-
const c = (u = (h =
|
|
1148
|
+
const c = (u = (h = v == null ? void 0 : v.sample) == null ? void 0 : h.hours) == null ? void 0 : u.at(-1);
|
|
1149
1149
|
if (c)
|
|
1150
|
-
m.lat = c.lat, m.lng = c.lng, r = I(c.eta), f.push(
|
|
1150
|
+
m.lat = c.lat, m.lng = c.lng, r = I(c.eta), f.push(v), l += 1, a = a ? 0 : 1;
|
|
1151
1151
|
else
|
|
1152
1152
|
break;
|
|
1153
1153
|
}
|
|
@@ -1217,10 +1217,10 @@ export {
|
|
|
1217
1217
|
U as AISImpl,
|
|
1218
1218
|
rt as AlertHelper,
|
|
1219
1219
|
it as AlertLevel,
|
|
1220
|
-
|
|
1220
|
+
wt as HifleetImpl,
|
|
1221
1221
|
ut as LoadCondition,
|
|
1222
1222
|
pt as MyShipImpl,
|
|
1223
|
-
|
|
1223
|
+
gt as MyVesselImpl,
|
|
1224
1224
|
It as ShipxyImpl,
|
|
1225
1225
|
H as SpeedHelper,
|
|
1226
1226
|
ht as SpeedLabel,
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(T,N){typeof exports=="object"&&typeof module<"u"?N(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"],N):(T=typeof globalThis<"u"?globalThis:T||self,N(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,N,K,I,R,X,$){"use strict";var mt=Object.defineProperty;var yt=(T,N,K)=>N in T?mt(T,N,{enumerable:!0,configurable:!0,writable:!0,value:K}):T[N]=K;var _=(T,N,K)=>(yt(T,typeof N!="symbol"?N+"":N,K),K);let M;try{M=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class rt extends G{constructor(t,o){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},a=await N.post(o,i).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,o,a),a.error||(this.token={accessToken:a.access_token,tokenType:a.token_type,expiresIn:a.expires_in,scope:a.scope,jti:a.jti,issuedAt:I().utc().format()})}async realTimePosition(t,o={}){var l,m,f;(!this.token||I().diff(I(this.token.issuedAt),"seconds")>((l=this.token)==null?void 0:l.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",a={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(f=this.token)==null?void 0:f.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,a);const n=await N.get(i,a).json();if(n.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:n.message,status:n.status,code:n.code}),n;const s=n.data;for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const d=I(`${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)?I.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,a,n=!0,s={}){(!this.token||I().diff(I(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(t,s),r=I(o),l=I(i),m=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,a,m,s),r.add(30,"day");return await this.trajectoryIn30Day(t,r,l,d,a,m,s),m}async trajectoryIn30Day(t,o,i,a,n,s,d={}){var u,g,j,y,p;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(u=this.token)==null?void 0:u.tokenType} ${(g=this.token)==null?void 0:g.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,l);const m=await N.post(r,l).json();if(m.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:m.message,status:m.status,code:m.code}),m;let f=-1;const h=I(`${(y=(j=m.data)==null?void 0:j[0])==null?void 0:y.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(p=m.data)==null||p.forEach(c=>{for(const L in c)!isNaN(c[L])&&Number(c[L])!==1/0&&(c[L]=Number(c[L]));const b=I(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),D=c.status,{labelCn:w,labelEn:k}=this.parseStatus(D),S={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:D,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?I(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:b.unix(),labelCn:w,labelEn:k,method:"trajectory",vendor:"myVessel",utc:b.utc().format()},x=Math.floor(b.diff(h,"minute",!0)/(n||1));x!==f&&(f=x,s.push(S))}),s}}class ct extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",a={searchParams:{mmsi:t,usertoken:this.token}},n=await N.post(i,a).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,a);const s=n==null?void 0:n.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",o.requestId,i,n),n;for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:l}=this.parseStatus(d),m=I(`${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)?I.utc(s.eta).format():void 0,destination:s.destination,positionTime:m.unix(),utc:m.utc().format(),status:d,labelCn:r,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,o={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const a={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let n=await N.post(i,a).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,a),n instanceof Array&&(n=n[0]);for(const d in n)!isNaN(n[d])&&Number(n[d])!==1/0&&(n[d]=Number(n[d]));const s={mmsi:n.m,name:n.n,imo:n.i,callSign:n.c,length:n.l,breadth:n.b,draught:n.dr,type:n.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",n=await N.post(i,a).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,a),n instanceof Array&&(n=n[0]),n&&(s.deadweight=Number(n.dwt)),s}async suggest(t,o={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",a={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},n=await N.post(i,a).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,a);const s=[];for(const d of n)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(t,o,i,a,n=!0,s={}){var c,b,D;const d=await this.realTimePosition(t,s);let r=I(o);const l=I(i),m=I();if(n){let w=l.diff(r,"d",!0);w<0?r=l.clone().subtract(40,"d"):w<30?r.subtract(10,"d"):w<60?r.subtract(5,"d"):r=l.clone().subtract(80,"d"),w=m.diff(l,"d",!0),l.add(w>10?240:w*24,"h")}const f={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},h="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",u=await N.get(h,f).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,h,f);let g;u&&(g=((b=(c=u.ships)==null?void 0:c.offors)==null?void 0:b.ship)||[],g.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,u));const j=[];let y=-1;const p=I(`${(D=g==null?void 0:g[0])==null?void 0:D.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const w of g){for(const E in w)!isNaN(w[E])&&Number(w[E])!==1/0&&(w[E]=Number(w[E]));const k=I(`${w.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");w.status=w.sp>4?0:1;const{labelEn:S,labelCn:x}=this.parseStatus(w.status),L={mmsi:w.m,name:w.n,imo:d==null?void 0:d.imo,lat:w.la,lng:w.lo,draught:w.draught,sog:w.sp,cog:w.co,hdg:w.hdg,positionTime:k.unix(),utc:k.utc().format(),status:w.status,labelCn:x,labelEn:S,method:"trajectory",vendor:"hifleet"},W=Math.floor(k.diff(p,"minute",!0)/(a||1));W!==y&&(y=W,j.push(L))}return j}}class dt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},a="https://api.shipxy.com/apicall/GetSingleShip",n=await N.get(a,i).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,a,i),(n==null?void 0:n.status)!==0)return n;const s=n.data[0];for(const f in s)!isNaN(s[f])&&Number(s[f])!==1/0&&(s[f]=Number(s[f]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),l=I.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:l.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,a,n=!0,s={}){var p;const d=await this.realTimePosition(t,s),r=I(o),l=I(i),m="https://api.shipxy.com/apicall/GetShipTrack",f={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:l.unix()}},h=await N.get(m,f).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,m,f),(h==null?void 0:h.status)!==0)return h;const u=h==null?void 0:h.points,g=[],j=I.unix((p=u[0])==null?void 0:p.utc);let y=-1;for(const c of u){const b=I.unix(c.utc),D={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:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"shipxy"},w=Math.floor(b.diff(j,"minute",!0)/(a||1));w!==y&&(y=w,g.push(D))}return g}}class ut extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},a="https://api3.myships.com/sp/ships/getShipIdByMMSI",n=await N.post(a,i).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",o.requestId,a,i),n.code!=="0"?n:n.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},a="https://api3.myships.com/sp/ships/aissta",n=await N.post(a,i).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",o.requestId,a,i),n.code!=="0")return n;const s=n.data;let d=s.imo;return t==="407170"&&(d="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),a=await this.getShipInfo(i,o),n={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await N.post(s,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,n);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:l,labelEn:m}=await this.parseStatus(r.aisNavStatus),f=I.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:f.utc().format(),status:r.aisNavStatus,labelEn:m,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,o,i,a,n=!0,s={}){const d=I(o),r=I(i),l=await this.getShipId(t),m=await this.getShipInfo(l),f=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(l,d.unix(),d.add(30,"day").unix(),m,t,a,f);return await this.trajectoryIn30Day(l,d.unix(),r.unix(),m,t,a,f),f}async trajectoryIn30Day(t,o,i,a,n,s,d,r={}){var j;const l={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},m="https://api3.myships.com/sp/ships/position/history",f=await N.post(m,l).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,m,l),f.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",r.requestId,f),f;const h=f.data;for(const y in h)!isNaN(h[y])&&Number(h[y])!==1/0&&(h[y]=Number(h[y]));const u=I.unix((j=h[0])==null?void 0:j.posTime);let g=-1;for(const y of h){const p=I.unix(y.posTime),c={imo:a==null?void 0:a.imo,mmsi:n,lat:Math.round(y.lat/1e4/60*1e5)/1e5,lng:Math.round(y.lon/1e4/60*1e5)/1e5,sog:Math.round(y.sog/10*100)/100,cog:Math.round(y.cog/10*100)/100,hdg:Math.round(y.heading*100)/100,rot:Math.round(y.rot*100)/100,positionTime:p.unix(),utc:p.utc().format(),method:"trajectory",vendor:"myship"},b=Math.floor(p.diff(u,"minute",!0)/(s||1));b!==g&&(g=b,d.push(c))}return d}}let V;try{V=K.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 o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,a=i==null?void 0:i.split(";");if(!a)return;const n={};for(let l=0;l<(a==null?void 0:a.length);l++){const m=(r=(d=a[l].match(o))==null?void 0:d[0])==null?void 0:r.split("],");if(l===0&&!m)n.scope=a[0];else if(m)for(let f=0,h=m.length;f<h;f++){const u=this.parseRule(m[f]);u&&(n[u.level]?u.key?n[u.level][u==null?void 0:u.key]=u:n[u.level]=u:u.key?n[u.level]={[u==null?void 0:u.key]:u}:n[u.level]=u)}}return n}parseRule(e,t={}){var n;V==null||V.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(n=e==null?void 0:e.match(o))==null?void 0:n[0],a=i==null?void 0:i.split(",");if(a)return{operator:a[0],number:Number.isNaN(Number(a[1]))?a[1]:Number(a[1]),level:a[2],time:Number(a[3]),key:a[4]}}checkWeather(e,t,o={}){var u,g,j,y,p,c,b,D,w,k,S,x,L,W,E;let i=0,a=0,n=0,s=0;const d=Math.round(((g=(u=t==null?void 0:t.SEVERE)==null?void 0:u.sigWave)==null?void 0:g.number)*1.6*100)/100,r=(y=(j=t==null?void 0:t.SEVERE)==null?void 0:j.sigWave)==null?void 0:y.number,l=(c=(p=t==null?void 0:t.HEAVY)==null?void 0:p.sigWave)==null?void 0:c.number,m=Math.round((((D=(b=t==null?void 0:t.SEVERE)==null?void 0:b.wind)==null?void 0:D.number)+2)*100)/100,f=(k=(w=t==null?void 0:t.SEVERE)==null?void 0:w.wind)==null?void 0:k.number,h=(x=(S=t==null?void 0:t.HEAVY)==null?void 0:S.wind)==null?void 0:x.number;for(let B=0;B<(e==null?void 0:e.length);B++){const q=e[B],P=(W=(L=q==null?void 0:q.meteo)==null?void 0:L.wave)==null?void 0:W.sig,A=(E=q==null?void 0:q.meteo)==null?void 0:E.wind,Z=B?I(q.eta).diff(I(e[B-1].eta),"hour",!0):0;s=Z>s?Z:s,V==null||V.info("[%s] check sig.wave: %j",o.requestId,{...P,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}),(P==null?void 0:P.height)>=d?q.isDangerous=!0:(P==null?void 0:P.height)>=r?q.isSevere=!0:(P==null?void 0:P.height)>=l&&(q.isHeavy=!0),V==null||V.info("[%s] check wind: %j",o.requestId,{...A,dgThd4Wd:m,svThd4Wd:f,hvThd4Wd:h}),(A==null?void 0:A.scale)>=m?(q.isDangerous=!0,delete q.isSevere,delete q.isHeavy):(A==null?void 0:A.scale)>f?(q.isDangerous||(q.isSevere=!0),delete q.isHeavy):(A==null?void 0:A.scale)===h&&!q.isDangerous&&!q.isSevere&&(q.isHeavy=!0),i+=q.isDangerous?Z:0,a+=q.isSevere?Z:0,n+=q.isHeavy?Z:0}return i=Math.round(i*100)/100,a=Math.round(a*100)/100,n=Math.round(n*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:a,heavy:n,step:s<3?3:s,wind:{dgThd4Wd:m,svThd4Wd:f,hvThd4Wd:h},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}}}}const ht=new et;let v;try{v=K.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||{}),ot=(Y=>(Y.Cp="CP",Y.Perf="Basis",Y.Instruct="Other",Y))(ot||{});class C{static blockCoefficient(e,t,o,i){let a=Math.round(e/(t*o*i)*100)/100;a=a<.55?.55:a>.85?.85:a;const n=[.55,.6,.65,.7,.75,.8,.85],s=n.map(d=>Math.abs(d-a));return n[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(n=i[e]),n[0]+n[1]*t+n[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let a;return o==="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 o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var f;const a=e.lbp??e.length??e.lengthOverall??198.9642,n=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,r=((f=e==null?void 0:e.type)==null?void 0:f.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:a,loadCondition:t,draught:n,breadthMoulded:s,displacement:Math.round((d/1.025+n*s*a*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",a=2,n=!0,s=!1,d={}){let r;if(t.velocity&&s&&(e.speed=R.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),n){let l;if(d.meteo2)try{const u=await lt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[g]=$.Meteo2Assist.pickHourly(u,o);l=$.Meteo2Assist.toLegacy(g)}catch(u){v.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},u)}else l=await X.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const m=C.weatherFactor(e,l),f=C.currentFactor(e.bearing,l==null?void 0:l.current,a),h=Math.round((e.speed*1.943844+m+f)*100)/100;r={meteo:{...l},wxFactor:m,cFactor:f,speed:t.velocity&&s?t.velocity:h<0?1:h,eta:o.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:o.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:o.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:o.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(e,t,o,i,a,n,s="",d=!0,r=!1,l={}){t.utc();const m=t.clone().add(14,"days"),f=[],h=[];let u=0,g=0,j,y;for(let p=0;p<n.length-1;p++){let c=n[p];c.distanceFromStart=Math.round((a+g)*1e4)/1e4;const b=n[p+1];if(e.bearing=R.LaneHelper.calculateBearing(c,b,!b.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 S=i-u;c.elapsed+=S,t.add(S,"hour"),i=0}if(v==null||v.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=g,{etd:t,from:y||c,to:c,next:n.filter(S=>S),wps:f,days:h}}else c.suspend=0;d=t.isAfter(m)?!1:d,c=await C.speedLoseAt(e,c,t,s,0,d,r,l),y=y||c,c.important&&f.push(c),t.isSameOrAfter(o)&&(h.push(c),o.add(24,"hour"));const D=R.LaneHelper.calculateDistance(c,b,!b.gcToPrevious);let w=Math.ceil(D/y.speed*1e4)/1e4;if(u+w<i){if(u+=w,t.add(w,"hour"),delete n[p],v==null||v.debug(`[%s] go to %j from %j with ${D}nm, and cost ${w} hours`,l.requestId,{lat:b.lat,lng:b.lng},{lat:y.lat,lng:y.lng,etd:y.etd}),g+=D,n.filter(k=>k).length<=1){j=b,j.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),j.distanceFromPrevious=D,j.distanceFromStart=Math.round((a+g)*1e4)/1e4,f.push(j),delete n[p+1];break}}else{w=i-u,t.add(w,"hour");const k=R.LngLatHelper.roundPrecision(y.speed*w,4);j=R.LaneHelper.calculateCoordinate(c,e.bearing,k,"nauticalmiles",!b.gcToPrevious),j.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),n[p]=j,v==null||v.debug(`[%s] go to %j from %j with ${k}nm, and cost ${w} hours`,l.requestId,{lat:j.lat,lng:j.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),g+=k,j.distanceFromPrevious=Math.round(g*1e4)/1e4,j.distanceFromStart=Math.round((a+g)*1e4)/1e4;break}}return{etd:t,from:y,to:j,next:n.filter(p=>p),wps:f,days:h}}static currentFactor(e,t,o=0){const i=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let a=((t==null?void 0:t.kts)||0)*Math.cos(i);return o&2?a=Math.ceil(a*100)/100:o&1?a=Math.floor(a*100)/100:a=Math.round(a*100)/100,Math.abs(a)>5?0:a}static weatherFactor(e,t){var m,f,h,u,g,j,y;v==null||v.debug("calculate weather factor via: %j",{...e,...t});const o=C.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=C.froudeNumber(e.speed,e.lbp),a=C.amendFactor(o,i,e.loadCondition);let n=Math.abs(e.bearing%360-(((m=t==null?void 0:t.wind)==null?void 0:m.degree)%360||0));n=n>180?360-n:n;const s=C.directionFactor(n,(f=t==null?void 0:t.wind)==null?void 0:f.scale),d=C.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(h=t==null?void 0:t.wind)==null?void 0:h.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)),v==null||v.debug("wind wx factor = %d",r),n=Math.abs(e.bearing%360-(((g=(u=t==null?void 0:t.wave)==null?void 0:u.sig)==null?void 0:g.degree)%360||0));const l=C.waveHeightFactor(((y=(j=t==null?void 0:t.wave)==null?void 0:j.sig)==null?void 0:y.height)??1,n);return v==null||v.debug("wave wx factor = %d",l),r=r*.4+l,v==null||v.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(e,t,o,i,a,n="",s=0,d=!0,r=!1,l={}){var Z,z,U,Q,J;const m=I().valueOf();e.lng=R.LngLatHelper.convertToStdLng(e.lng);const{route:f,waypoints:h}=a.points,u=R.LaneHelper.calculateSubRoute(e,f);if(((Z=u[0])==null?void 0:Z.length)<=1)return;const{v0:g,label:j}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},y=C.assembleProperties(o,i.loadCondition,g,0),p=h.length?R.LaneHelper.calculateSubWaypoints(e,h):[];p.forEach(H=>H.important=!0);const c={from:{...e},route:u,waypoints:p,v0:g,label:j},b={hours:[],days:[],wps:[]};s||(R.LaneHelper.calculateRouteDistance(u)/i.speed<=72?s=3:s=6);let D=R.LaneHelper.simplifyRouteToCoordinates(u,p,0),w=0,k=0,S=0,x=0;t=I(t).utc();const L=t.clone();for(;D.length>0;){const H=s-t.hour()%s,F=Math.ceil(t.clone().add(H,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,O=await C.speedLoseInHoursStep(y,t,L,F,w,D,n,d,r,l);(z=O.from)!=null&&z.speed&&(b.hours.push(O.from),b.wps.push(...O.wps),b.days.push(...O.days)),D=O==null?void 0:O.next,D.length||b.hours.push(O==null?void 0:O.to),w+=Math.round((((U=O==null?void 0:O.to)==null?void 0:U.distanceFromPrevious)??0)*1e4)/1e4}const W=b.hours;for(let H=0;H<W.length-1;H++){const F=I(W[H+1].eta).diff(W[H].etd,"hour",!0)||1;k+=(W[H].wxFactor||0)*F,S+=(W[H].cFactor||0)*F,x+=F}(Q=b.wps)==null||Q.forEach((H,F)=>{if(F){const O=b.wps[F-1],ft=H.distanceFromStart-O.distanceFromStart,nt=I(H.eta).diff(I(O.etd),"h",!0);if(nt<1)H.avgSpd=O.speed;else{H.avgSpd=Math.round(ft/nt*100)/100;const it=Math.round((O.speed+H.speed)/2*100)/100;H.avgSpd=H.avgSpd>it?it:H.avgSpd}}}),c.sample=b;const E=b.hours.at(0),B=b.hours.at(-1);c.distance=Math.round(B.distanceFromStart*1e4)/1e4,c.etd=I(E.eta).utc().format(),c.eta=I(B.eta).utc().format(),c.wxFactor=Math.round(k/x*1e4)/1e4,c.cFactor=Math.round(S/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 P=I().valueOf()-m,A=((J=b==null?void 0:b.hours)==null?void 0:J.length)||1;return v==null||v.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,P,A,Math.round(P/A*1e3)/1e3),c}static async analyseInstantWithThreshed(e,t,o,i,a,n,s,d="",r=3,l=!0,m=!1,f={}){var Z,z,U,Q;const h=I().valueOf();e.lng=R.LngLatHelper.convertToStdLng(e.lng);const{v0:u,label:g}=e.sog?{v0:e.sog,label:"Other"}:{v0:a.speed,label:"CP"},j=C.assembleProperties(i,a.loadCondition,u,0),y=R.LaneHelper.calculateSubRoute(e,n);if(((Z=y[0])==null?void 0:Z.length)<=1)return;const p=s.length?R.LaneHelper.calculateSubWaypoints(e,s):[];p.forEach(J=>J.important=!0);let c=R.LaneHelper.simplifyRouteToCoordinates(y,p,0),b=0,D=0,w=0,k=0;const S={hours:[],wps:[],days:[]};t=I(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;if(H=t.clone().add(H,"h").isAfter(o)?o.diff(t,"h",!0)*1e4/1e4:H,H){const F=await C.speedLoseInHoursStep(j,t,x,H,b,c,d,l,m,f);(z=F.from)!=null&&z.speed&&(S.hours.push(F.from),F!=null&&F.wps&&S.wps.push(...F.wps),S.days.push(...F.days)),c=F==null?void 0:F.next,c.length||S.hours.push(F==null?void 0:F.to),b+=Math.round((((U=F==null?void 0:F.to)==null?void 0:U.distanceFromPrevious)??0)*1e4)/1e4}else break}const L=S.hours;for(let J=0;J<L.length-1;J++){const H=I(L[J+1].eta).diff(L[J].etd,"hour",!0);D+=L[J].wxFactor*H,w+=L[J].cFactor*H,k+=H}const W=S.hours.at(0),E=S.hours.at(-1),B={sample:S,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:I(W.eta).utc().format(),eta:I(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(D/k*1e4)/1e4,cFactor:Math.round(w/k*1e4)/1e4,avgSpeed:Math.round(((E==null?void 0:E.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:W,to:E,route:y,waypoints:p,v0:u,label:g},P=I().valueOf()-h,A=((Q=S==null?void 0:S.hours)==null?void 0:Q.length)||1;return v==null||v.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",f==null?void 0:f.requestId,P,A,Math.round(P/A*1e3)/1e3),B}static async analyseCost(e,t,o,i,a={}){var g,j;const n=I().valueOf(),s=[];a.meteo2=!0,e.speedStep=e.speedStep||3;const d=I.utc(e.etd).add(14,"day");let r=1;for(const y of o){v==null||v.info("[%s][L%d-%d] analyse from %s to %s",a.requestId,1,r,e.etd,d.format()),v==null||v.info("[%s][L%d-%d] analyse with cp: %j",a.requestId,1,r,y);const p=JSON.parse(JSON.stringify(i.route)),c=JSON.parse(JSON.stringify(i.waypoints)),b=await C.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,d,t,y,p,c,e.meteoVendor,e.speedStep,!1,e.useRouteParam,a);b&&(await C.calculateCost(b,y,e,a),s.push(b),v==null||v.info("[%s][L%d-%d] cost: %j",a.requestId,1,r,{distance:b.distance,totalHrs:b.totalHrs,totalFoCons:b.totalFoCons,totalDgoCons:b.totalDgoCons,etd:b.etd,eta:b.eta,cost:b.cost})),r++}s.sort((y,p)=>y.cost.total-p.cost.total);const l=s.at(0),m=s.at(1),f=[];if(f.push({combined:!1,speeds:[l],cost:(g=l.cost)==null?void 0:g.total}),m){const y=l.cost.cp,p=m.cost.cp,c=I(l.eta),b=I(l.etd),D=c.diff(b,"days",!0);let w=Math.ceil(D/2);w=w>7?7:w;let k=2,S={combined:!1,speeds:[m],cost:(j=m.cost)==null?void 0:j.total},x;for(;w>=1&&(x=await C.combinedAnalyse(e,t,d,[y,p],i,w,{...a,level:k}),!(S.cost<x.cost));){const L=S;if(S=x,w===1){x=L;break}x=void 0,w=Math.ceil(w/2),k+=1}f.push(S),x&&f.push(x)}const u=I().valueOf()-n;return v==null||v.info("[%s] analyse elapsed: %d ms",a==null?void 0:a.requestId,u),f.sort((y,p)=>y.cost-p.cost)}static async combinedAnalyse(e,t,o,i,a,n,s={}){v==null||v.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,n);const d=await C.alternateAnalyse(e,t,o,i,0,a,n,s),r=d.reduce((f,h)=>f+h.cost.total,0);v==null||v.info("[%s][L%d] cost with alternate cp a first: %j",s.requestId,s.level,{cost:r});const l=await C.alternateAnalyse(e,t,o,i,1,a,n,s),m=l.reduce((f,h)=>f+h.cost.total,0);return v==null||v.info("[%s][L%d] cost with alternate cp b first: %j",s.requestId,s.level,{cost:m}),r<m?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d}:{combined:!0,cost:Math.round(m*1e3)/1e3,speeds:l}}static async alternateAnalyse(e,t,o,i,a,n,s,d={}){var h,u;let r=I.utc(e.etd),l=1;const m={lat:e.lat,lng:e.lng},f=[];for(;r.isBefore(o);){const g=r.clone().utc().add(s,"day");v==null||v.info("[%s][L%d-%d] analyse from %s to %s",d.requestId,d.level,l,e.etd,g.format()),v==null||v.info("[%s][L%d-%d] analyse with cp: %j",d.requestId,d.level,l,i[a]);const j=JSON.parse(JSON.stringify(n.route)),y=JSON.parse(JSON.stringify(n.waypoints)),p=await C.analyseInstantWithThreshed(m,r.format(),g,t,i[a],j,y,e.meteoVendor,e.speedStep,!1,e.useRouteParam,d);p&&(await C.calculateCost(p,i[a],e,d),v==null||v.info("[%s][L%d-%d] cost: %j",d.requestId,d.level,l,{distance:p.distance,totalHrs:p.totalHrs,totalFoCons:p.totalFoCons,totalDgoCons:p.totalDgoCons,etd:p.etd,eta:p.eta,cost:p.cost}));const c=(u=(h=p==null?void 0:p.sample)==null?void 0:h.hours)==null?void 0:u.at(-1);if(c)m.lat=c.lat,m.lng=c.lng,r=I(c.eta),f.push(p),l+=1,a=a?0:1;else break}return f}static async calculateCost(e,t,o,i={}){if(e){const a=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,n=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,s=Math.round(e.totalDgoCons*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((a+n+s)*1e3)/1e3,hire:a,bunker:Math.round((n+s)*1e3)/1e3,cp:t}}return e}static async mergeSpeeds(e,t={}){const o={hours:[],wps:[],days:[]},i=e.reduce((h,u)=>h+u.distance,0),a=e.reduce((h,u)=>h+u.totalHrs,0),n=e.reduce((h,u)=>h+u.wxFactor*u.totalHrs/a,0),s=e.reduce((h,u)=>h+u.cFactor*u.totalHrs/a,0),d=e.reduce((h,u)=>h+u.totalFoCons,0),r=e.reduce((h,u)=>h+u.totalDgoCons,0),l=e.reduce((h,u)=>h+u.cost.total,0),m=e.reduce((h,u)=>h+u.cost.hire,0),f=e.reduce((h,u)=>h+u.cost.bunker,0);for(const h of e){const u=h.sample.hours,g=h.sample.wps,j=h.sample.days;u.forEach(y=>{var c;((c=o.hours)==null?void 0:c.findIndex(b=>b.eta===y.eta))===-1&&o.hours.push(y)}),g.forEach(y=>{var c;((c=o.wps)==null?void 0:c.findIndex(b=>b.eta===y.eta))===-1&&o.wps.push(y)}),j.forEach(y=>{var c;((c=o==null?void 0:o.days)==null?void 0:c.findIndex(b=>b.eta===y.eta))===-1&&o.days.push(y)})}return{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,label:"combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(i/a*1e3)/1e3,wxFactor:Math.round(n/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(l*1e3)/1e3,hire:Math.round(m*1e3)/1e3,bunker:Math.round(f*1e3)/1e3}}}}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=C,T.SpeedLabel=ot,T.VesselTag=st,T.alertHelper=ht,Object.defineProperty(T,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(T,N){typeof exports=="object"&&typeof module<"u"?N(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"],N):(T=typeof globalThis<"u"?globalThis:T||self,N(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,N,K,g,R,X,$){"use strict";var mt=Object.defineProperty;var yt=(T,N,K)=>N in T?mt(T,N,{enumerable:!0,configurable:!0,writable:!0,value:K}):T[N]=K;var _=(T,N,K)=>(yt(T,typeof N!="symbol"?N+"":N,K),K);let M;try{M=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class rt extends G{constructor(t,o){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},a=await N.post(o,i).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,o,a),a.error||(this.token={accessToken:a.access_token,tokenType:a.token_type,expiresIn:a.expires_in,scope:a.scope,jti:a.jti,issuedAt:g().utc().format()})}async realTimePosition(t,o={}){var l,m,f;(!this.token||g().diff(g(this.token.issuedAt),"seconds")>((l=this.token)==null?void 0:l.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",a={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(f=this.token)==null?void 0:f.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,a);const n=await N.get(i,a).json();if(n.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:n.message,status:n.status,code:n.code}),n;const s=n.data;for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const d=g(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName,imo:s.imo,callSign:s.callsign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?g.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,a,n=!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(o),l=g(i),m=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,a,m,s),r.add(30,"day");return await this.trajectoryIn30Day(t,r,l,d,a,m,s),m}async trajectoryIn30Day(t,o,i,a,n,s,d={}){var u,I,j,y,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(u=this.token)==null?void 0:u.tokenType} ${(I=this.token)==null?void 0:I.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,l);const m=await N.post(r,l).json();if(m.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:m.message,status:m.status,code:m.code}),m;let f=-1;const h=g(`${(y=(j=m.data)==null?void 0:j[0])==null?void 0:y.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=m.data)==null||v.forEach(c=>{for(const L in c)!isNaN(c[L])&&Number(c[L])!==1/0&&(c[L]=Number(c[L]));const b=g(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),D=c.status,{labelCn:p,labelEn:k}=this.parseStatus(D),S={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:D,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:b.unix(),labelCn:p,labelEn:k,method:"trajectory",vendor:"myVessel",utc:b.utc().format()},x=Math.floor(b.diff(h,"minute",!0)/(n||1));x!==f&&(f=x,s.push(S))}),s}}class ct extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",a={searchParams:{mmsi:t,usertoken:this.token}},n=await N.post(i,a).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,a);const s=n==null?void 0:n.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",o.requestId,i,n),n;for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:l}=this.parseStatus(d),m=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:m.unix(),utc:m.utc().format(),status:d,labelCn:r,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,o={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const a={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let n=await N.post(i,a).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,a),n instanceof Array&&(n=n[0]);for(const d in n)!isNaN(n[d])&&Number(n[d])!==1/0&&(n[d]=Number(n[d]));const s={mmsi:n.m,name:n.n,imo:n.i,callSign:n.c,length:n.l,breadth:n.b,draught:n.dr,type:n.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",n=await N.post(i,a).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,a),n instanceof Array&&(n=n[0]),n&&(s.deadweight=Number(n.dwt)),s}async suggest(t,o={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",a={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},n=await N.post(i,a).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,a);const s=[];for(const d of n)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(t,o,i,a,n=!0,s={}){var c,b,D;const d=await this.realTimePosition(t,s);let r=g(o);const l=g(i),m=g();if(n){let p=l.diff(r,"d",!0);p<0?r=l.clone().subtract(40,"d"):p<30?r.subtract(10,"d"):p<60?r.subtract(5,"d"):r=l.clone().subtract(80,"d"),p=m.diff(l,"d",!0),l.add(p>10?240:p*24,"h")}const f={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},h="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",u=await N.get(h,f).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,h,f);let I;u&&(I=((b=(c=u.ships)==null?void 0:c.offors)==null?void 0:b.ship)||[],I.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,u));const j=[];let y=-1;const v=g(`${(D=I==null?void 0:I[0])==null?void 0:D.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const p of I){for(const E in p)!isNaN(p[E])&&Number(p[E])!==1/0&&(p[E]=Number(p[E]));const k=g(`${p.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");p.status=p.sp>4?0:1;const{labelEn:S,labelCn:x}=this.parseStatus(p.status),L={mmsi:p.m,name:p.n,imo:d==null?void 0:d.imo,lat:p.la,lng:p.lo,draught:p.draught,sog:p.sp,cog:p.co,hdg:p.hdg,positionTime:k.unix(),utc:k.utc().format(),status:p.status,labelCn:x,labelEn:S,method:"trajectory",vendor:"hifleet"},W=Math.floor(k.diff(v,"minute",!0)/(a||1));W!==y&&(y=W,j.push(L))}return j}}class dt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},a="https://api.shipxy.com/apicall/GetSingleShip",n=await N.get(a,i).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,a,i),(n==null?void 0:n.status)!==0)return n;const s=n.data[0];for(const f in s)!isNaN(s[f])&&Number(s[f])!==1/0&&(s[f]=Number(s[f]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),l=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:l.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,a,n=!0,s={}){var v;const d=await this.realTimePosition(t,s),r=g(o),l=g(i),m="https://api.shipxy.com/apicall/GetShipTrack",f={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:l.unix()}},h=await N.get(m,f).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,m,f),(h==null?void 0:h.status)!==0)return h;const u=h==null?void 0:h.points,I=[],j=g.unix((v=u[0])==null?void 0:v.utc);let y=-1;for(const c of u){const b=g.unix(c.utc),D={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:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"shipxy"},p=Math.floor(b.diff(j,"minute",!0)/(a||1));p!==y&&(y=p,I.push(D))}return I}}class ut extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},a="https://api3.myships.com/sp/ships/getShipIdByMMSI",n=await N.post(a,i).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",o.requestId,a,i),n.code!=="0"?n:n.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},a="https://api3.myships.com/sp/ships/aissta",n=await N.post(a,i).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",o.requestId,a,i),n.code!=="0")return n;const s=n.data;let d=s.imo;return t==="407170"&&(d="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),a=await this.getShipInfo(i,o),n={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await N.post(s,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,n);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:l,labelEn:m}=await this.parseStatus(r.aisNavStatus),f=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:f.utc().format(),status:r.aisNavStatus,labelEn:m,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,o,i,a,n=!0,s={}){const d=g(o),r=g(i),l=await this.getShipId(t),m=await this.getShipInfo(l),f=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(l,d.unix(),d.add(30,"day").unix(),m,t,a,f);return await this.trajectoryIn30Day(l,d.unix(),r.unix(),m,t,a,f),f}async trajectoryIn30Day(t,o,i,a,n,s,d,r={}){var j;const l={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},m="https://api3.myships.com/sp/ships/position/history",f=await N.post(m,l).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,m,l),f.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",r.requestId,f),f;const h=f.data;for(const y in h)!isNaN(h[y])&&Number(h[y])!==1/0&&(h[y]=Number(h[y]));const u=g.unix((j=h[0])==null?void 0:j.posTime);let I=-1;for(const y of h){const v=g.unix(y.posTime),c={imo:a==null?void 0:a.imo,mmsi:n,lat:Math.round(y.lat/1e4/60*1e5)/1e5,lng:Math.round(y.lon/1e4/60*1e5)/1e5,sog:Math.round(y.sog/10*100)/100,cog:Math.round(y.cog/10*100)/100,hdg:Math.round(y.heading*100)/100,rot:Math.round(y.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},b=Math.floor(v.diff(u,"minute",!0)/(s||1));b!==I&&(I=b,d.push(c))}return d}}let V;try{V=K.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 o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,a=i==null?void 0:i.split(";");if(!a)return;const n={};for(let l=0;l<(a==null?void 0:a.length);l++){const m=(r=(d=a[l].match(o))==null?void 0:d[0])==null?void 0:r.split("],");if(l===0&&!m)n.scope=a[0];else if(m)for(let f=0,h=m.length;f<h;f++){const u=this.parseRule(m[f]);u&&(n[u.level]?u.key?n[u.level][u==null?void 0:u.key]=u:n[u.level]=u:u.key?n[u.level]={[u==null?void 0:u.key]:u}:n[u.level]=u)}}return n}parseRule(e,t={}){var n;V==null||V.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(n=e==null?void 0:e.match(o))==null?void 0:n[0],a=i==null?void 0:i.split(",");if(a)return{operator:a[0],number:Number.isNaN(Number(a[1]))?a[1]:Number(a[1]),level:a[2],time:Number(a[3]),key:a[4]}}checkWeather(e,t,o={}){var u,I,j,y,v,c,b,D,p,k,S,x,L,W,E;let i=0,a=0,n=0,s=0;const d=Math.round(((I=(u=t==null?void 0:t.SEVERE)==null?void 0:u.sigWave)==null?void 0:I.number)*1.6*100)/100,r=(y=(j=t==null?void 0:t.SEVERE)==null?void 0:j.sigWave)==null?void 0:y.number,l=(c=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,m=Math.round((((D=(b=t==null?void 0:t.SEVERE)==null?void 0:b.wind)==null?void 0:D.number)+2)*100)/100,f=(k=(p=t==null?void 0:t.SEVERE)==null?void 0:p.wind)==null?void 0:k.number,h=(x=(S=t==null?void 0:t.HEAVY)==null?void 0:S.wind)==null?void 0:x.number;for(let B=0;B<(e==null?void 0:e.length);B++){const q=e[B],P=(W=(L=q==null?void 0:q.meteo)==null?void 0:L.wave)==null?void 0:W.sig,A=(E=q==null?void 0:q.meteo)==null?void 0:E.wind,Z=B?g(q.eta).diff(g(e[B-1].eta),"hour",!0):0;s=Z>s?Z:s,V==null||V.info("[%s] check sig.wave: %j",o.requestId,{...P,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}),(P==null?void 0:P.height)>=d?q.isDangerous=!0:(P==null?void 0:P.height)>=r?q.isSevere=!0:(P==null?void 0:P.height)>=l&&(q.isHeavy=!0),V==null||V.info("[%s] check wind: %j",o.requestId,{...A,dgThd4Wd:m,svThd4Wd:f,hvThd4Wd:h}),(A==null?void 0:A.scale)>=m?(q.isDangerous=!0,delete q.isSevere,delete q.isHeavy):(A==null?void 0:A.scale)>f?(q.isDangerous||(q.isSevere=!0),delete q.isHeavy):(A==null?void 0:A.scale)===h&&!q.isDangerous&&!q.isSevere&&(q.isHeavy=!0),i+=q.isDangerous?Z:0,a+=q.isSevere?Z:0,n+=q.isHeavy?Z:0}return i=Math.round(i*100)/100,a=Math.round(a*100)/100,n=Math.round(n*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:a,heavy:n,step:s<3?3:s,wind:{dgThd4Wd:m,svThd4Wd:f,hvThd4Wd:h},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}}}}const ht=new et;let w;try{w=K.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||{}),ot=(Y=>(Y.Cp="CP",Y.Perf="Basis",Y.Instruct="Other",Y))(ot||{});class C{static blockCoefficient(e,t,o,i){let a=Math.round(e/(t*o*i)*100)/100;a=a<.55?.55:a>.85?.85:a;const n=[.55,.6,.65,.7,.75,.8,.85],s=n.map(d=>Math.abs(d-a));return n[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(n=i[e]),n[0]+n[1]*t+n[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let a;return o==="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 o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var f;const a=e.lbp??e.length??e.lengthOverall??198.9642,n=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,r=((f=e==null?void 0:e.type)==null?void 0:f.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:a,loadCondition:t,draught:n,breadthMoulded:s,displacement:Math.round((d/1.025+n*s*a*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",a=2,n=!0,s=!1,d={}){let r;if(t.velocity&&s&&(e.speed=R.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),n){let l;if(d.meteo2)try{const u=await lt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[I]=$.Meteo2Assist.pickHourly(u,o);l=$.Meteo2Assist.toLegacy(I)}catch(u){w.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},u)}else l=await X.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const m=C.weatherFactor(e,l),f=C.currentFactor(e.bearing,l==null?void 0:l.current,a),h=Math.round((e.speed*1.943844+m+f)*100)/100;r={meteo:{...l},wxFactor:m,cFactor:f,speed:t.velocity&&s?t.velocity:h<0?1:h,eta:o.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:o.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:o.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:o.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(e,t,o,i,a,n,s="",d=!0,r=!1,l={}){t.utc();const m=t.clone().add(14,"days"),f=[],h=[];let u=0,I=0,j,y;for(let v=0;v<n.length-1;v++){let c=n[v];c.distanceFromStart=Math.round((a+I)*1e4)/1e4;const b=n[v+1];if(e.bearing=R.LaneHelper.calculateBearing(c,b,!b.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 S=i-u;c.elapsed+=S,t.add(S,"hour"),i=0}if(w==null||w.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=I,{etd:t,from:y||c,to:c,next:n.filter(S=>S),wps:f,days:h}}else c.suspend=0;d=t.isAfter(m)?!1:d,c=await C.speedLoseAt(e,c,t,s,0,d,r,l),y=y||c,c.important&&f.push(c),t.isSameOrAfter(o)&&(h.push(c),o.add(24,"hour"));const D=R.LaneHelper.calculateDistance(c,b,!b.gcToPrevious);let p=Math.ceil(D/y.speed*1e4)/1e4;if(u+p<i){if(u+=p,t.add(p,"hour"),delete n[v],w==null||w.debug(`[%s] go to %j from %j with ${D}nm, and cost ${p} hours`,l.requestId,{lat:b.lat,lng:b.lng},{lat:y.lat,lng:y.lng,etd:y.etd}),I+=D,n.filter(k=>k).length<=1){j=b,j.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),j.distanceFromPrevious=D,j.distanceFromStart=Math.round((a+I)*1e4)/1e4,f.push(j),delete n[v+1];break}}else{p=i-u,t.add(p,"hour");const k=R.LngLatHelper.roundPrecision(y.speed*p,4);j=R.LaneHelper.calculateCoordinate(c,e.bearing,k,"nauticalmiles",!b.gcToPrevious),j.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),n[v]=j,w==null||w.debug(`[%s] go to %j from %j with ${k}nm, and cost ${p} hours`,l.requestId,{lat:j.lat,lng:j.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),I+=k,j.distanceFromPrevious=Math.round(I*1e4)/1e4,j.distanceFromStart=Math.round((a+I)*1e4)/1e4;break}}return{etd:t,from:y,to:j,next:n.filter(v=>v),wps:f,days:h}}static currentFactor(e,t,o=0){const i=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let a=((t==null?void 0:t.kts)||0)*Math.cos(i);return o&2?a=Math.ceil(a*100)/100:o&1?a=Math.floor(a*100)/100:a=Math.round(a*100)/100,Math.abs(a)>5?0:a}static weatherFactor(e,t){var m,f,h,u,I,j,y;w==null||w.debug("calculate weather factor via: %j",{...e,...t});const o=C.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=C.froudeNumber(e.speed,e.lbp),a=C.amendFactor(o,i,e.loadCondition);let n=Math.abs(e.bearing%360-(((m=t==null?void 0:t.wind)==null?void 0:m.degree)%360||0));n=n>180?360-n:n;const s=C.directionFactor(n,(f=t==null?void 0:t.wind)==null?void 0:f.scale),d=C.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(h=t==null?void 0:t.wind)==null?void 0:h.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)),w==null||w.debug("wind wx factor = %d",r),n=Math.abs(e.bearing%360-(((I=(u=t==null?void 0:t.wave)==null?void 0:u.sig)==null?void 0:I.degree)%360||0));const l=C.waveHeightFactor(((y=(j=t==null?void 0:t.wave)==null?void 0:j.sig)==null?void 0:y.height)??1,n);return w==null||w.debug("wave wx factor = %d",l),r=r*.4+l,w==null||w.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(e,t,o,i,a,n="",s=0,d=!0,r=!1,l={}){var Z,z,U,Q,J;const m=g().valueOf();e.lng=R.LngLatHelper.convertToStdLng(e.lng);const{route:f,waypoints:h}=a.points,u=R.LaneHelper.calculateSubRoute(e,f);if(((Z=u[0])==null?void 0:Z.length)<=1)return;const{v0:I,label:j}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},y=C.assembleProperties(o,i.loadCondition,I,0),v=h.length?R.LaneHelper.calculateSubWaypoints(e,h):[];v.forEach(H=>H.important=!0);const c={from:{...e},route:u,waypoints:v,v0:I,label:j},b={hours:[],days:[],wps:[]};s||(R.LaneHelper.calculateRouteDistance(u)/i.speed<=72?s=3:s=6);let D=R.LaneHelper.simplifyRouteToCoordinates(u,v,0),p=0,k=0,S=0,x=0;t=g(t).utc();const L=t.clone();for(;D.length>0;){const H=s-t.hour()%s,F=Math.ceil(t.clone().add(H,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,O=await C.speedLoseInHoursStep(y,t,L,F,p,D,n,d,r,l);(z=O.from)!=null&&z.speed&&(b.hours.push(O.from),b.wps.push(...O.wps),b.days.push(...O.days)),D=O==null?void 0:O.next,D.length||b.hours.push(O==null?void 0:O.to),p+=Math.round((((U=O==null?void 0:O.to)==null?void 0:U.distanceFromPrevious)??0)*1e4)/1e4}const W=b.hours;for(let H=0;H<W.length-1;H++){const F=g(W[H+1].eta).diff(W[H].etd,"hour",!0)||1;k+=(W[H].wxFactor||0)*F,S+=(W[H].cFactor||0)*F,x+=F}(Q=b.wps)==null||Q.forEach((H,F)=>{if(F){const O=b.wps[F-1],ft=H.distanceFromStart-O.distanceFromStart,nt=g(H.eta).diff(g(O.etd),"h",!0);if(nt<1)H.avgSpd=O.speed;else{H.avgSpd=Math.round(ft/nt*100)/100;const it=Math.round((O.speed+H.speed)/2*100)/100;H.avgSpd=H.avgSpd>it?it:H.avgSpd}}}),c.sample=b;const E=b.hours.at(0),B=b.hours.at(-1);c.distance=Math.round(B.distanceFromStart*1e4)/1e4,c.etd=g(E.eta).utc().format(),c.eta=g(B.eta).utc().format(),c.wxFactor=Math.round(k/x*1e4)/1e4,c.cFactor=Math.round(S/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 P=g().valueOf()-m,A=((J=b==null?void 0:b.hours)==null?void 0:J.length)||1;return w==null||w.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,P,A,Math.round(P/A*1e3)/1e3),c}static async analyseInstantWithThreshed(e,t,o,i,a,n,s,d="",r=3,l=!0,m=!1,f={}){var Z,z,U,Q;const h=g().valueOf();e.lng=R.LngLatHelper.convertToStdLng(e.lng);const{v0:u,label:I}=e.sog?{v0:e.sog,label:"Other"}:{v0:a.speed,label:"CP"},j=C.assembleProperties(i,a.loadCondition,u,0),y=R.LaneHelper.calculateSubRoute(e,n);if(((Z=y[0])==null?void 0:Z.length)<=1)return;const v=s.length?R.LaneHelper.calculateSubWaypoints(e,s):[];v.forEach(J=>J.important=!0);let c=R.LaneHelper.simplifyRouteToCoordinates(y,v,0),b=0,D=0,p=0,k=0;const S={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;if(H=t.clone().add(H,"h").isAfter(o)?o.diff(t,"h",!0)*1e4/1e4:H,H){const F=await C.speedLoseInHoursStep(j,t,x,H,b,c,d,l,m,f);(z=F.from)!=null&&z.speed&&(S.hours.push(F.from),F!=null&&F.wps&&S.wps.push(...F.wps),S.days.push(...F.days)),c=F==null?void 0:F.next,c.length||S.hours.push(F==null?void 0:F.to),b+=Math.round((((U=F==null?void 0:F.to)==null?void 0:U.distanceFromPrevious)??0)*1e4)/1e4}else break}const L=S.hours;for(let J=0;J<L.length-1;J++){const H=g(L[J+1].eta).diff(L[J].etd,"hour",!0);D+=L[J].wxFactor*H,p+=L[J].cFactor*H,k+=H}const W=S.hours.at(0),E=S.hours.at(-1),B={sample:S,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:g(W.eta).utc().format(),eta:g(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(D/k*1e4)/1e4,cFactor:Math.round(p/k*1e4)/1e4,avgSpeed:Math.round(((E==null?void 0:E.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:W,to:E,route:y,waypoints:v,v0:u,label:I},P=g().valueOf()-h,A=((Q=S==null?void 0:S.hours)==null?void 0:Q.length)||1;return w==null||w.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",f==null?void 0:f.requestId,P,A,Math.round(P/A*1e3)/1e3),B}static async analyseCost(e,t,o,i,a={}){var I,j;const n=g().valueOf(),s=[];a.meteo2=!0,e.speedStep=e.speedStep||3;const d=g.utc(e.etd).add(14,"day");let r=1;for(const y of o){w==null||w.info("[%s][L%d-%d] analyse from %s to %s",a.requestId,1,r,e.etd,d.format());const v=JSON.parse(JSON.stringify(i.route)),c=JSON.parse(JSON.stringify(i.waypoints)),b=await C.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,d,t,y,v,c,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,a);b&&(await C.calculateCost(b,y,e,a),s.push(b),w==null||w.info("[%s][L%d-%d] cost: %j",a.requestId,1,r,{distance:b.distance,totalHrs:b.totalHrs,totalFoCons:b.totalFoCons,totalDgoCons:b.totalDgoCons,etd:b.etd,eta:b.eta,cost:b.cost})),r++}s.sort((y,v)=>y.cost.total-v.cost.total);const l=s.at(0),m=s.at(1),f=[];if(f.push({combined:!1,speeds:[l],cost:(I=l.cost)==null?void 0:I.total}),m){const y=l.cost.cp,v=m.cost.cp,c=g(l.eta),b=g(l.etd),D=c.diff(b,"days",!0);let p=Math.ceil(D/2);p=p>7?7:p;let k=2,S={combined:!1,speeds:[m],cost:(j=m.cost)==null?void 0:j.total},x;for(;p>=1&&(x=await C.combinedAnalyse(e,t,d,[y,v],i,p,{...a,level:k}),!(S.cost<x.cost));){const L=S;if(S=x,p===1){x=L;break}x=void 0,p=Math.ceil(p/2),k+=1}f.push(S),x&&f.push(x)}const u=g().valueOf()-n;return w==null||w.info("[%s] analyse elapsed: %d ms",a==null?void 0:a.requestId,u),f.sort((y,v)=>y.cost-v.cost)}static async combinedAnalyse(e,t,o,i,a,n,s={}){w==null||w.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,n);const d=await C.alternateAnalyse(e,t,o,i,0,a,n,s),r=d.reduce((f,h)=>f+h.cost.total,0);w==null||w.info("[%s][L%d] cost with alternate cp a first: %j",s.requestId,s.level,{cost:r});const l=await C.alternateAnalyse(e,t,o,i,1,a,n,s),m=l.reduce((f,h)=>f+h.cost.total,0);return w==null||w.info("[%s][L%d] cost with alternate cp b first: %j",s.requestId,s.level,{cost:m}),r<m?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d}:{combined:!0,cost:Math.round(m*1e3)/1e3,speeds:l}}static async alternateAnalyse(e,t,o,i,a,n,s,d={}){var h,u;let r=g.utc(e.etd),l=1;const m={lat:e.lat,lng:e.lng},f=[];for(;r.isBefore(o);){const I=r.clone().utc().add(s,"day");w==null||w.info("[%s][L%d-%d] analyse from %s to %s",d.requestId,d.level,l,e.etd,I.format());const j=JSON.parse(JSON.stringify(n.route)),y=JSON.parse(JSON.stringify(n.waypoints)),v=await C.analyseInstantWithThreshed(m,r.format(),I,t,i[a],j,y,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,d);v&&(await C.calculateCost(v,i[a],e,d),w==null||w.info("[%s][L%d-%d] cost: %j",d.requestId,d.level,l,{distance:v.distance,totalHrs:v.totalHrs,totalFoCons:v.totalFoCons,totalDgoCons:v.totalDgoCons,etd:v.etd,eta:v.eta,cost:v.cost}));const c=(u=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:u.at(-1);if(c)m.lat=c.lat,m.lng=c.lng,r=g(c.eta),f.push(v),l+=1,a=a?0:1;else break}return f}static async calculateCost(e,t,o,i={}){if(e){const a=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,n=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,s=Math.round(e.totalDgoCons*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((a+n+s)*1e3)/1e3,hire:a,bunker:Math.round((n+s)*1e3)/1e3,cp:t}}return e}static async mergeSpeeds(e,t={}){const o={hours:[],wps:[],days:[]},i=e.reduce((h,u)=>h+u.distance,0),a=e.reduce((h,u)=>h+u.totalHrs,0),n=e.reduce((h,u)=>h+u.wxFactor*u.totalHrs/a,0),s=e.reduce((h,u)=>h+u.cFactor*u.totalHrs/a,0),d=e.reduce((h,u)=>h+u.totalFoCons,0),r=e.reduce((h,u)=>h+u.totalDgoCons,0),l=e.reduce((h,u)=>h+u.cost.total,0),m=e.reduce((h,u)=>h+u.cost.hire,0),f=e.reduce((h,u)=>h+u.cost.bunker,0);for(const h of e){const u=h.sample.hours,I=h.sample.wps,j=h.sample.days;u.forEach(y=>{var c;((c=o.hours)==null?void 0:c.findIndex(b=>b.eta===y.eta))===-1&&o.hours.push(y)}),I.forEach(y=>{var c;((c=o.wps)==null?void 0:c.findIndex(b=>b.eta===y.eta))===-1&&o.wps.push(y)}),j.forEach(y=>{var c;((c=o==null?void 0:o.days)==null?void 0:c.findIndex(b=>b.eta===y.eta))===-1&&o.days.push(y)})}return{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,label:"combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(i/a*1e3)/1e3,wxFactor:Math.round(n/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(l*1e3)/1e3,hire:Math.round(m*1e3)/1e3,bunker:Math.round(f*1e3)/1e3}}}}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=C,T.SpeedLabel=ot,T.VesselTag=st,T.alertHelper=ht,Object.defineProperty(T,Symbol.toStringTag,{value:"Module"})});
|