@idm-plugin/vessel 3.4.3 → 3.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +251 -250
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var mt = Object.defineProperty;
|
|
2
|
-
var ft = (N,
|
|
3
|
-
var U = (N,
|
|
2
|
+
var ft = (N, s, t) => s in N ? mt(N, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : N[s] = t;
|
|
3
|
+
var U = (N, s, t) => (ft(N, typeof s != "symbol" ? s + "" : s, t), t);
|
|
4
4
|
import B from "got";
|
|
5
5
|
import ut from "@log4js-node/log4js-api";
|
|
6
6
|
import p from "moment";
|
|
@@ -18,9 +18,9 @@ class nt {
|
|
|
18
18
|
* 解析AIS状态码
|
|
19
19
|
* @param status
|
|
20
20
|
*/
|
|
21
|
-
parseStatus(
|
|
21
|
+
parseStatus(s) {
|
|
22
22
|
let t, a;
|
|
23
|
-
switch (
|
|
23
|
+
switch (s) {
|
|
24
24
|
case 0:
|
|
25
25
|
t = "在航(主机推动)", a = "Underway Using Engine";
|
|
26
26
|
break;
|
|
@@ -89,11 +89,11 @@ class Et extends nt {
|
|
|
89
89
|
* @param options
|
|
90
90
|
*/
|
|
91
91
|
async suggest(t, a = {}) {
|
|
92
|
-
var
|
|
92
|
+
var e, r;
|
|
93
93
|
await this.checkToken(a);
|
|
94
94
|
const i = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", n = {
|
|
95
95
|
headers: {
|
|
96
|
-
Authorization: `${(
|
|
96
|
+
Authorization: `${(e = this.token) == null ? void 0 : e.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
97
97
|
},
|
|
98
98
|
json: {
|
|
99
99
|
kw: t,
|
|
@@ -122,14 +122,14 @@ class Et extends nt {
|
|
|
122
122
|
async search(t, a = {}) {
|
|
123
123
|
var d, h;
|
|
124
124
|
await this.checkToken(a);
|
|
125
|
-
const i = /^\d{7}$/.test(t.toString()), n = i ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", o = i ? { imo: t } : { mmsi: t },
|
|
125
|
+
const i = /^\d{7}$/.test(t.toString()), n = i ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", o = i ? { imo: t } : { mmsi: t }, e = {
|
|
126
126
|
headers: {
|
|
127
127
|
Authorization: `${(d = this.token) == null ? void 0 : d.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
|
|
128
128
|
},
|
|
129
129
|
searchParams: o
|
|
130
130
|
};
|
|
131
|
-
y == null || y.info("[%s] fetch vessel from: %s - %j", a.requestId, n,
|
|
132
|
-
const r = await B.get(n,
|
|
131
|
+
y == null || y.info("[%s] fetch vessel from: %s - %j", a.requestId, n, e);
|
|
132
|
+
const r = await B.get(n, e).json();
|
|
133
133
|
if (r.status !== 200)
|
|
134
134
|
return y == null || y.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
|
|
135
135
|
{
|
|
@@ -162,11 +162,11 @@ class Et extends nt {
|
|
|
162
162
|
return {};
|
|
163
163
|
}
|
|
164
164
|
async archives(t, a = {}) {
|
|
165
|
-
var
|
|
165
|
+
var e, r;
|
|
166
166
|
await this.checkToken(a);
|
|
167
167
|
const i = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", n = {
|
|
168
168
|
headers: {
|
|
169
|
-
Authorization: `${(
|
|
169
|
+
Authorization: `${(e = this.token) == null ? void 0 : e.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
170
170
|
},
|
|
171
171
|
json: {
|
|
172
172
|
mmsiList: typeof t == "number" ? [t] : t
|
|
@@ -189,38 +189,38 @@ class Et extends nt {
|
|
|
189
189
|
const o = await B.get(i, n).json();
|
|
190
190
|
if (o.code)
|
|
191
191
|
return y == null || y.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: o.message, status: o.status, code: o.code }), o;
|
|
192
|
-
const
|
|
193
|
-
for (const h in
|
|
194
|
-
!isNaN(
|
|
195
|
-
if (
|
|
196
|
-
const h = p(`${
|
|
192
|
+
const e = o.data;
|
|
193
|
+
for (const h in e)
|
|
194
|
+
!isNaN(e[h]) && Number(e[h]) !== 1 / 0 && (e[h] = Number(e[h]));
|
|
195
|
+
if (e) {
|
|
196
|
+
const h = p(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
197
197
|
return {
|
|
198
|
-
mmsi:
|
|
199
|
-
name:
|
|
200
|
-
imo:
|
|
201
|
-
callSign:
|
|
202
|
-
lat:
|
|
203
|
-
lng:
|
|
204
|
-
length:
|
|
205
|
-
width:
|
|
206
|
-
draught:
|
|
207
|
-
sog:
|
|
208
|
-
cog:
|
|
209
|
-
hdg:
|
|
210
|
-
rot:
|
|
211
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(
|
|
212
|
-
destination:
|
|
198
|
+
mmsi: e.mmsi,
|
|
199
|
+
name: e.vesselName || e.aisVesselName,
|
|
200
|
+
imo: e.imo,
|
|
201
|
+
callSign: e.callsign || e.aisCallSign,
|
|
202
|
+
lat: e.lat,
|
|
203
|
+
lng: e.lon,
|
|
204
|
+
length: e.length,
|
|
205
|
+
width: e.width,
|
|
206
|
+
draught: e.currDraught,
|
|
207
|
+
sog: e.sog,
|
|
208
|
+
cog: e.cog,
|
|
209
|
+
hdg: e.hdg,
|
|
210
|
+
rot: e.rot,
|
|
211
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? p.utc(e.eta).format() : void 0,
|
|
212
|
+
destination: e.dest,
|
|
213
213
|
positionTime: h.unix(),
|
|
214
|
-
status:
|
|
215
|
-
labelCn:
|
|
216
|
-
labelEn:
|
|
217
|
-
vesselType:
|
|
218
|
-
flag:
|
|
219
|
-
clasz:
|
|
220
|
-
build:
|
|
221
|
-
dwt:
|
|
222
|
-
grt:
|
|
223
|
-
net:
|
|
214
|
+
status: e.status,
|
|
215
|
+
labelCn: e.statusNameCn,
|
|
216
|
+
labelEn: e.statusNameEn,
|
|
217
|
+
vesselType: e.vesselTypeNameEn,
|
|
218
|
+
flag: e.flagCtryNameEn,
|
|
219
|
+
clasz: e.classSociety,
|
|
220
|
+
build: e.buildYear,
|
|
221
|
+
dwt: e.dwt,
|
|
222
|
+
grt: e.grt,
|
|
223
|
+
net: e.net,
|
|
224
224
|
method: "position",
|
|
225
225
|
vendor: "myVessel",
|
|
226
226
|
utc: h.utc().format()
|
|
@@ -250,17 +250,17 @@ class Et extends nt {
|
|
|
250
250
|
}
|
|
251
251
|
};
|
|
252
252
|
y == null || y.info("[%s] fetch route from: %s - %j", i.requestId, n, o);
|
|
253
|
-
const
|
|
254
|
-
return
|
|
253
|
+
const e = await B.post(n, o).json();
|
|
254
|
+
return e.status !== 200 ? (y == null || y.warn("[%s] fetch route failed: %j", i.requestId, { message: e.message, status: e.status, code: e.code }), {}) : e.data;
|
|
255
255
|
}
|
|
256
|
-
async trajectory(t, a, i, n, o = !0,
|
|
257
|
-
await this.checkToken(
|
|
258
|
-
const r = await this.realTimePosition(t,
|
|
256
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
257
|
+
await this.checkToken(e);
|
|
258
|
+
const r = await this.realTimePosition(t, e), d = p(a), h = p(i), c = [];
|
|
259
259
|
for (; h.diff(d, "day", !0) > 30; )
|
|
260
|
-
await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), r, n, c,
|
|
261
|
-
return await this.trajectoryIn30Day(t, d, h, r, n, c,
|
|
260
|
+
await this.trajectoryIn30Day(t, d, d.clone().add(30, "day"), r, n, c, e), d.add(30, "day");
|
|
261
|
+
return await this.trajectoryIn30Day(t, d, h, r, n, c, e), c;
|
|
262
262
|
}
|
|
263
|
-
async trajectoryIn30Day(t, a, i, n, o,
|
|
263
|
+
async trajectoryIn30Day(t, a, i, n, o, e, r = {}) {
|
|
264
264
|
var b, j, F, g, v;
|
|
265
265
|
const d = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
266
266
|
headers: {
|
|
@@ -300,8 +300,8 @@ class Et extends nt {
|
|
|
300
300
|
vendor: "myVessel",
|
|
301
301
|
utc: u.utc().format()
|
|
302
302
|
}, E = Math.floor(u.diff(w, "minute", !0) / (o || 1));
|
|
303
|
-
E !== M && (M = E,
|
|
304
|
-
}),
|
|
303
|
+
E !== M && (M = E, e.push(k));
|
|
304
|
+
}), e;
|
|
305
305
|
}
|
|
306
306
|
}
|
|
307
307
|
class xt extends nt {
|
|
@@ -318,33 +318,33 @@ class xt extends nt {
|
|
|
318
318
|
}
|
|
319
319
|
}, o = await B.post(i, n).json();
|
|
320
320
|
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
|
|
321
|
-
const
|
|
322
|
-
if (!
|
|
321
|
+
const e = o == null ? void 0 : o.list;
|
|
322
|
+
if (!e)
|
|
323
323
|
return y == null || y.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
|
|
324
|
-
for (const w in
|
|
325
|
-
!isNaN(
|
|
326
|
-
|
|
327
|
-
const r =
|
|
324
|
+
for (const w in e)
|
|
325
|
+
!isNaN(e[w]) && Number(e[w]) !== 1 / 0 && (e[w] = Number(e[w]));
|
|
326
|
+
e.status = e.sp > 3 ? 0 : 1;
|
|
327
|
+
const r = e.status, { labelCn: d, labelEn: h } = this.parseStatus(r), c = p(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
328
328
|
return {
|
|
329
|
-
mmsi:
|
|
330
|
-
name:
|
|
331
|
-
imo:
|
|
332
|
-
callSign:
|
|
333
|
-
lat: Math.round(
|
|
334
|
-
lng: Math.round(
|
|
335
|
-
length:
|
|
336
|
-
width:
|
|
337
|
-
draught:
|
|
338
|
-
sog:
|
|
339
|
-
cog:
|
|
340
|
-
hdg:
|
|
341
|
-
rot: isNaN(
|
|
342
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(
|
|
343
|
-
destination:
|
|
344
|
-
vesselType:
|
|
345
|
-
dwt:
|
|
346
|
-
build:
|
|
347
|
-
flag:
|
|
329
|
+
mmsi: e.m,
|
|
330
|
+
name: e.n,
|
|
331
|
+
imo: e.imonumber,
|
|
332
|
+
callSign: e.callsign,
|
|
333
|
+
lat: Math.round(e.la / 60 * 1e5) / 1e5,
|
|
334
|
+
lng: Math.round(e.lo / 60 * 1e5) / 1e5,
|
|
335
|
+
length: e.l,
|
|
336
|
+
width: e.w,
|
|
337
|
+
draught: e.draught,
|
|
338
|
+
sog: e.sp,
|
|
339
|
+
cog: e.co,
|
|
340
|
+
hdg: e.h,
|
|
341
|
+
rot: isNaN(e.rot) ? 0 : e.rot,
|
|
342
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? p.utc(e.eta).format() : void 0,
|
|
343
|
+
destination: e.destination,
|
|
344
|
+
vesselType: e.type,
|
|
345
|
+
dwt: e.dwt,
|
|
346
|
+
build: e.buildyear,
|
|
347
|
+
flag: e.fn,
|
|
348
348
|
positionTime: c.unix(),
|
|
349
349
|
utc: c.utc().format(),
|
|
350
350
|
status: r,
|
|
@@ -370,7 +370,7 @@ class xt extends nt {
|
|
|
370
370
|
y == null || y.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]);
|
|
371
371
|
for (const r in o)
|
|
372
372
|
!isNaN(o[r]) && Number(o[r]) !== 1 / 0 && (o[r] = Number(o[r]));
|
|
373
|
-
const
|
|
373
|
+
const e = {
|
|
374
374
|
mmsi: o.m,
|
|
375
375
|
name: o.n,
|
|
376
376
|
imo: o.i,
|
|
@@ -380,7 +380,7 @@ class xt extends nt {
|
|
|
380
380
|
draught: o.dr,
|
|
381
381
|
type: o.t
|
|
382
382
|
};
|
|
383
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), y == null || y.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]), o && (
|
|
383
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), y == null || y.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]), o && (e.deadweight = Number(o.dwt)), e;
|
|
384
384
|
}
|
|
385
385
|
async suggest(t, a = {}) {
|
|
386
386
|
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
|
|
@@ -394,20 +394,20 @@ class xt extends nt {
|
|
|
394
394
|
}
|
|
395
395
|
}, o = await B.post(i, n).json();
|
|
396
396
|
y == null || y.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, n);
|
|
397
|
-
const
|
|
397
|
+
const e = [];
|
|
398
398
|
for (const r of o)
|
|
399
|
-
|
|
399
|
+
e.push({
|
|
400
400
|
mmsi: !r.mmsi || isNaN(r.mmsi) ? null : Number(r.mmsi),
|
|
401
401
|
name: r.name,
|
|
402
402
|
callSign: r.callsign,
|
|
403
403
|
imo: !r.imo || isNaN(r.imo) ? null : Number(r.imo),
|
|
404
404
|
score: r._score
|
|
405
405
|
});
|
|
406
|
-
return
|
|
406
|
+
return e.sort((r, d) => d.score - r.score), e;
|
|
407
407
|
}
|
|
408
|
-
async trajectory(t, a, i, n, o = !0,
|
|
408
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
409
409
|
var f, u, l;
|
|
410
|
-
const r = await this.realTimePosition(t,
|
|
410
|
+
const r = await this.realTimePosition(t, e);
|
|
411
411
|
let d = p(a);
|
|
412
412
|
const h = p(i), c = p();
|
|
413
413
|
if (o) {
|
|
@@ -422,9 +422,9 @@ class xt extends nt {
|
|
|
422
422
|
usertoken: this.token
|
|
423
423
|
}
|
|
424
424
|
}, w = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(w, M).json();
|
|
425
|
-
y == null || y.info("[%s] fetch trajectory from: %s - %j",
|
|
425
|
+
y == null || y.info("[%s] fetch trajectory from: %s - %j", e.requestId, w, M);
|
|
426
426
|
let j;
|
|
427
|
-
b && (j = ((u = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], j.length || y == null || y.warn("[%s] fetch trajectory failed: %j",
|
|
427
|
+
b && (j = ((u = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : u.ship) || [], j.length || y == null || y.warn("[%s] fetch trajectory failed: %j", e.requestId, b));
|
|
428
428
|
const F = [];
|
|
429
429
|
let g = -1;
|
|
430
430
|
const v = p(`${(l = j == null ? void 0 : j[0]) == null ? void 0 : l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
@@ -472,36 +472,36 @@ class Nt extends nt {
|
|
|
472
472
|
}, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(n, i).json();
|
|
473
473
|
if (y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, i), (o == null ? void 0 : o.status) !== 0)
|
|
474
474
|
return o;
|
|
475
|
-
const
|
|
476
|
-
for (const M in
|
|
477
|
-
!isNaN(
|
|
478
|
-
const { labelCn: r, labelEn: d } = await this.parseStatus(
|
|
475
|
+
const e = o.data[0];
|
|
476
|
+
for (const M in e)
|
|
477
|
+
!isNaN(e[M]) && Number(e[M]) !== 1 / 0 && (e[M] = Number(e[M]));
|
|
478
|
+
const { labelCn: r, labelEn: d } = await this.parseStatus(e.navistat), h = p.unix(e.lasttime);
|
|
479
479
|
return {
|
|
480
|
-
mmsi:
|
|
481
|
-
name:
|
|
482
|
-
imo:
|
|
483
|
-
callSign:
|
|
484
|
-
lat: Math.round(
|
|
485
|
-
lng: Math.round(
|
|
486
|
-
length: Math.round(
|
|
487
|
-
width: Math.round(
|
|
488
|
-
draught: Math.round(
|
|
489
|
-
sog: Math.round(
|
|
490
|
-
cog: Math.round(
|
|
491
|
-
hdg: Math.round(
|
|
492
|
-
rot: Math.round(
|
|
493
|
-
positionTime:
|
|
480
|
+
mmsi: e.ShipID,
|
|
481
|
+
name: e.name,
|
|
482
|
+
imo: e.imo,
|
|
483
|
+
callSign: e.callsign,
|
|
484
|
+
lat: Math.round(e.lat / 1e6 * 1e5) / 1e5,
|
|
485
|
+
lng: Math.round(e.lon / 1e6 * 1e5) / 1e5,
|
|
486
|
+
length: Math.round(e.length / 10 * 100) / 100,
|
|
487
|
+
width: Math.round(e.width / 10 * 100) / 100,
|
|
488
|
+
draught: Math.round(e.draught / 1e3 * 100) / 100,
|
|
489
|
+
sog: Math.round(e.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
490
|
+
cog: Math.round(e.cog / 100 * 100) / 100,
|
|
491
|
+
hdg: Math.round(e.hdg / 100 * 100) / 100,
|
|
492
|
+
rot: Math.round(e.rot / 100 * 100) / 100,
|
|
493
|
+
positionTime: e.lasttime,
|
|
494
494
|
utc: h.utc().format(),
|
|
495
|
-
status:
|
|
495
|
+
status: e.navistat,
|
|
496
496
|
labelEn: d,
|
|
497
497
|
labelCn: r,
|
|
498
498
|
method: "position",
|
|
499
499
|
vendor: "shipxy"
|
|
500
500
|
};
|
|
501
501
|
}
|
|
502
|
-
async trajectory(t, a, i, n, o = !0,
|
|
502
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
503
503
|
var v;
|
|
504
|
-
const r = await this.realTimePosition(t,
|
|
504
|
+
const r = await this.realTimePosition(t, e), d = p(a), h = p(i), c = "https://api.shipxy.com/apicall/GetShipTrack", M = {
|
|
505
505
|
searchParams: {
|
|
506
506
|
id: t,
|
|
507
507
|
k: this.token,
|
|
@@ -511,7 +511,7 @@ class Nt extends nt {
|
|
|
511
511
|
etm: h.unix()
|
|
512
512
|
}
|
|
513
513
|
}, w = await B.get(c, M).json();
|
|
514
|
-
if (y == null || y.info("[%s] fetch trajectory from: %s - %j",
|
|
514
|
+
if (y == null || y.info("[%s] fetch trajectory from: %s - %j", e.requestId, c, M), (w == null ? void 0 : w.status) !== 0)
|
|
515
515
|
return w;
|
|
516
516
|
const b = w == null ? void 0 : w.points, j = [], F = p.unix((v = b[0]) == null ? void 0 : v.utc);
|
|
517
517
|
let g = -1;
|
|
@@ -561,16 +561,16 @@ class Dt extends nt {
|
|
|
561
561
|
}, n = "https://api3.myships.com/sp/ships/aissta", o = await B.post(n, i).json();
|
|
562
562
|
if (y == null || y.info("[%s] fetch ship info from: %s - %j", a.requestId, n, i), o.code !== "0")
|
|
563
563
|
return o;
|
|
564
|
-
const
|
|
565
|
-
let r =
|
|
566
|
-
return t === "407170" && (r = "9198379", y == null || y.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t,
|
|
567
|
-
mmsi:
|
|
568
|
-
name:
|
|
564
|
+
const e = o.data;
|
|
565
|
+
let r = e.imo;
|
|
566
|
+
return t === "407170" && (r = "9198379", y == null || y.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, e.imo, r)), {
|
|
567
|
+
mmsi: e.mmsi,
|
|
568
|
+
name: e.shipnameEn,
|
|
569
569
|
imo: r,
|
|
570
|
-
callSign:
|
|
571
|
-
length:
|
|
572
|
-
width:
|
|
573
|
-
draught: (
|
|
570
|
+
callSign: e.callSign,
|
|
571
|
+
length: e.length,
|
|
572
|
+
width: e.breadth,
|
|
573
|
+
draught: (e.draught || 100) / 10
|
|
574
574
|
};
|
|
575
575
|
}
|
|
576
576
|
async realTimePosition(t, a = {}) {
|
|
@@ -581,8 +581,8 @@ class Dt extends nt {
|
|
|
581
581
|
json: {
|
|
582
582
|
shipId: i
|
|
583
583
|
}
|
|
584
|
-
},
|
|
585
|
-
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
584
|
+
}, e = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(e, o).json();
|
|
585
|
+
y == null || y.info("[%s] fetch realtime position from: %s - %j", a.requestId, e, o);
|
|
586
586
|
const d = r.data[0];
|
|
587
587
|
for (const b in d)
|
|
588
588
|
!isNaN(d[b]) && Number(d[b]) !== 1 / 0 && (d[b] = Number(d[b]));
|
|
@@ -605,13 +605,13 @@ class Dt extends nt {
|
|
|
605
605
|
vendor: "myship"
|
|
606
606
|
};
|
|
607
607
|
}
|
|
608
|
-
async trajectory(t, a, i, n, o = !0,
|
|
608
|
+
async trajectory(t, a, i, n, o = !0, e = {}) {
|
|
609
609
|
const r = p(a), d = p(i), h = await this.getShipId(t), c = await this.getShipInfo(h), M = [];
|
|
610
610
|
for (; d.diff(r, "day", !0) > 30; )
|
|
611
611
|
await this.trajectoryIn30Day(h, r.unix(), r.add(30, "day").unix(), c, t, n, M);
|
|
612
612
|
return await this.trajectoryIn30Day(h, r.unix(), d.unix(), c, t, n, M), M;
|
|
613
613
|
}
|
|
614
|
-
async trajectoryIn30Day(t, a, i, n, o,
|
|
614
|
+
async trajectoryIn30Day(t, a, i, n, o, e, r, d = {}) {
|
|
615
615
|
var F;
|
|
616
616
|
const h = {
|
|
617
617
|
headers: {
|
|
@@ -644,7 +644,7 @@ class Dt extends nt {
|
|
|
644
644
|
utc: v.utc().format(),
|
|
645
645
|
method: "trajectory",
|
|
646
646
|
vendor: "myship"
|
|
647
|
-
}, u = Math.floor(v.diff(b, "minute", !0) / (
|
|
647
|
+
}, u = Math.floor(v.diff(b, "minute", !0) / (e || 1));
|
|
648
648
|
u !== j && (j = u, r.push(f));
|
|
649
649
|
}
|
|
650
650
|
return r;
|
|
@@ -666,10 +666,10 @@ class bt {
|
|
|
666
666
|
*
|
|
667
667
|
* @param options
|
|
668
668
|
*/
|
|
669
|
-
parsePrinciple(
|
|
670
|
-
var
|
|
671
|
-
_ == null || _.debug("[%s] parse rule: %s", t.requestId,
|
|
672
|
-
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i =
|
|
669
|
+
parsePrinciple(s, t = {}) {
|
|
670
|
+
var e, r, d;
|
|
671
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, s);
|
|
672
|
+
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = s.match(a) ? (e = s.match(a)) == null ? void 0 : e[0] : void 0, n = i == null ? void 0 : i.split(";");
|
|
673
673
|
if (!n)
|
|
674
674
|
return;
|
|
675
675
|
const o = {};
|
|
@@ -691,17 +691,17 @@ class bt {
|
|
|
691
691
|
* @param rule
|
|
692
692
|
* @param options
|
|
693
693
|
*/
|
|
694
|
-
parseRule(
|
|
694
|
+
parseRule(s, t = {}) {
|
|
695
695
|
var o;
|
|
696
|
-
_ == null || _.debug("[%s] parse rule: %s", t.requestId,
|
|
697
|
-
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o =
|
|
696
|
+
_ == null || _.debug("[%s] parse rule: %s", t.requestId, s), s = s.startsWith("[") ? s : `[${s}`, s = s.endsWith("]") ? s : `${s}]`;
|
|
697
|
+
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o = s == null ? void 0 : s.match(a)) == null ? void 0 : o[0], n = i == null ? void 0 : i.split(",");
|
|
698
698
|
if (n) {
|
|
699
|
-
let
|
|
700
|
-
return
|
|
699
|
+
let e = n[3] === "Number.MAX_VALUE" ? 100 : Number(n[3]);
|
|
700
|
+
return e = isNaN(e) ? 1 : e, {
|
|
701
701
|
operator: n[0],
|
|
702
702
|
number: Number.isNaN(Number(n[1])) ? n[1] : Number(n[1]),
|
|
703
703
|
level: n[2],
|
|
704
|
-
time:
|
|
704
|
+
time: e,
|
|
705
705
|
key: n[4]
|
|
706
706
|
};
|
|
707
707
|
}
|
|
@@ -712,15 +712,15 @@ class bt {
|
|
|
712
712
|
* @param principle 告警规则
|
|
713
713
|
* @param options
|
|
714
714
|
*/
|
|
715
|
-
checkWeather(
|
|
715
|
+
checkWeather(s, t, a = {}) {
|
|
716
716
|
var b, j, F, g, v, f, u, l, m, I, k, E, q, D, H;
|
|
717
|
-
let i = 0, n = 0, o = 0,
|
|
717
|
+
let i = 0, n = 0, o = 0, e = 0;
|
|
718
718
|
const r = Math.round(((j = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, d = (g = (F = t == null ? void 0 : t.SEVERE) == null ? void 0 : F.sigWave) == null ? void 0 : g.number, h = (f = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : f.number, c = Math.round((((l = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : l.number) + 2) * 100) / 100, M = (I = (m = t == null ? void 0 : t.SEVERE) == null ? void 0 : m.wind) == null ? void 0 : I.number, w = (E = (k = t == null ? void 0 : t.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : E.number;
|
|
719
|
-
for (let T = 0; T < (
|
|
720
|
-
const x =
|
|
721
|
-
|
|
719
|
+
for (let T = 0; T < (s == null ? void 0 : s.length); T++) {
|
|
720
|
+
const x = s[T], O = (D = (q = x == null ? void 0 : x.meteo) == null ? void 0 : q.wave) == null ? void 0 : D.sig, R = (H = x == null ? void 0 : x.meteo) == null ? void 0 : H.wind, J = T ? p(x.eta).diff(p(s[T - 1].eta), "hour", !0) : 0;
|
|
721
|
+
e = J > e ? J : e, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...O, dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h }), (O == null ? void 0 : O.height) >= r ? x.isDangerous = !0 : (O == null ? void 0 : O.height) >= d ? x.isSevere = !0 : (O == null ? void 0 : O.height) >= h && (x.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= c ? (x.isDangerous = !0, delete x.isSevere, delete x.isHeavy) : (R == null ? void 0 : R.scale) > M ? (x.isDangerous || (x.isSevere = !0), delete x.isHeavy) : (R == null ? void 0 : R.scale) === w && !x.isDangerous && !x.isSevere && (x.isHeavy = !0), i += x.isDangerous ? J : 0, n += x.isSevere ? J : 0, o += x.isHeavy ? J : 0;
|
|
722
722
|
}
|
|
723
|
-
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100,
|
|
723
|
+
return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, e = Math.round(e), { sample: s, dangerous: i, severe: n, heavy: o, step: e < 3 ? 3 : e, wind: { dgThd4Wd: c, svThd4Wd: M, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: d, hvThd4Wv: h } };
|
|
724
724
|
}
|
|
725
725
|
}
|
|
726
726
|
const At = new bt();
|
|
@@ -745,11 +745,11 @@ class W {
|
|
|
745
745
|
* @param draught 吃水 m
|
|
746
746
|
* @return [0.55, 0.85]
|
|
747
747
|
*/
|
|
748
|
-
static blockCoefficient(
|
|
749
|
-
let n = Math.round(
|
|
748
|
+
static blockCoefficient(s, t, a, i) {
|
|
749
|
+
let n = Math.round(s / (t * a * i) * 100) / 100;
|
|
750
750
|
n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
|
|
751
|
-
const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85],
|
|
752
|
-
return o[
|
|
751
|
+
const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = o.map((r) => Math.abs(r - n));
|
|
752
|
+
return o[e.indexOf(Math.min(...e))];
|
|
753
753
|
}
|
|
754
754
|
/**
|
|
755
755
|
* @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
|
|
@@ -762,8 +762,8 @@ class W {
|
|
|
762
762
|
* @param g 重力加速度 9.80 m/s^2
|
|
763
763
|
* @return [0.05, 0.30]
|
|
764
764
|
*/
|
|
765
|
-
static froudeNumber(
|
|
766
|
-
let i = Math.round(Math.sqrt(
|
|
765
|
+
static froudeNumber(s, t, a = 9.8) {
|
|
766
|
+
let i = Math.round(Math.sqrt(s * s / (a * t)) * 100) / 100;
|
|
767
767
|
return i = i < 0.05 ? 0.05 : i > 0.3 ? 0.3 : i, i;
|
|
768
768
|
}
|
|
769
769
|
/**
|
|
@@ -773,7 +773,7 @@ class W {
|
|
|
773
773
|
* @param loadCondition
|
|
774
774
|
* @private
|
|
775
775
|
*/
|
|
776
|
-
static amendFactor(
|
|
776
|
+
static amendFactor(s, t, a) {
|
|
777
777
|
const i = {
|
|
778
778
|
0.55: [1.7, -1.4, -7.4],
|
|
779
779
|
0.6: [2.2, -2.5, -9.7],
|
|
@@ -791,8 +791,8 @@ class W {
|
|
|
791
791
|
0.75: [2.6, -12.5, -13.5],
|
|
792
792
|
0.8: [3, -16.3, -21.6],
|
|
793
793
|
0.85: [3.4, -20.9, 31.8]
|
|
794
|
-
}[
|
|
795
|
-
return a === "Laden" && (o = i[
|
|
794
|
+
}[s];
|
|
795
|
+
return a === "Laden" && (o = i[s]), o[0] + o[1] * t + o[2] * Math.pow(t, 2);
|
|
796
796
|
}
|
|
797
797
|
/**
|
|
798
798
|
* 失速方向因子
|
|
@@ -805,9 +805,9 @@ class W {
|
|
|
805
805
|
* @param bn
|
|
806
806
|
* @private
|
|
807
807
|
*/
|
|
808
|
-
static directionFactor(
|
|
808
|
+
static directionFactor(s, t = 0) {
|
|
809
809
|
let a;
|
|
810
|
-
return
|
|
810
|
+
return s > 30 && s <= 60 ? a = (1.7 - 0.03 * Math.pow(t - 4, 2)) / 2 : s > 60 && s <= 150 ? a = (0.9 - 0.06 * Math.pow(t - 6, 2)) / 2 : s > 150 && s <= 180 ? a = (0.4 - 0.03 * Math.pow(t - 8, 2)) / 2 : a = 1, Math.round(a * 1e5) / 1e5;
|
|
811
811
|
}
|
|
812
812
|
/**
|
|
813
813
|
* 失速船型因子
|
|
@@ -821,9 +821,9 @@ class W {
|
|
|
821
821
|
* @param kts
|
|
822
822
|
* @private
|
|
823
823
|
*/
|
|
824
|
-
static vesselTagFactor(
|
|
824
|
+
static vesselTagFactor(s, t, a, i) {
|
|
825
825
|
let n;
|
|
826
|
-
return a === "container" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (22 * Math.pow(
|
|
826
|
+
return a === "container" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (22 * Math.pow(s, 2 / 3)) : t === "Ballast" ? n = 0.7 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(s, 2 / 3)) : n = 0.5 * i / 2 + Math.pow(i, 3) / (2.7 * Math.pow(s, 2 / 3)), n;
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
829
829
|
* 浪高影响因子
|
|
@@ -831,10 +831,10 @@ class W {
|
|
|
831
831
|
* @param beta 夹角
|
|
832
832
|
* @private
|
|
833
833
|
*/
|
|
834
|
-
static waveHeightFactor(
|
|
835
|
-
|
|
834
|
+
static waveHeightFactor(s, t) {
|
|
835
|
+
s = s < 3 ? s * 0.7 : s, s = s < 0 ? 0.2 : s, s = s > 6 ? s - 0.9 * (s - 6) : s, s = s > 9 ? 9 : s;
|
|
836
836
|
let a;
|
|
837
|
-
return t > 30 && t <= 60 ? a = -0.6 : t > 60 && t <= 90 ? a = -0.4 : t > 90 && t <= 120 ? a =
|
|
837
|
+
return t > 30 && t <= 60 ? a = -0.6 : t > 60 && t <= 90 ? a = -0.4 : t > 90 && t <= 120 ? a = s < 3 ? 0.4 : -0.3 : t > 120 && t <= 150 ? a = s < 3 ? 0.6 : -0.5 : t > 150 && t <= 180 ? a = s < 3 ? 0.7 : -0.6 : a = -0.7, Math.round(a * (0.144 * Math.pow(s, 2) + 0.278 * s) * 1e4) / 1e4;
|
|
838
838
|
}
|
|
839
839
|
/**
|
|
840
840
|
* 组装船舶运行参数
|
|
@@ -844,18 +844,18 @@ class W {
|
|
|
844
844
|
* @param bearing 方位角
|
|
845
845
|
* @private
|
|
846
846
|
*/
|
|
847
|
-
static assembleProperties(
|
|
847
|
+
static assembleProperties(s, t, a, i) {
|
|
848
848
|
var M;
|
|
849
|
-
const n =
|
|
849
|
+
const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, o = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, r = s.deadweight ?? 67035.7773, d = ((M = s == null ? void 0 : s.type) == null ? void 0 : M.toLowerCase()) || "common";
|
|
850
850
|
return {
|
|
851
851
|
tag: d.indexOf("container") > -1 ? "container" : d.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
852
852
|
lbp: n,
|
|
853
853
|
loadCondition: t,
|
|
854
854
|
draught: o,
|
|
855
|
-
breadthMoulded:
|
|
855
|
+
breadthMoulded: e,
|
|
856
856
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
857
857
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
858
|
-
displacement: Math.round((r / 1.025 + o *
|
|
858
|
+
displacement: Math.round((r / 1.025 + o * e * n * 0.7) * 1e4) / 1e4,
|
|
859
859
|
// 换算为m/s
|
|
860
860
|
speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
861
861
|
bearing: i || 90
|
|
@@ -872,9 +872,9 @@ class W {
|
|
|
872
872
|
* @param useRouteParam true 启用设置速度
|
|
873
873
|
* @param options
|
|
874
874
|
*/
|
|
875
|
-
static async speedLoseAt(
|
|
875
|
+
static async speedLoseAt(s, t, a, i = "", n = 2, o = !0, e = !1, r = {}) {
|
|
876
876
|
let d;
|
|
877
|
-
if (t.velocity &&
|
|
877
|
+
if (t.velocity && e && (s.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), o) {
|
|
878
878
|
let h;
|
|
879
879
|
try {
|
|
880
880
|
i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
|
|
@@ -889,12 +889,12 @@ class W {
|
|
|
889
889
|
} catch (b) {
|
|
890
890
|
C.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: i }, b);
|
|
891
891
|
}
|
|
892
|
-
const c = W.currentFactor(
|
|
892
|
+
const c = W.currentFactor(s.bearing, h == null ? void 0 : h.current, n), M = W.weatherFactor(s, h, c), w = Math.round((s.speed * 1.943844 + M + c) * 100) / 100;
|
|
893
893
|
d = {
|
|
894
894
|
meteo: { ...h },
|
|
895
895
|
wxFactor: M,
|
|
896
896
|
cFactor: c,
|
|
897
|
-
speed: t.velocity &&
|
|
897
|
+
speed: t.velocity && e ? t.velocity : w < 0 ? 1 : w,
|
|
898
898
|
eta: a.utc().format(),
|
|
899
899
|
etd: a.utc().format()
|
|
900
900
|
};
|
|
@@ -902,7 +902,7 @@ class W {
|
|
|
902
902
|
d = {
|
|
903
903
|
wxFactor: 0,
|
|
904
904
|
cFactor: 0,
|
|
905
|
-
speed: t.velocity &&
|
|
905
|
+
speed: t.velocity && e ? t.velocity : Math.round(s.speed * 1.943844 * 100) / 100,
|
|
906
906
|
eta: a.utc().format(),
|
|
907
907
|
etd: a.utc().format()
|
|
908
908
|
};
|
|
@@ -922,7 +922,7 @@ class W {
|
|
|
922
922
|
* @param options
|
|
923
923
|
* @private
|
|
924
924
|
*/
|
|
925
|
-
static async speedLoseInHoursStep(
|
|
925
|
+
static async speedLoseInHoursStep(s, t, a, i, n, o, e = "", r = !0, d = !1, h = {}) {
|
|
926
926
|
t.utc();
|
|
927
927
|
const c = t.clone().add(14, "days"), M = [], w = [], b = [];
|
|
928
928
|
let j = 0, F = 0, g, v;
|
|
@@ -930,7 +930,7 @@ class W {
|
|
|
930
930
|
let u = o[f];
|
|
931
931
|
u.distanceFromStart = Math.round((n + F) * 1e3) / 1e3;
|
|
932
932
|
const l = o[f + 1];
|
|
933
|
-
if (
|
|
933
|
+
if (s.bearing = V.calculateBearing(u, l, !l.gcToPrevious), u.bearing = s.bearing, u.suspend && d) {
|
|
934
934
|
u.eta = u.eta || t.utc().format(), u.elapsed = u.elapsed ?? 0;
|
|
935
935
|
const k = u.suspend - u.elapsed;
|
|
936
936
|
if (i - j > k)
|
|
@@ -943,7 +943,7 @@ class W {
|
|
|
943
943
|
return u.distanceFromPrevious = F, { etd: t, from: v || u, to: u, next: o.filter((E) => E), wps: M, days: w, all: b };
|
|
944
944
|
} else
|
|
945
945
|
u.suspend = 0;
|
|
946
|
-
r = t.isAfter(c) ? !1 : r, u = await W.speedLoseAt(
|
|
946
|
+
r = t.isAfter(c) ? !1 : r, u = await W.speedLoseAt(s, u, t, e, 0, r, d, h), b.push(u), v = v || u, u.important && M.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
|
|
947
947
|
const m = V.calculateDistance(u, l, !l.gcToPrevious);
|
|
948
948
|
let I = Math.round(m / v.speed * 1e5) / 1e5;
|
|
949
949
|
if (j + I < i) {
|
|
@@ -959,7 +959,7 @@ class W {
|
|
|
959
959
|
} else {
|
|
960
960
|
I = i - j, t.add(I, "hour");
|
|
961
961
|
const k = z.roundPrecision(v.speed * I, 5);
|
|
962
|
-
g = V.calculateCoordinate(u,
|
|
962
|
+
g = V.calculateCoordinate(u, s.bearing, k, "nauticalmiles", !l.gcToPrevious), g.eta = t.utc().format(), o[f] = g, C == null || C.debug(
|
|
963
963
|
`[%s] go to %j from %j with ${k}nm, and cost ${I} hours`,
|
|
964
964
|
h.requestId,
|
|
965
965
|
{ lat: g.lat, lng: g.lng },
|
|
@@ -976,8 +976,8 @@ class W {
|
|
|
976
976
|
* @param current 洋流要素
|
|
977
977
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
978
978
|
*/
|
|
979
|
-
static currentFactor(
|
|
980
|
-
const i = (
|
|
979
|
+
static currentFactor(s, t, a = 0) {
|
|
980
|
+
const i = (s - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
981
981
|
if (Math.abs(i) === Math.PI / 2)
|
|
982
982
|
return 0;
|
|
983
983
|
let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(i);
|
|
@@ -989,15 +989,15 @@ class W {
|
|
|
989
989
|
* @param wwc 气象要素
|
|
990
990
|
* @param cFactor 洋流因子
|
|
991
991
|
*/
|
|
992
|
-
static weatherFactor(
|
|
992
|
+
static weatherFactor(s, t, a = 0) {
|
|
993
993
|
var w, b, j, F, g, v, f;
|
|
994
|
-
C == null || C.debug("calculate weather factor via: %j", { ...
|
|
995
|
-
const i = W.blockCoefficient(
|
|
996
|
-
let r = Math.abs(
|
|
994
|
+
C == null || C.debug("calculate weather factor via: %j", { ...s, ...t });
|
|
995
|
+
const i = W.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), n = z.roundPrecision(a * 1852 / 3600, 6), o = W.froudeNumber(s.speed - n, s.lbp), e = W.amendFactor(i, o, s.loadCondition);
|
|
996
|
+
let r = Math.abs(s.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
|
|
997
997
|
r = r > 180 ? 360 - r : r;
|
|
998
|
-
const d = W.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), h = W.vesselTagFactor(
|
|
999
|
-
let c = d *
|
|
1000
|
-
c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1,
|
|
998
|
+
const d = W.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), h = W.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (j = t == null ? void 0 : t.wind) == null ? void 0 : j.kts);
|
|
999
|
+
let c = d * e * h / 100 * (s.speed - n);
|
|
1000
|
+
c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, s.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), C == null || C.debug("wind wx factor = %d", c), r = Math.abs(s.bearing % 360 - (((g = (F = t == null ? void 0 : t.wave) == null ? void 0 : F.sig) == null ? void 0 : g.degree) % 360 || 0)), r = r > 180 ? 360 - r : r;
|
|
1001
1001
|
const M = W.waveHeightFactor(((f = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : f.height) ?? 1, r);
|
|
1002
1002
|
return C == null || C.debug("wave wx factor = %d", M), c = Math.abs(c) > Math.abs(M) ? c : c * 0.3 + M * 0.7, C == null || C.debug("weather factor = %d", c), c = Math.abs(c) > 3 ? 3 * (Math.abs(c) / c) + Math.abs(c) / c * (Math.abs(c) - 2) * 0.1 : c, Math.round((c || 0) * 100) / 100;
|
|
1003
1003
|
}
|
|
@@ -1014,25 +1014,25 @@ class W {
|
|
|
1014
1014
|
* @param useRouteParam
|
|
1015
1015
|
* @param options
|
|
1016
1016
|
*/
|
|
1017
|
-
static async analyseInstant(
|
|
1017
|
+
static async analyseInstant(s, t, a, i, n, o = "", e = 0, r = !0, d = !1, h = {}) {
|
|
1018
1018
|
var K, G, X, Q, Z, $, tt;
|
|
1019
1019
|
const c = p().valueOf();
|
|
1020
|
-
|
|
1021
|
-
const { route: M, waypoints: w } = n.points, b = V.calculateSubRoute(
|
|
1020
|
+
s.lng = z.convertToStdLng(s.lng);
|
|
1021
|
+
const { route: M, waypoints: w } = n.points, b = V.calculateSubRoute(s, M);
|
|
1022
1022
|
if (((K = b[0]) == null ? void 0 : K.length) <= 1)
|
|
1023
1023
|
return;
|
|
1024
|
-
const { v0: j, label: F } =
|
|
1025
|
-
v0:
|
|
1026
|
-
label:
|
|
1024
|
+
const { v0: j, label: F } = s.sog ? {
|
|
1025
|
+
v0: s.sog,
|
|
1026
|
+
label: s.label || "Other"
|
|
1027
1027
|
/* Instruct */
|
|
1028
1028
|
} : {
|
|
1029
1029
|
v0: i.speed,
|
|
1030
1030
|
label: "CP"
|
|
1031
1031
|
/* Cp */
|
|
1032
|
-
}, g = W.assembleProperties(a, i.loadCondition, j, 0), v = w.length ? V.calculateSubWaypoints(
|
|
1032
|
+
}, g = W.assembleProperties(a, i.loadCondition, j, 0), v = w.length ? V.calculateSubWaypoints(s, w) : [];
|
|
1033
1033
|
v.forEach((A) => A.important = !0);
|
|
1034
1034
|
const f = {
|
|
1035
|
-
from: { ...
|
|
1035
|
+
from: { ...s },
|
|
1036
1036
|
route: b,
|
|
1037
1037
|
waypoints: v,
|
|
1038
1038
|
v0: j,
|
|
@@ -1043,12 +1043,12 @@ class W {
|
|
|
1043
1043
|
wps: [],
|
|
1044
1044
|
all: []
|
|
1045
1045
|
};
|
|
1046
|
-
|
|
1046
|
+
e || (V.calculateRouteDistance(b) / i.speed <= 72 ? e = 3 : e = 6);
|
|
1047
1047
|
let l = V.simplifyRouteToCoordinates(b, v, 0), m = 0, I = 0, k = 0, E = 0;
|
|
1048
1048
|
t = p(t).utc();
|
|
1049
1049
|
const q = t.clone();
|
|
1050
1050
|
for (; l.length > 0; ) {
|
|
1051
|
-
const A =
|
|
1051
|
+
const A = e - t.hour() % e, L = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, S = await W.speedLoseInHoursStep(
|
|
1052
1052
|
g,
|
|
1053
1053
|
t,
|
|
1054
1054
|
q,
|
|
@@ -1108,22 +1108,22 @@ class W {
|
|
|
1108
1108
|
* @param useRouteParam
|
|
1109
1109
|
* @param options
|
|
1110
1110
|
*/
|
|
1111
|
-
static async analyseInstantWithThreshed(
|
|
1111
|
+
static async analyseInstantWithThreshed(s, t, a, i, n, o, e, r = "", d = 3, h = !0, c = !1, M = {}) {
|
|
1112
1112
|
var X, Q, Z, $, tt, A, L;
|
|
1113
1113
|
const w = p().valueOf();
|
|
1114
|
-
|
|
1115
|
-
const { v0: b, label: j } =
|
|
1116
|
-
v0:
|
|
1117
|
-
label:
|
|
1114
|
+
s.lng = z.convertToStdLng(s.lng);
|
|
1115
|
+
const { v0: b, label: j } = s.sog ? {
|
|
1116
|
+
v0: s.sog,
|
|
1117
|
+
label: s.label || "Other"
|
|
1118
1118
|
/* Instruct */
|
|
1119
1119
|
} : {
|
|
1120
1120
|
v0: n.speed,
|
|
1121
1121
|
label: "CP"
|
|
1122
1122
|
/* Cp */
|
|
1123
|
-
}, F = W.assembleProperties(i, n.loadCondition, b, 0), g = V.calculateSubRoute(
|
|
1123
|
+
}, F = W.assembleProperties(i, n.loadCondition, b, 0), g = V.calculateSubRoute(s, o);
|
|
1124
1124
|
if (((X = g[0]) == null ? void 0 : X.length) <= 1)
|
|
1125
1125
|
return;
|
|
1126
|
-
const v =
|
|
1126
|
+
const v = e.length ? V.calculateSubWaypoints(s, e) : [];
|
|
1127
1127
|
v.forEach((S) => S.important = !0);
|
|
1128
1128
|
let f = V.simplifyRouteToCoordinates(g, v, 0), u = 0, l = 0, m = 0, I = 0;
|
|
1129
1129
|
const k = {
|
|
@@ -1197,34 +1197,34 @@ class W {
|
|
|
1197
1197
|
* @param lane 基础航线(重要转向点)
|
|
1198
1198
|
* @param options
|
|
1199
1199
|
*/
|
|
1200
|
-
static async analyseCost(
|
|
1200
|
+
static async analyseCost(s, t, a, i, n = {}) {
|
|
1201
1201
|
var g, v;
|
|
1202
|
-
const o = p().valueOf(),
|
|
1203
|
-
|
|
1202
|
+
const o = p().valueOf(), e = [];
|
|
1203
|
+
s.speedStep = s.speedStep || 3, s.alterStep = s.alterStep ?? 1;
|
|
1204
1204
|
const r = V.calculateRouteDistance(i.route);
|
|
1205
1205
|
let d = 0;
|
|
1206
1206
|
a.forEach((f) => {
|
|
1207
1207
|
const u = Math.ceil(r / f.speed / 24);
|
|
1208
1208
|
d = d < u ? u : d;
|
|
1209
1209
|
}), d = d * 1.3;
|
|
1210
|
-
const h = p.utc(
|
|
1210
|
+
const h = p.utc(s.etd).add(d ?? 14, "day");
|
|
1211
1211
|
let c = 1;
|
|
1212
1212
|
for (const f of a) {
|
|
1213
1213
|
const u = JSON.parse(JSON.stringify(i.route)), l = JSON.parse(JSON.stringify(i.waypoints)), m = await W.analyseInstantWithThreshed(
|
|
1214
|
-
{ lat:
|
|
1215
|
-
|
|
1214
|
+
{ lat: s.lat, lng: s.lng },
|
|
1215
|
+
s.etd,
|
|
1216
1216
|
h,
|
|
1217
1217
|
t,
|
|
1218
1218
|
f,
|
|
1219
1219
|
u,
|
|
1220
1220
|
l,
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1221
|
+
s.meteoVendor,
|
|
1222
|
+
s.speedStep,
|
|
1223
|
+
s.useMeteo,
|
|
1224
|
+
s.useRouteParam,
|
|
1225
1225
|
n
|
|
1226
1226
|
);
|
|
1227
|
-
m && (await W.calculateCost(m, f,
|
|
1227
|
+
m && (await W.calculateCost(m, f, s, n), e.push(m), C == null || C.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, s.etd, h.format(), {
|
|
1228
1228
|
cost: m.cost.total,
|
|
1229
1229
|
hire: m.cost.hire,
|
|
1230
1230
|
bunker: m.cost.bunker,
|
|
@@ -1233,16 +1233,16 @@ class W {
|
|
|
1233
1233
|
cp: `${f.speed}/${f.fo}/${f.dgo}`
|
|
1234
1234
|
})), c++;
|
|
1235
1235
|
}
|
|
1236
|
-
|
|
1237
|
-
const M =
|
|
1236
|
+
e.sort((f, u) => f.cost.total - u.cost.total);
|
|
1237
|
+
const M = e.at(0), w = e.at(1), b = [];
|
|
1238
1238
|
if (b.push({ combined: !1, speeds: [M], cost: (g = M.cost) == null ? void 0 : g.total }), w) {
|
|
1239
1239
|
const f = M.cost.cp, u = w.cost.cp, l = p(M.eta), m = p(M.etd), I = l.diff(m, "days", !0);
|
|
1240
1240
|
let k = Math.ceil(I / 2);
|
|
1241
|
-
k = k > 7 ? 7 : k <
|
|
1241
|
+
k = k > 7 ? 7 : k < s.alterStep ? s.alterStep : k;
|
|
1242
1242
|
let E = 2, q = { combined: !1, speeds: [w], cost: (v = w.cost) == null ? void 0 : v.total }, D;
|
|
1243
|
-
for (; k >=
|
|
1244
|
-
const H = await W.combinedAnalyse(
|
|
1245
|
-
if (q.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = q, q = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), k <=
|
|
1243
|
+
for (; k >= s.alterStep; ) {
|
|
1244
|
+
const H = await W.combinedAnalyse(s, t, h, [f, u], i, k, { ...n, level: E });
|
|
1245
|
+
if (q.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = q, q = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), k <= s.alterStep)
|
|
1246
1246
|
break;
|
|
1247
1247
|
k = Math.ceil(k / 2), E += 1;
|
|
1248
1248
|
}
|
|
@@ -1261,18 +1261,18 @@ class W {
|
|
|
1261
1261
|
* @param step 步长,7,4,2,1
|
|
1262
1262
|
* @param options
|
|
1263
1263
|
*/
|
|
1264
|
-
static async combinedAnalyse(
|
|
1265
|
-
|
|
1266
|
-
const r = await W.alternateAnalyse(
|
|
1267
|
-
C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j",
|
|
1264
|
+
static async combinedAnalyse(s, t, a, i, n, o, e = {}) {
|
|
1265
|
+
e.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", e.requestId, e.level, o);
|
|
1266
|
+
const r = await W.alternateAnalyse(s, t, a, i, 0, n, o, e), d = r.reduce((u, l) => u + l.cost.total, 0), h = r.reduce((u, l) => u + l.cost.hire, 0), c = r.reduce((u, l) => u + l.cost.bunker, 0), M = r.reduce((u, l) => u + l.distance, 0), w = r.reduce((u, l) => u + l.totalHrs, 0);
|
|
1267
|
+
C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", e.requestId, e.level, {
|
|
1268
1268
|
cost: d,
|
|
1269
1269
|
hire: h,
|
|
1270
1270
|
bunker: c,
|
|
1271
1271
|
distance: M,
|
|
1272
1272
|
hours: w
|
|
1273
1273
|
});
|
|
1274
|
-
const b = await W.alternateAnalyse(
|
|
1275
|
-
return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j",
|
|
1274
|
+
const b = await W.alternateAnalyse(s, t, a, i, 1, n, o, e), j = b.reduce((u, l) => u + l.cost.total, 0), F = b.reduce((u, l) => u + l.cost.hire, 0), g = b.reduce((u, l) => u + l.cost.bunker, 0), v = b.reduce((u, l) => u + l.distance, 0), f = b.reduce((u, l) => u + l.totalHrs, 0);
|
|
1275
|
+
return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j", e.requestId, e.level, {
|
|
1276
1276
|
cost: j,
|
|
1277
1277
|
hire: F,
|
|
1278
1278
|
bunker: g,
|
|
@@ -1291,12 +1291,12 @@ class W {
|
|
|
1291
1291
|
* @param step 步长,7,4,2,1
|
|
1292
1292
|
* @param options
|
|
1293
1293
|
*/
|
|
1294
|
-
static async alternateAnalyse(
|
|
1294
|
+
static async alternateAnalyse(s, t, a, i, n, o, e, r = {}) {
|
|
1295
1295
|
var M, w;
|
|
1296
|
-
let d = p.utc(
|
|
1297
|
-
const h = { lat:
|
|
1296
|
+
let d = p.utc(s.etd);
|
|
1297
|
+
const h = { lat: s.lat, lng: s.lng }, c = [];
|
|
1298
1298
|
for (; d.isBefore(a); ) {
|
|
1299
|
-
const b = d.clone().utc().add(
|
|
1299
|
+
const b = d.clone().utc().add(e, "day"), j = JSON.parse(JSON.stringify(o.route)), F = JSON.parse(JSON.stringify(o.waypoints)), g = i[n], v = await W.analyseInstantWithThreshed(
|
|
1300
1300
|
h,
|
|
1301
1301
|
d.utc().format(),
|
|
1302
1302
|
b,
|
|
@@ -1304,13 +1304,13 @@ class W {
|
|
|
1304
1304
|
g,
|
|
1305
1305
|
j,
|
|
1306
1306
|
F,
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1307
|
+
s.meteoVendor,
|
|
1308
|
+
s.speedStep,
|
|
1309
|
+
s.useMeteo,
|
|
1310
|
+
s.useRouteParam,
|
|
1311
1311
|
r
|
|
1312
1312
|
);
|
|
1313
|
-
v && (await W.calculateCost(v, g,
|
|
1313
|
+
v && (await W.calculateCost(v, g, s, r), C == null || C.info(
|
|
1314
1314
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1315
1315
|
r.requestId,
|
|
1316
1316
|
r.level,
|
|
@@ -1341,39 +1341,40 @@ class W {
|
|
|
1341
1341
|
* @param props
|
|
1342
1342
|
* @param options
|
|
1343
1343
|
*/
|
|
1344
|
-
static async calculateCost(
|
|
1344
|
+
static async calculateCost(s, t, a, i = {}) {
|
|
1345
1345
|
var n;
|
|
1346
|
-
if (
|
|
1347
|
-
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0,
|
|
1348
|
-
|
|
1346
|
+
if (s) {
|
|
1347
|
+
const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, e = Math.round((a.dailyHire || 0) * s.suspend / 24 * 1e3) / 1e3, r = Math.round(e + s.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, d = Math.round(s.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, h = Math.round((s.totalDgoCons + (((n = s.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1348
|
+
s.cost = {
|
|
1349
1349
|
total: Math.round((r + d + h) * 1e3) / 1e3,
|
|
1350
1350
|
hire: r,
|
|
1351
|
+
suspendHire: e,
|
|
1351
1352
|
bunker: Math.round((d + h) * 1e3) / 1e3,
|
|
1352
1353
|
cp: t
|
|
1353
1354
|
};
|
|
1354
1355
|
}
|
|
1355
|
-
return
|
|
1356
|
+
return s;
|
|
1356
1357
|
}
|
|
1357
1358
|
/**
|
|
1358
1359
|
* 计算单cp模式下的ECA属性
|
|
1359
1360
|
*
|
|
1360
1361
|
*/
|
|
1361
|
-
static async calculateECA(
|
|
1362
|
+
static async calculateECA(s, t, a = {}) {
|
|
1362
1363
|
var r, d, h, c;
|
|
1363
|
-
const i = await V.intersectInECA((
|
|
1364
|
-
let n = 0, o = 0,
|
|
1365
|
-
(d = (r =
|
|
1364
|
+
const i = await V.intersectInECA((s == null ? void 0 : s.route) || []);
|
|
1365
|
+
let n = 0, o = 0, e = 0;
|
|
1366
|
+
(d = (r = s == null ? void 0 : s.sample) == null ? void 0 : r.wps) == null || d.forEach((M) => {
|
|
1366
1367
|
M.positionTime = p.utc(M.etd || M.eta).unix();
|
|
1367
1368
|
});
|
|
1368
1369
|
for (const M of i) {
|
|
1369
1370
|
n += M.distance;
|
|
1370
|
-
const w = await V.deadReckoningTime((h = M.waypoints) == null ? void 0 : h.at(0),
|
|
1371
|
-
M.in = w, M.out = b, M.totalHrs = z.roundPrecision((b.positionTime - w.positionTime) / 3600, 3), M.totalDgoCons = z.roundPrecision(t.fo / 24 * M.totalHrs, 3), o += M.totalHrs,
|
|
1371
|
+
const w = await V.deadReckoningTime((h = M.waypoints) == null ? void 0 : h.at(0), s.sample.all || s.sample.wps), b = await V.deadReckoningTime((c = M.waypoints) == null ? void 0 : c.at(-1), s.sample.all || s.sample.wps);
|
|
1372
|
+
M.in = w, M.out = b, M.totalHrs = z.roundPrecision((b.positionTime - w.positionTime) / 3600, 3), M.totalDgoCons = z.roundPrecision(t.fo / 24 * M.totalHrs, 3), o += M.totalHrs, e += M.totalDgoCons;
|
|
1372
1373
|
}
|
|
1373
|
-
return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3),
|
|
1374
|
+
return n = z.roundPrecision(n, 3), o = z.roundPrecision(o, 3), e = z.roundPrecision(e, 3), {
|
|
1374
1375
|
distanceInECA: n,
|
|
1375
1376
|
hoursInECA: o,
|
|
1376
|
-
totalDgoConsInECA:
|
|
1377
|
+
totalDgoConsInECA: e,
|
|
1377
1378
|
eca: i
|
|
1378
1379
|
};
|
|
1379
1380
|
}
|
|
@@ -1382,24 +1383,24 @@ class W {
|
|
|
1382
1383
|
* @param speeds
|
|
1383
1384
|
* @param options
|
|
1384
1385
|
*/
|
|
1385
|
-
static async mergeSpeeds(
|
|
1386
|
+
static async mergeSpeeds(s, t = {}) {
|
|
1386
1387
|
var f, u;
|
|
1387
1388
|
const a = {
|
|
1388
1389
|
hours: [],
|
|
1389
1390
|
wps: [],
|
|
1390
1391
|
days: []
|
|
1391
|
-
}, i =
|
|
1392
|
+
}, i = s.reduce((l, m) => l + m.distance, 0), n = s.reduce((l, m) => {
|
|
1392
1393
|
var I;
|
|
1393
1394
|
return l + (((I = m.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1394
|
-
}, 0), o =
|
|
1395
|
+
}, 0), o = s.reduce((l, m) => l + m.totalHrs, 0), e = s.reduce((l, m) => {
|
|
1395
1396
|
var I;
|
|
1396
1397
|
return l + (((I = m.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1397
|
-
}, 0), r =
|
|
1398
|
+
}, 0), r = s.reduce((l, m) => {
|
|
1398
1399
|
var I;
|
|
1399
1400
|
return l + (((I = m.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1400
|
-
}, 0), d =
|
|
1401
|
+
}, 0), d = s.reduce((l, m) => l + m.wxFactor * m.totalHrs / o, 0), h = s.reduce((l, m) => l + m.cFactor * m.totalHrs / o, 0), c = s.reduce((l, m) => l + m.totalFoCons, 0), M = s.reduce((l, m) => l + m.totalDgoCons, 0), w = s.reduce((l, m) => l + m.cost.total, 0), b = s.reduce((l, m) => l + m.cost.hire, 0), j = s.reduce((l, m) => l + m.cost.bunker, 0), F = [], g = [];
|
|
1401
1402
|
let v;
|
|
1402
|
-
for (const l of
|
|
1403
|
+
for (const l of s) {
|
|
1403
1404
|
g.push(...((f = l.extend) == null ? void 0 : f.eca) || []);
|
|
1404
1405
|
const m = l.sample.hours, I = l.sample.wps, k = l.sample.days, E = m.at(0);
|
|
1405
1406
|
v && (E.distanceFromPrevious = v.distanceFromPrevious, E.distanceFromStart = v.distanceFromStart, m.forEach((T, x) => {
|
|
@@ -1435,11 +1436,11 @@ class W {
|
|
|
1435
1436
|
}
|
|
1436
1437
|
}), {
|
|
1437
1438
|
sample: a,
|
|
1438
|
-
etd:
|
|
1439
|
-
eta:
|
|
1440
|
-
from:
|
|
1441
|
-
to:
|
|
1442
|
-
v0:
|
|
1439
|
+
etd: s.at(0).etd,
|
|
1440
|
+
eta: s.at(-1).eta,
|
|
1441
|
+
from: s.at(0).from,
|
|
1442
|
+
to: s.at(-1).to,
|
|
1443
|
+
v0: s.at(0).v0,
|
|
1443
1444
|
label: "Combined",
|
|
1444
1445
|
distance: Math.round(i * 1e3) / 1e3,
|
|
1445
1446
|
totalHrs: Math.round(o * 1e3) / 1e3,
|
|
@@ -1457,9 +1458,9 @@ class W {
|
|
|
1457
1458
|
cps: F,
|
|
1458
1459
|
eca: g,
|
|
1459
1460
|
distanceInECA: Math.round(n * 1e3) / 1e3,
|
|
1460
|
-
hoursInECA: Math.round(
|
|
1461
|
+
hoursInECA: Math.round(e * 1e3) / 1e3,
|
|
1461
1462
|
totalDgoConsInECA: Math.round(r * 1e3) / 1e3,
|
|
1462
|
-
speeds:
|
|
1463
|
+
speeds: s
|
|
1463
1464
|
}
|
|
1464
1465
|
};
|
|
1465
1466
|
}
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(P,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],D):(P=typeof globalThis<"u"?globalThis:P||self,D(P["idm-plugin-vessel"]={},P.got,P["@log4js-node/log4js-api"],P.moment,P["@idm-plugin/geo2"],P["@idm-plugin/meteo2"],P["@idm-plugin/meteo"]))})(this,function(P,D,U,v,H,pt,it){"use strict";var Ct=Object.defineProperty;var jt=(P,D,U)=>D in P?Ct(P,D,{enumerable:!0,configurable:!0,writable:!0,value:U}):P[D]=U;var K=(P,D,U)=>(jt(P,typeof D!="symbol"?D+"":D,U),U);let y;try{y=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(s){let t,a;switch(s){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class Mt extends G{constructor(t,a){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await D.post(a,i).json();y==null||y.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var e,r;await this.checkToken(a);const i="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};y==null||y.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),[]):(o.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,a={}){var d,l;await this.checkToken(a);const i=/^\d{7}$/.test(t.toString()),n=i?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",o=i?{imo:t}:{mmsi:t},e={headers:{Authorization:`${(d=this.token)==null?void 0:d.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:o};y==null||y.info("[%s] fetch vessel from: %s - %j",a.requestId,n,e);const r=await D.get(n,e).json();if(r.status!==200)return y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const c=r.data;if(c)return{mmsi:c.mmsi,imo:Number.isNaN(c.imo)?null:Number(c.imo),callSign:c.callsign,name:c.nameEn,nameCn:c.nameCn,type:c.vesselTypeNameEn,flagName:c.flagCtry,clasz:c.classSociety,dateOfBuild:c.buildYearMonth,deadweight:c.dwt,grossTonnage:c.grt,netTonnage:c.net,teu:c.teu,length:c.length,breadth:c.width,height:c.height,draught:c.draught,speed:c.speed,passengerCapacity:c.passengercapacity,vendor:"myvessel",raw:c}}return{}}async archives(t,a={}){var e,r;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};y==null||y.info("[%s] fetch vessel archive from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),{}):o.data}async realTimePosition(t,a={}){var r,d;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},searchParams:{mmsi:t}};y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await D.get(i,n).json();if(o.code)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),o;const e=o.data;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));if(e){const l=v(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName||e.aisVesselName,imo:e.imo,callSign:e.callsign||e.aisCallSign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.dest,positionTime:l.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,vesselType:e.vesselTypeNameEn,flag:e.flagCtryNameEn,clasz:e.classSociety,build:e.buildYear,dwt:e.dwt,grt:e.grt,net:e.net,method:"position",vendor:"myVessel",utc:l.utc().format()}}else return{}}async calculateRoute(t,a,i={}){var r,d;await this.checkToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:i.maxDraught||10,useAIModel:i.useAIModel||!1,withECA:i.withECA||!1}};y==null||y.info("[%s] fetch route from: %s - %j",i.requestId,n,o);const e=await D.post(n,o).json();return e.status!==200?(y==null||y.warn("[%s] fetch route failed: %j",i.requestId,{message:e.message,status:e.status,code:e.code}),{}):e.data}async trajectory(t,a,i,n,o=!0,e={}){await this.checkToken(e);const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c=[];for(;l.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(t,d,d.clone().add(30,"day"),r,n,c,e),d.add(30,"day");return await this.trajectoryIn30Day(t,d,l,r,n,c,e),c}async trajectoryIn30Day(t,a,i,n,o,e,r={}){var M,j,F,b,g;const d="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};y==null||y.info("[%s] fetch trajectory from: %s - %j",r.requestId,d,l);const c=await D.post(d,l).json();if(c.code)return y==null||y.warn("[%s] fetch trajectory failed: %j",r.requestId,d,{message:c.message,status:c.status,code:c.code}),c;let p=-1;const w=v(`${(b=(F=c.data)==null?void 0:F[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=c.data)==null||g.forEach(m=>{for(const Y in m)!isNaN(m[Y])&&Number(m[Y])!==1/0&&(m[Y]=Number(m[Y]));const u=v(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=m.status,{labelCn:f,labelEn:k}=this.parseStatus(h),I={mmsi:m.mmsi,imo:n==null?void 0:n.imo,lat:m.lat,lng:m.lon,sog:m.sog,cog:m.cog,hdg:m.hdg,draught:m.draught,status:h,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?v(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:u.unix(),labelCn:f,labelEn:k,method:"trajectory",vendor:"myVessel",utc:u.utc().format()},E=Math.floor(u.diff(w,"minute",!0)/(o||1));E!==p&&(p=E,e.push(I))}),e}}class bt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},o=await D.post(i,n).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const e=o==null?void 0:o.list;if(!e)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const w in e)!isNaN(e[w])&&Number(e[w])!==1/0&&(e[w]=Number(e[w]));e.status=e.sp>3?0:1;const r=e.status,{labelCn:d,labelEn:l}=this.parseStatus(r),c=v(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.destination,vesselType:e.type,dwt:e.dwt,build:e.buildyear,flag:e.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:d,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let o=await D.post(i,n).json();y==null||y.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const r in o)!isNaN(o[r])&&Number(o[r])!==1/0&&(o[r]=Number(o[r]));const e={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await D.post(i,n).json(),y==null||y.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(e.deadweight=Number(o.dwt)),e}async suggest(t,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},o=await D.post(i,n).json();y==null||y.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const e=[];for(const r of o)e.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return e.sort((r,d)=>d.score-r.score),e}async trajectory(t,a,i,n,o=!0,e={}){var m,u,h;const r=await this.realTimePosition(t,e);let d=v(a);const l=v(i),c=v();if(o){let f=l.diff(d,"d",!0);f<0?d=l.clone().subtract(40,"d"):f<30?d.subtract(10,"d"):f<60?d.subtract(5,"d"):d=l.clone().subtract(80,"d"),f=c.diff(l,"d",!0),l.add(f>10?240:f*24,"h")}const p={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},w="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await D.get(w,p).json();y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,w,p);let j;M&&(j=((u=(m=M.ships)==null?void 0:m.offors)==null?void 0:u.ship)||[],j.length||y==null||y.warn("[%s] fetch trajectory failed: %j",e.requestId,M));const F=[];let b=-1;const g=v(`${(h=j==null?void 0:j[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const f of j){for(const R in f)!isNaN(f[R])&&Number(f[R])!==1/0&&(f[R]=Number(f[R]));const k=v(`${f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");f.status=f.sp>4?0:1;const{labelEn:I,labelCn:E}=this.parseStatus(f.status),Y={mmsi:f.m,name:f.n,imo:r==null?void 0:r.imo,lat:f.la,lng:f.lo,draught:f.draught,sog:f.sp,cog:f.co,hdg:f.hdg,positionTime:k.unix(),utc:k.utc().format(),status:f.status,labelCn:E,labelEn:I,method:"trajectory",vendor:"hifleet"},x=Math.floor(k.diff(g,"minute",!0)/(n||1));x!==b&&(b=x,F.push(Y))}return F}}class vt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await D.get(n,i).json();if(y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const e=o.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:r,labelEn:d}=await this.parseStatus(e.navistat),l=v.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:l.utc().format(),status:e.navistat,labelEn:d,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,i,n,o=!0,e={}){var g;const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:d.unix(),etm:l.unix()}},w=await D.get(c,p).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,c,p),(w==null?void 0:w.status)!==0)return w;const M=w==null?void 0:w.points,j=[],F=v.unix((g=M[0])==null?void 0:g.utc);let b=-1;for(const m of M){const u=v.unix(m.utc),h={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(m.sog*3600/1e3/1852*100)/100,cog:Math.round(m.cog/100*100)/100,lat:Math.round(m.lat/1e6*1e5)/1e5,lng:Math.round(m.lon/1e6*1e5)/1e5,positionTime:u.unix(),utc:u.utc().format(),method:"trajectory",vendor:"shipxy"},f=Math.floor(u.diff(F,"minute",!0)/(n||1));f!==b&&(b=f,j.push(h))}return j}}class gt extends G{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,a={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await D.post(n,i).json();return y==null||y.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(t,a={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",o=await D.post(n,i).json();if(y==null||y.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const e=o.data;let r=e.imo;return t==="407170"&&(r="9198379",y==null||y.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,e.imo,r)),{mmsi:e.mmsi,name:e.shipnameEn,imo:r,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,a={}){const i=await this.getShipId(t,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},e="https://api3.myships.com/sp/ships/position/latest",r=await D.post(e,o).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,e,o);const d=r.data[0];for(const M in d)!isNaN(d[M])&&Number(d[M])!==1/0&&(d[M]=Number(d[M]));const{labelCn:l,labelEn:c}=await this.parseStatus(d.aisNavStatus),p=v.unix(d.posTime);return{...n,mmsi:t,lat:Math.round(d.lat/1e4/60*1e5)/1e5,lng:Math.round(d.lon/1e4/60*1e5)/1e5,sog:Math.round(d.sog/10*100)/100,cog:Math.round(d.cog/10*100)/100,hdg:Math.round(d.heading*100)/100,rot:Math.round(d.rot*100)/100,positionTime:d.posTime,utc:p.utc().format(),status:d.aisNavStatus,labelEn:c,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,a,i,n,o=!0,e={}){const r=v(a),d=v(i),l=await this.getShipId(t),c=await this.getShipInfo(l),p=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),c,t,n,p);return await this.trajectoryIn30Day(l,r.unix(),d.unix(),c,t,n,p),p}async trajectoryIn30Day(t,a,i,n,o,e,r,d={}){var F;const l={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:i}},c="https://api3.myships.com/sp/ships/position/history",p=await D.post(c,l).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",d.requestId,c,l),p.code!=="0")return y==null||y.warn("[%s] invoke myship trajectory failed: %j",d.requestId,p),p;const w=p.data;for(const b in w)!isNaN(w[b])&&Number(w[b])!==1/0&&(w[b]=Number(w[b]));const M=v.unix((F=w[0])==null?void 0:F.posTime);let j=-1;for(const b of w){const g=v.unix(b.posTime),m={imo:n==null?void 0:n.imo,mmsi:o,lat:Math.round(b.lat/1e4/60*1e5)/1e5,lng:Math.round(b.lon/1e4/60*1e5)/1e5,sog:Math.round(b.sog/10*100)/100,cog:Math.round(b.cog/10*100)/100,hdg:Math.round(b.heading*100)/100,rot:Math.round(b.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},u=Math.floor(g.diff(M,"minute",!0)/(e||1));u!==j&&(j=u,r.push(m))}return r}}let _;try{_=U.getLogger("vessel")}catch{}finally{}var lt=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(lt||{});class ht{parsePrinciple(s,t={}){var e,r,d;_==null||_.debug("[%s] parse rule: %s",t.requestId,s);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=s.match(a)?(e=s.match(a))==null?void 0:e[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let l=0;l<(n==null?void 0:n.length);l++){const c=(d=(r=n[l].match(a))==null?void 0:r[0])==null?void 0:d.split("],");if(l===0&&!c)o.scope=n[0];else if(c)for(let p=0,w=c.length;p<w;p++){const M=this.parseRule(c[p]);M&&(o[M.level]?M.key?o[M.level][M==null?void 0:M.key]=M:o[M.level]=M:M.key?o[M.level]={[M==null?void 0:M.key]:M}:o[M.level]=M)}}return o}parseRule(s,t={}){var o;_==null||_.debug("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=s==null?void 0:s.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let e=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return e=isNaN(e)?1:e,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:e,key:n[4]}}}checkWeather(s,t,a={}){var M,j,F,b,g,m,u,h,f,k,I,E,Y,x,R;let i=0,n=0,o=0,e=0;const r=Math.round(((j=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:j.number)*1.6*100)/100,d=(b=(F=t==null?void 0:t.SEVERE)==null?void 0:F.sigWave)==null?void 0:b.number,l=(m=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:m.number,c=Math.round((((h=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:h.number)+2)*100)/100,p=(k=(f=t==null?void 0:t.SEVERE)==null?void 0:f.wind)==null?void 0:k.number,w=(E=(I=t==null?void 0:t.HEAVY)==null?void 0:I.wind)==null?void 0:E.number;for(let T=0;T<(s==null?void 0:s.length);T++){const N=s[T],W=(x=(Y=N==null?void 0:N.meteo)==null?void 0:Y.wave)==null?void 0:x.sig,V=(R=N==null?void 0:N.meteo)==null?void 0:R.wind,J=T?v(N.eta).diff(v(s[T-1].eta),"hour",!0):0;e=J>e?J:e,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...W,dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}),(W==null?void 0:W.height)>=r?N.isDangerous=!0:(W==null?void 0:W.height)>=d?N.isSevere=!0:(W==null?void 0:W.height)>=l&&(N.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w}),(V==null?void 0:V.scale)>=c?(N.isDangerous=!0,delete N.isSevere,delete N.isHeavy):(V==null?void 0:V.scale)>p?(N.isDangerous||(N.isSevere=!0),delete N.isHeavy):(V==null?void 0:V.scale)===w&&!N.isDangerous&&!N.isSevere&&(N.isHeavy=!0),i+=N.isDangerous?J:0,n+=N.isSevere?J:0,o+=N.isHeavy?J:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,e=Math.round(e),{sample:s,dangerous:i,severe:n,heavy:o,step:e<3?3:e,wind:{dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w},sig:{dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}}}}const wt=new ht;let C;try{C=U.getLogger("vessel")}catch{}finally{}const It=new pt.MeteoHelper2("",!0);var ft=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ft||{}),mt=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(mt||{}),yt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(yt||{});class B{static blockCoefficient(s,t,a,i){let n=Math.round(s/(t*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],e=o.map(r=>Math.abs(r-n));return o[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,a=9.8){let i=Math.round(Math.sqrt(s*s/(a*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(s,t,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return a==="Laden"&&(o=i[s]),o[0]+o[1]*t+o[2]*Math.pow(t,2)}static directionFactor(s,t=0){let a;return s>30&&s<=60?a=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?a=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(s,t,a,i){let n;return a==="container"?n=.7*i/2+Math.pow(i,3)/(22*Math.pow(s,2/3)):t==="Ballast"?n=.7*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)):n=.5*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)),n}static waveHeightFactor(s,t){s=s<3?s*.7:s,s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=s<3?.4:-.3:t>120&&t<=150?a=s<3?.6:-.5:t>150&&t<=180?a=s<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(s,2)+.278*s)*1e4)/1e4}static assembleProperties(s,t,a,i){var p;const n=s.lbp??s.length??s.lengthOverall??198.9642,o=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,r=s.deadweight??67035.7773,d=((p=s==null?void 0:s.type)==null?void 0:p.toLowerCase())||"common";return{tag:d.indexOf("container")>-1?"container":d.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:o,breadthMoulded:e,displacement:Math.round((r/1.025+o*e*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(s,t,a,i="",n=2,o=!0,e=!1,r={}){let d;if(t.velocity&&e&&(s.speed=H.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),o){let l;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:M,marineModels:j}=await it.Meteo2Assist.autoPickMeteoModel(i),F=await It.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:j}),[b]=it.Meteo2Assist.pickHourly(F,a);l=it.Meteo2Assist.toLegacy(b)}catch(M){C.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:i},M)}const c=B.currentFactor(s.bearing,l==null?void 0:l.current,n),p=B.weatherFactor(s,l,c),w=Math.round((s.speed*1.943844+p+c)*100)/100;d={meteo:{...l},wxFactor:p,cFactor:c,speed:t.velocity&&e?t.velocity:w<0?1:w,eta:a.utc().format(),etd:a.utc().format()}}else d={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round(s.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...d,...t}}static async speedLoseInHoursStep(s,t,a,i,n,o,e="",r=!0,d=!1,l={}){t.utc();const c=t.clone().add(14,"days"),p=[],w=[],M=[];let j=0,F=0,b,g;for(let m=0;m<o.length-1;m++){let u=o[m];u.distanceFromStart=Math.round((n+F)*1e3)/1e3;const h=o[m+1];if(s.bearing=H.LaneHelper.calculateBearing(u,h,!h.gcToPrevious),u.bearing=s.bearing,u.suspend&&d){u.eta=u.eta||t.utc().format(),u.elapsed=u.elapsed??0;const I=u.suspend-u.elapsed;if(i-j>I)i=i-j-I,t.add(I,"hour"),u.elapsed=u.suspend;else{const E=i-j;u.elapsed+=E,t.add(E,"hour"),i=0}if(C==null||C.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,u),i===0)return u.distanceFromPrevious=F,{etd:t,from:g||u,to:u,next:o.filter(E=>E),wps:p,days:w,all:M}}else u.suspend=0;r=t.isAfter(c)?!1:r,u=await B.speedLoseAt(s,u,t,e,0,r,d,l),M.push(u),g=g||u,u.important&&p.push(u),t.isSameOrAfter(a)&&(w.push(u),a.add(24,"hour"));const f=H.LaneHelper.calculateDistance(u,h,!h.gcToPrevious);let k=Math.round(f/g.speed*1e5)/1e5;if(j+k<i){if(j+=k,t.add(k,"hour"),delete o[m],C==null||C.debug(`[%s] go to %j from %j with ${f}nm, and cost ${k} hours`,l.requestId,{lat:h.lat,lng:h.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),F+=f,o.filter(I=>I).length<=1){b=h,b.eta=t.utc().format(),b.distanceFromPrevious=f,b.distanceFromStart=Math.round((n+F)*1e4)/1e4,p.push(b),M.push(b),delete o[m+1];break}}else{k=i-j,t.add(k,"hour");const I=H.LngLatHelper.roundPrecision(g.speed*k,5);b=H.LaneHelper.calculateCoordinate(u,s.bearing,I,"nauticalmiles",!h.gcToPrevious),b.eta=t.utc().format(),o[m]=b,C==null||C.debug(`[%s] go to %j from %j with ${I}nm, and cost ${k} hours`,l.requestId,{lat:b.lat,lng:b.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),F+=I,b.distanceFromPrevious=Math.round(F*1e4)/1e4,b.distanceFromStart=Math.round((n+F)*1e4)/1e4;break}}return{etd:t,from:g,to:b,next:o.filter(m=>m),wps:p,days:w,all:M}}static currentFactor(s,t,a=0){const i=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(s,t,a=0){var w,M,j,F,b,g,m;C==null||C.debug("calculate weather factor via: %j",{...s,...t});const i=B.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=H.LngLatHelper.roundPrecision(a*1852/3600,6),o=B.froudeNumber(s.speed-n,s.lbp),e=B.amendFactor(i,o,s.loadCondition);let r=Math.abs(s.bearing%360-(((w=t==null?void 0:t.wind)==null?void 0:w.degree)%360||0));r=r>180?360-r:r;const d=B.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),l=B.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(j=t==null?void 0:t.wind)==null?void 0:j.kts);let c=d*e*l/100*(s.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),C==null||C.debug("wind wx factor = %d",c),r=Math.abs(s.bearing%360-(((b=(F=t==null?void 0:t.wave)==null?void 0:F.sig)==null?void 0:b.degree)%360||0)),r=r>180?360-r:r;const p=B.waveHeightFactor(((m=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:m.height)??1,r);return C==null||C.debug("wave wx factor = %d",p),c=Math.abs(c)>Math.abs(p)?c:c*.3+p*.7,C==null||C.debug("weather factor = %d",c),c=Math.abs(c)>3?3*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-2)*.1:c,Math.round((c||0)*100)/100}static async analyseInstant(s,t,a,i,n,o="",e=0,r=!0,d=!1,l={}){var X,Q,Z,$,tt,et,st;const c=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{route:p,waypoints:w}=n.points,M=H.LaneHelper.calculateSubRoute(s,p);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:j,label:F}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:i.speed,label:"CP"},b=B.assembleProperties(a,i.loadCondition,j,0),g=w.length?H.LaneHelper.calculateSubWaypoints(s,w):[];g.forEach(L=>L.important=!0);const m={from:{...s},route:M,waypoints:g,v0:j,label:F},u={hours:[],days:[],wps:[],all:[]};e||(H.LaneHelper.calculateRouteDistance(M)/i.speed<=72?e=3:e=6);let h=H.LaneHelper.simplifyRouteToCoordinates(M,g,0),f=0,k=0,I=0,E=0;t=v(t).utc();const Y=t.clone();for(;h.length>0;){const L=e-t.hour()%e,z=Math.ceil(t.clone().add(L,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,S=await B.speedLoseInHoursStep(b,t,Y,z,f,h,o,r,d,l);if(u.all.push(...S.all),(Q=S.from)!=null&&Q.speed&&(u.hours.push(S.from),u.wps.push(...S.wps),u.days.push(...S.days)),h=S==null?void 0:S.next,!h.length){const O=await B.speedLoseAt(b,S.to,v(S.to.eta),o,0,r,d,l);O.bearing=b.bearing,u.hours.push(O),u.all.push(O)}f+=Math.round((((Z=S==null?void 0:S.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const x=u.hours;for(let L=0;L<x.length-1;L++){const z=v(x[L+1].eta).diff(x[L].etd,"hour",!0)||1;k+=(x[L].wxFactor||0)*z,I+=(x[L].cFactor||0)*z,E+=z}const R=x.reduce((L,z)=>L+(z.suspend||0),0);($=u.wps)==null||$.forEach((L,z)=>{L.positionTime=v.utc(L.etd||L.eta).unix();const S=u.wps[z-1];if(S){const O=L.distanceFromStart-S.distanceFromStart,q=v(L.eta||L.etd).diff(v(S.etd||S.eta),"h",!0);L.avgSpd=Math.round(O/q*100)/100,S.bearing=H.LaneHelper.calculateBearing(S,L)}}),u.wps=(tt=u.wps)==null?void 0:tt.reduce((L,z)=>(L.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||L.push(z),L),[]),u.all=(et=u.all)==null?void 0:et.reduce((L,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),L.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||L.push(z),L),[]),m.sample=u;const T=u.hours.at(0),N=u.hours.at(-1);m.distance=Math.round(N.distanceFromStart*1e3)/1e3,m.etd=v(T.eta).utc().format(),m.eta=v(N.eta).utc().format(),m.wxFactor=Math.round(k/E*1e3)/1e3,m.cFactor=Math.round(I/E*1e3)/1e3,m.avgSpeed=Math.round(N.distanceFromStart/E*1e3)/1e3,m.totalHrs=Math.round(E*1e3)/1e3,m.suspend=Math.round(R*1e3)/1e3;const W=H.LngLatHelper.roundPrecision(i.dgo/24*R,3),{distanceInECA:V,hoursInECA:J,totalDgoConsInECA:rt,eca:at}=await this.calculateECA(m,i,l),nt=H.LngLatHelper.roundPrecision(i.fo/24*(E-J),3),ct=H.LngLatHelper.roundPrecision(i.dgo/24*E+W,3);m.extend={eca:at,distanceInECA:V,hoursInECA:J,totalDgoConsInECA:rt,totalDgoConsInSuspend:W},m.totalFoCons=nt<0?0:nt,m.totalDgoCons=ct;const ot=v().valueOf()-c,ut=((st=u==null?void 0:u.hours)==null?void 0:st.length)||1;return C==null||C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,ot,ut,Math.round(ot/ut*1e3)/1e3),m}static async analyseInstantWithThreshed(s,t,a,i,n,o,e,r="",d=3,l=!0,c=!1,p={}){var Z,$,tt,et,st,L,z;const w=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{v0:M,label:j}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:n.speed,label:"CP"},F=B.assembleProperties(i,n.loadCondition,M,0),b=H.LaneHelper.calculateSubRoute(s,o);if(((Z=b[0])==null?void 0:Z.length)<=1)return;const g=e.length?H.LaneHelper.calculateSubWaypoints(s,e):[];g.forEach(S=>S.important=!0);let m=H.LaneHelper.simplifyRouteToCoordinates(b,g,0),u=0,h=0,f=0,k=0;const I={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const E=t.clone();for(;m.length>0;){const S=d-t.hour()%d;let O=Math.ceil(t.clone().add(S,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;O=t.clone().add(O,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:O;const q=await B.speedLoseInHoursStep(F,t,E,O,u,m,r,l,c,p);if(I.all.push(...q.all),($=q.from)!=null&&$.speed&&(I.hours.push(q.from),q!=null&&q.wps&&I.wps.push(...q.wps),I.days.push(...q.days)),m=q==null?void 0:q.next,m.length||I.hours.push(q==null?void 0:q.to),u+=Math.round((((tt=q==null?void 0:q.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!O)break}I.wps=(et=I.wps)==null?void 0:et.reduce((S,O)=>(S.some(q=>Math.round(v(q.etd).unix()/60)===Math.round(v(O.etd).unix()/60))||S.push(O),S),[]),I.all=(st=I.all)==null?void 0:st.reduce((S,O)=>(O.positionTime=v.utc(O.etd||O.eta).unix(),S.some(q=>Math.round(v(q.etd).unix()/60)===Math.round(v(O.etd).unix()/60))||S.push(O),S),[]),(L=I.wps)==null||L.forEach((S,O)=>{const q=I.wps[O-1];if(q){const kt=S.distanceFromStart-q.distanceFromStart,St=v(S.eta||S.etd).diff(v(q.etd||q.eta),"h",!0);S.avgSpd=Math.round(kt/St*100)/100,q.bearing=H.LaneHelper.calculateBearing(q,S)}});const Y=I.hours;for(let S=0;S<Y.length-1;S++){const O=v(Y[S+1].eta).diff(Y[S].etd,"hour",!0);h+=Y[S].wxFactor*O,f+=Y[S].cFactor*O,k+=O}const x=Y.reduce((S,O)=>S+(O.suspend||0),0),R=I.hours.at(0),T=I.hours.at(-1),N=await H.LaneHelper.calculateRangeRoute(R,T,b),W=await H.LaneHelper.calculateRangeWaypoints(R,T,b,g),V={sample:I,distance:Math.round(((T==null?void 0:T.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(T==null?void 0:T.eta).utc().format(),wxFactor:Math.round(h/k*1e3)/1e3,cFactor:Math.round(f/k*1e3)/1e3,avgSpeed:Math.round(((T==null?void 0:T.distanceFromStart)||0)/k*1e3)/1e3,totalHrs:Math.round(k*1e3)/1e3,suspend:Math.round(x*1e3)/1e3,from:R,to:T,route:N,waypoints:W,v0:M,label:j},J=H.LngLatHelper.roundPrecision(n.dgo/24*x,3),{distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:nt,eca:ct}=await this.calculateECA(V,n,p),dt=H.LngLatHelper.roundPrecision(n.fo/24*(k-at),3),ot=H.LngLatHelper.roundPrecision(n.dgo/24*k+J,3);V.extend={eca:ct,distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:nt,totalDgoConsInSuspend:J},V.totalDgoCons=ot,V.totalFoCons=dt<0?0:dt;const X=v().valueOf()-w,Q=((z=I==null?void 0:I.hours)==null?void 0:z.length)||1;return C==null||C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",p==null?void 0:p.requestId,X,Q,Math.round(X/Q*1e3)/1e3),V}static async analyseCost(s,t,a,i,n={}){var b,g;const o=v().valueOf(),e=[];s.speedStep=s.speedStep||3,s.alterStep=s.alterStep??1;const r=H.LaneHelper.calculateRouteDistance(i.route);let d=0;a.forEach(m=>{const u=Math.ceil(r/m.speed/24);d=d<u?u:d}),d=d*1.3;const l=v.utc(s.etd).add(d??14,"day");let c=1;for(const m of a){const u=JSON.parse(JSON.stringify(i.route)),h=JSON.parse(JSON.stringify(i.waypoints)),f=await B.analyseInstantWithThreshed({lat:s.lat,lng:s.lng},s.etd,l,t,m,u,h,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,n);f&&(await B.calculateCost(f,m,s,n),e.push(f),C==null||C.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,s.etd,l.format(),{cost:f.cost.total,hire:f.cost.hire,bunker:f.cost.bunker,distance:f.distance,hours:f.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),c++}e.sort((m,u)=>m.cost.total-u.cost.total);const p=e.at(0),w=e.at(1),M=[];if(M.push({combined:!1,speeds:[p],cost:(b=p.cost)==null?void 0:b.total}),w){const m=p.cost.cp,u=w.cost.cp,h=v(p.eta),f=v(p.etd),k=h.diff(f,"days",!0);let I=Math.ceil(k/2);I=I>7?7:I<s.alterStep?s.alterStep:I;let E=2,Y={combined:!1,speeds:[w],cost:(g=w.cost)==null?void 0:g.total},x;for(;I>=s.alterStep;){const R=await B.combinedAnalyse(s,t,l,[m,u],i,I,{...n,level:E});if(Y.cost>R.cost?x?(x==null?void 0:x.cost)>R.cost&&(x=R):(x=Y,Y=R):(!x||(x==null?void 0:x.cost)>R.cost)&&(x=R),I<=s.alterStep)break;I=Math.ceil(I/2),E+=1}M.push(Y),x&&M.push(x)}const F=v().valueOf()-o;return C==null||C.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,F),M.sort((m,u)=>m.cost-u.cost)}static async combinedAnalyse(s,t,a,i,n,o,e={}){e.counter=1,C==null||C.info("[%s][L%d] analyse with alternate cp in every %d days",e.requestId,e.level,o);const r=await B.alternateAnalyse(s,t,a,i,0,n,o,e),d=r.reduce((u,h)=>u+h.cost.total,0),l=r.reduce((u,h)=>u+h.cost.hire,0),c=r.reduce((u,h)=>u+h.cost.bunker,0),p=r.reduce((u,h)=>u+h.distance,0),w=r.reduce((u,h)=>u+h.totalHrs,0);C==null||C.info("[%s][L%d] cost with cpa/cpb turn: %j",e.requestId,e.level,{cost:d,hire:l,bunker:c,distance:p,hours:w});const M=await B.alternateAnalyse(s,t,a,i,1,n,o,e),j=M.reduce((u,h)=>u+h.cost.total,0),F=M.reduce((u,h)=>u+h.cost.hire,0),b=M.reduce((u,h)=>u+h.cost.bunker,0),g=M.reduce((u,h)=>u+h.distance,0),m=M.reduce((u,h)=>u+h.totalHrs,0);return C==null||C.info("[%s][L%d] cost with cpb/cpa turn: %j",e.requestId,e.level,{cost:j,hire:F,bunker:b,distance:g,hours:m}),d<j?{combined:!0,cost:Math.round(d*1e3)/1e3,speeds:r,step:o}:{combined:!0,cost:Math.round(j*1e3)/1e3,speeds:M,step:o}}static async alternateAnalyse(s,t,a,i,n,o,e,r={}){var p,w;let d=v.utc(s.etd);const l={lat:s.lat,lng:s.lng},c=[];for(;d.isBefore(a);){const M=d.clone().utc().add(e,"day"),j=JSON.parse(JSON.stringify(o.route)),F=JSON.parse(JSON.stringify(o.waypoints)),b=i[n],g=await B.analyseInstantWithThreshed(l,d.utc().format(),M,t,b,j,F,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,r);g&&(await B.calculateCost(g,b,s,r),C==null||C.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,d.utc().format(),M.utc().format(),{cost:g.cost.total,hire:g.cost.hire,bunker:g.cost.bunker,distance:g.distance,hours:g.totalHrs,cp:`${b.speed}/${b.fo}/${b.dgo}`})),r.counter=r.counter+1;const m=(w=(p=g==null?void 0:g.sample)==null?void 0:p.hours)==null?void 0:w.at(-1);if(m)l.lat=m.lat,l.lng=m.lng,d=v(m.eta),c.push(g),n=n?0:1;else break}return c}static async calculateCost(s,t,a,i={}){var n;if(s){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,e=(a.dailyHire||0)*s.suspend/24,r=Math.round(e+s.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,d=Math.round(s.totalFoCons*(a.priceFO||0)*1e3)/1e3,l=Math.round((s.totalDgoCons+(((n=s.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;s.cost={total:Math.round((r+d+l)*1e3)/1e3,hire:r,bunker:Math.round((d+l)*1e3)/1e3,cp:t}}return s}static async calculateECA(s,t,a={}){var r,d,l,c;const i=await H.LaneHelper.intersectInECA((s==null?void 0:s.route)||[]);let n=0,o=0,e=0;(d=(r=s==null?void 0:s.sample)==null?void 0:r.wps)==null||d.forEach(p=>{p.positionTime=v.utc(p.etd||p.eta).unix()});for(const p of i){n+=p.distance;const w=await H.LaneHelper.deadReckoningTime((l=p.waypoints)==null?void 0:l.at(0),s.sample.all||s.sample.wps),M=await H.LaneHelper.deadReckoningTime((c=p.waypoints)==null?void 0:c.at(-1),s.sample.all||s.sample.wps);p.in=w,p.out=M,p.totalHrs=H.LngLatHelper.roundPrecision((M.positionTime-w.positionTime)/3600,3),p.totalDgoCons=H.LngLatHelper.roundPrecision(t.fo/24*p.totalHrs,3),o+=p.totalHrs,e+=p.totalDgoCons}return n=H.LngLatHelper.roundPrecision(n,3),o=H.LngLatHelper.roundPrecision(o,3),e=H.LngLatHelper.roundPrecision(e,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:e,eca:i}}static async mergeSpeeds(s,t={}){var m,u;const a={hours:[],wps:[],days:[]},i=s.reduce((h,f)=>h+f.distance,0),n=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.distanceInECA)||0)},0),o=s.reduce((h,f)=>h+f.totalHrs,0),e=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.hoursInECA)||0)},0),r=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.totalDgoConsInECA)||0)},0),d=s.reduce((h,f)=>h+f.wxFactor*f.totalHrs/o,0),l=s.reduce((h,f)=>h+f.cFactor*f.totalHrs/o,0),c=s.reduce((h,f)=>h+f.totalFoCons,0),p=s.reduce((h,f)=>h+f.totalDgoCons,0),w=s.reduce((h,f)=>h+f.cost.total,0),M=s.reduce((h,f)=>h+f.cost.hire,0),j=s.reduce((h,f)=>h+f.cost.bunker,0),F=[],b=[];let g;for(const h of s){b.push(...((m=h.extend)==null?void 0:m.eca)||[]);const f=h.sample.hours,k=h.sample.wps,I=h.sample.days,E=f.at(0);g&&(E.distanceFromPrevious=g.distanceFromPrevious,E.distanceFromStart=g.distanceFromStart,f.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)}),k.at(0).distanceFromPrevious=g.distanceFromPrevious,k.at(0).distanceFromStart=g.distanceFromStart,k.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)}),I.at(0).distanceFromPrevious=g.distanceFromPrevious,I.at(0).distanceFromStart=g.distanceFromStart,I.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)})),E.cp=h.cost.cp;const Y=[h.etd,h.eta],x=F.findIndex(T=>T.id===E.cp.id);x===-1?(E.cp.segment=[Y],F.push(E.cp)):F[x].segment.push(Y),f.forEach(T=>{var W;((W=a.hours)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.hours.push(T)}),k.forEach(T=>{var W;((W=a.wps)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.wps.push(T)}),I.forEach(T=>{var W;((W=a==null?void 0:a.days)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.days.push(T)});const R=(u=a.wps)==null?void 0:u.findIndex(T=>T.eta===E.eta);R===-1?a.wps.push(E):a.wps[R]=E,g=f.at(-1)}return a.wps.sort((h,f)=>{v(h.etd).unix()-v(f.etd).unix()}),a.wps.forEach((h,f)=>{const k=a.wps[f-1];if(k){const I=h.distanceFromStart-(k.distanceFromStart||0),E=v(h.eta||h.etd).diff(v(k.etd||k.eta),"hour",!0),Y=Math.round(I/E*100)/100;h.avgSpd=Y;const x=H.LaneHelper.calculateBearing(k,h);k.bearing=x}}),{sample:a,etd:s.at(0).etd,eta:s.at(-1).eta,from:s.at(0).from,to:s.at(-1).to,v0:s.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(d*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(p*1e3)/1e3,cost:{total:Math.round(w*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:F,eca:b,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(e*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:s}}}}P.AISImpl=G,P.AlertHelper=ht,P.AlertLevel=lt,P.HifleetImpl=bt,P.LoadCondition=mt,P.MyShipImpl=gt,P.MyVesselImpl=Mt,P.ShipxyImpl=vt,P.SpeedHelper=B,P.SpeedLabel=yt,P.VesselTag=ft,P.alertHelper=wt,Object.defineProperty(P,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(P,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],D):(P=typeof globalThis<"u"?globalThis:P||self,D(P["idm-plugin-vessel"]={},P.got,P["@log4js-node/log4js-api"],P.moment,P["@idm-plugin/geo2"],P["@idm-plugin/meteo2"],P["@idm-plugin/meteo"]))})(this,function(P,D,U,v,H,pt,it){"use strict";var Ct=Object.defineProperty;var jt=(P,D,U)=>D in P?Ct(P,D,{enumerable:!0,configurable:!0,writable:!0,value:U}):P[D]=U;var K=(P,D,U)=>(jt(P,typeof D!="symbol"?D+"":D,U),U);let y;try{y=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(s){let t,a;switch(s){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class Mt extends G{constructor(t,a){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await D.post(a,i).json();y==null||y.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var e,r;await this.checkToken(a);const i="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};y==null||y.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),[]):(o.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,a={}){var d,l;await this.checkToken(a);const i=/^\d{7}$/.test(t.toString()),n=i?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",o=i?{imo:t}:{mmsi:t},e={headers:{Authorization:`${(d=this.token)==null?void 0:d.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:o};y==null||y.info("[%s] fetch vessel from: %s - %j",a.requestId,n,e);const r=await D.get(n,e).json();if(r.status!==200)return y==null||y.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const c=r.data;if(c)return{mmsi:c.mmsi,imo:Number.isNaN(c.imo)?null:Number(c.imo),callSign:c.callsign,name:c.nameEn,nameCn:c.nameCn,type:c.vesselTypeNameEn,flagName:c.flagCtry,clasz:c.classSociety,dateOfBuild:c.buildYearMonth,deadweight:c.dwt,grossTonnage:c.grt,netTonnage:c.net,teu:c.teu,length:c.length,breadth:c.width,height:c.height,draught:c.draught,speed:c.speed,passengerCapacity:c.passengercapacity,vendor:"myvessel",raw:c}}return{}}async archives(t,a={}){var e,r;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(e=this.token)==null?void 0:e.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};y==null||y.info("[%s] fetch vessel archive from: %s - %j",a.requestId,i,n);const o=await D.post(i,n).json();return o.status!==200?(y==null||y.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),{}):o.data}async realTimePosition(t,a={}){var r,d;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},searchParams:{mmsi:t}};y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await D.get(i,n).json();if(o.code)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),o;const e=o.data;for(const l in e)!isNaN(e[l])&&Number(e[l])!==1/0&&(e[l]=Number(e[l]));if(e){const l=v(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName||e.aisVesselName,imo:e.imo,callSign:e.callsign||e.aisCallSign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.dest,positionTime:l.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,vesselType:e.vesselTypeNameEn,flag:e.flagCtryNameEn,clasz:e.classSociety,build:e.buildYear,dwt:e.dwt,grt:e.grt,net:e.net,method:"position",vendor:"myVessel",utc:l.utc().format()}}else return{}}async calculateRoute(t,a,i={}){var r,d;await this.checkToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(d=this.token)==null?void 0:d.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:i.maxDraught||10,useAIModel:i.useAIModel||!1,withECA:i.withECA||!1}};y==null||y.info("[%s] fetch route from: %s - %j",i.requestId,n,o);const e=await D.post(n,o).json();return e.status!==200?(y==null||y.warn("[%s] fetch route failed: %j",i.requestId,{message:e.message,status:e.status,code:e.code}),{}):e.data}async trajectory(t,a,i,n,o=!0,e={}){await this.checkToken(e);const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c=[];for(;l.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(t,d,d.clone().add(30,"day"),r,n,c,e),d.add(30,"day");return await this.trajectoryIn30Day(t,d,l,r,n,c,e),c}async trajectoryIn30Day(t,a,i,n,o,e,r={}){var M,j,F,b,g;const d="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};y==null||y.info("[%s] fetch trajectory from: %s - %j",r.requestId,d,l);const c=await D.post(d,l).json();if(c.code)return y==null||y.warn("[%s] fetch trajectory failed: %j",r.requestId,d,{message:c.message,status:c.status,code:c.code}),c;let p=-1;const w=v(`${(b=(F=c.data)==null?void 0:F[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=c.data)==null||g.forEach(m=>{for(const Y in m)!isNaN(m[Y])&&Number(m[Y])!==1/0&&(m[Y]=Number(m[Y]));const u=v(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=m.status,{labelCn:f,labelEn:k}=this.parseStatus(h),I={mmsi:m.mmsi,imo:n==null?void 0:n.imo,lat:m.lat,lng:m.lon,sog:m.sog,cog:m.cog,hdg:m.hdg,draught:m.draught,status:h,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?v(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:u.unix(),labelCn:f,labelEn:k,method:"trajectory",vendor:"myVessel",utc:u.utc().format()},E=Math.floor(u.diff(w,"minute",!0)/(o||1));E!==p&&(p=E,e.push(I))}),e}}class bt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},o=await D.post(i,n).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const e=o==null?void 0:o.list;if(!e)return y==null||y.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const w in e)!isNaN(e[w])&&Number(e[w])!==1/0&&(e[w]=Number(e[w]));e.status=e.sp>3?0:1;const r=e.status,{labelCn:d,labelEn:l}=this.parseStatus(r),c=v(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?v.utc(e.eta).format():void 0,destination:e.destination,vesselType:e.type,dwt:e.dwt,build:e.buildyear,flag:e.fn,positionTime:c.unix(),utc:c.utc().format(),status:r,labelCn:d,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let o=await D.post(i,n).json();y==null||y.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const r in o)!isNaN(o[r])&&Number(o[r])!==1/0&&(o[r]=Number(o[r]));const e={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await D.post(i,n).json(),y==null||y.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(e.deadweight=Number(o.dwt)),e}async suggest(t,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},o=await D.post(i,n).json();y==null||y.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const e=[];for(const r of o)e.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return e.sort((r,d)=>d.score-r.score),e}async trajectory(t,a,i,n,o=!0,e={}){var m,u,h;const r=await this.realTimePosition(t,e);let d=v(a);const l=v(i),c=v();if(o){let f=l.diff(d,"d",!0);f<0?d=l.clone().subtract(40,"d"):f<30?d.subtract(10,"d"):f<60?d.subtract(5,"d"):d=l.clone().subtract(80,"d"),f=c.diff(l,"d",!0),l.add(f>10?240:f*24,"h")}const p={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:d.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},w="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await D.get(w,p).json();y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,w,p);let j;M&&(j=((u=(m=M.ships)==null?void 0:m.offors)==null?void 0:u.ship)||[],j.length||y==null||y.warn("[%s] fetch trajectory failed: %j",e.requestId,M));const F=[];let b=-1;const g=v(`${(h=j==null?void 0:j[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const f of j){for(const R in f)!isNaN(f[R])&&Number(f[R])!==1/0&&(f[R]=Number(f[R]));const k=v(`${f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");f.status=f.sp>4?0:1;const{labelEn:I,labelCn:E}=this.parseStatus(f.status),Y={mmsi:f.m,name:f.n,imo:r==null?void 0:r.imo,lat:f.la,lng:f.lo,draught:f.draught,sog:f.sp,cog:f.co,hdg:f.hdg,positionTime:k.unix(),utc:k.utc().format(),status:f.status,labelCn:E,labelEn:I,method:"trajectory",vendor:"hifleet"},x=Math.floor(k.diff(g,"minute",!0)/(n||1));x!==b&&(b=x,F.push(Y))}return F}}class vt extends G{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,a={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await D.get(n,i).json();if(y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const e=o.data[0];for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const{labelCn:r,labelEn:d}=await this.parseStatus(e.navistat),l=v.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:l.utc().format(),status:e.navistat,labelEn:d,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,i,n,o=!0,e={}){var g;const r=await this.realTimePosition(t,e),d=v(a),l=v(i),c="https://api.shipxy.com/apicall/GetShipTrack",p={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:d.unix(),etm:l.unix()}},w=await D.get(c,p).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",e.requestId,c,p),(w==null?void 0:w.status)!==0)return w;const M=w==null?void 0:w.points,j=[],F=v.unix((g=M[0])==null?void 0:g.utc);let b=-1;for(const m of M){const u=v.unix(m.utc),h={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(m.sog*3600/1e3/1852*100)/100,cog:Math.round(m.cog/100*100)/100,lat:Math.round(m.lat/1e6*1e5)/1e5,lng:Math.round(m.lon/1e6*1e5)/1e5,positionTime:u.unix(),utc:u.utc().format(),method:"trajectory",vendor:"shipxy"},f=Math.floor(u.diff(F,"minute",!0)/(n||1));f!==b&&(b=f,j.push(h))}return j}}class gt extends G{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,a={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await D.post(n,i).json();return y==null||y.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(t,a={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",o=await D.post(n,i).json();if(y==null||y.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const e=o.data;let r=e.imo;return t==="407170"&&(r="9198379",y==null||y.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,e.imo,r)),{mmsi:e.mmsi,name:e.shipnameEn,imo:r,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,a={}){const i=await this.getShipId(t,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},e="https://api3.myships.com/sp/ships/position/latest",r=await D.post(e,o).json();y==null||y.info("[%s] fetch realtime position from: %s - %j",a.requestId,e,o);const d=r.data[0];for(const M in d)!isNaN(d[M])&&Number(d[M])!==1/0&&(d[M]=Number(d[M]));const{labelCn:l,labelEn:c}=await this.parseStatus(d.aisNavStatus),p=v.unix(d.posTime);return{...n,mmsi:t,lat:Math.round(d.lat/1e4/60*1e5)/1e5,lng:Math.round(d.lon/1e4/60*1e5)/1e5,sog:Math.round(d.sog/10*100)/100,cog:Math.round(d.cog/10*100)/100,hdg:Math.round(d.heading*100)/100,rot:Math.round(d.rot*100)/100,positionTime:d.posTime,utc:p.utc().format(),status:d.aisNavStatus,labelEn:c,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,a,i,n,o=!0,e={}){const r=v(a),d=v(i),l=await this.getShipId(t),c=await this.getShipInfo(l),p=[];for(;d.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),c,t,n,p);return await this.trajectoryIn30Day(l,r.unix(),d.unix(),c,t,n,p),p}async trajectoryIn30Day(t,a,i,n,o,e,r,d={}){var F;const l={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:i}},c="https://api3.myships.com/sp/ships/position/history",p=await D.post(c,l).json();if(y==null||y.info("[%s] fetch trajectory from: %s - %j",d.requestId,c,l),p.code!=="0")return y==null||y.warn("[%s] invoke myship trajectory failed: %j",d.requestId,p),p;const w=p.data;for(const b in w)!isNaN(w[b])&&Number(w[b])!==1/0&&(w[b]=Number(w[b]));const M=v.unix((F=w[0])==null?void 0:F.posTime);let j=-1;for(const b of w){const g=v.unix(b.posTime),m={imo:n==null?void 0:n.imo,mmsi:o,lat:Math.round(b.lat/1e4/60*1e5)/1e5,lng:Math.round(b.lon/1e4/60*1e5)/1e5,sog:Math.round(b.sog/10*100)/100,cog:Math.round(b.cog/10*100)/100,hdg:Math.round(b.heading*100)/100,rot:Math.round(b.rot*100)/100,positionTime:g.unix(),utc:g.utc().format(),method:"trajectory",vendor:"myship"},u=Math.floor(g.diff(M,"minute",!0)/(e||1));u!==j&&(j=u,r.push(m))}return r}}let _;try{_=U.getLogger("vessel")}catch{}finally{}var lt=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(lt||{});class ht{parsePrinciple(s,t={}){var e,r,d;_==null||_.debug("[%s] parse rule: %s",t.requestId,s);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=s.match(a)?(e=s.match(a))==null?void 0:e[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let l=0;l<(n==null?void 0:n.length);l++){const c=(d=(r=n[l].match(a))==null?void 0:r[0])==null?void 0:d.split("],");if(l===0&&!c)o.scope=n[0];else if(c)for(let p=0,w=c.length;p<w;p++){const M=this.parseRule(c[p]);M&&(o[M.level]?M.key?o[M.level][M==null?void 0:M.key]=M:o[M.level]=M:M.key?o[M.level]={[M==null?void 0:M.key]:M}:o[M.level]=M)}}return o}parseRule(s,t={}){var o;_==null||_.debug("[%s] parse rule: %s",t.requestId,s),s=s.startsWith("[")?s:`[${s}`,s=s.endsWith("]")?s:`${s}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=s==null?void 0:s.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let e=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return e=isNaN(e)?1:e,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:e,key:n[4]}}}checkWeather(s,t,a={}){var M,j,F,b,g,m,u,h,f,k,I,E,Y,x,R;let i=0,n=0,o=0,e=0;const r=Math.round(((j=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:j.number)*1.6*100)/100,d=(b=(F=t==null?void 0:t.SEVERE)==null?void 0:F.sigWave)==null?void 0:b.number,l=(m=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:m.number,c=Math.round((((h=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:h.number)+2)*100)/100,p=(k=(f=t==null?void 0:t.SEVERE)==null?void 0:f.wind)==null?void 0:k.number,w=(E=(I=t==null?void 0:t.HEAVY)==null?void 0:I.wind)==null?void 0:E.number;for(let T=0;T<(s==null?void 0:s.length);T++){const N=s[T],W=(x=(Y=N==null?void 0:N.meteo)==null?void 0:Y.wave)==null?void 0:x.sig,V=(R=N==null?void 0:N.meteo)==null?void 0:R.wind,J=T?v(N.eta).diff(v(s[T-1].eta),"hour",!0):0;e=J>e?J:e,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...W,dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}),(W==null?void 0:W.height)>=r?N.isDangerous=!0:(W==null?void 0:W.height)>=d?N.isSevere=!0:(W==null?void 0:W.height)>=l&&(N.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w}),(V==null?void 0:V.scale)>=c?(N.isDangerous=!0,delete N.isSevere,delete N.isHeavy):(V==null?void 0:V.scale)>p?(N.isDangerous||(N.isSevere=!0),delete N.isHeavy):(V==null?void 0:V.scale)===w&&!N.isDangerous&&!N.isSevere&&(N.isHeavy=!0),i+=N.isDangerous?J:0,n+=N.isSevere?J:0,o+=N.isHeavy?J:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,e=Math.round(e),{sample:s,dangerous:i,severe:n,heavy:o,step:e<3?3:e,wind:{dgThd4Wd:c,svThd4Wd:p,hvThd4Wd:w},sig:{dgThd4Wv:r,svThd4Wv:d,hvThd4Wv:l}}}}const wt=new ht;let C;try{C=U.getLogger("vessel")}catch{}finally{}const It=new pt.MeteoHelper2("",!0);var ft=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ft||{}),mt=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(mt||{}),yt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(yt||{});class B{static blockCoefficient(s,t,a,i){let n=Math.round(s/(t*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],e=o.map(r=>Math.abs(r-n));return o[e.indexOf(Math.min(...e))]}static froudeNumber(s,t,a=9.8){let i=Math.round(Math.sqrt(s*s/(a*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(s,t,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[s];return a==="Laden"&&(o=i[s]),o[0]+o[1]*t+o[2]*Math.pow(t,2)}static directionFactor(s,t=0){let a;return s>30&&s<=60?a=(1.7-.03*Math.pow(t-4,2))/2:s>60&&s<=150?a=(.9-.06*Math.pow(t-6,2))/2:s>150&&s<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(s,t,a,i){let n;return a==="container"?n=.7*i/2+Math.pow(i,3)/(22*Math.pow(s,2/3)):t==="Ballast"?n=.7*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)):n=.5*i/2+Math.pow(i,3)/(2.7*Math.pow(s,2/3)),n}static waveHeightFactor(s,t){s=s<3?s*.7:s,s=s<0?.2:s,s=s>6?s-.9*(s-6):s,s=s>9?9:s;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=s<3?.4:-.3:t>120&&t<=150?a=s<3?.6:-.5:t>150&&t<=180?a=s<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(s,2)+.278*s)*1e4)/1e4}static assembleProperties(s,t,a,i){var p;const n=s.lbp??s.length??s.lengthOverall??198.9642,o=s.draught??8,e=s.breadthMoulded??s.breadth??s.breadthExtreme??32.4572,r=s.deadweight??67035.7773,d=((p=s==null?void 0:s.type)==null?void 0:p.toLowerCase())||"common";return{tag:d.indexOf("container")>-1?"container":d.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:o,breadthMoulded:e,displacement:Math.round((r/1.025+o*e*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(s,t,a,i="",n=2,o=!0,e=!1,r={}){let d;if(t.velocity&&e&&(s.speed=H.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),o){let l;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:M,marineModels:j}=await it.Meteo2Assist.autoPickMeteoModel(i),F=await It.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:j}),[b]=it.Meteo2Assist.pickHourly(F,a);l=it.Meteo2Assist.toLegacy(b)}catch(M){C.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:i},M)}const c=B.currentFactor(s.bearing,l==null?void 0:l.current,n),p=B.weatherFactor(s,l,c),w=Math.round((s.speed*1.943844+p+c)*100)/100;d={meteo:{...l},wxFactor:p,cFactor:c,speed:t.velocity&&e?t.velocity:w<0?1:w,eta:a.utc().format(),etd:a.utc().format()}}else d={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round(s.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...d,...t}}static async speedLoseInHoursStep(s,t,a,i,n,o,e="",r=!0,d=!1,l={}){t.utc();const c=t.clone().add(14,"days"),p=[],w=[],M=[];let j=0,F=0,b,g;for(let m=0;m<o.length-1;m++){let u=o[m];u.distanceFromStart=Math.round((n+F)*1e3)/1e3;const h=o[m+1];if(s.bearing=H.LaneHelper.calculateBearing(u,h,!h.gcToPrevious),u.bearing=s.bearing,u.suspend&&d){u.eta=u.eta||t.utc().format(),u.elapsed=u.elapsed??0;const I=u.suspend-u.elapsed;if(i-j>I)i=i-j-I,t.add(I,"hour"),u.elapsed=u.suspend;else{const E=i-j;u.elapsed+=E,t.add(E,"hour"),i=0}if(C==null||C.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,u),i===0)return u.distanceFromPrevious=F,{etd:t,from:g||u,to:u,next:o.filter(E=>E),wps:p,days:w,all:M}}else u.suspend=0;r=t.isAfter(c)?!1:r,u=await B.speedLoseAt(s,u,t,e,0,r,d,l),M.push(u),g=g||u,u.important&&p.push(u),t.isSameOrAfter(a)&&(w.push(u),a.add(24,"hour"));const f=H.LaneHelper.calculateDistance(u,h,!h.gcToPrevious);let k=Math.round(f/g.speed*1e5)/1e5;if(j+k<i){if(j+=k,t.add(k,"hour"),delete o[m],C==null||C.debug(`[%s] go to %j from %j with ${f}nm, and cost ${k} hours`,l.requestId,{lat:h.lat,lng:h.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),F+=f,o.filter(I=>I).length<=1){b=h,b.eta=t.utc().format(),b.distanceFromPrevious=f,b.distanceFromStart=Math.round((n+F)*1e4)/1e4,p.push(b),M.push(b),delete o[m+1];break}}else{k=i-j,t.add(k,"hour");const I=H.LngLatHelper.roundPrecision(g.speed*k,5);b=H.LaneHelper.calculateCoordinate(u,s.bearing,I,"nauticalmiles",!h.gcToPrevious),b.eta=t.utc().format(),o[m]=b,C==null||C.debug(`[%s] go to %j from %j with ${I}nm, and cost ${k} hours`,l.requestId,{lat:b.lat,lng:b.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),F+=I,b.distanceFromPrevious=Math.round(F*1e4)/1e4,b.distanceFromStart=Math.round((n+F)*1e4)/1e4;break}}return{etd:t,from:g,to:b,next:o.filter(m=>m),wps:p,days:w,all:M}}static currentFactor(s,t,a=0){const i=(s-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(s,t,a=0){var w,M,j,F,b,g,m;C==null||C.debug("calculate weather factor via: %j",{...s,...t});const i=B.blockCoefficient(s.displacement,s.lbp,s.breadthMoulded,s.draught),n=H.LngLatHelper.roundPrecision(a*1852/3600,6),o=B.froudeNumber(s.speed-n,s.lbp),e=B.amendFactor(i,o,s.loadCondition);let r=Math.abs(s.bearing%360-(((w=t==null?void 0:t.wind)==null?void 0:w.degree)%360||0));r=r>180?360-r:r;const d=B.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),l=B.vesselTagFactor(s.displacement,s.loadCondition,s.tag,(j=t==null?void 0:t.wind)==null?void 0:j.kts);let c=d*e*l/100*(s.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,s.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),C==null||C.debug("wind wx factor = %d",c),r=Math.abs(s.bearing%360-(((b=(F=t==null?void 0:t.wave)==null?void 0:F.sig)==null?void 0:b.degree)%360||0)),r=r>180?360-r:r;const p=B.waveHeightFactor(((m=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:m.height)??1,r);return C==null||C.debug("wave wx factor = %d",p),c=Math.abs(c)>Math.abs(p)?c:c*.3+p*.7,C==null||C.debug("weather factor = %d",c),c=Math.abs(c)>3?3*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-2)*.1:c,Math.round((c||0)*100)/100}static async analyseInstant(s,t,a,i,n,o="",e=0,r=!0,d=!1,l={}){var X,Q,Z,$,tt,et,st;const c=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{route:p,waypoints:w}=n.points,M=H.LaneHelper.calculateSubRoute(s,p);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:j,label:F}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:i.speed,label:"CP"},b=B.assembleProperties(a,i.loadCondition,j,0),g=w.length?H.LaneHelper.calculateSubWaypoints(s,w):[];g.forEach(L=>L.important=!0);const m={from:{...s},route:M,waypoints:g,v0:j,label:F},u={hours:[],days:[],wps:[],all:[]};e||(H.LaneHelper.calculateRouteDistance(M)/i.speed<=72?e=3:e=6);let h=H.LaneHelper.simplifyRouteToCoordinates(M,g,0),f=0,k=0,I=0,E=0;t=v(t).utc();const Y=t.clone();for(;h.length>0;){const L=e-t.hour()%e,z=Math.ceil(t.clone().add(L,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,S=await B.speedLoseInHoursStep(b,t,Y,z,f,h,o,r,d,l);if(u.all.push(...S.all),(Q=S.from)!=null&&Q.speed&&(u.hours.push(S.from),u.wps.push(...S.wps),u.days.push(...S.days)),h=S==null?void 0:S.next,!h.length){const O=await B.speedLoseAt(b,S.to,v(S.to.eta),o,0,r,d,l);O.bearing=b.bearing,u.hours.push(O),u.all.push(O)}f+=Math.round((((Z=S==null?void 0:S.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const x=u.hours;for(let L=0;L<x.length-1;L++){const z=v(x[L+1].eta).diff(x[L].etd,"hour",!0)||1;k+=(x[L].wxFactor||0)*z,I+=(x[L].cFactor||0)*z,E+=z}const R=x.reduce((L,z)=>L+(z.suspend||0),0);($=u.wps)==null||$.forEach((L,z)=>{L.positionTime=v.utc(L.etd||L.eta).unix();const S=u.wps[z-1];if(S){const O=L.distanceFromStart-S.distanceFromStart,q=v(L.eta||L.etd).diff(v(S.etd||S.eta),"h",!0);L.avgSpd=Math.round(O/q*100)/100,S.bearing=H.LaneHelper.calculateBearing(S,L)}}),u.wps=(tt=u.wps)==null?void 0:tt.reduce((L,z)=>(L.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||L.push(z),L),[]),u.all=(et=u.all)==null?void 0:et.reduce((L,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),L.some(S=>Math.round(S.positionTime/60)===Math.round(z.positionTime/60))||L.push(z),L),[]),m.sample=u;const T=u.hours.at(0),N=u.hours.at(-1);m.distance=Math.round(N.distanceFromStart*1e3)/1e3,m.etd=v(T.eta).utc().format(),m.eta=v(N.eta).utc().format(),m.wxFactor=Math.round(k/E*1e3)/1e3,m.cFactor=Math.round(I/E*1e3)/1e3,m.avgSpeed=Math.round(N.distanceFromStart/E*1e3)/1e3,m.totalHrs=Math.round(E*1e3)/1e3,m.suspend=Math.round(R*1e3)/1e3;const W=H.LngLatHelper.roundPrecision(i.dgo/24*R,3),{distanceInECA:V,hoursInECA:J,totalDgoConsInECA:rt,eca:at}=await this.calculateECA(m,i,l),nt=H.LngLatHelper.roundPrecision(i.fo/24*(E-J),3),ct=H.LngLatHelper.roundPrecision(i.dgo/24*E+W,3);m.extend={eca:at,distanceInECA:V,hoursInECA:J,totalDgoConsInECA:rt,totalDgoConsInSuspend:W},m.totalFoCons=nt<0?0:nt,m.totalDgoCons=ct;const ot=v().valueOf()-c,ut=((st=u==null?void 0:u.hours)==null?void 0:st.length)||1;return C==null||C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,ot,ut,Math.round(ot/ut*1e3)/1e3),m}static async analyseInstantWithThreshed(s,t,a,i,n,o,e,r="",d=3,l=!0,c=!1,p={}){var Z,$,tt,et,st,L,z;const w=v().valueOf();s.lng=H.LngLatHelper.convertToStdLng(s.lng);const{v0:M,label:j}=s.sog?{v0:s.sog,label:s.label||"Other"}:{v0:n.speed,label:"CP"},F=B.assembleProperties(i,n.loadCondition,M,0),b=H.LaneHelper.calculateSubRoute(s,o);if(((Z=b[0])==null?void 0:Z.length)<=1)return;const g=e.length?H.LaneHelper.calculateSubWaypoints(s,e):[];g.forEach(S=>S.important=!0);let m=H.LaneHelper.simplifyRouteToCoordinates(b,g,0),u=0,h=0,f=0,k=0;const I={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const E=t.clone();for(;m.length>0;){const S=d-t.hour()%d;let O=Math.ceil(t.clone().add(S,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;O=t.clone().add(O,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:O;const q=await B.speedLoseInHoursStep(F,t,E,O,u,m,r,l,c,p);if(I.all.push(...q.all),($=q.from)!=null&&$.speed&&(I.hours.push(q.from),q!=null&&q.wps&&I.wps.push(...q.wps),I.days.push(...q.days)),m=q==null?void 0:q.next,m.length||I.hours.push(q==null?void 0:q.to),u+=Math.round((((tt=q==null?void 0:q.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!O)break}I.wps=(et=I.wps)==null?void 0:et.reduce((S,O)=>(S.some(q=>Math.round(v(q.etd).unix()/60)===Math.round(v(O.etd).unix()/60))||S.push(O),S),[]),I.all=(st=I.all)==null?void 0:st.reduce((S,O)=>(O.positionTime=v.utc(O.etd||O.eta).unix(),S.some(q=>Math.round(v(q.etd).unix()/60)===Math.round(v(O.etd).unix()/60))||S.push(O),S),[]),(L=I.wps)==null||L.forEach((S,O)=>{const q=I.wps[O-1];if(q){const kt=S.distanceFromStart-q.distanceFromStart,St=v(S.eta||S.etd).diff(v(q.etd||q.eta),"h",!0);S.avgSpd=Math.round(kt/St*100)/100,q.bearing=H.LaneHelper.calculateBearing(q,S)}});const Y=I.hours;for(let S=0;S<Y.length-1;S++){const O=v(Y[S+1].eta).diff(Y[S].etd,"hour",!0);h+=Y[S].wxFactor*O,f+=Y[S].cFactor*O,k+=O}const x=Y.reduce((S,O)=>S+(O.suspend||0),0),R=I.hours.at(0),T=I.hours.at(-1),N=await H.LaneHelper.calculateRangeRoute(R,T,b),W=await H.LaneHelper.calculateRangeWaypoints(R,T,b,g),V={sample:I,distance:Math.round(((T==null?void 0:T.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(T==null?void 0:T.eta).utc().format(),wxFactor:Math.round(h/k*1e3)/1e3,cFactor:Math.round(f/k*1e3)/1e3,avgSpeed:Math.round(((T==null?void 0:T.distanceFromStart)||0)/k*1e3)/1e3,totalHrs:Math.round(k*1e3)/1e3,suspend:Math.round(x*1e3)/1e3,from:R,to:T,route:N,waypoints:W,v0:M,label:j},J=H.LngLatHelper.roundPrecision(n.dgo/24*x,3),{distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:nt,eca:ct}=await this.calculateECA(V,n,p),dt=H.LngLatHelper.roundPrecision(n.fo/24*(k-at),3),ot=H.LngLatHelper.roundPrecision(n.dgo/24*k+J,3);V.extend={eca:ct,distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:nt,totalDgoConsInSuspend:J},V.totalDgoCons=ot,V.totalFoCons=dt<0?0:dt;const X=v().valueOf()-w,Q=((z=I==null?void 0:I.hours)==null?void 0:z.length)||1;return C==null||C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",p==null?void 0:p.requestId,X,Q,Math.round(X/Q*1e3)/1e3),V}static async analyseCost(s,t,a,i,n={}){var b,g;const o=v().valueOf(),e=[];s.speedStep=s.speedStep||3,s.alterStep=s.alterStep??1;const r=H.LaneHelper.calculateRouteDistance(i.route);let d=0;a.forEach(m=>{const u=Math.ceil(r/m.speed/24);d=d<u?u:d}),d=d*1.3;const l=v.utc(s.etd).add(d??14,"day");let c=1;for(const m of a){const u=JSON.parse(JSON.stringify(i.route)),h=JSON.parse(JSON.stringify(i.waypoints)),f=await B.analyseInstantWithThreshed({lat:s.lat,lng:s.lng},s.etd,l,t,m,u,h,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,n);f&&(await B.calculateCost(f,m,s,n),e.push(f),C==null||C.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,s.etd,l.format(),{cost:f.cost.total,hire:f.cost.hire,bunker:f.cost.bunker,distance:f.distance,hours:f.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),c++}e.sort((m,u)=>m.cost.total-u.cost.total);const p=e.at(0),w=e.at(1),M=[];if(M.push({combined:!1,speeds:[p],cost:(b=p.cost)==null?void 0:b.total}),w){const m=p.cost.cp,u=w.cost.cp,h=v(p.eta),f=v(p.etd),k=h.diff(f,"days",!0);let I=Math.ceil(k/2);I=I>7?7:I<s.alterStep?s.alterStep:I;let E=2,Y={combined:!1,speeds:[w],cost:(g=w.cost)==null?void 0:g.total},x;for(;I>=s.alterStep;){const R=await B.combinedAnalyse(s,t,l,[m,u],i,I,{...n,level:E});if(Y.cost>R.cost?x?(x==null?void 0:x.cost)>R.cost&&(x=R):(x=Y,Y=R):(!x||(x==null?void 0:x.cost)>R.cost)&&(x=R),I<=s.alterStep)break;I=Math.ceil(I/2),E+=1}M.push(Y),x&&M.push(x)}const F=v().valueOf()-o;return C==null||C.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,F),M.sort((m,u)=>m.cost-u.cost)}static async combinedAnalyse(s,t,a,i,n,o,e={}){e.counter=1,C==null||C.info("[%s][L%d] analyse with alternate cp in every %d days",e.requestId,e.level,o);const r=await B.alternateAnalyse(s,t,a,i,0,n,o,e),d=r.reduce((u,h)=>u+h.cost.total,0),l=r.reduce((u,h)=>u+h.cost.hire,0),c=r.reduce((u,h)=>u+h.cost.bunker,0),p=r.reduce((u,h)=>u+h.distance,0),w=r.reduce((u,h)=>u+h.totalHrs,0);C==null||C.info("[%s][L%d] cost with cpa/cpb turn: %j",e.requestId,e.level,{cost:d,hire:l,bunker:c,distance:p,hours:w});const M=await B.alternateAnalyse(s,t,a,i,1,n,o,e),j=M.reduce((u,h)=>u+h.cost.total,0),F=M.reduce((u,h)=>u+h.cost.hire,0),b=M.reduce((u,h)=>u+h.cost.bunker,0),g=M.reduce((u,h)=>u+h.distance,0),m=M.reduce((u,h)=>u+h.totalHrs,0);return C==null||C.info("[%s][L%d] cost with cpb/cpa turn: %j",e.requestId,e.level,{cost:j,hire:F,bunker:b,distance:g,hours:m}),d<j?{combined:!0,cost:Math.round(d*1e3)/1e3,speeds:r,step:o}:{combined:!0,cost:Math.round(j*1e3)/1e3,speeds:M,step:o}}static async alternateAnalyse(s,t,a,i,n,o,e,r={}){var p,w;let d=v.utc(s.etd);const l={lat:s.lat,lng:s.lng},c=[];for(;d.isBefore(a);){const M=d.clone().utc().add(e,"day"),j=JSON.parse(JSON.stringify(o.route)),F=JSON.parse(JSON.stringify(o.waypoints)),b=i[n],g=await B.analyseInstantWithThreshed(l,d.utc().format(),M,t,b,j,F,s.meteoVendor,s.speedStep,s.useMeteo,s.useRouteParam,r);g&&(await B.calculateCost(g,b,s,r),C==null||C.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,d.utc().format(),M.utc().format(),{cost:g.cost.total,hire:g.cost.hire,bunker:g.cost.bunker,distance:g.distance,hours:g.totalHrs,cp:`${b.speed}/${b.fo}/${b.dgo}`})),r.counter=r.counter+1;const m=(w=(p=g==null?void 0:g.sample)==null?void 0:p.hours)==null?void 0:w.at(-1);if(m)l.lat=m.lat,l.lng=m.lng,d=v(m.eta),c.push(g),n=n?0:1;else break}return c}static async calculateCost(s,t,a,i={}){var n;if(s){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,e=Math.round((a.dailyHire||0)*s.suspend/24*1e3)/1e3,r=Math.round(e+s.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,d=Math.round(s.totalFoCons*(a.priceFO||0)*1e3)/1e3,l=Math.round((s.totalDgoCons+(((n=s.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;s.cost={total:Math.round((r+d+l)*1e3)/1e3,hire:r,suspendHire:e,bunker:Math.round((d+l)*1e3)/1e3,cp:t}}return s}static async calculateECA(s,t,a={}){var r,d,l,c;const i=await H.LaneHelper.intersectInECA((s==null?void 0:s.route)||[]);let n=0,o=0,e=0;(d=(r=s==null?void 0:s.sample)==null?void 0:r.wps)==null||d.forEach(p=>{p.positionTime=v.utc(p.etd||p.eta).unix()});for(const p of i){n+=p.distance;const w=await H.LaneHelper.deadReckoningTime((l=p.waypoints)==null?void 0:l.at(0),s.sample.all||s.sample.wps),M=await H.LaneHelper.deadReckoningTime((c=p.waypoints)==null?void 0:c.at(-1),s.sample.all||s.sample.wps);p.in=w,p.out=M,p.totalHrs=H.LngLatHelper.roundPrecision((M.positionTime-w.positionTime)/3600,3),p.totalDgoCons=H.LngLatHelper.roundPrecision(t.fo/24*p.totalHrs,3),o+=p.totalHrs,e+=p.totalDgoCons}return n=H.LngLatHelper.roundPrecision(n,3),o=H.LngLatHelper.roundPrecision(o,3),e=H.LngLatHelper.roundPrecision(e,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:e,eca:i}}static async mergeSpeeds(s,t={}){var m,u;const a={hours:[],wps:[],days:[]},i=s.reduce((h,f)=>h+f.distance,0),n=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.distanceInECA)||0)},0),o=s.reduce((h,f)=>h+f.totalHrs,0),e=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.hoursInECA)||0)},0),r=s.reduce((h,f)=>{var k;return h+(((k=f.extend)==null?void 0:k.totalDgoConsInECA)||0)},0),d=s.reduce((h,f)=>h+f.wxFactor*f.totalHrs/o,0),l=s.reduce((h,f)=>h+f.cFactor*f.totalHrs/o,0),c=s.reduce((h,f)=>h+f.totalFoCons,0),p=s.reduce((h,f)=>h+f.totalDgoCons,0),w=s.reduce((h,f)=>h+f.cost.total,0),M=s.reduce((h,f)=>h+f.cost.hire,0),j=s.reduce((h,f)=>h+f.cost.bunker,0),F=[],b=[];let g;for(const h of s){b.push(...((m=h.extend)==null?void 0:m.eca)||[]);const f=h.sample.hours,k=h.sample.wps,I=h.sample.days,E=f.at(0);g&&(E.distanceFromPrevious=g.distanceFromPrevious,E.distanceFromStart=g.distanceFromStart,f.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)}),k.at(0).distanceFromPrevious=g.distanceFromPrevious,k.at(0).distanceFromStart=g.distanceFromStart,k.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)}),I.at(0).distanceFromPrevious=g.distanceFromPrevious,I.at(0).distanceFromStart=g.distanceFromStart,I.forEach((T,N)=>{N&&(T.distanceFromStart=T.distanceFromStart+g.distanceFromStart)})),E.cp=h.cost.cp;const Y=[h.etd,h.eta],x=F.findIndex(T=>T.id===E.cp.id);x===-1?(E.cp.segment=[Y],F.push(E.cp)):F[x].segment.push(Y),f.forEach(T=>{var W;((W=a.hours)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.hours.push(T)}),k.forEach(T=>{var W;((W=a.wps)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.wps.push(T)}),I.forEach(T=>{var W;((W=a==null?void 0:a.days)==null?void 0:W.findIndex(V=>V.eta===T.eta))===-1&&a.days.push(T)});const R=(u=a.wps)==null?void 0:u.findIndex(T=>T.eta===E.eta);R===-1?a.wps.push(E):a.wps[R]=E,g=f.at(-1)}return a.wps.sort((h,f)=>{v(h.etd).unix()-v(f.etd).unix()}),a.wps.forEach((h,f)=>{const k=a.wps[f-1];if(k){const I=h.distanceFromStart-(k.distanceFromStart||0),E=v(h.eta||h.etd).diff(v(k.etd||k.eta),"hour",!0),Y=Math.round(I/E*100)/100;h.avgSpd=Y;const x=H.LaneHelper.calculateBearing(k,h);k.bearing=x}}),{sample:a,etd:s.at(0).etd,eta:s.at(-1).eta,from:s.at(0).from,to:s.at(-1).to,v0:s.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(d*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(p*1e3)/1e3,cost:{total:Math.round(w*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:F,eca:b,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(e*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:s}}}}P.AISImpl=G,P.AlertHelper=ht,P.AlertLevel=lt,P.HifleetImpl=bt,P.LoadCondition=mt,P.MyShipImpl=gt,P.MyVesselImpl=Mt,P.ShipxyImpl=vt,P.SpeedHelper=B,P.SpeedLabel=yt,P.VesselTag=ft,P.alertHelper=wt,Object.defineProperty(P,Symbol.toStringTag,{value:"Module"})});
|