ogamejs 4.0.1 → 4.1.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/README.md CHANGED
@@ -354,6 +354,59 @@ const winRate = runs.filter((run) => run.winner === 'attacker').length / runs.le
354
354
 
355
355
  Destroyed defenses are left out of the debris field unless you pass `defenseDebris: true`. Defense repair after a battle is not modelled.
356
356
 
357
+ #### `getMoonbreakChance(moonSize, fleets)` / `getMoonbreakLosses(moonSize, fleets)` / `getMoonbreakWaves(rip)`
358
+
359
+ A moon destruction with Deathstars. `fleets` lists each attacker's Deathstars in firing order; each attacker spreads them over 6 waves, the extra ships in the first ones, and the moon is gone as soon as one wave succeeds.
360
+
361
+ ```javascript
362
+ Ogame.Fleets.getMoonbreakChance(8944, [100, 80]);
363
+ // → 0.9409… (94.09 %)
364
+ Ogame.Fleets.getMoonbreakLosses(8944, [100]);
365
+ // → { mean: 27.78…, sigma: 4.33…,
366
+ // bands: [{ confidence: 68, min: 23.45…, max: 32.11… }, { confidence: 95, … }, { confidence: 99, … }] }
367
+ Ogame.Fleets.getMoonbreakWaves(100);
368
+ // → [17, 17, 17, 17, 16, 16]
369
+ ```
370
+
371
+ The values are unrounded. The loss bands are a gaussian approximation around the expected losses.
372
+
373
+ #### `getExpeditionMaxFind(options)` / `getExpeditionFindBase(topScore)`
374
+
375
+ The largest metal find of one expedition. A Discoverer's find is `base × (1 + explorerBonus × (1 + lifeformExplorerBonus)) × economySpeed`; other classes get `base` alone. A Pathfinder doubles it and the lifeform expedition resource bonus multiplies it.
376
+
377
+ ```javascript
378
+ Ogame.Fleets.getExpeditionMaxFind({
379
+ topScore: 2e9, // points of the universe's top player
380
+ economySpeed: 10,
381
+ explorer: true, // Discoverer class
382
+ pathfinder: true,
383
+ explorerBonus: 0.5, // serverData `explorerBonusIncreasedExpeditionOutcome`
384
+ lifeformExplorerBonus: 0, // lifeform Discoverer enhancement, 0.2 for 20 %
385
+ lifeformResourceBonus: 0, // lifeform expedition resource bonus, 0.2 for 20 %
386
+ });
387
+ // → 150000000
388
+ ```
389
+
390
+ The lifeform bonuses are the totals the in-game lifeform bonus page shows, as fractions.
391
+
392
+ #### `getCargoCapacity(ship, options = {})`
393
+
394
+ One ship's cargo with its bonuses, all shares of the base cargo that add up: Hyperspace Technology (`hyperspaceMultiplier` %, 5 by default, per level) plus any other `bonus` (Collector class, lifeform…).
395
+
396
+ ```javascript
397
+ Ogame.Fleets.getCargoCapacity(Ogame.models.Destroyable[12], { hyperspaceLevel: 20, bonus: 0.25 });
398
+ // → 56250
399
+ ```
400
+
401
+ #### `getMoonLockShips(ship, debrisFactor, threshold = 2000000)`
402
+
403
+ How many ships to destroy on a position to reach the 2 000 000 debris that give a moon its maximum 20 % chance.
404
+
405
+ ```javascript
406
+ Ogame.Fleets.getMoonLockShips(Ogame.models.Destroyable[1], 0.5);
407
+ // → 1000
408
+ ```
409
+
357
410
  ### `Ogame.Trader`
358
411
 
359
412
  Converts one resource into the two others. Rates are a `metal:crystal:deut` string (default `'2:1.5:1'`), and the percentages split the traded amount between the two target resources. **All parameters are optional.**
@@ -366,7 +419,7 @@ Ogame.Trader.sellCrystal(10000); // → { deut, metal }
366
419
 
367
420
  #### `parseRate(rate = '2:1.5:1', type = 'deut')`
368
421
 
369
- Normalizes a rate relative to a reference resource (`'metal'`, `'crystal'` or `'deut'`). Throws if the rate is malformed.
422
+ Normalizes a rate relative to a reference resource (`'metal'`, `'crystal'` or `'deut'`). Throws if the rate is malformed — that includes a term that is not a number, but also a `0`, an empty one (`'2::1'`) and a negative one, none of which describe a trade.
370
423
 
371
424
  ```javascript
372
425
  Ogame.Trader.parseRate('3:2:1', 'deut');
@@ -464,7 +517,7 @@ import type { BuildingEntry, FleetEntry, Coordinates } from 'ogamejs/types';
464
517
 
465
518
  Stated plainly, so you know what you are not getting:
466
519
 
467
- - **Lifeforms** (the 2021 expansion) are not modelled — neither their buildings nor their technologies. This is a data problem, not a code one: the tables run to roughly 120 entries and we would rather have them sourced than guessed.
520
+ - **Lifeforms** (the 2021 expansion) are not modelled — neither their buildings nor their technologies. This is a data problem, not a code one: the tables run to roughly 120 entries and we would rather have them sourced than guessed. Where a formula needs a lifeform bonus (expeditions, cargo), it takes the total the in-game bonus page shows.
468
521
  - **Drive upgrade values** for the three ships that switch drive (small cargo, recycler, bomber) come from community tables rather than a first-party source. The speeds are solid; the post-switch fuel figures deserve an in-game check.
469
522
  - **Defense repair** after a battle is not simulated, and neither are moon-creation odds.
470
523
  - Officers other than the geologist, and alliance classes, are not modelled in the production bonuses.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ogamejs",
3
- "version": "4.0.1",
3
+ "version": "4.1.0",
4
4
  "description": "OGame formulas as a dependency-free ESM library: building and research costs, production, build times, fleet debris and marketplace rates.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -0,0 +1,124 @@
1
+ /**
2
+ * The maximum metal an expedition can find, tiered by the score of the
3
+ * universe's top player. `below` is an exclusive upper bound; above the last
4
+ * tier every universe shares `EXPEDITION_TOP_TIER_BASE`.
5
+ */
6
+ const EXPEDITION_FIND_TIERS = Object.freeze([
7
+ Object.freeze({ below: 1e4, base: 40000 }),
8
+ Object.freeze({ below: 1e5, base: 500000 }),
9
+ Object.freeze({ below: 1e6, base: 1200000 }),
10
+ Object.freeze({ below: 5e6, base: 1800000 }),
11
+ Object.freeze({ below: 25e6, base: 2400000 }),
12
+ Object.freeze({ below: 50e6, base: 3000000 }),
13
+ Object.freeze({ below: 75e6, base: 3600000 }),
14
+ Object.freeze({ below: 100e6, base: 4200000 }),
15
+ ]);
16
+ const EXPEDITION_TOP_TIER_BASE = 5000000;
17
+
18
+ /** The Discoverer class bonus on expedition finds, `explorerBonusIncreasedExpeditionOutcome` in serverData. */
19
+ const DEFAULT_EXPLORER_BONUS = 0.5;
20
+
21
+ /** The share of base cargo each Hyperspace Technology level adds, `cargoHyperspaceTechMultiplier` in serverData. */
22
+ const DEFAULT_HYPERSPACE_MULTIPLIER = 5;
23
+
24
+ function assertBonus(name, value) {
25
+ if (!Number.isFinite(value) || value < 0) {
26
+ throw new Error(`${name} must be a number >= 0, received ${value}`);
27
+ }
28
+ }
29
+
30
+ /**
31
+ *
32
+ * Return the expedition find base of a universe, before any multiplier
33
+ * @param {number} topScore The points of the universe's top player
34
+ * @return {number} The base, in metal
35
+ */
36
+ function getExpeditionFindBase(topScore) {
37
+ if (!Number.isFinite(topScore) || topScore < 0) {
38
+ throw new Error(`topScore must be a number >= 0, received ${topScore}`);
39
+ }
40
+
41
+ const tier = EXPEDITION_FIND_TIERS.find(({ below }) => topScore < below);
42
+ return tier ? tier.base : EXPEDITION_TOP_TIER_BASE;
43
+ }
44
+
45
+ /**
46
+ *
47
+ * Return the largest metal find a single expedition can bring back
48
+ *
49
+ * `base * classFactor * (pathfinder ? 2 : 1) * (1 + lifeformResourceBonus)`
50
+ *
51
+ * - a Discoverer gets `classFactor = (1 + explorerBonus * (1 + lifeformExplorerBonus)) * economySpeed`:
52
+ * the lifeform class enhancement amplifies the class bonus itself, and only
53
+ * the Discoverer's finds scale with the economy speed;
54
+ * - any other class gets `classFactor = 1`.
55
+ *
56
+ * Crystal and deuterium finds are smaller than metal finds. Every bonus is a
57
+ * fraction: 0.2 for the 20 % the in-game lifeform bonus page shows.
58
+ * @param {object} options The universe and the player's bonuses
59
+ * @param {number} options.topScore The points of the universe's top player
60
+ * @param {number} options.economySpeed The universe economy speed
61
+ * @param {boolean} [options.explorer] Whether the player is a Discoverer
62
+ * @param {boolean} [options.pathfinder] Whether the fleet holds a Pathfinder
63
+ * @param {number} [options.explorerBonus] The Discoverer class bonus, 0.5 by default
64
+ * @param {number} [options.lifeformExplorerBonus] The lifeform Discoverer enhancement
65
+ * @param {number} [options.lifeformResourceBonus] The lifeform expedition resource bonus
66
+ * @return {number} The maximum find, in metal
67
+ */
68
+ function getExpeditionMaxFind({
69
+ topScore,
70
+ economySpeed,
71
+ explorer = false,
72
+ pathfinder = false,
73
+ explorerBonus = DEFAULT_EXPLORER_BONUS,
74
+ lifeformExplorerBonus = 0,
75
+ lifeformResourceBonus = 0,
76
+ }) {
77
+ if (!(economySpeed > 0)) {
78
+ throw new Error(`economySpeed must be greater than 0, received ${economySpeed}`);
79
+ }
80
+ assertBonus('explorerBonus', explorerBonus);
81
+ assertBonus('lifeformExplorerBonus', lifeformExplorerBonus);
82
+ assertBonus('lifeformResourceBonus', lifeformResourceBonus);
83
+
84
+ const classFactor = explorer
85
+ ? (1 + explorerBonus * (1 + lifeformExplorerBonus)) * economySpeed
86
+ : 1;
87
+
88
+ return getExpeditionFindBase(topScore) * classFactor * (pathfinder ? 2 : 1) * (1 + lifeformResourceBonus);
89
+ }
90
+
91
+ /**
92
+ *
93
+ * Return the cargo capacity of one ship, with its bonuses
94
+ *
95
+ * `ship.cargo * (1 + hyperspaceLevel * hyperspaceMultiplier / 100 + bonus)`:
96
+ * every bonus is a share of the base cargo, so they add up.
97
+ * @param {import('../types.js').DestroyableEntry} ship An entry of models/destroyable.js
98
+ * @param {object} [options] The bonuses
99
+ * @param {number} [options.hyperspaceLevel] The Hyperspace Technology level
100
+ * @param {number} [options.hyperspaceMultiplier] The % of base cargo per level, 5 by default
101
+ * @param {number} [options.bonus] Any other bonus as a fraction: class (Collector 0.25 on cargo ships), lifeform…
102
+ * @return {number} The capacity
103
+ */
104
+ function getCargoCapacity(ship, {
105
+ hyperspaceLevel = 0,
106
+ hyperspaceMultiplier = DEFAULT_HYPERSPACE_MULTIPLIER,
107
+ bonus = 0,
108
+ } = {}) {
109
+ if (!Number.isInteger(hyperspaceLevel) || hyperspaceLevel < 0) {
110
+ throw new Error(`hyperspaceLevel must be an integer >= 0, received ${hyperspaceLevel}`);
111
+ }
112
+ assertBonus('hyperspaceMultiplier', hyperspaceMultiplier);
113
+ assertBonus('bonus', bonus);
114
+
115
+ return ship.cargo * (1 + (hyperspaceLevel * hyperspaceMultiplier) / 100 + bonus);
116
+ }
117
+
118
+ export {
119
+ getExpeditionFindBase,
120
+ getExpeditionMaxFind,
121
+ getCargoCapacity,
122
+ EXPEDITION_FIND_TIERS,
123
+ EXPEDITION_TOP_TIER_BASE,
124
+ };
@@ -3,6 +3,23 @@ import getDistance from './distance.js';
3
3
  import getShipSpeed, { getActiveDrive, getFleetSpeed } from './speed.js';
4
4
  import { getFlightTime, getFuelConsumption, getTrip } from './flight.js';
5
5
  import simulateCombat from './combat.js';
6
+ import {
7
+ getWaveChance,
8
+ getMoonbreakWaves,
9
+ getMoonbreakChance,
10
+ getMoonbreakLosses,
11
+ MIN_MOON_SIZE,
12
+ MAX_MOON_SIZE,
13
+ WAVES_PER_ATTACKER,
14
+ } from './moonbreak.js';
15
+ import {
16
+ getExpeditionFindBase,
17
+ getExpeditionMaxFind,
18
+ getCargoCapacity,
19
+ EXPEDITION_FIND_TIERS,
20
+ EXPEDITION_TOP_TIER_BASE,
21
+ } from './expedition.js';
22
+ import { getMoonLockShips, MOON_DEBRIS_THRESHOLD, MAX_MOON_CHANCE } from './moonLock.js';
6
23
 
7
24
  const Fleets = {
8
25
  getDebris,
@@ -14,6 +31,24 @@ const Fleets = {
14
31
  getFuelConsumption,
15
32
  getTrip,
16
33
  simulateCombat,
34
+ getWaveChance,
35
+ getMoonbreakWaves,
36
+ getMoonbreakChance,
37
+ getMoonbreakLosses,
38
+ getExpeditionFindBase,
39
+ getExpeditionMaxFind,
40
+ getCargoCapacity,
41
+ getMoonLockShips,
42
+ };
43
+
44
+ export {
45
+ MIN_MOON_SIZE,
46
+ MAX_MOON_SIZE,
47
+ WAVES_PER_ATTACKER,
48
+ EXPEDITION_FIND_TIERS,
49
+ EXPEDITION_TOP_TIER_BASE,
50
+ MOON_DEBRIS_THRESHOLD,
51
+ MAX_MOON_CHANCE,
17
52
  };
18
53
 
19
54
  export default Fleets;
@@ -0,0 +1,31 @@
1
+ /** The debris that gives a moon its maximum chance to appear. */
2
+ const MOON_DEBRIS_THRESHOLD = 2000000;
3
+
4
+ /** The maximum moon chance, in %, reached at `MOON_DEBRIS_THRESHOLD`. */
5
+ const MAX_MOON_CHANCE = 20;
6
+
7
+ /**
8
+ *
9
+ * Return how many ships must be destroyed on a position to reach the maximum moon chance
10
+ *
11
+ * Only metal and crystal land in the debris field here, and the universe keeps
12
+ * `debrisFactor` of them.
13
+ * @param {import('../types.js').DestroyableEntry} ship An entry of models/destroyable.js
14
+ * @param {number} debrisFactor The universe debris factor, e.g. 0.3 for 30%
15
+ * @param {number} [threshold] The debris to reach, 2 000 000 by default
16
+ * @return {number} The number of ships
17
+ */
18
+ function getMoonLockShips(ship, debrisFactor, threshold = MOON_DEBRIS_THRESHOLD) {
19
+ if (!(debrisFactor > 0)) {
20
+ throw new Error(`debrisFactor must be greater than 0, received ${debrisFactor}`);
21
+ }
22
+
23
+ const debris = (ship.cost.metal ?? 0) + (ship.cost.crystal ?? 0);
24
+ if (!(debris > 0)) {
25
+ throw new Error('the ship leaves no metal or crystal debris');
26
+ }
27
+
28
+ return Math.ceil(threshold / (debrisFactor * debris));
29
+ }
30
+
31
+ export { getMoonLockShips, MOON_DEBRIS_THRESHOLD, MAX_MOON_CHANCE };
@@ -0,0 +1,133 @@
1
+ /** A moon size, in km, can only be in this range. */
2
+ const MIN_MOON_SIZE = 3464;
3
+ const MAX_MOON_SIZE = 8944;
4
+
5
+ /** Each attacker spreads their Deathstars over this many waves. */
6
+ const WAVES_PER_ATTACKER = 6;
7
+
8
+ function assertMoonSize(moonSize) {
9
+ if (!Number.isFinite(moonSize) || moonSize < MIN_MOON_SIZE || moonSize > MAX_MOON_SIZE) {
10
+ throw new Error(`moonSize must be between ${MIN_MOON_SIZE} and ${MAX_MOON_SIZE}, received ${moonSize}`);
11
+ }
12
+ }
13
+
14
+ function assertFleets(fleets) {
15
+ if (!Array.isArray(fleets) || fleets.length === 0) {
16
+ throw new Error('fleets must be a non-empty array of Deathstar counts');
17
+ }
18
+ for (const rip of fleets) {
19
+ if (!Number.isInteger(rip) || rip < 0) {
20
+ throw new Error(`each fleet must be an integer >= 0, received ${rip}`);
21
+ }
22
+ }
23
+ }
24
+
25
+ /**
26
+ *
27
+ * Return the chance that a single wave of Deathstars destroys the moon
28
+ *
29
+ * `(100 - sqrt(moonSize)) * sqrt(rip) / 100`, capped at 1
30
+ * @param {number} moonSize The moon diameter, in km
31
+ * @param {number} rip The number of Deathstars in the wave
32
+ * @return {number} The chance, between 0 and 1
33
+ */
34
+ function getWaveChance(moonSize, rip) {
35
+ return Math.min(1, ((100 - Math.sqrt(moonSize)) * Math.sqrt(rip)) / 100);
36
+ }
37
+
38
+ /**
39
+ *
40
+ * Return the waves one attacker sends, in firing order
41
+ *
42
+ * The Deathstars are spread over 6 waves: when the count is not a multiple of 6,
43
+ * the first waves carry one extra ship. Under 6 Deathstars, the last waves are
44
+ * empty, which neither threaten the moon nor lose a ship.
45
+ * @param {number} rip The attacker's Deathstars
46
+ * @return {number[]} The size of each of the 6 waves
47
+ */
48
+ function getMoonbreakWaves(rip) {
49
+ const base = Math.floor(rip / WAVES_PER_ATTACKER);
50
+ const remainder = rip % WAVES_PER_ATTACKER;
51
+
52
+ return Array.from({ length: WAVES_PER_ATTACKER }, (_, i) => (i < remainder ? base + 1 : base));
53
+ }
54
+
55
+ /**
56
+ *
57
+ * Return the chance that a coordinated attack destroys the moon
58
+ *
59
+ * The attackers fire one after the other and the moon is gone as soon as one
60
+ * wave succeeds, so the attack fails only when every wave fails.
61
+ * @param {number} moonSize The moon diameter, in km (3464 to 8944)
62
+ * @param {number[]} fleets The Deathstars of each attacker, in firing order
63
+ * @return {number} The chance, between 0 and 1
64
+ */
65
+ function getMoonbreakChance(moonSize, fleets) {
66
+ assertMoonSize(moonSize);
67
+ assertFleets(fleets);
68
+
69
+ const failure = fleets
70
+ .flatMap(getMoonbreakWaves)
71
+ .reduce((acc, rip) => acc * (1 - getWaveChance(moonSize, rip)), 1);
72
+
73
+ return 1 - failure;
74
+ }
75
+
76
+ /**
77
+ *
78
+ * Return the expected Deathstar losses of a coordinated attack
79
+ *
80
+ * Each Deathstar of a wave is destroyed with probability `sqrt(moonSize) / 200`,
81
+ * and a wave only costs ships if every wave before it failed. The variance sums
82
+ * the per-wave binomial variances (the waves are treated as independent), and
83
+ * the spread is summarised as a gaussian around the mean: 1σ / 2σ / 3σ for the
84
+ * 68 / 95 / 99 % bands, clamped between 0 and the whole fleet.
85
+ * @param {number} moonSize The moon diameter, in km (3464 to 8944)
86
+ * @param {number[]} fleets The Deathstars of each attacker, in firing order
87
+ * @return {{
88
+ * mean: number, sigma: number,
89
+ * bands: { confidence: number, min: number, max: number }[],
90
+ * }} The losses, unrounded
91
+ */
92
+ function getMoonbreakLosses(moonSize, fleets) {
93
+ assertMoonSize(moonSize);
94
+ assertFleets(fleets);
95
+
96
+ const destructionRate = Math.sqrt(moonSize) / 200;
97
+ const total = fleets.reduce((acc, rip) => acc + rip, 0);
98
+
99
+ let mean = 0;
100
+ let variance = 0;
101
+ // The chance that every wave so far has failed, so that this one fires.
102
+ let reached = 1;
103
+
104
+ for (const size of fleets.flatMap(getMoonbreakWaves)) {
105
+ const p = destructionRate * reached;
106
+ mean += size * p;
107
+ variance += size * p * (1 - p);
108
+ reached *= 1 - getWaveChance(moonSize, size);
109
+ }
110
+
111
+ const sigma = Math.sqrt(variance);
112
+ const band = (confidence, sigmas) => ({
113
+ confidence,
114
+ min: Math.max(mean - sigmas * sigma, 0),
115
+ max: Math.min(mean + sigmas * sigma, total),
116
+ });
117
+
118
+ return {
119
+ mean,
120
+ sigma,
121
+ bands: [band(68, 1), band(95, 2), band(99, 3)],
122
+ };
123
+ }
124
+
125
+ export {
126
+ getWaveChance,
127
+ getMoonbreakWaves,
128
+ getMoonbreakChance,
129
+ getMoonbreakLosses,
130
+ MIN_MOON_SIZE,
131
+ MAX_MOON_SIZE,
132
+ WAVES_PER_ATTACKER,
133
+ };
@@ -1,4 +1,4 @@
1
- import hasNaN from './utils.js';
1
+ import isUsableRate from './utils.js';
2
2
 
3
3
  function extract(rate, type) {
4
4
  let res = {};
@@ -46,7 +46,10 @@ export default function parseRate(rate = '2:1.5:1', type = 'deut') {
46
46
 
47
47
  const res = extract(rate, type);
48
48
 
49
- if (hasNaN(Object.values(res))) {
49
+ // Checked after normalizing rather than on the raw terms: whatever makes a
50
+ // rate unusable — a term that is not a number, `0`, empty, negative — shows
51
+ // up here as a NaN, an Infinity, a 0 or a negative ratio.
52
+ if (!isUsableRate(Object.values(res))) {
50
53
  throw new Error('rate not parsed correctly');
51
54
  }
52
55
 
@@ -1,9 +1,8 @@
1
- export default function hasNaN(args) {
2
- let response = false;
3
- args.forEach((val) => {
4
- if (Number.isNaN(Number(val))) {
5
- response = true;
6
- }
7
- });
8
- return response;
1
+ // A normalized rate is usable when every term is a real, strictly positive
2
+ // number. Checking only for `NaN` let two kinds of nonsense through as if they
3
+ // were answers: `Infinity`, produced by dividing into a `0` term, and `0`
4
+ // itself, which is what an empty term (`'2::1'`) parses to. A negative worth is
5
+ // not something the game can express either.
6
+ export default function isUsableRate(values) {
7
+ return values.every((value) => Number.isFinite(value) && value > 0);
9
8
  }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The maximum metal an expedition can find, tiered by the score of the
3
+ * universe's top player. `below` is an exclusive upper bound; above the last
4
+ * tier every universe shares `EXPEDITION_TOP_TIER_BASE`.
5
+ */
6
+ declare const EXPEDITION_FIND_TIERS: readonly (Readonly<{
7
+ below: 10000;
8
+ base: 40000;
9
+ }> | Readonly<{
10
+ below: 100000;
11
+ base: 500000;
12
+ }> | Readonly<{
13
+ below: 1000000;
14
+ base: 1200000;
15
+ }> | Readonly<{
16
+ below: 5000000;
17
+ base: 1800000;
18
+ }> | Readonly<{
19
+ below: 25000000;
20
+ base: 2400000;
21
+ }> | Readonly<{
22
+ below: 50000000;
23
+ base: 3000000;
24
+ }> | Readonly<{
25
+ below: 75000000;
26
+ base: 3600000;
27
+ }> | Readonly<{
28
+ below: 100000000;
29
+ base: 4200000;
30
+ }>)[];
31
+ declare const EXPEDITION_TOP_TIER_BASE = 5000000;
32
+ /**
33
+ *
34
+ * Return the expedition find base of a universe, before any multiplier
35
+ * @param {number} topScore The points of the universe's top player
36
+ * @return {number} The base, in metal
37
+ */
38
+ declare function getExpeditionFindBase(topScore: number): number;
39
+ /**
40
+ *
41
+ * Return the largest metal find a single expedition can bring back
42
+ *
43
+ * `base * classFactor * (pathfinder ? 2 : 1) * (1 + lifeformResourceBonus)`
44
+ *
45
+ * - a Discoverer gets `classFactor = (1 + explorerBonus * (1 + lifeformExplorerBonus)) * economySpeed`:
46
+ * the lifeform class enhancement amplifies the class bonus itself, and only
47
+ * the Discoverer's finds scale with the economy speed;
48
+ * - any other class gets `classFactor = 1`.
49
+ *
50
+ * Crystal and deuterium finds are smaller than metal finds. Every bonus is a
51
+ * fraction: 0.2 for the 20 % the in-game lifeform bonus page shows.
52
+ * @param {object} options The universe and the player's bonuses
53
+ * @param {number} options.topScore The points of the universe's top player
54
+ * @param {number} options.economySpeed The universe economy speed
55
+ * @param {boolean} [options.explorer] Whether the player is a Discoverer
56
+ * @param {boolean} [options.pathfinder] Whether the fleet holds a Pathfinder
57
+ * @param {number} [options.explorerBonus] The Discoverer class bonus, 0.5 by default
58
+ * @param {number} [options.lifeformExplorerBonus] The lifeform Discoverer enhancement
59
+ * @param {number} [options.lifeformResourceBonus] The lifeform expedition resource bonus
60
+ * @return {number} The maximum find, in metal
61
+ */
62
+ declare function getExpeditionMaxFind({ topScore, economySpeed, explorer, pathfinder, explorerBonus, lifeformExplorerBonus, lifeformResourceBonus, }: {
63
+ topScore: number;
64
+ economySpeed: number;
65
+ explorer?: boolean;
66
+ pathfinder?: boolean;
67
+ explorerBonus?: number;
68
+ lifeformExplorerBonus?: number;
69
+ lifeformResourceBonus?: number;
70
+ }): number;
71
+ /**
72
+ *
73
+ * Return the cargo capacity of one ship, with its bonuses
74
+ *
75
+ * `ship.cargo * (1 + hyperspaceLevel * hyperspaceMultiplier / 100 + bonus)`:
76
+ * every bonus is a share of the base cargo, so they add up.
77
+ * @param {import('../types.js').DestroyableEntry} ship An entry of models/destroyable.js
78
+ * @param {object} [options] The bonuses
79
+ * @param {number} [options.hyperspaceLevel] The Hyperspace Technology level
80
+ * @param {number} [options.hyperspaceMultiplier] The % of base cargo per level, 5 by default
81
+ * @param {number} [options.bonus] Any other bonus as a fraction: class (Collector 0.25 on cargo ships), lifeform…
82
+ * @return {number} The capacity
83
+ */
84
+ declare function getCargoCapacity(ship: import('../types.js').DestroyableEntry, { hyperspaceLevel, hyperspaceMultiplier, bonus, }?: {
85
+ hyperspaceLevel?: number;
86
+ hyperspaceMultiplier?: number;
87
+ bonus?: number;
88
+ }): number;
89
+ export { getExpeditionFindBase, getExpeditionMaxFind, getCargoCapacity, EXPEDITION_FIND_TIERS, EXPEDITION_TOP_TIER_BASE, };
90
+ //# sourceMappingURL=expedition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expedition.d.ts","sourceRoot":"","sources":["../../src/fleets/expedition.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,QAAA,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;KASzB,CAAC;AACH,QAAA,MAAM,wBAAwB,UAAU,CAAC;AAczC;;;;;GAKG;AACH,iBAAS,qBAAqB,CAAC,QAAQ,EAH5B,MAG4B,GAF3B,MAAM,CASjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,iBAAS,oBAAoB,CAAC,EAC5B,QAAQ,EACR,YAAY,EACZ,QAAgB,EAChB,UAAkB,EAClB,aAAsC,EACtC,qBAAyB,EACzB,qBAAyB,GAC1B,EAjBE;IAAwB,QAAQ,EAAxB,MAAM,CACd;IAAwB,YAAY,EAA5B,MAAM,CACd;IAA0B,QAAQ,AAAlC,CACA,EADQ,OAAO,CACf;IAA0B,UAAU,AAApC,CACA,EADQ,OAAO,CACf;IAAyB,aAAa,AAAtC,CACA,EADQ,MAAM,CACd;IAAyB,qBAAqB,AAA9C,CACA,EADQ,MAAM,CACd;IAAyB,qBAAqB,AAA9C,CACA,EADQ,MAAM,CACd;CAUF,GAVW,MAAM,CAuBjB;AAED;;;;;;;;;;;;GAYG;AACH,iBAAS,gBAAgB,CAAC,IAAI,EAPnB,OAAO,aAAa,EAAE,gBAOH,EAAE,EAC9B,eAAmB,EACnB,oBAAoD,EACpD,KAAS,GACV,AAVE,CAIA,EAHA;IAAyB,eAAe,AAAxC,CACA,EADQ,MAAM,CACd;IAAyB,oBAAoB,AAA7C,CACA,EADQ,MAAM,CACd;IAAyB,KAAK,AAA9B,CACA,EADQ,MAAM,CACd;CAMG,GANM,MAAM,CAcjB;AAED,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,GACzB,CAAC"}
@@ -3,6 +3,9 @@ import getDistance from './distance.js';
3
3
  import getShipSpeed, { getActiveDrive, getFleetSpeed } from './speed.js';
4
4
  import { getFlightTime, getFuelConsumption, getTrip } from './flight.js';
5
5
  import simulateCombat from './combat.js';
6
+ import { getWaveChance, getMoonbreakWaves, getMoonbreakChance, getMoonbreakLosses, MIN_MOON_SIZE, MAX_MOON_SIZE, WAVES_PER_ATTACKER } from './moonbreak.js';
7
+ import { getExpeditionFindBase, getExpeditionMaxFind, getCargoCapacity, EXPEDITION_FIND_TIERS, EXPEDITION_TOP_TIER_BASE } from './expedition.js';
8
+ import { getMoonLockShips, MOON_DEBRIS_THRESHOLD, MAX_MOON_CHANCE } from './moonLock.js';
6
9
  declare const Fleets: {
7
10
  getDebris: typeof getDebris;
8
11
  getDistance: typeof getDistance;
@@ -13,6 +16,15 @@ declare const Fleets: {
13
16
  getFuelConsumption: typeof getFuelConsumption;
14
17
  getTrip: typeof getTrip;
15
18
  simulateCombat: typeof simulateCombat;
19
+ getWaveChance: typeof getWaveChance;
20
+ getMoonbreakWaves: typeof getMoonbreakWaves;
21
+ getMoonbreakChance: typeof getMoonbreakChance;
22
+ getMoonbreakLosses: typeof getMoonbreakLosses;
23
+ getExpeditionFindBase: typeof getExpeditionFindBase;
24
+ getExpeditionMaxFind: typeof getExpeditionMaxFind;
25
+ getCargoCapacity: typeof getCargoCapacity;
26
+ getMoonLockShips: typeof getMoonLockShips;
16
27
  };
28
+ export { MIN_MOON_SIZE, MAX_MOON_SIZE, WAVES_PER_ATTACKER, EXPEDITION_FIND_TIERS, EXPEDITION_TOP_TIER_BASE, MOON_DEBRIS_THRESHOLD, MAX_MOON_CHANCE, };
17
29
  export default Fleets;
18
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fleets/index.js"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,YAAY,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,cAAc,MAAM,aAAa,CAAC;AAEzC,QAAA,MAAM,MAAM;;;;;;;;;;CAUX,CAAC;eAEa,MAAM"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fleets/index.js"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,gBAAgB,CAAC;AACvC,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,YAAY,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,cAAc,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEzF,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;CAkBX,CAAC;AAEF,OAAO,EACL,aAAa,EACb,aAAa,EACb,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,eAAe,GAChB,CAAC;eAEa,MAAM"}
@@ -0,0 +1,18 @@
1
+ /** The debris that gives a moon its maximum chance to appear. */
2
+ declare const MOON_DEBRIS_THRESHOLD = 2000000;
3
+ /** The maximum moon chance, in %, reached at `MOON_DEBRIS_THRESHOLD`. */
4
+ declare const MAX_MOON_CHANCE = 20;
5
+ /**
6
+ *
7
+ * Return how many ships must be destroyed on a position to reach the maximum moon chance
8
+ *
9
+ * Only metal and crystal land in the debris field here, and the universe keeps
10
+ * `debrisFactor` of them.
11
+ * @param {import('../types.js').DestroyableEntry} ship An entry of models/destroyable.js
12
+ * @param {number} debrisFactor The universe debris factor, e.g. 0.3 for 30%
13
+ * @param {number} [threshold] The debris to reach, 2 000 000 by default
14
+ * @return {number} The number of ships
15
+ */
16
+ declare function getMoonLockShips(ship: import('../types.js').DestroyableEntry, debrisFactor: number, threshold?: number): number;
17
+ export { getMoonLockShips, MOON_DEBRIS_THRESHOLD, MAX_MOON_CHANCE };
18
+ //# sourceMappingURL=moonLock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moonLock.d.ts","sourceRoot":"","sources":["../../src/fleets/moonLock.js"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,QAAA,MAAM,qBAAqB,UAAU,CAAC;AAEtC,yEAAyE;AACzE,QAAA,MAAM,eAAe,KAAK,CAAC;AAE3B;;;;;;;;;;GAUG;AACH,iBAAS,gBAAgB,CAAC,IAAI,EALnB,OAAO,aAAa,EAAE,gBAKH,EAAE,YAAY,EAJjC,MAIiC,EAAE,SAAS,AAHpD,CACA,EADQ,MAGoE,GAFnE,MAAM,CAajB;AAED,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,64 @@
1
+ /** A moon size, in km, can only be in this range. */
2
+ declare const MIN_MOON_SIZE = 3464;
3
+ declare const MAX_MOON_SIZE = 8944;
4
+ /** Each attacker spreads their Deathstars over this many waves. */
5
+ declare const WAVES_PER_ATTACKER = 6;
6
+ /**
7
+ *
8
+ * Return the chance that a single wave of Deathstars destroys the moon
9
+ *
10
+ * `(100 - sqrt(moonSize)) * sqrt(rip) / 100`, capped at 1
11
+ * @param {number} moonSize The moon diameter, in km
12
+ * @param {number} rip The number of Deathstars in the wave
13
+ * @return {number} The chance, between 0 and 1
14
+ */
15
+ declare function getWaveChance(moonSize: number, rip: number): number;
16
+ /**
17
+ *
18
+ * Return the waves one attacker sends, in firing order
19
+ *
20
+ * The Deathstars are spread over 6 waves: when the count is not a multiple of 6,
21
+ * the first waves carry one extra ship. Under 6 Deathstars, the last waves are
22
+ * empty, which neither threaten the moon nor lose a ship.
23
+ * @param {number} rip The attacker's Deathstars
24
+ * @return {number[]} The size of each of the 6 waves
25
+ */
26
+ declare function getMoonbreakWaves(rip: number): number[];
27
+ /**
28
+ *
29
+ * Return the chance that a coordinated attack destroys the moon
30
+ *
31
+ * The attackers fire one after the other and the moon is gone as soon as one
32
+ * wave succeeds, so the attack fails only when every wave fails.
33
+ * @param {number} moonSize The moon diameter, in km (3464 to 8944)
34
+ * @param {number[]} fleets The Deathstars of each attacker, in firing order
35
+ * @return {number} The chance, between 0 and 1
36
+ */
37
+ declare function getMoonbreakChance(moonSize: number, fleets: number[]): number;
38
+ /**
39
+ *
40
+ * Return the expected Deathstar losses of a coordinated attack
41
+ *
42
+ * Each Deathstar of a wave is destroyed with probability `sqrt(moonSize) / 200`,
43
+ * and a wave only costs ships if every wave before it failed. The variance sums
44
+ * the per-wave binomial variances (the waves are treated as independent), and
45
+ * the spread is summarised as a gaussian around the mean: 1σ / 2σ / 3σ for the
46
+ * 68 / 95 / 99 % bands, clamped between 0 and the whole fleet.
47
+ * @param {number} moonSize The moon diameter, in km (3464 to 8944)
48
+ * @param {number[]} fleets The Deathstars of each attacker, in firing order
49
+ * @return {{
50
+ * mean: number, sigma: number,
51
+ * bands: { confidence: number, min: number, max: number }[],
52
+ * }} The losses, unrounded
53
+ */
54
+ declare function getMoonbreakLosses(moonSize: number, fleets: number[]): {
55
+ mean: number;
56
+ sigma: number;
57
+ bands: {
58
+ confidence: number;
59
+ min: number;
60
+ max: number;
61
+ }[];
62
+ };
63
+ export { getWaveChance, getMoonbreakWaves, getMoonbreakChance, getMoonbreakLosses, MIN_MOON_SIZE, MAX_MOON_SIZE, WAVES_PER_ATTACKER, };
64
+ //# sourceMappingURL=moonbreak.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moonbreak.d.ts","sourceRoot":"","sources":["../../src/fleets/moonbreak.js"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,QAAA,MAAM,aAAa,OAAO,CAAC;AAC3B,QAAA,MAAM,aAAa,OAAO,CAAC;AAE3B,mEAAmE;AACnE,QAAA,MAAM,kBAAkB,IAAI,CAAC;AAmB7B;;;;;;;;GAQG;AACH,iBAAS,aAAa,CAAC,QAAQ,EAJpB,MAIoB,EAAE,GAAG,EAHzB,MAGyB,GAFxB,MAAM,CAIjB;AAED;;;;;;;;;GASG;AACH,iBAAS,iBAAiB,CAAC,GAAG,EAHnB,MAGmB,GAFlB,MAAM,EAAE,CAOnB;AAED;;;;;;;;;GASG;AACH,iBAAS,kBAAkB,CAAC,QAAQ,EAJzB,MAIyB,EAAE,MAAM,EAHjC,MAAM,EAG2B,GAFhC,MAAM,CAWjB;AAED;;;;;;;;;;;;;;;GAeG;AACH,iBAAS,kBAAkB,CAAC,QAAQ,EAPzB,MAOyB,EAAE,MAAM,EANjC,MAAM,EAM2B,GALhC;IACP,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3D,CAiCH;AAED,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,aAAa,EACb,aAAa,EACb,kBAAkB,GACnB,CAAC"}
package/types/index.d.ts CHANGED
@@ -31,6 +31,14 @@ declare const Ogame: {
31
31
  getFuelConsumption: typeof import("./fleets/flight.js").getFuelConsumption;
32
32
  getTrip: typeof import("./fleets/flight.js").getTrip;
33
33
  simulateCombat: typeof import("./fleets/combat.js").default;
34
+ getWaveChance: typeof import("./fleets/moonbreak.js").getWaveChance;
35
+ getMoonbreakWaves: typeof import("./fleets/moonbreak.js").getMoonbreakWaves;
36
+ getMoonbreakChance: typeof import("./fleets/moonbreak.js").getMoonbreakChance;
37
+ getMoonbreakLosses: typeof import("./fleets/moonbreak.js").getMoonbreakLosses;
38
+ getExpeditionFindBase: typeof import("./fleets/expedition.js").getExpeditionFindBase;
39
+ getExpeditionMaxFind: typeof import("./fleets/expedition.js").getExpeditionMaxFind;
40
+ getCargoCapacity: typeof import("./fleets/expedition.js").getCargoCapacity;
41
+ getMoonLockShips: typeof import("./fleets/moonLock.js").getMoonLockShips;
34
42
  };
35
43
  Research: {
36
44
  getResearchCost: typeof import("./cost.js").default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAS,MAAM,WAAW,CAAC;AAEvD,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBV,CAAC;eAEa,KAAK"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAS,MAAM,WAAW,CAAC;AAEvD,QAAA,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBV,CAAC;eAEa,KAAK"}
@@ -1 +1 @@
1
- {"version":3,"file":"parseRate.d.ts","sourceRoot":"","sources":["../../src/trades/parseRate.js"],"names":[],"mappings":"AAuCA,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,IAAI,SAAY,EAAE,IAAI,SAAS,MAchE"}
1
+ {"version":3,"file":"parseRate.d.ts","sourceRoot":"","sources":["../../src/trades/parseRate.js"],"names":[],"mappings":"AAuCA,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,IAAI,SAAY,EAAE,IAAI,SAAS,MAiBhE"}
@@ -1,2 +1,2 @@
1
- export default function hasNaN(args: any): boolean;
1
+ export default function isUsableRate(values: any): any;
2
2
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/trades/utils.js"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,IAAI,KAAA,WAQlC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/trades/utils.js"],"names":[],"mappings":"AAKA,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,MAAM,KAAA,OAE1C"}