@idm-plugin/vessel 3.5.0 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7,9 +7,9 @@ import w from "moment";
7
7
  import { LaneHelper as O, LngLatHelper as z } from "@idm-plugin/geo2";
8
8
  import { MeteoHelper2 as ft } from "@idm-plugin/meteo2";
9
9
  import { Meteo2Assist as ct } from "@idm-plugin/meteo";
10
- let M;
10
+ let g;
11
11
  try {
12
- M = dt.getLogger("vessel");
12
+ g = dt.getLogger("vessel");
13
13
  } catch {
14
14
  } finally {
15
15
  }
@@ -70,7 +70,7 @@ class jt extends at {
70
70
  grant_type: "client_credentials"
71
71
  }
72
72
  }, n = await B.post(a, o).json();
73
- M == null || M.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
73
+ g == null || g.info("[%s] fetch access token from: %s - %j", t.requestId, a, n), n.error || (this.token = {
74
74
  accessToken: n.access_token,
75
75
  tokenType: n.token_type,
76
76
  expiresIn: n.expires_in,
@@ -100,9 +100,9 @@ class jt extends at {
100
100
  recordNum: a.ps || 10
101
101
  }
102
102
  };
103
- M == null || M.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, o, n);
103
+ g == null || g.info("[%s] fetch suggest vessels from: %s - %j", a.requestId, o, n);
104
104
  const i = await B.post(o, n).json();
