@idm-plugin/vessel 3.5.4 → 3.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -133,30 +133,30 @@ class jt extends at {
133
133
  if (r.status !== 200)
134
134
  return g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
135
135
  {
136
- const d = r.data;
137
- if (d)
136
+ const c = r.data;
137
+ if (c)
138
138
  return {
139
- mmsi: d.mmsi,
140
- imo: Number.isNaN(d.imo) ? null : Number(d.imo),
141
- callSign: d.callsign,
142
- name: d.nameEn,
143
- nameCn: d.nameCn,
144
- type: d.vesselTypeNameEn,
145
- flagName: d.flagCtry,
146
- clasz: d.classSociety,
147
- dateOfBuild: d.buildYearMonth,
148
- deadweight: d.dwt,
149
- grossTonnage: d.grt,
150
- netTonnage: d.net,
151
- teu: d.teu,
152
- length: d.length,
153
- breadth: d.width,
154
- height: d.height,
155
- draught: d.draught,
156
- speed: d.speed,
157
- passengerCapacity: d.passengercapacity,
139
+ mmsi: c.mmsi,
140
+ imo: Number.isNaN(c.imo) ? null : Number(c.imo),
141
+ callSign: c.callsign,
142
+ name: c.nameEn,
143
+ nameCn: c.nameCn,
144
+ type: c.vesselTypeNameEn,
145
+ flagName: c.flagCtry,
146
+ clasz: c.classSociety,
147
+ dateOfBuild: c.buildYearMonth,
148
+ deadweight: c.dwt,
149
+ grossTonnage: c.grt,
150
+ netTonnage: c.net,
151
+ teu: c.teu,
152
+ length: c.length,
153
+ breadth: c.width,
154
+ height: c.height,
155
+ draught: c.draught,
156
+ speed: c.speed,
157
+ passengerCapacity: c.passengercapacity,
158
158
  vendor: "myvessel",
159
- raw: d
159
+ raw: c
160
160
  };
161
161
  }
162
162
  return {};
@@ -253,16 +253,16 @@ class jt extends at {
253
253
  lon: a.lng,
254
254
  lat: a.lat
255
255
  }), o != null && o.length && (u.crossMonthList = o), n != null && n.length && (u.excludeNodes = n), i != null && i.length && (u.excludeSeaAreas = i);
256
- const d = {
256
+ const c = {
257
257
  headers: {
258
258
  Authorization: `${(k = this.token) == null ? void 0 : k.tokenType} ${(b = this.token) == null ? void 0 : b.accessToken}`
259
259
  },
260
260
  json: u
261
261
  };
262
- g == null || g.info("[%s] fetch route from: %s - %j", s.requestId, l, d);
263
- const y = await B.post(l, d).json();
264
- if (y.status !== 200)
265
- return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: y.message, status: y.status, code: y.code }), {};
262
+ g == null || g.info("[%s] fetch route from: %s - %j", s.requestId, l, c);
263
+ const h = await B.post(l, c).json();
264
+ if (h.status !== 200)
265
+ return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: h.message, status: h.status, code: h.code }), {};
266
266
  {
267
267
  const I = {
268
268
  status: "Success",
@@ -273,7 +273,7 @@ class jt extends at {
273
273
  route: [],
274
274
  distance: 0,
275
275
  memo: ""
276
- }, { nodes: p, seas: v, tracks: m, specialRegions: c, ecaLength: h } = y.data;
276
+ }, { nodes: p, seas: v, tracks: f, specialRegions: d, ecaLength: m } = h.data;
277
277
  I.nodes = p == null ? void 0 : p.map((M) => ({
278
278
  code: M.nodeCode,
279
279
  nameEn: M.nameEn,
@@ -314,7 +314,7 @@ class jt extends at {
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 && I.regions.push({
319
319
  type: M.regionType,
320
320
  distance: M.regionLength,
@@ -326,20 +326,20 @@ class jt extends at {
326
326
  distance: j.length
327
327
  }))
328
328
  });
329
- }), I.waypoints = m == null ? void 0 : m.map((M) => ({
329
+ }), I.waypoints = f == null ? void 0 : f.map((M) => ({
330
330
  lat: Math.round(M.lat * 1e5) / 1e5,
331
331
  lng: Math.round(M.lon * 1e5) / 1e5
332
- })), (S = I.waypoints) != null && S.length && (I.waypoints = O.simplifyCoordinates(I.waypoints), I.route = O.divideAccordingToLng(I.waypoints), I.distance = O.calculateRouteDistance(I.route), I.distanceInECA = h);
332
+ })), (S = I.waypoints) != null && S.length && (I.waypoints = O.simplifyCoordinates(I.waypoints), I.route = O.divideAccordingToLng(I.waypoints), I.distance = O.calculateRouteDistance(I.route), I.distanceInECA = m);
333
333
  const C = w().diff(r, "second");
334
334
  return I.memo = `time cost: ${C}s`, g.info("[%s] calculate route cost: %d seconds", s.requestId, C), I;
335
335
  }
336
336
  }
337
337
  async trajectory(t, a, o, n, i = !0, s = {}) {
338
338
  await this.checkToken(s);
339
- const r = await this.realTimePosition(t, s), l = w(a), u = w(o), d = [];
339
+ const r = await this.realTimePosition(t, s), l = w(a), u = w(o), c = [];
340
340
  for (; u.diff(l, "day", !0) > 30; )
341
- await this.trajectoryIn30Day(t, l, l.clone().add(30, "day"), r, n, d, s), l.add(30, "day");
342
- return await this.trajectoryIn30Day(t, l, u, r, n, d, s), d;
341
+ await this.trajectoryIn30Day(t, l, l.clone().add(30, "day"), r, n, c, s), l.add(30, "day");
342
+ return await this.trajectoryIn30Day(t, l, u, r, n, c, s), c;
343
343
  }
344
344
  async trajectoryIn30Day(t, a, o, n, i, s, r = {}) {
345
345
  var b, S, I, p, v;
@@ -354,34 +354,34 @@ class jt extends at {
354
354
  }
355
355
  };
356
356
  g == null || g.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
