@archivist-gg/dnd5e 0.3.17 → 0.3.24

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 (439) hide show
  1. package/LICENSE +48 -21
  2. package/README.md +26 -48
  3. package/dist/armor/armor.codec.d.ts +0 -7
  4. package/dist/armor/armor.codec.js +1 -9
  5. package/dist/armor/armor.parser.js +1 -8
  6. package/dist/armor/armor.schema.js +1 -7
  7. package/dist/armor/armor.types.d.ts +0 -3
  8. package/dist/background/background.codec.d.ts +0 -6
  9. package/dist/background/background.codec.js +1 -12
  10. package/dist/background/background.parser.js +1 -11
  11. package/dist/background/background.schema.js +1 -12
  12. package/dist/background/background.types.d.ts +0 -5
  13. package/dist/chunk-2EOGK6R6.js +1 -0
  14. package/dist/chunk-2HRRH3WL.js +1 -0
  15. package/dist/chunk-2LCGKNVM.js +1 -0
  16. package/dist/chunk-2NUDWOFG.js +1 -0
  17. package/dist/chunk-334WLI7V.js +1 -0
  18. package/dist/chunk-3LWOVRLA.js +1 -0
  19. package/dist/chunk-3QQOATV3.js +1 -0
  20. package/dist/chunk-4E2GIWJE.js +1 -0
  21. package/dist/chunk-4GN3GYMP.js +1 -0
  22. package/dist/chunk-4IAMSRHD.js +1 -0
  23. package/dist/chunk-4JEF3CET.js +1 -0
  24. package/dist/chunk-4KVVAENP.js +1 -0
  25. package/dist/chunk-56JK6VCL.js +1 -0
  26. package/dist/chunk-5FEXHY4U.js +1 -0
  27. package/dist/chunk-63YJPWTM.js +1 -0
  28. package/dist/chunk-6ASJ3MVB.js +1 -0
  29. package/dist/chunk-6IC53O3Q.js +1 -0
  30. package/dist/chunk-6LCNV26D.js +1 -0
  31. package/dist/chunk-6W253VHH.js +1 -0
  32. package/dist/chunk-7AKJBRBD.js +1 -0
  33. package/dist/chunk-7EL3GWWJ.js +1 -0
  34. package/dist/chunk-7FPQJDFD.js +1 -0
  35. package/dist/chunk-7J5BNH2D.js +1 -0
  36. package/dist/chunk-7LPKI27J.js +1 -0
  37. package/dist/chunk-7UPYRKMF.js +1 -0
  38. package/dist/chunk-A7H6LX47.js +1 -0
  39. package/dist/chunk-AINRPPLH.js +1 -0
  40. package/dist/chunk-BC52J4LA.js +1 -0
  41. package/dist/chunk-BCXGB4HP.js +1 -0
  42. package/dist/chunk-BGX36NPE.js +1 -0
  43. package/dist/chunk-BPKG6RZ7.js +1 -0
  44. package/dist/chunk-BREHZNTL.js +1 -0
  45. package/dist/chunk-BZ6BGGZS.js +1 -0
  46. package/dist/chunk-CAPYNIGK.js +1 -0
  47. package/dist/chunk-CCFIINBA.js +1 -0
  48. package/dist/chunk-CMIEZQL4.js +1 -0
  49. package/dist/chunk-DVUXUIPV.js +1 -0
  50. package/dist/chunk-DY6FVAGA.js +1 -0
  51. package/dist/chunk-DZITM5AG.js +1 -0
  52. package/dist/chunk-DZKSXSJF.js +1 -0
  53. package/dist/chunk-EAARMPCW.js +1 -0
  54. package/dist/chunk-EVT7MGAC.js +1 -0
  55. package/dist/chunk-FOLHTMSC.js +1 -0
  56. package/dist/chunk-GCYUCIDN.js +1 -0
  57. package/dist/chunk-GIOV6JW7.js +1 -0
  58. package/dist/chunk-HCK6IUB3.js +1 -0
  59. package/dist/chunk-HR5MKCP2.js +1 -0
  60. package/dist/chunk-I26FHSI6.js +1 -0
  61. package/dist/chunk-I4O2FIDT.js +1 -0
  62. package/dist/chunk-IGVRLGLM.js +1 -0
  63. package/dist/chunk-IHPLT2ZT.js +1 -0
  64. package/dist/chunk-IOCJIWCV.js +1 -0
  65. package/dist/chunk-JXDX2DKF.js +1 -0
  66. package/dist/chunk-KBFSJ5WE.js +1 -0
  67. package/dist/chunk-KM75CC6Q.js +1 -0
  68. package/dist/chunk-KZDDFG4O.js +1 -0
  69. package/dist/chunk-LJNT3PJP.js +1 -0
  70. package/dist/chunk-LR6UMA5V.js +1 -0
  71. package/dist/chunk-M6RPOLKS.js +1 -0
  72. package/dist/chunk-MC6PLWRZ.js +1 -0
  73. package/dist/chunk-MGGKZGLG.js +1 -0
  74. package/dist/chunk-N3RYJ7RE.js +1 -0
  75. package/dist/chunk-NEMX7QGG.js +1 -0
  76. package/dist/chunk-NI364WV7.js +1 -0
  77. package/dist/chunk-O2QZ73GA.js +1 -0
  78. package/dist/chunk-O776WL7O.js +1 -0
  79. package/dist/chunk-OTFNINUY.js +1 -0
  80. package/dist/chunk-PQAVMK3T.js +1 -0
  81. package/dist/chunk-PZ3ZZ5H5.js +1 -0
  82. package/dist/chunk-PZ4L2EEG.js +1 -0
  83. package/dist/chunk-PZUPZBTN.js +1 -0
  84. package/dist/chunk-QBA757AU.js +1 -0
  85. package/dist/chunk-QFIGPOFW.js +1 -0
  86. package/dist/chunk-QMEKQTUT.js +1 -0
  87. package/dist/chunk-QVWT67WA.js +1 -0
  88. package/dist/chunk-RDXQAZBA.js +1 -0
  89. package/dist/chunk-RE5Z5RNK.js +1 -0
  90. package/dist/chunk-RL4VY2AL.js +1 -0
  91. package/dist/chunk-RQGTBHJW.js +1 -0
  92. package/dist/chunk-RQZCGXUZ.js +1 -0
  93. package/dist/chunk-S5UCI27C.js +1 -0
  94. package/dist/chunk-SEOASDO4.js +1 -0
  95. package/dist/chunk-SU4MEZ5P.js +1 -0
  96. package/dist/chunk-T55DELVL.js +1 -0
  97. package/dist/chunk-TKIEPC6F.js +1 -0
  98. package/dist/chunk-TLXFGGWH.js +1 -0
  99. package/dist/chunk-UBUKCRZ3.js +1 -0
  100. package/dist/chunk-V6NQ547U.js +1 -0
  101. package/dist/chunk-VA3ZWV7C.js +1 -0
  102. package/dist/chunk-VIP3FH2O.js +1 -0
  103. package/dist/chunk-VTQ4RWEG.js +1 -0
  104. package/dist/chunk-WUHTSLG4.js +1 -0
  105. package/dist/chunk-X22SISGM.js +1 -0
  106. package/dist/chunk-XKJXT2PN.js +1 -0
  107. package/dist/chunk-XQMKH4R4.js +1 -0
  108. package/dist/chunk-YGH7S5ZF.js +1 -0
  109. package/dist/chunk-ZE46ADXS.js +1 -0
  110. package/dist/chunk-ZI3FEUX3.js +1 -0
  111. package/dist/class/class.codec.d.ts +0 -7
  112. package/dist/class/class.codec.js +1 -18
  113. package/dist/class/class.parser.js +1 -17
  114. package/dist/class/class.schema.d.ts +2 -1
  115. package/dist/class/class.schema.js +1 -15
  116. package/dist/class/class.slug.d.ts +0 -11
  117. package/dist/class/class.slug.js +1 -8
  118. package/dist/class/class.standard-array.d.ts +0 -7
  119. package/dist/class/class.standard-array.js +1 -20
  120. package/dist/class/class.types.d.ts +0 -20
  121. package/dist/condition/condition.codec.d.ts +0 -6
  122. package/dist/condition/condition.parser.d.ts +0 -10
  123. package/dist/condition/condition.parser.js +1 -7
  124. package/dist/condition/condition.schema.d.ts +0 -16
  125. package/dist/condition/condition.types.d.ts +0 -3
  126. package/dist/data-srd/index.generated.js +1 -146
  127. package/dist/dnd/amount-text.d.ts +4 -27
  128. package/dist/dnd/amount-text.js +1 -13
  129. package/dist/dnd/constants.d.ts +0 -18
  130. package/dist/dnd/constants.js +1 -42
  131. package/dist/dnd/formula-tags.d.ts +0 -2
  132. package/dist/dnd/formula-tags.js +1 -119
  133. package/dist/dnd/math.d.ts +0 -26
  134. package/dist/dnd/math.js +1 -45
  135. package/dist/dnd/prose-tags.d.ts +1 -15
  136. package/dist/dnd/prose-tags.js +1 -18
  137. package/dist/dnd/resource-die.d.ts +0 -4
  138. package/dist/dnd/resource-die.js +1 -17
  139. package/dist/dnd/resource-formula.d.ts +0 -43
  140. package/dist/dnd/resource-formula.js +1 -14
  141. package/dist/dnd/resource-words.d.ts +0 -2
  142. package/dist/dnd/resource-words.js +1 -30
  143. package/dist/dnd/srd-tag-converter.d.ts +0 -21
  144. package/dist/dnd/srd-tag-converter.js +1 -12
  145. package/dist/dnd/tag-grammar.js +1 -12
  146. package/dist/dnd/warn-once.js +1 -8
  147. package/dist/encounter/encounter.ai-schema.js +1 -8
  148. package/dist/entities/base-item-resolver.d.ts +0 -26
  149. package/dist/entities/base-item-resolver.js +1 -11
  150. package/dist/entities/registry-revision.d.ts +10 -0
  151. package/dist/entities/registry-revision.js +1 -0
  152. package/dist/entities/slug.d.ts +1 -31
  153. package/dist/entities/slug.js +1 -12
  154. package/dist/entities/wikilink-display.d.ts +0 -2
  155. package/dist/entities/wikilink-display.js +1 -10
  156. package/dist/feat/feat.category-codes.d.ts +1 -26
  157. package/dist/feat/feat.category-codes.js +1 -14
  158. package/dist/feat/feat.codec.d.ts +0 -6
  159. package/dist/feat/feat.codec.js +1 -12
  160. package/dist/feat/feat.parser.js +1 -11
  161. package/dist/feat/feat.schema.d.ts +31 -1
  162. package/dist/feat/feat.schema.js +1 -10
  163. package/dist/feat/feat.types.d.ts +0 -6
  164. package/dist/index.js +45 -138113
  165. package/dist/inline-tag-parser.js +1 -6
  166. package/dist/item/item.actions-map.d.ts +4 -63
  167. package/dist/item/item.actions-map.js +1 -10
  168. package/dist/item/item.ai-schema.js +1 -6
  169. package/dist/item/item.attunement.d.ts +0 -14
  170. package/dist/item/item.attunement.js +1 -6
  171. package/dist/item/item.bonuses.js +1 -10
  172. package/dist/item/item.codec.js +1 -9
  173. package/dist/item/item.conditions.d.ts +0 -7
  174. package/dist/item/item.conditions.js +1 -11
  175. package/dist/item/item.conditions.types.d.ts +0 -2
  176. package/dist/item/item.cost.js +1 -29
  177. package/dist/item/item.enrichment.js +1 -9
  178. package/dist/item/item.icon.d.ts +0 -8
  179. package/dist/item/item.icon.js +1 -211
  180. package/dist/item/item.parser.js +1 -8
  181. package/dist/item/item.schema.d.ts +2 -0
  182. package/dist/item/item.schema.js +1 -11
  183. package/dist/item/item.types.d.ts +2 -28
  184. package/dist/monster/monster.ai-schema.js +1 -6
  185. package/dist/monster/monster.codec.d.ts +0 -10
  186. package/dist/monster/monster.enrichment.js +1 -19
  187. package/dist/monster/monster.format.d.ts +0 -69
  188. package/dist/monster/monster.format.js +1 -78
  189. package/dist/monster/monster.parser.d.ts +0 -4
  190. package/dist/monster/monster.parser.js +1 -15
  191. package/dist/monster/monster.resolve.d.ts +0 -4
  192. package/dist/monster/monster.schema.d.ts +0 -9
  193. package/dist/monster/monster.schema.js +1 -34
  194. package/dist/monster/monster.types.d.ts +0 -3
  195. package/dist/monster/monster.types.js +1 -1
  196. package/dist/optional-feature/optional-feature.codec.d.ts +0 -11
  197. package/dist/optional-feature/optional-feature.codec.js +1 -13
  198. package/dist/optional-feature/optional-feature.parser.js +1 -12
  199. package/dist/optional-feature/optional-feature.schema.d.ts +30 -1
  200. package/dist/optional-feature/optional-feature.schema.js +1 -15
  201. package/dist/pack.d.ts +0 -9
  202. package/dist/pc/conditions.constants.js +1 -6
  203. package/dist/pc/decision-recognizer.js +1 -8
  204. package/dist/pc/pc.additional-spells.d.ts +4 -14
  205. package/dist/pc/pc.additional-spells.js +1 -23
  206. package/dist/pc/pc.amount-bindings.d.ts +4 -20
  207. package/dist/pc/pc.amount-bindings.js +1 -23
  208. package/dist/pc/pc.asi-flatten.d.ts +0 -59
  209. package/dist/pc/pc.asi-flatten.js +1 -16
  210. package/dist/pc/pc.conditions.d.ts +1 -0
  211. package/dist/pc/pc.conditions.js +1 -6
  212. package/dist/pc/pc.containment.d.ts +0 -5
  213. package/dist/pc/pc.containment.js +1 -24
  214. package/dist/pc/pc.decision-engine.d.ts +4 -141
  215. package/dist/pc/pc.decision-engine.js +1 -52
  216. package/dist/pc/pc.defense-normalize.d.ts +0 -10
  217. package/dist/pc/pc.defense-normalize.js +1 -6
  218. package/dist/pc/pc.entry-overrides.d.ts +0 -58
  219. package/dist/pc/pc.entry-overrides.js +1 -40
  220. package/dist/pc/pc.equipment.d.ts +2 -22
  221. package/dist/pc/pc.equipment.js +1 -33
  222. package/dist/pc/pc.feature-effects.d.ts +23 -275
  223. package/dist/pc/pc.feature-effects.js +1 -26
  224. package/dist/pc/pc.formula-context.js +1 -11
  225. package/dist/pc/pc.infusions.d.ts +0 -65
  226. package/dist/pc/pc.infusions.js +1 -64
  227. package/dist/pc/pc.item-effects.d.ts +18 -0
  228. package/dist/pc/pc.member-choices.d.ts +18 -49
  229. package/dist/pc/pc.member-choices.js +1 -32
  230. package/dist/pc/pc.parser.js +1 -58
  231. package/dist/pc/pc.pools.d.ts +7 -10
  232. package/dist/pc/pc.pools.js +1 -26
  233. package/dist/pc/pc.proficiencies.d.ts +7 -33
  234. package/dist/pc/pc.proficiencies.js +1 -107
  235. package/dist/pc/pc.proficiency-grants.d.ts +0 -26
  236. package/dist/pc/pc.proficiency-normalize.d.ts +4 -25
  237. package/dist/pc/pc.proficiency-normalize.js +1 -12
  238. package/dist/pc/pc.proficiency-query.d.ts +0 -13
  239. package/dist/pc/pc.proficiency-query.js +1 -27
  240. package/dist/pc/pc.recalc.d.ts +7 -131
  241. package/dist/pc/pc.recalc.js +1 -946
  242. package/dist/pc/pc.resolver.d.ts +0 -104
  243. package/dist/pc/pc.resolver.js +1 -59
  244. package/dist/pc/pc.resource-seed.d.ts +0 -8
  245. package/dist/pc/pc.resource-seed.js +1 -42
  246. package/dist/pc/pc.resources.d.ts +1 -59
  247. package/dist/pc/pc.resources.js +1 -23
  248. package/dist/pc/pc.rest.d.ts +1 -20
  249. package/dist/pc/pc.rest.js +1 -230
  250. package/dist/pc/pc.schema.d.ts +19 -2
  251. package/dist/pc/pc.schema.js +1 -9
  252. package/dist/pc/pc.slotting.d.ts +0 -29
  253. package/dist/pc/pc.slotting.js +1 -28
  254. package/dist/pc/pc.speeds.d.ts +19 -0
  255. package/dist/pc/pc.spell-scope.d.ts +6 -0
  256. package/dist/pc/pc.spellcasting.d.ts +0 -70
  257. package/dist/pc/pc.spellcasting.js +1 -28
  258. package/dist/pc/pc.table-column.d.ts +0 -22
  259. package/dist/pc/pc.table-column.js +1 -18
  260. package/dist/pc/pc.tool-picks.d.ts +0 -27
  261. package/dist/pc/pc.tool-picks.js +1 -18
  262. package/dist/pc/pc.types.d.ts +85 -344
  263. package/dist/pc/pc.weapon-grant.d.ts +0 -6
  264. package/dist/pc/pool-layout.d.ts +0 -39
  265. package/dist/pc/pool-layout.js +1 -18
  266. package/dist/pc/resource-equivalents.d.ts +2 -40
  267. package/dist/pc/roll-scope.js +1 -8
  268. package/dist/pc/roll-tag-labels.d.ts +0 -32
  269. package/dist/pc/roll-tag-labels.js +1 -17
  270. package/dist/pc/spell-source.d.ts +0 -11
  271. package/dist/pc/spell-source.js +1 -8
  272. package/dist/race/race.codec.d.ts +0 -6
  273. package/dist/race/race.codec.js +1 -15
  274. package/dist/race/race.parser.js +1 -14
  275. package/dist/race/race.schema.d.ts +0 -8
  276. package/dist/race/race.schema.js +1 -14
  277. package/dist/race/race.structural.d.ts +0 -6
  278. package/dist/race/race.structural.js +1 -6
  279. package/dist/race/race.types.d.ts +0 -8
  280. package/dist/schemas/attack-schema.d.ts +5 -0
  281. package/dist/schemas/caster-type-schema.d.ts +1 -6
  282. package/dist/schemas/caster-type-schema.js +1 -6
  283. package/dist/schemas/choice-schema.js +1 -7
  284. package/dist/schemas/duration-schema.d.ts +0 -2
  285. package/dist/schemas/duration-schema.js +1 -6
  286. package/dist/schemas/entity-extras-schema.d.ts +0 -30
  287. package/dist/schemas/entity-extras-schema.js +1 -10
  288. package/dist/schemas/equipment-grant-schema.d.ts +0 -2
  289. package/dist/schemas/equipment-grant-schema.js +1 -12
  290. package/dist/schemas/feature-alias.d.ts +0 -27
  291. package/dist/schemas/feature-effect-schema.d.ts +30 -1
  292. package/dist/schemas/feature-effect-schema.js +1 -6
  293. package/dist/schemas/feature-schema.d.ts +0 -6
  294. package/dist/schemas/feature-schema.js +1 -12
  295. package/dist/schemas/resource-schema.d.ts +1 -34
  296. package/dist/schemas/resource-schema.js +1 -12
  297. package/dist/schemas/selection-pool-schema.js +1 -10
  298. package/dist/spell/casting-time.d.ts +0 -15
  299. package/dist/spell/casting-time.js +1 -6
  300. package/dist/spell/spell.access.d.ts +0 -6
  301. package/dist/spell/spell.access.js +1 -45
  302. package/dist/spell/spell.ai-schema.js +1 -6
  303. package/dist/spell/spell.codec.js +1 -9
  304. package/dist/spell/spell.enrichment.js +1 -9
  305. package/dist/spell/spell.filter.d.ts +0 -5
  306. package/dist/spell/spell.filter.js +1 -75
  307. package/dist/spell/spell.parser.d.ts +0 -31
  308. package/dist/spell/spell.parser.js +1 -16
  309. package/dist/spell/spell.scaling.d.ts +0 -46
  310. package/dist/spell/spell.scaling.js +1 -79
  311. package/dist/spell/spell.schema.js +1 -7
  312. package/dist/spell/spell.types.d.ts +0 -7
  313. package/dist/srd/retired-items.d.ts +0 -4
  314. package/dist/srd/retired-items.js +1 -11
  315. package/dist/srd-store.d.ts +0 -33
  316. package/dist/subclass/subclass.codec.d.ts +0 -8
  317. package/dist/subclass/subclass.codec.js +1 -17
  318. package/dist/subclass/subclass.parser.js +1 -16
  319. package/dist/subclass/subclass.schema.d.ts +2 -1
  320. package/dist/subclass/subclass.schema.js +1 -14
  321. package/dist/subclass/subclass.types.d.ts +0 -3
  322. package/dist/types/attack.d.ts +2 -0
  323. package/dist/types/casting-option.d.ts +0 -4
  324. package/dist/types/choice.d.ts +1 -72
  325. package/dist/types/choice.js +1 -24
  326. package/dist/types/edition.d.ts +0 -3
  327. package/dist/types/equipment-grant.d.ts +1 -27
  328. package/dist/types/equipment-grant.js +1 -12
  329. package/dist/types/feature-effect.d.ts +14 -14
  330. package/dist/types/feature.d.ts +0 -22
  331. package/dist/types/optional-feature.types.d.ts +1 -31
  332. package/dist/types/resource.d.ts +1 -21
  333. package/dist/types/selection-pool.d.ts +0 -24
  334. package/dist/weapon/weapon-mastery.d.ts +0 -1
  335. package/dist/weapon/weapon.classify.d.ts +0 -11
  336. package/dist/weapon/weapon.classify.js +1 -7
  337. package/dist/weapon/weapon.codec.d.ts +0 -9
  338. package/dist/weapon/weapon.codec.js +1 -9
  339. package/dist/weapon/weapon.parser.js +1 -8
  340. package/dist/weapon/weapon.schema.js +1 -7
  341. package/dist/weapon/weapon.types.d.ts +0 -3
  342. package/package.json +3 -3
  343. package/src/data-srd/ATTRIBUTION.md +1 -1
  344. package/dist/chunk-2FRUSVZS.js +0 -489
  345. package/dist/chunk-2JSQE3DD.js +0 -206
  346. package/dist/chunk-2LULMQTF.js +0 -14
  347. package/dist/chunk-2UDSN6VW.js +0 -18
  348. package/dist/chunk-3LWMFYKS.js +0 -57
  349. package/dist/chunk-3MGQFFNE.js +0 -110
  350. package/dist/chunk-3TM34RSJ.js +0 -23
  351. package/dist/chunk-3VZZDKRA.js +0 -1014
  352. package/dist/chunk-4U55VNC7.js +0 -22
  353. package/dist/chunk-5GKJAUMX.js +0 -59
  354. package/dist/chunk-5MXFW4O3.js +0 -71
  355. package/dist/chunk-656QCX4U.js +0 -22
  356. package/dist/chunk-6EI737IO.js +0 -19
  357. package/dist/chunk-6GNXYAYP.js +0 -25
  358. package/dist/chunk-6PXTNCBP.js +0 -133
  359. package/dist/chunk-6X2NV665.js +0 -33
  360. package/dist/chunk-7ATNGKBS.js +0 -178
  361. package/dist/chunk-7Q2VPKCD.js +0 -181
  362. package/dist/chunk-7QN7XSAK.js +0 -19
  363. package/dist/chunk-A54HHCWW.js +0 -67
  364. package/dist/chunk-AZRGFUSR.js +0 -18
  365. package/dist/chunk-B3DP42OM.js +0 -55
  366. package/dist/chunk-CJYCVNW2.js +0 -7
  367. package/dist/chunk-CM5CWO4K.js +0 -735
  368. package/dist/chunk-DEEHHLAP.js +0 -271
  369. package/dist/chunk-DOXSFYLH.js +0 -158
  370. package/dist/chunk-DPUJDOKV.js +0 -365
  371. package/dist/chunk-EJP263OP.js +0 -186
  372. package/dist/chunk-EVMUJYUD.js +0 -195
  373. package/dist/chunk-EYX4JMAU.js +0 -101
  374. package/dist/chunk-FANQVQ3D.js +0 -89
  375. package/dist/chunk-FC4IGH5Y.js +0 -18
  376. package/dist/chunk-G6MHJDVT.js +0 -41
  377. package/dist/chunk-G6PBI2BU.js +0 -18
  378. package/dist/chunk-H5PTKYXL.js +0 -101
  379. package/dist/chunk-HHBD4SQ6.js +0 -24
  380. package/dist/chunk-HS6FIOLP.js +0 -52
  381. package/dist/chunk-HTYMW5CH.js +0 -228
  382. package/dist/chunk-IHE6KVC3.js +0 -13
  383. package/dist/chunk-IN4M4X7P.js +0 -34
  384. package/dist/chunk-IUAAXXNO.js +0 -58
  385. package/dist/chunk-JCMUVZIK.js +0 -133
  386. package/dist/chunk-JSM6JFZR.js +0 -709
  387. package/dist/chunk-K5NJBTE2.js +0 -18
  388. package/dist/chunk-KR6JF3BF.js +0 -14
  389. package/dist/chunk-KSTV7J2U.js +0 -112
  390. package/dist/chunk-KU3YLF6D.js +0 -106
  391. package/dist/chunk-LBEXLN6I.js +0 -91
  392. package/dist/chunk-LF5AGJA4.js +0 -81
  393. package/dist/chunk-LHZXYFBU.js +0 -94
  394. package/dist/chunk-LSLSG67V.js +0 -31
  395. package/dist/chunk-LVQLWRCU.js +0 -15
  396. package/dist/chunk-MBX25B6D.js +0 -18
  397. package/dist/chunk-MYY2C5MB.js +0 -233
  398. package/dist/chunk-OFCSP6MT.js +0 -23
  399. package/dist/chunk-ONTGZR5T.js +0 -1806
  400. package/dist/chunk-OOSRUJBI.js +0 -19
  401. package/dist/chunk-PDJSUH24.js +0 -110
  402. package/dist/chunk-PKX6TGRE.js +0 -93
  403. package/dist/chunk-PQZ4LM4Z.js +0 -19
  404. package/dist/chunk-PTXBIDG7.js +0 -63
  405. package/dist/chunk-PVCEA4HZ.js +0 -6
  406. package/dist/chunk-PXVNAY7T.js +0 -84
  407. package/dist/chunk-QH36K2PU.js +0 -158
  408. package/dist/chunk-QS5L5YTJ.js +0 -24
  409. package/dist/chunk-QYZV2MQA.js +0 -97
  410. package/dist/chunk-QZSWN2KT.js +0 -18
  411. package/dist/chunk-RLGQ5PZZ.js +0 -16
  412. package/dist/chunk-RYLXAYIQ.js +0 -18
  413. package/dist/chunk-S3YUXDSC.js +0 -278
  414. package/dist/chunk-S7REMWW4.js +0 -21
  415. package/dist/chunk-T6QIF5XR.js +0 -348
  416. package/dist/chunk-TOM66P2P.js +0 -38
  417. package/dist/chunk-TULQ4FFX.js +0 -353
  418. package/dist/chunk-UA5KS2PL.js +0 -26
  419. package/dist/chunk-UUBJCNQU.js +0 -187
  420. package/dist/chunk-UZXG6QSY.js +0 -58
  421. package/dist/chunk-VPYBK2MG.js +0 -18
  422. package/dist/chunk-VRV3NNTA.js +0 -161
  423. package/dist/chunk-VTTA2ALZ.js +0 -16
  424. package/dist/chunk-W6GC6OKK.js +0 -16
  425. package/dist/chunk-WELIKLZF.js +0 -256
  426. package/dist/chunk-WSVMLNTO.js +0 -31
  427. package/dist/chunk-WYGD2UGN.js +0 -14
  428. package/dist/chunk-XCFC7LGF.js +0 -122
  429. package/dist/chunk-XJ2F2WO6.js +0 -8
  430. package/dist/chunk-Y5VVP73C.js +0 -23
  431. package/dist/chunk-YBLDE5CG.js +0 -42
  432. package/dist/chunk-YD2VAHA6.js +0 -159
  433. package/dist/chunk-YDGMBMYI.js +0 -25
  434. package/dist/chunk-YHYTW5QA.js +0 -20
  435. package/dist/chunk-YKL6SHRJ.js +0 -23
  436. package/dist/chunk-ZCTUYGNV.js +0 -26
  437. package/dist/chunk-ZDAEGJH4.js +0 -102
  438. package/dist/chunk-ZJXSXVFP.js +0 -58
  439. package/dist/chunk-ZUQW5VBZ.js +0 -89
@@ -1,7 +1,7 @@
1
- import type { Ability } from "../types/choice.js";
1
+ import type { Ability, EntityFilter } from "../types/choice.js";
2
2
  import type { ArmorEntity } from "../armor/armor.types.js";
3
3
  import type { WeaponEntity } from "../weapon/weapon.types.js";
4
- import type { WeaponScope } from "../types/feature-effect.js";
4
+ import type { SpellScope, WeaponScope } from "../types/feature-effect.js";
5
5
  import type { ItemEntity } from "../item/item.types.js";
6
6
  import type { SkillSlug, Feature, Choice } from "@archivist-gg/dnd5e";
7
7
  import type { ClassEntity } from "@archivist-gg/dnd5e/class/class.types";
@@ -15,9 +15,6 @@ import type { OptionalFeatureEntity } from "@archivist-gg/dnd5e/types/optional-f
15
15
  import type { PoolLayout, PoolActive } from "../types/selection-pool.js";
16
16
  import type { ConditionSlug } from "./conditions.constants.js";
17
17
  import type { ResourceIndex } from "./pc.resources.js";
18
- /** A persisted decision value: entity slug / inline value (string), multi-select
19
- * slugs (string[]), or an ability-points allocation. Stale/odd legacy values
20
- * survive parsing (schema is permissive); readers narrow defensively. */
21
18
  export type ChoiceValue = string | string[] | Partial<Record<Ability, number>>;
22
19
  export type LevelChoices = Record<string, ChoiceValue>;
23
20
  export interface ClassEntry {
@@ -39,9 +36,7 @@ export interface EquipmentEntryOverrides {
39
36
  immune?: string[];
40
37
  vulnerable?: string[];
41
38
  condition_immune?: string[];
42
- /** Per-instance spell payload (e.g. the spell a Spell Scroll casts). */
43
39
  spell?: string;
44
- /** Ability governing this instance's spell save DC / attack when cast. */
45
40
  spell_ability?: Ability;
46
41
  }
47
42
  export interface EquipmentEntryState {
@@ -60,7 +55,6 @@ export interface EquipmentEntryState {
60
55
  effect: string;
61
56
  };
62
57
  }
63
- /** ART-a (spec §4.3): the infusion marker on an equipment entry; see `infusionMarkerSchema` in pc.schema.ts. */
64
58
  export interface InfusionMarker {
65
59
  kind: "infused" | "created";
66
60
  by: string;
@@ -79,17 +73,9 @@ export type EquipmentEntry = {
79
73
  slot?: SlotKey | null;
80
74
  overrides?: EquipmentEntryOverrides;
81
75
  state?: EquipmentEntryState;
82
- /** Build-only provenance tag for gear the Builder's Equipment step seeded
83
- * on the character's behalf (e.g. `"builder:starting"`, `"builder:gold-buy"`).
84
- * Lets the step reconcile its own grants on re-pick / mode-switch without
85
- * touching hand-managed entries. Stripped by finishBuild — absent on every
86
- * finished file. */
87
76
  granted_by?: string;
88
- /** I2a · this entry's stable identity; minted only when something is moved INTO it. */
89
77
  id?: string;
90
- /** I2a · the `id` of the container entry holding this one; ignored while the entry is equipped (C7). */
91
78
  in?: string;
92
- /** ART-a · the infusion marker (spec §4.3): a top-level key, never under `state` or `overrides` (both strict). */
93
79
  infusion?: InfusionMarker;
94
80
  };
95
81
  export interface ResolvedEquipped {
@@ -116,17 +102,10 @@ export interface KnownSpellObject {
116
102
  source?: "class" | "feat" | "item" | "race" | "domain";
117
103
  prepared?: boolean;
118
104
  always_prepared?: boolean;
119
- /** The spell's own spellcasting ability (e.g. WIS for a Magic Initiate (Cleric)
120
- * pick). Belongs on the persisted shape for symmetry with ResolvedSpell.ability;
121
- * feat spells arrive via origin_choices, but a known-spell entry may carry it. */
122
105
  ability?: Ability;
123
106
  }
124
107
  export type KnownSpellEntry = string | KnownSpellObject;
125
108
  export type PassiveKind = "perception" | "investigation" | "insight";
126
- /** The manual proficiency tri, in ONE place. The runtime twin is `proficiencyTri`
127
- * (pc.schema.ts); `pc.recalc.ts` imports this name for the skills tri, and the plugin's
128
- * `CharacterEditState.setToolProficiency` and `ProficiencyEditModal` import it for the
129
- * tools tri (R4-G4 §9.3, UR1), so no consumer re-spells the union. */
130
109
  export type ProficiencyTri = "none" | "proficient" | "expertise";
131
110
  export interface CharacterOverrides {
132
111
  scores?: Partial<Record<Ability, number>>;
@@ -152,26 +131,9 @@ export interface CharacterOverrides {
152
131
  speed?: number;
153
132
  initiative?: number;
154
133
  spellcasting_ability_by_class?: Partial<Record<string, Ability>>;
155
- /** Character-level spellcasting ability for spells that carry no ability of
156
- * their own (e.g. a Spell Scroll cast by a non-caster): the DC-ability fallback
157
- * after a per-instance override and the character's own class ability. */
158
134
  spellcasting_ability?: Ability;
159
135
  spell_slots?: Record<number, number>;
160
136
  attunement_limit?: number;
161
- /** Manual proficiency edits, mirroring `characterOverridesShape` (pc.schema.ts). `remove`
162
- * SUPPRESSES a rules-granted entry ("a dwarf who doesn't know dwarvish"). Both keys and EVERY
163
- * leaf are optional with no defaults, so an untouched note stays byte-identical: every reader
164
- * uses `?? []` (`?? {}` for the tools tri).
165
- *
166
- * `tools.proficiency` is the per-tool manual tri (R4-G4 §9.3, UR1); `languages` deliberately
167
- * gets none. This line is the ONLY thing keeping the interface honest about it, and what it
168
- * buys is TYPE VISIBILITY, not survival: the `NoOverridesKeyDrift` pair below compares
169
- * TOP-LEVEL keys only, so a sibling added to the schema and not here ROUND-TRIPS at runtime
170
- * (the plugin's `characterToYaml` deep-clones and dumps the RUNTIME object, and `parsePC`
171
- * runs `characterSchema.safeParse`, which keeps a key the schema declares) while staying
172
- * UNTYPED, so no consumer can read or write it without a cast. That is the same direction the
173
- * parity block below states; the STRIPPED case is the other one, a key here that the schema
174
- * lacks. */
175
137
  languages?: {
176
138
  add?: string[];
177
139
  remove?: string[];
@@ -181,13 +143,14 @@ export interface CharacterOverrides {
181
143
  remove?: string[];
182
144
  proficiency?: Record<string, ProficiencyTri>;
183
145
  };
184
- /** Manual defense edits, mirroring `characterOverridesShape` (pc.schema.ts). SUPPRESSION-ONLY:
185
- * the absent `add` channel is a DELIBERATE asymmetry with `languages`/`tools` above, not an
186
- * oversight · do not "complete the pattern". The additive store is `character.defenses.*`,
187
- * which already exists; a second additive channel would recreate the two-writers divergence
188
- * R4-P5 exists to remove. Every level is optional with no defaults, so an untouched note stays
189
- * byte-identical. The store has NO consumer as of this commit · Task 5 writes the first, and
190
- * should read every level as possibly absent (`?? []`) and match with `toDefenseSlug`. */
146
+ weapons?: {
147
+ add?: string[];
148
+ remove?: string[];
149
+ };
150
+ armor?: {
151
+ add?: string[];
152
+ remove?: string[];
153
+ };
191
154
  defenses?: {
192
155
  resistances?: {
193
156
  remove?: string[];
@@ -234,13 +197,8 @@ export interface CharacterState {
234
197
  used: number;
235
198
  max: number;
236
199
  }>;
237
- /** R4-G5 G8: banked prerolled dice, keyed by the SAME resource id as feature_uses.
238
- * SIGN IS STATE: negative = spent, positive = live; positions never move. */
239
200
  feature_rolls: Record<string, number[]>;
240
- /** Phase 3 activatable buffs: ids/slugs of activatable features/boons currently
241
- * toggled on. Their effects fold into recalc only while listed here. */
242
201
  active_buffs?: string[];
243
- /** @deprecated SP5: moved to Character.currency. Tolerated until Task 4 parser migration strips it. */
244
202
  currency?: {
245
203
  cp: number;
246
204
  sp: number;
@@ -248,15 +206,12 @@ export interface CharacterState {
248
206
  gp: number;
249
207
  pp: number;
250
208
  };
251
- /** @deprecated SP5: removed; per-entry attuned flag is canonical. Tolerated until Task 4 parser migration strips it. */
252
209
  attuned_items?: string[];
253
210
  }
254
- /** Per-character sheet state (phases AF and SL): layout and Actions/Passive view choices. Mirrors `sheetStateSchema`. */
255
211
  export interface SheetViewFilter {
256
212
  show?: string[];
257
213
  hide?: string[];
258
214
  }
259
- /** PT (spec §7): one pool tab's view: what Show keeps, the facet values un-ticked (by facet id), the folded groups. */
260
215
  export interface SheetPoolView {
261
216
  show?: "known" | "granted" | "not-known";
262
217
  off?: Record<string, string[]>;
@@ -265,6 +220,7 @@ export interface SheetPoolView {
265
220
  export interface CharacterSheetState {
266
221
  layout?: {
267
222
  saves?: "section";
223
+ body?: "wide";
268
224
  };
269
225
  favorites?: string[];
270
226
  filters?: {
@@ -276,32 +232,17 @@ export interface CharacterSheetState {
276
232
  export interface Character {
277
233
  name: string;
278
234
  edition: Edition;
279
- /** Present and `true` only while the file is a Builder draft (autosaved,
280
- * resumable). Removed by the Builder's Finish action, which flips the file
281
- * to the full character sheet. Absent on every pre-Builder/finished file. */
282
235
  builder?: boolean;
283
236
  alignment?: string;
284
- /** Optional free-text age ("26", "Ageless") — Details step. */
285
237
  age?: string;
286
238
  race: string | null;
287
239
  subrace: string | null;
288
240
  background: string | null;
289
241
  class: ClassEntry[];
290
- /** Race/background decision selections, keyed `race:<choice-id>` /
291
- * `background:<choice-id>` (SP2 Plan 3). */
292
242
  origin_choices?: Record<string, ChoiceValue>;
293
243
  abilities: Record<Ability, number>;
294
244
  ability_method: AbilityMethod;
295
- /** Persisted Roll-method ability pool (six 4d6-drop-lowest totals) while the
296
- * file is a Builder draft. Present only in `rolled` mode during a build so
297
- * the rolled pool survives view close / Obsidian restart (UI state cannot);
298
- * the Abilities step + Base popover read their pool from here. Removed by the
299
- * Builder's Finish action (see finishBuild) — a finished file carries none. */
300
245
  builder_rolls?: number[];
301
- /** Persisted Equipment-step mode while the file is a Builder draft: "starting"
302
- * takes the class/background starting-gear grants, "gold" buys with rolled
303
- * starting gold, "empty" begins with nothing. Present only during a build;
304
- * removed by the Builder's Finish action (see finishBuild). */
305
246
  builder_equipment_mode?: "starting" | "gold" | "empty";
306
247
  skills: {
307
248
  proficient: SkillSlug[];
@@ -321,8 +262,6 @@ export interface Character {
321
262
  gp: number;
322
263
  pp: number;
323
264
  };
324
- /** DM grants: optional-feature slugs resolved onto the character with no class, level or pool behind
325
- * them. Placement is the declaring note's `surface`, never a flag here. */
326
265
  additional_features?: string[];
327
266
  notes?: string;
328
267
  defenses?: {
@@ -334,9 +273,6 @@ export interface Character {
334
273
  sheet?: CharacterSheetState;
335
274
  state: CharacterState;
336
275
  }
337
- /** R4-G7 T8 RIDER-23 (F-FEATSRC) · the slot that granted a feat: a class's `choices[<level>].feat` pick, or a 2024
338
- * background's origin feat. Its two members ARE the `class` and `background` sources below, so a renderer formats `via`
339
- * through the arms it already has ("Fighter 4", "Background: Soldier"). */
340
276
  export type FeatVia = {
341
277
  kind: "class";
342
278
  slug: string;
@@ -344,10 +280,10 @@ export type FeatVia = {
344
280
  } | {
345
281
  kind: "background";
346
282
  slug: string;
347
- }
348
- /** D2b-A (design §2.2 step 6): a feat a POOL MEMBER grants (Lessons of the First Ones' Origin feat). `slug` is the
349
- * member's note slug and `name` its display name; `classSlug` / `level` are the pool's class and anchor level. */
350
- | {
283
+ } | {
284
+ kind: "race";
285
+ slug: string;
286
+ } | {
351
287
  kind: "pool";
352
288
  slug: string;
353
289
  name: string;
@@ -372,49 +308,24 @@ export type FeatureSource = {
372
308
  kind: "feat";
373
309
  slug: string;
374
310
  via?: FeatVia;
375
- }
376
- /** A DM grant listed in `character.additional_features`. No class, no level, no pool behind it. */
377
- | {
311
+ } | {
378
312
  kind: "campaign";
379
313
  slug: string;
314
+ } | {
315
+ kind: "item";
316
+ slug: string;
317
+ index: number;
380
318
  };
381
319
  export interface ResolvedFeature {
382
320
  feature: Feature;
383
321
  source: FeatureSource;
384
- /** #3: chosen select-inline option prose, folded onto the PARENT feature for
385
- * render (a shallow-copy wrapper field — the shared registry entity is never
386
- * mutated). One entry per select-inline choice with a recorded pick. */
387
322
  chosenInline?: {
388
323
  label: string;
389
324
  description?: string;
390
325
  }[];
391
- /** #3: marks a synthesized chosen-option feature the renderer must SKIP (its
392
- * prose shows on the parent via chosenInline). A wrapper-only flag —
393
- * computeFeatureEffects ignores it, so the synthetic's effects still fold. */
394
326
  renderSuppressed?: boolean;
395
- /** The feat's entire substance is a full ability-score improvement (a pure ASI). The DISPLAY layer hides these. */
396
327
  buildOnly?: boolean;
397
- /** R4-G7 §7.1: EVERY LOWER copy the resolve-time fold collapsed into this wrapper, ASCENDING by level, with
398
- * that copy's own card identity (`name`, and `description` = its `description` else its `entries` joined) and
399
- * its `choices` when it carries any. A wrapper-only field, the `chosenInline` precedent: the shared registry
400
- * `Feature` is never touched.
401
- *
402
- * The invariant every walker relies on: the TOP copy's own name, prose and choices stay on `feature` and are
403
- * NEVER repeated here, so visiting `foldedFrom` (each entry at its own `level`) and then `feature` (at
404
- * `source.level`) visits every folded copy EXACTLY ONCE, in ascending level order · the order the un-folded
405
- * list had. That is what keeps "a level-N decision on a repeated feature stays a decision at level N" true,
406
- * and what keeps the builder's per-level strip complete, while the sheet renders ONE row.
407
- *
408
- * Both readers live in `pc.decision-engine.ts`: `visitProficiencyChoices` (through
409
- * `collectChosenProficiencies`) walks the entries that carry `choices` and nothing else, and
410
- * `buildDecisionLedger` runs each entry at its own level through the SAME branch it runs the wrapper through
411
- * (`emitCopy`): its authored choices when it has them, else `recognizeDecision`'s synthesized decision under
412
- * the suppression filter, else the informational card, else nothing. Per-copy `name` and `description` are
413
- * load-bearing, not decoration: they decide what the recognizer sees and what the row prints. MEASURED over
414
- * both corpora, 63 of the 131 repeated-id families have a copy whose description differs from the top copy's
415
- * and 1 has a differing name (an UPPER BOUND: it counts `ability-score-improvement` families, which are
416
- * `buildOnly` and never fold; the non-ASI carriers are `artificer-specialist-feature`, `path-feature`,
417
- * `bard-college-feature`, `expertise` and their siblings). Absent on an unfolded wrapper. */
328
+ spellTargets?: SpellTargets;
418
329
  foldedFrom?: {
419
330
  level: number;
420
331
  name: string;
@@ -429,17 +340,10 @@ export interface ResolvedSpell {
429
340
  source: "class" | "feat" | "item" | "race" | "domain";
430
341
  prepared: boolean;
431
342
  alwaysPrepared: boolean;
432
- /** The spell's OWN spellcasting ability. For a feat spell this carries the
433
- * chosen ability (e.g. WIS for Magic Initiate (Cleric)) while classSlug stays
434
- * null (a feat spell is not owned by a class for DC/ability). Absent/undefined
435
- * for class spells, which derive their ability from classSlug. */
436
343
  ability?: Ability | null;
437
- /** Index of the originating equipment entry when this spell was granted by a
438
- * per-instance item (e.g. a Spell Scroll). Absent for class/feat/race spells. */
439
344
  entryIndex?: number;
440
- /** True ONLY for a row from character.spells.known (removable / toggleable);
441
- * absent on every grant · R4-G3b §5.2.7. */
442
345
  persisted?: boolean;
346
+ atWill?: boolean;
443
347
  }
444
348
  export interface ResolvedClass {
445
349
  entity: ClassEntity | null;
@@ -447,63 +351,28 @@ export interface ResolvedClass {
447
351
  subclass: SubclassEntity | null;
448
352
  choices: Record<number, LevelChoices>;
449
353
  }
450
- /** One pool member as resolved for a character: a stored PICK (`selected`), a candidate (`available`) or a subclass
451
- * grant (`grants`). `slug` is always the NOTE's registry slug. A pick is KEYED (ART-a, spec §4.4, §5.1): a COPY of a
452
- * repeatable note is keyed by its stored `<note slug>#<param>`, so two copies of one note are two entries with one `slug`;
453
- * a plain pick's `key` is its resolved `slug` (the stored string, or the survivor of a stored twin), unless it was stored
454
- * with a '#', which is kept; candidates and grants carry `key === slug` and `param: null`. */
455
354
  export interface ResolvedPoolEntry {
456
355
  slug: string;
457
356
  entity: OptionalFeatureEntity;
458
- /** ART-a (spec §4.6): the pick key the writers compare (see above); the slug for candidates and grants. */
459
357
  key: string;
460
- /** ART-a: a copy's parameter (a full item slug for `learn`, a row key for `create`); null for any other entry, and for a
461
- * repeatable note stored without `#` (a copy whose option is `needs-choice`). */
462
358
  param: string | null;
463
- /** ART-a (spec §4.1, §5.2): derived by `isItemBound`. Its subject is an item: no character tracker, no boon fold. */
464
359
  itemBound: boolean;
465
- /** ART-a (spec §5.8): present on every selected copy of a repeatable note. */
466
360
  option?: import("./pc.infusions.js").CopyOption;
467
- /** The compendium NAME the REGISTERED entity carries (R4-G5 §9.2.1), stamped at resolve time because `entity` is
468
- * `e.data` (an H3-rebound member's is a copy of it), which carries none: MEASURED 2026-09-07 over the WHOLE
469
- * converter output (226 documents under its `OptionalFeatures` folders) and the 7 bundle ones, 0 of 226 and 0 of 7
470
- * declare a `compendium` key INSIDE the fenced entity body, while 226 of 226 and 7 of 7 declare one in the note's
471
- * FRONTMATTER, which core keeps on `RegisteredEntity`.
472
- * The plugin's ONE visibility predicate reads it on BOTH surfaces (§3.2.2). Absent when the registry entry
473
- * carries none, which in practice means a test double. The COLLAPSE does not read it: its identity is the
474
- * slug PREFIX (§9.2.2). */
475
361
  compendium?: string;
476
362
  }
477
- /** A materialized selection pool: count from the table column, prereq-filtered
478
- * candidates, player picks (from the choices ledger), and subclass auto-grants. */
479
363
  export interface ResolvedPool {
480
364
  id: string;
481
365
  label: string;
482
- /** Which resolved class declared this pool (for ledger anchoring + writes). */
483
366
  classIndex: number;
484
- /** Picks allowed at the current level (table column value). */
485
367
  count: number;
486
- /** Lowest class level where count >= 1 — the stable persistence key level. */
487
368
  anchorLevel: number;
488
369
  selected: ResolvedPoolEntry[];
489
370
  available: ResolvedPoolEntry[];
490
371
  grants: ResolvedPoolEntry[];
491
- /** Derived at resolve time from the members' `rendering_hint` (pool-layout.ts),
492
- * unconditionally: an authored `TabDecl.renders.layout` does not suppress the
493
- * derivation, it OUTRANKS this field at the tab (§4.2.5). R4-G4 T5 LANDED that precedence in the
494
- * plugin: `TabsContainer`'s dynamic-pool-tab loop is the ONE reader of this field (measured
495
- * 2026-09-05 with `grep -rn "pool\.layout" packages/obsidian/src`, one line) and reads
496
- * authored-then-derived-then-default before handing the string to the `PoolTab` constructor. */
497
372
  layout?: PoolLayout;
498
- /** The OWNED resource id the members spend: the majority of the members' PAYERS (H3b `payingResourceId`: the named id
499
- * when owned, else its owned declared equivalent, the pool's class first); undefined when no member has an owned payer
500
- * (R4-G4 §4.2.3, Gate 0 B1; H3b spec §4). */
501
373
  resource?: string;
502
- /** ART-a (spec §4.5): the declaration's `count.label`, copied raw; read through `poolCountLabel` (absent reads "Known"). */
503
374
  countLabel?: string;
504
- /** ART-a (spec §4.5): the declaration's `active`, copied raw; read through `poolActiveWords`. */
505
375
  active?: PoolActive;
506
- /** ART-a (spec §4.5): the declaration's `head_resource`. */
507
376
  headResource?: string;
508
377
  }
509
378
  export interface ResolvedCharacter {
@@ -512,51 +381,17 @@ export interface ResolvedCharacter {
512
381
  classes: ResolvedClass[];
513
382
  background: BackgroundEntity | null;
514
383
  feats: FeatEntity[];
515
- /** The bare/full slug of the background's resolved origin feat (R4-G3b §8): stamped by the resolver OUTSIDE the
516
- * feats de-dup guard, so it is set even when the same feat is ALSO a class-slot pick. Read by
517
- * visitProficiencyChoices' origin arm; `resolved.feats` itself carries no provenance. */
518
384
  originFeatSlug?: string;
519
385
  totalLevel: number;
520
386
  features: ResolvedFeature[];
521
387
  spells: ResolvedSpell[];
522
388
  pools: ResolvedPool[];
523
- /** Every `resources[]` entry of every resolved feature, keyed by id, with the DECLARING feature
524
- * stamped as owner, PLUS every pool pick's own `uses` with the POOL stamped as owner
525
- * (R4-G4 §3.2.1 and §12). REQUIRED: the resolver's own literal sets it like `pools` and
526
- * reassigns it after pools resolve. Cast test fixtures omit it. Its readers outside the
527
- * resolver landed with R4-G4 T3, T4, T5 and T7b. Re-measured 2026-09-06 on the SHIPPED plugin
528
- * tree: `grep -rn "resolved\.resources" packages/obsidian/src` returns TEN lines, of
529
- * which SIX are read EXPRESSIONS and four are comment prose. The six expressions sit in six
530
- * functions across five files: the module-private `resourceLevel`
531
- * helper of `components/actions/feature-rows.ts` (T3, reading `?.owner`), `renderSpendControl`
532
- * (`components/actions/spend-control.ts`, reading the entry for its `name` and `die`),
533
- * `consumeCost` (`components/pool-tab.ts`, reading `?.name` for the Cost label), both T4,
534
- * `renderPoolHead` (`components/pool-tab.ts`, T5, reading the entry for the tab head's `name`,
535
- * `die`, `reset` and owner: §4.2.6), and T7b's two: `renderPickTracker`
536
- * (`components/actions/pick-tracker.ts`, reading the entry for a pick's `reset` and `name`) and
537
- * `seedFeatureUses` (`pc.resource-seed.ts`), which is the ONE expression that is not a
538
- * `?.get(...)`: it walks `?.values()` for the entries whose `owner.kind` is `pool`, because a
539
- * pick's `uses` reaches the seed through no other route. §3.2.1 names its consumers: T3's
540
- * `resourceLevel(id, ctx)`
541
- * die helper (§6.2.4), T4's spend control and Cost label (§3.2.2 / §3.2.4), T5's pool-tab
542
- * head and T7b's tracker and seed (§12.2), all LANDED. T7's restore affordance has LANDED too and
543
- * reads NOTHING here: its rest arm
544
- * walks the index `computeRestPlan` re-derives and its card arm routes on `resolveRecovery(rec)`
545
- * over the RAW `recovery[0]`.
546
- * Every one of the six reaches it through `?.`, because the plugin's card / row / rest fixtures
547
- * cast a `ResolvedCharacter` with no index. `computeRestPlan` never reads it at all, it re-derives
548
- * the index. */
549
389
  resources: ResourceIndex;
550
- /** 2024 Weapon Mastery: bare-normalized slugs of the weapons the character has
551
- * chosen mastery of, unioned across every class/level `weapon-mastery` pick
552
- * (e.g. "srd-2024_greatsword" → "greatsword"). Empty when the character has no
553
- * such pick. Populated by the resolver's collectChosenWeaponMasteries pass. */
554
390
  weaponMasteries: string[];
391
+ pactWeapon?: string;
555
392
  state: CharacterState;
556
- /** ART-a (spec §4.6, §5.4): the entry views, counters and flags `buildInfusionContext` derives after the resource
557
- * index. Absent (no cost) for a character with no item-bound pool and no marker; every fold reads it through
558
- * `resolveEntryEntity`. */
559
393
  infusions?: import("./pc.infusions.js").InfusionContext;
394
+ itemFeatures?: ResolvedFeature[];
560
395
  }
561
396
  export interface ProficiencySet {
562
397
  categories: string[];
@@ -566,12 +401,31 @@ export interface ACTerm {
566
401
  source: string;
567
402
  amount: number;
568
403
  kind: "armor" | "shield" | "item" | "unarmored" | "override" | "dex" | "ability" | "feature";
569
- /** Situational qualifier carried verbatim from the granting `ac-bonus` effect's `condition`
570
- * (R4-G3a §3.2.5), e.g. "While wearing heavy armor". Absent = unconditional. Rendered as the
571
- * AC-tooltip row's `title`; NEVER evaluated. */
572
404
  condition?: string;
573
405
  }
574
- /** Structured max-HP math for the Max HP modal. Spec: P5 2026-07-21. */
406
+ export type SpeedMode = "walk" | "fly" | "swim" | "climb" | "burrow";
407
+ export interface SpeedTerm {
408
+ source: string;
409
+ amount: number;
410
+ condition?: string;
411
+ }
412
+ export interface SpeedLine {
413
+ mode: SpeedMode;
414
+ value: number;
415
+ equalsWalk?: true;
416
+ hover?: true;
417
+ terms: SpeedTerm[];
418
+ }
419
+ export interface ItemSpeedTerm {
420
+ mode: SpeedMode;
421
+ kind: "bonus" | "grant" | "walk";
422
+ source: string;
423
+ amount: number;
424
+ }
425
+ export interface DefenseItemSource {
426
+ index: number;
427
+ name: string;
428
+ }
575
429
  export interface HPBreakdown {
576
430
  diceSum: number;
577
431
  diceSource: "rolled" | "average";
@@ -592,50 +446,45 @@ export interface HPBreakdown {
592
446
  override: number | null;
593
447
  final: number;
594
448
  }
595
- /** An additive on-hit damage rider (dice or flat) applied to an attack, from a
596
- * feature (global — all weapon attacks) or a magic item (that weapon only).
597
- * `amount` is a dice/flat string ("2d6", "1d8", "2"); `damage_type` optional
598
- * (a bare manual override string carries its type inline, and the schema's
599
- * `chosen` sentinel is kept, never replaced by the row's type, RIDER-13); `source`
600
- * is a human label for the expand/tooltip. `condition` is the source's own
601
- * qualifier ("for a 1st-level spell slot"), CARRIED verbatim and never evaluated,
602
- * from a feature effect (R4-G7 T8 RIDER-12) and from an item's `damage_riders`
603
- * entry alike; absent when the source authors none. `scope` is a feature effect's
604
- * structured weapon scope (its `applies_to` words, ART-c1 Task 9b): the merge in
605
- * `pc.recalc.ts` keeps the rider only on the rows it reaches (`riderReachesRow`);
606
- * absent = every row. How the sheet prints a rider (always inside the DAMAGE cell,
607
- * controller ruling 8) is the plugin renderer's policy, stated once at
608
- * `weapons-table.ts` `renderWeaponRow`. */
609
449
  export interface DamageRider {
610
450
  amount: string;
611
451
  damage_type?: string;
612
452
  source?: string;
613
453
  condition?: string;
614
454
  scope?: WeaponScope[];
615
- /** D2b-A: the source of the feature the rider comes from, so its amount resolves against the OWNING class's level
616
- * and spellcasting modifier (a multiclass character's Guided Precision reads the Artificer's INT). Set by
617
- * `computeFeatureEffects`; consumed and DROPPED by recalc's rider resolution (an attack row never carries it). */
618
455
  owner?: FeatureSource;
619
456
  }
457
+ export interface ConditionalCrit {
458
+ minRoll: number;
459
+ condition: string;
460
+ source: string;
461
+ }
462
+ export interface SpellTargets {
463
+ refs: string[];
464
+ open: EntityFilter[];
465
+ }
466
+ export interface SpellDamageRider {
467
+ amount: string;
468
+ damage_type?: string;
469
+ source?: string;
470
+ condition?: string;
471
+ once?: boolean;
472
+ spells?: string[];
473
+ owner?: FeatureSource;
474
+ targets?: SpellTargets;
475
+ scope?: SpellScope;
476
+ }
620
477
  export interface AttackRow {
621
478
  id: string;
622
479
  name: string;
623
480
  range?: string;
624
- /** Secondary thrown-mode range ("20/60 ft.") for a throwable melee weapon.
625
- * Display-only; rendered as a stacked muted second line in the Range cell.
626
- * Absent otherwise. */
627
481
  thrownRange?: string;
628
482
  toHit: number;
629
483
  damageDice: string;
630
484
  damageType: string;
631
- /** Accumulated additive on-hit damage riders (feature-global + item-local +
632
- * the migrated manual override), rendered as extra damage chips. Absent when
633
- * none apply (so untouched rows are unchanged). */
634
485
  damageRiders?: DamageRider[];
635
- /** The weapon's CATEGORY as the attack modes read it (`classifyWeaponRange`): `melee` for a weapon with a melee
636
- * mode (a thrown melee weapon stays melee), `ranged` for a pure ranged one. A rider's `melee` / `ranged` scope
637
- * reads it (ART-c1 Task 9b). Absent on the unarmed row. */
638
486
  weaponCategory?: "melee" | "ranged";
487
+ attacksPerAction?: number;
639
488
  properties: string[];
640
489
  proficient: boolean;
641
490
  breakdown: {
@@ -643,45 +492,16 @@ export interface AttackRow {
643
492
  damage: ACTerm[];
644
493
  };
645
494
  informational?: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
646
- /** Hand slot the attack came from. Absent on an equipped weapon that holds no hand slot (H234 H5: both hands full, an
647
- * explicit-slot conflict loser, a non-hand slot) and on the unarmed row. The Actions tab finds the originating
648
- * equipment entry by the index in the row's `id` (`<index>:standard`), never by this field. */
649
495
  slotKey?: "mainhand" | "offhand";
650
- /** Short caption under the weapon name in the Actions tab table.
651
- * e.g. "martial · versatile". Display-only. */
652
496
  subLabel?: string;
653
- /** Action-economy cost for the Cost badge. Defaults to "action" at
654
- * render time when absent. Settable via entry.overrides.action. */
655
497
  actionCost?: "action" | "bonus-action" | "reaction" | "free" | "special";
656
- /** The engine's always-present unarmed row (R4-G6b §5): never an equipment entry, never `equipped`, no `slotKey`.
657
- * The weapons table gates its expand on this flag BEFORE the equipment lookup. Absent on every weapon row. */
658
498
  unarmed?: true;
659
- /** When set, the weapon is being wielded one-handed but has a versatile
660
- * two-handed option. The Actions tab renders both lines stacked in the
661
- * damage cell instead of emitting a second row. */
662
499
  versatile?: {
663
500
  damageDice: string;
664
501
  };
665
- /** Lowest natural-roll threshold that scores a critical hit on this attack,
666
- * from `crit-range` feature effects (e.g. 19 = "crit on 19–20"). Display-only
667
- * metadata mapped on in recalc; absent (undefined) for the normal 20-only
668
- * crit so untouched attack rows are unchanged. The weapons table renders a
669
- * "crit X–20" caption whenever it is set and < 20. */
670
502
  critRange?: number;
671
- /** Order-preserving display-only captions from `reroll-damage` / `attack-rule`
672
- * feature effects (e.g. ["Reroll 2s", "No disadvantage firing in melee"]).
673
- * Mapped on in recalc; absent (undefined) when no such effect is present so
674
- * untouched attack rows are unchanged. The weapons table renders these joined
675
- * with " · " as a muted caption under the weapon name. */
503
+ conditionalCrits?: ConditionalCrit[];
676
504
  attackNotes?: string[];
677
- /** 2024 Weapon Mastery for this attack, present only when the character has
678
- * chosen mastery of this weapon AND is proficient with it AND the weapon
679
- * declares a mastery property. `slug`/`label`/`description`/`gist` come from
680
- * the mastery glossary (`gist` = a one-line effect summary for the Actions-tab
681
- * mastery column, e.g. "on fail: Prone"); `derived` carries the computed
682
- * number for the two numeric masteries (topple → Save DC, graze → On-miss
683
- * damage) and is absent for the rest. Additive + display-only, absent
684
- * (undefined) on untouched rows so nothing else changes. */
685
505
  mastery?: {
686
506
  slug: string;
687
507
  label: string;
@@ -692,13 +512,13 @@ export interface AttackRow {
692
512
  value: number;
693
513
  };
694
514
  };
515
+ grantedBy?: string;
516
+ pactWeapon?: true;
695
517
  }
696
518
  export interface AppliedBonuses {
697
519
  ability_bonuses: Partial<Record<Ability, number>>;
698
520
  ability_statics: Partial<Record<Ability, number>>;
699
521
  save_bonus: number;
700
- /** SL (spec §11.3): `save_bonus` term by term, one per item, each named by the entry's display name (`overrides.name`, else
701
- * the item's). The saves breakdown lists these, never a lumped "Equipment" term. */
702
522
  save_terms: {
703
523
  source: string;
704
524
  amount: number;
@@ -709,13 +529,19 @@ export interface AppliedBonuses {
709
529
  swim: number;
710
530
  climb: number;
711
531
  };
532
+ speed_walk_set: number;
533
+ speed_walk_set_terms: {
534
+ source: string;
535
+ amount: number;
536
+ }[];
537
+ speed_terms: ItemSpeedTerm[];
712
538
  spell_attack: number;
713
539
  spell_save_dc: number;
714
540
  defenses: {
715
- resistances: string[];
716
- immunities: string[];
717
- vulnerabilities: string[];
718
- condition_immunities: string[];
541
+ resistances: DefenseGrant[];
542
+ immunities: DefenseGrant[];
543
+ vulnerabilities: DefenseGrant[];
544
+ condition_immunities: DefenseGrant[];
719
545
  };
720
546
  informational: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
721
547
  senses: Record<import("@archivist-gg/dnd5e/types/feature-effect").SenseType, number>;
@@ -730,13 +556,6 @@ export interface DerivedEquipment {
730
556
  attunementUsed: number;
731
557
  attunementLimit: number;
732
558
  }
733
- /**
734
- * A structured advantage/disadvantage entry surfaced from a `roll-modifier`
735
- * feature effect. Order-preserving pass-through list on DerivedStats (no
736
- * dedupe/merge) — each entry carries the owning feature's name as `label`
737
- * for tooltips. `scope` absent = applies to all rolls of that `roll` type;
738
- * `condition` absent = always-on (not situational).
739
- */
740
559
  export interface RollModifierEntry {
741
560
  mode: "advantage" | "disadvantage" | "reroll" | "add-d4";
742
561
  roll: "ability-check" | "saving-throw" | "attack";
@@ -744,28 +563,9 @@ export interface RollModifierEntry {
744
563
  condition?: string;
745
564
  label: string;
746
565
  }
747
- /**
748
- * The two members' aliases, extracted from the entry's inline unions (R4-G3a §5.2). They are
749
- * declared HERE and nowhere else: `pc/roll-tag-labels.ts`'s `Record<RollModifierMode, string>`
750
- * tables and `pc/roll-scope.ts` import them, so widening the entry above is a COMPILE error in
751
- * every label table that has not been extended (§14 row 8i).
752
- */
753
566
  export type RollModifierMode = RollModifierEntry["mode"];
754
567
  export type RollKind = RollModifierEntry["roll"];
755
- /** The closed `save-outcome` result vocabulary, extracted the same way (R4-G3a §5.3): how much
756
- * of the effect still lands. `pc/roll-tag-labels.ts` types its OUTCOME glyph table
757
- * `Record<SaveOutcome, string>`, so the union is spelled ONCE and a widened member is a compile
758
- * error in the table rather than a silent missing glyph. */
759
568
  export type SaveOutcome = SaveOutcomeEntry["on_success"];
760
- /**
761
- * A `save-outcome` effect as it leaves the fold (R4-G3a §5.3) · Evasion and its shape-mates
762
- * ("on a failed save you take half damage, on a success none").
763
- *
764
- * `ability` ABSENT means every save, which is the save chip's existing "absent scope = every
765
- * chip" idiom: the effect schema's `ability: "any"` maps to `undefined` at the fold rather than
766
- * duplicating the entry six times. `appliesTo` is the effect's `applies_to` prose ("a spell"),
767
- * carried for the tooltip only; `condition` is the situational qualifier, never evaluated.
768
- */
769
569
  export interface SaveOutcomeEntry {
770
570
  ability?: Ability;
771
571
  on_success: "none" | "half" | "full";
@@ -774,47 +574,20 @@ export interface SaveOutcomeEntry {
774
574
  condition?: string;
775
575
  label: string;
776
576
  }
777
- /** Where a defense came from. Ordered weakest to strongest for the precedence rule in recalc. */
778
577
  export type DefenseOrigin = "manual" | "equipment" | "grant";
779
- /**
780
- * One defense a feature effect grants, as it leaves the fold (R4-G3a §3.2.1).
781
- *
782
- * The four defense totals on FeatureEffectTotals are lists of these. `value` is the AUTHORED
783
- * spelling, trimmed and never slugified · `toDefenseSlug` runs later, in pc.recalc.ts, which is
784
- * why the fold's dedupe is a case-insensitive comparison rather than a slug lookup. `sources`
785
- * holds the granting FEATURE NAMES, merged per value at the fold (two features granting the same
786
- * immunity yield ONE grant with TWO sources · dropping the second would lose it before
787
- * composeDefenseEntries ever saw it). `condition` is the first qualifier seen for that value,
788
- * carried verbatim and NEVER evaluated.
789
- */
790
578
  export interface DefenseGrant {
791
579
  value: string;
792
580
  sources: string[];
793
581
  condition?: string;
582
+ items?: DefenseItemSource[];
794
583
  }
795
- /**
796
- * One entry in a derived defense bucket.
797
- *
798
- * `value` is ALWAYS `toDefenseSlug(raw)` · it is what every comparison keys on.
799
- * `label` is the first-spelling-wins display string, which is what preserves an authored "Psychic".
800
- * `origin` is the STRONGEST contributing source, not the first list to supply it.
801
- *
802
- * `sources` is GRANT-ORIGIN attribution only (R4-G3a §3.2.3): the names of the features whose
803
- * effects granted this value, copied from the DefenseGrant. EQUIPMENT-origin attribution (the
804
- * `pc.equipment.ts` half of R4-P5 §10.1 · archivist-obsidian/docs/superpowers/specs/
805
- * 2026-08-05-r4-p5-defenses-design.md, the spec lives in the PLUGIN repo, not this one) stays
806
- * DEFERRED, so an equipment-only entry carries no `sources` at all and the plugin's chip host
807
- * must guard on emptiness rather than on origin alone.
808
- *
809
- * `condition` is the situational qualifier from the granting effect, carried verbatim for the
810
- * chip tooltip and NEVER evaluated. Both fields are optional: a manual entry has neither.
811
- */
812
584
  export interface DefenseEntry {
813
585
  value: string;
814
586
  label: string;
815
587
  origin: DefenseOrigin;
816
588
  condition?: string;
817
589
  sources?: string[];
590
+ items?: DefenseItemSource[];
818
591
  }
819
592
  export interface DerivedStats {
820
593
  totalLevel: number;
@@ -836,16 +609,11 @@ export interface DerivedStats {
836
609
  bonus: number;
837
610
  proficiency: "none" | "proficient" | "expertise";
838
611
  ability: Ability;
839
- /** The winning half-proficiency term (Jack of All Trades, Remarkable Athlete) on a skill whose tri is `none`;
840
- * absent otherwise. Additive: the tri never gains a half value, it is also the `overrides.skills.*.proficiency`
841
- * enum. Set under an `overrides.skills.<s>.bonus` too (the marker states the rule, the bonus is the number).
842
- * `source` is the owning feature's name. */
843
612
  halfProficiency?: {
844
613
  source: string;
845
614
  amount: number;
846
615
  };
847
616
  }>;
848
- /** Numeric terms behind the sheet's skill, save, speed and initiative hovers. */
849
617
  statBreakdowns?: {
850
618
  skills: Partial<Record<SkillSlug, {
851
619
  source: string;
@@ -869,7 +637,6 @@ export interface DerivedStats {
869
637
  investigation: number;
870
638
  insight: number;
871
639
  };
872
- /** Computed senses: max of race vision and feature-effect sense ranges. 0 = none per type. */
873
640
  senses: Record<import("@archivist-gg/dnd5e/types/feature-effect").SenseType, number>;
874
641
  hp: {
875
642
  max: number;
@@ -878,6 +645,7 @@ export interface DerivedStats {
878
645
  };
879
646
  ac: number;
880
647
  speed: number;
648
+ speeds?: SpeedLine[];
881
649
  initiative: number;
882
650
  spellcasting: {
883
651
  ability: Ability;
@@ -885,26 +653,16 @@ export interface DerivedStats {
885
653
  attackBonus: number;
886
654
  preparedCount?: number;
887
655
  } | null;
888
- /** One entry per casting class (multiclass-aware). Empty for non-casters. */
889
656
  spellcastingClasses: SpellcastingClassInfo[];
890
- /** Save DC / attack bonus for spells that carry their OWN spellcasting
891
- * ability rather than a class (feat-granted spells, e.g. Magic Initiate).
892
- * Keyed by that ability; populated for every ability a feat spell uses.
893
- * Computed independently of class casters, so a NON-caster (empty
894
- * spellcastingClasses / null spellcasting) still gets a real DC/attack.
895
- * Empty object when the character has no such spell. */
896
657
  abilitySpellcasting: Partial<Record<Ability, {
897
658
  saveDC: number;
898
659
  attackBonus: number;
899
660
  }>>;
900
- /** Derived standard slot totals by spell level (before user override). */
901
661
  derivedSpellSlots: Record<number, number>;
902
- /** Warlock Pact Magic, or null. */
903
662
  pactMagic: {
904
663
  level: number;
905
664
  total: number;
906
665
  } | null;
907
- /** Per-class known/prepared + cantrip limits (advisory). */
908
666
  spellLimits: SpellLimitInfo[];
909
667
  warnings: string[];
910
668
  defenses: {
@@ -916,32 +674,18 @@ export interface DerivedStats {
916
674
  acBreakdown: ACTerm[];
917
675
  hpBreakdown: HPBreakdown;
918
676
  acInformational: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
919
- /** Situational saving-throw bonuses (e.g. +1 vs spells) for save tooltips. */
920
677
  savesInformational: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
921
- /** Situational spell attack / save-DC bonuses for spellcasting tooltips. */
922
678
  spellcastingInformational: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
923
- /** Situational speed bonuses (e.g. swim while underwater) for speed tooltips. */
924
679
  speedInformational: import("@archivist-gg/dnd5e/item/item.conditions.types").InformationalBonus[];
925
- /**
926
- * Attacks per Attack action = 1 + max `extra-attack` effect count. Always ≥ 1
927
- * (everyone gets one attack). The Actions "Attacks" heading shows `(×N)` when > 1.
928
- */
929
680
  attacksPerAction: number;
930
681
  attacks: AttackRow[];
682
+ spellDamageRiders?: SpellDamageRider[];
931
683
  equippedSlots: EquippedSlots;
932
684
  carriedWeight: number;
933
685
  attunementUsed: number;
934
686
  attunementLimit: number;
935
687
  conditionEffects: ConditionEffects;
936
- /**
937
- * Structured `roll-modifier` entries: four `mode` members since R4-G3a §6, not only advantage/disadvantage.
938
- * Order-preserving pass-through (no dedupe/merge); rendered as ADV/DIS/RR/+D4 chips.
939
- */
940
688
  rollModifiers: RollModifierEntry[];
941
- /**
942
- * `save-outcome` entries (R4-G3a §5.3). Order-preserving pass-through; rendered as an outcome
943
- * tag ("0/½") on the matching save chip, or on every save chip when `ability` is absent.
944
- */
945
689
  saveOutcomes: SaveOutcomeEntry[];
946
690
  }
947
691
  export interface SpellcastingClassInfo {
@@ -951,11 +695,8 @@ export interface SpellcastingClassInfo {
951
695
  defaultAbility: Ability;
952
696
  saveDC: number;
953
697
  attackBonus: number;
954
- /** The shared caster-type vocabulary; see schemas/caster-type-schema.ts (never spell the members out again). */
955
698
  casterType: CasterType;
956
699
  preparation: "known" | "prepared";
957
- /** The profile's `spellList` (null when neither block names one), so the add drawer can call the same
958
- * `attributeUnclassedSpell` the resolver does. recalc always sets it; optional so hand-built rows read as unobservable. */
959
700
  spellList?: string | null;
960
701
  }
961
702
  export interface SpellLimitInfo {