105
- 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) => ({
105
+ return i.status !== 200 ? (g == null || g.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), []) : (i.data || []).map((u) => ({
106
106
  mmsi: u.mmsi,
107
107
  name: u.nameEn,
108
108
  nameCn: u.nameCn,
@@ -128,10 +128,10 @@ class jt extends at {
128
128
  },
129
129
  searchParams: i
130
130
  };
131
- M == null || M.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
131
+ g == null || g.info("[%s] fetch vessel from: %s - %j", a.requestId, n, s);
132
132
  const r = await B.get(n, s).json();
133
133
  if (r.status !== 200)
134
- return M == null || M.warn("[%s] fetch suggest vessels failed: %j", a.requestId, { message: r.message, status: r.status, code: r.code }), {};
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
136
  const d = r.data;
137
137
  if (d)
@@ -172,9 +172,9 @@ class jt extends at {
172
172
  mmsiList: typeof t == "number" ? [t] : t
173
173
  }
174
174
  };
175
- M == null || M.info("[%s] fetch vessel archive from: %s - %j", a.requestId, o, n);
175
+ g == null || g.info("[%s] fetch vessel archive from: %s - %j", a.requestId, o, n);
176
176
  const i = await B.post(o, n).json();
177
- 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;
177
+ return i.status !== 200 ? (g == null || g.warn("[%s] fetch vessel archive failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), {}) : i.data;
178
178
  }
179
179
  async realTimePosition(t, a = {}) {
180
180
  var r, l;
@@ -185,10 +185,10 @@ class jt extends at {
185
185
  },
186
186
  searchParams: { mmsi: t }
187
187
  };
188
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
188
+ g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
189
189
  const i = await B.get(o, n).json();
190
190
  if (i.code)
191
- return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), i;
191
+ return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId, { message: i.message, status: i.status, code: i.code }), i;
192
192
  const s = i.data;
193
193
  for (const u in s)
194
194
  !isNaN(s[u]) && Number(s[u]) !== 1 / 0 && (s[u] = Number(s[u]));
@@ -240,13 +240,9 @@ class jt extends at {
240
240
  var k, b, S;
241
241
  const r = w();
242
242
  await this.checkToken(s);
243
- const l = "https://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes", u = {
244
- endPoint: {
245
- lon: a.lng,
246
- lat: a.lat
247
- },
243
+ const l = "https://market.myvessel.cn/sdc/v1/mkt/routes/plan", u = {
248
244
  maxDraught: s.draught || 10,
249
- useAIModel: s.useAIModel || !1,
245
+ useAIModel: s.useAIModel ?? !0,
250
246
  withECA: s.withECA || !1,
251
247
  withSpecialRegion: s.withSpecial || !1
252
248
  };
@@ -263,12 +259,12 @@ class jt extends at {
263
259
  },
264
260
  json: u
265
261
  };
266
- M == null || M.info("[%s] fetch route from: %s - %j", s.requestId, l, d);
262
+ g == null || g.info("[%s] fetch route from: %s - %j", s.requestId, l, d);
267
263
  const y = await B.post(l, d).json();
268
264
  if (y.status !== 200)
269
- return M == null || M.warn("[%s] fetch route failed: %j", s.requestId, { message: y.message, status: y.status, code: y.code }), {};
265
+ return g == null || g.warn("[%s] fetch route failed: %j", s.requestId, { message: y.message, status: y.status, code: y.code }), {};
270
266
  {
271
- const C = {
267
+ const I = {
272
268
  status: "Success",
273
269
  nodes: [],
274
270
  seas: [],
@@ -277,65 +273,65 @@ class jt extends at {
277
273
  route: [],
278
274
  distance: 0,
279
275
  memo: ""
280
- }, { nodes: p, seas: v, tracks: m, specialRegions: c } = y.data;
281
- C.nodes = p == null ? void 0 : p.map((g) => ({
282
- code: g.nodeCode,
283
- nameEn: g.nameEn,
284
- nameCn: g.nameCn,
276
+ }, { nodes: p, seas: v, tracks: m, specialRegions: c, ecaLength: h } = y.data;
277
+ I.nodes = p == null ? void 0 : p.map((M) => ({
278
+ code: M.nodeCode,
279
+ nameEn: M.nameEn,
280
+ nameCn: M.nameCn,
285
281
  // 中心
286
282
  center: {
287
- lat: Math.round(g.lat * 1e6) / 1e6,
288
- lng: Math.round(g.lon * 1e6) / 1e6
283
+ lat: Math.round(M.lat * 1e6) / 1e6,
284
+ lng: Math.round(M.lon * 1e6) / 1e6
289
285
  },
290
286
  // 起点
291
287
  start: {
292
- lat: Math.round(g.startLat * 1e6) / 1e6,
293
- lng: Math.round(g.startLon * 1e6) / 1e6
288
+ lat: Math.round(M.startLat * 1e6) / 1e6,
289
+ lng: Math.round(M.startLon * 1e6) / 1e6
294
290
  },
295
291
  // 终点
296
292
  end: {
297
- lat: Math.round(g.endLat * 1e6) / 1e6,
298
- lng: Math.round(g.endLat * 1e6) / 1e6
293
+ lat: Math.round(M.endLat * 1e6) / 1e6,
294
+ lng: Math.round(M.endLat * 1e6) / 1e6
299
295
  },
300
296
  // 是否为不可避开关键节点
301
- isKey: g.isKeyNode,
297
+ isKey: M.isKeyNode,
302
298
  // 重要枢纽节点
303
- isHub: g.isHubNode
304
- })), C.seas = v == null ? void 0 : v.map((g) => ({
305
- code: g.mrgidSea,
306
- nameEn: g.nameEn,
307
- nameCn: g.nameCn,
299
+ isHub: M.isHubNode
300
+ })), I.seas = v == null ? void 0 : v.map((M) => ({
301
+ code: M.mrgidSea,
302
+ nameEn: M.nameEn,
303
+ nameCn: M.nameCn,
308
304
  center: {
309
- lat: Math.round(g.centerLat * 1e6) / 1e6,
310
- lng: Math.round(g.centerLon * 1e6) / 1e6
305
+ lat: Math.round(M.centerLat * 1e6) / 1e6,
306
+ lng: Math.round(M.centerLon * 1e6) / 1e6
311
307
  },
312
308
  min: {
313
- lat: Math.round(g.minLat * 1e6) / 1e6,
314
- lng: Math.round(g.minLon * 1e6) / 1e6
309
+ lat: Math.round(M.minLat * 1e6) / 1e6,
310
+ lng: Math.round(M.minLon * 1e6) / 1e6
315
311
  },
316
312
  max: {
317
- lat: Math.round(g.maxLat * 1e6) / 1e6,
318
- lng: Math.round(g.maxLon * 1e6) / 1e6
313
+ lat: Math.round(M.maxLat * 1e6) / 1e6,
314
+ lng: Math.round(M.maxLon * 1e6) / 1e6
319
315
  },
320
- level: g.mapLevel
321
- })), c == null || c.map((g) => {
322
- g.regionLength && C.regions.push({
323
- type: g.regionType,
324
- distance: g.regionLength,
325
- rows: g.regions.map((I) => ({
326
- code: I.regionCode,
327
- nameCn: I.nameCn,
328
- nameEn: I.nameEn,
329
- type: I.regionType,
330
- distance: I.length
316
+ level: M.mapLevel
317
+ })), c == null || c.map((M) => {
318
+ M.regionLength && I.regions.push({
319
+ type: M.regionType,
320
+ distance: M.regionLength,
321
+ rows: M.regions.map((j) => ({
322
+ code: j.regionCode,
323
+ nameCn: j.nameCn,
324
+ nameEn: j.nameEn,
325
+ type: j.regionType,
326
+ distance: j.length
331
327
  }))
332
328
  });
333
- }), C.waypoints = m == null ? void 0 : m.map((g) => ({
334
- lat: Math.round(g.lat * 1e5) / 1e5,
335
- lng: Math.round(g.lon * 1e5) / 1e5
336
- })), (S = C.waypoints) != null && S.length && (C.waypoints = O.simplifyCoordinates(C.waypoints), C.route = O.divideAccordingToLng(C.waypoints), C.distance = O.calculateRouteDistance(C.route));
337
- const h = w().diff(r, "second");
338
- return C.memo = `time cost: ${h}s`, M.info("[%s] calculate route cost: %d seconds", s.requestId, h), C;
329
+ }), I.waypoints = m == null ? void 0 : m.map((M) => ({
330
+ lat: Math.round(M.lat * 1e5) / 1e5,
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);
333
+ const C = w().diff(r, "second");
334
+ return I.memo = `time cost: ${C}s`, g.info("[%s] calculate route cost: %d seconds", s.requestId, C), I;
339
335
  }
340
336
  }
341
337
  async trajectory(t, a, o, n, i = !0, s = {}) {
@@ -346,7 +342,7 @@ class jt extends at {
346
342
  return await this.trajectoryIn30Day(t, l, u, r, n, d, s), d;
347
343
  }
348
344
  async trajectoryIn30Day(t, a, o, n, i, s, r = {}) {
349
- var b, S, C, p, v;
345
+ var b, S, I, p, v;
350
346
  const l = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
351
347
  headers: {
352
348
  Authorization: `${(b = this.token) == null ? void 0 : b.tokenType} ${(S = this.token) == null ? void 0 : S.accessToken}`
@@ -357,16 +353,16 @@ class jt extends at {
357
353
  endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
358
354
  }
359
355
  };
360
- M == null || M.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
356
+ g == null || g.info("[%s] fetch trajectory from: %s - %j", r.requestId, l, u);
361
357
  const d = await B.post(l, u).json();
362
358
  if (d.code)
363
- return M == null || M.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: d.message, status: d.status, code: d.code }), d;
359
+ return g == null || g.warn("[%s] fetch trajectory failed: %j", r.requestId, l, { message: d.message, status: d.status, code: d.code }), d;
364
360
  let y = -1;
365
- const k = w(`${(p = (C = d.data) == null ? void 0 : C[0]) == null ? void 0 : p.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
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");
366
362
  return (v = d.data) == null || v.forEach((m) => {
367
363
  for (const P in m)
368
364
  !isNaN(m[P]) && Number(m[P]) !== 1 / 0 && (m[P] = Number(m[P]));
369
- const c = w(`${m.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), f = m.status, { labelCn: h, labelEn: g } = this.parseStatus(f), I = {
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 = {
370
366
  mmsi: m.mmsi,
371
367
  imo: n == null ? void 0 : n.imo,
372
368
  lat: m.lat,
@@ -375,17 +371,17 @@ class jt extends at {
375
371
  cog: m.cog,
376
372
  hdg: m.hdg,
377
373
  draught: m.draught,
378
- status: f,
374
+ status: h,
379
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,
380
376
  destination: m.dest,
381
377
  positionTime: c.unix(),
382
- labelCn: h,
383
- labelEn: g,
378
+ labelCn: f,
379
+ labelEn: C,
384
380
  method: "trajectory",
385
381
  vendor: "myVessel",
386
382
  utc: c.utc().format()
387
- }, F = Math.floor(c.diff(k, "minute", !0) / (i || 1));
388
- F !== y && (y = F, s.push(I));
383
+ }, j = Math.floor(c.diff(k, "minute", !0) / (i || 1));
384
+ j !== y && (y = j, s.push(M));
389
385
  }), s;
390
386
  }
391
387
  }
@@ -402,10 +398,10 @@ class Ft extends at {
402
398
  usertoken: this.token
403
399
  }
404
400
  }, i = await B.post(o, n).json();
405
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
401
+ g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, o, n);
406
402
  const s = i == null ? void 0 : i.list;
407
403
  if (!s)
408
- return M == null || M.warn("[%s] fetch realtime position failed: %j", a.requestId, o, i), i;
404
+ return g == null || g.warn("[%s] fetch realtime position failed: %j", a.requestId, o, i), i;
409
405
  for (const k in s)
410
406
  !isNaN(s[k]) && Number(s[k]) !== 1 / 0 && (s[k] = Number(s[k]));
411
407
  s.status = s.sp > 3 ? 0 : 1;
@@ -452,7 +448,7 @@ class Ft extends at {
452
448
  }
453
449
  };
454
450
  let i = await B.post(o, n).json();
455
- M == null || M.info("[%s] fetch vessel props from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]);
451
+ g == null || g.info("[%s] fetch vessel props from: %s - %j", a.requestId, o, n), i instanceof Array && (i = i[0]);
456
452
  for (const r in i)
457
453
  !isNaN(i[r]) && Number(i[r]) !== 1 / 0 && (i[r] = Number(i[r]));
458
454
  const s = {
@@ -465,7 +461,7 @@ class Ft extends at {
465
461
  draught: i.dr,
466
462
  type: i.t
467
463
  };
468
- return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await B.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;
464
+ return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", i = await B.post(o, n).json(), g == null || g.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;
469
465
  }
470
466
  async suggest(t, a = {}) {
471
467
  const o = "https://www.hifleet.com/hifleetapi/getShipSuggest.do", n = {
@@ -478,7 +474,7 @@ class Ft extends at {
478
474
  Host: "www.hifleet.com"
479
475
  }
480
476
  }, i = await B.post(o, n).json();
481
- M == null || M.info("[%s] suggest vessel props from: %s - %j", a.requestId, o, n);
477
+ g == null || g.info("[%s] suggest vessel props from: %s - %j", a.requestId, o, n);
482
478
  const s = [];
483
479
  for (const r of i)
484
480
  s.push({
@@ -491,13 +487,13 @@ class Ft extends at {
491
487
  return s.sort((r, l) => l.score - r.score), s;
492
488
  }
493
489
  async trajectory(t, a, o, n, i = !0, s = {}) {
494
- var m, c, f;
490
+ var m, c, h;
495
491
  const r = await this.realTimePosition(t, s);
496
492
  let l = w(a);
497
493
  const u = w(o), d = w();
498
494
  if (i) {
499
- let h = u.diff(l, "d", !0);
500
- h < 0 ? l = u.clone().subtract(40, "d") : h < 30 ? l.subtract(10, "d") : h < 60 ? l.subtract(5, "d") : l = u.clone().subtract(80, "d"), h = d.diff(u, "d", !0), u.add(h > 10 ? 240 : h * 24, "h");
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");
501
497
  }
502
498
  const y = {
503
499
  searchParams: {
@@ -507,38 +503,38 @@ class Ft extends at {
507
503
  usertoken: this.token
508
504
  }
509
505
  }, k = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", b = await B.get(k, y).json();
510
- M == null || M.info("[%s] fetch trajectory from: %s - %j", s.requestId, k, y);
506
+ g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, k, y);
511
507
  let S;
512
- b && (S = ((c = (m = b.ships) == null ? void 0 : m.offors) == null ? void 0 : c.ship) || [], S.length || M == null || M.warn("[%s] fetch trajectory failed: %j", s.requestId, b));
513
- const C = [];
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));
509
+ const I = [];
514
510
  let p = -1;
515
- 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");
516
- for (const h of S) {
517
- for (const H in h)
518
- !isNaN(h[H]) && Number(h[H]) !== 1 / 0 && (h[H] = Number(h[H]));
519
- const g = w(`${h.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
520
- h.status = h.sp > 4 ? 0 : 1;
521
- const { labelEn: I, labelCn: F } = this.parseStatus(h.status), P = {
522
- mmsi: h.m,
523
- name: h.n,
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,
524
520
  imo: r == null ? void 0 : r.imo,
525
- lat: h.la,
526
- lng: h.lo,
527
- draught: h.draught,
528
- sog: h.sp,
529
- cog: h.co,
530
- hdg: h.hdg,
531
- positionTime: g.unix(),
532
- utc: g.utc().format(),
533
- status: h.status,
534
- labelCn: F,
535
- labelEn: I,
521
+ lat: f.la,
522
+ lng: f.lo,
523
+ draught: f.draught,
524
+ sog: f.sp,
525
+ cog: f.co,
526
+ hdg: f.hdg,
527
+ positionTime: C.unix(),
528
+ utc: C.utc().format(),
529
+ status: f.status,
530
+ labelCn: j,
531
+ labelEn: M,
536
532
  method: "trajectory",
537
533
  vendor: "hifleet"
538
- }, D = Math.floor(g.diff(v, "minute", !0) / (n || 1));
539
- D !== p && (p = D, C.push(P));
534
+ }, D = Math.floor(C.diff(v, "minute", !0) / (n || 1));
535
+ D !== p && (p = D, I.push(P));
540
536
  }
541
- return C;
537
+ return I;
542
538
  }
543
539
  }
544
540
  class Nt extends at {
@@ -555,7 +551,7 @@ class Nt extends at {
555
551
  enc: 1
556
552
  }
557
553
  }, n = "https://api.shipxy.com/apicall/GetSingleShip", i = await B.get(n, o).json();
558
- if (M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o), (i == null ? void 0 : i.status) !== 0)
554
+ if (g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, n, o), (i == null ? void 0 : i.status) !== 0)
559
555
  return i;
560
556
  const s = i.data[0];
561
557
  for (const y in s)
@@ -596,12 +592,12 @@ class Nt extends at {
596
592
  etm: u.unix()
597
593
  }
598
594
  }, k = await B.get(d, y).json();
599
- if (M == null || M.info("[%s] fetch trajectory from: %s - %j", s.requestId, d, y), (k == null ? void 0 : k.status) !== 0)
595
+ if (g == null || g.info("[%s] fetch trajectory from: %s - %j", s.requestId, d, y), (k == null ? void 0 : k.status) !== 0)
600
596
  return k;
601
- const b = k == null ? void 0 : k.points, S = [], C = w.unix((v = b[0]) == null ? void 0 : v.utc);
597
+ const b = k == null ? void 0 : k.points, S = [], I = w.unix((v = b[0]) == null ? void 0 : v.utc);
602
598
  let p = -1;
603
599
  for (const m of b) {
604
- const c = w.unix(m.utc), f = {
600
+ const c = w.unix(m.utc), h = {
605
601
  imo: r == null ? void 0 : r.imo,
606
602
  mmsi: t,
607
603
  sog: Math.round(m.sog * 3600 / 1e3 / 1852 * 100) / 100,
@@ -612,8 +608,8 @@ class Nt extends at {
612
608
  utc: c.utc().format(),
613
609
  method: "trajectory",
614
610
  vendor: "shipxy"
615
- }, h = Math.floor(c.diff(C, "minute", !0) / (n || 1));
616
- h !== p && (p = h, S.push(f));
611
+ }, f = Math.floor(c.diff(I, "minute", !0) / (n || 1));
612
+ f !== p && (p = f, S.push(h));
617
613
  }
618
614
  return S;
619
615
  }
@@ -633,7 +629,7 @@ class xt extends at {
633
629
  mmsiList: t
634
630
  }
635
631
  }, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", i = await B.post(n, o).json();
636
- return M == null || M.info("[%s] fetch ship id from: %s - %j", a.requestId, n, o), i.code !== "0" ? i : i.data[0].shipId;
632
+ return g == null || g.info("[%s] fetch ship id from: %s - %j", a.requestId, n, o), i.code !== "0" ? i : i.data[0].shipId;
637
633
  }
638
634
  async getShipInfo(t, a = {}) {
639
635
  const o = {
@@ -644,11 +640,11 @@ class xt extends at {
644
640
  shipId: t
645
641
  }
646
642
  }, n = "https://api3.myships.com/sp/ships/aissta", i = await B.post(n, o).json();
647
- if (M == null || M.info("[%s] fetch ship info from: %s - %j", a.requestId, n, o), i.code !== "0")
643
+ if (g == null || g.info("[%s] fetch ship info from: %s - %j", a.requestId, n, o), i.code !== "0")
648
644
  return i;
649
645
  const s = i.data;
650
646
  let r = s.imo;
651
- return t === "407170" && (r = "9198379", M == null || M.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, s.imo, r)), {
647
+ return t === "407170" && (r = "9198379", g == null || g.warn("[%s] ship(%s) imo error: %s, should be %s", a.requestId, t, s.imo, r)), {
652
648
  mmsi: s.mmsi,
653
649
  name: s.shipnameEn,
654
650
  imo: r,
@@ -667,7 +663,7 @@ class xt extends at {
667
663
  shipId: o
668
664
  }
669
665
  }, s = "https://api3.myships.com/sp/ships/position/latest", r = await B.post(s, i).json();
670
- M == null || M.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, i);
666
+ g == null || g.info("[%s] fetch realtime position from: %s - %j", a.requestId, s, i);
671
667
  const l = r.data[0];
672
668
  for (const b in l)
673
669
  !isNaN(l[b]) && Number(l[b]) !== 1 / 0 && (l[b] = Number(l[b]));
@@ -697,7 +693,7 @@ class xt extends at {
697
693
  return await this.trajectoryIn30Day(u, r.unix(), l.unix(), d, t, n, y), y;
698
694
  }
699
695
  async trajectoryIn30Day(t, a, o, n, i, s, r, l = {}) {
700
- var C;
696
+ var I;
701
697
  const u = {
702
698
  headers: {
703
699
  appKey: this.token
@@ -708,12 +704,12 @@ class xt extends at {
708
704
  endTime: o
709
705
  }
710
706
  }, d = "https://api3.myships.com/sp/ships/position/history", y = await B.post(d, u).json();
711
- if (M == null || M.info("[%s] fetch trajectory from: %s - %j", l.requestId, d, u), y.code !== "0")
712
- return M == null || M.warn("[%s] invoke myship trajectory failed: %j", l.requestId, y), y;
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;
713
709
  const k = y.data;
714
710
  for (const p in k)
715
711
  !isNaN(k[p]) && Number(k[p]) !== 1 / 0 && (k[p] = Number(k[p]));
716
- const b = w.unix((C = k[0]) == null ? void 0 : C.posTime);
712
+ const b = w.unix((I = k[0]) == null ? void 0 : I.posTime);
717
713
  let S = -1;
718
714
  for (const p of k) {
719
715
  const v = w.unix(p.posTime), m = {
@@ -798,20 +794,20 @@ class Mt {
798
794
  * @param options
799
795
  */
800
796
  checkWeather(e, t, a = {}) {
801
- var b, S, C, p, v, m, c, f, h, g, I, F, P, D, H;
797
+ var b, S, I, p, v, m, c, h, f, C, M, j, P, D, H;
802
798
  let o = 0, n = 0, i = 0, s = 0;
803
- 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 = (C = t == null ? void 0 : t.SEVERE) == null ? void 0 : C.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((((f = (c = t == null ? void 0 : t.SEVERE) == null ? void 0 : c.wind) == null ? void 0 : f.number) + 2) * 100) / 100, y = (g = (h = t == null ? void 0 : t.SEVERE) == null ? void 0 : h.wind) == null ? void 0 : g.number, k = (F = (I = t == null ? void 0 : t.HEAVY) == null ? void 0 : I.wind) == null ? void 0 : F.number;
804
- for (let j = 0; j < (e == null ? void 0 : e.length); j++) {
805
- const N = e[j], 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 = j ? w(N.eta).diff(w(e[j - 1].eta), "hour", !0) : 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;
800
+ for (let F = 0; F < (e == null ? void 0 : e.length); F++) {
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;
806
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;
807
803
  }
808
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 } };
809
805
  }
810
806
  }
811
807
  const Dt = new Mt();
812
- let T;
808
+ let E;
813
809
  try {
814
- T = dt.getLogger("vessel");
810
+ E = dt.getLogger("vessel");
815
811
  } catch {
816
812
  } finally {
817
813
  }
@@ -963,16 +959,16 @@ class Y {
963
959
  let u;
964
960
  try {
965
961
  o = (o == null ? void 0 : o.toUpperCase()) === "CMEMS" ? "ECMWF" : o, o = (o == null ? void 0 : o.toUpperCase()) === "METEO2" ? "best_match" : o;
966
- const { weatherModels: b, marineModels: S } = await ct.autoPickMeteoModel(o), C = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
962
+ const { weatherModels: b, marineModels: S } = await ct.autoPickMeteoModel(o), I = await gt.spotForecast(t.lat, t.lng, a.utc().format(), !1, !1, !0, {
967
963
  ...r,
968
964
  pastDays: 1,
969
965
  forecastDays: 1,
970
966
  weatherModels: b,
971
967
  marineModels: S
972
- }), [p] = ct.pickHourly(C, a);
968
+ }), [p] = ct.pickHourly(I, a);
973
969
  u = ct.toLegacy(p);
974
970
  } catch (b) {
975
- T.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, b);
971
+ E.warn("[%s] meteo2 spot(%j) forecast failed: %s", r.requestId, { ...t, eta: a.utc().format(), source: o }, b);
976
972
  }
977
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;
978
974
  l = {
@@ -1010,46 +1006,46 @@ class Y {
1010
1006
  static async speedLoseInHoursStep(e, t, a, o, n, i, s = "", r = !0, l = !1, u = {}) {
1011
1007
  t.utc();
1012
1008
  const d = t.clone().add(14, "days"), y = [], k = [], b = [];
1013
- let S = 0, C = 0, p, v;
1009
+ let S = 0, I = 0, p, v;
1014
1010
  for (let m = 0; m < i.length - 1; m++) {
1015
1011
  let c = i[m];
1016
- c.distanceFromStart = Math.round((n + C) * 1e3) / 1e3;
1017
- const f = i[m + 1];
1018
- if (e.bearing = O.calculateBearing(c, f, !f.gcToPrevious), c.bearing = e.bearing, c.suspend && l) {
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) {
1019
1015
  c.eta = c.eta || t.utc().format(), c.elapsed = c.elapsed ?? 0;
1020
- const I = c.suspend - c.elapsed;
1021
- if (o - S > I)
1022
- o = o - S - I, t.add(I, "hour"), c.elapsed = c.suspend;
1016
+ const M = c.suspend - c.elapsed;
1017
+ if (o - S > M)
1018
+ o = o - S - M, t.add(M, "hour"), c.elapsed = c.suspend;
1023
1019
  else {
1024
- const F = o - S;
1025
- c.elapsed += F, t.add(F, "hour"), o = 0;
1020
+ const j = o - S;
1021
+ c.elapsed += j, t.add(j, "hour"), o = 0;
1026
1022
  }
1027
- if (T == null || T.info(`[%s] suspend ${c.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, c), o === 0)
1028
- return c.distanceFromPrevious = C, { etd: t, from: v || c, to: c, next: i.filter((F) => F), wps: y, days: k, all: b };
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 };
1029
1025
  } else
1030
1026
  c.suspend = 0;
1031
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"));
1032
- const h = O.calculateDistance(c, f, !f.gcToPrevious);
1033
- let g = Math.round(h / v.speed * 1e5) / 1e5;
1034
- if (S + g < o) {
1035
- if (S += g, t.add(g, "hour"), delete i[m], T == null || T.debug(
1036
- `[%s] go to %j from %j with ${h}nm, and cost ${g} hours`,
1028
+ const f = O.calculateDistance(c, h, !h.gcToPrevious);
1029
+ let C = Math.round(f / v.speed * 1e5) / 1e5;
1030
+ 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`,
1037
1033
  u.requestId,
1038
- { lat: f.lat, lng: f.lng },
1034
+ { lat: h.lat, lng: h.lng },
1039
1035
  { lat: v.lat, lng: v.lng, etd: v.etd }
1040
- ), C += h, i.filter((I) => I).length <= 1) {
1041
- p = f, p.eta = t.utc().format(), p.distanceFromPrevious = h, p.distanceFromStart = Math.round((n + C) * 1e4) / 1e4, y.push(p), b.push(p), delete i[m + 1];
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];
1042
1038
  break;
1043
1039
  }
1044
1040
  } else {
1045
- g = o - S, t.add(g, "hour");
1046
- const I = z.roundPrecision(v.speed * g, 5);
1047
- p = O.calculateCoordinate(c, e.bearing, I, "nauticalmiles", !f.gcToPrevious), p.eta = t.utc().format(), i[m] = p, T == null || T.debug(
1048
- `[%s] go to %j from %j with ${I}nm, and cost ${g} hours`,
1041
+ C = o - S, t.add(C, "hour");
1042
+ 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(
1044
+ `[%s] go to %j from %j with ${M}nm, and cost ${C} hours`,
1049
1045
  u.requestId,
1050
1046
  { lat: p.lat, lng: p.lng },
1051
1047
  { lat: c.lat, lng: c.lng, etd: c.etd }
1052
- ), C += I, p.distanceFromPrevious = Math.round(C * 1e4) / 1e4, p.distanceFromStart = Math.round((n + C) * 1e4) / 1e4;
1048
+ ), I += M, p.distanceFromPrevious = Math.round(I * 1e4) / 1e4, p.distanceFromStart = Math.round((n + I) * 1e4) / 1e4;
1053
1049
  break;
1054
1050
  }
1055
1051
  }
@@ -1075,15 +1071,15 @@ class Y {
1075
1071
  * @param cFactor 洋流因子
1076
1072
  */
1077
1073
  static weatherFactor(e, t, a = 0) {
1078
- var k, b, S, C, p, v, m;
1079
- T == null || T.debug("calculate weather factor via: %j", { ...e, ...t });
1074
+ var k, b, S, I, p, v, m;
1075
+ E == null || E.debug("calculate weather factor via: %j", { ...e, ...t });
1080
1076
  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);
1081
1077
  let r = O.includedAngle(e.bearing, (k = t == null ? void 0 : t.wind) == null ? void 0 : k.degree);
1082
1078
  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);
1083
1079
  let d = l * s * u / 100 * (e.speed - n);
1084
- d = Math.round(d * 1.943844 * 1e4) / 1e4 * -1, e.tag === "tugs" && Math.abs(d) > 1 && (d = d / (Math.abs(Math.round(d)) + 1)), T == null || T.debug("wind wx factor = %d", d), r = O.includedAngle(e.bearing, (p = (C = t == null ? void 0 : t.wave) == null ? void 0 : C.sig) == null ? void 0 : p.degree);
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);
1085
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);
1086
- return T == null || T.debug("wave wx factor = %d", y), d = Math.abs(d) > Math.abs(y) ? d : d * 0.3 + y * 0.7, T == null || T.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;
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;
1087
1083
  }
1088
1084
  /**
1089
1085
  * 以12小时级别去掉重复的days
@@ -1121,7 +1117,7 @@ class Y {
1121
1117
  const { route: y, waypoints: k } = n.points, b = O.calculateSubRoute(e, y);
1122
1118
  if (((_ = b[0]) == null ? void 0 : _.length) <= 1)
1123
1119
  return;
1124
- const { v0: S, label: C } = e.sog ? {
1120
+ const { v0: S, label: I } = e.sog ? {
1125
1121
  v0: e.sog,
1126
1122
  label: e.label || "Other"
1127
1123
  /* Instruct */
@@ -1136,7 +1132,7 @@ class Y {
1136
1132
  route: b,
1137
1133
  waypoints: v,
1138
1134
  v0: S,
1139
- label: C
1135
+ label: I
1140
1136
  }, c = {
1141
1137
  hours: [],
1142
1138
  days: [],
@@ -1144,45 +1140,45 @@ class Y {
1144
1140
  all: []
1145
1141
  };
1146
1142
  s || (O.calculateRouteDistance(b) / o.speed <= 72 ? s = 3 : s = 6);
1147
- let f = O.simplifyRouteToCoordinates(b, v, 0), h = 0, g = 0, I = 0, F = 0;
1143
+ let h = O.simplifyRouteToCoordinates(b, v, 0), f = 0, C = 0, M = 0, j = 0;
1148
1144
  t = w(t).utc();
1149
1145
  const P = t.clone();
1150
- for (; f.length > 0; ) {
1151
- 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, E = await Y.speedLoseInHoursStep(
1146
+ for (; h.length > 0; ) {
1147
+ 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(
1152
1148
  p,
1153
1149
  t,
1154
1150
  P,
1155
1151
  V,
1156
- h,
1157
1152
  f,
1153
+ h,
1158
1154
  i,
1159
1155
  r,
1160
1156
  l,
1161
1157
  u
1162
1158
  );
1163
- if (c.all.push(...E.all), (G = E.from) != null && G.speed && (c.hours.push(E.from), c.wps.push(...E.wps), c.days.push(...E.days)), f = E == null ? void 0 : E.next, !f.length) {
1164
- const L = await Y.speedLoseAt(p, E.to, w(E.to.eta), i, 0, r, l, u);
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) {
1160
+ const L = await Y.speedLoseAt(p, T.to, w(T.to.eta), i, 0, r, l, u);
1165
1161
  L.bearing = p.bearing, c.hours.push(L), c.all.push(L);
1166
1162
  }
1167
- h += Math.round((((X = E == null ? void 0 : E.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1163
+ f += Math.round((((X = T == null ? void 0 : T.to) == null ? void 0 : X.distanceFromPrevious) ?? 0) * 1e4) / 1e4;
1168
1164
  }
1169
1165
  const D = c.hours;
1170
1166
  for (let A = 0; A < D.length - 1; A++) {
1171
1167
  const V = w(D[A + 1].eta).diff(D[A].etd, "hour", !0) || 1;
1172
- g += (D[A].wxFactor || 0) * V, I += (D[A].cFactor || 0) * V, F += V;
1168
+ C += (D[A].wxFactor || 0) * V, M += (D[A].cFactor || 0) * V, j += V;
1173
1169
  }
1174
1170
  const H = D.reduce((A, V) => A + (V.suspend || 0), 0);
1175
1171
  (Q = c.wps) == null || Q.forEach((A, V) => {
1176
1172
  A.positionTime = w.utc(A.etd || A.eta).unix();
1177
- const E = c.wps[V - 1];
1178
- if (E) {
1179
- const L = A.distanceFromStart - E.distanceFromStart, q = w(A.eta || A.etd).diff(w(E.etd || E.eta), "h", !0);
1180
- A.avgSpd = Math.round(L / q * 100) / 100, E.bearing = O.calculateBearing(E, A);
1173
+ const T = c.wps[V - 1];
1174
+ if (T) {
1175
+ const L = A.distanceFromStart - T.distanceFromStart, q = w(A.eta || A.etd).diff(w(T.etd || T.eta), "h", !0);
1176
+ A.avgSpd = Math.round(L / q * 100) / 100, T.bearing = O.calculateBearing(T, A);
1181
1177
  }
1182
- }), 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((E) => Math.round(E.positionTime / 60) === Math.round(V.positionTime / 60)) || A.push(V), A), []), m.sample = c;
1183
- const j = c.hours.at(0), N = c.hours.at(-1);
1184
- m.distance = Math.round(N.distanceFromStart * 1e3) / 1e3, m.etd = w(j.eta).utc().format(), m.eta = w(N.eta).utc().format(), m.wxFactor = Math.round(g / F * 1e3) / 1e3, m.cFactor = Math.round(I / F * 1e3) / 1e3, m.avgSpeed = Math.round(N.distanceFromStart / F * 1e3) / 1e3, m.totalHrs = Math.round(F * 1e3) / 1e3, m.suspend = Math.round(H * 1e3) / 1e3;
1185
- 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 * (F - K), 3), ot = z.roundPrecision(o.dgo / 24 * F + R, 3);
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);
1186
1182
  m.extend = {
1187
1183
  eca: tt,
1188
1184
  distanceInECA: W,
@@ -1191,7 +1187,7 @@ class Y {
1191
1187
  totalDgoConsInSuspend: R
1192
1188
  }, m.totalFoCons = et < 0 ? 0 : et, m.totalDgoCons = ot;
1193
1189
  const st = w().valueOf() - d, rt = (($ = c == null ? void 0 : c.hours) == null ? void 0 : $.length) || 1;
1194
- return T == null || T.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;
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;
1195
1191
  }
1196
1192
  /**
1197
1193
  * 分段失速分析(最多走hours 小时)
@@ -1220,58 +1216,58 @@ class Y {
1220
1216
  v0: n.speed,
1221
1217
  label: "CP"
1222
1218
  /* Cp */
1223
- }, C = Y.assembleProperties(o, n.loadCondition, b, 0), p = O.calculateSubRoute(e, i);
1219
+ }, I = Y.assembleProperties(o, n.loadCondition, b, 0), p = O.calculateSubRoute(e, i);
1224
1220
  if (((X = p[0]) == null ? void 0 : X.length) <= 1)
1225
1221
  return;
1226
1222
  const v = s.length ? O.calculateSubWaypoints(e, s) : [];
1227
- v.forEach((E) => E.important = !0);
1228
- let m = O.simplifyRouteToCoordinates(p, v, 0), c = 0, f = 0, h = 0, g = 0;
1229
- const I = {
1223
+ v.forEach((T) => T.important = !0);
1224
+ let m = O.simplifyRouteToCoordinates(p, v, 0), c = 0, h = 0, f = 0, C = 0;
1225
+ const M = {
1230
1226
  hours: [],
1231
1227
  wps: [],
1232
1228
  days: [],
1233
1229
  all: []
1234
1230
  };
1235
1231
  t = w(t).utc();
1236
- const F = t.clone();
1232
+ const j = t.clone();
1237
1233
  for (; m.length > 0; ) {
1238
- const E = l - t.hour() % l;
1239
- let L = Math.ceil(t.clone().add(E, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1234
+ const T = l - t.hour() % l;
1235
+ let L = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
1240
1236
  L = t.clone().add(L, "h").isSameOrAfter(a) ? a.diff(t, "h", !0) * 1e4 / 1e4 : L;
1241
- const q = await Y.speedLoseInHoursStep(C, t, F, L, c, m, r, u, d, y);
1242
- if (I.all.push(...q.all), (Q = q.from) != null && Q.speed && (I.hours.push(q.from), q != null && q.wps && I.wps.push(...q.wps), I.days.push(...q.days)), m = q == null ? void 0 : q.next, m.length || I.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)
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)
1243
1239
  break;
1244
1240
  }
1245
- I.wps = await Y.reduceWPS(I.wps), I.days = await Y.reduceDays(I.days), I.all = ($ = I.all) == null ? void 0 : $.reduce((E, L) => (L.positionTime = w.utc(L.etd || L.eta).unix(), E.some((q) => Math.round(w(q.etd).unix() / 60) === Math.round(w(L.etd).unix() / 60)) || E.push(L), E), []), (A = I.wps) == null || A.forEach((E, L) => {
1246
- const q = I.wps[L - 1];
1241
+ 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) => {
1242
+ const q = M.wps[L - 1];
1247
1243
  if (q) {
1248
- const ut = E.distanceFromStart - q.distanceFromStart, lt = w(E.eta || E.etd).diff(w(q.etd || q.eta), "h", !0);
1249
- q.bearing = O.calculateBearing(q, E), E.avgSpd = Math.round(ut / lt * 100) / 100;
1244
+ const ut = T.distanceFromStart - q.distanceFromStart, lt = w(T.eta || T.etd).diff(w(q.etd || q.eta), "h", !0);
1245
+ q.bearing = O.calculateBearing(q, T), T.avgSpd = Math.round(ut / lt * 100) / 100;
1250
1246
  }
1251
1247
  });
1252
- const P = I.hours;
1253
- for (let E = 0; E < P.length - 1; E++) {
1254
- const L = w(P[E + 1].eta).diff(P[E].etd, "hour", !0);
1255
- f += P[E].wxFactor * L, h += P[E].cFactor * L, g += L;
1248
+ const P = M.hours;
1249
+ for (let T = 0; T < P.length - 1; T++) {
1250
+ 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;
1256
1252
  }
1257
- const D = P.reduce((E, L) => E + (L.suspend || 0), 0), H = I.hours.at(0), j = I.hours.at(-1), N = await O.calculateRangeRoute(H, j, p), R = await O.calculateRangeWaypoints(H, j, p, v), W = {
1258
- sample: I,
1259
- distance: Math.round(((j == null ? void 0 : j.distanceFromStart) || 0) * 1e4) / 1e4,
1253
+ 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
+ sample: M,
1255
+ distance: Math.round(((F == null ? void 0 : F.distanceFromStart) || 0) * 1e4) / 1e4,
1260
1256
  // 注意,可能会在first节点Drift,所有采用eta做为初始出发时间
1261
1257
  etd: w(H.eta).utc().format(),
1262
- eta: w(j == null ? void 0 : j.eta).utc().format(),
1263
- wxFactor: Math.round(f / g * 1e3) / 1e3,
1264
- cFactor: Math.round(h / g * 1e3) / 1e3,
1265
- avgSpeed: Math.round(((j == null ? void 0 : j.distanceFromStart) || 0) / g * 1e3) / 1e3,
1266
- totalHrs: Math.round(g * 1e3) / 1e3,
1258
+ 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,
1261
+ avgSpeed: Math.round(((F == null ? void 0 : F.distanceFromStart) || 0) / C * 1e3) / 1e3,
1262
+ totalHrs: Math.round(C * 1e3) / 1e3,
1267
1263
  suspend: Math.round(D * 1e3) / 1e3,
1268
1264
  from: H,
1269
- to: j,
1265
+ to: F,
1270
1266
  route: N,
1271
1267
  waypoints: R,
1272
1268
  v0: b,
1273
1269
  label: S
1274
- }, 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 * (g - tt), 3), st = z.roundPrecision(n.dgo / 24 * g + K, 3);
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);
1275
1271
  W.extend = {
1276
1272
  eca: ot,
1277
1273
  distanceInECA: nt,
@@ -1279,8 +1275,8 @@ class Y {
1279
1275
  totalDgoConsInECA: et,
1280
1276
  totalDgoConsInSuspend: K
1281
1277
  }, W.totalDgoCons = st, W.totalFoCons = it < 0 ? 0 : it;
1282
- const _ = w().valueOf() - k, G = ((V = I == null ? void 0 : I.hours) == null ? void 0 : V.length) || 1;
1283
- return T == null || T.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;
1278
+ 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;
1284
1280
  }
1285
1281
  /**
1286
1282
  * 在指定航线条件下,基于多CP,动态计算最优成本(租金+油费)方案
@@ -1310,46 +1306,46 @@ class Y {
1310
1306
  const u = w.utc(e.etd).add(l ?? 14, "day");
1311
1307
  let d = 1;
1312
1308
  for (const m of a) {
1313
- const c = JSON.parse(JSON.stringify(o.route)), f = JSON.parse(JSON.stringify(o.waypoints)), h = await Y.analyseInstantWithThreshed(
1309
+ const c = JSON.parse(JSON.stringify(o.route)), h = JSON.parse(JSON.stringify(o.waypoints)), f = await Y.analyseInstantWithThreshed(
1314
1310
  { lat: e.lat, lng: e.lng },
1315
1311
  e.etd,
1316
1312
  u,
1317
1313
  t,
1318
1314
  m,
1319
1315
  c,
1320
- f,
1316
+ h,
1321
1317
  e.meteoVendor,
1322
1318
  e.speedStep,
1323
1319
  e.useMeteo,
1324
1320
  e.useRouteParam,
1325
1321
  n
1326
1322
  );
1327
- h && (await Y.calculateCost(h, m, e, n), s.push(h), T == null || T.info("[%s][L%d-%d] analyse from %s to %s cost: %j", n.requestId, 1, d, e.etd, u.format(), {
1328
- cost: h.cost.total,
1329
- hire: h.cost.hire,
1330
- bunker: h.cost.bunker,
1331
- distance: h.distance,
1332
- hours: h.totalHrs,
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,
1333
1329
  cp: `${m.speed}/${m.fo}/${m.dgo}`
1334
1330
  })), d++;
1335
1331
  }
1336
1332
  s.sort((m, c) => m.cost.total - c.cost.total);
1337
1333
  const y = s.at(0), k = s.at(1), b = [];
1338
1334
  if (b.push({ combined: !1, speeds: [y], cost: (p = y.cost) == null ? void 0 : p.total }), k) {
1339
- const m = y.cost.cp, c = k.cost.cp, f = w(y.eta), h = w(y.etd), g = f.diff(h, "days", !0);
1340
- let I = Math.ceil(g / 2);
1341
- I = I > 7 ? 7 : I < e.alterStep ? e.alterStep : I;
1342
- let F = 2, P = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
1343
- for (; I >= e.alterStep; ) {
1344
- const H = await Y.combinedAnalyse(e, t, u, [m, c], o, I, { ...n, level: F });
1345
- 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), I <= e.alterStep)
1335
+ const m = y.cost.cp, c = k.cost.cp, h = w(y.eta), f = w(y.etd), C = h.diff(f, "days", !0);
1336
+ let M = Math.ceil(C / 2);
1337
+ M = M > 7 ? 7 : M < e.alterStep ? e.alterStep : M;
1338
+ let j = 2, P = { combined: !1, speeds: [k], cost: (v = k.cost) == null ? void 0 : v.total }, D;
1339
+ for (; M >= e.alterStep; ) {
1340
+ const H = await Y.combinedAnalyse(e, t, u, [m, c], o, M, { ...n, level: j });
1341
+ 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)
1346
1342
  break;
1347
- I = Math.ceil(I / 2), F += 1;
1343
+ M = Math.ceil(M / 2), j += 1;
1348
1344
  }
1349
1345
  b.push(P), D && b.push(D);
1350
1346
  }
1351
- const C = w().valueOf() - i;
1352
- return T == null || T.info("[%s] analyse elapsed: %d ms", n == null ? void 0 : n.requestId, C), b.sort((m, c) => m.cost - c.cost);
1347
+ 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);
1353
1349
  }
1354
1350
  /**
1355
1351
  * 按步长多次减半,分别用7,4,2,1天步长及cpa,cpb交替计算各种组合下的成本
@@ -1362,19 +1358,19 @@ class Y {
1362
1358
  * @param options
1363
1359
  */
1364
1360
  static async combinedAnalyse(e, t, a, o, n, i, s = {}) {
1365
- s.counter = 1, T == null || T.info("[%s][L%d] analyse with alternate cp in every %d days", s.requestId, s.level, i);
1366
- const r = await Y.alternateAnalyse(e, t, a, o, 0, n, i, s), l = r.reduce((c, f) => c + f.cost.total, 0), u = r.reduce((c, f) => c + f.cost.hire, 0), d = r.reduce((c, f) => c + f.cost.bunker, 0), y = r.reduce((c, f) => c + f.distance, 0), k = r.reduce((c, f) => c + f.totalHrs, 0);
1367
- T == null || T.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1361
+ 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);
1363
+ E == null || E.info("[%s][L%d] cost with cpa/cpb turn: %j", s.requestId, s.level, {
1368
1364
  cost: l,
1369
1365
  hire: u,
1370
1366
  bunker: d,
1371
1367
  distance: y,
1372
1368
  hours: k
1373
1369
  });
1374
- const b = await Y.alternateAnalyse(e, t, a, o, 1, n, i, s), S = b.reduce((c, f) => c + f.cost.total, 0), C = b.reduce((c, f) => c + f.cost.hire, 0), p = b.reduce((c, f) => c + f.cost.bunker, 0), v = b.reduce((c, f) => c + f.distance, 0), m = b.reduce((c, f) => c + f.totalHrs, 0);
1375
- return T == null || T.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
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);
1371
+ return E == null || E.info("[%s][L%d] cost with cpb/cpa turn: %j", s.requestId, s.level, {
1376
1372
  cost: S,
1377
- hire: C,
1373
+ hire: I,
1378
1374
  bunker: p,
1379
1375
  distance: v,
1380
1376
  hours: m
@@ -1396,21 +1392,21 @@ class Y {
1396
1392
  let l = w.utc(e.etd);
1397
1393
  const u = { lat: e.lat, lng: e.lng }, d = [];
1398
1394
  for (; l.isBefore(a); ) {
1399
- const b = l.clone().utc().add(s, "day"), S = JSON.parse(JSON.stringify(i.route)), C = JSON.parse(JSON.stringify(i.waypoints)), p = o[n], v = await Y.analyseInstantWithThreshed(
1395
+ 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(
1400
1396
  u,
1401
1397
  l.utc().format(),
1402
1398
  b,
1403
1399
  t,
1404
1400
  p,
1405
1401
  S,
1406
- C,
1402
+ I,
1407
1403
  e.meteoVendor,
1408
1404
  e.speedStep,
1409
1405
  e.useMeteo,
1410
1406
  e.useRouteParam,
1411
1407
  r
1412
1408
  );
1413
- v && (await Y.calculateCost(v, p, e, r), T == null || T.info(
1409
+ v && (await Y.calculateCost(v, p, e, r), E == null || E.info(
1414
1410
  "[%s][L%d-%d] analyse from %s to %s cost: %j",
1415
1411
  r.requestId,
1416
1412
  r.level,
@@ -1489,48 +1485,48 @@ class Y {
1489
1485
  hours: [],
1490
1486
  wps: [],
1491
1487
  days: []
1492
- }, o = e.reduce((f, h) => f + h.distance, 0), n = e.reduce((f, h) => {
1493
- var g;
1494
- return f + (((g = h.extend) == null ? void 0 : g.distanceInECA) || 0);
1495
- }, 0), i = e.reduce((f, h) => f + h.totalHrs, 0), s = e.reduce((f, h) => {
1496
- var g;
1497
- return f + (((g = h.extend) == null ? void 0 : g.hoursInECA) || 0);
1498
- }, 0), r = e.reduce((f, h) => {
1499
- var g;
1500
- return f + (((g = h.extend) == null ? void 0 : g.totalDgoConsInECA) || 0);
1501
- }, 0), l = e.reduce((f, h) => f + h.wxFactor * h.totalHrs / i, 0), u = e.reduce((f, h) => f + h.cFactor * h.totalHrs / i, 0), d = e.reduce((f, h) => f + h.totalFoCons, 0), y = e.reduce((f, h) => f + h.totalDgoCons, 0), k = e.reduce((f, h) => f + h.cost.total, 0), b = e.reduce((f, h) => f + h.cost.hire, 0), S = e.reduce((f, h) => f + h.cost.bunker, 0), C = [], p = [];
1488
+ }, o = e.reduce((h, f) => h + f.distance, 0), n = e.reduce((h, f) => {
1489
+ 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) => {
1492
+ var C;
1493
+ return h + (((C = f.extend) == null ? void 0 : C.hoursInECA) || 0);
1494
+ }, 0), r = e.reduce((h, f) => {
1495
+ 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 = [];
1502
1498
  let v;
1503
- for (const f of e) {
1504
- p.push(...((m = f.extend) == null ? void 0 : m.eca) || []);
1505
- const h = f.sample.hours, g = f.sample.wps, I = f.sample.days, F = h.at(0);
1506
- v && (F.distanceFromPrevious = v.distanceFromPrevious, F.distanceFromStart = v.distanceFromStart, h.forEach((j, N) => {
1507
- N && (j.distanceFromStart = j.distanceFromStart + v.distanceFromStart);
1508
- }), g.at(0).distanceFromPrevious = v.distanceFromPrevious, g.at(0).distanceFromStart = v.distanceFromStart, g.forEach((j, N) => {
1509
- N && (j.distanceFromStart = j.distanceFromStart + v.distanceFromStart);
1510
- }), I.at(0).distanceFromPrevious = v.distanceFromPrevious, I.at(0).distanceFromStart = v.distanceFromStart, I.forEach((j, N) => {
1511
- N && (j.distanceFromStart = j.distanceFromStart + v.distanceFromStart);
1512
- })), F.cp = f.cost.cp;
1513
- const P = [f.etd, f.eta], D = C.findIndex((j) => j.id === F.cp.id);
1514
- D === -1 ? (F.cp.segment = [P], C.push(F.cp)) : C[D].segment.push(P), h.forEach((j) => {
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) => {
1503
+ N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1504
+ }), C.at(0).distanceFromPrevious = v.distanceFromPrevious, C.at(0).distanceFromStart = v.distanceFromStart, C.forEach((F, N) => {
1505
+ N && (F.distanceFromStart = F.distanceFromStart + v.distanceFromStart);
1506
+ }), M.at(0).distanceFromPrevious = v.distanceFromPrevious, M.at(0).distanceFromStart = v.distanceFromStart, M.forEach((F, N) => {
1507
+ 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) => {
1515
1511
  var R;
1516
- ((R = a.hours) == null ? void 0 : R.findIndex((W) => W.eta === j.eta)) === -1 && a.hours.push(j);
1517
- }), g.forEach((j) => {
1512
+ ((R = a.hours) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.hours.push(F);
1513
+ }), C.forEach((F) => {
1518
1514
  var R;
1519
- ((R = a.wps) == null ? void 0 : R.findIndex((W) => W.eta === j.eta)) === -1 && a.wps.push(j);
1520
- }), I.forEach((j) => {
1515
+ ((R = a.wps) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.wps.push(F);
1516
+ }), M.forEach((F) => {
1521
1517
  var R;
1522
- ((R = a == null ? void 0 : a.days) == null ? void 0 : R.findIndex((W) => W.eta === j.eta)) === -1 && a.days.push(j);
1518
+ ((R = a == null ? void 0 : a.days) == null ? void 0 : R.findIndex((W) => W.eta === F.eta)) === -1 && a.days.push(F);
1523
1519
  });
1524
- const H = (c = a.wps) == null ? void 0 : c.findIndex((j) => j.eta === F.eta);
1525
- H === -1 ? a.wps.push(F) : a.wps[H] = F, v = h.at(-1);
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);
1526
1522
  }
1527
- return a.wps.sort((f, h) => w(f.etd).unix() - w(h.etd).unix()), a.wps.forEach((f, h) => {
1528
- const g = a.wps[h - 1];
1529
- if (g) {
1530
- const I = f.distanceFromStart - (g.distanceFromStart || 0), F = w(f.eta || f.etd).diff(w(g.etd || g.eta), "hour", !0), P = Math.round(I / F * 100) / 100;
1531
- f.avgSpd = P;
1532
- const D = O.calculateBearing(g, f);
1533
- g.bearing = D;
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];
1525
+ 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);
1529
+ C.bearing = D;
1534
1530
  }
1535
1531
  }), {
1536
1532
  sample: a,
@@ -1553,7 +1549,7 @@ class Y {
1553
1549
  bunker: Math.round(S * 1e3) / 1e3
1554
1550
  },
1555
1551
  extend: {
1556
- cps: C,
1552
+ cps: I,
1557
1553
  eca: p,
1558
1554
  distanceInECA: Math.round(n * 1e3) / 1e3,
1559
1555
  hoursInECA: Math.round(s * 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,E,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 p;try{p=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();p==null||p.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}};p==null||p.info("[%s] fetch suggest vessels from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(p==null||p.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};p==null||p.info("[%s] fetch vessel from: %s - %j",a.requestId,n,s);const r=await x.get(n,s).json();if(r.status!==200)return p==null||p.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}};p==null||p.info("[%s] fetch vessel archive from: %s - %j",a.requestId,o,n);const i=await x.post(o,n).json();return i.status!==200?(p==null||p.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}};p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const i=await x.get(o,n).json();if(i.code)return p==null||p.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://svc.data.myvessel.cn/sdc/v1/routes/routing/nodes",u={endPoint:{lon:a.lng,lat:a.lat},maxDraught:s.draught||10,useAIModel:s.useAIModel||!1,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};p==null||p.info("[%s] fetch route from: %s - %j",s.requestId,l,d);const y=await x.post(l,d).json();if(y.status!==200)return p==null||p.warn("[%s] fetch route failed: %j",s.requestId,{message:y.message,status:y.status,code:y.code}),{};{const C={status:"Success",nodes:[],seas:[],regions:[],waypoints:[],route:[],distance:0,memo:""},{nodes:g,seas:w,tracks:f,specialRegions:c}=y.data;C.nodes=g==null?void 0:g.map(M=>({code:M.nodeCode,nameEn:M.nameEn,nameCn:M.nameCn,center:{lat:Math.round(M.lat*1e6)/1e6,lng:Math.round(M.lon*1e6)/1e6},start:{lat:Math.round(M.startLat*1e6)/1e6,lng:Math.round(M.startLon*1e6)/1e6},end:{lat:Math.round(M.endLat*1e6)/1e6,lng:Math.round(M.endLat*1e6)/1e6},isKey:M.isKeyNode,isHub:M.isHubNode})),C.seas=w==null?void 0:w.map(M=>({code:M.mrgidSea,nameEn:M.nameEn,nameCn:M.nameCn,center:{lat:Math.round(M.centerLat*1e6)/1e6,lng:Math.round(M.centerLon*1e6)/1e6},min:{lat:Math.round(M.minLat*1e6)/1e6,lng:Math.round(M.minLon*1e6)/1e6},max:{lat:Math.round(M.maxLat*1e6)/1e6,lng:Math.round(M.maxLon*1e6)/1e6},level:M.mapLevel})),c==null||c.map(M=>{M.regionLength&&C.regions.push({type:M.regionType,distance:M.regionLength,rows:M.regions.map(k=>({code:k.regionCode,nameCn:k.nameCn,nameEn:k.nameEn,type:k.regionType,distance:k.length}))})}),C.waypoints=f==null?void 0:f.map(M=>({lat:Math.round(M.lat*1e5)/1e5,lng:Math.round(M.lon*1e5)/1e5})),(T=C.waypoints)!=null&&T.length&&(C.waypoints=E.LaneHelper.simplifyCoordinates(C.waypoints),C.route=E.LaneHelper.divideAccordingToLng(C.waypoints),C.distance=E.LaneHelper.calculateRouteDistance(C.route));const h=v().diff(r,"second");return C.memo=`time cost: ${h}s`,p.info("[%s] calculate route cost: %d seconds",s.requestId,h),C}}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,C,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")}};p==null||p.info("[%s] fetch trajectory from: %s - %j",r.requestId,l,u);const d=await x.post(l,u).json();if(d.code)return p==null||p.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=(C=d.data)==null?void 0:C[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"),m=f.status,{labelCn:h,labelEn:M}=this.parseStatus(m),k={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:m,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:h,labelEn:M,method:"trajectory",vendor:"myVessel",utc:c.utc().format()},F=Math.floor(c.diff(I,"minute",!0)/(i||1));F!==y&&(y=F,s.push(k))}),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();p==null||p.info("[%s] fetch realtime position from: %s - %j",a.requestId,o,n);const s=i==null?void 0:i.list;if(!s)return p==null||p.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();p==null||p.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(),p==null||p.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();p==null||p.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,m;const r=await this.realTimePosition(t,s);let l=v(a);const u=v(o),d=v();if(i){let h=u.diff(l,"d",!0);h<0?l=u.clone().subtract(40,"d"):h<30?l.subtract(10,"d"):h<60?l.subtract(5,"d"):l=u.clone().subtract(80,"d"),h=d.diff(u,"d",!0),u.add(h>10?240:h*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();p==null||p.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||p==null||p.warn("[%s] fetch trajectory failed: %j",s.requestId,b));const C=[];let g=-1;const w=v(`${(m=T==null?void 0:T[0])==null?void 0:m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const h of T){for(const R in h)!isNaN(h[R])&&Number(h[R])!==1/0&&(h[R]=Number(h[R]));const M=v(`${h.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");h.status=h.sp>4?0:1;const{labelEn:k,labelCn:F}=this.parseStatus(h.status),q={mmsi:h.m,name:h.n,imo:r==null?void 0:r.imo,lat:h.la,lng:h.lo,draught:h.draught,sog:h.sp,cog:h.co,hdg:h.hdg,positionTime:M.unix(),utc:M.utc().format(),status:h.status,labelCn:F,labelEn:k,method:"trajectory",vendor:"hifleet"},N=Math.floor(M.diff(w,"minute",!0)/(n||1));N!==g&&(g=N,C.push(q))}return C}}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(p==null||p.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(p==null||p.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=[],C=v.unix((w=b[0])==null?void 0:w.utc);let g=-1;for(const f of b){const c=v.unix(f.utc),m={imo:r==null?void 0:r.imo,mmsi:t,sog:Math.round(f.sog*3600/1e3/1852*100)/100,cog:Math.round(f.cog/100*100)/100,lat:Math.round(f.lat/1e6*1e5)/1e5,lng:Math.round(f.lon/1e6*1e5)/1e5,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"shipxy"},h=Math.floor(c.diff(C,"minute",!0)/(n||1));h!==g&&(g=h,T.push(m))}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 p==null||p.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(p==null||p.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",p==null||p.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();p==null||p.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 C;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(p==null||p.info("[%s] fetch trajectory from: %s - %j",l.requestId,d,u),y.code!=="0")return p==null||p.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((C=I[0])==null?void 0:C.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,C,g,w,f,c,m,h,M,k,F,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=(C=t==null?void 0:t.SEVERE)==null?void 0:C.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((((m=(c=t==null?void 0:t.SEVERE)==null?void 0:c.wind)==null?void 0:m.number)+2)*100)/100,y=(M=(h=t==null?void 0:t.SEVERE)==null?void 0:h.wind)==null?void 0:M.number,I=(F=(k=t==null?void 0:t.HEAVY)==null?void 0:k.wind)==null?void 0:F.number;for(let L=0;L<(e==null?void 0:e.length);L++){const H=e[L],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=L?v(H.eta).diff(v(e[L-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=E.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),C=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(C,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,C=0,g,w;for(let f=0;f<i.length-1;f++){let c=i[f];c.distanceFromStart=Math.round((n+C)*1e3)/1e3;const m=i[f+1];if(e.bearing=E.LaneHelper.calculateBearing(c,m,!m.gcToPrevious),c.bearing=e.bearing,c.suspend&&l){c.eta=c.eta||t.utc().format(),c.elapsed=c.elapsed??0;const k=c.suspend-c.elapsed;if(o-T>k)o=o-T-k,t.add(k,"hour"),c.elapsed=c.suspend;else{const F=o-T;c.elapsed+=F,t.add(F,"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=C,{etd:t,from:w||c,to:c,next:i.filter(F=>F),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 h=E.LaneHelper.calculateDistance(c,m,!m.gcToPrevious);let M=Math.round(h/w.speed*1e5)/1e5;if(T+M<o){if(T+=M,t.add(M,"hour"),delete i[f],S==null||S.debug(`[%s] go to %j from %j with ${h}nm, and cost ${M} hours`,u.requestId,{lat:m.lat,lng:m.lng},{lat:w.lat,lng:w.lng,etd:w.etd}),C+=h,i.filter(k=>k).length<=1){g=m,g.eta=t.utc().format(),g.distanceFromPrevious=h,g.distanceFromStart=Math.round((n+C)*1e4)/1e4,y.push(g),b.push(g),delete i[f+1];break}}else{M=o-T,t.add(M,"hour");const k=E.LngLatHelper.roundPrecision(w.speed*M,5);g=E.LaneHelper.calculateCoordinate(c,e.bearing,k,"nauticalmiles",!m.gcToPrevious),g.eta=t.utc().format(),i[f]=g,S==null||S.debug(`[%s] go to %j from %j with ${k}nm, and cost ${M} hours`,u.requestId,{lat:g.lat,lng:g.lng},{lat:c.lat,lng:c.lng,etd:c.etd}),C+=k,g.distanceFromPrevious=Math.round(C*1e4)/1e4,g.distanceFromStart=Math.round((n+C)*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=E.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,C,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=E.LngLatHelper.roundPrecision(a*1852/3600,6),i=O.froudeNumber(e.speed-n,e.lbp),s=O.amendFactor(o,i,e.loadCondition);let r=E.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=E.LaneHelper.includedAngle(e.bearing,(g=(C=t==null?void 0:t.wave)==null?void 0:C.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=E.LngLatHelper.convertToStdLng(e.lng);const{route:y,waypoints:I}=n.points,b=E.LaneHelper.calculateSubRoute(e,y);if(((X=b[0])==null?void 0:X.length)<=1)return;const{v0:T,label:C}=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?E.LaneHelper.calculateSubWaypoints(e,I):[];w.forEach(P=>P.important=!0);const f={from:{...e},route:b,waypoints:w,v0:T,label:C},c={hours:[],days:[],wps:[],all:[]};s||(E.LaneHelper.calculateRouteDistance(b)/o.speed<=72?s=3:s=6);let m=E.LaneHelper.simplifyRouteToCoordinates(b,w,0),h=0,M=0,k=0,F=0;t=v(t).utc();const q=t.clone();for(;m.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,h,m,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)),m=j==null?void 0:j.next,!m.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)}h+=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;M+=(N[P].wxFactor||0)*z,k+=(N[P].cFactor||0)*z,F+=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=E.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 L=c.hours.at(0),H=c.hours.at(-1);f.distance=Math.round(H.distanceFromStart*1e3)/1e3,f.etd=v(L.eta).utc().format(),f.eta=v(H.eta).utc().format(),f.wxFactor=Math.round(M/F*1e3)/1e3,f.cFactor=Math.round(k/F*1e3)/1e3,f.avgSpeed=Math.round(H.distanceFromStart/F*1e3)/1e3,f.totalHrs=Math.round(F*1e3)/1e3,f.suspend=Math.round(R*1e3)/1e3;const V=E.LngLatHelper.roundPrecision(o.dgo/24*R,3),{distanceInECA:B,hoursInECA:K,totalDgoConsInECA:it,eca:st}=await this.calculateECA(f,o,u),at=E.LngLatHelper.roundPrecision(o.fo/24*(F-K),3),rt=E.LngLatHelper.roundPrecision(o.dgo/24*F+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=E.LngLatHelper.convertToStdLng(e.lng);const{v0:b,label:T}=e.sog?{v0:e.sog,label:e.label||"Other"}:{v0:n.speed,label:"CP"},C=O.assembleProperties(o,n.loadCondition,b,0),g=E.LaneHelper.calculateSubRoute(e,i);if(((Z=g[0])==null?void 0:Z.length)<=1)return;const w=s.length?E.LaneHelper.calculateSubWaypoints(e,s):[];w.forEach(j=>j.important=!0);let f=E.LaneHelper.simplifyRouteToCoordinates(g,w,0),c=0,m=0,h=0,M=0;const k={hours:[],wps:[],days:[],all:[]};t=v(t).utc();const F=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(C,t,F,W,c,f,r,u,d,y);if(k.all.push(...Y.all),($=Y.from)!=null&&$.speed&&(k.hours.push(Y.from),Y!=null&&Y.wps&&k.wps.push(...Y.wps),k.days.push(...Y.days)),f=Y==null?void 0:Y.next,f.length||k.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}k.wps=await O.reduceWPS(k.wps),k.days=await O.reduceDays(k.days),k.all=(et=k.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=k.wps)==null||P.forEach((j,W)=>{const Y=k.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=E.LaneHelper.calculateBearing(Y,j),j.avgSpd=Math.round(It/kt*100)/100}});const q=k.hours;for(let j=0;j<q.length-1;j++){const W=v(q[j+1].eta).diff(q[j].etd,"hour",!0);m+=q[j].wxFactor*W,h+=q[j].cFactor*W,M+=W}const N=q.reduce((j,W)=>j+(W.suspend||0),0),R=k.hours.at(0),L=k.hours.at(-1),H=await E.LaneHelper.calculateRangeRoute(R,L,g),V=await E.LaneHelper.calculateRangeWaypoints(R,L,g,w),B={sample:k,distance:Math.round(((L==null?void 0:L.distanceFromStart)||0)*1e4)/1e4,etd:v(R.eta).utc().format(),eta:v(L==null?void 0:L.eta).utc().format(),wxFactor:Math.round(m/M*1e3)/1e3,cFactor:Math.round(h/M*1e3)/1e3,avgSpeed:Math.round(((L==null?void 0:L.distanceFromStart)||0)/M*1e3)/1e3,totalHrs:Math.round(M*1e3)/1e3,suspend:Math.round(N*1e3)/1e3,from:R,to:L,route:H,waypoints:V,v0:b,label:T},K=E.LngLatHelper.roundPrecision(n.dgo/24*N,3),{distanceInECA:it,hoursInECA:st,totalDgoConsInECA:at,eca:rt}=await this.calculateECA(B,n,y),ct=E.LngLatHelper.roundPrecision(n.fo/24*(M-st),3),nt=E.LngLatHelper.roundPrecision(n.dgo/24*M+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=k==null?void 0:k.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=E.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)),m=JSON.parse(JSON.stringify(o.waypoints)),h=await O.analyseInstantWithThreshed({lat:e.lat,lng:e.lng},e.etd,u,t,f,c,m,e.meteoVendor,e.speedStep,e.useMeteo,e.useRouteParam,n);h&&(await O.calculateCost(h,f,e,n),s.push(h),S==null||S.info("[%s][L%d-%d] analyse from %s to %s cost: %j",n.requestId,1,d,e.etd,u.format(),{cost:h.cost.total,hire:h.cost.hire,bunker:h.cost.bunker,distance:h.distance,hours:h.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,m=v(y.eta),h=v(y.etd),M=m.diff(h,"days",!0);let k=Math.ceil(M/2);k=k>7?7:k<e.alterStep?e.alterStep:k;let F=2,q={combined:!1,speeds:[I],cost:(w=I.cost)==null?void 0:w.total},N;for(;k>=e.alterStep;){const R=await O.combinedAnalyse(e,t,u,[f,c],o,k,{...n,level:F});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),k<=e.alterStep)break;k=Math.ceil(k/2),F+=1}b.push(q),N&&b.push(N)}const C=v().valueOf()-i;return S==null||S.info("[%s] analyse elapsed: %d ms",n==null?void 0:n.requestId,C),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,m)=>c+m.cost.total,0),u=r.reduce((c,m)=>c+m.cost.hire,0),d=r.reduce((c,m)=>c+m.cost.bunker,0),y=r.reduce((c,m)=>c+m.distance,0),I=r.reduce((c,m)=>c+m.totalHrs,0);S==null||S.info("[%s][L%d] cost with cpa/cpb turn: %j",s.requestId,s.level,{cost: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,m)=>c+m.cost.total,0),C=b.reduce((c,m)=>c+m.cost.hire,0),g=b.reduce((c,m)=>c+m.cost.bunker,0),w=b.reduce((c,m)=>c+m.distance,0),f=b.reduce((c,m)=>c+m.totalHrs,0);return S==null||S.info("[%s][L%d] cost with cpb/cpa turn: %j",s.requestId,s.level,{cost:T,hire:C,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)),C=JSON.parse(JSON.stringify(i.waypoints)),g=o[n],w=await O.analyseInstantWithThreshed(u,l.utc().format(),b,t,g,T,C,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 E.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 E.LaneHelper.deadReckoningTime((u=y.waypoints)==null?void 0:u.at(0),e.sample.all||e.sample.wps),b=await E.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=E.LngLatHelper.roundPrecision((b.positionTime-I.positionTime)/3600,3),y.totalDgoCons=E.LngLatHelper.roundPrecision(t.fo/24*y.totalHrs,3),i+=y.totalHrs,s+=y.totalDgoCons}return n=E.LngLatHelper.roundPrecision(n,3),i=E.LngLatHelper.roundPrecision(i,3),s=E.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((m,h)=>m+h.distance,0),n=e.reduce((m,h)=>{var M;return m+(((M=h.extend)==null?void 0:M.distanceInECA)||0)},0),i=e.reduce((m,h)=>m+h.totalHrs,0),s=e.reduce((m,h)=>{var M;return m+(((M=h.extend)==null?void 0:M.hoursInECA)||0)},0),r=e.reduce((m,h)=>{var M;return m+(((M=h.extend)==null?void 0:M.totalDgoConsInECA)||0)},0),l=e.reduce((m,h)=>m+h.wxFactor*h.totalHrs/i,0),u=e.reduce((m,h)=>m+h.cFactor*h.totalHrs/i,0),d=e.reduce((m,h)=>m+h.totalFoCons,0),y=e.reduce((m,h)=>m+h.totalDgoCons,0),I=e.reduce((m,h)=>m+h.cost.total,0),b=e.reduce((m,h)=>m+h.cost.hire,0),T=e.reduce((m,h)=>m+h.cost.bunker,0),C=[],g=[];let w;for(const m of e){g.push(...((f=m.extend)==null?void 0:f.eca)||[]);const h=m.sample.hours,M=m.sample.wps,k=m.sample.days,F=h.at(0);w&&(F.distanceFromPrevious=w.distanceFromPrevious,F.distanceFromStart=w.distanceFromStart,h.forEach((L,H)=>{H&&(L.distanceFromStart=L.distanceFromStart+w.distanceFromStart)}),M.at(0).distanceFromPrevious=w.distanceFromPrevious,M.at(0).distanceFromStart=w.distanceFromStart,M.forEach((L,H)=>{H&&(L.distanceFromStart=L.distanceFromStart+w.distanceFromStart)}),k.at(0).distanceFromPrevious=w.distanceFromPrevious,k.at(0).distanceFromStart=w.distanceFromStart,k.forEach((L,H)=>{H&&(L.distanceFromStart=L.distanceFromStart+w.distanceFromStart)})),F.cp=m.cost.cp;const q=[m.etd,m.eta],N=C.findIndex(L=>L.id===F.cp.id);N===-1?(F.cp.segment=[q],C.push(F.cp)):C[N].segment.push(q),h.forEach(L=>{var V;((V=a.hours)==null?void 0:V.findIndex(B=>B.eta===L.eta))===-1&&a.hours.push(L)}),M.forEach(L=>{var V;((V=a.wps)==null?void 0:V.findIndex(B=>B.eta===L.eta))===-1&&a.wps.push(L)}),k.forEach(L=>{var V;((V=a==null?void 0:a.days)==null?void 0:V.findIndex(B=>B.eta===L.eta))===-1&&a.days.push(L)});const R=(c=a.wps)==null?void 0:c.findIndex(L=>L.eta===F.eta);R===-1?a.wps.push(F):a.wps[R]=F,w=h.at(-1)}return a.wps.sort((m,h)=>v(m.etd).unix()-v(h.etd).unix()),a.wps.forEach((m,h)=>{const M=a.wps[h-1];if(M){const k=m.distanceFromStart-(M.distanceFromStart||0),F=v(m.eta||m.etd).diff(v(M.etd||M.eta),"hour",!0),q=Math.round(k/F*100)/100;m.avgSpd=q;const N=E.LaneHelper.calculateBearing(M,m);M.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:C,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,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"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "3.5.0",
4
+ "version": "3.5.2",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [