@idm-plugin/vessel 2.2.4 → 2.2.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  var ht = Object.defineProperty;
2
- var lt = (E, t, e) => t in E ? ht(E, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : E[t] = e;
3
- var K = (E, t, e) => (lt(E, typeof t != "symbol" ? t + "" : t, e), e);
2
+ var lt = (x, t, e) => t in x ? ht(x, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : x[t] = e;
3
+ var K = (x, t, e) => (lt(x, typeof t != "symbol" ? t + "" : t, e), e);
4
4
  import B from "got";
5
5
  import ct from "@log4js-node/log4js-api";
6
6
  import g from "moment";
@@ -54,7 +54,7 @@ class st {
54
54
  return { labelCn: e, labelEn: a };
55
55
  }
56
56
  }
57
- class xt extends st {
57
+ class Et extends st {
58
58
  constructor(e, a) {
59
59
  super();
60
60
  K(this, "clientId");
@@ -69,30 +69,30 @@ class xt extends st {
69
69
  client_secret: this.clientSecret,
70
70
  grant_type: "client_credentials"
71
71
  }
72
- }, n = await B.post(a, i).json();
73
- v == null || v.info("[%s] fetch access token from: %s - %j", e.requestId, a, n), n.error || (this.token = {
74
- accessToken: n.access_token,
75
- tokenType: n.token_type,
76
- expiresIn: n.expires_in,
77
- scope: n.scope,
78
- jti: n.jti,
72
+ }, o = await B.post(a, i).json();
73
+ v == null || v.info("[%s] fetch access token from: %s - %j", e.requestId, a, o), o.error || (this.token = {
74
+ accessToken: o.access_token,
75
+ tokenType: o.token_type,
76
+ expiresIn: o.expires_in,
77
+ scope: o.scope,
78
+ jti: o.jti,
79
79
  issuedAt: g().utc().format()
80
80
  });
81
81
  }
82
82
  async realTimePosition(e, a = {}) {
83
83
  var d, r, m;
84
84
  (!this.token || g().diff(g(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(a);
85
- const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
85
+ const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", o = {
86
86
  headers: {
87
87
  Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(m = this.token) == null ? void 0 : m.accessToken}`
88
88
  },
89
89
  searchParams: { mmsi: e }
90
90
  };
91
- v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
92
- const o = await B.get(i, n).json();
93
- if (o.code)
94
- return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, { message: o.message, status: o.status, code: o.code }), o;
95
- const s = o.data;
91
+ v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, o);
92
+ const n = await B.get(i, o).json();
93
+ if (n.code)
94
+ return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, { message: n.message, status: n.status, code: n.code }), n;
95
+ const s = n.data;
96
96
  for (const M in s)
97
97
  !isNaN(s[M]) && Number(s[M]) !== 1 / 0 && (s[M] = Number(s[M]));
98
98
  if (s) {
@@ -131,14 +131,14 @@ class xt extends st {
131
131
  } else
132
132
  return {};
133
133
  }
134
- async trajectory(e, a, i, n, o = !0, s = {}) {
134
+ async trajectory(e, a, i, o, n = !0, s = {}) {
135
135
  (!this.token || g().diff(g(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(s);
136
136
  const d = await this.realTimePosition(e, s), r = g(a), m = g(i), M = [];
137
137
  for (; m.diff(r, "day", !0) > 30; )
138
- await this.trajectoryIn30Day(e, r, r.clone().add(30, "day"), d, n, M, s), r.add(30, "day");
139
- return await this.trajectoryIn30Day(e, r, m, d, n, M, s), M;
138
+ await this.trajectoryIn30Day(e, r, r.clone().add(30, "day"), d, o, M, s), r.add(30, "day");
139
+ return await this.trajectoryIn30Day(e, r, m, d, o, M, s), M;
140
140
  }
141
- async trajectoryIn30Day(e, a, i, n, o, s, d = {}) {
141
+ async trajectoryIn30Day(e, a, i, o, n, s, d = {}) {
142
142
  var f, C, S, p, w;
143
143
  const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", m = {
144
144
  headers: {
@@ -161,7 +161,7 @@ class xt extends st {
161
161
  !isNaN(c[Y]) && Number(c[Y]) !== 1 / 0 && (c[Y] = Number(c[Y]));
162
162
  const y = g(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), h = c.status, { labelCn: u, labelEn: I } = this.parseStatus(h), k = {
163
163
  mmsi: c.mmsi,
164
- imo: n == null ? void 0 : n.imo,
164
+ imo: o == null ? void 0 : o.imo,
165
165
  lat: c.lat,
166
166
  lng: c.lon,
167
167
  sog: c.sog,
@@ -177,28 +177,28 @@ class xt extends st {
177
177
  method: "trajectory",
178
178
  vendor: "myVessel",
179
179
  utc: y.utc().format()
180
- }, D = Math.floor(y.diff(b, "minute", !0) / (o || 1));
180
+ }, D = Math.floor(y.diff(b, "minute", !0) / (n || 1));
181
181
  D !== l && (l = D, s.push(k));
182
182
  }), s;
183
183
  }
184
184
  }
185
- class Et extends st {
185
+ class xt extends st {
186
186
  constructor(e) {
187
187
  super();
188
188
  K(this, "token");
189
189
  this.token = e;
190
190
  }
191
191
  async realTimePosition(e, a = {}) {
192
- const i = "https://api.hifleet.com/position/position/get/token", n = {
192
+ const i = "https://api.hifleet.com/position/position/get/token", o = {
193
193
  searchParams: {
194
194
  mmsi: e,
195
195
  usertoken: this.token
196
196
  }
197
- }, o = await B.post(i, n).json();
198
- v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, n);
199
- const s = o == null ? void 0 : o.list;
197
+ }, n = await B.post(i, o).json();
198
+ v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, i, o);
199
+ const s = n == null ? void 0 : n.list;
200
200
  if (!s)
201
- return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
201
+ return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, n), n;
202
202
  for (const b in s)
203
203
  !isNaN(s[b]) && Number(s[b]) !== 1 / 0 && (s[b] = Number(s[b]));
204
204
  s.status = s.sp > 3 ? 0 : 1;
@@ -234,7 +234,7 @@ class Et extends st {
234
234
  }
235
235
  async search(e, a = {}) {
236
236
  let i = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
237
- const n = {
237
+ const o = {
238
238
  searchParams: {
239
239
  keyword: e
240
240
  },
@@ -244,24 +244,24 @@ class Et extends st {
244
244
  Host: "www.hifleet.com"
245
245
  }
246
246
  };
247
- let o = await B.post(i, n).json();
248
- v == null || v.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]);
249
- for (const d in o)
250
- !isNaN(o[d]) && Number(o[d]) !== 1 / 0 && (o[d] = Number(o[d]));
247
+ let n = await B.post(i, o).json();
248
+ v == null || v.info("[%s] fetch vessel props from: %s - %j", a.requestId, i, o), n instanceof Array && (n = n[0]);
249
+ for (const d in n)
250
+ !isNaN(n[d]) && Number(n[d]) !== 1 / 0 && (n[d] = Number(n[d]));
251
251
  const s = {
252
- mmsi: o.m,
253
- name: o.n,
254
- imo: o.i,
255
- callSign: o.c,
256
- length: o.l,
257
- breadth: o.b,
258
- draught: o.dr,
259
- type: o.t
252
+ mmsi: n.m,
253
+ name: n.n,
254
+ imo: n.i,
255
+ callSign: n.c,
256
+ length: n.l,
257
+ breadth: n.b,
258
+ draught: n.dr,
259
+ type: n.t
260
260
  };
261
- return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", o = await B.post(i, n).json(), v == null || v.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, n), o instanceof Array && (o = o[0]), o && (s.deadweight = Number(o.dwt)), s;
261
+ return i = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", n = await B.post(i, o).json(), v == null || v.info("[%s] search vessel dead weight from: %s - %j", a.requestId, i, o), n instanceof Array && (n = n[0]), n && (s.deadweight = Number(n.dwt)), s;
262
262
  }
263
263
  async suggest(e, a = {}) {
264
- const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
264
+ const i = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", o = {
265
265
  searchParams: {
266
266
  q: e
267
267
  },
@@ -270,10 +270,10 @@ class Et extends st {
270
270
  Origin: "https://www.hifleet.com",
271
271
  Host: "www.hifleet.com"
272
272
  }
273
- }, o = await B.post(i, n).json();
274
- v == null || v.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, n);
273
+ }, n = await B.post(i, o).json();
274
+ v == null || v.info("[%s] suggest vessel props from: %s - %j", a.requestId, i, o);
275
275
  const s = [];
276
- for (const d of o)
276
+ for (const d of n)
277
277
  s.push({
278
278
  mmsi: !d.mmsi || isNaN(d.mmsi) ? null : Number(d.mmsi),
279
279
  name: d.name,
@@ -283,12 +283,12 @@ class Et extends st {
283
283
  });
284
284
  return s.sort((d, r) => r.score - d.score), s;
285
285
  }
286
- async trajectory(e, a, i, n, o = !0, s = {}) {
286
+ async trajectory(e, a, i, o, n = !0, s = {}) {
287
287
  var c, y, h;
288
288
  const d = await this.realTimePosition(e, s);
289
289
  let r = g(a);
290
290
  const m = g(i), M = g();
291
- if (o) {
291
+ if (n) {
292
292
  let u = m.diff(r, "d", !0);
293
293
  u < 0 ? r = m.clone().subtract(40, "d") : u < 30 ? r.subtract(10, "d") : u < 60 ? r.subtract(5, "d") : r = m.clone().subtract(80, "d"), u = M.diff(m, "d", !0), m.add(u > 10 ? 240 : u * 24, "h");
294
294
  }
@@ -307,8 +307,8 @@ class Et extends st {
307
307
  let p = -1;
308
308
  const w = g(`${(h = C == null ? void 0 : C[0]) == null ? void 0 : h.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
309
309
  for (const u of C) {
310
- for (const P in u)
311
- !isNaN(u[P]) && Number(u[P]) !== 1 / 0 && (u[P] = Number(u[P]));
310
+ for (const A in u)
311
+ !isNaN(u[A]) && Number(u[A]) !== 1 / 0 && (u[A] = Number(u[A]));
312
312
  const I = g(`${u.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
313
313
  u.status = u.sp > 4 ? 0 : 1;
314
314
  const { labelEn: k, labelCn: D } = this.parseStatus(u.status), Y = {
@@ -328,7 +328,7 @@ class Et extends st {
328
328
  labelEn: k,
329
329
  method: "trajectory",
330
330
  vendor: "hifleet"
331
- }, j = Math.floor(I.diff(w, "minute", !0) / (n || 1));
331
+ }, j = Math.floor(I.diff(w, "minute", !0) / (o || 1));
332
332
  j !== p && (p = j, S.push(Y));
333
333
  }
334
334
  return S;
@@ -347,10 +347,10 @@ class jt extends st {
347
347
  k: this.token,
348
348
  enc: 1
349
349
  }
350
- }, n = "https://api.shipxy.com/apicall/GetSingleShip", o = await B.get(n, i).json();
351
- if (v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, i), (o == null ? void 0 : o.status) !== 0)
352
- return o;
353
- const s = o.data[0];
350
+ }, o = "https://api.shipxy.com/apicall/GetSingleShip", n = await B.get(o, i).json();
351
+ if (v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, i), (n == null ? void 0 : n.status) !== 0)
352
+ return n;
353
+ const s = n.data[0];
354
354
  for (const l in s)
355
355
  !isNaN(s[l]) && Number(s[l]) !== 1 / 0 && (s[l] = Number(s[l]));
356
356
  const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), m = g.unix(s.lasttime);
@@ -377,7 +377,7 @@ class jt extends st {
377
377
  vendor: "shipxy"
378
378
  };
379
379
  }
380
- async trajectory(e, a, i, n, o = !0, s = {}) {
380
+ async trajectory(e, a, i, o, n = !0, s = {}) {
381
381
  var w;
382
382
  const d = await this.realTimePosition(e, s), r = g(a), m = g(i), M = "https://api.shipxy.com/apicall/GetShipTrack", l = {
383
383
  searchParams: {
@@ -405,7 +405,7 @@ class jt extends st {
405
405
  utc: y.utc().format(),
406
406
  method: "trajectory",
407
407
  vendor: "shipxy"
408
- }, u = Math.floor(y.diff(S, "minute", !0) / (n || 1));
408
+ }, u = Math.floor(y.diff(S, "minute", !0) / (o || 1));
409
409
  u !== p && (p = u, C.push(h));
410
410
  }
411
411
  return C;
@@ -425,8 +425,8 @@ class Nt extends st {
425
425
  json: {
426
426
  mmsiList: e
427
427
  }
428
- }, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", o = await B.post(n, i).json();
429
- return v == null || v.info("[%s] fetch ship id from: %s - %j", a.requestId, n, i), o.code !== "0" ? o : o.data[0].shipId;
428
+ }, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", n = await B.post(o, i).json();
429
+ return v == null || v.info("[%s] fetch ship id from: %s - %j", a.requestId, o, i), n.code !== "0" ? n : n.data[0].shipId;
430
430
  }
431
431
  async getShipInfo(e, a = {}) {
432
432
  const i = {
@@ -436,10 +436,10 @@ class Nt extends st {
436
436
  json: {
437
437
  shipId: e
438
438
  }
439
- }, n = "https://api3.myships.com/sp/ships/aissta", o = await B.post(n, i).json();
440
- if (v == null || v.info("[%s] fetch ship info from: %s - %j", a.requestId, n, i), o.code !== "0")
441
- return o;
442
- const s = o.data;
439
+ }, o = "https://api3.myships.com/sp/ships/aissta", n = await B.post(o, i).json();
440
+ if (v == null || v.info("[%s] fetch ship info from: %s - %j", a.requestId, o, i), n.code !== "0")
441
+ return n;
442
+ const s = n.data;
443
443
  let d = s.imo;
444
444
  return e === "407170" && (d = "9198379", v == null || v.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, e, s.imo, d)), {
445
445
  mmsi: s.mmsi,
@@ -452,21 +452,21 @@ class Nt extends st {
452
452
  };
453
453
  }
454
454
  async realTimePosition(e, a = {}) {
455
- const i = await this.getShipId(e, a), n = await this.getShipInfo(i, a), o = {
455
+ const i = await this.getShipId(e, a), o = await this.getShipInfo(i, a), n = {
456
456
  headers: {
457
457
  appKey: this.token
458
458
  },
459
459
  json: {
460
460
  shipId: i
461
461
  }
462
- }, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, o).json();
463
- v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, o);
462
+ }, s = "https://api3.myships.com/sp/ships/position/latest", d = await B.post(s, n).json();
463
+ v == null || v.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, n);
464
464
  const r = d.data[0];
465
465
  for (const f in r)
466
466
  !isNaN(r[f]) && Number(r[f]) !== 1 / 0 && (r[f] = Number(r[f]));
467
467
  const { labelCn: m, labelEn: M } = await this.parseStatus(r.aisNavStatus), l = g.unix(r.posTime);
468
468
  return {
469
- ...n,
469
+ ...o,
470
470
  mmsi: e,
471
471
  lat: Math.round(r.lat / 1e4 / 60 * 1e5) / 1e5,
472
472
  lng: Math.round(r.lon / 1e4 / 60 * 1e5) / 1e5,
@@ -483,13 +483,13 @@ class Nt extends st {
483
483
  vendor: "myship"
484
484
  };
485
485
  }
486
- async trajectory(e, a, i, n, o = !0, s = {}) {
486
+ async trajectory(e, a, i, o, n = !0, s = {}) {
487
487
  const d = g(a), r = g(i), m = await this.getShipId(e), M = await this.getShipInfo(m), l = [];
488
488
  for (; r.diff(d, "day", !0) > 30; )
489
- await this.trajectoryIn30Day(m, d.unix(), d.add(30, "day").unix(), M, e, n, l);
490
- return await this.trajectoryIn30Day(m, d.unix(), r.unix(), M, e, n, l), l;
489
+ await this.trajectoryIn30Day(m, d.unix(), d.add(30, "day").unix(), M, e, o, l);
490
+ return await this.trajectoryIn30Day(m, d.unix(), r.unix(), M, e, o, l), l;
491
491
  }
492
- async trajectoryIn30Day(e, a, i, n, o, s, d, r = {}) {
492
+ async trajectoryIn30Day(e, a, i, o, n, s, d, r = {}) {
493
493
  var S;
494
494
  const m = {
495
495
  headers: {
@@ -510,8 +510,8 @@ class Nt extends st {
510
510
  let C = -1;
511
511
  for (const p of b) {
512
512
  const w = g.unix(p.posTime), c = {
513
- imo: n == null ? void 0 : n.imo,
514
- mmsi: o,
513
+ imo: o == null ? void 0 : o.imo,
514
+ mmsi: n,
515
515
  lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
516
516
  lng: Math.round(p.lon / 1e4 / 60 * 1e5) / 1e5,
517
517
  sog: Math.round(p.sog / 10 * 100) / 100,
@@ -534,7 +534,7 @@ try {
534
534
  } catch {
535
535
  } finally {
536
536
  }
537
- var mt = /* @__PURE__ */ ((E) => (E.NOTICE = "NOTICE", E.WARN = "WARN", E.HEAVY = "HEAVY", E.SEVERE = "SEVERE", E.ERROR = "ERROR", E.FATAL = "FATAL", E))(mt || {});
537
+ var mt = /* @__PURE__ */ ((x) => (x.NOTICE = "NOTICE", x.WARN = "WARN", x.HEAVY = "HEAVY", x.SEVERE = "SEVERE", x.ERROR = "ERROR", x.FATAL = "FATAL", x))(mt || {});
538
538
  class yt {
539
539
  /**
540
540
  * 解析告警规则, 多规则场景
@@ -546,22 +546,22 @@ class yt {
546
546
  */
547
547
  parsePrinciple(t, e = {}) {
548
548
  var s, d, r;
549
- _ == null || _.info("[%s] parse rule: %s", e.requestId, t);
550
- const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = t.match(a) ? (s = t.match(a)) == null ? void 0 : s[0] : void 0, n = i == null ? void 0 : i.split(";");
551
- if (!n)
549
+ _ == null || _.debug("[%s] parse rule: %s", e.requestId, t);
550
+ const a = new RegExp("(?<=\\[)(.+)(?=])", "g"), i = t.match(a) ? (s = t.match(a)) == null ? void 0 : s[0] : void 0, o = i == null ? void 0 : i.split(";");
551
+ if (!o)
552
552
  return;
553
- const o = {};
554
- for (let m = 0; m < (n == null ? void 0 : n.length); m++) {
555
- const M = (r = (d = n[m].match(a)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
553
+ const n = {};
554
+ for (let m = 0; m < (o == null ? void 0 : o.length); m++) {
555
+ const M = (r = (d = o[m].match(a)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
556
556
  if (m === 0 && !M)
557
- o.scope = n[0];
557
+ n.scope = o[0];
558
558
  else if (M)
559
559
  for (let l = 0, b = M.length; l < b; l++) {
560
560
  const f = this.parseRule(M[l]);
561
- f && (o[f.level] ? f.key ? o[f.level][f == null ? void 0 : f.key] = f : o[f.level] = f : f.key ? o[f.level] = { [f == null ? void 0 : f.key]: f } : o[f.level] = f);
561
+ f && (n[f.level] ? f.key ? n[f.level][f == null ? void 0 : f.key] = f : n[f.level] = f : f.key ? n[f.level] = { [f == null ? void 0 : f.key]: f } : n[f.level] = f);
562
562
  }
563
563
  }
564
- return o;
564
+ return n;
565
565
  }
566
566
  /**
567
567
  * 解析单一告警规则
@@ -570,17 +570,19 @@ class yt {
570
570
  * @param options
571
571
  */
572
572
  parseRule(t, e = {}) {
573
- var o;
573
+ var n;
574
574
  _ == null || _.debug("[%s] parse rule: %s", e.requestId, t), t = t.startsWith("[") ? t : `[${t}`, t = t.endsWith("]") ? t : `${t}]`;
575
- const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (o = t == null ? void 0 : t.match(a)) == null ? void 0 : o[0], n = i == null ? void 0 : i.split(",");
576
- if (n)
577
- return {
578
- operator: n[0],
579
- number: Number.isNaN(Number(n[1])) ? n[1] : Number(n[1]),
580
- level: n[2],
581
- time: Number(n[3]),
582
- key: n[4]
575
+ const a = new RegExp("(?<=\\[)(.+?)(?=])", "g"), i = (n = t == null ? void 0 : t.match(a)) == null ? void 0 : n[0], o = i == null ? void 0 : i.split(",");
576
+ if (o) {
577
+ let s = o[3] === "Number.MAX_VALUE" ? 100 : Number(o[3]);
578
+ return s = isNaN(s) ? 1 : s, {
579
+ operator: o[0],
580
+ number: Number.isNaN(Number(o[1])) ? o[1] : Number(o[1]),
581
+ level: o[2],
582
+ time: s,
583
+ key: o[4]
583
584
  };
585
+ }
584
586
  }
585
587
  /**
586
588
  * 检查航路点天气
@@ -589,14 +591,14 @@ class yt {
589
591
  * @param options
590
592
  */
591
593
  checkWeather(t, e, a = {}) {
592
- var f, C, S, p, w, c, y, h, u, I, k, D, Y, j, P;
593
- let i = 0, n = 0, o = 0, s = 0;
594
+ var f, C, S, p, w, c, y, h, u, I, k, D, Y, j, A;
595
+ let i = 0, o = 0, n = 0, s = 0;
594
596
  const d = Math.round(((C = (f = e == null ? void 0 : e.SEVERE) == null ? void 0 : f.sigWave) == null ? void 0 : C.number) * 1.6 * 100) / 100, r = (p = (S = e == null ? void 0 : e.SEVERE) == null ? void 0 : S.sigWave) == null ? void 0 : p.number, m = (c = (w = e == null ? void 0 : e.HEAVY) == null ? void 0 : w.sigWave) == null ? void 0 : c.number, M = Math.round((((h = (y = e == null ? void 0 : e.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : h.number) + 2) * 100) / 100, l = (I = (u = e == null ? void 0 : e.SEVERE) == null ? void 0 : u.wind) == null ? void 0 : I.number, b = (D = (k = e == null ? void 0 : e.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : D.number;
595
597
  for (let T = 0; T < (t == null ? void 0 : t.length); T++) {
596
- const N = t[T], A = (j = (Y = N == null ? void 0 : N.meteo) == null ? void 0 : Y.wave) == null ? void 0 : j.sig, R = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wind, U = T ? g(N.eta).diff(g(t[T - 1].eta), "hour", !0) : 0;
597
- s = U > s ? U : s, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...A, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: m }), (A == null ? void 0 : A.height) >= d ? N.isDangerous = !0 : (A == null ? void 0 : A.height) >= r ? N.isSevere = !0 : (A == null ? void 0 : A.height) >= m && (N.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: b }), (R == null ? void 0 : R.scale) >= M ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > l ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === b && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? U : 0, n += N.isSevere ? U : 0, o += N.isHeavy ? U : 0;
598
+ const N = t[T], P = (j = (Y = N == null ? void 0 : N.meteo) == null ? void 0 : Y.wave) == null ? void 0 : j.sig, R = (A = N == null ? void 0 : N.meteo) == null ? void 0 : A.wind, U = T ? g(N.eta).diff(g(t[T - 1].eta), "hour", !0) : 0;
599
+ s = U > s ? U : s, _ == null || _.debug("[%s] check sig.wave: %j", a.requestId, { ...P, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: m }), (P == null ? void 0 : P.height) >= d ? N.isDangerous = !0 : (P == null ? void 0 : P.height) >= r ? N.isSevere = !0 : (P == null ? void 0 : P.height) >= m && (N.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", a.requestId, { ...R, dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: b }), (R == null ? void 0 : R.scale) >= M ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (R == null ? void 0 : R.scale) > l ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (R == null ? void 0 : R.scale) === b && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? U : 0, o += N.isSevere ? U : 0, n += N.isHeavy ? U : 0;
598
600
  }
599
- return i = Math.round(i * 100) / 100, n = Math.round(n * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s), { sample: t, dangerous: i, severe: n, heavy: o, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: b }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: m } };
601
+ return i = Math.round(i * 100) / 100, o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, s = Math.round(s), { sample: t, dangerous: i, severe: o, heavy: n, step: s < 3 ? 3 : s, wind: { dgThd4Wd: M, svThd4Wd: l, hvThd4Wd: b }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: m } };
600
602
  }
601
603
  }
602
604
  const Tt = new yt();
@@ -607,7 +609,7 @@ try {
607
609
  } finally {
608
610
  }
609
611
  const Mt = new ft("", !0);
610
- var bt = /* @__PURE__ */ ((E) => (E.common = "common", E.container = "container", E.tugs = "tugs", E))(bt || {}), gt = /* @__PURE__ */ ((E) => (E.Ballast = "Ballast", E.Laden = "Laden", E))(gt || {}), wt = /* @__PURE__ */ ((E) => (E.Cp = "CP", E.Perf = "Basis", E.Instruct = "Other", E))(wt || {});
612
+ var bt = /* @__PURE__ */ ((x) => (x.common = "common", x.container = "container", x.tugs = "tugs", x))(bt || {}), gt = /* @__PURE__ */ ((x) => (x.Ballast = "Ballast", x.Laden = "Laden", x))(gt || {}), wt = /* @__PURE__ */ ((x) => (x.Cp = "CP", x.Perf = "Basis", x.Instruct = "Other", x))(wt || {});
611
613
  class O {
612
614
  /**
613
615
  * @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
@@ -622,10 +624,10 @@ class O {
622
624
  * @return [0.55, 0.85]
623
625
  */
624
626
  static blockCoefficient(t, e, a, i) {
625
- let n = Math.round(t / (e * a * i) * 100) / 100;
626
- n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
627
- const o = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = o.map((d) => Math.abs(d - n));
628
- return o[s.indexOf(Math.min(...s))];
627
+ let o = Math.round(t / (e * a * i) * 100) / 100;
628
+ o = o < 0.55 ? 0.55 : o > 0.85 ? 0.85 : o;
629
+ const n = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], s = n.map((d) => Math.abs(d - o));
630
+ return n[s.indexOf(Math.min(...s))];
629
631
  }
630
632
  /**
631
633
  * @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
@@ -659,7 +661,7 @@ class O {
659
661
  0.8: [2.6, -13.1, -15.1],
660
662
  0.85: [3.1, -18.7, 28]
661
663
  };
662
- let o = {
664
+ let n = {
663
665
  0.55: [1.7, -1.4, -7.4],
664
666
  0.6: [2.2, -2.5, -9.7],
665
667
  0.65: [2.6, -3.7, -11.6],
@@ -668,7 +670,7 @@ class O {
668
670
  0.8: [3, -16.3, -21.6],
669
671
  0.85: [3.4, -20.9, 31.8]
670
672
  }[t];
671
- return a === "Laden" && (o = i[t]), o[0] + o[1] * e + o[2] * Math.pow(e, 2);
673
+ return a === "Laden" && (n = i[t]), n[0] + n[1] * e + n[2] * Math.pow(e, 2);
672
674
  }
673
675
  /**
674
676
  * 失速方向因子
@@ -698,8 +700,8 @@ class O {
698
700
  */
699
701
  static vesselTagFactor(t, e, a, i = 0) {
700
702
  i = i > 6 ? i - 0.9 * (i - 6) : i;
701
- let n;
702
- return a === "container" ? n = 0.7 * i + Math.pow(i, 6.5) / (22 * Math.pow(t, 2 / 3)) : e === "Ballast" ? n = 0.7 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(t, 2 / 3)) : n = 0.5 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(t, 2 / 3)), n;
703
+ let o;
704
+ return a === "container" ? o = 0.7 * i + Math.pow(i, 6.5) / (22 * Math.pow(t, 2 / 3)) : e === "Ballast" ? o = 0.7 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(t, 2 / 3)) : o = 0.5 * i + Math.pow(i, 6.5) / (2.7 * Math.pow(t, 2 / 3)), o;
703
705
  }
704
706
  /**
705
707
  * 浪高影响因子
@@ -721,16 +723,16 @@ class O {
721
723
  */
722
724
  static assembleProperties(t, e, a, i) {
723
725
  var l;
724
- const n = t.lbp ?? t.length ?? t.lengthOverall ?? 198.9642, o = t.draught ?? 8, s = t.breadthMoulded ?? t.breadth ?? t.breadthExtreme ?? 32.4572, d = t.deadweight ?? 67035.7773, r = ((l = t == null ? void 0 : t.type) == null ? void 0 : l.toLowerCase()) || "common";
726
+ const o = t.lbp ?? t.length ?? t.lengthOverall ?? 198.9642, n = t.draught ?? 8, s = t.breadthMoulded ?? t.breadth ?? t.breadthExtreme ?? 32.4572, d = t.deadweight ?? 67035.7773, r = ((l = t == null ? void 0 : t.type) == null ? void 0 : l.toLowerCase()) || "common";
725
727
  return {
726
728
  tag: r.indexOf("container") > -1 ? "container" : r.indexOf("tugs") > -1 ? "tugs" : "common",
727
- lbp: n,
729
+ lbp: o,
728
730
  loadCondition: e,
729
- draught: o,
731
+ draught: n,
730
732
  breadthMoulded: s,
731
733
  // 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
732
734
  // 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
733
- displacement: Math.round((d / 1.025 + o * s * n * 0.7) * 1e4) / 1e4,
735
+ displacement: Math.round((d / 1.025 + n * s * o * 0.7) * 1e4) / 1e4,
734
736
  // 换算为m/s
735
737
  speed: Math.round((a ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
736
738
  bearing: i || 90
@@ -746,9 +748,9 @@ class O {
746
748
  * @param useMeteo true 启用气象分析
747
749
  * @param useRouteParam true 启用设置速度
748
750
  */
749
- static async speedLoseAt(t, e, a, i = "", n = 2, o = !0, s = !1, d = {}) {
751
+ static async speedLoseAt(t, e, a, i = "", o = 2, n = !0, s = !1, d = {}) {
750
752
  let r;
751
- if (e.velocity && s && (t.speed = J.roundPrecision(e.velocity * 1852 / 3600, 6)), o) {
753
+ if (e.velocity && s && (t.speed = J.roundPrecision(e.velocity * 1852 / 3600, 6)), n) {
752
754
  let m;
753
755
  try {
754
756
  i = (i == null ? void 0 : i.toUpperCase()) === "CMEMS" ? "ECMWF" : i, i = (i == null ? void 0 : i.toUpperCase()) === "METEO2" ? "best_match" : i;
@@ -763,7 +765,7 @@ class O {
763
765
  } catch (f) {
764
766
  F.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...e, eta: a.utc().format(), source: i }, f);
765
767
  }
766
- const M = O.weatherFactor(t, m), l = O.currentFactor(t.bearing, m == null ? void 0 : m.current, n), b = Math.round((t.speed * 1.943844 + M + l) * 100) / 100;
768
+ const M = O.weatherFactor(t, m), l = O.currentFactor(t.bearing, m == null ? void 0 : m.current, o), b = Math.round((t.speed * 1.943844 + M + l) * 100) / 100;
767
769
  r = {
768
770
  meteo: { ...m },
769
771
  wxFactor: M,
@@ -795,14 +797,14 @@ class O {
795
797
  * @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
796
798
  * @private
797
799
  */
798
- static async speedLoseInHoursStep(t, e, a, i, n, o, s = "", d = !0, r = !1, m = {}) {
800
+ static async speedLoseInHoursStep(t, e, a, i, o, n, s = "", d = !0, r = !1, m = {}) {
799
801
  e.utc();
800
802
  const M = e.clone().add(14, "days"), l = [], b = [];
801
803
  let f = 0, C = 0, S, p;
802
- for (let w = 0; w < o.length - 1; w++) {
803
- let c = o[w];
804
- c.distanceFromStart = Math.round((n + C) * 1e3) / 1e3;
805
- const y = o[w + 1];
804
+ for (let w = 0; w < n.length - 1; w++) {
805
+ let c = n[w];
806
+ c.distanceFromStart = Math.round((o + C) * 1e3) / 1e3;
807
+ const y = n[w + 1];
806
808
  if (t.bearing = W.calculateBearing(c, y, !y.gcToPrevious), c.bearing = t.bearing, c.suspend && r) {
807
809
  c.eta = c.eta || e.utc().format(), c.elapsed = c.elapsed ?? 0;
808
810
  const I = c.suspend - c.elapsed;
@@ -813,35 +815,35 @@ class O {
813
815
  c.elapsed += k, e.add(k, "hour"), i = 0;
814
816
  }
815
817
  if (F == null || F.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`, m.requestId, c), i === 0)
816
- return c.distanceFromPrevious = C, { etd: e, from: p || c, to: c, next: o.filter((k) => k), wps: l, days: b };
818
+ return c.distanceFromPrevious = C, { etd: e, from: p || c, to: c, next: n.filter((k) => k), wps: l, days: b };
817
819
  } else
818
820
  c.suspend = 0;
819
821
  d = e.isAfter(M) ? !1 : d, c = await O.speedLoseAt(t, c, e, s, 0, d, r, m), p = p || c, c.important && l.push(c), e.isSameOrAfter(a) && (b.push(c), a.add(24, "hour"));
820
822
  const h = W.calculateDistance(c, y, !y.gcToPrevious);
821
823
  let u = Math.round(h / p.speed * 1e5) / 1e5;
822
824
  if (f + u < i) {
823
- if (f += u, e.add(u, "hour"), delete o[w], F == null || F.debug(
825
+ if (f += u, e.add(u, "hour"), delete n[w], F == null || F.debug(
824
826
  `[%s] go to %j from %j with ${h}nm, and cost ${u} hours`,
825
827
  m.requestId,
826
828
  { lat: y.lat, lng: y.lng },
827
829
  { lat: p.lat, lng: p.lng, etd: p.etd }
828
- ), C += h, o.filter((I) => I).length <= 1) {
829
- S = y, S.eta = e.utc().format(), S.distanceFromPrevious = h, S.distanceFromStart = Math.round((n + C) * 1e4) / 1e4, l.push(S), delete o[w + 1];
830
+ ), C += h, n.filter((I) => I).length <= 1) {
831
+ S = y, S.eta = e.utc().format(), S.distanceFromPrevious = h, S.distanceFromStart = Math.round((o + C) * 1e4) / 1e4, l.push(S), delete n[w + 1];
830
832
  break;
831
833
  }
832
834
  } else {
833
835
  u = i - f, e.add(u, "hour");
834
836
  const I = J.roundPrecision(p.speed * u, 5);
835
- S = W.calculateCoordinate(c, t.bearing, I, "nauticalmiles", !y.gcToPrevious), S.eta = e.utc().format(), o[w] = S, F == null || F.debug(
837
+ S = W.calculateCoordinate(c, t.bearing, I, "nauticalmiles", !y.gcToPrevious), S.eta = e.utc().format(), n[w] = S, F == null || F.debug(
836
838
  `[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,
837
839
  m.requestId,
838
840
  { lat: S.lat, lng: S.lng },
839
841
  { lat: c.lat, lng: c.lng, etd: c.etd }
840
- ), C += I, S.distanceFromPrevious = Math.round(C * 1e4) / 1e4, S.distanceFromStart = Math.round((n + C) * 1e4) / 1e4;
842
+ ), C += I, S.distanceFromPrevious = Math.round(C * 1e4) / 1e4, S.distanceFromStart = Math.round((o + C) * 1e4) / 1e4;
841
843
  break;
842
844
  }
843
845
  }
844
- return { etd: e, from: p, to: S, next: o.filter((w) => w), wps: l, days: b };
846
+ return { etd: e, from: p, to: S, next: n.filter((w) => w), wps: l, days: b };
845
847
  }
846
848
  /**
847
849
  * 洋流影响因子
@@ -853,8 +855,8 @@ class O {
853
855
  const i = (t - (e == null ? void 0 : e.degree) || 0) / 180 * Math.PI;
854
856
  if (Math.abs(i) === Math.PI / 2)
855
857
  return 0;
856
- let n = ((e == null ? void 0 : e.kts) || 0) * Math.cos(i);
857
- return a & 2 ? n = Math.ceil(n * 100) / 100 : a & 1 ? n = Math.floor(n * 100) / 100 : n = Math.round(n * 100) / 100, Math.abs(n) > 5 ? 0 : n;
858
+ let o = ((e == null ? void 0 : e.kts) || 0) * Math.cos(i);
859
+ return a & 2 ? o = Math.ceil(o * 100) / 100 : a & 1 ? o = Math.floor(o * 100) / 100 : o = Math.round(o * 100) / 100, Math.abs(o) > 5 ? 0 : o;
858
860
  }
859
861
  /**
860
862
  * 风浪影响因子
@@ -864,13 +866,13 @@ class O {
864
866
  static weatherFactor(t, e) {
865
867
  var M, l, b, f, C, S, p;
866
868
  F == null || F.debug("calculate weather factor via: %j", { ...t, ...e });
867
- const a = O.blockCoefficient(t.displacement, t.lbp, t.breadthMoulded, t.draught), i = O.froudeNumber(t.speed, t.lbp), n = O.amendFactor(a, i, t.loadCondition);
868
- let o = Math.abs(t.bearing % 360 - (((M = e == null ? void 0 : e.wind) == null ? void 0 : M.degree) % 360 || 0));
869
- o = o > 180 ? 360 - o : o;
870
- const s = O.directionFactor(o, (l = e == null ? void 0 : e.wind) == null ? void 0 : l.scale), d = O.vesselTagFactor(t.displacement, t.loadCondition, t.tag, (b = e == null ? void 0 : e.wind) == null ? void 0 : b.scale);
871
- let r = s * n * d / 100 * t.speed;
872
- r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, t.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r), o = Math.abs(t.bearing % 360 - (((C = (f = e == null ? void 0 : e.wave) == null ? void 0 : f.sig) == null ? void 0 : C.degree) % 360 || 0));
873
- const m = O.waveHeightFactor(((p = (S = e == null ? void 0 : e.wave) == null ? void 0 : S.sig) == null ? void 0 : p.height) ?? 1, o);
869
+ const a = O.blockCoefficient(t.displacement, t.lbp, t.breadthMoulded, t.draught), i = O.froudeNumber(t.speed, t.lbp), o = O.amendFactor(a, i, t.loadCondition);
870
+ let n = Math.abs(t.bearing % 360 - (((M = e == null ? void 0 : e.wind) == null ? void 0 : M.degree) % 360 || 0));
871
+ n = n > 180 ? 360 - n : n;
872
+ const s = O.directionFactor(n, (l = e == null ? void 0 : e.wind) == null ? void 0 : l.scale), d = O.vesselTagFactor(t.displacement, t.loadCondition, t.tag, (b = e == null ? void 0 : e.wind) == null ? void 0 : b.scale);
873
+ let r = s * o * d / 100 * t.speed;
874
+ r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1, t.tag === "tugs" && Math.abs(r) > 1 && (r = r / (Math.abs(Math.round(r)) + 1)), F == null || F.debug("wind wx factor = %d", r), n = Math.abs(t.bearing % 360 - (((C = (f = e == null ? void 0 : e.wave) == null ? void 0 : f.sig) == null ? void 0 : C.degree) % 360 || 0));
875
+ const m = O.waveHeightFactor(((p = (S = e == null ? void 0 : e.wave) == null ? void 0 : S.sig) == null ? void 0 : p.height) ?? 1, n);
874
876
  return F == null || F.debug("wave wx factor = %d", m), r = Math.abs(r) > Math.abs(m) ? r : r * 0.3 + m * 0.7, F == null || F.debug("weather factor = %d", r), r = Math.abs(r) > 3 ? 3 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 2) * 0.1 : r, Math.round((r || 0) * 100) / 100;
875
877
  }
876
878
  /**
@@ -885,11 +887,11 @@ class O {
885
887
  * @param useMeteo true 启用气象分析
886
888
  * @param useRouteParam
887
889
  */
888
- static async analyseInstant(t, e, a, i, n, o = "", s = 0, d = !0, r = !1, m = {}) {
889
- var z, G, Q, X, Z, $;
890
+ static async analyseInstant(t, e, a, i, o, n = "", s = 0, d = !0, r = !1, m = {}) {
891
+ var z, G, X, Q, Z, $;
890
892
  const M = g().valueOf();
891
893
  t.lng = J.convertToStdLng(t.lng);
892
- const { route: l, waypoints: b } = n.points, f = W.calculateSubRoute(t, l);
894
+ const { route: l, waypoints: b } = o.points, f = W.calculateSubRoute(t, l);
893
895
  if (((z = f[0]) == null ? void 0 : z.length) <= 1)
894
896
  return;
895
897
  const { v0: C, label: S } = t.sog ? {
@@ -918,42 +920,42 @@ class O {
918
920
  e = g(e).utc();
919
921
  const Y = e.clone();
920
922
  for (; h.length > 0; ) {
921
- const q = s - e.hour() % s, V = Math.ceil(e.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4, x = await O.speedLoseInHoursStep(
923
+ const q = s - e.hour() % s, V = Math.ceil(e.clone().add(q, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4, E = await O.speedLoseInHoursStep(
922
924
  p,
923
925
  e,
924
926
  Y,
925
927
  V,
926
928
  u,
927
929
  h,
928
- o,
930
+ n,
929
931
  d,
930
932
  r,
931
933
  m
932
934
  );
933
- (G = x.from) != null && G.speed && (y.hours.push(x.from), y.wps.push(...x.wps), y.days.push(...x.days)), h = x == null ? void 0 : x.next, h.length || y.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;
935
+ (G = E.from) != null && G.speed && (y.hours.push(E.from), y.wps.push(...E.wps), y.days.push(...E.days)), h = E == null ? void 0 : E.next, h.length || y.hours.push(E == null ? void 0 : E.to), u += Math.round((((X = E == null ? void 0 : E.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
934
936
  }
935
937
  const j = y.hours;
936
938
  for (let q = 0; q < j.length - 1; q++) {
937
939
  const V = g(j[q + 1].eta).diff(j[q].etd, "hour", !0) || 1;
938
940
  I += (j[q].wxFactor || 0) * V, k += (j[q].cFactor || 0) * V, D += V;
939
941
  }
940
- (X = y.wps) == null || X.forEach((q, V) => {
942
+ (Q = y.wps) == null || Q.forEach((q, V) => {
941
943
  q.positionTime = g.utc(q.etd || q.eta).unix();
942
- const x = y.wps[V - 1];
943
- if (x) {
944
- const L = q.distanceFromStart - x.distanceFromStart, H = g(q.eta || q.etd).diff(g(x.etd || x.eta), "h", !0);
944
+ const E = y.wps[V - 1];
945
+ if (E) {
946
+ const L = q.distanceFromStart - E.distanceFromStart, H = g(q.eta || q.etd).diff(g(E.etd || E.eta), "h", !0);
945
947
  q.avgSpd = Math.round(L / H * 100) / 100;
946
- const it = W.calculateBearing(x, q);
947
- x.bearing = it;
948
+ const it = W.calculateBearing(E, q);
949
+ E.bearing = it;
948
950
  }
949
- }), y.wps = (Z = y.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((x) => Math.round(x.positionTime / 60) === Math.round(V.positionTime / 60)) || q.push(V), q), []), c.sample = y;
950
- const P = y.hours.at(0), T = y.hours.at(-1);
951
- c.distance = Math.round(T.distanceFromStart * 1e3) / 1e3, c.etd = g(P.eta).utc().format(), c.eta = g(T.eta).utc().format(), c.wxFactor = Math.round(I / D * 1e3) / 1e3, c.cFactor = Math.round(k / D * 1e3) / 1e3, c.avgSpeed = Math.round(T.distanceFromStart / D * 1e3) / 1e3, c.totalHrs = Math.round(D * 1e3) / 1e3;
952
- const { distanceInECA: N, hoursInECA: A, totalDgoConsInECA: R, eca: U } = await this.calculateECA(c, i, m), tt = J.roundPrecision(i.fo / 24 * (D - A), 3), at = J.roundPrecision(i.dgo / 24 * D, 3);
951
+ }), y.wps = (Z = y.wps) == null ? void 0 : Z.reduce((q, V) => (q.some((E) => Math.round(E.positionTime / 60) === Math.round(V.positionTime / 60)) || q.push(V), q), []), c.sample = y;
952
+ const A = y.hours.at(0), T = y.hours.at(-1);
953
+ c.distance = Math.round(T.distanceFromStart * 1e3) / 1e3, c.etd = g(A.eta).utc().format(), c.eta = g(T.eta).utc().format(), c.wxFactor = Math.round(I / D * 1e3) / 1e3, c.cFactor = Math.round(k / D * 1e3) / 1e3, c.avgSpeed = Math.round(T.distanceFromStart / D * 1e3) / 1e3, c.totalHrs = Math.round(D * 1e3) / 1e3;
954
+ const { distanceInECA: N, hoursInECA: P, totalDgoConsInECA: R, eca: U } = await this.calculateECA(c, i, m), tt = J.roundPrecision(i.fo / 24 * (D - P), 3), at = J.roundPrecision(i.dgo / 24 * D, 3);
953
955
  c.extend = {
954
956
  eca: U,
955
957
  distanceInECA: N,
956
- hoursInECA: A,
958
+ hoursInECA: P,
957
959
  totalDgoConsInECA: R
958
960
  }, c.totalFoCons = tt < 0 ? 0 : tt, c.totalDgoCons = at;
959
961
  const et = g().valueOf() - M, nt = (($ = y == null ? void 0 : y.hours) == null ? void 0 : $.length) || 1;
@@ -972,8 +974,8 @@ class O {
972
974
  * @param useMeteo true 启用气象分析
973
975
  * @param useRouteParam
974
976
  */
975
- static async analyseInstantWithThreshed(t, e, a, i, n, o, s, d = "", r = 3, m = !0, M = !1, l = {}) {
976
- var Q, X, Z, $, q, V;
977
+ static async analyseInstantWithThreshed(t, e, a, i, o, n, s, d = "", r = 3, m = !0, M = !1, l = {}) {
978
+ var X, Q, Z, $, q, V;
977
979
  const b = g().valueOf();
978
980
  t.lng = J.convertToStdLng(t.lng);
979
981
  const { v0: f, label: C } = t.sog ? {
@@ -981,14 +983,14 @@ class O {
981
983
  label: t.label || "Other"
982
984
  /* Instruct */
983
985
  } : {
984
- v0: n.speed,
986
+ v0: o.speed,
985
987
  label: "CP"
986
988
  /* Cp */
987
- }, S = O.assembleProperties(i, n.loadCondition, f, 0), p = W.calculateSubRoute(t, o);
988
- if (((Q = p[0]) == null ? void 0 : Q.length) <= 1)
989
+ }, S = O.assembleProperties(i, o.loadCondition, f, 0), p = W.calculateSubRoute(t, n);
990
+ if (((X = p[0]) == null ? void 0 : X.length) <= 1)
989
991
  return;
990
992
  const w = s.length ? W.calculateSubWaypoints(t, s) : [];
991
- w.forEach((x) => x.important = !0);
993
+ w.forEach((E) => E.important = !0);
992
994
  let c = W.simplifyRouteToCoordinates(p, w, 0), y = 0, h = 0, u = 0, I = 0;
993
995
  const k = {
994
996
  hours: [],
@@ -998,52 +1000,52 @@ class O {
998
1000
  e = g(e).utc();
999
1001
  const D = e.clone();
1000
1002
  for (; c.length > 0; ) {
1001
- const x = r - e.hour() % r;
1002
- let L = Math.ceil(e.clone().add(x, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4;
1003
+ const E = r - e.hour() % r;
1004
+ let L = Math.ceil(e.clone().add(E, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(e, "h", !0) * 1e4) / 1e4;
1003
1005
  L = e.clone().add(L, "h").isSameOrAfter(a) ? a.diff(e, "h", !0) * 1e4 / 1e4 : L;
1004
1006
  const H = await O.speedLoseInHoursStep(S, e, D, L, y, c, d, m, M, l);
1005
- if ((X = H.from) != null && X.speed && (k.hours.push(H.from), H != null && H.wps && k.wps.push(...H.wps), k.days.push(...H.days)), c = H == null ? void 0 : H.next, c.length || k.hours.push(H == null ? void 0 : H.to), y += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1007
+ if ((Q = H.from) != null && Q.speed && (k.hours.push(H.from), H != null && H.wps && k.wps.push(...H.wps), k.days.push(...H.days)), c = H == null ? void 0 : H.next, c.length || k.hours.push(H == null ? void 0 : H.to), y += Math.round((((Z = H == null ? void 0 : H.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1006
1008
  break;
1007
1009
  }
1008
- k.wps = ($ = k.wps) == null ? void 0 : $.reduce((x, L) => (x.some((H) => Math.round(g(H.etd).unix() / 60) === Math.round(g(L.etd).unix() / 60)) || x.push(L), x), []), (q = k.wps) == null || q.forEach((x, L) => {
1010
+ k.wps = ($ = k.wps) == null ? void 0 : $.reduce((E, L) => (E.some((H) => Math.round(g(H.etd).unix() / 60) === Math.round(g(L.etd).unix() / 60)) || E.push(L), E), []), (q = k.wps) == null || q.forEach((E, L) => {
1009
1011
  const H = k.wps[L - 1];
1010
1012
  if (H) {
1011
- const it = x.distanceFromStart - H.distanceFromStart, dt = g(x.eta || x.etd).diff(g(H.etd || H.eta), "h", !0);
1012
- x.avgSpd = Math.round(it / dt * 100) / 100;
1013
- const ut = W.calculateBearing(H, x);
1013
+ const it = E.distanceFromStart - H.distanceFromStart, dt = g(E.eta || E.etd).diff(g(H.etd || H.eta), "h", !0);
1014
+ E.avgSpd = Math.round(it / dt * 100) / 100;
1015
+ const ut = W.calculateBearing(H, E);
1014
1016
  H.bearing = ut;
1015
1017
  }
1016
1018
  });
1017
1019
  const Y = k.hours;
1018
- for (let x = 0; x < Y.length - 1; x++) {
1019
- const L = g(Y[x + 1].eta).diff(Y[x].etd, "hour", !0);
1020
- h += Y[x].wxFactor * L, u += Y[x].cFactor * L, I += L;
1020
+ for (let E = 0; E < Y.length - 1; E++) {
1021
+ const L = g(Y[E + 1].eta).diff(Y[E].etd, "hour", !0);
1022
+ h += Y[E].wxFactor * L, u += Y[E].cFactor * L, I += L;
1021
1023
  }
1022
- const j = k.hours.at(0), P = k.hours.at(-1), T = await W.calculateRangeRoute(j, P, p), N = await W.calculateRangeWaypoints(j, P, p, w), A = {
1024
+ const j = k.hours.at(0), A = k.hours.at(-1), T = await W.calculateRangeRoute(j, A, p), N = await W.calculateRangeWaypoints(j, A, p, w), P = {
1023
1025
  sample: k,
1024
- distance: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) * 1e4) / 1e4,
1026
+ distance: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) * 1e4) / 1e4,
1025
1027
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1026
1028
  etd: g(j.eta).utc().format(),
1027
- eta: g(P == null ? void 0 : P.eta).utc().format(),
1029
+ eta: g(A == null ? void 0 : A.eta).utc().format(),
1028
1030
  wxFactor: Math.round(h / I * 1e3) / 1e3,
1029
1031
  cFactor: Math.round(u / I * 1e3) / 1e3,
1030
- avgSpeed: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) / I * 1e3) / 1e3,
1032
+ avgSpeed: Math.round(((A == null ? void 0 : A.distanceFromStart) || 0) / I * 1e3) / 1e3,
1031
1033
  totalHrs: Math.round(I * 1e3) / 1e3,
1032
1034
  from: j,
1033
- to: P,
1035
+ to: A,
1034
1036
  route: T,
1035
1037
  waypoints: N,
1036
1038
  v0: f,
1037
1039
  label: C
1038
- }, { distanceInECA: R, hoursInECA: U, totalDgoConsInECA: tt, eca: at } = await this.calculateECA(A, n, l), ot = J.roundPrecision(n.fo / 24 * (I - U), 3), et = J.roundPrecision(n.dgo / 24 * I, 3);
1039
- A.extend = {
1040
+ }, { distanceInECA: R, hoursInECA: U, totalDgoConsInECA: tt, eca: at } = await this.calculateECA(P, o, l), ot = J.roundPrecision(o.fo / 24 * (I - U), 3), et = J.roundPrecision(o.dgo / 24 * I, 3);
1041
+ P.extend = {
1040
1042
  eca: at,
1041
1043
  distanceInECA: R,
1042
1044
  hoursInECA: U,
1043
1045
  totalDgoConsInECA: tt
1044
- }, A.totalDgoCons = et, A.totalFoCons = ot < 0 ? 0 : ot;
1046
+ }, P.totalDgoCons = et, P.totalFoCons = ot < 0 ? 0 : ot;
1045
1047
  const z = g().valueOf() - b, G = ((V = k == null ? void 0 : k.hours) == null ? void 0 : V.length) || 1;
1046
- return F == null || F.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, z, G, Math.round(z / G * 1e3) / 1e3), A;
1048
+ return F == null || F.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, z, G, Math.round(z / G * 1e3) / 1e3), P;
1047
1049
  }
1048
1050
  /**
1049
1051
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1060,9 +1062,9 @@ class O {
1060
1062
  * @param lane 基础航线(重要转向点)
1061
1063
  * @param options
1062
1064
  */
1063
- static async analyseCost(t, e, a, i, n = {}) {
1065
+ static async analyseCost(t, e, a, i, o = {}) {
1064
1066
  var p, w;
1065
- const o = g().valueOf(), s = [];
1067
+ const n = g().valueOf(), s = [];
1066
1068
  t.speedStep = t.speedStep || 3, t.alterStep = t.alterStep ?? 1;
1067
1069
  const d = W.calculateRouteDistance(i.route);
1068
1070
  let r = 0;
@@ -1085,9 +1087,9 @@ class O {
1085
1087
  t.speedStep,
1086
1088
  t.useMeteo,
1087
1089
  t.useRouteParam,
1088
- n
1090
+ o
1089
1091
  );
1090
- u && (await O.calculateCost(u, c, t, n), s.push(u), F == null || F.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, M, t.etd, m.format(), {
1092
+ u && (await O.calculateCost(u, c, t, o), s.push(u), F == null || F.info("[%s][L%d-%d] analyse from %s to %s cost: %j", o.requestId, 1, M, t.etd, m.format(), {
1091
1093
  cost: u.cost.total,
1092
1094
  hire: u.cost.hire,
1093
1095
  bunker: u.cost.bunker,
@@ -1104,15 +1106,15 @@ class O {
1104
1106
  k = k > 7 ? 7 : k < t.alterStep ? t.alterStep : k;
1105
1107
  let D = 2, Y = { combined: !1, speeds: [b], cost: (w = b.cost) == null ? void 0 : w.total }, j;
1106
1108
  for (; k >= t.alterStep; ) {
1107
- const P = await O.combinedAnalyse(t, e, m, [c, y], i, k, { ...n, level: D });
1108
- if (Y.cost > P.cost ? j ? (j == null ? void 0 : j.cost) > P.cost && (j = P) : (j = Y, Y = P) : (!j || (j == null ? void 0 : j.cost) > P.cost) && (j = P), k <= t.alterStep)
1109
+ const A = await O.combinedAnalyse(t, e, m, [c, y], i, k, { ...o, level: D });
1110
+ if (Y.cost > A.cost ? j ? (j == null ? void 0 : j.cost) > A.cost && (j = A) : (j = Y, Y = A) : (!j || (j == null ? void 0 : j.cost) > A.cost) && (j = A), k <= t.alterStep)
1109
1111
  break;
1110
1112
  k = Math.ceil(k / 2), D += 1;
1111
1113
  }
1112
1114
  f.push(Y), j && f.push(j);
1113
1115
  }
1114
- const S = g().valueOf() - o;
1115
- return F == null || F.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, S), f.sort((c, y) => c.cost - y.cost);
1116
+ const S = g().valueOf() - n;
1117
+ return F == null || F.info("[%s] analyse elapsed: %d ms", o == null ? void 0 : o.requestId, S), f.sort((c, y) => c.cost - y.cost);
1116
1118
  }
1117
1119
  /**
1118
1120
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1124,9 +1126,9 @@ class O {
1124
1126
  * @param step 步长,7,4,2,1
1125
1127
  * @param options
1126
1128
  */
1127
- static async combinedAnalyse(t, e, a, i, n, o, s = {}) {
1128
- s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, o);
1129
- const d = await O.alternateAnalyse(t, e, a, i, 0, n, o, s), r = d.reduce((y, h) => y + h.cost.total, 0), m = d.reduce((y, h) => y + h.cost.hire, 0), M = d.reduce((y, h) => y + h.cost.bunker, 0), l = d.reduce((y, h) => y + h.distance, 0), b = d.reduce((y, h) => y + h.totalHrs, 0);
1129
+ static async combinedAnalyse(t, e, a, i, o, n, s = {}) {
1130
+ s.counter = 1, F == null || F.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, n);
1131
+ const d = await O.alternateAnalyse(t, e, a, i, 0, o, n, s), r = d.reduce((y, h) => y + h.cost.total, 0), m = d.reduce((y, h) => y + h.cost.hire, 0), M = d.reduce((y, h) => y + h.cost.bunker, 0), l = d.reduce((y, h) => y + h.distance, 0), b = d.reduce((y, h) => y + h.totalHrs, 0);
1130
1132
  F == null || F.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1131
1133
  cost: r,
1132
1134
  hire: m,
@@ -1134,14 +1136,14 @@ class O {
1134
1136
  distance: l,
1135
1137
  hours: b
1136
1138
  });
1137
- const f = await O.alternateAnalyse(t, e, a, i, 1, n, o, s), C = f.reduce((y, h) => y + h.cost.total, 0), S = f.reduce((y, h) => y + h.cost.hire, 0), p = f.reduce((y, h) => y + h.cost.bunker, 0), w = f.reduce((y, h) => y + h.distance, 0), c = f.reduce((y, h) => y + h.totalHrs, 0);
1139
+ const f = await O.alternateAnalyse(t, e, a, i, 1, o, n, s), C = f.reduce((y, h) => y + h.cost.total, 0), S = f.reduce((y, h) => y + h.cost.hire, 0), p = f.reduce((y, h) => y + h.cost.bunker, 0), w = f.reduce((y, h) => y + h.distance, 0), c = f.reduce((y, h) => y + h.totalHrs, 0);
1138
1140
  return F == null || F.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1139
1141
  cost: C,
1140
1142
  hire: S,
1141
1143
  bunker: p,
1142
1144
  distance: w,
1143
1145
  hours: c
1144
- }), r < C ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: o } : { combined: !0, cost: Math.round(C * 1e3) / 1e3, speeds: f, step: o };
1146
+ }), r < C ? { combined: !0, cost: Math.round(r * 1e3) / 1e3, speeds: d, step: n } : { combined: !0, cost: Math.round(C * 1e3) / 1e3, speeds: f, step: n };
1145
1147
  }
1146
1148
  /**
1147
1149
  * 基于cp索引,交替计算指定步长下的成本
@@ -1154,12 +1156,12 @@ class O {
1154
1156
  * @param step 步长,7,4,2,1
1155
1157
  * @param options
1156
1158
  */
1157
- static async alternateAnalyse(t, e, a, i, n, o, s, d = {}) {
1159
+ static async alternateAnalyse(t, e, a, i, o, n, s, d = {}) {
1158
1160
  var l, b;
1159
1161
  let r = g.utc(t.etd);
1160
1162
  const m = { lat: t.lat, lng: t.lng }, M = [];
1161
1163
  for (; r.isBefore(a); ) {
1162
- const f = r.clone().utc().add(s, "day"), C = JSON.parse(JSON.stringify(o.route)), S = JSON.parse(JSON.stringify(o.waypoints)), p = i[n], w = await O.analyseInstantWithThreshed(
1164
+ const f = r.clone().utc().add(s, "day"), C = JSON.parse(JSON.stringify(n.route)), S = JSON.parse(JSON.stringify(n.waypoints)), p = i[o], w = await O.analyseInstantWithThreshed(
1163
1165
  m,
1164
1166
  r.utc().format(),
1165
1167
  f,
@@ -1191,7 +1193,7 @@ class O {
1191
1193
  )), d.counter = d.counter + 1;
1192
1194
  const c = (b = (l = w == null ? void 0 : w.sample) == null ? void 0 : l.hours) == null ? void 0 : b.at(-1);
1193
1195
  if (c)
1194
- m.lat = c.lat, m.lng = c.lng, r = g(c.eta), M.push(w), n = n ? 0 : 1;
1196
+ m.lat = c.lat, m.lng = c.lng, r = g(c.eta), M.push(w), o = o ? 0 : 1;
1195
1197
  else
1196
1198
  break;
1197
1199
  }
@@ -1205,9 +1207,9 @@ class O {
1205
1207
  * @param options
1206
1208
  */
1207
1209
  static async calculateCost(t, e, a, i = {}) {
1208
- var n;
1210
+ var o;
1209
1211
  if (t) {
1210
- const o = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, s = Math.round(t.totalHrs / 24 * (a.dailyHire || 0) * (1 - o) * 1e3) / 1e3, d = Math.round(t.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, r = Math.round((t.totalDgoCons + (((n = t.extend) == null ? void 0 : n.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
1212
+ const n = (a.addComm || 0) >= 1 ? (a.addComm || 0) / 100 : a.addComm || 0, s = Math.round(t.totalHrs / 24 * (a.dailyHire || 0) * (1 - n) * 1e3) / 1e3, d = Math.round(t.totalFoCons * (a.priceFO || 0) * 1e3) / 1e3, r = Math.round((t.totalDgoCons + (((o = t.extend) == null ? void 0 : o.totalDgoConsInECA) || 0)) * (a.priceDGO || 0) * 1e3) / 1e3;
1211
1213
  t.cost = {
1212
1214
  total: Math.round((s + d + r) * 1e3) / 1e3,
1213
1215
  hire: s,
@@ -1224,18 +1226,18 @@ class O {
1224
1226
  static async calculateECA(t, e, a = {}) {
1225
1227
  var d, r, m, M;
1226
1228
  const i = await W.intersectInECA((t == null ? void 0 : t.route) || []);
1227
- let n = 0, o = 0, s = 0;
1229
+ let o = 0, n = 0, s = 0;
1228
1230
  (r = (d = t == null ? void 0 : t.sample) == null ? void 0 : d.wps) == null || r.forEach((l) => {
1229
1231
  l.positionTime = g.utc(l.etd || l.eta).unix();
1230
1232
  });
1231
1233
  for (const l of i) {
1232
- n += l.distance;
1234
+ o += l.distance;
1233
1235
  const b = await W.deadReckoningTime((m = l.waypoints) == null ? void 0 : m.at(0), t.sample.wps), f = await W.deadReckoningTime((M = l.waypoints) == null ? void 0 : M.at(-1), t.sample.wps);
1234
- l.in = b, l.out = f, l.totalHrs = J.roundPrecision((f.positionTime - b.positionTime) / 3600, 3), l.totalDgoCons = J.roundPrecision(e.fo / 24 * l.totalHrs, 3), o += l.totalHrs, s += l.totalDgoCons;
1236
+ l.in = b, l.out = f, l.totalHrs = J.roundPrecision((f.positionTime - b.positionTime) / 3600, 3), l.totalDgoCons = J.roundPrecision(e.fo / 24 * l.totalHrs, 3), n += l.totalHrs, s += l.totalDgoCons;
1235
1237
  }
1236
- return n = J.roundPrecision(n, 3), o = J.roundPrecision(o, 3), s = J.roundPrecision(s, 3), {
1237
- distanceInECA: n,
1238
- hoursInECA: o,
1238
+ return o = J.roundPrecision(o, 3), n = J.roundPrecision(n, 3), s = J.roundPrecision(s, 3), {
1239
+ distanceInECA: o,
1240
+ hoursInECA: n,
1239
1241
  totalDgoConsInECA: s,
1240
1242
  eca: i
1241
1243
  };
@@ -1251,16 +1253,16 @@ class O {
1251
1253
  hours: [],
1252
1254
  wps: [],
1253
1255
  days: []
1254
- }, i = t.reduce((h, u) => h + u.distance, 0), n = t.reduce((h, u) => {
1256
+ }, i = t.reduce((h, u) => h + u.distance, 0), o = t.reduce((h, u) => {
1255
1257
  var I;
1256
1258
  return h + (((I = u.extend) == null ? void 0 : I.distanceInECA) || 0);
1257
- }, 0), o = t.reduce((h, u) => h + u.totalHrs, 0), s = t.reduce((h, u) => {
1259
+ }, 0), n = t.reduce((h, u) => h + u.totalHrs, 0), s = t.reduce((h, u) => {
1258
1260
  var I;
1259
1261
  return h + (((I = u.extend) == null ? void 0 : I.hoursInECA) || 0);
1260
1262
  }, 0), d = t.reduce((h, u) => {
1261
1263
  var I;
1262
1264
  return h + (((I = u.extend) == null ? void 0 : I.totalDgoConsInECA) || 0);
1263
- }, 0), r = t.reduce((h, u) => h + u.wxFactor * u.totalHrs / o, 0), m = t.reduce((h, u) => h + u.cFactor * u.totalHrs / o, 0), M = t.reduce((h, u) => h + u.totalFoCons, 0), l = t.reduce((h, u) => h + u.totalDgoCons, 0), b = t.reduce((h, u) => h + u.cost.total, 0), f = t.reduce((h, u) => h + u.cost.hire, 0), C = t.reduce((h, u) => h + u.cost.bunker, 0), S = [], p = [];
1265
+ }, 0), r = t.reduce((h, u) => h + u.wxFactor * u.totalHrs / n, 0), m = t.reduce((h, u) => h + u.cFactor * u.totalHrs / n, 0), M = t.reduce((h, u) => h + u.totalFoCons, 0), l = t.reduce((h, u) => h + u.totalDgoCons, 0), b = t.reduce((h, u) => h + u.cost.total, 0), f = t.reduce((h, u) => h + u.cost.hire, 0), C = t.reduce((h, u) => h + u.cost.bunker, 0), S = [], p = [];
1264
1266
  let w;
1265
1267
  for (const h of t) {
1266
1268
  p.push(...((c = h.extend) == null ? void 0 : c.eca) || []);
@@ -1274,17 +1276,17 @@ class O {
1274
1276
  })), D.cp = h.cost.cp;
1275
1277
  const Y = [h.etd, h.eta], j = S.findIndex((T) => T.id === D.cp.id);
1276
1278
  j === -1 ? (D.cp.segment = [Y], S.push(D.cp)) : S[j].segment.push(Y), u.forEach((T) => {
1277
- var A;
1278
- ((A = a.hours) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && a.hours.push(T);
1279
+ var P;
1280
+ ((P = a.hours) == null ? void 0 : P.findIndex((R) => R.eta === T.eta)) === -1 && a.hours.push(T);
1279
1281
  }), I.forEach((T) => {
1280
- var A;
1281
- ((A = a.wps) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && a.wps.push(T);
1282
+ var P;
1283
+ ((P = a.wps) == null ? void 0 : P.findIndex((R) => R.eta === T.eta)) === -1 && a.wps.push(T);
1282
1284
  }), k.forEach((T) => {
1283
- var A;
1284
- ((A = a == null ? void 0 : a.days) == null ? void 0 : A.findIndex((R) => R.eta === T.eta)) === -1 && a.days.push(T);
1285
+ var P;
1286
+ ((P = a == null ? void 0 : a.days) == null ? void 0 : P.findIndex((R) => R.eta === T.eta)) === -1 && a.days.push(T);
1285
1287
  });
1286
- const P = (y = a.wps) == null ? void 0 : y.findIndex((T) => T.eta === D.eta);
1287
- P === -1 ? a.wps.push(D) : a.wps[P] = D, w = u.at(-1);
1288
+ const A = (y = a.wps) == null ? void 0 : y.findIndex((T) => T.eta === D.eta);
1289
+ A === -1 ? a.wps.push(D) : a.wps[A] = D, w = u.at(-1);
1288
1290
  }
1289
1291
  return a.wps.sort((h, u) => {
1290
1292
  g(h.etd).unix() - g(u.etd).unix();
@@ -1305,8 +1307,8 @@ class O {
1305
1307
  v0: t.at(0).v0,
1306
1308
  label: "Combined",
1307
1309
  distance: Math.round(i * 1e3) / 1e3,
1308
- totalHrs: Math.round(o * 1e3) / 1e3,
1309
- avgSpeed: Math.round(i / o * 1e3) / 1e3,
1310
+ totalHrs: Math.round(n * 1e3) / 1e3,
1311
+ avgSpeed: Math.round(i / n * 1e3) / 1e3,
1310
1312
  wxFactor: Math.round(r * 1e3) / 1e3,
1311
1313
  cFactor: Math.round(m * 1e3) / 1e3,
1312
1314
  totalFoCons: Math.round(M * 1e3) / 1e3,
@@ -1319,7 +1321,7 @@ class O {
1319
1321
  extend: {
1320
1322
  cps: S,
1321
1323
  eca: p,
1322
- distanceInECA: Math.round(n * 1e3) / 1e3,
1324
+ distanceInECA: Math.round(o * 1e3) / 1e3,
1323
1325
  hoursInECA: Math.round(s * 1e3) / 1e3,
1324
1326
  totalDgoConsInECA: Math.round(d * 1e3) / 1e3,
1325
1327
  speeds: t
@@ -1331,10 +1333,10 @@ export {
1331
1333
  st as AISImpl,
1332
1334
  yt as AlertHelper,
1333
1335
  mt as AlertLevel,
1334
- Et as HifleetImpl,
1336
+ xt as HifleetImpl,
1335
1337
  gt as LoadCondition,
1336
1338
  Nt as MyShipImpl,
1337
- xt as MyVesselImpl,
1339
+ Et as MyVesselImpl,
1338
1340
  jt as ShipxyImpl,
1339
1341
  O as SpeedHelper,
1340
1342
  wt as SpeedLabel,
@@ -1 +1 @@
1
- (function(A,R){typeof exports=="object"&&typeof module<"u"?R(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"],R):(A=typeof globalThis<"u"?globalThis:A||self,R(A["idm-plugin-vessel"]={},A.got,A["@log4js-node/log4js-api"],A.moment,A["@idm-plugin/geo2"],A["@idm-plugin/meteo2"],A["@idm-plugin/meteo"]))})(this,function(A,R,K,p,T,mt,nt){"use strict";var St=Object.defineProperty;var kt=(A,R,K)=>R in A?St(A,R,{enumerable:!0,configurable:!0,writable:!0,value:K}):A[R]=K;var z=(A,R,K)=>(kt(A,typeof R!="symbol"?R+"":R,K),K);let g;try{g=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(t){let e,a;switch(t){case 0:e="在航(主机推动)",a="Underway Using Engine";break;case 1:e="锚泊",a="Anchored";break;case 2:e="失控",a="Not operated";break;case 3:e="操纵受限",a="Limited airworthiness";break;case 4:e="吃水受限",a="Limited by ship's draft";break;case 5:e="靠泊",a="Mooring";break;case 6:e="搁浅",a="Stranded";break;case 7:e="捕捞作业",a="Engaged in fishing";break;case 8:e="靠帆船提供动力",a="Sailing";break;default:e="未定义",a="Undefined"}return{labelCn:e,labelEn:a}}}class yt extends G{constructor(e,a){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=e,this.clientSecret=a}async authToken(e={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await R.post(a,i).json();g==null||g.info("[%s] fetch access token from: %s - %j",e.requestId,a,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:p().utc().format()})}async realTimePosition(e,a={}){var d,r,m;(!this.token||p().diff(p(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(m=this.token)==null?void 0:m.accessToken}`},searchParams:{mmsi:e}};g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,o);const n=await R.get(i,o).json();if(n.code)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,{message:n.message,status:n.status,code:n.code}),n;const s=n.data;for(const M in s)!isNaN(s[M])&&Number(s[M])!==1/0&&(s[M]=Number(s[M]));if(s){const M=p(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?p.utc(s.eta).format():void 0,destination:s.dest,positionTime:M.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:M.utc().format()}}else return{}}async trajectory(e,a,i,o,n=!0,s={}){(!this.token||p().diff(p(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M=[];for(;m.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(e,r,r.clone().add(30,"day"),d,o,M,s),r.add(30,"day");return await this.trajectoryIn30Day(e,r,m,d,o,M,s),M}async trajectoryIn30Day(e,a,i,o,n,s,d={}){var f,C,k,w,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",m={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(C=this.token)==null?void 0:C.accessToken}`},json:{mmsi:e,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};g==null||g.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,m);const M=await R.post(r,m).json();if(M.code)return g==null||g.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:M.message,status:M.status,code:M.code}),M;let h=-1;const b=p(`${(w=(k=M.data)==null?void 0:k[0])==null?void 0:w.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 y=p(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),l=c.status,{labelCn:u,labelEn:I}=this.parseStatus(l),F={mmsi:c.mmsi,imo:o==null?void 0:o.imo,lat:c.lat,lng:c.lon,sog:c.sog,cog:c.cog,hdg:c.hdg,draught:c.draught,status:l,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,destination:c.dest,positionTime:y.unix(),labelCn:u,labelEn:I,method:"trajectory",vendor:"myVessel",utc:y.utc().format()},N=Math.floor(y.diff(b,"minute",!0)/(n||1));N!==h&&(h=N,s.push(F))}),s}}class Mt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:e,usertoken:this.token}},n=await R.post(i,o).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,o);const s=n==null?void 0:n.list;if(!s)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,n),n;for(const b in s)!isNaN(s[b])&&Number(s[b])!==1/0&&(s[b]=Number(s[b]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:m}=this.parseStatus(d),M=p(`${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)?p.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:M.unix(),utc:M.utc().format(),status:d,labelCn:r,labelEn:m,method:"position",vendor:"hifleet"}}async search(e,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let n=await R.post(i,o).json();g==null||g.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,o),n instanceof Array&&(n=n[0]);for(const d in n)!isNaN(n[d])&&Number(n[d])!==1/0&&(n[d]=Number(n[d]));const s={mmsi:n.m,name:n.n,imo:n.i,callSign:n.c,length:n.l,breadth:n.b,draught:n.dr,type:n.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",n=await R.post(i,o).json(),g==null||g.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,o),n instanceof Array&&(n=n[0]),n&&(s.deadweight=Number(n.dwt)),s}async suggest(e,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",o={searchParams:{q:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},n=await R.post(i,o).json();g==null||g.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,o);const s=[];for(const d of n)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(e,a,i,o,n=!0,s={}){var c,y,l;const d=await this.realTimePosition(e,s);let r=p(a);const m=p(i),M=p();if(n){let u=m.diff(r,"d",!0);u<0?r=m.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=m.clone().subtract(80,"d"),u=M.diff(m,"d",!0),m.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:e,usertoken:this.token}},b="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await R.get(b,h).json();g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,b,h);let C;f&&(C=((y=(c=f.ships)==null?void 0:c.offors)==null?void 0:y.ship)||[],C.length||g==null||g.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const k=[];let w=-1;const v=p(`${(l=C==null?void 0:C[0])==null?void 0:l.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of C){for(const L in u)!isNaN(u[L])&&Number(u[L])!==1/0&&(u[L]=Number(u[L]));const I=p(`${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"},E=Math.floor(I.diff(v,"minute",!0)/(o||1));E!==w&&(w=E,k.push(P))}return k}}class pt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i={searchParams:{id:e,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",n=await R.get(o,i).json();if(g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,i),(n==null?void 0:n.status)!==0)return n;const s=n.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),m=p.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:m.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(e,a,i,o,n=!0,s={}){var v;const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:e,k:this.token,enc:1,cut:0,btm:r.unix(),etm:m.unix()}},b=await R.get(M,h).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,M,h),(b==null?void 0:b.status)!==0)return b;const f=b==null?void 0:b.points,C=[],k=p.unix((v=f[0])==null?void 0:v.utc);let w=-1;for(const c of f){const y=p.unix(c.utc),l={imo:d==null?void 0:d.imo,mmsi:e,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:y.unix(),utc:y.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(y.diff(k,"minute",!0)/(o||1));u!==w&&(w=u,C.push(l))}return C}}class bt extends G{constructor(e){super();z(this,"token");this.token=e}async getShipId(e,a={}){const i={headers:{appKey:this.token},json:{mmsiList:e}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",n=await R.post(o,i).json();return g==null||g.info("[%s] fetch ship id from: %s - %j",a.requestId,o,i),n.code!=="0"?n:n.data[0].shipId}async getShipInfo(e,a={}){const i={headers:{appKey:this.token},json:{shipId:e}},o="https://api3.myships.com/sp/ships/aissta",n=await R.post(o,i).json();if(g==null||g.info("[%s] fetch ship info from: %s - %j",a.requestId,o,i),n.code!=="0")return n;const s=n.data;let d=s.imo;return e==="407170"&&(d="9198379",g==null||g.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,e,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(e,a={}){const i=await this.getShipId(e,a),o=await this.getShipInfo(i,a),n={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await R.post(s,n).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,n);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:m,labelEn:M}=await this.parseStatus(r.aisNavStatus),h=p.unix(r.posTime);return{...o,mmsi:e,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:m,method:"position",vendor:"myship"}}async trajectory(e,a,i,o,n=!0,s={}){const d=p(a),r=p(i),m=await this.getShipId(e),M=await this.getShipInfo(m),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(m,d.unix(),d.add(30,"day").unix(),M,e,o,h);return await this.trajectoryIn30Day(m,d.unix(),r.unix(),M,e,o,h),h}async trajectoryIn30Day(e,a,i,o,n,s,d,r={}){var k;const m={headers:{appKey:this.token},json:{shipId:e,startTime:a,endTime:i}},M="https://api3.myships.com/sp/ships/position/history",h=await R.post(M,m).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",r.requestId,M,m),h.code!=="0")return g==null||g.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const b=h.data;for(const w in b)!isNaN(b[w])&&Number(b[w])!==1/0&&(b[w]=Number(b[w]));const f=p.unix((k=b[0])==null?void 0:k.posTime);let C=-1;for(const w of b){const v=p.unix(w.posTime),c={imo:o==null?void 0:o.imo,mmsi:n,lat:Math.round(w.lat/1e4/60*1e5)/1e5,lng:Math.round(w.lon/1e4/60*1e5)/1e5,sog:Math.round(w.sog/10*100)/100,cog:Math.round(w.cog/10*100)/100,hdg:Math.round(w.heading*100)/100,rot:Math.round(w.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},y=Math.floor(v.diff(f,"minute",!0)/(s||1));y!==C&&(C=y,d.push(c))}return d}}let _;try{_=K.getLogger("vessel")}catch{}finally{}var dt=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(dt||{});class ut{parsePrinciple(t,e={}){var s,d,r;_==null||_.info("[%s] parse rule: %s",e.requestId,t);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=t.match(a)?(s=t.match(a))==null?void 0:s[0]:void 0,o=i==null?void 0:i.split(";");if(!o)return;const n={};for(let m=0;m<(o==null?void 0:o.length);m++){const M=(r=(d=o[m].match(a))==null?void 0:d[0])==null?void 0:r.split("],");if(m===0&&!M)n.scope=o[0];else if(M)for(let h=0,b=M.length;h<b;h++){const f=this.parseRule(M[h]);f&&(n[f.level]?f.key?n[f.level][f==null?void 0:f.key]=f:n[f.level]=f:f.key?n[f.level]={[f==null?void 0:f.key]:f}:n[f.level]=f)}}return n}parseRule(t,e={}){var n;_==null||_.debug("[%s] parse rule: %s",e.requestId,t),t=t.startsWith("[")?t:`[${t}`,t=t.endsWith("]")?t:`${t}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(n=t==null?void 0:t.match(a))==null?void 0:n[0],o=i==null?void 0:i.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(t,e,a={}){var f,C,k,w,v,c,y,l,u,I,F,N,P,E,L;let i=0,o=0,n=0,s=0;const d=Math.round(((C=(f=e==null?void 0:e.SEVERE)==null?void 0:f.sigWave)==null?void 0:C.number)*1.6*100)/100,r=(w=(k=e==null?void 0:e.SEVERE)==null?void 0:k.sigWave)==null?void 0:w.number,m=(c=(v=e==null?void 0:e.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,M=Math.round((((l=(y=e==null?void 0:e.SEVERE)==null?void 0:y.wind)==null?void 0:l.number)+2)*100)/100,h=(I=(u=e==null?void 0:e.SEVERE)==null?void 0:u.wind)==null?void 0:I.number,b=(N=(F=e==null?void 0:e.HEAVY)==null?void 0:F.wind)==null?void 0:N.number;for(let x=0;x<(t==null?void 0:t.length);x++){const H=t[x],q=(E=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:E.sig,V=(L=H==null?void 0:H.meteo)==null?void 0:L.wind,U=x?p(H.eta).diff(p(t[x-1].eta),"hour",!0):0;s=U>s?U:s,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...q,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}),(q==null?void 0:q.height)>=d?H.isDangerous=!0:(q==null?void 0:q.height)>=r?H.isSevere=!0:(q==null?void 0:q.height)>=m&&(H.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b}),(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)===b&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),i+=H.isDangerous?U:0,o+=H.isSevere?U:0,n+=H.isHeavy?U:0}return i=Math.round(i*100)/100,o=Math.round(o*100)/100,n=Math.round(n*100)/100,s=Math.round(s),{sample:t,dangerous:i,severe:o,heavy:n,step:s<3?3:s,wind:{dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}}}}const gt=new ut;let S;try{S=K.getLogger("vessel")}catch{}finally{}const vt=new mt.MeteoHelper2("",!0);var lt=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(lt||{}),ht=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ht||{}),ft=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ft||{});class W{static blockCoefficient(t,e,a,i){let o=Math.round(t/(e*a*i)*100)/100;o=o<.55?.55:o>.85?.85:o;const n=[.55,.6,.65,.7,.75,.8,.85],s=n.map(d=>Math.abs(d-o));return n[s.indexOf(Math.min(...s))]}static froudeNumber(t,e,a=9.8){let i=Math.round(Math.sqrt(t*t/(a*e))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(t,e,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[t];return a==="Laden"&&(n=i[t]),n[0]+n[1]*e+n[2]*Math.pow(e,2)}static directionFactor(t,e=0){let a;return t>30&&t<=60?a=(1.7-.03*Math.pow(e-4,2))/2:t>60&&t<=150?a=(.9-.06*Math.pow(e-6,2))/2:t>150&&t<=180?a=(.4-.03*Math.pow(e-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(t,e,a,i=0){i=i>6?i-.9*(i-6):i;let o;return a==="container"?o=.7*i+Math.pow(i,6.5)/(22*Math.pow(t,2/3)):e==="Ballast"?o=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)):o=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)),o}static waveHeightFactor(t,e){t=t<3?t*.7:t,t=t<0?.2:t,t=t>6?t-.9*(t-6):t,t=t>9?9:t;let a;return e>30&&e<=60?a=-.6:e>60&&e<=90?a=-.4:e>90&&e<=120?a=t<3?.4:-.3:e>120&&e<=150?a=t<3?.6:-.5:e>150&&e<=180?a=t<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(t,2)+.278*t)*1e4)/1e4}static assembleProperties(t,e,a,i){var h;const o=t.lbp??t.length??t.lengthOverall??198.9642,n=t.draught??8,s=t.breadthMoulded??t.breadth??t.breadthExtreme??32.4572,d=t.deadweight??67035.7773,r=((h=t==null?void 0:t.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:o,loadCondition:e,draught:n,breadthMoulded:s,displacement:Math.round((d/1.025+n*s*o*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(t,e,a,i="",o=2,n=!0,s=!1,d={}){let r;if(e.velocity&&s&&(t.speed=T.LngLatHelper.roundPrecision(e.velocity*1852/3600,6)),n){let m;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:f,marineModels:C}=await nt.Meteo2Assist.autoPickMeteoModel(i),k=await vt.spotForecast(e.lat,e.lng,a.utc().format(),!1,!1,!0,{...d,pastDays:1,forecastDays:1,weatherModels:f,marineModels:C}),[w]=nt.Meteo2Assist.pickHourly(k,a);m=nt.Meteo2Assist.toLegacy(w)}catch(f){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...e,eta:a.utc().format(),source:i},f)}const M=W.weatherFactor(t,m),h=W.currentFactor(t.bearing,m==null?void 0:m.current,o),b=Math.round((t.speed*1.943844+M+h)*100)/100;r={meteo:{...m},wxFactor:M,cFactor:h,speed:e.velocity&&s?e.velocity:b<0?1:b,eta:a.utc().format(),etd:a.utc().format()}}else r={wxFactor:0,cFactor:0,speed:e.velocity&&s?e.velocity:Math.round((t.speed*1.943844+0+0)*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete e.meteo,delete e.wxFactor,delete e.cFactor,delete e.speed,delete e.etd,{...r,...e}}static async speedLoseInHoursStep(t,e,a,i,o,n,s="",d=!0,r=!1,m={}){e.utc();const M=e.clone().add(14,"days"),h=[],b=[];let f=0,C=0,k,w;for(let v=0;v<n.length-1;v++){let c=n[v];c.distanceFromStart=Math.round((o+C)*1e3)/1e3;const y=n[v+1];if(t.bearing=T.LaneHelper.calculateBearing(c,y,!y.gcToPrevious),c.bearing=t.bearing,c.suspend&&r){c.eta=c.eta||e.utc().format(),c.elapsed=c.elapsed??0;const I=c.suspend-c.elapsed;if(i-f>I)i=i-f-I,e.add(I,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,e.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,m.requestId,c),i===0)return c.distanceFromPrevious=C,{etd:e,from:w||c,to:c,next:n.filter(F=>F),wps:h,days:b}}else c.suspend=0;d=e.isAfter(M)?!1:d,c=await W.speedLoseAt(t,c,e,s,0,d,r,m),w=w||c,c.important&&h.push(c),e.isSameOrAfter(a)&&(b.push(c),a.add(24,"hour"));const l=T.LaneHelper.calculateDistance(c,y,!y.gcToPrevious);let u=Math.round(l/w.speed*1e5)/1e5;if(f+u<i){if(f+=u,e.add(u,"hour"),delete n[v],S==null||S.debug(`[%s] go to %j from %j with ${l}nm, and cost ${u} hours`,m.requestId,{lat:y.lat,lng:y.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),C+=l,n.filter(I=>I).length<=1){k=y,k.eta=e.utc().format(),k.distanceFromPrevious=l,k.distanceFromStart=Math.round((o+C)*1e4)/1e4,h.push(k),delete n[v+1];break}}else{u=i-f,e.add(u,"hour");const I=T.LngLatHelper.roundPrecision(w.speed*u,5);k=T.LaneHelper.calculateCoordinate(c,t.bearing,I,"nauticalmiles",!y.gcToPrevious),k.eta=e.utc().format(),n[v]=k,S==null||S.debug(`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,m.requestId,{lat:k.lat,lng:k.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=I,k.distanceFromPrevious=Math.round(C*1e4)/1e4,k.distanceFromStart=Math.round((o+C)*1e4)/1e4;break}}return{etd:e,from:w,to:k,next:n.filter(v=>v),wps:h,days:b}}static currentFactor(t,e,a=0){const i=(t-(e==null?void 0:e.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let o=((e==null?void 0:e.kts)||0)*Math.cos(i);return a&2?o=Math.ceil(o*100)/100:a&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(t,e){var M,h,b,f,C,k,w;S==null||S.debug("calculate weather factor via: %j",{...t,...e});const a=W.blockCoefficient(t.displacement,t.lbp,t.breadthMoulded,t.draught),i=W.froudeNumber(t.speed,t.lbp),o=W.amendFactor(a,i,t.loadCondition);let n=Math.abs(t.bearing%360-(((M=e==null?void 0:e.wind)==null?void 0:M.degree)%360||0));n=n>180?360-n:n;const s=W.directionFactor(n,(h=e==null?void 0:e.wind)==null?void 0:h.scale),d=W.vesselTagFactor(t.displacement,t.loadCondition,t.tag,(b=e==null?void 0:e.wind)==null?void 0:b.scale);let r=s*o*d/100*t.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,t.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),n=Math.abs(t.bearing%360-(((C=(f=e==null?void 0:e.wave)==null?void 0:f.sig)==null?void 0:C.degree)%360||0));const m=W.waveHeightFactor(((w=(k=e==null?void 0:e.wave)==null?void 0:k.sig)==null?void 0:w.height)??1,n);return S==null||S.debug("wave wx factor = %d",m),r=Math.abs(r)>Math.abs(m)?r:r*.3+m*.7,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>3?3*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-2)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(t,e,a,i,o,n="",s=0,d=!0,r=!1,m={}){var Q,X,Z,$,tt,et;const M=p().valueOf();t.lng=T.LngLatHelper.convertToStdLng(t.lng);const{route:h,waypoints:b}=o.points,f=T.LaneHelper.calculateSubRoute(t,h);if(((Q=f[0])==null?void 0:Q.length)<=1)return;const{v0:C,label:k}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:i.speed,label:"CP"},w=W.assembleProperties(a,i.loadCondition,C,0),v=b.length?T.LaneHelper.calculateSubWaypoints(t,b):[];v.forEach(Y=>Y.important=!0);const c={from:{...t},route:f,waypoints:v,v0:C,label:k},y={hours:[],days:[],wps:[]};s||(T.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let l=T.LaneHelper.simplifyRouteToCoordinates(f,v,0),u=0,I=0,F=0,N=0;e=p(e).utc();const P=e.clone();for(;l.length>0;){const Y=s-e.hour()%s,J=Math.ceil(e.clone().add(Y,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4,j=await W.speedLoseInHoursStep(w,e,P,J,u,l,n,d,r,m);(X=j.from)!=null&&X.speed&&(y.hours.push(j.from),y.wps.push(...j.wps),y.days.push(...j.days)),l=j==null?void 0:j.next,l.length||y.hours.push(j==null?void 0:j.to),u+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const E=y.hours;for(let Y=0;Y<E.length-1;Y++){const J=p(E[Y+1].eta).diff(E[Y].etd,"hour",!0)||1;I+=(E[Y].wxFactor||0)*J,F+=(E[Y].cFactor||0)*J,N+=J}($=y.wps)==null||$.forEach((Y,J)=>{Y.positionTime=p.utc(Y.etd||Y.eta).unix();const j=y.wps[J-1];if(j){const B=Y.distanceFromStart-j.distanceFromStart,O=p(Y.eta||Y.etd).diff(p(j.etd||j.eta),"h",!0);Y.avgSpd=Math.round(B/O*100)/100;const ct=T.LaneHelper.calculateBearing(j,Y);j.bearing=ct}}),y.wps=(tt=y.wps)==null?void 0:tt.reduce((Y,J)=>(Y.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||Y.push(J),Y),[]),c.sample=y;const L=y.hours.at(0),x=y.hours.at(-1);c.distance=Math.round(x.distanceFromStart*1e3)/1e3,c.etd=p(L.eta).utc().format(),c.eta=p(x.eta).utc().format(),c.wxFactor=Math.round(I/N*1e3)/1e3,c.cFactor=Math.round(F/N*1e3)/1e3,c.avgSpeed=Math.round(x.distanceFromStart/N*1e3)/1e3,c.totalHrs=Math.round(N*1e3)/1e3;const{distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V,eca:U}=await this.calculateECA(c,i,m),st=T.LngLatHelper.roundPrecision(i.fo/24*(N-q),3),ot=T.LngLatHelper.roundPrecision(i.dgo/24*N,3);c.extend={eca:U,distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V},c.totalFoCons=st<0?0:st,c.totalDgoCons=ot;const at=p().valueOf()-M,rt=((et=y==null?void 0:y.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",m==null?void 0:m.requestId,at,rt,Math.round(at/rt*1e3)/1e3),c}static async analyseInstantWithThreshed(t,e,a,i,o,n,s,d="",r=3,m=!0,M=!1,h={}){var Z,$,tt,et,Y,J;const b=p().valueOf();t.lng=T.LngLatHelper.convertToStdLng(t.lng);const{v0:f,label:C}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:o.speed,label:"CP"},k=W.assembleProperties(i,o.loadCondition,f,0),w=T.LaneHelper.calculateSubRoute(t,n);if(((Z=w[0])==null?void 0:Z.length)<=1)return;const v=s.length?T.LaneHelper.calculateSubWaypoints(t,s):[];v.forEach(j=>j.important=!0);let c=T.LaneHelper.simplifyRouteToCoordinates(w,v,0),y=0,l=0,u=0,I=0;const F={hours:[],wps:[],days:[]};e=p(e).utc();const N=e.clone();for(;c.length>0;){const j=r-e.hour()%r;let B=Math.ceil(e.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4;B=e.clone().add(B,"h").isSameOrAfter(a)?a.diff(e,"h",!0)*1e4/1e4:B;const O=await W.speedLoseInHoursStep(k,e,N,B,y,c,d,m,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),y+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}F.wps=(et=F.wps)==null?void 0:et.reduce((j,B)=>(j.some(O=>Math.round(p(O.etd).unix()/60)===Math.round(p(B.etd).unix()/60))||j.push(B),j),[]),(Y=F.wps)==null||Y.forEach((j,B)=>{const O=F.wps[B-1];if(O){const ct=j.distanceFromStart-O.distanceFromStart,wt=p(j.eta||j.etd).diff(p(O.etd||O.eta),"h",!0);j.avgSpd=Math.round(ct/wt*100)/100;const It=T.LaneHelper.calculateBearing(O,j);O.bearing=It}});const P=F.hours;for(let j=0;j<P.length-1;j++){const B=p(P[j+1].eta).diff(P[j].etd,"hour",!0);l+=P[j].wxFactor*B,u+=P[j].cFactor*B,I+=B}const E=F.hours.at(0),L=F.hours.at(-1),x=await T.LaneHelper.calculateRangeRoute(E,L,w),H=await T.LaneHelper.calculateRangeWaypoints(E,L,w,v),q={sample:F,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:p(E.eta).utc().format(),eta:p(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(l/I*1e3)/1e3,cFactor:Math.round(u/I*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/I*1e3)/1e3,totalHrs:Math.round(I*1e3)/1e3,from:E,to:L,route:x,waypoints:H,v0:f,label:C},{distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st,eca:ot}=await this.calculateECA(q,o,h),it=T.LngLatHelper.roundPrecision(o.fo/24*(I-U),3),at=T.LngLatHelper.roundPrecision(o.dgo/24*I,3);q.extend={eca:ot,distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st},q.totalDgoCons=at,q.totalFoCons=it<0?0:it;const Q=p().valueOf()-b,X=((J=F==null?void 0:F.hours)==null?void 0:J.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),q}static async analyseCost(t,e,a,i,o={}){var w,v;const n=p().valueOf(),s=[];t.speedStep=t.speedStep||3,t.alterStep=t.alterStep??1;const d=T.LaneHelper.calculateRouteDistance(i.route);let r=0;a.forEach(c=>{const y=Math.ceil(d/c.speed/24);r=r<y?y:r}),r=r*1.3;const m=p.utc(t.etd).add(r??14,"day");let M=1;for(const c of a){const y=JSON.parse(JSON.stringify(i.route)),l=JSON.parse(JSON.stringify(i.waypoints)),u=await W.analyseInstantWithThreshed({lat:t.lat,lng:t.lng},t.etd,m,e,c,y,l,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,o);u&&(await W.calculateCost(u,c,t,o),s.push(u),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",o.requestId,1,M,t.etd,m.format(),{cost:u.cost.total,hire:u.cost.hire,bunker:u.cost.bunker,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),M++}s.sort((c,y)=>c.cost.total-y.cost.total);const h=s.at(0),b=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(w=h.cost)==null?void 0:w.total}),b){const c=h.cost.cp,y=b.cost.cp,l=p(h.eta),u=p(h.etd),I=l.diff(u,"days",!0);let F=Math.ceil(I/2);F=F>7?7:F<t.alterStep?t.alterStep:F;let N=2,P={combined:!1,speeds:[b],cost:(v=b.cost)==null?void 0:v.total},E;for(;F>=t.alterStep;){const L=await W.combinedAnalyse(t,e,m,[c,y],i,F,{...o,level:N});if(P.cost>L.cost?E?(E==null?void 0:E.cost)>L.cost&&(E=L):(E=P,P=L):(!E||(E==null?void 0:E.cost)>L.cost)&&(E=L),F<=t.alterStep)break;F=Math.ceil(F/2),N+=1}f.push(P),E&&f.push(E)}const k=p().valueOf()-n;return S==null||S.info("[%s] analyse elapsed: %d ms",o==null?void 0:o.requestId,k),f.sort((c,y)=>c.cost-y.cost)}static async combinedAnalyse(t,e,a,i,o,n,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,n);const d=await W.alternateAnalyse(t,e,a,i,0,o,n,s),r=d.reduce((y,l)=>y+l.cost.total,0),m=d.reduce((y,l)=>y+l.cost.hire,0),M=d.reduce((y,l)=>y+l.cost.bunker,0),h=d.reduce((y,l)=>y+l.distance,0),b=d.reduce((y,l)=>y+l.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:r,hire:m,bunker:M,distance:h,hours:b});const f=await W.alternateAnalyse(t,e,a,i,1,o,n,s),C=f.reduce((y,l)=>y+l.cost.total,0),k=f.reduce((y,l)=>y+l.cost.hire,0),w=f.reduce((y,l)=>y+l.cost.bunker,0),v=f.reduce((y,l)=>y+l.distance,0),c=f.reduce((y,l)=>y+l.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:C,hire:k,bunker:w,distance:v,hours:c}),r<C?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:n}:{combined:!0,cost:Math.round(C*1e3)/1e3,speeds:f,step:n}}static async alternateAnalyse(t,e,a,i,o,n,s,d={}){var h,b;let r=p.utc(t.etd);const m={lat:t.lat,lng:t.lng},M=[];for(;r.isBefore(a);){const f=r.clone().utc().add(s,"day"),C=JSON.parse(JSON.stringify(n.route)),k=JSON.parse(JSON.stringify(n.waypoints)),w=i[o],v=await W.analyseInstantWithThreshed(m,r.utc().format(),f,e,w,C,k,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,d);v&&(await W.calculateCost(v,w,t,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,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${w.speed}/${w.fo}/${w.dgo}`})),d.counter=d.counter+1;const c=(b=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:b.at(-1);if(c)m.lat=c.lat,m.lng=c.lng,r=p(c.eta),M.push(v),o=o?0:1;else break}return M}static async calculateCost(t,e,a,i={}){var o;if(t){const n=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round(t.totalHrs/24*(a.dailyHire||0)*(1-n)*1e3)/1e3,d=Math.round(t.totalFoCons*(a.priceFO||0)*1e3)/1e3,r=Math.round((t.totalDgoCons+(((o=t.extend)==null?void 0:o.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;t.cost={total:Math.round((s+d+r)*1e3)/1e3,hire:s,bunker:Math.round((d+r)*1e3)/1e3,cp:e}}return t}static async calculateECA(t,e,a={}){var d,r,m,M;const i=await T.LaneHelper.intersectInECA((t==null?void 0:t.route)||[]);let o=0,n=0,s=0;(r=(d=t==null?void 0:t.sample)==null?void 0:d.wps)==null||r.forEach(h=>{h.positionTime=p.utc(h.etd||h.eta).unix()});for(const h of i){o+=h.distance;const b=await T.LaneHelper.deadReckoningTime((m=h.waypoints)==null?void 0:m.at(0),t.sample.wps),f=await T.LaneHelper.deadReckoningTime((M=h.waypoints)==null?void 0:M.at(-1),t.sample.wps);h.in=b,h.out=f,h.totalHrs=T.LngLatHelper.roundPrecision((f.positionTime-b.positionTime)/3600,3),h.totalDgoCons=T.LngLatHelper.roundPrecision(e.fo/24*h.totalHrs,3),n+=h.totalHrs,s+=h.totalDgoCons}return o=T.LngLatHelper.roundPrecision(o,3),n=T.LngLatHelper.roundPrecision(n,3),s=T.LngLatHelper.roundPrecision(s,3),{distanceInECA:o,hoursInECA:n,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(t,e={}){var c,y;const a={hours:[],wps:[],days:[]},i=t.reduce((l,u)=>l+u.distance,0),o=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.distanceInECA)||0)},0),n=t.reduce((l,u)=>l+u.totalHrs,0),s=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.hoursInECA)||0)},0),d=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),r=t.reduce((l,u)=>l+u.wxFactor*u.totalHrs/n,0),m=t.reduce((l,u)=>l+u.cFactor*u.totalHrs/n,0),M=t.reduce((l,u)=>l+u.totalFoCons,0),h=t.reduce((l,u)=>l+u.totalDgoCons,0),b=t.reduce((l,u)=>l+u.cost.total,0),f=t.reduce((l,u)=>l+u.cost.hire,0),C=t.reduce((l,u)=>l+u.cost.bunker,0),k=[],w=[];let v;for(const l of t){w.push(...((c=l.extend)==null?void 0:c.eca)||[]);const u=l.sample.hours,I=l.sample.wps,F=l.sample.days,N=u.at(0);v&&(N.distanceFromPrevious=v.distanceFromPrevious,N.distanceFromStart=v.distanceFromStart,u.forEach((x,H)=>{H&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),I.at(0).distanceFromPrevious=v.distanceFromPrevious,I.at(0).distanceFromStart=v.distanceFromStart,I.forEach((x,H)=>{H&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((x,H)=>{H&&(x.distanceFromStart=x.distanceFromStart+v.distanceFromStart)})),N.cp=l.cost.cp;const P=[l.etd,l.eta],E=k.findIndex(x=>x.id===N.cp.id);E===-1?(N.cp.segment=[P],k.push(N.cp)):k[E].segment.push(P),u.forEach(x=>{var q;((q=a.hours)==null?void 0:q.findIndex(V=>V.eta===x.eta))===-1&&a.hours.push(x)}),I.forEach(x=>{var q;((q=a.wps)==null?void 0:q.findIndex(V=>V.eta===x.eta))===-1&&a.wps.push(x)}),F.forEach(x=>{var q;((q=a==null?void 0:a.days)==null?void 0:q.findIndex(V=>V.eta===x.eta))===-1&&a.days.push(x)});const L=(y=a.wps)==null?void 0:y.findIndex(x=>x.eta===N.eta);L===-1?a.wps.push(N):a.wps[L]=N,v=u.at(-1)}return a.wps.sort((l,u)=>{p(l.etd).unix()-p(u.etd).unix()}),a.wps.forEach((l,u)=>{const I=a.wps[u-1];if(I){const F=l.distanceFromStart-(I.distanceFromStart||0),N=p(l.eta||l.etd).diff(p(I.etd||I.eta),"hour",!0),P=Math.round(F/N*100)/100;l.avgSpd=P;const E=T.LaneHelper.calculateBearing(I,l);I.bearing=E}}),{sample:a,etd:t.at(0).etd,eta:t.at(-1).eta,from:t.at(0).from,to:t.at(-1).to,v0:t.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(n*1e3)/1e3,avgSpeed:Math.round(i/n*1e3)/1e3,wxFactor:Math.round(r*1e3)/1e3,cFactor:Math.round(m*1e3)/1e3,totalFoCons:Math.round(M*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(b*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(C*1e3)/1e3},extend:{cps:k,eca:w,distanceInECA:Math.round(o*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:t}}}}A.AISImpl=G,A.AlertHelper=ut,A.AlertLevel=dt,A.HifleetImpl=Mt,A.LoadCondition=ht,A.MyShipImpl=bt,A.MyVesselImpl=yt,A.ShipxyImpl=pt,A.SpeedHelper=W,A.SpeedLabel=ft,A.VesselTag=lt,A.alertHelper=gt,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});
1
+ (function(A,R){typeof exports=="object"&&typeof module<"u"?R(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"],R):(A=typeof globalThis<"u"?globalThis:A||self,R(A["idm-plugin-vessel"]={},A.got,A["@log4js-node/log4js-api"],A.moment,A["@idm-plugin/geo2"],A["@idm-plugin/meteo2"],A["@idm-plugin/meteo"]))})(this,function(A,R,K,p,x,mt,nt){"use strict";var St=Object.defineProperty;var kt=(A,R,K)=>R in A?St(A,R,{enumerable:!0,configurable:!0,writable:!0,value:K}):A[R]=K;var z=(A,R,K)=>(kt(A,typeof R!="symbol"?R+"":R,K),K);let g;try{g=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(t){let e,a;switch(t){case 0:e="在航(主机推动)",a="Underway Using Engine";break;case 1:e="锚泊",a="Anchored";break;case 2:e="失控",a="Not operated";break;case 3:e="操纵受限",a="Limited airworthiness";break;case 4:e="吃水受限",a="Limited by ship's draft";break;case 5:e="靠泊",a="Mooring";break;case 6:e="搁浅",a="Stranded";break;case 7:e="捕捞作业",a="Engaged in fishing";break;case 8:e="靠帆船提供动力",a="Sailing";break;default:e="未定义",a="Undefined"}return{labelCn:e,labelEn:a}}}class yt extends G{constructor(e,a){super();z(this,"clientId");z(this,"clientSecret");z(this,"token");this.clientId=e,this.clientSecret=a}async authToken(e={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",i={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await R.post(a,i).json();g==null||g.info("[%s] fetch access token from: %s - %j",e.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:p().utc().format()})}async realTimePosition(e,a={}){var d,r,m;(!this.token||p().diff(p(this.token.issuedAt),"seconds")>((d=this.token)==null?void 0:d.expiresIn)-300)&&await this.authToken(a);const i="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(m=this.token)==null?void 0:m.accessToken}`},searchParams:{mmsi:e}};g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const o=await R.get(i,n).json();if(o.code)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,{message:o.message,status:o.status,code:o.code}),o;const s=o.data;for(const M in s)!isNaN(s[M])&&Number(s[M])!==1/0&&(s[M]=Number(s[M]));if(s){const M=p(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?p.utc(s.eta).format():void 0,destination:s.dest,positionTime:M.unix(),status:s.status,labelCn:s.statusNameCn,labelEn:s.statusNameEn,vesselType:s.vesselTypeNameEn,flag:s.flagCtryNameEn,clasz:s.classSociety,build:s.buildYear,dwt:s.dwt,grt:s.grt,net:s.net,method:"position",vendor:"myVessel",utc:M.utc().format()}}else return{}}async trajectory(e,a,i,n,o=!0,s={}){(!this.token||p().diff(p(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(s);const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M=[];for(;m.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(e,r,r.clone().add(30,"day"),d,n,M,s),r.add(30,"day");return await this.trajectoryIn30Day(e,r,m,d,n,M,s),M}async trajectoryIn30Day(e,a,i,n,o,s,d={}){var f,C,k,w,v;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",m={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(C=this.token)==null?void 0:C.accessToken}`},json:{mmsi:e,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};g==null||g.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,m);const M=await R.post(r,m).json();if(M.code)return g==null||g.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:M.message,status:M.status,code:M.code}),M;let h=-1;const b=p(`${(w=(k=M.data)==null?void 0:k[0])==null?void 0:w.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 y=p(`${c.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),l=c.status,{labelCn:u,labelEn:I}=this.parseStatus(l),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:l,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,destination:c.dest,positionTime:y.unix(),labelCn:u,labelEn:I,method:"trajectory",vendor:"myVessel",utc:y.utc().format()},T=Math.floor(y.diff(b,"minute",!0)/(o||1));T!==h&&(h=T,s.push(F))}),s}}class Mt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:e,usertoken:this.token}},o=await R.post(i,n).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,i,n);const s=o==null?void 0:o.list;if(!s)return g==null||g.warn("[%s] fetch realtime position failed: %j",a.requestId,i,o),o;for(const b in s)!isNaN(s[b])&&Number(s[b])!==1/0&&(s[b]=Number(s[b]));s.status=s.sp>3?0:1;const d=s.status,{labelCn:r,labelEn:m}=this.parseStatus(d),M=p(`${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)?p.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:M.unix(),utc:M.utc().format(),status:d,labelCn:r,labelEn:m,method:"position",vendor:"hifleet"}}async search(e,a={}){let i="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let o=await R.post(i,n).json();g==null||g.info("[%s] fetch vessel props from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]);for(const d in o)!isNaN(o[d])&&Number(o[d])!==1/0&&(o[d]=Number(o[d]));const s={mmsi:o.m,name:o.n,imo:o.i,callSign:o.c,length:o.l,breadth:o.b,draught:o.dr,type:o.t};return i="https://www.hifleet.com/hifleetapi/sameShipSearch.do",o=await R.post(i,n).json(),g==null||g.info("[%s] search vessel dead weight from: %s - %j",a.requestId,i,n),o instanceof Array&&(o=o[0]),o&&(s.deadweight=Number(o.dwt)),s}async suggest(e,a={}){const i="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:e},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},o=await R.post(i,n).json();g==null||g.info("[%s] suggest vessel props from: %s - %j",a.requestId,i,n);const s=[];for(const d of o)s.push({mmsi:!d.mmsi||isNaN(d.mmsi)?null:Number(d.mmsi),name:d.name,callSign:d.callsign,imo:!d.imo||isNaN(d.imo)?null:Number(d.imo),score:d._score});return s.sort((d,r)=>r.score-d.score),s}async trajectory(e,a,i,n,o=!0,s={}){var c,y,l;const d=await this.realTimePosition(e,s);let r=p(a);const m=p(i),M=p();if(o){let u=m.diff(r,"d",!0);u<0?r=m.clone().subtract(40,"d"):u<30?r.subtract(10,"d"):u<60?r.subtract(5,"d"):r=m.clone().subtract(80,"d"),u=M.diff(m,"d",!0),m.add(u>10?240:u*24,"h")}const h={searchParams:{endtime:m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:e,usertoken:this.token}},b="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",f=await R.get(b,h).json();g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,b,h);let C;f&&(C=((y=(c=f.ships)==null?void 0:c.offors)==null?void 0:y.ship)||[],C.length||g==null||g.warn("[%s] fetch trajectory failed: %j",s.requestId,f));const k=[];let w=-1;const v=p(`${(l=C==null?void 0:C[0])==null?void 0:l.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const u of C){for(const L in u)!isNaN(u[L])&&Number(u[L])!==1/0&&(u[L]=Number(u[L]));const I=p(`${u.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");u.status=u.sp>4?0:1;const{labelEn:F,labelCn:T}=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:T,labelEn:F,method:"trajectory",vendor:"hifleet"},E=Math.floor(I.diff(v,"minute",!0)/(n||1));E!==w&&(w=E,k.push(P))}return k}}class pt extends G{constructor(e){super();z(this,"token");this.token=e}async realTimePosition(e,a={}){const i={searchParams:{id:e,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",o=await R.get(n,i).json();if(g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,i),(o==null?void 0:o.status)!==0)return o;const s=o.data[0];for(const 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),m=p.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:m.utc().format(),status:s.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(e,a,i,n,o=!0,s={}){var v;const d=await this.realTimePosition(e,s),r=p(a),m=p(i),M="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:e,k:this.token,enc:1,cut:0,btm:r.unix(),etm:m.unix()}},b=await R.get(M,h).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",s.requestId,M,h),(b==null?void 0:b.status)!==0)return b;const f=b==null?void 0:b.points,C=[],k=p.unix((v=f[0])==null?void 0:v.utc);let w=-1;for(const c of f){const y=p.unix(c.utc),l={imo:d==null?void 0:d.imo,mmsi:e,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:y.unix(),utc:y.utc().format(),method:"trajectory",vendor:"shipxy"},u=Math.floor(y.diff(k,"minute",!0)/(n||1));u!==w&&(w=u,C.push(l))}return C}}class bt extends G{constructor(e){super();z(this,"token");this.token=e}async getShipId(e,a={}){const i={headers:{appKey:this.token},json:{mmsiList:e}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",o=await R.post(n,i).json();return g==null||g.info("[%s] fetch ship id from: %s - %j",a.requestId,n,i),o.code!=="0"?o:o.data[0].shipId}async getShipInfo(e,a={}){const i={headers:{appKey:this.token},json:{shipId:e}},n="https://api3.myships.com/sp/ships/aissta",o=await R.post(n,i).json();if(g==null||g.info("[%s] fetch ship info from: %s - %j",a.requestId,n,i),o.code!=="0")return o;const s=o.data;let d=s.imo;return e==="407170"&&(d="9198379",g==null||g.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,e,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(e,a={}){const i=await this.getShipId(e,a),n=await this.getShipInfo(i,a),o={headers:{appKey:this.token},json:{shipId:i}},s="https://api3.myships.com/sp/ships/position/latest",d=await R.post(s,o).json();g==null||g.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,o);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:m,labelEn:M}=await this.parseStatus(r.aisNavStatus),h=p.unix(r.posTime);return{...n,mmsi:e,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:m,method:"position",vendor:"myship"}}async trajectory(e,a,i,n,o=!0,s={}){const d=p(a),r=p(i),m=await this.getShipId(e),M=await this.getShipInfo(m),h=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(m,d.unix(),d.add(30,"day").unix(),M,e,n,h);return await this.trajectoryIn30Day(m,d.unix(),r.unix(),M,e,n,h),h}async trajectoryIn30Day(e,a,i,n,o,s,d,r={}){var k;const m={headers:{appKey:this.token},json:{shipId:e,startTime:a,endTime:i}},M="https://api3.myships.com/sp/ships/position/history",h=await R.post(M,m).json();if(g==null||g.info("[%s] fetch trajectory from: %s - %j",r.requestId,M,m),h.code!=="0")return g==null||g.warn("[%s] invoke myship trajectory failed: %j",r.requestId,h),h;const b=h.data;for(const w in b)!isNaN(b[w])&&Number(b[w])!==1/0&&(b[w]=Number(b[w]));const f=p.unix((k=b[0])==null?void 0:k.posTime);let C=-1;for(const w of b){const v=p.unix(w.posTime),c={imo:n==null?void 0:n.imo,mmsi:o,lat:Math.round(w.lat/1e4/60*1e5)/1e5,lng:Math.round(w.lon/1e4/60*1e5)/1e5,sog:Math.round(w.sog/10*100)/100,cog:Math.round(w.cog/10*100)/100,hdg:Math.round(w.heading*100)/100,rot:Math.round(w.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},y=Math.floor(v.diff(f,"minute",!0)/(s||1));y!==C&&(C=y,d.push(c))}return d}}let _;try{_=K.getLogger("vessel")}catch{}finally{}var dt=(D=>(D.NOTICE="NOTICE",D.WARN="WARN",D.HEAVY="HEAVY",D.SEVERE="SEVERE",D.ERROR="ERROR",D.FATAL="FATAL",D))(dt||{});class ut{parsePrinciple(t,e={}){var s,d,r;_==null||_.debug("[%s] parse rule: %s",e.requestId,t);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),i=t.match(a)?(s=t.match(a))==null?void 0:s[0]:void 0,n=i==null?void 0:i.split(";");if(!n)return;const o={};for(let m=0;m<(n==null?void 0:n.length);m++){const M=(r=(d=n[m].match(a))==null?void 0:d[0])==null?void 0:r.split("],");if(m===0&&!M)o.scope=n[0];else if(M)for(let h=0,b=M.length;h<b;h++){const f=this.parseRule(M[h]);f&&(o[f.level]?f.key?o[f.level][f==null?void 0:f.key]=f:o[f.level]=f:f.key?o[f.level]={[f==null?void 0:f.key]:f}:o[f.level]=f)}}return o}parseRule(t,e={}){var o;_==null||_.debug("[%s] parse rule: %s",e.requestId,t),t=t.startsWith("[")?t:`[${t}`,t=t.endsWith("]")?t:`${t}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),i=(o=t==null?void 0:t.match(a))==null?void 0:o[0],n=i==null?void 0:i.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(t,e,a={}){var f,C,k,w,v,c,y,l,u,I,F,T,P,E,L;let i=0,n=0,o=0,s=0;const d=Math.round(((C=(f=e==null?void 0:e.SEVERE)==null?void 0:f.sigWave)==null?void 0:C.number)*1.6*100)/100,r=(w=(k=e==null?void 0:e.SEVERE)==null?void 0:k.sigWave)==null?void 0:w.number,m=(c=(v=e==null?void 0:e.HEAVY)==null?void 0:v.sigWave)==null?void 0:c.number,M=Math.round((((l=(y=e==null?void 0:e.SEVERE)==null?void 0:y.wind)==null?void 0:l.number)+2)*100)/100,h=(I=(u=e==null?void 0:e.SEVERE)==null?void 0:u.wind)==null?void 0:I.number,b=(T=(F=e==null?void 0:e.HEAVY)==null?void 0:F.wind)==null?void 0:T.number;for(let N=0;N<(t==null?void 0:t.length);N++){const H=t[N],q=(E=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:E.sig,V=(L=H==null?void 0:H.meteo)==null?void 0:L.wind,U=N?p(H.eta).diff(p(t[N-1].eta),"hour",!0):0;s=U>s?U:s,_==null||_.debug("[%s] check sig.wave: %j",a.requestId,{...q,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}),(q==null?void 0:q.height)>=d?H.isDangerous=!0:(q==null?void 0:q.height)>=r?H.isSevere=!0:(q==null?void 0:q.height)>=m&&(H.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",a.requestId,{...V,dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b}),(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)===b&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),i+=H.isDangerous?U:0,n+=H.isSevere?U:0,o+=H.isHeavy?U:0}return i=Math.round(i*100)/100,n=Math.round(n*100)/100,o=Math.round(o*100)/100,s=Math.round(s),{sample:t,dangerous:i,severe:n,heavy:o,step:s<3?3:s,wind:{dgThd4Wd:M,svThd4Wd:h,hvThd4Wd:b},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:m}}}}const gt=new ut;let S;try{S=K.getLogger("vessel")}catch{}finally{}const vt=new mt.MeteoHelper2("",!0);var lt=(D=>(D.common="common",D.container="container",D.tugs="tugs",D))(lt||{}),ht=(D=>(D.Ballast="Ballast",D.Laden="Laden",D))(ht||{}),ft=(D=>(D.Cp="CP",D.Perf="Basis",D.Instruct="Other",D))(ft||{});class W{static blockCoefficient(t,e,a,i){let n=Math.round(t/(e*a*i)*100)/100;n=n<.55?.55:n>.85?.85:n;const o=[.55,.6,.65,.7,.75,.8,.85],s=o.map(d=>Math.abs(d-n));return o[s.indexOf(Math.min(...s))]}static froudeNumber(t,e,a=9.8){let i=Math.round(Math.sqrt(t*t/(a*e))*100)/100;return i=i<.05?.05:i>.3?.3:i,i}static amendFactor(t,e,a){const i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[t];return a==="Laden"&&(o=i[t]),o[0]+o[1]*e+o[2]*Math.pow(e,2)}static directionFactor(t,e=0){let a;return t>30&&t<=60?a=(1.7-.03*Math.pow(e-4,2))/2:t>60&&t<=150?a=(.9-.06*Math.pow(e-6,2))/2:t>150&&t<=180?a=(.4-.03*Math.pow(e-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(t,e,a,i=0){i=i>6?i-.9*(i-6):i;let n;return a==="container"?n=.7*i+Math.pow(i,6.5)/(22*Math.pow(t,2/3)):e==="Ballast"?n=.7*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)):n=.5*i+Math.pow(i,6.5)/(2.7*Math.pow(t,2/3)),n}static waveHeightFactor(t,e){t=t<3?t*.7:t,t=t<0?.2:t,t=t>6?t-.9*(t-6):t,t=t>9?9:t;let a;return e>30&&e<=60?a=-.6:e>60&&e<=90?a=-.4:e>90&&e<=120?a=t<3?.4:-.3:e>120&&e<=150?a=t<3?.6:-.5:e>150&&e<=180?a=t<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(t,2)+.278*t)*1e4)/1e4}static assembleProperties(t,e,a,i){var h;const n=t.lbp??t.length??t.lengthOverall??198.9642,o=t.draught??8,s=t.breadthMoulded??t.breadth??t.breadthExtreme??32.4572,d=t.deadweight??67035.7773,r=((h=t==null?void 0:t.type)==null?void 0:h.toLowerCase())||"common";return{tag:r.indexOf("container")>-1?"container":r.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:e,draught:o,breadthMoulded:s,displacement:Math.round((d/1.025+o*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:i||90}}static async speedLoseAt(t,e,a,i="",n=2,o=!0,s=!1,d={}){let r;if(e.velocity&&s&&(t.speed=x.LngLatHelper.roundPrecision(e.velocity*1852/3600,6)),o){let m;try{i=(i==null?void 0:i.toUpperCase())==="CMEMS"?"ECMWF":i,i=(i==null?void 0:i.toUpperCase())==="METEO2"?"best_match":i;const{weatherModels:f,marineModels:C}=await nt.Meteo2Assist.autoPickMeteoModel(i),k=await vt.spotForecast(e.lat,e.lng,a.utc().format(),!1,!1,!0,{...d,pastDays:1,forecastDays:1,weatherModels:f,marineModels:C}),[w]=nt.Meteo2Assist.pickHourly(k,a);m=nt.Meteo2Assist.toLegacy(w)}catch(f){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",d.requestId,{...e,eta:a.utc().format(),source:i},f)}const M=W.weatherFactor(t,m),h=W.currentFactor(t.bearing,m==null?void 0:m.current,n),b=Math.round((t.speed*1.943844+M+h)*100)/100;r={meteo:{...m},wxFactor:M,cFactor:h,speed:e.velocity&&s?e.velocity:b<0?1:b,eta:a.utc().format(),etd:a.utc().format()}}else r={wxFactor:0,cFactor:0,speed:e.velocity&&s?e.velocity:Math.round((t.speed*1.943844+0+0)*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete e.meteo,delete e.wxFactor,delete e.cFactor,delete e.speed,delete e.etd,{...r,...e}}static async speedLoseInHoursStep(t,e,a,i,n,o,s="",d=!0,r=!1,m={}){e.utc();const M=e.clone().add(14,"days"),h=[],b=[];let f=0,C=0,k,w;for(let v=0;v<o.length-1;v++){let c=o[v];c.distanceFromStart=Math.round((n+C)*1e3)/1e3;const y=o[v+1];if(t.bearing=x.LaneHelper.calculateBearing(c,y,!y.gcToPrevious),c.bearing=t.bearing,c.suspend&&r){c.eta=c.eta||e.utc().format(),c.elapsed=c.elapsed??0;const I=c.suspend-c.elapsed;if(i-f>I)i=i-f-I,e.add(I,"hour"),c.elapsed=c.suspend;else{const F=i-f;c.elapsed+=F,e.add(F,"hour"),i=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${i} hours need to go...`,m.requestId,c),i===0)return c.distanceFromPrevious=C,{etd:e,from:w||c,to:c,next:o.filter(F=>F),wps:h,days:b}}else c.suspend=0;d=e.isAfter(M)?!1:d,c=await W.speedLoseAt(t,c,e,s,0,d,r,m),w=w||c,c.important&&h.push(c),e.isSameOrAfter(a)&&(b.push(c),a.add(24,"hour"));const l=x.LaneHelper.calculateDistance(c,y,!y.gcToPrevious);let u=Math.round(l/w.speed*1e5)/1e5;if(f+u<i){if(f+=u,e.add(u,"hour"),delete o[v],S==null||S.debug(`[%s] go to %j from %j with ${l}nm, and cost ${u} hours`,m.requestId,{lat:y.lat,lng:y.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),C+=l,o.filter(I=>I).length<=1){k=y,k.eta=e.utc().format(),k.distanceFromPrevious=l,k.distanceFromStart=Math.round((n+C)*1e4)/1e4,h.push(k),delete o[v+1];break}}else{u=i-f,e.add(u,"hour");const I=x.LngLatHelper.roundPrecision(w.speed*u,5);k=x.LaneHelper.calculateCoordinate(c,t.bearing,I,"nauticalmiles",!y.gcToPrevious),k.eta=e.utc().format(),o[v]=k,S==null||S.debug(`[%s] go to %j from %j with ${I}nm, and cost ${u} hours`,m.requestId,{lat:k.lat,lng:k.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=I,k.distanceFromPrevious=Math.round(C*1e4)/1e4,k.distanceFromStart=Math.round((n+C)*1e4)/1e4;break}}return{etd:e,from:w,to:k,next:o.filter(v=>v),wps:h,days:b}}static currentFactor(t,e,a=0){const i=(t-(e==null?void 0:e.degree)||0)/180*Math.PI;if(Math.abs(i)===Math.PI/2)return 0;let n=((e==null?void 0:e.kts)||0)*Math.cos(i);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(t,e){var M,h,b,f,C,k,w;S==null||S.debug("calculate weather factor via: %j",{...t,...e});const a=W.blockCoefficient(t.displacement,t.lbp,t.breadthMoulded,t.draught),i=W.froudeNumber(t.speed,t.lbp),n=W.amendFactor(a,i,t.loadCondition);let o=Math.abs(t.bearing%360-(((M=e==null?void 0:e.wind)==null?void 0:M.degree)%360||0));o=o>180?360-o:o;const s=W.directionFactor(o,(h=e==null?void 0:e.wind)==null?void 0:h.scale),d=W.vesselTagFactor(t.displacement,t.loadCondition,t.tag,(b=e==null?void 0:e.wind)==null?void 0:b.scale);let r=s*n*d/100*t.speed;r=Math.round(r*1.943844*1e4)/1e4*-1,t.tag==="tugs"&&Math.abs(r)>1&&(r=r/(Math.abs(Math.round(r))+1)),S==null||S.debug("wind wx factor = %d",r),o=Math.abs(t.bearing%360-(((C=(f=e==null?void 0:e.wave)==null?void 0:f.sig)==null?void 0:C.degree)%360||0));const m=W.waveHeightFactor(((w=(k=e==null?void 0:e.wave)==null?void 0:k.sig)==null?void 0:w.height)??1,o);return S==null||S.debug("wave wx factor = %d",m),r=Math.abs(r)>Math.abs(m)?r:r*.3+m*.7,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>3?3*(Math.abs(r)/r)+Math.abs(r)/r*(Math.abs(r)-2)*.1:r,Math.round((r||0)*100)/100}static async analyseInstant(t,e,a,i,n,o="",s=0,d=!0,r=!1,m={}){var X,Q,Z,$,tt,et;const M=p().valueOf();t.lng=x.LngLatHelper.convertToStdLng(t.lng);const{route:h,waypoints:b}=n.points,f=x.LaneHelper.calculateSubRoute(t,h);if(((X=f[0])==null?void 0:X.length)<=1)return;const{v0:C,label:k}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:i.speed,label:"CP"},w=W.assembleProperties(a,i.loadCondition,C,0),v=b.length?x.LaneHelper.calculateSubWaypoints(t,b):[];v.forEach(Y=>Y.important=!0);const c={from:{...t},route:f,waypoints:v,v0:C,label:k},y={hours:[],days:[],wps:[]};s||(x.LaneHelper.calculateRouteDistance(f)/i.speed<=72?s=3:s=6);let l=x.LaneHelper.simplifyRouteToCoordinates(f,v,0),u=0,I=0,F=0,T=0;e=p(e).utc();const P=e.clone();for(;l.length>0;){const Y=s-e.hour()%s,J=Math.ceil(e.clone().add(Y,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4,j=await W.speedLoseInHoursStep(w,e,P,J,u,l,o,d,r,m);(Q=j.from)!=null&&Q.speed&&(y.hours.push(j.from),y.wps.push(...j.wps),y.days.push(...j.days)),l=j==null?void 0:j.next,l.length||y.hours.push(j==null?void 0:j.to),u+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const E=y.hours;for(let Y=0;Y<E.length-1;Y++){const J=p(E[Y+1].eta).diff(E[Y].etd,"hour",!0)||1;I+=(E[Y].wxFactor||0)*J,F+=(E[Y].cFactor||0)*J,T+=J}($=y.wps)==null||$.forEach((Y,J)=>{Y.positionTime=p.utc(Y.etd||Y.eta).unix();const j=y.wps[J-1];if(j){const B=Y.distanceFromStart-j.distanceFromStart,O=p(Y.eta||Y.etd).diff(p(j.etd||j.eta),"h",!0);Y.avgSpd=Math.round(B/O*100)/100;const ct=x.LaneHelper.calculateBearing(j,Y);j.bearing=ct}}),y.wps=(tt=y.wps)==null?void 0:tt.reduce((Y,J)=>(Y.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||Y.push(J),Y),[]),c.sample=y;const L=y.hours.at(0),N=y.hours.at(-1);c.distance=Math.round(N.distanceFromStart*1e3)/1e3,c.etd=p(L.eta).utc().format(),c.eta=p(N.eta).utc().format(),c.wxFactor=Math.round(I/T*1e3)/1e3,c.cFactor=Math.round(F/T*1e3)/1e3,c.avgSpeed=Math.round(N.distanceFromStart/T*1e3)/1e3,c.totalHrs=Math.round(T*1e3)/1e3;const{distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V,eca:U}=await this.calculateECA(c,i,m),st=x.LngLatHelper.roundPrecision(i.fo/24*(T-q),3),ot=x.LngLatHelper.roundPrecision(i.dgo/24*T,3);c.extend={eca:U,distanceInECA:H,hoursInECA:q,totalDgoConsInECA:V},c.totalFoCons=st<0?0:st,c.totalDgoCons=ot;const at=p().valueOf()-M,rt=((et=y==null?void 0:y.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",m==null?void 0:m.requestId,at,rt,Math.round(at/rt*1e3)/1e3),c}static async analyseInstantWithThreshed(t,e,a,i,n,o,s,d="",r=3,m=!0,M=!1,h={}){var Z,$,tt,et,Y,J;const b=p().valueOf();t.lng=x.LngLatHelper.convertToStdLng(t.lng);const{v0:f,label:C}=t.sog?{v0:t.sog,label:t.label||"Other"}:{v0:n.speed,label:"CP"},k=W.assembleProperties(i,n.loadCondition,f,0),w=x.LaneHelper.calculateSubRoute(t,o);if(((Z=w[0])==null?void 0:Z.length)<=1)return;const v=s.length?x.LaneHelper.calculateSubWaypoints(t,s):[];v.forEach(j=>j.important=!0);let c=x.LaneHelper.simplifyRouteToCoordinates(w,v,0),y=0,l=0,u=0,I=0;const F={hours:[],wps:[],days:[]};e=p(e).utc();const T=e.clone();for(;c.length>0;){const j=r-e.hour()%r;let B=Math.ceil(e.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(e,"h",!0)*1e4)/1e4;B=e.clone().add(B,"h").isSameOrAfter(a)?a.diff(e,"h",!0)*1e4/1e4:B;const O=await W.speedLoseInHoursStep(k,e,T,B,y,c,d,m,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),y+=Math.round((((tt=O==null?void 0:O.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!B)break}F.wps=(et=F.wps)==null?void 0:et.reduce((j,B)=>(j.some(O=>Math.round(p(O.etd).unix()/60)===Math.round(p(B.etd).unix()/60))||j.push(B),j),[]),(Y=F.wps)==null||Y.forEach((j,B)=>{const O=F.wps[B-1];if(O){const ct=j.distanceFromStart-O.distanceFromStart,wt=p(j.eta||j.etd).diff(p(O.etd||O.eta),"h",!0);j.avgSpd=Math.round(ct/wt*100)/100;const It=x.LaneHelper.calculateBearing(O,j);O.bearing=It}});const P=F.hours;for(let j=0;j<P.length-1;j++){const B=p(P[j+1].eta).diff(P[j].etd,"hour",!0);l+=P[j].wxFactor*B,u+=P[j].cFactor*B,I+=B}const E=F.hours.at(0),L=F.hours.at(-1),N=await x.LaneHelper.calculateRangeRoute(E,L,w),H=await x.LaneHelper.calculateRangeWaypoints(E,L,w,v),q={sample:F,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:p(E.eta).utc().format(),eta:p(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(l/I*1e3)/1e3,cFactor:Math.round(u/I*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/I*1e3)/1e3,totalHrs:Math.round(I*1e3)/1e3,from:E,to:L,route:N,waypoints:H,v0:f,label:C},{distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st,eca:ot}=await this.calculateECA(q,n,h),it=x.LngLatHelper.roundPrecision(n.fo/24*(I-U),3),at=x.LngLatHelper.roundPrecision(n.dgo/24*I,3);q.extend={eca:ot,distanceInECA:V,hoursInECA:U,totalDgoConsInECA:st},q.totalDgoCons=at,q.totalFoCons=it<0?0:it;const X=p().valueOf()-b,Q=((J=F==null?void 0:F.hours)==null?void 0:J.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,X,Q,Math.round(X/Q*1e3)/1e3),q}static async analyseCost(t,e,a,i,n={}){var w,v;const o=p().valueOf(),s=[];t.speedStep=t.speedStep||3,t.alterStep=t.alterStep??1;const d=x.LaneHelper.calculateRouteDistance(i.route);let r=0;a.forEach(c=>{const y=Math.ceil(d/c.speed/24);r=r<y?y:r}),r=r*1.3;const m=p.utc(t.etd).add(r??14,"day");let M=1;for(const c of a){const y=JSON.parse(JSON.stringify(i.route)),l=JSON.parse(JSON.stringify(i.waypoints)),u=await W.analyseInstantWithThreshed({lat:t.lat,lng:t.lng},t.etd,m,e,c,y,l,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,n);u&&(await W.calculateCost(u,c,t,n),s.push(u),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,M,t.etd,m.format(),{cost:u.cost.total,hire:u.cost.hire,bunker:u.cost.bunker,distance:u.distance,hours:u.totalHrs,cp:`${c.speed}/${c.fo}/${c.dgo}`})),M++}s.sort((c,y)=>c.cost.total-y.cost.total);const h=s.at(0),b=s.at(1),f=[];if(f.push({combined:!1,speeds:[h],cost:(w=h.cost)==null?void 0:w.total}),b){const c=h.cost.cp,y=b.cost.cp,l=p(h.eta),u=p(h.etd),I=l.diff(u,"days",!0);let F=Math.ceil(I/2);F=F>7?7:F<t.alterStep?t.alterStep:F;let T=2,P={combined:!1,speeds:[b],cost:(v=b.cost)==null?void 0:v.total},E;for(;F>=t.alterStep;){const L=await W.combinedAnalyse(t,e,m,[c,y],i,F,{...n,level:T});if(P.cost>L.cost?E?(E==null?void 0:E.cost)>L.cost&&(E=L):(E=P,P=L):(!E||(E==null?void 0:E.cost)>L.cost)&&(E=L),F<=t.alterStep)break;F=Math.ceil(F/2),T+=1}f.push(P),E&&f.push(E)}const k=p().valueOf()-o;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),f.sort((c,y)=>c.cost-y.cost)}static async combinedAnalyse(t,e,a,i,n,o,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,o);const d=await W.alternateAnalyse(t,e,a,i,0,n,o,s),r=d.reduce((y,l)=>y+l.cost.total,0),m=d.reduce((y,l)=>y+l.cost.hire,0),M=d.reduce((y,l)=>y+l.cost.bunker,0),h=d.reduce((y,l)=>y+l.distance,0),b=d.reduce((y,l)=>y+l.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:r,hire:m,bunker:M,distance:h,hours:b});const f=await W.alternateAnalyse(t,e,a,i,1,n,o,s),C=f.reduce((y,l)=>y+l.cost.total,0),k=f.reduce((y,l)=>y+l.cost.hire,0),w=f.reduce((y,l)=>y+l.cost.bunker,0),v=f.reduce((y,l)=>y+l.distance,0),c=f.reduce((y,l)=>y+l.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:C,hire:k,bunker:w,distance:v,hours:c}),r<C?{combined:!0,cost:Math.round(r*1e3)/1e3,speeds:d,step:o}:{combined:!0,cost:Math.round(C*1e3)/1e3,speeds:f,step:o}}static async alternateAnalyse(t,e,a,i,n,o,s,d={}){var h,b;let r=p.utc(t.etd);const m={lat:t.lat,lng:t.lng},M=[];for(;r.isBefore(a);){const f=r.clone().utc().add(s,"day"),C=JSON.parse(JSON.stringify(o.route)),k=JSON.parse(JSON.stringify(o.waypoints)),w=i[n],v=await W.analyseInstantWithThreshed(m,r.utc().format(),f,e,w,C,k,t.meteoVendor,t.speedStep,t.useMeteo,t.useRouteParam,d);v&&(await W.calculateCost(v,w,t,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,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${w.speed}/${w.fo}/${w.dgo}`})),d.counter=d.counter+1;const c=(b=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:b.at(-1);if(c)m.lat=c.lat,m.lng=c.lng,r=p(c.eta),M.push(v),n=n?0:1;else break}return M}static async calculateCost(t,e,a,i={}){var n;if(t){const o=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round(t.totalHrs/24*(a.dailyHire||0)*(1-o)*1e3)/1e3,d=Math.round(t.totalFoCons*(a.priceFO||0)*1e3)/1e3,r=Math.round((t.totalDgoCons+(((n=t.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;t.cost={total:Math.round((s+d+r)*1e3)/1e3,hire:s,bunker:Math.round((d+r)*1e3)/1e3,cp:e}}return t}static async calculateECA(t,e,a={}){var d,r,m,M;const i=await x.LaneHelper.intersectInECA((t==null?void 0:t.route)||[]);let n=0,o=0,s=0;(r=(d=t==null?void 0:t.sample)==null?void 0:d.wps)==null||r.forEach(h=>{h.positionTime=p.utc(h.etd||h.eta).unix()});for(const h of i){n+=h.distance;const b=await x.LaneHelper.deadReckoningTime((m=h.waypoints)==null?void 0:m.at(0),t.sample.wps),f=await x.LaneHelper.deadReckoningTime((M=h.waypoints)==null?void 0:M.at(-1),t.sample.wps);h.in=b,h.out=f,h.totalHrs=x.LngLatHelper.roundPrecision((f.positionTime-b.positionTime)/3600,3),h.totalDgoCons=x.LngLatHelper.roundPrecision(e.fo/24*h.totalHrs,3),o+=h.totalHrs,s+=h.totalDgoCons}return n=x.LngLatHelper.roundPrecision(n,3),o=x.LngLatHelper.roundPrecision(o,3),s=x.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:o,totalDgoConsInECA:s,eca:i}}static async mergeSpeeds(t,e={}){var c,y;const a={hours:[],wps:[],days:[]},i=t.reduce((l,u)=>l+u.distance,0),n=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.distanceInECA)||0)},0),o=t.reduce((l,u)=>l+u.totalHrs,0),s=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.hoursInECA)||0)},0),d=t.reduce((l,u)=>{var I;return l+(((I=u.extend)==null?void 0:I.totalDgoConsInECA)||0)},0),r=t.reduce((l,u)=>l+u.wxFactor*u.totalHrs/o,0),m=t.reduce((l,u)=>l+u.cFactor*u.totalHrs/o,0),M=t.reduce((l,u)=>l+u.totalFoCons,0),h=t.reduce((l,u)=>l+u.totalDgoCons,0),b=t.reduce((l,u)=>l+u.cost.total,0),f=t.reduce((l,u)=>l+u.cost.hire,0),C=t.reduce((l,u)=>l+u.cost.bunker,0),k=[],w=[];let v;for(const l of t){w.push(...((c=l.extend)==null?void 0:c.eca)||[]);const u=l.sample.hours,I=l.sample.wps,F=l.sample.days,T=u.at(0);v&&(T.distanceFromPrevious=v.distanceFromPrevious,T.distanceFromStart=v.distanceFromStart,u.forEach((N,H)=>{H&&(N.distanceFromStart=N.distanceFromStart+v.distanceFromStart)}),I.at(0).distanceFromPrevious=v.distanceFromPrevious,I.at(0).distanceFromStart=v.distanceFromStart,I.forEach((N,H)=>{H&&(N.distanceFromStart=N.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((N,H)=>{H&&(N.distanceFromStart=N.distanceFromStart+v.distanceFromStart)})),T.cp=l.cost.cp;const P=[l.etd,l.eta],E=k.findIndex(N=>N.id===T.cp.id);E===-1?(T.cp.segment=[P],k.push(T.cp)):k[E].segment.push(P),u.forEach(N=>{var q;((q=a.hours)==null?void 0:q.findIndex(V=>V.eta===N.eta))===-1&&a.hours.push(N)}),I.forEach(N=>{var q;((q=a.wps)==null?void 0:q.findIndex(V=>V.eta===N.eta))===-1&&a.wps.push(N)}),F.forEach(N=>{var q;((q=a==null?void 0:a.days)==null?void 0:q.findIndex(V=>V.eta===N.eta))===-1&&a.days.push(N)});const L=(y=a.wps)==null?void 0:y.findIndex(N=>N.eta===T.eta);L===-1?a.wps.push(T):a.wps[L]=T,v=u.at(-1)}return a.wps.sort((l,u)=>{p(l.etd).unix()-p(u.etd).unix()}),a.wps.forEach((l,u)=>{const I=a.wps[u-1];if(I){const F=l.distanceFromStart-(I.distanceFromStart||0),T=p(l.eta||l.etd).diff(p(I.etd||I.eta),"hour",!0),P=Math.round(F/T*100)/100;l.avgSpd=P;const E=x.LaneHelper.calculateBearing(I,l);I.bearing=E}}),{sample:a,etd:t.at(0).etd,eta:t.at(-1).eta,from:t.at(0).from,to:t.at(-1).to,v0:t.at(0).v0,label:"Combined",distance:Math.round(i*1e3)/1e3,totalHrs:Math.round(o*1e3)/1e3,avgSpeed:Math.round(i/o*1e3)/1e3,wxFactor:Math.round(r*1e3)/1e3,cFactor:Math.round(m*1e3)/1e3,totalFoCons:Math.round(M*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(b*1e3)/1e3,hire:Math.round(f*1e3)/1e3,bunker:Math.round(C*1e3)/1e3},extend:{cps:k,eca:w,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(d*1e3)/1e3,speeds:t}}}}A.AISImpl=G,A.AlertHelper=ut,A.AlertLevel=dt,A.HifleetImpl=Mt,A.LoadCondition=ht,A.MyShipImpl=bt,A.MyVesselImpl=yt,A.ShipxyImpl=pt,A.SpeedHelper=W,A.SpeedLabel=ft,A.VesselTag=lt,A.alertHelper=gt,Object.defineProperty(A,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "2.2.4",
4
+ "version": "2.2.6",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [
@@ -39,7 +39,7 @@
39
39
  },
40
40
  "devDependencies": {
41
41
  "@idm-plugin/geo2": "^1.4.7",
42
- "@idm-plugin/meteo": "^0.5.2",
42
+ "@idm-plugin/meteo": "^0.5.3",
43
43
  "@idm-plugin/meteo2": "^0.7.2",
44
44
  "@idm-plugin/tag": "^0.2.3",
45
45
  "@types/jest": "^25.2.2",