@classytic/stage 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +18 -0
  2. package/dist/atomic/aufbau.d.mts +144 -0
  3. package/dist/atomic/aufbau.mjs +384 -0
  4. package/dist/atomic/elements.d.mts +67 -0
  5. package/dist/atomic/elements.mjs +785 -0
  6. package/dist/atomic/emission.d.mts +112 -0
  7. package/dist/atomic/emission.mjs +179 -0
  8. package/dist/atomic/index.d.mts +8 -0
  9. package/dist/atomic/index.mjs +9 -0
  10. package/dist/atomic/periodic.d.mts +82 -0
  11. package/dist/atomic/periodic.mjs +231 -0
  12. package/dist/atomic/properties.d.mts +100 -0
  13. package/dist/atomic/properties.mjs +574 -0
  14. package/dist/atomic/shells.d.mts +137 -0
  15. package/dist/atomic/shells.mjs +170 -0
  16. package/dist/atomic/trends.d.mts +148 -0
  17. package/dist/atomic/trends.mjs +225 -0
  18. package/dist/chem/chromatography.d.mts +66 -0
  19. package/dist/chem/chromatography.mjs +63 -0
  20. package/dist/chem/complex.d.mts +114 -0
  21. package/dist/chem/complex.mjs +234 -0
  22. package/dist/chem/cycle.d.mts +75 -0
  23. package/dist/chem/cycle.mjs +145 -0
  24. package/dist/chem/equation.d.mts +86 -0
  25. package/dist/chem/equation.mjs +168 -0
  26. package/dist/chem/formula.d.mts +90 -0
  27. package/dist/chem/formula.mjs +201 -0
  28. package/dist/chem/functional-groups.d.mts +31 -0
  29. package/dist/chem/functional-groups.mjs +187 -0
  30. package/dist/chem/hazard.d.mts +94 -0
  31. package/dist/chem/hazard.mjs +329 -0
  32. package/dist/chem/index.d.mts +34 -33
  33. package/dist/chem/index.mjs +34 -28
  34. package/dist/chem/ionic.d.mts +98 -0
  35. package/dist/chem/ionic.mjs +156 -0
  36. package/dist/chem/layout.d.mts +46 -0
  37. package/dist/chem/layout.mjs +342 -0
  38. package/dist/chem/lewis.d.mts +79 -0
  39. package/dist/chem/lewis.mjs +163 -0
  40. package/dist/chem/molecular-orbital.d.mts +114 -0
  41. package/dist/chem/molecular-orbital.mjs +201 -0
  42. package/dist/chem/molecule.d.mts +154 -0
  43. package/dist/chem/molecule.mjs +282 -0
  44. package/dist/chem/nmr.d.mts +153 -0
  45. package/dist/chem/nmr.mjs +165 -0
  46. package/dist/chem/polymer.d.mts +65 -0
  47. package/dist/chem/polymer.mjs +179 -0
  48. package/dist/chem/redox.d.mts +138 -0
  49. package/dist/chem/redox.mjs +328 -0
  50. package/dist/chem/relations.d.mts +183 -0
  51. package/dist/chem/relations.mjs +299 -0
  52. package/dist/chem/skeleton.d.mts +51 -0
  53. package/dist/chem/skeleton.mjs +186 -0
  54. package/dist/chem/solution.d.mts +116 -0
  55. package/dist/chem/solution.mjs +186 -0
  56. package/dist/chem/species.d.mts +47 -0
  57. package/dist/chem/species.mjs +128 -0
  58. package/dist/chem/stereo.d.mts +108 -0
  59. package/dist/chem/stereo.mjs +286 -0
  60. package/dist/chem/stoichiometry.d.mts +95 -0
  61. package/dist/chem/stoichiometry.mjs +145 -0
  62. package/dist/chem/synthesis.d.mts +113 -0
  63. package/dist/chem/synthesis.mjs +281 -0
  64. package/dist/chem/vsepr.d.mts +80 -0
  65. package/dist/chem/vsepr.mjs +247 -0
  66. package/dist/circuit/ac.d.mts +163 -0
  67. package/dist/circuit/ac.mjs +452 -0
  68. package/dist/circuit/dc.d.mts +92 -0
  69. package/dist/circuit/dc.mjs +333 -0
  70. package/dist/circuit/index.d.mts +5 -92
  71. package/dist/circuit/index.mjs +5 -332
  72. package/dist/circuit/network.d.mts +99 -0
  73. package/dist/circuit/network.mjs +440 -0
  74. package/dist/circuit/topology.d.mts +102 -0
  75. package/dist/circuit/topology.mjs +143 -0
  76. package/dist/colour/absorption.d.mts +79 -0
  77. package/dist/colour/absorption.mjs +137 -0
  78. package/dist/colour/index.d.mts +6 -0
  79. package/dist/colour/index.mjs +7 -0
  80. package/dist/colour/name.d.mts +14 -0
  81. package/dist/colour/name.mjs +76 -0
  82. package/dist/colour/observer.d.mts +31 -0
  83. package/dist/colour/observer.mjs +46 -0
  84. package/dist/colour/spectrum.d.mts +61 -0
  85. package/dist/colour/spectrum.mjs +108 -0
  86. package/dist/colour/srgb.d.mts +49 -0
  87. package/dist/colour/srgb.mjs +108 -0
  88. package/dist/core/constants.d.mts +138 -0
  89. package/dist/core/constants.mjs +139 -0
  90. package/dist/core/index.d.mts +3 -1
  91. package/dist/core/index.mjs +3 -1
  92. package/dist/core/vec3.d.mts +94 -0
  93. package/dist/core/vec3.mjs +123 -0
  94. package/dist/core/worked.d.mts +35 -0
  95. package/dist/core/worked.mjs +44 -0
  96. package/dist/electro/cell.d.mts +102 -0
  97. package/dist/electro/cell.mjs +170 -0
  98. package/dist/electro/conductivity.d.mts +157 -0
  99. package/dist/electro/conductivity.mjs +156 -0
  100. package/dist/electro/couples.d.mts +114 -0
  101. package/dist/electro/couples.mjs +334 -0
  102. package/dist/electro/electrolysis.d.mts +96 -0
  103. package/dist/electro/electrolysis.mjs +274 -0
  104. package/dist/electro/faraday.d.mts +150 -0
  105. package/dist/electro/faraday.mjs +118 -0
  106. package/dist/electro/index.d.mts +6 -0
  107. package/dist/electro/index.mjs +7 -0
  108. package/dist/finance/accounting/adjustments.d.mts +17 -0
  109. package/dist/finance/accounting/adjustments.mjs +202 -0
  110. package/dist/finance/accounting/analysis.d.mts +8 -0
  111. package/dist/finance/accounting/analysis.mjs +205 -0
  112. package/dist/finance/accounting/clubs.d.mts +21 -0
  113. package/dist/finance/accounting/clubs.mjs +217 -0
  114. package/dist/finance/accounting/company-statements.d.mts +7 -0
  115. package/dist/finance/accounting/company-statements.mjs +150 -0
  116. package/dist/finance/accounting/harness.d.mts +7 -0
  117. package/dist/finance/accounting/harness.mjs +45 -0
  118. package/dist/finance/accounting/index.d.mts +18 -0
  119. package/dist/finance/accounting/index.mjs +18 -0
  120. package/dist/finance/accounting/journalize.d.mts +16 -0
  121. package/dist/finance/accounting/journalize.mjs +128 -0
  122. package/dist/finance/accounting/manufacturing.d.mts +8 -0
  123. package/dist/finance/accounting/manufacturing.mjs +236 -0
  124. package/dist/finance/accounting/partnership.d.mts +7 -0
  125. package/dist/finance/accounting/partnership.mjs +152 -0
  126. package/dist/finance/accounting/period-case.d.mts +6 -0
  127. package/dist/finance/accounting/period-case.mjs +71 -0
  128. package/dist/finance/accounting/post.d.mts +9 -0
  129. package/dist/finance/accounting/post.mjs +84 -0
  130. package/dist/finance/accounting/precision.d.mts +9 -0
  131. package/dist/finance/accounting/precision.mjs +15 -0
  132. package/dist/finance/accounting/rules.d.mts +21 -0
  133. package/dist/finance/accounting/rules.mjs +37 -0
  134. package/dist/finance/accounting/solve.d.mts +28 -0
  135. package/dist/finance/accounting/solve.mjs +92 -0
  136. package/dist/finance/accounting/statements.d.mts +7 -0
  137. package/dist/finance/accounting/statements.mjs +142 -0
  138. package/dist/finance/accounting/types.d.mts +649 -0
  139. package/dist/finance/accounting/validate.d.mts +7 -0
  140. package/dist/finance/accounting/validate.mjs +67 -0
  141. package/dist/finance/accounting/verification.d.mts +24 -0
  142. package/dist/finance/accounting/verification.mjs +386 -0
  143. package/dist/finance/bizsim.d.mts +21 -39
  144. package/dist/finance/bizsim.mjs +276 -97
  145. package/dist/finance/index.d.mts +20 -43
  146. package/dist/finance/index.mjs +19 -77
  147. package/dist/finance/investment-math.d.mts +7 -0
  148. package/dist/finance/investment-math.mjs +18 -0
  149. package/dist/finance/management-accounting/budgeting.d.mts +7 -0
  150. package/dist/finance/management-accounting/budgeting.mjs +189 -0
  151. package/dist/finance/management-accounting/cash-budget.d.mts +7 -0
  152. package/dist/finance/management-accounting/cash-budget.mjs +154 -0
  153. package/dist/finance/management-accounting/costing.d.mts +8 -0
  154. package/dist/finance/management-accounting/costing.mjs +175 -0
  155. package/dist/finance/management-accounting/decisions.d.mts +8 -0
  156. package/dist/finance/management-accounting/decisions.mjs +164 -0
  157. package/dist/finance/management-accounting/index.d.mts +13 -0
  158. package/dist/finance/management-accounting/index.mjs +13 -0
  159. package/dist/finance/management-accounting/integrated-budget.d.mts +8 -0
  160. package/dist/finance/management-accounting/integrated-budget.mjs +67 -0
  161. package/dist/finance/management-accounting/inventory-costing.d.mts +7 -0
  162. package/dist/finance/management-accounting/inventory-costing.mjs +173 -0
  163. package/dist/finance/management-accounting/investment-appraisal.d.mts +7 -0
  164. package/dist/finance/management-accounting/investment-appraisal.mjs +148 -0
  165. package/dist/finance/management-accounting/management-case.d.mts +8 -0
  166. package/dist/finance/management-accounting/management-case.mjs +91 -0
  167. package/dist/finance/management-accounting/master-budget.d.mts +7 -0
  168. package/dist/finance/management-accounting/master-budget.mjs +137 -0
  169. package/dist/finance/management-accounting/production-costing.d.mts +8 -0
  170. package/dist/finance/management-accounting/production-costing.mjs +214 -0
  171. package/dist/finance/management-accounting/types.d.mts +644 -0
  172. package/dist/finance/management-accounting/variances.d.mts +7 -0
  173. package/dist/finance/management-accounting/variances.mjs +150 -0
  174. package/dist/index.d.mts +6 -6
  175. package/dist/index.mjs +1 -1
  176. package/dist/math/analysis.d.mts +61 -0
  177. package/dist/math/analysis.mjs +187 -0
  178. package/dist/math/answer-check.d.mts +50 -0
  179. package/dist/math/answer-check.mjs +106 -0
  180. package/dist/math/calculus.d.mts +4 -9
  181. package/dist/math/calculus.mjs +216 -7
  182. package/dist/math/complex.d.mts +93 -0
  183. package/dist/math/complex.mjs +239 -0
  184. package/dist/math/expr.d.mts +23 -0
  185. package/dist/math/expr.mjs +36 -0
  186. package/dist/math/index.d.mts +8 -22
  187. package/dist/math/index.mjs +8 -37
  188. package/dist/math/latex.mjs +2 -1
  189. package/dist/math/parse.mjs +1 -1
  190. package/dist/math/poly.d.mts +55 -0
  191. package/dist/math/poly.mjs +273 -0
  192. package/dist/math/rearrange.d.mts +14 -0
  193. package/dist/math/rearrange.mjs +125 -0
  194. package/dist/math/solve.d.mts +21 -0
  195. package/dist/math/solve.mjs +75 -0
  196. package/dist/networking/addressing.d.mts +26 -0
  197. package/dist/networking/addressing.mjs +33 -0
  198. package/dist/networking/cloud/access.d.mts +36 -0
  199. package/dist/networking/cloud/access.mjs +95 -0
  200. package/dist/networking/cloud/containers.d.mts +43 -0
  201. package/dist/networking/cloud/containers.mjs +54 -0
  202. package/dist/networking/cloud/edge.d.mts +17 -0
  203. package/dist/networking/cloud/edge.mjs +31 -0
  204. package/dist/networking/cloud/failure-domains.d.mts +19 -0
  205. package/dist/networking/cloud/failure-domains.mjs +22 -0
  206. package/dist/networking/cloud/geo-routing.d.mts +22 -0
  207. package/dist/networking/cloud/geo-routing.mjs +64 -0
  208. package/dist/networking/cloud/index.d.mts +18 -0
  209. package/dist/networking/cloud/index.mjs +19 -0
  210. package/dist/networking/cloud/inference-reliability.d.mts +30 -0
  211. package/dist/networking/cloud/inference-reliability.mjs +76 -0
  212. package/dist/networking/cloud/inference.d.mts +118 -0
  213. package/dist/networking/cloud/inference.mjs +179 -0
  214. package/dist/networking/cloud/infrastructure.d.mts +45 -0
  215. package/dist/networking/cloud/infrastructure.mjs +96 -0
  216. package/dist/networking/cloud/observability.d.mts +24 -0
  217. package/dist/networking/cloud/observability.mjs +34 -0
  218. package/dist/networking/cloud/orchestration.d.mts +32 -0
  219. package/dist/networking/cloud/orchestration.mjs +38 -0
  220. package/dist/networking/cloud/recovery.d.mts +21 -0
  221. package/dist/networking/cloud/recovery.mjs +27 -0
  222. package/dist/networking/cloud/releases.d.mts +42 -0
  223. package/dist/networking/cloud/releases.mjs +135 -0
  224. package/dist/networking/cloud/scaling.d.mts +25 -0
  225. package/dist/networking/cloud/scaling.mjs +65 -0
  226. package/dist/networking/cloud/secrets.d.mts +39 -0
  227. package/dist/networking/cloud/secrets.mjs +68 -0
  228. package/dist/networking/cloud/server-deployment.d.mts +29 -0
  229. package/dist/networking/cloud/server-deployment.mjs +72 -0
  230. package/dist/networking/cloud/storage.d.mts +16 -0
  231. package/dist/networking/cloud/storage.mjs +58 -0
  232. package/dist/networking/cloud/vpc.d.mts +18 -0
  233. package/dist/networking/cloud/vpc.mjs +100 -0
  234. package/dist/networking/delivery.d.mts +34 -0
  235. package/dist/networking/delivery.mjs +52 -0
  236. package/dist/networking/index.d.mts +47 -0
  237. package/dist/networking/index.mjs +47 -0
  238. package/dist/networking/ipv6.d.mts +28 -0
  239. package/dist/networking/ipv6.mjs +17 -0
  240. package/dist/networking/journeys.d.mts +83 -0
  241. package/dist/networking/journeys.mjs +161 -0
  242. package/dist/networking/models/airtime.d.mts +87 -0
  243. package/dist/networking/models/airtime.mjs +130 -0
  244. package/dist/networking/models/cellular.d.mts +157 -0
  245. package/dist/networking/models/cellular.mjs +252 -0
  246. package/dist/networking/models/encapsulation.d.mts +98 -0
  247. package/dist/networking/models/encapsulation.mjs +132 -0
  248. package/dist/networking/models/handover.d.mts +116 -0
  249. package/dist/networking/models/handover.mjs +209 -0
  250. package/dist/networking/models/handshake.d.mts +90 -0
  251. package/dist/networking/models/handshake.mjs +122 -0
  252. package/dist/networking/models/index.d.mts +14 -0
  253. package/dist/networking/models/index.mjs +15 -0
  254. package/dist/networking/models/media.d.mts +82 -0
  255. package/dist/networking/models/media.mjs +188 -0
  256. package/dist/networking/models/satellite.d.mts +86 -0
  257. package/dist/networking/models/satellite.mjs +121 -0
  258. package/dist/networking/models/spectrum.d.mts +83 -0
  259. package/dist/networking/models/spectrum.mjs +235 -0
  260. package/dist/networking/models/switch.d.mts +80 -0
  261. package/dist/networking/models/switch.mjs +155 -0
  262. package/dist/networking/models/vlan.d.mts +62 -0
  263. package/dist/networking/models/vlan.mjs +100 -0
  264. package/dist/networking/models/vpn.d.mts +66 -0
  265. package/dist/networking/models/vpn.mjs +125 -0
  266. package/dist/networking/models/wifi-privacy.d.mts +82 -0
  267. package/dist/networking/models/wifi-privacy.mjs +130 -0
  268. package/dist/networking/models/wifi.d.mts +240 -0
  269. package/dist/networking/models/wifi.mjs +562 -0
  270. package/dist/networking/nat-traversal.d.mts +24 -0
  271. package/dist/networking/nat-traversal.mjs +38 -0
  272. package/dist/networking/protocols.d.mts +17 -0
  273. package/dist/networking/protocols.mjs +57 -0
  274. package/dist/networking/queue.d.mts +12 -0
  275. package/dist/networking/queue.mjs +18 -0
  276. package/dist/networking/route-learning.d.mts +23 -0
  277. package/dist/networking/route-learning.mjs +43 -0
  278. package/dist/networking/routing.d.mts +11 -0
  279. package/dist/networking/routing.mjs +25 -0
  280. package/dist/networking/signals.d.mts +26 -0
  281. package/dist/networking/signals.mjs +35 -0
  282. package/dist/networking/subnet.d.mts +49 -0
  283. package/dist/networking/subnet.mjs +89 -0
  284. package/dist/networking/tcp-reliability.d.mts +24 -0
  285. package/dist/networking/tcp-reliability.mjs +38 -0
  286. package/dist/networking/topology/contract.d.mts +123 -0
  287. package/dist/networking/topology/index.d.mts +4 -0
  288. package/dist/networking/topology/index.mjs +4 -0
  289. package/dist/networking/topology/presets.d.mts +7 -0
  290. package/dist/networking/topology/presets.mjs +302 -0
  291. package/dist/networking/topology/simulation.d.mts +8 -0
  292. package/dist/networking/topology/simulation.mjs +179 -0
  293. package/dist/networking/wireless.d.mts +11 -0
  294. package/dist/networking/wireless.mjs +17 -0
  295. package/dist/optics/imaging.d.mts +218 -0
  296. package/dist/optics/imaging.mjs +276 -0
  297. package/dist/optics/index.d.mts +7 -0
  298. package/dist/optics/index.mjs +8 -0
  299. package/dist/optics/laws.d.mts +70 -0
  300. package/dist/optics/laws.mjs +195 -0
  301. package/dist/optics/prism.d.mts +148 -0
  302. package/dist/optics/prism.mjs +197 -0
  303. package/dist/optics/refraction.d.mts +201 -0
  304. package/dist/optics/refraction.mjs +270 -0
  305. package/dist/optics/wave-optics.d.mts +171 -0
  306. package/dist/optics/wave-optics.mjs +259 -0
  307. package/dist/physics/ac/index.d.mts +183 -0
  308. package/dist/physics/ac/index.mjs +203 -0
  309. package/dist/physics/dynamics/forces.d.mts +98 -0
  310. package/dist/physics/dynamics/forces.mjs +153 -0
  311. package/dist/physics/dynamics/friction.d.mts +76 -0
  312. package/dist/physics/dynamics/friction.mjs +119 -0
  313. package/dist/physics/dynamics/system.d.mts +68 -0
  314. package/dist/physics/dynamics/system.mjs +125 -0
  315. package/dist/physics/electrostatics/index.d.mts +169 -0
  316. package/dist/physics/electrostatics/index.mjs +249 -0
  317. package/dist/physics/energy/centre-of-mass.d.mts +115 -0
  318. package/dist/physics/energy/centre-of-mass.mjs +180 -0
  319. package/dist/physics/energy/conservation.d.mts +81 -0
  320. package/dist/physics/energy/conservation.mjs +129 -0
  321. package/dist/physics/energy/power.d.mts +90 -0
  322. package/dist/physics/energy/power.mjs +167 -0
  323. package/dist/physics/energy/spring.d.mts +73 -0
  324. package/dist/physics/energy/spring.mjs +129 -0
  325. package/dist/physics/energy/store.d.mts +63 -0
  326. package/dist/physics/energy/store.mjs +108 -0
  327. package/dist/physics/energy/theorem.d.mts +65 -0
  328. package/dist/physics/energy/theorem.mjs +113 -0
  329. package/dist/physics/energy/work.d.mts +114 -0
  330. package/dist/physics/energy/work.mjs +219 -0
  331. package/dist/physics/gravitation/body.d.mts +85 -0
  332. package/dist/physics/gravitation/body.mjs +168 -0
  333. package/dist/physics/gravitation/kepler.d.mts +127 -0
  334. package/dist/physics/gravitation/kepler.mjs +216 -0
  335. package/dist/physics/gravitation/law.d.mts +117 -0
  336. package/dist/physics/gravitation/law.mjs +175 -0
  337. package/dist/physics/gravitation/orbit.d.mts +119 -0
  338. package/dist/physics/gravitation/orbit.mjs +202 -0
  339. package/dist/physics/gravitation/potential.d.mts +114 -0
  340. package/dist/physics/gravitation/potential.mjs +202 -0
  341. package/dist/physics/gravitation/variation.d.mts +97 -0
  342. package/dist/physics/gravitation/variation.mjs +175 -0
  343. package/dist/physics/index.d.mts +35 -0
  344. package/dist/physics/index.mjs +36 -0
  345. package/dist/physics/integral-sweep.d.mts +63 -0
  346. package/dist/physics/integral-sweep.mjs +126 -0
  347. package/dist/physics/kinematics/equations.d.mts +47 -0
  348. package/dist/physics/kinematics/equations.mjs +126 -0
  349. package/dist/physics/kinematics/free-fall.d.mts +53 -0
  350. package/dist/physics/kinematics/free-fall.mjs +71 -0
  351. package/dist/physics/kinematics/given.d.mts +16 -0
  352. package/dist/physics/kinematics/given.mjs +55 -0
  353. package/dist/physics/kinematics/roots.d.mts +41 -0
  354. package/dist/physics/kinematics/roots.mjs +72 -0
  355. package/dist/physics/kinematics/solve.d.mts +52 -0
  356. package/dist/physics/kinematics/solve.mjs +172 -0
  357. package/dist/physics/magnetism/biot-savart.d.mts +161 -0
  358. package/dist/physics/magnetism/biot-savart.mjs +353 -0
  359. package/dist/physics/magnetism/flux.d.mts +94 -0
  360. package/dist/physics/magnetism/flux.mjs +313 -0
  361. package/dist/physics/magnetism/geomagnetism.d.mts +151 -0
  362. package/dist/physics/magnetism/geomagnetism.mjs +184 -0
  363. package/dist/physics/magnetism/index.d.mts +12 -0
  364. package/dist/physics/magnetism/index.mjs +74 -0
  365. package/dist/physics/magnetism/lorentz.d.mts +28 -0
  366. package/dist/physics/magnetism/lorentz.mjs +88 -0
  367. package/dist/physics/magnetism/magnetic-force.d.mts +102 -0
  368. package/dist/physics/magnetism/magnetic-force.mjs +169 -0
  369. package/dist/physics/momentum/collide.d.mts +77 -0
  370. package/dist/physics/momentum/collide.mjs +115 -0
  371. package/dist/physics/momentum/impulse.d.mts +89 -0
  372. package/dist/physics/momentum/impulse.mjs +159 -0
  373. package/dist/physics/momentum/planar.d.mts +60 -0
  374. package/dist/physics/momentum/planar.mjs +110 -0
  375. package/dist/physics/projectile.d.mts +107 -0
  376. package/dist/physics/projectile.mjs +185 -0
  377. package/dist/physics/rotation/angular.d.mts +85 -0
  378. package/dist/physics/rotation/angular.mjs +130 -0
  379. package/dist/physics/rotation/circular.d.mts +79 -0
  380. package/dist/physics/rotation/circular.mjs +131 -0
  381. package/dist/physics/rotation/inertia.d.mts +164 -0
  382. package/dist/physics/rotation/inertia.mjs +332 -0
  383. package/dist/physics/rotation/torque.d.mts +65 -0
  384. package/dist/physics/rotation/torque.mjs +134 -0
  385. package/dist/physics/vectors.d.mts +64 -0
  386. package/dist/physics/vectors.mjs +114 -0
  387. package/dist/quantity/index.d.mts +119 -0
  388. package/dist/quantity/index.mjs +417 -0
  389. package/dist/relation/derive.d.mts +74 -0
  390. package/dist/relation/derive.mjs +73 -0
  391. package/dist/relation/index.d.mts +56 -0
  392. package/dist/relation/index.mjs +234 -0
  393. package/dist/scene/evaluators.mjs +1 -1
  394. package/dist/sim/thermal.mjs +45 -20
  395. package/dist/thermo/calorimetry.d.mts +207 -0
  396. package/dist/thermo/calorimetry.mjs +345 -0
  397. package/dist/thermo/cycles.d.mts +142 -0
  398. package/dist/thermo/cycles.mjs +256 -0
  399. package/dist/thermo/entropy.d.mts +87 -0
  400. package/dist/thermo/entropy.mjs +140 -0
  401. package/dist/thermo/expansion.d.mts +130 -0
  402. package/dist/thermo/expansion.mjs +178 -0
  403. package/dist/thermo/gas.d.mts +197 -0
  404. package/dist/thermo/gas.mjs +279 -0
  405. package/dist/thermo/heat-transfer.d.mts +164 -0
  406. package/dist/thermo/heat-transfer.mjs +217 -0
  407. package/dist/thermo/index.d.mts +9 -82
  408. package/dist/thermo/index.mjs +9 -132
  409. package/dist/thermo/processes.d.mts +95 -0
  410. package/dist/thermo/processes.mjs +154 -0
  411. package/dist/thermo/temperature.d.mts +174 -0
  412. package/dist/thermo/temperature.mjs +236 -0
  413. package/dist/waves/damping.d.mts +224 -0
  414. package/dist/waves/damping.mjs +317 -0
  415. package/dist/waves/doppler.d.mts +72 -0
  416. package/dist/waves/doppler.mjs +125 -0
  417. package/dist/waves/index.d.mts +10 -0
  418. package/dist/waves/index.mjs +10 -0
  419. package/dist/waves/pendulum.d.mts +130 -0
  420. package/dist/waves/pendulum.mjs +211 -0
  421. package/dist/waves/pitch.d.mts +125 -0
  422. package/dist/waves/pitch.mjs +158 -0
  423. package/dist/waves/shm.d.mts +170 -0
  424. package/dist/waves/shm.mjs +279 -0
  425. package/dist/waves/springs.d.mts +103 -0
  426. package/dist/waves/springs.mjs +176 -0
  427. package/dist/waves/superposition.d.mts +124 -0
  428. package/dist/waves/superposition.mjs +196 -0
  429. package/dist/waves/wave.d.mts +154 -0
  430. package/dist/waves/wave.mjs +178 -0
  431. package/package.json +74 -2
