@elite-dangerous-almanac/core 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/PROVENANCE/ships/SOURCES.md +23 -0
  2. package/README.md +3 -2
  3. package/THIRD_PARTY_NOTICES.md +24 -2
  4. package/dist/astro/body-orbit.d.ts +174 -0
  5. package/dist/astro/body-orbit.js +1 -0
  6. package/dist/astro/body-orbit.js.map +1 -0
  7. package/dist/astro/body-physics.d.ts +228 -0
  8. package/dist/astro/body-physics.js +1 -0
  9. package/dist/astro/body-physics.js.map +1 -0
  10. package/dist/astro/body-rings.d.ts +223 -0
  11. package/dist/astro/body-rings.js +1 -0
  12. package/dist/astro/body-rings.js.map +1 -0
  13. package/dist/astro/codex-region-lookup.js +1 -1
  14. package/dist/astro/codex-region-lookup.js.map +1 -1
  15. package/dist/astro/index.d.ts +38 -1
  16. package/dist/astro/index.js +1 -1
  17. package/dist/astro/nebulae.d.ts +4 -4
  18. package/dist/astro/procedural-system.js +1 -1
  19. package/dist/astro/star-physics.d.ts +255 -0
  20. package/dist/astro/star-physics.js +1 -0
  21. package/dist/astro/star-physics.js.map +1 -0
  22. package/dist/body-scan-CEUYjCfH.d.ts +416 -0
  23. package/dist/chunk-37JIMWLK.js +1 -0
  24. package/dist/chunk-37JIMWLK.js.map +1 -0
  25. package/dist/{chunk-PA5EITW5.js → chunk-3LZXB2MC.js} +1 -1
  26. package/dist/{chunk-PA5EITW5.js.map → chunk-3LZXB2MC.js.map} +1 -1
  27. package/dist/chunk-3RTUSDQF.js +1 -0
  28. package/dist/chunk-3RTUSDQF.js.map +1 -0
  29. package/dist/chunk-4CBMQULR.js +1 -0
  30. package/dist/{chunk-4ZGUSHTP.js.map → chunk-4CBMQULR.js.map} +1 -1
  31. package/dist/{chunk-GZYPQIO2.js → chunk-4OTQBHQL.js} +1 -1
  32. package/dist/chunk-4OTQBHQL.js.map +1 -0
  33. package/dist/{chunk-QTAMQ6ME.js → chunk-5VWACBTN.js} +1 -1
  34. package/dist/chunk-65FZECUX.js +1 -0
  35. package/dist/chunk-65FZECUX.js.map +1 -0
  36. package/dist/chunk-6BFQIYGZ.js +1 -0
  37. package/dist/chunk-6BFQIYGZ.js.map +1 -0
  38. package/dist/chunk-6HA2YIKW.js +1 -0
  39. package/dist/chunk-6HA2YIKW.js.map +1 -0
  40. package/dist/{chunk-7EE5VIHR.js → chunk-6HMIF2RJ.js} +1 -1
  41. package/dist/chunk-6WTUY6ZX.js +1 -0
  42. package/dist/{chunk-V3AEUBHV.js.map → chunk-6WTUY6ZX.js.map} +1 -1
  43. package/dist/chunk-77TT4K53.js +1 -0
  44. package/dist/{chunk-MRTTQYT5.js → chunk-7EWZGDWY.js} +1 -1
  45. package/dist/{chunk-TBZJIQ5P.js → chunk-7TVFV3VO.js} +1 -1
  46. package/dist/chunk-7TVFV3VO.js.map +1 -0
  47. package/dist/chunk-7ZERP4TB.js +1 -0
  48. package/dist/{chunk-QY3L5BKN.js.map → chunk-7ZERP4TB.js.map} +1 -1
  49. package/dist/{chunk-Y6KJJMIM.js → chunk-A4QKXXZD.js} +1 -1
  50. package/dist/{chunk-Q5XOGATC.js → chunk-AIEC3LBT.js} +1 -1
  51. package/dist/chunk-B5VTFOK4.js +1 -0
  52. package/dist/chunk-B5VTFOK4.js.map +1 -0
  53. package/dist/chunk-DAQ3PJ4R.js +1 -0
  54. package/dist/chunk-DAQ3PJ4R.js.map +1 -0
  55. package/dist/{chunk-JGOAQLYW.js → chunk-F44QX47A.js} +1 -1
  56. package/dist/{chunk-EVJ32UF3.js → chunk-FA5JVXVG.js} +1 -1
  57. package/dist/{chunk-EVJ32UF3.js.map → chunk-FA5JVXVG.js.map} +1 -1
  58. package/dist/chunk-GBTCWNO6.js +1 -0
  59. package/dist/chunk-GBTCWNO6.js.map +1 -0
  60. package/dist/chunk-GGQMIQPC.js +1 -0
  61. package/dist/chunk-GGQMIQPC.js.map +1 -0
  62. package/dist/{chunk-EYGVDJ2I.js → chunk-GMTAFUAG.js} +1 -1
  63. package/dist/{chunk-Z43DN4PY.js → chunk-GTEHRZPN.js} +1 -1
  64. package/dist/{chunk-Z43DN4PY.js.map → chunk-GTEHRZPN.js.map} +1 -1
  65. package/dist/{chunk-HKXXFIRI.js → chunk-ITKZKREP.js} +1 -1
  66. package/dist/{chunk-OYR5HUQZ.js → chunk-IWFQ4ZKF.js} +1 -1
  67. package/dist/{chunk-ZCEAPJDH.js → chunk-J7BM5NGK.js} +1 -1
  68. package/dist/chunk-JMAXSXXQ.js +1 -0
  69. package/dist/chunk-JMAXSXXQ.js.map +1 -0
  70. package/dist/chunk-JO52LYO3.js +1 -0
  71. package/dist/chunk-M2TCZKRT.js +1 -0
  72. package/dist/chunk-M2TCZKRT.js.map +1 -0
  73. package/dist/chunk-M4FZRDAH.js +1 -0
  74. package/dist/chunk-M4FZRDAH.js.map +1 -0
  75. package/dist/chunk-NEXDA73Y.js +1 -0
  76. package/dist/chunk-NEXDA73Y.js.map +1 -0
  77. package/dist/chunk-OJC6AUL7.js +1 -0
  78. package/dist/chunk-OJC6AUL7.js.map +1 -0
  79. package/dist/chunk-P2MUFVJC.js +1 -0
  80. package/dist/chunk-P2MUFVJC.js.map +1 -0
  81. package/dist/{chunk-FYVPZBXN.js → chunk-Q5ALV3DI.js} +1 -1
  82. package/dist/{chunk-SQS7672E.js → chunk-Q6YDPREF.js} +1 -1
  83. package/dist/chunk-SS6XK336.js +1 -0
  84. package/dist/chunk-SS6XK336.js.map +1 -0
  85. package/dist/{chunk-OVUHQEH5.js → chunk-T4MKUKYS.js} +1 -1
  86. package/dist/{chunk-OVUHQEH5.js.map → chunk-T4MKUKYS.js.map} +1 -1
  87. package/dist/chunk-TMXKC6JL.js +1 -0
  88. package/dist/chunk-TMXKC6JL.js.map +1 -0
  89. package/dist/{chunk-XUHAPOM6.js → chunk-VEEBJFJ7.js} +1 -1
  90. package/dist/{chunk-L747RVPO.js → chunk-VQJXRPYI.js} +1 -1
  91. package/dist/{chunk-L747RVPO.js.map → chunk-VQJXRPYI.js.map} +1 -1
  92. package/dist/chunk-VTMCSCXV.js +1 -0
  93. package/dist/chunk-VTMCSCXV.js.map +1 -0
  94. package/dist/chunk-XQJERZUS.js +1 -0
  95. package/dist/chunk-XQJERZUS.js.map +1 -0
  96. package/dist/chunk-ZZ376WHL.js +1 -0
  97. package/dist/chunk-ZZ376WHL.js.map +1 -0
  98. package/dist/commodities/commodities-all.js +1 -1
  99. package/dist/commodities/commodities-rare.js +1 -1
  100. package/dist/commodities/commodities-standard.js +1 -1
  101. package/dist/commodities/commodities.d.ts +1 -1
  102. package/dist/commodities/commodities.js +1 -1
  103. package/dist/commodities/index.js +1 -1
  104. package/dist/equipment/index.js +1 -1
  105. package/dist/equipment/upgrade-costs.js +1 -1
  106. package/dist/equipment/upgrade-costs.js.map +1 -1
  107. package/dist/i18n/index.js +1 -1
  108. package/dist/materials/index.js +1 -1
  109. package/dist/materials/materials-all.js +1 -1
  110. package/dist/materials/materials-encoded.js +1 -1
  111. package/dist/materials/materials-manufactured.js +1 -1
  112. package/dist/materials/materials-raw.js +1 -1
  113. package/dist/materials/materials.d.ts +1 -1
  114. package/dist/materials/materials.js +1 -1
  115. package/dist/materials/micro-resources-all.js +1 -1
  116. package/dist/materials/micro-resources.d.ts +1 -1
  117. package/dist/materials/micro-resources.js +1 -1
  118. package/dist/ships/armour.js +1 -1
  119. package/dist/ships/build-metrics.d.ts +21 -232
  120. package/dist/ships/build-metrics.js +1 -1
  121. package/dist/ships/distributor.d.ts +1 -1
  122. package/dist/ships/distributor.js +1 -1
  123. package/dist/ships/heat.d.ts +1 -1
  124. package/dist/ships/heat.js +1 -1
  125. package/dist/ships/index.d.ts +3 -3
  126. package/dist/ships/index.js +1 -1
  127. package/dist/ships/jump-range.js +1 -1
  128. package/dist/ships/loadout-calculations.d.ts +2 -2
  129. package/dist/ships/loadout-validation.d.ts +111 -5
  130. package/dist/ships/loadout-validation.js +1 -1
  131. package/dist/ships/mobility-capacitor.d.ts +1 -1
  132. package/dist/ships/mobility-capacitor.js +1 -1
  133. package/dist/ships/mobility.js +1 -1
  134. package/dist/ships/modules-all.js +1 -1
  135. package/dist/ships/modules-core.js +1 -1
  136. package/dist/ships/modules-internal.js +1 -1
  137. package/dist/ships/modules.d.ts +21 -1
  138. package/dist/ships/modules.js +1 -1
  139. package/dist/ships/power.js +1 -1
  140. package/dist/ships/pre-engineered-stats.d.ts +17 -10
  141. package/dist/ships/pre-engineered-stats.js +1 -1
  142. package/dist/ships/resistances.js +1 -1
  143. package/dist/ships/shield-capacitor.d.ts +1 -1
  144. package/dist/ships/shield-capacitor.js +1 -1
  145. package/dist/ships/shield-recovery.js +1 -1
  146. package/dist/ships/shields.d.ts +1 -1
  147. package/dist/ships/shields.js +1 -1
  148. package/dist/ships/ship-loadout.d.ts +140 -18
  149. package/dist/ships/ship-loadout.js +1 -1
  150. package/dist/ships/slef.d.ts +4 -1
  151. package/dist/ships/slef.js +1 -1
  152. package/dist/ships/weapons-capacitor.js +1 -1
  153. package/dist/ships/weapons.js +1 -1
  154. package/package.json +18 -3
  155. package/dist/chunk-4KJ7CR74.js +0 -1
  156. package/dist/chunk-4KJ7CR74.js.map +0 -1
  157. package/dist/chunk-4ZGUSHTP.js +0 -1
  158. package/dist/chunk-6L56LWTT.js +0 -1
  159. package/dist/chunk-6L56LWTT.js.map +0 -1
  160. package/dist/chunk-6O4NRRSB.js +0 -1
  161. package/dist/chunk-6O4NRRSB.js.map +0 -1
  162. package/dist/chunk-7TQ2X6Q3.js +0 -1
  163. package/dist/chunk-7TQ2X6Q3.js.map +0 -1
  164. package/dist/chunk-B4ZSTOM4.js +0 -1
  165. package/dist/chunk-B4ZSTOM4.js.map +0 -1
  166. package/dist/chunk-D6YEHR5S.js +0 -1
  167. package/dist/chunk-D6YEHR5S.js.map +0 -1
  168. package/dist/chunk-EVW4Z4CB.js +0 -1
  169. package/dist/chunk-EVW4Z4CB.js.map +0 -1
  170. package/dist/chunk-GVNTKCVF.js +0 -1
  171. package/dist/chunk-GVNTKCVF.js.map +0 -1
  172. package/dist/chunk-GZYPQIO2.js.map +0 -1
  173. package/dist/chunk-JQG4C67D.js +0 -1
  174. package/dist/chunk-OYFMHDYT.js +0 -1
  175. package/dist/chunk-OYFMHDYT.js.map +0 -1
  176. package/dist/chunk-PY5L6WC5.js +0 -1
  177. package/dist/chunk-PY5L6WC5.js.map +0 -1
  178. package/dist/chunk-Q2L75GSI.js +0 -1
  179. package/dist/chunk-Q2L75GSI.js.map +0 -1
  180. package/dist/chunk-QJ7GB6FF.js +0 -1
  181. package/dist/chunk-QJ7GB6FF.js.map +0 -1
  182. package/dist/chunk-QY3L5BKN.js +0 -1
  183. package/dist/chunk-RRYBSAPX.js +0 -1
  184. package/dist/chunk-RRYBSAPX.js.map +0 -1
  185. package/dist/chunk-TBZJIQ5P.js.map +0 -1
  186. package/dist/chunk-V3AEUBHV.js +0 -1
  187. package/dist/chunk-V4C6FIE2.js +0 -1
  188. package/dist/chunk-VYDQHPY2.js +0 -1
  189. package/dist/chunk-VYDQHPY2.js.map +0 -1
  190. package/dist/chunk-YXPZ7QQB.js +0 -1
  191. package/dist/chunk-YXPZ7QQB.js.map +0 -1
  192. /package/dist/{chunk-QTAMQ6ME.js.map → chunk-5VWACBTN.js.map} +0 -0
  193. /package/dist/{chunk-7EE5VIHR.js.map → chunk-6HMIF2RJ.js.map} +0 -0
  194. /package/dist/{chunk-JQG4C67D.js.map → chunk-77TT4K53.js.map} +0 -0
  195. /package/dist/{chunk-MRTTQYT5.js.map → chunk-7EWZGDWY.js.map} +0 -0
  196. /package/dist/{chunk-Y6KJJMIM.js.map → chunk-A4QKXXZD.js.map} +0 -0
  197. /package/dist/{chunk-Q5XOGATC.js.map → chunk-AIEC3LBT.js.map} +0 -0
  198. /package/dist/{chunk-JGOAQLYW.js.map → chunk-F44QX47A.js.map} +0 -0
  199. /package/dist/{chunk-EYGVDJ2I.js.map → chunk-GMTAFUAG.js.map} +0 -0
  200. /package/dist/{chunk-HKXXFIRI.js.map → chunk-ITKZKREP.js.map} +0 -0
  201. /package/dist/{chunk-OYR5HUQZ.js.map → chunk-IWFQ4ZKF.js.map} +0 -0
  202. /package/dist/{chunk-ZCEAPJDH.js.map → chunk-J7BM5NGK.js.map} +0 -0
  203. /package/dist/{chunk-V4C6FIE2.js.map → chunk-JO52LYO3.js.map} +0 -0
  204. /package/dist/{chunk-FYVPZBXN.js.map → chunk-Q5ALV3DI.js.map} +0 -0
  205. /package/dist/{chunk-SQS7672E.js.map → chunk-Q6YDPREF.js.map} +0 -0
  206. /package/dist/{chunk-XUHAPOM6.js.map → chunk-VEEBJFJ7.js.map} +0 -0
@@ -0,0 +1,416 @@
1
+ import { SystemAddressInput } from './astro/system-address-input.js';
2
+
3
+ /**
4
+ * The shape a scanned body arrives in: {@link BodyProperties}, the physical body every
5
+ * calculation reads, and {@link BodyScanEvent}, that body plus the game journal's own
6
+ * `Scan` bookkeeping — with the records both nest.
7
+ *
8
+ * Types only. No catalogue, no parser, no computation, so importing costs nothing at
9
+ * runtime; `./astro` re-exports every symbol, which is why there is no subpath of its own.
10
+ * The orientation a reader needs lives on the two interfaces themselves.
11
+ *
12
+ * @packageDocumentation
13
+ */
14
+
15
+ /**
16
+ * One step up a body's parent chain, as one entry of {@link BodyScanEvent.Parents}.
17
+ *
18
+ * @remarks
19
+ * **Exactly one key is present**, and its value is that parent's
20
+ * {@link BodyScanEvent.BodyID} — so a moon orbiting a planet reads `{ Planet: 4 }`.
21
+ * The four keys are the four kinds of thing a body can orbit; `Null` is a barycentre,
22
+ * which is a point rather than a body and has no scan of its own.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import type { BodyParent } from '@elite-dangerous-almanac/core/astro';
27
+ *
28
+ * // A moon of the second planet, which orbits the main star.
29
+ * const parents: readonly BodyParent[] = [{ Planet: 4 }, { Star: 0 }];
30
+ *
31
+ * Object.keys(parents[0] ?? {})[0]; // -> 'Planet'
32
+ * ```
33
+ */
34
+ interface BodyParent {
35
+ /** `BodyID` of the star this body orbits. */
36
+ readonly Star?: number;
37
+ /** `BodyID` of the planet this body orbits — the body is a moon of it. */
38
+ readonly Planet?: number;
39
+ /** `BodyID` of the ring this body sits in — written for a belt cluster. */
40
+ readonly Ring?: number;
41
+ /** `BodyID` of the barycentre this body orbits. A point, not a scannable body. */
42
+ readonly Null?: number;
43
+ }
44
+ /**
45
+ * One ring or belt around a body, as one entry of {@link BodyProperties.Rings}.
46
+ *
47
+ * @remarks
48
+ * The same shape covers a planet's rings and a star's asteroid belts; `Name` tells them
49
+ * apart, ending in `" A Ring"` or `" A Belt"`. Radii are **metres** from the body's
50
+ * centre, and `MassMT` is **megatonnes** — the one mass in this module that is neither
51
+ * solar nor Earth masses.
52
+ */
53
+ interface BodyRing {
54
+ /** The ring's in-game name, e.g. `"Synuefe EN-H d11-96 A 1 A Ring"`. */
55
+ readonly Name: string;
56
+ /**
57
+ * The ring's material class, as the game's internal token: `"eRingClass_Rocky"`,
58
+ * `"eRingClass_Icy"`, `"eRingClass_MetalRich"` or `"eRingClass_Metalic"`.
59
+ *
60
+ * @remarks
61
+ * `"eRingClass_Metalic"` is spelt that way by the game. It is Frontier's token, not a
62
+ * typo introduced here, and a consumer matching on the string must spell it likewise.
63
+ */
64
+ readonly RingClass: string;
65
+ /** The ring's total mass, in megatonnes. */
66
+ readonly MassMT: number;
67
+ /** Inner radius, in metres from the body's centre. */
68
+ readonly InnerRad: number;
69
+ /** Outer radius, in metres from the body's centre. */
70
+ readonly OuterRad: number;
71
+ }
72
+ /**
73
+ * One gas in a body's atmosphere, as one entry of
74
+ * {@link BodyProperties.AtmosphereComposition}.
75
+ */
76
+ interface AtmosphereComponent {
77
+ /** The gas, as the game names it, e.g. `"Nitrogen"`, `"SulphurDioxide"`. */
78
+ readonly Name: string;
79
+ /** Share of the atmosphere, as a **percentage** — `99.124542`, not `0.99124542`. */
80
+ readonly Percent: number;
81
+ }
82
+ /**
83
+ * One material available at a landable body's surface, as one entry of
84
+ * {@link BodyProperties.Materials}.
85
+ *
86
+ * @remarks
87
+ * `Name` is the journal's material symbol in lower case, which is what
88
+ * `getMaterialBySymbol` (`../materials`) takes — the same spelling a `MaterialCollected`
89
+ * line uses.
90
+ */
91
+ interface SurfaceMaterial {
92
+ /** The material's journal symbol, lower-cased, e.g. `"iron"`, `"sulphur"`. */
93
+ readonly Name: string;
94
+ /** The material's display name, when the game localised it into the line. */
95
+ readonly Name_Localised?: string;
96
+ /** Share of the body's surface materials, as a **percentage** out of 100. */
97
+ readonly Percent: number;
98
+ }
99
+ /**
100
+ * What a planet or moon is made of, as {@link BodyProperties.Composition}.
101
+ *
102
+ * @remarks
103
+ * Each share is a **fraction of 1**, not a percentage, and the three sum to 1. This is
104
+ * the body's bulk composition; {@link BodyProperties.Materials} is the separate question
105
+ * of what can be collected from its surface.
106
+ */
107
+ interface BodyComposition {
108
+ /** Ice share of the body, 0–1. */
109
+ readonly Ice: number;
110
+ /** Rock share of the body, 0–1. */
111
+ readonly Rock: number;
112
+ /** Metal share of the body, 0–1. */
113
+ readonly Metal: number;
114
+ }
115
+ /**
116
+ * The physical body a scan describes — everything a calculation reads, and nothing that
117
+ * names the journal line it arrived on.
118
+ *
119
+ * @remarks
120
+ * {@link BodyScanEvent} extends this with the journal's own bookkeeping — `event`,
121
+ * `timestamp`, `ScanType`, `BodyName`, `BodyID`, `StarSystem`, `SystemAddress`,
122
+ * `DistanceFromArrivalLS`, `Parents` and the discovery flags. None of that is physics, so
123
+ * none of it is required here: every field below is optional, and a body assembled from a
124
+ * database row, an EDSM or Spansh record, or a literal in a test is as good an input as a
125
+ * captured line. A `BodyScanEvent` is a `BodyProperties`, so a parsed journal line passes
126
+ * to every calculation unchanged.
127
+ *
128
+ * Each calculation states which fields it needs and returns `null` when one is missing —
129
+ * see `./body-physics`, `./body-orbit`, `./body-rings` and `./star-physics`.
130
+ *
131
+ * Units are the journal's throughout: metres, seconds, kelvin, pascals, Earth masses for
132
+ * a planet and solar masses for a star. Angles are degrees except
133
+ * {@link BodyProperties.AxialTilt | AxialTilt}, which is radians.
134
+ *
135
+ * @example
136
+ * Only the fields a calculation reads need be present.
137
+ *
138
+ * ```ts
139
+ * import type { BodyProperties } from '@elite-dangerous-almanac/core/astro';
140
+ * import { bulkDensity } from '@elite-dangerous-almanac/core/astro/body-physics';
141
+ *
142
+ * const earthLike: BodyProperties = { MassEM: 1, Radius: 6_371_000 };
143
+ *
144
+ * bulkDensity(earthLike); // -> 5513.2…
145
+ * ```
146
+ */
147
+ interface BodyProperties {
148
+ /** Semi-major axis of the body's orbit, in **metres**. */
149
+ readonly SemiMajorAxis?: number;
150
+ /** Orbital eccentricity, 0 for a circular orbit and approaching 1 for a long ellipse. */
151
+ readonly Eccentricity?: number;
152
+ /** Orbital inclination, in **degrees**. */
153
+ readonly OrbitalInclination?: number;
154
+ /** Argument of periapsis, in **degrees**. */
155
+ readonly Periapsis?: number;
156
+ /** Time to complete one orbit, in **seconds**. */
157
+ readonly OrbitalPeriod?: number;
158
+ /** Longitude of the ascending node, in **degrees**. */
159
+ readonly AscendingNode?: number;
160
+ /** Mean anomaly at the moment the body was observed, in **degrees**. */
161
+ readonly MeanAnomaly?: number;
162
+ /**
163
+ * Time to complete one rotation, in **seconds**. Negative when the body rotates
164
+ * retrograde.
165
+ */
166
+ readonly RotationPeriod?: number;
167
+ /**
168
+ * Axial tilt, in **radians** — the one angle here that is not degrees.
169
+ */
170
+ readonly AxialTilt?: number;
171
+ /** Whether the body keeps one face to its parent. */
172
+ readonly TidalLock?: boolean;
173
+ /**
174
+ * The star's spectral class, e.g. `"G"`, `"M"`, `"TTS"` (T Tauri), `"N"` (neutron
175
+ * star), `"H"` (black hole). Present only on a star's line, and the surest way to
176
+ * tell one.
177
+ */
178
+ readonly StarType?: string;
179
+ /** The spectral subclass, 0–9, hotter at 0. */
180
+ readonly Subclass?: number;
181
+ /** The star's mass, in **solar masses**. */
182
+ readonly StellarMass?: number;
183
+ /** The star's absolute magnitude — smaller is brighter, and it can be negative. */
184
+ readonly AbsoluteMagnitude?: number;
185
+ /** The star's age, in **millions of years**. */
186
+ readonly Age_MY?: number;
187
+ /** The star's luminosity class, e.g. `"V"`, `"Va"`, `"VI"`. */
188
+ readonly Luminosity?: string;
189
+ /**
190
+ * The body's class, e.g. `"High metal content body"`, `"Icy body"`,
191
+ * `"Earthlike body"`, `"Water world"`, `"Sudarsky class I gas giant"`. Present only
192
+ * on a planet's or moon's line.
193
+ */
194
+ readonly PlanetClass?: string;
195
+ /**
196
+ * Whether the body's terraforming potential has been realised: `""` when there is
197
+ * none, `"Terraformable"` when it is a candidate, `"Terraformed"` when it already is.
198
+ */
199
+ readonly TerraformState?: string;
200
+ /**
201
+ * The atmosphere as the game describes it in full, e.g.
202
+ * `"thin sulphur dioxide atmosphere"`. `""` when the body has none.
203
+ */
204
+ readonly Atmosphere?: string;
205
+ /**
206
+ * The atmosphere's dominant gas as a bare token, e.g. `"Nitrogen"`,
207
+ * `"SulphurDioxide"`, `"None"`.
208
+ *
209
+ * @remarks
210
+ * The token drops the density and temperature that {@link BodyProperties.Atmosphere | Atmosphere}
211
+ * spells out, so `"thin nitrogen atmosphere"` and `"hot thick nitrogen atmosphere"`
212
+ * share one `AtmosphereType`. Match on this and read the other for the qualifiers.
213
+ */
214
+ readonly AtmosphereType?: string;
215
+ /** What the atmosphere is made of, by percentage. */
216
+ readonly AtmosphereComposition?: readonly AtmosphereComponent[];
217
+ /**
218
+ * The body's volcanism as the game describes it, e.g.
219
+ * `"minor silicate vapour geysers volcanism"`. `""` when the body has none.
220
+ */
221
+ readonly Volcanism?: string;
222
+ /** The body's mass, in **Earth masses**. */
223
+ readonly MassEM?: number;
224
+ /**
225
+ * Surface gravity, in **m/s²** — divide by `9.80665` for the `g` figure the game's
226
+ * own UI shows.
227
+ */
228
+ readonly SurfaceGravity?: number;
229
+ /**
230
+ * Atmospheric pressure at the surface, in **pascals** — divide by `101325` for
231
+ * atmospheres. `0` on an airless body.
232
+ */
233
+ readonly SurfacePressure?: number;
234
+ /** Whether a ship can land on the body. */
235
+ readonly Landable?: boolean;
236
+ /** The body's bulk composition, when the scan resolved it. */
237
+ readonly Composition?: BodyComposition;
238
+ /**
239
+ * The materials collectable at the surface, by percentage.
240
+ *
241
+ * @remarks
242
+ * Written for a landable body. Each `Name` is a journal material symbol that
243
+ * `getMaterialBySymbol` (`../materials`) resolves.
244
+ */
245
+ readonly Materials?: readonly SurfaceMaterial[];
246
+ /**
247
+ * The body's radius, in **metres** — for a star as much as for a planet.
248
+ */
249
+ readonly Radius?: number;
250
+ /** Surface — or, for a star, photospheric — temperature, in **kelvin**. */
251
+ readonly SurfaceTemperature?: number;
252
+ /** The body's rings and belts, absent when it has none. */
253
+ readonly Rings?: readonly BodyRing[];
254
+ /**
255
+ * How rich the body's rings are, e.g. `"PristineResources"`, `"MajorResources"`,
256
+ * `"CommonResources"`, `"LowResources"`, `"DepletedResources"` — the game's reserve
257
+ * levels, each suffixed `Resources`.
258
+ *
259
+ * @remarks
260
+ * Written only when the body has rings, and it describes those rings rather than the
261
+ * body itself.
262
+ */
263
+ readonly ReserveLevel?: string;
264
+ }
265
+ /**
266
+ * A journal `Scan` event — one scanned star, planet, moon or belt cluster, and the
267
+ * library's import shape for body data.
268
+ *
269
+ * @remarks
270
+ * Elite Dangerous writes one `Scan` line per body whenever the discovery scanner, the FSS
271
+ * or a nav beacon resolves it, and that line is the community's lingua franca for bodies:
272
+ * EDDN relays it, EDSM and Spansh store it, every journal-reading app already holds it.
273
+ * So it is what this library takes in, field for field — the journal's own names,
274
+ * capitalisation and units — and a parsed line is already this type:
275
+ *
276
+ * ```ts
277
+ * const scan = JSON.parse(line) as BodyScanEvent;
278
+ * ```
279
+ *
280
+ * **Units are the journal's, and they are not the ones the game's UI shows.** Radii and
281
+ * orbital distances are metres, not light-seconds; pressure is pascals, not atmospheres;
282
+ * surface gravity is m/s², not g; `AxialTilt` is radians while every other angle is
283
+ * degrees. Every field below says which, because getting this wrong is silent — a
284
+ * plausible number in the wrong scale.
285
+ *
286
+ * **Almost every field is optional, because almost every field is conditional.** A star's
287
+ * line carries no {@link BodyProperties.PlanetClass | PlanetClass}, a planet's no
288
+ * {@link BodyProperties.StarType | StarType}, a belt cluster's little beyond its identity, and a body
289
+ * with no rings no {@link BodyProperties.ReserveLevel | ReserveLevel}. Only `ScanType`, `BodyName`,
290
+ * `BodyID`, `StarSystem`, `SystemAddress`, `DistanceFromArrivalLS`, `WasDiscovered` and
291
+ * `WasMapped` are written for every body. Treat a missing field as "not written for this
292
+ * body, or not resolved by this scan" — never as a zero.
293
+ *
294
+ * **A body has no id64 of its own.** {@link BodyScanEvent.SystemAddress | SystemAddress} identifies the
295
+ * system and {@link BodyScanEvent.BodyID | BodyID} the body within it; the pair is the identity to
296
+ * store and join on.
297
+ *
298
+ * `event` and `timestamp` name the journal line rather than the body, and are optional so
299
+ * that a record reassembled from a database or an EDDN message is still this type.
300
+ *
301
+ * @example
302
+ * A parsed line is already the interface, and its address goes straight into the rest of
303
+ * the astro API.
304
+ *
305
+ * ```ts
306
+ * import type { BodyScanEvent } from '@elite-dangerous-almanac/core/astro';
307
+ * import { ProceduralSystem } from '@elite-dangerous-almanac/core/astro/procedural-system';
308
+ *
309
+ * const scan: BodyScanEvent = {
310
+ * event: 'Scan',
311
+ * ScanType: 'Detailed',
312
+ * BodyName: 'Synuefe EN-H d11-96 A 1',
313
+ * BodyID: 3,
314
+ * StarSystem: 'Synuefe EN-H d11-96',
315
+ * SystemAddress: 3309179996515,
316
+ * DistanceFromArrivalLS: 543.2,
317
+ * WasDiscovered: false,
318
+ * WasMapped: false,
319
+ * };
320
+ *
321
+ * ProceduralSystem.fromSystemAddress(scan.SystemAddress).massCode; // -> 'd'
322
+ * ```
323
+ *
324
+ * @example
325
+ * Which kind of body a line describes is told by which fields it carries: `StarType` for
326
+ * a star, `PlanetClass` for a planet or moon, neither for a belt cluster.
327
+ *
328
+ * ```ts
329
+ * import type { BodyScanEvent } from '@elite-dangerous-almanac/core/astro';
330
+ *
331
+ * declare const scan: BodyScanEvent;
332
+ *
333
+ * const kind =
334
+ * scan.StarType !== undefined
335
+ * ? 'star'
336
+ * : scan.PlanetClass !== undefined
337
+ * ? 'planet'
338
+ * : 'belt cluster or barycentre';
339
+ * ```
340
+ *
341
+ * @example
342
+ * A landable body's {@link BodyProperties.Materials | Materials} name journal material symbols, which
343
+ * the materials catalogue reads directly.
344
+ *
345
+ * ```ts
346
+ * import { getMaterialBySymbol } from '@elite-dangerous-almanac/core/materials';
347
+ *
348
+ * getMaterialBySymbol('sulphur')?.name; // -> 'Sulphur'
349
+ * ```
350
+ */
351
+ interface BodyScanEvent extends BodyProperties {
352
+ /** `"Scan"` when a journal line supplied it. */
353
+ readonly event?: string;
354
+ /** When the scan happened, ISO 8601 in UTC, e.g. `"2026-08-26T21:04:11Z"`. */
355
+ readonly timestamp?: string;
356
+ /**
357
+ * How the body was scanned: `"AutoScan"` (passive, on approach or from the discovery
358
+ * scanner's honk), `"Basic"`, `"Detailed"` (resolved in the FSS or by flying to the
359
+ * body) or `"NavBeaconDetail"` (read off a populated system's nav beacon).
360
+ *
361
+ * @remarks
362
+ * This is the field that decides how much of the rest is present. A `"Detailed"` or
363
+ * `"NavBeaconDetail"` line is the full record; an `"AutoScan"` of a distant body may
364
+ * carry little more than its identity and orbit.
365
+ */
366
+ readonly ScanType: string;
367
+ /** The body's in-game name, e.g. `"Synuefe EN-H d11-96 A 1"`. */
368
+ readonly BodyName: string;
369
+ /**
370
+ * The body's id within its system, unique and stable there, with the system's first
371
+ * star at 0.
372
+ *
373
+ * @remarks
374
+ * A body has no galaxy-wide id of its own: `SystemAddress` + `BodyID` is the identity
375
+ * to store and join on. It is also what {@link BodyParent} entries point at.
376
+ */
377
+ readonly BodyID: number;
378
+ /** The system's name, e.g. `"Synuefe EN-H d11-96"`. */
379
+ readonly StarSystem: string;
380
+ /**
381
+ * The system's `id64` address.
382
+ *
383
+ * @remarks
384
+ * Typed as {@link SystemAddressInput} rather than `number`, so the value survives
385
+ * however the line was parsed: `JSON.parse` yields a `number`, a lossless parser a
386
+ * `bigint`, a database column a decimal `string`. All three pass straight into
387
+ * `decodeSystemAddress`, `ProceduralSystem.fromSystemAddress` and the permit-lock
388
+ * lookups. Addresses reach bit 55, so a `number` beyond `2^53 - 1` has already been
389
+ * rounded — those entry points reject one rather than answer for the wrong system.
390
+ */
391
+ readonly SystemAddress: SystemAddressInput;
392
+ /**
393
+ * Distance from the system's arrival point, in **light-seconds**. The main star reads
394
+ * `0`.
395
+ */
396
+ readonly DistanceFromArrivalLS: number;
397
+ /**
398
+ * The body's parent chain, nearest first and ending at the system's root — so a moon
399
+ * reads `[{ Planet: … }, { Star: 0 }]`.
400
+ *
401
+ * @remarks
402
+ * Absent for a body that orbits nothing, i.e. a single-star system's main star.
403
+ */
404
+ readonly Parents?: readonly BodyParent[];
405
+ /** Whether someone had already discovered the body before this scan. */
406
+ readonly WasDiscovered: boolean;
407
+ /** Whether someone had already surface-mapped the body before this scan. */
408
+ readonly WasMapped: boolean;
409
+ /**
410
+ * Whether someone had already set foot on the body. Written since Odyssey, and only
411
+ * for a body that can be walked on.
412
+ */
413
+ readonly WasFootfalled?: boolean;
414
+ }
415
+
416
+ export type { AtmosphereComponent as A, BodyComposition as B, SurfaceMaterial as S, BodyParent as a, BodyProperties as b, BodyRing as c, BodyScanEvent as d };
@@ -0,0 +1 @@
1
+ import{requireFiniteNonNegative}from"./chunk-65FZECUX.js";function combinedRateOfFire(weapon){const interval=weapon.burstInterval;if(interval===void 0||interval<=0)return void 0;const burst=weapon.burstRounds&&weapon.burstRounds>0?weapon.burstRounds:1;const burstRate=weapon.burstRateOfFire&&weapon.burstRateOfFire>0?weapon.burstRateOfFire:1;const cycle=(burst>1?(burst-1)/burstRate:0)+interval;return cycle>0?burst/cycle:void 0}var ZERO_SPLIT={kinetic:0,thermal:0,explosive:0,absolute:0,antiXeno:0};function splitDamage(damage,distribution){if(!distribution)return Object.freeze({...ZERO_SPLIT,absolute:damage});return Object.freeze({kinetic:damage*(distribution.kinetic??0),thermal:damage*(distribution.thermal??0),explosive:damage*(distribution.explosive??0),absolute:damage*(distribution.absolute??0),...(distribution.unclassified??0)===0?{}:{unclassified:damage*distribution.unclassified},antiXeno:damage*(distribution.antiXeno??0)})}function splitComponents(damage,components){const unclassified=(components.unclassified??[]).reduce((sum,value)=>sum+value,0);const conventional=(components.kinetic??0)+(components.thermal??0)+(components.explosive??0)+(components.absolute??0)+unclassified;if(conventional<=0)return Object.freeze({...ZERO_SPLIT,absolute:damage});const scale=damage/conventional;return Object.freeze({kinetic:(components.kinetic??0)*scale,thermal:(components.thermal??0)*scale,explosive:(components.explosive??0)*scale,absolute:(components.absolute??0)*scale,...unclassified===0?{}:{unclassified:unclassified*scale},antiXeno:(components.antiXeno??0)*scale})}function sustainedFireFactor(weapon){const rateOfFire=weapon.rateOfFire;const clip=weapon.clipSize===void 0?void 0:Math.ceil(weapon.clipSize);if(!rateOfFire||!clip||clip<=0)return 1;const burst=weapon.burstRounds&&weapon.burstRounds>0?weapon.burstRounds:1;const burstRate=weapon.burstRateOfFire&&weapon.burstRateOfFire>0?weapon.burstRateOfFire:1;const reload=weapon.reloadTime??0;const cycle=(clip-burst)/rateOfFire+(burst-1)/burstRate+reload;if(cycle<=0)return 1;const sustainedRate=clip/cycle;return Math.min(1,sustainedRate/rateOfFire)}function damagePerSecond(weapon){const damage=weapon.damage??0;const rounds=weapon.roundsPerShot&&weapon.roundsPerShot>0?weapon.roundsPerShot:1;return damage*rounds*(weapon.rateOfFire??1)}function sustainedDamagePerSecond(weapon){return damagePerSecond(weapon)*sustainedFireFactor(weapon)}function energyPerSecond(weapon){return(weapon.distributorDraw??0)*(weapon.rateOfFire??1)}function heatPerSecond(weapon){return(weapon.thermalLoad??0)*(weapon.rateOfFire??1)}function damageFalloff(weapon,metres){const maximum=weapon.maximumRange;if(maximum!==void 0&&metres>maximum)return 0;const falloff=weapon.falloffRange;if(falloff===void 0||maximum===void 0||metres<=falloff)return 1;const taper=maximum-falloff;if(taper<=0)return 1;return Math.max(0,1-(metres-falloff)/taper)}function armourPiercingFactor(armourPiercing,hardness){requireFiniteNonNegative("armourPiercingFactor","armour piercing",armourPiercing);requireFiniteNonNegative("armourPiercingFactor","hardness",hardness);if(hardness===0)return 1;return Math.min(1,armourPiercing/hardness)}function weaponMetrics(weapon){const continuous=weapon.rateOfFire===void 0;const rateOfFire=weapon.rateOfFire??1;const factor=sustainedFireFactor(weapon);const dps=damagePerSecond(weapon);const sdps=dps*factor;const eps=energyPerSecond(weapon);const hps=heatPerSecond(weapon);const rounds=weapon.roundsPerShot&&weapon.roundsPerShot>0?weapon.roundsPerShot:1;return Object.freeze({damagePerShot:(weapon.damage??0)*rounds,rateOfFire:rateOfFire,sustainedRateOfFire:rateOfFire*factor,damagePerSecond:dps,sustainedDamagePerSecond:sdps,energyPerSecond:eps,sustainedEnergyPerSecond:eps*factor,heatPerSecond:hps,sustainedHeatPerSecond:hps*factor,thermalLoad:weapon.thermalLoad??0,powerDraw:weapon.powerDraw??0,damageByType:weapon.damageComponents?splitComponents(dps,weapon.damageComponents):splitDamage(dps,weapon.damageDistribution),sustainedDamageByType:weapon.damageComponents?splitComponents(sdps,weapon.damageComponents):splitDamage(sdps,weapon.damageDistribution),continuous:continuous})}function sumWeaponMetrics(metrics){const damageByType=emptyDamageSplitAccumulator();const sustainedDamageByType=emptyDamageSplitAccumulator();let damagePerSecond2=0;let sustainedDamagePerSecond2=0;let energyPerSecond2=0;let sustainedEnergyPerSecond=0;let heatPerSecond2=0;let sustainedHeatPerSecond=0;let thermalLoad=0;let powerDraw=0;for(const metric of metrics){damagePerSecond2+=metric.damagePerSecond;sustainedDamagePerSecond2+=metric.sustainedDamagePerSecond;energyPerSecond2+=metric.energyPerSecond;sustainedEnergyPerSecond+=metric.sustainedEnergyPerSecond;heatPerSecond2+=metric.heatPerSecond;sustainedHeatPerSecond+=metric.sustainedHeatPerSecond;thermalLoad+=metric.thermalLoad;powerDraw+=metric.powerDraw;addDamageSplit(damageByType,metric.damageByType);addDamageSplit(sustainedDamageByType,metric.sustainedDamageByType)}return Object.freeze({damagePerSecond:damagePerSecond2,sustainedDamagePerSecond:sustainedDamagePerSecond2,energyPerSecond:energyPerSecond2,sustainedEnergyPerSecond:sustainedEnergyPerSecond,heatPerSecond:heatPerSecond2,sustainedHeatPerSecond:sustainedHeatPerSecond,thermalLoad:thermalLoad,powerDraw:powerDraw,damageByType:finishDamageSplit(damageByType),sustainedDamageByType:finishDamageSplit(sustainedDamageByType)})}function emptyDamageSplitAccumulator(){return{kinetic:0,thermal:0,explosive:0,absolute:0,unclassified:0,antiXeno:0}}function addDamageSplit(total,split){total.kinetic+=split.kinetic;total.thermal+=split.thermal;total.explosive+=split.explosive;total.absolute+=split.absolute;total.unclassified+=split.unclassified??0;total.antiXeno+=split.antiXeno}function finishDamageSplit(total){const{unclassified:unclassified,...classified}=total;return Object.freeze(unclassified===0?classified:{...classified,unclassified:unclassified})}export{armourPiercingFactor,combinedRateOfFire,damageFalloff,damagePerSecond,energyPerSecond,heatPerSecond,splitDamage,sumWeaponMetrics,sustainedDamagePerSecond,sustainedFireFactor,weaponMetrics};//# sourceMappingURL=chunk-37JIMWLK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ships/weapons.ts"],"names":["requireFiniteNonNegative","combinedRateOfFire","weapon","interval","burstInterval","burst","burstRounds","burstRate","burstRateOfFire","cycle","ZERO_SPLIT","kinetic","thermal","explosive","absolute","antiXeno","splitDamage","damage","distribution","Object","freeze","unclassified","splitComponents","components","reduce","sum","value","conventional","scale","sustainedFireFactor","rateOfFire","clip","clipSize","Math","ceil","reload","reloadTime","sustainedRate","min","damagePerSecond","rounds","roundsPerShot","sustainedDamagePerSecond","energyPerSecond","distributorDraw","heatPerSecond","thermalLoad","damageFalloff","metres","maximum","maximumRange","falloff","falloffRange","taper","max","armourPiercingFactor","armourPiercing","hardness","weaponMetrics","continuous","factor","dps","sdps","eps","hps","damagePerShot","sustainedRateOfFire","sustainedEnergyPerSecond","sustainedHeatPerSecond","powerDraw","damageByType","damageComponents","damageDistribution","sustainedDamageByType","sumWeaponMetrics","metrics","emptyDamageSplitAccumulator","metric","addDamageSplit","finishDamageSplit","total","split","classified"],"mappings":"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"}
@@ -1 +1 @@
1
- import{ALL_MODULES}from"./chunk-QY3L5BKN.js";import{findInKeyIndex,findByKey,filterByKey,createKeyIndex}from"./chunk-BKWLI44T.js";var MODULES_BY_SYMBOL=/* @__PURE__ */createKeyIndex(ALL_MODULES,"symbol");function builtInModuleBySymbol(symbol,label){return findInKeyIndex(MODULES_BY_SYMBOL,symbol,label)}function getModuleBySymbol(symbol,modules=ALL_MODULES){return modules===ALL_MODULES?builtInModuleBySymbol(symbol,"getModuleBySymbol: symbol"):findByKey(modules,"symbol",symbol,"getModuleBySymbol: symbol")}function getModulesByName(name,modules=ALL_MODULES){return filterByKey(modules,"name",name,"getModulesByName: name")}function getBulkheadsForShip(ship,modules=ALL_MODULES){return filterByKey(modules,"ship",ship,"getBulkheadsForShip: ship")}export{builtInModuleBySymbol,getBulkheadsForShip,getModuleBySymbol,getModulesByName};//# sourceMappingURL=chunk-PA5EITW5.js.map
1
+ import{ALL_MODULES}from"./chunk-7ZERP4TB.js";import{findInKeyIndex,findByKey,filterByKey,createKeyIndex}from"./chunk-BKWLI44T.js";var MODULES_BY_SYMBOL=/* @__PURE__ */createKeyIndex(ALL_MODULES,"symbol");function builtInModuleBySymbol(symbol,label){return findInKeyIndex(MODULES_BY_SYMBOL,symbol,label)}function getModuleBySymbol(symbol,modules=ALL_MODULES){return modules===ALL_MODULES?builtInModuleBySymbol(symbol,"getModuleBySymbol: symbol"):findByKey(modules,"symbol",symbol,"getModuleBySymbol: symbol")}function getModulesByName(name,modules=ALL_MODULES){return filterByKey(modules,"name",name,"getModulesByName: name")}function getBulkheadsForShip(ship,modules=ALL_MODULES){return filterByKey(modules,"ship",ship,"getBulkheadsForShip: ship")}export{builtInModuleBySymbol,getBulkheadsForShip,getModuleBySymbol,getModulesByName};//# sourceMappingURL=chunk-3LZXB2MC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ships/internal/module-symbol-index.ts","../src/ships/modules.ts"],"names":["ALL_MODULES","findInKeyIndex","findByKey","filterByKey","createKeyIndex","MODULES_BY_SYMBOL","builtInModuleBySymbol","symbol","label","getModuleBySymbol","modules","getModulesByName","name","getBulkheadsForShip","ship"],"mappings":"O,2HAMA,IAAMK,iCAAoCD,eAAeJ,YAAa,UAS/D,SAASM,sBAAsBC,OAAgBC,OAClD,OAAOP,eAAeI,kBAAmBE,OAAQC,MACrD,CCg1BO,SAASC,kBACZF,OACAG,QAAuCV,aAEvC,OAAOU,UAAYV,YACbM,sBAAsBC,OAAQ,6BAC9BL,UAAUQ,QAAS,SAAUH,OAAQ,4BAC/C,CAoBO,SAASI,iBACZC,KACAF,QAAuCV,aAEvC,OAAOG,YAAYO,QAAS,OAAQE,KAAM,yBAC9C,CA8BO,SAASC,oBACZC,KACAJ,QAAuCV,aAEvC,OAAOG,YAAYO,QAAS,OAAQI,KAAM,4BAC9C,QAAAR,sBAAAO,oBAAAJ,kBAAAE"}
1
+ {"version":3,"sources":["../src/ships/internal/module-symbol-index.ts","../src/ships/modules.ts"],"names":["ALL_MODULES","findInKeyIndex","findByKey","filterByKey","createKeyIndex","MODULES_BY_SYMBOL","builtInModuleBySymbol","symbol","label","getModuleBySymbol","modules","getModulesByName","name","getBulkheadsForShip","ship"],"mappings":"O,2HAMA,IAAMK,iCAAoCD,eAAeJ,YAAa,UAS/D,SAASM,sBAAsBC,OAAgBC,OAClD,OAAOP,eAAeI,kBAAmBE,OAAQC,MACrD,CCo2BO,SAASC,kBACZF,OACAG,QAAuCV,aAEvC,OAAOU,UAAYV,YACbM,sBAAsBC,OAAQ,6BAC9BL,UAAUQ,QAAS,SAAUH,OAAQ,4BAC/C,CAoBO,SAASI,iBACZC,KACAF,QAAuCV,aAEvC,OAAOG,YAAYO,QAAS,OAAQE,KAAM,yBAC9C,CA8BO,SAASC,oBACZC,KACAJ,QAAuCV,aAEvC,OAAOG,YAAYO,QAAS,OAAQI,KAAM,4BAC9C,QAAAR,sBAAAO,oBAAAJ,kBAAAE"}
@@ -0,0 +1 @@
1
+ import{cellBankSummary,shieldRecovery}from"./chunk-JMAXSXXQ.js";import{loadoutInternals,fittedThrusterParamsFor,preEngineeredVariantFor,powerConsumerFor,powerAvailable,heatInputResultFor,completeResult,cellBankInputsFor,armourInputFor,weaponStatsFor,weaponsCapacitorInputFor,mobilityInputResultFor,shieldInputResultFor,shieldCapacitorInputResultFor,shieldRecoveryInputResultFor,distributorInputResultFor,incompleteResult}from"./chunk-SS6XK336.js";import{shieldMetrics}from"./chunk-5VWACBTN.js";import{weaponsCapacitorMetrics}from"./chunk-M4FZRDAH.js";import{powerBudget}from"./chunk-GGQMIQPC.js";import{isNonOutfittingSlot,isBuiltInHullModule,orderBySlotLayout}from"./chunk-4OTQBHQL.js";import{weaponMetrics,sumWeaponMetrics}from"./chunk-37JIMWLK.js";import{shieldCapacitorMetrics}from"./chunk-XQJERZUS.js";import{mobilityCapacitorMetrics}from"./chunk-VEEBJFJ7.js";import{mobilityMetrics}from"./chunk-A4QKXXZD.js";import{getExperimentalEffectCost}from"./chunk-CJK2IBI2.js";import{heatMetrics}from"./chunk-6HA2YIKW.js";import{frameShiftDriveMassFactor,singleJumpRange,fuelPerJump,totalRange}from"./chunk-VTMCSCXV.js";import{calculateUnladenMass}from"./chunk-DCB4COCL.js";import{getBlueprintCost}from"./chunk-MTJ4MS7W.js";import{distributorMetrics}from"./chunk-M2TCZKRT.js";import{sumMaterials}from"./chunk-CJQ37JII.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{armourMetrics}from"./chunk-Q5ALV3DI.js";import{requirePips,requireFiniteNonNegative}from"./chunk-65FZECUX.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var FACADE="BuildMetrics";function requireLoadOptions(scope,options){for(const field of["fuel","cargo"]){const value=options[field];if(value!==void 0)requireFiniteNonNegative(scope,field,value)}}var BuildMetrics=class _BuildMetrics{#build;#state;constructor(build,state){this.#build=build;this.#state=state}static of(build){return new _BuildMetrics(build,loadoutInternals(build,`${FACADE}.of: build`))}loadout(){return this.#build}frameShiftDrive(){const drive=this.#state.resolveDrive();if(drive===null){throw new TypeError(`${FACADE}: build has no frame shift drive`)}return drive}thrusters(){return fittedThrusterParamsFor(this.#state.modules(),this.#state.statsFor)}frameShiftDriveMassFactor(options={}){requireLoadOptions(`${FACADE}.frameShiftDriveMassFactor`,options);return frameShiftDriveMassFactor(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}maxJumpRange(){const fsd=this.frameShiftDrive();return singleJumpRange(this.#loadedMass(0),this.#maxJumpFuel(fsd),fsd)}jumpRange(options={}){requireLoadOptions(`${FACADE}.jumpRange`,options);return singleJumpRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}ladenJumpRange(){return this.jumpRange({cargo:this.#build.cargoCapacity})}fuelPerJump(distance,options={}){requireLoadOptions(`${FACADE}.fuelPerJump`,options);return fuelPerJump(distance,this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}totalRange(options={}){requireLoadOptions(`${FACADE}.totalRange`,options);return totalRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}standardLoadResult(load){return this.#standardLoad(load)}jumpRangeSummary(){const maximum=this.#require(this.standardLoadResult("maximum"),"maximum load");const unladen=this.#require(this.standardLoadResult("unladen"),"unladen load");const laden=this.#require(this.standardLoadResult("laden"),"laden load");return{max:this.jumpRange(maximum),unladen:this.jumpRange(unladen),laden:this.jumpRange(laden),totalMax:this.totalRange(maximum),totalUnladen:this.totalRange(unladen),totalLaden:this.totalRange(laden)}}buildMass(options={}){requireLoadOptions(`${FACADE}.buildMass`,options);const unladen=this.#build.unladenMass;const fuel=options.fuel??this.#build.fuelCapacity.main;const cargo=options.cargo??0;return Object.freeze({hull:this.#state.ship.hullMass,modules:calculateUnladenMass(0,this.#state.calculationModules()),unladen:unladen,fuel:fuel,cargo:cargo,total:unladen+fuel+cargo})}buildCost(){const hull=this.#state.ship.hullCost;let modules=0;let mercCoins=0;const unpriced=[];const materials=[];for(const module of this.#state.modules()){const stats=this.#state.statsFor(module);if(stats?.cost!==void 0){modules+=stats.cost}else if(stats!==null||!isNonOutfittingSlot(module.Slot)&&!isBuiltInHullModule(module)){unpriced.push({slot:module.Slot,symbol:module.Item})}const variant=preEngineeredVariantFor(module);mercCoins+=variant?.mercCoinCost??0;const engineering=module.Engineering;if(!engineering)continue;const grade=engineering.Level;const bought=variant?.grade??0;if(Number.isInteger(grade)&&grade>bought&&grade<=5){const climb=getBlueprintCost(engineering.BlueprintName,grade,bought);if(climb){materials.push(climb.materials);mercCoins+=climb.mercCoins}}const experimental=engineering.ExperimentalEffect;if(experimental!==void 0&&experimental.toLowerCase()!==variant?.experimentalEffectSymbol?.toLowerCase()){const cost=getExperimentalEffectCost(experimental);if(cost)materials.push(cost)}}return deepFreeze({credits:{total:hull+modules,hull:hull,modules:modules,rebuy:Math.trunc((hull+modules)*.05),unpriced:unpriced},mercCoins:mercCoins,materials:sumMaterials(...materials)})}powerBudget(){const modules=this.#state.modules();const consumers=[];for(const module of modules){const consumer=powerConsumerFor(module,this.#state.statsFor(module));if(consumer)consumers.push(consumer)}return powerBudget(powerAvailable(modules,this.#state.statsFor),consumers)}heatMetricsResult(){const input=heatInputResultFor(this.#state.ship,this.#state.effectiveModules(),this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(heatMetrics(input.value)):input}mobilityMetricsResult(options={}){return this.#mobility(options)}mobilityCapacitorMetricsResult(options={}){return this.#mobilityCapacitor(options)}shieldMetricsResult(){return this.#shields()}shieldCapacitorMetricsResult(options={}){return this.#shieldCapacitor(options)}shieldRecoveryResult(options={}){return this.#recovery(options)}cellBanks(){return cellBankSummary(orderBySlotLayout(cellBankInputsFor(this.#state.modules(),this.powerBudget(),this.#state.statsFor),this.#state.layout(),bank=>bank.slot))}armourMetrics(){return armourMetrics(armourInputFor(this.#state.ship,this.#state.modules(),this.#state.statsFor))}weaponMetrics(){const weapons=[];for(const module of this.#state.modules()){const record=this.#state.statsFor(module);const stats=weaponStatsFor(this.#state.effectiveModule(module),record);if(!stats)continue;weapons.push({slot:module.Slot,symbol:module.Item,name:record?.name??module.Item,enabled:module.On!==false,metrics:weaponMetrics(stats),ammunition:ammunitionCapacity(stats),...stats.maximumRange===void 0?{}:{maximumRange:stats.maximumRange},...stats.falloffRange===void 0?{}:{falloffRange:stats.falloffRange},...stats.projectileRange===void 0?{}:{projectileRange:{...stats.projectileRange}},...stats.armourPiercing===void 0?{}:{armourPiercing:stats.armourPiercing}})}const orderedWeapons=orderBySlotLayout(weapons,this.#state.layout(),weapon=>weapon.slot);return{weapons:orderedWeapons,total:sumWeaponMetrics(orderedWeapons.filter(weapon=>weapon.enabled).map(weapon=>weapon.metrics))}}weaponsCapacitorMetrics(options={}){const weaponsPips=requirePips(`${FACADE}.weaponsCapacitorMetrics`,"weaponsPips",options.weaponsPips??4);return weaponsCapacitorMetrics(weaponsCapacitorInputFor(this.#state.effectiveModules(),weaponsPips,this.powerBudget(),this.#state.statsFor))}distributorMetricsResult(options={}){return this.#distributor(options)}#mobility(options){const input=this.#mobilityInput(`${FACADE}.mobilityMetricsResult`,options);return input.complete?completeResult(mobilityMetrics(input.value)):input}#mobilityCapacitor(options){const scope=`${FACADE}.mobilityCapacitorMetricsResult`;const enginesPips=requirePips(scope,"enginesPips",options.enginesPips??4);const input=this.#mobilityInput(scope,options);return input.complete?completeResult(mobilityCapacitorMetrics({...input.value,enginesPips:enginesPips})):input}#mobilityInput(scope,options){requireLoadOptions(scope,options);return mobilityInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),()=>this.#loadedMass(options.cargo??0)+(options.fuel??this.#state.statedMainFuel()??this.#build.fuelCapacity.main),this.#state.statsFor)}#shields(){const input=shieldInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(shieldMetrics(input.value)):input}#shieldCapacitor(options){const systemsPips=requirePips(`${FACADE}.shieldCapacitorMetricsResult`,"systemsPips",options.systemsPips??4);const input=shieldCapacitorInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldCapacitorMetrics(input.value)):input}#recovery(options){const systemsPips=requirePips(`${FACADE}.shieldRecoveryResult`,"systemsPips",options.systemsPips??4);const input=shieldRecoveryInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldRecovery(input.value)):input}#distributor(options){const scope=`${FACADE}.distributorMetricsResult`;const pips={systemsPips:requirePips(scope,"systemsPips",options.systemsPips??4),enginesPips:requirePips(scope,"enginesPips",options.enginesPips??4),weaponsPips:requirePips(scope,"weaponsPips",options.weaponsPips??4)};const input=distributorInputResultFor(this.#state.effectiveModules(),pips,this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(distributorMetrics(input.value)):input}#standardLoad(load){if(load!=="maximum"&&load!=="unladen"&&load!=="laden"){throw new RangeError(`${FACADE}.standardLoadResult: load must be 'maximum', 'unladen', or 'laden'`)}const fuel=this.#build.fuelCapacity;const cargo=load==="laden"?this.#build.cargoCapacity:0;const mass=load==="maximum"?this.#build.unladenMass:0;let drive=null;let maximumFuel=null;if(load==="maximum"){const fitted=this.#state.frameShiftDriveModule();let driveError=null;try{drive=this.#state.resolveDrive();maximumFuel=drive?.maxFuel??null}catch(error){if(!(error instanceof Error))throw error;driveError=error}if(maximumFuel===null){return incompleteResult([{field:"frameShiftDrive",reason:fitted?"unresolved":"missing",slot:fitted?.Slot??"FrameShiftDrive",...fitted?{symbol:fitted.Item}:{},message:driveError?.message??"FrameShiftDrive: no frame shift drive is fitted",params:fitted?{field:"frameShiftDrive",reason:"unresolved",slot:fitted.Slot,symbol:fitted.Item}:{field:"frameShiftDrive",reason:"missing",slot:"FrameShiftDrive"}}])}}const carriedFuel=load==="maximum"?Math.min(fuel.main,maximumFuel):fuel.main;const value=Object.freeze({fuel:carriedFuel,cargo:cargo,mass:this.#build.unladenMass+carriedFuel+cargo});if(load==="maximum"){try{this.jumpRange(value)}catch(error){if(!(error instanceof RangeError))throw error;const fitted=this.#state.frameShiftDriveModule();const field=drive!==null&&(!Number.isFinite(drive.maxFuel)||drive.maxFuel<0)?"frameShiftDrive":!Number.isFinite(value.fuel)||value.fuel<0?"fuelCapacity":!Number.isFinite(mass)||mass<0?"mass":"frameShiftDrive";const driveParams=field==="frameShiftDrive"&&fitted?{slot:fitted.Slot,symbol:fitted.Item}:{};return incompleteResult([{field:field,reason:"invalid",...driveParams,message:error.message,params:{field:field,reason:"invalid",...driveParams}}])}}return completeResult(value)}#require(result,what){if(result.value===null){throw new TypeError(`${FACADE}: cannot determine ${what} (${result.issues.map(issue=>issue.message).join("; ")})`)}return result.value}#loadedMass(cargo){return this.#build.unladenMass+cargo}#maxJumpFuel(fsd){return Math.min(this.#build.fuelCapacity.main,fsd.maxFuel)}};export{BuildMetrics};//# sourceMappingURL=chunk-3RTUSDQF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ships/build-metrics.ts"],"names":["cellBankSummary","shieldRecovery","loadoutInternals","fittedThrusterParamsFor","preEngineeredVariantFor","powerConsumerFor","powerAvailable","heatInputResultFor","completeResult","cellBankInputsFor","armourInputFor","weaponStatsFor","weaponsCapacitorInputFor","mobilityInputResultFor","shieldInputResultFor","shieldCapacitorInputResultFor","shieldRecoveryInputResultFor","distributorInputResultFor","incompleteResult","shieldMetrics","weaponsCapacitorMetrics","powerBudget","isNonOutfittingSlot","isBuiltInHullModule","orderBySlotLayout","weaponMetrics","sumWeaponMetrics","shieldCapacitorMetrics","mobilityCapacitorMetrics","mobilityMetrics","getExperimentalEffectCost","heatMetrics","frameShiftDriveMassFactor","singleJumpRange","fuelPerJump","totalRange","calculateUnladenMass","getBlueprintCost","distributorMetrics","sumMaterials","ammunitionCapacity","armourMetrics","requirePips","requireFiniteNonNegative","deepFreeze","FACADE","requireLoadOptions","scope","options","field","value","BuildMetrics","_BuildMetrics","build","state","constructor","this","of","loadout","frameShiftDrive","drive","resolveDrive","TypeError","thrusters","modules","statsFor","loadedMass","cargo","fuel","fuelCapacity","main","maxJumpRange","fsd","maxJumpFuel","jumpRange","ladenJumpRange","cargoCapacity","distance","standardLoadResult","load","standardLoad","jumpRangeSummary","maximum","require","unladen","laden","max","totalMax","totalUnladen","totalLaden","buildMass","unladenMass","Object","freeze","hull","ship","hullMass","calculationModules","total","buildCost","hullCost","mercCoins","unpriced","materials","module","stats","cost","Slot","push","slot","symbol","Item","variant","mercCoinCost","engineering","Engineering","grade","Level","bought","Number","isInteger","climb","BlueprintName","experimental","ExperimentalEffect","toLowerCase","experimentalEffectSymbol","credits","rebuy","Math","trunc","consumers","consumer","heatMetricsResult","input","effectiveModules","complete","mobilityMetricsResult","mobility","mobilityCapacitorMetricsResult","mobilityCapacitor","shieldMetricsResult","shields","shieldCapacitorMetricsResult","shieldCapacitor","shieldRecoveryResult","recovery","cellBanks","layout","bank","weapons","record","effectiveModule","name","enabled","On","metrics","ammunition","maximumRange","falloffRange","projectileRange","armourPiercing","orderedWeapons","weapon","filter","map","weaponsPips","distributorMetricsResult","distributor","mobilityInput","enginesPips","statedMainFuel","systemsPips","pips","RangeError","mass","maximumFuel","fitted","frameShiftDriveModule","driveError","maxFuel","error","Error","reason","message","params","carriedFuel","min","isFinite","driveParams","result","what","issues","issue","join"],"mappings":"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"}