357
- const d = await B.post(l, u).json();
358
- if (d.code)
359
- return g == null || g.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: d.message, status: d.status, code: d.code }), d;
360
- let y = -1;
361
- const k = w(`${(p = (I = d.data) == null ? void 0 : I[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
362
- return (v = d.data) == null || v.forEach((m) => {
363
- for (const P in m)
364
- !isNaN(m[P]) && Number(m[P]) !== 1 / 0 && (m[P] = Number(m[P]));
365
- const c = w(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), h = m.status, { labelCn: f, labelEn: C } = this.parseStatus(h), M = {
366
- mmsi: m.mmsi,
357
+ const c = await B.post(l, u).json();
358
+ if (c.code)
359
+ return g == null || g.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: c.message, status: c.status, code: c.code }), c;
360
+ let h = -1;
361
+ const k = w(`${(p = (I = c.data) == null ? void 0 : I[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
362
+ return (v = c.data) == null || v.forEach((f) => {
363
+ for (const P in f)
364
+ !isNaN(f[P]) && Number(f[P]) !== 1 / 0 && (f[P] = Number(f[P]));
365
+ const d = w(`${f.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), m = f.status, { labelCn: y, labelEn: C } = this.parseStatus(m), M = {
366
+ mmsi: f.mmsi,
367
367
  imo: n == null ? void 0 : n.imo,
368
- lat: m.lat,
369
- lng: m.lon,
370
- sog: m.sog,
371
- cog: m.cog,
372
- hdg: m.hdg,
373
- draught: m.draught,
374
- status: h,
375
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta) ? w(`${m.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").utc().format() : void 0,
376
- destination: m.dest,
377
- positionTime: c.unix(),
378
- labelCn: f,
368
+ lat: f.lat,
369
+ lng: f.lon,
370
+ sog: f.sog,
371
+ cog: f.cog,
372
+ hdg: f.hdg,
373
+ draught: f.draught,
374
+ status: m,
375
+ 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,
376
+ destination: f.dest,
377
+ positionTime: d.unix(),
378
+ labelCn: y,
379
379
  labelEn: C,
380
380
  method: "trajectory",
381
381
  vendor: "myVessel",
382
- utc: c.utc().format()
383
- }, j = Math.floor(c.diff(k, "minute", !0) / (i || 1));
384
- j !== y && (y = j, s.push(M));
382
+ utc: d.utc().format()
383
+ }, j = Math.floor(d.diff(k, "minute", !0) / (i || 1));
384
+ j !== h && (h = j, s.push(M));
385
385
  }), s;
386
386
  }
387
387
  }
@@ -405,7 +405,7 @@ class Ft extends at {
405
405
  for (const k in s)
406
406
  !isNaN(s[k]) && Number(s[k]) !== 1 / 0 && (s[k] = Number(s[k]));
407
407
  s.status = s.sp > 3 ? 0 : 1;
408
- const r = s.status, { labelCn: l, labelEn: u } = this.parseStatus(r), d = w(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
408
+ const r = s.status, { labelCn: l, labelEn: u } = this.parseStatus(r), c = w(`${s.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
409
409
  return {
410
410
  mmsi: s.m,
411
411
  name: s.n,
@@ -426,8 +426,8 @@ class Ft extends at {
426
426
  dwt: s.dwt,
427
427
  build: s.buildyear,
428
428
  flag: s.fn,
429
- positionTime: d.unix(),
430
- utc: d.utc().format(),
429
+ positionTime: c.unix(),
430
+ utc: c.utc().format(),
431
431
  status: r,
432
432
  labelCn: l,
433
433
  labelEn: u,
@@ -487,46 +487,46 @@ class Ft extends at {
487
487
  return s.sort((r, l) => l.score - r.score), s;
488
488
  }
489
489
  async trajectory(t, a, o, n, i = !0, s = {}) {
490
- var m, c, h;
490
+ var f, d, m;
491
491
  const r = await this.realTimePosition(t, s);
492
492
  let l = w(a);
493
- const u = w(o), d = w();
493
+ const u = w(o), c = w();
494
494
  if (i) {
495
- let f = u.diff(l, "d", !0);
496
- f < 0 ? l = u.clone().subtract(40, "d") : f < 30 ? l.subtract(10, "d") : f < 60 ? l.subtract(5, "d") : l = u.clone().subtract(80, "d"), f = d.diff(u, "d", !0), u.add(f > 10 ? 240 : f * 24, "h");
495
+ let y = u.diff(l, "d", !0);
496
+ y < 0 ? l = u.clone().subtract(40, "d") : y < 30 ? l.subtract(10, "d") : y < 60 ? l.subtract(5, "d") : l = u.clone().subtract(80, "d"), y = c.diff(u, "d", !0), u.add(y > 10 ? 240 : y * 24, "h");
497
497
  }
498
- const y = {
498
+ const h = {
499
499
  searchParams: {
500
500
  endtime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
501
501
  starttime: l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
502
502
  mmsi: t,
503
503
  usertoken: this.token
504
504
  }
505
- }, k = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(k, y).json();
506
- g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, k, y);
505
+ }, k = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(k, h).json();
506
+ g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, k, h);
507
507
  let S;
508
- b && (S = ((c = (m = b.ships) == null ? void 0 : m.offors) == null ? void 0 : c.ship) || [], S.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
508
+ b && (S = ((d = (f = b.ships) == null ? void 0 : f.offors) == null ? void 0 : d.ship) || [], S.length || g == null || g.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
509
509
  const I = [];
510
510
  let p = -1;
511
- const v = w(`${(h = S == null ? void 0 : S[0]) == null ? void 0 : h.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
512
- for (const f of S) {
513
- for (const H in f)
514
- !isNaN(f[H]) && Number(f[H]) !== 1 / 0 && (f[H] = Number(f[H]));
515
- const C = w(`${f.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
516
- f.status = f.sp > 4 ? 0 : 1;
517
- const { labelEn: M, labelCn: j } = this.parseStatus(f.status), P = {
518
- mmsi: f.m,
519
- name: f.n,
511
+ const v = w(`${(m = S == null ? void 0 : S[0]) == null ? void 0 : m.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
512
+ for (const y of S) {
513
+ for (const H in y)
514
+ !isNaN(y[H]) && Number(y[H]) !== 1 / 0 && (y[H] = Number(y[H]));
515
+ const C = w(`${y.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
516
+ y.status = y.sp > 4 ? 0 : 1;
517
+ const { labelEn: M, labelCn: j } = this.parseStatus(y.status), P = {
518
+ mmsi: y.m,
519
+ name: y.n,
520
520
  imo: r == null ? void 0 : r.imo,
521
- lat: f.la,
522
- lng: f.lo,
523
- draught: f.draught,
524
- sog: f.sp,
525
- cog: f.co,
526
- hdg: f.hdg,
521
+ lat: y.la,
522
+ lng: y.lo,
523
+ draught: y.draught,
524
+ sog: y.sp,
525
+ cog: y.co,
526
+ hdg: y.hdg,
527
527
  positionTime: C.unix(),
528
528
  utc: C.utc().format(),
529
- status: f.status,
529
+ status: y.status,
530
530
  labelCn: j,
531
531
  labelEn: M,
532
532
  method: "trajectory",
@@ -554,8 +554,8 @@ class Nt extends at {
554
554
  if (g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o), (i == null ? void 0 : i.status) !== 0)
555
555
  return i;
556
556
  const s = i.data[0];
557
- for (const y in s)
558
- !isNaN(s[y]) && Number(s[y]) !== 1 / 0 && (s[y] = Number(s[y]));
557
+ for (const h in s)
558
+ !isNaN(s[h]) && Number(s[h]) !== 1 / 0 && (s[h] = Number(s[h]));
559
559
  const { labelCn: r, labelEn: l } = await this.parseStatus(s.navistat), u = w.unix(s.lasttime);
560
560
  return {
561
561
  mmsi: s.ShipID,
@@ -582,7 +582,7 @@ class Nt extends at {
582
582
  }
583
583
  async trajectory(t, a, o, n, i = !0, s = {}) {
584
584
  var v;
585
- const r = await this.realTimePosition(t, s), l = w(a), u = w(o), d = "https://api.shipxy.com/apicall/GetShipTrack", y = {
585
+ const r = await this.realTimePosition(t, s), l = w(a), u = w(o), c = "https://api.shipxy.com/apicall/GetShipTrack", h = {
586
586
  searchParams: {
587
587
  id: t,
588
588
  k: this.token,
@@ -591,25 +591,25 @@ class Nt extends at {
591
591
  btm: l.unix(),
592
592
  etm: u.unix()
593
593
  }
594
- }, k = await B.get(d, y).json();
595
- if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, d, y), (k == null ? void 0 : k.status) !== 0)
594
+ }, k = await B.get(c, h).json();
595
+ if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, c, h), (k == null ? void 0 : k.status) !== 0)
596
596
  return k;
597
597
  const b = k == null ? void 0 : k.points, S = [], I = w.unix((v = b[0]) == null ? void 0 : v.utc);
598
598
  let p = -1;
599
- for (const m of b) {
600
- const c = w.unix(m.utc), h = {
599
+ for (const f of b) {
600
+ const d = w.unix(f.utc), m = {
601
601
  imo: r == null ? void 0 : r.imo,
602
602
  mmsi: t,
603
- sog: Math.round(m.sog * 3600 / 1e3 / 1852 * 100) / 100,
604
- cog: Math.round(m.cog / 100 * 100) / 100,
605
- lat: Math.round(m.lat / 1e6 * 1e5) / 1e5,
606
- lng: Math.round(m.lon / 1e6 * 1e5) / 1e5,
607
- positionTime: c.unix(),
608
- utc: c.utc().format(),
603
+ sog: Math.round(f.sog * 3600 / 1e3 / 1852 * 100) / 100,
604
+ cog: Math.round(f.cog / 100 * 100) / 100,
605
+ lat: Math.round(f.lat / 1e6 * 1e5) / 1e5,
606
+ lng: Math.round(f.lon / 1e6 * 1e5) / 1e5,
607
+ positionTime: d.unix(),
608
+ utc: d.utc().format(),
609
609
  method: "trajectory",
610
610
  vendor: "shipxy"
611
- }, f = Math.floor(c.diff(I, "minute", !0) / (n || 1));
612
- f !== p && (p = f, S.push(h));
611
+ }, y = Math.floor(d.diff(I, "minute", !0) / (n || 1));
612
+ y !== p && (p = y, S.push(m));
613
613
  }
614
614
  return S;
615
615
  }
@@ -667,7 +667,7 @@ class xt extends at {
667
667
  const l = r.data[0];
668
668
  for (const b in l)
669
669
  !isNaN(l[b]) && Number(l[b]) !== 1 / 0 && (l[b] = Number(l[b]));
670
- const { labelCn: u, labelEn: d } = await this.parseStatus(l.aisNavStatus), y = w.unix(l.posTime);
670
+ const { labelCn: u, labelEn: c } = await this.parseStatus(l.aisNavStatus), h = w.unix(l.posTime);
671
671
  return {
672
672
  ...n,
673
673
  mmsi: t,
@@ -678,19 +678,19 @@ class xt extends at {
678
678
  hdg: Math.round(l.heading * 100) / 100,
679
679
  rot: Math.round(l.rot * 100) / 100,
680
680
  positionTime: l.posTime,
681
- utc: y.utc().format(),
681
+ utc: h.utc().format(),
682
682
  status: l.aisNavStatus,
683
- labelEn: d,
683
+ labelEn: c,
684
684
  labelCn: u,
685
685
  method: "position",
686
686
  vendor: "myship"
687
687
  };
688
688
  }
689
689
  async trajectory(t, a, o, n, i = !0, s = {}) {
690
- const r = w(a), l = w(o), u = await this.getShipId(t), d = await this.getShipInfo(u), y = [];
690
+ const r = w(a), l = w(o), u = await this.getShipId(t), c = await this.getShipInfo(u), h = [];
691
691
  for (; l.diff(r, "day", !0) > 30; )
692
- await this.trajectoryIn30Day(u, r.unix(), r.add(30, "day").unix(), d, t, n, y);
693
- return await this.trajectoryIn30Day(u, r.unix(), l.unix(), d, t, n, y), y;
692
+ await this.trajectoryIn30Day(u, r.unix(), r.add(30, "day").unix(), c, t, n, h);
693
+ return await this.trajectoryIn30Day(u, r.unix(), l.unix(), c, t, n, h), h;
694
694
  }
695
695
  async trajectoryIn30Day(t, a, o, n, i, s, r, l = {}) {
696
696
  var I;
@@ -703,16 +703,16 @@ class xt extends at {
703
703
  startTime: a,
704
704
  endTime: o
705
705
  }
706
- }, d = "https://api3.myships.com/sp/ships/position/history", y = await B.post(d, u).json();
707
- if (g == null || g.info("[%s] fetch trajectory from: %s - %j", l.requestId, d, u), y.code !== "0")
708
- return g == null || g.warn("[%s] invoke myship trajectory failed: %j", l.requestId, y), y;
709
- const k = y.data;
706
+ }, c = "https://api3.myships.com/sp/ships/position/history", h = await B.post(c, u).json();
707
+ if (g == null || g.info("[%s] fetch trajectory from: %s - %j", l.requestId, c, u), h.code !== "0")
708
+ return g == null || g.warn("[%s] invoke myship trajectory failed: %j", l.requestId, h), h;
709
+ const k = h.data;
710
710
  for (const p in k)
711
711
  !isNaN(k[p]) && Number(k[p]) !== 1 / 0 && (k[p] = Number(k[p]));
712
712
  const b = w.unix((I = k[0]) == null ? void 0 : I.posTime);
713
713
  let S = -1;
714
714
  for (const p of k) {
715
- const v = w.unix(p.posTime), m = {
715
+ const v = w.unix(p.posTime), f = {
716
716
  imo: n == null ? void 0 : n.imo,
717
717
  mmsi: i,
718
718
  lat: Math.round(p.lat / 1e4 / 60 * 1e5) / 1e5,
@@ -725,8 +725,8 @@ class xt extends at {
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 !== S && (S = c, r.push(m));
728
+ }, d = Math.floor(v.diff(b, "minute", !0) / (s || 1));
729
+ d !== S && (S = d, r.push(f));
730
730
  }
731
731
  return r;
732
732
  }
@@ -755,12 +755,12 @@ class Mt {
755
755
  return;
756
756
  const i = {};
757
757
  for (let u = 0; u < (n == null ? void 0 : n.length); u++) {
758
- const d = (l = (r = n[u].match(a)) == null ? void 0 : r[0]) == null ? void 0 : l.split("],");
759
- if (u === 0 && !d)
758
+ const c = (l = (r = n[u].match(a)) == null ? void 0 : r[0]) == null ? void 0 : l.split("],");
759
+ if (u === 0 && !c)
760
760
  i.scope = n[0];
761
- else if (d)
762
- for (let y = 0, k = d.length; y < k; y++) {
763
- const b = this.parseRule(d[y]);
761
+ else if (c)
762
+ for (let h = 0, k = c.length; h < k; h++) {
763
+ const b = this.parseRule(c[h]);
764
764
  b && (i[b.level] ? b.key ? i[b.level][b == null ? void 0 : b.key] = b : i[b.level] = b : b.key ? i[b.level] = { [b == null ? void 0 : b.key]: b } : i[b.level] = b);
765
765
  }
766
766
  }
@@ -794,14 +794,14 @@ class Mt {
794
794
  * @param options
795
795
  */
796
796
  checkWeather(e, t, a = {}) {
797
- var b, S, I, p, v, m, c, h, f, C, M, j, P, D, H;
797
+ var b, S, I, p, v, f, d, m, y, C, M, j, P, D, H;
798
798
  let o = 0, n = 0, i = 0, s = 0;
799
- const r = Math.round(((S = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : S.number) * 1.6 * 100) / 100, l = (p = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : p.number, u = (m = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : m.number, d = Math.round((((h = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : h.number) + 2) * 100) / 100, y = (C = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.wind) == null ? void 0 : C.number, k = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
799
+ const r = Math.round(((S = (b = t == null ? void 0 : t.SEVERE) == null ? void 0 : b.sigWave) == null ? void 0 : S.number) * 1.6 * 100) / 100, l = (p = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : p.number, u = (f = (v = t == null ? void 0 : t.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : f.number, c = Math.round((((m = (d = t == null ? void 0 : t.SEVERE) == null ? void 0 : d.wind) == null ? void 0 : m.number) + 2) * 100) / 100, h = (C = (y = t == null ? void 0 : t.SEVERE) == null ? void 0 : y.wind) == null ? void 0 : C.number, k = (j = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.wind) == null ? void 0 : j.number;
800
800
  for (let F = 0; F < (e == null ? void 0 : e.length); F++) {
801
801
  const N = e[F], R = (D = (P = N == null ? void 0 : N.meteo) == null ? void 0 : P.wave) == null ? void 0 : D.sig, W = (H = N == null ? void 0 : N.meteo) == null ? void 0 : H.wind, K = F ? w(N.eta).diff(w(e[F - 1].eta), "hour", !0) : 0;
802
- s = K > s ? K : s, J == null || J.debug("[%s] check sig.wave: %j", a.requestId, { ...R, dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u }), (R == null ? void 0 : R.height) >= r ? N.isDangerous = !0 : (R == null ? void 0 : R.height) >= l ? N.isSevere = !0 : (R == null ? void 0 : R.height) >= u && (N.isHeavy = !0), J == null || J.debug("[%s] check wind: %j", a.requestId, { ...W, dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: k }), (W == null ? void 0 : W.scale) >= d ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (W == null ? void 0 : W.scale) > y ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (W == null ? void 0 : W.scale) === k && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), o += N.isDangerous ? K : 0, n += N.isSevere ? K : 0, i += N.isHeavy ? K : 0;
802
+ s = K > s ? K : s, J == null || J.debug("[%s] check sig.wave: %j", a.requestId, { ...R, dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u }), (R == null ? void 0 : R.height) >= r ? N.isDangerous = !0 : (R == null ? void 0 : R.height) >= l ? N.isSevere = !0 : (R == null ? void 0 : R.height) >= u && (N.isHeavy = !0), J == null || J.debug("[%s] check wind: %j", a.requestId, { ...W, dgThd4Wd: c, svThd4Wd: h, hvThd4Wd: k }), (W == null ? void 0 : W.scale) >= c ? (N.isDangerous = !0, delete N.isSevere, delete N.isHeavy) : (W == null ? void 0 : W.scale) > h ? (N.isDangerous || (N.isSevere = !0), delete N.isHeavy) : (W == null ? void 0 : W.scale) === k && !N.isDangerous && !N.isSevere && (N.isHeavy = !0), o += N.isDangerous ? K : 0, n += N.isSevere ? K : 0, i += N.isHeavy ? K : 0;
803
803
  }
804
- return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, i = Math.round(i * 100) / 100, s = Math.round(s), { sample: e, dangerous: o, severe: n, heavy: i, step: s < 3 ? 3 : s, wind: { dgThd4Wd: d, svThd4Wd: y, hvThd4Wd: k }, sig: { dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u } };
804
+ return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, i = Math.round(i * 100) / 100, s = Math.round(s), { sample: e, dangerous: o, severe: n, heavy: i, step: s < 3 ? 3 : s, wind: { dgThd4Wd: c, svThd4Wd: h, hvThd4Wd: k }, sig: { dgThd4Wv: r, svThd4Wv: l, hvThd4Wv: u } };
805
805
  }
806
806
  }
807
807
  const Dt = new Mt();
@@ -926,8 +926,8 @@ class Y {
926
926
  * @private
927
927
  */
928
928
  static assembleProperties(e, t, a, o) {
929
- var y;
930
- const n = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, i = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, l = ((y = e == null ? void 0 : e.type) == null ? void 0 : y.toLowerCase()) || "common";
929
+ var h;
930
+ const n = e.lbp ?? e.length ?? e.lengthOverall ?? 198.9642, i = e.draught ?? 8, s = e.breadthMoulded ?? e.breadth ?? e.breadthExtreme ?? 32.4572, r = e.deadweight ?? 67035.7773, l = ((h = e == null ? void 0 : e.type) == null ? void 0 : h.toLowerCase()) || "common";
931
931
  return {
932
932
  tag: l.indexOf("container") > -1 ? "container" : l.indexOf("tugs") > -1 ? "tugs" : "common",
933
933
  lbp: n,
@@ -959,23 +959,34 @@ class Y {
959
959
  let u;
960
960
  try {
961
961
  o = (o == null ? void 0 : o.toUpperCase()) === "CMEMS" ? "ECMWF" : o, o = (o == null ? void 0 : o.toUpperCase()) === "METEO2" ? "best_match" : o;
962
- const { weatherModels: b, marineModels: S } = await ct.autoPickMeteoModel(o), I = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
962
+ const { weatherModels: S, marineModels: I } = await ct.autoPickMeteoModel(o), p = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
963
963
  ...r,
964
964
  pastDays: 1,
965
965
  forecastDays: 1,
966
- weatherModels: b,
967
- marineModels: S
968
- }), [p] = ct.pickHourly(I, a);
969
- u = ct.toLegacy(p);
970
- } catch (b) {
971
- E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, b);
966
+ weatherModels: S,
967
+ marineModels: I
968
+ }), [v] = ct.pickHourly(p, a);
969
+ u = ct.toLegacy(v);
970
+ } catch (S) {
971
+ E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, S);
972
972
  }
973
- const d = Y.currentFactor(e.bearing, u == null ? void 0 : u.current, n), y = Y.weatherFactor(e, u, d), k = Math.round((e.speed * 1.943844 + y + d) * 100) / 100;
973
+ let c = Y.currentFactor(e.bearing, u == null ? void 0 : u.current, n), h = Y.weatherFactor(e, u, c);
974
+ const k = e.speed * 1.943844;
975
+ for (; k + c + h <= 0; )
976
+ E.warn(
977
+ "[%s] v0(%.2d) is less then factor(%.2d) = wxFactor(%.2d) + cFactor(%.2d), scale factor with 0.6",
978
+ r.requestId,
979
+ k,
980
+ h + c,
981
+ h,
982
+ c
983
+ ), c = c * 0.6, h = h * 0.6;
984
+ const b = Math.round((k + c + h) * 100) / 100;
974
985
  l = {
975
986
  meteo: { ...u },
976
- wxFactor: y,
977
- cFactor: d,
978
- speed: t.velocity && s ? t.velocity : k < 0 ? 1 : k,
987
+ wxFactor: h,
988
+ cFactor: c,
989
+ speed: t.velocity && s ? t.velocity : b < 0 ? 1 : b,
979
990
  eta: a.utc().format(),
980
991
  etd: a.utc().format()
981
992
  };
@@ -1005,51 +1016,51 @@ class Y {
1005
1016
  */
1006
1017
  static async speedLoseInHoursStep(e, t, a, o, n, i, s = "", r = !0, l = !1, u = {}) {
1007
1018
  t.utc();
1008
- const d = t.clone().add(14, "days"), y = [], k = [], b = [];
1019
+ const c = t.clone().add(14, "days"), h = [], k = [], b = [];
1009
1020
  let S = 0, I = 0, p, v;
1010
- for (let m = 0; m < i.length - 1; m++) {
1011
- let c = i[m];
1012
- c.distanceFromStart = Math.round((n + I) * 1e3) / 1e3;
1013
- const h = i[m + 1];
1014
- if (e.bearing = O.calculateBearing(c, h, !h.gcToPrevious), c.bearing = e.bearing, c.suspend && l) {
1015
- c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
1016
- const M = c.suspend - c.elapsed;
1021
+ for (let f = 0; f < i.length - 1; f++) {
1022
+ let d = i[f];
1023
+ d.distanceFromStart = Math.round((n + I) * 1e3) / 1e3;
1024
+ const m = i[f + 1];
1025
+ if (e.bearing = O.calculateBearing(d, m, !m.gcToPrevious), d.bearing = e.bearing, d.suspend && l) {
1026
+ d.eta = d.eta || t.utc().format(), d.elapsed = d.elapsed ?? 0;
1027
+ const M = d.suspend - d.elapsed;
1017
1028
  if (o - S > M)
1018
- o = o - S - M, t.add(M, "hour"), c.elapsed = c.suspend;
1029
+ o = o - S - M, t.add(M, "hour"), d.elapsed = d.suspend;
1019
1030
  else {
1020
1031
  const j = o - S;
1021
- c.elapsed += j, t.add(j, "hour"), o = 0;
1032
+ d.elapsed += j, t.add(j, "hour"), o = 0;
1022
1033
  }
1023
- if (E == null || E.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, c), o === 0)
1024
- return c.distanceFromPrevious = I, { etd: t, from: v || c, to: c, next: i.filter((j) => j), wps: y, days: k, all: b };
1034
+ if (E == null || E.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, d), o === 0)
1035
+ return d.distanceFromPrevious = I, { etd: t, from: v || d, to: d, next: i.filter((j) => j), wps: h, days: k, all: b };
1025
1036
  } else
1026
- c.suspend = 0;
1027
- r = t.isAfter(d) ? !1 : r, c = await Y.speedLoseAt(e, c, t, s, 0, r, l, u), b.push(c), v = v || c, c.important && y.push(c), t.isSameOrAfter(a) && (k.push(c), a.add(24, "hour"));
1028
- const f = O.calculateDistance(c, h, !h.gcToPrevious);
1029
- let C = Math.round(f / v.speed * 1e5) / 1e5;
1037
+ d.suspend = 0;
1038
+ r = t.isAfter(c) ? !1 : r, d = await Y.speedLoseAt(e, d, t, s, 0, r, l, u), b.push(d), v = v || d, d.important && h.push(d), t.isSameOrAfter(a) && (k.push(d), a.add(24, "hour"));
1039
+ const y = O.calculateDistance(d, m, !m.gcToPrevious);
1040
+ let C = Math.round(y / v.speed * 1e5) / 1e5;
1030
1041
  if (S + C < o) {
1031
- if (S += C, t.add(C, "hour"), delete i[m], E == null || E.debug(
1032
- `[%s] go to %j from %j with ${f}nm, and cost ${C} hours`,
1042
+ if (S += C, t.add(C, "hour"), delete i[f], E == null || E.debug(
1043
+ `[%s] go to %j from %j with ${y}nm, and cost ${C} hours`,
1033
1044
  u.requestId,
1034
- { lat: h.lat, lng: h.lng },
1045
+ { lat: m.lat, lng: m.lng },
1035
1046
  { lat: v.lat, lng: v.lng, etd: v.etd }
1036
- ), I += f, i.filter((M) => M).length <= 1) {
1037
- p = h, p.eta = t.utc().format(), p.distanceFromPrevious = f, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4, y.push(p), b.push(p), delete i[m + 1];
1047
+ ), I += y, i.filter((M) => M).length <= 1) {
1048
+ p = m, p.eta = t.utc().format(), p.distanceFromPrevious = y, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4, h.push(p), b.push(p), delete i[f + 1];
1038
1049
  break;
1039
1050
  }
1040
1051
  } else {
1041
1052
  C = o - S, t.add(C, "hour");
1042
1053
  const M = z.roundPrecision(v.speed * C, 5);
1043
- p = O.calculateCoordinate(c, e.bearing, M, "nauticalmiles", !h.gcToPrevious), p.eta = t.utc().format(), i[m] = p, E == null || E.debug(
1054
+ p = O.calculateCoordinate(d, e.bearing, M, "nauticalmiles", !m.gcToPrevious), p.eta = t.utc().format(), i[f] = p, E == null || E.debug(
1044
1055
  `[%s] go to %j from %j with ${M}nm, and cost ${C} hours`,
1045
1056
  u.requestId,
1046
1057
  { lat: p.lat, lng: p.lng },
1047
- { lat: c.lat, lng: c.lng, etd: c.etd }
1058
+ { lat: d.lat, lng: d.lng, etd: d.etd }
1048
1059
  ), I += M, p.distanceFromPrevious = Math.round(I * 1e4) / 1e4, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4;
1049
1060
  break;
1050
1061
  }
1051
1062
  }
1052
- return { etd: t, from: v, to: p, next: i.filter((m) => m), wps: y, days: k, all: b };
1063
+ return { etd: t, from: v, to: p, next: i.filter((f) => f), wps: h, days: k, all: b };
1053
1064
  }
1054
1065
  /**
1055
1066
  * 洋流影响因子
@@ -1071,15 +1082,15 @@ class Y {
1071
1082
  * @param cFactor 洋流因子
1072
1083
  */
1073
1084
  static weatherFactor(e, t, a = 0) {
1074
- var k, b, S, I, p, v, m;
1085
+ var k, b, S, I, p, v, f;
1075
1086
  E == null || E.debug("calculate weather factor via: %j", { ...e, ...t });
1076
1087
  const o = Y.blockCoefficient(e.displacement, e.lbp, e.breadthMoulded, e.draught), n = z.roundPrecision(a * 1852 / 3600, 6), i = Y.froudeNumber(e.speed - n, e.lbp), s = Y.amendFactor(o, i, e.loadCondition);
1077
1088
  let r = O.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
1078
1089
  const l = Y.directionFactor(r, (b = t == null ? void 0 : t.wind) == null ? void 0 : b.scale), u = Y.vesselTagFactor(e.displacement, e.loadCondition, e.tag, (S = t == null ? void 0 : t.wind) == null ? void 0 : S.kts);
1079
- let d = l * s * u / 100 * (e.speed - n);
1080
- d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), E == null || E.debug("wind wx factor = %d", d), r = O.includedAngle(e.bearing, (p = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : p.degree);
1081
- const y = Y.waveHeightFactor(((m = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : m.height) ?? 1, r);
1082
- return E == null || E.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, E == null || E.debug("weather factor = %d", d), d = Math.abs(d) > 3 ? 3 * (Math.abs(d) / d) + Math.abs(d) / d * (Math.abs(d) - 2) * 0.1 : d, Math.round((d || 0) * 100) / 100;
1090
+ let c = l * s * u / 100 * (e.speed - n);
1091
+ c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(c) > 1 && (c = c / (Math.abs(Math.round(c)) + 1)), E == null || E.debug("wind wx factor = %d", c), r = O.includedAngle(e.bearing, (p = (I = t == null ? void 0 : t.wave) == null ? void 0 : I.sig) == null ? void 0 : p.degree);
1092
+ const h = Y.waveHeightFactor(((f = (v = t == null ? void 0 : t.wave) == null ? void 0 : v.sig) == null ? void 0 : f.height) ?? 1, r);
1093
+ return E == null || E.debug("wave wx factor = %d", h), c = Math.abs(c) > Math.abs(h) ? c : c * 0.3 + h * 0.7, E == null || E.debug("weather factor = %d", c), c = Math.abs(c) > 3 ? 3 * (Math.abs(c) / c) + Math.abs(c) / c * (Math.abs(c) - 2) * 0.1 : c, Math.round((c || 0) * 100) / 100;
1083
1094
  }
1084
1095
  /**
1085
1096
  * 以12小时级别去掉重复的days
@@ -1112,9 +1123,9 @@ class Y {
1112
1123
  */
1113
1124
  static async analyseInstant(e, t, a, o, n, i = "", s = 0, r = !0, l = !1, u = {}) {
1114
1125
  var _, G, X, Q, Z, $;
1115
- const d = w().valueOf();
1126
+ const c = w().valueOf();
1116
1127
  e.lng = z.convertToStdLng(e.lng);
1117
- const { route: y, waypoints: k } = n.points, b = O.calculateSubRoute(e, y);
1128
+ const { route: h, waypoints: k } = n.points, b = O.calculateSubRoute(e, h);
1118
1129
  if (((_ = b[0]) == null ? void 0 : _.length) <= 1)
1119
1130
  return;
1120
1131
  const { v0: S, label: I } = e.sog ? {
@@ -1127,67 +1138,67 @@ class Y {
1127
1138
  /* Cp */
1128
1139
  }, p = Y.assembleProperties(a, o.loadCondition, S, 0), v = k.length ? O.calculateSubWaypoints(e, k) : [];
1129
1140
  v.forEach((A) => A.important = !0);
1130
- const m = {
1141
+ const f = {
1131
1142
  from: { ...e },
1132
1143
  route: b,
1133
1144
  waypoints: v,
1134
1145
  v0: S,
1135
1146
  label: I
1136
- }, c = {
1147
+ }, d = {
1137
1148
  hours: [],
1138
1149
  days: [],
1139
1150
  wps: [],
1140
1151
  all: []
1141
1152
  };
1142
1153
  s || (O.calculateRouteDistance(b) / o.speed <= 72 ? s = 3 : s = 6);
1143
- let h = O.simplifyRouteToCoordinates(b, v, 0), f = 0, C = 0, M = 0, j = 0;
1154
+ let m = O.simplifyRouteToCoordinates(b, v, 0), y = 0, C = 0, M = 0, j = 0;
1144
1155
  t = w(t).utc();
1145
1156
  const P = t.clone();
1146
- for (; h.length > 0; ) {
1157
+ for (; m.length > 0; ) {
1147
1158
  const A = s - t.hour() % s, V = Math.ceil(t.clone().add(A, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, T = await Y.speedLoseInHoursStep(
1148
1159
  p,
1149
1160
  t,
1150
1161
  P,
1151
1162
  V,
1152
- f,
1153
- h,
1163
+ y,
1164
+ m,
1154
1165
  i,
1155
1166
  r,
1156
1167
  l,
1157
1168
  u
1158
1169
  );
1159
- 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)), h = T == null ? void 0 : T.next, !h.length) {
1170
+ 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)), m = T == null ? void 0 : T.next, !m.length) {
1160
1171
  const L = await Y.speedLoseAt(p, T.to, w(T.to.eta), i, 0, r, l, u);
1161
- L.bearing = p.bearing, c.hours.push(L), c.all.push(L);
1172
+ L.bearing = p.bearing, d.hours.push(L), d.all.push(L);
1162
1173
  }
1163
- f += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1174
+ y += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1164
1175
  }
1165
- const D = c.hours;
1176
+ const D = d.hours;
1166
1177
  for (let A = 0; A < D.length - 1; A++) {
1167
1178
  const V = w(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
1168
1179
  C += (D[A].wxFactor || 0) * V, M += (D[A].cFactor || 0) * V, j += V;
1169
1180
  }
1170
1181
  const H = D.reduce((A, V) => A + (V.suspend || 0), 0);
1171
- (Q = c.wps) == null || Q.forEach((A, V) => {
1182
+ (Q = d.wps) == null || Q.forEach((A, V) => {
1172
1183
  A.positionTime = w.utc(A.etd || A.eta).unix();
1173
- const T = c.wps[V - 1];
1184
+ const T = d.wps[V - 1];
1174
1185
  if (T) {
1175
1186
  const L = A.distanceFromStart - T.distanceFromStart, q = w(A.eta || A.etd).diff(w(T.etd || T.eta), "h", !0);
1176
1187
  A.avgSpd = Math.round(L / q * 100) / 100, T.bearing = O.calculateBearing(T, A);
1177
1188
  }
1178
- }), c.wps = await Y.reduceWPS(c.wps), c.days = await Y.reduceDays(c.days), c.all = (Z = c.all) == null ? void 0 : Z.reduce((A, V) => (V.positionTime = w.utc(V.etd || V.eta).unix(), A.some((T) => Math.round(T.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), m.sample = c;
1179
- const F = c.hours.at(0), N = c.hours.at(-1);
1180
- m.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, m.etd = w(F.eta).utc().format(), m.eta = w(N.eta).utc().format(), m.wxFactor = Math.round(C / j * 1e3) / 1e3, m.cFactor = Math.round(M / j * 1e3) / 1e3, m.avgSpeed = Math.round(N.distanceFromStart / j * 1e3) / 1e3, m.totalHrs = Math.round(j * 1e3) / 1e3, m.suspend = Math.round(H * 1e3) / 1e3;
1181
- const R = z.roundPrecision(o.dgo / 24 * H, 3), { distanceInECA: W, hoursInECA: K, totalDgoConsInECA: nt, eca: tt } = await this.calculateECA(m, o, u), et = z.roundPrecision(o.fo / 24 * (j - K), 3), ot = z.roundPrecision(o.dgo / 24 * j + R, 3);
1182
- m.extend = {
1189
+ }), d.wps = await Y.reduceWPS(d.wps), d.days = await Y.reduceDays(d.days), d.all = (Z = d.all) == null ? void 0 : Z.reduce((A, V) => (V.positionTime = w.utc(V.etd || V.eta).unix(), A.some((T) => Math.round(T.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), f.sample = d;
1190
+ const F = d.hours.at(0), N = d.hours.at(-1);
1191
+ f.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, f.etd = w(F.eta).utc().format(), f.eta = w(N.eta).utc().format(), f.wxFactor = Math.round(C / j * 1e3) / 1e3, f.cFactor = Math.round(M / j * 1e3) / 1e3, f.avgSpeed = Math.round(N.distanceFromStart / j * 1e3) / 1e3, f.totalHrs = Math.round(j * 1e3) / 1e3, f.suspend = Math.round(H * 1e3) / 1e3;
1192
+ const R = z.roundPrecision(o.dgo / 24 * H, 3), { distanceInECA: W, hoursInECA: K, totalDgoConsInECA: nt, eca: tt } = await this.calculateECA(f, o, u), et = z.roundPrecision(o.fo / 24 * (j - K), 3), ot = z.roundPrecision(o.dgo / 24 * j + R, 3);
1193
+ f.extend = {
1183
1194
  eca: tt,
1184
1195
  distanceInECA: W,
1185
1196
  hoursInECA: K,
1186
1197
  totalDgoConsInECA: nt,
1187
1198
  totalDgoConsInSuspend: R
1188
- }, m.totalFoCons = et < 0 ? 0 : et, m.totalDgoCons = ot;
1189
- const st = w().valueOf() - d, rt = (($ = c == null ? void 0 : c.hours) == null ? void 0 : $.length) || 1;
1190
- return E == null || E.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, st, rt, Math.round(st / rt * 1e3) / 1e3), m;
1199
+ }, f.totalFoCons = et < 0 ? 0 : et, f.totalDgoCons = ot;
1200
+ const st = w().valueOf() - c, rt = (($ = d == null ? void 0 : d.hours) == null ? void 0 : $.length) || 1;
1201
+ return E == null || E.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, st, rt, Math.round(st / rt * 1e3) / 1e3), f;
1191
1202
  }
1192
1203
  /**
1193
1204
  * 分段失速分析(最多走hours 小时)
@@ -1204,7 +1215,7 @@ class Y {
1204
1215
  * @param useRouteParam
1205
1216
  * @param options
1206
1217
  */
1207
- static async analyseInstantWithThreshed(e, t, a, o, n, i, s, r = "", l = 3, u = !0, d = !1, y = {}) {
1218
+ static async analyseInstantWithThreshed(e, t, a, o, n, i, s, r = "", l = 3, u = !0, c = !1, h = {}) {
1208
1219
  var X, Q, Z, $, A, V;
1209
1220
  const k = w().valueOf();
1210
1221
  e.lng = z.convertToStdLng(e.lng);
@@ -1221,7 +1232,7 @@ class Y {
1221
1232
  return;
1222
1233
  const v = s.length ? O.calculateSubWaypoints(e, s) : [];
1223
1234
  v.forEach((T) => T.important = !0);
1224
- let m = O.simplifyRouteToCoordinates(p, v, 0), c = 0, h = 0, f = 0, C = 0;
1235
+ let f = O.simplifyRouteToCoordinates(p, v, 0), d = 0, m = 0, y = 0, C = 0;
1225
1236
  const M = {
1226
1237
  hours: [],
1227
1238
  wps: [],
@@ -1230,12 +1241,12 @@ class Y {
1230
1241
  };
1231
1242
  t = w(t).utc();
1232
1243
  const j = t.clone();
1233
- for (; m.length > 0; ) {
1244
+ for (; f.length > 0; ) {
1234
1245
  const T = l - t.hour() % l;
1235
1246
  let L = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1236
1247
  L = t.clone().add(L, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : L;
1237
- const q = await Y.speedLoseInHoursStep(I, t, j, L, c, m, r, u, d, y);
1238
- if (M.all.push(...q.all), (Q = q.from) != null && Q.speed && (M.hours.push(q.from), q != null && q.wps && M.wps.push(...q.wps), M.days.push(...q.days)), m = q == null ? void 0 : q.next, m.length || M.hours.push(q == null ? void 0 : q.to), c += Math.round((((Z = q == null ? void 0 : q.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1248
+ const q = await Y.speedLoseInHoursStep(I, t, j, L, d, f, r, u, c, h);
1249
+ if (M.all.push(...q.all), (Q = q.from) != null && Q.speed && (M.hours.push(q.from), q != null && q.wps && M.wps.push(...q.wps), M.days.push(...q.days)), f = q == null ? void 0 : q.next, f.length || M.hours.push(q == null ? void 0 : q.to), d += Math.round((((Z = q == null ? void 0 : q.to) == null ? void 0 : Z.distanceFromPrevious) ?? 0) * 1e4) / 1e4, !L)
1239
1250
  break;
1240
1251
  }
1241
1252
  M.wps = await Y.reduceWPS(M.wps), M.days = await Y.reduceDays(M.days), M.all = ($ = M.all) == null ? void 0 : $.reduce((T, L) => (L.positionTime = w.utc(L.etd || L.eta).unix(), T.some((q) => Math.round(w(q.etd).unix() / 60) === Math.round(w(L.etd).unix() / 60)) || T.push(L), T), []), (A = M.wps) == null || A.forEach((T, L) => {
@@ -1248,7 +1259,7 @@ class Y {
1248
1259
  const P = M.hours;
1249
1260
  for (let T = 0; T < P.length - 1; T++) {
1250
1261
  const L = w(P[T + 1].eta).diff(P[T].etd, "hour", !0);
1251
- h += P[T].wxFactor * L, f += P[T].cFactor * L, C += L;
1262
+ m += P[T].wxFactor * L, y += P[T].cFactor * L, C += L;
1252
1263
  }
1253
1264
  const D = P.reduce((T, L) => T + (L.suspend || 0), 0), H = M.hours.at(0), F = M.hours.at(-1), N = await O.calculateRangeRoute(H, F, p), R = await O.calculateRangeWaypoints(H, F, p, v), W = {
1254
1265
  sample: M,
@@ -1256,8 +1267,8 @@ class Y {
1256
1267
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1257
1268
  etd: w(H.eta).utc().format(),
1258
1269
  eta: w(F == null ? void 0 : F.eta).utc().format(),
1259
- wxFactor: Math.round(h / C * 1e3) / 1e3,
1260
- cFactor: Math.round(f / C * 1e3) / 1e3,
1270
+ wxFactor: Math.round(m / C * 1e3) / 1e3,
1271
+ cFactor: Math.round(y / C * 1e3) / 1e3,
1261
1272
  avgSpeed: Math.round(((F == null ? void 0 : F.distanceFromStart) || 0) / C * 1e3) / 1e3,
1262
1273
  totalHrs: Math.round(C * 1e3) / 1e3,
1263
1274
  suspend: Math.round(D * 1e3) / 1e3,
@@ -1267,7 +1278,7 @@ class Y {
1267
1278
  waypoints: R,
1268
1279
  v0: b,
1269
1280
  label: S
1270
- }, K = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: nt, hoursInECA: tt, totalDgoConsInECA: et, eca: ot } = await this.calculateECA(W, n, y), it = z.roundPrecision(n.fo / 24 * (C - tt), 3), st = z.roundPrecision(n.dgo / 24 * C + K, 3);
1281
+ }, K = z.roundPrecision(n.dgo / 24 * D, 3), { distanceInECA: nt, hoursInECA: tt, totalDgoConsInECA: et, eca: ot } = await this.calculateECA(W, n, h), it = z.roundPrecision(n.fo / 24 * (C - tt), 3), st = z.roundPrecision(n.dgo / 24 * C + K, 3);
1271
1282
  W.extend = {
1272
1283
  eca: ot,
1273
1284
  distanceInECA: nt,
@@ -1276,7 +1287,7 @@ class Y {
1276
1287
  totalDgoConsInSuspend: K
1277
1288
  }, W.totalDgoCons = st, W.totalFoCons = it < 0 ? 0 : it;
1278
1289
  const _ = w().valueOf() - k, G = ((V = M == null ? void 0 : M.hours) == null ? void 0 : V.length) || 1;
1279
- return E == null || E.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", y == null ? void 0 : y.requestId, _, G, Math.round(_ / G * 1e3) / 1e3), W;
1290
+ return E == null || E.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", h == null ? void 0 : h.requestId, _, G, Math.round(_ / G * 1e3) / 1e3), W;
1280
1291
  }
1281
1292
  /**
1282
1293
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1299,45 +1310,45 @@ class Y {
1299
1310
  e.speedStep = e.speedStep || 3, e.alterStep = e.alterStep ?? 1;
1300
1311
  const r = O.calculateRouteDistance(o.route);
1301
1312
  let l = 0;
1302
- a.forEach((m) => {
1303
- const c = Math.ceil(r / m.speed / 24);
1304
- l = l < c ? c : l;
1313
+ a.forEach((f) => {
1314
+ const d = Math.ceil(r / f.speed / 24);
1315
+ l = l < d ? d : l;
1305
1316
  }), l = l * 1.3;
1306
1317
  const u = w.utc(e.etd).add(l ?? 14, "day");
1307
- let d = 1;
1308
- for (const m of a) {
1309
- const c = JSON.parse(JSON.stringify(o.route)), h = JSON.parse(JSON.stringify(o.waypoints)), f = await Y.analyseInstantWithThreshed(
1318
+ let c = 1;
1319
+ for (const f of a) {
1320
+ const d = JSON.parse(JSON.stringify(o.route)), m = JSON.parse(JSON.stringify(o.waypoints)), y = await Y.analyseInstantWithThreshed(
1310
1321
  { lat: e.lat, lng: e.lng },
1311
1322
  e.etd,
1312
1323
  u,
1313
1324
  t,
1325
+ f,
1326
+ d,
1314
1327
  m,
1315
- c,
1316
- h,
1317
1328
  e.meteoVendor,
1318
1329
  e.speedStep,
1319
1330
  e.useMeteo,
1320
1331
  e.useRouteParam,
1321
1332
  n
1322
1333
  );
1323
- f && (await Y.calculateCost(f, m, e, n), s.push(f), E == null || E.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, e.etd, u.format(), {
1324
- cost: f.cost.total,
1325
- hire: f.cost.hire,
1326
- bunker: f.cost.bunker,
1327
- distance: f.distance,
1328
- hours: f.totalHrs,
1329
- cp: `${m.speed}/${m.fo}/${m.dgo}`
1330
- })), d++;
1334
+ y && (await Y.calculateCost(y, f, e, n), s.push(y), E == null || E.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, c, e.etd, u.format(), {
1335
+ cost: y.cost.total,
1336
+ hire: y.cost.hire,
1337
+ bunker: y.cost.bunker,
1338
+ distance: y.distance,
1339
+ hours: y.totalHrs,
1340
+ cp: `${f.speed}/${f.fo}/${f.dgo}`
1341
+ })), c++;
1331
1342
  }
1332
- s.sort((m, c) => m.cost.total - c.cost.total);
1333
- const y = s.at(0), k = s.at(1), b = [];
1334
- if (b.push({ combined: !1, speeds: [y], cost: (p = y.cost) == null ? void 0 : p.total }), k) {
1335
- const m = y.cost.cp, c = k.cost.cp, h = w(y.eta), f = w(y.etd), C = h.diff(f, "days", !0);
1343
+ s.sort((f, d) => f.cost.total - d.cost.total);
1344
+ const h = s.at(0), k = s.at(1), b = [];
1345
+ if (b.push({ combined: !1, speeds: [h], cost: (p = h.cost) == null ? void 0 : p.total }), k) {
1346
+ const f = h.cost.cp, d = k.cost.cp, m = w(h.eta), y = w(h.etd), C = m.diff(y, "days", !0);
1336
1347
  let M = Math.ceil(C / 2);
1337
1348
  M = M > 7 ? 7 : M < e.alterStep ? e.alterStep : M;
1338
1349
  let j = 2, P = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
1339
1350
  for (; M >= e.alterStep; ) {
1340
- const H = await Y.combinedAnalyse(e, t, u, [m, c], o, M, { ...n, level: j });
1351
+ const H = await Y.combinedAnalyse(e, t, u, [f, d], o, M, { ...n, level: j });
1341
1352
  if (P.cost > H.cost ? D ? (D == null ? void 0 : D.cost) > H.cost && (D = H) : (D = P, P = H) : (!D || (D == null ? void 0 : D.cost) > H.cost) && (D = H), M <= e.alterStep)
1342
1353
  break;
1343
1354
  M = Math.ceil(M / 2), j += 1;
@@ -1345,7 +1356,7 @@ class Y {
1345
1356
  b.push(P), D && b.push(D);
1346
1357
  }
1347
1358
  const I = w().valueOf() - i;
1348
- return E == null || E.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, I), b.sort((m, c) => m.cost - c.cost);
1359
+ return E == null || E.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, I), b.sort((f, d) => f.cost - d.cost);
1349
1360
  }
1350
1361
  /**
1351
1362
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1359,21 +1370,21 @@ class Y {
1359
1370
  */
1360
1371
  static async combinedAnalyse(e, t, a, o, n, i, s = {}) {
1361
1372
  s.counter = 1, E == null || E.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, i);
1362
- const r = await Y.alternateAnalyse(e, t, a, o, 0, n, i, s), l = r.reduce((c, h) => c + h.cost.total, 0), u = r.reduce((c, h) => c + h.cost.hire, 0), d = r.reduce((c, h) => c + h.cost.bunker, 0), y = r.reduce((c, h) => c + h.distance, 0), k = r.reduce((c, h) => c + h.totalHrs, 0);
1373
+ const r = await Y.alternateAnalyse(e, t, a, o, 0, n, i, s), l = r.reduce((d, m) => d + m.cost.total, 0), u = r.reduce((d, m) => d + m.cost.hire, 0), c = r.reduce((d, m) => d + m.cost.bunker, 0), h = r.reduce((d, m) => d + m.distance, 0), k = r.reduce((d, m) => d + m.totalHrs, 0);
1363
1374
  E == null || E.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1364
1375
  cost: l,
1365
1376
  hire: u,
1366
- bunker: d,
1367
- distance: y,
1377
+ bunker: c,
1378
+ distance: h,
1368
1379
  hours: k
1369
1380
  });
1370
- const b = await Y.alternateAnalyse(e, t, a, o, 1, n, i, s), S = b.reduce((c, h) => c + h.cost.total, 0), I = b.reduce((c, h) => c + h.cost.hire, 0), p = b.reduce((c, h) => c + h.cost.bunker, 0), v = b.reduce((c, h) => c + h.distance, 0), m = b.reduce((c, h) => c + h.totalHrs, 0);
1381
+ const b = await Y.alternateAnalyse(e, t, a, o, 1, n, i, s), S = b.reduce((d, m) => d + m.cost.total, 0), I = b.reduce((d, m) => d + m.cost.hire, 0), p = 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);
1371
1382
  return E == null || E.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1372
1383
  cost: S,
1373
1384
  hire: I,
1374
1385
  bunker: p,
1375
1386
  distance: v,
1376
- hours: m
1387
+ hours: f
1377
1388
  }), l < S ? { combined: !0, cost: Math.round(l * 1e3) / 1e3, speeds: r, step: i } : { combined: !0, cost: Math.round(S * 1e3) / 1e3, speeds: b, step: i };
1378
1389
  }
1379
1390
  /**
@@ -1388,9 +1399,9 @@ class Y {
1388
1399
  * @param options
1389
1400
  */
1390
1401
  static async alternateAnalyse(e, t, a, o, n, i, s, r = {}) {
1391
- var y, k;
1402
+ var h, k;
1392
1403
  let l = w.utc(e.etd);
1393
- const u = { lat: e.lat, lng: e.lng }, d = [];
1404
+ const u = { lat: e.lat, lng: e.lng }, c = [];
1394
1405
  for (; l.isBefore(a); ) {
1395
1406
  const b = l.clone().utc().add(s, "day"), S = JSON.parse(JSON.stringify(i.route)), I = JSON.parse(JSON.stringify(i.waypoints)), p = o[n], v = await Y.analyseInstantWithThreshed(
1396
1407
  u,
@@ -1422,13 +1433,13 @@ class Y {
1422
1433
  cp: `${p.speed}/${p.fo}/${p.dgo}`
1423
1434
  }
1424
1435
  )), r.counter = r.counter + 1;
1425
- const m = (k = (y = v == null ? void 0 : v.sample) == null ? void 0 : y.hours) == null ? void 0 : k.at(-1);
1426
- if (m)
1427
- u.lat = m.lat, u.lng = m.lng, l = w(m.eta), d.push(v), n = n ? 0 : 1;
1436
+ const f = (k = (h = v == null ? void 0 : v.sample) == null ? void 0 : h.hours) == null ? void 0 : k.at(-1);
1437
+ if (f)
1438
+ u.lat = f.lat, u.lng = f.lng, l = w(f.eta), c.push(v), n = n ? 0 : 1;
1428
1439
  else
1429
1440
  break;
1430
1441
  }
1431
- return d;
1442
+ return c;
1432
1443
  }
1433
1444
  /**
1434
1445
  * 计算Speed的cost
@@ -1456,16 +1467,16 @@ class Y {
1456
1467
  *
1457
1468
  */
1458
1469
  static async calculateECA(e, t, a = {}) {
1459
- var r, l, u, d;
1470
+ var r, l, u, c;
1460
1471
  const o = await O.intersectInECA((e == null ? void 0 : e.route) || []);
1461
1472
  let n = 0, i = 0, s = 0;
1462
- (l = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || l.forEach((y) => {
1463
- y.positionTime = w.utc(y.etd || y.eta).unix();
1473
+ (l = (r = e == null ? void 0 : e.sample) == null ? void 0 : r.wps) == null || l.forEach((h) => {
1474
+ h.positionTime = w.utc(h.etd || h.eta).unix();
1464
1475
  });
1465
- for (const y of o) {
1466
- n += y.distance;
1467
- const k = await O.deadReckoningTime((u = y.waypoints) == null ? void 0 : u.at(0), e.sample.all || e.sample.wps), b = await O.deadReckoningTime((d = y.waypoints) == null ? void 0 : d.at(-1), e.sample.all || e.sample.wps);
1468
- y.in = k, y.out = b, y.totalHrs = z.roundPrecision((b.positionTime - k.positionTime) / 3600, 3), y.totalDgoCons = z.roundPrecision(t.fo / 24 * y.totalHrs, 3), i += y.totalHrs, s += y.totalDgoCons;
1476
+ for (const h of o) {
1477
+ n += h.distance;
1478
+ const k = await O.deadReckoningTime((u = h.waypoints) == null ? void 0 : u.at(0), e.sample.all || e.sample.wps), b = await O.deadReckoningTime((c = h.waypoints) == null ? void 0 : c.at(-1), e.sample.all || e.sample.wps);
1479
+ h.in = k, h.out = b, h.totalHrs = z.roundPrecision((b.positionTime - k.positionTime) / 3600, 3), h.totalDgoCons = z.roundPrecision(t.fo / 24 * h.totalHrs, 3), i += h.totalHrs, s += h.totalDgoCons;
1469
1480
  }
1470
1481
  return n = z.roundPrecision(n, 3), i = z.roundPrecision(i, 3), s = z.roundPrecision(s, 3), {
1471
1482
  distanceInECA: n,
@@ -1480,34 +1491,34 @@ class Y {
1480
1491
  * @param options
1481
1492
  */
1482
1493
  static async mergeSpeeds(e, t = {}) {
1483
- var m, c;
1494
+ var f, d;
1484
1495
  const a = {
1485
1496
  hours: [],
1486
1497
  wps: [],
1487
1498
  days: []
1488
- }, o = e.reduce((h, f) => h + f.distance, 0), n = e.reduce((h, f) => {
1499
+ }, o = e.reduce((m, y) => m + y.distance, 0), n = e.reduce((m, y) => {
1489
1500
  var C;
1490
- return h + (((C = f.extend) == null ? void 0 : C.distanceInECA) || 0);
1491
- }, 0), i = e.reduce((h, f) => h + f.totalHrs, 0), s = e.reduce((h, f) => {
1501
+ return m + (((C = y.extend) == null ? void 0 : C.distanceInECA) || 0);
1502
+ }, 0), i = e.reduce((m, y) => m + y.totalHrs, 0), s = e.reduce((m, y) => {
1492
1503
  var C;
1493
- return h + (((C = f.extend) == null ? void 0 : C.hoursInECA) || 0);
1494
- }, 0), r = e.reduce((h, f) => {
1504
+ return m + (((C = y.extend) == null ? void 0 : C.hoursInECA) || 0);
1505
+ }, 0), r = e.reduce((m, y) => {
1495
1506
  var C;
1496
- return h + (((C = f.extend) == null ? void 0 : C.totalDgoConsInECA) || 0);
1497
- }, 0), l = e.reduce((h, f) => h + f.wxFactor * f.totalHrs / i, 0), u = e.reduce((h, f) => h + f.cFactor * f.totalHrs / i, 0), d = e.reduce((h, f) => h + f.totalFoCons, 0), y = e.reduce((h, f) => h + f.totalDgoCons, 0), k = e.reduce((h, f) => h + f.cost.total, 0), b = e.reduce((h, f) => h + f.cost.hire, 0), S = e.reduce((h, f) => h + f.cost.bunker, 0), I = [], p = [];
1507
+ return m + (((C = y.extend) == null ? void 0 : C.totalDgoConsInECA) || 0);
1508
+ }, 0), l = e.reduce((m, y) => m + y.wxFactor * y.totalHrs / i, 0), u = e.reduce((m, y) => m + y.cFactor * y.totalHrs / i, 0), c = e.reduce((m, y) => m + y.totalFoCons, 0), h = e.reduce((m, y) => m + y.totalDgoCons, 0), k = e.reduce((m, y) => m + y.cost.total, 0), b = e.reduce((m, y) => m + y.cost.hire, 0), S = e.reduce((m, y) => m + y.cost.bunker, 0), I = [], p = [];
1498
1509
  let v;
1499
- for (const h of e) {
1500
- p.push(...((m = h.extend) == null ? void 0 : m.eca) || []);
1501
- const f = h.sample.hours, C = h.sample.wps, M = h.sample.days, j = f.at(0);
1502
- v && (j.distanceFromPrevious = v.distanceFromPrevious, j.distanceFromStart = v.distanceFromStart, f.forEach((F, N) => {
1510
+ for (const m of e) {
1511
+ p.push(...((f = m.extend) == null ? void 0 : f.eca) || []);
1512
+ const y = m.sample.hours, C = m.sample.wps, M = m.sample.days, j = y.at(0);
1513
+ v && (j.distanceFromPrevious = v.distanceFromPrevious, j.distanceFromStart = v.distanceFromStart, y.forEach((F, N) => {
1503
1514
  N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1504
1515
  }), C.at(0).distanceFromPrevious = v.distanceFromPrevious, C.at(0).distanceFromStart = v.distanceFromStart, C.forEach((F, N) => {
1505
1516
  N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1506
1517
  }), M.at(0).distanceFromPrevious = v.distanceFromPrevious, M.at(0).distanceFromStart = v.distanceFromStart, M.forEach((F, N) => {
1507
1518
  N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1508
- })), j.cp = h.cost.cp;
1509
- const P = [h.etd, h.eta], D = I.findIndex((F) => F.id === j.cp.id);
1510
- D === -1 ? (j.cp.segment = [P], I.push(j.cp)) : I[D].segment.push(P), f.forEach((F) => {
1519
+ })), j.cp = m.cost.cp;
1520
+ const P = [m.etd, m.eta], D = I.findIndex((F) => F.id === j.cp.id);
1521
+ D === -1 ? (j.cp.segment = [P], I.push(j.cp)) : I[D].segment.push(P), y.forEach((F) => {
1511
1522
  var R;
1512
1523
  ((R = a.hours) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.hours.push(F);
1513
1524
  }), C.forEach((F) => {
@@ -1517,15 +1528,15 @@ class Y {
1517
1528
  var R;
1518
1529
  ((R = a == null ? void 0 : a.days) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.days.push(F);
1519
1530
  });
1520
- const H = (c = a.wps) == null ? void 0 : c.findIndex((F) => F.eta === j.eta);
1521
- H === -1 ? a.wps.push(j) : a.wps[H] = j, v = f.at(-1);
1531
+ const H = (d = a.wps) == null ? void 0 : d.findIndex((F) => F.eta === j.eta);
1532
+ H === -1 ? a.wps.push(j) : a.wps[H] = j, v = y.at(-1);
1522
1533
  }
1523
- return a.wps.sort((h, f) => w(h.etd).unix() - w(f.etd).unix()), a.wps.forEach((h, f) => {
1524
- const C = a.wps[f - 1];
1534
+ return a.wps.sort((m, y) => w(m.etd).unix() - w(y.etd).unix()), a.wps.forEach((m, y) => {
1535
+ const C = a.wps[y - 1];
1525
1536
  if (C) {
1526
- const M = h.distanceFromStart - (C.distanceFromStart || 0), j = w(h.eta || h.etd).diff(w(C.etd || C.eta), "hour", !0), P = Math.round(M / j * 100) / 100;
1527
- h.avgSpd = P;
1528
- const D = O.calculateBearing(C, h);
1537
+ const M = m.distanceFromStart - (C.distanceFromStart || 0), j = w(m.eta || m.etd).diff(w(C.etd || C.eta), "hour", !0), P = Math.round(M / j * 100) / 100;
1538
+ m.avgSpd = P;
1539
+ const D = O.calculateBearing(C, m);
1529
1540
  C.bearing = D;
1530
1541
  }
1531
1542
  }), {
@@ -1541,8 +1552,8 @@ class Y {
1541
1552
  avgSpeed: Math.round(o / i * 1e3) / 1e3,
1542
1553
  wxFactor: Math.round(l * 1e3) / 1e3,
1543
1554
  cFactor: Math.round(u * 1e3) / 1e3,
1544
- totalFoCons: Math.round(d * 1e3) / 1e3,
1545
- totalDgoCons: Math.round(y * 1e3) / 1e3,
1555
+ totalFoCons: Math.round(c * 1e3) / 1e3,
1556
+ totalDgoCons: Math.round(h * 1e3) / 1e3,
1546
1557
  cost: {
1547
1558
  total: Math.round(k * 1e3) / 1e3,
1548
1559
  hire: Math.round(b * 1e3) / 1e3,
@@ -1 +1 @@
1
- (function(D,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):(D=typeof globalThis<"u"?globalThis:D||self,x(D["idm-plugin-vessel"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,x,U,v,F,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(D,x,U)=>x in D?Ct(D,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):D[x]=U;var _=(D,x,U)=>(St(D,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:v().utc().format()})}async checkToken(t={}){var a;return(!this.token||v().diff(v(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const d=r.data;if(d)return{mmsi:d.mmsi,imo:Number.isNaN(d.imo)?null:Number(d.imo),callSign:d.callsign,name:d.nameEn,nameCn:d.nameCn,type:d.vesselTypeNameEn,flagName:d.flagCtry,clasz:d.classSociety,dateOfBuild:d.buildYearMonth,deadweight:d.dwt,grossTonnage:d.grt,netTonnage:d.net,teu:d.teu,length:d.length,breadth:d.width,height:d.height,draught:d.draught,speed:d.speed,passengerCapacity:d.passengercapacity,vendor:"myvessel",raw:d}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=v(`${s.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.mmsi,name:s.vesselName||s.aisVesselName,imo:s.imo,callSign:s.callsign||s.aisCallSign,lat:s.lat,lng:s.lon,length:s.length,width:s.width,draught:s.currDraught,sog:s.sog,cog:s.cog,hdg:s.hdg,rot:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.dest,positionTime:u.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:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,T;const r=v();await this.checkToken(s);const l="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",u={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const d={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,d);const y=await x.post(l,d).json();if(y.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:y.message,status:y.status,code:y.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:w,tracks:f,specialRegions:c,ecaLength:h}=y.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=w==null?void 0:w.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=F.LaneHelper.simplifyCoordinates(k.waypoints),k.route=F.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=F.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=h);const C=v().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,d,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,d,s),d}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,T,k,g,w;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(T=this.token)==null?void 0:T.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const d=await x.post(l,u).json();if(d.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:d.message,status:d.status,code:d.code}),d;let y=-1;const I=v(`${(g=(k=d.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(w=d.data)==null||w.forEach(f=>{for(const q in f)!isNaN(f[q])&&Number(f[q])!==1/0&&(f[q]=Number(f[q]));const c=v(`${f.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),h=f.status,{labelCn:m,labelEn:C}=this.parseStatus(h),p={mmsi:f.mmsi,imo:n==null?void 0:n.imo,lat:f.lat,lng:f.lon,sog:f.sog,cog:f.cog,hdg:f.hdg,draught:f.draught,status:h,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(f.eta)?v(`${f.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:f.dest,positionTime:c.unix(),labelCn:m,labelEn:C,method:"trajectory",vendor:"myVessel",utc:c.utc().format()},L=Math.floor(c.diff(I,"minute",!0)/(i||1));L!==y&&(y=L,s.push(p))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;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:l,labelEn:u}=this.parseStatus(r),d=v(`${s.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:s.m,name:s.n,imo:s.imonumber,callSign:s.callsign,lat:Math.round(s.la/60*1e5)/1e5,lng:Math.round(s.lo/60*1e5)/1e5,length:s.l,width:s.w,draught:s.draught,sog:s.sp,cog:s.co,hdg:s.h,rot:isNaN(s.rot)?0:s.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(s.eta)?v.utc(s.eta).format():void 0,destination:s.destination,vesselType:s.type,dwt:s.dwt,build:s.buildyear,flag:s.fn,positionTime:d.unix(),utc:d.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var f,c,h;const r=await this.realTimePosition(t,s);let l=v(a);const u=v(o),d=v();if(i){let m=u.diff(l,"d",!0);m<0?l=u.clone().subtract(40,"d"):m<30?l.subtract(10,"d"):m<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),m=d.diff(u,"d",!0),u.add(m>10?240:m*24,"h")}const y={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,y).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,y);let T;b&&(T=((c=(f=b.ships)==null?void 0:f.offors)==null?void 0:c.ship)||[],T.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let g=-1;const w=v(`${(h=T==null?void 0:T[0])==null?void 0:h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const m of T){for(const R in m)!isNaN(m[R])&&Number(m[R])!==1/0&&(m[R]=Number(m[R]));const C=v(`${m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");m.status=m.sp>4?0:1;const{labelEn:p,labelCn:L}=this.parseStatus(m.status),q={mmsi:m.m,name:m.n,imo:r==null?void 0:r.imo,lat:m.la,lng:m.lo,draught:m.draught,sog:m.sp,cog:m.co,hdg:m.hdg,positionTime:C.unix(),utc:C.utc().format(),status:m.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(w,"minute",!0)/(n||1));N!==g&&(g=N,k.push(q))}return k}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const y in s)!isNaN(s[y])&&Number(s[y])!==1/0&&(s[y]=Number(s[y]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=v.unix(s.lasttime);return{mmsi:s.ShipID,name:s.name,imo:s.imo,callSign:s.callsign,lat:Math.round(s.lat/1e6*1e5)/1e5,lng:Math.round(s.lon/1e6*1e5)/1e5,length:Math.round(s.length/10*100)/100,width:Math.round(s.width/10*100)/100,draught:Math.round(s.draught/1e3*100)/100,sog:Math.round(s.sog*3600/1e3/1852*100)/100,cog:Math.round(s.cog/100*100)/100,hdg:Math.round(s.hdg/100*100)/100,rot:Math.round(s.rot/100*100)/100,positionTime:s.lasttime,utc:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var w;const r=await this.realTimePosition(t,s),l=v(a),u=v(o),d="https://api.shipxy.com/apicall/GetShipTrack",y={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(d,y).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,d,y),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,T=[],k=v.unix((w=b[0])==null?void 0:w.utc);let g=-1;for(const f of b){const c=v.unix(f.utc),h={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"},m=Math.floor(c.diff(k,"minute",!0)/(n||1));m!==g&&(g=m,T.push(h))}return T}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:d}=await this.parseStatus(l.aisNavStatus),y=v.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:y.utc().format(),status:l.aisNavStatus,labelEn:d,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=v(a),l=v(o),u=await this.getShipId(t),d=await this.getShipInfo(u),y=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),d,t,n,y);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),d,t,n,y),y}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},d="https://api3.myships.com/sp/ships/position/history",y=await x.post(d,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,u),y.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,y),y;const I=y.data;for(const g in I)!isNaN(I[g])&&Number(I[g])!==1/0&&(I[g]=Number(I[g]));const b=v.unix((k=I[0])==null?void 0:k.posTime);let T=-1;for(const g of I){const w=v.unix(g.posTime),f={imo:n==null?void 0:n.imo,mmsi:i,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:w.unix(),utc:w.utc().format(),method:"trajectory",vendor:"myship"},c=Math.floor(w.diff(b,"minute",!0)/(s||1));c!==T&&(T=c,r.push(f))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const d=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!d)i.scope=n[0];else if(d)for(let y=0,I=d.length;y<I;y++){const b=this.parseRule(d[y]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,T,k,g,w,f,c,h,m,C,p,L,q,N,R;let o=0,n=0,i=0,s=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,l=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,u=(f=(w=t==null?void 0:t.HEAVY)==null?void 0:w.sigWave)==null?void 0:f.number,d=Math.round((((h=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:h.number)+2)*100)/100,y=(C=(m=t==null?void 0:t.SEVERE)==null?void 0:m.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(q=H==null?void 0:H.meteo)==null?void 0:q.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?v(H.eta).diff(v(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=u&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I}),(B==null?void 0:B.scale)>=d?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>y?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===I&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:d,svThd4Wd:y,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const vt=new lt;let S;try{S=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ht||{}),ft=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(ft||{}),mt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var y;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((y=e==null?void 0:e.type)==null?void 0:y.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=F.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:b,marineModels:T}=await ot.Meteo2Assist.autoPickMeteoModel(o),k=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:b,marineModels:T}),[g]=ot.Meteo2Assist.pickHourly(k,a);u=ot.Meteo2Assist.toLegacy(g)}catch(b){S.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},b)}const d=O.currentFactor(e.bearing,u==null?void 0:u.current,n),y=O.weatherFactor(e,u,d),I=Math.round((e.speed*1.943844+y+d)*100)/100;l={meteo:{...u},wxFactor:y,cFactor:d,speed:t.velocity&&s?t.velocity:I<0?1:I,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const d=t.clone().add(14,"days"),y=[],I=[],b=[];let T=0,k=0,g,w;for(let f=0;f<i.length-1;f++){let c=i[f];c.distanceFromStart=Math.round((n+k)*1e3)/1e3;const h=i[f+1];if(e.bearing=F.LaneHelper.calculateBearing(c,h,!h.gcToPrevious),c.bearing=e.bearing,c.suspend&&l){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...`,u.requestId,c),o===0)return c.distanceFromPrevious=k,{etd:t,from:w||c,to:c,next:i.filter(L=>L),wps:y,days:I,all:b}}else c.suspend=0;r=t.isAfter(d)?!1:r,c=await O.speedLoseAt(e,c,t,s,0,r,l,u),b.push(c),w=w||c,c.important&&y.push(c),t.isSameOrAfter(a)&&(I.push(c),a.add(24,"hour"));const m=F.LaneHelper.calculateDistance(c,h,!h.gcToPrevious);let C=Math.round(m/w.speed*1e5)/1e5;if(T+C<o){if(T+=C,t.add(C,"hour"),delete i[f],S==null||S.debug(`[%s] go to %j from %j with ${m}nm, and cost ${C} hours`,u.requestId,{lat:h.lat,lng:h.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),k+=m,i.filter(p=>p).length<=1){g=h,g.eta=t.utc().format(),g.distanceFromPrevious=m,g.distanceFromStart=Math.round((n+k)*1e4)/1e4,y.push(g),b.push(g),delete i[f+1];break}}else{C=o-T,t.add(C,"hour");const p=F.LngLatHelper.roundPrecision(w.speed*C,5);g=F.LaneHelper.calculateCoordinate(c,e.bearing,p,"nauticalmiles",!h.gcToPrevious),g.eta=t.utc().format(),i[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.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((n+k)*1e4)/1e4;break}}return{etd:t,from:w,to:g,next:i.filter(f=>f),wps:y,days:I,all:b}}static currentFactor(e,t,a=0){const o=F.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var I,b,T,k,g,w,f;S==null||S.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=F.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=F.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(T=t==null?void 0:t.wind)==null?void 0:T.kts);let d=l*s*u/100*(e.speed-n);d=Math.round(d*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(d)>1&&(d=d/(Math.abs(Math.round(d))+1)),S==null||S.debug("wind wx factor = %d",d),r=F.LaneHelper.includedAngle(e.bearing,(g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.degree);const y=O.waveHeightFactor(((f=(w=t==null?void 0:t.wave)==null?void 0:w.sig)==null?void 0:f.height)??1,r);return S==null||S.debug("wave wx factor = %d",y),d=Math.abs(d)>Math.abs(y)?d:d*.3+y*.7,S==null||S.debug("weather factor = %d",d),d=Math.abs(d)>3?3*(Math.abs(d)/d)+Math.abs(d)/d*(Math.abs(d)-2)*.1:d,Math.round((d||0)*100)/100}static async reduceDays(e,t=12*60*60){return e=e==null?void 0:e.reduce((a,o)=>(o.positionTime||(o.positionTime=v.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(v(n.etd).unix()/t)===Math.floor(v(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const d=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:I}=n.points,b=F.LaneHelper.calculateSubRoute(e,y);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(a,o.loadCondition,T,0),w=I.length?F.LaneHelper.calculateSubWaypoints(e,I):[];w.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:w,v0:T,label:k},c={hours:[],days:[],wps:[],all:[]};s||(F.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let h=F.LaneHelper.simplifyRouteToCoordinates(b,w,0),m=0,C=0,p=0,L=0;t=v(t).utc();const q=t.clone();for(;h.length>0;){const P=s-t.hour()%s,z=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,q,z,m,h,i,r,l,u);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)),h=j==null?void 0:j.next,!h.length){const W=await O.speedLoseAt(g,j.to,v(j.to.eta),i,0,r,l,u);W.bearing=g.bearing,c.hours.push(W),c.all.push(W)}m+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=c.hours;for(let P=0;P<N.length-1;P++){const z=v(N[P+1].eta).diff(N[P].etd,"hour",!0)||1;C+=(N[P].wxFactor||0)*z,p+=(N[P].cFactor||0)*z,L+=z}const R=N.reduce((P,z)=>P+(z.suspend||0),0);($=c.wps)==null||$.forEach((P,z)=>{P.positionTime=v.utc(P.etd||P.eta).unix();const j=c.wps[z-1];if(j){const W=P.distanceFromStart-j.distanceFromStart,Y=v(P.eta||P.etd).diff(v(j.etd||j.eta),"h",!0);P.avgSpd=Math.round(W/Y*100)/100,j.bearing=F.LaneHelper.calculateBearing(j,P)}}),c.wps=await O.reduceWPS(c.wps),c.days=await O.reduceDays(c.days),c.all=(tt=c.all)==null?void 0:tt.reduce((P,z)=>(z.positionTime=v.utc(z.etd||z.eta).unix(),P.some(j=>Math.round(j.positionTime/60)===Math.round(z.positionTime/60))||P.push(z),P),[]),f.sample=c;const E=c.hours.at(0),H=c.hours.at(-1);f.distance=Math.round(H.distanceFromStart*1e3)/1e3,f.etd=v(E.eta).utc().format(),f.eta=v(H.eta).utc().format(),f.wxFactor=Math.round(C/L*1e3)/1e3,f.cFactor=Math.round(p/L*1e3)/1e3,f.avgSpeed=Math.round(H.distanceFromStart/L*1e3)/1e3,f.totalHrs=Math.round(L*1e3)/1e3,f.suspend=Math.round(R*1e3)/1e3;const V=F.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(f,o,u),at=F.LngLatHelper.roundPrecision(o.fo/24*(L-K),3),rt=F.LngLatHelper.roundPrecision(o.dgo/24*L+V,3);f.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},f.totalFoCons=at<0?0:at,f.totalDgoCons=rt;const nt=v().valueOf()-d,dt=((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",u==null?void 0:u.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),f}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,d=!1,y={}){var Z,$,tt,et,P,z;const I=v().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),g=F.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const w=s.length?F.LaneHelper.calculateSubWaypoints(e,s):[];w.forEach(j=>j.important=!0);let f=F.LaneHelper.simplifyRouteToCoordinates(g,w,0),c=0,h=0,m=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const L=t.clone();for(;f.length>0;){const j=l-t.hour()%l;let W=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(k,t,L,W,c,f,r,u,d,y);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,!W)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,W)=>(W.positionTime=v.utc(W.etd||W.eta).unix(),j.some(Y=>Math.round(v(Y.etd).unix()/60)===Math.round(v(W.etd).unix()/60))||j.push(W),j),[]),(P=p.wps)==null||P.forEach((j,W)=>{const Y=p.wps[W-1];if(Y){const It=j.distanceFromStart-Y.distanceFromStart,kt=v(j.eta||j.etd).diff(v(Y.etd||Y.eta),"h",!0);Y.bearing=F.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const q=p.hours;for(let j=0;j<q.length-1;j++){const W=v(q[j+1].eta).diff(q[j].etd,"hour",!0);h+=q[j].wxFactor*W,m+=q[j].cFactor*W,C+=W}const N=q.reduce((j,W)=>j+(W.suspend||0),0),R=p.hours.at(0),E=p.hours.at(-1),H=await F.LaneHelper.calculateRangeRoute(R,E,g),V=await F.LaneHelper.calculateRangeWaypoints(R,E,g,w),B={sample:p,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(h/C*1e3)/1e3,cFactor:Math.round(m/C*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:b,label:T},K=F.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=F.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=F.LngLatHelper.roundPrecision(n.dgo/24*C+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=v().valueOf()-I,Q=((z=p==null?void 0:p.hours)==null?void 0:z.length)||1;return S==null||S.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",y==null?void 0:y.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var g,w;const i=v().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=F.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(f=>{const c=Math.ceil(r/f.speed/24);l=l<c?c:l}),l=l*1.3;const u=v.utc(e.etd).add(l??14,"day");let d=1;for(const f of a){const c=JSON.parse(JSON.stringify(o.route)),h=JSON.parse(JSON.stringify(o.waypoints)),m=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,c,h,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);m&&(await O.calculateCost(m,f,e,n),s.push(m),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,u.format(),{cost:m.cost.total,hire:m.cost.hire,bunker:m.cost.bunker,distance:m.distance,hours:m.totalHrs,cp:`${f.speed}/${f.fo}/${f.dgo}`})),d++}s.sort((f,c)=>f.cost.total-c.cost.total);const y=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[y],cost:(g=y.cost)==null?void 0:g.total}),I){const f=y.cost.cp,c=I.cost.cp,h=v(y.eta),m=v(y.etd),C=h.diff(m,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,q={combined:!1,speeds:[I],cost:(w=I.cost)==null?void 0:w.total},N;for(;p>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[f,c],o,p,{...n,level:L});if(q.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=q,q=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(q),N&&b.push(N)}const k=v().valueOf()-i;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((f,c)=>f.cost-c.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,S==null||S.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((c,h)=>c+h.cost.total,0),u=r.reduce((c,h)=>c+h.cost.hire,0),d=r.reduce((c,h)=>c+h.cost.bunker,0),y=r.reduce((c,h)=>c+h.distance,0),I=r.reduce((c,h)=>c+h.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:d,distance:y,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),T=b.reduce((c,h)=>c+h.cost.total,0),k=b.reduce((c,h)=>c+h.cost.hire,0),g=b.reduce((c,h)=>c+h.cost.bunker,0),w=b.reduce((c,h)=>c+h.distance,0),f=b.reduce((c,h)=>c+h.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:w,hours:f}),l<T?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(T*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var y,I;let l=v.utc(e.etd);const u={lat:e.lat,lng:e.lng},d=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),T=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],w=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,T,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);w&&(await O.calculateCost(w,g,e,r),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.utc().format(),b.utc().format(),{cost:w.cost.total,hire:w.cost.hire,bunker:w.cost.bunker,distance:w.distance,hours:w.totalHrs,cp:`${g.speed}/${g.fo}/${g.dgo}`})),r.counter=r.counter+1;const f=(I=(y=w==null?void 0:w.sample)==null?void 0:y.hours)==null?void 0:I.at(-1);if(f)u.lat=f.lat,u.lng=f.lng,l=v(f.eta),d.push(w),n=n?0:1;else break}return d}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,d;const o=await F.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(y=>{y.positionTime=v.utc(y.etd||y.eta).unix()});for(const y of o){n+=y.distance;const I=await F.LaneHelper.deadReckoningTime((u=y.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await F.LaneHelper.deadReckoningTime((d=y.waypoints)==null?void 0:d.at(-1),e.sample.all||e.sample.wps);y.in=I,y.out=b,y.totalHrs=F.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),y.totalDgoCons=F.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),i+=y.totalHrs,s+=y.totalDgoCons}return n=F.LngLatHelper.roundPrecision(n,3),i=F.LngLatHelper.roundPrecision(i,3),s=F.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var f,c;const a={hours:[],wps:[],days:[]},o=e.reduce((h,m)=>h+m.distance,0),n=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((h,m)=>h+m.totalHrs,0),s=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((h,m)=>{var C;return h+(((C=m.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((h,m)=>h+m.wxFactor*m.totalHrs/i,0),u=e.reduce((h,m)=>h+m.cFactor*m.totalHrs/i,0),d=e.reduce((h,m)=>h+m.totalFoCons,0),y=e.reduce((h,m)=>h+m.totalDgoCons,0),I=e.reduce((h,m)=>h+m.cost.total,0),b=e.reduce((h,m)=>h+m.cost.hire,0),T=e.reduce((h,m)=>h+m.cost.bunker,0),k=[],g=[];let w;for(const h of e){g.push(...((f=h.extend)==null?void 0:f.eca)||[]);const m=h.sample.hours,C=h.sample.wps,p=h.sample.days,L=m.at(0);w&&(L.distanceFromPrevious=w.distanceFromPrevious,L.distanceFromStart=w.distanceFromStart,m.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),C.at(0).distanceFromPrevious=w.distanceFromPrevious,C.at(0).distanceFromStart=w.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)}),p.at(0).distanceFromPrevious=w.distanceFromPrevious,p.at(0).distanceFromStart=w.distanceFromStart,p.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+w.distanceFromStart)})),L.cp=h.cost.cp;const q=[h.etd,h.eta],N=k.findIndex(E=>E.id===L.cp.id);N===-1?(L.cp.segment=[q],k.push(L.cp)):k[N].segment.push(q),m.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),C.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),p.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(c=a.wps)==null?void 0:c.findIndex(E=>E.eta===L.eta);R===-1?a.wps.push(L):a.wps[R]=L,w=m.at(-1)}return a.wps.sort((h,m)=>v(h.etd).unix()-v(m.etd).unix()),a.wps.forEach((h,m)=>{const C=a.wps[m-1];if(C){const p=h.distanceFromStart-(C.distanceFromStart||0),L=v(h.eta||h.etd).diff(v(C.etd||C.eta),"hour",!0),q=Math.round(p/L*100)/100;h.avgSpd=q;const N=F.LaneHelper.calculateBearing(C,h);C.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(d*1e3)/1e3,totalDgoCons:Math.round(y*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(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}D.AISImpl=G,D.AlertHelper=lt,D.AlertLevel=ut,D.HifleetImpl=Mt,D.LoadCondition=ft,D.MyShipImpl=gt,D.MyVesselImpl=pt,D.ShipxyImpl=bt,D.SpeedHelper=O,D.SpeedLabel=mt,D.VesselTag=ht,D.alertHelper=vt,Object.defineProperty(D,Symbol.toStringTag,{value:"Module"})});
1
+ (function(D,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):(D=typeof globalThis<"u"?globalThis:D||self,x(D["idm-plugin-vessel"]={},D.got,D["@log4js-node/log4js-api"],D.moment,D["@idm-plugin/geo2"],D["@idm-plugin/meteo2"],D["@idm-plugin/meteo"]))})(this,function(D,x,U,w,F,yt,ot){"use strict";var Ct=Object.defineProperty;var St=(D,x,U)=>x in D?Ct(D,x,{enumerable:!0,configurable:!0,writable:!0,value:U}):D[x]=U;var _=(D,x,U)=>(St(D,typeof x!="symbol"?x+"":x,U),U);let M;try{M=U.getLogger("vessel")}catch{}finally{}class G{parseStatus(e){let t,a;switch(e){case 0:t="在航(主机推动)",a="Underway Using Engine";break;case 1:t="锚泊",a="Anchored";break;case 2:t="失控",a="Not under command";break;case 3:t="操纵受限",a="Limited airworthiness";break;case 4:t="吃水受限",a="Limited by ship's draft";break;case 5:t="靠泊",a="Mooring";break;case 6:t="搁浅",a="Stranded";break;case 7:t="捕捞作业",a="Engaged in fishing";break;case 8:t="靠帆船提供动力",a="Sailing";break;default:t="未定义",a="Undefined"}return{labelCn:t,labelEn:a}}}class pt extends G{constructor(t,a){super();_(this,"clientId");_(this,"clientSecret");_(this,"token");this.clientId=t,this.clientSecret=a}async authToken(t={}){const a="https://svc.data.myvessel.cn/ada/oauth/token",o={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},n=await x.post(a,o).json();M==null||M.info("[%s] fetch access token from: %s - %j",t.requestId,a,n),n.error||(this.token={accessToken:n.access_token,tokenType:n.token_type,expiresIn:n.expires_in,scope:n.scope,jti:n.jti,issuedAt:w().utc().format()})}async checkToken(t={}){var a;return(!this.token||w().diff(w(this.token.issuedAt),"seconds")>(((a=this.token)==null?void 0:a.expiresIn)||0)-300)&&await this.authToken(t),this.token}async suggest(t,a={}){var s,r;await this.checkToken(a);const o="https://market.myvessel.cn/sdc/v1/mkt/vessels/fuzzy",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{kw:t,recordNum:a.ps||10}};M==null||M.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),[]):(i.data||[]).map(u=>({mmsi:u.mmsi,name:u.nameEn,nameCn:u.nameCn,imo:Number.isNaN(u.imo)?null:Number(u.imo),callSign:u.callsign,type:u.vesselTypeNameEn,flagName:u.flagCtry,vendor:"myvessel",raw:u}))}async search(t,a={}){var l,u;await this.checkToken(a);const o=/^\d{7}$/.test(t.toString()),n=o?"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/imo":"https://market.myvessel.cn/sdc/v1/mkt/vessels/detail/mmsi",i=o?{imo:t}:{mmsi:t},s={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(u=this.token)==null?void 0:u.accessToken}`},searchParams:i};M==null||M.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return M==null||M.warn("[%s] fetch suggest vessels failed: %j",a.requestId,{message:r.message,status:r.status,code:r.code}),{};{const c=r.data;if(c)return{mmsi:c.mmsi,imo:Number.isNaN(c.imo)?null:Number(c.imo),callSign:c.callsign,name:c.nameEn,nameCn:c.nameCn,type:c.vesselTypeNameEn,flagName:c.flagCtry,clasz:c.classSociety,dateOfBuild:c.buildYearMonth,deadweight:c.dwt,grossTonnage:c.grt,netTonnage:c.net,teu:c.teu,length:c.length,breadth:c.width,height:c.height,draught:c.draught,speed:c.speed,passengerCapacity:c.passengercapacity,vendor:"myvessel",raw:c}}return{}}async archives(t,a={}){var s,r;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/ship/info/batch",n={headers:{Authorization:`${(s=this.token)==null?void 0:s.tokenType} ${(r=this.token)==null?void 0:r.accessToken}`},json:{mmsiList:typeof t=="number"?[t]:t}};M==null||M.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(M==null||M.warn("[%s] fetch vessel archive failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),{}):i.data}async realTimePosition(t,a={}){var r,l;await this.checkToken(a);const o="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",n={headers:{Authorization:`${(r=this.token)==null?void 0:r.tokenType} ${(l=this.token)==null?void 0:l.accessToken}`},searchParams:{mmsi:t}};M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,{message:i.message,status:i.status,code:i.code}),i;const s=i.data;for(const u in s)!isNaN(s[u])&&Number(s[u])!==1/0&&(s[u]=Number(s[u]));if(s){const u=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:u.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:u.utc().format()}}else return{}}async calculateRoute(t,a,o,n,i,s={}){var I,b,S;const r=w();await this.checkToken(s);const l="https://market.myvessel.cn/sdc/v1/mkt/routes/plan",u={maxDraught:s.draught||10,useAIModel:s.useAIModel??!0,withECA:s.withECA||!1,withSpecialRegion:s.withSpecial||!1};t.code&&(u.startPortCode=t.code),t.lng!==void 0&&t.lat!==void 0&&(u.startPoint={lon:t.lng,lat:t.lat}),a.code&&(u.endPortCode=a.code),a.lng!==void 0&&a.lat!==void 0&&(u.endPoint={lon:a.lng,lat:a.lat}),o!=null&&o.length&&(u.crossMonthList=o),n!=null&&n.length&&(u.excludeNodes=n),i!=null&&i.length&&(u.excludeSeaAreas=i);const c={headers:{Authorization:`${(I=this.token)==null?void 0:I.tokenType} ${(b=this.token)==null?void 0:b.accessToken}`},json:u};M==null||M.info("[%s] fetch route from: %s - %j",s.requestId,l,c);const h=await x.post(l,c).json();if(h.status!==200)return M==null||M.warn("[%s] fetch route failed: %j",s.requestId,{message:h.message,status:h.status,code:h.code}),{};{const k={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:v,tracks:m,specialRegions:d,ecaLength:f}=h.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=v==null?void 0:v.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})),d==null||d.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=m==null?void 0:m.map(p=>({lat:Math.round(p.lat*1e5)/1e5,lng:Math.round(p.lon*1e5)/1e5})),(S=k.waypoints)!=null&&S.length&&(k.waypoints=F.LaneHelper.simplifyCoordinates(k.waypoints),k.route=F.LaneHelper.divideAccordingToLng(k.waypoints),k.distance=F.LaneHelper.calculateRouteDistance(k.route),k.distanceInECA=f);const C=w().diff(r,"second");return k.memo=`time cost: ${C}s`,M.info("[%s] calculate route cost: %d seconds",s.requestId,C),k}}async trajectory(t,a,o,n,i=!0,s={}){await this.checkToken(s);const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c=[];for(;u.diff(l,"day",!0)>30;)await this.trajectoryIn30Day(t,l,l.clone().add(30,"day"),r,n,c,s),l.add(30,"day");return await this.trajectoryIn30Day(t,l,u,r,n,c,s),c}async trajectoryIn30Day(t,a,o,n,i,s,r={}){var b,S,k,g,v;const l="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(b=this.token)==null?void 0:b.tokenType} ${(S=this.token)==null?void 0:S.accessToken}`},json:{mmsi:t,startTime:a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};M==null||M.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const c=await x.post(l,u).json();if(c.code)return M==null||M.warn("[%s] fetch trajectory failed: %j",r.requestId,l,{message:c.message,status:c.status,code:c.code}),c;let h=-1;const I=w(`${(g=(k=c.data)==null?void 0:k[0])==null?void 0:g.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(v=c.data)==null||v.forEach(m=>{for(const P in m)!isNaN(m[P])&&Number(m[P])!==1/0&&(m[P]=Number(m[P]));const d=w(`${m.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),f=m.status,{labelCn:y,labelEn:C}=this.parseStatus(f),p={mmsi:m.mmsi,imo:n==null?void 0:n.imo,lat:m.lat,lng:m.lon,sog:m.sog,cog:m.cog,hdg:m.hdg,draught:m.draught,status:f,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(m.eta)?w(`${m.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").utc().format():void 0,destination:m.dest,positionTime:d.unix(),labelCn:y,labelEn:C,method:"trajectory",vendor:"myVessel",utc:d.utc().format()},L=Math.floor(d.diff(I,"minute",!0)/(i||1));L!==h&&(h=L,s.push(p))}),s}}class Mt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o="https://api.hifleet.com/position/position/get/token",n={searchParams:{mmsi:t,usertoken:this.token}},i=await x.post(o,n).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return M==null||M.warn("[%s] fetch realtime position failed: %j",a.requestId,o,i),i;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:l,labelEn:u}=this.parseStatus(r),c=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:c.unix(),utc:c.utc().format(),status:r,labelCn:l,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,a={}){let o="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const n={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let i=await x.post(o,n).json();M==null||M.info("[%s] fetch vessel props from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]);for(const r in i)!isNaN(i[r])&&Number(i[r])!==1/0&&(i[r]=Number(i[r]));const s={mmsi:i.m,name:i.n,imo:i.i,callSign:i.c,length:i.l,breadth:i.b,draught:i.dr,type:i.t};return o="https://www.hifleet.com/hifleetapi/sameShipSearch.do",i=await x.post(o,n).json(),M==null||M.info("[%s] search vessel dead weight from: %s - %j",a.requestId,o,n),i instanceof Array&&(i=i[0]),i&&(s.deadweight=Number(i.dwt)),s}async suggest(t,a={}){const o="https://www.hifleet.com/hifleetapi/getShipSuggest.do",n={searchParams:{q:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}},i=await x.post(o,n).json();M==null||M.info("[%s] suggest vessel props from: %s - %j",a.requestId,o,n);const s=[];for(const r of i)s.push({mmsi:!r.mmsi||isNaN(r.mmsi)?null:Number(r.mmsi),name:r.name,callSign:r.callsign,imo:!r.imo||isNaN(r.imo)?null:Number(r.imo),score:r._score});return s.sort((r,l)=>l.score-r.score),s}async trajectory(t,a,o,n,i=!0,s={}){var m,d,f;const r=await this.realTimePosition(t,s);let l=w(a);const u=w(o),c=w();if(i){let y=u.diff(l,"d",!0);y<0?l=u.clone().subtract(40,"d"):y<30?l.subtract(10,"d"):y<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),y=c.diff(u,"d",!0),u.add(y>10?240:y*24,"h")}const h={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:l.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},I="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",b=await x.get(I,h).json();M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,I,h);let S;b&&(S=((d=(m=b.ships)==null?void 0:m.offors)==null?void 0:d.ship)||[],S.length||M==null||M.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const k=[];let g=-1;const v=w(`${(f=S==null?void 0:S[0])==null?void 0:f.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const y of S){for(const R in y)!isNaN(y[R])&&Number(y[R])!==1/0&&(y[R]=Number(y[R]));const C=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),P={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:C.unix(),utc:C.utc().format(),status:y.status,labelCn:L,labelEn:p,method:"trajectory",vendor:"hifleet"},N=Math.floor(C.diff(v,"minute",!0)/(n||1));N!==g&&(g=N,k.push(P))}return k}}class bt extends G{constructor(t){super();_(this,"token");this.token=t}async realTimePosition(t,a={}){const o={searchParams:{id:t,k:this.token,enc:1}},n="https://api.shipxy.com/apicall/GetSingleShip",i=await x.get(n,o).json();if(M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,n,o),(i==null?void 0:i.status)!==0)return i;const s=i.data[0];for(const h in s)!isNaN(s[h])&&Number(s[h])!==1/0&&(s[h]=Number(s[h]));const{labelCn:r,labelEn:l}=await this.parseStatus(s.navistat),u=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:u.utc().format(),status:s.navistat,labelEn:l,labelCn:r,method:"position",vendor:"shipxy"}}async trajectory(t,a,o,n,i=!0,s={}){var v;const r=await this.realTimePosition(t,s),l=w(a),u=w(o),c="https://api.shipxy.com/apicall/GetShipTrack",h={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:l.unix(),etm:u.unix()}},I=await x.get(c,h).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",s.requestId,c,h),(I==null?void 0:I.status)!==0)return I;const b=I==null?void 0:I.points,S=[],k=w.unix((v=b[0])==null?void 0:v.utc);let g=-1;for(const m of b){const d=w.unix(m.utc),f={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(m.sog*3600/1e3/1852*100)/100,cog:Math.round(m.cog/100*100)/100,lat:Math.round(m.lat/1e6*1e5)/1e5,lng:Math.round(m.lon/1e6*1e5)/1e5,positionTime:d.unix(),utc:d.utc().format(),method:"trajectory",vendor:"shipxy"},y=Math.floor(d.diff(k,"minute",!0)/(n||1));y!==g&&(g=y,S.push(f))}return S}}class gt extends G{constructor(t){super();_(this,"token");this.token=t}async getShipId(t,a={}){const o={headers:{appKey:this.token},json:{mmsiList:t}},n="https://api3.myships.com/sp/ships/getShipIdByMMSI",i=await x.post(n,o).json();return M==null||M.info("[%s] fetch ship id from: %s - %j",a.requestId,n,o),i.code!=="0"?i:i.data[0].shipId}async getShipInfo(t,a={}){const o={headers:{appKey:this.token},json:{shipId:t}},n="https://api3.myships.com/sp/ships/aissta",i=await x.post(n,o).json();if(M==null||M.info("[%s] fetch ship info from: %s - %j",a.requestId,n,o),i.code!=="0")return i;const s=i.data;let r=s.imo;return t==="407170"&&(r="9198379",M==null||M.warn("[%s] ship(%s) imo error: %s, should be %s",a.requestId,t,s.imo,r)),{mmsi:s.mmsi,name:s.shipnameEn,imo:r,callSign:s.callSign,length:s.length,width:s.breadth,draught:(s.draught||100)/10}}async realTimePosition(t,a={}){const o=await this.getShipId(t,a),n=await this.getShipInfo(o,a),i={headers:{appKey:this.token},json:{shipId:o}},s="https://api3.myships.com/sp/ships/position/latest",r=await x.post(s,i).json();M==null||M.info("[%s] fetch realtime position from: %s - %j",a.requestId,s,i);const l=r.data[0];for(const b in l)!isNaN(l[b])&&Number(l[b])!==1/0&&(l[b]=Number(l[b]));const{labelCn:u,labelEn:c}=await this.parseStatus(l.aisNavStatus),h=w.unix(l.posTime);return{...n,mmsi:t,lat:Math.round(l.lat/1e4/60*1e5)/1e5,lng:Math.round(l.lon/1e4/60*1e5)/1e5,sog:Math.round(l.sog/10*100)/100,cog:Math.round(l.cog/10*100)/100,hdg:Math.round(l.heading*100)/100,rot:Math.round(l.rot*100)/100,positionTime:l.posTime,utc:h.utc().format(),status:l.aisNavStatus,labelEn:c,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,a,o,n,i=!0,s={}){const r=w(a),l=w(o),u=await this.getShipId(t),c=await this.getShipInfo(u),h=[];for(;l.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(u,r.unix(),r.add(30,"day").unix(),c,t,n,h);return await this.trajectoryIn30Day(u,r.unix(),l.unix(),c,t,n,h),h}async trajectoryIn30Day(t,a,o,n,i,s,r,l={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:a,endTime:o}},c="https://api3.myships.com/sp/ships/position/history",h=await x.post(c,u).json();if(M==null||M.info("[%s] fetch trajectory from: %s - %j",l.requestId,c,u),h.code!=="0")return M==null||M.warn("[%s] invoke myship trajectory failed: %j",l.requestId,h),h;const I=h.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 S=-1;for(const g of I){const v=w.unix(g.posTime),m={imo:n==null?void 0:n.imo,mmsi:i,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)/(s||1));d!==S&&(S=d,r.push(m))}return r}}let J;try{J=U.getLogger("vessel")}catch{}finally{}var ut=(A=>(A.NOTICE="NOTICE",A.WARN="WARN",A.HEAVY="HEAVY",A.SEVERE="SEVERE",A.ERROR="ERROR",A.FATAL="FATAL",A))(ut||{});class lt{parsePrinciple(e,t={}){var s,r,l;J==null||J.debug("[%s] parse rule: %s",t.requestId,e);const a=new RegExp("(?<=\\[)(.+)(?=])","g"),o=e.match(a)?(s=e.match(a))==null?void 0:s[0]:void 0,n=o==null?void 0:o.split(";");if(!n)return;const i={};for(let u=0;u<(n==null?void 0:n.length);u++){const c=(l=(r=n[u].match(a))==null?void 0:r[0])==null?void 0:l.split("],");if(u===0&&!c)i.scope=n[0];else if(c)for(let h=0,I=c.length;h<I;h++){const b=this.parseRule(c[h]);b&&(i[b.level]?b.key?i[b.level][b==null?void 0:b.key]=b:i[b.level]=b:b.key?i[b.level]={[b==null?void 0:b.key]:b}:i[b.level]=b)}}return i}parseRule(e,t={}){var i;J==null||J.debug("[%s] parse rule: %s",t.requestId,e),e=e.startsWith("[")?e:`[${e}`,e=e.endsWith("]")?e:`${e}]`;const a=new RegExp("(?<=\\[)(.+?)(?=])","g"),o=(i=e==null?void 0:e.match(a))==null?void 0:i[0],n=o==null?void 0:o.split(",");if(n){let s=n[3]==="Number.MAX_VALUE"?100:Number(n[3]);return s=isNaN(s)?1:s,{operator:n[0],number:Number.isNaN(Number(n[1]))?n[1]:Number(n[1]),level:n[2],time:s,key:n[4]}}}checkWeather(e,t,a={}){var b,S,k,g,v,m,d,f,y,C,p,L,P,N,R;let o=0,n=0,i=0,s=0;const r=Math.round(((S=(b=t==null?void 0:t.SEVERE)==null?void 0:b.sigWave)==null?void 0:S.number)*1.6*100)/100,l=(g=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:g.number,u=(m=(v=t==null?void 0:t.HEAVY)==null?void 0:v.sigWave)==null?void 0:m.number,c=Math.round((((f=(d=t==null?void 0:t.SEVERE)==null?void 0:d.wind)==null?void 0:f.number)+2)*100)/100,h=(C=(y=t==null?void 0:t.SEVERE)==null?void 0:y.wind)==null?void 0:C.number,I=(L=(p=t==null?void 0:t.HEAVY)==null?void 0:p.wind)==null?void 0:L.number;for(let E=0;E<(e==null?void 0:e.length);E++){const H=e[E],V=(N=(P=H==null?void 0:H.meteo)==null?void 0:P.wave)==null?void 0:N.sig,B=(R=H==null?void 0:H.meteo)==null?void 0:R.wind,K=E?w(H.eta).diff(w(e[E-1].eta),"hour",!0):0;s=K>s?K:s,J==null||J.debug("[%s] check sig.wave: %j",a.requestId,{...V,dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}),(V==null?void 0:V.height)>=r?H.isDangerous=!0:(V==null?void 0:V.height)>=l?H.isSevere=!0:(V==null?void 0:V.height)>=u&&(H.isHeavy=!0),J==null||J.debug("[%s] check wind: %j",a.requestId,{...B,dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I}),(B==null?void 0:B.scale)>=c?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(B==null?void 0:B.scale)>h?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(B==null?void 0:B.scale)===I&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),o+=H.isDangerous?K:0,n+=H.isSevere?K:0,i+=H.isHeavy?K:0}return o=Math.round(o*100)/100,n=Math.round(n*100)/100,i=Math.round(i*100)/100,s=Math.round(s),{sample:e,dangerous:o,severe:n,heavy:i,step:s<3?3:s,wind:{dgThd4Wd:c,svThd4Wd:h,hvThd4Wd:I},sig:{dgThd4Wv:r,svThd4Wv:l,hvThd4Wv:u}}}}const vt=new lt;let T;try{T=U.getLogger("vessel")}catch{}finally{}const wt=new yt.MeteoHelper2("",!0);var ht=(A=>(A.common="common",A.container="container",A.tugs="tugs",A))(ht||{}),ft=(A=>(A.Ballast="Ballast",A.Laden="Laden",A))(ft||{}),mt=(A=>(A.Cp="CP",A.Perf="Basis",A.Instruct="Other",A))(mt||{});class O{static blockCoefficient(e,t,a,o){let n=Math.round(e/(t*a*o)*100)/100;n=n<.55?.55:n>.85?.85:n;const i=[.55,.6,.65,.7,.75,.8,.85],s=i.map(r=>Math.abs(r-n));return i[s.indexOf(Math.min(...s))]}static froudeNumber(e,t,a=9.8){let o=Math.round(Math.sqrt(e*e/(a*t))*100)/100;return o=o<.05?.05:o>.3?.3:o,o}static amendFactor(e,t,a){const o={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let i={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[e];return a==="Laden"&&(i=o[e]),i[0]+i[1]*t+i[2]*Math.pow(t,2)}static directionFactor(e,t=0){let a;return e>30&&e<=60?a=(1.7-.03*Math.pow(t-4,2))/2:e>60&&e<=150?a=(.9-.06*Math.pow(t-6,2))/2:e>150&&e<=180?a=(.4-.03*Math.pow(t-8,2))/2:a=1,Math.round(a*1e5)/1e5}static vesselTagFactor(e,t,a,o){let n;return a==="container"?n=.7*o/2+Math.pow(o,3)/(22*Math.pow(e,2/3)):t==="Ballast"?n=.7*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)):n=.5*o/2+Math.pow(o,3)/(2.7*Math.pow(e,2/3)),n}static waveHeightFactor(e,t){e=e<3?e*.7:e,e=e<0?.2:e,e=e>6?e-.9*(e-6):e,e=e>9?9:e;let a;return t>30&&t<=60?a=-.6:t>60&&t<=90?a=-.4:t>90&&t<=120?a=e<3?.4:-.3:t>120&&t<=150?a=e<3?.6:-.5:t>150&&t<=180?a=e<3?.7:-.6:a=-.7,Math.round(a*(.144*Math.pow(e,2)+.278*e)*1e4)/1e4}static assembleProperties(e,t,a,o){var h;const n=e.lbp??e.length??e.lengthOverall??198.9642,i=e.draught??8,s=e.breadthMoulded??e.breadth??e.breadthExtreme??32.4572,r=e.deadweight??67035.7773,l=((h=e==null?void 0:e.type)==null?void 0:h.toLowerCase())||"common";return{tag:l.indexOf("container")>-1?"container":l.indexOf("tugs")>-1?"tugs":"common",lbp:n,loadCondition:t,draught:i,breadthMoulded:s,displacement:Math.round((r/1.025+i*s*n*.7)*1e4)/1e4,speed:Math.round((a??14.1382)*1852/3600*1e4)/1e4,bearing:o||90}}static async speedLoseAt(e,t,a,o="",n=2,i=!0,s=!1,r={}){let l;if(t.velocity&&s&&(e.speed=F.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),i){let u;try{o=(o==null?void 0:o.toUpperCase())==="CMEMS"?"ECMWF":o,o=(o==null?void 0:o.toUpperCase())==="METEO2"?"best_match":o;const{weatherModels:S,marineModels:k}=await ot.Meteo2Assist.autoPickMeteoModel(o),g=await wt.spotForecast(t.lat,t.lng,a.utc().format(),!1,!1,!0,{...r,pastDays:1,forecastDays:1,weatherModels:S,marineModels:k}),[v]=ot.Meteo2Assist.pickHourly(g,a);u=ot.Meteo2Assist.toLegacy(v)}catch(S){T.warn("[%s] meteo2 spot(%j) forecast failed: %s",r.requestId,{...t,eta:a.utc().format(),source:o},S)}let c=O.currentFactor(e.bearing,u==null?void 0:u.current,n),h=O.weatherFactor(e,u,c);const I=e.speed*1.943844;for(;I+c+h<=0;)T.warn("[%s] v0(%.2d) is less then factor(%.2d) = wxFactor(%.2d) + cFactor(%.2d), scale factor with 0.6",r.requestId,I,h+c,h,c),c=c*.6,h=h*.6;const b=Math.round((I+c+h)*100)/100;l={meteo:{...u},wxFactor:h,cFactor:c,speed:t.velocity&&s?t.velocity:b<0?1:b,eta:a.utc().format(),etd:a.utc().format()}}else l={wxFactor:0,cFactor:0,speed:t.velocity&&s?t.velocity:Math.round(e.speed*1.943844*100)/100,eta:a.utc().format(),etd:a.utc().format()};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...l,...t}}static async speedLoseInHoursStep(e,t,a,o,n,i,s="",r=!0,l=!1,u={}){t.utc();const c=t.clone().add(14,"days"),h=[],I=[],b=[];let S=0,k=0,g,v;for(let m=0;m<i.length-1;m++){let d=i[m];d.distanceFromStart=Math.round((n+k)*1e3)/1e3;const f=i[m+1];if(e.bearing=F.LaneHelper.calculateBearing(d,f,!f.gcToPrevious),d.bearing=e.bearing,d.suspend&&l){d.eta=d.eta||t.utc().format(),d.elapsed=d.elapsed??0;const p=d.suspend-d.elapsed;if(o-S>p)o=o-S-p,t.add(p,"hour"),d.elapsed=d.suspend;else{const L=o-S;d.elapsed+=L,t.add(L,"hour"),o=0}if(T==null||T.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`,u.requestId,d),o===0)return d.distanceFromPrevious=k,{etd:t,from:v||d,to:d,next:i.filter(L=>L),wps:h,days:I,all:b}}else d.suspend=0;r=t.isAfter(c)?!1:r,d=await O.speedLoseAt(e,d,t,s,0,r,l,u),b.push(d),v=v||d,d.important&&h.push(d),t.isSameOrAfter(a)&&(I.push(d),a.add(24,"hour"));const y=F.LaneHelper.calculateDistance(d,f,!f.gcToPrevious);let C=Math.round(y/v.speed*1e5)/1e5;if(S+C<o){if(S+=C,t.add(C,"hour"),delete i[m],T==null||T.debug(`[%s] go to %j from %j with ${y}nm, and cost ${C} hours`,u.requestId,{lat:f.lat,lng:f.lng},{lat:v.lat,lng:v.lng,etd:v.etd}),k+=y,i.filter(p=>p).length<=1){g=f,g.eta=t.utc().format(),g.distanceFromPrevious=y,g.distanceFromStart=Math.round((n+k)*1e4)/1e4,h.push(g),b.push(g),delete i[m+1];break}}else{C=o-S,t.add(C,"hour");const p=F.LngLatHelper.roundPrecision(v.speed*C,5);g=F.LaneHelper.calculateCoordinate(d,e.bearing,p,"nauticalmiles",!f.gcToPrevious),g.eta=t.utc().format(),i[m]=g,T==null||T.debug(`[%s] go to %j from %j with ${p}nm, and cost ${C} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:d.lat,lng:d.lng,etd:d.etd}),k+=p,g.distanceFromPrevious=Math.round(k*1e4)/1e4,g.distanceFromStart=Math.round((n+k)*1e4)/1e4;break}}return{etd:t,from:v,to:g,next:i.filter(m=>m),wps:h,days:I,all:b}}static currentFactor(e,t,a=0){const o=F.LaneHelper.includedAngle(e,(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(o)===Math.PI/2)return 0;let n=((t==null?void 0:t.kts)||0)*Math.cos(o);return a&2?n=Math.ceil(n*100)/100:a&1?n=Math.floor(n*100)/100:n=Math.round(n*100)/100,Math.abs(n)>5?0:n}static weatherFactor(e,t,a=0){var I,b,S,k,g,v,m;T==null||T.debug("calculate weather factor via: %j",{...e,...t});const o=O.blockCoefficient(e.displacement,e.lbp,e.breadthMoulded,e.draught),n=F.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=F.LaneHelper.includedAngle(e.bearing,(I=t==null?void 0:t.wind)==null?void 0:I.degree);const l=O.directionFactor(r,(b=t==null?void 0:t.wind)==null?void 0:b.scale),u=O.vesselTagFactor(e.displacement,e.loadCondition,e.tag,(S=t==null?void 0:t.wind)==null?void 0:S.kts);let c=l*s*u/100*(e.speed-n);c=Math.round(c*1.943844*1e4)/1e4*-1,e.tag==="tugs"&&Math.abs(c)>1&&(c=c/(Math.abs(Math.round(c))+1)),T==null||T.debug("wind wx factor = %d",c),r=F.LaneHelper.includedAngle(e.bearing,(g=(k=t==null?void 0:t.wave)==null?void 0:k.sig)==null?void 0:g.degree);const h=O.waveHeightFactor(((m=(v=t==null?void 0:t.wave)==null?void 0:v.sig)==null?void 0:m.height)??1,r);return T==null||T.debug("wave wx factor = %d",h),c=Math.abs(c)>Math.abs(h)?c:c*.3+h*.7,T==null||T.debug("weather factor = %d",c),c=Math.abs(c)>3?3*(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((a,o)=>(o.positionTime||(o.positionTime=w.utc(o.etd||o.eta).unix()),a.some(n=>Math.floor(n.positionTime/t)===Math.floor(o.positionTime/t))||a.push(o),a),[]),e}static async reduceWPS(e,t=60){return e=e==null?void 0:e.reduce((a,o)=>(a.some(n=>Math.floor(w(n.etd).unix()/t)===Math.floor(w(o.etd).unix()/t))||a.push(o),a),[]),e}static async analyseInstant(e,t,a,o,n,i="",s=0,r=!0,l=!1,u={}){var X,Q,Z,$,tt,et;const c=w().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{route:h,waypoints:I}=n.points,b=F.LaneHelper.calculateSubRoute(e,h);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:S,label:k}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:o.speed,label:"CP"},g=O.assembleProperties(a,o.loadCondition,S,0),v=I.length?F.LaneHelper.calculateSubWaypoints(e,I):[];v.forEach(q=>q.important=!0);const m={from:{...e},route:b,waypoints:v,v0:S,label:k},d={hours:[],days:[],wps:[],all:[]};s||(F.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let f=F.LaneHelper.simplifyRouteToCoordinates(b,v,0),y=0,C=0,p=0,L=0;t=w(t).utc();const P=t.clone();for(;f.length>0;){const q=s-t.hour()%s,z=Math.ceil(t.clone().add(q,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,j=await O.speedLoseInHoursStep(g,t,P,z,y,f,i,r,l,u);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)),f=j==null?void 0:j.next,!f.length){const W=await O.speedLoseAt(g,j.to,w(j.to.eta),i,0,r,l,u);W.bearing=g.bearing,d.hours.push(W),d.all.push(W)}y+=Math.round((((Z=j==null?void 0:j.to)==null?void 0:Z.distanceFromPrevious)??0)*1e4)/1e4}const N=d.hours;for(let q=0;q<N.length-1;q++){const z=w(N[q+1].eta).diff(N[q].etd,"hour",!0)||1;C+=(N[q].wxFactor||0)*z,p+=(N[q].cFactor||0)*z,L+=z}const R=N.reduce((q,z)=>q+(z.suspend||0),0);($=d.wps)==null||$.forEach((q,z)=>{q.positionTime=w.utc(q.etd||q.eta).unix();const j=d.wps[z-1];if(j){const W=q.distanceFromStart-j.distanceFromStart,Y=w(q.eta||q.etd).diff(w(j.etd||j.eta),"h",!0);q.avgSpd=Math.round(W/Y*100)/100,j.bearing=F.LaneHelper.calculateBearing(j,q)}}),d.wps=await O.reduceWPS(d.wps),d.days=await O.reduceDays(d.days),d.all=(tt=d.all)==null?void 0:tt.reduce((q,z)=>(z.positionTime=w.utc(z.etd||z.eta).unix(),q.some(j=>Math.round(j.positionTime/60)===Math.round(z.positionTime/60))||q.push(z),q),[]),m.sample=d;const E=d.hours.at(0),H=d.hours.at(-1);m.distance=Math.round(H.distanceFromStart*1e3)/1e3,m.etd=w(E.eta).utc().format(),m.eta=w(H.eta).utc().format(),m.wxFactor=Math.round(C/L*1e3)/1e3,m.cFactor=Math.round(p/L*1e3)/1e3,m.avgSpeed=Math.round(H.distanceFromStart/L*1e3)/1e3,m.totalHrs=Math.round(L*1e3)/1e3,m.suspend=Math.round(R*1e3)/1e3;const V=F.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(m,o,u),at=F.LngLatHelper.roundPrecision(o.fo/24*(L-K),3),rt=F.LngLatHelper.roundPrecision(o.dgo/24*L+V,3);m.extend={eca:st,distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,totalDgoConsInSuspend:V},m.totalFoCons=at<0?0:at,m.totalDgoCons=rt;const nt=w().valueOf()-c,dt=((et=d==null?void 0:d.hours)==null?void 0:et.length)||1;return T==null||T.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,nt,dt,Math.round(nt/dt*1e3)/1e3),m}static async analyseInstantWithThreshed(e,t,a,o,n,i,s,r="",l=3,u=!0,c=!1,h={}){var Z,$,tt,et,q,z;const I=w().valueOf();e.lng=F.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:S}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},k=O.assembleProperties(o,n.loadCondition,b,0),g=F.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const v=s.length?F.LaneHelper.calculateSubWaypoints(e,s):[];v.forEach(j=>j.important=!0);let m=F.LaneHelper.simplifyRouteToCoordinates(g,v,0),d=0,f=0,y=0,C=0;const p={hours:[],wps:[],days:[],all:[]};t=w(t).utc();const L=t.clone();for(;m.length>0;){const j=l-t.hour()%l;let W=Math.ceil(t.clone().add(j,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;W=t.clone().add(W,"h").isSameOrAfter(a)?a.diff(t,"h",!0)*1e4/1e4:W;const Y=await O.speedLoseInHoursStep(k,t,L,W,d,m,r,u,c,h);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)),m=Y==null?void 0:Y.next,m.length||p.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,!W)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,W)=>(W.positionTime=w.utc(W.etd||W.eta).unix(),j.some(Y=>Math.round(w(Y.etd).unix()/60)===Math.round(w(W.etd).unix()/60))||j.push(W),j),[]),(q=p.wps)==null||q.forEach((j,W)=>{const Y=p.wps[W-1];if(Y){const It=j.distanceFromStart-Y.distanceFromStart,kt=w(j.eta||j.etd).diff(w(Y.etd||Y.eta),"h",!0);Y.bearing=F.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const P=p.hours;for(let j=0;j<P.length-1;j++){const W=w(P[j+1].eta).diff(P[j].etd,"hour",!0);f+=P[j].wxFactor*W,y+=P[j].cFactor*W,C+=W}const N=P.reduce((j,W)=>j+(W.suspend||0),0),R=p.hours.at(0),E=p.hours.at(-1),H=await F.LaneHelper.calculateRangeRoute(R,E,g),V=await F.LaneHelper.calculateRangeWaypoints(R,E,g,v),B={sample:p,distance:Math.round(((E==null?void 0:E.distanceFromStart)||0)*1e4)/1e4,etd:w(R.eta).utc().format(),eta:w(E==null?void 0:E.eta).utc().format(),wxFactor:Math.round(f/C*1e3)/1e3,cFactor:Math.round(y/C*1e3)/1e3,avgSpeed:Math.round(((E==null?void 0:E.distanceFromStart)||0)/C*1e3)/1e3,totalHrs:Math.round(C*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:E,route:H,waypoints:V,v0:b,label:S},K=F.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,h),ct=F.LngLatHelper.roundPrecision(n.fo/24*(C-st),3),nt=F.LngLatHelper.roundPrecision(n.dgo/24*C+K,3);B.extend={eca:rt,distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,totalDgoConsInSuspend:K},B.totalDgoCons=nt,B.totalFoCons=ct<0?0:ct;const X=w().valueOf()-I,Q=((z=p==null?void 0:p.hours)==null?void 0:z.length)||1;return T==null||T.debug("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",h==null?void 0:h.requestId,X,Q,Math.round(X/Q*1e3)/1e3),B}static async analyseCost(e,t,a,o,n={}){var g,v;const i=w().valueOf(),s=[];e.speedStep=e.speedStep||3,e.alterStep=e.alterStep??1;const r=F.LaneHelper.calculateRouteDistance(o.route);let l=0;a.forEach(m=>{const d=Math.ceil(r/m.speed/24);l=l<d?d:l}),l=l*1.3;const u=w.utc(e.etd).add(l??14,"day");let c=1;for(const m of a){const d=JSON.parse(JSON.stringify(o.route)),f=JSON.parse(JSON.stringify(o.waypoints)),y=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,m,d,f,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);y&&(await O.calculateCost(y,m,e,n),s.push(y),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,c,e.etd,u.format(),{cost:y.cost.total,hire:y.cost.hire,bunker:y.cost.bunker,distance:y.distance,hours:y.totalHrs,cp:`${m.speed}/${m.fo}/${m.dgo}`})),c++}s.sort((m,d)=>m.cost.total-d.cost.total);const h=s.at(0),I=s.at(1),b=[];if(b.push({combined:!1,speeds:[h],cost:(g=h.cost)==null?void 0:g.total}),I){const m=h.cost.cp,d=I.cost.cp,f=w(h.eta),y=w(h.etd),C=f.diff(y,"days",!0);let p=Math.ceil(C/2);p=p>7?7:p<e.alterStep?e.alterStep:p;let L=2,P={combined:!1,speeds:[I],cost:(v=I.cost)==null?void 0:v.total},N;for(;p>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[m,d],o,p,{...n,level:L});if(P.cost>R.cost?N?(N==null?void 0:N.cost)>R.cost&&(N=R):(N=P,P=R):(!N||(N==null?void 0:N.cost)>R.cost)&&(N=R),p<=e.alterStep)break;p=Math.ceil(p/2),L+=1}b.push(P),N&&b.push(N)}const k=w().valueOf()-i;return T==null||T.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,k),b.sort((m,d)=>m.cost-d.cost)}static async combinedAnalyse(e,t,a,o,n,i,s={}){s.counter=1,T==null||T.info("[%s][L%d] analyse with alternate cp in every %d days",s.requestId,s.level,i);const r=await O.alternateAnalyse(e,t,a,o,0,n,i,s),l=r.reduce((d,f)=>d+f.cost.total,0),u=r.reduce((d,f)=>d+f.cost.hire,0),c=r.reduce((d,f)=>d+f.cost.bunker,0),h=r.reduce((d,f)=>d+f.distance,0),I=r.reduce((d,f)=>d+f.totalHrs,0);T==null||T.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost:l,hire:u,bunker:c,distance:h,hours:I});const b=await O.alternateAnalyse(e,t,a,o,1,n,i,s),S=b.reduce((d,f)=>d+f.cost.total,0),k=b.reduce((d,f)=>d+f.cost.hire,0),g=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);return T==null||T.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:S,hire:k,bunker:g,distance:v,hours:m}),l<S?{combined:!0,cost:Math.round(l*1e3)/1e3,speeds:r,step:i}:{combined:!0,cost:Math.round(S*1e3)/1e3,speeds:b,step:i}}static async alternateAnalyse(e,t,a,o,n,i,s,r={}){var h,I;let l=w.utc(e.etd);const u={lat:e.lat,lng:e.lng},c=[];for(;l.isBefore(a);){const b=l.clone().utc().add(s,"day"),S=JSON.parse(JSON.stringify(i.route)),k=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],v=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,S,k,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,r);v&&(await O.calculateCost(v,g,e,r),T==null||T.info("[%s][L%d-%d] analyse from %s to %s cost: %j",r.requestId,r.level,r.counter,l.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 m=(I=(h=v==null?void 0:v.sample)==null?void 0:h.hours)==null?void 0:I.at(-1);if(m)u.lat=m.lat,u.lng=m.lng,l=w(m.eta),c.push(v),n=n?0:1;else break}return c}static async calculateCost(e,t,a,o={}){var n;if(e){const i=(a.addComm||0)>=1?(a.addComm||0)/100:a.addComm||0,s=Math.round((a.dailyHire||0)*(e.suspend||0)/24*1e3)/1e3,r=Math.round(e.totalHrs/24*(a.dailyHire||0)*(1-i)*1e3)/1e3+s,l=Math.round(e.totalFoCons*(a.priceFO||0)*1e3)/1e3,u=Math.round((e.totalDgoCons+(((n=e.extend)==null?void 0:n.totalDgoConsInECA)||0))*(a.priceDGO||0)*1e3)/1e3;e.cost={total:Math.round((r+l+u)*1e3)/1e3,hire:Math.round(r*1e3)/1e3,suspendHire:s,bunker:Math.round((l+u)*1e3)/1e3,cp:t}}return e}static async calculateECA(e,t,a={}){var r,l,u,c;const o=await F.LaneHelper.intersectInECA((e==null?void 0:e.route)||[]);let n=0,i=0,s=0;(l=(r=e==null?void 0:e.sample)==null?void 0:r.wps)==null||l.forEach(h=>{h.positionTime=w.utc(h.etd||h.eta).unix()});for(const h of o){n+=h.distance;const I=await F.LaneHelper.deadReckoningTime((u=h.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await F.LaneHelper.deadReckoningTime((c=h.waypoints)==null?void 0:c.at(-1),e.sample.all||e.sample.wps);h.in=I,h.out=b,h.totalHrs=F.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),h.totalDgoCons=F.LngLatHelper.roundPrecision(t.fo/24*h.totalHrs,3),i+=h.totalHrs,s+=h.totalDgoCons}return n=F.LngLatHelper.roundPrecision(n,3),i=F.LngLatHelper.roundPrecision(i,3),s=F.LngLatHelper.roundPrecision(s,3),{distanceInECA:n,hoursInECA:i,totalDgoConsInECA:s,eca:o}}static async mergeSpeeds(e,t={}){var m,d;const a={hours:[],wps:[],days:[]},o=e.reduce((f,y)=>f+y.distance,0),n=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.distanceInECA)||0)},0),i=e.reduce((f,y)=>f+y.totalHrs,0),s=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.hoursInECA)||0)},0),r=e.reduce((f,y)=>{var C;return f+(((C=y.extend)==null?void 0:C.totalDgoConsInECA)||0)},0),l=e.reduce((f,y)=>f+y.wxFactor*y.totalHrs/i,0),u=e.reduce((f,y)=>f+y.cFactor*y.totalHrs/i,0),c=e.reduce((f,y)=>f+y.totalFoCons,0),h=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),S=e.reduce((f,y)=>f+y.cost.bunker,0),k=[],g=[];let v;for(const f of e){g.push(...((m=f.extend)==null?void 0:m.eca)||[]);const y=f.sample.hours,C=f.sample.wps,p=f.sample.days,L=y.at(0);v&&(L.distanceFromPrevious=v.distanceFromPrevious,L.distanceFromStart=v.distanceFromStart,y.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)}),C.at(0).distanceFromPrevious=v.distanceFromPrevious,C.at(0).distanceFromStart=v.distanceFromStart,C.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)}),p.at(0).distanceFromPrevious=v.distanceFromPrevious,p.at(0).distanceFromStart=v.distanceFromStart,p.forEach((E,H)=>{H&&(E.distanceFromStart=E.distanceFromStart+v.distanceFromStart)})),L.cp=f.cost.cp;const P=[f.etd,f.eta],N=k.findIndex(E=>E.id===L.cp.id);N===-1?(L.cp.segment=[P],k.push(L.cp)):k[N].segment.push(P),y.forEach(E=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.hours.push(E)}),C.forEach(E=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.wps.push(E)}),p.forEach(E=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===E.eta))===-1&&a.days.push(E)});const R=(d=a.wps)==null?void 0:d.findIndex(E=>E.eta===L.eta);R===-1?a.wps.push(L):a.wps[R]=L,v=y.at(-1)}return a.wps.sort((f,y)=>w(f.etd).unix()-w(y.etd).unix()),a.wps.forEach((f,y)=>{const C=a.wps[y-1];if(C){const p=f.distanceFromStart-(C.distanceFromStart||0),L=w(f.eta||f.etd).diff(w(C.etd||C.eta),"hour",!0),P=Math.round(p/L*100)/100;f.avgSpd=P;const N=F.LaneHelper.calculateBearing(C,f);C.bearing=N}}),{sample:a,etd:e.at(0).etd,eta:e.at(-1).eta,from:e.at(0).from,to:e.at(-1).to,v0:e.at(0).v0,label:"Combined",distance:Math.round(o*1e3)/1e3,totalHrs:Math.round(i*1e3)/1e3,avgSpeed:Math.round(o/i*1e3)/1e3,wxFactor:Math.round(l*1e3)/1e3,cFactor:Math.round(u*1e3)/1e3,totalFoCons:Math.round(c*1e3)/1e3,totalDgoCons:Math.round(h*1e3)/1e3,cost:{total:Math.round(I*1e3)/1e3,hire:Math.round(b*1e3)/1e3,bunker:Math.round(S*1e3)/1e3},extend:{cps:k,eca:g,distanceInECA:Math.round(n*1e3)/1e3,hoursInECA:Math.round(s*1e3)/1e3,totalDgoConsInECA:Math.round(r*1e3)/1e3,speeds:e}}}}D.AISImpl=G,D.AlertHelper=lt,D.AlertLevel=ut,D.HifleetImpl=Mt,D.LoadCondition=ft,D.MyShipImpl=gt,D.MyVesselImpl=pt,D.ShipxyImpl=bt,D.SpeedHelper=O,D.SpeedLabel=mt,D.VesselTag=ht,D.alertHelper=vt,Object.defineProperty(D,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.5.4",
4
+ "version": "3.5.6",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [