@neaps/tide-predictor 0.0.5 → 0.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.
Files changed (52) hide show
  1. package/README.md +41 -48
  2. package/dist/index.cjs +931 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +150 -0
  5. package/dist/index.d.ts +150 -0
  6. package/dist/index.js +930 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +20 -36
  9. package/.eslintrc.js +0 -22
  10. package/.github/workflows/test.yml +0 -15
  11. package/.prettierrc +0 -4
  12. package/Gruntfile.js +0 -87
  13. package/LICENSE +0 -21
  14. package/babel.config.js +0 -9
  15. package/dist/tide-predictor.js +0 -1013
  16. package/examples/browser/index.html +0 -51
  17. package/jest.config.js +0 -14
  18. package/lib/astronomy/coefficients.js +0 -31
  19. package/lib/astronomy/constants.js +0 -10
  20. package/lib/astronomy/index.js +0 -199
  21. package/lib/constituents/compound-constituent.js +0 -67
  22. package/lib/constituents/constituent.js +0 -74
  23. package/lib/constituents/index.js +0 -140
  24. package/lib/harmonics/index.js +0 -113
  25. package/lib/harmonics/prediction.js +0 -195
  26. package/lib/index.es6.js +0 -1005
  27. package/lib/index.js +0 -53
  28. package/lib/node-corrections/index.js +0 -147
  29. package/rollup.config.js +0 -21
  30. package/src/__mocks__/constituents.js +0 -335
  31. package/src/__mocks__/secondary-station.js +0 -11
  32. package/src/__tests__/index.js +0 -81
  33. package/src/__tests__/noaa.js +0 -92
  34. package/src/astronomy/__tests__/coefficients.js +0 -12
  35. package/src/astronomy/__tests__/index.js +0 -96
  36. package/src/astronomy/coefficients.js +0 -72
  37. package/src/astronomy/constants.js +0 -4
  38. package/src/astronomy/index.js +0 -201
  39. package/src/constituents/__tests__/compound-constituent.js +0 -44
  40. package/src/constituents/__tests__/constituent.js +0 -65
  41. package/src/constituents/__tests__/index.js +0 -34
  42. package/src/constituents/compound-constituent.js +0 -55
  43. package/src/constituents/constituent.js +0 -74
  44. package/src/constituents/index.js +0 -119
  45. package/src/harmonics/__mocks__/water-levels.js +0 -0
  46. package/src/harmonics/__tests__/index.js +0 -123
  47. package/src/harmonics/__tests__/prediction.js +0 -148
  48. package/src/harmonics/index.js +0 -87
  49. package/src/harmonics/prediction.js +0 -175
  50. package/src/index.js +0 -45
  51. package/src/node-corrections/__tests__/index.js +0 -114
  52. package/src/node-corrections/index.js +0 -208