@@ -0,0 +1,145 @@
1
+ import { calc } from "../core/worked.mjs";
2
+ import { Quantity, qty } from "../quantity/index.mjs";
3
+
4
+ //#region src/chem/cycle.ts
5
+ /**
6
+ * cycle, an energy cycle: a list of steps whose enthalpies must sum to a known total.
7
+ *
8
+ * This is Hess's law as a data structure. The law says the enthalpy change between two states does
9
+ * not depend on the route, so any two routes between the same states sum to the same number:
10
+ *
11
+ * ΔH(step 1) + ΔH(step 2) + … + ΔH(step n) = ΔH(overall)
12
+ *
13
+ * Exactly one term may be unknown, anywhere in the cycle INCLUDING the total, and the kernel
14
+ * returns it. That single rule covers three different-looking exam questions:
15
+ *
16
+ * • Born-Haber — every step known except the lattice energy.
17
+ * • Hess's law — the route is known and the overall change is wanted.
18
+ * • enthalpy of formation from combustion data — the total is known and one step is not.
19
+ *
20
+ * WHY A CYCLE IS NOT A `relation`. A relation has a fixed set of named variables. A cycle has an
21
+ * arbitrary number of steps whose only constraint is that they sum, so expressing it as a relation
22
+ * would mean one relation per cycle shape: one for NaCl, another for MgCl₂, another for MgO.
23
+ *
24
+ * SIGN CONVENTION, which is where the marks are lost. Every value is the enthalpy change for the
25
+ * step AS WRITTEN, left to right, with exothermic negative. So the electron affinity of chlorine is
26
+ * −349 kJ mol⁻¹ and the lattice energy of NaCl is −787 kJ mol⁻¹, both being formation processes.
27
+ * A step written in the reverse direction takes the opposite sign, and `reversed` on a term says so
28
+ * explicitly rather than leaving the author to flip it by hand and hope.
29
+ *
30
+ * STOICHIOMETRY. `per` multiplies a step, because a Born-Haber cycle for MgCl₂ needs two chlorine
31
+ * atomisations and two electron affinities. Writing `per: 2` keeps the per-mole datum visible in the
32
+ * working, which is what the mark scheme wants to see; writing 244 instead of 2 × 122 hides it.
33
+ *
34
+ * Pure: no React, no pixels.
35
+ */
36
+ /** kJ mol⁻¹ is what every data book and every mark scheme uses. */
37
+ const DEFAULT_CYCLE_UNIT = "kJ/mol";
38
+ const known = (t) => t.value !== void 0;
39
+ var Cycle = class {
40
+ title;
41
+ unit;
42
+ route;
43
+ total;
44
+ constructor(spec) {
45
+ this.unit = spec.unit ?? "kJ/mol";
46
+ this.title = spec.title ?? "energy cycle";
47
+ this.route = spec.route;
48
+ this.total = spec.total;
49
+ if (!spec.route.length) throw new Error(`${this.title}: a cycle needs at least one step.`);
50
+ const unknowns = [...spec.route, spec.total].filter((t) => !known(t));
51
+ if (unknowns.length > 1) throw new Error(`${this.title}: ${unknowns.length} unknown terms (${unknowns.map((t) => t.label).join(", ")}). A cycle determines exactly one.`);
52
+ for (const t of spec.route) if (t.per !== void 0 && (!Number.isFinite(t.per) || t.per === 0)) throw new Error(`${this.title}: "${t.label}" has per = ${t.per}, which is not a count of steps.`);
53
+ }
54
+ /** The signed contribution of a term, in `this.unit`, with `per` and `reversed` applied. */
55
+ contribution(term) {
56
+ if (term.value === void 0) throw new Error(`${this.title}: "${term.label}" has no value.`);
57
+ return (term.value instanceof Quantity ? term.value.in(this.unit) : term.value) * (term.per ?? 1) * (term.reversed ? -1 : 1);
58
+ }
59
+ /** Sum of the steps that have values. */
60
+ sumKnownSteps() {
61
+ return this.route.filter(known).reduce((acc, t) => acc + this.contribution(t), 0);
62
+ }
63
+ /**
64
+ * The one unknown term.
65
+ *
66
+ * If a step is unknown: step = total − (the other steps).
67
+ * If the total is unknown: total = the sum of the steps.
68
+ */
69
+ solve() {
70
+ const missingStep = this.route.find((t) => !known(t));
71
+ const totalKnown = known(this.total);
72
+ if (!missingStep && totalKnown) throw new Error(`${this.title}: every term is known, so there is nothing to solve. Use residual() to check consistency.`);
73
+ if (!totalKnown) {
74
+ const value = this.sumKnownSteps();
75
+ return this.report(this.total, value, true);
76
+ }
77
+ const per = missingStep.per ?? 1;
78
+ const sign = missingStep.reversed ? -1 : 1;
79
+ const value = (this.contribution(this.total) - this.sumKnownSteps()) / per * sign;
80
+ return this.report(missingStep, value, false);
81
+ }
82
+ report(term, value, isTotal) {
83
+ return {
84
+ label: term.label,
85
+ value,
86
+ unit: this.unit,
87
+ quantity: qty(value, this.unit),
88
+ exothermic: value < 0,
89
+ isTotal
90
+ };
91
+ }
92
+ /**
93
+ * With every term known, how far the route misses the total by.
94
+ *
95
+ * Zero is a cycle that is self-consistent. This is the check worth running over an authored
96
+ * lesson: five data-book enthalpies and a quoted formation enthalpy that do NOT close to within a
97
+ * kilojoule mean one of the six numbers is wrong, and the lesson cannot say which.
98
+ */
99
+ residual() {
100
+ if (!known(this.total)) throw new Error(`${this.title}: the total is unknown, so use solve().`);
101
+ const missing = this.route.find((t) => !known(t));
102
+ if (missing) throw new Error(`${this.title}: "${missing.label}" is unknown, so use solve().`);
103
+ return this.sumKnownSteps() - this.contribution(this.total);
104
+ }
105
+ /** True when the cycle closes to within `tol` (default 1 kJ/mol, the data-book rounding). */
106
+ closes(tol = 1) {
107
+ return Math.abs(this.residual()) <= tol;
108
+ }
109
+ /**
110
+ * The working: every step with its sign, then the rearrangement and the answer.
111
+ *
112
+ * A `per` factor is shown as `2 × 122`, not as `244`, because the per-mole datum is the thing the
113
+ * mark scheme wants to see quoted.
114
+ */
115
+ steps(sf = 4) {
116
+ const solved = this.solve();
117
+ const w = calc().step(`\\sum \\Delta H(\\text{route}) = \\Delta H(\\text{overall})`, `${this.title}: Hess's law, so the route and the direct change agree`);
118
+ for (const t of this.route) {
119
+ const per = t.per ?? 1;
120
+ if (!known(t)) {
121
+ w.step(`${tex(t.label)} = ?`, "the unknown");
122
+ continue;
123
+ }
124
+ const base = t.value instanceof Quantity ? t.value.in(this.unit) : t.value;
125
+ const shown = per === 1 ? fmt(base, sf) : `${per} \\times ${fmt(base, sf)}`;
126
+ w.step(`${tex(t.label)} = ${shown}\\ \\mathrm{${this.unit}}`, t.reversed ? "quoted for the reverse step, so the sign flips" : void 0);
127
+ }
128
+ if (known(this.total)) {
129
+ w.step(`${tex(this.total.label)} = ${fmt(this.contribution(this.total), sf)}\\ \\mathrm{${this.unit}}`, "the overall change");
130
+ w.step(`${tex(solved.label)} = ${fmt(this.contribution(this.total), sf)} - (${fmt(this.sumKnownSteps(), sf)})`, "the unknown step is the overall change minus the rest of the route");
131
+ }
132
+ w.step(`${tex(solved.label)} = ${fmt(solved.value, sf)}\\ \\mathrm{${this.unit}}`, solved.exothermic ? "negative, so the step is exothermic" : "positive, so the step is endothermic");
133
+ return w.done(solved.value);
134
+ }
135
+ };
136
+ const tex = (label) => `\\Delta H(\\text{${label}})`;
137
+ function fmt(value, sf) {
138
+ if (!Number.isFinite(value)) return "\\text{?}";
139
+ return String(Number(value.toPrecision(sf)));
140
+ }
141
+ /** `cycle({ route: [...], total: {...} })`. */
142
+ const cycle = (spec) => new Cycle(spec);
143
+
144
+ //#endregion
145
+ export { Cycle, DEFAULT_CYCLE_UNIT, cycle };
@@ -0,0 +1,86 @@
1
+ //#region src/chem/equation.d.ts
2
+ /**
3
+ * Balancing a chemical equation, by solving it rather than by trial and error.
4
+ *
5
+ * ## Balancing is linear algebra, and saying so is the lesson
6
+ *
7
+ * Balancing is taught as inspection: try a number, see what breaks, adjust. That works for simple
8
+ * equations, fails on awkward ones, and teaches nothing about why an equation can be balanced at
9
+ * all. It is actually a small linear system. Write one row per element and one column per species,
10
+ * with reactants positive and products negative, and a balanced equation is any vector of
11
+ * coefficients the matrix sends to zero:
12
+ *
13
+ * Fe 3a - c = 0
14
+ * O 4a - 2d = 0 for a Fe3O4 + b CO -> c Fe + d CO2
15
+ * C b - d = 0
16
+ *
17
+ * So the coefficients are the null space of the element matrix, and the smallest whole-number
18
+ * answer is that vector cleared of fractions. Conservation of atoms is not a rule applied to the
19
+ * arithmetic, it IS the arithmetic.
20
+ *
21
+ * It also explains the cases inspection cannot. A system with no non-zero solution is an equation
22
+ * that cannot be balanced, which is a real answer and usually means a species is missing. A system
23
+ * with more than one independent solution is an equation that can be balanced in more than one way,
24
+ * which is also real and means the reaction as written is really two reactions.
25
+ *
26
+ * ## Exact arithmetic, because floating point cannot be trusted with this
27
+ *
28
+ * The elimination runs on fractions held as a numerator and a denominator, not on doubles. A
29
+ * coefficient is a whole number or the equation is wrong, and a solver that produced 2.9999999998
30
+ * would either have to round, which hides a genuine failure, or refuse a correct equation. Integers
31
+ * throughout means the answer is exactly right or honestly rejected.
32
+ *
33
+ * Pure: no React, no pixels.
34
+ */
35
+ /** One species in an equation, with the coefficient balancing gave it. */
36
+ interface Term {
37
+ readonly formula: string;
38
+ readonly coefficient: number;
39
+ }
40
+ interface BalancedEquation {
41
+ readonly reactants: readonly Term[];
42
+ readonly products: readonly Term[];
43
+ /** The elements the balance was solved over. */
44
+ readonly elements: readonly string[];
45
+ }
46
+ /** Split "a + b -> c + d" into its two sides, accepting the arrows people actually type. */
47
+ declare function splitEquation(input: string): {
48
+ left: string[];
49
+ right: string[];
50
+ };
51
+ /**
52
+ * Balance an equation, returning the smallest whole-number coefficients.
53
+ *
54
+ * `balance('Fe3O4 + CO -> Fe + CO2')`, `balance('C3H8 + O2 -> CO2 + H2O')`.
55
+ *
56
+ * Coefficients already written into the input are ignored: the whole point is to compute them, and
57
+ * accepting them would let a wrong one through unchallenged.
58
+ */
59
+ declare function balance(input: string): BalancedEquation;
60
+ /** Write a balanced equation out, leaving a coefficient of one unwritten. */
61
+ declare function formatEquation(equation: BalancedEquation, arrow?: string): string;
62
+ /**
63
+ * How many atoms of each element sit on each side.
64
+ *
65
+ * For showing the check rather than doing it: the balance is exact by construction, and a learner
66
+ * still has to see both columns match before they believe it.
67
+ */
68
+ declare function atomTally(equation: BalancedEquation): {
69
+ element: string;
70
+ left: number;
71
+ right: number;
72
+ }[];
73
+ /**
74
+ * Total charge on each side.
75
+ *
76
+ * Separate from the atom tally because it is a different conservation law, and because showing it
77
+ * beside the atoms is what makes an ionic equation make sense: the two sides of a precipitation
78
+ * carry the same charge as well as the same atoms, and a learner who only counts atoms will balance
79
+ * it wrongly and never see why.
80
+ */
81
+ declare function chargeTally(equation: BalancedEquation): {
82
+ left: number;
83
+ right: number;
84
+ };
85
+ //#endregion
86
+ export { BalancedEquation, Term, atomTally, balance, chargeTally, formatEquation, splitEquation };
@@ -0,0 +1,168 @@
1
+ import { readFormula } from "./species.mjs";
2
+
3
+ //#region src/chem/equation.ts
4
+ /**
5
+ * Strip a trailing state symbol.
6
+ *
7
+ * `(aq)` looks exactly like a bracketed group to the formula reader, which would take the a and the
8
+ * q for elements. It has to come off before the formula is read, and only from the END, because
9
+ * `Fe(OH)3` has a bracketed group in the middle that must survive.
10
+ */
11
+ const STATE_SYMBOL = /\((?:g|l|s|aq)\)\s*$/i;
12
+ const withoutState = (species) => species.replace(STATE_SYMBOL, "").trim();
13
+ const gcd = (a, b) => b === 0 ? Math.abs(a) : gcd(b, a % b);
14
+ function fraction(n, d = 1) {
15
+ if (d === 0) throw new Error("a fraction cannot have a denominator of zero");
16
+ const sign = d < 0 ? -1 : 1;
17
+ const divisor = gcd(n, d) || 1;
18
+ return {
19
+ n: sign * n / divisor,
20
+ d: sign * d / divisor
21
+ };
22
+ }
23
+ const sub = (a, b) => fraction(a.n * b.d - b.n * a.d, a.d * b.d);
24
+ const mul = (a, b) => fraction(a.n * b.n, a.d * b.d);
25
+ const div = (a, b) => {
26
+ if (b.n === 0) throw new Error("cannot divide by zero while balancing");
27
+ return fraction(a.n * b.d, a.d * b.n);
28
+ };
29
+ const isZero = (f) => f.n === 0;
30
+ const ZERO = {
31
+ n: 0,
32
+ d: 1
33
+ };
34
+ const ONE = {
35
+ n: 1,
36
+ d: 1
37
+ };
38
+ /** Split "a + b -> c + d" into its two sides, accepting the arrows people actually type. */
39
+ function splitEquation(input) {
40
+ const parts = input.split(/->|=>|→|⟶|=/);
41
+ if (parts.length !== 2) throw new Error(`"${input}" is not an equation: it needs exactly one arrow, written as -> or = or →`);
42
+ const side = (text) => text.split(/\s+\+\s+/).map((s) => s.trim()).map((s) => s.replace(/^\d+(?=[A-Z([])/, "")).filter((s) => s !== "");
43
+ const left = side(parts[0]);
44
+ const right = side(parts[1]);
45
+ if (left.length === 0 || right.length === 0) throw new Error(`"${input}" has nothing on one side of the arrow`);
46
+ return {
47
+ left,
48
+ right
49
+ };
50
+ }
51
+ /**
52
+ * Balance an equation, returning the smallest whole-number coefficients.
53
+ *
54
+ * `balance('Fe3O4 + CO -> Fe + CO2')`, `balance('C3H8 + O2 -> CO2 + H2O')`.
55
+ *
56
+ * Coefficients already written into the input are ignored: the whole point is to compute them, and
57
+ * accepting them would let a wrong one through unchallenged.
58
+ */
59
+ function balance(input) {
60
+ const { left, right } = splitEquation(input);
61
+ const species = [...left, ...right];
62
+ const read = species.map((formula) => readFormula(withoutState(formula)));
63
+ const compositions = read.map((r) => r.counts);
64
+ const elements = [...new Set(compositions.flatMap((c) => c.map((e) => e.element)))];
65
+ /** Reactants count positive and products negative, so a balance sums to zero. */
66
+ const signed = (column, value) => fraction(column < left.length ? value : -value);
67
+ const rows = elements.map((element) => compositions.map((composition, column) => signed(column, composition.find((e) => e.element === element)?.count ?? 0)));
68
+ if (read.some((r) => r.charge !== 0)) rows.push(read.map((r, column) => signed(column, r.charge)));
69
+ const whole = clearFractions(nullSpaceVector(rows, species.length, input));
70
+ if (whole.some((value) => value <= 0)) throw new Error(`${input} cannot be balanced as written: the only solution needs a coefficient of zero or below, which usually means a species is on the wrong side or one is missing`);
71
+ return {
72
+ reactants: left.map((formula, i) => ({
73
+ formula,
74
+ coefficient: whole[i]
75
+ })),
76
+ products: right.map((formula, i) => ({
77
+ formula,
78
+ coefficient: whole[left.length + i]
79
+ })),
80
+ elements
81
+ };
82
+ }
83
+ /**
84
+ * The one direction the element matrix sends to zero.
85
+ *
86
+ * Gaussian elimination to reduced row echelon form, then the single free column is set to one and
87
+ * the others read off. More than one free column means the equation has more than one independent
88
+ * balance, which is refused with that as the reason rather than by picking one of them.
89
+ */
90
+ function nullSpaceVector(rows, columns, input) {
91
+ const matrix = rows.map((row) => [...row]);
92
+ const pivotOf = [];
93
+ let pivotRow = 0;
94
+ for (let column = 0; column < columns && pivotRow < matrix.length; column += 1) {
95
+ const found = matrix.findIndex((row, i) => i >= pivotRow && !isZero(row[column]));
96
+ if (found === -1) continue;
97
+ [matrix[pivotRow], matrix[found]] = [matrix[found], matrix[pivotRow]];
98
+ const pivot = matrix[pivotRow][column];
99
+ matrix[pivotRow] = matrix[pivotRow].map((value) => div(value, pivot));
100
+ for (let r = 0; r < matrix.length; r += 1) {
101
+ if (r === pivotRow || isZero(matrix[r][column])) continue;
102
+ const factor = matrix[r][column];
103
+ matrix[r] = matrix[r].map((value, c) => sub(value, mul(factor, matrix[pivotRow][c])));
104
+ }
105
+ pivotOf.push(column);
106
+ pivotRow += 1;
107
+ }
108
+ const free = [...Array(columns).keys()].filter((c) => !pivotOf.includes(c));
109
+ if (free.length === 0) throw new Error(`${input} cannot be balanced: no set of coefficients conserves every element, so a species is missing or a formula is wrong`);
110
+ if (free.length > 1) throw new Error(`${input} can be balanced in more than one independent way, which means it describes more than one reaction. Split it into separate equations.`);
111
+ const solution = Array(columns).fill(ZERO);
112
+ solution[free[0]] = ONE;
113
+ pivotOf.forEach((column, row) => {
114
+ solution[column] = mul(matrix[row][free[0]], {
115
+ n: -1,
116
+ d: 1
117
+ });
118
+ });
119
+ return solution;
120
+ }
121
+ /** Scale a set of fractions to the smallest whole numbers with the same ratios. */
122
+ function clearFractions(values) {
123
+ const lcm = (a, b) => Math.abs(a * b) / (gcd(a, b) || 1);
124
+ const denominator = values.reduce((total, f) => lcm(total, f.d), 1);
125
+ const scaled = values.map((f) => f.n * denominator / f.d);
126
+ const divisor = scaled.reduce((total, v) => gcd(total, v), 0) || 1;
127
+ return scaled.map((v) => v / divisor);
128
+ }
129
+ /** Write a balanced equation out, leaving a coefficient of one unwritten. */
130
+ function formatEquation(equation, arrow = "->") {
131
+ const side = (terms) => terms.map((t) => `${t.coefficient === 1 ? "" : t.coefficient}${t.formula}`).join(" + ");
132
+ return `${side(equation.reactants)} ${arrow} ${side(equation.products)}`;
133
+ }
134
+ /**
135
+ * How many atoms of each element sit on each side.
136
+ *
137
+ * For showing the check rather than doing it: the balance is exact by construction, and a learner
138
+ * still has to see both columns match before they believe it.
139
+ */
140
+ function atomTally(equation) {
141
+ const count = (terms, element) => terms.reduce((total, term) => {
142
+ const composition = readFormula(withoutState(term.formula)).counts;
143
+ return total + term.coefficient * (composition.find((e) => e.element === element)?.count ?? 0);
144
+ }, 0);
145
+ return equation.elements.map((element) => ({
146
+ element,
147
+ left: count(equation.reactants, element),
148
+ right: count(equation.products, element)
149
+ }));
150
+ }
151
+ /**
152
+ * Total charge on each side.
153
+ *
154
+ * Separate from the atom tally because it is a different conservation law, and because showing it
155
+ * beside the atoms is what makes an ionic equation make sense: the two sides of a precipitation
156
+ * carry the same charge as well as the same atoms, and a learner who only counts atoms will balance
157
+ * it wrongly and never see why.
158
+ */
159
+ function chargeTally(equation) {
160
+ const total = (terms) => terms.reduce((sum, term) => sum + term.coefficient * readFormula(withoutState(term.formula)).charge, 0);
161
+ return {
162
+ left: total(equation.reactants),
163
+ right: total(equation.products)
164
+ };
165
+ }
166
+
167
+ //#endregion
168
+ export { atomTally, balance, chargeTally, formatEquation, splitEquation };
@@ -0,0 +1,90 @@
1
+ //#region src/chem/formula.d.ts
2
+ /**
3
+ * Chemical formulae: what is in them, what they weigh, and what they weigh per element.
4
+ *
5
+ * ## One parser, because two would disagree
6
+ *
7
+ * A formula turns up in every quantitative question there is, and each of them needs the same three
8
+ * answers: which atoms, how many, and what that comes to. Writing a small reader for each caller is
9
+ * how a kernel ends up telling two different stories about Ca(NO3)2, so everything reads formulae
10
+ * here.
11
+ *
12
+ * What it understands:
13
+ *
14
+ * Ca(NO3)2 groups in brackets, with a multiplier
15
+ * K4[Fe(CN)6] square brackets, nested
16
+ * CuSO4.5H2O a hydrate, written with a dot and a leading count
17
+ * MgCl2.KCl.6H2O a double salt, as many parts as it takes
18
+ *
19
+ * ## Masses come from the element table, and a formula that names nothing is refused
20
+ *
21
+ * Relative atomic masses are the IUPAC values the atomic engine already holds, so a mass computed
22
+ * here cannot disagree with one computed anywhere else. A symbol that is not an element stops the
23
+ * parse: `Xy2O3` is a typo, and a parser that skipped it would return a mass for a substance that
24
+ * does not exist, which is worse than no answer at all.
25
+ *
26
+ * ## The empirical formula is a search, not a division
27
+ *
28
+ * Dividing by the smallest mole count is only the first half. It lands on whole numbers for some
29
+ * compounds and on 1.5 or 1.33 for others, and the answer is to scale until every ratio is close to
30
+ * a whole number. {@link empiricalFormula} tries multipliers in order and takes the first that
31
+ * works, which is exactly the step a learner is told to do "by inspection" and is the step most
32
+ * often fudged.
33
+ *
34
+ * Pure: no React, no pixels.
35
+ */
36
+ /** One element and how many of its atoms the formula contains. */
37
+ interface ElementCount {
38
+ readonly element: string;
39
+ readonly count: number;
40
+ }
41
+ /**
42
+ * The atoms in a formula, in the order they are written.
43
+ *
44
+ * Hydrates and double salts are split on the dot, each part parsed on its own and multiplied by its
45
+ * leading count, then added together. So CuSO4.5H2O has ten hydrogens, nine oxygens, one copper and
46
+ * one sulfur, which is what it weighs as.
47
+ */
48
+ declare function parseFormula(input: string): ElementCount[];
49
+ /**
50
+ * Relative molecular mass, from the IUPAC atomic weights the element table holds.
51
+ *
52
+ * Called relative FORMULA mass for anything ionic, since sodium chloride has no molecules, and the
53
+ * arithmetic is identical either way.
54
+ */
55
+ declare function molarMass(formula: string): number;
56
+ interface MassFraction {
57
+ readonly element: string;
58
+ /** Mass of this element in one formula unit. */
59
+ readonly mass: number;
60
+ /** Its share of the total, as a percentage. */
61
+ readonly percent: number;
62
+ }
63
+ /** What fraction of a compound's mass each element accounts for. */
64
+ declare function percentComposition(formula: string): MassFraction[];
65
+ /**
66
+ * The empirical formula implied by a composition.
67
+ *
68
+ * Takes percentages by mass, or any set of masses in the same unit: only the ratios matter, so the
69
+ * numbers do not have to add to a hundred and a set of measured masses works directly.
70
+ *
71
+ * The scaling step is the one that is usually waved through. Dividing by the smallest mole count
72
+ * can land on 1.5 or 1.33, and the ratios then have to be multiplied up until they are all close to
73
+ * whole numbers. That search is done here rather than left to inspection, and if no multiplier up
74
+ * to eight works the composition is refused rather than rounded into something tidy.
75
+ */
76
+ declare function empiricalFormula(composition: Readonly<Record<string, number>>): ElementCount[];
77
+ /**
78
+ * How many empirical units make up the real molecule.
79
+ *
80
+ * Rounded, because the ratio of a measured molar mass to an exact empirical mass never comes out
81
+ * whole. Refuses when it is not close to one, since a value of 2.4 means the molar mass or the
82
+ * composition is wrong and multiplying by 2 would bury that.
83
+ */
84
+ declare function unitsInMolecule(empirical: readonly ElementCount[], relativeMolecularMass: number): number;
85
+ /** The molecular formula: the empirical formula multiplied up to fit the measured mass. */
86
+ declare const molecularFormulaFor: (empirical: readonly ElementCount[], relativeMolecularMass: number) => ElementCount[];
87
+ /** Write counts back out as a formula, leaving a count of one unwritten. */
88
+ declare const formatFormula: (counts: readonly ElementCount[]) => string;
89
+ //#endregion
90
+ export { ElementCount, MassFraction, empiricalFormula, formatFormula, molarMass, molecularFormulaFor, parseFormula, percentComposition, unitsInMolecule };