@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,178 @@
1
+ //#region src/thermo/expansion.ts
2
+ /**
3
+ * Thermal expansion: how much bigger things get when they are warmed, and what
4
+ * happens when they are not allowed to.
5
+ *
6
+ * THE MODEL. To first order every dimension grows in proportion to its own
7
+ * length and to the temperature rise:
8
+ *
9
+ * length ΔL = L₀·α·Δθ
10
+ * area ΔA = A₀·β·Δθ with β ≈ 2α
11
+ * volume ΔV = V₀·γ·Δθ with γ ≈ 3α
12
+ *
13
+ * WHY β = 2α AND γ = 3α ARE NOT SEPARATE MEASUREMENTS. A square of side L has
14
+ * area L², and (1+αΔθ)² = 1 + 2αΔθ + (αΔθ)², so the area coefficient is twice
15
+ * the linear one plus a term in α² that is about 10⁻⁸ for a metal over a 100 K
16
+ * rise. The functions below use the EXACT powers rather than the doubled and
17
+ * tripled approximations, and `areaCoefficient` / `volumeCoefficient` return
18
+ * the textbook 2α and 3α, so a lab can show the two agreeing and then show
19
+ * where they part company.
20
+ *
21
+ * THE THING STUDENTS GET WRONG. A hole in a plate gets BIGGER, not smaller.
22
+ * Every function here takes a dimension and scales it, with no notion of
23
+ * "solid" or "hole", precisely because the material does not have one: the
24
+ * plate expands as if the hole were filled with more plate.
25
+ *
26
+ * UNITS: SI. Lengths in m, areas in m², volumes in m³, coefficients per kelvin,
27
+ * temperature changes in K (identical to changes in °C).
28
+ */
29
+ const finite = (value, what) => {
30
+ if (!Number.isFinite(value)) throw new RangeError(`${what} must be a finite number.`);
31
+ return value;
32
+ };
33
+ const positive = (value, what) => {
34
+ if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${what} must be positive.`);
35
+ return value;
36
+ };
37
+ /**
38
+ * Linear expansivity α, per kelvin, for materials that appear in the standard
39
+ * questions.
40
+ *
41
+ * Invar is in the table because it is the control: an alloy chosen to have
42
+ * almost no expansion, which is what makes the others' numbers mean something.
43
+ * The glass pair matters for the same reason, since the whole point of Pyrex is
44
+ * that a third of the expansion is a third of the thermal shock.
45
+ */
46
+ const LINEAR_EXPANSIVITY = {
47
+ aluminium: 23e-6,
48
+ brass: 19e-6,
49
+ copper: 17e-6,
50
+ steel: 12e-6,
51
+ iron: 12e-6,
52
+ concrete: 12e-6,
53
+ glass: 85e-7,
54
+ pyrex: 32e-7,
55
+ invar: 12e-7,
56
+ quartz: 55e-8
57
+ };
58
+ /** Length after a temperature change: L = L₀(1 + αΔθ). */
59
+ function expandedLengthM(length0, alpha, deltaT) {
60
+ return positive(length0, "A length") * (1 + finite(alpha, "The expansivity") * finite(deltaT, "A temperature change"));
61
+ }
62
+ /** The change in length itself, m: ΔL = L₀·α·Δθ. */
63
+ function lengthChangeM(length0, alpha, deltaT) {
64
+ return positive(length0, "A length") * finite(alpha, "The expansivity") * finite(deltaT, "A temperature change");
65
+ }
66
+ /**
67
+ * Area after a temperature change, using the exact square rather than 2α.
68
+ *
69
+ * A = A₀(1 + αΔθ)², which is where β = 2α comes from and where it stops being
70
+ * quite right.
71
+ */
72
+ function expandedAreaM2(area0, alpha, deltaT) {
73
+ return positive(area0, "An area") * (1 + finite(alpha, "The expansivity") * finite(deltaT, "A temperature change")) ** 2;
74
+ }
75
+ /** Volume after a temperature change, using the exact cube rather than 3α. */
76
+ function expandedVolumeM3(volume0, alpha, deltaT) {
77
+ return positive(volume0, "A volume") * (1 + finite(alpha, "The expansivity") * finite(deltaT, "A temperature change")) ** 3;
78
+ }
79
+ /** The area expansivity β = 2α, as the textbook approximation. */
80
+ const areaCoefficient = (alpha) => 2 * finite(alpha, "The expansivity");
81
+ /** The volume expansivity γ = 3α, as the textbook approximation. */
82
+ const volumeCoefficient = (alpha) => 3 * finite(alpha, "The expansivity");
83
+ /**
84
+ * Density after a temperature change, kg/m³: ρ = ρ₀/(1 + γΔθ).
85
+ *
86
+ * The mass does not change and the volume does, so the density falls. This is
87
+ * the engine behind convection: warmed fluid is less dense, so it rises, and
88
+ * the buoyancy that drives every convection current is this division.
89
+ */
90
+ function densityAfterExpansionKgM3(density0, volumeExpansivity, deltaT) {
91
+ const factor = 1 + finite(volumeExpansivity, "The volume expansivity") * finite(deltaT, "A temperature change");
92
+ if (factor <= 0) throw new RangeError("That temperature change would shrink the material to nothing or less.");
93
+ return positive(density0, "A density") / factor;
94
+ }
95
+ /**
96
+ * The real expansivity of a liquid from the apparent one:
97
+ *
98
+ * γ_real = γ_apparent + γ_container
99
+ *
100
+ * Measuring a liquid's expansion means watching it rise in a vessel that is
101
+ * also expanding, so what you see is the DIFFERENCE. Forgetting the container's
102
+ * share is the standard error in this experiment, and it is systematic rather
103
+ * than random, so no amount of repetition finds it.
104
+ */
105
+ function realExpansivity(apparent, containerVolumeExpansivity) {
106
+ return finite(apparent, "The apparent expansivity") + finite(containerVolumeExpansivity, "The container expansivity");
107
+ }
108
+ /**
109
+ * Thermal stress in a bar held rigidly while its temperature changes, Pa:
110
+ *
111
+ * σ = E·α·Δθ
112
+ *
113
+ * Note what is NOT in it: the length. A rail a kilometre long and a bolt a
114
+ * centimetre long, both clamped, reach the same stress for the same temperature
115
+ * rise, because the strain that would have been αΔθ is the same fraction
116
+ * either way. That is why expansion gaps are about the same size whatever the
117
+ * span, and why a long bridge needs more of them rather than bigger ones.
118
+ */
119
+ function thermalStressPa(youngsModulus, alpha, deltaT) {
120
+ return positive(youngsModulus, "Young's modulus") * finite(alpha, "The expansivity") * finite(deltaT, "A temperature change");
121
+ }
122
+ /**
123
+ * A bimetallic strip's bend, for two bonded strips of EQUAL thickness and
124
+ * equal Young's modulus:
125
+ *
126
+ * 1/ρ = 3·(α₂ − α₁)·Δθ / (2·t)
127
+ *
128
+ * with t the TOTAL thickness of the pair. The strip bends because the two
129
+ * metals want different lengths and are not allowed to have them, so it curves
130
+ * with the faster-expanding metal on the OUTSIDE of the curve.
131
+ *
132
+ * The sign follows through: a negative Δθ bends it the other way, which is what
133
+ * makes the strip a switch rather than merely a warning light.
134
+ *
135
+ * SCOPE: the equal-thickness, equal-modulus case of Timoshenko's result, which
136
+ * is how these strips are actually made and what every textbook quotes. A pair
137
+ * with different moduli bends less than this predicts.
138
+ */
139
+ function bimetallicBend(totalThicknessM, alphaHigh, alphaLow, deltaT, lengthM) {
140
+ const t = positive(totalThicknessM, "The strip thickness");
141
+ const L = positive(lengthM, "The strip length");
142
+ const curvature = 3 * (finite(alphaHigh, "The higher expansivity") - finite(alphaLow, "The lower expansivity")) * finite(deltaT, "A temperature change") / (2 * t);
143
+ if (curvature === 0) return {
144
+ radiusM: Number.POSITIVE_INFINITY,
145
+ angleRad: 0,
146
+ deflectionM: 0
147
+ };
148
+ const radiusM = 1 / curvature;
149
+ const angleRad = L * curvature;
150
+ return {
151
+ radiusM,
152
+ angleRad,
153
+ deflectionM: radiusM * (1 - Math.cos(angleRad))
154
+ };
155
+ }
156
+ /**
157
+ * The density of liquid water, kg/m³, between 0 °C and 100 °C.
158
+ *
159
+ * Water is the exception this whole file otherwise assumes away: its density
160
+ * PEAKS near 4 °C, so between 0 and 4 it contracts on warming and its expansion
161
+ * coefficient is negative. That anomaly is why ice floats, why a lake freezes
162
+ * from the top down, and why fish survive winter, so it is worth having as real
163
+ * data rather than as a note saying water is unusual.
164
+ *
165
+ * Uses the Thiesen-Scheel-Diesselhorst form, which fits measurement to about
166
+ * one part in 10⁵ across the range. A polynomial, not a physical model: it
167
+ * knows the shape of the curve and nothing about why.
168
+ */
169
+ function waterDensityKgM3(celsius) {
170
+ const t = finite(celsius, "A temperature");
171
+ if (t < 0 || t > 100) throw new RangeError(`This fit covers liquid water from 0 to 100 °C, and ${t} °C is outside it.`);
172
+ return 999.97495 * (1 - (t + 288.9414) * (t - 3.9863) ** 2 / (508929.2 * (t + 68.12963)));
173
+ }
174
+ /** The temperature at which water is densest, °C: the anomaly's turning point. */
175
+ const WATER_DENSITY_PEAK_C = 3.9863;
176
+
177
+ //#endregion
178
+ export { LINEAR_EXPANSIVITY, WATER_DENSITY_PEAK_C, areaCoefficient, bimetallicBend, densityAfterExpansionKgM3, expandedAreaM2, expandedLengthM, expandedVolumeM3, lengthChangeM, realExpansivity, thermalStressPa, volumeCoefficient, waterDensityKgM3 };
@@ -0,0 +1,197 @@
1
+ //#region src/thermo/gas.d.ts
2
+ /**
3
+ * The ideal gas and the kinetic theory behind it.
4
+ *
5
+ * THE MODEL, in one line each:
6
+ *
7
+ * equation of state pV = nRT = Nk_BT
8
+ * kinetic theory pV = ⅓·N·m·⟨c²⟩
9
+ *
10
+ * Setting those equal is the derivation the syllabus asks for, and it gives the
11
+ * whole of this file: ½m⟨c²⟩ = (3/2)k_BT says temperature IS mean translational
12
+ * kinetic energy, and everything about molecular speeds follows from it.
13
+ *
14
+ * WHY BOTH FORMS ARE HERE. `pV = nRT` is per MOLE and `pV = Nk_BT` is per
15
+ * MOLECULE, and mixing them up by a factor of N_A is the single most common
16
+ * arithmetic failure in this topic. Each function below states which it uses in
17
+ * its parameter names: `moles`/`molarMassKgPerMol` for the first,
18
+ * `molecules`/`particleMassKg` for the second.
19
+ *
20
+ * UNITS: strict SI. Pressure in pascals, volume in m³, temperature in KELVIN
21
+ * (never Celsius: these are ratios and proportionalities, so an offset scale
22
+ * gives nonsense rather than an error), molar mass in kg/mol (so oxygen is
23
+ * 0.032, not 32), speeds in m/s, energy in joules.
24
+ *
25
+ * SCOPE. The ideal gas, plus van der Waals as the first correction. No
26
+ * quantised internal modes, so the molar heat capacities here are the classical
27
+ * equipartition values and do not fall off at low temperature.
28
+ */
29
+ /** Molar gas constant, J/(mol·K). The one value, re-exported under its physics name. */
30
+ declare const R: number;
31
+ /** Boltzmann constant, J/K: the gas constant per molecule rather than per mole. */
32
+ declare const k_B = 1.380649e-23;
33
+ /** Avogadro constant, per mole. */
34
+ declare const N_A = 6.02214076e+23;
35
+ interface GasStateSpec {
36
+ /** Pressure, Pa. */
37
+ pressurePa?: number;
38
+ /** Volume, m³. */
39
+ volumeM3?: number;
40
+ /** Amount, mol. */
41
+ moles?: number;
42
+ /** Temperature, K. */
43
+ temperatureK?: number;
44
+ }
45
+ interface SolvedGasState {
46
+ pressurePa: number;
47
+ volumeM3: number;
48
+ moles: number;
49
+ temperatureK: number;
50
+ }
51
+ /**
52
+ * Solve pV = nRT for whichever single variable is missing.
53
+ *
54
+ * One function rather than four, because the equation is one equation: a lab
55
+ * that lets a student pick which quantity to find should not need a switch
56
+ * statement, and a question that changes which variable is unknown should not
57
+ * need a different call.
58
+ *
59
+ * Throws unless exactly one of the four is absent, since zero missing is a
60
+ * consistency check rather than a solve, and two missing has no unique answer.
61
+ */
62
+ declare function solveIdealGas(spec: GasStateSpec): SolvedGasState;
63
+ /**
64
+ * The combined gas law across a change of conditions: p₁V₁/T₁ = p₂V₂/T₂.
65
+ *
66
+ * Give the full initial state and the two known coordinates of the final one;
67
+ * the third comes back. This is the same physics as `solveIdealGas` with the
68
+ * amount held fixed, and it exists separately because the amount is what
69
+ * cancels: a question about a sealed container never mentions n, and forcing a
70
+ * caller to invent one would be asking them to supply a number the answer does
71
+ * not depend on.
72
+ */
73
+ declare function combinedGasLaw(from: {
74
+ pressurePa: number;
75
+ volumeM3: number;
76
+ temperatureK: number;
77
+ }, to: {
78
+ pressurePa?: number;
79
+ volumeM3?: number;
80
+ temperatureK?: number;
81
+ }): {
82
+ pressurePa: number;
83
+ volumeM3: number;
84
+ temperatureK: number;
85
+ };
86
+ /**
87
+ * Pressure from the kinetic theory: p = N·m·⟨c²⟩ / 3V.
88
+ *
89
+ * The factor of three is the only interesting thing in it: molecules move in
90
+ * three dimensions and only the component along one axis pushes on that axis's
91
+ * wall, so ⟨c_x²⟩ = ⟨c²⟩/3.
92
+ */
93
+ declare function kineticPressurePa(molecules: number, particleMassKg: number, meanSquareSpeed: number, volumeM3: number): number;
94
+ /** Mean square speed ⟨c²⟩ = 3RT/M, m²/s². */
95
+ declare function meanSquareSpeed(temperatureK: number, molarMassKgPerMol: number): number;
96
+ /**
97
+ * Root mean square speed, √(3RT/M), m/s.
98
+ *
99
+ * The speed that appears in the pressure, and the largest of the three
100
+ * averages below. It is larger than the plain mean because squaring weights the
101
+ * fast molecules more heavily, and that difference is not a rounding detail:
102
+ * evaporation and escape from the atmosphere both depend on the tail.
103
+ */
104
+ declare function rmsSpeedMs(temperatureK: number, molarMassKgPerMol: number): number;
105
+ /** Mean (arithmetic average) speed, √(8RT/πM), m/s. */
106
+ declare function meanSpeedMs(temperatureK: number, molarMassKgPerMol: number): number;
107
+ /** Most probable speed, √(2RT/M), m/s: the peak of the distribution. */
108
+ declare function mostProbableSpeedMs(temperatureK: number, molarMassKgPerMol: number): number;
109
+ /**
110
+ * The root mean square of a list of individual speeds.
111
+ *
112
+ * For the question that hands you five molecules and asks for the rms rather
113
+ * than a temperature. Kept beside the theoretical version so the two can be
114
+ * compared, which is the point of asking.
115
+ */
116
+ declare function rmsOf(speeds: readonly number[]): number;
117
+ /** Mean translational kinetic energy per molecule, (3/2)k_BT, J. */
118
+ declare function meanTranslationalEnergyJ(temperatureK: number): number;
119
+ /**
120
+ * The Maxwell-Boltzmann speed distribution, as a probability density in s/m:
121
+ *
122
+ * f(v) = 4π (M/2πRT)^{3/2} · v² · exp(−Mv²/2RT)
123
+ *
124
+ * Note it is a DENSITY, so f(v) alone is not a probability and only ∫f dv
125
+ * between two speeds is. The v² in front is why the curve starts at zero rather
126
+ * than at its maximum: there are very few ways to be slow in three dimensions,
127
+ * however favourable the exponential.
128
+ */
129
+ declare function maxwellBoltzmannPdf(speedMs: number, temperatureK: number, molarMassKgPerMol: number): number;
130
+ /**
131
+ * Mean free path, m: λ = 1 / (√2 · π · d² · n).
132
+ *
133
+ * `numberDensity` is molecules per m³, `diameterM` the molecular diameter. The
134
+ * √2 is the correction for the other molecules moving too, which is the part
135
+ * that is usually dropped in a first derivation and then quietly restored.
136
+ */
137
+ declare function meanFreePathM(diameterM: number, numberDensity: number): number;
138
+ interface MolarHeatCapacities {
139
+ /** At constant volume, J/(mol·K). */
140
+ cv: number;
141
+ /** At constant pressure, J/(mol·K). */
142
+ cp: number;
143
+ /** The ratio Cp/Cv. */
144
+ gamma: number;
145
+ /** Degrees of freedom implied by that ratio. */
146
+ degreesOfFreedom: number;
147
+ }
148
+ /**
149
+ * The molar heat capacities implied by a ratio γ, through Mayer's relation.
150
+ *
151
+ * Cp − Cv = R and γ = Cp/Cv ⟹ Cv = R/(γ−1), Cp = γR/(γ−1)
152
+ *
153
+ * Mayer's relation is not an extra assumption: heating at constant pressure has
154
+ * to pay for the expansion work as well as the internal energy, and for an
155
+ * ideal gas that work is exactly R per mole per kelvin. So the two capacities
156
+ * differ by R and by nothing else, and the ratio alone fixes both.
157
+ */
158
+ declare function molarHeatCapacities(gamma: number): MolarHeatCapacities;
159
+ /**
160
+ * γ from the number of active degrees of freedom: γ = 1 + 2/f.
161
+ *
162
+ * Equipartition gives each degree of freedom ½k_BT, so f fixes Cv and therefore
163
+ * γ. Monatomic f = 3 (translation only) → 5/3; diatomic f = 5 (plus two
164
+ * rotations) → 7/5; a non-linear triatomic f = 6 → 4/3.
165
+ */
166
+ declare function gammaFromDegreesOfFreedom(f: number): number;
167
+ /** γ = 5/3, a monatomic gas: three translational degrees of freedom and no more. */
168
+ declare const gammaMonatomic: number;
169
+ /** γ = 7/5, a diatomic gas: translation plus two rotations. */
170
+ declare const gammaDiatomic: number;
171
+ /** γ = 4/3, a non-linear polyatomic gas: translation plus three rotations. */
172
+ declare const gammaPolyatomic: number;
173
+ /**
174
+ * Internal energy of an ideal gas, J: U = n·Cv·T.
175
+ *
176
+ * Depends on temperature ALONE, with no volume term, and that is the defining
177
+ * property of an ideal gas rather than an approximation to one. There are no
178
+ * intermolecular forces, so pulling the molecules further apart costs nothing
179
+ * and the internal energy does not notice the volume changed.
180
+ */
181
+ declare function internalEnergyJ(moles: number, temperatureK: number, gamma?: number): number;
182
+ /**
183
+ * Van der Waals pressure, Pa:
184
+ *
185
+ * p = nRT/(V − nb) − a·n²/V²
186
+ *
187
+ * The two corrections say the two things an ideal gas denies. `b` is the volume
188
+ * the molecules themselves occupy, so the space available to move in is less
189
+ * than V; `a` is the attraction between them, so a molecule about to strike the
190
+ * wall is pulled back by the ones behind it and the pressure is less than it
191
+ * would otherwise be.
192
+ *
193
+ * Units: `a` in Pa·m⁶/mol², `b` in m³/mol.
194
+ */
195
+ declare function vanDerWaalsPressurePa(moles: number, volumeM3: number, temperatureK: number, a: number, b: number): number;
196
+ //#endregion
197
+ export { GasStateSpec, MolarHeatCapacities, N_A, R, SolvedGasState, combinedGasLaw, gammaDiatomic, gammaFromDegreesOfFreedom, gammaMonatomic, gammaPolyatomic, internalEnergyJ, k_B, kineticPressurePa, maxwellBoltzmannPdf, meanFreePathM, meanSpeedMs, meanSquareSpeed, meanTranslationalEnergyJ, molarHeatCapacities, mostProbableSpeedMs, rmsOf, rmsSpeedMs, solveIdealGas, vanDerWaalsPressurePa };
@@ -0,0 +1,279 @@
1
+ import { AVOGADRO, BOLTZMANN, GAS_CONSTANT } from "../core/constants.mjs";
2
+
3
+ //#region src/thermo/gas.ts
4
+ /**
5
+ * The ideal gas and the kinetic theory behind it.
6
+ *
7
+ * THE MODEL, in one line each:
8
+ *
9
+ * equation of state pV = nRT = Nk_BT
10
+ * kinetic theory pV = ⅓·N·m·⟨c²⟩
11
+ *
12
+ * Setting those equal is the derivation the syllabus asks for, and it gives the
13
+ * whole of this file: ½m⟨c²⟩ = (3/2)k_BT says temperature IS mean translational
14
+ * kinetic energy, and everything about molecular speeds follows from it.
15
+ *
16
+ * WHY BOTH FORMS ARE HERE. `pV = nRT` is per MOLE and `pV = Nk_BT` is per
17
+ * MOLECULE, and mixing them up by a factor of N_A is the single most common
18
+ * arithmetic failure in this topic. Each function below states which it uses in
19
+ * its parameter names: `moles`/`molarMassKgPerMol` for the first,
20
+ * `molecules`/`particleMassKg` for the second.
21
+ *
22
+ * UNITS: strict SI. Pressure in pascals, volume in m³, temperature in KELVIN
23
+ * (never Celsius: these are ratios and proportionalities, so an offset scale
24
+ * gives nonsense rather than an error), molar mass in kg/mol (so oxygen is
25
+ * 0.032, not 32), speeds in m/s, energy in joules.
26
+ *
27
+ * SCOPE. The ideal gas, plus van der Waals as the first correction. No
28
+ * quantised internal modes, so the molar heat capacities here are the classical
29
+ * equipartition values and do not fall off at low temperature.
30
+ */
31
+ /** Molar gas constant, J/(mol·K). The one value, re-exported under its physics name. */
32
+ const R = GAS_CONSTANT;
33
+ /** Boltzmann constant, J/K: the gas constant per molecule rather than per mole. */
34
+ const k_B = BOLTZMANN;
35
+ /** Avogadro constant, per mole. */
36
+ const N_A = AVOGADRO;
37
+ const finite = (value, what) => {
38
+ if (!Number.isFinite(value)) throw new RangeError(`${what} must be a finite number.`);
39
+ return value;
40
+ };
41
+ const positive = (value, what) => {
42
+ if (!Number.isFinite(value) || value <= 0) throw new RangeError(`${what} must be positive.`);
43
+ return value;
44
+ };
45
+ /**
46
+ * Guard for a thermodynamic temperature.
47
+ *
48
+ * Separate from `positive` so the message can say the useful thing. A caller
49
+ * who passes 25 meaning room temperature gets a plausible wrong answer, but a
50
+ * caller who passes −10 meaning a cold day gets told what the problem is.
51
+ */
52
+ const kelvin = (value) => {
53
+ if (!Number.isFinite(value) || value <= 0) throw new RangeError(`Temperature must be a positive number of kelvin (got ${value}). Celsius readings need converting first.`);
54
+ return value;
55
+ };
56
+ /**
57
+ * Solve pV = nRT for whichever single variable is missing.
58
+ *
59
+ * One function rather than four, because the equation is one equation: a lab
60
+ * that lets a student pick which quantity to find should not need a switch
61
+ * statement, and a question that changes which variable is unknown should not
62
+ * need a different call.
63
+ *
64
+ * Throws unless exactly one of the four is absent, since zero missing is a
65
+ * consistency check rather than a solve, and two missing has no unique answer.
66
+ */
67
+ function solveIdealGas(spec) {
68
+ const { pressurePa: p, volumeM3: V, moles: n, temperatureK: T } = spec;
69
+ const given = [
70
+ p,
71
+ V,
72
+ n,
73
+ T
74
+ ].filter((x) => x !== void 0);
75
+ if (given.length !== 3) throw new RangeError(`pV = nRT determines one unknown from three knowns, but ${given.length} of the four were given.`);
76
+ if (p === void 0) return {
77
+ pressurePa: positive(n, "Amount") * R * kelvin(T) / positive(V, "Volume"),
78
+ volumeM3: V,
79
+ moles: n,
80
+ temperatureK: T
81
+ };
82
+ if (V === void 0) return {
83
+ pressurePa: p,
84
+ volumeM3: positive(n, "Amount") * R * kelvin(T) / positive(p, "Pressure"),
85
+ moles: n,
86
+ temperatureK: T
87
+ };
88
+ if (n === void 0) return {
89
+ pressurePa: p,
90
+ volumeM3: V,
91
+ moles: positive(p, "Pressure") * positive(V, "Volume") / (R * kelvin(T)),
92
+ temperatureK: T
93
+ };
94
+ return {
95
+ pressurePa: p,
96
+ volumeM3: V,
97
+ moles: n,
98
+ temperatureK: positive(p, "Pressure") * positive(V, "Volume") / (positive(n, "Amount") * R)
99
+ };
100
+ }
101
+ /**
102
+ * The combined gas law across a change of conditions: p₁V₁/T₁ = p₂V₂/T₂.
103
+ *
104
+ * Give the full initial state and the two known coordinates of the final one;
105
+ * the third comes back. This is the same physics as `solveIdealGas` with the
106
+ * amount held fixed, and it exists separately because the amount is what
107
+ * cancels: a question about a sealed container never mentions n, and forcing a
108
+ * caller to invent one would be asking them to supply a number the answer does
109
+ * not depend on.
110
+ */
111
+ function combinedGasLaw(from, to) {
112
+ const ratio = positive(from.pressurePa, "Initial pressure") * positive(from.volumeM3, "Initial volume") / kelvin(from.temperatureK);
113
+ const given = [
114
+ to.pressurePa,
115
+ to.volumeM3,
116
+ to.temperatureK
117
+ ].filter((x) => x !== void 0);
118
+ if (given.length !== 2) throw new RangeError(`The final state needs exactly two of its three coordinates, but ${given.length} were given.`);
119
+ if (to.pressurePa === void 0) return {
120
+ pressurePa: ratio * kelvin(to.temperatureK) / positive(to.volumeM3, "Final volume"),
121
+ volumeM3: to.volumeM3,
122
+ temperatureK: to.temperatureK
123
+ };
124
+ if (to.volumeM3 === void 0) return {
125
+ pressurePa: to.pressurePa,
126
+ volumeM3: ratio * kelvin(to.temperatureK) / positive(to.pressurePa, "Final pressure"),
127
+ temperatureK: to.temperatureK
128
+ };
129
+ return {
130
+ pressurePa: to.pressurePa,
131
+ volumeM3: to.volumeM3,
132
+ temperatureK: positive(to.pressurePa, "Final pressure") * positive(to.volumeM3, "Final volume") / ratio
133
+ };
134
+ }
135
+ /**
136
+ * Pressure from the kinetic theory: p = N·m·⟨c²⟩ / 3V.
137
+ *
138
+ * The factor of three is the only interesting thing in it: molecules move in
139
+ * three dimensions and only the component along one axis pushes on that axis's
140
+ * wall, so ⟨c_x²⟩ = ⟨c²⟩/3.
141
+ */
142
+ function kineticPressurePa(molecules, particleMassKg, meanSquareSpeed, volumeM3) {
143
+ return positive(molecules, "The number of molecules") * positive(particleMassKg, "Particle mass") * positive(meanSquareSpeed, "Mean square speed") / (3 * positive(volumeM3, "Volume"));
144
+ }
145
+ /** Mean square speed ⟨c²⟩ = 3RT/M, m²/s². */
146
+ function meanSquareSpeed(temperatureK, molarMassKgPerMol) {
147
+ return 3 * R * kelvin(temperatureK) / positive(molarMassKgPerMol, "Molar mass");
148
+ }
149
+ /**
150
+ * Root mean square speed, √(3RT/M), m/s.
151
+ *
152
+ * The speed that appears in the pressure, and the largest of the three
153
+ * averages below. It is larger than the plain mean because squaring weights the
154
+ * fast molecules more heavily, and that difference is not a rounding detail:
155
+ * evaporation and escape from the atmosphere both depend on the tail.
156
+ */
157
+ function rmsSpeedMs(temperatureK, molarMassKgPerMol) {
158
+ return Math.sqrt(meanSquareSpeed(temperatureK, molarMassKgPerMol));
159
+ }
160
+ /** Mean (arithmetic average) speed, √(8RT/πM), m/s. */
161
+ function meanSpeedMs(temperatureK, molarMassKgPerMol) {
162
+ return Math.sqrt(8 * R * kelvin(temperatureK) / (Math.PI * positive(molarMassKgPerMol, "Molar mass")));
163
+ }
164
+ /** Most probable speed, √(2RT/M), m/s: the peak of the distribution. */
165
+ function mostProbableSpeedMs(temperatureK, molarMassKgPerMol) {
166
+ return Math.sqrt(2 * R * kelvin(temperatureK) / positive(molarMassKgPerMol, "Molar mass"));
167
+ }
168
+ /**
169
+ * The root mean square of a list of individual speeds.
170
+ *
171
+ * For the question that hands you five molecules and asks for the rms rather
172
+ * than a temperature. Kept beside the theoretical version so the two can be
173
+ * compared, which is the point of asking.
174
+ */
175
+ function rmsOf(speeds) {
176
+ if (speeds.length === 0) throw new RangeError("No speeds to average.");
177
+ return Math.sqrt(speeds.reduce((sum, v) => sum + finite(v, "A speed") ** 2, 0) / speeds.length);
178
+ }
179
+ /** Mean translational kinetic energy per molecule, (3/2)k_BT, J. */
180
+ function meanTranslationalEnergyJ(temperatureK) {
181
+ return 1.5 * k_B * kelvin(temperatureK);
182
+ }
183
+ /**
184
+ * The Maxwell-Boltzmann speed distribution, as a probability density in s/m:
185
+ *
186
+ * f(v) = 4π (M/2πRT)^{3/2} · v² · exp(−Mv²/2RT)
187
+ *
188
+ * Note it is a DENSITY, so f(v) alone is not a probability and only ∫f dv
189
+ * between two speeds is. The v² in front is why the curve starts at zero rather
190
+ * than at its maximum: there are very few ways to be slow in three dimensions,
191
+ * however favourable the exponential.
192
+ */
193
+ function maxwellBoltzmannPdf(speedMs, temperatureK, molarMassKgPerMol) {
194
+ const v = finite(speedMs, "Speed");
195
+ if (v < 0) throw new RangeError("A speed cannot be negative.");
196
+ const M = positive(molarMassKgPerMol, "Molar mass");
197
+ const T = kelvin(temperatureK);
198
+ const a = M / (2 * Math.PI * R * T);
199
+ return 4 * Math.PI * a ** 1.5 * v * v * Math.exp(-M * v * v / (2 * R * T));
200
+ }
201
+ /**
202
+ * Mean free path, m: λ = 1 / (√2 · π · d² · n).
203
+ *
204
+ * `numberDensity` is molecules per m³, `diameterM` the molecular diameter. The
205
+ * √2 is the correction for the other molecules moving too, which is the part
206
+ * that is usually dropped in a first derivation and then quietly restored.
207
+ */
208
+ function meanFreePathM(diameterM, numberDensity) {
209
+ return 1 / (Math.SQRT2 * Math.PI * positive(diameterM, "Molecular diameter") ** 2 * positive(numberDensity, "Number density"));
210
+ }
211
+ /**
212
+ * The molar heat capacities implied by a ratio γ, through Mayer's relation.
213
+ *
214
+ * Cp − Cv = R and γ = Cp/Cv ⟹ Cv = R/(γ−1), Cp = γR/(γ−1)
215
+ *
216
+ * Mayer's relation is not an extra assumption: heating at constant pressure has
217
+ * to pay for the expansion work as well as the internal energy, and for an
218
+ * ideal gas that work is exactly R per mole per kelvin. So the two capacities
219
+ * differ by R and by nothing else, and the ratio alone fixes both.
220
+ */
221
+ function molarHeatCapacities(gamma) {
222
+ if (!(gamma > 1)) throw new RangeError(`γ must exceed 1 (got ${gamma}). Cp always exceeds Cv, because heating at constant pressure also pays for the expansion.`);
223
+ return {
224
+ cv: R / (gamma - 1),
225
+ cp: gamma * R / (gamma - 1),
226
+ gamma,
227
+ degreesOfFreedom: 2 / (gamma - 1)
228
+ };
229
+ }
230
+ /**
231
+ * γ from the number of active degrees of freedom: γ = 1 + 2/f.
232
+ *
233
+ * Equipartition gives each degree of freedom ½k_BT, so f fixes Cv and therefore
234
+ * γ. Monatomic f = 3 (translation only) → 5/3; diatomic f = 5 (plus two
235
+ * rotations) → 7/5; a non-linear triatomic f = 6 → 4/3.
236
+ */
237
+ function gammaFromDegreesOfFreedom(f) {
238
+ return 1 + 2 / positive(f, "The number of degrees of freedom");
239
+ }
240
+ /** γ = 5/3, a monatomic gas: three translational degrees of freedom and no more. */
241
+ const gammaMonatomic = 5 / 3;
242
+ /** γ = 7/5, a diatomic gas: translation plus two rotations. */
243
+ const gammaDiatomic = 7 / 5;
244
+ /** γ = 4/3, a non-linear polyatomic gas: translation plus three rotations. */
245
+ const gammaPolyatomic = 4 / 3;
246
+ /**
247
+ * Internal energy of an ideal gas, J: U = n·Cv·T.
248
+ *
249
+ * Depends on temperature ALONE, with no volume term, and that is the defining
250
+ * property of an ideal gas rather than an approximation to one. There are no
251
+ * intermolecular forces, so pulling the molecules further apart costs nothing
252
+ * and the internal energy does not notice the volume changed.
253
+ */
254
+ function internalEnergyJ(moles, temperatureK, gamma = gammaMonatomic) {
255
+ return positive(moles, "Amount") * molarHeatCapacities(gamma).cv * kelvin(temperatureK);
256
+ }
257
+ /**
258
+ * Van der Waals pressure, Pa:
259
+ *
260
+ * p = nRT/(V − nb) − a·n²/V²
261
+ *
262
+ * The two corrections say the two things an ideal gas denies. `b` is the volume
263
+ * the molecules themselves occupy, so the space available to move in is less
264
+ * than V; `a` is the attraction between them, so a molecule about to strike the
265
+ * wall is pulled back by the ones behind it and the pressure is less than it
266
+ * would otherwise be.
267
+ *
268
+ * Units: `a` in Pa·m⁶/mol², `b` in m³/mol.
269
+ */
270
+ function vanDerWaalsPressurePa(moles, volumeM3, temperatureK, a, b) {
271
+ const n = positive(moles, "Amount");
272
+ const V = positive(volumeM3, "Volume");
273
+ const free = V - n * finite(b, "The excluded volume b");
274
+ if (free <= 0) throw new RangeError("The gas is compressed past the volume of its own molecules, where van der Waals no longer applies.");
275
+ return n * R * kelvin(temperatureK) / free - finite(a, "The attraction term a") * n * n / (V * V);
276
+ }
277
+
278
+ //#endregion
279
+ export { N_A, R, combinedGasLaw, gammaDiatomic, gammaFromDegreesOfFreedom, gammaMonatomic, gammaPolyatomic, internalEnergyJ, k_B, kineticPressurePa, maxwellBoltzmannPdf, meanFreePathM, meanSpeedMs, meanSquareSpeed, meanTranslationalEnergyJ, molarHeatCapacities, mostProbableSpeedMs, rmsOf, rmsSpeedMs, solveIdealGas, vanDerWaalsPressurePa };