@idm-plugin/vessel 2.2.1 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ var lt = (E, t, e) => t in E ? ht(E, t, { enumerable: !0, configurable: !0, writ
3
3
  var K = (E, t, e) => (lt(E, typeof t != "symbol" ? t + "" : t, e), e);
4
4
  import B from "got";
5
5
  import ct from "@log4js-node/log4js-api";
6
- import b from "moment";
6
+ import g from "moment";
7
7
  import { LngLatHelper as J, LaneHelper as W } from "@idm-plugin/geo2";
8
8
  import { MeteoHelper2 as ft } from "@idm-plugin/meteo2";
9
9
  import { Meteo2Assist as rt } from "@idm-plugin/meteo";
@@ -76,12 +76,12 @@ class xt extends st {
76
76
  expiresIn: n.expires_in,
77
77
  scope: n.scope,
78
78
  jti: n.jti,
79
- issuedAt: b().utc().format()
79
+ issuedAt: g().utc().format()
80
80
  });
81
81
  }
82
82
  async realTimePosition(e, a = {}) {
83
83
  var d, r, m;
84
- (!this.token || b().diff(b(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(a);
84
+ (!this.token || g().diff(g(this.token.issuedAt), "seconds") > ((d = this.token) == null ? void 0 : d.expiresIn) - 300) && await this.authToken(a);
85
85
  const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
86
86
  headers: {
87
87
  Authorization: `${(r = this.token) == null ? void 0 : r.tokenType} ${(m = this.token) == null ? void 0 : m.accessToken}`
@@ -96,7 +96,7 @@ class xt extends st {
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) {
99
- const M = b(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
99
+ const M = g(`${s.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
100
100
  return {
101
101
  mmsi: s.mmsi,
102
102
  name: s.vesselName || s.aisVesselName,
@@ -111,7 +111,7 @@ class xt extends st {
111
111
  cog: s.cog,
112
112
  hdg: s.hdg,
113
113
  rot: s.rot,
114
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? b.utc(s.eta).format() : void 0,
114
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? g.utc(s.eta).format() : void 0,
115
115
  destination: s.dest,
116
116
  positionTime: M.unix(),
117
117
  status: s.status,
@@ -132,8 +132,8 @@ class xt extends st {
132
132
  return {};
133
133
  }
134
134
  async trajectory(e, a, i, n, o = !0, s = {}) {
135
- (!this.token || b().diff(b(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(s);
136
- const d = await this.realTimePosition(e, s), r = b(a), m = b(i), M = [];
135
+ (!this.token || g().diff(g(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(s);
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
138
  await this.trajectoryIn30Day(e, r, r.clone().add(30, "day"), d, n, M, s), r.add(30, "day");
139
139
  return await this.trajectoryIn30Day(e, r, m, d, n, M, s), M;
@@ -155,11 +155,11 @@ class xt extends st {
155
155
  if (M.code)
156
156
  return v == null || v.warn("[%s] fetch trajectory failed: %j", d.requestId, r, { message: M.message, status: M.status, code: M.code }), M;
157
157
  let l = -1;
158
- const g = b(`${(p = (S = M.data) == null ? void 0 : S[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
158
+ const b = g(`${(p = (S = M.data) == null ? void 0 : S[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
159
159
  return (w = M.data) == null || w.forEach((c) => {
160
160
  for (const Y in c)
161
161
  !isNaN(c[Y]) && Number(c[Y]) !== 1 / 0 && (c[Y] = Number(c[Y]));
162
- const y = b(`${c.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), h = c.status, { labelCn: u, labelEn: I } = this.parseStatus(h), k = {
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
164
  imo: n == null ? void 0 : n.imo,
165
165
  lat: c.lat,
@@ -169,7 +169,7 @@ class xt extends st {
169
169
  hdg: c.hdg,
170
170
  draught: c.draught,
171
171
  status: h,
172
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta) ? b(`${c.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
172
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(c.eta) ? g(`${c.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
173
173
  destination: c.dest,
174
174
  positionTime: y.unix(),
175
175
  labelCn: u,
@@ -177,7 +177,7 @@ class xt extends st {
177
177
  method: "trajectory",
178
178
  vendor: "myVessel",
179
179
  utc: y.utc().format()
180
- }, D = Math.floor(y.diff(g, "minute", !0) / (o || 1));
180
+ }, D = Math.floor(y.diff(b, "minute", !0) / (o || 1));
181
181
  D !== l && (l = D, s.push(k));
182
182
  }), s;
183
183
  }
@@ -199,10 +199,10 @@ class Et extends st {
199
199
  const s = o == null ? void 0 : o.list;
200
200
  if (!s)
201
201
  return v == null || v.warn("[%s] fetch realtime position failed: %j", a.requestId, i, o), o;
202
- for (const g in s)
203
- !isNaN(s[g]) && Number(s[g]) !== 1 / 0 && (s[g] = Number(s[g]));
202
+ for (const b in s)
203
+ !isNaN(s[b]) && Number(s[b]) !== 1 / 0 && (s[b] = Number(s[b]));
204
204
  s.status = s.sp > 3 ? 0 : 1;
205
- const d = s.status, { labelCn: r, labelEn: m } = this.parseStatus(d), M = b(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
205
+ const d = s.status, { labelCn: r, labelEn: m } = this.parseStatus(d), M = g(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
206
206
  return {
207
207
  mmsi: s.m,
208
208
  name: s.n,
@@ -217,7 +217,7 @@ class Et extends st {
217
217
  cog: s.co,
218
218
  hdg: s.h,
219
219
  rot: isNaN(s.rot) ? 0 : s.rot,
220
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? b.utc(s.eta).format() : void 0,
220
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta) ? g.utc(s.eta).format() : void 0,
221
221
  destination: s.destination,
222
222
  vesselType: s.type,
223
223
  dwt: s.dwt,
@@ -286,8 +286,8 @@ class Et extends st {
286
286
  async trajectory(e, a, i, n, o = !0, s = {}) {
287
287
  var c, y, h;
288
288
  const d = await this.realTimePosition(e, s);
289
- let r = b(a);
290
- const m = b(i), M = b();
289
+ let r = g(a);
290
+ const m = g(i), M = g();
291
291
  if (o) {
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");
@@ -299,17 +299,17 @@ class Et extends st {
299
299
  mmsi: e,
300
300
  usertoken: this.token
301
301
  }
302
- }, g = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", f = await B.get(g, l).json();
303
- v == null || v.info("[%s] fetch trajectory from: %s - %j", s.requestId, g, l);
302
+ }, b = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", f = await B.get(b, l).json();
303
+ v == null || v.info("[%s] fetch trajectory from: %s - %j", s.requestId, b, l);
304
304
  let C;
305
305
  f && (C = ((y = (c = f.ships) == null ? void 0 : c.offors) == null ? void 0 : y.ship) || [], C.length || v == null || v.warn("[%s] fetch trajectory failed: %j", s.requestId, f));
306
306
  const S = [];
307
307
  let p = -1;
308
- const w = b(`${(h = C == null ? void 0 : C[0]) == null ? void 0 : h.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
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
310
  for (const P in u)
311
311
  !isNaN(u[P]) && Number(u[P]) !== 1 / 0 && (u[P] = Number(u[P]));
312
- const I = b(`${u.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
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 = {
315
315
  mmsi: u.m,
@@ -353,7 +353,7 @@ class jt extends st {
353
353
  const s = o.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
- const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), m = b.unix(s.lasttime);
356
+ const { labelCn: d, labelEn: r } = await this.parseStatus(s.navistat), m = g.unix(s.lasttime);
357
357
  return {
358
358
  mmsi: s.ShipID,
359
359
  name: s.name,
@@ -379,7 +379,7 @@ class jt extends st {
379
379
  }
380
380
  async trajectory(e, a, i, n, o = !0, s = {}) {
381
381
  var w;
382
- const d = await this.realTimePosition(e, s), r = b(a), m = b(i), M = "https://api.shipxy.com/apicall/GetShipTrack", l = {
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: {
384
384
  id: e,
385
385
  k: this.token,
@@ -388,13 +388,13 @@ class jt extends st {
388
388
  btm: r.unix(),
389
389
  etm: m.unix()
390
390
  }
391
- }, g = await B.get(M, l).json();
392
- if (v == null || v.info("[%s] fetch trajectory from: %s - %j", s.requestId, M, l), (g == null ? void 0 : g.status) !== 0)
393
- return g;
394
- const f = g == null ? void 0 : g.points, C = [], S = b.unix((w = f[0]) == null ? void 0 : w.utc);
391
+ }, b = await B.get(M, l).json();
392
+ if (v == null || v.info("[%s] fetch trajectory from: %s - %j", s.requestId, M, l), (b == null ? void 0 : b.status) !== 0)
393
+ return b;
394
+ const f = b == null ? void 0 : b.points, C = [], S = g.unix((w = f[0]) == null ? void 0 : w.utc);
395
395
  let p = -1;
396
396
  for (const c of f) {
397
- const y = b.unix(c.utc), h = {
397
+ const y = g.unix(c.utc), h = {
398
398
  imo: d == null ? void 0 : d.imo,
399
399
  mmsi: e,
400
400
  sog: Math.round(c.sog * 3600 / 1e3 / 1852 * 100) / 100,
@@ -464,7 +464,7 @@ class Nt extends st {
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
- const { labelCn: m, labelEn: M } = await this.parseStatus(r.aisNavStatus), l = b.unix(r.posTime);
467
+ const { labelCn: m, labelEn: M } = await this.parseStatus(r.aisNavStatus), l = g.unix(r.posTime);
468
468
  return {
469
469
  ...n,
470
470
  mmsi: e,
@@ -484,7 +484,7 @@ class Nt extends st {
484
484
  };
485
485
  }
486
486
  async trajectory(e, a, i, n, o = !0, s = {}) {
487
- const d = b(a), r = b(i), m = await this.getShipId(e), M = await this.getShipInfo(m), l = [];
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
489
  await this.trajectoryIn30Day(m, d.unix(), d.add(30, "day").unix(), M, e, n, l);
490
490
  return await this.trajectoryIn30Day(m, d.unix(), r.unix(), M, e, n, l), l;
@@ -503,13 +503,13 @@ class Nt extends st {
503
503
  }, M = "https://api3.myships.com/sp/ships/position/history", l = await B.post(M, m).json();
504
504
  if (v == null || v.info("[%s] fetch trajectory from: %s - %j", r.requestId, M, m), l.code !== "0")
505
505
  return v == null || v.warn("[%s] invoke myship trajectory failed: %j", r.requestId, l), l;
506
- const g = l.data;
507
- for (const p in g)
508
- !isNaN(g[p]) && Number(g[p]) !== 1 / 0 && (g[p] = Number(g[p]));
509
- const f = b.unix((S = g[0]) == null ? void 0 : S.posTime);
506
+ const b = l.data;
507
+ for (const p in b)
508
+ !isNaN(b[p]) && Number(b[p]) !== 1 / 0 && (b[p] = Number(b[p]));
509
+ const f = g.unix((S = b[0]) == null ? void 0 : S.posTime);
510
510
  let C = -1;
511
- for (const p of g) {
512
- const w = b.unix(p.posTime), c = {
511
+ for (const p of b) {
512
+ const w = g.unix(p.posTime), c = {
513
513
  imo: n == null ? void 0 : n.imo,
514
514
  mmsi: o,
515
515
  lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
@@ -556,7 +556,7 @@ class yt {
556
556
  if (m === 0 && !M)
557
557
  o.scope = n[0];
558
558
  else if (M)
559
- for (let l = 0, g = M.length; l < g; l++) {
559
+ for (let l = 0, b = M.length; l < b; l++) {
560
560
  const f = this.parseRule(M[l]);
561
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);
562
562
  }
@@ -591,12 +591,12 @@ class yt {
591
591
  checkWeather(t, e, a = {}) {
592
592
  var f, C, S, p, w, c, y, h, u, I, k, D, Y, j, P;
593
593
  let i = 0, n = 0, o = 0, s = 0;
594
- 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, g = (D = (k = e == null ? void 0 : e.HEAVY) == null ? void 0 : k.wind) == null ? void 0 : D.number;
594
+ 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
595
  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 ? b(N.eta).diff(b(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: g }), (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) === g && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), i += N.isDangerous ? U : 0, n += N.isSevere ? U : 0, o += N.isHeavy ? U : 0;
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
598
  }
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: g }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: m } };
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 } };
600
600
  }
601
601
  }
602
602
  const Tt = new yt();
@@ -607,7 +607,7 @@ try {
607
607
  } finally {
608
608
  }
609
609
  const Mt = new ft("", !0);
610
- var gt = /* @__PURE__ */ ((E) => (E.common = "common", E.container = "container", E.tugs = "tugs", E))(gt || {}), bt = /* @__PURE__ */ ((E) => (E.Ballast = "Ballast", E.Laden = "Laden", E))(bt || {}), wt = /* @__PURE__ */ ((E) => (E.Cp = "CP", E.Perf = "Basis", E.Instruct = "Other", E))(wt || {});
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 || {});
611
611
  class O {
612
612
  /**
613
613
  * @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
@@ -709,7 +709,7 @@ class O {
709
709
  static waveHeightFactor(t, e) {
710
710
  t = t < 3 ? t * 0.7 : t, t = t < 0 ? 0.2 : t, t = t > 6 ? t - 0.9 * (t - 6) : t, t = t > 9 ? 9 : t;
711
711
  let a;
712
- return e > 30 && e <= 60 ? a = -0.6 : e > 60 && e <= 90 ? a = -0.4 : e > 90 && e <= 120 ? a = t < 3 ? 0.4 : -0.3 : e > 120 && e <= 150 ? a = t < 3 ? 0.6 : -0.5 : e > 150 && e <= 180 ? a = t < 3 ? 0.7 : -0.6 : a = -0.7, Math.round(a * (0.102 * Math.pow(t, 2) + 0.178 * t) * 1e4) / 1e4;
712
+ return e > 30 && e <= 60 ? a = -0.6 : e > 60 && e <= 90 ? a = -0.4 : e > 90 && e <= 120 ? a = t < 3 ? 0.4 : -0.3 : e > 120 && e <= 150 ? a = t < 3 ? 0.6 : -0.5 : e > 150 && e <= 180 ? a = t < 3 ? 0.7 : -0.6 : a = -0.7, Math.round(a * (0.144 * Math.pow(t, 3) + 0.178 * t) * 1e4) / 1e4;
713
713
  }
714
714
  /**
715
715
  * 组装船舶运行参数
@@ -763,12 +763,12 @@ class O {
763
763
  } catch (f) {
764
764
  F.warn("[%s] meteo2 spot(%j) forecast failed: %s", d.requestId, { ...e, eta: a.utc().format(), source: i }, f);
765
765
  }
766
- const M = O.weatherFactor(t, m), l = O.currentFactor(t.bearing, m == null ? void 0 : m.current, n), g = Math.round((t.speed * 1.943844 + M + l) * 100) / 100;
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;
767
767
  r = {
768
768
  meteo: { ...m },
769
769
  wxFactor: M,
770
770
  cFactor: l,
771
- speed: e.velocity && s ? e.velocity : g < 0 ? 1 : g,
771
+ speed: e.velocity && s ? e.velocity : b < 0 ? 1 : b,
772
772
  eta: a.utc().format(),
773
773
  etd: a.utc().format()
774
774
  };
@@ -797,7 +797,7 @@ class O {
797
797
  */
798
798
  static async speedLoseInHoursStep(t, e, a, i, n, o, s = "", d = !0, r = !1, m = {}) {
799
799
  e.utc();
800
- const M = e.clone().add(14, "days"), l = [], g = [];
800
+ const M = e.clone().add(14, "days"), l = [], b = [];
801
801
  let f = 0, C = 0, S, p;
802
802
  for (let w = 0; w < o.length - 1; w++) {
803
803
  let c = o[w];
@@ -813,10 +813,10 @@ class O {
813
813
  c.elapsed += k, e.add(k, "hour"), i = 0;
814
814
  }
815
815
  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: g };
816
+ return c.distanceFromPrevious = C, { etd: e, from: p || c, to: c, next: o.filter((k) => k), wps: l, days: b };
817
817
  } else
818
818
  c.suspend = 0;
819
- 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) && (g.push(c), a.add(24, "hour"));
819
+ 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
820
  const h = W.calculateDistance(c, y, !y.gcToPrevious);
821
821
  let u = Math.round(h / p.speed * 1e5) / 1e5;
822
822
  if (f + u < i) {
@@ -841,7 +841,7 @@ class O {
841
841
  break;
842
842
  }
843
843
  }
844
- return { etd: e, from: p, to: S, next: o.filter((w) => w), wps: l, days: g };
844
+ return { etd: e, from: p, to: S, next: o.filter((w) => w), wps: l, days: b };
845
845
  }
846
846
  /**
847
847
  * 洋流影响因子
@@ -862,16 +862,16 @@ class O {
862
862
  * @param wwc 气象要素
863
863
  */
864
864
  static weatherFactor(t, e) {
865
- var M, l, g, f, C, S, p;
865
+ var M, l, b, f, C, S, p;
866
866
  F == null || F.debug("calculate weather factor via: %j", { ...t, ...e });
867
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
868
  let o = Math.abs(t.bearing % 360 - (((M = e == null ? void 0 : e.wind) == null ? void 0 : M.degree) % 360 || 0));
869
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, (g = e == null ? void 0 : e.wind) == null ? void 0 : g.scale);
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
871
  let r = s * n * d / 100 * t.speed;
872
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
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);
874
- return F == null || F.debug("wave wx factor = %d", m), r = r * 0.3 + m * 0.7, F == null || F.debug("weather factor = %d", r), r = Math.abs(r) > 2 ? 2 * (Math.abs(r) / r) + Math.abs(r) / r * (Math.abs(r) - 2) * 0.1 : r, Math.round((r || 0) * 100) / 100;
874
+ 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
875
  }
876
876
  /**
877
877
  * 全程失速分析(走完航程)
@@ -887,9 +887,9 @@ class O {
887
887
  */
888
888
  static async analyseInstant(t, e, a, i, n, o = "", s = 0, d = !0, r = !1, m = {}) {
889
889
  var z, G, Q, X, Z, $;
890
- const M = b().valueOf();
890
+ const M = g().valueOf();
891
891
  t.lng = J.convertToStdLng(t.lng);
892
- const { route: l, waypoints: g } = n.points, f = W.calculateSubRoute(t, l);
892
+ const { route: l, waypoints: b } = n.points, f = W.calculateSubRoute(t, l);
893
893
  if (((z = f[0]) == null ? void 0 : z.length) <= 1)
894
894
  return;
895
895
  const { v0: C, label: S } = t.sog ? {
@@ -900,7 +900,7 @@ class O {
900
900
  v0: i.speed,
901
901
  label: "CP"
902
902
  /* Cp */
903
- }, p = O.assembleProperties(a, i.loadCondition, C, 0), w = g.length ? W.calculateSubWaypoints(t, g) : [];
903
+ }, p = O.assembleProperties(a, i.loadCondition, C, 0), w = b.length ? W.calculateSubWaypoints(t, b) : [];
904
904
  w.forEach((q) => q.important = !0);
905
905
  const c = {
906
906
  from: { ...t },
@@ -915,7 +915,7 @@ class O {
915
915
  };
916
916
  s || (W.calculateRouteDistance(f) / i.speed <= 72 ? s = 3 : s = 6);
917
917
  let h = W.simplifyRouteToCoordinates(f, w, 0), u = 0, I = 0, k = 0, D = 0;
918
- e = b(e).utc();
918
+ e = g(e).utc();
919
919
  const Y = e.clone();
920
920
  for (; h.length > 0; ) {
921
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(
@@ -934,21 +934,21 @@ class O {
934
934
  }
935
935
  const j = y.hours;
936
936
  for (let q = 0; q < j.length - 1; q++) {
937
- const V = b(j[q + 1].eta).diff(j[q].etd, "hour", !0) || 1;
937
+ const V = g(j[q + 1].eta).diff(j[q].etd, "hour", !0) || 1;
938
938
  I += (j[q].wxFactor || 0) * V, k += (j[q].cFactor || 0) * V, D += V;
939
939
  }
940
940
  (X = y.wps) == null || X.forEach((q, V) => {
941
- q.positionTime = b.utc(q.etd || q.eta).unix();
941
+ q.positionTime = g.utc(q.etd || q.eta).unix();
942
942
  const x = y.wps[V - 1];
943
943
  if (x) {
944
- const L = q.distanceFromStart - x.distanceFromStart, H = b(q.eta || q.etd).diff(b(x.etd || x.eta), "h", !0);
944
+ const L = q.distanceFromStart - x.distanceFromStart, H = g(q.eta || q.etd).diff(g(x.etd || x.eta), "h", !0);
945
945
  q.avgSpd = Math.round(L / H * 100) / 100;
946
946
  const it = W.calculateBearing(x, q);
947
947
  x.bearing = it;
948
948
  }
949
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
950
  const P = y.hours.at(0), T = y.hours.at(-1);
951
- c.distance = Math.round(T.distanceFromStart * 1e3) / 1e3, c.etd = b(P.eta).utc().format(), c.eta = b(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;
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
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);
953
953
  c.extend = {
954
954
  eca: U,
@@ -956,7 +956,7 @@ class O {
956
956
  hoursInECA: A,
957
957
  totalDgoConsInECA: R
958
958
  }, c.totalFoCons = tt < 0 ? 0 : tt, c.totalDgoCons = at;
959
- const et = b().valueOf() - M, nt = (($ = y == null ? void 0 : y.hours) == null ? void 0 : $.length) || 1;
959
+ const et = g().valueOf() - M, nt = (($ = y == null ? void 0 : y.hours) == null ? void 0 : $.length) || 1;
960
960
  return F == null || F.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", m == null ? void 0 : m.requestId, et, nt, Math.round(et / nt * 1e3) / 1e3), c;
961
961
  }
962
962
  /**
@@ -974,7 +974,7 @@ class O {
974
974
  */
975
975
  static async analyseInstantWithThreshed(t, e, a, i, n, o, s, d = "", r = 3, m = !0, M = !1, l = {}) {
976
976
  var Q, X, Z, $, q, V;
977
- const g = b().valueOf();
977
+ const b = g().valueOf();
978
978
  t.lng = J.convertToStdLng(t.lng);
979
979
  const { v0: f, label: C } = t.sog ? {
980
980
  v0: t.sog,
@@ -995,7 +995,7 @@ class O {
995
995
  wps: [],
996
996
  days: []
997
997
  };
998
- e = b(e).utc();
998
+ e = g(e).utc();
999
999
  const D = e.clone();
1000
1000
  for (; c.length > 0; ) {
1001
1001
  const x = r - e.hour() % r;
@@ -1005,10 +1005,10 @@ class O {
1005
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)
1006
1006
  break;
1007
1007
  }
1008
- k.wps = ($ = k.wps) == null ? void 0 : $.reduce((x, L) => (x.some((H) => Math.round(b(H.etd).unix() / 60) === Math.round(b(L.etd).unix() / 60)) || x.push(L), x), []), (q = k.wps) == null || q.forEach((x, L) => {
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) => {
1009
1009
  const H = k.wps[L - 1];
1010
1010
  if (H) {
1011
- const it = x.distanceFromStart - H.distanceFromStart, dt = b(x.eta || x.etd).diff(b(H.etd || H.eta), "h", !0);
1011
+ const it = x.distanceFromStart - H.distanceFromStart, dt = g(x.eta || x.etd).diff(g(H.etd || H.eta), "h", !0);
1012
1012
  x.avgSpd = Math.round(it / dt * 100) / 100;
1013
1013
  const ut = W.calculateBearing(H, x);
1014
1014
  H.bearing = ut;
@@ -1016,15 +1016,15 @@ class O {
1016
1016
  });
1017
1017
  const Y = k.hours;
1018
1018
  for (let x = 0; x < Y.length - 1; x++) {
1019
- const L = b(Y[x + 1].eta).diff(Y[x].etd, "hour", !0);
1019
+ const L = g(Y[x + 1].eta).diff(Y[x].etd, "hour", !0);
1020
1020
  h += Y[x].wxFactor * L, u += Y[x].cFactor * L, I += L;
1021
1021
  }
1022
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 = {
1023
1023
  sample: k,
1024
1024
  distance: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) * 1e4) / 1e4,
1025
1025
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1026
- etd: b(j.eta).utc().format(),
1027
- eta: b(P == null ? void 0 : P.eta).utc().format(),
1026
+ etd: g(j.eta).utc().format(),
1027
+ eta: g(P == null ? void 0 : P.eta).utc().format(),
1028
1028
  wxFactor: Math.round(h / I * 1e3) / 1e3,
1029
1029
  cFactor: Math.round(u / I * 1e3) / 1e3,
1030
1030
  avgSpeed: Math.round(((P == null ? void 0 : P.distanceFromStart) || 0) / I * 1e3) / 1e3,
@@ -1042,7 +1042,7 @@ class O {
1042
1042
  hoursInECA: U,
1043
1043
  totalDgoConsInECA: tt
1044
1044
  }, A.totalDgoCons = et, A.totalFoCons = ot < 0 ? 0 : ot;
1045
- const z = b().valueOf() - g, G = ((V = k == null ? void 0 : k.hours) == null ? void 0 : V.length) || 1;
1045
+ const z = g().valueOf() - b, G = ((V = k == null ? void 0 : k.hours) == null ? void 0 : V.length) || 1;
1046
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;
1047
1047
  }
1048
1048
  /**
@@ -1062,7 +1062,7 @@ class O {
1062
1062
  */
1063
1063
  static async analyseCost(t, e, a, i, n = {}) {
1064
1064
  var p, w;
1065
- const o = b().valueOf(), s = [];
1065
+ const o = g().valueOf(), s = [];
1066
1066
  t.speedStep = t.speedStep || 3, t.alterStep = t.alterStep ?? 1;
1067
1067
  const d = W.calculateRouteDistance(i.route);
1068
1068
  let r = 0;
@@ -1070,7 +1070,7 @@ class O {
1070
1070
  const y = Math.ceil(d / c.speed / 24);
1071
1071
  r = r < y ? y : r;
1072
1072
  }), r = r * 1.3;
1073
- const m = b.utc(t.etd).add(r ?? 14, "day");
1073
+ const m = g.utc(t.etd).add(r ?? 14, "day");
1074
1074
  let M = 1;
1075
1075
  for (const c of a) {
1076
1076
  const y = JSON.parse(JSON.stringify(i.route)), h = JSON.parse(JSON.stringify(i.waypoints)), u = await O.analyseInstantWithThreshed(
@@ -1097,12 +1097,12 @@ class O {
1097
1097
  })), M++;
1098
1098
  }
1099
1099
  s.sort((c, y) => c.cost.total - y.cost.total);
1100
- const l = s.at(0), g = s.at(1), f = [];
1101
- if (f.push({ combined: !1, speeds: [l], cost: (p = l.cost) == null ? void 0 : p.total }), g) {
1102
- const c = l.cost.cp, y = g.cost.cp, h = b(l.eta), u = b(l.etd), I = h.diff(u, "days", !0);
1100
+ const l = s.at(0), b = s.at(1), f = [];
1101
+ if (f.push({ combined: !1, speeds: [l], cost: (p = l.cost) == null ? void 0 : p.total }), b) {
1102
+ const c = l.cost.cp, y = b.cost.cp, h = g(l.eta), u = g(l.etd), I = h.diff(u, "days", !0);
1103
1103
  let k = Math.ceil(I / 2);
1104
1104
  k = k > 7 ? 7 : k < t.alterStep ? t.alterStep : k;
1105
- let D = 2, Y = { combined: !1, speeds: [g], cost: (w = g.cost) == null ? void 0 : w.total }, j;
1105
+ let D = 2, Y = { combined: !1, speeds: [b], cost: (w = b.cost) == null ? void 0 : w.total }, j;
1106
1106
  for (; k >= t.alterStep; ) {
1107
1107
  const P = await O.combinedAnalyse(t, e, m, [c, y], i, k, { ...n, level: D });
1108
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)
@@ -1111,7 +1111,7 @@ class O {
1111
1111
  }
1112
1112
  f.push(Y), j && f.push(j);
1113
1113
  }
1114
- const S = b().valueOf() - o;
1114
+ const S = g().valueOf() - o;
1115
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
1116
  }
1117
1117
  /**
@@ -1126,13 +1126,13 @@ class O {
1126
1126
  */
1127
1127
  static async combinedAnalyse(t, e, a, i, n, o, s = {}) {
1128
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), g = d.reduce((y, h) => y + h.totalHrs, 0);
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);
1130
1130
  F == null || F.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1131
1131
  cost: r,
1132
1132
  hire: m,
1133
1133
  bunker: M,
1134
1134
  distance: l,
1135
- hours: g
1135
+ hours: b
1136
1136
  });
1137
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);
1138
1138
  return F == null || F.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
@@ -1155,8 +1155,8 @@ class O {
1155
1155
  * @param options
1156
1156
  */
1157
1157
  static async alternateAnalyse(t, e, a, i, n, o, s, d = {}) {
1158
- var l, g;
1159
- let r = b.utc(t.etd);
1158
+ var l, b;
1159
+ let r = g.utc(t.etd);
1160
1160
  const m = { lat: t.lat, lng: t.lng }, M = [];
1161
1161
  for (; r.isBefore(a); ) {
1162
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(
@@ -1189,9 +1189,9 @@ class O {
1189
1189
  cp: `${p.speed}/${p.fo}/${p.dgo}`
1190
1190
  }
1191
1191
  )), d.counter = d.counter + 1;
1192
- const c = (g = (l = w == null ? void 0 : w.sample) == null ? void 0 : l.hours) == null ? void 0 : g.at(-1);
1192
+ const c = (b = (l = w == null ? void 0 : w.sample) == null ? void 0 : l.hours) == null ? void 0 : b.at(-1);
1193
1193
  if (c)
1194
- m.lat = c.lat, m.lng = c.lng, r = b(c.eta), M.push(w), n = n ? 0 : 1;
1194
+ m.lat = c.lat, m.lng = c.lng, r = g(c.eta), M.push(w), n = n ? 0 : 1;
1195
1195
  else
1196
1196
  break;
1197
1197
  }
@@ -1226,12 +1226,12 @@ class O {
1226
1226
  const i = await W.intersectInECA((t == null ? void 0 : t.route) || []);
1227
1227
  let n = 0, o = 0, s = 0;
1228
1228
  (r = (d = t == null ? void 0 : t.sample) == null ? void 0 : d.wps) == null || r.forEach((l) => {
1229
- l.positionTime = b.utc(l.etd || l.eta).unix();
1229
+ l.positionTime = g.utc(l.etd || l.eta).unix();
1230
1230
  });
1231
1231
  for (const l of i) {
1232
1232
  n += l.distance;
1233
- const g = 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 = g, l.out = f, l.totalHrs = J.roundPrecision((f.positionTime - g.positionTime) / 3600, 3), l.totalDgoCons = J.roundPrecision(e.fo / 24 * l.totalHrs, 3), o += l.totalHrs, s += l.totalDgoCons;
1233
+ 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;
1235
1235
  }
1236
1236
  return n = J.roundPrecision(n, 3), o = J.roundPrecision(o, 3), s = J.roundPrecision(s, 3), {
1237
1237
  distanceInECA: n,
@@ -1260,7 +1260,7 @@ class O {
1260
1260
  }, 0), d = t.reduce((h, u) => {
1261
1261
  var I;
1262
1262
  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), g = 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 = [];
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 = [];
1264
1264
  let w;
1265
1265
  for (const h of t) {
1266
1266
  p.push(...((c = h.extend) == null ? void 0 : c.eca) || []);
@@ -1287,11 +1287,11 @@ class O {
1287
1287
  P === -1 ? a.wps.push(D) : a.wps[P] = D, w = u.at(-1);
1288
1288
  }
1289
1289
  return a.wps.sort((h, u) => {
1290
- b(h.etd).unix() - b(u.etd).unix();
1290
+ g(h.etd).unix() - g(u.etd).unix();
1291
1291
  }), a.wps.forEach((h, u) => {
1292
1292
  const I = a.wps[u - 1];
1293
1293
  if (I) {
1294
- const k = h.distanceFromStart - (I.distanceFromStart || 0), D = b(h.eta || h.etd).diff(b(I.etd || I.eta), "hour", !0), Y = Math.round(k / D * 100) / 100;
1294
+ const k = h.distanceFromStart - (I.distanceFromStart || 0), D = g(h.eta || h.etd).diff(g(I.etd || I.eta), "hour", !0), Y = Math.round(k / D * 100) / 100;
1295
1295
  h.avgSpd = Y;
1296
1296
  const j = W.calculateBearing(I, h);
1297
1297
  I.bearing = j;
@@ -1312,7 +1312,7 @@ class O {
1312
1312
  totalFoCons: Math.round(M * 1e3) / 1e3,
1313
1313
  totalDgoCons: Math.round(l * 1e3) / 1e3,
1314
1314
  cost: {
1315
- total: Math.round(g * 1e3) / 1e3,
1315
+ total: Math.round(b * 1e3) / 1e3,
1316
1316
  hire: Math.round(f * 1e3) / 1e3,
1317
1317
  bunker: Math.round(C * 1e3) / 1e3
1318
1318
  },
@@ -1332,12 +1332,12 @@ export {
1332
1332
  yt as AlertHelper,
1333
1333
  mt as AlertLevel,
1334
1334
  Et as HifleetImpl,
1335
- bt as LoadCondition,
1335
+ gt as LoadCondition,
1336
1336
  Nt as MyShipImpl,
1337
1337
  xt as MyVesselImpl,
1338
1338
  jt as ShipxyImpl,
1339
1339
  O as SpeedHelper,
1340
1340
  wt as SpeedLabel,
1341
- gt as VesselTag,
1341
+ bt as VesselTag,
1342
1342
  Tt as alertHelper
1343
1343
  };
@@ -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*(.102*Math.pow(t,2)+.178*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=r*.3+m*.7,S==null||S.debug("weather factor = %d",r),r=Math.abs(r)>2?2*(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,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,3)+.178*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"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "2.2.1",
4
+ "version": "2.2.2",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [