@idm-plugin/vessel 3.4.8 → 3.4.9
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 +208 -208
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -54,7 +54,7 @@ class at {
|
|
|
54
54
|
return { labelCn: t, labelEn: a };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class Et extends at {
|
|
58
58
|
constructor(t, a) {
|
|
59
59
|
super();
|
|
60
60
|
U(this, "clientId");
|
|
@@ -63,13 +63,13 @@ class Tt extends at {
|
|
|
63
63
|
this.clientId = t, this.clientSecret = a;
|
|
64
64
|
}
|
|
65
65
|
async authToken(t = {}) {
|
|
66
|
-
const a = "https://svc.data.myvessel.cn/ada/oauth/token",
|
|
66
|
+
const a = "https://svc.data.myvessel.cn/ada/oauth/token", o = {
|
|
67
67
|
searchParams: {
|
|
68
68
|
client_id: this.clientId,
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
}, n = await B.post(a,
|
|
72
|
+
}, n = await B.post(a, o).json();
|
|
73
73
|
M == null || M.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
|
|
74
74
|
accessToken: n.access_token,
|
|
75
75
|
tokenType: n.token_type,
|
|
@@ -91,7 +91,7 @@ class Tt extends at {
|
|
|
91
91
|
async suggest(t, a = {}) {
|
|
92
92
|
var s, r;
|
|
93
93
|
await this.checkToken(a);
|
|
94
|
-
const
|
|
94
|
+
const o = "https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy", n = {
|
|
95
95
|
headers: {
|
|
96
96
|
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
97
97
|
},
|
|
@@ -100,9 +100,9 @@ class Tt extends at {
|
|
|
100
100
|
recordNum: a.ps || 10
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
M == null || M.info("[%s] fetch suggest vessels from: %s - %j", a.requestId,
|
|
104
|
-
const
|
|
105
|
-
return
|
|
103
|
+
M == null || M.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, o, n);
|
|
104
|
+
const i = await B.post(o, n).json();
|
|
105
|
+
return i.status !== 200 ? (M == null || M.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), []) : (i.data || []).map((l) => ({
|
|
106
106
|
mmsi: l.mmsi,
|
|
107
107
|
name: l.nameEn,
|
|
108
108
|
nameCn: l.nameCn,
|
|
@@ -122,11 +122,11 @@ class Tt extends at {
|
|
|
122
122
|
async search(t, a = {}) {
|
|
123
123
|
var h, l;
|
|
124
124
|
await this.checkToken(a);
|
|
125
|
-
const
|
|
125
|
+
const o = /^\d{7}$/.test(t.toString()), n = o ? "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo" : "https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi", i = o ? { imo: t } : { mmsi: t }, s = {
|
|
126
126
|
headers: {
|
|
127
127
|
Authorization: `${(h = this.token) == null ? void 0 : h.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
|
|
128
128
|
},
|
|
129
|
-
searchParams:
|
|
129
|
+
searchParams: i
|
|
130
130
|
};
|
|
131
131
|
M == null || M.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
|
|
132
132
|
const r = await B.get(n, s).json();
|
|
@@ -164,7 +164,7 @@ class Tt extends at {
|
|
|
164
164
|
async archives(t, a = {}) {
|
|
165
165
|
var s, r;
|
|
166
166
|
await this.checkToken(a);
|
|
167
|
-
const
|
|
167
|
+
const o = "https://svc.data.myvessel.cn/sdc/v1/ship/info/batch", n = {
|
|
168
168
|
headers: {
|
|
169
169
|
Authorization: `${(s = this.token) == null ? void 0 : s.tokenType} ${(r = this.token) == null ? void 0 : r.accessToken}`
|
|
170
170
|
},
|
|
@@ -172,24 +172,24 @@ class Tt extends at {
|
|
|
172
172
|
mmsiList: typeof t == "number" ? [t] : t
|
|
173
173
|
}
|
|
174
174
|
};
|
|
175
|
-
M == null || M.info("[%s] fetch vessel archive from: %s - %j", a.requestId,
|
|
176
|
-
const
|
|
177
|
-
return
|
|
175
|
+
M == null || M.info("[%s] fetch vessel archive from: %s - %j", a.requestId, o, n);
|
|
176
|
+
const i = await B.post(o, n).json();
|
|
177
|
+
return i.status !== 200 ? (M == null || M.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), {}) : i.data;
|
|
178
178
|
}
|
|
179
179
|
async realTimePosition(t, a = {}) {
|
|
180
180
|
var r, h;
|
|
181
181
|
await this.checkToken(a);
|
|
182
|
-
const
|
|
182
|
+
const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
|
|
183
183
|
headers: {
|
|
184
184
|
Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(h = this.token) == null ? void 0 : h.accessToken}`
|
|
185
185
|
},
|
|
186
186
|
searchParams: { mmsi: t }
|
|
187
187
|
};
|
|
188
|
-
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
189
|
-
const
|
|
190
|
-
if (
|
|
191
|
-
return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, { message:
|
|
192
|
-
const s =
|
|
188
|
+
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
|
|
189
|
+
const i = await B.get(o, n).json();
|
|
190
|
+
if (i.code)
|
|
191
|
+
return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), i;
|
|
192
|
+
const s = i.data;
|
|
193
193
|
for (const l in s)
|
|
194
194
|
!isNaN(s[l]) && Number(s[l]) !== 1 / 0 && (s[l] = Number(s[l]));
|
|
195
195
|
if (s) {
|
|
@@ -236,7 +236,7 @@ class Tt extends at {
|
|
|
236
236
|
* @param excludeSeas 排除水域, [sea.code]
|
|
237
237
|
* @param options { requiretId: '请求ID', useAIModel: '启用AI算法', withECA: '是否计算低硫区航行距离', withSpecial: '是否计算穿越的特战区列表和海盗区列表', draught: '最大吃水' }
|
|
238
238
|
*/
|
|
239
|
-
async calculateRoute(t, a,
|
|
239
|
+
async calculateRoute(t, a, o, n, i, s = {}) {
|
|
240
240
|
var y, w, g;
|
|
241
241
|
const r = v();
|
|
242
242
|
await this.checkToken(s);
|
|
@@ -259,7 +259,7 @@ class Tt extends at {
|
|
|
259
259
|
withSpecialRegion: s.withSpecial || !1
|
|
260
260
|
}
|
|
261
261
|
};
|
|
262
|
-
|
|
262
|
+
o != null && o.length && (l.json.crossMonthList = o), n != null && n.length && (l.json.excludeNodes = n), i != null && i.length && (l.json.excludeSeaAreas = i), M == null || M.info("[%s] fetch route from: %s - %j", s.requestId, h, l);
|
|
263
263
|
const d = await B.post(h, l).json();
|
|
264
264
|
if (d.status !== 200)
|
|
265
265
|
return M == null || M.warn("[%s] fetch route failed: %j", s.requestId, { message: d.message, status: d.status, code: d.code }), {};
|
|
@@ -334,14 +334,14 @@ class Tt extends at {
|
|
|
334
334
|
return k.memo = `time cost: ${m}s`, M.info("[%s] calculate route cost: %d seconds", s.requestId, m), k;
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
|
-
async trajectory(t, a,
|
|
337
|
+
async trajectory(t, a, o, n, i = !0, s = {}) {
|
|
338
338
|
await this.checkToken(s);
|
|
339
|
-
const r = await this.realTimePosition(t, s), h = v(a), l = v(
|
|
339
|
+
const r = await this.realTimePosition(t, s), h = v(a), l = v(o), d = [];
|
|
340
340
|
for (; l.diff(h, "day", !0) > 30; )
|
|
341
341
|
await this.trajectoryIn30Day(t, h, h.clone().add(30, "day"), r, n, d, s), h.add(30, "day");
|
|
342
342
|
return await this.trajectoryIn30Day(t, h, l, r, n, d, s), d;
|
|
343
343
|
}
|
|
344
|
-
async trajectoryIn30Day(t, a,
|
|
344
|
+
async trajectoryIn30Day(t, a, o, n, i, s, r = {}) {
|
|
345
345
|
var g, k, j, b, p;
|
|
346
346
|
const h = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", l = {
|
|
347
347
|
headers: {
|
|
@@ -350,7 +350,7 @@ class Tt extends at {
|
|
|
350
350
|
json: {
|
|
351
351
|
mmsi: t,
|
|
352
352
|
startTime: a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
|
|
353
|
-
endTime:
|
|
353
|
+
endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
|
|
354
354
|
}
|
|
355
355
|
};
|
|
356
356
|
M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId, h, l);
|
|
@@ -380,7 +380,7 @@ class Tt extends at {
|
|
|
380
380
|
method: "trajectory",
|
|
381
381
|
vendor: "myVessel",
|
|
382
382
|
utc: u.utc().format()
|
|
383
|
-
}, F = Math.floor(u.diff(w, "minute", !0) / (
|
|
383
|
+
}, F = Math.floor(u.diff(w, "minute", !0) / (i || 1));
|
|
384
384
|
F !== y && (y = F, s.push(C));
|
|
385
385
|
}), s;
|
|
386
386
|
}
|
|
@@ -392,16 +392,16 @@ class Ft extends at {
|
|
|
392
392
|
this.token = t;
|
|
393
393
|
}
|
|
394
394
|
async realTimePosition(t, a = {}) {
|
|
395
|
-
const
|
|
395
|
+
const o = "https://api.hifleet.com/position/position/get/token", n = {
|
|
396
396
|
searchParams: {
|
|
397
397
|
mmsi: t,
|
|
398
398
|
usertoken: this.token
|
|
399
399
|
}
|
|
400
|
-
},
|
|
401
|
-
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId,
|
|
402
|
-
const s =
|
|
400
|
+
}, i = await B.post(o, n).json();
|
|
401
|
+
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
|
|
402
|
+
const s = i == null ? void 0 : i.list;
|
|
403
403
|
if (!s)
|
|
404
|
-
return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId,
|
|
404
|
+
return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, o, i), i;
|
|
405
405
|
for (const w in s)
|
|
406
406
|
!isNaN(s[w]) && Number(s[w]) !== 1 / 0 && (s[w] = Number(s[w]));
|
|
407
407
|
s.status = s.sp > 3 ? 0 : 1;
|
|
@@ -436,7 +436,7 @@ class Ft extends at {
|
|
|
436
436
|
};
|
|
437
437
|
}
|
|
438
438
|
async search(t, a = {}) {
|
|
439
|
-
let
|
|
439
|
+
let o = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
|
|
440
440
|
const n = {
|
|
441
441
|
searchParams: {
|
|
442
442
|
keyword: t
|
|
@@ -447,24 +447,24 @@ class Ft extends at {
|
|
|
447
447
|
Host: "www.hifleet.com"
|
|
448
448
|
}
|
|
449
449
|
};
|
|
450
|
-
let
|
|
451
|
-
M == null || M.info("[%s] fetch vessel props from: %s - %j", a.requestId,
|
|
452
|
-
for (const r in
|
|
453
|
-
!isNaN(
|
|
450
|
+
let i = await B.post(o, n).json();
|
|
451
|
+
M == null || M.info("[%s] fetch vessel props from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]);
|
|
452
|
+
for (const r in i)
|
|
453
|
+
!isNaN(i[r]) && Number(i[r]) !== 1 / 0 && (i[r] = Number(i[r]));
|
|
454
454
|
const s = {
|
|
455
|
-
mmsi:
|
|
456
|
-
name:
|
|
457
|
-
imo:
|
|
458
|
-
callSign:
|
|
459
|
-
length:
|
|
460
|
-
breadth:
|
|
461
|
-
draught:
|
|
462
|
-
type:
|
|
455
|
+
mmsi: i.m,
|
|
456
|
+
name: i.n,
|
|
457
|
+
imo: i.i,
|
|
458
|
+
callSign: i.c,
|
|
459
|
+
length: i.l,
|
|
460
|
+
breadth: i.b,
|
|
461
|
+
draught: i.dr,
|
|
462
|
+
type: i.t
|
|
463
463
|
};
|
|
464
|
-
return
|
|
464
|
+
return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await B.post(o, n).json(), M == null || M.info("[%s] search vessel dead weight from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]), i && (s.deadweight = Number(i.dwt)), s;
|
|
465
465
|
}
|
|
466
466
|
async suggest(t, a = {}) {
|
|
467
|
-
const
|
|
467
|
+
const o = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
|
|
468
468
|
searchParams: {
|
|
469
469
|
q: t
|
|
470
470
|
},
|
|
@@ -473,10 +473,10 @@ class Ft extends at {
|
|
|
473
473
|
Origin: "https://www.hifleet.com",
|
|
474
474
|
Host: "www.hifleet.com"
|
|
475
475
|
}
|
|
476
|
-
},
|
|
477
|
-
M == null || M.info("[%s] suggest vessel props from: %s - %j", a.requestId,
|
|
476
|
+
}, i = await B.post(o, n).json();
|
|
477
|
+
M == null || M.info("[%s] suggest vessel props from: %s - %j", a.requestId, o, n);
|
|
478
478
|
const s = [];
|
|
479
|
-
for (const r of
|
|
479
|
+
for (const r of i)
|
|
480
480
|
s.push({
|
|
481
481
|
mmsi: !r.mmsi || isNaN(r.mmsi) ? null : Number(r.mmsi),
|
|
482
482
|
name: r.name,
|
|
@@ -486,12 +486,12 @@ class Ft extends at {
|
|
|
486
486
|
});
|
|
487
487
|
return s.sort((r, h) => h.score - r.score), s;
|
|
488
488
|
}
|
|
489
|
-
async trajectory(t, a,
|
|
489
|
+
async trajectory(t, a, o, n, i = !0, s = {}) {
|
|
490
490
|
var f, u, m;
|
|
491
491
|
const r = await this.realTimePosition(t, s);
|
|
492
492
|
let h = v(a);
|
|
493
|
-
const l = v(
|
|
494
|
-
if (
|
|
493
|
+
const l = v(o), d = v();
|
|
494
|
+
if (i) {
|
|
495
495
|
let c = l.diff(h, "d", !0);
|
|
496
496
|
c < 0 ? h = l.clone().subtract(40, "d") : c < 30 ? h.subtract(10, "d") : c < 60 ? h.subtract(5, "d") : h = l.clone().subtract(80, "d"), c = d.diff(l, "d", !0), l.add(c > 10 ? 240 : c * 24, "h");
|
|
497
497
|
}
|
|
@@ -544,16 +544,16 @@ class Nt extends at {
|
|
|
544
544
|
this.token = t;
|
|
545
545
|
}
|
|
546
546
|
async realTimePosition(t, a = {}) {
|
|
547
|
-
const
|
|
547
|
+
const o = {
|
|
548
548
|
searchParams: {
|
|
549
549
|
id: t,
|
|
550
550
|
k: this.token,
|
|
551
551
|
enc: 1
|
|
552
552
|
}
|
|
553
|
-
}, n = "https://api.shipxy.com/apicall/GetSingleShip",
|
|
554
|
-
if (M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, n,
|
|
555
|
-
return
|
|
556
|
-
const s =
|
|
553
|
+
}, n = "https://api.shipxy.com/apicall/GetSingleShip", i = await B.get(n, o).json();
|
|
554
|
+
if (M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o), (i == null ? void 0 : i.status) !== 0)
|
|
555
|
+
return i;
|
|
556
|
+
const s = i.data[0];
|
|
557
557
|
for (const y in s)
|
|
558
558
|
!isNaN(s[y]) && Number(s[y]) !== 1 / 0 && (s[y] = Number(s[y]));
|
|
559
559
|
const { labelCn: r, labelEn: h } = await this.parseStatus(s.navistat), l = v.unix(s.lasttime);
|
|
@@ -580,9 +580,9 @@ class Nt extends at {
|
|
|
580
580
|
vendor: "shipxy"
|
|
581
581
|
};
|
|
582
582
|
}
|
|
583
|
-
async trajectory(t, a,
|
|
583
|
+
async trajectory(t, a, o, n, i = !0, s = {}) {
|
|
584
584
|
var p;
|
|
585
|
-
const r = await this.realTimePosition(t, s), h = v(a), l = v(
|
|
585
|
+
const r = await this.realTimePosition(t, s), h = v(a), l = v(o), d = "https://api.shipxy.com/apicall/GetShipTrack", y = {
|
|
586
586
|
searchParams: {
|
|
587
587
|
id: t,
|
|
588
588
|
k: this.token,
|
|
@@ -621,28 +621,28 @@ class xt extends at {
|
|
|
621
621
|
this.token = t;
|
|
622
622
|
}
|
|
623
623
|
async getShipId(t, a = {}) {
|
|
624
|
-
const
|
|
624
|
+
const o = {
|
|
625
625
|
headers: {
|
|
626
626
|
appKey: this.token
|
|
627
627
|
},
|
|
628
628
|
json: {
|
|
629
629
|
mmsiList: t
|
|
630
630
|
}
|
|
631
|
-
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI",
|
|
632
|
-
return M == null || M.info("[%s] fetch ship id from: %s - %j", a.requestId, n,
|
|
631
|
+
}, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", i = await B.post(n, o).json();
|
|
632
|
+
return M == null || M.info("[%s] fetch ship id from: %s - %j", a.requestId, n, o), i.code !== "0" ? i : i.data[0].shipId;
|
|
633
633
|
}
|
|
634
634
|
async getShipInfo(t, a = {}) {
|
|
635
|
-
const
|
|
635
|
+
const o = {
|
|
636
636
|
headers: {
|
|
637
637
|
appKey: this.token
|
|
638
638
|
},
|
|
639
639
|
json: {
|
|
640
640
|
shipId: t
|
|
641
641
|
}
|
|
642
|
-
}, n = "https://api3.myships.com/sp/ships/aissta",
|
|
643
|
-
if (M == null || M.info("[%s] fetch ship info from: %s - %j", a.requestId, n,
|
|
644
|
-
return
|
|
645
|
-
const s =
|
|
642
|
+
}, n = "https://api3.myships.com/sp/ships/aissta", i = await B.post(n, o).json();
|
|
643
|
+
if (M == null || M.info("[%s] fetch ship info from: %s - %j", a.requestId, n, o), i.code !== "0")
|
|
644
|
+
return i;
|
|
645
|
+
const s = i.data;
|
|
646
646
|
let r = s.imo;
|
|
647
647
|
return t === "407170" && (r = "9198379", M == null || M.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, s.imo, r)), {
|
|
648
648
|
mmsi: s.mmsi,
|
|
@@ -655,15 +655,15 @@ class xt extends at {
|
|
|
655
655
|
};
|
|
656
656
|
}
|
|
657
657
|
async realTimePosition(t, a = {}) {
|
|
658
|
-
const
|
|
658
|
+
const o = await this.getShipId(t, a), n = await this.getShipInfo(o, a), i = {
|
|
659
659
|
headers: {
|
|
660
660
|
appKey: this.token
|
|
661
661
|
},
|
|
662
662
|
json: {
|
|
663
|
-
shipId:
|
|
663
|
+
shipId: o
|
|
664
664
|
}
|
|
665
|
-
}, s = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(s,
|
|
666
|
-
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, s,
|
|
665
|
+
}, s = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(s, i).json();
|
|
666
|
+
M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, i);
|
|
667
667
|
const h = r.data[0];
|
|
668
668
|
for (const g in h)
|
|
669
669
|
!isNaN(h[g]) && Number(h[g]) !== 1 / 0 && (h[g] = Number(h[g]));
|
|
@@ -686,13 +686,13 @@ class xt extends at {
|
|
|
686
686
|
vendor: "myship"
|
|
687
687
|
};
|
|
688
688
|
}
|
|
689
|
-
async trajectory(t, a,
|
|
690
|
-
const r = v(a), h = v(
|
|
689
|
+
async trajectory(t, a, o, n, i = !0, s = {}) {
|
|
690
|
+
const r = v(a), h = v(o), l = await this.getShipId(t), d = await this.getShipInfo(l), y = [];
|
|
691
691
|
for (; h.diff(r, "day", !0) > 30; )
|
|
692
692
|
await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), d, t, n, y);
|
|
693
693
|
return await this.trajectoryIn30Day(l, r.unix(), h.unix(), d, t, n, y), y;
|
|
694
694
|
}
|
|
695
|
-
async trajectoryIn30Day(t, a,
|
|
695
|
+
async trajectoryIn30Day(t, a, o, n, i, s, r, h = {}) {
|
|
696
696
|
var j;
|
|
697
697
|
const l = {
|
|
698
698
|
headers: {
|
|
@@ -701,7 +701,7 @@ class xt extends at {
|
|
|
701
701
|
json: {
|
|
702
702
|
shipId: t,
|
|
703
703
|
startTime: a,
|
|
704
|
-
endTime:
|
|
704
|
+
endTime: o
|
|
705
705
|
}
|
|
706
706
|
}, d = "https://api3.myships.com/sp/ships/position/history", y = await B.post(d, l).json();
|
|
707
707
|
if (M == null || M.info("[%s] fetch trajectory from: %s - %j", h.requestId, d, l), y.code !== "0")
|
|
@@ -714,7 +714,7 @@ class xt extends at {
|
|
|
714
714
|
for (const b of w) {
|
|
715
715
|
const p = v.unix(b.posTime), f = {
|
|
716
716
|
imo: n == null ? void 0 : n.imo,
|
|
717
|
-
mmsi:
|
|
717
|
+
mmsi: i,
|
|
718
718
|
lat: Math.round(b.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
719
719
|
lng: Math.round(b.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
720
720
|
sog: Math.round(b.sog / 10 * 100) / 100,
|
|
@@ -750,21 +750,21 @@ class Mt {
|
|
|
750
750
|
parsePrinciple(e, t = {}) {
|
|
751
751
|
var s, r, h;
|
|
752
752
|
J == null || J.debug("[%s] parse rule: %s", t.requestId, e);
|
|
753
|
-
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"),
|
|
753
|
+
const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = e.match(a) ? (s = e.match(a)) == null ? void 0 : s[0] : void 0, n = o == null ? void 0 : o.split(";");
|
|
754
754
|
if (!n)
|
|
755
755
|
return;
|
|
756
|
-
const
|
|
756
|
+
const i = {};
|
|
757
757
|
for (let l = 0; l < (n == null ? void 0 : n.length); l++) {
|
|
758
758
|
const d = (h = (r = n[l].match(a)) == null ? void 0 : r[0]) == null ? void 0 : h.split("],");
|
|
759
759
|
if (l === 0 && !d)
|
|
760
|
-
|
|
760
|
+
i.scope = n[0];
|
|
761
761
|
else if (d)
|
|
762
762
|
for (let y = 0, w = d.length; y < w; y++) {
|
|
763
763
|
const g = this.parseRule(d[y]);
|
|
764
|
-
g && (
|
|
764
|
+
g && (i[g.level] ? g.key ? i[g.level][g == null ? void 0 : g.key] = g : i[g.level] = g : g.key ? i[g.level] = { [g == null ? void 0 : g.key]: g } : i[g.level] = g);
|
|
765
765
|
}
|
|
766
766
|
}
|
|
767
|
-
return
|
|
767
|
+
return i;
|
|
768
768
|
}
|
|
769
769
|
/**
|
|
770
770
|
* 解析单一告警规则
|
|
@@ -773,9 +773,9 @@ class Mt {
|
|
|
773
773
|
* @param options
|
|
774
774
|
*/
|
|
775
775
|
parseRule(e, t = {}) {
|
|
776
|
-
var
|
|
776
|
+
var i;
|
|
777
777
|
J == null || J.debug("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
|
|
778
|
-
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"),
|
|
778
|
+
const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), o = (i = e == null ? void 0 : e.match(a)) == null ? void 0 : i[0], n = o == null ? void 0 : o.split(",");
|
|
779
779
|
if (n) {
|
|
780
780
|
let s = n[3] === "Number.MAX_VALUE" ? 100 : Number(n[3]);
|
|
781
781
|
return s = isNaN(s) ? 1 : s, {
|
|
@@ -795,13 +795,13 @@ class Mt {
|
|
|
795
795
|
*/
|
|
796
796
|
checkWeather(e, t, a = {}) {
|
|
797
797
|
var g, k, j, b, p, f, u, m, c, I, C, F, P, D, H;
|
|
798
|
-
let
|
|
798
|
+
let o = 0, n = 0, i = 0, s = 0;
|
|
799
799
|
const r = Math.round(((k = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.sigWave) == null ? void 0 : k.number) * 1.6 * 100) / 100, h = (b = (j = t == null ? void 0 : t.SEVERE) == null ? void 0 : j.sigWave) == null ? void 0 : b.number, l = (f = (p = t == null ? void 0 : t.HEAVY) == null ? void 0 : p.sigWave) == null ? void 0 : f.number, d = Math.round((((m = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : m.number) + 2) * 100) / 100, y = (I = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : I.number, w = (F = (C = t == null ? void 0 : t.HEAVY) == null ? void 0 : C.wind) == null ? void 0 : F.number;
|
|
800
|
-
for (let
|
|
801
|
-
const N = e[
|
|
802
|
-
s = K > s ? K : s, J == null || J.debug("[%s] check sig.wave: %j", a.requestId, { ...O, dgThd4Wv: r, svThd4Wv: h, hvThd4Wv: l }), (O == null ? void 0 : O.height) >= r ? N.isDangerous = !0 : (O == null ? void 0 : O.height) >= h ? N.isSevere = !0 : (O == null ? void 0 : O.height) >= l && (N.isHeavy = !0), J == null || J.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= d ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === w && !N.isDangerous && !N.isSevere && (N.isHeavy = !0),
|
|
800
|
+
for (let E = 0; E < (e == null ? void 0 : e.length); E++) {
|
|
801
|
+
const N = e[E], O = (D = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wave) == null ? void 0 : D.sig, R = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wind, K = E ? v(N.eta).diff(v(e[E - 1].eta), "hour", !0) : 0;
|
|
802
|
+
s = K > s ? K : s, J == null || J.debug("[%s] check sig.wave: %j", a.requestId, { ...O, dgThd4Wv: r, svThd4Wv: h, hvThd4Wv: l }), (O == null ? void 0 : O.height) >= r ? N.isDangerous = !0 : (O == null ? void 0 : O.height) >= h ? N.isSevere = !0 : (O == null ? void 0 : O.height) >= l && (N.isHeavy = !0), J == null || J.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }), (R == null ? void 0 : R.scale) >= d ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === w && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), o += N.isDangerous ? K : 0, n += N.isSevere ? K : 0, i += N.isHeavy ? K : 0;
|
|
803
803
|
}
|
|
804
|
-
return
|
|
804
|
+
return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, i = Math.round(i * 100) / 100, s = Math.round(s), { sample: e, dangerous: o, severe: n, heavy: i, step: s < 3 ? 3 : s, wind: { dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: w }, sig: { dgThd4Wv: r, svThd4Wv: h, hvThd4Wv: l } };
|
|
805
805
|
}
|
|
806
806
|
}
|
|
807
807
|
const Dt = new Mt();
|
|
@@ -826,11 +826,11 @@ class Y {
|
|
|
826
826
|
* @param draught 吃水 m
|
|
827
827
|
* @return [0.55, 0.85]
|
|
828
828
|
*/
|
|
829
|
-
static blockCoefficient(e, t, a,
|
|
830
|
-
let n = Math.round(e / (t * a *
|
|
829
|
+
static blockCoefficient(e, t, a, o) {
|
|
830
|
+
let n = Math.round(e / (t * a * o) * 100) / 100;
|
|
831
831
|
n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
|
|
832
|
-
const
|
|
833
|
-
return
|
|
832
|
+
const i = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = i.map((r) => Math.abs(r - n));
|
|
833
|
+
return i[s.indexOf(Math.min(...s))];
|
|
834
834
|
}
|
|
835
835
|
/**
|
|
836
836
|
* @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
|
|
@@ -844,8 +844,8 @@ class Y {
|
|
|
844
844
|
* @return [0.05, 0.30]
|
|
845
845
|
*/
|
|
846
846
|
static froudeNumber(e, t, a = 9.8) {
|
|
847
|
-
let
|
|
848
|
-
return
|
|
847
|
+
let o = Math.round(Math.sqrt(e * e / (a * t)) * 100) / 100;
|
|
848
|
+
return o = o < 0.05 ? 0.05 : o > 0.3 ? 0.3 : o, o;
|
|
849
849
|
}
|
|
850
850
|
/**
|
|
851
851
|
* 失速修正系數
|
|
@@ -855,7 +855,7 @@ class Y {
|
|
|
855
855
|
* @private
|
|
856
856
|
*/
|
|
857
857
|
static amendFactor(e, t, a) {
|
|
858
|
-
const
|
|
858
|
+
const o = {
|
|
859
859
|
0.55: [1.7, -1.4, -7.4],
|
|
860
860
|
0.6: [2.2, -2.5, -9.7],
|
|
861
861
|
0.65: [2.6, -3.7, -11.6],
|
|
@@ -864,7 +864,7 @@ class Y {
|
|
|
864
864
|
0.8: [2.6, -13.1, -15.1],
|
|
865
865
|
0.85: [3.1, -18.7, 28]
|
|
866
866
|
};
|
|
867
|
-
let
|
|
867
|
+
let i = {
|
|
868
868
|
0.55: [1.7, -1.4, -7.4],
|
|
869
869
|
0.6: [2.2, -2.5, -9.7],
|
|
870
870
|
0.65: [2.6, -3.7, -11.6],
|
|
@@ -873,7 +873,7 @@ class Y {
|
|
|
873
873
|
0.8: [3, -16.3, -21.6],
|
|
874
874
|
0.85: [3.4, -20.9, 31.8]
|
|
875
875
|
}[e];
|
|
876
|
-
return a === "Laden" && (
|
|
876
|
+
return a === "Laden" && (i = o[e]), i[0] + i[1] * t + i[2] * Math.pow(t, 2);
|
|
877
877
|
}
|
|
878
878
|
/**
|
|
879
879
|
* 失速方向因子
|
|
@@ -902,9 +902,9 @@ class Y {
|
|
|
902
902
|
* @param kts
|
|
903
903
|
* @private
|
|
904
904
|
*/
|
|
905
|
-
static vesselTagFactor(e, t, a,
|
|
905
|
+
static vesselTagFactor(e, t, a, o) {
|
|
906
906
|
let n;
|
|
907
|
-
return a === "container" ? n = 0.7 *
|
|
907
|
+
return a === "container" ? n = 0.7 * o / 2 + Math.pow(o, 3) / (22 * Math.pow(e, 2 / 3)) : t === "Ballast" ? n = 0.7 * o / 2 + Math.pow(o, 3) / (2.7 * Math.pow(e, 2 / 3)) : n = 0.5 * o / 2 + Math.pow(o, 3) / (2.7 * Math.pow(e, 2 / 3)), n;
|
|
908
908
|
}
|
|
909
909
|
/**
|
|
910
910
|
* 浪高影响因子
|
|
@@ -925,21 +925,21 @@ class Y {
|
|
|
925
925
|
* @param bearing 方位角
|
|
926
926
|
* @private
|
|
927
927
|
*/
|
|
928
|
-
static assembleProperties(e, t, a,
|
|
928
|
+
static assembleProperties(e, t, a, o) {
|
|
929
929
|
var y;
|
|
930
|
-
const n = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642,
|
|
930
|
+
const n = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, i = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, h = ((y = e == null ? void 0 : e.type) == null ? void 0 : y.toLowerCase()) || "common";
|
|
931
931
|
return {
|
|
932
932
|
tag: h.indexOf("container") > -1 ? "container" : h.indexOf("tugs") > -1 ? "tugs" : "common",
|
|
933
933
|
lbp: n,
|
|
934
934
|
loadCondition: t,
|
|
935
|
-
draught:
|
|
935
|
+
draught: i,
|
|
936
936
|
breadthMoulded: s,
|
|
937
937
|
// 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
|
|
938
938
|
// 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
|
|
939
|
-
displacement: Math.round((r / 1.025 +
|
|
939
|
+
displacement: Math.round((r / 1.025 + i * s * n * 0.7) * 1e4) / 1e4,
|
|
940
940
|
// 换算为m/s
|
|
941
941
|
speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
|
|
942
|
-
bearing:
|
|
942
|
+
bearing: o || 90
|
|
943
943
|
};
|
|
944
944
|
}
|
|
945
945
|
/**
|
|
@@ -953,13 +953,13 @@ class Y {
|
|
|
953
953
|
* @param useRouteParam true 启用设置速度
|
|
954
954
|
* @param options
|
|
955
955
|
*/
|
|
956
|
-
static async speedLoseAt(e, t, a,
|
|
956
|
+
static async speedLoseAt(e, t, a, o = "", n = 2, i = !0, s = !1, r = {}) {
|
|
957
957
|
let h;
|
|
958
|
-
if (t.velocity && s && (e.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)),
|
|
958
|
+
if (t.velocity && s && (e.speed = z.roundPrecision(t.velocity * 1852 / 3600, 6)), i) {
|
|
959
959
|
let l;
|
|
960
960
|
try {
|
|
961
|
-
|
|
962
|
-
const { weatherModels: g, marineModels: k } = await ct.autoPickMeteoModel(
|
|
961
|
+
o = (o == null ? void 0 : o.toUpperCase()) === "CMEMS" ? "ECMWF" : o, o = (o == null ? void 0 : o.toUpperCase()) === "METEO2" ? "best_match" : o;
|
|
962
|
+
const { weatherModels: g, marineModels: k } = await ct.autoPickMeteoModel(o), j = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
|
|
963
963
|
...r,
|
|
964
964
|
pastDays: 1,
|
|
965
965
|
forecastDays: 1,
|
|
@@ -968,7 +968,7 @@ class Y {
|
|
|
968
968
|
}), [b] = ct.pickHourly(j, a);
|
|
969
969
|
l = ct.toLegacy(b);
|
|
970
970
|
} catch (g) {
|
|
971
|
-
S.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source:
|
|
971
|
+
S.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, g);
|
|
972
972
|
}
|
|
973
973
|
const d = Y.currentFactor(e.bearing, l == null ? void 0 : l.current, n), y = Y.weatherFactor(e, l, d), w = Math.round((e.speed * 1.943844 + y + d) * 100) / 100;
|
|
974
974
|
h = {
|
|
@@ -1003,44 +1003,44 @@ class Y {
|
|
|
1003
1003
|
* @param options
|
|
1004
1004
|
* @private
|
|
1005
1005
|
*/
|
|
1006
|
-
static async speedLoseInHoursStep(e, t, a,
|
|
1006
|
+
static async speedLoseInHoursStep(e, t, a, o, n, i, s = "", r = !0, h = !1, l = {}) {
|
|
1007
1007
|
t.utc();
|
|
1008
1008
|
const d = t.clone().add(14, "days"), y = [], w = [], g = [];
|
|
1009
1009
|
let k = 0, j = 0, b, p;
|
|
1010
|
-
for (let f = 0; f <
|
|
1011
|
-
let u =
|
|
1010
|
+
for (let f = 0; f < i.length - 1; f++) {
|
|
1011
|
+
let u = i[f];
|
|
1012
1012
|
u.distanceFromStart = Math.round((n + j) * 1e3) / 1e3;
|
|
1013
|
-
const m =
|
|
1013
|
+
const m = i[f + 1];
|
|
1014
1014
|
if (e.bearing = W.calculateBearing(u, m, !m.gcToPrevious), u.bearing = e.bearing, u.suspend && h) {
|
|
1015
1015
|
u.eta = u.eta || t.utc().format(), u.elapsed = u.elapsed ?? 0;
|
|
1016
1016
|
const C = u.suspend - u.elapsed;
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
1017
|
+
if (o - k > C)
|
|
1018
|
+
o = o - k - C, t.add(C, "hour"), u.elapsed = u.suspend;
|
|
1019
1019
|
else {
|
|
1020
|
-
const F =
|
|
1021
|
-
u.elapsed += F, t.add(F, "hour"),
|
|
1020
|
+
const F = o - k;
|
|
1021
|
+
u.elapsed += F, t.add(F, "hour"), o = 0;
|
|
1022
1022
|
}
|
|
1023
|
-
if (S == null || S.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${
|
|
1024
|
-
return u.distanceFromPrevious = j, { etd: t, from: p || u, to: u, next:
|
|
1023
|
+
if (S == null || S.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${o} hours need to go...`, l.requestId, u), o === 0)
|
|
1024
|
+
return u.distanceFromPrevious = j, { etd: t, from: p || u, to: u, next: i.filter((F) => F), wps: y, days: w, all: g };
|
|
1025
1025
|
} else
|
|
1026
1026
|
u.suspend = 0;
|
|
1027
1027
|
r = t.isAfter(d) ? !1 : r, u = await Y.speedLoseAt(e, u, t, s, 0, r, h, l), g.push(u), p = p || u, u.important && y.push(u), t.isSameOrAfter(a) && (w.push(u), a.add(24, "hour"));
|
|
1028
1028
|
const c = W.calculateDistance(u, m, !m.gcToPrevious);
|
|
1029
1029
|
let I = Math.round(c / p.speed * 1e5) / 1e5;
|
|
1030
|
-
if (k + I <
|
|
1031
|
-
if (k += I, t.add(I, "hour"), delete
|
|
1030
|
+
if (k + I < o) {
|
|
1031
|
+
if (k += I, t.add(I, "hour"), delete i[f], S == null || S.debug(
|
|
1032
1032
|
`[%s] go to %j from %j with ${c}nm, and cost ${I} hours`,
|
|
1033
1033
|
l.requestId,
|
|
1034
1034
|
{ lat: m.lat, lng: m.lng },
|
|
1035
1035
|
{ lat: p.lat, lng: p.lng, etd: p.etd }
|
|
1036
|
-
), j += c,
|
|
1037
|
-
b = m, b.eta = t.utc().format(), b.distanceFromPrevious = c, b.distanceFromStart = Math.round((n + j) * 1e4) / 1e4, y.push(b), g.push(b), delete
|
|
1036
|
+
), j += c, i.filter((C) => C).length <= 1) {
|
|
1037
|
+
b = m, b.eta = t.utc().format(), b.distanceFromPrevious = c, b.distanceFromStart = Math.round((n + j) * 1e4) / 1e4, y.push(b), g.push(b), delete i[f + 1];
|
|
1038
1038
|
break;
|
|
1039
1039
|
}
|
|
1040
1040
|
} else {
|
|
1041
|
-
I =
|
|
1041
|
+
I = o - k, t.add(I, "hour");
|
|
1042
1042
|
const C = z.roundPrecision(p.speed * I, 5);
|
|
1043
|
-
b = W.calculateCoordinate(u, e.bearing, C, "nauticalmiles", !m.gcToPrevious), b.eta = t.utc().format(),
|
|
1043
|
+
b = W.calculateCoordinate(u, e.bearing, C, "nauticalmiles", !m.gcToPrevious), b.eta = t.utc().format(), i[f] = b, S == null || S.debug(
|
|
1044
1044
|
`[%s] go to %j from %j with ${C}nm, and cost ${I} hours`,
|
|
1045
1045
|
l.requestId,
|
|
1046
1046
|
{ lat: b.lat, lng: b.lng },
|
|
@@ -1049,7 +1049,7 @@ class Y {
|
|
|
1049
1049
|
break;
|
|
1050
1050
|
}
|
|
1051
1051
|
}
|
|
1052
|
-
return { etd: t, from: p, to: b, next:
|
|
1052
|
+
return { etd: t, from: p, to: b, next: i.filter((f) => f), wps: y, days: w, all: g };
|
|
1053
1053
|
}
|
|
1054
1054
|
/**
|
|
1055
1055
|
* 洋流影响因子
|
|
@@ -1058,10 +1058,10 @@ class Y {
|
|
|
1058
1058
|
* @param role 1: 船东, 2: 租家, 0: 未知
|
|
1059
1059
|
*/
|
|
1060
1060
|
static currentFactor(e, t, a = 0) {
|
|
1061
|
-
const
|
|
1062
|
-
if (Math.abs(
|
|
1061
|
+
const o = (e - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
|
|
1062
|
+
if (Math.abs(o) === Math.PI / 2)
|
|
1063
1063
|
return 0;
|
|
1064
|
-
let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(
|
|
1064
|
+
let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(o);
|
|
1065
1065
|
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;
|
|
1066
1066
|
}
|
|
1067
1067
|
/**
|
|
@@ -1073,7 +1073,7 @@ class Y {
|
|
|
1073
1073
|
static weatherFactor(e, t, a = 0) {
|
|
1074
1074
|
var w, g, k, j, b, p, f;
|
|
1075
1075
|
S == null || S.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
1076
|
-
const
|
|
1076
|
+
const o = Y.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), n = z.roundPrecision(a * 1852 / 3600, 6), i = Y.froudeNumber(e.speed - n, e.lbp), s = Y.amendFactor(o, i, e.loadCondition);
|
|
1077
1077
|
let r = Math.abs(e.bearing % 360 - (((w = t == null ? void 0 : t.wind) == null ? void 0 : w.degree) % 360 || 0));
|
|
1078
1078
|
r = r > 180 ? 360 - r : r;
|
|
1079
1079
|
const h = Y.directionFactor(r, (g = t == null ? void 0 : t.wind) == null ? void 0 : g.scale), l = Y.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.kts);
|
|
@@ -1088,7 +1088,7 @@ class Y {
|
|
|
1088
1088
|
* @param interval 12 hours
|
|
1089
1089
|
*/
|
|
1090
1090
|
static async reduceDays(e, t = 12 * 60 * 60) {
|
|
1091
|
-
return e = e == null ? void 0 : e.reduce((a,
|
|
1091
|
+
return e = e == null ? void 0 : e.reduce((a, o) => (o.positionTime || (o.positionTime = v.utc(o.etd || o.eta).unix()), a.some((n) => Math.floor(n.positionTime / t) === Math.floor(o.positionTime / t)) || a.push(o), a), []), e;
|
|
1092
1092
|
}
|
|
1093
1093
|
/**
|
|
1094
1094
|
* 以分钟级别去掉重复的wps
|
|
@@ -1096,7 +1096,7 @@ class Y {
|
|
|
1096
1096
|
* @param interval 1 minute
|
|
1097
1097
|
*/
|
|
1098
1098
|
static async reduceWPS(e, t = 60) {
|
|
1099
|
-
return e = e == null ? void 0 : e.reduce((a,
|
|
1099
|
+
return e = e == null ? void 0 : e.reduce((a, o) => (a.some((n) => Math.floor(v(n.etd).unix() / t) === Math.floor(v(o.etd).unix() / t)) || a.push(o), a), []), e;
|
|
1100
1100
|
}
|
|
1101
1101
|
/**
|
|
1102
1102
|
* 全程失速分析(走完航程)
|
|
@@ -1111,7 +1111,7 @@ class Y {
|
|
|
1111
1111
|
* @param useRouteParam
|
|
1112
1112
|
* @param options
|
|
1113
1113
|
*/
|
|
1114
|
-
static async analyseInstant(e, t, a,
|
|
1114
|
+
static async analyseInstant(e, t, a, o, n, i = "", s = 0, r = !0, h = !1, l = {}) {
|
|
1115
1115
|
var _, G, X, Q, Z, $;
|
|
1116
1116
|
const d = v().valueOf();
|
|
1117
1117
|
e.lng = z.convertToStdLng(e.lng);
|
|
@@ -1123,10 +1123,10 @@ class Y {
|
|
|
1123
1123
|
label: e.label || "Other"
|
|
1124
1124
|
/* Instruct */
|
|
1125
1125
|
} : {
|
|
1126
|
-
v0:
|
|
1126
|
+
v0: o.speed,
|
|
1127
1127
|
label: "CP"
|
|
1128
1128
|
/* Cp */
|
|
1129
|
-
}, b = Y.assembleProperties(a,
|
|
1129
|
+
}, b = Y.assembleProperties(a, o.loadCondition, k, 0), p = w.length ? W.calculateSubWaypoints(e, w) : [];
|
|
1130
1130
|
p.forEach((A) => A.important = !0);
|
|
1131
1131
|
const f = {
|
|
1132
1132
|
from: { ...e },
|
|
@@ -1140,28 +1140,28 @@ class Y {
|
|
|
1140
1140
|
wps: [],
|
|
1141
1141
|
all: []
|
|
1142
1142
|
};
|
|
1143
|
-
s || (W.calculateRouteDistance(g) /
|
|
1143
|
+
s || (W.calculateRouteDistance(g) / o.speed <= 72 ? s = 3 : s = 6);
|
|
1144
1144
|
let m = W.simplifyRouteToCoordinates(g, p, 0), c = 0, I = 0, C = 0, F = 0;
|
|
1145
1145
|
t = v(t).utc();
|
|
1146
1146
|
const P = t.clone();
|
|
1147
1147
|
for (; m.length > 0; ) {
|
|
1148
|
-
const A = s - t.hour() % s, V = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4,
|
|
1148
|
+
const A = s - t.hour() % s, V = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, T = await Y.speedLoseInHoursStep(
|
|
1149
1149
|
b,
|
|
1150
1150
|
t,
|
|
1151
1151
|
P,
|
|
1152
1152
|
V,
|
|
1153
1153
|
c,
|
|
1154
1154
|
m,
|
|
1155
|
-
|
|
1155
|
+
i,
|
|
1156
1156
|
r,
|
|
1157
1157
|
h,
|
|
1158
1158
|
l
|
|
1159
1159
|
);
|
|
1160
|
-
if (u.all.push(...
|
|
1161
|
-
const L = await Y.speedLoseAt(b,
|
|
1160
|
+
if (u.all.push(...T.all), (G = T.from) != null && G.speed && (u.hours.push(T.from), u.wps.push(...T.wps), u.days.push(...T.days)), m = T == null ? void 0 : T.next, !m.length) {
|
|
1161
|
+
const L = await Y.speedLoseAt(b, T.to, v(T.to.eta), i, 0, r, h, l);
|
|
1162
1162
|
L.bearing = b.bearing, u.hours.push(L), u.all.push(L);
|
|
1163
1163
|
}
|
|
1164
|
-
c += Math.round((((X =
|
|
1164
|
+
c += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
1165
1165
|
}
|
|
1166
1166
|
const D = u.hours;
|
|
1167
1167
|
for (let A = 0; A < D.length - 1; A++) {
|
|
@@ -1171,15 +1171,15 @@ class Y {
|
|
|
1171
1171
|
const H = D.reduce((A, V) => A + (V.suspend || 0), 0);
|
|
1172
1172
|
(Q = u.wps) == null || Q.forEach((A, V) => {
|
|
1173
1173
|
A.positionTime = v.utc(A.etd || A.eta).unix();
|
|
1174
|
-
const
|
|
1175
|
-
if (
|
|
1176
|
-
const L = A.distanceFromStart -
|
|
1177
|
-
A.avgSpd = Math.round(L / q * 100) / 100,
|
|
1174
|
+
const T = u.wps[V - 1];
|
|
1175
|
+
if (T) {
|
|
1176
|
+
const L = A.distanceFromStart - T.distanceFromStart, q = v(A.eta || A.etd).diff(v(T.etd || T.eta), "h", !0);
|
|
1177
|
+
A.avgSpd = Math.round(L / q * 100) / 100, T.bearing = W.calculateBearing(T, A);
|
|
1178
1178
|
}
|
|
1179
|
-
}), u.wps = await Y.reduceWPS(u.wps), u.days = await Y.reduceDays(u.days), u.all = (Z = u.all) == null ? void 0 : Z.reduce((A, V) => (V.positionTime = v.utc(V.etd || V.eta).unix(), A.some((
|
|
1180
|
-
const
|
|
1181
|
-
f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = v(
|
|
1182
|
-
const O = z.roundPrecision(
|
|
1179
|
+
}), u.wps = await Y.reduceWPS(u.wps), u.days = await Y.reduceDays(u.days), u.all = (Z = u.all) == null ? void 0 : Z.reduce((A, V) => (V.positionTime = v.utc(V.etd || V.eta).unix(), A.some((T) => Math.round(T.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), f.sample = u;
|
|
1180
|
+
const E = u.hours.at(0), N = u.hours.at(-1);
|
|
1181
|
+
f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = v(E.eta).utc().format(), f.eta = v(N.eta).utc().format(), f.wxFactor = Math.round(I / F * 1e3) / 1e3, f.cFactor = Math.round(C / F * 1e3) / 1e3, f.avgSpeed = Math.round(N.distanceFromStart / F * 1e3) / 1e3, f.totalHrs = Math.round(F * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
|
|
1182
|
+
const O = z.roundPrecision(o.dgo / 24 * H, 3), { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: nt, eca: tt } = await this.calculateECA(f, o, l), et = z.roundPrecision(o.fo / 24 * (F - K), 3), ot = z.roundPrecision(o.dgo / 24 * F + O, 3);
|
|
1183
1183
|
f.extend = {
|
|
1184
1184
|
eca: tt,
|
|
1185
1185
|
distanceInECA: R,
|
|
@@ -1205,7 +1205,7 @@ class Y {
|
|
|
1205
1205
|
* @param useRouteParam
|
|
1206
1206
|
* @param options
|
|
1207
1207
|
*/
|
|
1208
|
-
static async analyseInstantWithThreshed(e, t, a,
|
|
1208
|
+
static async analyseInstantWithThreshed(e, t, a, o, n, i, s, r = "", h = 3, l = !0, d = !1, y = {}) {
|
|
1209
1209
|
var X, Q, Z, $, A, V;
|
|
1210
1210
|
const w = v().valueOf();
|
|
1211
1211
|
e.lng = z.convertToStdLng(e.lng);
|
|
@@ -1217,11 +1217,11 @@ class Y {
|
|
|
1217
1217
|
v0: n.speed,
|
|
1218
1218
|
label: "CP"
|
|
1219
1219
|
/* Cp */
|
|
1220
|
-
}, j = Y.assembleProperties(
|
|
1220
|
+
}, j = Y.assembleProperties(o, n.loadCondition, g, 0), b = W.calculateSubRoute(e, i);
|
|
1221
1221
|
if (((X = b[0]) == null ? void 0 : X.length) <= 1)
|
|
1222
1222
|
return;
|
|
1223
1223
|
const p = s.length ? W.calculateSubWaypoints(e, s) : [];
|
|
1224
|
-
p.forEach((
|
|
1224
|
+
p.forEach((T) => T.important = !0);
|
|
1225
1225
|
let f = W.simplifyRouteToCoordinates(b, p, 0), u = 0, m = 0, c = 0, I = 0;
|
|
1226
1226
|
const C = {
|
|
1227
1227
|
hours: [],
|
|
@@ -1232,38 +1232,38 @@ class Y {
|
|
|
1232
1232
|
t = v(t).utc();
|
|
1233
1233
|
const F = t.clone();
|
|
1234
1234
|
for (; f.length > 0; ) {
|
|
1235
|
-
const
|
|
1236
|
-
let L = Math.ceil(t.clone().add(
|
|
1235
|
+
const T = h - t.hour() % h;
|
|
1236
|
+
let L = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
1237
1237
|
L = t.clone().add(L, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : L;
|
|
1238
1238
|
const q = await Y.speedLoseInHoursStep(j, t, F, L, u, f, r, l, d, y);
|
|
1239
1239
|
if (C.all.push(...q.all), (Q = q.from) != null && Q.speed && (C.hours.push(q.from), q != null && q.wps && C.wps.push(...q.wps), C.days.push(...q.days)), f = q == null ? void 0 : q.next, f.length || C.hours.push(q == null ? void 0 : q.to), u += Math.round((((Z = q == null ? void 0 : q.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
|
|
1240
1240
|
break;
|
|
1241
1241
|
}
|
|
1242
|
-
C.wps = await Y.reduceWPS(C.wps), C.days = await Y.reduceDays(C.days), C.all = ($ = C.all) == null ? void 0 : $.reduce((
|
|
1242
|
+
C.wps = await Y.reduceWPS(C.wps), C.days = await Y.reduceDays(C.days), C.all = ($ = C.all) == null ? void 0 : $.reduce((T, L) => (L.positionTime = v.utc(L.etd || L.eta).unix(), T.some((q) => Math.round(v(q.etd).unix() / 60) === Math.round(v(L.etd).unix() / 60)) || T.push(L), T), []), (A = C.wps) == null || A.forEach((T, L) => {
|
|
1243
1243
|
const q = C.wps[L - 1];
|
|
1244
1244
|
if (q) {
|
|
1245
|
-
const ut =
|
|
1246
|
-
q.bearing = W.calculateBearing(q,
|
|
1245
|
+
const ut = T.distanceFromStart - q.distanceFromStart, ht = v(T.eta || T.etd).diff(v(q.etd || q.eta), "h", !0);
|
|
1246
|
+
q.bearing = W.calculateBearing(q, T), T.avgSpd = Math.round(ut / ht * 100) / 100;
|
|
1247
1247
|
}
|
|
1248
1248
|
});
|
|
1249
1249
|
const P = C.hours;
|
|
1250
|
-
for (let
|
|
1251
|
-
const L = v(P[
|
|
1252
|
-
m += P[
|
|
1250
|
+
for (let T = 0; T < P.length - 1; T++) {
|
|
1251
|
+
const L = v(P[T + 1].eta).diff(P[T].etd, "hour", !0);
|
|
1252
|
+
m += P[T].wxFactor * L, c += P[T].cFactor * L, I += L;
|
|
1253
1253
|
}
|
|
1254
|
-
const D = P.reduce((
|
|
1254
|
+
const D = P.reduce((T, L) => T + (L.suspend || 0), 0), H = C.hours.at(0), E = C.hours.at(-1), N = await W.calculateRangeRoute(H, E, b), O = await W.calculateRangeWaypoints(H, E, b, p), R = {
|
|
1255
1255
|
sample: C,
|
|
1256
|
-
distance: Math.round(((
|
|
1256
|
+
distance: Math.round(((E == null ? void 0 : E.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1257
1257
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1258
1258
|
etd: v(H.eta).utc().format(),
|
|
1259
|
-
eta: v(
|
|
1259
|
+
eta: v(E == null ? void 0 : E.eta).utc().format(),
|
|
1260
1260
|
wxFactor: Math.round(m / I * 1e3) / 1e3,
|
|
1261
1261
|
cFactor: Math.round(c / I * 1e3) / 1e3,
|
|
1262
|
-
avgSpeed: Math.round(((
|
|
1262
|
+
avgSpeed: Math.round(((E == null ? void 0 : E.distanceFromStart) || 0) / I * 1e3) / 1e3,
|
|
1263
1263
|
totalHrs: Math.round(I * 1e3) / 1e3,
|
|
1264
1264
|
suspend: Math.round(D * 1e3) / 1e3,
|
|
1265
1265
|
from: H,
|
|
1266
|
-
to:
|
|
1266
|
+
to: E,
|
|
1267
1267
|
route: N,
|
|
1268
1268
|
waypoints: O,
|
|
1269
1269
|
v0: g,
|
|
@@ -1294,11 +1294,11 @@ class Y {
|
|
|
1294
1294
|
* @param lane 基础航线(重要转向点)
|
|
1295
1295
|
* @param options
|
|
1296
1296
|
*/
|
|
1297
|
-
static async analyseCost(e, t, a,
|
|
1297
|
+
static async analyseCost(e, t, a, o, n = {}) {
|
|
1298
1298
|
var b, p;
|
|
1299
|
-
const
|
|
1299
|
+
const i = v().valueOf(), s = [];
|
|
1300
1300
|
e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1301
|
-
const r = W.calculateRouteDistance(
|
|
1301
|
+
const r = W.calculateRouteDistance(o.route);
|
|
1302
1302
|
let h = 0;
|
|
1303
1303
|
a.forEach((f) => {
|
|
1304
1304
|
const u = Math.ceil(r / f.speed / 24);
|
|
@@ -1307,7 +1307,7 @@ class Y {
|
|
|
1307
1307
|
const l = v.utc(e.etd).add(h ?? 14, "day");
|
|
1308
1308
|
let d = 1;
|
|
1309
1309
|
for (const f of a) {
|
|
1310
|
-
const u = JSON.parse(JSON.stringify(
|
|
1310
|
+
const u = JSON.parse(JSON.stringify(o.route)), m = JSON.parse(JSON.stringify(o.waypoints)), c = await Y.analyseInstantWithThreshed(
|
|
1311
1311
|
{ lat: e.lat, lng: e.lng },
|
|
1312
1312
|
e.etd,
|
|
1313
1313
|
l,
|
|
@@ -1338,14 +1338,14 @@ class Y {
|
|
|
1338
1338
|
C = C > 7 ? 7 : C < e.alterStep ? e.alterStep : C;
|
|
1339
1339
|
let F = 2, P = { combined: !1, speeds: [w], cost: (p = w.cost) == null ? void 0 : p.total }, D;
|
|
1340
1340
|
for (; C >= e.alterStep; ) {
|
|
1341
|
-
const H = await Y.combinedAnalyse(e, t, l, [f, u],
|
|
1341
|
+
const H = await Y.combinedAnalyse(e, t, l, [f, u], o, C, { ...n, level: F });
|
|
1342
1342
|
if (P.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = P, P = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), C <= e.alterStep)
|
|
1343
1343
|
break;
|
|
1344
1344
|
C = Math.ceil(C / 2), F += 1;
|
|
1345
1345
|
}
|
|
1346
1346
|
g.push(P), D && g.push(D);
|
|
1347
1347
|
}
|
|
1348
|
-
const j = v().valueOf() -
|
|
1348
|
+
const j = v().valueOf() - i;
|
|
1349
1349
|
return S == null || S.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, j), g.sort((f, u) => f.cost - u.cost);
|
|
1350
1350
|
}
|
|
1351
1351
|
/**
|
|
@@ -1358,9 +1358,9 @@ class Y {
|
|
|
1358
1358
|
* @param step 步长,7,4,2,1
|
|
1359
1359
|
* @param options
|
|
1360
1360
|
*/
|
|
1361
|
-
static async combinedAnalyse(e, t, a,
|
|
1362
|
-
s.counter = 1, S == null || S.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level,
|
|
1363
|
-
const r = await Y.alternateAnalyse(e, t, a,
|
|
1361
|
+
static async combinedAnalyse(e, t, a, o, n, i, s = {}) {
|
|
1362
|
+
s.counter = 1, S == null || S.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, i);
|
|
1363
|
+
const r = await Y.alternateAnalyse(e, t, a, o, 0, n, i, s), h = r.reduce((u, m) => u + m.cost.total, 0), l = r.reduce((u, m) => u + m.cost.hire, 0), d = r.reduce((u, m) => u + m.cost.bunker, 0), y = r.reduce((u, m) => u + m.distance, 0), w = r.reduce((u, m) => u + m.totalHrs, 0);
|
|
1364
1364
|
S == null || S.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
|
|
1365
1365
|
cost: h,
|
|
1366
1366
|
hire: l,
|
|
@@ -1368,14 +1368,14 @@ class Y {
|
|
|
1368
1368
|
distance: y,
|
|
1369
1369
|
hours: w
|
|
1370
1370
|
});
|
|
1371
|
-
const g = await Y.alternateAnalyse(e, t, a,
|
|
1371
|
+
const g = await Y.alternateAnalyse(e, t, a, o, 1, n, i, s), k = g.reduce((u, m) => u + m.cost.total, 0), j = g.reduce((u, m) => u + m.cost.hire, 0), b = g.reduce((u, m) => u + m.cost.bunker, 0), p = g.reduce((u, m) => u + m.distance, 0), f = g.reduce((u, m) => u + m.totalHrs, 0);
|
|
1372
1372
|
return S == null || S.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
|
|
1373
1373
|
cost: k,
|
|
1374
1374
|
hire: j,
|
|
1375
1375
|
bunker: b,
|
|
1376
1376
|
distance: p,
|
|
1377
1377
|
hours: f
|
|
1378
|
-
}), h < k ? { combined: !0, cost: Math.round(h * 1e3) / 1e3, speeds: r, step:
|
|
1378
|
+
}), h < k ? { combined: !0, cost: Math.round(h * 1e3) / 1e3, speeds: r, step: i } : { combined: !0, cost: Math.round(k * 1e3) / 1e3, speeds: g, step: i };
|
|
1379
1379
|
}
|
|
1380
1380
|
/**
|
|
1381
1381
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1388,12 +1388,12 @@ class Y {
|
|
|
1388
1388
|
* @param step 步长,7,4,2,1
|
|
1389
1389
|
* @param options
|
|
1390
1390
|
*/
|
|
1391
|
-
static async alternateAnalyse(e, t, a,
|
|
1391
|
+
static async alternateAnalyse(e, t, a, o, n, i, s, r = {}) {
|
|
1392
1392
|
var y, w;
|
|
1393
1393
|
let h = v.utc(e.etd);
|
|
1394
1394
|
const l = { lat: e.lat, lng: e.lng }, d = [];
|
|
1395
1395
|
for (; h.isBefore(a); ) {
|
|
1396
|
-
const g = h.clone().utc().add(s, "day"), k = JSON.parse(JSON.stringify(
|
|
1396
|
+
const g = h.clone().utc().add(s, "day"), k = JSON.parse(JSON.stringify(i.route)), j = JSON.parse(JSON.stringify(i.waypoints)), b = o[n], p = await Y.analyseInstantWithThreshed(
|
|
1397
1397
|
l,
|
|
1398
1398
|
h.utc().format(),
|
|
1399
1399
|
g,
|
|
@@ -1438,10 +1438,10 @@ class Y {
|
|
|
1438
1438
|
* @param props
|
|
1439
1439
|
* @param options
|
|
1440
1440
|
*/
|
|
1441
|
-
static async calculateCost(e, t, a,
|
|
1441
|
+
static async calculateCost(e, t, a, o = {}) {
|
|
1442
1442
|
var n;
|
|
1443
1443
|
if (e) {
|
|
1444
|
-
const
|
|
1444
|
+
const i = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, s = Math.round((a.dailyHire || 0) * (e.suspend || 0) / 24 * 1e3) / 1e3, r = Math.round(e.totalHrs / 24 * (a.dailyHire || 0) * (1 - i) * 1e3) / 1e3 + s, h = Math.round(e.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, l = Math.round((e.totalDgoCons + (((n = e.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
|
|
1445
1445
|
e.cost = {
|
|
1446
1446
|
total: Math.round((r + h + l) * 1e3) / 1e3,
|
|
1447
1447
|
hire: Math.round(r * 1e3) / 1e3,
|
|
@@ -1458,21 +1458,21 @@ class Y {
|
|
|
1458
1458
|
*/
|
|
1459
1459
|
static async calculateECA(e, t, a = {}) {
|
|
1460
1460
|
var r, h, l, d;
|
|
1461
|
-
const
|
|
1462
|
-
let n = 0,
|
|
1461
|
+
const o = await W.intersectInECA((e == null ? void 0 : e.route) || []);
|
|
1462
|
+
let n = 0, i = 0, s = 0;
|
|
1463
1463
|
(h = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || h.forEach((y) => {
|
|
1464
1464
|
y.positionTime = v.utc(y.etd || y.eta).unix();
|
|
1465
1465
|
});
|
|
1466
|
-
for (const y of
|
|
1466
|
+
for (const y of o) {
|
|
1467
1467
|
n += y.distance;
|
|
1468
1468
|
const w = await W.deadReckoningTime((l = y.waypoints) == null ? void 0 : l.at(0), e.sample.all || e.sample.wps), g = await W.deadReckoningTime((d = y.waypoints) == null ? void 0 : d.at(-1), e.sample.all || e.sample.wps);
|
|
1469
|
-
y.in = w, y.out = g, y.totalHrs = z.roundPrecision((g.positionTime - w.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3),
|
|
1469
|
+
y.in = w, y.out = g, y.totalHrs = z.roundPrecision((g.positionTime - w.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3), i += y.totalHrs, s += y.totalDgoCons;
|
|
1470
1470
|
}
|
|
1471
|
-
return n = z.roundPrecision(n, 3),
|
|
1471
|
+
return n = z.roundPrecision(n, 3), i = z.roundPrecision(i, 3), s = z.roundPrecision(s, 3), {
|
|
1472
1472
|
distanceInECA: n,
|
|
1473
|
-
hoursInECA:
|
|
1473
|
+
hoursInECA: i,
|
|
1474
1474
|
totalDgoConsInECA: s,
|
|
1475
|
-
eca:
|
|
1475
|
+
eca: o
|
|
1476
1476
|
};
|
|
1477
1477
|
}
|
|
1478
1478
|
/**
|
|
@@ -1486,39 +1486,39 @@ class Y {
|
|
|
1486
1486
|
hours: [],
|
|
1487
1487
|
wps: [],
|
|
1488
1488
|
days: []
|
|
1489
|
-
},
|
|
1489
|
+
}, o = e.reduce((m, c) => m + c.distance, 0), n = e.reduce((m, c) => {
|
|
1490
1490
|
var I;
|
|
1491
1491
|
return m + (((I = c.extend) == null ? void 0 : I.distanceInECA) || 0);
|
|
1492
|
-
}, 0),
|
|
1492
|
+
}, 0), i = e.reduce((m, c) => m + c.totalHrs, 0), s = e.reduce((m, c) => {
|
|
1493
1493
|
var I;
|
|
1494
1494
|
return m + (((I = c.extend) == null ? void 0 : I.hoursInECA) || 0);
|
|
1495
1495
|
}, 0), r = e.reduce((m, c) => {
|
|
1496
1496
|
var I;
|
|
1497
1497
|
return m + (((I = c.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1498
|
-
}, 0), h = e.reduce((m, c) => m + c.wxFactor * c.totalHrs /
|
|
1498
|
+
}, 0), h = e.reduce((m, c) => m + c.wxFactor * c.totalHrs / i, 0), l = e.reduce((m, c) => m + c.cFactor * c.totalHrs / i, 0), d = e.reduce((m, c) => m + c.totalFoCons, 0), y = e.reduce((m, c) => m + c.totalDgoCons, 0), w = e.reduce((m, c) => m + c.cost.total, 0), g = e.reduce((m, c) => m + c.cost.hire, 0), k = e.reduce((m, c) => m + c.cost.bunker, 0), j = [], b = [];
|
|
1499
1499
|
let p;
|
|
1500
1500
|
for (const m of e) {
|
|
1501
1501
|
b.push(...((f = m.extend) == null ? void 0 : f.eca) || []);
|
|
1502
1502
|
const c = m.sample.hours, I = m.sample.wps, C = m.sample.days, F = c.at(0);
|
|
1503
|
-
p && (F.distanceFromPrevious = p.distanceFromPrevious, F.distanceFromStart = p.distanceFromStart, c.forEach((
|
|
1504
|
-
N && (
|
|
1505
|
-
}), I.at(0).distanceFromPrevious = p.distanceFromPrevious, I.at(0).distanceFromStart = p.distanceFromStart, I.forEach((
|
|
1506
|
-
N && (
|
|
1507
|
-
}), C.at(0).distanceFromPrevious = p.distanceFromPrevious, C.at(0).distanceFromStart = p.distanceFromStart, C.forEach((
|
|
1508
|
-
N && (
|
|
1503
|
+
p && (F.distanceFromPrevious = p.distanceFromPrevious, F.distanceFromStart = p.distanceFromStart, c.forEach((E, N) => {
|
|
1504
|
+
N && (E.distanceFromStart = E.distanceFromStart + p.distanceFromStart);
|
|
1505
|
+
}), I.at(0).distanceFromPrevious = p.distanceFromPrevious, I.at(0).distanceFromStart = p.distanceFromStart, I.forEach((E, N) => {
|
|
1506
|
+
N && (E.distanceFromStart = E.distanceFromStart + p.distanceFromStart);
|
|
1507
|
+
}), C.at(0).distanceFromPrevious = p.distanceFromPrevious, C.at(0).distanceFromStart = p.distanceFromStart, C.forEach((E, N) => {
|
|
1508
|
+
N && (E.distanceFromStart = E.distanceFromStart + p.distanceFromStart);
|
|
1509
1509
|
})), F.cp = m.cost.cp;
|
|
1510
|
-
const P = [m.etd, m.eta], D = j.findIndex((
|
|
1511
|
-
D === -1 ? (F.cp.segment = [P], j.push(F.cp)) : j[D].segment.push(P), c.forEach((
|
|
1510
|
+
const P = [m.etd, m.eta], D = j.findIndex((E) => E.id === F.cp.id);
|
|
1511
|
+
D === -1 ? (F.cp.segment = [P], j.push(F.cp)) : j[D].segment.push(P), c.forEach((E) => {
|
|
1512
1512
|
var O;
|
|
1513
|
-
((O = a.hours) == null ? void 0 : O.findIndex((R) => R.eta ===
|
|
1514
|
-
}), I.forEach((
|
|
1513
|
+
((O = a.hours) == null ? void 0 : O.findIndex((R) => R.eta === E.eta)) === -1 && a.hours.push(E);
|
|
1514
|
+
}), I.forEach((E) => {
|
|
1515
1515
|
var O;
|
|
1516
|
-
((O = a.wps) == null ? void 0 : O.findIndex((R) => R.eta ===
|
|
1517
|
-
}), C.forEach((
|
|
1516
|
+
((O = a.wps) == null ? void 0 : O.findIndex((R) => R.eta === E.eta)) === -1 && a.wps.push(E);
|
|
1517
|
+
}), C.forEach((E) => {
|
|
1518
1518
|
var O;
|
|
1519
|
-
((O = a == null ? void 0 : a.days) == null ? void 0 : O.findIndex((R) => R.eta ===
|
|
1519
|
+
((O = a == null ? void 0 : a.days) == null ? void 0 : O.findIndex((R) => R.eta === E.eta)) === -1 && a.days.push(E);
|
|
1520
1520
|
});
|
|
1521
|
-
const H = (u = a.wps) == null ? void 0 : u.findIndex((
|
|
1521
|
+
const H = (u = a.wps) == null ? void 0 : u.findIndex((E) => E.eta === F.eta);
|
|
1522
1522
|
H === -1 ? a.wps.push(F) : a.wps[H] = F, p = c.at(-1);
|
|
1523
1523
|
}
|
|
1524
1524
|
return a.wps.sort((m, c) => v(m.etd).unix() - v(c.etd).unix()), a.wps.forEach((m, c) => {
|
|
@@ -1537,9 +1537,9 @@ class Y {
|
|
|
1537
1537
|
to: e.at(-1).to,
|
|
1538
1538
|
v0: e.at(0).v0,
|
|
1539
1539
|
label: "Combined",
|
|
1540
|
-
distance: Math.round(
|
|
1541
|
-
totalHrs: Math.round(
|
|
1542
|
-
avgSpeed: Math.round(
|
|
1540
|
+
distance: Math.round(o * 1e3) / 1e3,
|
|
1541
|
+
totalHrs: Math.round(i * 1e3) / 1e3,
|
|
1542
|
+
avgSpeed: Math.round(o / i * 1e3) / 1e3,
|
|
1543
1543
|
wxFactor: Math.round(h * 1e3) / 1e3,
|
|
1544
1544
|
cFactor: Math.round(l * 1e3) / 1e3,
|
|
1545
1545
|
totalFoCons: Math.round(d * 1e3) / 1e3,
|
|
@@ -1567,7 +1567,7 @@ export {
|
|
|
1567
1567
|
Ft as HifleetImpl,
|
|
1568
1568
|
pt as LoadCondition,
|
|
1569
1569
|
xt as MyShipImpl,
|
|
1570
|
-
|
|
1570
|
+
Et as MyVesselImpl,
|
|
1571
1571
|
Nt as ShipxyImpl,
|
|
1572
1572
|
Y as SpeedHelper,
|
|
1573
1573
|
vt as SpeedLabel,
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(A,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(A=typeof globalThis<"u"?globalThis:A||self,x(A["idm-plugin-vessel"]={},A.got,A["@log4js-node/log4js-api"],A.moment,A["@idm-plugin/geo2"],A["@idm-plugin/meteo2"],A["@idm-plugin/meteo"]))})(this,function(A,x,U,v,L,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(A,x,U)=>x in A?Ct(A,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):A[x]=U;var _=(A,x,U)=>(St(A,typeof x!="symbol"?x+"":x,U),U);let p;try{p=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,i).json();p==null||p.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const i="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};p==null||p.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,i,n);const o=await x.post(i,n).json();return o.status!==200?(p==null||p.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),[]):(o.data||[]).map(h=>({mmsi:h.mmsi,name:h.nameEn,nameCn:h.nameCn,imo:Number.isNaN(h.imo)?null:Number(h.imo),callSign:h.callsign,type:h.vesselTypeNameEn,flagName:h.flagCtry,vendor:"myvessel",raw:h}))}async search(t,a={}){var l,h;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},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:o};p==null||p.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return p==null||p.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const d=r.data;if(d)return{mmsi:d.mmsi,imo:Number.isNaN(d.imo)?null:Number(d.imo),callSign:d.callsign,name:d.nameEn,nameCn:d.nameCn,type:d.vesselTypeNameEn,flagName:d.flagCtry,clasz:d.classSociety,dateOfBuild:d.buildYearMonth,deadweight:d.dwt,grossTonnage:d.grt,netTonnage:d.net,teu:d.teu,length:d.length,breadth:d.width,height:d.height,draught:d.draught,speed:d.speed,passengerCapacity:d.passengercapacity,vendor:"myvessel",raw:d}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};p==null||p.info("[%s] fetch vessel archive from: %s - %j",a.requestId,i,n);const o=await x.post(i,n).json();return o.status!==200?(p==null||p.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,l;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} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await x.get(i,n).json();if(o.code)return p==null||p.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:o.message,status:o.status,code:o.code}),o;const s=o.data;for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));if(s){const h=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.dest,positionTime:h.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:h.utc().format()}}else return{}}async calculateRoute(t,a,i,n,o,s={}){var y,w,M;const r=v();await this.checkToken(s);const l="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",h={headers:{Authorization:`${(y=this.token)==null?void 0:y.tokenType} ${(w=this.token)==null?void 0:w.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:s.draught||10,useAIModel:s.useAIModel||!1,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1}};i!=null&&i.length&&(h.json.crossMonthList=i),n!=null&&n.length&&(h.json.excludeNodes=n),o!=null&&o.length&&(h.json.excludeSeaAreas=o),p==null||p.info("[%s] fetch route from: %s - %j",s.requestId,l,h);const d=await x.post(l,h).json();if(d.status!==200)return p==null||p.warn("[%s] fetch route failed: %j",s.requestId,{message:d.message,status:d.status,code:d.code}),{};{const I={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:j,seas:b,tracks:g,specialRegions:m}=d.data;I.nodes=j==null?void 0:j.map(c=>({code:c.nodeCode,nameEn:c.nameEn,nameCn:c.nameCn,center:{lat:Math.round(c.lat*1e6)/1e6,lng:Math.round(c.lon*1e6)/1e6},start:{lat:Math.round(c.startLat*1e6)/1e6,lng:Math.round(c.startLon*1e6)/1e6},end:{lat:Math.round(c.endLat*1e6)/1e6,lng:Math.round(c.endLat*1e6)/1e6},isKey:c.isKeyNode,isHub:c.isHubNode})),I.seas=b==null?void 0:b.map(c=>({code:c.mrgidSea,nameEn:c.nameEn,nameCn:c.nameCn,center:{lat:Math.round(c.centerLat*1e6)/1e6,lng:Math.round(c.centerLon*1e6)/1e6},min:{lat:Math.round(c.minLat*1e6)/1e6,lng:Math.round(c.minLon*1e6)/1e6},max:{lat:Math.round(c.maxLat*1e6)/1e6,lng:Math.round(c.maxLon*1e6)/1e6},level:c.mapLevel})),m==null||m.map(c=>{c.regionLength&&I.regions.push({type:c.regionType,distance:c.regionLength,rows:c.regions.map(k=>({code:k.regionCode,nameCn:k.nameCn,nameEn:k.nameEn,type:k.regionType,distance:k.length}))})}),I.waypoints=g==null?void 0:g.map(c=>({lat:Math.round(c.lat*1e5)/1e5,lng:Math.round(c.lon*1e5)/1e5})),(M=I.waypoints)!=null&&M.length&&(I.waypoints=L.LaneHelper.simplifyCoordinates(I.waypoints),I.route=L.LaneHelper.divideAccordingToLng(I.waypoints),I.distance=L.LaneHelper.calculateRouteDistance(I.route));const f=v().diff(r,"second");return I.memo=`time cost: ${f}s`,p.info("[%s] calculate route cost: %d seconds",s.requestId,f),I}}async trajectory(t,a,i,n,o=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=v(a),h=v(i),d=[];for(;h.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,d,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,h,r,n,d,s),d}async trajectoryIn30Day(t,a,i,n,o,s,r={}){var M,I,j,b,g;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",h={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(I=this.token)==null?void 0:I.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")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,h);const d=await x.post(l,h).json();if(d.code)return p==null||p.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const w=v(`${(b=(j=d.data)==null?void 0:j[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(g=d.data)==null||g.forEach(m=>{for(const P in m)!isNaN(m[P])&&Number(m[P])!==1/0&&(m[P]=Number(m[P]));const u=v(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),f=m.status,{labelCn:c,labelEn:k}=this.parseStatus(f),C={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:f,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:c,labelEn:k,method:"trajectory",vendor:"myVessel",utc:u.utc().format()},F=Math.floor(u.diff(w,"minute",!0)/(o||1));F!==y&&(y=F,s.push(C))}),s}}class Mt extends G{constructor(t){super();_(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 x.post(i,n).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const s=o==null?void 0:o.list;if(!s)return p==null||p.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const w in s)!isNaN(s[w])&&Number(s[w])!==1/0&&(s[w]=Number(s[w]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:h}=this.parseStatus(r),d=v(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:l,labelEn:h,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 x.post(i,n).json();p==null||p.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 s={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await x.post(i,n).json(),p==null||p.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(s.deadweight=Number(o.dwt)),s}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 x.post(i,n).json();p==null||p.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const s=[];for(const r of o)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,i,n,o=!0,s={}){var m,u,f;const r=await this.realTimePosition(t,s);let l=v(a);const h=v(i),d=v();if(o){let c=h.diff(l,"d",!0);c<0?l=h.clone().subtract(40,"d"):c<30?l.subtract(10,"d"):c<60?l.subtract(5,"d"):l=h.clone().subtract(80,"d"),c=d.diff(h,"d",!0),h.add(c>10?240:c*24,"h")}const y={searchParams:{endtime:h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},w="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await x.get(w,y).json();p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,w,y);let I;M&&(I=((u=(m=M.ships)==null?void 0:m.offors)==null?void 0:u.ship)||[],I.length||p==null||p.warn("[%s] fetch trajectory failed: %j",s.requestId,M));const j=[];let b=-1;const g=v(`${(f=I==null?void 0:I[0])==null?void 0:f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const c of I){for(const R in c)!isNaN(c[R])&&Number(c[R])!==1/0&&(c[R]=Number(c[R]));const k=v(`${c.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");c.status=c.sp>4?0:1;const{labelEn:C,labelCn:F}=this.parseStatus(c.status),P={mmsi:c.m,name:c.n,imo:r==null?void 0:r.imo,lat:c.la,lng:c.lo,draught:c.draught,sog:c.sp,cog:c.co,hdg:c.hdg,positionTime:k.unix(),utc:k.utc().format(),status:c.status,labelCn:F,labelEn:C,method:"trajectory",vendor:"hifleet"},N=Math.floor(k.diff(g,"minute",!0)/(n||1));N!==b&&(b=N,j.push(P))}return j}}class bt extends G{constructor(t){super();_(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 x.get(n,i).json();if(p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const s=o.data[0];for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),h=v.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:h.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,i,n,o=!0,s={}){var g;const r=await this.realTimePosition(t,s),l=v(a),h=v(i),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:h.unix()}},w=await x.get(d,y).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,d,y),(w==null?void 0:w.status)!==0)return w;const M=w==null?void 0:w.points,I=[],j=v.unix((g=M[0])==null?void 0:g.utc);let b=-1;for(const m of M){const u=v.unix(m.utc),f={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"},c=Math.floor(u.diff(j,"minute",!0)/(n||1));c!==b&&(b=c,I.push(f))}return I}}class gt extends G{constructor(t){super();_(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 x.post(n,i).json();return p==null||p.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 x.post(n,i).json();if(p==null||p.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const s=o.data;let r=s.imo;return t==="407170"&&(r="9198379",p==null||p.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const i=await this.getShipId(t,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,o).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,o);const l=r.data[0];for(const M in l)!isNaN(l[M])&&Number(l[M])!==1/0&&(l[M]=Number(l[M]));const{labelCn:h,labelEn:d}=await this.parseStatus(l.aisNavStatus),y=v.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:y.utc().format(),status:l.aisNavStatus,labelEn:d,labelCn:h,method:"position",vendor:"myship"}}async trajectory(t,a,i,n,o=!0,s={}){const r=v(a),l=v(i),h=await this.getShipId(t),d=await this.getShipInfo(h),y=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(h,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(h,r.unix(),l.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,i,n,o,s,r,l={}){var j;const h={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:i}},d="https://api3.myships.com/sp/ships/position/history",y=await x.post(d,h).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,h),y.code!=="0")return p==null||p.warn("[%s] invoke myship trajectory failed: %j",l.requestId,y),y;const w=y.data;for(const b in w)!isNaN(w[b])&&Number(w[b])!==1/0&&(w[b]=Number(w[b]));const M=v.unix((j=w[0])==null?void 0:j.posTime);let I=-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)/(s||1));u!==I&&(I=u,r.push(m))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let h=0;h<(n==null?void 0:n.length);h++){const d=(l=(r=n[h].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(h===0&&!d)o.scope=n[0];else if(d)for(let y=0,w=d.length;y<w;y++){const M=this.parseRule(d[y]);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(e,t={}){var o;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=e==null?void 0:e.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var M,I,j,b,g,m,u,f,c,k,C,F,P,N,R;let i=0,n=0,o=0,s=0;const r=Math.round(((I=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:I.number)*1.6*100)/100,l=(b=(j=t==null?void 0:t.SEVERE)==null?void 0:j.sigWave)==null?void 0:b.number,h=(m=(g=t==null?void 0:t.HEAVY)==null?void 0:g.sigWave)==null?void 0:m.number,d=Math.round((((f=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:f.number)+2)*100)/100,y=(k=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:k.number,w=(F=(C=t==null?void 0:t.HEAVY)==null?void 0:C.wind)==null?void 0:F.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?v(H.eta).diff(v(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:h}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=h&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:w}),(B==null?void 0:B.scale)>=d?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>y?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===w&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),i+=H.isDangerous?K:0,n+=H.isSevere?K:0,o+=H.isHeavy?K:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:n,heavy:o,step:s<3?3:s,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:w},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:h}}}}const vt=new lt;let S;try{S=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(ht||{}),ft=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ft||{}),mt=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(mt||{});class O{static blockCoefficient(e,t,a,i){let n=Math.round(e/(t*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],s=o.map(r=>Math.abs(r-n));return o[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let i=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,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]}[e];return a==="Laden"&&(o=i[e]),o[0]+o[1]*t+o[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,i){let n;return a==="container"?n=.7*i/2+Math.pow(i,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*i/2+Math.pow(i,3)/(2.7*Math.pow(e,2/3)):n=.5*i/2+Math.pow(i,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,i){var y;const n=e.lbp??e.length??e.lengthOverall??198.9642,o=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((y=e==null?void 0:e.type)==null?void 0:y.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:o,breadthMoulded:s,displacement:Math.round((r/1.025+o*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,a,i="",n=2,o=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=L.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),o){let h;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:I}=await ot.Meteo2Assist.autoPickMeteoModel(i),j=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:I}),[b]=ot.Meteo2Assist.pickHourly(j,a);h=ot.Meteo2Assist.toLegacy(b)}catch(M){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:i},M)}const d=O.currentFactor(e.bearing,h==null?void 0:h.current,n),y=O.weatherFactor(e,h,d),w=Math.round((e.speed*1.943844+y+d)*100)/100;l={meteo:{...h},wxFactor:y,cFactor:d,speed:t.velocity&&s?t.velocity:w<0?1:w,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,i,n,o,s="",r=!0,l=!1,h={}){t.utc();const d=t.clone().add(14,"days"),y=[],w=[],M=[];let I=0,j=0,b,g;for(let m=0;m<o.length-1;m++){let u=o[m];u.distanceFromStart=Math.round((n+j)*1e3)/1e3;const f=o[m+1];if(e.bearing=L.LaneHelper.calculateBearing(u,f,!f.gcToPrevious),u.bearing=e.bearing,u.suspend&&l){u.eta=u.eta||t.utc().format(),u.elapsed=u.elapsed??0;const C=u.suspend-u.elapsed;if(i-I>C)i=i-I-C,t.add(C,"hour"),u.elapsed=u.suspend;else{const F=i-I;u.elapsed+=F,t.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${i} hours need to go...`,h.requestId,u),i===0)return u.distanceFromPrevious=j,{etd:t,from:g||u,to:u,next:o.filter(F=>F),wps:y,days:w,all:M}}else u.suspend=0;r=t.isAfter(d)?!1:r,u=await O.speedLoseAt(e,u,t,s,0,r,l,h),M.push(u),g=g||u,u.important&&y.push(u),t.isSameOrAfter(a)&&(w.push(u),a.add(24,"hour"));const c=L.LaneHelper.calculateDistance(u,f,!f.gcToPrevious);let k=Math.round(c/g.speed*1e5)/1e5;if(I+k<i){if(I+=k,t.add(k,"hour"),delete o[m],S==null||S.debug(`[%s] go to %j from %j with ${c}nm, and cost ${k} hours`,h.requestId,{lat:f.lat,lng:f.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),j+=c,o.filter(C=>C).length<=1){b=f,b.eta=t.utc().format(),b.distanceFromPrevious=c,b.distanceFromStart=Math.round((n+j)*1e4)/1e4,y.push(b),M.push(b),delete o[m+1];break}}else{k=i-I,t.add(k,"hour");const C=L.LngLatHelper.roundPrecision(g.speed*k,5);b=L.LaneHelper.calculateCoordinate(u,e.bearing,C,"nauticalmiles",!f.gcToPrevious),b.eta=t.utc().format(),o[m]=b,S==null||S.debug(`[%s] go to %j from %j with ${C}nm, and cost ${k} hours`,h.requestId,{lat:b.lat,lng:b.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),j+=C,b.distanceFromPrevious=Math.round(j*1e4)/1e4,b.distanceFromStart=Math.round((n+j)*1e4)/1e4;break}}return{etd:t,from:g,to:b,next:o.filter(m=>m),wps:y,days:w,all:M}}static currentFactor(e,t,a=0){const i=(e-(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(e,t,a=0){var w,M,I,j,b,g,m;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const i=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=L.LngLatHelper.roundPrecision(a*1852/3600,6),o=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(i,o,e.loadCondition);let r=Math.abs(e.bearing%360-(((w=t==null?void 0:t.wind)==null?void 0:w.degree)%360||0));r=r>180?360-r:r;const l=O.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),h=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(I=t==null?void 0:t.wind)==null?void 0:I.kts);let d=l*s*h/100*(e.speed-n);d=Math.round(d*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(d)>1&&(d=d/(Math.abs(Math.round(d))+1)),S==null||S.debug("wind wx factor = %d",d),r=Math.abs(e.bearing%360-(((b=(j=t==null?void 0:t.wave)==null?void 0:j.sig)==null?void 0:b.degree)%360||0)),r=r>180?360-r:r;const y=O.waveHeightFactor(((m=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:m.height)??1,r);return S==null||S.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.7,S==null||S.debug("weather factor = %d",d),d=Math.abs(d)>3?3*(Math.abs(d)/d)+Math.abs(d)/d*(Math.abs(d)-2)*.1:d,Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,i)=>(a.some(n=>Math.floor(n.positionTime/t)===Math.floor(i.positionTime/t))||a.push(i),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,i)=>(a.some(n=>Math.floor(v(n.etd).unix()/t)===Math.floor(v(i.etd).unix()/t))||a.push(i),a),[]),e}static async analyseInstant(e,t,a,i,n,o="",s=0,r=!0,l=!1,h={}){var X,Q,Z,$,tt,et;const d=v().valueOf();e.lng=L.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:w}=n.points,M=L.LaneHelper.calculateSubRoute(e,y);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:I,label:j}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:i.speed,label:"CP"},b=O.assembleProperties(a,i.loadCondition,I,0),g=w.length?L.LaneHelper.calculateSubWaypoints(e,w):[];g.forEach(q=>q.important=!0);const m={from:{...e},route:M,waypoints:g,v0:I,label:j},u={hours:[],days:[],wps:[],all:[]};s||(L.LaneHelper.calculateRouteDistance(M)/i.speed<=72?s=3:s=6);let f=L.LaneHelper.simplifyRouteToCoordinates(M,g,0),c=0,k=0,C=0,F=0;t=v(t).utc();const P=t.clone();for(;f.length>0;){const q=s-t.hour()%s,z=Math.ceil(t.clone().add(q,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,T=await O.speedLoseInHoursStep(b,t,P,z,c,f,o,r,l,h);if(u.all.push(...T.all),(Q=T.from)!=null&&Q.speed&&(u.hours.push(T.from),u.wps.push(...T.wps),u.days.push(...T.days)),f=T==null?void 0:T.next,!f.length){const W=await O.speedLoseAt(b,T.to,v(T.to.eta),o,0,r,l,h);W.bearing=b.bearing,u.hours.push(W),u.all.push(W)}c+=Math.round((((Z=T==null?void 0:T.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=u.hours;for(let q=0;q<N.length-1;q++){const z=v(N[q+1].eta).diff(N[q].etd,"hour",!0)||1;k+=(N[q].wxFactor||0)*z,C+=(N[q].cFactor||0)*z,F+=z}const R=N.reduce((q,z)=>q+(z.suspend||0),0);($=u.wps)==null||$.forEach((q,z)=>{q.positionTime=v.utc(q.etd||q.eta).unix();const T=u.wps[z-1];if(T){const W=q.distanceFromStart-T.distanceFromStart,Y=v(q.eta||q.etd).diff(v(T.etd||T.eta),"h",!0);q.avgSpd=Math.round(W/Y*100)/100,T.bearing=L.LaneHelper.calculateBearing(T,q)}}),u.wps=await O.reduceWPS(u.wps),u.days=await O.reduceDays(u.days),u.all=(tt=u.all)==null?void 0:tt.reduce((q,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),q.some(T=>Math.round(T.positionTime/60)===Math.round(z.positionTime/60))||q.push(z),q),[]),m.sample=u;const E=u.hours.at(0),H=u.hours.at(-1);m.distance=Math.round(H.distanceFromStart*1e3)/1e3,m.etd=v(E.eta).utc().format(),m.eta=v(H.eta).utc().format(),m.wxFactor=Math.round(k/F*1e3)/1e3,m.cFactor=Math.round(C/F*1e3)/1e3,m.avgSpeed=Math.round(H.distanceFromStart/F*1e3)/1e3,m.totalHrs=Math.round(F*1e3)/1e3,m.suspend=Math.round(R*1e3)/1e3;const V=L.LngLatHelper.roundPrecision(i.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(m,i,h),at=L.LngLatHelper.roundPrecision(i.fo/24*(F-K),3),rt=L.LngLatHelper.roundPrecision(i.dgo/24*F+V,3);m.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},m.totalFoCons=at<0?0:at,m.totalDgoCons=rt;const nt=v().valueOf()-d,dt=((et=u==null?void 0:u.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),m}static async analyseInstantWithThreshed(e,t,a,i,n,o,s,r="",l=3,h=!0,d=!1,y={}){var Z,$,tt,et,q,z;const w=v().valueOf();e.lng=L.LngLatHelper.convertToStdLng(e.lng);const{v0:M,label:I}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},j=O.assembleProperties(i,n.loadCondition,M,0),b=L.LaneHelper.calculateSubRoute(e,o);if(((Z=b[0])==null?void 0:Z.length)<=1)return;const g=s.length?L.LaneHelper.calculateSubWaypoints(e,s):[];g.forEach(T=>T.important=!0);let m=L.LaneHelper.simplifyRouteToCoordinates(b,g,0),u=0,f=0,c=0,k=0;const C={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const F=t.clone();for(;m.length>0;){const T=l-t.hour()%l;let W=Math.ceil(t.clone().add(T,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(j,t,F,W,u,m,r,h,d,y);if(C.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(C.hours.push(Y.from),Y!=null&&Y.wps&&C.wps.push(...Y.wps),C.days.push(...Y.days)),m=Y==null?void 0:Y.next,m.length||C.hours.push(Y==null?void 0:Y.to),u+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}C.wps=await O.reduceWPS(C.wps),C.days=await O.reduceDays(C.days),C.all=(et=C.all)==null?void 0:et.reduce((T,W)=>(W.positionTime=v.utc(W.etd||W.eta).unix(),T.some(Y=>Math.round(v(Y.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||T.push(W),T),[]),(q=C.wps)==null||q.forEach((T,W)=>{const Y=C.wps[W-1];if(Y){const It=T.distanceFromStart-Y.distanceFromStart,kt=v(T.eta||T.etd).diff(v(Y.etd||Y.eta),"h",!0);Y.bearing=L.LaneHelper.calculateBearing(Y,T),T.avgSpd=Math.round(It/kt*100)/100}});const P=C.hours;for(let T=0;T<P.length-1;T++){const W=v(P[T+1].eta).diff(P[T].etd,"hour",!0);f+=P[T].wxFactor*W,c+=P[T].cFactor*W,k+=W}const N=P.reduce((T,W)=>T+(W.suspend||0),0),R=C.hours.at(0),E=C.hours.at(-1),H=await L.LaneHelper.calculateRangeRoute(R,E,b),V=await L.LaneHelper.calculateRangeWaypoints(R,E,b,g),B={sample:C,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(f/k*1e3)/1e3,cFactor:Math.round(c/k*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/k*1e3)/1e3,totalHrs:Math.round(k*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:M,label:I},K=L.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=L.LngLatHelper.roundPrecision(n.fo/24*(k-st),3),nt=L.LngLatHelper.roundPrecision(n.dgo/24*k+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=v().valueOf()-w,Q=((z=C==null?void 0:C.hours)==null?void 0:z.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",y==null?void 0:y.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,i,n={}){var b,g;const o=v().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=L.LaneHelper.calculateRouteDistance(i.route);let l=0;a.forEach(m=>{const u=Math.ceil(r/m.speed/24);l=l<u?u:l}),l=l*1.3;const h=v.utc(e.etd).add(l??14,"day");let d=1;for(const m of a){const u=JSON.parse(JSON.stringify(i.route)),f=JSON.parse(JSON.stringify(i.waypoints)),c=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,h,t,m,u,f,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);c&&(await O.calculateCost(c,m,e,n),s.push(c),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,h.format(),{cost:c.cost.total,hire:c.cost.hire,bunker:c.cost.bunker,distance:c.distance,hours:c.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),d++}s.sort((m,u)=>m.cost.total-u.cost.total);const y=s.at(0),w=s.at(1),M=[];if(M.push({combined:!1,speeds:[y],cost:(b=y.cost)==null?void 0:b.total}),w){const m=y.cost.cp,u=w.cost.cp,f=v(y.eta),c=v(y.etd),k=f.diff(c,"days",!0);let C=Math.ceil(k/2);C=C>7?7:C<e.alterStep?e.alterStep:C;let F=2,P={combined:!1,speeds:[w],cost:(g=w.cost)==null?void 0:g.total},N;for(;C>=e.alterStep;){const R=await O.combinedAnalyse(e,t,h,[m,u],i,C,{...n,level:F});if(P.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=P,P=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),C<=e.alterStep)break;C=Math.ceil(C/2),F+=1}M.push(P),N&&M.push(N)}const j=v().valueOf()-o;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,j),M.sort((m,u)=>m.cost-u.cost)}static async combinedAnalyse(e,t,a,i,n,o,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,o);const r=await O.alternateAnalyse(e,t,a,i,0,n,o,s),l=r.reduce((u,f)=>u+f.cost.total,0),h=r.reduce((u,f)=>u+f.cost.hire,0),d=r.reduce((u,f)=>u+f.cost.bunker,0),y=r.reduce((u,f)=>u+f.distance,0),w=r.reduce((u,f)=>u+f.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:h,bunker:d,distance:y,hours:w});const M=await O.alternateAnalyse(e,t,a,i,1,n,o,s),I=M.reduce((u,f)=>u+f.cost.total,0),j=M.reduce((u,f)=>u+f.cost.hire,0),b=M.reduce((u,f)=>u+f.cost.bunker,0),g=M.reduce((u,f)=>u+f.distance,0),m=M.reduce((u,f)=>u+f.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:I,hire:j,bunker:b,distance:g,hours:m}),l<I?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:o}:{combined:!0,cost:Math.round(I*1e3)/1e3,speeds:M,step:o}}static async alternateAnalyse(e,t,a,i,n,o,s,r={}){var y,w;let l=v.utc(e.etd);const h={lat:e.lat,lng:e.lng},d=[];for(;l.isBefore(a);){const M=l.clone().utc().add(s,"day"),I=JSON.parse(JSON.stringify(o.route)),j=JSON.parse(JSON.stringify(o.waypoints)),b=i[n],g=await O.analyseInstantWithThreshed(h,l.utc().format(),M,t,b,I,j,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);g&&(await O.calculateCost(g,b,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),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=(y=g==null?void 0:g.sample)==null?void 0:y.hours)==null?void 0:w.at(-1);if(m)h.lat=m.lat,h.lng=m.lng,l=v(m.eta),d.push(g),n=n?0:1;else break}return d}static async calculateCost(e,t,a,i={}){var n;if(e){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,h=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+h)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+h)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,h,d;const i=await L.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,o=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(y=>{y.positionTime=v.utc(y.etd||y.eta).unix()});for(const y of i){n+=y.distance;const w=await L.LaneHelper.deadReckoningTime((h=y.waypoints)==null?void 0:h.at(0),e.sample.all||e.sample.wps),M=await L.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),e.sample.all||e.sample.wps);y.in=w,y.out=M,y.totalHrs=L.LngLatHelper.roundPrecision((M.positionTime-w.positionTime)/3600,3),y.totalDgoCons=L.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),o+=y.totalHrs,s+=y.totalDgoCons}return n=L.LngLatHelper.roundPrecision(n,3),o=L.LngLatHelper.roundPrecision(o,3),s=L.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(e,t={}){var m,u;const a={hours:[],wps:[],days:[]},i=e.reduce((f,c)=>f+c.distance,0),n=e.reduce((f,c)=>{var k;return f+(((k=c.extend)==null?void 0:k.distanceInECA)||0)},0),o=e.reduce((f,c)=>f+c.totalHrs,0),s=e.reduce((f,c)=>{var k;return f+(((k=c.extend)==null?void 0:k.hoursInECA)||0)},0),r=e.reduce((f,c)=>{var k;return f+(((k=c.extend)==null?void 0:k.totalDgoConsInECA)||0)},0),l=e.reduce((f,c)=>f+c.wxFactor*c.totalHrs/o,0),h=e.reduce((f,c)=>f+c.cFactor*c.totalHrs/o,0),d=e.reduce((f,c)=>f+c.totalFoCons,0),y=e.reduce((f,c)=>f+c.totalDgoCons,0),w=e.reduce((f,c)=>f+c.cost.total,0),M=e.reduce((f,c)=>f+c.cost.hire,0),I=e.reduce((f,c)=>f+c.cost.bunker,0),j=[],b=[];let g;for(const f of e){b.push(...((m=f.extend)==null?void 0:m.eca)||[]);const c=f.sample.hours,k=f.sample.wps,C=f.sample.days,F=c.at(0);g&&(F.distanceFromPrevious=g.distanceFromPrevious,F.distanceFromStart=g.distanceFromStart,c.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+g.distanceFromStart)}),k.at(0).distanceFromPrevious=g.distanceFromPrevious,k.at(0).distanceFromStart=g.distanceFromStart,k.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+g.distanceFromStart)}),C.at(0).distanceFromPrevious=g.distanceFromPrevious,C.at(0).distanceFromStart=g.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+g.distanceFromStart)})),F.cp=f.cost.cp;const P=[f.etd,f.eta],N=j.findIndex(E=>E.id===F.cp.id);N===-1?(F.cp.segment=[P],j.push(F.cp)):j[N].segment.push(P),c.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),k.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),C.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(u=a.wps)==null?void 0:u.findIndex(E=>E.eta===F.eta);R===-1?a.wps.push(F):a.wps[R]=F,g=c.at(-1)}return a.wps.sort((f,c)=>v(f.etd).unix()-v(c.etd).unix()),a.wps.forEach((f,c)=>{const k=a.wps[c-1];if(k){const C=f.distanceFromStart-(k.distanceFromStart||0),F=v(f.eta||f.etd).diff(v(k.etd||k.eta),"hour",!0),P=Math.round(C/F*100)/100;f.avgSpd=P;const N=L.LaneHelper.calculateBearing(k,f);k.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(h*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(w*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(I*1e3)/1e3},extend:{cps:j,eca:b,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}A.AISImpl=G,A.AlertHelper=lt,A.AlertLevel=ut,A.HifleetImpl=Mt,A.LoadCondition=ft,A.MyShipImpl=gt,A.MyVesselImpl=pt,A.ShipxyImpl=bt,A.SpeedHelper=O,A.SpeedLabel=mt,A.VesselTag=ht,A.alertHelper=vt,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(A,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(A=typeof globalThis<"u"?globalThis:A||self,x(A["idm-plugin-vessel"]={},A.got,A["@log4js-node/log4js-api"],A.moment,A["@idm-plugin/geo2"],A["@idm-plugin/meteo2"],A["@idm-plugin/meteo"]))})(this,function(A,x,U,g,L,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(A,x,U)=>x in A?Ct(A,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):A[x]=U;var _=(A,x,U)=>(St(A,typeof x!="symbol"?x+"":x,U),U);let p;try{p=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();p==null||p.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:g().utc().format()})}async checkToken(t={}){var a;return(!this.token||g().diff(g(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};p==null||p.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(p==null||p.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(h=>({mmsi:h.mmsi,name:h.nameEn,nameCn:h.nameCn,imo:Number.isNaN(h.imo)?null:Number(h.imo),callSign:h.callsign,type:h.vesselTypeNameEn,flagName:h.flagCtry,vendor:"myvessel",raw:h}))}async search(t,a={}){var l,h;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:i};p==null||p.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return p==null||p.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const d=r.data;if(d)return{mmsi:d.mmsi,imo:Number.isNaN(d.imo)?null:Number(d.imo),callSign:d.callsign,name:d.nameEn,nameCn:d.nameCn,type:d.vesselTypeNameEn,flagName:d.flagCtry,clasz:d.classSociety,dateOfBuild:d.buildYearMonth,deadweight:d.dwt,grossTonnage:d.grt,netTonnage:d.net,teu:d.teu,length:d.length,breadth:d.width,height:d.height,draught:d.draught,speed:d.speed,passengerCapacity:d.passengercapacity,vendor:"myvessel",raw:d}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};p==null||p.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(p==null||p.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return p==null||p.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));if(s){const h=g(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?g.utc(s.eta).format():void 0,destination:s.dest,positionTime:h.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:h.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var y,w,M;const r=g();await this.checkToken(s);const l="https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",h={headers:{Authorization:`${(y=this.token)==null?void 0:y.tokenType} ${(w=this.token)==null?void 0:w.accessToken}`},json:{startPoint:{lon:t.lng,lat:t.lat},endPoint:{lon:a.lng,lat:a.lat},maxDraught:s.draught||10,useAIModel:s.useAIModel||!1,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1}};o!=null&&o.length&&(h.json.crossMonthList=o),n!=null&&n.length&&(h.json.excludeNodes=n),i!=null&&i.length&&(h.json.excludeSeaAreas=i),p==null||p.info("[%s] fetch route from: %s - %j",s.requestId,l,h);const d=await x.post(l,h).json();if(d.status!==200)return p==null||p.warn("[%s] fetch route failed: %j",s.requestId,{message:d.message,status:d.status,code:d.code}),{};{const I={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:j,seas:b,tracks:v,specialRegions:m}=d.data;I.nodes=j==null?void 0:j.map(c=>({code:c.nodeCode,nameEn:c.nameEn,nameCn:c.nameCn,center:{lat:Math.round(c.lat*1e6)/1e6,lng:Math.round(c.lon*1e6)/1e6},start:{lat:Math.round(c.startLat*1e6)/1e6,lng:Math.round(c.startLon*1e6)/1e6},end:{lat:Math.round(c.endLat*1e6)/1e6,lng:Math.round(c.endLat*1e6)/1e6},isKey:c.isKeyNode,isHub:c.isHubNode})),I.seas=b==null?void 0:b.map(c=>({code:c.mrgidSea,nameEn:c.nameEn,nameCn:c.nameCn,center:{lat:Math.round(c.centerLat*1e6)/1e6,lng:Math.round(c.centerLon*1e6)/1e6},min:{lat:Math.round(c.minLat*1e6)/1e6,lng:Math.round(c.minLon*1e6)/1e6},max:{lat:Math.round(c.maxLat*1e6)/1e6,lng:Math.round(c.maxLon*1e6)/1e6},level:c.mapLevel})),m==null||m.map(c=>{c.regionLength&&I.regions.push({type:c.regionType,distance:c.regionLength,rows:c.regions.map(k=>({code:k.regionCode,nameCn:k.nameCn,nameEn:k.nameEn,type:k.regionType,distance:k.length}))})}),I.waypoints=v==null?void 0:v.map(c=>({lat:Math.round(c.lat*1e5)/1e5,lng:Math.round(c.lon*1e5)/1e5})),(M=I.waypoints)!=null&&M.length&&(I.waypoints=L.LaneHelper.simplifyCoordinates(I.waypoints),I.route=L.LaneHelper.divideAccordingToLng(I.waypoints),I.distance=L.LaneHelper.calculateRouteDistance(I.route));const f=g().diff(r,"second");return I.memo=`time cost: ${f}s`,p.info("[%s] calculate route cost: %d seconds",s.requestId,f),I}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=g(a),h=g(o),d=[];for(;h.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,d,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,h,r,n,d,s),d}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var M,I,j,b,v;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",h={headers:{Authorization:`${(M=this.token)==null?void 0:M.tokenType} ${(I=this.token)==null?void 0:I.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,h);const d=await x.post(l,h).json();if(d.code)return p==null||p.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const w=g(`${(b=(j=d.data)==null?void 0:j[0])==null?void 0:b.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=d.data)==null||v.forEach(m=>{for(const P in m)!isNaN(m[P])&&Number(m[P])!==1/0&&(m[P]=Number(m[P]));const u=g(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),f=m.status,{labelCn:c,labelEn:k}=this.parseStatus(f),C={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:f,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?g(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:u.unix(),labelCn:c,labelEn:k,method:"trajectory",vendor:"myVessel",utc:u.utc().format()},F=Math.floor(u.diff(w,"minute",!0)/(i||1));F!==y&&(y=F,s.push(C))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return p==null||p.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;for(const w in s)!isNaN(s[w])&&Number(s[w])!==1/0&&(s[w]=Number(s[w]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:l,labelEn:h}=this.parseStatus(r),d=g(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?g.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:l,labelEn:h,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let i=await x.post(o,n).json();p==null||p.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),p==null||p.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},i=await x.post(o,n).json();p==null||p.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var m,u,f;const r=await this.realTimePosition(t,s);let l=g(a);const h=g(o),d=g();if(i){let c=h.diff(l,"d",!0);c<0?l=h.clone().subtract(40,"d"):c<30?l.subtract(10,"d"):c<60?l.subtract(5,"d"):l=h.clone().subtract(80,"d"),c=d.diff(h,"d",!0),h.add(c>10?240:c*24,"h")}const y={searchParams:{endtime:h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},w="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",M=await x.get(w,y).json();p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,w,y);let I;M&&(I=((u=(m=M.ships)==null?void 0:m.offors)==null?void 0:u.ship)||[],I.length||p==null||p.warn("[%s] fetch trajectory failed: %j",s.requestId,M));const j=[];let b=-1;const v=g(`${(f=I==null?void 0:I[0])==null?void 0:f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const c of I){for(const R in c)!isNaN(c[R])&&Number(c[R])!==1/0&&(c[R]=Number(c[R]));const k=g(`${c.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");c.status=c.sp>4?0:1;const{labelEn:C,labelCn:F}=this.parseStatus(c.status),P={mmsi:c.m,name:c.n,imo:r==null?void 0:r.imo,lat:c.la,lng:c.lo,draught:c.draught,sog:c.sp,cog:c.co,hdg:c.hdg,positionTime:k.unix(),utc:k.utc().format(),status:c.status,labelCn:F,labelEn:C,method:"trajectory",vendor:"hifleet"},N=Math.floor(k.diff(v,"minute",!0)/(n||1));N!==b&&(b=N,j.push(P))}return j}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),h=g.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:h.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var v;const r=await this.realTimePosition(t,s),l=g(a),h=g(o),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:h.unix()}},w=await x.get(d,y).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,d,y),(w==null?void 0:w.status)!==0)return w;const M=w==null?void 0:w.points,I=[],j=g.unix((v=M[0])==null?void 0:v.utc);let b=-1;for(const m of M){const u=g.unix(m.utc),f={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"},c=Math.floor(u.diff(j,"minute",!0)/(n||1));c!==b&&(b=c,I.push(f))}return I}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return p==null||p.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(p==null||p.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",p==null||p.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const M in l)!isNaN(l[M])&&Number(l[M])!==1/0&&(l[M]=Number(l[M]));const{labelCn:h,labelEn:d}=await this.parseStatus(l.aisNavStatus),y=g.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:y.utc().format(),status:l.aisNavStatus,labelEn:d,labelCn:h,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=g(a),l=g(o),h=await this.getShipId(t),d=await this.getShipInfo(h),y=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(h,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(h,r.unix(),l.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var j;const h={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},d="https://api3.myships.com/sp/ships/position/history",y=await x.post(d,h).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,h),y.code!=="0")return p==null||p.warn("[%s] invoke myship trajectory failed: %j",l.requestId,y),y;const w=y.data;for(const b in w)!isNaN(w[b])&&Number(w[b])!==1/0&&(w[b]=Number(w[b]));const M=g.unix((j=w[0])==null?void 0:j.posTime);let I=-1;for(const b of w){const v=g.unix(b.posTime),m={imo:n==null?void 0:n.imo,mmsi:i,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:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},u=Math.floor(v.diff(M,"minute",!0)/(s||1));u!==I&&(I=u,r.push(m))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let h=0;h<(n==null?void 0:n.length);h++){const d=(l=(r=n[h].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(h===0&&!d)i.scope=n[0];else if(d)for(let y=0,w=d.length;y<w;y++){const M=this.parseRule(d[y]);M&&(i[M.level]?M.key?i[M.level][M==null?void 0:M.key]=M:i[M.level]=M:M.key?i[M.level]={[M==null?void 0:M.key]:M}:i[M.level]=M)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var M,I,j,b,v,m,u,f,c,k,C,F,P,N,R;let o=0,n=0,i=0,s=0;const r=Math.round(((I=(M=t==null?void 0:t.SEVERE)==null?void 0:M.sigWave)==null?void 0:I.number)*1.6*100)/100,l=(b=(j=t==null?void 0:t.SEVERE)==null?void 0:j.sigWave)==null?void 0:b.number,h=(m=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:m.number,d=Math.round((((f=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:f.number)+2)*100)/100,y=(k=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:k.number,w=(F=(C=t==null?void 0:t.HEAVY)==null?void 0:C.wind)==null?void 0:F.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?g(H.eta).diff(g(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:h}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=h&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:w}),(B==null?void 0:B.scale)>=d?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>y?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===w&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:w},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:h}}}}const vt=new lt;let S;try{S=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(ht||{}),ft=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ft||{}),mt=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var y;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((y=e==null?void 0:e.type)==null?void 0:y.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=L.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let h;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:M,marineModels:I}=await ot.Meteo2Assist.autoPickMeteoModel(o),j=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:M,marineModels:I}),[b]=ot.Meteo2Assist.pickHourly(j,a);h=ot.Meteo2Assist.toLegacy(b)}catch(M){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},M)}const d=O.currentFactor(e.bearing,h==null?void 0:h.current,n),y=O.weatherFactor(e,h,d),w=Math.round((e.speed*1.943844+y+d)*100)/100;l={meteo:{...h},wxFactor:y,cFactor:d,speed:t.velocity&&s?t.velocity:w<0?1:w,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,h={}){t.utc();const d=t.clone().add(14,"days"),y=[],w=[],M=[];let I=0,j=0,b,v;for(let m=0;m<i.length-1;m++){let u=i[m];u.distanceFromStart=Math.round((n+j)*1e3)/1e3;const f=i[m+1];if(e.bearing=L.LaneHelper.calculateBearing(u,f,!f.gcToPrevious),u.bearing=e.bearing,u.suspend&&l){u.eta=u.eta||t.utc().format(),u.elapsed=u.elapsed??0;const C=u.suspend-u.elapsed;if(o-I>C)o=o-I-C,t.add(C,"hour"),u.elapsed=u.suspend;else{const F=o-I;u.elapsed+=F,t.add(F,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${o} hours need to go...`,h.requestId,u),o===0)return u.distanceFromPrevious=j,{etd:t,from:v||u,to:u,next:i.filter(F=>F),wps:y,days:w,all:M}}else u.suspend=0;r=t.isAfter(d)?!1:r,u=await O.speedLoseAt(e,u,t,s,0,r,l,h),M.push(u),v=v||u,u.important&&y.push(u),t.isSameOrAfter(a)&&(w.push(u),a.add(24,"hour"));const c=L.LaneHelper.calculateDistance(u,f,!f.gcToPrevious);let k=Math.round(c/v.speed*1e5)/1e5;if(I+k<o){if(I+=k,t.add(k,"hour"),delete i[m],S==null||S.debug(`[%s] go to %j from %j with ${c}nm, and cost ${k} hours`,h.requestId,{lat:f.lat,lng:f.lng},{lat:v.lat,lng:v.lng,etd:v.etd}),j+=c,i.filter(C=>C).length<=1){b=f,b.eta=t.utc().format(),b.distanceFromPrevious=c,b.distanceFromStart=Math.round((n+j)*1e4)/1e4,y.push(b),M.push(b),delete i[m+1];break}}else{k=o-I,t.add(k,"hour");const C=L.LngLatHelper.roundPrecision(v.speed*k,5);b=L.LaneHelper.calculateCoordinate(u,e.bearing,C,"nauticalmiles",!f.gcToPrevious),b.eta=t.utc().format(),i[m]=b,S==null||S.debug(`[%s] go to %j from %j with ${C}nm, and cost ${k} hours`,h.requestId,{lat:b.lat,lng:b.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),j+=C,b.distanceFromPrevious=Math.round(j*1e4)/1e4,b.distanceFromStart=Math.round((n+j)*1e4)/1e4;break}}return{etd:t,from:v,to:b,next:i.filter(m=>m),wps:y,days:w,all:M}}static currentFactor(e,t,a=0){const o=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var w,M,I,j,b,v,m;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=L.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=Math.abs(e.bearing%360-(((w=t==null?void 0:t.wind)==null?void 0:w.degree)%360||0));r=r>180?360-r:r;const l=O.directionFactor(r,(M=t==null?void 0:t.wind)==null?void 0:M.scale),h=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(I=t==null?void 0:t.wind)==null?void 0:I.kts);let d=l*s*h/100*(e.speed-n);d=Math.round(d*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(d)>1&&(d=d/(Math.abs(Math.round(d))+1)),S==null||S.debug("wind wx factor = %d",d),r=Math.abs(e.bearing%360-(((b=(j=t==null?void 0:t.wave)==null?void 0:j.sig)==null?void 0:b.degree)%360||0)),r=r>180?360-r:r;const y=O.waveHeightFactor(((m=(v=t==null?void 0:t.wave)==null?void 0:v.sig)==null?void 0:m.height)??1,r);return S==null||S.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.7,S==null||S.debug("weather factor = %d",d),d=Math.abs(d)>3?3*(Math.abs(d)/d)+Math.abs(d)/d*(Math.abs(d)-2)*.1:d,Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=g.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(g(n.etd).unix()/t)===Math.floor(g(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,h={}){var X,Q,Z,$,tt,et;const d=g().valueOf();e.lng=L.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:w}=n.points,M=L.LaneHelper.calculateSubRoute(e,y);if(((X=M[0])==null?void 0:X.length)<=1)return;const{v0:I,label:j}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},b=O.assembleProperties(a,o.loadCondition,I,0),v=w.length?L.LaneHelper.calculateSubWaypoints(e,w):[];v.forEach(q=>q.important=!0);const m={from:{...e},route:M,waypoints:v,v0:I,label:j},u={hours:[],days:[],wps:[],all:[]};s||(L.LaneHelper.calculateRouteDistance(M)/o.speed<=72?s=3:s=6);let f=L.LaneHelper.simplifyRouteToCoordinates(M,v,0),c=0,k=0,C=0,F=0;t=g(t).utc();const P=t.clone();for(;f.length>0;){const q=s-t.hour()%s,z=Math.ceil(t.clone().add(q,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,T=await O.speedLoseInHoursStep(b,t,P,z,c,f,i,r,l,h);if(u.all.push(...T.all),(Q=T.from)!=null&&Q.speed&&(u.hours.push(T.from),u.wps.push(...T.wps),u.days.push(...T.days)),f=T==null?void 0:T.next,!f.length){const W=await O.speedLoseAt(b,T.to,g(T.to.eta),i,0,r,l,h);W.bearing=b.bearing,u.hours.push(W),u.all.push(W)}c+=Math.round((((Z=T==null?void 0:T.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=u.hours;for(let q=0;q<N.length-1;q++){const z=g(N[q+1].eta).diff(N[q].etd,"hour",!0)||1;k+=(N[q].wxFactor||0)*z,C+=(N[q].cFactor||0)*z,F+=z}const R=N.reduce((q,z)=>q+(z.suspend||0),0);($=u.wps)==null||$.forEach((q,z)=>{q.positionTime=g.utc(q.etd||q.eta).unix();const T=u.wps[z-1];if(T){const W=q.distanceFromStart-T.distanceFromStart,Y=g(q.eta||q.etd).diff(g(T.etd||T.eta),"h",!0);q.avgSpd=Math.round(W/Y*100)/100,T.bearing=L.LaneHelper.calculateBearing(T,q)}}),u.wps=await O.reduceWPS(u.wps),u.days=await O.reduceDays(u.days),u.all=(tt=u.all)==null?void 0:tt.reduce((q,z)=>(z.positionTime=g.utc(z.etd||z.eta).unix(),q.some(T=>Math.round(T.positionTime/60)===Math.round(z.positionTime/60))||q.push(z),q),[]),m.sample=u;const E=u.hours.at(0),H=u.hours.at(-1);m.distance=Math.round(H.distanceFromStart*1e3)/1e3,m.etd=g(E.eta).utc().format(),m.eta=g(H.eta).utc().format(),m.wxFactor=Math.round(k/F*1e3)/1e3,m.cFactor=Math.round(C/F*1e3)/1e3,m.avgSpeed=Math.round(H.distanceFromStart/F*1e3)/1e3,m.totalHrs=Math.round(F*1e3)/1e3,m.suspend=Math.round(R*1e3)/1e3;const V=L.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(m,o,h),at=L.LngLatHelper.roundPrecision(o.fo/24*(F-K),3),rt=L.LngLatHelper.roundPrecision(o.dgo/24*F+V,3);m.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},m.totalFoCons=at<0?0:at,m.totalDgoCons=rt;const nt=g().valueOf()-d,dt=((et=u==null?void 0:u.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),m}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,h=!0,d=!1,y={}){var Z,$,tt,et,q,z;const w=g().valueOf();e.lng=L.LngLatHelper.convertToStdLng(e.lng);const{v0:M,label:I}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},j=O.assembleProperties(o,n.loadCondition,M,0),b=L.LaneHelper.calculateSubRoute(e,i);if(((Z=b[0])==null?void 0:Z.length)<=1)return;const v=s.length?L.LaneHelper.calculateSubWaypoints(e,s):[];v.forEach(T=>T.important=!0);let m=L.LaneHelper.simplifyRouteToCoordinates(b,v,0),u=0,f=0,c=0,k=0;const C={hours:[],wps:[],days:[],all:[]};t=g(t).utc();const F=t.clone();for(;m.length>0;){const T=l-t.hour()%l;let W=Math.ceil(t.clone().add(T,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(j,t,F,W,u,m,r,h,d,y);if(C.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(C.hours.push(Y.from),Y!=null&&Y.wps&&C.wps.push(...Y.wps),C.days.push(...Y.days)),m=Y==null?void 0:Y.next,m.length||C.hours.push(Y==null?void 0:Y.to),u+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!W)break}C.wps=await O.reduceWPS(C.wps),C.days=await O.reduceDays(C.days),C.all=(et=C.all)==null?void 0:et.reduce((T,W)=>(W.positionTime=g.utc(W.etd||W.eta).unix(),T.some(Y=>Math.round(g(Y.etd).unix()/60)===Math.round(g(W.etd).unix()/60))||T.push(W),T),[]),(q=C.wps)==null||q.forEach((T,W)=>{const Y=C.wps[W-1];if(Y){const It=T.distanceFromStart-Y.distanceFromStart,kt=g(T.eta||T.etd).diff(g(Y.etd||Y.eta),"h",!0);Y.bearing=L.LaneHelper.calculateBearing(Y,T),T.avgSpd=Math.round(It/kt*100)/100}});const P=C.hours;for(let T=0;T<P.length-1;T++){const W=g(P[T+1].eta).diff(P[T].etd,"hour",!0);f+=P[T].wxFactor*W,c+=P[T].cFactor*W,k+=W}const N=P.reduce((T,W)=>T+(W.suspend||0),0),R=C.hours.at(0),E=C.hours.at(-1),H=await L.LaneHelper.calculateRangeRoute(R,E,b),V=await L.LaneHelper.calculateRangeWaypoints(R,E,b,v),B={sample:C,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:g(R.eta).utc().format(),eta:g(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(f/k*1e3)/1e3,cFactor:Math.round(c/k*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/k*1e3)/1e3,totalHrs:Math.round(k*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:M,label:I},K=L.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=L.LngLatHelper.roundPrecision(n.fo/24*(k-st),3),nt=L.LngLatHelper.roundPrecision(n.dgo/24*k+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=g().valueOf()-w,Q=((z=C==null?void 0:C.hours)==null?void 0:z.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",y==null?void 0:y.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var b,v;const i=g().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=L.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(m=>{const u=Math.ceil(r/m.speed/24);l=l<u?u:l}),l=l*1.3;const h=g.utc(e.etd).add(l??14,"day");let d=1;for(const m of a){const u=JSON.parse(JSON.stringify(o.route)),f=JSON.parse(JSON.stringify(o.waypoints)),c=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,h,t,m,u,f,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);c&&(await O.calculateCost(c,m,e,n),s.push(c),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,h.format(),{cost:c.cost.total,hire:c.cost.hire,bunker:c.cost.bunker,distance:c.distance,hours:c.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),d++}s.sort((m,u)=>m.cost.total-u.cost.total);const y=s.at(0),w=s.at(1),M=[];if(M.push({combined:!1,speeds:[y],cost:(b=y.cost)==null?void 0:b.total}),w){const m=y.cost.cp,u=w.cost.cp,f=g(y.eta),c=g(y.etd),k=f.diff(c,"days",!0);let C=Math.ceil(k/2);C=C>7?7:C<e.alterStep?e.alterStep:C;let F=2,P={combined:!1,speeds:[w],cost:(v=w.cost)==null?void 0:v.total},N;for(;C>=e.alterStep;){const R=await O.combinedAnalyse(e,t,h,[m,u],o,C,{...n,level:F});if(P.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=P,P=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),C<=e.alterStep)break;C=Math.ceil(C/2),F+=1}M.push(P),N&&M.push(N)}const j=g().valueOf()-i;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,j),M.sort((m,u)=>m.cost-u.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((u,f)=>u+f.cost.total,0),h=r.reduce((u,f)=>u+f.cost.hire,0),d=r.reduce((u,f)=>u+f.cost.bunker,0),y=r.reduce((u,f)=>u+f.distance,0),w=r.reduce((u,f)=>u+f.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:h,bunker:d,distance:y,hours:w});const M=await O.alternateAnalyse(e,t,a,o,1,n,i,s),I=M.reduce((u,f)=>u+f.cost.total,0),j=M.reduce((u,f)=>u+f.cost.hire,0),b=M.reduce((u,f)=>u+f.cost.bunker,0),v=M.reduce((u,f)=>u+f.distance,0),m=M.reduce((u,f)=>u+f.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:I,hire:j,bunker:b,distance:v,hours:m}),l<I?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(I*1e3)/1e3,speeds:M,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var y,w;let l=g.utc(e.etd);const h={lat:e.lat,lng:e.lng},d=[];for(;l.isBefore(a);){const M=l.clone().utc().add(s,"day"),I=JSON.parse(JSON.stringify(i.route)),j=JSON.parse(JSON.stringify(i.waypoints)),b=o[n],v=await O.analyseInstantWithThreshed(h,l.utc().format(),M,t,b,I,j,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);v&&(await O.calculateCost(v,b,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),M.utc().format(),{cost:v.cost.total,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${b.speed}/${b.fo}/${b.dgo}`})),r.counter=r.counter+1;const m=(w=(y=v==null?void 0:v.sample)==null?void 0:y.hours)==null?void 0:w.at(-1);if(m)h.lat=m.lat,h.lng=m.lng,l=g(m.eta),d.push(v),n=n?0:1;else break}return d}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,h=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+h)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+h)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,h,d;const o=await L.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(y=>{y.positionTime=g.utc(y.etd||y.eta).unix()});for(const y of o){n+=y.distance;const w=await L.LaneHelper.deadReckoningTime((h=y.waypoints)==null?void 0:h.at(0),e.sample.all||e.sample.wps),M=await L.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),e.sample.all||e.sample.wps);y.in=w,y.out=M,y.totalHrs=L.LngLatHelper.roundPrecision((M.positionTime-w.positionTime)/3600,3),y.totalDgoCons=L.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),i+=y.totalHrs,s+=y.totalDgoCons}return n=L.LngLatHelper.roundPrecision(n,3),i=L.LngLatHelper.roundPrecision(i,3),s=L.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var m,u;const a={hours:[],wps:[],days:[]},o=e.reduce((f,c)=>f+c.distance,0),n=e.reduce((f,c)=>{var k;return f+(((k=c.extend)==null?void 0:k.distanceInECA)||0)},0),i=e.reduce((f,c)=>f+c.totalHrs,0),s=e.reduce((f,c)=>{var k;return f+(((k=c.extend)==null?void 0:k.hoursInECA)||0)},0),r=e.reduce((f,c)=>{var k;return f+(((k=c.extend)==null?void 0:k.totalDgoConsInECA)||0)},0),l=e.reduce((f,c)=>f+c.wxFactor*c.totalHrs/i,0),h=e.reduce((f,c)=>f+c.cFactor*c.totalHrs/i,0),d=e.reduce((f,c)=>f+c.totalFoCons,0),y=e.reduce((f,c)=>f+c.totalDgoCons,0),w=e.reduce((f,c)=>f+c.cost.total,0),M=e.reduce((f,c)=>f+c.cost.hire,0),I=e.reduce((f,c)=>f+c.cost.bunker,0),j=[],b=[];let v;for(const f of e){b.push(...((m=f.extend)==null?void 0:m.eca)||[]);const c=f.sample.hours,k=f.sample.wps,C=f.sample.days,F=c.at(0);v&&(F.distanceFromPrevious=v.distanceFromPrevious,F.distanceFromStart=v.distanceFromStart,c.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)}),k.at(0).distanceFromPrevious=v.distanceFromPrevious,k.at(0).distanceFromStart=v.distanceFromStart,k.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)}),C.at(0).distanceFromPrevious=v.distanceFromPrevious,C.at(0).distanceFromStart=v.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)})),F.cp=f.cost.cp;const P=[f.etd,f.eta],N=j.findIndex(E=>E.id===F.cp.id);N===-1?(F.cp.segment=[P],j.push(F.cp)):j[N].segment.push(P),c.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),k.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),C.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(u=a.wps)==null?void 0:u.findIndex(E=>E.eta===F.eta);R===-1?a.wps.push(F):a.wps[R]=F,v=c.at(-1)}return a.wps.sort((f,c)=>g(f.etd).unix()-g(c.etd).unix()),a.wps.forEach((f,c)=>{const k=a.wps[c-1];if(k){const C=f.distanceFromStart-(k.distanceFromStart||0),F=g(f.eta||f.etd).diff(g(k.etd||k.eta),"hour",!0),P=Math.round(C/F*100)/100;f.avgSpd=P;const N=L.LaneHelper.calculateBearing(k,f);k.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(h*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*1e3)/1e3,cost:{total:Math.round(w*1e3)/1e3,hire:Math.round(M*1e3)/1e3,bunker:Math.round(I*1e3)/1e3},extend:{cps:j,eca:b,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}A.AISImpl=G,A.AlertHelper=lt,A.AlertLevel=ut,A.HifleetImpl=Mt,A.LoadCondition=ft,A.MyShipImpl=gt,A.MyVesselImpl=pt,A.ShipxyImpl=bt,A.SpeedHelper=O,A.SpeedLabel=mt,A.VesselTag=ht,A.alertHelper=vt,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});
|