package/dist/index.js ADDED
@@ -0,0 +1,930 @@
1
+ //#region src/astronomy/constants.ts
2
+ const d2r = Math.PI / 180;
3
+ const r2d = 180 / Math.PI;
4
+
5
+ //#endregion
6
+ //#region src/astronomy/coefficients.ts
7
+ const sexagesimalToDecimal = (degrees, arcmins = 0, arcsecs = 0, mas = 0, muas = 0) => {
8
+ return degrees + arcmins / 60 + arcsecs / 3600 + mas / (3600 * 1e3) + muas / (3600 * 1e6);
9
+ };
10
+ const coefficients = {
11
+ terrestrialObliquity: [
12
+ sexagesimalToDecimal(23, 26, 21.448),
13
+ -sexagesimalToDecimal(0, 0, 4680.93),
14
+ -sexagesimalToDecimal(0, 0, 1.55),
15
+ sexagesimalToDecimal(0, 0, 1999.25),
16
+ -sexagesimalToDecimal(0, 0, 51.38),
17
+ -sexagesimalToDecimal(0, 0, 249.67),
18
+ -sexagesimalToDecimal(0, 0, 39.05),
19
+ sexagesimalToDecimal(0, 0, 7.12),
20
+ sexagesimalToDecimal(0, 0, 27.87),
21
+ sexagesimalToDecimal(0, 0, 5.79),
22
+ sexagesimalToDecimal(0, 0, 2.45)
23
+ ].map((number, index) => {
24
+ return number * Math.pow(.01, index);
25
+ }),
26
+ solarPerigee: [
27
+ -77.06265000000002,
28
+ 1.7190199999968172,
29
+ 4591e-7,
30
+ 48e-8
31
+ ],
32
+ solarLongitude: [
33
+ 280.46645,
34
+ 36000.76983,
35
+ 3032e-7
36
+ ],
37
+ lunarInclination: [5.145],
38
+ lunarLongitude: [
39
+ 218.3164591,
40
+ 481267.88134236,
41
+ -.0013268,
42
+ 1 / 538841 - 1 / 65194e3
43
+ ],
44
+ lunarNode: [
45
+ 125.044555,
46
+ -1934.1361849,
47
+ .0020762,
48
+ 1 / 467410,
49
+ -1 / 60616e3
50
+ ],
51
+ lunarPerigee: [
52
+ 83.353243,
53
+ 4069.0137111,
54
+ -.0103238,
55
+ -1 / 80053,
56
+ 1 / 18999e3
57
+ ]
58
+ };
59
+ var coefficients_default = coefficients;
60
+
61
+ //#endregion
62
+ //#region src/astronomy/index.ts
63
+ const polynomial = (coefficients$1, argument) => {
64
+ const result = [];
65
+ coefficients$1.forEach((coefficient, index) => {
66
+ result.push(coefficient * Math.pow(argument, index));
67
+ });
68
+ return result.reduce((a, b) => a + b);
69
+ };
70
+ const derivativePolynomial = (coefficients$1, argument) => {
71
+ const result = [];
72
+ coefficients$1.forEach((coefficient, index) => {
73
+ result.push(coefficient * index * Math.pow(argument, index - 1));
74
+ });
75
+ return result.reduce((a, b) => a + b);
76
+ };
77
+ const T = (t) => {
78
+ return (JD(t) - 2451545) / 36525;
79
+ };
80
+ const JD = (t) => {
81
+ let Y = t.getFullYear();
82
+ let M = t.getMonth() + 1;
83
+ const D = t.getDate() + t.getHours() / 24 + t.getMinutes() / 1440 + t.getSeconds() / (1440 * 60) + t.getMilliseconds() / (1440 * 60 * 1e6);
84
+ if (M <= 2) {
85
+ Y = Y - 1;
86
+ M = M + 12;
87
+ }
88
+ const A = Math.floor(Y / 100);
89
+ const B = 2 - A + Math.floor(A / 4);
90
+ return Math.floor(365.25 * (Y + 4716)) + Math.floor(30.6001 * (M + 1)) + D + B - 1524.5;
91
+ };
92
+ const _I = (N, i, omega) => {
93
+ N = d2r * N;
94
+ i = d2r * i;
95
+ omega = d2r * omega;
96
+ const cosI = Math.cos(i) * Math.cos(omega) - Math.sin(i) * Math.sin(omega) * Math.cos(N);
97
+ return r2d * Math.acos(cosI);
98
+ };
99
+ const _xi = (N, i, omega) => {
100
+ N = d2r * N;
101
+ i = d2r * i;
102
+ omega = d2r * omega;
103
+ let e1 = Math.cos(.5 * (omega - i)) / Math.cos(.5 * (omega + i)) * Math.tan(.5 * N);
104
+ let e2 = Math.sin(.5 * (omega - i)) / Math.sin(.5 * (omega + i)) * Math.tan(.5 * N);
105
+ e1 = Math.atan(e1);
106
+ e2 = Math.atan(e2);
107
+ e1 = e1 - .5 * N;
108
+ e2 = e2 - .5 * N;
109
+ return -(e1 + e2) * r2d;
110
+ };
111
+ const _nu = (N, i, omega) => {
112
+ N = d2r * N;
113
+ i = d2r * i;
114
+ omega = d2r * omega;
115
+ let e1 = Math.cos(.5 * (omega - i)) / Math.cos(.5 * (omega + i)) * Math.tan(.5 * N);
116
+ let e2 = Math.sin(.5 * (omega - i)) / Math.sin(.5 * (omega + i)) * Math.tan(.5 * N);
117
+ e1 = Math.atan(e1);
118
+ e2 = Math.atan(e2);
119
+ e1 = e1 - .5 * N;
120
+ e2 = e2 - .5 * N;
121
+ return (e1 - e2) * r2d;
122
+ };
123
+ const _nup = (N, i, omega) => {
124
+ const I = d2r * _I(N, i, omega);
125
+ const nu = d2r * _nu(N, i, omega);
126
+ return r2d * Math.atan(Math.sin(2 * I) * Math.sin(nu) / (Math.sin(2 * I) * Math.cos(nu) + .3347));
127
+ };
128
+ const _nupp = (N, i, omega) => {
129
+ const I = d2r * _I(N, i, omega);
130
+ const nu = d2r * _nu(N, i, omega);
131
+ const tan2nupp = Math.sin(I) ** 2 * Math.sin(2 * nu) / (Math.sin(I) ** 2 * Math.cos(2 * nu) + .0727);
132
+ return r2d * .5 * Math.atan(tan2nupp);
133
+ };
134
+ const modulus$1 = (a, b) => {
135
+ return (a % b + b) % b;
136
+ };
137
+ const astro = (time) => {
138
+ const result = {};
139
+ const polynomials = {
140
+ s: coefficients_default.lunarLongitude,
141
+ h: coefficients_default.solarLongitude,
142
+ p: coefficients_default.lunarPerigee,
143
+ N: coefficients_default.lunarNode,
144
+ pp: coefficients_default.solarPerigee,
145
+ "90": [90],
146
+ omega: coefficients_default.terrestrialObliquity,
147
+ i: coefficients_default.lunarInclination
148
+ };
149
+ const dTdHour = 1 / (24 * 365.25 * 100);
150
+ for (const name in polynomials) result[name] = {
151
+ value: modulus$1(polynomial(polynomials[name], T(time)), 360),
152
+ speed: derivativePolynomial(polynomials[name], T(time)) * dTdHour
153
+ };
154
+ const functions = {
155
+ I: _I,
156
+ xi: _xi,
157
+ nu: _nu,
158
+ nup: _nup,
159
+ nupp: _nupp
160
+ };
161
+ Object.keys(functions).forEach((name) => {
162
+ const functionCall = functions[name];
163
+ result[name] = {
164
+ value: modulus$1(functionCall(result.N.value, result.i.value, result.omega.value), 360),
165
+ speed: null
166
+ };
167
+ });
168
+ const hour = {
169
+ value: (JD(time) - Math.floor(JD(time))) * 360,
170
+ speed: 15
171
+ };
172
+ result["T+h-s"] = {
173
+ value: hour.value + result.h.value - result.s.value,
174
+ speed: hour.speed + result.h.speed - result.s.speed
175
+ };
176
+ result.P = {
177
+ value: result.p.value - result.xi.value % 360,
178
+ speed: null
179
+ };
180
+ return result;
181
+ };
182
+ var astronomy_default = astro;
183
+
184
+ //#endregion
185
+ //#region src/harmonics/prediction.ts
186
+ const modulus = (a, b) => {
187
+ return (a % b + b) % b;
188
+ };
189
+ const addExtremesOffsets = (extreme, offsets) => {
190
+ if (typeof offsets === "undefined" || !offsets) return extreme;
191
+ if (extreme.high && offsets.height?.high) if (offsets.height.type === "fixed") extreme.level += offsets.height.high;
192
+ else extreme.level *= offsets.height.high;
193
+ if (extreme.low && offsets.height?.low) if (offsets.height.type === "fixed") extreme.level += offsets.height.low;
194
+ else extreme.level *= offsets.height.low;
195
+ if (extreme.high && offsets.time?.high) extreme.time = new Date(extreme.time.getTime() + offsets.time.high * 60 * 1e3);
196
+ if (extreme.low && offsets.time?.low) extreme.time = new Date(extreme.time.getTime() + offsets.time.low * 60 * 1e3);
197
+ return extreme;
198
+ };
199
+ const getExtremeLabel = (label, highLowLabels) => {
200
+ if (typeof highLowLabels !== "undefined" && typeof highLowLabels[label] !== "undefined") return highLowLabels[label];
201
+ return {
202
+ high: "High",
203
+ low: "Low"
204
+ }[label];
205
+ };
206
+ const predictionFactory = ({ timeline, constituents: constituents$1, start }) => {
207
+ const getLevel = (hour, modelBaseSpeed, modelU, modelF, modelBaseValue) => {
208
+ const amplitudes = [];
209
+ let result = 0;
210
+ constituents$1.forEach((constituent) => {
211
+ const amplitude = constituent.amplitude;
212
+ const phase = constituent._phase;
213
+ const f = modelF[constituent.name];
214
+ const speed = modelBaseSpeed[constituent.name];
215
+ const u = modelU[constituent.name];
216
+ const V0 = modelBaseValue[constituent.name];
217
+ amplitudes.push(amplitude * f * Math.cos(speed * hour + (V0 + u) - phase));
218
+ });
219
+ amplitudes.forEach((item) => {
220
+ result += item;
221
+ });
222
+ return result;
223
+ };
224
+ const prediction = {};
225
+ prediction.getExtremesPrediction = (options) => {
226
+ const { labels, offsets } = typeof options !== "undefined" ? options : {};
227
+ const results = [];
228
+ const { baseSpeed, u, f, baseValue } = prepare();
229
+ let goingUp = false;
230
+ let goingDown = false;
231
+ let lastLevel = getLevel(0, baseSpeed, u[0], f[0], baseValue);
232
+ timeline.items.forEach((time, index) => {
233
+ const hour = timeline.hours[index];
234
+ const level = getLevel(hour, baseSpeed, u[index], f[index], baseValue);
235
+ if (level > lastLevel && goingDown) results.push(addExtremesOffsets({
236
+ time: timeline.items[index - 1],
237
+ level: lastLevel,
238
+ high: false,
239
+ low: true,
240
+ label: getExtremeLabel("low", labels)
241
+ }, offsets));
242
+ if (level < lastLevel && goingUp) results.push(addExtremesOffsets({
243
+ time: timeline.items[index - 1],
244
+ level: lastLevel,
245
+ high: true,
246
+ low: false,
247
+ label: getExtremeLabel("high", labels)
248
+ }, offsets));
249
+ if (level > lastLevel) {
250
+ goingUp = true;
251
+ goingDown = false;
252
+ }
253
+ if (level < lastLevel) {
254
+ goingUp = false;
255
+ goingDown = true;
256
+ }
257
+ lastLevel = level;
258
+ });
259
+ return results;
260
+ };
261
+ prediction.getTimelinePrediction = () => {
262
+ const results = [];
263
+ const { baseSpeed, u, f, baseValue } = prepare();
264
+ timeline.items.forEach((time, index) => {
265
+ const hour = timeline.hours[index];
266
+ const prediction$1 = {
267
+ time,
268
+ hour,
269
+ level: getLevel(hour, baseSpeed, u[index], f[index], baseValue)
270
+ };
271
+ results.push(prediction$1);
272
+ });
273
+ return results;
274
+ };
275
+ const prepare = () => {
276
+ const baseAstro = astronomy_default(start);
277
+ const baseValue = {};
278
+ const baseSpeed = {};
279
+ const u = [];
280
+ const f = [];
281
+ constituents$1.forEach((constituent) => {
282
+ const value = constituent._model.value(baseAstro);
283
+ const speed = constituent._model.speed(baseAstro);
284
+ baseValue[constituent.name] = d2r * value;
285
+ baseSpeed[constituent.name] = d2r * speed;
286
+ });
287
+ timeline.items.forEach((time) => {
288
+ const uItem = {};
289
+ const fItem = {};
290
+ const itemAstro = astronomy_default(time);
291
+ constituents$1.forEach((constituent) => {
292
+ const constituentU = modulus(constituent._model.u(itemAstro), 360);
293
+ uItem[constituent.name] = d2r * constituentU;
294
+ fItem[constituent.name] = modulus(constituent._model.f(itemAstro), 360);
295
+ });
296
+ u.push(uItem);
297
+ f.push(fItem);
298
+ });
299
+ return {
300
+ baseValue,
301
+ baseSpeed,
302
+ u,
303
+ f
304
+ };
305
+ };
306
+ return Object.freeze(prediction);
307
+ };
308
+ var prediction_default = predictionFactory;
309
+
310
+ //#endregion
311
+ //#region src/node-corrections/index.ts
312
+ const corrections = {
313
+ fUnity() {
314
+ return 1;
315
+ },
316
+ fMm(a) {
317
+ const omega = d2r * a.omega.value;
318
+ const i = d2r * a.i.value;
319
+ const I = d2r * a.I.value;
320
+ const mean = (2 / 3 - Math.pow(Math.sin(omega), 2)) * (1 - 3 / 2 * Math.pow(Math.sin(i), 2));
321
+ return (2 / 3 - Math.pow(Math.sin(I), 2)) / mean;
322
+ },
323
+ fMf(a) {
324
+ const omega = d2r * a.omega.value;
325
+ const i = d2r * a.i.value;
326
+ const I = d2r * a.I.value;
327
+ const mean = Math.pow(Math.sin(omega), 2) * Math.pow(Math.cos(.5 * i), 4);
328
+ return Math.pow(Math.sin(I), 2) / mean;
329
+ },
330
+ fO1(a) {
331
+ const omega = d2r * a.omega.value;
332
+ const i = d2r * a.i.value;
333
+ const I = d2r * a.I.value;
334
+ const mean = Math.sin(omega) * Math.pow(Math.cos(.5 * omega), 2) * Math.pow(Math.cos(.5 * i), 4);
335
+ return Math.sin(I) * Math.pow(Math.cos(.5 * I), 2) / mean;
336
+ },
337
+ fJ1(a) {
338
+ const omega = d2r * a.omega.value;
339
+ const i = d2r * a.i.value;
340
+ const I = d2r * a.I.value;
341
+ const mean = Math.sin(2 * omega) * (1 - 3 / 2 * Math.pow(Math.sin(i), 2));
342
+ return Math.sin(2 * I) / mean;
343
+ },
344
+ fOO1(a) {
345
+ const omega = d2r * a.omega.value;
346
+ const i = d2r * a.i.value;
347
+ const I = d2r * a.I.value;
348
+ const mean = Math.sin(omega) * Math.pow(Math.sin(.5 * omega), 2) * Math.pow(Math.cos(.5 * i), 4);
349
+ return Math.sin(I) * Math.pow(Math.sin(.5 * I), 2) / mean;
350
+ },
351
+ fM2(a) {
352
+ const omega = d2r * a.omega.value;
353
+ const i = d2r * a.i.value;
354
+ const I = d2r * a.I.value;
355
+ const mean = Math.pow(Math.cos(.5 * omega), 4) * Math.pow(Math.cos(.5 * i), 4);
356
+ return Math.pow(Math.cos(.5 * I), 4) / mean;
357
+ },
358
+ fK1(a) {
359
+ const omega = d2r * a.omega.value;
360
+ const i = d2r * a.i.value;
361
+ const I = d2r * a.I.value;
362
+ const nu = d2r * a.nu.value;
363
+ const mean = .5023 * (Math.sin(2 * omega) * (1 - 3 / 2 * Math.pow(Math.sin(i), 2))) + .1681;
364
+ return Math.pow(.2523 * Math.pow(Math.sin(2 * I), 2) + .1689 * Math.sin(2 * I) * Math.cos(nu) + .0283, .5) / mean;
365
+ },
366
+ fL2(a) {
367
+ const P = d2r * a.P.value;
368
+ const I = d2r * a.I.value;
369
+ const rAInv = Math.pow(1 - 12 * Math.pow(Math.tan(.5 * I), 2) * Math.cos(2 * P) + 36 * Math.pow(Math.tan(.5 * I), 4), .5);
370
+ return corrections.fM2(a) * rAInv;
371
+ },
372
+ fK2(a) {
373
+ const omega = d2r * a.omega.value;
374
+ const i = d2r * a.i.value;
375
+ const I = d2r * a.I.value;
376
+ const nu = d2r * a.nu.value;
377
+ const mean = .5023 * (Math.sin(omega) ** 2 * (1 - 3 / 2 * Math.sin(i) ** 2)) + .0365;
378
+ return Math.pow(.2523 * Math.pow(Math.sin(I), 4) + .0367 * Math.pow(Math.sin(I), 2) * Math.cos(2 * nu) + .0013, .5) / mean;
379
+ },
380
+ fM1(a) {
381
+ const P = d2r * a.P.value;
382
+ const I = d2r * a.I.value;
383
+ const qAInv = Math.pow(.25 + 1.5 * Math.cos(I) * Math.cos(2 * P) * Math.pow(Math.cos(.5 * I), -.5) + 2.25 * Math.pow(Math.cos(I), 2) * Math.pow(Math.cos(.5 * I), -4), .5);
384
+ return corrections.fO1(a) * qAInv;
385
+ },
386
+ fModd(a, n) {
387
+ return Math.pow(corrections.fM2(a), n / 2);
388
+ },
389
+ uZero() {
390
+ return 0;
391
+ },
392
+ uMf(a) {
393
+ return -2 * a.xi.value;
394
+ },
395
+ uO1(a) {
396
+ return 2 * a.xi.value - a.nu.value;
397
+ },
398
+ uJ1(a) {
399
+ return -a.nu.value;
400
+ },
401
+ uOO1(a) {
402
+ return -2 * a.xi.value - a.nu.value;
403
+ },
404
+ uM2(a) {
405
+ return 2 * a.xi.value - 2 * a.nu.value;
406
+ },
407
+ uK1(a) {
408
+ return -a.nup.value;
409
+ },
410
+ uL2(a) {
411
+ const I = d2r * a.I.value;
412
+ const P = d2r * a.P.value;
413
+ const R = r2d * Math.atan(Math.sin(2 * P) / (1 / 6 * Math.pow(Math.tan(.5 * I), -2) - Math.cos(2 * P)));
414
+ return 2 * a.xi.value - 2 * a.nu.value - R;
415
+ },
416
+ uK2(a) {
417
+ return -2 * a.nupp.value;
418
+ },
419
+ uM1(a) {
420
+ const I = d2r * a.I.value;
421
+ const P = d2r * a.P.value;
422
+ const Q = r2d * Math.atan((5 * Math.cos(I) - 1) / (7 * Math.cos(I) + 1) * Math.tan(P));
423
+ return a.xi.value - a.nu.value + Q;
424
+ },
425
+ uModd(a, n) {
426
+ return n / 2 * corrections.uM2(a);
427
+ }
428
+ };
429
+ var node_corrections_default = corrections;
430
+
431
+ //#endregion
432
+ //#region src/constituents/constituent.ts
433
+ /**
434
+ * Computes the dot notation of two arrays
435
+ */
436
+ const dotArray = (a, b) => {
437
+ const results = [];
438
+ a.forEach((value, index) => {
439
+ results.push(value * b[index]);
440
+ });
441
+ return results.reduce((total, value) => total + value);
442
+ };
443
+ const astronimicDoodsonNumber = (astro$1) => {
444
+ return [
445
+ astro$1["T+h-s"],
446
+ astro$1.s,
447
+ astro$1.h,
448
+ astro$1.p,
449
+ astro$1.N,
450
+ astro$1.pp,
451
+ astro$1["90"]
452
+ ];
453
+ };
454
+ const astronomicSpeed = (astro$1) => {
455
+ const results = [];
456
+ astronimicDoodsonNumber(astro$1).forEach((number) => {
457
+ results.push(number.speed);
458
+ });
459
+ return results;
460
+ };
461
+ const astronomicValues = (astro$1) => {
462
+ const results = [];
463
+ astronimicDoodsonNumber(astro$1).forEach((number) => {
464
+ results.push(number.value);
465
+ });
466
+ return results;
467
+ };
468
+ const constituentFactory = (name, coefficients$1, u, f) => {
469
+ if (!coefficients$1) throw new Error("Coefficient must be defined for a constituent");
470
+ const constituent = {
471
+ name,
472
+ coefficients: coefficients$1,
473
+ value: (astro$1) => {
474
+ return dotArray(coefficients$1, astronomicValues(astro$1));
475
+ },
476
+ speed(astro$1) {
477
+ return dotArray(coefficients$1, astronomicSpeed(astro$1));
478
+ },
479
+ u: typeof u !== "undefined" ? u : node_corrections_default.uZero,
480
+ f: typeof f !== "undefined" ? f : node_corrections_default.fUnity
481
+ };
482
+ return Object.freeze(constituent);
483
+ };
484
+ var constituent_default = constituentFactory;
485
+
486
+ //#endregion
487
+ //#region src/constituents/compound-constituent.ts
488
+ const compoundConstituentFactory = (name, members) => {
489
+ const coefficients$1 = [];
490
+ members.forEach(({ constituent, factor }) => {
491
+ constituent.coefficients.forEach((coefficient, index) => {
492
+ if (typeof coefficients$1[index] === "undefined") coefficients$1[index] = 0;
493
+ coefficients$1[index] += coefficient * factor;
494
+ });
495
+ });
496
+ const compoundConstituent = {
497
+ name,
498
+ coefficients: coefficients$1,
499
+ speed: (astro$1) => {
500
+ let speed = 0;
501
+ members.forEach(({ constituent, factor }) => {
502
+ speed += constituent.speed(astro$1) * factor;
503
+ });
504
+ return speed;
505
+ },
506
+ value: (astro$1) => {
507
+ let value = 0;
508
+ members.forEach(({ constituent, factor }) => {
509
+ value += constituent.value(astro$1) * factor;
510
+ });
511
+ return value;
512
+ },
513
+ u: (astro$1) => {
514
+ let u = 0;
515
+ members.forEach(({ constituent, factor }) => {
516
+ u += constituent.u(astro$1) * factor;
517
+ });
518
+ return u;
519
+ },
520
+ f: (astro$1) => {
521
+ const f = [];
522
+ members.forEach(({ constituent, factor }) => {
523
+ f.push(Math.pow(constituent.f(astro$1), Math.abs(factor)));
524
+ });
525
+ return f.reduce((previous, value) => previous * value);
526
+ }
527
+ };
528
+ return Object.freeze(compoundConstituent);
529
+ };
530
+ var compound_constituent_default = compoundConstituentFactory;
531
+
532
+ //#endregion
533
+ //#region src/constituents/index.ts
534
+ const constituents = {};
535
+ constituents.Z0 = constituent_default("Z0", [
536
+ 0,
537
+ 0,
538
+ 0,
539
+ 0,
540
+ 0,
541
+ 0,
542
+ 0
543
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
544
+ constituents.SA = constituent_default("Sa", [
545
+ 0,
546
+ 0,
547
+ 1,
548
+ 0,
549
+ 0,
550
+ 0,
551
+ 0
552
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
553
+ constituents.SSA = constituent_default("Ssa", [
554
+ 0,
555
+ 0,
556
+ 2,
557
+ 0,
558
+ 0,
559
+ 0,
560
+ 0
561
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
562
+ constituents.MM = constituent_default("MM", [
563
+ 0,
564
+ 1,
565
+ 0,
566
+ -1,
567
+ 0,
568
+ 0,
569
+ 0
570
+ ], node_corrections_default.uZero, node_corrections_default.fMm);
571
+ constituents.MF = constituent_default("MF", [
572
+ 0,
573
+ 2,
574
+ 0,
575
+ 0,
576
+ 0,
577
+ 0,
578
+ 0
579
+ ], node_corrections_default.uMf, node_corrections_default.fMf);
580
+ constituents.Q1 = constituent_default("Q1", [
581
+ 1,
582
+ -2,
583
+ 0,
584
+ 1,
585
+ 0,
586
+ 0,
587
+ 1
588
+ ], node_corrections_default.uO1, node_corrections_default.fO1);
589
+ constituents.O1 = constituent_default("O1", [
590
+ 1,
591
+ -1,
592
+ 0,
593
+ 0,
594
+ 0,
595
+ 0,
596
+ 1
597
+ ], node_corrections_default.uO1, node_corrections_default.fO1);
598
+ constituents.K1 = constituent_default("K1", [
599
+ 1,
600
+ 1,
601
+ 0,
602
+ 0,
603
+ 0,
604
+ 0,
605
+ -1
606
+ ], node_corrections_default.uK1, node_corrections_default.fK1);
607
+ constituents.J1 = constituent_default("J1", [
608
+ 1,
609
+ 2,
610
+ 0,
611
+ -1,
612
+ 0,
613
+ 0,
614
+ -1
615
+ ], node_corrections_default.uJ1, node_corrections_default.fJ1);
616
+ constituents.M1 = constituent_default("M1", [
617
+ 1,
618
+ 0,
619
+ 0,
620
+ 0,
621
+ 0,
622
+ 0,
623
+ 1
624
+ ], node_corrections_default.uM1, node_corrections_default.fM1);
625
+ constituents.P1 = constituent_default("P1", [
626
+ 1,
627
+ 1,
628
+ -2,
629
+ 0,
630
+ 0,
631
+ 0,
632
+ 1
633
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
634
+ constituents.S1 = constituent_default("S1", [
635
+ 1,
636
+ 1,
637
+ -1,
638
+ 0,
639
+ 0,
640
+ 0,
641
+ 0
642
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
643
+ constituents.OO1 = constituent_default("OO1", [
644
+ 1,
645
+ 3,
646
+ 0,
647
+ 0,
648
+ 0,
649
+ 0,
650
+ -1
651
+ ], node_corrections_default.uOO1, node_corrections_default.fOO1);
652
+ constituents["2N2"] = constituent_default("2N2", [
653
+ 2,
654
+ -2,
655
+ 0,
656
+ 2,
657
+ 0,
658
+ 0,
659
+ 0
660
+ ], node_corrections_default.uM2, node_corrections_default.fM2);
661
+ constituents.N2 = constituent_default("N2", [
662
+ 2,
663
+ -1,
664
+ 0,
665
+ 1,
666
+ 0,
667
+ 0,
668
+ 0
669
+ ], node_corrections_default.uM2, node_corrections_default.fM2);
670
+ constituents.NU2 = constituent_default("NU2", [
671
+ 2,
672
+ -1,
673
+ 2,
674
+ -1,
675
+ 0,
676
+ 0,
677
+ 0
678
+ ], node_corrections_default.uM2, node_corrections_default.fM2);
679
+ constituents.M2 = constituent_default("M2", [
680
+ 2,
681
+ 0,
682
+ 0,
683
+ 0,
684
+ 0,
685
+ 0,
686
+ 0
687
+ ], node_corrections_default.uM2, node_corrections_default.fM2);
688
+ constituents.LAM2 = constituent_default("LAM2", [
689
+ 2,
690
+ 1,
691
+ -2,
692
+ 1,
693
+ 0,
694
+ 0,
695
+ 2
696
+ ], node_corrections_default.uM2, node_corrections_default.fM2);
697
+ constituents.L2 = constituent_default("L2", [
698
+ 2,
699
+ 1,
700
+ 0,
701
+ -1,
702
+ 0,
703
+ 0,
704
+ 2
705
+ ], node_corrections_default.uL2, node_corrections_default.fL2);
706
+ constituents.T2 = constituent_default("T2", [
707
+ 2,
708
+ 2,
709
+ -3,
710
+ 0,
711
+ 0,
712
+ 1,
713
+ 0
714
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
715
+ constituents.S2 = constituent_default("S2", [
716
+ 2,
717
+ 2,
718
+ -2,
719
+ 0,
720
+ 0,
721
+ 0,
722
+ 0
723
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
724
+ constituents.R2 = constituent_default("R2", [
725
+ 2,
726
+ 2,
727
+ -1,
728
+ 0,
729
+ 0,
730
+ -1,
731
+ 2
732
+ ], node_corrections_default.uZero, node_corrections_default.fUnity);
733
+ constituents.K2 = constituent_default("K2", [
734
+ 2,
735
+ 2,
736
+ 0,
737
+ 0,
738
+ 0,
739
+ 0,
740
+ 0
741
+ ], node_corrections_default.uK2, node_corrections_default.fK2);
742
+ constituents.M3 = constituent_default("M3", [
743
+ 3,
744
+ 0,
745
+ 0,
746
+ 0,
747
+ 0,
748
+ 0,
749
+ 0
750
+ ], (a) => {
751
+ return node_corrections_default.uModd(a, 3);
752
+ }, (a) => {
753
+ return node_corrections_default.fModd(a, 3);
754
+ });
755
+ constituents.MSF = compound_constituent_default("MSF", [{
756
+ constituent: constituents.S2,
757
+ factor: 1
758
+ }, {
759
+ constituent: constituents.M2,
760
+ factor: -1
761
+ }]);
762
+ constituents["2Q1"] = compound_constituent_default("2Q1", [{
763
+ constituent: constituents.N2,
764
+ factor: 1
765
+ }, {
766
+ constituent: constituents.J1,
767
+ factor: -1
768
+ }]);
769
+ constituents.RHO = compound_constituent_default("RHO", [{
770
+ constituent: constituents.NU2,
771
+ factor: 1
772
+ }, {
773
+ constituent: constituents.K1,
774
+ factor: -1
775
+ }]);
776
+ constituents.MU2 = compound_constituent_default("MU2", [{
777
+ constituent: constituents.M2,
778
+ factor: 2
779
+ }, {
780
+ constituent: constituents.S2,
781
+ factor: -1
782
+ }]);
783
+ constituents["2SM2"] = compound_constituent_default("2SM2", [{
784
+ constituent: constituents.S2,
785
+ factor: 2
786
+ }, {
787
+ constituent: constituents.M2,
788
+ factor: -1
789
+ }]);
790
+ constituents["2MK3"] = compound_constituent_default("2MK3", [{
791
+ constituent: constituents.M2,
792
+ factor: 1
793
+ }, {
794
+ constituent: constituents.O1,
795
+ factor: 1
796
+ }]);
797
+ constituents.MK3 = compound_constituent_default("MK3", [{
798
+ constituent: constituents.M2,
799
+ factor: 1
800
+ }, {
801
+ constituent: constituents.K1,
802
+ factor: 1
803
+ }]);
804
+ constituents.MN4 = compound_constituent_default("MN4", [{
805
+ constituent: constituents.M2,
806
+ factor: 1
807
+ }, {
808
+ constituent: constituents.N2,
809
+ factor: 1
810
+ }]);
811
+ constituents.M4 = compound_constituent_default("M4", [{
812
+ constituent: constituents.M2,
813
+ factor: 2
814
+ }]);
815
+ constituents.MS4 = compound_constituent_default("MS4", [{
816
+ constituent: constituents.M2,
817
+ factor: 1
818
+ }, {
819
+ constituent: constituents.S2,
820
+ factor: 1
821
+ }]);
822
+ constituents.S4 = compound_constituent_default("S4", [{
823
+ constituent: constituents.S2,
824
+ factor: 2
825
+ }]);
826
+ constituents.M6 = compound_constituent_default("M6", [{
827
+ constituent: constituents.M2,
828
+ factor: 3
829
+ }]);
830
+ constituents.S6 = compound_constituent_default("S6", [{
831
+ constituent: constituents.S2,
832
+ factor: 3
833
+ }]);
834
+ constituents.M8 = compound_constituent_default("M8", [{
835
+ constituent: constituents.M2,
836
+ factor: 4
837
+ }]);
838
+ var constituents_default = constituents;
839
+
840
+ //#endregion
841
+ //#region src/harmonics/index.ts
842
+ const getDate = (time) => {
843
+ if (time instanceof Date) return time;
844
+ if (typeof time === "number") return /* @__PURE__ */ new Date(time * 1e3);
845
+ throw new Error("Invalid date format, should be a Date object, or timestamp");
846
+ };
847
+ const getTimeline = (start, end, seconds = 600) => {
848
+ const items = [];
849
+ const endTime = end.getTime() / 1e3;
850
+ let lastTime = start.getTime() / 1e3;
851
+ const startTime = lastTime;
852
+ const hours = [];
853
+ while (lastTime <= endTime) {
854
+ items.push(/* @__PURE__ */ new Date(lastTime * 1e3));
855
+ hours.push((lastTime - startTime) / 3600);
856
+ lastTime += seconds;
857
+ }
858
+ return {
859
+ items,
860
+ hours
861
+ };
862
+ };
863
+ const harmonicsFactory = ({ harmonicConstituents, phaseKey, offset }) => {
864
+ if (!Array.isArray(harmonicConstituents)) throw new Error("Harmonic constituents are not an array");
865
+ const constituents$1 = [];
866
+ harmonicConstituents.forEach((constituent) => {
867
+ if (typeof constituent.name === "undefined") throw new Error("Harmonic constituents must have a name property");
868
+ if (constituents_default[constituent.name] !== void 0) constituents$1.push({
869
+ ...constituent,
870
+ _model: constituents_default[constituent.name],
871
+ _phase: d2r * constituent[phaseKey]
872
+ });
873
+ });
874
+ if (offset !== false) constituents$1.push({
875
+ name: "Z0",
876
+ _model: constituents_default.Z0,
877
+ _phase: 0,
878
+ amplitude: offset
879
+ });
880
+ let start = /* @__PURE__ */ new Date();
881
+ let end = /* @__PURE__ */ new Date();
882
+ const harmonics = {};
883
+ harmonics.setTimeSpan = (startTime, endTime) => {
884
+ start = getDate(startTime);
885
+ end = getDate(endTime);
886
+ if (start.getTime() >= end.getTime()) throw new Error("Start time must be before end time");
887
+ return harmonics;
888
+ };
889
+ harmonics.prediction = (options) => {
890
+ return prediction_default({
891
+ timeline: getTimeline(start, end, (typeof options !== "undefined" ? options : { timeFidelity: 600 }).timeFidelity),
892
+ constituents: constituents$1,
893
+ start
894
+ });
895
+ };
896
+ return Object.freeze(harmonics);
897
+ };
898
+ var harmonics_default = harmonicsFactory;
899
+
900
+ //#endregion
901
+ //#region src/index.ts
902
+ const tidePredictionFactory = (constituents$1, options = {}) => {
903
+ const harmonicsOptions = {
904
+ harmonicConstituents: constituents$1,
905
+ phaseKey: "phase_GMT",
906
+ offset: false,
907
+ ...options
908
+ };
909
+ return {
910
+ getTimelinePrediction: ({ start, end }) => {
911
+ return harmonics_default(harmonicsOptions).setTimeSpan(start, end).prediction().getTimelinePrediction();
912
+ },
913
+ getExtremesPrediction: ({ start, end, labels, offsets, timeFidelity }) => {
914
+ return harmonics_default(harmonicsOptions).setTimeSpan(start, end).prediction({ timeFidelity }).getExtremesPrediction({
915
+ labels,
916
+ offsets
917
+ });
918
+ },
919
+ getWaterLevelAtTime: ({ time }) => {
920
+ const endDate = new Date(time.getTime() + 600 * 1e3);
921
+ return harmonics_default(harmonicsOptions).setTimeSpan(time, endDate).prediction().getTimelinePrediction()[0];
922
+ }
923
+ };
924
+ };
925
+ tidePredictionFactory.constituents = constituents_default;
926
+ var src_default = tidePredictionFactory;
927
+
928
+ //#endregion
929
+ export { src_default as default };
930
+ //# sourceMappingURL=index.js.map