@idm-plugin/vessel 1.2.2 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
- var X = Object.defineProperty;
2
- var $ = (k, s, t) => s in k ? X(k, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : k[s] = t;
3
- var B = (k, s, t) => ($(k, typeof s != "symbol" ? s + "" : s, t), t);
1
+ var $ = Object.defineProperty;
2
+ var tt = (w, s, t) => s in w ? $(w, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : w[s] = t;
3
+ var _ = (w, s, t) => (tt(w, typeof s != "symbol" ? s + "" : s, t), t);
4
4
  import R from "got";
5
5
  import z from "@log4js-node/log4js-api";
6
- import b from "moment";
7
- import { LngLatHelper as Z, LaneHelper as O } from "@idm-plugin/geo";
8
- import { MeteoHelper as tt } from "@idm-plugin/meteo";
6
+ import v from "moment";
7
+ import { LngLatHelper as B, LaneHelper as W } from "@idm-plugin/geo";
8
+ import { MeteoHelper as et } from "@idm-plugin/meteo";
9
9
  let m;
10
10
  try {
11
11
  m = z.getLogger("vessel");
@@ -53,12 +53,12 @@ class K {
53
53
  return { labelCn: t, labelEn: i };
54
54
  }
55
55
  }
56
- class lt extends K {
56
+ class ft extends K {
57
57
  constructor(t, i) {
58
58
  super();
59
- B(this, "clientId");
60
- B(this, "clientSecret");
61
- B(this, "token");
59
+ _(this, "clientId");
60
+ _(this, "clientSecret");
61
+ _(this, "token");
62
62
  this.clientId = t, this.clientSecret = i;
63
63
  }
64
64
  async authToken(t = {}) {
@@ -75,15 +75,15 @@ class lt extends K {
75
75
  expiresIn: n.expires_in,
76
76
  scope: n.scope,
77
77
  jti: n.jti,
78
- issuedAt: b().utc().format()
78
+ issuedAt: v().utc().format()
79
79
  });
80
80
  }
81
81
  async realTimePosition(t, i = {}) {
82
- var p, M, y;
83
- (!this.token || b().diff(b(this.token.issuedAt), "seconds") > ((p = this.token) == null ? void 0 : p.expiresIn) - 300) && await this.authToken(i);
82
+ var u, l, y;
83
+ (!this.token || v().diff(v(this.token.issuedAt), "seconds") > ((u = this.token) == null ? void 0 : u.expiresIn) - 300) && await this.authToken(i);
84
84
  const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
85
85
  headers: {
86
- Authorization: `${(M = this.token) == null ? void 0 : M.tokenType} ${(y = this.token) == null ? void 0 : y.accessToken}`
86
+ Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(y = this.token) == null ? void 0 : y.accessToken}`
87
87
  },
88
88
  searchParams: { mmsi: t }
89
89
  };
@@ -92,9 +92,9 @@ class lt extends K {
92
92
  if (a.code)
93
93
  return m == null || m.warn("[%s] fetch realtime position failed: %j", i.requestId, o, { message: a.message, status: a.status, code: a.code }), a;
94
94
  const e = a.data;
95
- for (const f in e)
96
- !isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
97
- const d = b(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
95
+ for (const p in e)
96
+ !isNaN(e[p]) && Number(e[p]) !== 1 / 0 && (e[p] = Number(e[p]));
97
+ const d = v(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
98
98
  return {
99
99
  mmsi: e.mmsi,
100
100
  name: e.vesselName,
@@ -121,17 +121,17 @@ class lt extends K {
121
121
  };
122
122
  }
123
123
  async trajectory(t, i, o, n, a = !0, e = {}) {
124
- (!this.token || b().diff(b(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
125
- const d = await this.realTimePosition(t, e), r = b(i), p = b(o), M = [];
126
- for (; p.diff(r, "day", !0) > 30; )
127
- await this.trajectoryIn30Day(t, r, r.clone().add(30, "day"), d, n, M, e), r.add(30, "day");
128
- return await this.trajectoryIn30Day(t, r, p, d, n, M, e), M;
124
+ (!this.token || v().diff(v(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
125
+ const d = await this.realTimePosition(t, e), c = v(i), u = v(o), l = [];
126
+ for (; u.diff(c, "day", !0) > 30; )
127
+ await this.trajectoryIn30Day(t, c, c.clone().add(30, "day"), d, n, l, e), c.add(30, "day");
128
+ return await this.trajectoryIn30Day(t, c, u, d, n, l, e), l;
129
129
  }
130
130
  async trajectoryIn30Day(t, i, o, n, a, e, d = {}) {
131
- var l, v, Y, u, c;
132
- const r = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", p = {
131
+ var h, b, I, Y, M;
132
+ const c = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", u = {
133
133
  headers: {
134
- Authorization: `${(l = this.token) == null ? void 0 : l.tokenType} ${(v = this.token) == null ? void 0 : v.accessToken}`
134
+ Authorization: `${(h = this.token) == null ? void 0 : h.tokenType} ${(b = this.token) == null ? void 0 : b.accessToken}`
135
135
  },
136
136
  json: {
137
137
  mmsi: t,
@@ -139,42 +139,42 @@ class lt extends K {
139
139
  endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
140
140
  }
141
141
  };
142
- m == null || m.info("[%s] fetch trajectory from: %s - %j", d.requestId, r, p);
143
- const M = await R.post(r, p).json();
144
- if (M.code)
145
- return m == null || m.warn("[%s] fetch trajectory failed: %j", d.requestId, r, { message: M.message, status: M.status, code: M.code }), M;
142
+ m == null || m.info("[%s] fetch trajectory from: %s - %j", d.requestId, c, u);
143
+ const l = await R.post(c, u).json();
144
+ if (l.code)
145
+ return m == null || m.warn("[%s] fetch trajectory failed: %j", d.requestId, c, { message: l.message, status: l.status, code: l.code }), l;
146
146
  let y = -1;
147
- const f = b(`${(u = (Y = M.data) == null ? void 0 : Y[0]) == null ? void 0 : u.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
148
- return (c = M.data) == null || c.forEach((h) => {
149
- for (const S in h)
150
- !isNaN(h[S]) && Number(h[S]) !== 1 / 0 && (h[S] = Number(h[S]));
151
- const w = b(`${h.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), I = h.eta ? b(`${h.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, g = h.status, { labelCn: F, labelEn: x } = this.parseStatus(g), A = {
152
- mmsi: h.mmsi,
147
+ const p = v(`${(Y = (I = l.data) == null ? void 0 : I[0]) == null ? void 0 : Y.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
148
+ return (M = l.data) == null || M.forEach((r) => {
149
+ for (const j in r)
150
+ !isNaN(r[j]) && Number(r[j]) !== 1 / 0 && (r[j] = Number(r[j]));
151
+ const g = v(`${r.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), k = r.eta ? v(`${r.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, f = r.status, { labelCn: N, labelEn: A } = this.parseStatus(f), x = {
152
+ mmsi: r.mmsi,
153
153
  imo: n == null ? void 0 : n.imo,
154
- lat: h.lat,
155
- lng: h.lon,
156
- sog: h.sog,
157
- cog: h.cog,
158
- hdg: h.hdg,
159
- draught: h.draught,
160
- status: g,
161
- eta: I == null ? void 0 : I.unix(),
162
- destination: h.dest,
163
- positionTime: w.unix(),
164
- labelCn: F,
165
- labelEn: x,
154
+ lat: r.lat,
155
+ lng: r.lon,
156
+ sog: r.sog,
157
+ cog: r.cog,
158
+ hdg: r.hdg,
159
+ draught: r.draught,
160
+ status: f,
161
+ eta: k == null ? void 0 : k.unix(),
162
+ destination: r.dest,
163
+ positionTime: g.unix(),
164
+ labelCn: N,
165
+ labelEn: A,
166
166
  method: "trajectory",
167
167
  vendor: "myVessel",
168
- utc: w.utc().format()
169
- }, T = Math.floor(w.diff(f, "minute", !0) / (a || 1));
170
- T !== y && (y = T, e.push(A));
168
+ utc: g.utc().format()
169
+ }, O = Math.floor(g.diff(p, "minute", !0) / (a || 1));
170
+ O !== y && (y = O, e.push(x));
171
171
  }), e;
172
172
  }
173
173
  }
174
- class ft extends K {
174
+ class mt extends K {
175
175
  constructor(t) {
176
176
  super();
177
- B(this, "token");
177
+ _(this, "token");
178
178
  this.token = t;
179
179
  }
180
180
  async realTimePosition(t, i = {}) {
@@ -188,10 +188,10 @@ class ft extends K {
188
188
  const e = a == null ? void 0 : a.list;
189
189
  if (!e)
190
190
  return m == null || m.warn("[%s] fetch realtime position failed: %j", i.requestId, o, a), a;
191
- for (const f in e)
192
- !isNaN(e[f]) && Number(e[f]) !== 1 / 0 && (e[f] = Number(e[f]));
191
+ for (const p in e)
192
+ !isNaN(e[p]) && Number(e[p]) !== 1 / 0 && (e[p] = Number(e[p]));
193
193
  e.status = e.sp > 3 ? 0 : 1;
194
- const d = e.status, { labelCn: r, labelEn: p } = this.parseStatus(d), M = b(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
194
+ const d = e.status, { labelCn: c, labelEn: u } = this.parseStatus(d), l = v(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
195
195
  return {
196
196
  mmsi: e.m,
197
197
  name: e.n,
@@ -206,13 +206,13 @@ class ft extends K {
206
206
  cog: e.co,
207
207
  hdg: e.h,
208
208
  rot: isNaN(e.rot) ? 0 : e.rot,
209
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? b(`${e.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
209
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? v(`${e.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
210
210
  destination: e.destination,
211
- positionTime: M.unix(),
212
- utc: M.utc().format(),
211
+ positionTime: l.unix(),
212
+ utc: l.utc().format(),
213
213
  status: d,
214
- labelCn: r,
215
- labelEn: p,
214
+ labelCn: c,
215
+ labelEn: u,
216
216
  method: "position",
217
217
  vendor: "hifleet"
218
218
  };
@@ -245,60 +245,60 @@ class ft extends K {
245
245
  return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await R.post(o, n).json(), m == null || m.info("[%s] fetch vessel dead weight from: %s - %j", i.requestId, o, n), a instanceof Array && (a = a[0]), a && (e.deadweight = Number(a.dwt)), e;
246
246
  }
247
247
  async trajectory(t, i, o, n, a = !0, e = {}) {
248
- var h, w, I;
248
+ var r, g, k;
249
249
  const d = await this.realTimePosition(t, e);
250
- let r = b(i);
251
- const p = b(o), M = b();
250
+ let c = v(i);
251
+ const u = v(o), l = v();
252
252
  if (a) {
253
- let g = p.diff(r, "d", !0);
254
- g < 0 ? r = p.clone().subtract(40, "d") : g < 30 ? r.subtract(10, "d") : g < 60 ? r.subtract(5, "d") : r = p.clone().subtract(80, "d"), g = M.diff(p, "d", !0), p.add(g > 10 ? 240 : g * 24, "h");
253
+ let f = u.diff(c, "d", !0);
254
+ f < 0 ? c = u.clone().subtract(40, "d") : f < 30 ? c.subtract(10, "d") : f < 60 ? c.subtract(5, "d") : c = u.clone().subtract(80, "d"), f = l.diff(u, "d", !0), u.add(f > 10 ? 240 : f * 24, "h");
255
255
  }
256
256
  const y = {
257
257
  searchParams: {
258
- endtime: p.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
259
- starttime: r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
258
+ endtime: u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
259
+ starttime: c.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
260
260
  mmsi: t,
261
261
  usertoken: this.token
262
262
  }
263
- }, f = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", l = await R.get(f, y).json();
264
- m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, f, y);
265
- let v;
266
- l && (v = ((w = (h = l.ships) == null ? void 0 : h.offors) == null ? void 0 : w.ship) || [], v.length || m == null || m.warn("[%s] fetch trajectory failed: %j", e.requestId, l));
267
- const Y = [];
268
- let u = -1;
269
- const c = b(`${(I = v == null ? void 0 : v[0]) == null ? void 0 : I.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
270
- for (const g of v) {
271
- for (const L in g)
272
- !isNaN(g[L]) && Number(g[L]) !== 1 / 0 && (g[L] = Number(g[L]));
273
- const F = b(`${g.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
274
- g.status = g.sp > 4 ? 0 : 1;
275
- const { labelEn: x, labelCn: A } = this.parseStatus(g.status), T = {
276
- mmsi: g.m,
277
- name: g.n,
263
+ }, p = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", h = await R.get(p, y).json();
264
+ m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, p, y);
265
+ let b;
266
+ h && (b = ((g = (r = h.ships) == null ? void 0 : r.offors) == null ? void 0 : g.ship) || [], b.length || m == null || m.warn("[%s] fetch trajectory failed: %j", e.requestId, h));
267
+ const I = [];
268
+ let Y = -1;
269
+ const M = v(`${(k = b == null ? void 0 : b[0]) == null ? void 0 : k.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
270
+ for (const f of b) {
271
+ for (const D in f)
272
+ !isNaN(f[D]) && Number(f[D]) !== 1 / 0 && (f[D] = Number(f[D]));
273
+ const N = v(`${f.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
274
+ f.status = f.sp > 4 ? 0 : 1;
275
+ const { labelEn: A, labelCn: x } = this.parseStatus(f.status), O = {
276
+ mmsi: f.m,
277
+ name: f.n,
278
278
  imo: d == null ? void 0 : d.imo,
279
- lat: g.la,
280
- lng: g.lo,
281
- draught: g.draught,
282
- sog: g.sp,
283
- cog: g.co,
284
- hdg: g.hdg,
285
- positionTime: F.unix(),
286
- utc: F.utc().format(),
287
- status: g.status,
288
- labelCn: A,
289
- labelEn: x,
279
+ lat: f.la,
280
+ lng: f.lo,
281
+ draught: f.draught,
282
+ sog: f.sp,
283
+ cog: f.co,
284
+ hdg: f.hdg,
285
+ positionTime: N.unix(),
286
+ utc: N.utc().format(),
287
+ status: f.status,
288
+ labelCn: x,
289
+ labelEn: A,
290
290
  method: "trajectory",
291
291
  vendor: "hifleet"
292
- }, S = Math.floor(F.diff(c, "minute", !0) / (n || 1));
293
- S !== u && (u = S, Y.push(T));
292
+ }, j = Math.floor(N.diff(M, "minute", !0) / (n || 1));
293
+ j !== Y && (Y = j, I.push(O));
294
294
  }
295
- return Y;
295
+ return I;
296
296
  }
297
297
  }
298
- class mt extends K {
298
+ class pt extends K {
299
299
  constructor(t) {
300
300
  super();
301
- B(this, "token");
301
+ _(this, "token");
302
302
  this.token = t;
303
303
  }
304
304
  async realTimePosition(t, i = {}) {
@@ -314,7 +314,7 @@ class mt extends K {
314
314
  const e = a.data[0];
315
315
  for (const y in e)
316
316
  !isNaN(e[y]) && Number(e[y]) !== 1 / 0 && (e[y] = Number(e[y]));
317
- const { labelCn: d, labelEn: r } = await this.parseStatus(e.navistat), p = b.unix(e.lasttime);
317
+ const { labelCn: d, labelEn: c } = await this.parseStatus(e.navistat), u = v.unix(e.lasttime);
318
318
  return {
319
319
  mmsi: e.ShipID,
320
320
  name: e.name,
@@ -330,52 +330,52 @@ class mt extends K {
330
330
  hdg: Math.round(e.hdg / 100 * 100) / 100,
331
331
  rot: Math.round(e.rot / 100 * 100) / 100,
332
332
  positionTime: e.lasttime,
333
- utc: p.utc().format(),
333
+ utc: u.utc().format(),
334
334
  status: e.navistat,
335
- labelEn: r,
335
+ labelEn: c,
336
336
  labelCn: d,
337
337
  method: "position",
338
338
  vendor: "shipxy"
339
339
  };
340
340
  }
341
341
  async trajectory(t, i, o, n, a = !0, e = {}) {
342
- var c;
343
- const d = await this.realTimePosition(t, e), r = b(i), p = b(o), M = "https://api.shipxy.com/apicall/GetShipTrack", y = {
342
+ var M;
343
+ const d = await this.realTimePosition(t, e), c = v(i), u = v(o), l = "https://api.shipxy.com/apicall/GetShipTrack", y = {
344
344
  searchParams: {
345
345
  id: t,
346
346
  k: this.token,
347
347
  enc: 1,
348
348
  cut: 0,
349
- btm: r.unix(),
350
- etm: p.unix()
349
+ btm: c.unix(),
350
+ etm: u.unix()
351
351
  }
352
- }, f = await R.get(M, y).json();
353
- if (m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, M, y), (f == null ? void 0 : f.status) !== 0)
354
- return f;
355
- const l = f == null ? void 0 : f.points, v = [], Y = b.unix((c = l[0]) == null ? void 0 : c.utc);
356
- let u = -1;
357
- for (const h of l) {
358
- const w = b.unix(h.utc), I = {
352
+ }, p = await R.get(l, y).json();
353
+ if (m == null || m.info("[%s] fetch trajectory from: %s - %j", e.requestId, l, y), (p == null ? void 0 : p.status) !== 0)
354
+ return p;
355
+ const h = p == null ? void 0 : p.points, b = [], I = v.unix((M = h[0]) == null ? void 0 : M.utc);
356
+ let Y = -1;
357
+ for (const r of h) {
358
+ const g = v.unix(r.utc), k = {
359
359
  imo: d == null ? void 0 : d.imo,
360
360
  mmsi: t,
361
- sog: Math.round(h.sog * 3600 / 1e3 / 1852 * 100) / 100,
362
- cog: Math.round(h.cog / 100 * 100) / 100,
363
- lat: Math.round(h.lat / 1e6 * 1e5) / 1e5,
364
- lng: Math.round(h.lon / 1e6 * 1e5) / 1e5,
365
- positionTime: w.unix(),
366
- utc: w.utc().format(),
361
+ sog: Math.round(r.sog * 3600 / 1e3 / 1852 * 100) / 100,
362
+ cog: Math.round(r.cog / 100 * 100) / 100,
363
+ lat: Math.round(r.lat / 1e6 * 1e5) / 1e5,
364
+ lng: Math.round(r.lon / 1e6 * 1e5) / 1e5,
365
+ positionTime: g.unix(),
366
+ utc: g.utc().format(),
367
367
  method: "trajectory",
368
368
  vendor: "shipxy"
369
- }, g = Math.floor(w.diff(Y, "minute", !0) / (n || 1));
370
- g !== u && (u = g, v.push(I));
369
+ }, f = Math.floor(g.diff(I, "minute", !0) / (n || 1));
370
+ f !== Y && (Y = f, b.push(k));
371
371
  }
372
- return v;
372
+ return b;
373
373
  }
374
374
  }
375
- class pt extends K {
375
+ class Mt extends K {
376
376
  constructor(t) {
377
377
  super();
378
- B(this, "token");
378
+ _(this, "token");
379
379
  this.token = t;
380
380
  }
381
381
  async getShipId(t, i = {}) {
@@ -422,37 +422,37 @@ class pt extends K {
422
422
  }
423
423
  }, e = "https://api3.myships.com/sp/ships/position/latest", d = await R.post(e, a).json();
424
424
  m == null || m.info("[%s] fetch realtime position from: %s - %j", i.requestId, e, a);
425
- const r = d.data[0];
426
- for (const l in r)
427
- !isNaN(r[l]) && Number(r[l]) !== 1 / 0 && (r[l] = Number(r[l]));
428
- const { labelCn: p, labelEn: M } = await this.parseStatus(r.aisNavStatus), y = b.unix(r.posTime);
425
+ const c = d.data[0];
426
+ for (const h in c)
427
+ !isNaN(c[h]) && Number(c[h]) !== 1 / 0 && (c[h] = Number(c[h]));
428
+ const { labelCn: u, labelEn: l } = await this.parseStatus(c.aisNavStatus), y = v.unix(c.posTime);
429
429
  return {
430
430
  ...n,
431
431
  mmsi: t,
432
- lat: Math.round(r.lat / 1e4 / 60 * 1e5) / 1e5,
433
- lng: Math.round(r.lon / 1e4 / 60 * 1e5) / 1e5,
434
- sog: Math.round(r.sog / 10 * 100) / 100,
435
- cog: Math.round(r.cog / 10 * 100) / 100,
436
- hdg: Math.round(r.heading * 100) / 100,
437
- rot: Math.round(r.rot * 100) / 100,
438
- positionTime: r.posTime,
432
+ lat: Math.round(c.lat / 1e4 / 60 * 1e5) / 1e5,
433
+ lng: Math.round(c.lon / 1e4 / 60 * 1e5) / 1e5,
434
+ sog: Math.round(c.sog / 10 * 100) / 100,
435
+ cog: Math.round(c.cog / 10 * 100) / 100,
436
+ hdg: Math.round(c.heading * 100) / 100,
437
+ rot: Math.round(c.rot * 100) / 100,
438
+ positionTime: c.posTime,
439
439
  utc: y.utc().format(),
440
- status: r.aisNavStatus,
441
- labelEn: M,
442
- labelCn: p,
440
+ status: c.aisNavStatus,
441
+ labelEn: l,
442
+ labelCn: u,
443
443
  method: "position",
444
444
  vendor: "myship"
445
445
  };
446
446
  }
447
447
  async trajectory(t, i, o, n, a = !0, e = {}) {
448
- const d = b(i), r = b(o), p = await this.getShipId(t), M = await this.getShipInfo(p), y = [];
449
- for (; r.diff(d, "day", !0) > 30; )
450
- await this.trajectoryIn30Day(p, d.unix(), d.add(30, "day").unix(), M, t, n, y);
451
- return await this.trajectoryIn30Day(p, d.unix(), r.unix(), M, t, n, y), y;
452
- }
453
- async trajectoryIn30Day(t, i, o, n, a, e, d, r = {}) {
454
- var Y;
455
- const p = {
448
+ const d = v(i), c = v(o), u = await this.getShipId(t), l = await this.getShipInfo(u), y = [];
449
+ for (; c.diff(d, "day", !0) > 30; )
450
+ await this.trajectoryIn30Day(u, d.unix(), d.add(30, "day").unix(), l, t, n, y);
451
+ return await this.trajectoryIn30Day(u, d.unix(), c.unix(), l, t, n, y), y;
452
+ }
453
+ async trajectoryIn30Day(t, i, o, n, a, e, d, c = {}) {
454
+ var I;
455
+ const u = {
456
456
  headers: {
457
457
  appKey: this.token
458
458
  },
@@ -461,30 +461,30 @@ class pt extends K {
461
461
  startTime: i,
462
462
  endTime: o
463
463
  }
464
- }, M = "https://api3.myships.com/sp/ships/position/history", y = await R.post(M, p).json();
465
- if (m == null || m.info("[%s] fetch trajectory from: %s - %j", r.requestId, M, p), y.code !== "0")
466
- return m == null || m.warn("[%s] invoke myship trajectory failed: %j", r.requestId, y), y;
467
- const f = y.data;
468
- for (const u in f)
469
- !isNaN(f[u]) && Number(f[u]) !== 1 / 0 && (f[u] = Number(f[u]));
470
- const l = b.unix((Y = f[0]) == null ? void 0 : Y.posTime);
471
- let v = -1;
472
- for (const u of f) {
473
- const c = b.unix(u.posTime), h = {
464
+ }, l = "https://api3.myships.com/sp/ships/position/history", y = await R.post(l, u).json();
465
+ if (m == null || m.info("[%s] fetch trajectory from: %s - %j", c.requestId, l, u), y.code !== "0")
466
+ return m == null || m.warn("[%s] invoke myship trajectory failed: %j", c.requestId, y), y;
467
+ const p = y.data;
468
+ for (const Y in p)
469
+ !isNaN(p[Y]) && Number(p[Y]) !== 1 / 0 && (p[Y] = Number(p[Y]));
470
+ const h = v.unix((I = p[0]) == null ? void 0 : I.posTime);
471
+ let b = -1;
472
+ for (const Y of p) {
473
+ const M = v.unix(Y.posTime), r = {
474
474
  imo: n == null ? void 0 : n.imo,
475
475
  mmsi: a,
476
- lat: Math.round(u.lat / 1e4 / 60 * 1e5) / 1e5,
477
- lng: Math.round(u.lon / 1e4 / 60 * 1e5) / 1e5,
478
- sog: Math.round(u.sog / 10 * 100) / 100,
479
- cog: Math.round(u.cog / 10 * 100) / 100,
480
- hdg: Math.round(u.heading * 100) / 100,
481
- rot: Math.round(u.rot * 100) / 100,
482
- positionTime: c.unix(),
483
- utc: c.utc().format(),
476
+ lat: Math.round(Y.lat / 1e4 / 60 * 1e5) / 1e5,
477
+ lng: Math.round(Y.lon / 1e4 / 60 * 1e5) / 1e5,
478
+ sog: Math.round(Y.sog / 10 * 100) / 100,
479
+ cog: Math.round(Y.cog / 10 * 100) / 100,
480
+ hdg: Math.round(Y.heading * 100) / 100,
481
+ rot: Math.round(Y.rot * 100) / 100,
482
+ positionTime: M.unix(),
483
+ utc: M.utc().format(),
484
484
  method: "trajectory",
485
485
  vendor: "myship"
486
- }, w = Math.floor(c.diff(l, "minute", !0) / (e || 1));
487
- w !== v && (v = w, d.push(h));
486
+ }, g = Math.floor(M.diff(h, "minute", !0) / (e || 1));
487
+ g !== b && (b = g, d.push(r));
488
488
  }
489
489
  return d;
490
490
  }
@@ -495,8 +495,8 @@ try {
495
495
  } catch {
496
496
  } finally {
497
497
  }
498
- var et = /* @__PURE__ */ ((k) => (k.NOTICE = "NOTICE", k.WARN = "WARN", k.HEAVY = "HEAVY", k.SEVERE = "SEVERE", k.ERROR = "ERROR", k.FATAL = "FATAL", k))(et || {});
499
- class st {
498
+ var st = /* @__PURE__ */ ((w) => (w.NOTICE = "NOTICE", w.WARN = "WARN", w.HEAVY = "HEAVY", w.SEVERE = "SEVERE", w.ERROR = "ERROR", w.FATAL = "FATAL", w))(st || {});
499
+ class at {
500
500
  /**
501
501
  * 解析告警规则, 多规则场景
502
502
  * @param rule
@@ -506,20 +506,20 @@ class st {
506
506
  * @param options
507
507
  */
508
508
  parsePrinciple(s, t = {}) {
509
- var e, d, r;
509
+ var e, d, c;
510
510
  C == null || C.info("[%s] parse rule: %s", t.requestId, s);
511
511
  const i = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = s.match(i) ? (e = s.match(i)) == null ? void 0 : e[0] : void 0, n = o == null ? void 0 : o.split(";");
512
512
  if (!n)
513
513
  return;
514
514
  const a = {};
515
- for (let p = 0; p < (n == null ? void 0 : n.length); p++) {
516
- const M = (r = (d = n[p].match(i)) == null ? void 0 : d[0]) == null ? void 0 : r.split("],");
517
- if (p === 0 && !M)
515
+ for (let u = 0; u < (n == null ? void 0 : n.length); u++) {
516
+ const l = (c = (d = n[u].match(i)) == null ? void 0 : d[0]) == null ? void 0 : c.split("],");
517
+ if (u === 0 && !l)
518
518
  a.scope = n[0];
519
- else if (M)
520
- for (let y = 0, f = M.length; y < f; y++) {
521
- const l = this.parseRule(M[y]);
522
- l && (a[l.level] ? l.key ? a[l.level][l == null ? void 0 : l.key] = l : a[l.level] = l : l.key ? a[l.level] = { [l == null ? void 0 : l.key]: l } : a[l.level] = l);
519
+ else if (l)
520
+ for (let y = 0, p = l.length; y < p; y++) {
521
+ const h = this.parseRule(l[y]);
522
+ h && (a[h.level] ? h.key ? a[h.level][h == null ? void 0 : h.key] = h : a[h.level] = h : h.key ? a[h.level] = { [h == null ? void 0 : h.key]: h } : a[h.level] = h);
523
523
  }
524
524
  }
525
525
  return a;
@@ -550,24 +550,24 @@ class st {
550
550
  * @param options
551
551
  */
552
552
  checkWeather(s, t, i = {}) {
553
- var l, v, Y, u, c, h, w, I, g, F, x, A, T, S, L;
553
+ var h, b, I, Y, M, r, g, k, f, N, A, x, O, j, D;
554
554
  let o = 0, n = 0, a = 0, e = 0;
555
- const d = Math.round(((v = (l = t == null ? void 0 : t.SEVERE) == null ? void 0 : l.sigWave) == null ? void 0 : v.number) * 1.6 * 100) / 100, r = (u = (Y = t == null ? void 0 : t.SEVERE) == null ? void 0 : Y.sigWave) == null ? void 0 : u.number, p = (h = (c = t == null ? void 0 : t.HEAVY) == null ? void 0 : c.sigWave) == null ? void 0 : h.number, M = Math.round((((I = (w = t == null ? void 0 : t.SEVERE) == null ? void 0 : w.wind) == null ? void 0 : I.number) + 2) * 100) / 100, y = (F = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.wind) == null ? void 0 : F.number, f = (A = (x = t == null ? void 0 : t.HEAVY) == null ? void 0 : x.wind) == null ? void 0 : A.number;
556
- for (let V = 0; V < (s == null ? void 0 : s.length); V++) {
557
- const j = s[V], q = (S = (T = j == null ? void 0 : j.meteo) == null ? void 0 : T.wave) == null ? void 0 : S.sig, P = (L = j == null ? void 0 : j.meteo) == null ? void 0 : L.wind, _ = V ? b(j.eta).diff(b(s[V - 1].eta), "hour", !0) : 0;
558
- e = _ > e ? _ : e, C == null || C.info("[%s] check sig.wave: %j", i.requestId, { ...q, dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: p }), (q == null ? void 0 : q.height) >= d ? j.isDangerous = !0 : (q == null ? void 0 : q.height) >= r ? j.isSevere = !0 : (q == null ? void 0 : q.height) >= p && (j.isHeavy = !0), C == null || C.info("[%s] check wind: %j", i.requestId, { ...P, dgThd4Wd: M, svThd4Wd: y, hvThd4Wd: f }), (P == null ? void 0 : P.scale) >= M ? (j.isDangerous = !0, delete j.isSevere, delete j.isHeavy) : (P == null ? void 0 : P.scale) > y ? (j.isDangerous || (j.isSevere = !0), delete j.isHeavy) : (P == null ? void 0 : P.scale) === f && !j.isDangerous && !j.isSevere && (j.isHeavy = !0), o += j.isDangerous ? _ : 0, n += j.isSevere ? _ : 0, a += j.isHeavy ? _ : 0;
555
+ const d = Math.round(((b = (h = t == null ? void 0 : t.SEVERE) == null ? void 0 : h.sigWave) == null ? void 0 : b.number) * 1.6 * 100) / 100, c = (Y = (I = t == null ? void 0 : t.SEVERE) == null ? void 0 : I.sigWave) == null ? void 0 : Y.number, u = (r = (M = t == null ? void 0 : t.HEAVY) == null ? void 0 : M.sigWave) == null ? void 0 : r.number, l = Math.round((((k = (g = t == null ? void 0 : t.SEVERE) == null ? void 0 : g.wind) == null ? void 0 : k.number) + 2) * 100) / 100, y = (N = (f = t == null ? void 0 : t.SEVERE) == null ? void 0 : f.wind) == null ? void 0 : N.number, p = (x = (A = t == null ? void 0 : t.HEAVY) == null ? void 0 : A.wind) == null ? void 0 : x.number;
556
+ for (let Z = 0; Z < (s == null ? void 0 : s.length); Z++) {
557
+ const T = s[Z], q = (j = (O = T == null ? void 0 : T.meteo) == null ? void 0 : O.wave) == null ? void 0 : j.sig, P = (D = T == null ? void 0 : T.meteo) == null ? void 0 : D.wind, V = Z ? v(T.eta).diff(v(s[Z - 1].eta), "hour", !0) : 0;
558
+ e = V > e ? V : e, C == null || C.info("[%s] check sig.wave: %j", i.requestId, { ...q, dgThd4Wv: d, svThd4Wv: c, hvThd4Wv: u }), (q == null ? void 0 : q.height) >= d ? T.isDangerous = !0 : (q == null ? void 0 : q.height) >= c ? T.isSevere = !0 : (q == null ? void 0 : q.height) >= u && (T.isHeavy = !0), C == null || C.info("[%s] check wind: %j", i.requestId, { ...P, dgThd4Wd: l, svThd4Wd: y, hvThd4Wd: p }), (P == null ? void 0 : P.scale) >= l ? (T.isDangerous = !0, delete T.isSevere, delete T.isHeavy) : (P == null ? void 0 : P.scale) > y ? (T.isDangerous || (T.isSevere = !0), delete T.isHeavy) : (P == null ? void 0 : P.scale) === p && !T.isDangerous && !T.isSevere && (T.isHeavy = !0), o += T.isDangerous ? V : 0, n += T.isSevere ? V : 0, a += T.isHeavy ? V : 0;
559
559
  }
560
- return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, a = Math.round(a * 100) / 100, e = Math.round(e), { sample: s, dangerous: o, severe: n, heavy: a, step: e < 3 ? 3 : e, wind: { dgThd4Wd: M, svThd4Wd: y, hvThd4Wd: f }, sig: { dgThd4Wv: d, svThd4Wv: r, hvThd4Wv: p } };
560
+ return o = Math.round(o * 100) / 100, n = Math.round(n * 100) / 100, a = Math.round(a * 100) / 100, e = Math.round(e), { sample: s, dangerous: o, severe: n, heavy: a, step: e < 3 ? 3 : e, wind: { dgThd4Wd: l, svThd4Wd: y, hvThd4Wd: p }, sig: { dgThd4Wv: d, svThd4Wv: c, hvThd4Wv: u } };
561
561
  }
562
562
  }
563
- const Mt = new st();
564
- let D;
563
+ const yt = new at();
564
+ let S;
565
565
  try {
566
- D = z.getLogger("vessel");
566
+ S = z.getLogger("vessel");
567
567
  } catch {
568
568
  } finally {
569
569
  }
570
- var at = /* @__PURE__ */ ((k) => (k.common = "common", k.container = "container", k))(at || {}), ot = /* @__PURE__ */ ((k) => (k.Ballast = "Ballast", k.Laden = "Laden", k))(ot || {}), nt = /* @__PURE__ */ ((k) => (k.Cp = "CP", k.Perf = "Basis", k.Instruct = "Other", k))(nt || {});
570
+ var ot = /* @__PURE__ */ ((w) => (w.common = "common", w.container = "container", w))(ot || {}), nt = /* @__PURE__ */ ((w) => (w.Ballast = "Ballast", w.Laden = "Laden", w))(nt || {}), it = /* @__PURE__ */ ((w) => (w.Cp = "CP", w.Perf = "Basis", w.Instruct = "Other", w))(it || {});
571
571
  class E {
572
572
  /**
573
573
  * @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
@@ -678,11 +678,11 @@ class E {
678
678
  * @private
679
679
  */
680
680
  static assembleProperties(s, t, i, o) {
681
- var p, M;
681
+ var u, l;
682
682
  const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, a = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, d = s.deadweight ?? 67035.7773;
683
683
  return {
684
684
  // @ts-ignore
685
- tag: ((M = (p = s == null ? void 0 : s.type) == null ? void 0 : p.toLowerCase()) == null ? void 0 : M.indexOf("container")) > -1 ? "container" : "common",
685
+ tag: ((l = (u = s == null ? void 0 : s.type) == null ? void 0 : u.toLowerCase()) == null ? void 0 : l.indexOf("container")) > -1 ? "container" : "common",
686
686
  lbp: n,
687
687
  loadCondition: t,
688
688
  draught: a,
@@ -702,19 +702,30 @@ class E {
702
702
  * @param eta 位置时间
703
703
  * @param source [CMEMS, GFS, Other]
704
704
  * @param role 1: 船东, 2: 租家, 0: 未知
705
+ * @param useMeteo true 启用气象分析
705
706
  * @param useRouteParam true 启用设置速度
706
707
  */
707
- static async speedLoseAt(s, t, i, o = "", n = 2, a = !1, e = {}) {
708
- t.velocity && !t.noFactor && a && (s.speed = Z.roundPrecision(t.velocity * 1852 / 3600, 6));
709
- const d = await tt.queryPointFactor(t.lng, t.lat, i.valueOf(), "wind,wave,current,watertemp", o, e), r = E.weatherFactor(s, d), p = E.currentFactor(s.bearing, d == null ? void 0 : d.current, n), M = {
710
- meteo: { ...d },
711
- wxFactor: r,
712
- cFactor: p,
713
- speed: t.velocity && a ? t.velocity : Math.round((s.speed * 1.943844 + r + p) * 100) / 100,
714
- eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
715
- etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
716
- };
717
- return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...M, ...t };
708
+ static async speedLoseAt(s, t, i, o = "", n = 2, a = !0, e = !1, d = {}) {
709
+ let c;
710
+ if (t.velocity && e && (s.speed = B.roundPrecision(t.velocity * 1852 / 3600, 6)), a) {
711
+ const u = await et.queryPointFactor(t.lng, t.lat, i.valueOf(), "wind,wave,current,watertemp", o, d), l = E.weatherFactor(s, u), y = E.currentFactor(s.bearing, u == null ? void 0 : u.current, n);
712
+ c = {
713
+ meteo: { ...u },
714
+ wxFactor: l,
715
+ cFactor: y,
716
+ speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 + l + y) * 100) / 100,
717
+ eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
718
+ etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
719
+ };
720
+ } else
721
+ c = {
722
+ wxFactor: 0,
723
+ cFactor: 0,
724
+ speed: t.velocity && e ? t.velocity : Math.round((s.speed * 1.943844 + 0 + 0) * 100) / 100,
725
+ eta: i.utc().format("YYYY-MM-DDTHH:mm[Z]"),
726
+ etd: i.utc().format("YYYY-MM-DDTHH:mm[Z]")
727
+ };
728
+ return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...c, ...t };
718
729
  }
719
730
  /**
720
731
  * 基于步长计算失速样本
@@ -725,55 +736,56 @@ class E {
725
736
  * @param distanceFromStart 与最开始起点的距离
726
737
  * @param keypoints 剩下的航路点
727
738
  * @param source 气象数据源: CMEMS / GFS
739
+ * @param useMeteo true 启用气象分析
728
740
  * @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
729
741
  * @private
730
742
  */
731
- static async speedLoseInHoursStep(s, t, i, o, n, a, e = "", d = !1, r = {}) {
743
+ static async speedLoseInHoursStep(s, t, i, o, n, a, e = "", d = !0, c = !1, u = {}) {
732
744
  t.utc();
733
- const p = [], M = [];
734
- let y = 0, f = 0, l, v;
745
+ const l = [], y = [];
746
+ let p = 0, h = 0, b, I;
735
747
  for (let Y = 0; Y < a.length - 1; Y++) {
736
- let u = a[Y];
737
- u.distanceFromStart = n + f;
738
- const c = a[Y + 1];
739
- if (s.bearing = O.calculateBearing(u, c, !c.gcToPrevious), u.bearing = s.bearing, u.suspend && d) {
740
- u.eta = u.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), u.elapsed = u.elapsed ?? 0;
741
- const I = u.suspend - u.elapsed;
742
- if (o - y > I)
743
- o = o - y - I, t.add(I, "hour"), u.elapsed = u.suspend;
748
+ let M = a[Y];
749
+ M.distanceFromStart = n + h;
750
+ const r = a[Y + 1];
751
+ if (s.bearing = W.calculateBearing(M, r, !r.gcToPrevious), M.bearing = s.bearing, M.suspend && c) {
752
+ M.eta = M.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), M.elapsed = M.elapsed ?? 0;
753
+ const f = M.suspend - M.elapsed;
754
+ if (o - p > f)
755
+ o = o - p - f, t.add(f, "hour"), M.elapsed = M.suspend;
744
756
  else {
745
- const g = o - y;
746
- u.elapsed += g, t.add(g, "hour"), o = 0;
757
+ const N = o - p;
758
+ M.elapsed += N, t.add(N, "hour"), o = 0;
747
759
  }
748
- if (D == null || D.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${o} hours need to go...`, r.requestId, u), o === 0)
749
- return u.distanceFromPrevious = f, { etd: t, from: v || u, to: u, next: a.filter((g) => g), wps: p, days: M };
760
+ if (S == null || S.info(`[%s] suspend ${M.elapsed} hours at %j, and remain ${o} hours need to go...`, u.requestId, M), o === 0)
761
+ return M.distanceFromPrevious = h, { etd: t, from: I || M, to: M, next: a.filter((N) => N), wps: l, days: y };
750
762
  }
751
- u = await E.speedLoseAt(s, u, t, e, 0, d, r), v = v || u, u.important && p.push(u), t.isSameOrAfter(i) && (M.push(u), i.add(24, "hour"));
752
- const h = O.calculateDistance(u, c, !c.gcToPrevious);
753
- let w = Math.ceil(h / v.speed * 1e4) / 1e4;
754
- if (y + w < o) {
755
- if (y += w, t.add(w, "hour"), delete a[Y], D == null || D.info(
756
- `[%s] go to %j from %j with ${h}nm, and cost ${w} hours`,
757
- r.requestId,
758
- { lat: c.lat, lng: c.lng },
759
- { lat: v.lat, lng: v.lng, etd: v.etd }
760
- ), f += h, a.filter((I) => I).length <= 1) {
761
- l = c, l.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), l.distanceFromPrevious = h, l.distanceFromStart = n + f, p.push(l), delete a[Y + 1];
763
+ M = await E.speedLoseAt(s, M, t, e, 0, d, c, u), I = I || M, M.important && l.push(M), t.isSameOrAfter(i) && (y.push(M), i.add(24, "hour"));
764
+ const g = W.calculateDistance(M, r, !r.gcToPrevious);
765
+ let k = Math.ceil(g / I.speed * 1e4) / 1e4;
766
+ if (p + k < o) {
767
+ if (p += k, t.add(k, "hour"), delete a[Y], S == null || S.info(
768
+ `[%s] go to %j from %j with ${g}nm, and cost ${k} hours`,
769
+ u.requestId,
770
+ { lat: r.lat, lng: r.lng },
771
+ { lat: I.lat, lng: I.lng, etd: I.etd }
772
+ ), h += g, a.filter((f) => f).length <= 1) {
773
+ b = r, b.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), b.distanceFromPrevious = g, b.distanceFromStart = n + h, l.push(b), delete a[Y + 1];
762
774
  break;
763
775
  }
764
776
  } else {
765
- w = o - y, t.add(w, "hour");
766
- const I = Z.roundPrecision(v.speed * w, 4);
767
- l = O.calculateCoordinate(u, s.bearing, I, "nauticalmiles", !c.gcToPrevious), l.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[Y] = l, D == null || D.info(
768
- `[%s] go to %j from %j with ${I}nm, and cost ${w} hours`,
769
- r.requestId,
770
- { lat: l.lat, lng: l.lng },
771
- { lat: u.lat, lng: u.lng, etd: u.etd }
772
- ), f += I, l.distanceFromPrevious = f, l.distanceFromStart = n + f;
777
+ k = o - p, t.add(k, "hour");
778
+ const f = B.roundPrecision(I.speed * k, 4);
779
+ b = W.calculateCoordinate(M, s.bearing, f, "nauticalmiles", !r.gcToPrevious), b.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[Y] = b, S == null || S.info(
780
+ `[%s] go to %j from %j with ${f}nm, and cost ${k} hours`,
781
+ u.requestId,
782
+ { lat: b.lat, lng: b.lng },
783
+ { lat: M.lat, lng: M.lng, etd: M.etd }
784
+ ), h += f, b.distanceFromPrevious = h, b.distanceFromStart = n + h;
773
785
  break;
774
786
  }
775
787
  }
776
- return { etd: t, from: v, to: l, next: a.filter((Y) => Y), wps: p, days: M };
788
+ return { etd: t, from: I, to: b, next: a.filter((Y) => Y), wps: l, days: y };
777
789
  }
778
790
  /**
779
791
  * 洋流影响因子
@@ -794,16 +806,16 @@ class E {
794
806
  * @param wwc 气象要素
795
807
  */
796
808
  static weatherFactor(s, t) {
797
- var M, y, f, l, v;
798
- D == null || D.debug("calculate weather factor via: %j", { ...s, ...t });
809
+ var l, y, p, h, b;
810
+ S == null || S.debug("calculate weather factor via: %j", { ...s, ...t });
799
811
  const i = E.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), o = E.froudeNumber(s.speed, s.lbp), n = E.amendFactor(i, o, s.loadCondition);
800
- let a = Math.abs(s.bearing % 360 - (((M = t == null ? void 0 : t.wind) == null ? void 0 : M.degree) % 360 || 0));
812
+ let a = Math.abs(s.bearing % 360 - (((l = t == null ? void 0 : t.wind) == null ? void 0 : l.degree) % 360 || 0));
801
813
  a = a > 180 ? 360 - a : a;
802
- const e = E.directionFactor(a, (y = t == null ? void 0 : t.wind) == null ? void 0 : y.scale), d = E.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (f = t == null ? void 0 : t.wind) == null ? void 0 : f.scale);
803
- let r = e * n * d / 100 * s.speed;
804
- r = Math.round(r * 1.943844 * 1e4) / 1e4 * -1;
805
- const p = E.waveHeightFactor(((v = (l = t == null ? void 0 : t.wave) == null ? void 0 : l.sig) == null ? void 0 : v.height) ?? 1);
806
- return r = r * 0.24 + p * 0.76, D == null || D.debug("weather factor = %s", r), Math.round(r * 100) / 100;
814
+ const e = E.directionFactor(a, (y = t == null ? void 0 : t.wind) == null ? void 0 : y.scale), d = E.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (p = t == null ? void 0 : t.wind) == null ? void 0 : p.scale);
815
+ let c = e * n * d / 100 * s.speed;
816
+ c = Math.round(c * 1.943844 * 1e4) / 1e4 * -1;
817
+ const u = E.waveHeightFactor(((b = (h = t == null ? void 0 : t.wave) == null ? void 0 : h.sig) == null ? void 0 : b.height) ?? 1);
818
+ return c = c * 0.24 + u * 0.76, S == null || S.debug("weather factor = %s", c), Math.round(c * 100) / 100;
807
819
  }
808
820
  /**
809
821
  * 全程失速分析(走完航程)
@@ -814,16 +826,17 @@ class E {
814
826
  * @param lane 航线 { points: { route, waypoints }}
815
827
  * @param source 气象数据源,GFS or CMEMES, 默认CMEMS
816
828
  * @param stepHrs 样本步长, 0表示动态计算(6 or 3 hrs)
829
+ * @param useMeteo true 启用气象分析
817
830
  * @param useRouteParam
818
831
  */
819
- static async analyseInstant(s, t, i, o, n, a = "", e = 0, d = !1, r = {}) {
820
- var q, P, _, G, U;
821
- const p = b().valueOf();
822
- s.lng = Z.convertToStdLng(s.lng);
823
- const { route: M, waypoints: y } = n.points, f = O.calculateSubRoute(s, M);
824
- if (((q = f[0]) == null ? void 0 : q.length) <= 1)
832
+ static async analyseInstant(s, t, i, o, n, a = "", e = 0, d = !0, c = !1, u = {}) {
833
+ var P, V, G, U, J;
834
+ const l = v().valueOf();
835
+ s.lng = B.convertToStdLng(s.lng);
836
+ const { route: y, waypoints: p } = n.points, h = W.calculateSubRoute(s, y);
837
+ if (((P = h[0]) == null ? void 0 : P.length) <= 1)
825
838
  return;
826
- const { v0: l, label: v } = s.sog ? {
839
+ const { v0: b, label: I } = s.sog ? {
827
840
  v0: s.sog,
828
841
  label: "Other"
829
842
  /* Instruct */
@@ -831,40 +844,51 @@ class E {
831
844
  v0: o.speed,
832
845
  label: "CP"
833
846
  /* Cp */
834
- }, Y = E.assembleProperties(i, o.loadCondition, l, 0), u = y.length ? O.calculateSubWaypoints(s, y) : [], c = {
847
+ }, Y = E.assembleProperties(i, o.loadCondition, b, 0), M = p.length ? W.calculateSubWaypoints(s, p) : [], r = {
835
848
  from: { ...s },
836
- route: f,
837
- waypoints: u,
838
- v0: l,
839
- label: v
840
- }, h = {
849
+ route: h,
850
+ waypoints: M,
851
+ v0: b,
852
+ label: I
853
+ }, g = {
841
854
  hours: [],
842
855
  days: [],
843
856
  wps: []
844
857
  };
845
- e || (O.calculateRouteDistance(f) / o.speed <= 72 ? e = 3 : e = 6);
846
- let w = O.simplifyRouteToCoordinates(f, u, 0), I = 0, g = 0, F = 0, x = 0;
847
- t = b(t).utc();
848
- const A = t.clone();
849
- for (; w.length > 0; ) {
850
- const H = e - t.hour() % e, W = Math.ceil(t.clone().add(H, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, N = await E.speedLoseInHoursStep(Y, t, A, W, I, w, a, d, r);
851
- (P = N.from) != null && P.speed && (h.hours.push(N.from), h.wps.push(...N.wps), h.days.push(...N.days)), w = N == null ? void 0 : N.next, w.length || h.hours.push(N == null ? void 0 : N.to), I += ((_ = N == null ? void 0 : N.to) == null ? void 0 : _.distanceFromPrevious) ?? 0;
858
+ e || (W.calculateRouteDistance(h) / o.speed <= 72 ? e = 3 : e = 6);
859
+ let k = W.simplifyRouteToCoordinates(h, M, 0), f = 0, N = 0, A = 0, x = 0;
860
+ t = v(t).utc();
861
+ const O = t.clone();
862
+ for (; k.length > 0; ) {
863
+ const F = e - t.hour() % e, L = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, H = await E.speedLoseInHoursStep(
864
+ Y,
865
+ t,
866
+ O,
867
+ L,
868
+ f,
869
+ k,
870
+ a,
871
+ d,
872
+ c,
873
+ u
874
+ );
875
+ (V = H.from) != null && V.speed && (g.hours.push(H.from), g.wps.push(...H.wps), g.days.push(...H.days)), k = H == null ? void 0 : H.next, k.length || g.hours.push(H == null ? void 0 : H.to), f += ((G = H == null ? void 0 : H.to) == null ? void 0 : G.distanceFromPrevious) ?? 0;
852
876
  }
853
- const T = h.hours;
854
- for (let H = 0; H < T.length - 1; H++) {
855
- const W = b(T[H + 1].eta).diff(T[H].etd, "hour", !0) || 1;
856
- g += T[H].wxFactor * W, F += T[H].cFactor * W, x += W;
877
+ const j = g.hours;
878
+ for (let F = 0; F < j.length - 1; F++) {
879
+ const L = v(j[F + 1].eta).diff(j[F].etd, "hour", !0) || 1;
880
+ N += j[F].wxFactor || 0 * L, A += j[F].cFactor || 0 * L, x += L;
857
881
  }
858
- (G = h.wps) == null || G.forEach((H, W) => {
859
- if (W) {
860
- const N = h.wps[W - 1], Q = H.distanceFromStart - N.distanceFromStart, J = b(H.eta).diff(b(N.etd), "h", !0);
861
- J < 1 ? H.avgSpd = N.speed : H.avgSpd = Math.round(Q / J * 100) / 100;
882
+ (U = g.wps) == null || U.forEach((F, L) => {
883
+ if (L) {
884
+ const H = g.wps[L - 1], X = F.distanceFromStart - H.distanceFromStart, Q = v(F.eta).diff(v(H.etd), "h", !0);
885
+ Q < 1 ? F.avgSpd = H.speed : F.avgSpd = Math.round(X / Q * 100) / 100;
862
886
  }
863
- }), c.sample = h;
864
- const S = h.hours.at(-1);
865
- c.distance = Math.round(S.distanceFromStart * 1e4) / 1e4, c.eta = b(S.eta).toDate(), c.wxFactor = Math.round(g / x * 1e4) / 1e4, c.cFactor = Math.round(F / x * 1e4) / 1e4, c.avgSpeed = Math.round(S.distanceFromStart / x * 1e4) / 1e4, c.totalHrs = Math.round(x * 1e4) / 1e4, c.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * c.totalHrs * 1e3) / 1e3, c.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * c.totalHrs * 1e3) / 1e3;
866
- const V = b().valueOf() - p, j = ((U = h == null ? void 0 : h.hours) == null ? void 0 : U.length) || 1;
867
- return D == null || D.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", r == null ? void 0 : r.requestId, V, j, Math.round(V / j * 1e3) / 1e3), c;
887
+ }), r.sample = g;
888
+ const D = g.hours.at(-1);
889
+ r.distance = Math.round(D.distanceFromStart * 1e4) / 1e4, r.eta = v(D.eta).toDate(), r.wxFactor = Math.round(N / x * 1e4) / 1e4, r.cFactor = Math.round(A / x * 1e4) / 1e4, r.avgSpeed = Math.round(D.distanceFromStart / x * 1e4) / 1e4, r.totalHrs = Math.round(x * 1e4) / 1e4, r.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * r.totalHrs * 1e3) / 1e3, r.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * r.totalHrs * 1e3) / 1e3;
890
+ const T = v().valueOf() - l, q = ((J = g == null ? void 0 : g.hours) == null ? void 0 : J.length) || 1;
891
+ return S == null || S.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", u == null ? void 0 : u.requestId, T, q, Math.round(T / q * 1e3) / 1e3), r;
868
892
  }
869
893
  /**
870
894
  * 分段失速分析(最多走hours 小时)
@@ -876,61 +900,74 @@ class E {
876
900
  * @param route 航路[[[lng, lat]]]
877
901
  * @param source 气象数据源,GFS or CMEMES, 默认CMEMS
878
902
  * @param stepHrs
903
+ * @param useMeteo true 启用气象分析
904
+ * @param useRouteParam
879
905
  */
880
- static async analyseInstantWithThreshed(s, t, i, o, n, a, e = "", d = 3, r = !1, p = {}) {
881
- var F, x, A;
882
- s.lng = Z.convertToStdLng(s.lng);
883
- const M = E.assembleProperties(o, n.loadCondition, n.speed, 0), y = O.calculateSubRoute(s, a);
884
- if (((F = y[0]) == null ? void 0 : F.length) <= 1)
906
+ static async analyseInstantWithThreshed(s, t, i, o, n, a, e = "", d = 3, c = !0, u = !1, l = {}) {
907
+ var A, x, O;
908
+ s.lng = B.convertToStdLng(s.lng);
909
+ const y = E.assembleProperties(o, n.loadCondition, n.speed, 0), p = W.calculateSubRoute(s, a);
910
+ if (((A = p[0]) == null ? void 0 : A.length) <= 1)
885
911
  return;
886
- let f = O.simplifyRouteToCoordinates(y, [], 0);
887
- f.forEach((T) => T.important = !0);
888
- let l = 0, v = 0, Y = 0, u = 0, c;
889
- const h = {
912
+ let h = W.simplifyRouteToCoordinates(p, [], 0);
913
+ h.forEach((j) => j.important = !0);
914
+ let b = 0, I = 0, Y = 0, M = 0, r;
915
+ const g = {
890
916
  hours: [],
891
917
  wps: [],
892
918
  days: []
893
919
  };
894
- for (t = b(t).utc(); f.length > 0; ) {
895
- const T = d - t.hour() % d;
896
- let S = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
897
- if (S = t.clone().add(S, "h").isAfter(i) ? i.diff(t, "h", !0) * 1e4 / 1e4 : S, S)
898
- c = await E.speedLoseInHoursStep(M, t, i.clone(), S, l, f, e, r, p), (x = c.from) != null && x.speed && (h.hours.push(c.from), c != null && c.wps && h.wps.push(...c.wps), h.days.push(...c.days)), f = c == null ? void 0 : c.next, f.length || (h.hours.push(c == null ? void 0 : c.to), c != null && c.wps && h.wps.push(...c.wps), h.days.push(c == null ? void 0 : c.to)), l += ((A = c == null ? void 0 : c.to) == null ? void 0 : A.distanceFromPrevious) ?? 0;
920
+ for (t = v(t).utc(); h.length > 0; ) {
921
+ const j = d - t.hour() % d;
922
+ let D = Math.ceil(t.clone().add(j, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
923
+ if (D = t.clone().add(D, "h").isAfter(i) ? i.diff(t, "h", !0) * 1e4 / 1e4 : D, D)
924
+ r = await E.speedLoseInHoursStep(
925
+ y,
926
+ t,
927
+ i.clone(),
928
+ D,
929
+ b,
930
+ h,
931
+ e,
932
+ c,
933
+ u,
934
+ l
935
+ ), (x = r.from) != null && x.speed && (g.hours.push(r.from), r != null && r.wps && g.wps.push(...r.wps), g.days.push(...r.days)), h = r == null ? void 0 : r.next, h.length || (g.hours.push(r == null ? void 0 : r.to), r != null && r.wps && g.wps.push(...r.wps), g.days.push(r == null ? void 0 : r.to)), b += ((O = r == null ? void 0 : r.to) == null ? void 0 : O.distanceFromPrevious) ?? 0;
899
936
  else {
900
- c && (h.hours.push(c.to), c != null && c.wps && h.wps.push(...c.wps), h.days.push(c.to));
937
+ r && (g.hours.push(r.to), r != null && r.wps && g.wps.push(...r.wps), g.days.push(r.to));
901
938
  break;
902
939
  }
903
940
  }
904
- const w = h.hours;
905
- for (let T = 0; T < w.length - 1; T++) {
906
- const S = b(w[T + 1].eta).diff(w[T].etd, "hour", !0);
907
- v += w[T].wxFactor * S, Y += w[T].cFactor * S, u += S;
941
+ const k = g.hours;
942
+ for (let j = 0; j < k.length - 1; j++) {
943
+ const D = v(k[j + 1].eta).diff(k[j].etd, "hour", !0);
944
+ I += k[j].wxFactor * D, Y += k[j].cFactor * D, M += D;
908
945
  }
909
- const I = h.hours.at(-1);
946
+ const f = g.hours.at(-1);
910
947
  return {
911
- sample: h,
912
- distance: Math.round(((I == null ? void 0 : I.distanceFromStart) || 0) * 1e4) / 1e4,
913
- eta: b(I == null ? void 0 : I.eta).utc().format(),
914
- wxFactor: Math.round(v / u * 1e4) / 1e4,
915
- cFactor: Math.round(Y / u * 1e4) / 1e4,
916
- avgSpeed: Math.round(((I == null ? void 0 : I.distanceFromStart) || 0) / u * 1e4) / 1e4,
917
- totalHrs: Math.round(u * 1e4) / 1e4,
918
- to: I,
919
- route: O.generateRouteAccordingToWaypoints(f)
948
+ sample: g,
949
+ distance: Math.round(((f == null ? void 0 : f.distanceFromStart) || 0) * 1e4) / 1e4,
950
+ eta: v(f == null ? void 0 : f.eta).utc().format(),
951
+ wxFactor: Math.round(I / M * 1e4) / 1e4,
952
+ cFactor: Math.round(Y / M * 1e4) / 1e4,
953
+ avgSpeed: Math.round(((f == null ? void 0 : f.distanceFromStart) || 0) / M * 1e4) / 1e4,
954
+ totalHrs: Math.round(M * 1e4) / 1e4,
955
+ to: f,
956
+ route: W.generateRouteAccordingToWaypoints(h)
920
957
  };
921
958
  }
922
959
  }
923
960
  export {
924
961
  K as AISImpl,
925
- st as AlertHelper,
926
- et as AlertLevel,
927
- ft as HifleetImpl,
928
- ot as LoadCondition,
929
- pt as MyShipImpl,
930
- lt as MyVesselImpl,
931
- mt as ShipxyImpl,
962
+ at as AlertHelper,
963
+ st as AlertLevel,
964
+ mt as HifleetImpl,
965
+ nt as LoadCondition,
966
+ Mt as MyShipImpl,
967
+ ft as MyVesselImpl,
968
+ pt as ShipxyImpl,
932
969
  E as SpeedHelper,
933
- nt as SpeedLabel,
934
- at as VesselTag,
935
- Mt as alertHelper
970
+ it as SpeedLabel,
971
+ ot as VesselTag,
972
+ yt as alertHelper
936
973
  };
@@ -1 +1 @@
1
- (function(k,T){typeof exports=="object"&&typeof module<"u"?T(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo"],T):(k=typeof globalThis<"u"?globalThis:k||self,T(k["idm-plugin-rabbitmq"]={},k.got,k["@log4js-node/log4js-api"],k.moment,k["@idm-plugin/geo"],k["@idm-plugin/meteo"]))})(this,function(k,T,W,g,E,st){"use strict";var dt=Object.defineProperty;var ut=(k,T,W)=>T in k?dt(k,T,{enumerable:!0,configurable:!0,writable:!0,value:W}):k[T]=W;var K=(k,T,W)=>(ut(k,typeof T!="symbol"?T+"":T,W),W);let m;try{m=W.getLogger("vessel")}catch{}finally{}class z{parseStatus(a){let t,i;switch(a){case 0:t="在航(主机推动)",i="The engine is in use";break;case 1:t="锚泊",i="Anchored";break;case 2:t="失控",i="Not operated";break;case 3:t="操纵受限",i="Limited airworthiness";break;case 4:t="吃水受限",i="Limited by ship's draft";break;case 5:t="靠泊",i="Mooring";break;case 6:t="搁浅",i="Stranded";break;case 7:t="捕捞作业",i="Engaged in fishing";break;case 8:t="靠帆船提供动力",i="Sailing";break;default:t="未定义",i="Undefined"}return{labelCn:t,labelEn:i}}}class at extends z{constructor(t,i){super();K(this,"clientId");K(this,"clientSecret");K(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await T.post(i,n).json();m==null||m.info("[%s] fetch access token from: %s - %j",t.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:g().utc().format()})}async realTimePosition(t,i={}){var p,y,M;(!this.token||g().diff(g(this.token.issuedAt),"seconds")>((p=this.token)==null?void 0:p.expiresIn)-300)&&await this.authToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(y=this.token)==null?void 0:y.tokenType} ${(M=this.token)==null?void 0:M.accessToken}`},searchParams:{mmsi:t}};m==null||m.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const s=await T.get(n,o).json();if(s.code)return m==null||m.warn("[%s] fetch realtime position failed: %j",i.requestId,n,{message:s.message,status:s.status,code:s.code}),s;const e=s.data;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));const d=g(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:e.eta,destination:e.dest,positionTime:d.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,i,n,o,s=!0,e={}){(!this.token||g().diff(g(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const d=await this.realTimePosition(t,e),r=g(i),p=g(n),y=[];for(;p.diff(r,"day",!0)>30;)await this.trajectoryIn30Day(t,r,r.clone().add(30,"day"),d,o,y,e),r.add(30,"day");return await this.trajectoryIn30Day(t,r,p,d,o,y,e),y}async trajectoryIn30Day(t,i,n,o,s,e,d={}){var l,v,Y,u,c;const r="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",p={headers:{Authorization:`${(l=this.token)==null?void 0:l.tokenType} ${(v=this.token)==null?void 0:v.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};m==null||m.info("[%s] fetch trajectory from: %s - %j",d.requestId,r,p);const y=await T.post(r,p).json();if(y.code)return m==null||m.warn("[%s] fetch trajectory failed: %j",d.requestId,r,{message:y.message,status:y.status,code:y.code}),y;let M=-1;const f=g(`${(u=(Y=y.data)==null?void 0:Y[0])==null?void 0:u.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(c=y.data)==null||c.forEach(h=>{for(const D in h)!isNaN(h[D])&&Number(h[D])!==1/0&&(h[D]=Number(h[D]));const I=g(`${h.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),j=h.eta?g(`${h.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,b=h.status,{labelCn:P,labelEn:x}=this.parseStatus(b),O={mmsi:h.mmsi,imo:o==null?void 0:o.imo,lat:h.lat,lng:h.lon,sog:h.sog,cog:h.cog,hdg:h.hdg,draught:h.draught,status:b,eta:j==null?void 0:j.unix(),destination:h.dest,positionTime:I.unix(),labelCn:P,labelEn:x,method:"trajectory",vendor:"myVessel",utc:I.utc().format()},S=Math.floor(I.diff(f,"minute",!0)/(s||1));S!==M&&(M=S,e.push(O))}),e}}class nt extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},s=await T.post(n,o).json();m==null||m.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const e=s==null?void 0:s.list;if(!e)return m==null||m.warn("[%s] fetch realtime position failed: %j",i.requestId,n,s),s;for(const f in e)!isNaN(e[f])&&Number(e[f])!==1/0&&(e[f]=Number(e[f]));e.status=e.sp>3?0:1;const d=e.status,{labelCn:r,labelEn:p}=this.parseStatus(d),y=g(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?g(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:y.unix(),utc:y.utc().format(),status:d,labelCn:r,labelEn:p,method:"position",vendor:"hifleet"}}async search(t,i={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let s=await T.post(n,o).json();m==null||m.info("[%s] fetch vessel props from: %s - %j",i.requestId,n,o),s instanceof Array&&(s=s[0]);for(const d in s)!isNaN(s[d])&&Number(s[d])!==1/0&&(s[d]=Number(s[d]));const e={mmsi:s.m,name:s.n,imo:s.i,callSign:s.c,length:s.l,breadth:s.b,draught:s.dr};return n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",s=await T.post(n,o).json(),m==null||m.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,n,o),s instanceof Array&&(s=s[0]),s&&(e.deadweight=Number(s.dwt)),e}async trajectory(t,i,n,o,s=!0,e={}){var h,I,j;const d=await this.realTimePosition(t,e);let r=g(i);const p=g(n),y=g();if(s){let b=p.diff(r,"d",!0);b<0?r=p.clone().subtract(40,"d"):b<30?r.subtract(10,"d"):b<60?r.subtract(5,"d"):r=p.clone().subtract(80,"d"),b=y.diff(p,"d",!0),p.add(b>10?240:b*24,"h")}const M={searchParams:{endtime:p.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:r.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},f="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",l=await T.get(f,M).json();m==null||m.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,M);let v;l&&(v=((I=(h=l.ships)==null?void 0:h.offors)==null?void 0:I.ship)||[],v.length||m==null||m.warn("[%s] fetch trajectory failed: %j",e.requestId,l));const Y=[];let u=-1;const c=g(`${(j=v==null?void 0:v[0])==null?void 0:j.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const b of v){for(const _ in b)!isNaN(b[_])&&Number(b[_])!==1/0&&(b[_]=Number(b[_]));const P=g(`${b.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");b.status=b.sp>4?0:1;const{labelEn:x,labelCn:O}=this.parseStatus(b.status),S={mmsi:b.m,name:b.n,imo:d==null?void 0:d.imo,lat:b.la,lng:b.lo,draught:b.draught,sog:b.sp,cog:b.co,hdg:b.hdg,positionTime:P.unix(),utc:P.utc().format(),status:b.status,labelCn:O,labelEn:x,method:"trajectory",vendor:"hifleet"},D=Math.floor(P.diff(c,"minute",!0)/(o||1));D!==u&&(u=D,Y.push(S))}return Y}}class ot extends z{constructor(t){super();K(this,"token");this.token=t}async realTimePosition(t,i={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",s=await T.get(o,n).json();if(m==null||m.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n),(s==null?void 0:s.status)!==0)return s;const e=s.data[0];for(const M in e)!isNaN(e[M])&&Number(e[M])!==1/0&&(e[M]=Number(e[M]));const{labelCn:d,labelEn:r}=await this.parseStatus(e.navistat),p=g.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:p.utc().format(),status:e.navistat,labelEn:r,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,i,n,o,s=!0,e={}){var c;const d=await this.realTimePosition(t,e),r=g(i),p=g(n),y="https://api.shipxy.com/apicall/GetShipTrack",M={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:r.unix(),etm:p.unix()}},f=await T.get(y,M).json();if(m==null||m.info("[%s] fetch trajectory from: %s - %j",e.requestId,y,M),(f==null?void 0:f.status)!==0)return f;const l=f==null?void 0:f.points,v=[],Y=g.unix((c=l[0])==null?void 0:c.utc);let u=-1;for(const h of l){const I=g.unix(h.utc),j={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(h.sog*3600/1e3/1852*100)/100,cog:Math.round(h.cog/100*100)/100,lat:Math.round(h.lat/1e6*1e5)/1e5,lng:Math.round(h.lon/1e6*1e5)/1e5,positionTime:I.unix(),utc:I.utc().format(),method:"trajectory",vendor:"shipxy"},b=Math.floor(I.diff(Y,"minute",!0)/(o||1));b!==u&&(u=b,v.push(j))}return v}}class it extends z{constructor(t){super();K(this,"token");this.token=t}async getShipId(t,i={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",s=await T.post(o,n).json();return m==null||m.info("[%s] fetch ship id from: %s - %j",i.requestId,o,n),s.code!=="0"?s:s.data[0].shipId}async getShipInfo(t,i={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",s=await T.post(o,n).json();if(m==null||m.info("[%s] fetch ship info from: %s - %j",i.requestId,o,n),s.code!=="0")return s;const e=s.data;let d=e.imo;return t==="407170"&&(d="9198379",m==null||m.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,t,e.imo,d)),{mmsi:e.mmsi,name:e.shipnameEn,imo:d,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,i={}){const n=await this.getShipId(t,i),o=await this.getShipInfo(n,i),s={headers:{appKey:this.token},json:{shipId:n}},e="https://api3.myships.com/sp/ships/position/latest",d=await T.post(e,s).json();m==null||m.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,s);const r=d.data[0];for(const l in r)!isNaN(r[l])&&Number(r[l])!==1/0&&(r[l]=Number(r[l]));const{labelCn:p,labelEn:y}=await this.parseStatus(r.aisNavStatus),M=g.unix(r.posTime);return{...o,mmsi:t,lat:Math.round(r.lat/1e4/60*1e5)/1e5,lng:Math.round(r.lon/1e4/60*1e5)/1e5,sog:Math.round(r.sog/10*100)/100,cog:Math.round(r.cog/10*100)/100,hdg:Math.round(r.heading*100)/100,rot:Math.round(r.rot*100)/100,positionTime:r.posTime,utc:M.utc().format(),status:r.aisNavStatus,labelEn:y,labelCn:p,method:"position",vendor:"myship"}}async trajectory(t,i,n,o,s=!0,e={}){const d=g(i),r=g(n),p=await this.getShipId(t),y=await this.getShipInfo(p),M=[];for(;r.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(p,d.unix(),d.add(30,"day").unix(),y,t,o,M);return await this.trajectoryIn30Day(p,d.unix(),r.unix(),y,t,o,M),M}async trajectoryIn30Day(t,i,n,o,s,e,d,r={}){var Y;const p={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:n}},y="https://api3.myships.com/sp/ships/position/history",M=await T.post(y,p).json();if(m==null||m.info("[%s] fetch trajectory from: %s - %j",r.requestId,y,p),M.code!=="0")return m==null||m.warn("[%s] invoke myship trajectory failed: %j",r.requestId,M),M;const f=M.data;for(const u in f)!isNaN(f[u])&&Number(f[u])!==1/0&&(f[u]=Number(f[u]));const l=g.unix((Y=f[0])==null?void 0:Y.posTime);let v=-1;for(const u of f){const c=g.unix(u.posTime),h={imo:o==null?void 0:o.imo,mmsi:s,lat:Math.round(u.lat/1e4/60*1e5)/1e5,lng:Math.round(u.lon/1e4/60*1e5)/1e5,sog:Math.round(u.sog/10*100)/100,cog:Math.round(u.cog/10*100)/100,hdg:Math.round(u.heading*100)/100,rot:Math.round(u.rot*100)/100,positionTime:c.unix(),utc:c.utc().format(),method:"trajectory",vendor:"myship"},I=Math.floor(c.diff(l,"minute",!0)/(e||1));I!==v&&(v=I,d.push(h))}return d}}let C;try{C=W.getLogger("vessel")}catch{}finally{}var G=(w=>(w.NOTICE="NOTICE",w.WARN="WARN",w.HEAVY="HEAVY",w.SEVERE="SEVERE",w.ERROR="ERROR",w.FATAL="FATAL",w))(G||{});class U{parsePrinciple(a,t={}){var e,d,r;C==null||C.info("[%s] parse rule: %s",t.requestId,a);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),n=a.match(i)?(e=a.match(i))==null?void 0:e[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const s={};for(let p=0;p<(o==null?void 0:o.length);p++){const y=(r=(d=o[p].match(i))==null?void 0:d[0])==null?void 0:r.split("],");if(p===0&&!y)s.scope=o[0];else if(y)for(let M=0,f=y.length;M<f;M++){const l=this.parseRule(y[M]);l&&(s[l.level]?l.key?s[l.level][l==null?void 0:l.key]=l:s[l.level]=l:l.key?s[l.level]={[l==null?void 0:l.key]:l}:s[l.level]=l)}}return s}parseRule(a,t={}){var s;C==null||C.info("[%s] parse rule: %s",t.requestId,a),a=a.startsWith("[")?a:`[${a}`,a=a.endsWith("]")?a:`${a}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(s=a==null?void 0:a.match(i))==null?void 0:s[0],o=n==null?void 0:n.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(a,t,i={}){var l,v,Y,u,c,h,I,j,b,P,x,O,S,D,_;let n=0,o=0,s=0,e=0;const d=Math.round(((v=(l=t==null?void 0:t.SEVERE)==null?void 0:l.sigWave)==null?void 0:v.number)*1.6*100)/100,r=(u=(Y=t==null?void 0:t.SEVERE)==null?void 0:Y.sigWave)==null?void 0:u.number,p=(h=(c=t==null?void 0:t.HEAVY)==null?void 0:c.sigWave)==null?void 0:h.number,y=Math.round((((j=(I=t==null?void 0:t.SEVERE)==null?void 0:I.wind)==null?void 0:j.number)+2)*100)/100,M=(P=(b=t==null?void 0:t.SEVERE)==null?void 0:b.wind)==null?void 0:P.number,f=(O=(x=t==null?void 0:t.HEAVY)==null?void 0:x.wind)==null?void 0:O.number;for(let B=0;B<(a==null?void 0:a.length);B++){const H=a[B],A=(D=(S=H==null?void 0:H.meteo)==null?void 0:S.wave)==null?void 0:D.sig,R=(_=H==null?void 0:H.meteo)==null?void 0:_.wind,Z=B?g(H.eta).diff(g(a[B-1].eta),"hour",!0):0;e=Z>e?Z:e,C==null||C.info("[%s] check sig.wave: %j",i.requestId,{...A,dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:p}),(A==null?void 0:A.height)>=d?H.isDangerous=!0:(A==null?void 0:A.height)>=r?H.isSevere=!0:(A==null?void 0:A.height)>=p&&(H.isHeavy=!0),C==null||C.info("[%s] check wind: %j",i.requestId,{...R,dgThd4Wd:y,svThd4Wd:M,hvThd4Wd:f}),(R==null?void 0:R.scale)>=y?(H.isDangerous=!0,delete H.isSevere,delete H.isHeavy):(R==null?void 0:R.scale)>M?(H.isDangerous||(H.isSevere=!0),delete H.isHeavy):(R==null?void 0:R.scale)===f&&!H.isDangerous&&!H.isSevere&&(H.isHeavy=!0),n+=H.isDangerous?Z:0,o+=H.isSevere?Z:0,s+=H.isHeavy?Z:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,s=Math.round(s*100)/100,e=Math.round(e),{sample:a,dangerous:n,severe:o,heavy:s,step:e<3?3:e,wind:{dgThd4Wd:y,svThd4Wd:M,hvThd4Wd:f},sig:{dgThd4Wv:d,svThd4Wv:r,hvThd4Wv:p}}}}const rt=new U;let N;try{N=W.getLogger("vessel")}catch{}finally{}var J=(w=>(w.common="common",w.container="container",w))(J||{}),Q=(w=>(w.Ballast="Ballast",w.Laden="Laden",w))(Q||{}),X=(w=>(w.Cp="CP",w.Perf="Basis",w.Instruct="Other",w))(X||{});class q{static blockCoefficient(a,t,i,n){let o=Math.round(a/(t*i*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const s=[.55,.6,.65,.7,.75,.8,.85],e=s.map(d=>Math.abs(d-o));return s[e.indexOf(Math.min(...e))]}static froudeNumber(a,t,i=9.8){let n=Math.round(Math.sqrt(a*a/(i*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(a,t,i){const n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let s={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[a];return i==="Laden"&&(s=n[a]),s[0]+s[1]*t+s[2]*Math.pow(t,2)}static directionFactor(a,t=0){let i;return a>30&&a<=60?i=(1.7-.03*Math.pow(t-4,2))/2:a>60&&a<=150?i=(.9-.06*Math.pow(t-6,2))/2:i=(.4-.03*Math.pow(t-8,2))/2,Math.round(i*1e5)/1e5}static vesselTagFactor(a,t,i,n=0){n=n>5?n-.9*(n-5):n;let o;return i==="container"?o=.7*n+Math.pow(n,6.5)/(22*Math.pow(a,2/3)):t==="Ballast"?o=.7*n+Math.pow(n,6.5)/(2.7*Math.pow(a,2/3)):o=.5*n+Math.pow(n,6.5)/(2.7*Math.pow(a,2/3)),o}static waveHeightFactor(a){return a=a<1.25?1.25:a,a=a>6?a-.9*(a-6):a,Math.round((-.144*Math.pow(a,2)+.178*a)*1e4)/1e4}static assembleProperties(a,t,i,n){var p,y;const o=a.lbp??a.length??a.lengthOverall??198.9642,s=a.draught??8,e=a.breadthMoulded??a.breadth??a.breadthExtreme??32.4572,d=a.deadweight??67035.7773;return{tag:((y=(p=a==null?void 0:a.type)==null?void 0:p.toLowerCase())==null?void 0:y.indexOf("container"))>-1?"container":"common",lbp:o,loadCondition:t,draught:s,breadthMoulded:e,displacement:Math.round((d/1.025+s*e*o*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(a,t,i,n="",o=2,s=!1,e={}){t.velocity&&!t.noFactor&&s&&(a.speed=E.LngLatHelper.roundPrecision(t.velocity*1852/3600,6));const d=await st.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",n,e),r=q.weatherFactor(a,d),p=q.currentFactor(a.bearing,d==null?void 0:d.current,o),y={meteo:{...d},wxFactor:r,cFactor:p,speed:t.velocity&&s?t.velocity:Math.round((a.speed*1.943844+r+p)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...y,...t}}static async speedLoseInHoursStep(a,t,i,n,o,s,e="",d=!1,r={}){t.utc();const p=[],y=[];let M=0,f=0,l,v;for(let Y=0;Y<s.length-1;Y++){let u=s[Y];u.distanceFromStart=o+f;const c=s[Y+1];if(a.bearing=E.LaneHelper.calculateBearing(u,c,!c.gcToPrevious),u.bearing=a.bearing,u.suspend&&d){u.eta=u.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),u.elapsed=u.elapsed??0;const j=u.suspend-u.elapsed;if(n-M>j)n=n-M-j,t.add(j,"hour"),u.elapsed=u.suspend;else{const b=n-M;u.elapsed+=b,t.add(b,"hour"),n=0}if(N==null||N.info(`[%s] suspend ${u.elapsed} hours at %j, and remain ${n} hours need to go...`,r.requestId,u),n===0)return u.distanceFromPrevious=f,{etd:t,from:v||u,to:u,next:s.filter(b=>b),wps:p,days:y}}u=await q.speedLoseAt(a,u,t,e,0,d,r),v=v||u,u.important&&p.push(u),t.isSameOrAfter(i)&&(y.push(u),i.add(24,"hour"));const h=E.LaneHelper.calculateDistance(u,c,!c.gcToPrevious);let I=Math.ceil(h/v.speed*1e4)/1e4;if(M+I<n){if(M+=I,t.add(I,"hour"),delete s[Y],N==null||N.info(`[%s] go to %j from %j with ${h}nm, and cost ${I} hours`,r.requestId,{lat:c.lat,lng:c.lng},{lat:v.lat,lng:v.lng,etd:v.etd}),f+=h,s.filter(j=>j).length<=1){l=c,l.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),l.distanceFromPrevious=h,l.distanceFromStart=o+f,p.push(l),delete s[Y+1];break}}else{I=n-M,t.add(I,"hour");const j=E.LngLatHelper.roundPrecision(v.speed*I,4);l=E.LaneHelper.calculateCoordinate(u,a.bearing,j,"nauticalmiles",!c.gcToPrevious),l.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),s[Y]=l,N==null||N.info(`[%s] go to %j from %j with ${j}nm, and cost ${I} hours`,r.requestId,{lat:l.lat,lng:l.lng},{lat:u.lat,lng:u.lng,etd:u.etd}),f+=j,l.distanceFromPrevious=f,l.distanceFromStart=o+f;break}}return{etd:t,from:v,to:l,next:s.filter(Y=>Y),wps:p,days:y}}static currentFactor(a,t,i=0){const n=(a-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return i&2?o=Math.ceil(o*100)/100:i&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(a,t){var y,M,f,l,v;N==null||N.debug("calculate weather factor via: %j",{...a,...t});const i=q.blockCoefficient(a.displacement,a.lbp,a.breadthMoulded,a.draught),n=q.froudeNumber(a.speed,a.lbp),o=q.amendFactor(i,n,a.loadCondition);let s=Math.abs(a.bearing%360-(((y=t==null?void 0:t.wind)==null?void 0:y.degree)%360||0));s=s>180?360-s:s;const e=q.directionFactor(s,(M=t==null?void 0:t.wind)==null?void 0:M.scale),d=q.vesselTagFactor(a.displacement,a.loadCondition,a.tag,(f=t==null?void 0:t.wind)==null?void 0:f.scale);let r=e*o*d/100*a.speed;r=Math.round(r*1.943844*1e4)/1e4*-1;const p=q.waveHeightFactor(((v=(l=t==null?void 0:t.wave)==null?void 0:l.sig)==null?void 0:v.height)??1);return r=r*.24+p*.76,N==null||N.debug("weather factor = %s",r),Math.round(r*100)/100}static async analyseInstant(a,t,i,n,o,s="",e=0,d=!1,r={}){var A,R,Z,$,tt;const p=g().valueOf();a.lng=E.LngLatHelper.convertToStdLng(a.lng);const{route:y,waypoints:M}=o.points,f=E.LaneHelper.calculateSubRoute(a,y);if(((A=f[0])==null?void 0:A.length)<=1)return;const{v0:l,label:v}=a.sog?{v0:a.sog,label:"Other"}:{v0:n.speed,label:"CP"},Y=q.assembleProperties(i,n.loadCondition,l,0),u=M.length?E.LaneHelper.calculateSubWaypoints(a,M):[],c={from:{...a},route:f,waypoints:u,v0:l,label:v},h={hours:[],days:[],wps:[]};e||(E.LaneHelper.calculateRouteDistance(f)/n.speed<=72?e=3:e=6);let I=E.LaneHelper.simplifyRouteToCoordinates(f,u,0),j=0,b=0,P=0,x=0;t=g(t).utc();const O=t.clone();for(;I.length>0;){const L=e-t.hour()%e,V=Math.ceil(t.clone().add(L,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,F=await q.speedLoseInHoursStep(Y,t,O,V,j,I,s,d,r);(R=F.from)!=null&&R.speed&&(h.hours.push(F.from),h.wps.push(...F.wps),h.days.push(...F.days)),I=F==null?void 0:F.next,I.length||h.hours.push(F==null?void 0:F.to),j+=((Z=F==null?void 0:F.to)==null?void 0:Z.distanceFromPrevious)??0}const S=h.hours;for(let L=0;L<S.length-1;L++){const V=g(S[L+1].eta).diff(S[L].etd,"hour",!0)||1;b+=S[L].wxFactor*V,P+=S[L].cFactor*V,x+=V}($=h.wps)==null||$.forEach((L,V)=>{if(V){const F=h.wps[V-1],ct=L.distanceFromStart-F.distanceFromStart,et=g(L.eta).diff(g(F.etd),"h",!0);et<1?L.avgSpd=F.speed:L.avgSpd=Math.round(ct/et*100)/100}}),c.sample=h;const D=h.hours.at(-1);c.distance=Math.round(D.distanceFromStart*1e4)/1e4,c.eta=g(D.eta).toDate(),c.wxFactor=Math.round(b/x*1e4)/1e4,c.cFactor=Math.round(P/x*1e4)/1e4,c.avgSpeed=Math.round(D.distanceFromStart/x*1e4)/1e4,c.totalHrs=Math.round(x*1e4)/1e4,c.totalFoCons=Math.round((n==null?void 0:n.fo)/24*c.totalHrs*1e3)/1e3,c.totalDgoCons=Math.round((n==null?void 0:n.dgo)/24*c.totalHrs*1e3)/1e3;const B=g().valueOf()-p,H=((tt=h==null?void 0:h.hours)==null?void 0:tt.length)||1;return N==null||N.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",r==null?void 0:r.requestId,B,H,Math.round(B/H*1e3)/1e3),c}static async analyseInstantWithThreshed(a,t,i,n,o,s,e="",d=3,r=!1,p={}){var P,x,O;a.lng=E.LngLatHelper.convertToStdLng(a.lng);const y=q.assembleProperties(n,o.loadCondition,o.speed,0),M=E.LaneHelper.calculateSubRoute(a,s);if(((P=M[0])==null?void 0:P.length)<=1)return;let f=E.LaneHelper.simplifyRouteToCoordinates(M,[],0);f.forEach(S=>S.important=!0);let l=0,v=0,Y=0,u=0,c;const h={hours:[],wps:[],days:[]};for(t=g(t).utc();f.length>0;){const S=d-t.hour()%d;let D=Math.ceil(t.clone().add(S,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(D=t.clone().add(D,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:D,D)c=await q.speedLoseInHoursStep(y,t,i.clone(),D,l,f,e,r,p),(x=c.from)!=null&&x.speed&&(h.hours.push(c.from),c!=null&&c.wps&&h.wps.push(...c.wps),h.days.push(...c.days)),f=c==null?void 0:c.next,f.length||(h.hours.push(c==null?void 0:c.to),c!=null&&c.wps&&h.wps.push(...c.wps),h.days.push(c==null?void 0:c.to)),l+=((O=c==null?void 0:c.to)==null?void 0:O.distanceFromPrevious)??0;else{c&&(h.hours.push(c.to),c!=null&&c.wps&&h.wps.push(...c.wps),h.days.push(c.to));break}}const I=h.hours;for(let S=0;S<I.length-1;S++){const D=g(I[S+1].eta).diff(I[S].etd,"hour",!0);v+=I[S].wxFactor*D,Y+=I[S].cFactor*D,u+=D}const j=h.hours.at(-1);return{sample:h,distance:Math.round(((j==null?void 0:j.distanceFromStart)||0)*1e4)/1e4,eta:g(j==null?void 0:j.eta).utc().format(),wxFactor:Math.round(v/u*1e4)/1e4,cFactor:Math.round(Y/u*1e4)/1e4,avgSpeed:Math.round(((j==null?void 0:j.distanceFromStart)||0)/u*1e4)/1e4,totalHrs:Math.round(u*1e4)/1e4,to:j,route:E.LaneHelper.generateRouteAccordingToWaypoints(f)}}}k.AISImpl=z,k.AlertHelper=U,k.AlertLevel=G,k.HifleetImpl=nt,k.LoadCondition=Q,k.MyShipImpl=it,k.MyVesselImpl=at,k.ShipxyImpl=ot,k.SpeedHelper=q,k.SpeedLabel=X,k.VesselTag=J,k.alertHelper=rt,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})});
1
+ (function(j,T){typeof exports=="object"&&typeof module<"u"?T(exports,require("got"),require("@log4js-node/log4js-api"),require("moment"),require("@idm-plugin/geo"),require("@idm-plugin/meteo")):typeof define=="function"&&define.amd?define(["exports","got","@log4js-node/log4js-api","moment","@idm-plugin/geo","@idm-plugin/meteo"],T):(j=typeof globalThis<"u"?globalThis:j||self,T(j["idm-plugin-rabbitmq"]={},j.got,j["@log4js-node/log4js-api"],j.moment,j["@idm-plugin/geo"],j["@idm-plugin/meteo"]))})(this,function(j,T,V,g,L,at){"use strict";var ut=Object.defineProperty;var ht=(j,T,V)=>T in j?ut(j,T,{enumerable:!0,configurable:!0,writable:!0,value:V}):j[T]=V;var B=(j,T,V)=>(ht(j,typeof T!="symbol"?T+"":T,V),V);let l;try{l=V.getLogger("vessel")}catch{}finally{}class z{parseStatus(a){let t,i;switch(a){case 0:t="在航(主机推动)",i="The engine is in use";break;case 1:t="锚泊",i="Anchored";break;case 2:t="失控",i="Not operated";break;case 3:t="操纵受限",i="Limited airworthiness";break;case 4:t="吃水受限",i="Limited by ship's draft";break;case 5:t="靠泊",i="Mooring";break;case 6:t="搁浅",i="Stranded";break;case 7:t="捕捞作业",i="Engaged in fishing";break;case 8:t="靠帆船提供动力",i="Sailing";break;default:t="未定义",i="Undefined"}return{labelCn:t,labelEn:i}}}class nt extends z{constructor(t,i){super();B(this,"clientId");B(this,"clientSecret");B(this,"token");this.clientId=t,this.clientSecret=i}async authToken(t={}){const i="https://svc.data.myvessel.cn/ada/oauth/token",n={searchParams:{client_id:this.clientId,client_secret:this.clientSecret,grant_type:"client_credentials"}},o=await T.post(i,n).json();l==null||l.info("[%s] fetch access token from: %s - %j",t.requestId,i,o),o.error||(this.token={accessToken:o.access_token,tokenType:o.token_type,expiresIn:o.expires_in,scope:o.scope,jti:o.jti,issuedAt:g().utc().format()})}async realTimePosition(t,i={}){var u,f,M;(!this.token||g().diff(g(this.token.issuedAt),"seconds")>((u=this.token)==null?void 0:u.expiresIn)-300)&&await this.authToken(i);const n="https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit",o={headers:{Authorization:`${(f=this.token)==null?void 0:f.tokenType} ${(M=this.token)==null?void 0:M.accessToken}`},searchParams:{mmsi:t}};l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const s=await T.get(n,o).json();if(s.code)return l==null||l.warn("[%s] fetch realtime position failed: %j",i.requestId,n,{message:s.message,status:s.status,code:s.code}),s;const e=s.data;for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));const d=g(`${e.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.mmsi,name:e.vesselName,imo:e.imo,callSign:e.callsign,lat:e.lat,lng:e.lon,length:e.length,width:e.width,draught:e.currDraught,sog:e.sog,cog:e.cog,hdg:e.hdg,rot:e.rot,eta:e.eta,destination:e.dest,positionTime:d.unix(),status:e.status,labelCn:e.statusNameCn,labelEn:e.statusNameEn,method:"position",vendor:"myVessel",utc:d.utc().format()}}async trajectory(t,i,n,o,s=!0,e={}){(!this.token||g().diff(g(this.token.issuedAt),"seconds")>this.token.expiresIn-300)&&await this.authToken(e);const d=await this.realTimePosition(t,e),c=g(i),u=g(n),f=[];for(;u.diff(c,"day",!0)>30;)await this.trajectoryIn30Day(t,c,c.clone().add(30,"day"),d,o,f,e),c.add(30,"day");return await this.trajectoryIn30Day(t,c,u,d,o,f,e),f}async trajectoryIn30Day(t,i,n,o,s,e,d={}){var h,v,k,Y,y;const c="https://svc.data.myvessel.cn/sdc/v1/vessels/status/track",u={headers:{Authorization:`${(h=this.token)==null?void 0:h.tokenType} ${(v=this.token)==null?void 0:v.accessToken}`},json:{mmsi:t,startTime:i.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),endTime:n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")}};l==null||l.info("[%s] fetch trajectory from: %s - %j",d.requestId,c,u);const f=await T.post(c,u).json();if(f.code)return l==null||l.warn("[%s] fetch trajectory failed: %j",d.requestId,c,{message:f.message,status:f.status,code:f.code}),f;let M=-1;const p=g(`${(Y=(k=f.data)==null?void 0:k[0])==null?void 0:Y.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return(y=f.data)==null||y.forEach(r=>{for(const H in r)!isNaN(r[H])&&Number(r[H])!==1/0&&(r[H]=Number(r[H]));const b=g(`${r.postime} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"),I=r.eta?g(`${r.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00"):void 0,m=r.status,{labelCn:F,labelEn:O}=this.parseStatus(m),E={mmsi:r.mmsi,imo:o==null?void 0:o.imo,lat:r.lat,lng:r.lon,sog:r.sog,cog:r.cog,hdg:r.hdg,draught:r.draught,status:m,eta:I==null?void 0:I.unix(),destination:r.dest,positionTime:b.unix(),labelCn:F,labelEn:O,method:"trajectory",vendor:"myVessel",utc:b.utc().format()},W=Math.floor(b.diff(p,"minute",!0)/(s||1));W!==M&&(M=W,e.push(E))}),e}}class ot extends z{constructor(t){super();B(this,"token");this.token=t}async realTimePosition(t,i={}){const n="https://api.hifleet.com/position/position/get/token",o={searchParams:{mmsi:t,usertoken:this.token}},s=await T.post(n,o).json();l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,n,o);const e=s==null?void 0:s.list;if(!e)return l==null||l.warn("[%s] fetch realtime position failed: %j",i.requestId,n,s),s;for(const p in e)!isNaN(e[p])&&Number(e[p])!==1/0&&(e[p]=Number(e[p]));e.status=e.sp>3?0:1;const d=e.status,{labelCn:c,labelEn:u}=this.parseStatus(d),f=g(`${e.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");return{mmsi:e.m,name:e.n,imo:e.imonumber,callSign:e.callsign,lat:Math.round(e.la/60*1e5)/1e5,lng:Math.round(e.lo/60*1e5)/1e5,length:e.l,width:e.w,draught:e.draught,sog:e.sp,cog:e.co,hdg:e.h,rot:isNaN(e.rot)?0:e.rot,eta:/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta)?g(`${e.eta} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00").unix():void 0,destination:e.destination,positionTime:f.unix(),utc:f.utc().format(),status:d,labelCn:c,labelEn:u,method:"position",vendor:"hifleet"}}async search(t,i={}){let n="https://www.hifleet.com/hifleetapi/searchVesselOL.do";const o={searchParams:{keyword:t},headers:{Referer:"https://www.hifleet.com",Origin:"https://www.hifleet.com",Host:"www.hifleet.com"}};let s=await T.post(n,o).json();l==null||l.info("[%s] fetch vessel props from: %s - %j",i.requestId,n,o),s instanceof Array&&(s=s[0]);for(const d in s)!isNaN(s[d])&&Number(s[d])!==1/0&&(s[d]=Number(s[d]));const e={mmsi:s.m,name:s.n,imo:s.i,callSign:s.c,length:s.l,breadth:s.b,draught:s.dr};return n="https://www.hifleet.com/hifleetapi/sameShipSearch.do",s=await T.post(n,o).json(),l==null||l.info("[%s] fetch vessel dead weight from: %s - %j",i.requestId,n,o),s instanceof Array&&(s=s[0]),s&&(e.deadweight=Number(s.dwt)),e}async trajectory(t,i,n,o,s=!0,e={}){var r,b,I;const d=await this.realTimePosition(t,e);let c=g(i);const u=g(n),f=g();if(s){let m=u.diff(c,"d",!0);m<0?c=u.clone().subtract(40,"d"):m<30?c.subtract(10,"d"):m<60?c.subtract(5,"d"):c=u.clone().subtract(80,"d"),m=f.diff(u,"d",!0),u.add(m>10?240:m*24,"h")}const M={searchParams:{endtime:u.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),starttime:c.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),mmsi:t,usertoken:this.token}},p="https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token",h=await T.get(p,M).json();l==null||l.info("[%s] fetch trajectory from: %s - %j",e.requestId,p,M);let v;h&&(v=((b=(r=h.ships)==null?void 0:r.offors)==null?void 0:b.ship)||[],v.length||l==null||l.warn("[%s] fetch trajectory failed: %j",e.requestId,h));const k=[];let Y=-1;const y=g(`${(I=v==null?void 0:v[0])==null?void 0:I.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");for(const m of v){for(const D in m)!isNaN(m[D])&&Number(m[D])!==1/0&&(m[D]=Number(m[D]));const F=g(`${m.ti} +08:00`,"YYYY-MM-DD HH:mm:ss +08:00");m.status=m.sp>4?0:1;const{labelEn:O,labelCn:E}=this.parseStatus(m.status),W={mmsi:m.m,name:m.n,imo:d==null?void 0:d.imo,lat:m.la,lng:m.lo,draught:m.draught,sog:m.sp,cog:m.co,hdg:m.hdg,positionTime:F.unix(),utc:F.utc().format(),status:m.status,labelCn:E,labelEn:O,method:"trajectory",vendor:"hifleet"},H=Math.floor(F.diff(y,"minute",!0)/(o||1));H!==Y&&(Y=H,k.push(W))}return k}}class it extends z{constructor(t){super();B(this,"token");this.token=t}async realTimePosition(t,i={}){const n={searchParams:{id:t,k:this.token,enc:1}},o="https://api.shipxy.com/apicall/GetSingleShip",s=await T.get(o,n).json();if(l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,o,n),(s==null?void 0:s.status)!==0)return s;const e=s.data[0];for(const M in e)!isNaN(e[M])&&Number(e[M])!==1/0&&(e[M]=Number(e[M]));const{labelCn:d,labelEn:c}=await this.parseStatus(e.navistat),u=g.unix(e.lasttime);return{mmsi:e.ShipID,name:e.name,imo:e.imo,callSign:e.callsign,lat:Math.round(e.lat/1e6*1e5)/1e5,lng:Math.round(e.lon/1e6*1e5)/1e5,length:Math.round(e.length/10*100)/100,width:Math.round(e.width/10*100)/100,draught:Math.round(e.draught/1e3*100)/100,sog:Math.round(e.sog*3600/1e3/1852*100)/100,cog:Math.round(e.cog/100*100)/100,hdg:Math.round(e.hdg/100*100)/100,rot:Math.round(e.rot/100*100)/100,positionTime:e.lasttime,utc:u.utc().format(),status:e.navistat,labelEn:c,labelCn:d,method:"position",vendor:"shipxy"}}async trajectory(t,i,n,o,s=!0,e={}){var y;const d=await this.realTimePosition(t,e),c=g(i),u=g(n),f="https://api.shipxy.com/apicall/GetShipTrack",M={searchParams:{id:t,k:this.token,enc:1,cut:0,btm:c.unix(),etm:u.unix()}},p=await T.get(f,M).json();if(l==null||l.info("[%s] fetch trajectory from: %s - %j",e.requestId,f,M),(p==null?void 0:p.status)!==0)return p;const h=p==null?void 0:p.points,v=[],k=g.unix((y=h[0])==null?void 0:y.utc);let Y=-1;for(const r of h){const b=g.unix(r.utc),I={imo:d==null?void 0:d.imo,mmsi:t,sog:Math.round(r.sog*3600/1e3/1852*100)/100,cog:Math.round(r.cog/100*100)/100,lat:Math.round(r.lat/1e6*1e5)/1e5,lng:Math.round(r.lon/1e6*1e5)/1e5,positionTime:b.unix(),utc:b.utc().format(),method:"trajectory",vendor:"shipxy"},m=Math.floor(b.diff(k,"minute",!0)/(o||1));m!==Y&&(Y=m,v.push(I))}return v}}class rt extends z{constructor(t){super();B(this,"token");this.token=t}async getShipId(t,i={}){const n={headers:{appKey:this.token},json:{mmsiList:t}},o="https://api3.myships.com/sp/ships/getShipIdByMMSI",s=await T.post(o,n).json();return l==null||l.info("[%s] fetch ship id from: %s - %j",i.requestId,o,n),s.code!=="0"?s:s.data[0].shipId}async getShipInfo(t,i={}){const n={headers:{appKey:this.token},json:{shipId:t}},o="https://api3.myships.com/sp/ships/aissta",s=await T.post(o,n).json();if(l==null||l.info("[%s] fetch ship info from: %s - %j",i.requestId,o,n),s.code!=="0")return s;const e=s.data;let d=e.imo;return t==="407170"&&(d="9198379",l==null||l.warn("[%s] ship(%s) imo error: %s, should be %s",i.requestId,t,e.imo,d)),{mmsi:e.mmsi,name:e.shipnameEn,imo:d,callSign:e.callSign,length:e.length,width:e.breadth,draught:(e.draught||100)/10}}async realTimePosition(t,i={}){const n=await this.getShipId(t,i),o=await this.getShipInfo(n,i),s={headers:{appKey:this.token},json:{shipId:n}},e="https://api3.myships.com/sp/ships/position/latest",d=await T.post(e,s).json();l==null||l.info("[%s] fetch realtime position from: %s - %j",i.requestId,e,s);const c=d.data[0];for(const h in c)!isNaN(c[h])&&Number(c[h])!==1/0&&(c[h]=Number(c[h]));const{labelCn:u,labelEn:f}=await this.parseStatus(c.aisNavStatus),M=g.unix(c.posTime);return{...o,mmsi:t,lat:Math.round(c.lat/1e4/60*1e5)/1e5,lng:Math.round(c.lon/1e4/60*1e5)/1e5,sog:Math.round(c.sog/10*100)/100,cog:Math.round(c.cog/10*100)/100,hdg:Math.round(c.heading*100)/100,rot:Math.round(c.rot*100)/100,positionTime:c.posTime,utc:M.utc().format(),status:c.aisNavStatus,labelEn:f,labelCn:u,method:"position",vendor:"myship"}}async trajectory(t,i,n,o,s=!0,e={}){const d=g(i),c=g(n),u=await this.getShipId(t),f=await this.getShipInfo(u),M=[];for(;c.diff(d,"day",!0)>30;)await this.trajectoryIn30Day(u,d.unix(),d.add(30,"day").unix(),f,t,o,M);return await this.trajectoryIn30Day(u,d.unix(),c.unix(),f,t,o,M),M}async trajectoryIn30Day(t,i,n,o,s,e,d,c={}){var k;const u={headers:{appKey:this.token},json:{shipId:t,startTime:i,endTime:n}},f="https://api3.myships.com/sp/ships/position/history",M=await T.post(f,u).json();if(l==null||l.info("[%s] fetch trajectory from: %s - %j",c.requestId,f,u),M.code!=="0")return l==null||l.warn("[%s] invoke myship trajectory failed: %j",c.requestId,M),M;const p=M.data;for(const Y in p)!isNaN(p[Y])&&Number(p[Y])!==1/0&&(p[Y]=Number(p[Y]));const h=g.unix((k=p[0])==null?void 0:k.posTime);let v=-1;for(const Y of p){const y=g.unix(Y.posTime),r={imo:o==null?void 0:o.imo,mmsi:s,lat:Math.round(Y.lat/1e4/60*1e5)/1e5,lng:Math.round(Y.lon/1e4/60*1e5)/1e5,sog:Math.round(Y.sog/10*100)/100,cog:Math.round(Y.cog/10*100)/100,hdg:Math.round(Y.heading*100)/100,rot:Math.round(Y.rot*100)/100,positionTime:y.unix(),utc:y.utc().format(),method:"trajectory",vendor:"myship"},b=Math.floor(y.diff(h,"minute",!0)/(e||1));b!==v&&(v=b,d.push(r))}return d}}let C;try{C=V.getLogger("vessel")}catch{}finally{}var G=(w=>(w.NOTICE="NOTICE",w.WARN="WARN",w.HEAVY="HEAVY",w.SEVERE="SEVERE",w.ERROR="ERROR",w.FATAL="FATAL",w))(G||{});class U{parsePrinciple(a,t={}){var e,d,c;C==null||C.info("[%s] parse rule: %s",t.requestId,a);const i=new RegExp("(?<=\\[)(.+)(?=])","g"),n=a.match(i)?(e=a.match(i))==null?void 0:e[0]:void 0,o=n==null?void 0:n.split(";");if(!o)return;const s={};for(let u=0;u<(o==null?void 0:o.length);u++){const f=(c=(d=o[u].match(i))==null?void 0:d[0])==null?void 0:c.split("],");if(u===0&&!f)s.scope=o[0];else if(f)for(let M=0,p=f.length;M<p;M++){const h=this.parseRule(f[M]);h&&(s[h.level]?h.key?s[h.level][h==null?void 0:h.key]=h:s[h.level]=h:h.key?s[h.level]={[h==null?void 0:h.key]:h}:s[h.level]=h)}}return s}parseRule(a,t={}){var s;C==null||C.info("[%s] parse rule: %s",t.requestId,a),a=a.startsWith("[")?a:`[${a}`,a=a.endsWith("]")?a:`${a}]`;const i=new RegExp("(?<=\\[)(.+?)(?=])","g"),n=(s=a==null?void 0:a.match(i))==null?void 0:s[0],o=n==null?void 0:n.split(",");if(o)return{operator:o[0],number:Number.isNaN(Number(o[1]))?o[1]:Number(o[1]),level:o[2],time:Number(o[3]),key:o[4]}}checkWeather(a,t,i={}){var h,v,k,Y,y,r,b,I,m,F,O,E,W,H,D;let n=0,o=0,s=0,e=0;const d=Math.round(((v=(h=t==null?void 0:t.SEVERE)==null?void 0:h.sigWave)==null?void 0:v.number)*1.6*100)/100,c=(Y=(k=t==null?void 0:t.SEVERE)==null?void 0:k.sigWave)==null?void 0:Y.number,u=(r=(y=t==null?void 0:t.HEAVY)==null?void 0:y.sigWave)==null?void 0:r.number,f=Math.round((((I=(b=t==null?void 0:t.SEVERE)==null?void 0:b.wind)==null?void 0:I.number)+2)*100)/100,M=(F=(m=t==null?void 0:t.SEVERE)==null?void 0:m.wind)==null?void 0:F.number,p=(E=(O=t==null?void 0:t.HEAVY)==null?void 0:O.wind)==null?void 0:E.number;for(let K=0;K<(a==null?void 0:a.length);K++){const S=a[K],A=(H=(W=S==null?void 0:S.meteo)==null?void 0:W.wave)==null?void 0:H.sig,R=(D=S==null?void 0:S.meteo)==null?void 0:D.wind,Z=K?g(S.eta).diff(g(a[K-1].eta),"hour",!0):0;e=Z>e?Z:e,C==null||C.info("[%s] check sig.wave: %j",i.requestId,{...A,dgThd4Wv:d,svThd4Wv:c,hvThd4Wv:u}),(A==null?void 0:A.height)>=d?S.isDangerous=!0:(A==null?void 0:A.height)>=c?S.isSevere=!0:(A==null?void 0:A.height)>=u&&(S.isHeavy=!0),C==null||C.info("[%s] check wind: %j",i.requestId,{...R,dgThd4Wd:f,svThd4Wd:M,hvThd4Wd:p}),(R==null?void 0:R.scale)>=f?(S.isDangerous=!0,delete S.isSevere,delete S.isHeavy):(R==null?void 0:R.scale)>M?(S.isDangerous||(S.isSevere=!0),delete S.isHeavy):(R==null?void 0:R.scale)===p&&!S.isDangerous&&!S.isSevere&&(S.isHeavy=!0),n+=S.isDangerous?Z:0,o+=S.isSevere?Z:0,s+=S.isHeavy?Z:0}return n=Math.round(n*100)/100,o=Math.round(o*100)/100,s=Math.round(s*100)/100,e=Math.round(e),{sample:a,dangerous:n,severe:o,heavy:s,step:e<3?3:e,wind:{dgThd4Wd:f,svThd4Wd:M,hvThd4Wd:p},sig:{dgThd4Wv:d,svThd4Wv:c,hvThd4Wv:u}}}}const ct=new U;let N;try{N=V.getLogger("vessel")}catch{}finally{}var J=(w=>(w.common="common",w.container="container",w))(J||{}),Q=(w=>(w.Ballast="Ballast",w.Laden="Laden",w))(Q||{}),X=(w=>(w.Cp="CP",w.Perf="Basis",w.Instruct="Other",w))(X||{});class x{static blockCoefficient(a,t,i,n){let o=Math.round(a/(t*i*n)*100)/100;o=o<.55?.55:o>.85?.85:o;const s=[.55,.6,.65,.7,.75,.8,.85],e=s.map(d=>Math.abs(d-o));return s[e.indexOf(Math.min(...e))]}static froudeNumber(a,t,i=9.8){let n=Math.round(Math.sqrt(a*a/(i*t))*100)/100;return n=n<.05?.05:n>.3?.3:n,n}static amendFactor(a,t,i){const n={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.4,-10.6,-9.5],.8:[2.6,-13.1,-15.1],.85:[3.1,-18.7,28]};let s={.55:[1.7,-1.4,-7.4],.6:[2.2,-2.5,-9.7],.65:[2.6,-3.7,-11.6],.7:[3.1,-5.3,-12.4],.75:[2.6,-12.5,-13.5],.8:[3,-16.3,-21.6],.85:[3.4,-20.9,31.8]}[a];return i==="Laden"&&(s=n[a]),s[0]+s[1]*t+s[2]*Math.pow(t,2)}static directionFactor(a,t=0){let i;return a>30&&a<=60?i=(1.7-.03*Math.pow(t-4,2))/2:a>60&&a<=150?i=(.9-.06*Math.pow(t-6,2))/2:i=(.4-.03*Math.pow(t-8,2))/2,Math.round(i*1e5)/1e5}static vesselTagFactor(a,t,i,n=0){n=n>5?n-.9*(n-5):n;let o;return i==="container"?o=.7*n+Math.pow(n,6.5)/(22*Math.pow(a,2/3)):t==="Ballast"?o=.7*n+Math.pow(n,6.5)/(2.7*Math.pow(a,2/3)):o=.5*n+Math.pow(n,6.5)/(2.7*Math.pow(a,2/3)),o}static waveHeightFactor(a){return a=a<1.25?1.25:a,a=a>6?a-.9*(a-6):a,Math.round((-.144*Math.pow(a,2)+.178*a)*1e4)/1e4}static assembleProperties(a,t,i,n){var u,f;const o=a.lbp??a.length??a.lengthOverall??198.9642,s=a.draught??8,e=a.breadthMoulded??a.breadth??a.breadthExtreme??32.4572,d=a.deadweight??67035.7773;return{tag:((f=(u=a==null?void 0:a.type)==null?void 0:u.toLowerCase())==null?void 0:f.indexOf("container"))>-1?"container":"common",lbp:o,loadCondition:t,draught:s,breadthMoulded:e,displacement:Math.round((d/1.025+s*e*o*.7)*1e4)/1e4,speed:Math.round((i??14.1382)*1852/3600*1e4)/1e4,bearing:n||90}}static async speedLoseAt(a,t,i,n="",o=2,s=!0,e=!1,d={}){let c;if(t.velocity&&e&&(a.speed=L.LngLatHelper.roundPrecision(t.velocity*1852/3600,6)),s){const u=await at.MeteoHelper.queryPointFactor(t.lng,t.lat,i.valueOf(),"wind,wave,current,watertemp",n,d),f=x.weatherFactor(a,u),M=x.currentFactor(a.bearing,u==null?void 0:u.current,o);c={meteo:{...u},wxFactor:f,cFactor:M,speed:t.velocity&&e?t.velocity:Math.round((a.speed*1.943844+f+M)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")}}else c={wxFactor:0,cFactor:0,speed:t.velocity&&e?t.velocity:Math.round((a.speed*1.943844+0+0)*100)/100,eta:i.utc().format("YYYY-MM-DDTHH:mm[Z]"),etd:i.utc().format("YYYY-MM-DDTHH:mm[Z]")};return delete t.meteo,delete t.wxFactor,delete t.cFactor,delete t.speed,delete t.etd,{...c,...t}}static async speedLoseInHoursStep(a,t,i,n,o,s,e="",d=!0,c=!1,u={}){t.utc();const f=[],M=[];let p=0,h=0,v,k;for(let Y=0;Y<s.length-1;Y++){let y=s[Y];y.distanceFromStart=o+h;const r=s[Y+1];if(a.bearing=L.LaneHelper.calculateBearing(y,r,!r.gcToPrevious),y.bearing=a.bearing,y.suspend&&c){y.eta=y.eta||t.format("YYYY-MM-DDTHH:mm[Z]"),y.elapsed=y.elapsed??0;const m=y.suspend-y.elapsed;if(n-p>m)n=n-p-m,t.add(m,"hour"),y.elapsed=y.suspend;else{const F=n-p;y.elapsed+=F,t.add(F,"hour"),n=0}if(N==null||N.info(`[%s] suspend ${y.elapsed} hours at %j, and remain ${n} hours need to go...`,u.requestId,y),n===0)return y.distanceFromPrevious=h,{etd:t,from:k||y,to:y,next:s.filter(F=>F),wps:f,days:M}}y=await x.speedLoseAt(a,y,t,e,0,d,c,u),k=k||y,y.important&&f.push(y),t.isSameOrAfter(i)&&(M.push(y),i.add(24,"hour"));const b=L.LaneHelper.calculateDistance(y,r,!r.gcToPrevious);let I=Math.ceil(b/k.speed*1e4)/1e4;if(p+I<n){if(p+=I,t.add(I,"hour"),delete s[Y],N==null||N.info(`[%s] go to %j from %j with ${b}nm, and cost ${I} hours`,u.requestId,{lat:r.lat,lng:r.lng},{lat:k.lat,lng:k.lng,etd:k.etd}),h+=b,s.filter(m=>m).length<=1){v=r,v.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),v.distanceFromPrevious=b,v.distanceFromStart=o+h,f.push(v),delete s[Y+1];break}}else{I=n-p,t.add(I,"hour");const m=L.LngLatHelper.roundPrecision(k.speed*I,4);v=L.LaneHelper.calculateCoordinate(y,a.bearing,m,"nauticalmiles",!r.gcToPrevious),v.eta=t.format("YYYY-MM-DDTHH:mm[Z]"),s[Y]=v,N==null||N.info(`[%s] go to %j from %j with ${m}nm, and cost ${I} hours`,u.requestId,{lat:v.lat,lng:v.lng},{lat:y.lat,lng:y.lng,etd:y.etd}),h+=m,v.distanceFromPrevious=h,v.distanceFromStart=o+h;break}}return{etd:t,from:k,to:v,next:s.filter(Y=>Y),wps:f,days:M}}static currentFactor(a,t,i=0){const n=(a-(t==null?void 0:t.degree)||0)/180*Math.PI;if(Math.abs(n)===Math.PI/2)return 0;let o=((t==null?void 0:t.kts)||0)*Math.cos(n);return i&2?o=Math.ceil(o*100)/100:i&1?o=Math.floor(o*100)/100:o=Math.round(o*100)/100,Math.abs(o)>5?0:o}static weatherFactor(a,t){var f,M,p,h,v;N==null||N.debug("calculate weather factor via: %j",{...a,...t});const i=x.blockCoefficient(a.displacement,a.lbp,a.breadthMoulded,a.draught),n=x.froudeNumber(a.speed,a.lbp),o=x.amendFactor(i,n,a.loadCondition);let s=Math.abs(a.bearing%360-(((f=t==null?void 0:t.wind)==null?void 0:f.degree)%360||0));s=s>180?360-s:s;const e=x.directionFactor(s,(M=t==null?void 0:t.wind)==null?void 0:M.scale),d=x.vesselTagFactor(a.displacement,a.loadCondition,a.tag,(p=t==null?void 0:t.wind)==null?void 0:p.scale);let c=e*o*d/100*a.speed;c=Math.round(c*1.943844*1e4)/1e4*-1;const u=x.waveHeightFactor(((v=(h=t==null?void 0:t.wave)==null?void 0:h.sig)==null?void 0:v.height)??1);return c=c*.24+u*.76,N==null||N.debug("weather factor = %s",c),Math.round(c*100)/100}static async analyseInstant(a,t,i,n,o,s="",e=0,d=!0,c=!1,u={}){var R,Z,$,tt,et;const f=g().valueOf();a.lng=L.LngLatHelper.convertToStdLng(a.lng);const{route:M,waypoints:p}=o.points,h=L.LaneHelper.calculateSubRoute(a,M);if(((R=h[0])==null?void 0:R.length)<=1)return;const{v0:v,label:k}=a.sog?{v0:a.sog,label:"Other"}:{v0:n.speed,label:"CP"},Y=x.assembleProperties(i,n.loadCondition,v,0),y=p.length?L.LaneHelper.calculateSubWaypoints(a,p):[],r={from:{...a},route:h,waypoints:y,v0:v,label:k},b={hours:[],days:[],wps:[]};e||(L.LaneHelper.calculateRouteDistance(h)/n.speed<=72?e=3:e=6);let I=L.LaneHelper.simplifyRouteToCoordinates(h,y,0),m=0,F=0,O=0,E=0;t=g(t).utc();const W=t.clone();for(;I.length>0;){const P=e-t.hour()%e,_=Math.ceil(t.clone().add(P,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4,q=await x.speedLoseInHoursStep(Y,t,W,_,m,I,s,d,c,u);(Z=q.from)!=null&&Z.speed&&(b.hours.push(q.from),b.wps.push(...q.wps),b.days.push(...q.days)),I=q==null?void 0:q.next,I.length||b.hours.push(q==null?void 0:q.to),m+=(($=q==null?void 0:q.to)==null?void 0:$.distanceFromPrevious)??0}const H=b.hours;for(let P=0;P<H.length-1;P++){const _=g(H[P+1].eta).diff(H[P].etd,"hour",!0)||1;F+=H[P].wxFactor||0*_,O+=H[P].cFactor||0*_,E+=_}(tt=b.wps)==null||tt.forEach((P,_)=>{if(_){const q=b.wps[_-1],dt=P.distanceFromStart-q.distanceFromStart,st=g(P.eta).diff(g(q.etd),"h",!0);st<1?P.avgSpd=q.speed:P.avgSpd=Math.round(dt/st*100)/100}}),r.sample=b;const D=b.hours.at(-1);r.distance=Math.round(D.distanceFromStart*1e4)/1e4,r.eta=g(D.eta).toDate(),r.wxFactor=Math.round(F/E*1e4)/1e4,r.cFactor=Math.round(O/E*1e4)/1e4,r.avgSpeed=Math.round(D.distanceFromStart/E*1e4)/1e4,r.totalHrs=Math.round(E*1e4)/1e4,r.totalFoCons=Math.round((n==null?void 0:n.fo)/24*r.totalHrs*1e3)/1e3,r.totalDgoCons=Math.round((n==null?void 0:n.dgo)/24*r.totalHrs*1e3)/1e3;const S=g().valueOf()-f,A=((et=b==null?void 0:b.hours)==null?void 0:et.length)||1;return N==null||N.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms",u==null?void 0:u.requestId,S,A,Math.round(S/A*1e3)/1e3),r}static async analyseInstantWithThreshed(a,t,i,n,o,s,e="",d=3,c=!0,u=!1,f={}){var O,E,W;a.lng=L.LngLatHelper.convertToStdLng(a.lng);const M=x.assembleProperties(n,o.loadCondition,o.speed,0),p=L.LaneHelper.calculateSubRoute(a,s);if(((O=p[0])==null?void 0:O.length)<=1)return;let h=L.LaneHelper.simplifyRouteToCoordinates(p,[],0);h.forEach(H=>H.important=!0);let v=0,k=0,Y=0,y=0,r;const b={hours:[],wps:[],days:[]};for(t=g(t).utc();h.length>0;){const H=d-t.hour()%d;let D=Math.ceil(t.clone().add(H,"h").set({minute:0,second:0,millisecond:0}).diff(t,"h",!0)*1e4)/1e4;if(D=t.clone().add(D,"h").isAfter(i)?i.diff(t,"h",!0)*1e4/1e4:D,D)r=await x.speedLoseInHoursStep(M,t,i.clone(),D,v,h,e,c,u,f),(E=r.from)!=null&&E.speed&&(b.hours.push(r.from),r!=null&&r.wps&&b.wps.push(...r.wps),b.days.push(...r.days)),h=r==null?void 0:r.next,h.length||(b.hours.push(r==null?void 0:r.to),r!=null&&r.wps&&b.wps.push(...r.wps),b.days.push(r==null?void 0:r.to)),v+=((W=r==null?void 0:r.to)==null?void 0:W.distanceFromPrevious)??0;else{r&&(b.hours.push(r.to),r!=null&&r.wps&&b.wps.push(...r.wps),b.days.push(r.to));break}}const I=b.hours;for(let H=0;H<I.length-1;H++){const D=g(I[H+1].eta).diff(I[H].etd,"hour",!0);k+=I[H].wxFactor*D,Y+=I[H].cFactor*D,y+=D}const m=b.hours.at(-1);return{sample:b,distance:Math.round(((m==null?void 0:m.distanceFromStart)||0)*1e4)/1e4,eta:g(m==null?void 0:m.eta).utc().format(),wxFactor:Math.round(k/y*1e4)/1e4,cFactor:Math.round(Y/y*1e4)/1e4,avgSpeed:Math.round(((m==null?void 0:m.distanceFromStart)||0)/y*1e4)/1e4,totalHrs:Math.round(y*1e4)/1e4,to:m,route:L.LaneHelper.generateRouteAccordingToWaypoints(h)}}}j.AISImpl=z,j.AlertHelper=U,j.AlertLevel=G,j.HifleetImpl=ot,j.LoadCondition=Q,j.MyShipImpl=rt,j.MyVesselImpl=nt,j.ShipxyImpl=it,j.SpeedHelper=x,j.SpeedLabel=X,j.VesselTag=J,j.alertHelper=ct,Object.defineProperty(j,Symbol.toStringTag,{value:"Module"})});
@@ -130,6 +130,7 @@ export declare class SpeedHelper {
130
130
  * @param eta 位置时间
131
131
  * @param source [CMEMS, GFS, Other]
132
132
  * @param role 1: 船东, 2: 租家, 0: 未知
133
+ * @param useMeteo true 启用气象分析
133
134
  * @param useRouteParam true 启用设置速度
134
135
  */
135
136
  private static speedLoseAt;
@@ -142,6 +143,7 @@ export declare class SpeedHelper {
142
143
  * @param distanceFromStart 与最开始起点的距离
143
144
  * @param keypoints 剩下的航路点
144
145
  * @param source 气象数据源: CMEMS / GFS
146
+ * @param useMeteo true 启用气象分析
145
147
  * @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
146
148
  * @private
147
149
  */
@@ -168,6 +170,7 @@ export declare class SpeedHelper {
168
170
  * @param lane 航线 { points: { route, waypoints }}
169
171
  * @param source 气象数据源,GFS or CMEMES, 默认CMEMS
170
172
  * @param stepHrs 样本步长, 0表示动态计算(6 or 3 hrs)
173
+ * @param useMeteo true 启用气象分析
171
174
  * @param useRouteParam
172
175
  */
173
176
  static analyseInstant(from: any, etd: any, vessel: VesselAssemble, cp: {
@@ -181,7 +184,7 @@ export declare class SpeedHelper {
181
184
  waypoints: any[];
182
185
  };
183
186
  voyage: any;
184
- }, source?: string, stepHrs?: number, useRouteParam?: boolean, options?: {
187
+ }, source?: string, stepHrs?: number, useMeteo?: boolean, useRouteParam?: boolean, options?: {
185
188
  requestId?: string;
186
189
  }): Promise<any>;
187
190
  /**
@@ -194,13 +197,15 @@ export declare class SpeedHelper {
194
197
  * @param route 航路[[[lng, lat]]]
195
198
  * @param source 气象数据源,GFS or CMEMES, 默认CMEMS
196
199
  * @param stepHrs
200
+ * @param useMeteo true 启用气象分析
201
+ * @param useRouteParam
197
202
  */
198
203
  static analyseInstantWithThreshed(from: any, etd: any, threshed: moment.Moment, vessel: VesselAssemble, cp: {
199
204
  loadCondition: string;
200
205
  speed: number;
201
206
  fo: number;
202
207
  dgo: number;
203
- }, route: number[][][], source?: string, stepHrs?: number, useRouteParam?: boolean, options?: {
208
+ }, route: number[][][], source?: string, stepHrs?: number, useMeteo?: boolean, useRouteParam?: boolean, options?: {
204
209
  requestId?: string;
205
210
  }): Promise<{
206
211
  sample: any;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@idm-plugin/vessel",
3
3
  "private": false,
4
- "version": "1.2.2",
4
+ "version": "1.2.3",
5
5
  "description": "idm plugin for vessel",
6
6
  "type": "module",
7
7
  "keywords": [