@idm-plugin/vessel 3.7.9 → 3.8.0

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
@@ -260,9 +260,9 @@ class Tt extends nt {
260
260
  json: l
261
261
  };
262
262
  g == null || g.info("[%s] fetch route from: %s - %j", s.requestId, u, h);
263
- const d = await z.post(u, h).json();
264
- if (d.status !== 200)
265
- return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: d.message, status: d.status, code: d.code }), {};
263
+ const c = await z.post(u, h).json();
264
+ if (c.status !== 200)
265
+ return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: c.message, status: c.status, code: c.code }), {};
266
266
  {
267
267
  const k = {
268
268
  status: "Success",
@@ -273,7 +273,7 @@ class Tt extends nt {
273
273
  route: [],
274
274
  distance: 0,
275
275
  memo: ""
276
- }, { nodes: w, seas: v, tracks: m, specialRegions: c, ecaLength: f } = d.data;
276
+ }, { nodes: w, seas: v, tracks: m, specialRegions: d, ecaLength: f } = c.data;
277
277
  k.nodes = w == null ? void 0 : w.map((M) => ({
278
278
  code: M.nodeCode,
279
279
  nameEn: M.nameEn,
@@ -314,7 +314,7 @@ class Tt extends nt {
314
314
  lng: Math.round(M.maxLon * 1e6) / 1e6
315
315
  },
316
316
  level: M.mapLevel
317
- })), c == null || c.map((M) => {
317
+ })), d == null || d.map((M) => {
318
318
  M.regionLength && k.regions.push({
319
319
  type: M.regionType,
320
320
  distance: M.regionLength,
@@ -357,12 +357,12 @@ class Tt extends nt {
357
357
  const h = await z.post(u, l).json();
358
358
  if (h.code)
359
359
  return g == null || g.warn("[%s] fetch trajectory failed: %j", r.requestId, u, { message: h.message, status: h.status, code: h.code }), h;
360
- let d = -1;
360
+ let c = -1;
361
361
  const I = p(`${(w = (k = h.data) == null ? void 0 : k[0]) == null ? void 0 : w.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
362
362
  return (v = h.data) == null || v.forEach((m) => {
363
363
  for (const N in m)
364
364
  !isNaN(m[N]) && Number(m[N]) !== 1 / 0 && (m[N] = Number(m[N]));
365
- const c = p(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), f = m.status, { labelCn: y, labelEn: S } = this.parseStatus(f), M = {
365
+ const d = p(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), f = m.status, { labelCn: y, labelEn: S } = this.parseStatus(f), M = {
366
366
  mmsi: m.mmsi,
367
367
  imo: i == null ? void 0 : i.imo,
368
368
  lat: m.lat,
@@ -374,14 +374,14 @@ class Tt extends nt {
374
374
  status: f,
375
375
  eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta) ? p(`${m.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
376
376
  destination: m.dest,
377
- positionTime: c.unix(),
377
+ positionTime: d.unix(),
378
378
  labelCn: y,
379
379
  labelEn: S,
380
380
  method: "trajectory",
381
381
  vendor: "myVessel",
382
- utc: c.utc().format()
383
- }, j = Math.floor(c.diff(I, "minute", !0) / (a || 1));
384
- j !== d && (d = j, s.push(M));
382
+ utc: d.utc().format()
383
+ }, j = Math.floor(d.diff(I, "minute", !0) / (a || 1));
384
+ j !== c && (c = j, s.push(M));
385
385
  }), s;
386
386
  }
387
387
  }
@@ -487,7 +487,7 @@ class jt extends nt {
487
487
  return s.sort((r, u) => u.score - r.score), s;
488
488
  }
489
489
  async trajectory(t, n, o, i, a = !0, s = {}) {
490
- var m, c, f;
490
+ var m, d, f;
491
491
  const r = await this.realTimePosition(t, s);
492
492
  let u = p(n);
493
493
  const l = p(o), h = p();
@@ -495,17 +495,17 @@ class jt extends nt {
495
495
  let y = l.diff(u, "d", !0);
496
496
  y < 0 ? u = l.clone().subtract(40, "d") : y < 30 ? u.subtract(10, "d") : y < 60 ? u.subtract(5, "d") : u = l.clone().subtract(80, "d"), y = h.diff(l, "d", !0), l.add(y > 10 ? 240 : y * 24, "h");
497
497
  }
498
- const d = {
498
+ const c = {
499
499
  searchParams: {
500
500
  endtime: l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
501
501
  starttime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
502
502
  mmsi: t,
503
503
  usertoken: this.token
504
504
  }
505
- }, I = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await z.get(I, d).json();
506
- g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, I, d);
505
+ }, I = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await z.get(I, c).json();
506
+ g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, I, c);
507
507
  let E;
508
- b && (E = ((c = (m = b.ships) == null ? void 0 : m.offors) == null ? void 0 : c.ship) || [], E.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
508
+ b && (E = ((d = (m = b.ships) == null ? void 0 : m.offors) == null ? void 0 : d.ship) || [], E.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
509
509
  const k = [];
510
510
  let w = -1;
511
511
  const v = p(`${(f = E == null ? void 0 : E[0]) == null ? void 0 : f.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
@@ -554,8 +554,8 @@ class xt extends nt {
554
554
  if (g == null || g.info("[%s] fetch realtime position from: %s - %j", n.requestId, i, o), (a == null ? void 0 : a.status) !== 0)
555
555
  return a;
556
556
  const s = a.data[0];
557
- for (const d in s)
558
- !isNaN(s[d]) && Number(s[d]) !== 1 / 0 && (s[d] = Number(s[d]));
557
+ for (const c in s)
558
+ !isNaN(s[c]) && Number(s[c]) !== 1 / 0 && (s[c] = Number(s[c]));
559
559
  const { labelCn: r, labelEn: u } = await this.parseStatus(s.navistat), l = p.unix(s.lasttime);
560
560
  return {
561
561
  mmsi: s.ShipID,
@@ -582,7 +582,7 @@ class xt extends nt {
582
582
  }
583
583
  async trajectory(t, n, o, i, a = !0, s = {}) {
584
584
  var v;
585
- const r = await this.realTimePosition(t, s), u = p(n), l = p(o), h = "https://api.shipxy.com/apicall/GetShipTrack", d = {
585
+ const r = await this.realTimePosition(t, s), u = p(n), l = p(o), h = "https://api.shipxy.com/apicall/GetShipTrack", c = {
586
586
  searchParams: {
587
587
  id: t,
588
588
  k: this.token,
@@ -591,24 +591,24 @@ class xt extends nt {
591
591
  btm: u.unix(),
592
592
  etm: l.unix()
593
593
  }
594
- }, I = await z.get(h, d).json();
595
- if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, h, d), (I == null ? void 0 : I.status) !== 0)
594
+ }, I = await z.get(h, c).json();
595
+ if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, h, c), (I == null ? void 0 : I.status) !== 0)
596
596
  return I;
597
597
  const b = I == null ? void 0 : I.points, E = [], k = p.unix((v = b[0]) == null ? void 0 : v.utc);
598
598
  let w = -1;
599
599
  for (const m of b) {
600
- const c = p.unix(m.utc), f = {
600
+ const d = p.unix(m.utc), f = {
601
601
  imo: r == null ? void 0 : r.imo,
602
602
  mmsi: t,
603
603
  sog: Math.round(m.sog * 3600 / 1e3 / 1852 * 100) / 100,
604
604
  cog: Math.round(m.cog / 100 * 100) / 100,
605
605
  lat: Math.round(m.lat / 1e6 * 1e5) / 1e5,
606
606
  lng: Math.round(m.lon / 1e6 * 1e5) / 1e5,
607
- positionTime: c.unix(),
608
- utc: c.utc().format(),
607
+ positionTime: d.unix(),
608
+ utc: d.utc().format(),
609
609
  method: "trajectory",
610
610
  vendor: "shipxy"
611
- }, y = Math.floor(c.diff(k, "minute", !0) / (i || 1));
611
+ }, y = Math.floor(d.diff(k, "minute", !0) / (i || 1));
612
612
  y !== w && (w = y, E.push(f));
613
613
  }
614
614
  return E;
@@ -667,7 +667,7 @@ class Nt extends nt {
667
667
  const u = r.data[0];
668
668
  for (const b in u)
669
669
  !isNaN(u[b]) && Number(u[b]) !== 1 / 0 && (u[b] = Number(u[b]));
670
- const { labelCn: l, labelEn: h } = await this.parseStatus(u.aisNavStatus), d = p.unix(u.posTime);
670
+ const { labelCn: l, labelEn: h } = await this.parseStatus(u.aisNavStatus), c = p.unix(u.posTime);
671
671
  return {
672
672
  ...i,
673
673
  mmsi: t,
@@ -678,7 +678,7 @@ class Nt extends nt {
678
678
  hdg: Math.round(u.heading * 100) / 100,
679
679
  rot: Math.round(u.rot * 100) / 100,
680
680
  positionTime: u.posTime,
681
- utc: d.utc().format(),
681
+ utc: c.utc().format(),
682
682
  status: u.aisNavStatus,
683
683
  labelEn: h,
684
684
  labelCn: l,
@@ -687,10 +687,10 @@ class Nt extends nt {
687
687
  };
688
688
  }
689
689
  async trajectory(t, n, o, i, a = !0, s = {}) {
690
- const r = p(n), u = p(o), l = await this.getShipId(t), h = await this.getShipInfo(l), d = [];
690
+ const r = p(n), u = p(o), l = await this.getShipId(t), h = await this.getShipInfo(l), c = [];
691
691
  for (; u.diff(r, "day", !0) > 30; )
692
- await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), h, t, i, d);
693
- return await this.trajectoryIn30Day(l, r.unix(), u.unix(), h, t, i, d), d;
692
+ await this.trajectoryIn30Day(l, r.unix(), r.add(30, "day").unix(), h, t, i, c);
693
+ return await this.trajectoryIn30Day(l, r.unix(), u.unix(), h, t, i, c), c;
694
694
  }
695
695
  async trajectoryIn30Day(t, n, o, i, a, s, r, u = {}) {
696
696
  var k;
@@ -703,10 +703,10 @@ class Nt extends nt {
703
703
  startTime: n,
704
704
  endTime: o
705
705
  }
706
- }, h = "https://api3.myships.com/sp/ships/position/history", d = await z.post(h, l).json();
707
- if (g == null || g.info("[%s] fetch trajectory from: %s - %j", u.requestId, h, l), d.code !== "0")
708
- return g == null || g.warn("[%s] invoke myship trajectory failed: %j", u.requestId, d), d;
709
- const I = d.data;
706
+ }, h = "https://api3.myships.com/sp/ships/position/history", c = await z.post(h, l).json();
707
+ if (g == null || g.info("[%s] fetch trajectory from: %s - %j", u.requestId, h, l), c.code !== "0")
708
+ return g == null || g.warn("[%s] invoke myship trajectory failed: %j", u.requestId, c), c;
709
+ const I = c.data;
710
710
  for (const w in I)
711
711
  !isNaN(I[w]) && Number(I[w]) !== 1 / 0 && (I[w] = Number(I[w]));
712
712
  const b = p.unix((k = I[0]) == null ? void 0 : k.posTime);
@@ -725,8 +725,8 @@ class Nt extends nt {
725
725
  utc: v.utc().format(),
726
726
  method: "trajectory",
727
727
  vendor: "myship"
728
- }, c = Math.floor(v.diff(b, "minute", !0) / (s || 1));
729
- c !== E && (E = c, r.push(m));
728
+ }, d = Math.floor(v.diff(b, "minute", !0) / (s || 1));
729
+ d !== E && (E = d, r.push(m));
730
730
  }
731
731
  return r;
732
732
  }
@@ -759,8 +759,8 @@ class Mt {
759
759
  if (l === 0 && !h)
760
760
  a.scope = i[0];
761
761
  else if (h)
762
- for (let d = 0, I = h.length; d < I; d++) {
763
- const b = this.parseRule(h[d]);
762
+ for (let c = 0, I = h.length; c < I; c++) {
763
+ const b = this.parseRule(h[c]);
764
764
  b && (a[b.level] ? b.key ? a[b.level][b == null ? void 0 : b.key] = b : a[b.level] = b : b.key ? a[b.level] = { [b == null ? void 0 : b.key]: b } : a[b.level] = b);
765
765
  }
766
766
  }
@@ -794,14 +794,14 @@ class Mt {
794
794
  * @param options
795
795
  */
796
796
  checkWeather(e, t, n = {}) {
797
- var b, E, k, w, v, m, c, f, y, S, M, j, N, D, L;
797
+ var b, E, k, w, v, m, d, f, y, S, M, j, N, D, L;
798
798
  let o = 0, i = 0, a = 0, s = 0;
799
- const r = Math.round(((E = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : E.number) * 1.6 * 100) / 100, u = (w = (k = t == null ? void 0 : t.SEVERE) == null ? void 0 : k.sigWave) == null ? void 0 : w.number, l = (m = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : m.number, h = Math.round((((f = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : f.number) + 2) * 100) / 100, d = (S = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : S.number, I = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
799
+ const r = Math.round(((E = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : E.number) * 1.6 * 100) / 100, u = (w = (k = t == null ? void 0 : t.SEVERE) == null ? void 0 : k.sigWave) == null ? void 0 : w.number, l = (m = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : m.number, h = Math.round((((f = (d = t == null ? void 0 : t.SEVERE) == null ? void 0 : d.wind) == null ? void 0 : f.number) + 2) * 100) / 100, c = (S = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : S.number, I = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
800
800
  for (let W = 0; W < (e == null ? void 0 : e.length); W++) {
801
801
  const F = e[W], Y = (D = (N = F == null ? void 0 : F.meteo) == null ? void 0 : N.wave) == null ? void 0 : D.sig, A = (L = F == null ? void 0 : F.meteo) == null ? void 0 : L.wind, V = W ? p(F.eta).diff(p(e[W - 1].eta), "hour", !0) : 0;
802
- s = V > s ? V : s, _ == null || _.debug("[%s] check sig.wave: %j", n.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l }), (Y == null ? void 0 : Y.height) >= r ? F.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= u ? F.isSevere = !0 : (Y == null ? void 0 : Y.height) >= l && (F.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", n.requestId, { ...A, dgThd4Wd: h, svThd4Wd: d, hvThd4Wd: I }), (A == null ? void 0 : A.scale) >= h ? (F.isDangerous = !0, delete F.isSevere, delete F.isHeavy) : (A == null ? void 0 : A.scale) > d ? (F.isDangerous || (F.isSevere = !0), delete F.isHeavy) : (A == null ? void 0 : A.scale) === I && !F.isDangerous && !F.isSevere && (F.isHeavy = !0), o += F.isDangerous ? V : 0, i += F.isSevere ? V : 0, a += F.isHeavy ? V : 0;
802
+ s = V > s ? V : s, _ == null || _.debug("[%s] check sig.wave: %j", n.requestId, { ...Y, dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l }), (Y == null ? void 0 : Y.height) >= r ? F.isDangerous = !0 : (Y == null ? void 0 : Y.height) >= u ? F.isSevere = !0 : (Y == null ? void 0 : Y.height) >= l && (F.isHeavy = !0), _ == null || _.debug("[%s] check wind: %j", n.requestId, { ...A, dgThd4Wd: h, svThd4Wd: c, hvThd4Wd: I }), (A == null ? void 0 : A.scale) >= h ? (F.isDangerous = !0, delete F.isSevere, delete F.isHeavy) : (A == null ? void 0 : A.scale) > c ? (F.isDangerous || (F.isSevere = !0), delete F.isHeavy) : (A == null ? void 0 : A.scale) === I && !F.isDangerous && !F.isSevere && (F.isHeavy = !0), o += F.isDangerous ? V : 0, i += F.isSevere ? V : 0, a += F.isHeavy ? V : 0;
803
803
  }
804
- return o = Math.round(o * 100) / 100, i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, s = Math.round(s), { sample: e, dangerous: o, severe: i, heavy: a, step: s < 3 ? 3 : s, wind: { dgThd4Wd: h, svThd4Wd: d, hvThd4Wd: I }, sig: { dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l } };
804
+ return o = Math.round(o * 100) / 100, i = Math.round(i * 100) / 100, a = Math.round(a * 100) / 100, s = Math.round(s), { sample: e, dangerous: o, severe: i, heavy: a, step: s < 3 ? 3 : s, wind: { dgThd4Wd: h, svThd4Wd: c, hvThd4Wd: I }, sig: { dgThd4Wv: r, svThd4Wv: u, hvThd4Wv: l } };
805
805
  }
806
806
  }
807
807
  const Dt = new Mt();
@@ -929,8 +929,8 @@ class H {
929
929
  * @private
930
930
  */
931
931
  static assembleProperties(e, t, n, o) {
932
- var d;
933
- const i = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, a = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, u = ((d = e == null ? void 0 : e.type) == null ? void 0 : d.toLowerCase()) || "common";
932
+ var c;
933
+ const i = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, a = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, u = ((c = e == null ? void 0 : e.type) == null ? void 0 : c.toLowerCase()) || "common";
934
934
  return {
935
935
  tag: u.indexOf("container") > -1 ? "container" : u.indexOf("tugs") > -1 ? "tugs" : "common",
936
936
  lbp: i,
@@ -968,27 +968,27 @@ class H {
968
968
  forecastDays: 2,
969
969
  weatherModels: k,
970
970
  marineModels: w
971
- }), [c] = dt.pickHourly(m, v);
972
- l = dt.toLegacy(c);
971
+ }), [d] = dt.pickHourly(m, v);
972
+ l = dt.toLegacy(d);
973
973
  } catch (k) {
974
974
  C.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: n.utc().format(), source: o }, k);
975
975
  }
976
- let h = H.currentFactor(e.bearing, l == null ? void 0 : l.current, i, r), d = H.weatherFactor(e, l, h, r);
976
+ let h = H.currentFactor(e.bearing, l == null ? void 0 : l.current, i, r), c = H.weatherFactor(e, l, h, r);
977
977
  const I = e.speed * 1.943844;
978
- I + h + d <= 0 && (C.warn(
978
+ I + h + c <= 0 && (C.warn(
979
979
  "[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",
980
980
  r.requestId,
981
981
  I,
982
- d + h,
983
- d,
982
+ c + h,
983
+ c,
984
984
  h
985
- ), h = Math.round(h * 0.6 * 1e3) / 1e3, d = Math.round(d * 0.6 * 1e3) / 1e3);
986
- const b = d <= (r.minV0Factor || -1) ? Math.max(r.maxV0Factor || -3, -1 * d * (d / 1.2)) : 0;
987
- C == null || C.info("[%s] calculate speed lose with v0Factor(%d), cFactor(%d) and wxFactor(%d)", r.requestId, b, h, d), d += b;
988
- let E = Math.round((I + h + d) * 100) / 100;
985
+ ), h = Math.round(h * 0.6 * 1e3) / 1e3, c = Math.round(c * 0.6 * 1e3) / 1e3);
986
+ const b = c <= (r.minV0Factor || -1) ? Math.max(r.maxV0Factor || -2.5, -1 * c * (c / 1.2)) : 0;
987
+ C == null || C.info("[%s] calculate speed lose with v0Factor(%d), cFactor(%d) and wxFactor(%d)", r.requestId, b, h, c), c += b;
988
+ let E = Math.round((I + h + c) * 100) / 100;
989
989
  E = E <= 0 ? 1 : E, u = {
990
990
  meteo: { ...l },
991
- wxFactor: d,
991
+ wxFactor: c,
992
992
  v0Factor: b,
993
993
  cFactor: h,
994
994
  speed: t.velocity && s ? t.velocity : E,
@@ -1022,27 +1022,27 @@ class H {
1022
1022
  */
1023
1023
  static async speedLoseInHoursStep(e, t, n, o, i, a, s = "", r = !0, u = !1, l = {}) {
1024
1024
  t.utc();
1025
- const h = t.clone().add(14, "days"), d = [], I = [], b = [];
1025
+ const h = t.clone().add(14, "days"), c = [], I = [], b = [];
1026
1026
  let E = 0, k = 0, w, v;
1027
1027
  for (let m = 0; m < a.length - 1; m++) {
1028
- let c = a[m];
1029
- c.distanceFromStart = Math.round((i + k) * 1e3) / 1e3;
1028
+ let d = a[m];
1029
+ d.distanceFromStart = Math.round((i + k) * 1e3) / 1e3;
1030
1030
  const f = a[m + 1];
1031
- if (e.bearing = R.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend && u) {
1032
- c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
1033
- const M = c.suspend - c.elapsed;
1031
+ if (e.bearing = R.calculateBearing(d, f, !f.gcToPrevious), d.bearing = e.bearing, d.suspend && u) {
1032
+ d.eta = d.eta || t.utc().format(), d.elapsed = d.elapsed ?? 0;
1033
+ const M = d.suspend - d.elapsed;
1034
1034
  if (o - E > M)
1035
- o = o - E - M, t.add(M, "hour"), c.elapsed = c.suspend;
1035
+ o = o - E - M, t.add(M, "hour"), d.elapsed = d.suspend;
1036
1036
  else {
1037
1037
  const j = o - E;
1038
- c.elapsed += j, t.add(j, "hour"), o = 0;
1038
+ d.elapsed += j, t.add(j, "hour"), o = 0;
1039
1039
  }
1040
- if (C == null || C.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`, l.requestId, c), o === 0)
1041
- return c.distanceFromPrevious = k, { etd: t, from: v || c, to: c, next: a.filter((j) => j), wps: d, days: I, all: b };
1040
+ if (C == null || C.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`, l.requestId, d), o === 0)
1041
+ return d.distanceFromPrevious = k, { etd: t, from: v || d, to: d, next: a.filter((j) => j), wps: c, days: I, all: b };
1042
1042
  } else
1043
- c.suspend = 0;
1044
- r = t.isAfter(h) ? !1 : r, c = await H.speedLoseAt(e, c, t, s, 0, r, u, l), b.push(c), v = v || c, c.important && d.push(c), t.isSameOrAfter(n) && (I.push(c), n.add(24, "hour"));
1045
- const y = R.calculateDistance(c, f, !f.gcToPrevious);
1043
+ d.suspend = 0;
1044
+ r = t.isAfter(h) ? !1 : r, d = await H.speedLoseAt(e, d, t, s, 0, r, u, l), b.push(d), v = v || d, d.important && c.push(d), t.isSameOrAfter(n) && (I.push(d), n.add(24, "hour"));
1045
+ const y = R.calculateDistance(d, f, !f.gcToPrevious);
1046
1046
  let S = Math.round(y / v.speed * 1e5) / 1e5;
1047
1047
  if (E + S < o) {
1048
1048
  if (E += S, t.add(S, "hour"), delete a[m], C == null || C.debug(
@@ -1051,22 +1051,22 @@ class H {
1051
1051
  { lat: f.lat, lng: f.lng },
1052
1052
  { lat: v.lat, lng: v.lng, etd: v.etd }
1053
1053
  ), k += y, a.filter((M) => M).length <= 1) {
1054
- w = f, w.eta = t.utc().format(), w.distanceFromPrevious = y, w.distanceFromStart = Math.round((i + k) * 1e4) / 1e4, d.push(w), b.push(w), delete a[m + 1];
1054
+ w = f, w.eta = t.utc().format(), w.distanceFromPrevious = y, w.distanceFromStart = Math.round((i + k) * 1e4) / 1e4, c.push(w), b.push(w), delete a[m + 1];
1055
1055
  break;
1056
1056
  }
1057
1057
  } else {
1058
1058
  S = o - E, t.add(S, "hour");
1059
1059
  const M = J.roundPrecision(v.speed * S, 5);
1060
- w = R.calculateCoordinate(c, e.bearing, M, "nauticalmiles", !f.gcToPrevious), w.eta = t.utc().format(), a[m] = w, C == null || C.debug(
1060
+ w = R.calculateCoordinate(d, e.bearing, M, "nauticalmiles", !f.gcToPrevious), w.eta = t.utc().format(), a[m] = w, C == null || C.debug(
1061
1061
  `[%s] go to %j from %j with ${M}nm, and cost ${S} hours`,
1062
1062
  l.requestId,
1063
1063
  { lat: w.lat, lng: w.lng },
1064
- { lat: c.lat, lng: c.lng, etd: c.etd }
1064
+ { lat: d.lat, lng: d.lng, etd: d.etd }
1065
1065
  ), k += M, w.distanceFromPrevious = Math.round(k * 1e4) / 1e4, w.distanceFromStart = Math.round((i + k) * 1e4) / 1e4;
1066
1066
  break;
1067
1067
  }
1068
1068
  }
1069
- return { etd: t, from: v, to: w, next: a.filter((m) => m), wps: d, days: I, all: b };
1069
+ return { etd: t, from: v, to: w, next: a.filter((m) => m), wps: c, days: I, all: b };
1070
1070
  }
1071
1071
  /**
1072
1072
  * 洋流影响因子
@@ -1088,15 +1088,15 @@ class H {
1088
1088
  * @param options
1089
1089
  */
1090
1090
  static weatherFactor(e, t, n = 0, o = {}) {
1091
- var b, E, k, w, v, m, c;
1091
+ var b, E, k, w, v, m, d;
1092
1092
  C == null || C.info("[%s] calculate weather factor via: %j", o.requestId, { ...e, ...t });
1093
1093
  const i = H.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), a = J.roundPrecision(n * 1852 / 3600, 6), s = H.froudeNumber(e.speed - a, e.lbp), r = H.amendFactor(i, s, e.loadCondition);
1094
1094
  let u = R.includedAngle(e.bearing, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.degree);
1095
1095
  const l = H.directionFactor(u, (E = t == null ? void 0 : t.wind) == null ? void 0 : E.scale), h = H.vesselTagFactor(e.displacement, e.loadCondition, e.tag, ((k = t == null ? void 0 : t.wind) == null ? void 0 : k.kts) || 10);
1096
- let d = l * r * h / 100 * (e.speed - a);
1097
- d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), C == null || C.info("[%s] calculate wind wx factor: %d", o.requestId, d), u = R.includedAngle(e.bearing, (v = (w = t == null ? void 0 : t.wave) == null ? void 0 : w.sig) == null ? void 0 : v.degree);
1098
- const I = H.waveHeightFactor(((c = (m = t == null ? void 0 : t.wave) == null ? void 0 : m.sig) == null ? void 0 : c.height) ?? 1, u, e.draught, o);
1099
- return C == null || C.info("[%s] calculate wave wx factor: %d", o.requestId, I), d = Math.abs(d) > Math.abs(I) ? d : 0.7 * d + 0.9 * I, C == null || C.info("[%s] calculate finial weather factor: %d (0.7 * wf) + (0.9 * hf)", o.requestId, d), Math.round((d || 0) * 100) / 100;
1096
+ let c = l * r * h / 100 * (e.speed - a);
1097
+ c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), C == null || C.info("[%s] calculate wind wx factor: %d", o.requestId, c), u = R.includedAngle(e.bearing, (v = (w = t == null ? void 0 : t.wave) == null ? void 0 : w.sig) == null ? void 0 : v.degree);
1098
+ const I = H.waveHeightFactor(((d = (m = t == null ? void 0 : t.wave) == null ? void 0 : m.sig) == null ? void 0 : d.height) ?? 1, u, e.draught, o);
1099
+ return C == null || C.info("[%s] calculate wave wx factor: %d", o.requestId, I), c = Math.abs(c) > Math.abs(I) ? c : 0.7 * c + 0.9 * I, C == null || C.info("[%s] calculate finial weather factor: %d (0.7 * wf) + (0.9 * hf)", o.requestId, c), c = Math.abs(c) > 4 ? 4 * (Math.abs(c) / c) + Math.abs(c) / c * (Math.abs(c) - 2) * 0.1 : c, Math.round((c || 0) * 100) / 100;
1100
1100
  }
1101
1101
  /**
1102
1102
  * 以12小时级别去掉重复的days
@@ -1131,7 +1131,7 @@ class H {
1131
1131
  var U, G, X, Q, Z, $;
1132
1132
  const h = p().valueOf();
1133
1133
  e.lng = J.convertToStdLng(e.lng);
1134
- const { route: d, waypoints: I } = i.points, b = R.calculateSubRoute(e, d);
1134
+ const { route: c, waypoints: I } = i.points, b = R.calculateSubRoute(e, c);
1135
1135
  if (((U = b[0]) == null ? void 0 : U.length) <= 1)
1136
1136
  return;
1137
1137
  const { v0: E, label: k } = e.sog ? {
@@ -1150,7 +1150,7 @@ class H {
1150
1150
  waypoints: v,
1151
1151
  v0: E,
1152
1152
  label: k
1153
- }, c = {
1153
+ }, d = {
1154
1154
  hours: [],
1155
1155
  days: [],
1156
1156
  wps: [],
@@ -1173,29 +1173,29 @@ class H {
1173
1173
  u,
1174
1174
  l
1175
1175
  );
1176
- if (c.all.push(...T.all), (G = T.from) != null && G.speed && (c.hours.push(T.from), c.wps.push(...T.wps), c.days.push(...T.days)), f = T == null ? void 0 : T.next, !f.length) {
1176
+ if (d.all.push(...T.all), (G = T.from) != null && G.speed && (d.hours.push(T.from), d.wps.push(...T.wps), d.days.push(...T.days)), f = T == null ? void 0 : T.next, !f.length) {
1177
1177
  const O = await H.speedLoseAt(w, T.to, p(T.to.eta), a, 0, r, u, l);
1178
- O.bearing = w.bearing, c.hours.push(O), c.all.push(O);
1178
+ O.bearing = w.bearing, d.hours.push(O), d.all.push(O);
1179
1179
  }
1180
1180
  y += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1181
1181
  }
1182
- const D = c.hours;
1182
+ const D = d.hours;
1183
1183
  for (let q = 0; q < D.length - 1; q++) {
1184
1184
  const B = p(D[q + 1].eta).diff(D[q].etd, "hour", !0) || 1;
1185
1185
  S += (D[q].wxFactor || 0) * B, M += (D[q].cFactor || 0) * B, j += B;
1186
1186
  }
1187
1187
  const L = D.reduce((q, B) => q + (B.suspend || 0), 0);
1188
- (Q = c.wps) == null || Q.forEach((q, B) => {
1188
+ (Q = d.wps) == null || Q.forEach((q, B) => {
1189
1189
  q.positionTime = p.utc(q.etd || q.eta).unix();
1190
- const T = c.wps[B - 1];
1190
+ const T = d.wps[B - 1];
1191
1191
  if (T) {
1192
1192
  const O = q.distanceFromStart - T.distanceFromStart, P = p(q.eta || q.etd).diff(p(T.etd || T.eta), "h", !0);
1193
1193
  q.avgSpd = Math.round(O / P * 100) / 100;
1194
1194
  const at = R.calculateBearing(T, q);
1195
1195
  q.avgBearing = at, T.bearing = at;
1196
1196
  }
1197
- }), c.wps = await H.reduceWPS(c.wps), c.days = await H.reduceDays(c.days), c.all = (Z = c.all) == null ? void 0 : Z.reduce((q, B) => (B.positionTime = p.utc(B.etd || B.eta).unix(), q.some((T) => Math.round(T.positionTime / 60) === Math.round(B.positionTime / 60)) || q.push(B), q), []), m.sample = c;
1198
- const W = c.hours.at(0), F = c.hours.at(-1);
1197
+ }), d.wps = await H.reduceWPS(d.wps), d.days = await H.reduceDays(d.days), d.all = (Z = d.all) == null ? void 0 : Z.reduce((q, B) => (B.positionTime = p.utc(B.etd || B.eta).unix(), q.some((T) => Math.round(T.positionTime / 60) === Math.round(B.positionTime / 60)) || q.push(B), q), []), m.sample = d;
1198
+ const W = d.hours.at(0), F = d.hours.at(-1);
1199
1199
  m.distance = Math.round(F.distanceFromStart * 1e3) / 1e3, m.etd = p(W.eta).utc().format(), m.eta = p(F.eta).utc().format(), m.wxFactor = Math.round(S / j * 1e3) / 1e3, m.cFactor = Math.round(M / j * 1e3) / 1e3, m.avgSpeed = Math.round(F.distanceFromStart / j * 1e3) / 1e3, m.totalHrs = Math.round(j * 1e3) / 1e3, m.suspend = Math.round(L * 1e3) / 1e3;
1200
1200
  const Y = J.roundPrecision(o.dgo / 24 * L, 3), { distanceInECA: A, hoursInECA: V, totalDgoConsInECA: ot, eca: tt } = await this.calculateECA(m, o, l), et = J.roundPrecision(o.fo / 24 * (j - V), 3), it = J.roundPrecision(o.dgo / 24 * j + Y, 3);
1201
1201
  m.extend = {
@@ -1205,7 +1205,7 @@ class H {
1205
1205
  totalDgoConsInECA: ot,
1206
1206
  totalDgoConsInSuspend: Y
1207
1207
  }, m.totalFoCons = et < 0 ? 0 : et, m.totalDgoCons = it;
1208
- const st = p().valueOf() - h, ct = (($ = c == null ? void 0 : c.hours) == null ? void 0 : $.length) || 1;
1208
+ const st = p().valueOf() - h, ct = (($ = d == null ? void 0 : d.hours) == null ? void 0 : $.length) || 1;
1209
1209
  return C == null || C.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", l == null ? void 0 : l.requestId, st, ct, Math.round(st / ct * 1e3) / 1e3), m;
1210
1210
  }
1211
1211
  /**
@@ -1223,7 +1223,7 @@ class H {
1223
1223
  * @param useRouteParam
1224
1224
  * @param options
1225
1225
  */
1226
- static async analyseInstantWithThreshed(e, t, n, o, i, a, s, r = "", u = 3, l = !0, h = !1, d = {}) {
1226
+ static async analyseInstantWithThreshed(e, t, n, o, i, a, s, r = "", u = 3, l = !0, h = !1, c = {}) {
1227
1227
  var X, Q, Z, $, q, B;
1228
1228
  const I = p().valueOf();
1229
1229
  e.lng = J.convertToStdLng(e.lng);
@@ -1240,7 +1240,7 @@ class H {
1240
1240
  return;
1241
1241
  const v = s.length ? R.calculateSubWaypoints(e, s) : [];
1242
1242
  v.forEach((T) => T.important = !0);
1243
- let m = R.simplifyRouteToCoordinates(w, v, 0), c = 0, f = 0, y = 0, S = 0;
1243
+ let m = R.simplifyRouteToCoordinates(w, v, 0), d = 0, f = 0, y = 0, S = 0;
1244
1244
  const M = {
1245
1245
  hours: [],
1246
1246
  wps: [],
@@ -1253,8 +1253,8 @@ class H {
1253
1253
  const T = u - t.hour() % u;
1254
1254
  let O = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1255
1255
  O = t.clone().add(O, "h").isSameOrAfter(n) ? n.diff(t, "h", !0) * 1e4 / 1e4 : O;
1256
- const P = await H.speedLoseInHoursStep(k, t, j, O, c, m, r, l, h, d);
1257
- if (M.all.push(...P.all), (Q = P.from) != null && Q.speed && (M.hours.push(P.from), P != null && P.wps && M.wps.push(...P.wps), M.days.push(...P.days)), m = P == null ? void 0 : P.next, m.length || M.hours.push(P == null ? void 0 : P.to), c += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !O)
1256
+ const P = await H.speedLoseInHoursStep(k, t, j, O, d, m, r, l, h, c);
1257
+ if (M.all.push(...P.all), (Q = P.from) != null && Q.speed && (M.hours.push(P.from), P != null && P.wps && M.wps.push(...P.wps), M.days.push(...P.days)), m = P == null ? void 0 : P.next, m.length || M.hours.push(P == null ? void 0 : P.to), d += Math.round((((Z = P == null ? void 0 : P.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !O)
1258
1258
  break;
1259
1259
  }
1260
1260
  M.wps = await H.reduceWPS(M.wps), M.days = await H.reduceDays(M.days), M.all = ($ = M.all) == null ? void 0 : $.reduce((T, O) => (O.positionTime = p.utc(O.etd || O.eta).unix(), T.some((P) => Math.round(p(P.etd).unix() / 60) === Math.round(p(O.etd).unix() / 60)) || T.push(O), T), []), (q = M.wps) == null || q.forEach((T, O) => {
@@ -1286,7 +1286,7 @@ class H {
1286
1286
  waypoints: Y,
1287
1287
  v0: b,
1288
1288
  label: E
1289
- }, V = J.roundPrecision(i.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: tt, totalDgoConsInECA: et, eca: it } = await this.calculateECA(A, i, d), rt = J.roundPrecision(i.fo / 24 * (S - tt), 3), st = J.roundPrecision(i.dgo / 24 * S + V, 3);
1289
+ }, V = J.roundPrecision(i.dgo / 24 * D, 3), { distanceInECA: ot, hoursInECA: tt, totalDgoConsInECA: et, eca: it } = await this.calculateECA(A, i, c), rt = J.roundPrecision(i.fo / 24 * (S - tt), 3), st = J.roundPrecision(i.dgo / 24 * S + V, 3);
1290
1290
  A.extend = {
1291
1291
  eca: it,
1292
1292
  distanceInECA: ot,
@@ -1295,7 +1295,7 @@ class H {
1295
1295
  totalDgoConsInSuspend: V
1296
1296
  }, A.totalDgoCons = st, A.totalFoCons = rt < 0 ? 0 : rt;
1297
1297
  const U = p().valueOf() - I, G = ((B = M == null ? void 0 : M.hours) == null ? void 0 : B.length) || 1;
1298
- return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", d == null ? void 0 : d.requestId, U, G, Math.round(U / G * 1e3) / 1e3), A;
1298
+ return C == null || C.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", c == null ? void 0 : c.requestId, U, G, Math.round(U / G * 1e3) / 1e3), A;
1299
1299
  }
1300
1300
  /**
1301
1301
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1319,19 +1319,19 @@ class H {
1319
1319
  const r = R.calculateRouteDistance(o.route);
1320
1320
  let u = 0;
1321
1321
  n.forEach((m) => {
1322
- const c = Math.ceil(r / m.speed / 24);
1323
- u = u < c ? c : u;
1322
+ const d = Math.ceil(r / m.speed / 24);
1323
+ u = u < d ? d : u;
1324
1324
  }), u = u * 1.3;
1325
1325
  const l = p.utc(e.etd).add(u ?? 14, "day");
1326
1326
  let h = 1;
1327
1327
  for (const m of n) {
1328
- const c = JSON.parse(JSON.stringify(o.route)), f = JSON.parse(JSON.stringify(o.waypoints)), y = await H.analyseInstantWithThreshed(
1328
+ const d = JSON.parse(JSON.stringify(o.route)), f = JSON.parse(JSON.stringify(o.waypoints)), y = await H.analyseInstantWithThreshed(
1329
1329
  { lat: e.lat, lng: e.lng },
1330
1330
  e.etd,
1331
1331
  l,
1332
1332
  t,
1333
1333
  m,
1334
- c,
1334
+ d,
1335
1335
  f,
1336
1336
  e.meteoVendor,
1337
1337
  e.speedStep,
@@ -1348,15 +1348,15 @@ class H {
1348
1348
  cp: `${m.speed}/${m.fo}/${m.dgo}`
1349
1349
  })), h++;
1350
1350
  }
1351
- s.sort((m, c) => m.cost.total - c.cost.total);
1352
- const d = s.at(0), I = s.at(1), b = [];
1353
- if (b.push({ combined: !1, speeds: [d], cost: (w = d.cost) == null ? void 0 : w.total }), I) {
1354
- const m = d.cost.cp, c = I.cost.cp, f = p(d.eta), y = p(d.etd), S = f.diff(y, "days", !0);
1351
+ s.sort((m, d) => m.cost.total - d.cost.total);
1352
+ const c = s.at(0), I = s.at(1), b = [];
1353
+ if (b.push({ combined: !1, speeds: [c], cost: (w = c.cost) == null ? void 0 : w.total }), I) {
1354
+ const m = c.cost.cp, d = I.cost.cp, f = p(c.eta), y = p(c.etd), S = f.diff(y, "days", !0);
1355
1355
  let M = Math.ceil(S / 2);
1356
1356
  M = M > 7 ? 7 : M < e.alterStep ? e.alterStep : M;
1357
1357
  let j = 2, N = { combined: !1, speeds: [I], cost: (v = I.cost) == null ? void 0 : v.total }, D;
1358
1358
  for (; M >= e.alterStep; ) {
1359
- const L = await H.combinedAnalyse(e, t, l, [m, c], o, M, { ...i, level: j });
1359
+ const L = await H.combinedAnalyse(e, t, l, [m, d], o, M, { ...i, level: j });
1360
1360
  if (N.cost > L.cost ? D ? (D == null ? void 0 : D.cost) > L.cost && (D = L) : (D = N, N = L) : (!D || (D == null ? void 0 : D.cost) > L.cost) && (D = L), M <= e.alterStep)
1361
1361
  break;
1362
1362
  M = Math.ceil(M / 2), j += 1;
@@ -1364,7 +1364,7 @@ class H {
1364
1364
  b.push(N), D && b.push(D);
1365
1365
  }
1366
1366
  const k = p().valueOf() - a;
1367
- return C == null || C.info("[%s] analyse elapsed: %d ms", i == null ? void 0 : i.requestId, k), b.sort((m, c) => m.cost - c.cost);
1367
+ return C == null || C.info("[%s] analyse elapsed: %d ms", i == null ? void 0 : i.requestId, k), b.sort((m, d) => m.cost - d.cost);
1368
1368
  }
1369
1369
  /**
1370
1370
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1378,15 +1378,15 @@ class H {
1378
1378
  */
1379
1379
  static async combinedAnalyse(e, t, n, o, i, a, s = {}) {
1380
1380
  s.counter = 1, C == null || C.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, a);
1381
- const r = await H.alternateAnalyse(e, t, n, o, 0, i, a, s), u = r.reduce((c, f) => c + f.cost.total, 0), l = r.reduce((c, f) => c + f.cost.hire, 0), h = r.reduce((c, f) => c + f.cost.bunker, 0), d = r.reduce((c, f) => c + f.distance, 0), I = r.reduce((c, f) => c + f.totalHrs, 0);
1381
+ const r = await H.alternateAnalyse(e, t, n, o, 0, i, a, s), u = r.reduce((d, f) => d + f.cost.total, 0), l = r.reduce((d, f) => d + f.cost.hire, 0), h = r.reduce((d, f) => d + f.cost.bunker, 0), c = r.reduce((d, f) => d + f.distance, 0), I = r.reduce((d, f) => d + f.totalHrs, 0);
1382
1382
  C == null || C.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1383
1383
  cost: u,
1384
1384
  hire: l,
1385
1385
  bunker: h,
1386
- distance: d,
1386
+ distance: c,
1387
1387
  hours: I
1388
1388
  });
1389
- const b = await H.alternateAnalyse(e, t, n, o, 1, i, a, s), E = b.reduce((c, f) => c + f.cost.total, 0), k = b.reduce((c, f) => c + f.cost.hire, 0), w = b.reduce((c, f) => c + f.cost.bunker, 0), v = b.reduce((c, f) => c + f.distance, 0), m = b.reduce((c, f) => c + f.totalHrs, 0);
1389
+ const b = await H.alternateAnalyse(e, t, n, o, 1, i, a, s), E = b.reduce((d, f) => d + f.cost.total, 0), k = b.reduce((d, f) => d + f.cost.hire, 0), w = b.reduce((d, f) => d + f.cost.bunker, 0), v = b.reduce((d, f) => d + f.distance, 0), m = b.reduce((d, f) => d + f.totalHrs, 0);
1390
1390
  return C == null || C.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1391
1391
  cost: E,
1392
1392
  hire: k,
@@ -1407,7 +1407,7 @@ class H {
1407
1407
  * @param options
1408
1408
  */
1409
1409
  static async alternateAnalyse(e, t, n, o, i, a, s, r = {}) {
1410
- var d, I;
1410
+ var c, I;
1411
1411
  let u = p.utc(e.etd);
1412
1412
  const l = { lat: e.lat, lng: e.lng }, h = [];
1413
1413
  for (; u.isBefore(n); ) {
@@ -1441,7 +1441,7 @@ class H {
1441
1441
  cp: `${w.speed}/${w.fo}/${w.dgo}`
1442
1442
  }
1443
1443
  )), r.counter = r.counter + 1;
1444
- const m = (I = (d = v == null ? void 0 : v.sample) == null ? void 0 : d.hours) == null ? void 0 : I.at(-1);
1444
+ const m = (I = (c = v == null ? void 0 : v.sample) == null ? void 0 : c.hours) == null ? void 0 : I.at(-1);
1445
1445
  if (m)
1446
1446
  l.lat = m.lat, l.lng = m.lng, u = p(m.eta), h.push(v), i = i ? 0 : 1;
1447
1447
  else
@@ -1478,13 +1478,13 @@ class H {
1478
1478
  var r, u, l, h;
1479
1479
  const o = await R.intersectInECA((e == null ? void 0 : e.route) || []);
1480
1480
  let i = 0, a = 0, s = 0;
1481
- (u = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || u.forEach((d) => {
1482
- d.positionTime = p.utc(d.etd || d.eta).unix();
1481
+ (u = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || u.forEach((c) => {
1482
+ c.positionTime = p.utc(c.etd || c.eta).unix();
1483
1483
  });
1484
- for (const d of o) {
1485
- i += d.distance;
1486
- const I = await R.deadReckoningTime((l = d.waypoints) == null ? void 0 : l.at(0), e.sample.all || e.sample.wps), b = await R.deadReckoningTime((h = d.waypoints) == null ? void 0 : h.at(-1), e.sample.all || e.sample.wps);
1487
- d.in = I, d.out = b, d.totalHrs = J.roundPrecision((b.positionTime - I.positionTime) / 3600, 3), d.totalDgoCons = J.roundPrecision(t.fo / 24 * d.totalHrs, 3), a += d.totalHrs, s += d.totalDgoCons;
1484
+ for (const c of o) {
1485
+ i += c.distance;
1486
+ const I = await R.deadReckoningTime((l = c.waypoints) == null ? void 0 : l.at(0), e.sample.all || e.sample.wps), b = await R.deadReckoningTime((h = c.waypoints) == null ? void 0 : h.at(-1), e.sample.all || e.sample.wps);
1487
+ c.in = I, c.out = b, c.totalHrs = J.roundPrecision((b.positionTime - I.positionTime) / 3600, 3), c.totalDgoCons = J.roundPrecision(t.fo / 24 * c.totalHrs, 3), a += c.totalHrs, s += c.totalDgoCons;
1488
1488
  }
1489
1489
  return i = J.roundPrecision(i, 3), a = J.roundPrecision(a, 3), s = J.roundPrecision(s, 3), {
1490
1490
  distanceInECA: i,
@@ -1499,7 +1499,7 @@ class H {
1499
1499
  * @param options
1500
1500
  */
1501
1501
  static async mergeSpeeds(e, t = {}) {
1502
- var m, c;
1502
+ var m, d;
1503
1503
  const n = {
1504
1504
  hours: [],
1505
1505
  wps: [],
@@ -1514,7 +1514,7 @@ class H {
1514
1514
  }, 0), r = e.reduce((f, y) => {
1515
1515
  var S;
1516
1516
  return f + (((S = y.extend) == null ? void 0 : S.totalDgoConsInECA) || 0);
1517
- }, 0), u = e.reduce((f, y) => f + y.wxFactor * y.totalHrs / a, 0), l = e.reduce((f, y) => f + y.cFactor * y.totalHrs / a, 0), h = e.reduce((f, y) => f + y.totalFoCons, 0), d = e.reduce((f, y) => f + y.totalDgoCons, 0), I = e.reduce((f, y) => f + y.cost.total, 0), b = e.reduce((f, y) => f + y.cost.hire, 0), E = e.reduce((f, y) => f + y.cost.bunker, 0), k = [], w = [];
1517
+ }, 0), u = e.reduce((f, y) => f + y.wxFactor * y.totalHrs / a, 0), l = e.reduce((f, y) => f + y.cFactor * y.totalHrs / a, 0), h = e.reduce((f, y) => f + y.totalFoCons, 0), c = e.reduce((f, y) => f + y.totalDgoCons, 0), I = e.reduce((f, y) => f + y.cost.total, 0), b = e.reduce((f, y) => f + y.cost.hire, 0), E = e.reduce((f, y) => f + y.cost.bunker, 0), k = [], w = [];
1518
1518
  let v;
1519
1519
  for (const f of e) {
1520
1520
  w.push(...((m = f.extend) == null ? void 0 : m.eca) || []);
@@ -1542,7 +1542,7 @@ class H {
1542
1542
  var A;
1543
1543
  ((A = n == null ? void 0 : n.days) == null ? void 0 : A.findIndex((V) => V.eta === F.eta)) === -1 && n.days.push(F);
1544
1544
  });
1545
- const W = (c = n.wps) == null ? void 0 : c.findIndex((F) => F.eta === N.eta);
1545
+ const W = (d = n.wps) == null ? void 0 : d.findIndex((F) => F.eta === N.eta);
1546
1546
  W === -1 ? n.wps.push(N) : n.wps[W] = N, v = y.at(-1);
1547
1547
  }
1548
1548
  return n.wps.sort((f, y) => p(f.etd).unix() - p(y.etd).unix()), n.wps.forEach((f, y) => {
@@ -1567,7 +1567,7 @@ class H {
1567
1567
  wxFactor: Math.round(u * 1e3) / 1e3,
1568
1568
  cFactor: Math.round(l * 1e3) / 1e3,
1569
1569
  totalFoCons: Math.round(h * 1e3) / 1e3,
1570
- totalDgoCons: Math.round(d * 1e3) / 1e3,
1570
+ totalDgoCons: Math.round(c * 1e3) / 1e3,
1571
1571
  cost: {
1572
1572
  total: Math.round(I * 1e3) / 1e3,
1573
1573
  hire: Math.round(b * 1e3) / 1e3,
@@ -1 +1 @@
1
- (function(P,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(P=typeof globalThis<"u"?globalThis:P||self,x(P["idm-plugin-vessel"]={},P.got,P["@log4js-node/log4js-api"],P.moment,P["@idm-plugin/geo2"],P["@idm-plugin/meteo2"],P["@idm-plugin/meteo"]))})(this,function(P,x,K,w,E,pt,it){"use strict";var St=Object.defineProperty;var Ct=(P,x,K)=>x in P?St(P,x,{enumerable:!0,configurable:!0,writable:!0,value:K}):P[x]=K;var U=(P,x,K)=>(Ct(P,typeof x!="symbol"?x+"":x,K),K);let M;try{M=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,n;switch(e){case 0:t="在航(主机推动)",n="Underway Using Engine";break;case 1:t="锚泊",n="Anchored";break;case 2:t="失控",n="Not under command";break;case 3:t="操纵受限",n="Limited airworthiness";break;case 4:t="吃水受限",n="Limited by ship's draft";break;case 5:t="靠泊",n="Mooring";break;case 6:t="搁浅",n="Stranded";break;case 7:t="捕捞作业",n="Engaged in fishing";break;case 8:t="靠帆船提供动力",n="Sailing";break;default:t="未定义",n="Undefined"}return{labelCn:t,labelEn:n}}}class Mt extends G{constructor(t,n){super();U(this,"clientId");U(this,"clientSecret");U(this,"token");this.clientId=t,this.clientSecret=n}async authToken(t={}){const n="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},i=await x.post(n,o).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,n,i),i.error||(this.token={accessToken:i.access_token,tokenType:i.token_type,expiresIn:i.expires_in,scope:i.scope,jti:i.jti,issuedAt:w().utc().format()})}async checkToken(t={}){var n;return(!this.token||w().diff(w(this.token.issuedAt),"seconds")>(((n=this.token)==null?void 0:n.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,n={}){var s,r;await this.checkToken(n);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",i={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:n.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",n.requestId,o,i);const a=await x.post(o,i).json();return a.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",n.requestId,{message:a.message,status:a.status,code:a.code}),[]):(a.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,n={}){var u,l;await this.checkToken(n);const o=/^\d{7}$/.test(t.toString()),i=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",a=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(u=this.token)==null?void 0:u.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:a};M==null||M.info("[%s] fetch vessel from: %s - %j",n.requestId,i,s);const r=await x.get(i,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",n.requestId,{message:r.message,status:r.status,code:r.code}),{};{const h=r.data;if(h)return{mmsi:h.mmsi,imo:Number.isNaN(h.imo)?null:Number(h.imo),callSign:h.callsign,name:h.nameEn,nameCn:h.nameCn,type:h.vesselTypeNameEn,flagName:h.flagCtry,clasz:h.classSociety,dateOfBuild:h.buildYearMonth,deadweight:h.dwt,grossTonnage:h.grt,netTonnage:h.net,teu:h.teu,length:h.length,breadth:h.width,height:h.height,draught:h.draught,speed:h.speed,passengerCapacity:h.passengercapacity,vendor:"myvessel",raw:h}}return{}}async archives(t,n={}){var s,r;await this.checkToken(n);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",i={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",n.requestId,o,i);const a=await x.post(o,i).json();return a.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",n.requestId,{message:a.message,status:a.status,code:a.code}),{}):a.data}async realTimePosition(t,n={}){var r,u;await this.checkToken(n);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",i={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",n.requestId,o,i);const a=await x.get(o,i).json();if(a.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",n.requestId,{message:a.message,status:a.status,code:a.code}),a;const s=a.data;for(const l in s)!isNaN(s[l])&&Number(s[l])!==1/0&&(s[l]=Number(s[l]));if(s){const l=w(`${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)?w.utc(s.eta).format():void 0,destination:s.dest,positionTime:l.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:l.utc().format()}}else return{}}async calculateRoute(t,n,o,i,a,s={}){var I,v,T;const r=w();await this.checkToken(s);const u="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",l={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(l.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(l.startPoint={lon:t.lng,lat:t.lat}),n.code&&(l.endPortCode=n.code),n.lng!==void 0&&n.lat!==void 0&&(l.endPoint={lon:n.lng,lat:n.lat}),o!=null&&o.length&&(l.crossMonthList=o),i!=null&&i.length&&(l.excludeNodes=i),a!=null&&a.length&&(l.excludeSeaAreas=a);const h={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(v=this.token)==null?void 0:v.accessToken}`},json:l};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,u,h);const d=await x.post(u,h).json();if(d.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:d.message,status:d.status,code:d.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:b,tracks:f,specialRegions:c,ecaLength:m}=d.data;k.nodes=g==null?void 0:g.map(p=>({code:p.nodeCode,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.lat*1e6)/1e6,lng:Math.round(p.lon*1e6)/1e6},start:{lat:Math.round(p.startLat*1e6)/1e6,lng:Math.round(p.startLon*1e6)/1e6},end:{lat:Math.round(p.endLat*1e6)/1e6,lng:Math.round(p.endLat*1e6)/1e6},isKey:p.isKeyNode,isHub:p.isHubNode})),k.seas=b==null?void 0:b.map(p=>({code:p.mrgidSea,nameEn:p.nameEn,nameCn:p.nameCn,center:{lat:Math.round(p.centerLat*1e6)/1e6,lng:Math.round(p.centerLon*1e6)/1e6},min:{lat:Math.round(p.minLat*1e6)/1e6,lng:Math.round(p.minLon*1e6)/1e6},max:{lat:Math.round(p.maxLat*1e6)/1e6,lng:Math.round(p.maxLon*1e6)/1e6},level:p.mapLevel})),c==null||c.map(p=>{p.regionLength&&k.regions.push({type:p.regionType,distance:p.regionLength,rows:p.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=f==null?void 0:f.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(T=k.waypoints)!=null&&T.length&&(k.waypoints=E.LaneHelper.simplifyCoordinates(k.waypoints),k.route=E.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=E.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=m);const F=w().diff(r,"second");return k.memo=`time cost: ${F}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,F),k}}async trajectory(t,n,o,i,a=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),u=w(n),l=w(o),h=[];for(;l.diff(u,"day",!0)>30;)await this.trajectoryIn30Day(t,u,u.clone().add(30,"day"),r,i,h,s),u.add(30,"day");return await this.trajectoryIn30Day(t,u,l,r,i,h,s),h}async trajectoryIn30Day(t,n,o,i,a,s,r={}){var v,T,k,g,b;const u="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(v=this.token)==null?void 0:v.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,u,l);const h=await x.post(u,l).json();if(h.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,u,{message:h.message,status:h.status,code:h.code}),h;let d=-1;const I=w(`${(g=(k=h.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(b=h.data)==null||b.forEach(f=>{for(const H in f)!isNaN(f[H])&&Number(f[H])!==1/0&&(f[H]=Number(f[H]));const c=w(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),m=f.status,{labelCn:y,labelEn:F}=this.parseStatus(m),p={mmsi:f.mmsi,imo:i==null?void 0:i.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:m,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?w(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:c.unix(),labelCn:y,labelEn:F,method:"trajectory",vendor:"myVessel",utc:c.utc().format()},L=Math.floor(c.diff(I,"minute",!0)/(a||1));L!==d&&(d=L,s.push(p))}),s}}class vt extends G{constructor(t){super();U(this,"token");this.token=t}async realTimePosition(t,n={}){const o="https://api.hifleet.com/position/position/get/token",i={searchParams:{mmsi:t,usertoken:this.token}},a=await x.post(o,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",n.requestId,o,i);const s=a==null?void 0:a.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",n.requestId,o,a),a;for(const I in s)!isNaN(s[I])&&Number(s[I])!==1/0&&(s[I]=Number(s[I]));s.status=s.sp>3?0:1;const r=s.status,{labelCn:u,labelEn:l}=this.parseStatus(r),h=w(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?w.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:h.unix(),utc:h.utc().format(),status:r,labelCn:u,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,n={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const i={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let a=await x.post(o,i).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",n.requestId,o,i),a instanceof Array&&(a=a[0]);for(const r in a)!isNaN(a[r])&&Number(a[r])!==1/0&&(a[r]=Number(a[r]));const s={mmsi:a.m,name:a.n,imo:a.i,callSign:a.c,length:a.l,breadth:a.b,draught:a.dr,type:a.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",a=await x.post(o,i).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",n.requestId,o,i),a instanceof Array&&(a=a[0]),a&&(s.deadweight=Number(a.dwt)),s}async suggest(t,n={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",i={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},a=await x.post(o,i).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",n.requestId,o,i);const s=[];for(const r of a)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,u)=>u.score-r.score),s}async trajectory(t,n,o,i,a=!0,s={}){var f,c,m;const r=await this.realTimePosition(t,s);let u=w(n);const l=w(o),h=w();if(a){let y=l.diff(u,"d",!0);y<0?u=l.clone().subtract(40,"d"):y<30?u.subtract(10,"d"):y<60?u.subtract(5,"d"):u=l.clone().subtract(80,"d"),y=h.diff(l,"d",!0),l.add(y>10?240:y*24,"h")}const d={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",v=await x.get(I,d).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,d);let T;v&&(T=((c=(f=v.ships)==null?void 0:f.offors)==null?void 0:c.ship)||[],T.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,v));const k=[];let g=-1;const b=w(`${(m=T==null?void 0:T[0])==null?void 0:m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of T){for(const W in y)!isNaN(y[W])&&Number(y[W])!==1/0&&(y[W]=Number(y[W]));const F=w(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(y.status),H={mmsi:y.m,name:y.n,imo:r==null?void 0:r.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:F.unix(),utc:F.utc().format(),status:y.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(F.diff(b,"minute",!0)/(i||1));N!==g&&(g=N,k.push(H))}return k}}class bt extends G{constructor(t){super();U(this,"token");this.token=t}async realTimePosition(t,n={}){const o={searchParams:{id:t,k:this.token,enc:1}},i="https://api.shipxy.com/apicall/GetSingleShip",a=await x.get(i,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",n.requestId,i,o),(a==null?void 0:a.status)!==0)return a;const s=a.data[0];for(const d in s)!isNaN(s[d])&&Number(s[d])!==1/0&&(s[d]=Number(s[d]));const{labelCn:r,labelEn:u}=await this.parseStatus(s.navistat),l=w.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:l.utc().format(),status:s.navistat,labelEn:u,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,n,o,i,a=!0,s={}){var b;const r=await this.realTimePosition(t,s),u=w(n),l=w(o),h="https://api.shipxy.com/apicall/GetShipTrack",d={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:u.unix(),etm:l.unix()}},I=await x.get(h,d).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,h,d),(I==null?void 0:I.status)!==0)return I;const v=I==null?void 0:I.points,T=[],k=w.unix((b=v[0])==null?void 0:b.utc);let g=-1;for(const f of v){const c=w.unix(f.utc),m={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(c.diff(k,"minute",!0)/(i||1));y!==g&&(g=y,T.push(m))}return T}}class gt extends G{constructor(t){super();U(this,"token");this.token=t}async getShipId(t,n={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},i="https://api3.myships.com/sp/ships/getShipIdByMMSI",a=await x.post(i,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",n.requestId,i,o),a.code!=="0"?a:a.data[0].shipId}async getShipInfo(t,n={}){const o={headers:{appKey:this.token},json:{shipId:t}},i="https://api3.myships.com/sp/ships/aissta",a=await x.post(i,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",n.requestId,i,o),a.code!=="0")return a;const s=a.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",n.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,n={}){const o=await this.getShipId(t,n),i=await this.getShipInfo(o,n),a={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,a).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",n.requestId,s,a);const u=r.data[0];for(const v in u)!isNaN(u[v])&&Number(u[v])!==1/0&&(u[v]=Number(u[v]));const{labelCn:l,labelEn:h}=await this.parseStatus(u.aisNavStatus),d=w.unix(u.posTime);return{...i,mmsi:t,lat:Math.round(u.lat/1e4/60*1e5)/1e5,lng:Math.round(u.lon/1e4/60*1e5)/1e5,sog:Math.round(u.sog/10*100)/100,cog:Math.round(u.cog/10*100)/100,hdg:Math.round(u.heading*100)/100,rot:Math.round(u.rot*100)/100,positionTime:u.posTime,utc:d.utc().format(),status:u.aisNavStatus,labelEn:h,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,n,o,i,a=!0,s={}){const r=w(n),u=w(o),l=await this.getShipId(t),h=await this.getShipInfo(l),d=[];for(;u.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),h,t,i,d);return await this.trajectoryIn30Day(l,r.unix(),u.unix(),h,t,i,d),d}async trajectoryIn30Day(t,n,o,i,a,s,r,u={}){var k;const l={headers:{appKey:this.token},json:{shipId:t,startTime:n,endTime:o}},h="https://api3.myships.com/sp/ships/position/history",d=await x.post(h,l).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",u.requestId,h,l),d.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",u.requestId,d),d;const I=d.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const v=w.unix((k=I[0])==null?void 0:k.posTime);let T=-1;for(const g of I){const b=w.unix(g.posTime),f={imo:i==null?void 0:i.imo,mmsi:a,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"myship"},c=Math.floor(b.diff(v,"minute",!0)/(s||1));c!==T&&(T=c,r.push(f))}return r}}let _;try{_=K.getLogger("vessel")}catch{}finally{}var lt=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(lt||{});class ht{parsePrinciple(e,t={}){var s,r,u;_==null||_.debug("[%s] parse rule: %s",t.requestId,e);const n=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(n)?(s=e.match(n))==null?void 0:s[0]:void 0,i=o==null?void 0:o.split(";");if(!i)return;const a={};for(let l=0;l<(i==null?void 0:i.length);l++){const h=(u=(r=i[l].match(n))==null?void 0:r[0])==null?void 0:u.split("],");if(l===0&&!h)a.scope=i[0];else if(h)for(let d=0,I=h.length;d<I;d++){const v=this.parseRule(h[d]);v&&(a[v.level]?v.key?a[v.level][v==null?void 0:v.key]=v:a[v.level]=v:v.key?a[v.level]={[v==null?void 0:v.key]:v}:a[v.level]=v)}}return a}parseRule(e,t={}){var a;_==null||_.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const n=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(a=e==null?void 0:e.match(n))==null?void 0:a[0],i=o==null?void 0:o.split(",");if(i){let s=i[3]==="Number.MAX_VALUE"?100:Number(i[3]);return s=isNaN(s)?1:s,{operator:i[0],number:Number.isNaN(Number(i[1]))?i[1]:Number(i[1]),level:i[2],time:s,key:i[4]}}}checkWeather(e,t,n={}){var v,T,k,g,b,f,c,m,y,F,p,L,H,N,W;let o=0,i=0,a=0,s=0;const r=Math.round(((T=(v=t==null?void 0:t.SEVERE)==null?void 0:v.sigWave)==null?void 0:T.number)*1.6*100)/100,u=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,l=(f=(b=t==null?void 0:t.HEAVY)==null?void 0:b.sigWave)==null?void 0:f.number,h=Math.round((((m=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:m.number)+2)*100)/100,d=(F=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:F.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let B=0;B<(e==null?void 0:e.length);B++){const C=e[B],R=(N=(H=C==null?void 0:C.meteo)==null?void 0:H.wave)==null?void 0:N.sig,q=(W=C==null?void 0:C.meteo)==null?void 0:W.wind,z=B?w(C.eta).diff(w(e[B-1].eta),"hour",!0):0;s=z>s?z:s,_==null||_.debug("[%s] check sig.wave: %j",n.requestId,{...R,dgThd4Wv:r,svThd4Wv:u,hvThd4Wv:l}),(R==null?void 0:R.height)>=r?C.isDangerous=!0:(R==null?void 0:R.height)>=u?C.isSevere=!0:(R==null?void 0:R.height)>=l&&(C.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",n.requestId,{...q,dgThd4Wd:h,svThd4Wd:d,hvThd4Wd:I}),(q==null?void 0:q.scale)>=h?(C.isDangerous=!0,delete C.isSevere,delete C.isHeavy):(q==null?void 0:q.scale)>d?(C.isDangerous||(C.isSevere=!0),delete C.isHeavy):(q==null?void 0:q.scale)===I&&!C.isDangerous&&!C.isSevere&&(C.isHeavy=!0),o+=C.isDangerous?z:0,i+=C.isSevere?z:0,a+=C.isHeavy?z:0}return o=Math.round(o*100)/100,i=Math.round(i*100)/100,a=Math.round(a*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:i,heavy:a,step:s<3?3:s,wind:{dgThd4Wd:h,svThd4Wd:d,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:u,hvThd4Wv:l}}}}const wt=new ht;let S;try{S=K.getLogger("vessel")}catch{}finally{}const It=new pt.MeteoHelper2("",!0);var ft=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ft||{}),mt=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(mt||{}),yt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(yt||{});class O{static blockCoefficient(e,t,n,o){let i=Math.round(e/(t*n*o)*100)/100;i=i<.55?.55:i>.85?.85:i;const a=[.55,.6,.65,.7,.75,.8,.85],s=a.map(r=>Math.abs(r-i));return a[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,n=9.8){let o=Math.round(Math.sqrt(e*e/(n*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,n){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let a={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return n==="Laden"&&(a=o[e]),a[0]+a[1]*t+a[2]*Math.pow(t,2)}static directionFactor(e,t=0){let n;return e>30&&e<=60?n=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?n=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?n=(.4-.03*Math.pow(t-8,2))/2:n=1,Math.round(n*1e5)/1e5}static vesselTagFactor(e,t,n,o){let i;return n==="container"?i=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?i=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):i=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),i}static waveHeightFactor(e,t,n=10,o={}){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;const i=Math.max(n>10?n-10:2.8);let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.5:t>90&&t<=120?a=e<i?.2:-.3:t>120&&t<=150?a=e<i?.25:-.2:t>150&&t<=180?a=e<i?.3:-.1:a=-.7,S==null||S.info("[%s] calculate wave height factor with ht(%d), beta(%d), draught(%d) and factor(%d)",o.requestId,e,t,n,a),Math.round(a*(.144*Math.pow(e,2)+.378*e)*1e4)/1e4}static assembleProperties(e,t,n,o){var d;const i=e.lbp??e.length??e.lengthOverall??198.9642,a=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,u=((d=e==null?void 0:e.type)==null?void 0:d.toLowerCase())||"common";return{tag:u.indexOf("container")>-1?"container":u.indexOf("tugs")>-1?"tugs":"common",lbp:i,loadCondition:t,draught:a,breadthMoulded:s,displacement:Math.round((r/1.025+a*s*i*.7)*1e4)/1e4,speed:Math.round((n??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,n,o="",i=2,a=!0,s=!1,r={}){let u;if(t.velocity&&s&&(e.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),a){let l;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:k,marineModels:g}=await it.Meteo2Assist.autoPickMeteoModel(o),b=n.utc().format(),f=await It.spotForecast(t.lat,t.lng,b,!1,!1,!0,{...r,pastDays:1,forecastDays:2,weatherModels:k,marineModels:g}),[c]=it.Meteo2Assist.pickHourly(f,b);l=it.Meteo2Assist.toLegacy(c)}catch(k){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:n.utc().format(),source:o},k)}let h=O.currentFactor(e.bearing,l==null?void 0:l.current,i,r),d=O.weatherFactor(e,l,h,r);const I=e.speed*1.943844;I+h+d<=0&&(S.warn("[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",r.requestId,I,d+h,d,h),h=Math.round(h*.6*1e3)/1e3,d=Math.round(d*.6*1e3)/1e3);const v=d<=(r.minV0Factor||-1)?Math.max(r.maxV0Factor||-3,-1*d*(d/1.2)):0;S==null||S.info("[%s] calculate speed lose with v0Factor(%d), cFactor(%d) and wxFactor(%d)",r.requestId,v,h,d),d+=v;let T=Math.round((I+h+d)*100)/100;T=T<=0?1:T,u={meteo:{...l},wxFactor:d,v0Factor:v,cFactor:h,speed:t.velocity&&s?t.velocity:T,eta:n.utc().format(),etd:n.utc().format()}}else u={wxFactor:0,v0Factor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:n.utc().format(),etd:n.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...u,...t}}static async speedLoseInHoursStep(e,t,n,o,i,a,s="",r=!0,u=!1,l={}){t.utc();const h=t.clone().add(14,"days"),d=[],I=[],v=[];let T=0,k=0,g,b;for(let f=0;f<a.length-1;f++){let c=a[f];c.distanceFromStart=Math.round((i+k)*1e3)/1e3;const m=a[f+1];if(e.bearing=E.LaneHelper.calculateBearing(c,m,!m.gcToPrevious),c.bearing=e.bearing,c.suspend&&u){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const p=c.suspend-c.elapsed;if(o-T>p)o=o-T-p,t.add(p,"hour"),c.elapsed=c.suspend;else{const L=o-T;c.elapsed+=L,t.add(L,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`,l.requestId,c),o===0)return c.distanceFromPrevious=k,{etd:t,from:b||c,to:c,next:a.filter(L=>L),wps:d,days:I,all:v}}else c.suspend=0;r=t.isAfter(h)?!1:r,c=await O.speedLoseAt(e,c,t,s,0,r,u,l),v.push(c),b=b||c,c.important&&d.push(c),t.isSameOrAfter(n)&&(I.push(c),n.add(24,"hour"));const y=E.LaneHelper.calculateDistance(c,m,!m.gcToPrevious);let F=Math.round(y/b.speed*1e5)/1e5;if(T+F<o){if(T+=F,t.add(F,"hour"),delete a[f],S==null||S.debug(`[%s] go to %j from %j with ${y}nm, and cost ${F} hours`,l.requestId,{lat:m.lat,lng:m.lng},{lat:b.lat,lng:b.lng,etd:b.etd}),k+=y,a.filter(p=>p).length<=1){g=m,g.eta=t.utc().format(),g.distanceFromPrevious=y,g.distanceFromStart=Math.round((i+k)*1e4)/1e4,d.push(g),v.push(g),delete a[f+1];break}}else{F=o-T,t.add(F,"hour");const p=E.LngLatHelper.roundPrecision(b.speed*F,5);g=E.LaneHelper.calculateCoordinate(c,e.bearing,p,"nauticalmiles",!m.gcToPrevious),g.eta=t.utc().format(),a[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${p}nm, and cost ${F} hours`,l.requestId,{lat:g.lat,lng:g.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),k+=p,g.distanceFromPrevious=Math.round(k*1e4)/1e4,g.distanceFromStart=Math.round((i+k)*1e4)/1e4;break}}return{etd:t,from:b,to:g,next:a.filter(f=>f),wps:d,days:I,all:v}}static currentFactor(e,t,n=0,o={}){const i=E.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;let a;return Math.abs(i)===Math.PI/2&&(a=0),a=((t==null?void 0:t.kts)||0)*Math.cos(i),n&2?a=Math.ceil(a*100)/100:n&1?a=Math.floor(a*100)/100:a=Math.round(a*100)/100,S==null||S.info("[%s] calculate current factor with %j",o.requestId,{beta:i,current:t,factor:a,role:n}),Math.abs(a)>5?0:a}static weatherFactor(e,t,n=0,o={}){var v,T,k,g,b,f,c;S==null||S.info("[%s] calculate weather factor via: %j",o.requestId,{...e,...t});const i=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),a=E.LngLatHelper.roundPrecision(n*1852/3600,6),s=O.froudeNumber(e.speed-a,e.lbp),r=O.amendFactor(i,s,e.loadCondition);let u=E.LaneHelper.includedAngle(e.bearing,(v=t==null?void 0:t.wind)==null?void 0:v.degree);const l=O.directionFactor(u,(T=t==null?void 0:t.wind)==null?void 0:T.scale),h=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,((k=t==null?void 0:t.wind)==null?void 0:k.kts)||10);let d=l*r*h/100*(e.speed-a);d=Math.round(d*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(d)>1&&(d=d/(Math.abs(Math.round(d))+1)),S==null||S.info("[%s] calculate wind wx factor: %d",o.requestId,d),u=E.LaneHelper.includedAngle(e.bearing,(b=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:b.degree);const I=O.waveHeightFactor(((c=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:c.height)??1,u,e.draught,o);return S==null||S.info("[%s] calculate wave wx factor: %d",o.requestId,I),d=Math.abs(d)>Math.abs(I)?d:.7*d+.9*I,S==null||S.info("[%s] calculate finial weather factor: %d (0.7 * wf) + (0.9 * hf)",o.requestId,d),Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((n,o)=>(o.positionTime||(o.positionTime=w.utc(o.etd||o.eta).unix()),n.some(i=>Math.floor(i.positionTime/t)===Math.floor(o.positionTime/t))||n.push(o),n),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((n,o)=>(n.some(i=>Math.floor(w(i.etd).unix()/t)===Math.floor(w(o.etd).unix()/t))||n.push(o),n),[]),e}static async analyseInstant(e,t,n,o,i,a="",s=0,r=!0,u=!1,l={}){var X,Q,Z,$,tt,et;const h=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{route:d,waypoints:I}=i.points,v=E.LaneHelper.calculateSubRoute(e,d);if(((X=v[0])==null?void 0:X.length)<=1)return;const{v0:T,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(n,o.loadCondition,T,0),b=I.length?E.LaneHelper.calculateSubWaypoints(e,I):[];b.forEach(D=>D.important=!0);const f={from:{...e},route:v,waypoints:b,v0:T,label:k},c={hours:[],days:[],wps:[],all:[]};s||(E.LaneHelper.calculateRouteDistance(v)/o.speed<=72?s=3:s=6);let m=E.LaneHelper.simplifyRouteToCoordinates(v,b,0),y=0,F=0,p=0,L=0;t=w(t).utc();const H=t.clone();for(;m.length>0;){const D=s-t.hour()%s,J=Math.ceil(t.clone().add(D,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,H,J,y,m,a,r,u,l);if(c.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(c.hours.push(j.from),c.wps.push(...j.wps),c.days.push(...j.days)),m=j==null?void 0:j.next,!m.length){const V=await O.speedLoseAt(g,j.to,w(j.to.eta),a,0,r,u,l);V.bearing=g.bearing,c.hours.push(V),c.all.push(V)}y+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=c.hours;for(let D=0;D<N.length-1;D++){const J=w(N[D+1].eta).diff(N[D].etd,"hour",!0)||1;F+=(N[D].wxFactor||0)*J,p+=(N[D].cFactor||0)*J,L+=J}const W=N.reduce((D,J)=>D+(J.suspend||0),0);($=c.wps)==null||$.forEach((D,J)=>{D.positionTime=w.utc(D.etd||D.eta).unix();const j=c.wps[J-1];if(j){const V=D.distanceFromStart-j.distanceFromStart,Y=w(D.eta||D.etd).diff(w(j.etd||j.eta),"h",!0);D.avgSpd=Math.round(V/Y*100)/100;const ot=E.LaneHelper.calculateBearing(j,D);D.avgBearing=ot,j.bearing=ot}}),c.wps=await O.reduceWPS(c.wps),c.days=await O.reduceDays(c.days),c.all=(tt=c.all)==null?void 0:tt.reduce((D,J)=>(J.positionTime=w.utc(J.etd||J.eta).unix(),D.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||D.push(J),D),[]),f.sample=c;const B=c.hours.at(0),C=c.hours.at(-1);f.distance=Math.round(C.distanceFromStart*1e3)/1e3,f.etd=w(B.eta).utc().format(),f.eta=w(C.eta).utc().format(),f.wxFactor=Math.round(F/L*1e3)/1e3,f.cFactor=Math.round(p/L*1e3)/1e3,f.avgSpeed=Math.round(C.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(W*1e3)/1e3;const R=E.LngLatHelper.roundPrecision(o.dgo/24*W,3),{distanceInECA:q,hoursInECA:z,totalDgoConsInECA:rt,eca:st}=await this.calculateECA(f,o,l),at=E.LngLatHelper.roundPrecision(o.fo/24*(L-z),3),ct=E.LngLatHelper.roundPrecision(o.dgo/24*L+R,3);f.extend={eca:st,distanceInECA:q,hoursInECA:z,totalDgoConsInECA:rt,totalDgoConsInSuspend:R},f.totalFoCons=at<0?0:at,f.totalDgoCons=ct;const nt=w().valueOf()-h,ut=((et=c==null?void 0:c.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,nt,ut,Math.round(nt/ut*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,n,o,i,a,s,r="",u=3,l=!0,h=!1,d={}){var Z,$,tt,et,D,J;const I=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{v0:v,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:i.speed,label:"CP"},k=O.assembleProperties(o,i.loadCondition,v,0),g=E.LaneHelper.calculateSubRoute(e,a);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const b=s.length?E.LaneHelper.calculateSubWaypoints(e,s):[];b.forEach(j=>j.important=!0);let f=E.LaneHelper.simplifyRouteToCoordinates(g,b,0),c=0,m=0,y=0,F=0;const p={hours:[],wps:[],days:[],all:[]};t=w(t).utc();const L=t.clone();for(;f.length>0;){const j=u-t.hour()%u;let V=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;V=t.clone().add(V,"h").isSameOrAfter(n)?n.diff(t,"h",!0)*1e4/1e4:V;const Y=await O.speedLoseInHoursStep(k,t,L,V,c,f,r,l,h,d);if(p.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(p.hours.push(Y.from),Y!=null&&Y.wps&&p.wps.push(...Y.wps),p.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||p.hours.push(Y==null?void 0:Y.to),c+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!V)break}p.wps=await O.reduceWPS(p.wps),p.days=await O.reduceDays(p.days),p.all=(et=p.all)==null?void 0:et.reduce((j,V)=>(V.positionTime=w.utc(V.etd||V.eta).unix(),j.some(Y=>Math.round(w(Y.etd).unix()/60)===Math.round(w(V.etd).unix()/60))||j.push(V),j),[]),(D=p.wps)==null||D.forEach((j,V)=>{const Y=p.wps[V-1];if(Y){const ot=j.distanceFromStart-Y.distanceFromStart,kt=w(j.eta||j.etd).diff(w(Y.etd||Y.eta),"h",!0);Y.bearing=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(ot/kt*100)/100}});const H=p.hours;for(let j=0;j<H.length-1;j++){const V=w(H[j+1].eta).diff(H[j].etd,"hour",!0);m+=H[j].wxFactor*V,y+=H[j].cFactor*V,F+=V}const N=H.reduce((j,V)=>j+(V.suspend||0),0),W=p.hours.at(0),B=p.hours.at(-1),C=await E.LaneHelper.calculateRangeRoute(W,B,g),R=await E.LaneHelper.calculateRangeWaypoints(W,B,g,b),q={sample:p,distance:Math.round(((B==null?void 0:B.distanceFromStart)||0)*1e4)/1e4,etd:w(W.eta).utc().format(),eta:w(B==null?void 0:B.eta).utc().format(),wxFactor:Math.round(m/F*1e3)/1e3,cFactor:Math.round(y/F*1e3)/1e3,avgSpeed:Math.round(((B==null?void 0:B.distanceFromStart)||0)/F*1e3)/1e3,totalHrs:Math.round(F*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:W,to:B,route:C,waypoints:R,v0:v,label:T},z=E.LngLatHelper.roundPrecision(i.dgo/24*N,3),{distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,eca:ct}=await this.calculateECA(q,i,d),dt=E.LngLatHelper.roundPrecision(i.fo/24*(F-st),3),nt=E.LngLatHelper.roundPrecision(i.dgo/24*F+z,3);q.extend={eca:ct,distanceInECA:rt,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:z},q.totalDgoCons=nt,q.totalFoCons=dt<0?0:dt;const X=w().valueOf()-I,Q=((J=p==null?void 0:p.hours)==null?void 0:J.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",d==null?void 0:d.requestId,X,Q,Math.round(X/Q*1e3)/1e3),q}static async analyseCost(e,t,n,o,i={}){var g,b;const a=w().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=E.LaneHelper.calculateRouteDistance(o.route);let u=0;n.forEach(f=>{const c=Math.ceil(r/f.speed/24);u=u<c?c:u}),u=u*1.3;const l=w.utc(e.etd).add(u??14,"day");let h=1;for(const f of n){const c=JSON.parse(JSON.stringify(o.route)),m=JSON.parse(JSON.stringify(o.waypoints)),y=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,l,t,f,c,m,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,i);y&&(await O.calculateCost(y,f,e,i),s.push(y),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",i.requestId,1,h,e.etd,l.format(),{cost:y.cost.total,hire:y.cost.hire,bunker:y.cost.bunker,distance:y.distance,hours:y.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),h++}s.sort((f,c)=>f.cost.total-c.cost.total);const d=s.at(0),I=s.at(1),v=[];if(v.push({combined:!1,speeds:[d],cost:(g=d.cost)==null?void 0:g.total}),I){const f=d.cost.cp,c=I.cost.cp,m=w(d.eta),y=w(d.etd),F=m.diff(y,"days",!0);let p=Math.ceil(F/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,H={combined:!1,speeds:[I],cost:(b=I.cost)==null?void 0:b.total},N;for(;p>=e.alterStep;){const W=await O.combinedAnalyse(e,t,l,[f,c],o,p,{...i,level:L});if(H.cost>W.cost?N?(N==null?void 0:N.cost)>W.cost&&(N=W):(N=H,H=W):(!N||(N==null?void 0:N.cost)>W.cost)&&(N=W),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}v.push(H),N&&v.push(N)}const k=w().valueOf()-a;return S==null||S.info("[%s] analyse elapsed: %d ms",i==null?void 0:i.requestId,k),v.sort((f,c)=>f.cost-c.cost)}static async combinedAnalyse(e,t,n,o,i,a,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,a);const r=await O.alternateAnalyse(e,t,n,o,0,i,a,s),u=r.reduce((c,m)=>c+m.cost.total,0),l=r.reduce((c,m)=>c+m.cost.hire,0),h=r.reduce((c,m)=>c+m.cost.bunker,0),d=r.reduce((c,m)=>c+m.distance,0),I=r.reduce((c,m)=>c+m.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:u,hire:l,bunker:h,distance:d,hours:I});const v=await O.alternateAnalyse(e,t,n,o,1,i,a,s),T=v.reduce((c,m)=>c+m.cost.total,0),k=v.reduce((c,m)=>c+m.cost.hire,0),g=v.reduce((c,m)=>c+m.cost.bunker,0),b=v.reduce((c,m)=>c+m.distance,0),f=v.reduce((c,m)=>c+m.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:T,hire:k,bunker:g,distance:b,hours:f}),u<T?{combined:!0,cost:Math.round(u*1e3)/1e3,speeds:r,step:a}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:v,step:a}}static async alternateAnalyse(e,t,n,o,i,a,s,r={}){var d,I;let u=w.utc(e.etd);const l={lat:e.lat,lng:e.lng},h=[];for(;u.isBefore(n);){const v=u.clone().utc().add(s,"day"),T=JSON.parse(JSON.stringify(a.route)),k=JSON.parse(JSON.stringify(a.waypoints)),g=o[i],b=await O.analyseInstantWithThreshed(l,u.utc().format(),v,t,g,T,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);b&&(await O.calculateCost(b,g,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,u.utc().format(),v.utc().format(),{cost:b.cost.total,hire:b.cost.hire,bunker:b.cost.bunker,distance:b.distance,hours:b.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const f=(I=(d=b==null?void 0:b.sample)==null?void 0:d.hours)==null?void 0:I.at(-1);if(f)l.lat=f.lat,l.lng=f.lng,u=w(f.eta),h.push(b),i=i?0:1;else break}return h}static async calculateCost(e,t,n,o={}){var i;if(e){const a=(n.addComm||0)>=1?(n.addComm||0)/100:n.addComm||0,s=Math.round((n.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(n.dailyHire||0)*(1-a)*1e3)/1e3+s,u=Math.round(e.totalFoCons*(n.priceFO||0)*1e3)/1e3,l=Math.round((e.totalDgoCons+(((i=e.extend)==null?void 0:i.totalDgoConsInECA)||0))*(n.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+u+l)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((u+l)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,n={}){var r,u,l,h;const o=await E.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let i=0,a=0,s=0;(u=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||u.forEach(d=>{d.positionTime=w.utc(d.etd||d.eta).unix()});for(const d of o){i+=d.distance;const I=await E.LaneHelper.deadReckoningTime((l=d.waypoints)==null?void 0:l.at(0),e.sample.all||e.sample.wps),v=await E.LaneHelper.deadReckoningTime((h=d.waypoints)==null?void 0:h.at(-1),e.sample.all||e.sample.wps);d.in=I,d.out=v,d.totalHrs=E.LngLatHelper.roundPrecision((v.positionTime-I.positionTime)/3600,3),d.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*d.totalHrs,3),a+=d.totalHrs,s+=d.totalDgoCons}return i=E.LngLatHelper.roundPrecision(i,3),a=E.LngLatHelper.roundPrecision(a,3),s=E.LngLatHelper.roundPrecision(s,3),{distanceInECA:i,hoursInECA:a,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var f,c;const n={hours:[],wps:[],days:[],all:[]},o=e.reduce((m,y)=>m+y.distance,0),i=e.reduce((m,y)=>{var F;return m+(((F=y.extend)==null?void 0:F.distanceInECA)||0)},0),a=e.reduce((m,y)=>m+y.totalHrs,0),s=e.reduce((m,y)=>{var F;return m+(((F=y.extend)==null?void 0:F.hoursInECA)||0)},0),r=e.reduce((m,y)=>{var F;return m+(((F=y.extend)==null?void 0:F.totalDgoConsInECA)||0)},0),u=e.reduce((m,y)=>m+y.wxFactor*y.totalHrs/a,0),l=e.reduce((m,y)=>m+y.cFactor*y.totalHrs/a,0),h=e.reduce((m,y)=>m+y.totalFoCons,0),d=e.reduce((m,y)=>m+y.totalDgoCons,0),I=e.reduce((m,y)=>m+y.cost.total,0),v=e.reduce((m,y)=>m+y.cost.hire,0),T=e.reduce((m,y)=>m+y.cost.bunker,0),k=[],g=[];let b;for(const m of e){g.push(...((f=m.extend)==null?void 0:f.eca)||[]);const y=m.sample.hours,F=m.sample.all,p=m.sample.wps,L=m.sample.days,H=y.at(0);b&&(H.distanceFromPrevious=b.distanceFromPrevious,H.distanceFromStart=b.distanceFromStart,y.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+b.distanceFromStart)}),F.at(0).distanceFromPrevious=b.distanceFromPrevious,F.at(0).distanceFromStart=b.distanceFromStart,F.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+b.distanceFromStart)}),p.at(0).distanceFromPrevious=b.distanceFromPrevious,p.at(0).distanceFromStart=b.distanceFromStart,p.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+b.distanceFromStart)}),L.at(0).distanceFromPrevious=b.distanceFromPrevious,L.at(0).distanceFromStart=b.distanceFromStart,L.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+b.distanceFromStart)})),H.cp=m.cost.cp;const N=[m.etd,m.eta],W=k.findIndex(C=>C.id===H.cp.id);W===-1?(H.cp.segment=[N],k.push(H.cp)):k[W].segment.push(N),y.forEach(C=>{var q;((q=n.hours)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.hours.push(C)}),F.forEach(C=>{var q;((q=n.all)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.all.push(C)}),p.forEach(C=>{var q;((q=n.wps)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.wps.push(C)}),L.forEach(C=>{var q;((q=n==null?void 0:n.days)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.days.push(C)});const B=(c=n.wps)==null?void 0:c.findIndex(C=>C.eta===H.eta);B===-1?n.wps.push(H):n.wps[B]=H,b=y.at(-1)}return n.wps.sort((m,y)=>w(m.etd).unix()-w(y.etd).unix()),n.wps.forEach((m,y)=>{const F=n.wps[y-1];if(F){const p=m.distanceFromStart-(F.distanceFromStart||0),L=w(m.eta||m.etd).diff(w(F.etd||F.eta),"hour",!0),H=Math.round(p/L*100)/100;m.avgSpd=H;const N=E.LaneHelper.calculateBearing(F,m);F.bearing=N}}),{sample:n,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(a*1e3)/1e3,avgSpeed:Math.round(o/a*1e3)/1e3,wxFactor:Math.round(u*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(h*1e3)/1e3,totalDgoCons:Math.round(d*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(v*1e3)/1e3,bunker:Math.round(T*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(i*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}P.AISImpl=G,P.AlertHelper=ht,P.AlertLevel=lt,P.HifleetImpl=vt,P.LoadCondition=mt,P.MyShipImpl=gt,P.MyVesselImpl=Mt,P.ShipxyImpl=bt,P.SpeedHelper=O,P.SpeedLabel=yt,P.VesselTag=ft,P.alertHelper=wt,Object.defineProperty(P,Symbol.toStringTag,{value:"Module"})});
1
+ (function(P,x){typeof exports=="object"&&typeof module<"u"?x(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo2"),require("@idm-plugin/meteo2"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo2","@idm-plugin/meteo2","@idm-plugin/meteo"],x):(P=typeof globalThis<"u"?globalThis:P||self,x(P["idm-plugin-vessel"]={},P.got,P["@log4js-node/log4js-api"],P.moment,P["@idm-plugin/geo2"],P["@idm-plugin/meteo2"],P["@idm-plugin/meteo"]))})(this,function(P,x,K,w,E,Mt,it){"use strict";var St=Object.defineProperty;var Ct=(P,x,K)=>x in P?St(P,x,{enumerable:!0,configurable:!0,writable:!0,value:K}):P[x]=K;var U=(P,x,K)=>(Ct(P,typeof x!="symbol"?x+"":x,K),K);let p;try{p=K.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,n;switch(e){case 0:t="在航(主机推动)",n="Underway Using Engine";break;case 1:t="锚泊",n="Anchored";break;case 2:t="失控",n="Not under command";break;case 3:t="操纵受限",n="Limited airworthiness";break;case 4:t="吃水受限",n="Limited by ship's draft";break;case 5:t="靠泊",n="Mooring";break;case 6:t="搁浅",n="Stranded";break;case 7:t="捕捞作业",n="Engaged in fishing";break;case 8:t="靠帆船提供动力",n="Sailing";break;default:t="未定义",n="Undefined"}return{labelCn:t,labelEn:n}}}class pt extends G{constructor(t,n){super();U(this,"clientId");U(this,"clientSecret");U(this,"token");this.clientId=t,this.clientSecret=n}async authToken(t={}){const n="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},i=await x.post(n,o).json();p==null||p.info("[%s] fetch access token from: %s - %j",t.requestId,n,i),i.error||(this.token={accessToken:i.access_token,tokenType:i.token_type,expiresIn:i.expires_in,scope:i.scope,jti:i.jti,issuedAt:w().utc().format()})}async checkToken(t={}){var n;return(!this.token||w().diff(w(this.token.issuedAt),"seconds")>(((n=this.token)==null?void 0:n.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,n={}){var a,r;await this.checkToken(n);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",i={headers:{Authorization:`${(a=this.token)==null?void 0:a.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:n.ps||10}};p==null||p.info("[%s] fetch suggest vessels from: %s - %j",n.requestId,o,i);const s=await x.post(o,i).json();return s.status!==200?(p==null||p.warn("[%s] fetch suggest vessels failed: %j",n.requestId,{message:s.message,status:s.status,code:s.code}),[]):(s.data||[]).map(l=>({mmsi:l.mmsi,name:l.nameEn,nameCn:l.nameCn,imo:Number.isNaN(l.imo)?null:Number(l.imo),callSign:l.callsign,type:l.vesselTypeNameEn,flagName:l.flagCtry,vendor:"myvessel",raw:l}))}async search(t,n={}){var u,l;await this.checkToken(n);const o=/^\d{7}$/.test(t.toString()),i=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",s=o?{imo:t}:{mmsi:t},a={headers:{Authorization:`${(u=this.token)==null?void 0:u.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:s};p==null||p.info("[%s] fetch vessel from: %s - %j",n.requestId,i,a);const r=await x.get(i,a).json();if(r.status!==200)return p==null||p.warn("[%s] fetch suggest vessels failed: %j",n.requestId,{message:r.message,status:r.status,code:r.code}),{};{const h=r.data;if(h)return{mmsi:h.mmsi,imo:Number.isNaN(h.imo)?null:Number(h.imo),callSign:h.callsign,name:h.nameEn,nameCn:h.nameCn,type:h.vesselTypeNameEn,flagName:h.flagCtry,clasz:h.classSociety,dateOfBuild:h.buildYearMonth,deadweight:h.dwt,grossTonnage:h.grt,netTonnage:h.net,teu:h.teu,length:h.length,breadth:h.width,height:h.height,draught:h.draught,speed:h.speed,passengerCapacity:h.passengercapacity,vendor:"myvessel",raw:h}}return{}}async archives(t,n={}){var a,r;await this.checkToken(n);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",i={headers:{Authorization:`${(a=this.token)==null?void 0:a.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};p==null||p.info("[%s] fetch vessel archive from: %s - %j",n.requestId,o,i);const s=await x.post(o,i).json();return s.status!==200?(p==null||p.warn("[%s] fetch vessel archive failed: %j",n.requestId,{message:s.message,status:s.status,code:s.code}),{}):s.data}async realTimePosition(t,n={}){var r,u;await this.checkToken(n);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",i={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:{mmsi:t}};p==null||p.info("[%s] fetch realtime position from: %s - %j",n.requestId,o,i);const s=await x.get(o,i).json();if(s.code)return p==null||p.warn("[%s] fetch realtime position failed: %j",n.requestId,{message:s.message,status:s.status,code:s.code}),s;const a=s.data;for(const l in a)!isNaN(a[l])&&Number(a[l])!==1/0&&(a[l]=Number(a[l]));if(a){const l=w(`${a.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:a.mmsi,name:a.vesselName||a.aisVesselName,imo:a.imo,callSign:a.callsign||a.aisCallSign,lat:a.lat,lng:a.lon,length:a.length,width:a.width,draught:a.currDraught,sog:a.sog,cog:a.cog,hdg:a.hdg,rot:a.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(a.eta)?w.utc(a.eta).format():void 0,destination:a.dest,positionTime:l.unix(),status:a.status,labelCn:a.statusNameCn,labelEn:a.statusNameEn,vesselType:a.vesselTypeNameEn,flag:a.flagCtryNameEn,clasz:a.classSociety,build:a.buildYear,dwt:a.dwt,grt:a.grt,net:a.net,method:"position",vendor:"myVessel",utc:l.utc().format()}}else return{}}async calculateRoute(t,n,o,i,s,a={}){var I,b,T;const r=w();await this.checkToken(a);const u="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",l={maxDraught:a.draught||10,useAIModel:a.useAIModel??!0,withECA:a.withECA||!1,withSpecialRegion:a.withSpecial||!1};t.code&&(l.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(l.startPoint={lon:t.lng,lat:t.lat}),n.code&&(l.endPortCode=n.code),n.lng!==void 0&&n.lat!==void 0&&(l.endPoint={lon:n.lng,lat:n.lat}),o!=null&&o.length&&(l.crossMonthList=o),i!=null&&i.length&&(l.excludeNodes=i),s!=null&&s.length&&(l.excludeSeaAreas=s);const h={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:l};p==null||p.info("[%s] fetch route from: %s - %j",a.requestId,u,h);const c=await x.post(u,h).json();if(c.status!==200)return p==null||p.warn("[%s] fetch route failed: %j",a.requestId,{message:c.message,status:c.status,code:c.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:v,tracks:f,specialRegions:d,ecaLength:m}=c.data;k.nodes=g==null?void 0:g.map(M=>({code:M.nodeCode,nameEn:M.nameEn,nameCn:M.nameCn,center:{lat:Math.round(M.lat*1e6)/1e6,lng:Math.round(M.lon*1e6)/1e6},start:{lat:Math.round(M.startLat*1e6)/1e6,lng:Math.round(M.startLon*1e6)/1e6},end:{lat:Math.round(M.endLat*1e6)/1e6,lng:Math.round(M.endLat*1e6)/1e6},isKey:M.isKeyNode,isHub:M.isHubNode})),k.seas=v==null?void 0:v.map(M=>({code:M.mrgidSea,nameEn:M.nameEn,nameCn:M.nameCn,center:{lat:Math.round(M.centerLat*1e6)/1e6,lng:Math.round(M.centerLon*1e6)/1e6},min:{lat:Math.round(M.minLat*1e6)/1e6,lng:Math.round(M.minLon*1e6)/1e6},max:{lat:Math.round(M.maxLat*1e6)/1e6,lng:Math.round(M.maxLon*1e6)/1e6},level:M.mapLevel})),d==null||d.map(M=>{M.regionLength&&k.regions.push({type:M.regionType,distance:M.regionLength,rows:M.regions.map(L=>({code:L.regionCode,nameCn:L.nameCn,nameEn:L.nameEn,type:L.regionType,distance:L.length}))})}),k.waypoints=f==null?void 0:f.map(M=>({lat:Math.round(M.lat*1e5)/1e5,lng:Math.round(M.lon*1e5)/1e5})),(T=k.waypoints)!=null&&T.length&&(k.waypoints=E.LaneHelper.simplifyCoordinates(k.waypoints),k.route=E.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=E.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=m);const F=w().diff(r,"second");return k.memo=`time cost: ${F}s`,p.info("[%s] calculate route cost: %d seconds",a.requestId,F),k}}async trajectory(t,n,o,i,s=!0,a={}){await this.checkToken(a);const r=await this.realTimePosition(t,a),u=w(n),l=w(o),h=[];for(;l.diff(u,"day",!0)>30;)await this.trajectoryIn30Day(t,u,u.clone().add(30,"day"),r,i,h,a),u.add(30,"day");return await this.trajectoryIn30Day(t,u,l,r,i,h,a),h}async trajectoryIn30Day(t,n,o,i,s,a,r={}){var b,T,k,g,v;const u="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",l={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",r.requestId,u,l);const h=await x.post(u,l).json();if(h.code)return p==null||p.warn("[%s] fetch trajectory failed: %j",r.requestId,u,{message:h.message,status:h.status,code:h.code}),h;let c=-1;const I=w(`${(g=(k=h.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=h.data)==null||v.forEach(f=>{for(const H in f)!isNaN(f[H])&&Number(f[H])!==1/0&&(f[H]=Number(f[H]));const d=w(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),m=f.status,{labelCn:y,labelEn:F}=this.parseStatus(m),M={mmsi:f.mmsi,imo:i==null?void 0:i.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:m,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?w(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:d.unix(),labelCn:y,labelEn:F,method:"trajectory",vendor:"myVessel",utc:d.utc().format()},L=Math.floor(d.diff(I,"minute",!0)/(s||1));L!==c&&(c=L,a.push(M))}),a}}class bt extends G{constructor(t){super();U(this,"token");this.token=t}async realTimePosition(t,n={}){const o="https://api.hifleet.com/position/position/get/token",i={searchParams:{mmsi:t,usertoken:this.token}},s=await x.post(o,i).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",n.requestId,o,i);const a=s==null?void 0:s.list;if(!a)return p==null||p.warn("[%s] fetch realtime position failed: %j",n.requestId,o,s),s;for(const I in a)!isNaN(a[I])&&Number(a[I])!==1/0&&(a[I]=Number(a[I]));a.status=a.sp>3?0:1;const r=a.status,{labelCn:u,labelEn:l}=this.parseStatus(r),h=w(`${a.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:a.m,name:a.n,imo:a.imonumber,callSign:a.callsign,lat:Math.round(a.la/60*1e5)/1e5,lng:Math.round(a.lo/60*1e5)/1e5,length:a.l,width:a.w,draught:a.draught,sog:a.sp,cog:a.co,hdg:a.h,rot:isNaN(a.rot)?0:a.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(a.eta)?w.utc(a.eta).format():void 0,destination:a.destination,vesselType:a.type,dwt:a.dwt,build:a.buildyear,flag:a.fn,positionTime:h.unix(),utc:h.utc().format(),status:r,labelCn:u,labelEn:l,method:"position",vendor:"hifleet"}}async search(t,n={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const i={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let s=await x.post(o,i).json();p==null||p.info("[%s] fetch vessel props from: %s - %j",n.requestId,o,i),s instanceof Array&&(s=s[0]);for(const r in s)!isNaN(s[r])&&Number(s[r])!==1/0&&(s[r]=Number(s[r]));const a={mmsi:s.m,name:s.n,imo:s.i,callSign:s.c,length:s.l,breadth:s.b,draught:s.dr,type:s.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",s=await x.post(o,i).json(),p==null||p.info("[%s] search vessel dead weight from: %s - %j",n.requestId,o,i),s instanceof Array&&(s=s[0]),s&&(a.deadweight=Number(s.dwt)),a}async suggest(t,n={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",i={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},s=await x.post(o,i).json();p==null||p.info("[%s] suggest vessel props from: %s - %j",n.requestId,o,i);const a=[];for(const r of s)a.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return a.sort((r,u)=>u.score-r.score),a}async trajectory(t,n,o,i,s=!0,a={}){var f,d,m;const r=await this.realTimePosition(t,a);let u=w(n);const l=w(o),h=w();if(s){let y=l.diff(u,"d",!0);y<0?u=l.clone().subtract(40,"d"):y<30?u.subtract(10,"d"):y<60?u.subtract(5,"d"):u=l.clone().subtract(80,"d"),y=h.diff(l,"d",!0),l.add(y>10?240:y*24,"h")}const c={searchParams:{endtime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,c).json();p==null||p.info("[%s] fetch trajectory from: %s - %j",a.requestId,I,c);let T;b&&(T=((d=(f=b.ships)==null?void 0:f.offors)==null?void 0:d.ship)||[],T.length||p==null||p.warn("[%s] fetch trajectory failed: %j",a.requestId,b));const k=[];let g=-1;const v=w(`${(m=T==null?void 0:T[0])==null?void 0:m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of T){for(const W in y)!isNaN(y[W])&&Number(y[W])!==1/0&&(y[W]=Number(y[W]));const F=w(`${y.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");y.status=y.sp>4?0:1;const{labelEn:M,labelCn:L}=this.parseStatus(y.status),H={mmsi:y.m,name:y.n,imo:r==null?void 0:r.imo,lat:y.la,lng:y.lo,draught:y.draught,sog:y.sp,cog:y.co,hdg:y.hdg,positionTime:F.unix(),utc:F.utc().format(),status:y.status,labelCn:L,labelEn:M,method:"trajectory",vendor:"hifleet"},N=Math.floor(F.diff(v,"minute",!0)/(i||1));N!==g&&(g=N,k.push(H))}return k}}class vt extends G{constructor(t){super();U(this,"token");this.token=t}async realTimePosition(t,n={}){const o={searchParams:{id:t,k:this.token,enc:1}},i="https://api.shipxy.com/apicall/GetSingleShip",s=await x.get(i,o).json();if(p==null||p.info("[%s] fetch realtime position from: %s - %j",n.requestId,i,o),(s==null?void 0:s.status)!==0)return s;const a=s.data[0];for(const c in a)!isNaN(a[c])&&Number(a[c])!==1/0&&(a[c]=Number(a[c]));const{labelCn:r,labelEn:u}=await this.parseStatus(a.navistat),l=w.unix(a.lasttime);return{mmsi:a.ShipID,name:a.name,imo:a.imo,callSign:a.callsign,lat:Math.round(a.lat/1e6*1e5)/1e5,lng:Math.round(a.lon/1e6*1e5)/1e5,length:Math.round(a.length/10*100)/100,width:Math.round(a.width/10*100)/100,draught:Math.round(a.draught/1e3*100)/100,sog:Math.round(a.sog*3600/1e3/1852*100)/100,cog:Math.round(a.cog/100*100)/100,hdg:Math.round(a.hdg/100*100)/100,rot:Math.round(a.rot/100*100)/100,positionTime:a.lasttime,utc:l.utc().format(),status:a.navistat,labelEn:u,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,n,o,i,s=!0,a={}){var v;const r=await this.realTimePosition(t,a),u=w(n),l=w(o),h="https://api.shipxy.com/apicall/GetShipTrack",c={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:u.unix(),etm:l.unix()}},I=await x.get(h,c).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",a.requestId,h,c),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,T=[],k=w.unix((v=b[0])==null?void 0:v.utc);let g=-1;for(const f of b){const d=w.unix(f.utc),m={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:d.unix(),utc:d.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(d.diff(k,"minute",!0)/(i||1));y!==g&&(g=y,T.push(m))}return T}}class gt extends G{constructor(t){super();U(this,"token");this.token=t}async getShipId(t,n={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},i="https://api3.myships.com/sp/ships/getShipIdByMMSI",s=await x.post(i,o).json();return p==null||p.info("[%s] fetch ship id from: %s - %j",n.requestId,i,o),s.code!=="0"?s:s.data[0].shipId}async getShipInfo(t,n={}){const o={headers:{appKey:this.token},json:{shipId:t}},i="https://api3.myships.com/sp/ships/aissta",s=await x.post(i,o).json();if(p==null||p.info("[%s] fetch ship info from: %s - %j",n.requestId,i,o),s.code!=="0")return s;const a=s.data;let r=a.imo;return t==="407170"&&(r="9198379",p==null||p.warn("[%s] ship(%s) imo error: %s, should be %s",n.requestId,t,a.imo,r)),{mmsi:a.mmsi,name:a.shipnameEn,imo:r,callSign:a.callSign,length:a.length,width:a.breadth,draught:(a.draught||100)/10}}async realTimePosition(t,n={}){const o=await this.getShipId(t,n),i=await this.getShipInfo(o,n),s={headers:{appKey:this.token},json:{shipId:o}},a="https://api3.myships.com/sp/ships/position/latest",r=await x.post(a,s).json();p==null||p.info("[%s] fetch realtime position from: %s - %j",n.requestId,a,s);const u=r.data[0];for(const b in u)!isNaN(u[b])&&Number(u[b])!==1/0&&(u[b]=Number(u[b]));const{labelCn:l,labelEn:h}=await this.parseStatus(u.aisNavStatus),c=w.unix(u.posTime);return{...i,mmsi:t,lat:Math.round(u.lat/1e4/60*1e5)/1e5,lng:Math.round(u.lon/1e4/60*1e5)/1e5,sog:Math.round(u.sog/10*100)/100,cog:Math.round(u.cog/10*100)/100,hdg:Math.round(u.heading*100)/100,rot:Math.round(u.rot*100)/100,positionTime:u.posTime,utc:c.utc().format(),status:u.aisNavStatus,labelEn:h,labelCn:l,method:"position",vendor:"myship"}}async trajectory(t,n,o,i,s=!0,a={}){const r=w(n),u=w(o),l=await this.getShipId(t),h=await this.getShipInfo(l),c=[];for(;u.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(l,r.unix(),r.add(30,"day").unix(),h,t,i,c);return await this.trajectoryIn30Day(l,r.unix(),u.unix(),h,t,i,c),c}async trajectoryIn30Day(t,n,o,i,s,a,r,u={}){var k;const l={headers:{appKey:this.token},json:{shipId:t,startTime:n,endTime:o}},h="https://api3.myships.com/sp/ships/position/history",c=await x.post(h,l).json();if(p==null||p.info("[%s] fetch trajectory from: %s - %j",u.requestId,h,l),c.code!=="0")return p==null||p.warn("[%s] invoke myship trajectory failed: %j",u.requestId,c),c;const I=c.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const b=w.unix((k=I[0])==null?void 0:k.posTime);let T=-1;for(const g of I){const v=w.unix(g.posTime),f={imo:i==null?void 0:i.imo,mmsi:s,lat:Math.round(g.lat/1e4/60*1e5)/1e5,lng:Math.round(g.lon/1e4/60*1e5)/1e5,sog:Math.round(g.sog/10*100)/100,cog:Math.round(g.cog/10*100)/100,hdg:Math.round(g.heading*100)/100,rot:Math.round(g.rot*100)/100,positionTime:v.unix(),utc:v.utc().format(),method:"trajectory",vendor:"myship"},d=Math.floor(v.diff(b,"minute",!0)/(a||1));d!==T&&(T=d,r.push(f))}return r}}let _;try{_=K.getLogger("vessel")}catch{}finally{}var lt=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(lt||{});class ht{parsePrinciple(e,t={}){var a,r,u;_==null||_.debug("[%s] parse rule: %s",t.requestId,e);const n=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(n)?(a=e.match(n))==null?void 0:a[0]:void 0,i=o==null?void 0:o.split(";");if(!i)return;const s={};for(let l=0;l<(i==null?void 0:i.length);l++){const h=(u=(r=i[l].match(n))==null?void 0:r[0])==null?void 0:u.split("],");if(l===0&&!h)s.scope=i[0];else if(h)for(let c=0,I=h.length;c<I;c++){const b=this.parseRule(h[c]);b&&(s[b.level]?b.key?s[b.level][b==null?void 0:b.key]=b:s[b.level]=b:b.key?s[b.level]={[b==null?void 0:b.key]:b}:s[b.level]=b)}}return s}parseRule(e,t={}){var s;_==null||_.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const n=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(s=e==null?void 0:e.match(n))==null?void 0:s[0],i=o==null?void 0:o.split(",");if(i){let a=i[3]==="Number.MAX_VALUE"?100:Number(i[3]);return a=isNaN(a)?1:a,{operator:i[0],number:Number.isNaN(Number(i[1]))?i[1]:Number(i[1]),level:i[2],time:a,key:i[4]}}}checkWeather(e,t,n={}){var b,T,k,g,v,f,d,m,y,F,M,L,H,N,W;let o=0,i=0,s=0,a=0;const r=Math.round(((T=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:T.number)*1.6*100)/100,u=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,l=(f=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:f.number,h=Math.round((((m=(d=t==null?void 0:t.SEVERE)==null?void 0:d.wind)==null?void 0:m.number)+2)*100)/100,c=(F=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:F.number,I=(L=(M=t==null?void 0:t.HEAVY)==null?void 0:M.wind)==null?void 0:L.number;for(let B=0;B<(e==null?void 0:e.length);B++){const C=e[B],R=(N=(H=C==null?void 0:C.meteo)==null?void 0:H.wave)==null?void 0:N.sig,q=(W=C==null?void 0:C.meteo)==null?void 0:W.wind,z=B?w(C.eta).diff(w(e[B-1].eta),"hour",!0):0;a=z>a?z:a,_==null||_.debug("[%s] check sig.wave: %j",n.requestId,{...R,dgThd4Wv:r,svThd4Wv:u,hvThd4Wv:l}),(R==null?void 0:R.height)>=r?C.isDangerous=!0:(R==null?void 0:R.height)>=u?C.isSevere=!0:(R==null?void 0:R.height)>=l&&(C.isHeavy=!0),_==null||_.debug("[%s] check wind: %j",n.requestId,{...q,dgThd4Wd:h,svThd4Wd:c,hvThd4Wd:I}),(q==null?void 0:q.scale)>=h?(C.isDangerous=!0,delete C.isSevere,delete C.isHeavy):(q==null?void 0:q.scale)>c?(C.isDangerous||(C.isSevere=!0),delete C.isHeavy):(q==null?void 0:q.scale)===I&&!C.isDangerous&&!C.isSevere&&(C.isHeavy=!0),o+=C.isDangerous?z:0,i+=C.isSevere?z:0,s+=C.isHeavy?z:0}return o=Math.round(o*100)/100,i=Math.round(i*100)/100,s=Math.round(s*100)/100,a=Math.round(a),{sample:e,dangerous:o,severe:i,heavy:s,step:a<3?3:a,wind:{dgThd4Wd:h,svThd4Wd:c,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:u,hvThd4Wv:l}}}}const wt=new ht;let S;try{S=K.getLogger("vessel")}catch{}finally{}const It=new Mt.MeteoHelper2("",!0);var ft=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ft||{}),mt=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(mt||{}),yt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(yt||{});class O{static blockCoefficient(e,t,n,o){let i=Math.round(e/(t*n*o)*100)/100;i=i<.55?.55:i>.85?.85:i;const s=[.55,.6,.65,.7,.75,.8,.85],a=s.map(r=>Math.abs(r-i));return s[a.indexOf(Math.min(...a))]}static froudeNumber(e,t,n=9.8){let o=Math.round(Math.sqrt(e*e/(n*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,n){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let s={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return n==="Laden"&&(s=o[e]),s[0]+s[1]*t+s[2]*Math.pow(t,2)}static directionFactor(e,t=0){let n;return e>30&&e<=60?n=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?n=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?n=(.4-.03*Math.pow(t-8,2))/2:n=1,Math.round(n*1e5)/1e5}static vesselTagFactor(e,t,n,o){let i;return n==="container"?i=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?i=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):i=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),i}static waveHeightFactor(e,t,n=10,o={}){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;const i=Math.max(n>10?n-10:2.8);let s;return t>30&&t<=60?s=-.6:t>60&&t<=90?s=-.5:t>90&&t<=120?s=e<i?.2:-.3:t>120&&t<=150?s=e<i?.25:-.2:t>150&&t<=180?s=e<i?.3:-.1:s=-.7,S==null||S.info("[%s] calculate wave height factor with ht(%d), beta(%d), draught(%d) and factor(%d)",o.requestId,e,t,n,s),Math.round(s*(.144*Math.pow(e,2)+.378*e)*1e4)/1e4}static assembleProperties(e,t,n,o){var c;const i=e.lbp??e.length??e.lengthOverall??198.9642,s=e.draught??8,a=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,u=((c=e==null?void 0:e.type)==null?void 0:c.toLowerCase())||"common";return{tag:u.indexOf("container")>-1?"container":u.indexOf("tugs")>-1?"tugs":"common",lbp:i,loadCondition:t,draught:s,breadthMoulded:a,displacement:Math.round((r/1.025+s*a*i*.7)*1e4)/1e4,speed:Math.round((n??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,n,o="",i=2,s=!0,a=!1,r={}){let u;if(t.velocity&&a&&(e.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),s){let l;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:k,marineModels:g}=await it.Meteo2Assist.autoPickMeteoModel(o),v=n.utc().format(),f=await It.spotForecast(t.lat,t.lng,v,!1,!1,!0,{...r,pastDays:1,forecastDays:2,weatherModels:k,marineModels:g}),[d]=it.Meteo2Assist.pickHourly(f,v);l=it.Meteo2Assist.toLegacy(d)}catch(k){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:n.utc().format(),source:o},k)}let h=O.currentFactor(e.bearing,l==null?void 0:l.current,i,r),c=O.weatherFactor(e,l,h,r);const I=e.speed*1.943844;I+h+c<=0&&(S.warn("[%s] v0(%d) is less then factor(%d) = wxFactor(%d) + cFactor(%d), scale factor with 0.6",r.requestId,I,c+h,c,h),h=Math.round(h*.6*1e3)/1e3,c=Math.round(c*.6*1e3)/1e3);const b=c<=(r.minV0Factor||-1)?Math.max(r.maxV0Factor||-2.5,-1*c*(c/1.2)):0;S==null||S.info("[%s] calculate speed lose with v0Factor(%d), cFactor(%d) and wxFactor(%d)",r.requestId,b,h,c),c+=b;let T=Math.round((I+h+c)*100)/100;T=T<=0?1:T,u={meteo:{...l},wxFactor:c,v0Factor:b,cFactor:h,speed:t.velocity&&a?t.velocity:T,eta:n.utc().format(),etd:n.utc().format()}}else u={wxFactor:0,v0Factor:0,cFactor:0,speed:t.velocity&&a?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:n.utc().format(),etd:n.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...u,...t}}static async speedLoseInHoursStep(e,t,n,o,i,s,a="",r=!0,u=!1,l={}){t.utc();const h=t.clone().add(14,"days"),c=[],I=[],b=[];let T=0,k=0,g,v;for(let f=0;f<s.length-1;f++){let d=s[f];d.distanceFromStart=Math.round((i+k)*1e3)/1e3;const m=s[f+1];if(e.bearing=E.LaneHelper.calculateBearing(d,m,!m.gcToPrevious),d.bearing=e.bearing,d.suspend&&u){d.eta=d.eta||t.utc().format(),d.elapsed=d.elapsed??0;const M=d.suspend-d.elapsed;if(o-T>M)o=o-T-M,t.add(M,"hour"),d.elapsed=d.suspend;else{const L=o-T;d.elapsed+=L,t.add(L,"hour"),o=0}if(S==null||S.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`,l.requestId,d),o===0)return d.distanceFromPrevious=k,{etd:t,from:v||d,to:d,next:s.filter(L=>L),wps:c,days:I,all:b}}else d.suspend=0;r=t.isAfter(h)?!1:r,d=await O.speedLoseAt(e,d,t,a,0,r,u,l),b.push(d),v=v||d,d.important&&c.push(d),t.isSameOrAfter(n)&&(I.push(d),n.add(24,"hour"));const y=E.LaneHelper.calculateDistance(d,m,!m.gcToPrevious);let F=Math.round(y/v.speed*1e5)/1e5;if(T+F<o){if(T+=F,t.add(F,"hour"),delete s[f],S==null||S.debug(`[%s] go to %j from %j with ${y}nm, and cost ${F} hours`,l.requestId,{lat:m.lat,lng:m.lng},{lat:v.lat,lng:v.lng,etd:v.etd}),k+=y,s.filter(M=>M).length<=1){g=m,g.eta=t.utc().format(),g.distanceFromPrevious=y,g.distanceFromStart=Math.round((i+k)*1e4)/1e4,c.push(g),b.push(g),delete s[f+1];break}}else{F=o-T,t.add(F,"hour");const M=E.LngLatHelper.roundPrecision(v.speed*F,5);g=E.LaneHelper.calculateCoordinate(d,e.bearing,M,"nauticalmiles",!m.gcToPrevious),g.eta=t.utc().format(),s[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${M}nm, and cost ${F} hours`,l.requestId,{lat:g.lat,lng:g.lng},{lat:d.lat,lng:d.lng,etd:d.etd}),k+=M,g.distanceFromPrevious=Math.round(k*1e4)/1e4,g.distanceFromStart=Math.round((i+k)*1e4)/1e4;break}}return{etd:t,from:v,to:g,next:s.filter(f=>f),wps:c,days:I,all:b}}static currentFactor(e,t,n=0,o={}){const i=E.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;let s;return Math.abs(i)===Math.PI/2&&(s=0),s=((t==null?void 0:t.kts)||0)*Math.cos(i),n&2?s=Math.ceil(s*100)/100:n&1?s=Math.floor(s*100)/100:s=Math.round(s*100)/100,S==null||S.info("[%s] calculate current factor with %j",o.requestId,{beta:i,current:t,factor:s,role:n}),Math.abs(s)>5?0:s}static weatherFactor(e,t,n=0,o={}){var b,T,k,g,v,f,d;S==null||S.info("[%s] calculate weather factor via: %j",o.requestId,{...e,...t});const i=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),s=E.LngLatHelper.roundPrecision(n*1852/3600,6),a=O.froudeNumber(e.speed-s,e.lbp),r=O.amendFactor(i,a,e.loadCondition);let u=E.LaneHelper.includedAngle(e.bearing,(b=t==null?void 0:t.wind)==null?void 0:b.degree);const l=O.directionFactor(u,(T=t==null?void 0:t.wind)==null?void 0:T.scale),h=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,((k=t==null?void 0:t.wind)==null?void 0:k.kts)||10);let c=l*r*h/100*(e.speed-s);c=Math.round(c*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),S==null||S.info("[%s] calculate wind wx factor: %d",o.requestId,c),u=E.LaneHelper.includedAngle(e.bearing,(v=(g=t==null?void 0:t.wave)==null?void 0:g.sig)==null?void 0:v.degree);const I=O.waveHeightFactor(((d=(f=t==null?void 0:t.wave)==null?void 0:f.sig)==null?void 0:d.height)??1,u,e.draught,o);return S==null||S.info("[%s] calculate wave wx factor: %d",o.requestId,I),c=Math.abs(c)>Math.abs(I)?c:.7*c+.9*I,S==null||S.info("[%s] calculate finial weather factor: %d (0.7 * wf) + (0.9 * hf)",o.requestId,c),c=Math.abs(c)>4?4*(Math.abs(c)/c)+Math.abs(c)/c*(Math.abs(c)-2)*.1:c,Math.round((c||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((n,o)=>(o.positionTime||(o.positionTime=w.utc(o.etd||o.eta).unix()),n.some(i=>Math.floor(i.positionTime/t)===Math.floor(o.positionTime/t))||n.push(o),n),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((n,o)=>(n.some(i=>Math.floor(w(i.etd).unix()/t)===Math.floor(w(o.etd).unix()/t))||n.push(o),n),[]),e}static async analyseInstant(e,t,n,o,i,s="",a=0,r=!0,u=!1,l={}){var X,Q,Z,$,tt,et;const h=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{route:c,waypoints:I}=i.points,b=E.LaneHelper.calculateSubRoute(e,c);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:T,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(n,o.loadCondition,T,0),v=I.length?E.LaneHelper.calculateSubWaypoints(e,I):[];v.forEach(D=>D.important=!0);const f={from:{...e},route:b,waypoints:v,v0:T,label:k},d={hours:[],days:[],wps:[],all:[]};a||(E.LaneHelper.calculateRouteDistance(b)/o.speed<=72?a=3:a=6);let m=E.LaneHelper.simplifyRouteToCoordinates(b,v,0),y=0,F=0,M=0,L=0;t=w(t).utc();const H=t.clone();for(;m.length>0;){const D=a-t.hour()%a,J=Math.ceil(t.clone().add(D,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,H,J,y,m,s,r,u,l);if(d.all.push(...j.all),(Q=j.from)!=null&&Q.speed&&(d.hours.push(j.from),d.wps.push(...j.wps),d.days.push(...j.days)),m=j==null?void 0:j.next,!m.length){const V=await O.speedLoseAt(g,j.to,w(j.to.eta),s,0,r,u,l);V.bearing=g.bearing,d.hours.push(V),d.all.push(V)}y+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=d.hours;for(let D=0;D<N.length-1;D++){const J=w(N[D+1].eta).diff(N[D].etd,"hour",!0)||1;F+=(N[D].wxFactor||0)*J,M+=(N[D].cFactor||0)*J,L+=J}const W=N.reduce((D,J)=>D+(J.suspend||0),0);($=d.wps)==null||$.forEach((D,J)=>{D.positionTime=w.utc(D.etd||D.eta).unix();const j=d.wps[J-1];if(j){const V=D.distanceFromStart-j.distanceFromStart,Y=w(D.eta||D.etd).diff(w(j.etd||j.eta),"h",!0);D.avgSpd=Math.round(V/Y*100)/100;const ot=E.LaneHelper.calculateBearing(j,D);D.avgBearing=ot,j.bearing=ot}}),d.wps=await O.reduceWPS(d.wps),d.days=await O.reduceDays(d.days),d.all=(tt=d.all)==null?void 0:tt.reduce((D,J)=>(J.positionTime=w.utc(J.etd||J.eta).unix(),D.some(j=>Math.round(j.positionTime/60)===Math.round(J.positionTime/60))||D.push(J),D),[]),f.sample=d;const B=d.hours.at(0),C=d.hours.at(-1);f.distance=Math.round(C.distanceFromStart*1e3)/1e3,f.etd=w(B.eta).utc().format(),f.eta=w(C.eta).utc().format(),f.wxFactor=Math.round(F/L*1e3)/1e3,f.cFactor=Math.round(M/L*1e3)/1e3,f.avgSpeed=Math.round(C.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(W*1e3)/1e3;const R=E.LngLatHelper.roundPrecision(o.dgo/24*W,3),{distanceInECA:q,hoursInECA:z,totalDgoConsInECA:rt,eca:at}=await this.calculateECA(f,o,l),st=E.LngLatHelper.roundPrecision(o.fo/24*(L-z),3),ct=E.LngLatHelper.roundPrecision(o.dgo/24*L+R,3);f.extend={eca:at,distanceInECA:q,hoursInECA:z,totalDgoConsInECA:rt,totalDgoConsInSuspend:R},f.totalFoCons=st<0?0:st,f.totalDgoCons=ct;const nt=w().valueOf()-h,ut=((et=d==null?void 0:d.hours)==null?void 0:et.length)||1;return S==null||S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",l==null?void 0:l.requestId,nt,ut,Math.round(nt/ut*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,n,o,i,s,a,r="",u=3,l=!0,h=!1,c={}){var Z,$,tt,et,D,J;const I=w().valueOf();e.lng=E.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:i.speed,label:"CP"},k=O.assembleProperties(o,i.loadCondition,b,0),g=E.LaneHelper.calculateSubRoute(e,s);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const v=a.length?E.LaneHelper.calculateSubWaypoints(e,a):[];v.forEach(j=>j.important=!0);let f=E.LaneHelper.simplifyRouteToCoordinates(g,v,0),d=0,m=0,y=0,F=0;const M={hours:[],wps:[],days:[],all:[]};t=w(t).utc();const L=t.clone();for(;f.length>0;){const j=u-t.hour()%u;let V=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;V=t.clone().add(V,"h").isSameOrAfter(n)?n.diff(t,"h",!0)*1e4/1e4:V;const Y=await O.speedLoseInHoursStep(k,t,L,V,d,f,r,l,h,c);if(M.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(M.hours.push(Y.from),Y!=null&&Y.wps&&M.wps.push(...Y.wps),M.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||M.hours.push(Y==null?void 0:Y.to),d+=Math.round((((tt=Y==null?void 0:Y.to)==null?void 0:tt.distanceFromPrevious)??0)*1e4)/1e4,!V)break}M.wps=await O.reduceWPS(M.wps),M.days=await O.reduceDays(M.days),M.all=(et=M.all)==null?void 0:et.reduce((j,V)=>(V.positionTime=w.utc(V.etd||V.eta).unix(),j.some(Y=>Math.round(w(Y.etd).unix()/60)===Math.round(w(V.etd).unix()/60))||j.push(V),j),[]),(D=M.wps)==null||D.forEach((j,V)=>{const Y=M.wps[V-1];if(Y){const ot=j.distanceFromStart-Y.distanceFromStart,kt=w(j.eta||j.etd).diff(w(Y.etd||Y.eta),"h",!0);Y.bearing=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(ot/kt*100)/100}});const H=M.hours;for(let j=0;j<H.length-1;j++){const V=w(H[j+1].eta).diff(H[j].etd,"hour",!0);m+=H[j].wxFactor*V,y+=H[j].cFactor*V,F+=V}const N=H.reduce((j,V)=>j+(V.suspend||0),0),W=M.hours.at(0),B=M.hours.at(-1),C=await E.LaneHelper.calculateRangeRoute(W,B,g),R=await E.LaneHelper.calculateRangeWaypoints(W,B,g,v),q={sample:M,distance:Math.round(((B==null?void 0:B.distanceFromStart)||0)*1e4)/1e4,etd:w(W.eta).utc().format(),eta:w(B==null?void 0:B.eta).utc().format(),wxFactor:Math.round(m/F*1e3)/1e3,cFactor:Math.round(y/F*1e3)/1e3,avgSpeed:Math.round(((B==null?void 0:B.distanceFromStart)||0)/F*1e3)/1e3,totalHrs:Math.round(F*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:W,to:B,route:C,waypoints:R,v0:b,label:T},z=E.LngLatHelper.roundPrecision(i.dgo/24*N,3),{distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:st,eca:ct}=await this.calculateECA(q,i,c),dt=E.LngLatHelper.roundPrecision(i.fo/24*(F-at),3),nt=E.LngLatHelper.roundPrecision(i.dgo/24*F+z,3);q.extend={eca:ct,distanceInECA:rt,hoursInECA:at,totalDgoConsInECA:st,totalDgoConsInSuspend:z},q.totalDgoCons=nt,q.totalFoCons=dt<0?0:dt;const X=w().valueOf()-I,Q=((J=M==null?void 0:M.hours)==null?void 0:J.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",c==null?void 0:c.requestId,X,Q,Math.round(X/Q*1e3)/1e3),q}static async analyseCost(e,t,n,o,i={}){var g,v;const s=w().valueOf(),a=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=E.LaneHelper.calculateRouteDistance(o.route);let u=0;n.forEach(f=>{const d=Math.ceil(r/f.speed/24);u=u<d?d:u}),u=u*1.3;const l=w.utc(e.etd).add(u??14,"day");let h=1;for(const f of n){const d=JSON.parse(JSON.stringify(o.route)),m=JSON.parse(JSON.stringify(o.waypoints)),y=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,l,t,f,d,m,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,i);y&&(await O.calculateCost(y,f,e,i),a.push(y),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",i.requestId,1,h,e.etd,l.format(),{cost:y.cost.total,hire:y.cost.hire,bunker:y.cost.bunker,distance:y.distance,hours:y.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),h++}a.sort((f,d)=>f.cost.total-d.cost.total);const c=a.at(0),I=a.at(1),b=[];if(b.push({combined:!1,speeds:[c],cost:(g=c.cost)==null?void 0:g.total}),I){const f=c.cost.cp,d=I.cost.cp,m=w(c.eta),y=w(c.etd),F=m.diff(y,"days",!0);let M=Math.ceil(F/2);M=M>7?7:M<e.alterStep?e.alterStep:M;let L=2,H={combined:!1,speeds:[I],cost:(v=I.cost)==null?void 0:v.total},N;for(;M>=e.alterStep;){const W=await O.combinedAnalyse(e,t,l,[f,d],o,M,{...i,level:L});if(H.cost>W.cost?N?(N==null?void 0:N.cost)>W.cost&&(N=W):(N=H,H=W):(!N||(N==null?void 0:N.cost)>W.cost)&&(N=W),M<=e.alterStep)break;M=Math.ceil(M/2),L+=1}b.push(H),N&&b.push(N)}const k=w().valueOf()-s;return S==null||S.info("[%s] analyse elapsed: %d ms",i==null?void 0:i.requestId,k),b.sort((f,d)=>f.cost-d.cost)}static async combinedAnalyse(e,t,n,o,i,s,a={}){a.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",a.requestId,a.level,s);const r=await O.alternateAnalyse(e,t,n,o,0,i,s,a),u=r.reduce((d,m)=>d+m.cost.total,0),l=r.reduce((d,m)=>d+m.cost.hire,0),h=r.reduce((d,m)=>d+m.cost.bunker,0),c=r.reduce((d,m)=>d+m.distance,0),I=r.reduce((d,m)=>d+m.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",a.requestId,a.level,{cost:u,hire:l,bunker:h,distance:c,hours:I});const b=await O.alternateAnalyse(e,t,n,o,1,i,s,a),T=b.reduce((d,m)=>d+m.cost.total,0),k=b.reduce((d,m)=>d+m.cost.hire,0),g=b.reduce((d,m)=>d+m.cost.bunker,0),v=b.reduce((d,m)=>d+m.distance,0),f=b.reduce((d,m)=>d+m.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",a.requestId,a.level,{cost:T,hire:k,bunker:g,distance:v,hours:f}),u<T?{combined:!0,cost:Math.round(u*1e3)/1e3,speeds:r,step:s}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:b,step:s}}static async alternateAnalyse(e,t,n,o,i,s,a,r={}){var c,I;let u=w.utc(e.etd);const l={lat:e.lat,lng:e.lng},h=[];for(;u.isBefore(n);){const b=u.clone().utc().add(a,"day"),T=JSON.parse(JSON.stringify(s.route)),k=JSON.parse(JSON.stringify(s.waypoints)),g=o[i],v=await O.analyseInstantWithThreshed(l,u.utc().format(),b,t,g,T,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);v&&(await O.calculateCost(v,g,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,u.utc().format(),b.utc().format(),{cost:v.cost.total,hire:v.cost.hire,bunker:v.cost.bunker,distance:v.distance,hours:v.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const f=(I=(c=v==null?void 0:v.sample)==null?void 0:c.hours)==null?void 0:I.at(-1);if(f)l.lat=f.lat,l.lng=f.lng,u=w(f.eta),h.push(v),i=i?0:1;else break}return h}static async calculateCost(e,t,n,o={}){var i;if(e){const s=(n.addComm||0)>=1?(n.addComm||0)/100:n.addComm||0,a=Math.round((n.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(n.dailyHire||0)*(1-s)*1e3)/1e3+a,u=Math.round(e.totalFoCons*(n.priceFO||0)*1e3)/1e3,l=Math.round((e.totalDgoCons+(((i=e.extend)==null?void 0:i.totalDgoConsInECA)||0))*(n.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+u+l)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:a,bunker:Math.round((u+l)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,n={}){var r,u,l,h;const o=await E.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let i=0,s=0,a=0;(u=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||u.forEach(c=>{c.positionTime=w.utc(c.etd||c.eta).unix()});for(const c of o){i+=c.distance;const I=await E.LaneHelper.deadReckoningTime((l=c.waypoints)==null?void 0:l.at(0),e.sample.all||e.sample.wps),b=await E.LaneHelper.deadReckoningTime((h=c.waypoints)==null?void 0:h.at(-1),e.sample.all||e.sample.wps);c.in=I,c.out=b,c.totalHrs=E.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),c.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*c.totalHrs,3),s+=c.totalHrs,a+=c.totalDgoCons}return i=E.LngLatHelper.roundPrecision(i,3),s=E.LngLatHelper.roundPrecision(s,3),a=E.LngLatHelper.roundPrecision(a,3),{distanceInECA:i,hoursInECA:s,totalDgoConsInECA:a,eca:o}}static async mergeSpeeds(e,t={}){var f,d;const n={hours:[],wps:[],days:[],all:[]},o=e.reduce((m,y)=>m+y.distance,0),i=e.reduce((m,y)=>{var F;return m+(((F=y.extend)==null?void 0:F.distanceInECA)||0)},0),s=e.reduce((m,y)=>m+y.totalHrs,0),a=e.reduce((m,y)=>{var F;return m+(((F=y.extend)==null?void 0:F.hoursInECA)||0)},0),r=e.reduce((m,y)=>{var F;return m+(((F=y.extend)==null?void 0:F.totalDgoConsInECA)||0)},0),u=e.reduce((m,y)=>m+y.wxFactor*y.totalHrs/s,0),l=e.reduce((m,y)=>m+y.cFactor*y.totalHrs/s,0),h=e.reduce((m,y)=>m+y.totalFoCons,0),c=e.reduce((m,y)=>m+y.totalDgoCons,0),I=e.reduce((m,y)=>m+y.cost.total,0),b=e.reduce((m,y)=>m+y.cost.hire,0),T=e.reduce((m,y)=>m+y.cost.bunker,0),k=[],g=[];let v;for(const m of e){g.push(...((f=m.extend)==null?void 0:f.eca)||[]);const y=m.sample.hours,F=m.sample.all,M=m.sample.wps,L=m.sample.days,H=y.at(0);v&&(H.distanceFromPrevious=v.distanceFromPrevious,H.distanceFromStart=v.distanceFromStart,y.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+v.distanceFromStart)}),F.at(0).distanceFromPrevious=v.distanceFromPrevious,F.at(0).distanceFromStart=v.distanceFromStart,F.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+v.distanceFromStart)}),M.at(0).distanceFromPrevious=v.distanceFromPrevious,M.at(0).distanceFromStart=v.distanceFromStart,M.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+v.distanceFromStart)}),L.at(0).distanceFromPrevious=v.distanceFromPrevious,L.at(0).distanceFromStart=v.distanceFromStart,L.forEach((C,R)=>{R&&(C.distanceFromStart=C.distanceFromStart+v.distanceFromStart)})),H.cp=m.cost.cp;const N=[m.etd,m.eta],W=k.findIndex(C=>C.id===H.cp.id);W===-1?(H.cp.segment=[N],k.push(H.cp)):k[W].segment.push(N),y.forEach(C=>{var q;((q=n.hours)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.hours.push(C)}),F.forEach(C=>{var q;((q=n.all)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.all.push(C)}),M.forEach(C=>{var q;((q=n.wps)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.wps.push(C)}),L.forEach(C=>{var q;((q=n==null?void 0:n.days)==null?void 0:q.findIndex(z=>z.eta===C.eta))===-1&&n.days.push(C)});const B=(d=n.wps)==null?void 0:d.findIndex(C=>C.eta===H.eta);B===-1?n.wps.push(H):n.wps[B]=H,v=y.at(-1)}return n.wps.sort((m,y)=>w(m.etd).unix()-w(y.etd).unix()),n.wps.forEach((m,y)=>{const F=n.wps[y-1];if(F){const M=m.distanceFromStart-(F.distanceFromStart||0),L=w(m.eta||m.etd).diff(w(F.etd||F.eta),"hour",!0),H=Math.round(M/L*100)/100;m.avgSpd=H;const N=E.LaneHelper.calculateBearing(F,m);F.bearing=N}}),{sample:n,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(s*1e3)/1e3,avgSpeed:Math.round(o/s*1e3)/1e3,wxFactor:Math.round(u*1e3)/1e3,cFactor:Math.round(l*1e3)/1e3,totalFoCons:Math.round(h*1e3)/1e3,totalDgoCons:Math.round(c*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(T*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(i*1e3)/1e3,hoursInECA:Math.round(a*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}P.AISImpl=G,P.AlertHelper=ht,P.AlertLevel=lt,P.HifleetImpl=bt,P.LoadCondition=mt,P.MyShipImpl=gt,P.MyVesselImpl=pt,P.ShipxyImpl=vt,P.SpeedHelper=O,P.SpeedLabel=yt,P.VesselTag=ft,P.alertHelper=wt,Object.defineProperty(P,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": "3.7.9",
4
+ "version": "3.8.0",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [