@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,164 @@
1
+ import { Worked } from "../../core/worked.mjs";
2
+ import { Node } from "../../math/ast.mjs";
3
+ import { Sweep } from "../integral-sweep.mjs";
4
+
5
+ //#region src/physics/rotation/inertia.d.ts
6
+ /**
7
+ * How to DRAW the body and the element sweeping through it.
8
+ *
9
+ * This lives in the kernel rather than in each lab on purpose. The element's shape is not
10
+ * decoration, it IS the derivation: the disc is cut into rings because a ring is the set of points
11
+ * at one distance from the axis, and the sphere is cut into discs because a disc is a thing whose
12
+ * moment of inertia we already know. A renderer that invented its own picture could easily draw
13
+ * strips across a disc, which would look fine and would be a different integral.
14
+ *
15
+ * Kept as a small closed vocabulary rather than as drawing instructions, so the kernel stays free
16
+ * of pixels and a renderer can draw a band however suits its scene.
17
+ */
18
+ interface ShapeGeometry {
19
+ /** The body's outline. */
20
+ readonly body: 'rod' | 'disc' | 'ring' | 'sphere' | 'shell' | 'plate';
21
+ /** The shape of one element of the integral. */
22
+ readonly element: 'strip' | 'annulus' | 'slice' | 'band' | 'whole-ring';
23
+ /** Which way the element travels as the variable runs from `from` to `to`. */
24
+ readonly sweep: 'along-length' | 'outward-from-axis' | 'along-axis' | 'by-mass';
25
+ /**
26
+ * Which symbol sets the body's overall size, so a renderer can scale the scene to fit without
27
+ * being told separately.
28
+ */
29
+ readonly extent: string;
30
+ }
31
+ /** A rigid body declared by how its mass is spread, not by its answer. */
32
+ interface ShapeSpec {
33
+ readonly id: string;
34
+ /** "uniform rod", for a lesson heading. */
35
+ readonly name: string;
36
+ /** Which axis this is about. Half the exam marks in this topic are about the axis. */
37
+ readonly axis: string;
38
+ /** Each symbol and what it means, so a lab can label its controls. */
39
+ readonly symbols: Readonly<Record<string, string>>;
40
+ /** The variable integrated over. */
41
+ readonly variable: string;
42
+ /**
43
+ * `dI`, the contribution of one element, as an expression in `variable`. EXPANDED: see the note
44
+ * at the top of the file about what the integrator will and will not accept.
45
+ */
46
+ readonly element: string;
47
+ /** Where the element expression came from, in words, for the derivation. */
48
+ readonly elementNote: string;
49
+ /** Integration limits, as expressions in the symbols. */
50
+ readonly from: string;
51
+ readonly to: string;
52
+ /** The standard result. Used to CHECK the integral, never to replace it. */
53
+ readonly closedForm: string;
54
+ /** How the standard result is usually written, in LaTeX. */
55
+ readonly closedFormTex: string;
56
+ /** What a lab draws, and how the element moves through it. */
57
+ readonly geometry: ShapeGeometry;
58
+ }
59
+ interface InertiaResult {
60
+ readonly shape: ShapeSpec;
61
+ /** kg m², from the integral. */
62
+ readonly value: number;
63
+ /** The same thing from the closed form. Equal to `value`; the tests are what enforce that. */
64
+ readonly checkValue: number;
65
+ /** The antiderivative, for a lesson that wants to show the middle of the working. */
66
+ readonly antiderivative: Node;
67
+ readonly worked: Worked;
68
+ }
69
+ declare const SHAPES: Readonly<Record<string, ShapeSpec>>;
70
+ declare const shapeIds: () => readonly string[];
71
+ /**
72
+ * `I = ∫ r² dm` for a declared shape, with the integral shown.
73
+ *
74
+ * `values` supplies the symbols: `{ M: 2, R: 0.5 }`. The integral is done symbolically once and
75
+ * then evaluated at the limits, so what a lesson displays and what a lab computes are the same
76
+ * object rather than two implementations that agree today.
77
+ */
78
+ declare function momentOfInertia(shape: ShapeSpec, values: Readonly<Record<string, number>>, sf?: number): InertiaResult;
79
+ /**
80
+ * The shape's integral as a watchable sweep: the element travelling through the body with the
81
+ * running total behind it.
82
+ *
83
+ * This is where the `r²` stops being a symbol. For a uniform disc, half the moment of inertia comes
84
+ * from beyond 84% of the radius, and a learner who has watched the meter barely move across the
85
+ * inner half will not need to be told why a flywheel is heavy at the rim.
86
+ */
87
+ declare const sweepOf: (shape: ShapeSpec, values: Readonly<Record<string, number>>, samples?: number) => Sweep;
88
+ /** Where a given fraction of the moment of inertia has accumulated by. */
89
+ declare const inertiaComesFrom: (shape: ShapeSpec, values: Readonly<Record<string, number>>, fraction?: number) => number;
90
+ /**
91
+ * `I = Σ m r²` for point masses, where `r` is the distance from the AXIS, not from the origin.
92
+ *
93
+ * That distinction is the whole difficulty. For a mass at (x, y, z) rotating about the z axis the
94
+ * distance that matters is `√(x² + y²)`: the z coordinate is along the axis and contributes
95
+ * nothing, however large it is. Students routinely use the full position vector and get an answer
96
+ * that is too big, and the error is invisible in the common textbook case where every mass happens
97
+ * to lie in a plane through the origin.
98
+ *
99
+ * This is also the definition the continuous shapes are integrals OF, so it belongs beside them: a
100
+ * disc is this sum with the masses made infinitesimal and the sum made an integral.
101
+ */
102
+ declare function pointMasses(masses: readonly {
103
+ label?: string;
104
+ mass: number;
105
+ distance: number;
106
+ }[], sf?: number): {
107
+ value: number;
108
+ totalMass: number;
109
+ worked: Worked;
110
+ };
111
+ /** Distance from an axis through the origin along `axis`, for a mass at (x, y, z). */
112
+ declare function distanceFromAxis(position: {
113
+ x: number;
114
+ y: number;
115
+ z: number;
116
+ }, axis?: 'x' | 'y' | 'z'): number;
117
+ /**
118
+ * Move an axis sideways: `I = I_cm + Mh²`.
119
+ *
120
+ * An operation, not a formula to recall, so a lab can let a learner drag the pivot and watch the
121
+ * number rise. It only works from the CENTRE OF MASS axis, and the error message says so, because
122
+ * applying it from an arbitrary axis is the standard mistake.
123
+ */
124
+ declare function parallelAxis(aboutCentreOfMass: number, mass: number, distance: number, sf?: number): {
125
+ value: number;
126
+ worked: Worked;
127
+ };
128
+ /**
129
+ * For a FLAT body only: `I_z = I_x + I_y`.
130
+ *
131
+ * The flatness is the whole condition and is where the marks go, so it is in the note rather than
132
+ * in a comment. This is how the disc's `¼MR²` about a diameter is obtained from its `½MR²` about
133
+ * the axis, which is exactly the move the textbook makes and never justifies.
134
+ */
135
+ declare function perpendicularAxis(inPlaneX: number, inPlaneY: number, sf?: number): {
136
+ value: number;
137
+ worked: Worked;
138
+ };
139
+ /**
140
+ * Add rigid bodies that share an axis.
141
+ *
142
+ * Moment of inertia is a scalar once the axis is fixed, so assemblies just add. That is what makes
143
+ * a three-blade fan tractable: one disc plus three rods, each rod moved out by the parallel axis
144
+ * theorem. A lab that lets a learner build a body out of parts is this function.
145
+ */
146
+ declare function combine(parts: readonly {
147
+ label: string;
148
+ value: number;
149
+ }[], sf?: number): {
150
+ value: number;
151
+ worked: Worked;
152
+ };
153
+ /**
154
+ * `K = √(I/M)`: where a single point mass would have to sit to have the same moment of inertia.
155
+ *
156
+ * Worth saying in those words. It is routinely confused with the distance to the centre of mass,
157
+ * which it is not, and the textbook flags that confusion without explaining it.
158
+ */
159
+ declare function radiusOfGyration(inertia: number, mass: number, sf?: number): {
160
+ value: number;
161
+ worked: Worked;
162
+ };
163
+ //#endregion
164
+ export { InertiaResult, SHAPES, ShapeGeometry, ShapeSpec, combine, distanceFromAxis, inertiaComesFrom, momentOfInertia, parallelAxis, perpendicularAxis, pointMasses, radiusOfGyration, shapeIds, sweepOf };
@@ -0,0 +1,332 @@
1
+ import { evaluate } from "../../math/ast.mjs";
2
+ import { parse } from "../../math/parse.mjs";
3
+ import { integrate, simplify } from "../../math/calculus.mjs";
4
+ import { toLatex } from "../../math/latex.mjs";
5
+ import { calc, texSigFigs } from "../../core/worked.mjs";
6
+ import { positionAtFraction, sweep } from "../integral-sweep.mjs";
7
+
8
+ //#region src/physics/rotation/inertia.ts
9
+ /**
10
+ * Moment of inertia, DERIVED rather than looked up.
11
+ *
12
+ * Every textbook at this level prints a table of eight standard results to memorise, and derives
13
+ * one or two of them in passing. The table is the problem. A student who memorises `I = ⅖MR²` has
14
+ * no way to check it, no idea why the sphere differs from the disc, and nothing to fall back on
15
+ * when the question is about a shape that is not in the table.
16
+ *
17
+ * So no result here is a constant. A shape is declared as a MASS DISTRIBUTION, and `I` comes out of
18
+ * an integral performed symbolically by `math/calculus`, together with the integral itself so a
19
+ * lesson can show it. The standard table is then an OUTPUT of this module rather than an input to
20
+ * it, which is the whole point.
21
+ *
22
+ * ```
23
+ * I = ∫ r² dm
24
+ * ```
25
+ *
26
+ * WHY EACH SHAPE ALSO DECLARES ITS CLOSED FORM. It is not a duplicated source of truth, it is a
27
+ * CHECK: the tests integrate the distribution and evaluate the closed form at randomised
28
+ * dimensions and require them to agree, so a mis-stated distribution cannot pass silently.
29
+ * Deriving without verifying would just be a more elaborate way to be wrong.
30
+ *
31
+ * The integrand is written the way a learner would write it, `(R² − x²)²` and not its expansion,
32
+ * because `math/calculus` multiplies out before integrating. An integrand with no closed form at
33
+ * all is still fine for the SWEEP, which falls back to quadrature and says that it did; it is only
34
+ * this function, which quotes a formula, that needs a symbolic answer.
35
+ *
36
+ * Pure: no React, no pixels.
37
+ */
38
+ const SHAPE_LIST = [
39
+ {
40
+ id: "rod-centre",
41
+ name: "uniform rod",
42
+ axis: "through its centre, at right angles to its length",
43
+ symbols: {
44
+ M: "mass",
45
+ l: "length"
46
+ },
47
+ variable: "x",
48
+ element: "(M/l)*x^2",
49
+ elementNote: "a piece of length dx has mass (M/l)dx, and sits a distance x from the axis",
50
+ from: "-l/2",
51
+ to: "l/2",
52
+ closedForm: "M*l^2/12",
53
+ closedFormTex: "\\tfrac{1}{12}Ml^2",
54
+ geometry: {
55
+ body: "rod",
56
+ element: "strip",
57
+ sweep: "along-length",
58
+ extent: "l"
59
+ }
60
+ },
61
+ {
62
+ id: "rod-end",
63
+ name: "uniform rod",
64
+ axis: "through one end, at right angles to its length",
65
+ symbols: {
66
+ M: "mass",
67
+ l: "length"
68
+ },
69
+ variable: "x",
70
+ element: "(M/l)*x^2",
71
+ elementNote: "the same rod and the same elements; only the limits move, because the axis moved",
72
+ from: "0",
73
+ to: "l",
74
+ closedForm: "M*l^2/3",
75
+ closedFormTex: "\\tfrac{1}{3}Ml^2",
76
+ geometry: {
77
+ body: "rod",
78
+ element: "strip",
79
+ sweep: "along-length",
80
+ extent: "l"
81
+ }
82
+ },
83
+ {
84
+ id: "disc-axis",
85
+ name: "uniform disc",
86
+ axis: "through its centre, perpendicular to its face",
87
+ symbols: {
88
+ M: "mass",
89
+ R: "radius"
90
+ },
91
+ variable: "r",
92
+ element: "(2*M/R^2)*r^3",
93
+ elementNote: "a ring of radius r and width dr has area 2πr dr, so mass (M/πR²)·2πr dr, all of it a distance r from the axis",
94
+ from: "0",
95
+ to: "R",
96
+ closedForm: "M*R^2/2",
97
+ closedFormTex: "\\tfrac{1}{2}MR^2",
98
+ geometry: {
99
+ body: "disc",
100
+ element: "annulus",
101
+ sweep: "outward-from-axis",
102
+ extent: "R"
103
+ }
104
+ },
105
+ {
106
+ id: "ring-axis",
107
+ name: "thin ring",
108
+ axis: "through its centre, perpendicular to its plane",
109
+ symbols: {
110
+ M: "mass",
111
+ R: "radius"
112
+ },
113
+ variable: "m",
114
+ element: "R^2",
115
+ elementNote: "every part of the ring is the same distance R from the axis, so no shape is needed at all",
116
+ from: "0",
117
+ to: "M",
118
+ closedForm: "M*R^2",
119
+ closedFormTex: "MR^2",
120
+ geometry: {
121
+ body: "ring",
122
+ element: "whole-ring",
123
+ sweep: "by-mass",
124
+ extent: "R"
125
+ }
126
+ },
127
+ {
128
+ id: "solid-sphere",
129
+ name: "solid sphere",
130
+ axis: "through its centre",
131
+ symbols: {
132
+ M: "mass",
133
+ R: "radius"
134
+ },
135
+ variable: "x",
136
+ element: "(3*M/(8*R^3))*(R^2 - x^2)^2",
137
+ elementNote: "slice it into discs. The disc at x has radius √(R²−x²), and a disc contributes ½r²dm, which is where the square comes from",
138
+ from: "-R",
139
+ to: "R",
140
+ closedForm: "2*M*R^2/5",
141
+ closedFormTex: "\\tfrac{2}{5}MR^2",
142
+ geometry: {
143
+ body: "sphere",
144
+ element: "slice",
145
+ sweep: "along-axis",
146
+ extent: "R"
147
+ }
148
+ },
149
+ {
150
+ id: "hollow-sphere",
151
+ name: "thin spherical shell",
152
+ axis: "through its centre",
153
+ symbols: {
154
+ M: "mass",
155
+ R: "radius"
156
+ },
157
+ variable: "x",
158
+ element: "(M/(2*R))*(R^2 - x^2)",
159
+ elementNote: "a band of the shell between x and x+dx has mass (M/2R)dx, which is Archimedes’ result that equal slices of a sphere carry equal surface area, and it sits at radius √(R²−x²)",
160
+ from: "-R",
161
+ to: "R",
162
+ closedForm: "2*M*R^2/3",
163
+ closedFormTex: "\\tfrac{2}{3}MR^2",
164
+ geometry: {
165
+ body: "shell",
166
+ element: "band",
167
+ sweep: "along-axis",
168
+ extent: "R"
169
+ }
170
+ },
171
+ {
172
+ id: "plate-in-plane",
173
+ name: "rectangular plate",
174
+ axis: "in its plane, through the centre, parallel to the side of length b",
175
+ symbols: {
176
+ M: "mass",
177
+ l: "length",
178
+ b: "breadth"
179
+ },
180
+ variable: "x",
181
+ element: "(M/l)*x^2",
182
+ elementNote: "strips parallel to the axis. Each strip’s own width does not matter, so this is the rod integral again and b never appears",
183
+ from: "-l/2",
184
+ to: "l/2",
185
+ closedForm: "M*l^2/12",
186
+ closedFormTex: "\\tfrac{1}{12}Ml^2",
187
+ geometry: {
188
+ body: "plate",
189
+ element: "strip",
190
+ sweep: "along-length",
191
+ extent: "l"
192
+ }
193
+ }
194
+ ];
195
+ const SHAPES = Object.fromEntries(SHAPE_LIST.map((s) => [s.id, s]));
196
+ const shapeIds = () => SHAPE_LIST.map((s) => s.id);
197
+ /**
198
+ * `I = ∫ r² dm` for a declared shape, with the integral shown.
199
+ *
200
+ * `values` supplies the symbols: `{ M: 2, R: 0.5 }`. The integral is done symbolically once and
201
+ * then evaluated at the limits, so what a lesson displays and what a lab computes are the same
202
+ * object rather than two implementations that agree today.
203
+ */
204
+ function momentOfInertia(shape, values, sf = 3) {
205
+ for (const symbol of Object.keys(shape.symbols)) if (!(symbol in values)) throw new Error(`${shape.name} (${shape.axis}) needs ${symbol}: ${shape.symbols[symbol]}.`);
206
+ const element = parse(shape.element);
207
+ const antiderivative = integrate(element, shape.variable);
208
+ if (!antiderivative) throw new Error(`Could not integrate ${shape.element} with respect to ${shape.variable}. The integrand must be an expanded polynomial; see the note in inertia.ts.`);
209
+ const lower = evaluate(parse(shape.from), values);
210
+ const upper = evaluate(parse(shape.to), values);
211
+ const at = (point) => evaluate(antiderivative, {
212
+ ...values,
213
+ [shape.variable]: point
214
+ });
215
+ const value = at(upper) - at(lower);
216
+ const checkValue = evaluate(parse(shape.closedForm), values);
217
+ const tidy = simplify(antiderivative);
218
+ return {
219
+ shape,
220
+ value,
221
+ checkValue,
222
+ antiderivative,
223
+ worked: calc().step("I = \\int r^2 \\, dm", `${shape.name}, ${shape.axis}`).step(`dI = ${toLatex(element)} \\, d${shape.variable}`, shape.elementNote).step(`I = \\int_{${toLatex(parse(shape.from))}}^{${toLatex(parse(shape.to))}} ${toLatex(element)} \\, d${shape.variable}`, "the same integral the textbook writes, over the whole body").step(`= \\left[ ${toLatex(tidy)} \\right]_{${toLatex(parse(shape.from))}}^{${toLatex(parse(shape.to))}}`).step(`I = ${shape.closedFormTex}`, "which is the standard result, and now it is a conclusion").step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, `with ${Object.entries(values).map(([k, v]) => `${k} = ${v}`).join(", ")}`).done(value)
224
+ };
225
+ }
226
+ /**
227
+ * The shape's integral as a watchable sweep: the element travelling through the body with the
228
+ * running total behind it.
229
+ *
230
+ * This is where the `r²` stops being a symbol. For a uniform disc, half the moment of inertia comes
231
+ * from beyond 84% of the radius, and a learner who has watched the meter barely move across the
232
+ * inner half will not need to be told why a flywheel is heavy at the rim.
233
+ */
234
+ const sweepOf = (shape, values, samples = 64) => sweep({
235
+ element: shape.element,
236
+ variable: shape.variable,
237
+ from: shape.from,
238
+ to: shape.to
239
+ }, values, samples);
240
+ /** Where a given fraction of the moment of inertia has accumulated by. */
241
+ const inertiaComesFrom = (shape, values, fraction = .5) => positionAtFraction(sweepOf(shape, values), fraction);
242
+ /**
243
+ * `I = Σ m r²` for point masses, where `r` is the distance from the AXIS, not from the origin.
244
+ *
245
+ * That distinction is the whole difficulty. For a mass at (x, y, z) rotating about the z axis the
246
+ * distance that matters is `√(x² + y²)`: the z coordinate is along the axis and contributes
247
+ * nothing, however large it is. Students routinely use the full position vector and get an answer
248
+ * that is too big, and the error is invisible in the common textbook case where every mass happens
249
+ * to lie in a plane through the origin.
250
+ *
251
+ * This is also the definition the continuous shapes are integrals OF, so it belongs beside them: a
252
+ * disc is this sum with the masses made infinitesimal and the sum made an integral.
253
+ */
254
+ function pointMasses(masses, sf = 3) {
255
+ const value = masses.reduce((sum, m) => sum + m.mass * m.distance * m.distance, 0);
256
+ const totalMass = masses.reduce((sum, m) => sum + m.mass, 0);
257
+ const w = calc().step("I = \\sum m r^2", "r is the distance from the AXIS, not from the origin: a coordinate along the axis contributes nothing");
258
+ for (const m of masses) w.step(`${m.label ? `${m.label}: ` : ""}${texSigFigs(m.mass, sf)} \\times ${texSigFigs(m.distance, sf)}^2 = ${texSigFigs(m.mass * m.distance * m.distance, sf)}`);
259
+ w.step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, "total");
260
+ return {
261
+ value,
262
+ totalMass,
263
+ worked: w.done(value)
264
+ };
265
+ }
266
+ /** Distance from an axis through the origin along `axis`, for a mass at (x, y, z). */
267
+ function distanceFromAxis(position, axis = "z") {
268
+ if (axis === "z") return Math.hypot(position.x, position.y);
269
+ if (axis === "y") return Math.hypot(position.x, position.z);
270
+ return Math.hypot(position.y, position.z);
271
+ }
272
+ /**
273
+ * Move an axis sideways: `I = I_cm + Mh²`.
274
+ *
275
+ * An operation, not a formula to recall, so a lab can let a learner drag the pivot and watch the
276
+ * number rise. It only works from the CENTRE OF MASS axis, and the error message says so, because
277
+ * applying it from an arbitrary axis is the standard mistake.
278
+ */
279
+ function parallelAxis(aboutCentreOfMass, mass, distance, sf = 3) {
280
+ const value = aboutCentreOfMass + mass * distance * distance;
281
+ return {
282
+ value,
283
+ worked: calc().step("I = I_{cm} + Mh^2", "and it must start from the centre-of-mass axis, or it is not true").step(`I = ${texSigFigs(aboutCentreOfMass, sf)} + ${texSigFigs(mass, sf)} \\times ${texSigFigs(distance, sf)}^2`).step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, "moving the axis away always increases it").done(value)
284
+ };
285
+ }
286
+ /**
287
+ * For a FLAT body only: `I_z = I_x + I_y`.
288
+ *
289
+ * The flatness is the whole condition and is where the marks go, so it is in the note rather than
290
+ * in a comment. This is how the disc's `¼MR²` about a diameter is obtained from its `½MR²` about
291
+ * the axis, which is exactly the move the textbook makes and never justifies.
292
+ */
293
+ function perpendicularAxis(inPlaneX, inPlaneY, sf = 3) {
294
+ const value = inPlaneX + inPlaneY;
295
+ return {
296
+ value,
297
+ worked: calc().step("I_z = I_x + I_y", "for a LAMINA only: the body must be flat, and the two axes lie in it").step(`I_z = ${texSigFigs(inPlaneX, sf)} + ${texSigFigs(inPlaneY, sf)}`).step(`I_z = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`).done(value)
298
+ };
299
+ }
300
+ /**
301
+ * Add rigid bodies that share an axis.
302
+ *
303
+ * Moment of inertia is a scalar once the axis is fixed, so assemblies just add. That is what makes
304
+ * a three-blade fan tractable: one disc plus three rods, each rod moved out by the parallel axis
305
+ * theorem. A lab that lets a learner build a body out of parts is this function.
306
+ */
307
+ function combine(parts, sf = 3) {
308
+ const value = parts.reduce((sum, p) => sum + p.value, 0);
309
+ const w = calc().step("I = \\sum I_i", "about ONE axis, they simply add, because each part’s mass is at its own distance from that same axis");
310
+ for (const p of parts) w.step(`${texSigFigs(p.value, sf)}\\ \\mathrm{kg\\,m^2}`, p.label);
311
+ w.step(`I = ${texSigFigs(value, sf)}\\ \\mathrm{kg\\,m^2}`, "total");
312
+ return {
313
+ value,
314
+ worked: w.done(value)
315
+ };
316
+ }
317
+ /**
318
+ * `K = √(I/M)`: where a single point mass would have to sit to have the same moment of inertia.
319
+ *
320
+ * Worth saying in those words. It is routinely confused with the distance to the centre of mass,
321
+ * which it is not, and the textbook flags that confusion without explaining it.
322
+ */
323
+ function radiusOfGyration(inertia, mass, sf = 3) {
324
+ const value = Math.sqrt(inertia / mass);
325
+ return {
326
+ value,
327
+ worked: calc().step("I = MK^2 \\;\\Rightarrow\\; K = \\sqrt{I/M}").step(`K = \\sqrt{${texSigFigs(inertia, sf)} / ${texSigFigs(mass, sf)}}`).step(`K = ${texSigFigs(value, sf)}\\ \\mathrm{m}`, "the radius a single point of the same mass would need. It is NOT the distance to the centre of mass").done(value)
328
+ };
329
+ }
330
+
331
+ //#endregion
332
+ export { SHAPES, combine, distanceFromAxis, inertiaComesFrom, momentOfInertia, parallelAxis, perpendicularAxis, pointMasses, radiusOfGyration, shapeIds, sweepOf };
@@ -0,0 +1,65 @@
1
+ import { Worked } from "../../core/worked.mjs";
2
+
3
+ //#region src/physics/rotation/torque.d.ts
4
+ /** The linear quantity and its rotational counterpart, for a lesson that prints the mapping. */
5
+ declare const ROTATIONAL_ANALOGUE: readonly {
6
+ linear: string;
7
+ rotational: string;
8
+ relation: string;
9
+ }[];
10
+ /**
11
+ * The turning effect of one force: `τ = F r sin θ`.
12
+ *
13
+ * `θ` is between the force and the line from the axis to where it acts. Only the PERPENDICULAR
14
+ * component turns anything; a force aimed straight at the hinge has no effect however large it is,
15
+ * which is why you push a door at its edge and at right angles.
16
+ */
17
+ declare function torque(force: number, distance: number, angleDeg?: number, sf?: number): {
18
+ value: number;
19
+ worked: Worked;
20
+ };
21
+ /**
22
+ * The moment of a couple: `M = F d`, with `d` the perpendicular distance BETWEEN the two forces.
23
+ *
24
+ * Not `F × distance from some axis`, because there is no axis in it. The moment of a couple is the
25
+ * same about every point in the plane, which is the property that makes it a couple rather than two
26
+ * separate moments, and it is why the answer never asks you where the pivot is.
27
+ */
28
+ declare function couple(force: number, separation: number, sf?: number): {
29
+ value: number;
30
+ worked: Worked;
31
+ };
32
+ /**
33
+ * The force a second couple needs to balance the first.
34
+ *
35
+ * Two couples balance when their moments are equal and opposite, so a wide couple can be held by a
36
+ * small force and a narrow one needs a large force. That is the whole of the rectangular-plate
37
+ * question these chapters set.
38
+ */
39
+ declare function balancingCouple(known: {
40
+ force: number;
41
+ separation: number;
42
+ }, separation: number, sf?: number): {
43
+ force: number;
44
+ worked: Worked;
45
+ };
46
+ /**
47
+ * `τ = Iα`: Newton's second law, rotated.
48
+ *
49
+ * Give any two and it returns the third. The same torque produces very different accelerations on
50
+ * bodies of the same mass shaped differently, which is the thing moment of inertia is FOR.
51
+ */
52
+ declare function angularAcceleration(torqueValue: number, inertia: number, sf?: number): {
53
+ alpha: number;
54
+ worked: Worked;
55
+ };
56
+ /**
57
+ * The torque needed to change angular momentum at a given rate: `τ = dL/dt`.
58
+ *
59
+ * The more fundamental statement, and the one that survives when the moment of inertia itself is
60
+ * changing, which `τ = Iα` does not. Supplied as a rate rather than as a derivative because that is
61
+ * how the question arrives: "the angular momentum changes by this much in this time".
62
+ */
63
+ declare const torqueFromRate: (deltaL: number, deltaT: number) => number;
64
+ //#endregion
65
+ export { ROTATIONAL_ANALOGUE, angularAcceleration, balancingCouple, couple, torque, torqueFromRate };