@idm-plugin/vessel 1.1.9 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,220 +1,222 @@
1
- var C = Object.defineProperty;
2
- var O = (M, u, e) => u in M ? C(M, u, { enumerable: !0, configurable: !0, writable: !0, value: e }) : M[u] = e;
3
- var q = (M, u, e) => (O(M, typeof u != "symbol" ? u + "" : u, e), e);
4
- import Y from "got";
5
- import W from "@log4js-node/log4js-api";
6
- import p from "moment";
7
- const b = W.getLogger("vessel");
8
- class V {
1
+ var Q = Object.defineProperty;
2
+ var X = (I, s, t) => s in I ? Q(I, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : I[s] = t;
3
+ var L = (I, s, t) => (X(I, typeof s != "symbol" ? s + "" : s, t), t);
4
+ import P from "got";
5
+ import K from "@log4js-node/log4js-api";
6
+ import y from "moment";
7
+ import { LngLatHelper as _, LaneHelper as R } from "@idm-plugin/geo";
8
+ import { MeteoHelper as tt } from "@idm-plugin/meteo";
9
+ const S = K.getLogger("vessel");
10
+ class Z {
9
11
  /**
10
12
  * 解析AIS状态码
11
13
  * @param status
12
14
  */
13
- parseStatus(u) {
14
- let e, n;
15
- switch (u) {
15
+ parseStatus(s) {
16
+ let t, r;
17
+ switch (s) {
16
18
  case 0:
17
- e = "在航(主机推动)", n = "The engine is in use";
19
+ t = "在航(主机推动)", r = "The engine is in use";
18
20
  break;
19
21
  case 1:
20
- e = "锚泊", n = "Anchored";
22
+ t = "锚泊", r = "Anchored";
21
23
  break;
22
24
  case 2:
23
- e = "失控", n = "Not operated";
25
+ t = "失控", r = "Not operated";
24
26
  break;
25
27
  case 3:
26
- e = "操纵受限", n = "Limited airworthiness";
28
+ t = "操纵受限", r = "Limited airworthiness";
27
29
  break;
28
30
  case 4:
29
- e = "吃水受限", n = "Limited by ship's draft";
31
+ t = "吃水受限", r = "Limited by ship's draft";
30
32
  break;
31
33
  case 5:
32
- e = "靠泊", n = "Mooring";
34
+ t = "靠泊", r = "Mooring";
33
35
  break;
34
36
  case 6:
35
- e = "搁浅", n = "Stranded";
37
+ t = "搁浅", r = "Stranded";
36
38
  break;
37
39
  case 7:
38
- e = "捕捞作业", n = "Engaged in fishing";
40
+ t = "捕捞作业", r = "Engaged in fishing";
39
41
  break;
40
42
  case 8:
41
- e = "靠帆船提供动力", n = "Sailing";
43
+ t = "靠帆船提供动力", r = "Sailing";
42
44
  break;
43
45
  default:
44
- e = "未定义", n = "Undefined";
46
+ t = "未定义", r = "Undefined";
45
47
  }
46
- return { labelCn: e, labelEn: n };
48
+ return { labelCn: t, labelEn: r };
47
49
  }
48
50
  }
49
- class U extends V {
50
- constructor(e, n) {
51
+ class lt extends Z {
52
+ constructor(t, r) {
51
53
  super();
52
- q(this, "clientId");
53
- q(this, "clientSecret");
54
- q(this, "token");
55
- this.clientId = e, this.clientSecret = n;
54
+ L(this, "clientId");
55
+ L(this, "clientSecret");
56
+ L(this, "token");
57
+ this.clientId = t, this.clientSecret = r;
56
58
  }
57
- async authToken(e = {}) {
58
- const n = "https://svc.data.myvessel.cn/ada/oauth/token", a = {
59
+ async authToken(t = {}) {
60
+ const r = "https://svc.data.myvessel.cn/ada/oauth/token", o = {
59
61
  searchParams: {
60
62
  client_id: this.clientId,
61
63
  client_secret: this.clientSecret,
62
64
  grant_type: "client_credentials"
63
65
  }
64
- }, o = await Y.post(n, a).json();
65
- b.info("[%s] fetch access token from: %s - %j", e.requestId, n, o), o.error || (this.token = {
66
- accessToken: o.access_token,
67
- tokenType: o.token_type,
68
- expiresIn: o.expires_in,
69
- scope: o.scope,
70
- jti: o.jti,
71
- issuedAt: p().utc().format()
66
+ }, n = await P.post(r, o).json();
67
+ S.info("[%s] fetch access token from: %s - %j", t.requestId, r, n), n.error || (this.token = {
68
+ accessToken: n.access_token,
69
+ tokenType: n.token_type,
70
+ expiresIn: n.expires_in,
71
+ scope: n.scope,
72
+ jti: n.jti,
73
+ issuedAt: y().utc().format()
72
74
  });
73
75
  }
74
- async realTimePosition(e, n = {}) {
75
- var h, c, f;
76
- (!this.token || p().diff(p(this.token.issuedAt), "seconds") > ((h = this.token) == null ? void 0 : h.expiresIn) - 300) && await this.authToken(n);
77
- const a = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", o = {
76
+ async realTimePosition(t, r = {}) {
77
+ var m, f, M;
78
+ (!this.token || y().diff(y(this.token.issuedAt), "seconds") > ((m = this.token) == null ? void 0 : m.expiresIn) - 300) && await this.authToken(r);
79
+ const o = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/location/unit", n = {
78
80
  headers: {
79
- Authorization: `${(c = this.token) == null ? void 0 : c.tokenType} ${(f = this.token) == null ? void 0 : f.accessToken}`
81
+ Authorization: `${(f = this.token) == null ? void 0 : f.tokenType} ${(M = this.token) == null ? void 0 : M.accessToken}`
80
82
  },
81
- searchParams: { mmsi: e }
83
+ searchParams: { mmsi: t }
82
84
  };
83
- b.info("[%s] fetch realtime position from: %s - %j", n.requestId, a, o);
84
- const s = await Y.get(a, o).json();
85
- if (s.code)
86
- return b.warn("[%s] fetch realtime position failed: %j", n.requestId, a, { message: s.message, status: s.status, code: s.code }), s;
87
- const t = s.data;
88
- for (const m in t)
89
- !isNaN(t[m]) && Number(t[m]) !== 1 / 0 && (t[m] = Number(t[m]));
90
- const r = p(`${t.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
85
+ S.info("[%s] fetch realtime position from: %s - %j", r.requestId, o, n);
86
+ const a = await P.get(o, n).json();
87
+ if (a.code)
88
+ return S.warn("[%s] fetch realtime position failed: %j", r.requestId, o, { message: a.message, status: a.status, code: a.code }), a;
89
+ const e = a.data;
90
+ for (const h in e)
91
+ !isNaN(e[h]) && Number(e[h]) !== 1 / 0 && (e[h] = Number(e[h]));
92
+ const c = y(`${e.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
91
93
  return {
92
- mmsi: t.mmsi,
93
- name: t.vesselName,
94
- imo: t.imo,
95
- callSign: t.callsign,
96
- lat: t.lat,
97
- lng: t.lon,
98
- length: t.length,
99
- width: t.width,
100
- draught: t.currDraught,
101
- sog: t.sog,
102
- cog: t.cog,
103
- hdg: t.hdg,
104
- rot: t.rot,
105
- eta: t.eta,
106
- destination: t.dest,
107
- positionTime: r.unix(),
108
- status: t.status,
109
- labelCn: t.statusNameCn,
110
- labelEn: t.statusNameEn,
94
+ mmsi: e.mmsi,
95
+ name: e.vesselName,
96
+ imo: e.imo,
97
+ callSign: e.callsign,
98
+ lat: e.lat,
99
+ lng: e.lon,
100
+ length: e.length,
101
+ width: e.width,
102
+ draught: e.currDraught,
103
+ sog: e.sog,
104
+ cog: e.cog,
105
+ hdg: e.hdg,
106
+ rot: e.rot,
107
+ eta: e.eta,
108
+ destination: e.dest,
109
+ positionTime: c.unix(),
110
+ status: e.status,
111
+ labelCn: e.statusNameCn,
112
+ labelEn: e.statusNameEn,
111
113
  method: "position",
112
114
  vendor: "myVessel",
113
- utc: r.utc().format()
115
+ utc: c.utc().format()
114
116
  };
115
117
  }
116
- async trajectory(e, n, a, o, s = !0, t = {}) {
117
- (!this.token || p().diff(p(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(t);
118
- const r = await this.realTimePosition(e, t), i = p(n), h = p(a), c = [];
119
- for (; h.diff(i, "day", !0) > 30; )
120
- await this.trajectoryIn30Day(e, i, i.clone().add(30, "day"), r, o, c, t), i.add(30, "day");
121
- return await this.trajectoryIn30Day(e, i, h, r, o, c, t), c;
118
+ async trajectory(t, r, o, n, a = !0, e = {}) {
119
+ (!this.token || y().diff(y(this.token.issuedAt), "seconds") > this.token.expiresIn - 300) && await this.authToken(e);
120
+ const c = await this.realTimePosition(t, e), i = y(r), m = y(o), f = [];
121
+ for (; m.diff(i, "day", !0) > 30; )
122
+ await this.trajectoryIn30Day(t, i, i.clone().add(30, "day"), c, n, f, e), i.add(30, "day");
123
+ return await this.trajectoryIn30Day(t, i, m, c, n, f, e), f;
122
124
  }
123
- async trajectoryIn30Day(e, n, a, o, s, t, r = {}) {
124
- var d, j, w, y, v;
125
- const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", h = {
125
+ async trajectoryIn30Day(t, r, o, n, a, e, c = {}) {
126
+ var u, b, Y, d, g;
127
+ const i = "https://svc.data.myvessel.cn/sdc/v1/vessels/status/track", m = {
126
128
  headers: {
127
- Authorization: `${(d = this.token) == null ? void 0 : d.tokenType} ${(j = this.token) == null ? void 0 : j.accessToken}`
129
+ Authorization: `${(u = this.token) == null ? void 0 : u.tokenType} ${(b = this.token) == null ? void 0 : b.accessToken}`
128
130
  },
129
131
  json: {
130
- mmsi: e,
131
- startTime: n.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
132
- endTime: a.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
132
+ mmsi: t,
133
+ startTime: r.utcOffset(8).format("YYYY-MM-DD HH:mm:ss"),
134
+ endTime: o.utcOffset(8).format("YYYY-MM-DD HH:mm:ss")
133
135
  }
134
136
  };
135
- b.info("[%s] fetch trajectory from: %s - %j", r.requestId, i, h);
136
- const c = await Y.post(i, h).json();
137
- if (c.code)
138
- return b.warn("[%s] fetch trajectory failed: %j", r.requestId, i, { message: c.message, status: c.status, code: c.code }), c;
139
- let f = -1;
140
- const m = p(`${(y = (w = c.data) == null ? void 0 : w[0]) == null ? void 0 : y.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
141
- return (v = c.data) == null || v.forEach((g) => {
142
- for (const S in g)
143
- !isNaN(g[S]) && Number(g[S]) !== 1 / 0 && (g[S] = Number(g[S]));
144
- const I = p(`${g.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), N = g.eta ? p(`${g.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, l = g.status, { labelCn: E, labelEn: _ } = this.parseStatus(l), R = {
145
- mmsi: g.mmsi,
146
- imo: o == null ? void 0 : o.imo,
147
- lat: g.lat,
148
- lng: g.lon,
149
- sog: g.sog,
150
- cog: g.cog,
151
- hdg: g.hdg,
152
- draught: g.draught,
153
- status: l,
154
- eta: N == null ? void 0 : N.unix(),
155
- destination: g.dest,
156
- positionTime: I.unix(),
157
- labelCn: E,
158
- labelEn: _,
137
+ S.info("[%s] fetch trajectory from: %s - %j", c.requestId, i, m);
138
+ const f = await P.post(i, m).json();
139
+ if (f.code)
140
+ return S.warn("[%s] fetch trajectory failed: %j", c.requestId, i, { message: f.message, status: f.status, code: f.code }), f;
141
+ let M = -1;
142
+ const h = y(`${(d = (Y = f.data) == null ? void 0 : Y[0]) == null ? void 0 : d.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
143
+ return (g = f.data) == null || g.forEach((l) => {
144
+ for (const w in l)
145
+ !isNaN(l[w]) && Number(l[w]) !== 1 / 0 && (l[w] = Number(l[w]));
146
+ const v = y(`${l.postime} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00"), k = l.eta ? y(`${l.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00") : void 0, p = l.status, { labelCn: x, labelEn: N } = this.parseStatus(p), C = {
147
+ mmsi: l.mmsi,
148
+ imo: n == null ? void 0 : n.imo,
149
+ lat: l.lat,
150
+ lng: l.lon,
151
+ sog: l.sog,
152
+ cog: l.cog,
153
+ hdg: l.hdg,
154
+ draught: l.draught,
155
+ status: p,
156
+ eta: k == null ? void 0 : k.unix(),
157
+ destination: l.dest,
158
+ positionTime: v.unix(),
159
+ labelCn: x,
160
+ labelEn: N,
159
161
  method: "trajectory",
160
162
  vendor: "myVessel",
161
- utc: I.utc().format()
162
- }, H = Math.floor(I.diff(m, "minute", !0) / (s || 1));
163
- H !== f && (f = H, t.push(R));
164
- }), t;
163
+ utc: v.utc().format()
164
+ }, T = Math.floor(v.diff(h, "minute", !0) / (a || 1));
165
+ T !== M && (M = T, e.push(C));
166
+ }), e;
165
167
  }
166
168
  }
167
- class J extends V {
168
- constructor(e) {
169
+ class mt extends Z {
170
+ constructor(t) {
169
171
  super();
170
- q(this, "token");
171
- this.token = e;
172
+ L(this, "token");
173
+ this.token = t;
172
174
  }
173
- async realTimePosition(e, n = {}) {
174
- const a = "https://api.hifleet.com/position/position/get/token", o = {
175
+ async realTimePosition(t, r = {}) {
176
+ const o = "https://api.hifleet.com/position/position/get/token", n = {
175
177
  searchParams: {
176
- mmsi: e,
178
+ mmsi: t,
177
179
  usertoken: this.token
178
180
  }
179
- }, s = await Y.post(a, o).json();
180
- b.info("[%s] fetch realtime position from: %s - %j", n.requestId, a, o);
181
- const t = s == null ? void 0 : s.list;
182
- if (!t)
183
- return b.warn("[%s] fetch realtime position failed: %j", n.requestId, a, s), s;
184
- for (const m in t)
185
- !isNaN(t[m]) && Number(t[m]) !== 1 / 0 && (t[m] = Number(t[m]));
186
- t.status = t.sp > 3 ? 0 : 1;
187
- const r = t.status, { labelCn: i, labelEn: h } = this.parseStatus(r), c = p(`${t.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
181
+ }, a = await P.post(o, n).json();
182
+ S.info("[%s] fetch realtime position from: %s - %j", r.requestId, o, n);
183
+ const e = a == null ? void 0 : a.list;
184
+ if (!e)
185
+ return S.warn("[%s] fetch realtime position failed: %j", r.requestId, o, a), a;
186
+ for (const h in e)
187
+ !isNaN(e[h]) && Number(e[h]) !== 1 / 0 && (e[h] = Number(e[h]));
188
+ e.status = e.sp > 3 ? 0 : 1;
189
+ const c = e.status, { labelCn: i, labelEn: m } = this.parseStatus(c), f = y(`${e.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
188
190
  return {
189
- mmsi: t.m,
190
- name: t.n,
191
- imo: t.imonumber,
192
- callSign: t.callsign,
193
- lat: Math.round(t.la / 60 * 1e5) / 1e5,
194
- lng: Math.round(t.lo / 60 * 1e5) / 1e5,
195
- length: t.l,
196
- width: t.w,
197
- draught: t.draught,
198
- sog: t.sp,
199
- cog: t.co,
200
- hdg: t.h,
201
- rot: isNaN(t.rot) ? 0 : t.rot,
202
- eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(t.eta) ? p(`${t.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
203
- destination: t.destination,
204
- positionTime: c.unix(),
205
- utc: c.utc().format(),
206
- status: r,
191
+ mmsi: e.m,
192
+ name: e.n,
193
+ imo: e.imonumber,
194
+ callSign: e.callsign,
195
+ lat: Math.round(e.la / 60 * 1e5) / 1e5,
196
+ lng: Math.round(e.lo / 60 * 1e5) / 1e5,
197
+ length: e.l,
198
+ width: e.w,
199
+ draught: e.draught,
200
+ sog: e.sp,
201
+ cog: e.co,
202
+ hdg: e.h,
203
+ rot: isNaN(e.rot) ? 0 : e.rot,
204
+ eta: /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(e.eta) ? y(`${e.eta} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00").unix() : void 0,
205
+ destination: e.destination,
206
+ positionTime: f.unix(),
207
+ utc: f.utc().format(),
208
+ status: c,
207
209
  labelCn: i,
208
- labelEn: h,
210
+ labelEn: m,
209
211
  method: "position",
210
212
  vendor: "hifleet"
211
213
  };
212
214
  }
213
- async search(e, n = {}) {
214
- let a = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
215
- const o = {
215
+ async search(t, r = {}) {
216
+ let o = "https://www.hifleet.com/hifleetapi/searchVesselOL.do";
217
+ const n = {
216
218
  searchParams: {
217
- keyword: e
219
+ keyword: t
218
220
  },
219
221
  headers: {
220
222
  Referer: "https://www.hifleet.com",
@@ -222,206 +224,206 @@ class J extends V {
222
224
  Host: "www.hifleet.com"
223
225
  }
224
226
  };
225
- let s = await Y.post(a, o).json();
226
- b.info("[%s] fetch vessel props from: %s - %j", n.requestId, a, o), s instanceof Array && (s = s[0]);
227
- for (const r in s)
228
- !isNaN(s[r]) && Number(s[r]) !== 1 / 0 && (s[r] = Number(s[r]));
229
- const t = {
230
- mmsi: s.m,
231
- name: s.n,
232
- imo: s.i,
233
- callSign: s.c,
234
- length: s.l,
235
- breadth: s.b,
236
- draught: s.dr
227
+ let a = await P.post(o, n).json();
228
+ S.info("[%s] fetch vessel props from: %s - %j", r.requestId, o, n), a instanceof Array && (a = a[0]);
229
+ for (const c in a)
230
+ !isNaN(a[c]) && Number(a[c]) !== 1 / 0 && (a[c] = Number(a[c]));
231
+ const e = {
232
+ mmsi: a.m,
233
+ name: a.n,
234
+ imo: a.i,
235
+ callSign: a.c,
236
+ length: a.l,
237
+ breadth: a.b,
238
+ draught: a.dr
237
239
  };
238
- return a = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", s = await Y.post(a, o).json(), b.info("[%s] fetch vessel dead weight from: %s - %j", n.requestId, a, o), s instanceof Array && (s = s[0]), s && (t.deadweight = Number(s.dwt)), t;
239
- }
240
- async trajectory(e, n, a, o, s = !0, t = {}) {
241
- var g, I, N;
242
- const r = await this.realTimePosition(e, t);
243
- let i = p(n);
244
- const h = p(a), c = p();
245
- if (s) {
246
- let l = h.diff(i, "d", !0);
247
- l < 0 ? i = h.clone().subtract(40, "d") : l < 30 ? i.subtract(10, "d") : l < 60 ? i.subtract(5, "d") : i = h.clone().subtract(80, "d"), l = c.diff(h, "d", !0), h.add(l > 10 ? 240 : l * 24, "h");
240
+ return o = "https://www.hifleet.com/hifleetapi/sameShipSearch.do", a = await P.post(o, n).json(), S.info("[%s] fetch vessel dead weight from: %s - %j", r.requestId, o, n), a instanceof Array && (a = a[0]), a && (e.deadweight = Number(a.dwt)), e;
241
+ }
242
+ async trajectory(t, r, o, n, a = !0, e = {}) {
243
+ var l, v, k;
244
+ const c = await this.realTimePosition(t, e);
245
+ let i = y(r);
246
+ const m = y(o), f = y();
247
+ if (a) {
248
+ let p = m.diff(i, "d", !0);
249
+ p < 0 ? i = m.clone().subtract(40, "d") : p < 30 ? i.subtract(10, "d") : p < 60 ? i.subtract(5, "d") : i = m.clone().subtract(80, "d"), p = f.diff(m, "d", !0), m.add(p > 10 ? 240 : p * 24, "h");
248
250
  }
249
- const f = {
251
+ const M = {
250
252
  searchParams: {
251
- endtime: h.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
253
+ endtime: m.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
252
254
  starttime: i.utcOffset("+8:00").format("YYYY-MM-DD HH:mm:ss"),
253
- mmsi: e,
255
+ mmsi: t,
254
256
  usertoken: this.token
255
257
  }
256
- }, m = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", d = await Y.get(m, f).json();
257
- b.info("[%s] fetch trajectory from: %s - %j", t.requestId, m, f);
258
- let j;
259
- d && (j = ((I = (g = d.ships) == null ? void 0 : g.offors) == null ? void 0 : I.ship) || [], j.length || b.warn("[%s] fetch trajectory failed: %j", t.requestId, d));
260
- const w = [];
261
- let y = -1;
262
- const v = p(`${(N = j == null ? void 0 : j[0]) == null ? void 0 : N.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
263
- for (const l of j) {
264
- for (const x in l)
265
- !isNaN(l[x]) && Number(l[x]) !== 1 / 0 && (l[x] = Number(l[x]));
266
- const E = p(`${l.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
267
- l.status = l.sp > 4 ? 0 : 1;
268
- const { labelEn: _, labelCn: R } = this.parseStatus(l.status), H = {
269
- mmsi: l.m,
270
- name: l.n,
271
- imo: r == null ? void 0 : r.imo,
272
- lat: l.la,
273
- lng: l.lo,
274
- draught: l.draught,
275
- sog: l.sp,
276
- cog: l.co,
277
- hdg: l.hdg,
278
- positionTime: E.unix(),
279
- utc: E.utc().format(),
280
- status: l.status,
281
- labelCn: R,
282
- labelEn: _,
258
+ }, h = "https://api.hifleet.com/position/trajectory/nocompressed/withstatic/token", u = await P.get(h, M).json();
259
+ S.info("[%s] fetch trajectory from: %s - %j", e.requestId, h, M);
260
+ let b;
261
+ u && (b = ((v = (l = u.ships) == null ? void 0 : l.offors) == null ? void 0 : v.ship) || [], b.length || S.warn("[%s] fetch trajectory failed: %j", e.requestId, u));
262
+ const Y = [];
263
+ let d = -1;
264
+ const g = y(`${(k = b == null ? void 0 : b[0]) == null ? void 0 : k.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
265
+ for (const p of b) {
266
+ for (const A in p)
267
+ !isNaN(p[A]) && Number(p[A]) !== 1 / 0 && (p[A] = Number(p[A]));
268
+ const x = y(`${p.ti} +08:00`, "YYYY-MM-DD HH:mm:ss +08:00");
269
+ p.status = p.sp > 4 ? 0 : 1;
270
+ const { labelEn: N, labelCn: C } = this.parseStatus(p.status), T = {
271
+ mmsi: p.m,
272
+ name: p.n,
273
+ imo: c == null ? void 0 : c.imo,
274
+ lat: p.la,
275
+ lng: p.lo,
276
+ draught: p.draught,
277
+ sog: p.sp,
278
+ cog: p.co,
279
+ hdg: p.hdg,
280
+ positionTime: x.unix(),
281
+ utc: x.utc().format(),
282
+ status: p.status,
283
+ labelCn: C,
284
+ labelEn: N,
283
285
  method: "trajectory",
284
286
  vendor: "hifleet"
285
- }, S = Math.floor(E.diff(v, "minute", !0) / (o || 1));
286
- S !== y && (y = S, w.push(H));
287
+ }, w = Math.floor(x.diff(g, "minute", !0) / (n || 1));
288
+ w !== d && (d = w, Y.push(T));
287
289
  }
288
- return w;
290
+ return Y;
289
291
  }
290
292
  }
291
- class Q extends V {
292
- constructor(e) {
293
+ class ft extends Z {
294
+ constructor(t) {
293
295
  super();
294
- q(this, "token");
295
- this.token = e;
296
+ L(this, "token");
297
+ this.token = t;
296
298
  }
297
- async realTimePosition(e, n = {}) {
298
- const a = {
299
+ async realTimePosition(t, r = {}) {
300
+ const o = {
299
301
  searchParams: {
300
- id: e,
302
+ id: t,
301
303
  k: this.token,
302
304
  enc: 1
303
305
  }
304
- }, o = "https://api.shipxy.com/apicall/GetSingleShip", s = await Y.get(o, a).json();
305
- if (b.info("[%s] fetch realtime position from: %s - %j", n.requestId, o, a), (s == null ? void 0 : s.status) !== 0)
306
- return s;
307
- const t = s.data[0];
308
- for (const f in t)
309
- !isNaN(t[f]) && Number(t[f]) !== 1 / 0 && (t[f] = Number(t[f]));
310
- const { labelCn: r, labelEn: i } = await this.parseStatus(t.navistat), h = p.unix(t.lasttime);
306
+ }, n = "https://api.shipxy.com/apicall/GetSingleShip", a = await P.get(n, o).json();
307
+ if (S.info("[%s] fetch realtime position from: %s - %j", r.requestId, n, o), (a == null ? void 0 : a.status) !== 0)
308
+ return a;
309
+ const e = a.data[0];
310
+ for (const M in e)
311
+ !isNaN(e[M]) && Number(e[M]) !== 1 / 0 && (e[M] = Number(e[M]));
312
+ const { labelCn: c, labelEn: i } = await this.parseStatus(e.navistat), m = y.unix(e.lasttime);
311
313
  return {
312
- mmsi: t.ShipID,
313
- name: t.name,
314
- imo: t.imo,
315
- callSign: t.callsign,
316
- lat: Math.round(t.lat / 1e6 * 1e5) / 1e5,
317
- lng: Math.round(t.lon / 1e6 * 1e5) / 1e5,
318
- length: Math.round(t.length / 10 * 100) / 100,
319
- width: Math.round(t.width / 10 * 100) / 100,
320
- draught: Math.round(t.draught / 1e3 * 100) / 100,
321
- sog: Math.round(t.sog * 3600 / 1e3 / 1852 * 100) / 100,
322
- cog: Math.round(t.cog / 100 * 100) / 100,
323
- hdg: Math.round(t.hdg / 100 * 100) / 100,
324
- rot: Math.round(t.rot / 100 * 100) / 100,
325
- positionTime: t.lasttime,
326
- utc: h.utc().format(),
327
- status: t.navistat,
314
+ mmsi: e.ShipID,
315
+ name: e.name,
316
+ imo: e.imo,
317
+ callSign: e.callsign,
318
+ lat: Math.round(e.lat / 1e6 * 1e5) / 1e5,
319
+ lng: Math.round(e.lon / 1e6 * 1e5) / 1e5,
320
+ length: Math.round(e.length / 10 * 100) / 100,
321
+ width: Math.round(e.width / 10 * 100) / 100,
322
+ draught: Math.round(e.draught / 1e3 * 100) / 100,
323
+ sog: Math.round(e.sog * 3600 / 1e3 / 1852 * 100) / 100,
324
+ cog: Math.round(e.cog / 100 * 100) / 100,
325
+ hdg: Math.round(e.hdg / 100 * 100) / 100,
326
+ rot: Math.round(e.rot / 100 * 100) / 100,
327
+ positionTime: e.lasttime,
328
+ utc: m.utc().format(),
329
+ status: e.navistat,
328
330
  labelEn: i,
329
- labelCn: r,
331
+ labelCn: c,
330
332
  method: "position",
331
333
  vendor: "shipxy"
332
334
  };
333
335
  }
334
- async trajectory(e, n, a, o, s = !0, t = {}) {
335
- var v;
336
- const r = await this.realTimePosition(e, t), i = p(n), h = p(a), c = "https://api.shipxy.com/apicall/GetShipTrack", f = {
336
+ async trajectory(t, r, o, n, a = !0, e = {}) {
337
+ var g;
338
+ const c = await this.realTimePosition(t, e), i = y(r), m = y(o), f = "https://api.shipxy.com/apicall/GetShipTrack", M = {
337
339
  searchParams: {
338
- id: e,
340
+ id: t,
339
341
  k: this.token,
340
342
  enc: 1,
341
343
  cut: 0,
342
344
  btm: i.unix(),
343
- etm: h.unix()
345
+ etm: m.unix()
344
346
  }
345
- }, m = await Y.get(c, f).json();
346
- if (b.info("[%s] fetch trajectory from: %s - %j", t.requestId, c, f), (m == null ? void 0 : m.status) !== 0)
347
- return m;
348
- const d = m == null ? void 0 : m.points, j = [], w = p.unix((v = d[0]) == null ? void 0 : v.utc);
349
- let y = -1;
350
- for (const g of d) {
351
- const I = p.unix(g.utc), N = {
352
- imo: r == null ? void 0 : r.imo,
353
- mmsi: e,
354
- sog: Math.round(g.sog * 3600 / 1e3 / 1852 * 100) / 100,
355
- cog: Math.round(g.cog / 100 * 100) / 100,
356
- lat: Math.round(g.lat / 1e6 * 1e5) / 1e5,
357
- lng: Math.round(g.lon / 1e6 * 1e5) / 1e5,
358
- positionTime: I.unix(),
359
- utc: I.utc().format(),
347
+ }, h = await P.get(f, M).json();
348
+ if (S.info("[%s] fetch trajectory from: %s - %j", e.requestId, f, M), (h == null ? void 0 : h.status) !== 0)
349
+ return h;
350
+ const u = h == null ? void 0 : h.points, b = [], Y = y.unix((g = u[0]) == null ? void 0 : g.utc);
351
+ let d = -1;
352
+ for (const l of u) {
353
+ const v = y.unix(l.utc), k = {
354
+ imo: c == null ? void 0 : c.imo,
355
+ mmsi: t,
356
+ sog: Math.round(l.sog * 3600 / 1e3 / 1852 * 100) / 100,
357
+ cog: Math.round(l.cog / 100 * 100) / 100,
358
+ lat: Math.round(l.lat / 1e6 * 1e5) / 1e5,
359
+ lng: Math.round(l.lon / 1e6 * 1e5) / 1e5,
360
+ positionTime: v.unix(),
361
+ utc: v.utc().format(),
360
362
  method: "trajectory",
361
363
  vendor: "shipxy"
362
- }, l = Math.floor(I.diff(w, "minute", !0) / (o || 1));
363
- l !== y && (y = l, j.push(N));
364
+ }, p = Math.floor(v.diff(Y, "minute", !0) / (n || 1));
365
+ p !== d && (d = p, b.push(k));
364
366
  }
365
- return j;
367
+ return b;
366
368
  }
367
369
  }
368
- class X extends V {
369
- constructor(e) {
370
+ class gt extends Z {
371
+ constructor(t) {
370
372
  super();
371
- q(this, "token");
372
- this.token = e;
373
+ L(this, "token");
374
+ this.token = t;
373
375
  }
374
- async getShipId(e, n = {}) {
375
- const a = {
376
+ async getShipId(t, r = {}) {
377
+ const o = {
376
378
  headers: {
377
379
  appKey: this.token
378
380
  },
379
381
  json: {
380
- mmsiList: e
382
+ mmsiList: t
381
383
  }
382
- }, o = "https://api3.myships.com/sp/ships/getShipIdByMMSI", s = await Y.post(o, a).json();
383
- return b.info("[%s] fetch ship id from: %s - %j", n.requestId, o, a), s.code !== "0" ? s : s.data[0].shipId;
384
+ }, n = "https://api3.myships.com/sp/ships/getShipIdByMMSI", a = await P.post(n, o).json();
385
+ return S.info("[%s] fetch ship id from: %s - %j", r.requestId, n, o), a.code !== "0" ? a : a.data[0].shipId;
384
386
  }
385
- async getShipInfo(e, n = {}) {
386
- const a = {
387
+ async getShipInfo(t, r = {}) {
388
+ const o = {
387
389
  headers: {
388
390
  appKey: this.token
389
391
  },
390
392
  json: {
391
- shipId: e
393
+ shipId: t
392
394
  }
393
- }, o = "https://api3.myships.com/sp/ships/aissta", s = await Y.post(o, a).json();
394
- if (b.info("[%s] fetch ship info from: %s - %j", n.requestId, o, a), s.code !== "0")
395
- return s;
396
- const t = s.data;
397
- let r = t.imo;
398
- return e === "407170" && (r = "9198379", b.warn("[%s] ship(%s) imo error: %s, should be %s", n.requestId, e, t.imo, r)), {
399
- mmsi: t.mmsi,
400
- name: t.shipnameEn,
401
- imo: r,
402
- callSign: t.callSign,
403
- length: t.length,
404
- width: t.breadth,
405
- draught: (t.draught || 100) / 10
395
+ }, n = "https://api3.myships.com/sp/ships/aissta", a = await P.post(n, o).json();
396
+ if (S.info("[%s] fetch ship info from: %s - %j", r.requestId, n, o), a.code !== "0")
397
+ return a;
398
+ const e = a.data;
399
+ let c = e.imo;
400
+ return t === "407170" && (c = "9198379", S.warn("[%s] ship(%s) imo error: %s, should be %s", r.requestId, t, e.imo, c)), {
401
+ mmsi: e.mmsi,
402
+ name: e.shipnameEn,
403
+ imo: c,
404
+ callSign: e.callSign,
405
+ length: e.length,
406
+ width: e.breadth,
407
+ draught: (e.draught || 100) / 10
406
408
  };
407
409
  }
408
- async realTimePosition(e, n = {}) {
409
- const a = await this.getShipId(e, n), o = await this.getShipInfo(a, n), s = {
410
+ async realTimePosition(t, r = {}) {
411
+ const o = await this.getShipId(t, r), n = await this.getShipInfo(o, r), a = {
410
412
  headers: {
411
413
  appKey: this.token
412
414
  },
413
415
  json: {
414
- shipId: a
416
+ shipId: o
415
417
  }
416
- }, t = "https://api3.myships.com/sp/ships/position/latest", r = await Y.post(t, s).json();
417
- b.info("[%s] fetch realtime position from: %s - %j", n.requestId, t, s);
418
- const i = r.data[0];
419
- for (const d in i)
420
- !isNaN(i[d]) && Number(i[d]) !== 1 / 0 && (i[d] = Number(i[d]));
421
- const { labelCn: h, labelEn: c } = await this.parseStatus(i.aisNavStatus), f = p.unix(i.posTime);
418
+ }, e = "https://api3.myships.com/sp/ships/position/latest", c = await P.post(e, a).json();
419
+ S.info("[%s] fetch realtime position from: %s - %j", r.requestId, e, a);
420
+ const i = c.data[0];
421
+ for (const u in i)
422
+ !isNaN(i[u]) && Number(i[u]) !== 1 / 0 && (i[u] = Number(i[u]));
423
+ const { labelCn: m, labelEn: f } = await this.parseStatus(i.aisNavStatus), M = y.unix(i.posTime);
422
424
  return {
423
- ...o,
424
- mmsi: e,
425
+ ...n,
426
+ mmsi: t,
425
427
  lat: Math.round(i.lat / 1e4 / 60 * 1e5) / 1e5,
426
428
  lng: Math.round(i.lon / 1e4 / 60 * 1e5) / 1e5,
427
429
  sog: Math.round(i.sog / 10 * 100) / 100,
@@ -429,62 +431,62 @@ class X extends V {
429
431
  hdg: Math.round(i.heading * 100) / 100,
430
432
  rot: Math.round(i.rot * 100) / 100,
431
433
  positionTime: i.posTime,
432
- utc: f.utc().format(),
434
+ utc: M.utc().format(),
433
435
  status: i.aisNavStatus,
434
- labelEn: c,
435
- labelCn: h,
436
+ labelEn: f,
437
+ labelCn: m,
436
438
  method: "position",
437
439
  vendor: "myship"
438
440
  };
439
441
  }
440
- async trajectory(e, n, a, o, s = !0, t = {}) {
441
- const r = p(n), i = p(a), h = await this.getShipId(e), c = await this.getShipInfo(h), f = [];
442
- for (; i.diff(r, "day", !0) > 30; )
443
- await this.trajectoryIn30Day(h, r.unix(), r.add(30, "day").unix(), c, e, o, f);
444
- return await this.trajectoryIn30Day(h, r.unix(), i.unix(), c, e, o, f), f;
442
+ async trajectory(t, r, o, n, a = !0, e = {}) {
443
+ const c = y(r), i = y(o), m = await this.getShipId(t), f = await this.getShipInfo(m), M = [];
444
+ for (; i.diff(c, "day", !0) > 30; )
445
+ await this.trajectoryIn30Day(m, c.unix(), c.add(30, "day").unix(), f, t, n, M);
446
+ return await this.trajectoryIn30Day(m, c.unix(), i.unix(), f, t, n, M), M;
445
447
  }
446
- async trajectoryIn30Day(e, n, a, o, s, t, r, i = {}) {
447
- var w;
448
- const h = {
448
+ async trajectoryIn30Day(t, r, o, n, a, e, c, i = {}) {
449
+ var Y;
450
+ const m = {
449
451
  headers: {
450
452
  appKey: this.token
451
453
  },
452
454
  json: {
453
- shipId: e,
454
- startTime: n,
455
- endTime: a
455
+ shipId: t,
456
+ startTime: r,
457
+ endTime: o
456
458
  }
457
- }, c = "https://api3.myships.com/sp/ships/position/history", f = await Y.post(c, h).json();
458
- if (b.info("[%s] fetch trajectory from: %s - %j", i.requestId, c, h), f.code !== "0")
459
- return b.warn("[%s] invoke myship trajectory failed: %j", i.requestId, f), f;
460
- const m = f.data;
461
- for (const y in m)
462
- !isNaN(m[y]) && Number(m[y]) !== 1 / 0 && (m[y] = Number(m[y]));
463
- const d = p.unix((w = m[0]) == null ? void 0 : w.posTime);
464
- let j = -1;
465
- for (const y of m) {
466
- const v = p.unix(y.posTime), g = {
467
- imo: o == null ? void 0 : o.imo,
468
- mmsi: s,
469
- lat: Math.round(y.lat / 1e4 / 60 * 1e5) / 1e5,
470
- lng: Math.round(y.lon / 1e4 / 60 * 1e5) / 1e5,
471
- sog: Math.round(y.sog / 10 * 100) / 100,
472
- cog: Math.round(y.cog / 10 * 100) / 100,
473
- hdg: Math.round(y.heading * 100) / 100,
474
- rot: Math.round(y.rot * 100) / 100,
475
- positionTime: v.unix(),
476
- utc: v.utc().format(),
459
+ }, f = "https://api3.myships.com/sp/ships/position/history", M = await P.post(f, m).json();
460
+ if (S.info("[%s] fetch trajectory from: %s - %j", i.requestId, f, m), M.code !== "0")
461
+ return S.warn("[%s] invoke myship trajectory failed: %j", i.requestId, M), M;
462
+ const h = M.data;
463
+ for (const d in h)
464
+ !isNaN(h[d]) && Number(h[d]) !== 1 / 0 && (h[d] = Number(h[d]));
465
+ const u = y.unix((Y = h[0]) == null ? void 0 : Y.posTime);
466
+ let b = -1;
467
+ for (const d of h) {
468
+ const g = y.unix(d.posTime), l = {
469
+ imo: n == null ? void 0 : n.imo,
470
+ mmsi: a,
471
+ lat: Math.round(d.lat / 1e4 / 60 * 1e5) / 1e5,
472
+ lng: Math.round(d.lon / 1e4 / 60 * 1e5) / 1e5,
473
+ sog: Math.round(d.sog / 10 * 100) / 100,
474
+ cog: Math.round(d.cog / 10 * 100) / 100,
475
+ hdg: Math.round(d.heading * 100) / 100,
476
+ rot: Math.round(d.rot * 100) / 100,
477
+ positionTime: g.unix(),
478
+ utc: g.utc().format(),
477
479
  method: "trajectory",
478
480
  vendor: "myship"
479
- }, I = Math.floor(v.diff(d, "minute", !0) / (t || 1));
480
- I !== j && (j = I, r.push(g));
481
+ }, v = Math.floor(g.diff(u, "minute", !0) / (e || 1));
482
+ v !== b && (b = v, c.push(l));
481
483
  }
482
- return r;
484
+ return c;
483
485
  }
484
486
  }
485
- const $ = W.getLogger("vessel");
486
- var K = /* @__PURE__ */ ((M) => (M.NOTICE = "NOTICE", M.WARN = "WARN", M.HEAVY = "HEAVY", M.SEVERE = "SEVERE", M.ERROR = "ERROR", M.FATAL = "FATAL", M))(K || {});
487
- class L {
487
+ const B = K.getLogger("vessel");
488
+ var et = /* @__PURE__ */ ((I) => (I.NOTICE = "NOTICE", I.WARN = "WARN", I.HEAVY = "HEAVY", I.SEVERE = "SEVERE", I.ERROR = "ERROR", I.FATAL = "FATAL", I))(et || {});
489
+ class st {
488
490
  /**
489
491
  * 解析告警规则, 多规则场景
490
492
  * @param rule
@@ -493,24 +495,24 @@ class L {
493
495
  *
494
496
  * @param options
495
497
  */
496
- parsePrinciple(u, e = {}) {
497
- var t, r, i;
498
- $.info("[%s] parse rule: %s", e.requestId, u);
499
- const n = new RegExp("(?<=\\[)(.+)(?=])", "g"), a = u.match(n) ? (t = u.match(n)) == null ? void 0 : t[0] : void 0, o = a == null ? void 0 : a.split(";");
500
- if (!o)
498
+ parsePrinciple(s, t = {}) {
499
+ var e, c, i;
500
+ B.info("[%s] parse rule: %s", t.requestId, s);
501
+ const r = new RegExp("(?<=\\[)(.+)(?=])", "g"), o = s.match(r) ? (e = s.match(r)) == null ? void 0 : e[0] : void 0, n = o == null ? void 0 : o.split(";");
502
+ if (!n)
501
503
  return;
502
- const s = {};
503
- for (let h = 0; h < (o == null ? void 0 : o.length); h++) {
504
- const c = (i = (r = o[h].match(n)) == null ? void 0 : r[0]) == null ? void 0 : i.split("],");
505
- if (h === 0 && !c)
506
- s.scope = o[0];
507
- else if (c)
508
- for (let f = 0, m = c.length; f < m; f++) {
509
- const d = this.parseRule(c[f]);
510
- d && (s[d.level] ? d.key ? s[d.level][d == null ? void 0 : d.key] = d : s[d.level] = d : d.key ? s[d.level] = { [d == null ? void 0 : d.key]: d } : s[d.level] = d);
504
+ const a = {};
505
+ for (let m = 0; m < (n == null ? void 0 : n.length); m++) {
506
+ const f = (i = (c = n[m].match(r)) == null ? void 0 : c[0]) == null ? void 0 : i.split("],");
507
+ if (m === 0 && !f)
508
+ a.scope = n[0];
509
+ else if (f)
510
+ for (let M = 0, h = f.length; M < h; M++) {
511
+ const u = this.parseRule(f[M]);
512
+ u && (a[u.level] ? u.key ? a[u.level][u == null ? void 0 : u.key] = u : a[u.level] = u : u.key ? a[u.level] = { [u == null ? void 0 : u.key]: u } : a[u.level] = u);
511
513
  }
512
514
  }
513
- return s;
515
+ return a;
514
516
  }
515
517
  /**
516
518
  * 解析单一告警规则
@@ -518,17 +520,17 @@ class L {
518
520
  * @param rule
519
521
  * @param options
520
522
  */
521
- parseRule(u, e = {}) {
522
- var s;
523
- $.info("[%s] parse rule: %s", e.requestId, u), u = u.startsWith("[") ? u : `[${u}`, u = u.endsWith("]") ? u : `${u}]`;
524
- const n = new RegExp("(?<=\\[)(.+?)(?=])", "g"), a = (s = u == null ? void 0 : u.match(n)) == null ? void 0 : s[0], o = a == null ? void 0 : a.split(",");
525
- if (o)
523
+ parseRule(s, t = {}) {
524
+ var a;
525
+ B.info("[%s] parse rule: %s", t.requestId, s), s = s.startsWith("[") ? s : `[${s}`, s = s.endsWith("]") ? s : `${s}]`;
526
+ const r = new RegExp("(?<=\\[)(.+?)(?=])", "g"), o = (a = s == null ? void 0 : s.match(r)) == null ? void 0 : a[0], n = o == null ? void 0 : o.split(",");
527
+ if (n)
526
528
  return {
527
- operator: o[0],
528
- number: Number.isNaN(Number(o[1])) ? o[1] : Number(o[1]),
529
- level: o[2],
530
- time: Number(o[3]),
531
- key: o[4]
529
+ operator: n[0],
530
+ number: Number.isNaN(Number(n[1])) ? n[1] : Number(n[1]),
531
+ level: n[2],
532
+ time: Number(n[3]),
533
+ key: n[4]
532
534
  };
533
535
  }
534
536
  /**
@@ -537,25 +539,379 @@ class L {
537
539
  * @param principle 告警规则
538
540
  * @param options
539
541
  */
540
- checkWeather(u, e, n = {}) {
541
- var d, j, w, y, v, g, I, N, l, E, _, R, H, S, x;
542
- let a = 0, o = 0, s = 0, t = 0;
543
- const r = Math.round(((j = (d = e == null ? void 0 : e.SEVERE) == null ? void 0 : d.sigWave) == null ? void 0 : j.number) * 1.6 * 100) / 100, i = (y = (w = e == null ? void 0 : e.SEVERE) == null ? void 0 : w.sigWave) == null ? void 0 : y.number, h = (g = (v = e == null ? void 0 : e.HEAVY) == null ? void 0 : v.sigWave) == null ? void 0 : g.number, c = Math.round((((N = (I = e == null ? void 0 : e.SEVERE) == null ? void 0 : I.wind) == null ? void 0 : N.number) + 2) * 100) / 100, f = (E = (l = e == null ? void 0 : e.SEVERE) == null ? void 0 : l.wind) == null ? void 0 : E.number, m = (R = (_ = e == null ? void 0 : e.HEAVY) == null ? void 0 : _.wind) == null ? void 0 : R.number;
544
- for (let A = 0; A < (u == null ? void 0 : u.length); A++) {
545
- const k = u[A], T = (S = (H = k == null ? void 0 : k.meteo) == null ? void 0 : H.wave) == null ? void 0 : S.sig, D = (x = k == null ? void 0 : k.meteo) == null ? void 0 : x.wind, P = A ? p(k.eta).diff(p(u[A - 1].eta), "hour", !0) : 0;
546
- t = P > t ? P : t, $.info("[%s] check sig.wave: %j", n.requestId, { ...T, dgThd4Wv: r, svThd4Wv: i, hvThd4Wv: h }), (T == null ? void 0 : T.height) >= r ? k.isDangerous = !0 : (T == null ? void 0 : T.height) >= i ? k.isSevere = !0 : (T == null ? void 0 : T.height) >= h && (k.isHeavy = !0), $.info("[%s] check wind: %j", n.requestId, { ...D, dgThd4Wd: c, svThd4Wd: f, hvThd4Wd: m }), (D == null ? void 0 : D.scale) >= c ? (k.isDangerous = !0, delete k.isSevere, delete k.isHeavy) : (D == null ? void 0 : D.scale) > f ? (k.isDangerous || (k.isSevere = !0), delete k.isHeavy) : (D == null ? void 0 : D.scale) === m && !k.isDangerous && !k.isSevere && (k.isHeavy = !0), a += k.isDangerous ? P : 0, o += k.isSevere ? P : 0, s += k.isHeavy ? P : 0;
542
+ checkWeather(s, t, r = {}) {
543
+ var u, b, Y, d, g, l, v, k, p, x, N, C, T, w, A;
544
+ let o = 0, n = 0, a = 0, e = 0;
545
+ const c = Math.round(((b = (u = t == null ? void 0 : t.SEVERE) == null ? void 0 : u.sigWave) == null ? void 0 : b.number) * 1.6 * 100) / 100, i = (d = (Y = t == null ? void 0 : t.SEVERE) == null ? void 0 : Y.sigWave) == null ? void 0 : d.number, m = (l = (g = t == null ? void 0 : t.HEAVY) == null ? void 0 : g.sigWave) == null ? void 0 : l.number, f = Math.round((((k = (v = t == null ? void 0 : t.SEVERE) == null ? void 0 : v.wind) == null ? void 0 : k.number) + 2) * 100) / 100, M = (x = (p = t == null ? void 0 : t.SEVERE) == null ? void 0 : p.wind) == null ? void 0 : x.number, h = (C = (N = t == null ? void 0 : t.HEAVY) == null ? void 0 : N.wind) == null ? void 0 : C.number;
546
+ for (let O = 0; O < (s == null ? void 0 : s.length); O++) {
547
+ const j = s[O], E = (w = (T = j == null ? void 0 : j.meteo) == null ? void 0 : T.wave) == null ? void 0 : w.sig, q = (A = j == null ? void 0 : j.meteo) == null ? void 0 : A.wind, W = O ? y(j.eta).diff(y(s[O - 1].eta), "hour", !0) : 0;
548
+ e = W > e ? W : e, B.info("[%s] check sig.wave: %j", r.requestId, { ...E, dgThd4Wv: c, svThd4Wv: i, hvThd4Wv: m }), (E == null ? void 0 : E.height) >= c ? j.isDangerous = !0 : (E == null ? void 0 : E.height) >= i ? j.isSevere = !0 : (E == null ? void 0 : E.height) >= m && (j.isHeavy = !0), B.info("[%s] check wind: %j", r.requestId, { ...q, dgThd4Wd: f, svThd4Wd: M, hvThd4Wd: h }), (q == null ? void 0 : q.scale) >= f ? (j.isDangerous = !0, delete j.isSevere, delete j.isHeavy) : (q == null ? void 0 : q.scale) > M ? (j.isDangerous || (j.isSevere = !0), delete j.isHeavy) : (q == null ? void 0 : q.scale) === h && !j.isDangerous && !j.isSevere && (j.isHeavy = !0), o += j.isDangerous ? W : 0, n += j.isSevere ? W : 0, a += j.isHeavy ? W : 0;
547
549
  }
548
- return a = Math.round(a * 100) / 100, o = Math.round(o * 100) / 100, s = Math.round(s * 100) / 100, t = Math.round(t), { sample: u, dangerous: a, severe: o, heavy: s, step: t < 3 ? 3 : t, wind: { dgThd4Wd: c, svThd4Wd: f, hvThd4Wd: m }, sig: { dgThd4Wv: r, svThd4Wv: i, hvThd4Wv: h } };
550
+ 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: f, svThd4Wd: M, hvThd4Wd: h }, sig: { dgThd4Wv: c, svThd4Wv: i, hvThd4Wv: m } };
551
+ }
552
+ }
553
+ const Mt = new st(), V = K.getLogger("vessel");
554
+ var at = /* @__PURE__ */ ((I) => (I.common = "common", I.container = "container", I))(at || {}), ot = /* @__PURE__ */ ((I) => (I.Ballast = "Ballast", I.Laden = "Laden", I))(ot || {}), nt = /* @__PURE__ */ ((I) => (I.Cp = "CP", I.Perf = "Basis", I.Instruct = "Other", I))(nt || {});
555
+ class H {
556
+ /**
557
+ * @see https://baike.baidu.com/item/%E6%96%B9%E5%BD%A2%E7%B3%BB%E6%95%B0/4965568?fr=aladdin
558
+ * 方形系数(block coefficient)
559
+ * 是指与基平面相平行的任一水线面以下的船型排水体积与对应的船长、型宽
560
+ * 和平均吃水的乘积所表示的长方体体积之比
561
+ * 方块系数介于 0.55 - 0.85
562
+ * @param displacement 排水 m^3
563
+ * @param length 水线长 m
564
+ * @param breadth 水线宽 m
565
+ * @param draught 吃水 m
566
+ * @return [0.55, 0.85]
567
+ */
568
+ static blockCoefficient(s, t, r, o) {
569
+ let n = Math.round(s / (t * r * o) * 100) / 100;
570
+ n = n < 0.55 ? 0.55 : n > 0.85 ? 0.85 : n;
571
+ const a = [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85], e = a.map((c) => Math.abs(c - n));
572
+ return a[e.indexOf(Math.min(...e))];
573
+ }
574
+ /**
575
+ * @see https://baike.baidu.com/item/%E5%BC%97%E5%8A%B3%E5%BE%B7%E6%95%B0/228891?fromModule=search-result_lemma-recommend
576
+ * 弗劳德数 (froude number)
577
+ * 流体力学中表征流体惯性力和重力相对大小的一个无量纲参数,记为Fr。它表示惯性力和重力量级的比,即:Fr=sqrt(U²/(gL)) [6] ,
578
+ * 式中U为物体运动速度,g为重力加速度;L为物体的特征长度
579
+ * 佛勞德數介乎 0.05 - 0.30
580
+ * @param speed 速度 m/s
581
+ * @param length 船长 m
582
+ * @param g 重力加速度 9.80 m/s^2
583
+ * @return [0.05, 0.30]
584
+ */
585
+ static froudeNumber(s, t, r = 9.8) {
586
+ let o = Math.round(Math.sqrt(s * s / (r * t)) * 100) / 100;
587
+ return o = o < 0.05 ? 0.05 : o > 0.3 ? 0.3 : o, o;
588
+ }
589
+ /**
590
+ * 失速修正系數
591
+ * @param bc 方形系数 [0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85]
592
+ * @param fr 弗劳德数 [0.05 - 0.30]
593
+ * @param loadCondition
594
+ * @private
595
+ */
596
+ static amendFactor(s, t, r) {
597
+ const o = {
598
+ 0.55: [1.7, -1.4, -7.4],
599
+ 0.6: [2.2, -2.5, -9.7],
600
+ 0.65: [2.6, -3.7, -11.6],
601
+ 0.7: [3.1, -5.3, -12.4],
602
+ 0.75: [2.4, -10.6, -9.5],
603
+ 0.8: [2.6, -13.1, -15.1],
604
+ 0.85: [3.1, -18.7, 28]
605
+ };
606
+ let a = {
607
+ 0.55: [1.7, -1.4, -7.4],
608
+ 0.6: [2.2, -2.5, -9.7],
609
+ 0.65: [2.6, -3.7, -11.6],
610
+ 0.7: [3.1, -5.3, -12.4],
611
+ 0.75: [2.6, -12.5, -13.5],
612
+ 0.8: [3, -16.3, -21.6],
613
+ 0.85: [3.4, -20.9, 31.8]
614
+ }[s];
615
+ return r === "Laden" && (a = o[s]), a[0] + a[1] * t + a[2] * Math.pow(t, 2);
616
+ }
617
+ /**
618
+ * 失速方向因子
619
+ * 頂浪(不規則 波)、頂風 (0°): 2 * 𝐶𝜇 = 2
620
+ * 艏斜浪(不規 則波)、前迎風 (30°~60°): 2 𝐶𝜇 = 1.7 −0.03(Bn − 4)^2
621
+ * 橫浪(不規則 波)、橫風 (60°~150°): 2 𝐶𝜇 = 0.9 −0.06(Bn − 6)^2
622
+ * 順浪(不規則 波)、順風 (150°~180°): 2 𝐶𝜇 = 0.4 −0.03(Bn− 8)^2
623
+ *
624
+ * @param beta 航向与风浪的夹角
625
+ * @param bn
626
+ * @private
627
+ */
628
+ static directionFactor(s, t = 0) {
629
+ let r;
630
+ return s > 30 && s <= 60 ? r = (1.7 - 0.03 * Math.pow(t - 4, 2)) / 2 : s > 60 && s <= 150 ? r = (0.9 - 0.06 * Math.pow(t - 6, 2)) / 2 : r = (0.4 - 0.03 * Math.pow(t - 8, 2)) / 2, Math.round(r * 1e5) / 1e5;
631
+ }
632
+ /**
633
+ * 失速船型因子
634
+ * 集装箱(普通裝載狀態): 0.7Bn + Bn^6.5/(22 * ∇^(2/3))
635
+ * 散货等(满载): 0.5Bn + Bn^6.5 2 /(2.7 * ∇^(2/3))
636
+ * 散货等(压载): 0.7Bn + Bn^6.5 2 /(2.7 * ∇^(2/3))
637
+ * @param displacement 排水量,m^3
638
+ * @param loadCondition
639
+ * @param tag
640
+ * @param bn
641
+ * @private
642
+ */
643
+ static vesselTagFactor(s, t, r, o = 0) {
644
+ o = o > 5 ? o - 0.9 * (o - 5) : o;
645
+ let n;
646
+ return r === "container" ? n = 0.7 * o + Math.pow(o, 6.5) / (22 * Math.pow(s, 2 / 3)) : t === "Ballast" ? n = 0.7 * o + Math.pow(o, 6.5) / (2.7 * Math.pow(s, 2 / 3)) : n = 0.5 * o + Math.pow(o, 6.5) / (2.7 * Math.pow(s, 2 / 3)), n;
647
+ }
648
+ /**
649
+ * 浪高影响因子
650
+ * @param ht 浪高,单位m
651
+ * @private
652
+ */
653
+ static waveHeightFactor(s) {
654
+ return s = s < 1.25 ? 1.25 : s, s = s > 6 ? s - 0.9 * (s - 6) : s, Math.round((-0.144 * Math.pow(s, 2) + 0.178 * s) * 1e4) / 1e4;
655
+ }
656
+ /**
657
+ * 组装船舶运行参数
658
+ * @param vessel 船舶基础档案
659
+ * @param loadCondition 装载状态
660
+ * @param speed 速度,kts
661
+ * @param bearing 方位角
662
+ * @private
663
+ */
664
+ static assembleProperties(s, t, r, o) {
665
+ var m, f;
666
+ const n = s.lbp ?? s.length ?? s.lengthOverall ?? 198.9642, a = s.draught ?? 8, e = s.breadthMoulded ?? s.breadth ?? s.breadthExtreme ?? 32.4572, c = s.deadweight ?? 67035.7773;
667
+ return {
668
+ // @ts-ignore
669
+ tag: ((f = (m = s == null ? void 0 : s.type) == null ? void 0 : m.toLowerCase()) == null ? void 0 : f.indexOf("container")) > -1 ? "container" : "common",
670
+ lbp: n,
671
+ loadCondition: t,
672
+ draught: a,
673
+ breadthMoulded: e,
674
+ // 排水量(吨)= 载重量(吨)/ 1.025 + 吃水(米)× 船舶型宽(米)× 船舶型长(米)× 0.7
675
+ // 其中,1.025是指海水的密度,吨是指公吨,吃水是指船舶的最大吃水深度。船舶型宽是指船舶的最大型宽,船舶型长是指船舶的设计型长。上述公式是针对常规船舶适用的,不同类型的船舶可能会有一些差异。
676
+ displacement: Math.round((c / 1.025 + a * e * n * 0.7) * 1e4) / 1e4,
677
+ // 换算为m/s
678
+ speed: Math.round((r ?? 14.1382) * 1852 / 3600 * 1e4) / 1e4,
679
+ bearing: o || 90
680
+ };
681
+ }
682
+ /**
683
+ * 船舶特定时间的瞬时失速样本
684
+ * @param props 船舶属性
685
+ * @param coordinate {lat: 纬度, lng: 经度, velocity: 速度(kts, 可选,指定速度) }
686
+ * @param eta 位置时间
687
+ * @param source [CMEMS, GFS, Other]
688
+ * @param role 1: 船东, 2: 租家, 0: 未知
689
+ * @param useRouteParam true 启用设置速度
690
+ */
691
+ static async speedLoseAt(s, t, r, o = "", n = 2, a = !1, e = {}) {
692
+ t.velocity && !t.noFactor && a && (s.speed = _.roundPrecision(t.velocity * 1852 / 3600, 6));
693
+ const c = await tt.queryPointFactor(t.lng, t.lat, r.valueOf(), "wind,wave,current,watertemp", o, e), i = H.weatherFactor(s, c), m = H.currentFactor(s.bearing, c == null ? void 0 : c.current, n), f = {
694
+ meteo: { ...c },
695
+ wxFactor: i,
696
+ cFactor: m,
697
+ speed: t.velocity && a ? t.velocity : Math.round((s.speed * 1.943844 + i + m) * 100) / 100,
698
+ eta: r.utc().format("YYYY-MM-DDTHH:mm[Z]"),
699
+ etd: r.utc().format("YYYY-MM-DDTHH:mm[Z]")
700
+ };
701
+ return delete t.meteo, delete t.wxFactor, delete t.cFactor, delete t.speed, delete t.etd, { ...f, ...t };
702
+ }
703
+ /**
704
+ * 基于步长计算失速样本
705
+ * @param props 船舶属性(失速模型依赖)
706
+ * @param etd 出发时间
707
+ * @param etd4Day 前行过程中动态计算加24小时的天(etd + 24 * n)
708
+ * @param hours 前行的步长(小时)
709
+ * @param distanceFromStart 与最开始起点的距离
710
+ * @param keypoints 剩下的航路点
711
+ * @param source 气象数据源: CMEMS / GFS
712
+ * @param useRouteParam true 启用航线上设置的参数 { suspend: 停留时长(小时), velocity: 速度(kts)}
713
+ * @private
714
+ */
715
+ static async speedLoseInHoursStep(s, t, r, o, n, a, e = "", c = !1, i = {}) {
716
+ t.utc();
717
+ const m = [], f = [];
718
+ let M = 0, h = 0, u, b;
719
+ for (let Y = 0; Y < a.length - 1; Y++) {
720
+ let d = a[Y];
721
+ d.distanceFromStart = n + h;
722
+ const g = a[Y + 1];
723
+ if (s.bearing = R.calculateBearing(d, g, !g.gcToPrevious), d.bearing = s.bearing, d.suspend && c) {
724
+ d.eta = d.eta || t.format("YYYY-MM-DDTHH:mm[Z]"), d.elapsed = d.elapsed ?? 0;
725
+ const k = d.suspend - d.elapsed;
726
+ if (o - M > k)
727
+ o = o - M - k, t.add(k, "hour"), d.elapsed = d.suspend;
728
+ else {
729
+ const p = o - M;
730
+ d.elapsed += p, t.add(p, "hour"), o = 0;
731
+ }
732
+ if (V.info(`[%s] suspend ${d.elapsed} hours at %j, and remain ${o} hours need to go...`, i.requestId, d), o === 0)
733
+ return d.distanceFromPrevious = h, { etd: t, from: b || d, to: d, next: a.filter((p) => p), wps: m, days: f };
734
+ }
735
+ d = await H.speedLoseAt(s, d, t, e, 0, c, i), b = b || d, d.important && m.push(d), t.isSameOrAfter(r) && (f.push(d), r.add(24, "hour"));
736
+ const l = R.calculateDistance(d, g, !g.gcToPrevious);
737
+ let v = Math.ceil(l / b.speed * 1e4) / 1e4;
738
+ if (M + v < o) {
739
+ if (M += v, t.add(v, "hour"), delete a[Y], V.info(
740
+ `[%s] go to %j from %j with ${l}nm, and cost ${v} hours`,
741
+ i.requestId,
742
+ { lat: g.lat, lng: g.lng },
743
+ { lat: b.lat, lng: b.lng, etd: b.etd }
744
+ ), h += l, a.filter((k) => k).length <= 1) {
745
+ u = g, u.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), u.distanceFromPrevious = l, u.distanceFromStart = n + h, m.push(u), delete a[Y + 1];
746
+ break;
747
+ }
748
+ } else {
749
+ v = o - M, t.add(v, "hour");
750
+ const k = _.roundPrecision(b.speed * v, 4);
751
+ u = R.calculateCoordinate(d, s.bearing, k, "nauticalmiles", !g.gcToPrevious), u.eta = t.format("YYYY-MM-DDTHH:mm[Z]"), a[Y] = u, V.info(
752
+ `[%s] go to %j from %j with ${k}nm, and cost ${v} hours`,
753
+ i.requestId,
754
+ { lat: u.lat, lng: u.lng },
755
+ { lat: d.lat, lng: d.lng, etd: d.etd }
756
+ ), h += k, u.distanceFromPrevious = h, u.distanceFromStart = n + h;
757
+ break;
758
+ }
759
+ }
760
+ return { etd: t, from: b, to: u, next: a.filter((Y) => Y), wps: m, days: f };
761
+ }
762
+ /**
763
+ * 洋流影响因子
764
+ * @param bearing 船舶航行方位角
765
+ * @param current 洋流要素
766
+ * @param role 1: 船东, 2: 租家, 0: 未知
767
+ */
768
+ static currentFactor(s, t, r = 0) {
769
+ const o = (s - (t == null ? void 0 : t.degree) || 0) / 180 * Math.PI;
770
+ if (Math.abs(o) === Math.PI / 2)
771
+ return 0;
772
+ let n = ((t == null ? void 0 : t.kts) || 0) * Math.cos(o);
773
+ return r & 2 ? n = Math.ceil(n * 100) / 100 : r & 1 ? n = Math.floor(n * 100) / 100 : n = Math.round(n * 100) / 100, Math.abs(n) > 5 ? 0 : n;
774
+ }
775
+ /**
776
+ * 风浪影响因子
777
+ * @param props 船舶档案
778
+ * @param wwc 气象要素
779
+ */
780
+ static weatherFactor(s, t) {
781
+ var f, M, h, u, b;
782
+ V.debug("calculate weather factor via: %j", { ...s, ...t });
783
+ const r = H.blockCoefficient(s.displacement, s.lbp, s.breadthMoulded, s.draught), o = H.froudeNumber(s.speed, s.lbp), n = H.amendFactor(r, o, s.loadCondition);
784
+ let a = Math.abs(s.bearing % 360 - (((f = t == null ? void 0 : t.wind) == null ? void 0 : f.degree) % 360 || 0));
785
+ a = a > 180 ? 360 - a : a;
786
+ const e = H.directionFactor(a, (M = t == null ? void 0 : t.wind) == null ? void 0 : M.scale), c = H.vesselTagFactor(s.displacement, s.loadCondition, s.tag, (h = t == null ? void 0 : t.wind) == null ? void 0 : h.scale);
787
+ let i = e * n * c / 100 * s.speed;
788
+ i = Math.round(i * 1.943844 * 1e4) / 1e4 * -1;
789
+ const m = H.waveHeightFactor(((b = (u = t == null ? void 0 : t.wave) == null ? void 0 : u.sig) == null ? void 0 : b.height) ?? 1);
790
+ return i = i * 0.24 + m * 0.76, V.debug("weather factor = %s", i), Math.round(i * 100) / 100;
791
+ }
792
+ /**
793
+ * 全程失速分析(走完航程)
794
+ * @param from 起点 {lng, lat}
795
+ * @param etd 出发时间,YYYY-MM-DDTHH:mm:ssZ
796
+ * @param vessel 船舶属性 @see VesselAssemble, 注意吃水为船舶实时吃水,非档案中的固定吃水,一般可以从ais获取; 如获取不得,用档案吃水代替
797
+ * @param cp { loadCondition, speed } LoadCondition: Ballast or Laden, speed(kts)
798
+ * @param lane 航线 { points: { route, waypoints }}
799
+ * @param source 气象数据源,GFS or CMEMES, 默认CMEMS
800
+ * @param stepHrs 样本步长, 0表示动态计算(6 or 3 hrs)
801
+ * @param useRouteParam
802
+ */
803
+ static async analyseInstant(s, t, r, o, n, a = "", e = 0, c = !1, i = {}) {
804
+ var E, q, W, z, G;
805
+ const m = y().valueOf();
806
+ s.lng = _.convertToStdLng(s.lng);
807
+ const { route: f, waypoints: M } = n.points, h = R.calculateSubRoute(s, f);
808
+ if (((E = h[0]) == null ? void 0 : E.length) <= 1)
809
+ return;
810
+ const { v0: u, label: b } = s.sog ? {
811
+ v0: s.sog,
812
+ label: "Other"
813
+ /* Instruct */
814
+ } : {
815
+ v0: o.speed,
816
+ label: "CP"
817
+ /* Cp */
818
+ }, Y = H.assembleProperties(r, o.loadCondition, u, 0), d = M.length ? R.calculateSubWaypoints(s, M) : [], g = {
819
+ from: { ...s },
820
+ route: h,
821
+ waypoints: d,
822
+ v0: u,
823
+ label: b
824
+ }, l = {
825
+ hours: [],
826
+ days: [],
827
+ wps: []
828
+ };
829
+ e || (R.calculateRouteDistance(h) / o.speed <= 72 ? e = 3 : e = 6);
830
+ let v = R.simplifyRouteToCoordinates(h, d, 0), k = 0, p = 0, x = 0, N = 0;
831
+ t = y(t).utc();
832
+ const C = t.clone();
833
+ for (; v.length > 0; ) {
834
+ const F = e - t.hour() % e, $ = Math.ceil(t.clone().add(F, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4, D = await H.speedLoseInHoursStep(Y, t, C, $, k, v, a, c, i);
835
+ (q = D.from) != null && q.speed && (l.hours.push(D.from), l.wps.push(...D.wps), l.days.push(...D.days)), v = D == null ? void 0 : D.next, v.length || l.hours.push(D == null ? void 0 : D.to), k += ((W = D == null ? void 0 : D.to) == null ? void 0 : W.distanceFromPrevious) ?? 0;
836
+ }
837
+ const T = l.hours;
838
+ for (let F = 0; F < T.length - 1; F++) {
839
+ const $ = y(T[F + 1].eta).diff(T[F].etd, "hour", !0) || 1;
840
+ p += T[F].wxFactor * $, x += T[F].cFactor * $, N += $;
841
+ }
842
+ (z = l.wps) == null || z.forEach((F, $) => {
843
+ if ($) {
844
+ const D = l.wps[$ - 1], J = F.distanceFromStart - D.distanceFromStart, U = y(F.eta).diff(y(D.etd), "h", !0);
845
+ U < 1 ? F.avgSpd = D.speed : F.avgSpd = Math.round(J / U * 100) / 100;
846
+ }
847
+ }), g.sample = l;
848
+ const w = l.hours.at(-1);
849
+ g.distance = Math.round(w.distanceFromStart * 1e4) / 1e4, g.eta = y(w.eta).toDate(), g.wxFactor = Math.round(p / N * 1e4) / 1e4, g.cFactor = Math.round(x / N * 1e4) / 1e4, g.avgSpeed = Math.round(w.distanceFromStart / N * 1e4) / 1e4, g.totalHrs = Math.round(N * 1e4) / 1e4, g.totalFoCons = Math.round((o == null ? void 0 : o.fo) / 24 * g.totalHrs * 1e3) / 1e3, g.totalDgoCons = Math.round((o == null ? void 0 : o.dgo) / 24 * g.totalHrs * 1e3) / 1e3;
850
+ const O = y().valueOf() - m, j = ((G = l == null ? void 0 : l.hours) == null ? void 0 : G.length) || 1;
851
+ return V.info("[%s] each hour-sample speed analyse cost: (%d / %d = %d) ms", i == null ? void 0 : i.requestId, O, j, Math.round(O / j * 1e3) / 1e3), g;
852
+ }
853
+ /**
854
+ * 分段失速分析(最多走hours 小时)
855
+ * @param from 起点 {lng, lat}
856
+ * @param etd 出发时间,YYYY-MM-DDTHH:mm:ssZ
857
+ * @param threshed 单次所走上限时间
858
+ * @param vessel 船舶属性 @see VesselAssemble, 注意吃水为船舶实时吃水,非档案中的固定吃水,一般可以从ais获取; 如获取不得,用档案吃水代替
859
+ * @param cp { loadCondition, speed } LoadCondition: Ballast or Laden, speed(kts)
860
+ * @param route 航路[[[lng, lat]]]
861
+ * @param source 气象数据源,GFS or CMEMES, 默认CMEMS
862
+ * @param stepHrs
863
+ */
864
+ static async analyseInstantWithThreshed(s, t, r, o, n, a, e = "", c = 3, i = !1, m = {}) {
865
+ var x, N, C;
866
+ s.lng = _.convertToStdLng(s.lng);
867
+ const f = H.assembleProperties(o, n.loadCondition, n.speed, 0), M = R.calculateSubRoute(s, a);
868
+ if (((x = M[0]) == null ? void 0 : x.length) <= 1)
869
+ return;
870
+ let h = R.simplifyRouteToCoordinates(M, [], 0), u = 0, b = 0, Y = 0, d = 0, g;
871
+ const l = {
872
+ hours: [],
873
+ days: []
874
+ };
875
+ for (t = y(t).utc(); h.length > 0; ) {
876
+ const T = c - t.hour() % c;
877
+ let w = Math.ceil(t.clone().add(T, "h").set({ minute: 0, second: 0, millisecond: 0 }).diff(t, "h", !0) * 1e4) / 1e4;
878
+ if (w = t.clone().add(w, "h").isAfter(r) ? r.diff(t, "h", !0) * 1e4 / 1e4 : w, w)
879
+ g = await H.speedLoseInHoursStep(f, t, r.clone(), w, u, h, e, i, m), (N = g.from) != null && N.speed && l.hours.push(g.from), h = g == null ? void 0 : g.next, h.length || (l.hours.push(g == null ? void 0 : g.to), l.days.push(g.to)), u += ((C = g == null ? void 0 : g.to) == null ? void 0 : C.distanceFromPrevious) ?? 0;
880
+ else {
881
+ g && (l.hours.push(g.to), l.days.push(g.to));
882
+ break;
883
+ }
884
+ }
885
+ const v = l.hours;
886
+ for (let T = 0; T < v.length - 1; T++) {
887
+ const w = y(v[T + 1].eta).diff(v[T].etd, "hour", !0);
888
+ b += v[T].wxFactor * w, Y += v[T].cFactor * w, d += w;
889
+ }
890
+ const k = l.hours.at(-1);
891
+ return {
892
+ sample: l,
893
+ distance: Math.round(((k == null ? void 0 : k.distanceFromStart) || 0) * 1e4) / 1e4,
894
+ eta: y(k == null ? void 0 : k.eta).utc().format(),
895
+ wxFactor: Math.round(b / d * 1e4) / 1e4,
896
+ cFactor: Math.round(Y / d * 1e4) / 1e4,
897
+ avgSpeed: Math.round(((k == null ? void 0 : k.distanceFromStart) || 0) / d * 1e4) / 1e4,
898
+ totalHrs: Math.round(d * 1e4) / 1e4,
899
+ to: k,
900
+ route: R.generateRouteAccordingToWaypoints(h)
901
+ };
549
902
  }
550
903
  }
551
- const Z = new L();
552
904
  export {
553
- V as AISImpl,
554
- L as AlertHelper,
555
- K as AlertLevel,
556
- J as HifleetImpl,
557
- X as MyShipImpl,
558
- U as MyVesselImpl,
559
- Q as ShipxyImpl,
560
- Z as alertHelper
905
+ Z as AISImpl,
906
+ st as AlertHelper,
907
+ et as AlertLevel,
908
+ mt as HifleetImpl,
909
+ ot as LoadCondition,
910
+ gt as MyShipImpl,
911
+ lt as MyVesselImpl,
912
+ ft as ShipxyImpl,
913
+ H as SpeedHelper,
914
+ nt as SpeedLabel,
915
+ at as VesselTag,
916
+ Mt as alertHelper
561
917
  };