@idm-plugin/vessel 1.7.4 → 1.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +251 -253
- package/dist/index.umd.cjs +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var G = (
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import { LngLatHelper as
|
|
8
|
-
import { MeteoHelper2 as
|
|
1
|
+
var ut = Object.defineProperty;
|
|
2
|
+
var ht = (j, e, t) => e in j ? ut(j, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : j[e] = t;
|
|
3
|
+
var G = (j, e, t) => (ht(j, typeof e != "symbol" ? e + "" : e, t), t);
|
|
4
|
+
import J from "got";
|
|
5
|
+
import nt from "@log4js-node/log4js-api";
|
|
6
|
+
import p from "moment";
|
|
7
|
+
import { LngLatHelper as B, LaneHelper as L } from "@idm-plugin/geo2";
|
|
8
|
+
import { MeteoHelper2 as lt, MeteoHelper as ft } from "@idm-plugin/meteo2";
|
|
9
9
|
import { Meteo2Assist as rt } from "@idm-plugin/meteo";
|
|
10
10
|
let g;
|
|
11
11
|
try {
|
|
12
|
-
g =
|
|
12
|
+
g = nt.getLogger("vessel");
|
|
13
13
|
} catch {
|
|
14
14
|
} finally {
|
|
15
15
|
}
|
|
16
|
-
class
|
|
16
|
+
class et {
|
|
17
17
|
/**
|
|
18
18
|
* 解析AIS状态码
|
|
19
19
|
* @param status
|
|
@@ -54,7 +54,7 @@ class tt {
|
|
|
54
54
|
return { labelCn: t, labelEn: n };
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
class
|
|
57
|
+
class xt extends et {
|
|
58
58
|
constructor(t, n) {
|
|
59
59
|
super();
|
|
60
60
|
G(this, "clientId");
|
|
@@ -69,19 +69,19 @@ class Ct extends tt {
|
|
|
69
69
|
client_secret: this.clientSecret,
|
|
70
70
|
grant_type: "client_credentials"
|
|
71
71
|
}
|
|
72
|
-
}, o = await
|
|
72
|
+
}, o = await J.post(n, i).json();
|
|
73
73
|
g == null || g.info("[%s] fetch access token from: %s - %j", t.requestId, n, o), o.error || (this.token = {
|
|
74
74
|
accessToken: o.access_token,
|
|
75
75
|
tokenType: o.token_type,
|
|
76
76
|
expiresIn: o.expires_in,
|
|
77
77
|
scope: o.scope,
|
|
78
78
|
jti: o.jti,
|
|
79
|
-
issuedAt:
|
|
79
|
+
issuedAt: p().utc().format()
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
82
|
async realTimePosition(t, n = {}) {
|
|
83
83
|
var h, m, l;
|
|
84
|
-
(!this.token ||
|
|
84
|
+
(!this.token || p().diff(p(this.token.issuedAt), "seconds") > ((h = this.token) == null ? void 0 : h.expiresIn) - 300) && await this.authToken(n);
|
|
85
85
|
const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", o = {
|
|
86
86
|
headers: {
|
|
87
87
|
Authorization: `${(m = this.token) == null ? void 0 : m.tokenType} ${(l = this.token) == null ? void 0 : l.accessToken}`
|
|
@@ -89,13 +89,13 @@ class Ct extends tt {
|
|
|
89
89
|
searchParams: { mmsi: t }
|
|
90
90
|
};
|
|
91
91
|
g == null || g.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o);
|
|
92
|
-
const a = await
|
|
92
|
+
const a = await J.get(i, o).json();
|
|
93
93
|
if (a.code)
|
|
94
94
|
return g == null || g.warn("[%s] fetch realtime position failed: %j", n.requestId, i, { message: a.message, status: a.status, code: a.code }), a;
|
|
95
95
|
const s = a.data;
|
|
96
96
|
for (const y in s)
|
|
97
97
|
!isNaN(s[y]) && Number(s[y]) !== 1 / 0 && (s[y] = Number(s[y]));
|
|
98
|
-
const d =
|
|
98
|
+
const d = p(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
99
99
|
return {
|
|
100
100
|
mmsi: s.mmsi,
|
|
101
101
|
name: s.vesselName,
|
|
@@ -110,7 +110,7 @@ class Ct extends tt {
|
|
|
110
110
|
cog: s.cog,
|
|
111
111
|
hdg: s.hdg,
|
|
112
112
|
rot: s.rot,
|
|
113
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ?
|
|
113
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? p.utc(s.eta).format() : void 0,
|
|
114
114
|
destination: s.dest,
|
|
115
115
|
positionTime: d.unix(),
|
|
116
116
|
status: s.status,
|
|
@@ -122,14 +122,14 @@ class Ct extends tt {
|
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
async trajectory(t, n, i, o, a = !0, s = {}) {
|
|
125
|
-
(!this.token ||
|
|
126
|
-
const d = await this.realTimePosition(t, s), r =
|
|
125
|
+
(!this.token || p().diff(p(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(s);
|
|
126
|
+
const d = await this.realTimePosition(t, s), r = p(n), h = p(i), m = [];
|
|
127
127
|
for (; h.diff(r, "day", !0) > 30; )
|
|
128
128
|
await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, o, m, s), r.add(30, "day");
|
|
129
129
|
return await this.trajectoryIn30Day(t, r, h, d, o, m, s), m;
|
|
130
130
|
}
|
|
131
131
|
async trajectoryIn30Day(t, n, i, o, a, s, d = {}) {
|
|
132
|
-
var f, C, k,
|
|
132
|
+
var f, C, k, v, b;
|
|
133
133
|
const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
|
|
134
134
|
headers: {
|
|
135
135
|
Authorization: `${(f = this.token) == null ? void 0 : f.tokenType} ${(C = this.token) == null ? void 0 : C.accessToken}`
|
|
@@ -141,15 +141,15 @@ class Ct extends tt {
|
|
|
141
141
|
}
|
|
142
142
|
};
|
|
143
143
|
g == null || g.info("[%s] fetch trajectory from: %s - %j", d.requestId, r, h);
|
|
144
|
-
const m = await
|
|
144
|
+
const m = await J.post(r, h).json();
|
|
145
145
|
if (m.code)
|
|
146
146
|
return g == null || g.warn("[%s] fetch trajectory failed: %j", d.requestId, r, { message: m.message, status: m.status, code: m.code }), m;
|
|
147
147
|
let l = -1;
|
|
148
|
-
const y =
|
|
149
|
-
return (
|
|
148
|
+
const y = p(`${(v = (k = m.data) == null ? void 0 : k[0]) == null ? void 0 : v.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
149
|
+
return (b = m.data) == null || b.forEach((c) => {
|
|
150
150
|
for (const Y in c)
|
|
151
151
|
!isNaN(c[Y]) && Number(c[Y]) !== 1 / 0 && (c[Y] = Number(c[Y]));
|
|
152
|
-
const w =
|
|
152
|
+
const w = p(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), M = c.status, { labelCn: u, labelEn: I } = this.parseStatus(M), S = {
|
|
153
153
|
mmsi: c.mmsi,
|
|
154
154
|
imo: o == null ? void 0 : o.imo,
|
|
155
155
|
lat: c.lat,
|
|
@@ -159,7 +159,7 @@ class Ct extends tt {
|
|
|
159
159
|
hdg: c.hdg,
|
|
160
160
|
draught: c.draught,
|
|
161
161
|
status: M,
|
|
162
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta) ?
|
|
162
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta) ? p(`${c.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
|
|
163
163
|
destination: c.dest,
|
|
164
164
|
positionTime: w.unix(),
|
|
165
165
|
labelCn: u,
|
|
@@ -168,11 +168,11 @@ class Ct extends tt {
|
|
|
168
168
|
vendor: "myVessel",
|
|
169
169
|
utc: w.utc().format()
|
|
170
170
|
}, D = Math.floor(w.diff(y, "minute", !0) / (a || 1));
|
|
171
|
-
D !== l && (l = D, s.push(
|
|
171
|
+
D !== l && (l = D, s.push(S));
|
|
172
172
|
}), s;
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
|
-
class
|
|
175
|
+
class jt extends et {
|
|
176
176
|
constructor(t) {
|
|
177
177
|
super();
|
|
178
178
|
G(this, "token");
|
|
@@ -184,7 +184,7 @@ class xt extends tt {
|
|
|
184
184
|
mmsi: t,
|
|
185
185
|
usertoken: this.token
|
|
186
186
|
}
|
|
187
|
-
}, a = await
|
|
187
|
+
}, a = await J.post(i, o).json();
|
|
188
188
|
g == null || g.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o);
|
|
189
189
|
const s = a == null ? void 0 : a.list;
|
|
190
190
|
if (!s)
|
|
@@ -192,7 +192,7 @@ class xt extends tt {
|
|
|
192
192
|
for (const y in s)
|
|
193
193
|
!isNaN(s[y]) && Number(s[y]) !== 1 / 0 && (s[y] = Number(s[y]));
|
|
194
194
|
s.status = s.sp > 3 ? 0 : 1;
|
|
195
|
-
const d = s.status, { labelCn: r, labelEn: h } = this.parseStatus(d), m =
|
|
195
|
+
const d = s.status, { labelCn: r, labelEn: h } = this.parseStatus(d), m = p(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
196
196
|
return {
|
|
197
197
|
mmsi: s.m,
|
|
198
198
|
name: s.n,
|
|
@@ -207,7 +207,7 @@ class xt extends tt {
|
|
|
207
207
|
cog: s.co,
|
|
208
208
|
hdg: s.h,
|
|
209
209
|
rot: isNaN(s.rot) ? 0 : s.rot,
|
|
210
|
-
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ?
|
|
210
|
+
eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? p.utc(s.eta).format() : void 0,
|
|
211
211
|
destination: s.destination,
|
|
212
212
|
positionTime: m.unix(),
|
|
213
213
|
utc: m.utc().format(),
|
|
@@ -230,7 +230,7 @@ class xt extends tt {
|
|
|
230
230
|
Host: "www.hifleet.com"
|
|
231
231
|
}
|
|
232
232
|
};
|
|
233
|
-
let a = await
|
|
233
|
+
let a = await J.post(i, o).json();
|
|
234
234
|
g == null || g.info("[%s] fetch vessel props from: %s - %j", n.requestId, i, o), a instanceof Array && (a = a[0]);
|
|
235
235
|
for (const d in a)
|
|
236
236
|
!isNaN(a[d]) && Number(a[d]) !== 1 / 0 && (a[d] = Number(a[d]));
|
|
@@ -244,7 +244,7 @@ class xt extends tt {
|
|
|
244
244
|
draught: a.dr,
|
|
245
245
|
type: a.t
|
|
246
246
|
};
|
|
247
|
-
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await
|
|
247
|
+
return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await J.post(i, o).json(), g == null || g.info("[%s] search vessel dead weight from: %s - %j", n.requestId, i, o), a instanceof Array && (a = a[0]), a && (s.deadweight = Number(a.dwt)), s;
|
|
248
248
|
}
|
|
249
249
|
async suggest(t, n = {}) {
|
|
250
250
|
const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", o = {
|
|
@@ -256,7 +256,7 @@ class xt extends tt {
|
|
|
256
256
|
Origin: "https://www.hifleet.com",
|
|
257
257
|
Host: "www.hifleet.com"
|
|
258
258
|
}
|
|
259
|
-
}, a = await
|
|
259
|
+
}, a = await J.post(i, o).json();
|
|
260
260
|
g == null || g.info("[%s] suggest vessel props from: %s - %j", n.requestId, i, o);
|
|
261
261
|
const s = [];
|
|
262
262
|
for (const d of a)
|
|
@@ -272,8 +272,8 @@ class xt extends tt {
|
|
|
272
272
|
async trajectory(t, n, i, o, a = !0, s = {}) {
|
|
273
273
|
var c, w, M;
|
|
274
274
|
const d = await this.realTimePosition(t, s);
|
|
275
|
-
let r =
|
|
276
|
-
const h =
|
|
275
|
+
let r = p(n);
|
|
276
|
+
const h = p(i), m = p();
|
|
277
277
|
if (a) {
|
|
278
278
|
let u = h.diff(r, "d", !0);
|
|
279
279
|
u < 0 ? r = h.clone().subtract(40, "d") : u < 30 ? r.subtract(10, "d") : u < 60 ? r.subtract(5, "d") : r = h.clone().subtract(80, "d"), u = m.diff(h, "d", !0), h.add(u > 10 ? 240 : u * 24, "h");
|
|
@@ -285,19 +285,19 @@ class xt extends tt {
|
|
|
285
285
|
mmsi: t,
|
|
286
286
|
usertoken: this.token
|
|
287
287
|
}
|
|
288
|
-
}, y = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", f = await
|
|
288
|
+
}, y = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", f = await J.get(y, l).json();
|
|
289
289
|
g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, y, l);
|
|
290
290
|
let C;
|
|
291
291
|
f && (C = ((w = (c = f.ships) == null ? void 0 : c.offors) == null ? void 0 : w.ship) || [], C.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, f));
|
|
292
292
|
const k = [];
|
|
293
|
-
let
|
|
294
|
-
const
|
|
293
|
+
let v = -1;
|
|
294
|
+
const b = p(`${(M = C == null ? void 0 : C[0]) == null ? void 0 : M.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
295
295
|
for (const u of C) {
|
|
296
296
|
for (const P in u)
|
|
297
297
|
!isNaN(u[P]) && Number(u[P]) !== 1 / 0 && (u[P] = Number(u[P]));
|
|
298
|
-
const I =
|
|
298
|
+
const I = p(`${u.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
|
|
299
299
|
u.status = u.sp > 4 ? 0 : 1;
|
|
300
|
-
const { labelEn:
|
|
300
|
+
const { labelEn: S, labelCn: D } = this.parseStatus(u.status), Y = {
|
|
301
301
|
mmsi: u.m,
|
|
302
302
|
name: u.n,
|
|
303
303
|
imo: d == null ? void 0 : d.imo,
|
|
@@ -311,16 +311,16 @@ class xt extends tt {
|
|
|
311
311
|
utc: I.utc().format(),
|
|
312
312
|
status: u.status,
|
|
313
313
|
labelCn: D,
|
|
314
|
-
labelEn:
|
|
314
|
+
labelEn: S,
|
|
315
315
|
method: "trajectory",
|
|
316
316
|
vendor: "hifleet"
|
|
317
|
-
},
|
|
318
|
-
|
|
317
|
+
}, N = Math.floor(I.diff(b, "minute", !0) / (o || 1));
|
|
318
|
+
N !== v && (v = N, k.push(Y));
|
|
319
319
|
}
|
|
320
320
|
return k;
|
|
321
321
|
}
|
|
322
322
|
}
|
|
323
|
-
class
|
|
323
|
+
class Et extends et {
|
|
324
324
|
constructor(t) {
|
|
325
325
|
super();
|
|
326
326
|
G(this, "token");
|
|
@@ -333,13 +333,13 @@ class jt extends tt {
|
|
|
333
333
|
k: this.token,
|
|
334
334
|
enc: 1
|
|
335
335
|
}
|
|
336
|
-
}, o = "https://api.shipxy.com/apicall/GetSingleShip", a = await
|
|
336
|
+
}, o = "https://api.shipxy.com/apicall/GetSingleShip", a = await J.get(o, i).json();
|
|
337
337
|
if (g == null || g.info("[%s] fetch realtime position from: %s - %j", n.requestId, o, i), (a == null ? void 0 : a.status) !== 0)
|
|
338
338
|
return a;
|
|
339
339
|
const s = a.data[0];
|
|
340
340
|
for (const l in s)
|
|
341
341
|
!isNaN(s[l]) && Number(s[l]) !== 1 / 0 && (s[l] = Number(s[l]));
|
|
342
|
-
const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), h =
|
|
342
|
+
const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), h = p.unix(s.lasttime);
|
|
343
343
|
return {
|
|
344
344
|
mmsi: s.ShipID,
|
|
345
345
|
name: s.name,
|
|
@@ -364,8 +364,8 @@ class jt extends tt {
|
|
|
364
364
|
};
|
|
365
365
|
}
|
|
366
366
|
async trajectory(t, n, i, o, a = !0, s = {}) {
|
|
367
|
-
var
|
|
368
|
-
const d = await this.realTimePosition(t, s), r =
|
|
367
|
+
var b;
|
|
368
|
+
const d = await this.realTimePosition(t, s), r = p(n), h = p(i), m = "https://api.shipxy.com/apicall/GetShipTrack", l = {
|
|
369
369
|
searchParams: {
|
|
370
370
|
id: t,
|
|
371
371
|
k: this.token,
|
|
@@ -374,13 +374,13 @@ class jt extends tt {
|
|
|
374
374
|
btm: r.unix(),
|
|
375
375
|
etm: h.unix()
|
|
376
376
|
}
|
|
377
|
-
}, y = await
|
|
377
|
+
}, y = await J.get(m, l).json();
|
|
378
378
|
if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, m, l), (y == null ? void 0 : y.status) !== 0)
|
|
379
379
|
return y;
|
|
380
|
-
const f = y == null ? void 0 : y.points, C = [], k =
|
|
381
|
-
let
|
|
380
|
+
const f = y == null ? void 0 : y.points, C = [], k = p.unix((b = f[0]) == null ? void 0 : b.utc);
|
|
381
|
+
let v = -1;
|
|
382
382
|
for (const c of f) {
|
|
383
|
-
const w =
|
|
383
|
+
const w = p.unix(c.utc), M = {
|
|
384
384
|
imo: d == null ? void 0 : d.imo,
|
|
385
385
|
mmsi: t,
|
|
386
386
|
sog: Math.round(c.sog * 3600 / 1e3 / 1852 * 100) / 100,
|
|
@@ -392,12 +392,12 @@ class jt extends tt {
|
|
|
392
392
|
method: "trajectory",
|
|
393
393
|
vendor: "shipxy"
|
|
394
394
|
}, u = Math.floor(w.diff(k, "minute", !0) / (o || 1));
|
|
395
|
-
u !==
|
|
395
|
+
u !== v && (v = u, C.push(M));
|
|
396
396
|
}
|
|
397
397
|
return C;
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
|
-
class
|
|
400
|
+
class Nt extends et {
|
|
401
401
|
constructor(t) {
|
|
402
402
|
super();
|
|
403
403
|
G(this, "token");
|
|
@@ -411,7 +411,7 @@ class Et extends tt {
|
|
|
411
411
|
json: {
|
|
412
412
|
mmsiList: t
|
|
413
413
|
}
|
|
414
|
-
}, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await
|
|
414
|
+
}, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await J.post(o, i).json();
|
|
415
415
|
return g == null || g.info("[%s] fetch ship id from: %s - %j", n.requestId, o, i), a.code !== "0" ? a : a.data[0].shipId;
|
|
416
416
|
}
|
|
417
417
|
async getShipInfo(t, n = {}) {
|
|
@@ -422,7 +422,7 @@ class Et extends tt {
|
|
|
422
422
|
json: {
|
|
423
423
|
shipId: t
|
|
424
424
|
}
|
|
425
|
-
}, o = "https://api3.myships.com/sp/ships/aissta", a = await
|
|
425
|
+
}, o = "https://api3.myships.com/sp/ships/aissta", a = await J.post(o, i).json();
|
|
426
426
|
if (g == null || g.info("[%s] fetch ship info from: %s - %j", n.requestId, o, i), a.code !== "0")
|
|
427
427
|
return a;
|
|
428
428
|
const s = a.data;
|
|
@@ -445,12 +445,12 @@ class Et extends tt {
|
|
|
445
445
|
json: {
|
|
446
446
|
shipId: i
|
|
447
447
|
}
|
|
448
|
-
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await
|
|
448
|
+
}, s = "https://api3.myships.com/sp/ships/position/latest", d = await J.post(s, a).json();
|
|
449
449
|
g == null || g.info("[%s] fetch realtime position from: %s - %j", n.requestId, s, a);
|
|
450
450
|
const r = d.data[0];
|
|
451
451
|
for (const f in r)
|
|
452
452
|
!isNaN(r[f]) && Number(r[f]) !== 1 / 0 && (r[f] = Number(r[f]));
|
|
453
|
-
const { labelCn: h, labelEn: m } = await this.parseStatus(r.aisNavStatus), l =
|
|
453
|
+
const { labelCn: h, labelEn: m } = await this.parseStatus(r.aisNavStatus), l = p.unix(r.posTime);
|
|
454
454
|
return {
|
|
455
455
|
...o,
|
|
456
456
|
mmsi: t,
|
|
@@ -470,7 +470,7 @@ class Et extends tt {
|
|
|
470
470
|
};
|
|
471
471
|
}
|
|
472
472
|
async trajectory(t, n, i, o, a = !0, s = {}) {
|
|
473
|
-
const d =
|
|
473
|
+
const d = p(n), r = p(i), h = await this.getShipId(t), m = await this.getShipInfo(h), l = [];
|
|
474
474
|
for (; r.diff(d, "day", !0) > 30; )
|
|
475
475
|
await this.trajectoryIn30Day(h, d.unix(), d.add(30, "day").unix(), m, t, o, l);
|
|
476
476
|
return await this.trajectoryIn30Day(h, d.unix(), r.unix(), m, t, o, l), l;
|
|
@@ -486,42 +486,42 @@ class Et extends tt {
|
|
|
486
486
|
startTime: n,
|
|
487
487
|
endTime: i
|
|
488
488
|
}
|
|
489
|
-
}, m = "https://api3.myships.com/sp/ships/position/history", l = await
|
|
489
|
+
}, m = "https://api3.myships.com/sp/ships/position/history", l = await J.post(m, h).json();
|
|
490
490
|
if (g == null || g.info("[%s] fetch trajectory from: %s - %j", r.requestId, m, h), l.code !== "0")
|
|
491
491
|
return g == null || g.warn("[%s] invoke myship trajectory failed: %j", r.requestId, l), l;
|
|
492
492
|
const y = l.data;
|
|
493
|
-
for (const
|
|
494
|
-
!isNaN(y[
|
|
495
|
-
const f =
|
|
493
|
+
for (const v in y)
|
|
494
|
+
!isNaN(y[v]) && Number(y[v]) !== 1 / 0 && (y[v] = Number(y[v]));
|
|
495
|
+
const f = p.unix((k = y[0]) == null ? void 0 : k.posTime);
|
|
496
496
|
let C = -1;
|
|
497
|
-
for (const
|
|
498
|
-
const
|
|
497
|
+
for (const v of y) {
|
|
498
|
+
const b = p.unix(v.posTime), c = {
|
|
499
499
|
imo: o == null ? void 0 : o.imo,
|
|
500
500
|
mmsi: a,
|
|
501
|
-
lat: Math.round(
|
|
502
|
-
lng: Math.round(
|
|
503
|
-
sog: Math.round(
|
|
504
|
-
cog: Math.round(
|
|
505
|
-
hdg: Math.round(
|
|
506
|
-
rot: Math.round(
|
|
507
|
-
positionTime:
|
|
508
|
-
utc:
|
|
501
|
+
lat: Math.round(v.lat / 1e4 / 60 * 1e5) / 1e5,
|
|
502
|
+
lng: Math.round(v.lon / 1e4 / 60 * 1e5) / 1e5,
|
|
503
|
+
sog: Math.round(v.sog / 10 * 100) / 100,
|
|
504
|
+
cog: Math.round(v.cog / 10 * 100) / 100,
|
|
505
|
+
hdg: Math.round(v.heading * 100) / 100,
|
|
506
|
+
rot: Math.round(v.rot * 100) / 100,
|
|
507
|
+
positionTime: b.unix(),
|
|
508
|
+
utc: b.utc().format(),
|
|
509
509
|
method: "trajectory",
|
|
510
510
|
vendor: "myship"
|
|
511
|
-
}, w = Math.floor(
|
|
511
|
+
}, w = Math.floor(b.diff(f, "minute", !0) / (s || 1));
|
|
512
512
|
w !== C && (C = w, d.push(c));
|
|
513
513
|
}
|
|
514
514
|
return d;
|
|
515
515
|
}
|
|
516
516
|
}
|
|
517
|
-
let
|
|
517
|
+
let _;
|
|
518
518
|
try {
|
|
519
|
-
|
|
519
|
+
_ = nt.getLogger("vessel");
|
|
520
520
|
} catch {
|
|
521
521
|
} finally {
|
|
522
522
|
}
|
|
523
|
-
var
|
|
524
|
-
class
|
|
523
|
+
var mt = /* @__PURE__ */ ((j) => (j.NOTICE = "NOTICE", j.WARN = "WARN", j.HEAVY = "HEAVY", j.SEVERE = "SEVERE", j.ERROR = "ERROR", j.FATAL = "FATAL", j))(mt || {});
|
|
524
|
+
class yt {
|
|
525
525
|
/**
|
|
526
526
|
* 解析告警规则, 多规则场景
|
|
527
527
|
* @param rule
|
|
@@ -532,7 +532,7 @@ class mt {
|
|
|
532
532
|
*/
|
|
533
533
|
parsePrinciple(e, t = {}) {
|
|
534
534
|
var s, d, r;
|
|
535
|
-
|
|
535
|
+
_ == null || _.info("[%s] parse rule: %s", t.requestId, e);
|
|
536
536
|
const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = e.match(n) ? (s = e.match(n)) == null ? void 0 : s[0] : void 0, o = i == null ? void 0 : i.split(";");
|
|
537
537
|
if (!o)
|
|
538
538
|
return;
|
|
@@ -557,7 +557,7 @@ class mt {
|
|
|
557
557
|
*/
|
|
558
558
|
parseRule(e, t = {}) {
|
|
559
559
|
var a;
|
|
560
|
-
|
|
560
|
+
_ == null || _.info("[%s] parse rule: %s", t.requestId, e), e = e.startsWith("[") ? e : `[${e}`, e = e.endsWith("]") ? e : `${e}]`;
|
|
561
561
|
const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (a = e == null ? void 0 : e.match(n)) == null ? void 0 : a[0], o = i == null ? void 0 : i.split(",");
|
|
562
562
|
if (o)
|
|
563
563
|
return {
|
|
@@ -575,25 +575,25 @@ class mt {
|
|
|
575
575
|
* @param options
|
|
576
576
|
*/
|
|
577
577
|
checkWeather(e, t, n = {}) {
|
|
578
|
-
var f, C, k,
|
|
578
|
+
var f, C, k, v, b, c, w, M, u, I, S, D, Y, N, P;
|
|
579
579
|
let i = 0, o = 0, a = 0, s = 0;
|
|
580
|
-
const d = Math.round(((C = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.sigWave) == null ? void 0 : C.number) * 1.6 * 100) / 100, r = (
|
|
581
|
-
for (let
|
|
582
|
-
const
|
|
583
|
-
s = K > s ? K : s,
|
|
580
|
+
const d = Math.round(((C = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.sigWave) == null ? void 0 : C.number) * 1.6 * 100) / 100, r = (v = (k = t == null ? void 0 : t.SEVERE) == null ? void 0 : k.sigWave) == null ? void 0 : v.number, h = (c = (b = t == null ? void 0 : t.HEAVY) == null ? void 0 : b.sigWave) == null ? void 0 : c.number, m = Math.round((((M = (w = t == null ? void 0 : t.SEVERE) == null ? void 0 : w.wind) == null ? void 0 : M.number) + 2) * 100) / 100, l = (I = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : I.number, y = (D = (S = t == null ? void 0 : t.HEAVY) == null ? void 0 : S.wind) == null ? void 0 : D.number;
|
|
581
|
+
for (let T = 0; T < (e == null ? void 0 : e.length); T++) {
|
|
582
|
+
const E = e[T], A = (N = (Y = E == null ? void 0 : E.meteo) == null ? void 0 : Y.wave) == null ? void 0 : N.sig, R = (P = E == null ? void 0 : E.meteo) == null ? void 0 : P.wind, K = T ? p(E.eta).diff(p(e[T - 1].eta), "hour", !0) : 0;
|
|
583
|
+
s = K > s ? K : s, _ == null || _.info("[%s] check sig.wave: %j", n.requestId, { ...A, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h }), (A == null ? void 0 : A.height) >= d ? E.isDangerous = !0 : (A == null ? void 0 : A.height) >= r ? E.isSevere = !0 : (A == null ? void 0 : A.height) >= h && (E.isHeavy = !0), _ == null || _.info("[%s] check wind: %j", n.requestId, { ...R, dgThd4Wd: m, svThd4Wd: l, hvThd4Wd: y }), (R == null ? void 0 : R.scale) >= m ? (E.isDangerous = !0, delete E.isSevere, delete E.isHeavy) : (R == null ? void 0 : R.scale) > l ? (E.isDangerous || (E.isSevere = !0), delete E.isHeavy) : (R == null ? void 0 : R.scale) === y && !E.isDangerous && !E.isSevere && (E.isHeavy = !0), i += E.isDangerous ? K : 0, o += E.isSevere ? K : 0, a += E.isHeavy ? K : 0;
|
|
584
584
|
}
|
|
585
585
|
return i = Math.round(i * 100) / 100, o = Math.round(o * 100) / 100, a = Math.round(a * 100) / 100, s = Math.round(s), { sample: e, dangerous: i, severe: o, heavy: a, step: s < 3 ? 3 : s, wind: { dgThd4Wd: m, svThd4Wd: l, hvThd4Wd: y }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: h } };
|
|
586
586
|
}
|
|
587
587
|
}
|
|
588
|
-
const
|
|
589
|
-
let
|
|
588
|
+
const Tt = new yt();
|
|
589
|
+
let F;
|
|
590
590
|
try {
|
|
591
|
-
|
|
591
|
+
F = nt.getLogger("vessel");
|
|
592
592
|
} catch {
|
|
593
593
|
} finally {
|
|
594
594
|
}
|
|
595
|
-
const
|
|
596
|
-
var
|
|
595
|
+
const Mt = new lt("", !0);
|
|
596
|
+
var gt = /* @__PURE__ */ ((j) => (j.common = "common", j.container = "container", j.tugs = "tugs", j))(gt || {}), pt = /* @__PURE__ */ ((j) => (j.Ballast = "Ballast", j.Laden = "Laden", j))(pt || {}), wt = /* @__PURE__ */ ((j) => (j.Cp = "CP", j.Perf = "Basis", j.Instruct = "Other", j))(wt || {});
|
|
597
597
|
class O {
|
|
598
598
|
/**
|
|
599
599
|
* @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
|
|
@@ -734,17 +734,17 @@ class O {
|
|
|
734
734
|
*/
|
|
735
735
|
static async speedLoseAt(e, t, n, i = "", o = 2, a = !0, s = !1, d = {}) {
|
|
736
736
|
let r;
|
|
737
|
-
if (t.velocity && s && (e.speed =
|
|
737
|
+
if (t.velocity && s && (e.speed = B.roundPrecision(t.velocity * 1852 / 3600, 6)), a) {
|
|
738
738
|
let h;
|
|
739
739
|
if (d.meteo2)
|
|
740
740
|
try {
|
|
741
|
-
const f = await
|
|
741
|
+
const f = await Mt.spotForecast(t.lat, t.lng, n.utc().format(), !1, !1, !0, d), [C] = rt.pickHourly(f, n);
|
|
742
742
|
h = rt.toLegacy(C);
|
|
743
743
|
} catch (f) {
|
|
744
|
-
|
|
744
|
+
F.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...t, eta: n.utc().format() }, f);
|
|
745
745
|
}
|
|
746
746
|
else
|
|
747
|
-
h = await
|
|
747
|
+
h = await ft.queryPointFactor(t.lng, t.lat, n.valueOf(), "wind,wave,current,watertemp", i, d);
|
|
748
748
|
const m = O.weatherFactor(e, h), l = O.currentFactor(e.bearing, h == null ? void 0 : h.current, o), y = Math.round((e.speed * 1.943844 + m + l) * 100) / 100;
|
|
749
749
|
r = {
|
|
750
750
|
meteo: { ...h },
|
|
@@ -780,41 +780,41 @@ class O {
|
|
|
780
780
|
static async speedLoseInHoursStep(e, t, n, i, o, a, s = "", d = !0, r = !1, h = {}) {
|
|
781
781
|
t.utc();
|
|
782
782
|
const m = t.clone().add(14, "days"), l = [], y = [];
|
|
783
|
-
let f = 0, C = 0, k,
|
|
784
|
-
for (let
|
|
785
|
-
let c = a[
|
|
783
|
+
let f = 0, C = 0, k, v;
|
|
784
|
+
for (let b = 0; b < a.length - 1; b++) {
|
|
785
|
+
let c = a[b];
|
|
786
786
|
c.distanceFromStart = Math.round((o + C) * 1e4) / 1e4;
|
|
787
|
-
const w = a[
|
|
788
|
-
if (e.bearing =
|
|
787
|
+
const w = a[b + 1];
|
|
788
|
+
if (e.bearing = L.calculateBearing(c, w, !w.gcToPrevious), c.bearing = e.bearing, c.suspend && r) {
|
|
789
789
|
c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
|
|
790
790
|
const I = c.suspend - c.elapsed;
|
|
791
791
|
if (i - f > I)
|
|
792
792
|
i = i - f - I, t.add(I, "hour"), c.elapsed = c.suspend;
|
|
793
793
|
else {
|
|
794
|
-
const
|
|
795
|
-
c.elapsed +=
|
|
794
|
+
const S = i - f;
|
|
795
|
+
c.elapsed += S, t.add(S, "hour"), i = 0;
|
|
796
796
|
}
|
|
797
|
-
if (
|
|
798
|
-
return c.distanceFromPrevious = C, { etd: t, from:
|
|
797
|
+
if (F == null || F.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`, h.requestId, c), i === 0)
|
|
798
|
+
return c.distanceFromPrevious = C, { etd: t, from: v || c, to: c, next: a.filter((S) => S), wps: l, days: y };
|
|
799
799
|
} else
|
|
800
800
|
c.suspend = 0;
|
|
801
|
-
d = t.isAfter(m) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d, r, h),
|
|
802
|
-
const M =
|
|
803
|
-
let u = Math.round(M /
|
|
801
|
+
d = t.isAfter(m) ? !1 : d, c = await O.speedLoseAt(e, c, t, s, 0, d, r, h), v = v || c, c.important && l.push(c), t.isSameOrAfter(n) && (y.push(c), n.add(24, "hour"));
|
|
802
|
+
const M = L.calculateDistance(c, w, !w.gcToPrevious);
|
|
803
|
+
let u = Math.round(M / v.speed * 1e5) / 1e5;
|
|
804
804
|
if (f + u < i) {
|
|
805
|
-
if (f += u, t.add(u, "hour"), delete a[
|
|
805
|
+
if (f += u, t.add(u, "hour"), delete a[b], F == null || F.debug(
|
|
806
806
|
`[%s] go to %j from %j with ${M}nm, and cost ${u} hours`,
|
|
807
807
|
h.requestId,
|
|
808
808
|
{ lat: w.lat, lng: w.lng },
|
|
809
|
-
{ lat:
|
|
809
|
+
{ lat: v.lat, lng: v.lng, etd: v.etd }
|
|
810
810
|
), C += M, a.filter((I) => I).length <= 1) {
|
|
811
|
-
k = w, k.eta = t.utc().format(), k.distanceFromPrevious = M, k.distanceFromStart = Math.round((o + C) * 1e4) / 1e4, l.push(k), delete a[
|
|
811
|
+
k = w, k.eta = t.utc().format(), k.distanceFromPrevious = M, k.distanceFromStart = Math.round((o + C) * 1e4) / 1e4, l.push(k), delete a[b + 1];
|
|
812
812
|
break;
|
|
813
813
|
}
|
|
814
814
|
} else {
|
|
815
815
|
u = i - f, t.add(u, "hour");
|
|
816
|
-
const I =
|
|
817
|
-
k =
|
|
816
|
+
const I = B.roundPrecision(v.speed * u, 5);
|
|
817
|
+
k = L.calculateCoordinate(c, e.bearing, I, "nauticalmiles", !w.gcToPrevious), k.eta = t.utc().format(), a[b] = k, F == null || F.debug(
|
|
818
818
|
`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,
|
|
819
819
|
h.requestId,
|
|
820
820
|
{ lat: k.lat, lng: k.lng },
|
|
@@ -823,7 +823,7 @@ class O {
|
|
|
823
823
|
break;
|
|
824
824
|
}
|
|
825
825
|
}
|
|
826
|
-
return { etd: t, from:
|
|
826
|
+
return { etd: t, from: v, to: k, next: a.filter((b) => b), wps: l, days: y };
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
829
829
|
* 洋流影响因子
|
|
@@ -844,16 +844,16 @@ class O {
|
|
|
844
844
|
* @param wwc 气象要素
|
|
845
845
|
*/
|
|
846
846
|
static weatherFactor(e, t) {
|
|
847
|
-
var m, l, y, f, C, k,
|
|
848
|
-
|
|
847
|
+
var m, l, y, f, C, k, v;
|
|
848
|
+
F == null || F.debug("calculate weather factor via: %j", { ...e, ...t });
|
|
849
849
|
const n = O.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), i = O.froudeNumber(e.speed, e.lbp), o = O.amendFactor(n, i, e.loadCondition);
|
|
850
850
|
let a = Math.abs(e.bearing % 360 - (((m = t == null ? void 0 : t.wind) == null ? void 0 : m.degree) % 360 || 0));
|
|
851
851
|
a = a > 180 ? 360 - a : a;
|
|
852
852
|
const s = O.directionFactor(a, (l = t == null ? void 0 : t.wind) == null ? void 0 : l.scale), d = O.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (y = t == null ? void 0 : t.wind) == null ? void 0 : y.scale);
|
|
853
853
|
let r = s * o * d / 100 * e.speed;
|
|
854
|
-
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)),
|
|
855
|
-
const h = O.waveHeightFactor(((
|
|
856
|
-
return
|
|
854
|
+
r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r), a = Math.abs(e.bearing % 360 - (((C = (f = t == null ? void 0 : t.wave) == null ? void 0 : f.sig) == null ? void 0 : C.degree) % 360 || 0));
|
|
855
|
+
const h = O.waveHeightFactor(((v = (k = t == null ? void 0 : t.wave) == null ? void 0 : k.sig) == null ? void 0 : v.height) ?? 1, a);
|
|
856
|
+
return F == null || F.debug("wave wx factor = %d", h), r = r * 0.4 + h, F == null || F.debug("weather factor = %d", r), r = Math.abs(r) > 4 ? 4 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 4) * 0.1 : r, Math.round((r || 0) * 100) / 100;
|
|
857
857
|
}
|
|
858
858
|
/**
|
|
859
859
|
* 全程失速分析(走完航程)
|
|
@@ -868,10 +868,10 @@ class O {
|
|
|
868
868
|
* @param useRouteParam
|
|
869
869
|
*/
|
|
870
870
|
static async analyseInstant(e, t, n, i, o, a = "", s = 0, d = !0, r = !1, h = {}) {
|
|
871
|
-
var z, U, Q, X, Z
|
|
872
|
-
const m =
|
|
873
|
-
e.lng =
|
|
874
|
-
const { route: l, waypoints: y } = o.points, f =
|
|
871
|
+
var z, U, Q, X, Z, $;
|
|
872
|
+
const m = p().valueOf();
|
|
873
|
+
e.lng = B.convertToStdLng(e.lng);
|
|
874
|
+
const { route: l, waypoints: y } = o.points, f = L.calculateSubRoute(e, l);
|
|
875
875
|
if (((z = f[0]) == null ? void 0 : z.length) <= 1)
|
|
876
876
|
return;
|
|
877
877
|
const { v0: C, label: k } = e.sog ? {
|
|
@@ -882,12 +882,12 @@ class O {
|
|
|
882
882
|
v0: i.speed,
|
|
883
883
|
label: "CP"
|
|
884
884
|
/* Cp */
|
|
885
|
-
},
|
|
886
|
-
|
|
885
|
+
}, v = O.assembleProperties(n, i.loadCondition, C, 0), b = y.length ? L.calculateSubWaypoints(e, y) : [];
|
|
886
|
+
b.forEach((q) => q.important = !0);
|
|
887
887
|
const c = {
|
|
888
888
|
from: { ...e },
|
|
889
889
|
route: f,
|
|
890
|
-
waypoints:
|
|
890
|
+
waypoints: b,
|
|
891
891
|
v0: C,
|
|
892
892
|
label: k
|
|
893
893
|
}, w = {
|
|
@@ -895,16 +895,16 @@ class O {
|
|
|
895
895
|
days: [],
|
|
896
896
|
wps: []
|
|
897
897
|
};
|
|
898
|
-
s || (
|
|
899
|
-
let M =
|
|
900
|
-
t =
|
|
898
|
+
s || (L.calculateRouteDistance(f) / i.speed <= 72 ? s = 3 : s = 6);
|
|
899
|
+
let M = L.simplifyRouteToCoordinates(f, b, 0), u = 0, I = 0, S = 0, D = 0;
|
|
900
|
+
t = p(t).utc();
|
|
901
901
|
const Y = t.clone();
|
|
902
902
|
for (; M.length > 0; ) {
|
|
903
|
-
const
|
|
904
|
-
|
|
903
|
+
const q = s - t.hour() % s, V = Math.ceil(t.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, x = await O.speedLoseInHoursStep(
|
|
904
|
+
v,
|
|
905
905
|
t,
|
|
906
906
|
Y,
|
|
907
|
-
|
|
907
|
+
V,
|
|
908
908
|
u,
|
|
909
909
|
M,
|
|
910
910
|
a,
|
|
@@ -912,30 +912,30 @@ class O {
|
|
|
912
912
|
r,
|
|
913
913
|
h
|
|
914
914
|
);
|
|
915
|
-
(U =
|
|
915
|
+
(U = x.from) != null && U.speed && (w.hours.push(x.from), w.wps.push(...x.wps), w.days.push(...x.days)), M = x == null ? void 0 : x.next, M.length || w.hours.push(x == null ? void 0 : x.to), u += Math.round((((Q = x == null ? void 0 : x.to) == null ? void 0 : Q.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
|
|
916
916
|
}
|
|
917
|
-
const
|
|
918
|
-
for (let
|
|
919
|
-
const
|
|
920
|
-
I += (
|
|
917
|
+
const N = w.hours;
|
|
918
|
+
for (let q = 0; q < N.length - 1; q++) {
|
|
919
|
+
const V = p(N[q + 1].eta).diff(N[q].etd, "hour", !0) || 1;
|
|
920
|
+
I += (N[q].wxFactor || 0) * V, S += (N[q].cFactor || 0) * V, D += V;
|
|
921
921
|
}
|
|
922
|
-
(X = w.wps) == null || X.forEach((
|
|
923
|
-
if (
|
|
924
|
-
const
|
|
925
|
-
q
|
|
922
|
+
(X = w.wps) == null || X.forEach((q, V) => {
|
|
923
|
+
if (q.positionTime = p.utc(q.etd || q.eta).unix(), V) {
|
|
924
|
+
const x = w.wps[V - 1], W = q.distanceFromStart - x.distanceFromStart, H = p(q.eta).diff(p(x.etd), "h", !0);
|
|
925
|
+
q.avgSpd = Math.round(W / H * 100) / 100;
|
|
926
926
|
}
|
|
927
|
-
}), c.sample = w;
|
|
928
|
-
const P = w.hours.at(0),
|
|
929
|
-
c.distance = Math.round(
|
|
930
|
-
const { distanceInECA:
|
|
927
|
+
}), w.wps = (Z = w.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((x) => x.positionTime === V.positionTime) || q.push(V), q), []), c.sample = w;
|
|
928
|
+
const P = w.hours.at(0), T = w.hours.at(-1);
|
|
929
|
+
c.distance = Math.round(T.distanceFromStart * 1e4) / 1e4, c.etd = p(P.eta).utc().format(), c.eta = p(T.eta).utc().format(), c.wxFactor = Math.round(I / D * 1e4) / 1e4, c.cFactor = Math.round(S / D * 1e4) / 1e4, c.avgSpeed = Math.round(T.distanceFromStart / D * 1e4) / 1e4, c.totalHrs = Math.round(D * 1e4) / 1e4;
|
|
930
|
+
const { distanceInECA: E, hoursInECA: A, totalDgoConsInECA: R, eca: K } = await this.calculateECA(c, i, h), st = B.roundPrecision(i.fo / 24 * (D - A), 3), at = B.roundPrecision(i.dgo / 24 * D, 3);
|
|
931
931
|
c.extend = {
|
|
932
932
|
eca: K,
|
|
933
|
-
distanceInECA:
|
|
933
|
+
distanceInECA: E,
|
|
934
934
|
hoursInECA: A,
|
|
935
935
|
totalDgoConsInECA: R
|
|
936
|
-
}, c.totalFoCons =
|
|
937
|
-
const
|
|
938
|
-
return
|
|
936
|
+
}, c.totalFoCons = st, c.totalDgoCons = at;
|
|
937
|
+
const tt = p().valueOf() - m, ot = (($ = w == null ? void 0 : w.hours) == null ? void 0 : $.length) || 1;
|
|
938
|
+
return F == null || F.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, tt, ot, Math.round(tt / ot * 1e3) / 1e3), c;
|
|
939
939
|
}
|
|
940
940
|
/**
|
|
941
941
|
* 分段失速分析(最多走hours 小时)
|
|
@@ -951,9 +951,9 @@ class O {
|
|
|
951
951
|
* @param useRouteParam
|
|
952
952
|
*/
|
|
953
953
|
static async analyseInstantWithThreshed(e, t, n, i, o, a, s, d = "", r = 3, h = !0, m = !1, l = {}) {
|
|
954
|
-
var Q, X, Z,
|
|
955
|
-
const y =
|
|
956
|
-
e.lng =
|
|
954
|
+
var Q, X, Z, $, q, V;
|
|
955
|
+
const y = p().valueOf();
|
|
956
|
+
e.lng = B.convertToStdLng(e.lng);
|
|
957
957
|
const { v0: f, label: C } = e.sog ? {
|
|
958
958
|
v0: e.sog,
|
|
959
959
|
label: "Other"
|
|
@@ -962,63 +962,63 @@ class O {
|
|
|
962
962
|
v0: o.speed,
|
|
963
963
|
label: "CP"
|
|
964
964
|
/* Cp */
|
|
965
|
-
}, k = O.assembleProperties(i, o.loadCondition, f, 0),
|
|
966
|
-
if (((Q =
|
|
965
|
+
}, k = O.assembleProperties(i, o.loadCondition, f, 0), v = L.calculateSubRoute(e, a);
|
|
966
|
+
if (((Q = v[0]) == null ? void 0 : Q.length) <= 1)
|
|
967
967
|
return;
|
|
968
|
-
const
|
|
969
|
-
|
|
970
|
-
let c =
|
|
971
|
-
const
|
|
968
|
+
const b = s.length ? L.calculateSubWaypoints(e, s) : [];
|
|
969
|
+
b.forEach((x) => x.important = !0);
|
|
970
|
+
let c = L.simplifyRouteToCoordinates(v, b, 0), w = 0, M = 0, u = 0, I = 0;
|
|
971
|
+
const S = {
|
|
972
972
|
hours: [],
|
|
973
973
|
wps: [],
|
|
974
974
|
days: []
|
|
975
975
|
};
|
|
976
|
-
t =
|
|
976
|
+
t = p(t).utc();
|
|
977
977
|
const D = t.clone();
|
|
978
978
|
for (; c.length > 0; ) {
|
|
979
|
-
const
|
|
980
|
-
let
|
|
981
|
-
|
|
982
|
-
const
|
|
983
|
-
if ((X =
|
|
979
|
+
const x = r - t.hour() % r;
|
|
980
|
+
let W = Math.ceil(t.clone().add(x, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
|
|
981
|
+
W = t.clone().add(W, "h").isSameOrAfter(n) ? n.diff(t, "h", !0) * 1e4 / 1e4 : W;
|
|
982
|
+
const H = await O.speedLoseInHoursStep(k, t, D, W, w, c, d, h, m, l);
|
|
983
|
+
if ((X = H.from) != null && X.speed && (S.hours.push(H.from), H != null && H.wps && S.wps.push(...H.wps), S.days.push(...H.days)), c = H == null ? void 0 : H.next, c.length || S.hours.push(H == null ? void 0 : H.to), w += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !W)
|
|
984
984
|
break;
|
|
985
985
|
}
|
|
986
|
-
(H =
|
|
987
|
-
if (
|
|
988
|
-
const
|
|
989
|
-
|
|
986
|
+
S.wps = ($ = S.wps) == null ? void 0 : $.reduce((x, W) => (x.some((H) => H.etd === W.etd) || x.push(W), x), []), (q = S.wps) == null || q.forEach((x, W) => {
|
|
987
|
+
if (W) {
|
|
988
|
+
const H = S.wps[W - 1], ct = x.distanceFromStart - H.distanceFromStart, dt = p(x.eta).diff(p(H.etd), "h", !0);
|
|
989
|
+
x.avgSpd = Math.round(ct / dt * 100) / 100;
|
|
990
990
|
}
|
|
991
991
|
});
|
|
992
|
-
const Y =
|
|
993
|
-
for (let
|
|
994
|
-
const
|
|
995
|
-
M += Y[
|
|
992
|
+
const Y = S.hours;
|
|
993
|
+
for (let x = 0; x < Y.length - 1; x++) {
|
|
994
|
+
const W = p(Y[x + 1].eta).diff(Y[x].etd, "hour", !0);
|
|
995
|
+
M += Y[x].wxFactor * W, u += Y[x].cFactor * W, I += W;
|
|
996
996
|
}
|
|
997
|
-
const
|
|
998
|
-
sample:
|
|
997
|
+
const N = S.hours.at(0), P = S.hours.at(-1), T = await L.calculateRangeRoute(N, P, v), E = await L.calculateRangeWaypoints(N, P, v, b), A = {
|
|
998
|
+
sample: S,
|
|
999
999
|
distance: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) * 1e4) / 1e4,
|
|
1000
1000
|
// 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
|
|
1001
|
-
etd:
|
|
1002
|
-
eta:
|
|
1001
|
+
etd: p(N.eta).utc().format(),
|
|
1002
|
+
eta: p(P == null ? void 0 : P.eta).utc().format(),
|
|
1003
1003
|
wxFactor: Math.round(M / I * 1e4) / 1e4,
|
|
1004
1004
|
cFactor: Math.round(u / I * 1e4) / 1e4,
|
|
1005
1005
|
avgSpeed: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) / I * 1e4) / 1e4,
|
|
1006
1006
|
totalHrs: Math.round(I * 1e4) / 1e4,
|
|
1007
|
-
from:
|
|
1007
|
+
from: N,
|
|
1008
1008
|
to: P,
|
|
1009
|
-
route:
|
|
1010
|
-
waypoints:
|
|
1009
|
+
route: T,
|
|
1010
|
+
waypoints: E,
|
|
1011
1011
|
v0: f,
|
|
1012
1012
|
label: C
|
|
1013
|
-
}, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA:
|
|
1013
|
+
}, { distanceInECA: R, hoursInECA: K, totalDgoConsInECA: st, eca: at } = await this.calculateECA(A, o, l), it = B.roundPrecision(o.fo / 24 * (I - K), 3), tt = B.roundPrecision(o.dgo / 24 * I, 3);
|
|
1014
1014
|
A.extend = {
|
|
1015
|
-
eca:
|
|
1015
|
+
eca: at,
|
|
1016
1016
|
distanceInECA: R,
|
|
1017
1017
|
hoursInECA: K,
|
|
1018
|
-
totalDgoConsInECA:
|
|
1019
|
-
}, A.totalDgoCons =
|
|
1020
|
-
const z =
|
|
1021
|
-
return
|
|
1018
|
+
totalDgoConsInECA: st
|
|
1019
|
+
}, A.totalDgoCons = tt, A.totalFoCons = it;
|
|
1020
|
+
const z = p().valueOf() - y, U = ((V = S == null ? void 0 : S.hours) == null ? void 0 : V.length) || 1;
|
|
1021
|
+
return F == null || F.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, z, U, Math.round(z / U * 1e3) / 1e3), A;
|
|
1022
1022
|
}
|
|
1023
1023
|
/**
|
|
1024
1024
|
* 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
|
|
@@ -1036,16 +1036,16 @@ class O {
|
|
|
1036
1036
|
* @param options
|
|
1037
1037
|
*/
|
|
1038
1038
|
static async analyseCost(e, t, n, i, o = {}) {
|
|
1039
|
-
var
|
|
1040
|
-
const a =
|
|
1039
|
+
var v, b;
|
|
1040
|
+
const a = p().valueOf(), s = [];
|
|
1041
1041
|
o.meteo2 = o.meteo2 || !0, e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
|
|
1042
|
-
const d =
|
|
1042
|
+
const d = L.calculateRouteDistance(i.route);
|
|
1043
1043
|
let r = 0;
|
|
1044
1044
|
n.forEach((c) => {
|
|
1045
1045
|
const w = Math.ceil(d / c.speed / 24);
|
|
1046
1046
|
r = r < w ? w : r;
|
|
1047
1047
|
}), r = r * 1.3;
|
|
1048
|
-
const h =
|
|
1048
|
+
const h = p.utc(e.etd).add(r ?? 14, "day");
|
|
1049
1049
|
let m = 1;
|
|
1050
1050
|
for (const c of n) {
|
|
1051
1051
|
const w = JSON.parse(JSON.stringify(i.route)), M = JSON.parse(JSON.stringify(i.waypoints)), u = await O.analyseInstantWithThreshed(
|
|
@@ -1062,7 +1062,7 @@ class O {
|
|
|
1062
1062
|
e.useRouteParam,
|
|
1063
1063
|
o
|
|
1064
1064
|
);
|
|
1065
|
-
u && (await O.calculateCost(u, c, e, o), s.push(u),
|
|
1065
|
+
u && (await O.calculateCost(u, c, e, o), s.push(u), F == null || F.info("[%s][L%d-%d] analyse from %s to %s cost: %j", o.requestId, 1, m, e.etd, h.format(), {
|
|
1066
1066
|
cost: u.cost.total,
|
|
1067
1067
|
distance: u.distance,
|
|
1068
1068
|
hours: u.totalHrs,
|
|
@@ -1071,21 +1071,21 @@ class O {
|
|
|
1071
1071
|
}
|
|
1072
1072
|
s.sort((c, w) => c.cost.total - w.cost.total);
|
|
1073
1073
|
const l = s.at(0), y = s.at(1), f = [];
|
|
1074
|
-
if (f.push({ combined: !1, speeds: [l], cost: (
|
|
1075
|
-
const c = l.cost.cp, w = y.cost.cp, M =
|
|
1076
|
-
let
|
|
1077
|
-
|
|
1078
|
-
let D = 2, Y = { combined: !1, speeds: [y], cost: (
|
|
1079
|
-
for (;
|
|
1080
|
-
const P = await O.combinedAnalyse(e, t, h, [c, w], i,
|
|
1081
|
-
if (Y.cost > P.cost ?
|
|
1074
|
+
if (f.push({ combined: !1, speeds: [l], cost: (v = l.cost) == null ? void 0 : v.total }), y) {
|
|
1075
|
+
const c = l.cost.cp, w = y.cost.cp, M = p(l.eta), u = p(l.etd), I = M.diff(u, "days", !0);
|
|
1076
|
+
let S = Math.ceil(I / 2);
|
|
1077
|
+
S = S > 7 ? 7 : S < e.alterStep ? e.alterStep : S;
|
|
1078
|
+
let D = 2, Y = { combined: !1, speeds: [y], cost: (b = y.cost) == null ? void 0 : b.total }, N;
|
|
1079
|
+
for (; S >= e.alterStep; ) {
|
|
1080
|
+
const P = await O.combinedAnalyse(e, t, h, [c, w], i, S, { ...o, level: D });
|
|
1081
|
+
if (Y.cost > P.cost ? N ? (N == null ? void 0 : N.cost) > P.cost && (N = P) : (N = Y, Y = P) : (!N || (N == null ? void 0 : N.cost) > P.cost) && (N = P), S <= e.alterStep)
|
|
1082
1082
|
break;
|
|
1083
|
-
|
|
1083
|
+
S = Math.ceil(S / 2), D += 1;
|
|
1084
1084
|
}
|
|
1085
|
-
f.push(Y),
|
|
1085
|
+
f.push(Y), N && f.push(N);
|
|
1086
1086
|
}
|
|
1087
|
-
const k =
|
|
1088
|
-
return
|
|
1087
|
+
const k = p().valueOf() - a;
|
|
1088
|
+
return F == null || F.info("[%s] analyse elapsed: %d ms", o == null ? void 0 : o.requestId, k), f.sort((c, w) => c.cost - w.cost);
|
|
1089
1089
|
}
|
|
1090
1090
|
/**
|
|
1091
1091
|
* 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
|
|
@@ -1098,11 +1098,11 @@ class O {
|
|
|
1098
1098
|
* @param options
|
|
1099
1099
|
*/
|
|
1100
1100
|
static async combinedAnalyse(e, t, n, i, o, a, s = {}) {
|
|
1101
|
-
s.counter = 1,
|
|
1101
|
+
s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, a);
|
|
1102
1102
|
const d = await O.alternateAnalyse(e, t, n, i, 0, o, a, s), r = d.reduce((l, y) => l + y.cost.total, 0);
|
|
1103
|
-
|
|
1103
|
+
F == null || F.info("[%s][L%d] cost with cpa/cpb turn: %d", s.requestId, s.level, r);
|
|
1104
1104
|
const h = await O.alternateAnalyse(e, t, n, i, 1, o, a, s), m = h.reduce((l, y) => l + y.cost.total, 0);
|
|
1105
|
-
return
|
|
1105
|
+
return F == null || F.info("[%s][L%d] cost with cpb/cpa turn: %d", s.requestId, s.level, m), r < m ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: a } : { combined: !0, cost: Math.round(m * 1e3) / 1e3, speeds: h, step: a };
|
|
1106
1106
|
}
|
|
1107
1107
|
/**
|
|
1108
1108
|
* 基于cp索引,交替计算指定步长下的成本
|
|
@@ -1117,15 +1117,15 @@ class O {
|
|
|
1117
1117
|
*/
|
|
1118
1118
|
static async alternateAnalyse(e, t, n, i, o, a, s, d = {}) {
|
|
1119
1119
|
var l, y;
|
|
1120
|
-
let r =
|
|
1120
|
+
let r = p.utc(e.etd);
|
|
1121
1121
|
const h = { lat: e.lat, lng: e.lng }, m = [];
|
|
1122
1122
|
for (; r.isBefore(n); ) {
|
|
1123
|
-
const f = r.clone().utc().add(s, "day"), C = JSON.parse(JSON.stringify(a.route)), k = JSON.parse(JSON.stringify(a.waypoints)),
|
|
1123
|
+
const f = r.clone().utc().add(s, "day"), C = JSON.parse(JSON.stringify(a.route)), k = JSON.parse(JSON.stringify(a.waypoints)), v = i[o], b = await O.analyseInstantWithThreshed(
|
|
1124
1124
|
h,
|
|
1125
1125
|
r.utc().format(),
|
|
1126
1126
|
f,
|
|
1127
1127
|
t,
|
|
1128
|
-
|
|
1128
|
+
v,
|
|
1129
1129
|
C,
|
|
1130
1130
|
k,
|
|
1131
1131
|
e.meteoVendor,
|
|
@@ -1134,18 +1134,18 @@ class O {
|
|
|
1134
1134
|
e.useRouteParam,
|
|
1135
1135
|
d
|
|
1136
1136
|
);
|
|
1137
|
-
|
|
1137
|
+
b && (await O.calculateCost(b, v, e, d), F == null || F.info(
|
|
1138
1138
|
"[%s][L%d-%d] analyse from %s to %s cost: %j",
|
|
1139
1139
|
d.requestId,
|
|
1140
1140
|
d.level,
|
|
1141
1141
|
d.counter,
|
|
1142
1142
|
r.utc().format(),
|
|
1143
1143
|
f.utc().format(),
|
|
1144
|
-
{ cost:
|
|
1144
|
+
{ cost: b.cost.total, distance: b.distance, hours: b.totalHrs, cp: `${v.speed}/${v.fo}/${v.dgo}` }
|
|
1145
1145
|
)), d.counter = d.counter + 1;
|
|
1146
|
-
const c = (y = (l =
|
|
1146
|
+
const c = (y = (l = b == null ? void 0 : b.sample) == null ? void 0 : l.hours) == null ? void 0 : y.at(-1);
|
|
1147
1147
|
if (c)
|
|
1148
|
-
h.lat = c.lat, h.lng = c.lng, r =
|
|
1148
|
+
h.lat = c.lat, h.lng = c.lng, r = p(c.eta), m.push(b), o = o ? 0 : 1;
|
|
1149
1149
|
else
|
|
1150
1150
|
break;
|
|
1151
1151
|
}
|
|
@@ -1176,17 +1176,17 @@ class O {
|
|
|
1176
1176
|
*/
|
|
1177
1177
|
static async calculateECA(e, t, n = {}) {
|
|
1178
1178
|
var d, r;
|
|
1179
|
-
const i = await
|
|
1179
|
+
const i = await L.intersectInECA(e.route);
|
|
1180
1180
|
let o = 0, a = 0, s = 0;
|
|
1181
1181
|
e.sample.wps.forEach((h) => {
|
|
1182
|
-
h.positionTime =
|
|
1182
|
+
h.positionTime = p.utc(h.etd || h.eta).unix();
|
|
1183
1183
|
});
|
|
1184
1184
|
for (const h of i) {
|
|
1185
1185
|
o += h.distance;
|
|
1186
|
-
const m = await
|
|
1187
|
-
h.in = m, h.out = l, h.totalHrs =
|
|
1186
|
+
const m = await L.deadReckoningTime((d = h.waypoints) == null ? void 0 : d.at(0), e.sample.wps), l = await L.deadReckoningTime((r = h.waypoints) == null ? void 0 : r.at(-1), e.sample.wps);
|
|
1187
|
+
h.in = m, h.out = l, h.totalHrs = B.roundPrecision((l.positionTime - m.positionTime) / 3600, 2), h.totalDgoCons = B.roundPrecision(t.fo / 24 * h.totalHrs, 3), a += h.totalHrs, s += h.totalDgoCons;
|
|
1188
1188
|
}
|
|
1189
|
-
return o =
|
|
1189
|
+
return o = B.roundPrecision(o, 3), a = B.roundPrecision(a, 3), s = B.roundPrecision(s, 3), {
|
|
1190
1190
|
distanceInECA: o,
|
|
1191
1191
|
hoursInECA: a,
|
|
1192
1192
|
totalDgoConsInECA: s,
|
|
@@ -1213,41 +1213,39 @@ class O {
|
|
|
1213
1213
|
}, 0), d = e.reduce((M, u) => {
|
|
1214
1214
|
var I;
|
|
1215
1215
|
return M + (((I = u.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
|
|
1216
|
-
}, 0), r = e.reduce((M, u) => M + u.wxFactor * u.totalHrs / a, 0), h = e.reduce((M, u) => M + u.cFactor * u.totalHrs / a, 0), m = e.reduce((M, u) => M + u.totalFoCons, 0), l = e.reduce((M, u) => M + u.totalDgoCons, 0), y = e.reduce((M, u) => M + u.cost.total, 0), f = e.reduce((M, u) => M + u.cost.hire, 0), C = e.reduce((M, u) => M + u.cost.bunker, 0), k = [],
|
|
1217
|
-
let
|
|
1216
|
+
}, 0), r = e.reduce((M, u) => M + u.wxFactor * u.totalHrs / a, 0), h = e.reduce((M, u) => M + u.cFactor * u.totalHrs / a, 0), m = e.reduce((M, u) => M + u.totalFoCons, 0), l = e.reduce((M, u) => M + u.totalDgoCons, 0), y = e.reduce((M, u) => M + u.cost.total, 0), f = e.reduce((M, u) => M + u.cost.hire, 0), C = e.reduce((M, u) => M + u.cost.bunker, 0), k = [], v = [];
|
|
1217
|
+
let b;
|
|
1218
1218
|
for (const M of e) {
|
|
1219
|
-
|
|
1220
|
-
const u = M.sample.hours, I = M.sample.wps,
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
}), I.at(0).distanceFromPrevious =
|
|
1224
|
-
|
|
1225
|
-
}),
|
|
1226
|
-
|
|
1219
|
+
v.push(...((c = M.extend) == null ? void 0 : c.eca) || []);
|
|
1220
|
+
const u = M.sample.hours, I = M.sample.wps, S = M.sample.days, D = u.at(0);
|
|
1221
|
+
b && (D.distanceFromPrevious = b.distanceFromPrevious, D.distanceFromStart = b.distanceFromStart, u.forEach((T, E) => {
|
|
1222
|
+
E && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1223
|
+
}), I.at(0).distanceFromPrevious = b.distanceFromPrevious, I.at(0).distanceFromStart = b.distanceFromStart, I.forEach((T, E) => {
|
|
1224
|
+
E && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1225
|
+
}), S.at(0).distanceFromPrevious = b.distanceFromPrevious, S.at(0).distanceFromStart = b.distanceFromStart, S.forEach((T, E) => {
|
|
1226
|
+
E && (T.distanceFromStart = T.distanceFromStart + b.distanceFromStart);
|
|
1227
1227
|
})), D.cp = M.cost.cp;
|
|
1228
|
-
const Y = [M.etd, M.eta],
|
|
1229
|
-
|
|
1228
|
+
const Y = [M.etd, M.eta], N = k.findIndex((T) => T.id === D.cp.id);
|
|
1229
|
+
N === -1 ? (D.cp.segment = [Y], k.push(D.cp)) : k[N].segment.push(Y), u.forEach((T) => {
|
|
1230
1230
|
var A;
|
|
1231
|
-
((A = n.hours) == null ? void 0 : A.findIndex((R) => R.eta ===
|
|
1232
|
-
}), I.forEach((
|
|
1231
|
+
((A = n.hours) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.hours.push(T);
|
|
1232
|
+
}), I.forEach((T) => {
|
|
1233
1233
|
var A;
|
|
1234
|
-
((A = n.wps) == null ? void 0 : A.findIndex((R) => R.eta ===
|
|
1235
|
-
}),
|
|
1234
|
+
((A = n.wps) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.wps.push(T);
|
|
1235
|
+
}), S.forEach((T) => {
|
|
1236
1236
|
var A;
|
|
1237
|
-
((A = n == null ? void 0 : n.days) == null ? void 0 : A.findIndex((R) => R.eta ===
|
|
1237
|
+
((A = n == null ? void 0 : n.days) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && n.days.push(T);
|
|
1238
1238
|
});
|
|
1239
|
-
const P = (w = n.wps) == null ? void 0 : w.findIndex((
|
|
1240
|
-
P === -1 ? n.wps.push(D) : n.wps[P] = D,
|
|
1239
|
+
const P = (w = n.wps) == null ? void 0 : w.findIndex((T) => T.eta === D.eta);
|
|
1240
|
+
P === -1 ? n.wps.push(D) : n.wps[P] = D, b = u.at(-1);
|
|
1241
1241
|
}
|
|
1242
1242
|
return n.wps.sort((M, u) => {
|
|
1243
|
-
|
|
1243
|
+
p(M.etd).unix() - p(u.etd).unix();
|
|
1244
1244
|
}), n.wps.forEach((M, u) => {
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
M.avgSpd = Y;
|
|
1250
|
-
}
|
|
1245
|
+
let I;
|
|
1246
|
+
if (u === 0 ? I = n.wps.at(1) : I = n.wps.at(u + 1), I) {
|
|
1247
|
+
const S = I.distanceFromStart - (M.distanceFromStart || 0), D = p(I.etd || I.eta).diff(p(M.etd || I.eta), "hour", !0), Y = Math.round(S / D * 100) / 100;
|
|
1248
|
+
M.avgSpd = Y;
|
|
1251
1249
|
}
|
|
1252
1250
|
}), {
|
|
1253
1251
|
sample: n,
|
|
@@ -1271,7 +1269,7 @@ class O {
|
|
|
1271
1269
|
},
|
|
1272
1270
|
extend: {
|
|
1273
1271
|
cps: k,
|
|
1274
|
-
eca:
|
|
1272
|
+
eca: v,
|
|
1275
1273
|
distanceInECA: Math.round(o * 1e4) / 1e4,
|
|
1276
1274
|
hoursInECA: Math.round(s * 1e3) / 1e3,
|
|
1277
1275
|
totalDgoConsInECA: Math.round(d * 1e3) / 1e3,
|
|
@@ -1281,16 +1279,16 @@ class O {
|
|
|
1281
1279
|
}
|
|
1282
1280
|
}
|
|
1283
1281
|
export {
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1282
|
+
et as AISImpl,
|
|
1283
|
+
yt as AlertHelper,
|
|
1284
|
+
mt as AlertLevel,
|
|
1285
|
+
jt as HifleetImpl,
|
|
1286
|
+
pt as LoadCondition,
|
|
1287
|
+
Nt as MyShipImpl,
|
|
1288
|
+
xt as MyVesselImpl,
|
|
1289
|
+
Et as ShipxyImpl,
|
|
1292
1290
|
O as SpeedHelper,
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1291
|
+
wt as SpeedLabel,
|
|
1292
|
+
gt as VesselTag,
|
|
1293
|
+
Tt as alertHelper
|
|
1296
1294
|
};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(D,Y){typeof exports=="object"&&typeof module<"u"?Y(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"],Y):(D=typeof globalThis<"u"?globalThis:D||self,Y(D["idm-plugin-rabbitmq"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,Y,G,v,q,ot,it){"use strict";var wt=Object.defineProperty;var It=(D,Y,G)=>Y in D?wt(D,Y,{enumerable:!0,configurable:!0,writable:!0,value:G}):D[Y]=G;var z=(D,Y,G)=>(It(D,typeof Y!="symbol"?Y+"":Y,G),G);let p;try{p=G.getLogger("vessel")}catch{}finally{}class U{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class mt extends U{constructor(t,o){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await Y.post(o,i).json();p==null||p.info("[%s] fetch access token from: %s - %j",t.requestId,o,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 realTimePosition(t,o={}){var l,m,h;(!this.token||v().diff(v(this.token.issuedAt),"seconds")>((l=this.token)==null?void 0:l.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:{mmsi:t}};p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const a=await Y.get(i,n).json();if(a.code)return p==null||p.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:a.message,status:a.status,code:a.code}),a;const s=a.data;for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const d=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName,imo:s.imo,callSign:s.callsign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,n,a=!0,s={}){(!this.token||v().diff(v(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(t,s),r=v(o),l=v(i),m=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,n,m,s),r.add(30,"day");return await this.trajectoryIn30Day(t,r,l,d,n,m,s),m}async trajectoryIn30Day(t,o,i,n,a,s,d={}){var f,j,k,g,b;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,l);const m=await Y.post(r,l).json();if(m.code)return p==null||p.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:m.message,status:m.status,code:m.code}),m;let h=-1;const y=v(`${(g=(k=m.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(b=m.data)==null||b.forEach(c=>{for(const P in c)!isNaN(c[P])&&Number(c[P])!==1/0&&(c[P]=Number(c[P]));const w=v(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),M=c.status,{labelCn:u,labelEn:I}=this.parseStatus(M),F={mmsi:c.mmsi,imo:n==null?void 0:n.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:M,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?v(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:w.unix(),labelCn:u,labelEn:I,method:"trajectory",vendor:"myVessel",utc:w.utc().format()},N=Math.floor(w.diff(y,"minute",!0)/(a||1));N!==h&&(h=N,s.push(F))}),s}}class yt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},a=await Y.post(i,n).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const s=a==null?void 0:a.list;if(!s)return p==null||p.warn("[%s] fetch realtime position failed: %j",o.requestId,i,a),a;for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:l}=this.parseStatus(d),m=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,positionTime:m.unix(),utc:m.utc().format(),status:d,labelCn:r,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,o={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await Y.post(i,n).json();p==null||p.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]);for(const d in a)!isNaN(a[d])&&Number(a[d])!==1/0&&(a[d]=Number(a[d]));const s={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr,type:a.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await Y.post(i,n).json(),p==null||p.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]),a&&(s.deadweight=Number(a.dwt)),s}async suggest(t,o={}){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"}},a=await Y.post(i,n).json();p==null||p.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,n);const s=[];for(const d of a)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(t,o,i,n,a=!0,s={}){var c,w,M;const d=await this.realTimePosition(t,s);let r=v(o);const l=v(i),m=v();if(a){let u=l.diff(r,"d",!0);u<0?r=l.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=l.clone().subtract(80,"d"),u=m.diff(l,"d",!0),l.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},y="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await Y.get(y,h).json();p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,y,h);let j;f&&(j=((w=(c=f.ships)==null?void 0:c.offors)==null?void 0:w.ship)||[],j.length||p==null||p.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const k=[];let g=-1;const b=v(`${(M=j==null?void 0:j[0])==null?void 0:M.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of j){for(const T in u)!isNaN(u[T])&&Number(u[T])!==1/0&&(u[T]=Number(u[T]));const I=v(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:N}=this.parseStatus(u.status),P={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:I.unix(),utc:I.utc().format(),status:u.status,labelCn:N,labelEn:F,method:"trajectory",vendor:"hifleet"},H=Math.floor(I.diff(b,"minute",!0)/(n||1));H!==g&&(g=H,k.push(P))}return k}}class Mt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",a=await Y.get(n,i).json();if(p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,n,i),(a==null?void 0:a.status)!==0)return a;const s=a.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),l=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:l.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,n,a=!0,s={}){var b;const d=await this.realTimePosition(t,s),r=v(o),l=v(i),m="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:l.unix()}},y=await Y.get(m,h).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",s.requestId,m,h),(y==null?void 0:y.status)!==0)return y;const f=y==null?void 0:y.points,j=[],k=v.unix((b=f[0])==null?void 0:b.utc);let g=-1;for(const c of f){const w=v.unix(c.utc),M={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(c.sog*3600/1e3/1852*100)/100,cog:Math.round(c.cog/100*100)/100,lat:Math.round(c.lat/1e6*1e5)/1e5,lng:Math.round(c.lon/1e6*1e5)/1e5,positionTime:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(w.diff(k,"minute",!0)/(n||1));u!==g&&(g=u,j.push(M))}return j}}class pt extends U{constructor(t){super();z(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await Y.post(n,i).json();return p==null||p.info("[%s] fetch ship id from: %s - %j",o.requestId,n,i),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",a=await Y.post(n,i).json();if(p==null||p.info("[%s] fetch ship info from: %s - %j",o.requestId,n,i),a.code!=="0")return a;const s=a.data;let d=s.imo;return t==="407170"&&(d="9198379",p==null||p.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),n=await this.getShipInfo(i,o),a={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await Y.post(s,a).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,a);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:l,labelEn:m}=await this.parseStatus(r.aisNavStatus),h=v.unix(r.posTime);return{...n,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:h.utc().format(),status:r.aisNavStatus,labelEn:m,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,o,i,n,a=!0,s={}){const d=v(o),r=v(i),l=await this.getShipId(t),m=await this.getShipInfo(l),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(l,d.unix(),d.add(30,"day").unix(),m,t,n,h);return await this.trajectoryIn30Day(l,d.unix(),r.unix(),m,t,n,h),h}async trajectoryIn30Day(t,o,i,n,a,s,d,r={}){var k;const l={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},m="https://api3.myships.com/sp/ships/position/history",h=await Y.post(m,l).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",r.requestId,m,l),h.code!=="0")return p==null||p.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const y=h.data;for(const g in y)!isNaN(y[g])&&Number(y[g])!==1/0&&(y[g]=Number(y[g]));const f=v.unix((k=y[0])==null?void 0:k.posTime);let j=-1;for(const g of y){const b=v.unix(g.posTime),c={imo:n==null?void 0:n.imo,mmsi:a,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"myship"},w=Math.floor(b.diff(f,"minute",!0)/(s||1));w!==j&&(j=w,d.push(c))}return d}}let B;try{B=G.getLogger("vessel")}catch{}finally{}var rt=(L=>(L.NOTICE="NOTICE",L.WARN="WARN",L.HEAVY="HEAVY",L.SEVERE="SEVERE",L.ERROR="ERROR",L.FATAL="FATAL",L))(rt||{});class ct{parsePrinciple(e,t={}){var s,d,r;B==null||B.info("[%s] parse rule: %s",t.requestId,e);const o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const a={};for(let l=0;l<(n==null?void 0:n.length);l++){const m=(r=(d=n[l].match(o))==null?void 0:d[0])==null?void 0:r.split("],");if(l===0&&!m)a.scope=n[0];else if(m)for(let h=0,y=m.length;h<y;h++){const f=this.parseRule(m[h]);f&&(a[f.level]?f.key?a[f.level][f==null?void 0:f.key]=f:a[f.level]=f:f.key?a[f.level]={[f==null?void 0:f.key]:f}:a[f.level]=f)}}return a}parseRule(e,t={}){var a;B==null||B.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(a=e==null?void 0:e.match(o))==null?void 0:a[0],n=i==null?void 0:i.split(",");if(n)return{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:Number(n[3]),key:n[4]}}checkWeather(e,t,o={}){var f,j,k,g,b,c,w,M,u,I,F,N,P,H,T;let i=0,n=0,a=0,s=0;const d=Math.round(((j=(f=t==null?void 0:t.SEVERE)==null?void 0:f.sigWave)==null?void 0:j.number)*1.6*100)/100,r=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,l=(c=(b=t==null?void 0:t.HEAVY)==null?void 0:b.sigWave)==null?void 0:c.number,m=Math.round((((M=(w=t==null?void 0:t.SEVERE)==null?void 0:w.wind)==null?void 0:M.number)+2)*100)/100,h=(I=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:I.number,y=(N=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:N.number;for(let E=0;E<(e==null?void 0:e.length);E++){const C=e[E],A=(H=(P=C==null?void 0:C.meteo)==null?void 0:P.wave)==null?void 0:H.sig,V=(T=C==null?void 0:C.meteo)==null?void 0:T.wind,K=E?v(C.eta).diff(v(e[E-1].eta),"hour",!0):0;s=K>s?K:s,B==null||B.info("[%s] check sig.wave: %j",o.requestId,{...A,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}),(A==null?void 0:A.height)>=d?C.isDangerous=!0:(A==null?void 0:A.height)>=r?C.isSevere=!0:(A==null?void 0:A.height)>=l&&(C.isHeavy=!0),B==null||B.info("[%s] check wind: %j",o.requestId,{...V,dgThd4Wd:m,svThd4Wd:h,hvThd4Wd:y}),(V==null?void 0:V.scale)>=m?(C.isDangerous=!0,delete C.isSevere,delete C.isHeavy):(V==null?void 0:V.scale)>h?(C.isDangerous||(C.isSevere=!0),delete C.isHeavy):(V==null?void 0:V.scale)===y&&!C.isDangerous&&!C.isSevere&&(C.isHeavy=!0),i+=C.isDangerous?K:0,n+=C.isSevere?K:0,a+=C.isHeavy?K:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,a=Math.round(a*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:n,heavy:a,step:s<3?3:s,wind:{dgThd4Wd:m,svThd4Wd:h,hvThd4Wd:y},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}}}}const vt=new ct;let S;try{S=G.getLogger("vessel")}catch{}finally{}const bt=new ot.MeteoHelper2("",!0);var dt=(L=>(L.common="common",L.container="container",L.tugs="tugs",L))(dt||{}),ut=(L=>(L.Ballast="Ballast",L.Laden="Laden",L))(ut||{}),lt=(L=>(L.Cp="CP",L.Perf="Basis",L.Instruct="Other",L))(lt||{});class R{static blockCoefficient(e,t,o,i){let n=Math.round(e/(t*o*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const a=[.55,.6,.65,.7,.75,.8,.85],s=a.map(d=>Math.abs(d-n));return a[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(a=i[e]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let n;return o==="container"?n=.7*i+Math.pow(i,6.5)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)):n=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,a=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,r=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:a,breadthMoulded:s,displacement:Math.round((d/1.025+a*s*n*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",n=2,a=!0,s=!1,d={}){let r;if(t.velocity&&s&&(e.speed=q.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let l;if(d.meteo2)try{const f=await bt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[j]=it.Meteo2Assist.pickHourly(f,o);l=it.Meteo2Assist.toLegacy(j)}catch(f){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},f)}else l=await ot.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const m=R.weatherFactor(e,l),h=R.currentFactor(e.bearing,l==null?void 0:l.current,n),y=Math.round((e.speed*1.943844+m+h)*100)/100;r={meteo:{...l},wxFactor:m,cFactor:h,speed:t.velocity&&s?t.velocity:y<0?1:y,eta:o.utc().format(),etd:o.utc().format()}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round((e.speed*1.943844+0+0)*100)/100,eta:o.utc().format(),etd:o.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(e,t,o,i,n,a,s="",d=!0,r=!1,l={}){t.utc();const m=t.clone().add(14,"days"),h=[],y=[];let f=0,j=0,k,g;for(let b=0;b<a.length-1;b++){let c=a[b];c.distanceFromStart=Math.round((n+j)*1e4)/1e4;const w=a[b+1];if(e.bearing=q.LaneHelper.calculateBearing(c,w,!w.gcToPrevious),c.bearing=e.bearing,c.suspend&&r){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const I=c.suspend-c.elapsed;if(i-f>I)i=i-f-I,t.add(I,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,t.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=j,{etd:t,from:g||c,to:c,next:a.filter(F=>F),wps:h,days:y}}else c.suspend=0;d=t.isAfter(m)?!1:d,c=await R.speedLoseAt(e,c,t,s,0,d,r,l),g=g||c,c.important&&h.push(c),t.isSameOrAfter(o)&&(y.push(c),o.add(24,"hour"));const M=q.LaneHelper.calculateDistance(c,w,!w.gcToPrevious);let u=Math.round(M/g.speed*1e5)/1e5;if(f+u<i){if(f+=u,t.add(u,"hour"),delete a[b],S==null||S.debug(`[%s] go to %j from %j with ${M}nm, and cost ${u} hours`,l.requestId,{lat:w.lat,lng:w.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),j+=M,a.filter(I=>I).length<=1){k=w,k.eta=t.utc().format(),k.distanceFromPrevious=M,k.distanceFromStart=Math.round((n+j)*1e4)/1e4,h.push(k),delete a[b+1];break}}else{u=i-f,t.add(u,"hour");const I=q.LngLatHelper.roundPrecision(g.speed*u,5);k=q.LaneHelper.calculateCoordinate(c,e.bearing,I,"nauticalmiles",!w.gcToPrevious),k.eta=t.utc().format(),a[b]=k,S==null||S.debug(`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,l.requestId,{lat:k.lat,lng:k.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),j+=I,k.distanceFromPrevious=Math.round(j*1e4)/1e4,k.distanceFromStart=Math.round((n+j)*1e4)/1e4;break}}return{etd:t,from:g,to:k,next:a.filter(b=>b),wps:h,days:y}}static currentFactor(e,t,o=0){const i=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return o&2?n=Math.ceil(n*100)/100:o&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t){var m,h,y,f,j,k,g;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=R.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=R.froudeNumber(e.speed,e.lbp),n=R.amendFactor(o,i,e.loadCondition);let a=Math.abs(e.bearing%360-(((m=t==null?void 0:t.wind)==null?void 0:m.degree)%360||0));a=a>180?360-a:a;const s=R.directionFactor(a,(h=t==null?void 0:t.wind)==null?void 0:h.scale),d=R.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(y=t==null?void 0:t.wind)==null?void 0:y.scale);let r=s*n*d/100*e.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),a=Math.abs(e.bearing%360-(((j=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:j.degree)%360||0));const l=R.waveHeightFactor(((g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.height)??1,a);return S==null||S.debug("wave wx factor = %d",l),r=r*.4+l,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(e,t,o,i,n,a="",s=0,d=!0,r=!1,l={}){var Q,X,Z,$,tt;const m=v().valueOf();e.lng=q.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:y}=n.points,f=q.LaneHelper.calculateSubRoute(e,h);if(((Q=f[0])==null?void 0:Q.length)<=1)return;const{v0:j,label:k}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},g=R.assembleProperties(o,i.loadCondition,j,0),b=y.length?q.LaneHelper.calculateSubWaypoints(e,y):[];b.forEach(W=>W.important=!0);const c={from:{...e},route:f,waypoints:b,v0:j,label:k},w={hours:[],days:[],wps:[]};s||(q.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let M=q.LaneHelper.simplifyRouteToCoordinates(f,b,0),u=0,I=0,F=0,N=0;t=v(t).utc();const P=t.clone();for(;M.length>0;){const W=s-t.hour()%s,_=Math.ceil(t.clone().add(W,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,x=await R.speedLoseInHoursStep(g,t,P,_,u,M,a,d,r,l);(X=x.from)!=null&&X.speed&&(w.hours.push(x.from),w.wps.push(...x.wps),w.days.push(...x.days)),M=x==null?void 0:x.next,M.length||w.hours.push(x==null?void 0:x.to),u+=Math.round((((Z=x==null?void 0:x.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const H=w.hours;for(let W=0;W<H.length-1;W++){const _=v(H[W+1].eta).diff(H[W].etd,"hour",!0)||1;I+=(H[W].wxFactor||0)*_,F+=(H[W].cFactor||0)*_,N+=_}($=w.wps)==null||$.forEach((W,_)=>{if(W.positionTime=v.utc(W.etd||W.eta).unix(),_){const x=w.wps[_-1],J=W.distanceFromStart-x.distanceFromStart,O=v(W.eta).diff(v(x.etd),"h",!0);O<.5?W.avgSpd=x.speed:W.avgSpd=Math.round(J/O*100)/100}}),c.sample=w;const T=w.hours.at(0),E=w.hours.at(-1);c.distance=Math.round(E.distanceFromStart*1e4)/1e4,c.etd=v(T.eta).utc().format(),c.eta=v(E.eta).utc().format(),c.wxFactor=Math.round(I/N*1e4)/1e4,c.cFactor=Math.round(F/N*1e4)/1e4,c.avgSpeed=Math.round(E.distanceFromStart/N*1e4)/1e4,c.totalHrs=Math.round(N*1e4)/1e4;const{distanceInECA:C,hoursInECA:A,totalDgoConsInECA:V,eca:K}=await this.calculateECA(c,i,l),st=q.LngLatHelper.roundPrecision(i.fo/24*(N-A),3),at=q.LngLatHelper.roundPrecision(i.dgo/24*N,3);c.extend={eca:K,distanceInECA:C,hoursInECA:A,totalDgoConsInECA:V},c.totalFoCons=st,c.totalDgoCons=at;const et=v().valueOf()-m,nt=((tt=w==null?void 0:w.hours)==null?void 0:tt.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,et,nt,Math.round(et/nt*1e3)/1e3),c}static async analyseInstantWithThreshed(e,t,o,i,n,a,s,d="",r=3,l=!0,m=!1,h={}){var Z,$,tt,W,_;const y=v().valueOf();e.lng=q.LngLatHelper.convertToStdLng(e.lng);const{v0:f,label:j}=e.sog?{v0:e.sog,label:"Other"}:{v0:n.speed,label:"CP"},k=R.assembleProperties(i,n.loadCondition,f,0),g=q.LaneHelper.calculateSubRoute(e,a);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const b=s.length?q.LaneHelper.calculateSubWaypoints(e,s):[];b.forEach(x=>x.important=!0);let c=q.LaneHelper.simplifyRouteToCoordinates(g,b,0),w=0,M=0,u=0,I=0;const F={hours:[],wps:[],days:[]};t=v(t).utc();const N=t.clone();for(;c.length>0;){const x=r-t.hour()%r;let J=Math.ceil(t.clone().add(x,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;J=t.clone().add(J,"h").isSameOrAfter(o)?o.diff(t,"h",!0)*1e4/1e4:J;const O=await R.speedLoseInHoursStep(k,t,N,J,w,c,d,l,m,h);if(($=O.from)!=null&&$.speed&&(F.hours.push(O.from),O!=null&&O.wps&&F.wps.push(...O.wps),F.days.push(...O.days)),c=O==null?void 0:O.next,c.length||F.hours.push(O==null?void 0:O.to),w+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!J)break}(W=F.wps)==null||W.forEach((x,J)=>{if(J){const O=F.wps[J-1],gt=x.distanceFromStart-O.distanceFromStart,ft=v(x.eta).diff(v(O.etd),"h",!0);ft<.5?x.avgSpd=O.speed:x.avgSpd=Math.round(gt/ft*100)/100}});const P=F.hours;for(let x=0;x<P.length-1;x++){const J=v(P[x+1].eta).diff(P[x].etd,"hour",!0);M+=P[x].wxFactor*J,u+=P[x].cFactor*J,I+=J}const H=F.hours.at(0),T=F.hours.at(-1),E=await q.LaneHelper.calculateRangeRoute(H,T,g),C=await q.LaneHelper.calculateRangeWaypoints(H,T,g,b),A={sample:F,distance:Math.round(((T==null?void 0:T.distanceFromStart)||0)*1e4)/1e4,etd:v(H.eta).utc().format(),eta:v(T==null?void 0:T.eta).utc().format(),wxFactor:Math.round(M/I*1e4)/1e4,cFactor:Math.round(u/I*1e4)/1e4,avgSpeed:Math.round(((T==null?void 0:T.distanceFromStart)||0)/I*1e4)/1e4,totalHrs:Math.round(I*1e4)/1e4,from:H,to:T,route:E,waypoints:C,v0:f,label:j},{distanceInECA:V,hoursInECA:K,totalDgoConsInECA:st,eca:at}=await this.calculateECA(A,n,h),ht=q.LngLatHelper.roundPrecision(n.fo/24*(I-K),3),et=q.LngLatHelper.roundPrecision(n.dgo/24*I,3);A.extend={eca:at,distanceInECA:V,hoursInECA:K,totalDgoConsInECA:st},A.totalDgoCons=et,A.totalFoCons=ht;const Q=v().valueOf()-y,X=((_=F==null?void 0:F.hours)==null?void 0:_.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,Q,X,Math.round(Q/X*1e3)/1e3),A}static async analyseCost(e,t,o,i,n={}){var g,b;const a=v().valueOf(),s=[];n.meteo2=n.meteo2||!0,e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const d=q.LaneHelper.calculateRouteDistance(i.route);let r=0;o.forEach(c=>{const w=Math.ceil(d/c.speed/24);r=r<w?w:r}),r=r*1.3;const l=v.utc(e.etd).add(r??14,"day");let m=1;for(const c of o){const w=JSON.parse(JSON.stringify(i.route)),M=JSON.parse(JSON.stringify(i.waypoints)),u=await R.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,l,t,c,w,M,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);u&&(await R.calculateCost(u,c,e,n),s.push(u),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,m,e.etd,l.format(),{cost:u.cost.total,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),m++}s.sort((c,w)=>c.cost.total-w.cost.total);const h=s.at(0),y=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(g=h.cost)==null?void 0:g.total}),y){const c=h.cost.cp,w=y.cost.cp,M=v(h.eta),u=v(h.etd),I=M.diff(u,"days",!0);let F=Math.ceil(I/2);F=F>7?7:F<e.alterStep?e.alterStep:F;let N=2,P={combined:!1,speeds:[y],cost:(b=y.cost)==null?void 0:b.total},H;for(;F>=e.alterStep;){const T=await R.combinedAnalyse(e,t,l,[c,w],i,F,{...n,level:N});if(P.cost>T.cost?H?(H==null?void 0:H.cost)>T.cost&&(H=T):(H=P,P=T):(!H||(H==null?void 0:H.cost)>T.cost)&&(H=T),F<=e.alterStep)break;F=Math.ceil(F/2),N+=1}f.push(P),H&&f.push(H)}const k=v().valueOf()-a;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),f.sort((c,w)=>c.cost-w.cost)}static async combinedAnalyse(e,t,o,i,n,a,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,a);const d=await R.alternateAnalyse(e,t,o,i,0,n,a,s),r=d.reduce((h,y)=>h+y.cost.total,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %d",s.requestId,s.level,r);const l=await R.alternateAnalyse(e,t,o,i,1,n,a,s),m=l.reduce((h,y)=>h+y.cost.total,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %d",s.requestId,s.level,m),r<m?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:a}:{combined:!0,cost:Math.round(m*1e3)/1e3,speeds:l,step:a}}static async alternateAnalyse(e,t,o,i,n,a,s,d={}){var h,y;let r=v.utc(e.etd);const l={lat:e.lat,lng:e.lng},m=[];for(;r.isBefore(o);){const f=r.clone().utc().add(s,"day"),j=JSON.parse(JSON.stringify(a.route)),k=JSON.parse(JSON.stringify(a.waypoints)),g=i[n],b=await R.analyseInstantWithThreshed(l,r.utc().format(),f,t,g,j,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,d);b&&(await R.calculateCost(b,g,e,d),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,r.utc().format(),f.utc().format(),{cost:b.cost.total,distance:b.distance,hours:b.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),d.counter=d.counter+1;const c=(y=(h=b==null?void 0:b.sample)==null?void 0:h.hours)==null?void 0:y.at(-1);if(c)l.lat=c.lat,l.lng=c.lng,r=v(c.eta),m.push(b),n=n?0:1;else break}return m}static async calculateCost(e,t,o,i={}){var n;if(e){const a=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,s=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,d=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((a+s+d)*1e3)/1e3,hire:a,bunker:Math.round((s+d)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,o={}){var d,r;const i=await q.LaneHelper.intersectInECA(e.route);let n=0,a=0,s=0;e.sample.wps.forEach(l=>{l.positionTime=v.utc(l.etd||l.eta).unix()});for(const l of i){n+=l.distance;const m=await q.LaneHelper.deadReckoningTime((d=l.waypoints)==null?void 0:d.at(0),e.sample.wps),h=await q.LaneHelper.deadReckoningTime((r=l.waypoints)==null?void 0:r.at(-1),e.sample.wps);l.in=m,l.out=h,l.totalHrs=q.LngLatHelper.roundPrecision((h.positionTime-m.positionTime)/3600,2),l.totalDgoCons=q.LngLatHelper.roundPrecision(t.fo/24*l.totalHrs,3),a+=l.totalHrs,s+=l.totalDgoCons}return n=q.LngLatHelper.roundPrecision(n,3),a=q.LngLatHelper.roundPrecision(a,3),s=q.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:a,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(e,t={}){var c,w;const o={hours:[],wps:[],days:[]},i=e.reduce((M,u)=>M+u.distance,0),n=e.reduce((M,u)=>{var I;return M+(((I=u.extend)==null?void 0:I.distanceInECA)||0)},0),a=e.reduce((M,u)=>M+u.totalHrs,0),s=e.reduce((M,u)=>{var I;return M+(((I=u.extend)==null?void 0:I.hoursInECA)||0)},0),d=e.reduce((M,u)=>{var I;return M+(((I=u.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),r=e.reduce((M,u)=>M+u.wxFactor*u.totalHrs/a,0),l=e.reduce((M,u)=>M+u.cFactor*u.totalHrs/a,0),m=e.reduce((M,u)=>M+u.totalFoCons,0),h=e.reduce((M,u)=>M+u.totalDgoCons,0),y=e.reduce((M,u)=>M+u.cost.total,0),f=e.reduce((M,u)=>M+u.cost.hire,0),j=e.reduce((M,u)=>M+u.cost.bunker,0),k=[],g=[];let b;for(const M of e){g.push(...((c=M.extend)==null?void 0:c.eca)||[]);const u=M.sample.hours,I=M.sample.wps,F=M.sample.days,N=u.at(0);b&&(N.distanceFromPrevious=b.distanceFromPrevious,N.distanceFromStart=b.distanceFromStart,u.forEach((E,C)=>{C&&(E.distanceFromStart=E.distanceFromStart+b.distanceFromStart)}),I.at(0).distanceFromPrevious=b.distanceFromPrevious,I.at(0).distanceFromStart=b.distanceFromStart,I.forEach((E,C)=>{C&&(E.distanceFromStart=E.distanceFromStart+b.distanceFromStart)}),F.at(0).distanceFromPrevious=b.distanceFromPrevious,F.at(0).distanceFromStart=b.distanceFromStart,F.forEach((E,C)=>{C&&(E.distanceFromStart=E.distanceFromStart+b.distanceFromStart)})),N.cp=M.cost.cp;const P=[M.etd,M.eta],H=k.findIndex(E=>E.id===N.cp.id);H===-1?(N.cp.segment=[P],k.push(N.cp)):k[H].segment.push(P),u.forEach(E=>{var A;((A=o.hours)==null?void 0:A.findIndex(V=>V.eta===E.eta))===-1&&o.hours.push(E)}),I.forEach(E=>{var A;((A=o.wps)==null?void 0:A.findIndex(V=>V.eta===E.eta))===-1&&o.wps.push(E)}),F.forEach(E=>{var A;((A=o==null?void 0:o.days)==null?void 0:A.findIndex(V=>V.eta===E.eta))===-1&&o.days.push(E)});const T=(w=o.wps)==null?void 0:w.findIndex(E=>E.eta===N.eta);T===-1?o.wps.push(N):o.wps[T]=N,b=u.at(-1)}return o.wps.sort((M,u)=>{v(M.etd).unix()-v(u.etd).unix()}),o.wps.forEach((M,u)=>{if(!M.avgSpd){let I;if(u===0?I=o.wps.at(1):I=o.wps.at(u+1),I){const F=I.distanceFromStart-(M.distanceFromStart||0),N=v(I.etd||I.eta).diff(v(M.etd||I.eta),"hour",!0),P=Math.round(F/N*100)/100;M.avgSpd=P}}}),{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(i/a*1e3)/1e3,wxFactor:Math.round(r/a*1e3)/1e3,cFactor:Math.round(l/a*1e3)/1e3,totalFoCons:Math.round(m*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(y*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e4)/1e4,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:e}}}}D.AISImpl=U,D.AlertHelper=ct,D.AlertLevel=rt,D.HifleetImpl=yt,D.LoadCondition=ut,D.MyShipImpl=pt,D.MyVesselImpl=mt,D.ShipxyImpl=Mt,D.SpeedHelper=R,D.SpeedLabel=lt,D.VesselTag=dt,D.alertHelper=vt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(D,Y){typeof exports=="object"&&typeof module<"u"?Y(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"],Y):(D=typeof globalThis<"u"?globalThis:D||self,Y(D["idm-plugin-rabbitmq"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,Y,G,w,q,it,rt){"use strict";var It=Object.defineProperty;var St=(D,Y,G)=>Y in D?It(D,Y,{enumerable:!0,configurable:!0,writable:!0,value:G}):D[Y]=G;var z=(D,Y,G)=>(St(D,typeof Y!="symbol"?Y+"":Y,G),G);let M;try{M=G.getLogger("vessel")}catch{}finally{}class U{parseStatus(e){let t,o;switch(e){case 0:t="在航(主机推动)",o="The engine is in use";break;case 1:t="锚泊",o="Anchored";break;case 2:t="失控",o="Not operated";break;case 3:t="操纵受限",o="Limited airworthiness";break;case 4:t="吃水受限",o="Limited by ship's draft";break;case 5:t="靠泊",o="Mooring";break;case 6:t="搁浅",o="Stranded";break;case 7:t="捕捞作业",o="Engaged in fishing";break;case 8:t="靠帆船提供动力",o="Sailing";break;default:t="未定义",o="Undefined"}return{labelCn:t,labelEn:o}}}class mt extends U{constructor(t,o){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=t,this.clientSecret=o}async authToken(t={}){const o="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await Y.post(o,i).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,o,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:w().utc().format()})}async realTimePosition(t,o={}){var l,m,h;(!this.token||w().diff(w(this.token.issuedAt),"seconds")>((l=this.token)==null?void 0:l.expiresIn)-300)&&await this.authToken(o);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(m=this.token)==null?void 0:m.tokenType} ${(h=this.token)==null?void 0:h.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const a=await Y.get(i,n).json();if(a.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",o.requestId,i,{message:a.message,status:a.status,code:a.code}),a;const s=a.data;for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const d=w(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName,imo:s.imo,callSign:s.callsign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.dest,positionTime:d.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,o,i,n,a=!0,s={}){(!this.token||w().diff(w(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(t,s),r=w(o),l=w(i),m=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,n,m,s),r.add(30,"day");return await this.trajectoryIn30Day(t,r,l,d,n,m,s),m}async trajectoryIn30Day(t,o,i,n,a,s,d={}){var f,j,k,g,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(j=this.token)==null?void 0:j.accessToken}`},json:{mmsi:t,startTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,l);const m=await Y.post(r,l).json();if(m.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:m.message,status:m.status,code:m.code}),m;let h=-1;const y=w(`${(g=(k=m.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=m.data)==null||v.forEach(c=>{for(const P in c)!isNaN(c[P])&&Number(c[P])!==1/0&&(c[P]=Number(c[P]));const b=w(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),p=c.status,{labelCn:u,labelEn:I}=this.parseStatus(p),F={mmsi:c.mmsi,imo:n==null?void 0:n.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:p,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta)?w(`${c.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:c.dest,positionTime:b.unix(),labelCn:u,labelEn:I,method:"trajectory",vendor:"myVessel",utc:b.utc().format()},x=Math.floor(b.diff(y,"minute",!0)/(a||1));x!==h&&(h=x,s.push(F))}),s}}class yt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},a=await Y.post(i,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,i,n);const s=a==null?void 0:a.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",o.requestId,i,a),a;for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:l}=this.parseStatus(d),m=w(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.destination,positionTime:m.unix(),utc:m.utc().format(),status:d,labelCn:r,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,o={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await Y.post(i,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]);for(const d in a)!isNaN(a[d])&&Number(a[d])!==1/0&&(a[d]=Number(a[d]));const s={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr,type:a.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await Y.post(i,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",o.requestId,i,n),a instanceof Array&&(a=a[0]),a&&(s.deadweight=Number(a.dwt)),s}async suggest(t,o={}){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"}},a=await Y.post(i,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",o.requestId,i,n);const s=[];for(const d of a)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(t,o,i,n,a=!0,s={}){var c,b,p;const d=await this.realTimePosition(t,s);let r=w(o);const l=w(i),m=w();if(a){let u=l.diff(r,"d",!0);u<0?r=l.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=l.clone().subtract(80,"d"),u=m.diff(l,"d",!0),l.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},y="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await Y.get(y,h).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,y,h);let j;f&&(j=((b=(c=f.ships)==null?void 0:c.offors)==null?void 0:b.ship)||[],j.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const k=[];let g=-1;const v=w(`${(p=j==null?void 0:j[0])==null?void 0:p.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of j){for(const N in u)!isNaN(u[N])&&Number(u[N])!==1/0&&(u[N]=Number(u[N]));const I=w(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:x}=this.parseStatus(u.status),P={mmsi:u.m,name:u.n,imo:d==null?void 0:d.imo,lat:u.la,lng:u.lo,draught:u.draught,sog:u.sp,cog:u.co,hdg:u.hdg,positionTime:I.unix(),utc:I.utc().format(),status:u.status,labelCn:x,labelEn:F,method:"trajectory",vendor:"hifleet"},E=Math.floor(I.diff(v,"minute",!0)/(n||1));E!==g&&(g=E,k.push(P))}return k}}class pt extends U{constructor(t){super();z(this,"token");this.token=t}async realTimePosition(t,o={}){const i={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",a=await Y.get(n,i).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,n,i),(a==null?void 0:a.status)!==0)return a;const s=a.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:d,labelEn:r}=await this.parseStatus(s.navistat),l=w.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:l.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,o,i,n,a=!0,s={}){var v;const d=await this.realTimePosition(t,s),r=w(o),l=w(i),m="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:l.unix()}},y=await Y.get(m,h).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,m,h),(y==null?void 0:y.status)!==0)return y;const f=y==null?void 0:y.points,j=[],k=w.unix((v=f[0])==null?void 0:v.utc);let g=-1;for(const c of f){const b=w.unix(c.utc),p={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(c.sog*3600/1e3/1852*100)/100,cog:Math.round(c.cog/100*100)/100,lat:Math.round(c.lat/1e6*1e5)/1e5,lng:Math.round(c.lon/1e6*1e5)/1e5,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(b.diff(k,"minute",!0)/(n||1));u!==g&&(g=u,j.push(p))}return j}}class Mt extends U{constructor(t){super();z(this,"token");this.token=t}async getShipId(t,o={}){const i={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await Y.post(n,i).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",o.requestId,n,i),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,o={}){const i={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",a=await Y.post(n,i).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",o.requestId,n,i),a.code!=="0")return a;const s=a.data;let d=s.imo;return t==="407170"&&(d="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",o.requestId,t,s.imo,d)),{mmsi:s.mmsi,name:s.shipnameEn,imo:d,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,o={}){const i=await this.getShipId(t,o),n=await this.getShipInfo(i,o),a={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await Y.post(s,a).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",o.requestId,s,a);const r=d.data[0];for(const f in r)!isNaN(r[f])&&Number(r[f])!==1/0&&(r[f]=Number(r[f]));const{labelCn:l,labelEn:m}=await this.parseStatus(r.aisNavStatus),h=w.unix(r.posTime);return{...n,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:h.utc().format(),status:r.aisNavStatus,labelEn:m,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,o,i,n,a=!0,s={}){const d=w(o),r=w(i),l=await this.getShipId(t),m=await this.getShipInfo(l),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(l,d.unix(),d.add(30,"day").unix(),m,t,n,h);return await this.trajectoryIn30Day(l,d.unix(),r.unix(),m,t,n,h),h}async trajectoryIn30Day(t,o,i,n,a,s,d,r={}){var k;const l={headers:{appKey:this.token},json:{shipId:t,startTime:o,endTime:i}},m="https://api3.myships.com/sp/ships/position/history",h=await Y.post(m,l).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,m,l),h.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const y=h.data;for(const g in y)!isNaN(y[g])&&Number(y[g])!==1/0&&(y[g]=Number(y[g]));const f=w.unix((k=y[0])==null?void 0:k.posTime);let j=-1;for(const g of y){const v=w.unix(g.posTime),c={imo:n==null?void 0:n.imo,mmsi:a,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},b=Math.floor(v.diff(f,"minute",!0)/(s||1));b!==j&&(j=b,d.push(c))}return d}}let _;try{_=G.getLogger("vessel")}catch{}finally{}var ct=(L=>(L.NOTICE="NOTICE",L.WARN="WARN",L.HEAVY="HEAVY",L.SEVERE="SEVERE",L.ERROR="ERROR",L.FATAL="FATAL",L))(ct||{});class dt{parsePrinciple(e,t={}){var s,d,r;_==null||_.info("[%s] parse rule: %s",t.requestId,e);const o=new RegExp("(?<=\\[)(.+)(?=])","g"),i=e.match(o)?(s=e.match(o))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const a={};for(let l=0;l<(n==null?void 0:n.length);l++){const m=(r=(d=n[l].match(o))==null?void 0:d[0])==null?void 0:r.split("],");if(l===0&&!m)a.scope=n[0];else if(m)for(let h=0,y=m.length;h<y;h++){const f=this.parseRule(m[h]);f&&(a[f.level]?f.key?a[f.level][f==null?void 0:f.key]=f:a[f.level]=f:f.key?a[f.level]={[f==null?void 0:f.key]:f}:a[f.level]=f)}}return a}parseRule(e,t={}){var a;_==null||_.info("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const o=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(a=e==null?void 0:e.match(o))==null?void 0:a[0],n=i==null?void 0:i.split(",");if(n)return{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:Number(n[3]),key:n[4]}}checkWeather(e,t,o={}){var f,j,k,g,v,c,b,p,u,I,F,x,P,E,N;let i=0,n=0,a=0,s=0;const d=Math.round(((j=(f=t==null?void 0:t.SEVERE)==null?void 0:f.sigWave)==null?void 0:j.number)*1.6*100)/100,r=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,l=(c=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,m=Math.round((((p=(b=t==null?void 0:t.SEVERE)==null?void 0:b.wind)==null?void 0:p.number)+2)*100)/100,h=(I=(u=t==null?void 0:t.SEVERE)==null?void 0:u.wind)==null?void 0:I.number,y=(x=(F=t==null?void 0:t.HEAVY)==null?void 0:F.wind)==null?void 0:x.number;for(let T=0;T<(e==null?void 0:e.length);T++){const H=e[T],A=(E=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:E.sig,V=(N=H==null?void 0:H.meteo)==null?void 0:N.wind,K=T?w(H.eta).diff(w(e[T-1].eta),"hour",!0):0;s=K>s?K:s,_==null||_.info("[%s] check sig.wave: %j",o.requestId,{...A,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}),(A==null?void 0:A.height)>=d?H.isDangerous=!0:(A==null?void 0:A.height)>=r?H.isSevere=!0:(A==null?void 0:A.height)>=l&&(H.isHeavy=!0),_==null||_.info("[%s] check wind: %j",o.requestId,{...V,dgThd4Wd:m,svThd4Wd:h,hvThd4Wd:y}),(V==null?void 0:V.scale)>=m?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(V==null?void 0:V.scale)>h?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(V==null?void 0:V.scale)===y&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),i+=H.isDangerous?K:0,n+=H.isSevere?K:0,a+=H.isHeavy?K:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,a=Math.round(a*100)/100,s=Math.round(s),{sample:e,dangerous:i,severe:n,heavy:a,step:s<3?3:s,wind:{dgThd4Wd:m,svThd4Wd:h,hvThd4Wd:y},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:l}}}}const wt=new dt;let S;try{S=G.getLogger("vessel")}catch{}finally{}const bt=new it.MeteoHelper2("",!0);var ut=(L=>(L.common="common",L.container="container",L.tugs="tugs",L))(ut||{}),lt=(L=>(L.Ballast="Ballast",L.Laden="Laden",L))(lt||{}),ht=(L=>(L.Cp="CP",L.Perf="Basis",L.Instruct="Other",L))(ht||{});class W{static blockCoefficient(e,t,o,i){let n=Math.round(e/(t*o*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const a=[.55,.6,.65,.7,.75,.8,.85],s=a.map(d=>Math.abs(d-n));return a[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,o=9.8){let i=Math.round(Math.sqrt(e*e/(o*t))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(e,t,o){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return o==="Laden"&&(a=i[e]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(e,t=0){let o;return e>30&&e<=60?o=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?o=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?o=(.4-.03*Math.pow(t-8,2))/2:o=1,Math.round(o*1e5)/1e5}static vesselTagFactor(e,t,o,i=0){i=i>6?i-.9*(i-6):i;let n;return o==="container"?n=.7*i+Math.pow(i,6.5)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)):n=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let o;return t>30&&t<=60?o=-.6:t>60&&t<=90?o=-.4:t>90&&t<=120?o=e<3?.4:-.3:t>120&&t<=150?o=e<3?.6:-.5:t>150&&t<=180?o=e<3?.7:-.6:o=-.7,Math.round(o*(.144*Math.pow(e,2)+.178*e)*1e4)/1e4}static assembleProperties(e,t,o,i){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,a=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,d=e.deadweight??67035.7773,r=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:a,breadthMoulded:s,displacement:Math.round((d/1.025+a*s*n*.7)*1e4)/1e4,speed:Math.round((o??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(e,t,o,i="",n=2,a=!0,s=!1,d={}){let r;if(t.velocity&&s&&(e.speed=q.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let l;if(d.meteo2)try{const f=await bt.spotForecast(t.lat,t.lng,o.utc().format(),!1,!1,!0,d),[j]=rt.Meteo2Assist.pickHourly(f,o);l=rt.Meteo2Assist.toLegacy(j)}catch(f){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...t,eta:o.utc().format()},f)}else l=await it.MeteoHelper.queryPointFactor(t.lng,t.lat,o.valueOf(),"wind,wave,current,watertemp",i,d);const m=W.weatherFactor(e,l),h=W.currentFactor(e.bearing,l==null?void 0:l.current,n),y=Math.round((e.speed*1.943844+m+h)*100)/100;r={meteo:{...l},wxFactor:m,cFactor:h,speed:t.velocity&&s?t.velocity:y<0?1:y,eta:o.utc().format(),etd:o.utc().format()}}else r={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round((e.speed*1.943844+0+0)*100)/100,eta:o.utc().format(),etd:o.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...r,...t}}static async speedLoseInHoursStep(e,t,o,i,n,a,s="",d=!0,r=!1,l={}){t.utc();const m=t.clone().add(14,"days"),h=[],y=[];let f=0,j=0,k,g;for(let v=0;v<a.length-1;v++){let c=a[v];c.distanceFromStart=Math.round((n+j)*1e4)/1e4;const b=a[v+1];if(e.bearing=q.LaneHelper.calculateBearing(c,b,!b.gcToPrevious),c.bearing=e.bearing,c.suspend&&r){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const I=c.suspend-c.elapsed;if(i-f>I)i=i-f-I,t.add(I,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,t.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,l.requestId,c),i===0)return c.distanceFromPrevious=j,{etd:t,from:g||c,to:c,next:a.filter(F=>F),wps:h,days:y}}else c.suspend=0;d=t.isAfter(m)?!1:d,c=await W.speedLoseAt(e,c,t,s,0,d,r,l),g=g||c,c.important&&h.push(c),t.isSameOrAfter(o)&&(y.push(c),o.add(24,"hour"));const p=q.LaneHelper.calculateDistance(c,b,!b.gcToPrevious);let u=Math.round(p/g.speed*1e5)/1e5;if(f+u<i){if(f+=u,t.add(u,"hour"),delete a[v],S==null||S.debug(`[%s] go to %j from %j with ${p}nm, and cost ${u} hours`,l.requestId,{lat:b.lat,lng:b.lng},{lat:g.lat,lng:g.lng,etd:g.etd}),j+=p,a.filter(I=>I).length<=1){k=b,k.eta=t.utc().format(),k.distanceFromPrevious=p,k.distanceFromStart=Math.round((n+j)*1e4)/1e4,h.push(k),delete a[v+1];break}}else{u=i-f,t.add(u,"hour");const I=q.LngLatHelper.roundPrecision(g.speed*u,5);k=q.LaneHelper.calculateCoordinate(c,e.bearing,I,"nauticalmiles",!b.gcToPrevious),k.eta=t.utc().format(),a[v]=k,S==null||S.debug(`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,l.requestId,{lat:k.lat,lng:k.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),j+=I,k.distanceFromPrevious=Math.round(j*1e4)/1e4,k.distanceFromStart=Math.round((n+j)*1e4)/1e4;break}}return{etd:t,from:g,to:k,next:a.filter(v=>v),wps:h,days:y}}static currentFactor(e,t,o=0){const i=(e-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(i);return o&2?n=Math.ceil(n*100)/100:o&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t){var m,h,y,f,j,k,g;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=W.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),i=W.froudeNumber(e.speed,e.lbp),n=W.amendFactor(o,i,e.loadCondition);let a=Math.abs(e.bearing%360-(((m=t==null?void 0:t.wind)==null?void 0:m.degree)%360||0));a=a>180?360-a:a;const s=W.directionFactor(a,(h=t==null?void 0:t.wind)==null?void 0:h.scale),d=W.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(y=t==null?void 0:t.wind)==null?void 0:y.scale);let r=s*n*d/100*e.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),a=Math.abs(e.bearing%360-(((j=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:j.degree)%360||0));const l=W.waveHeightFactor(((g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.height)??1,a);return S==null||S.debug("wave wx factor = %d",l),r=r*.4+l,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>4?4*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-4)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(e,t,o,i,n,a="",s=0,d=!0,r=!1,l={}){var Q,X,Z,$,tt,et;const m=w().valueOf();e.lng=q.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:y}=n.points,f=q.LaneHelper.calculateSubRoute(e,h);if(((Q=f[0])==null?void 0:Q.length)<=1)return;const{v0:j,label:k}=e.sog?{v0:e.sog,label:"Other"}:{v0:i.speed,label:"CP"},g=W.assembleProperties(o,i.loadCondition,j,0),v=y.length?q.LaneHelper.calculateSubWaypoints(e,y):[];v.forEach(O=>O.important=!0);const c={from:{...e},route:f,waypoints:v,v0:j,label:k},b={hours:[],days:[],wps:[]};s||(q.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let p=q.LaneHelper.simplifyRouteToCoordinates(f,v,0),u=0,I=0,F=0,x=0;t=w(t).utc();const P=t.clone();for(;p.length>0;){const O=s-t.hour()%s,B=Math.ceil(t.clone().add(O,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,C=await W.speedLoseInHoursStep(g,t,P,B,u,p,a,d,r,l);(X=C.from)!=null&&X.speed&&(b.hours.push(C.from),b.wps.push(...C.wps),b.days.push(...C.days)),p=C==null?void 0:C.next,p.length||b.hours.push(C==null?void 0:C.to),u+=Math.round((((Z=C==null?void 0:C.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const E=b.hours;for(let O=0;O<E.length-1;O++){const B=w(E[O+1].eta).diff(E[O].etd,"hour",!0)||1;I+=(E[O].wxFactor||0)*B,F+=(E[O].cFactor||0)*B,x+=B}($=b.wps)==null||$.forEach((O,B)=>{if(O.positionTime=w.utc(O.etd||O.eta).unix(),B){const C=b.wps[B-1],J=O.distanceFromStart-C.distanceFromStart,R=w(O.eta).diff(w(C.etd),"h",!0);O.avgSpd=Math.round(J/R*100)/100}}),b.wps=(tt=b.wps)==null?void 0:tt.reduce((O,B)=>(O.some(C=>C.positionTime===B.positionTime)||O.push(B),O),[]),c.sample=b;const N=b.hours.at(0),T=b.hours.at(-1);c.distance=Math.round(T.distanceFromStart*1e4)/1e4,c.etd=w(N.eta).utc().format(),c.eta=w(T.eta).utc().format(),c.wxFactor=Math.round(I/x*1e4)/1e4,c.cFactor=Math.round(F/x*1e4)/1e4,c.avgSpeed=Math.round(T.distanceFromStart/x*1e4)/1e4,c.totalHrs=Math.round(x*1e4)/1e4;const{distanceInECA:H,hoursInECA:A,totalDgoConsInECA:V,eca:K}=await this.calculateECA(c,i,l),at=q.LngLatHelper.roundPrecision(i.fo/24*(x-A),3),nt=q.LngLatHelper.roundPrecision(i.dgo/24*x,3);c.extend={eca:K,distanceInECA:H,hoursInECA:A,totalDgoConsInECA:V},c.totalFoCons=at,c.totalDgoCons=nt;const st=w().valueOf()-m,ot=((et=b==null?void 0:b.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,st,ot,Math.round(st/ot*1e3)/1e3),c}static async analyseInstantWithThreshed(e,t,o,i,n,a,s,d="",r=3,l=!0,m=!1,h={}){var Z,$,tt,et,O,B;const y=w().valueOf();e.lng=q.LngLatHelper.convertToStdLng(e.lng);const{v0:f,label:j}=e.sog?{v0:e.sog,label:"Other"}:{v0:n.speed,label:"CP"},k=W.assembleProperties(i,n.loadCondition,f,0),g=q.LaneHelper.calculateSubRoute(e,a);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const v=s.length?q.LaneHelper.calculateSubWaypoints(e,s):[];v.forEach(C=>C.important=!0);let c=q.LaneHelper.simplifyRouteToCoordinates(g,v,0),b=0,p=0,u=0,I=0;const F={hours:[],wps:[],days:[]};t=w(t).utc();const x=t.clone();for(;c.length>0;){const C=r-t.hour()%r;let J=Math.ceil(t.clone().add(C,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;J=t.clone().add(J,"h").isSameOrAfter(o)?o.diff(t,"h",!0)*1e4/1e4:J;const R=await W.speedLoseInHoursStep(k,t,x,J,b,c,d,l,m,h);if(($=R.from)!=null&&$.speed&&(F.hours.push(R.from),R!=null&&R.wps&&F.wps.push(...R.wps),F.days.push(...R.days)),c=R==null?void 0:R.next,c.length||F.hours.push(R==null?void 0:R.to),b+=Math.round((((tt=R==null?void 0:R.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!J)break}F.wps=(et=F.wps)==null?void 0:et.reduce((C,J)=>(C.some(R=>R.etd===J.etd)||C.push(J),C),[]),(O=F.wps)==null||O.forEach((C,J)=>{if(J){const R=F.wps[J-1],vt=C.distanceFromStart-R.distanceFromStart,gt=w(C.eta).diff(w(R.etd),"h",!0);C.avgSpd=Math.round(vt/gt*100)/100}});const P=F.hours;for(let C=0;C<P.length-1;C++){const J=w(P[C+1].eta).diff(P[C].etd,"hour",!0);p+=P[C].wxFactor*J,u+=P[C].cFactor*J,I+=J}const E=F.hours.at(0),N=F.hours.at(-1),T=await q.LaneHelper.calculateRangeRoute(E,N,g),H=await q.LaneHelper.calculateRangeWaypoints(E,N,g,v),A={sample:F,distance:Math.round(((N==null?void 0:N.distanceFromStart)||0)*1e4)/1e4,etd:w(E.eta).utc().format(),eta:w(N==null?void 0:N.eta).utc().format(),wxFactor:Math.round(p/I*1e4)/1e4,cFactor:Math.round(u/I*1e4)/1e4,avgSpeed:Math.round(((N==null?void 0:N.distanceFromStart)||0)/I*1e4)/1e4,totalHrs:Math.round(I*1e4)/1e4,from:E,to:N,route:T,waypoints:H,v0:f,label:j},{distanceInECA:V,hoursInECA:K,totalDgoConsInECA:at,eca:nt}=await this.calculateECA(A,n,h),ft=q.LngLatHelper.roundPrecision(n.fo/24*(I-K),3),st=q.LngLatHelper.roundPrecision(n.dgo/24*I,3);A.extend={eca:nt,distanceInECA:V,hoursInECA:K,totalDgoConsInECA:at},A.totalDgoCons=st,A.totalFoCons=ft;const Q=w().valueOf()-y,X=((B=F==null?void 0:F.hours)==null?void 0:B.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,Q,X,Math.round(Q/X*1e3)/1e3),A}static async analyseCost(e,t,o,i,n={}){var g,v;const a=w().valueOf(),s=[];n.meteo2=n.meteo2||!0,e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const d=q.LaneHelper.calculateRouteDistance(i.route);let r=0;o.forEach(c=>{const b=Math.ceil(d/c.speed/24);r=r<b?b:r}),r=r*1.3;const l=w.utc(e.etd).add(r??14,"day");let m=1;for(const c of o){const b=JSON.parse(JSON.stringify(i.route)),p=JSON.parse(JSON.stringify(i.waypoints)),u=await W.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,l,t,c,b,p,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);u&&(await W.calculateCost(u,c,e,n),s.push(u),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,m,e.etd,l.format(),{cost:u.cost.total,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),m++}s.sort((c,b)=>c.cost.total-b.cost.total);const h=s.at(0),y=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(g=h.cost)==null?void 0:g.total}),y){const c=h.cost.cp,b=y.cost.cp,p=w(h.eta),u=w(h.etd),I=p.diff(u,"days",!0);let F=Math.ceil(I/2);F=F>7?7:F<e.alterStep?e.alterStep:F;let x=2,P={combined:!1,speeds:[y],cost:(v=y.cost)==null?void 0:v.total},E;for(;F>=e.alterStep;){const N=await W.combinedAnalyse(e,t,l,[c,b],i,F,{...n,level:x});if(P.cost>N.cost?E?(E==null?void 0:E.cost)>N.cost&&(E=N):(E=P,P=N):(!E||(E==null?void 0:E.cost)>N.cost)&&(E=N),F<=e.alterStep)break;F=Math.ceil(F/2),x+=1}f.push(P),E&&f.push(E)}const k=w().valueOf()-a;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),f.sort((c,b)=>c.cost-b.cost)}static async combinedAnalyse(e,t,o,i,n,a,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,a);const d=await W.alternateAnalyse(e,t,o,i,0,n,a,s),r=d.reduce((h,y)=>h+y.cost.total,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %d",s.requestId,s.level,r);const l=await W.alternateAnalyse(e,t,o,i,1,n,a,s),m=l.reduce((h,y)=>h+y.cost.total,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %d",s.requestId,s.level,m),r<m?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:a}:{combined:!0,cost:Math.round(m*1e3)/1e3,speeds:l,step:a}}static async alternateAnalyse(e,t,o,i,n,a,s,d={}){var h,y;let r=w.utc(e.etd);const l={lat:e.lat,lng:e.lng},m=[];for(;r.isBefore(o);){const f=r.clone().utc().add(s,"day"),j=JSON.parse(JSON.stringify(a.route)),k=JSON.parse(JSON.stringify(a.waypoints)),g=i[n],v=await W.analyseInstantWithThreshed(l,r.utc().format(),f,t,g,j,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,d);v&&(await W.calculateCost(v,g,e,d),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",d.requestId,d.level,d.counter,r.utc().format(),f.utc().format(),{cost:v.cost.total,distance:v.distance,hours:v.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),d.counter=d.counter+1;const c=(y=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:y.at(-1);if(c)l.lat=c.lat,l.lng=c.lng,r=w(c.eta),m.push(v),n=n?0:1;else break}return m}static async calculateCost(e,t,o,i={}){var n;if(e){const a=Math.round(e.totalHrs/24*(o.dailyHire||0)*(1-(o.addComm||0))*1e3)/1e3,s=Math.round(e.totalFoCons*(o.priceFO||0)*1e3)/1e3,d=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(o.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((a+s+d)*1e3)/1e3,hire:a,bunker:Math.round((s+d)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,o={}){var d,r;const i=await q.LaneHelper.intersectInECA(e.route);let n=0,a=0,s=0;e.sample.wps.forEach(l=>{l.positionTime=w.utc(l.etd||l.eta).unix()});for(const l of i){n+=l.distance;const m=await q.LaneHelper.deadReckoningTime((d=l.waypoints)==null?void 0:d.at(0),e.sample.wps),h=await q.LaneHelper.deadReckoningTime((r=l.waypoints)==null?void 0:r.at(-1),e.sample.wps);l.in=m,l.out=h,l.totalHrs=q.LngLatHelper.roundPrecision((h.positionTime-m.positionTime)/3600,2),l.totalDgoCons=q.LngLatHelper.roundPrecision(t.fo/24*l.totalHrs,3),a+=l.totalHrs,s+=l.totalDgoCons}return n=q.LngLatHelper.roundPrecision(n,3),a=q.LngLatHelper.roundPrecision(a,3),s=q.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:a,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(e,t={}){var c,b;const o={hours:[],wps:[],days:[]},i=e.reduce((p,u)=>p+u.distance,0),n=e.reduce((p,u)=>{var I;return p+(((I=u.extend)==null?void 0:I.distanceInECA)||0)},0),a=e.reduce((p,u)=>p+u.totalHrs,0),s=e.reduce((p,u)=>{var I;return p+(((I=u.extend)==null?void 0:I.hoursInECA)||0)},0),d=e.reduce((p,u)=>{var I;return p+(((I=u.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),r=e.reduce((p,u)=>p+u.wxFactor*u.totalHrs/a,0),l=e.reduce((p,u)=>p+u.cFactor*u.totalHrs/a,0),m=e.reduce((p,u)=>p+u.totalFoCons,0),h=e.reduce((p,u)=>p+u.totalDgoCons,0),y=e.reduce((p,u)=>p+u.cost.total,0),f=e.reduce((p,u)=>p+u.cost.hire,0),j=e.reduce((p,u)=>p+u.cost.bunker,0),k=[],g=[];let v;for(const p of e){g.push(...((c=p.extend)==null?void 0:c.eca)||[]);const u=p.sample.hours,I=p.sample.wps,F=p.sample.days,x=u.at(0);v&&(x.distanceFromPrevious=v.distanceFromPrevious,x.distanceFromStart=v.distanceFromStart,u.forEach((T,H)=>{H&&(T.distanceFromStart=T.distanceFromStart+v.distanceFromStart)}),I.at(0).distanceFromPrevious=v.distanceFromPrevious,I.at(0).distanceFromStart=v.distanceFromStart,I.forEach((T,H)=>{H&&(T.distanceFromStart=T.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((T,H)=>{H&&(T.distanceFromStart=T.distanceFromStart+v.distanceFromStart)})),x.cp=p.cost.cp;const P=[p.etd,p.eta],E=k.findIndex(T=>T.id===x.cp.id);E===-1?(x.cp.segment=[P],k.push(x.cp)):k[E].segment.push(P),u.forEach(T=>{var A;((A=o.hours)==null?void 0:A.findIndex(V=>V.eta===T.eta))===-1&&o.hours.push(T)}),I.forEach(T=>{var A;((A=o.wps)==null?void 0:A.findIndex(V=>V.eta===T.eta))===-1&&o.wps.push(T)}),F.forEach(T=>{var A;((A=o==null?void 0:o.days)==null?void 0:A.findIndex(V=>V.eta===T.eta))===-1&&o.days.push(T)});const N=(b=o.wps)==null?void 0:b.findIndex(T=>T.eta===x.eta);N===-1?o.wps.push(x):o.wps[N]=x,v=u.at(-1)}return o.wps.sort((p,u)=>{w(p.etd).unix()-w(u.etd).unix()}),o.wps.forEach((p,u)=>{let I;if(u===0?I=o.wps.at(1):I=o.wps.at(u+1),I){const F=I.distanceFromStart-(p.distanceFromStart||0),x=w(I.etd||I.eta).diff(w(p.etd||I.eta),"hour",!0),P=Math.round(F/x*100)/100;p.avgSpd=P}}),{sample:o,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(i*1e4)/1e4,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(i/a*1e3)/1e3,wxFactor:Math.round(r/a*1e3)/1e3,cFactor:Math.round(l/a*1e3)/1e3,totalFoCons:Math.round(m*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(y*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(j*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e4)/1e4,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:e}}}}D.AISImpl=U,D.AlertHelper=dt,D.AlertLevel=ct,D.HifleetImpl=yt,D.LoadCondition=lt,D.MyShipImpl=Mt,D.MyVesselImpl=mt,D.ShipxyImpl=pt,D.SpeedHelper=W,D.SpeedLabel=ht,D.VesselTag=ut,D.alertHelper=wt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
|