@archivist-gg/dnd5e 0.3.19 → 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 (440) 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 +3 -30
  128. package/dist/dnd/amount-text.js +1 -15
  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 +0 -15
  151. package/dist/entities/registry-revision.js +1 -10
  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 +22 -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 -141495
  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 +21 -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 +0 -24
  205. package/dist/pc/pc.additional-spells.js +1 -26
  206. package/dist/pc/pc.amount-bindings.d.ts +0 -25
  207. package/dist/pc/pc.amount-bindings.js +1 -28
  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 +0 -145
  215. package/dist/pc/pc.decision-engine.js +1 -55
  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 -41
  220. package/dist/pc/pc.equipment.d.ts +2 -22
  221. package/dist/pc/pc.equipment.js +1 -34
  222. package/dist/pc/pc.feature-effects.d.ts +22 -281
  223. package/dist/pc/pc.feature-effects.js +1 -39
  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 -65
  227. package/dist/pc/pc.item-effects.d.ts +18 -0
  228. package/dist/pc/pc.member-choices.d.ts +3 -66
  229. package/dist/pc/pc.member-choices.js +1 -39
  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 -27
  233. package/dist/pc/pc.proficiencies.d.ts +0 -40
  234. package/dist/pc/pc.proficiencies.js +1 -156
  235. package/dist/pc/pc.proficiency-grants.d.ts +0 -26
  236. package/dist/pc/pc.proficiency-normalize.d.ts +0 -35
  237. package/dist/pc/pc.proficiency-normalize.js +1 -18
  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 -1042
  242. package/dist/pc/pc.resolver.d.ts +0 -107
  243. package/dist/pc/pc.resolver.js +1 -60
  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 -231
  250. package/dist/pc/pc.schema.d.ts +0 -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 +0 -16
  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 +54 -374
  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 +21 -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 +4 -22
  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-2LULMQTF.js +0 -14
  346. package/dist/chunk-3LWMFYKS.js +0 -57
  347. package/dist/chunk-3SFGWFVQ.js +0 -19
  348. package/dist/chunk-3SIUAFDQ.js +0 -18
  349. package/dist/chunk-3TM34RSJ.js +0 -23
  350. package/dist/chunk-4J6DS3EJ.js +0 -30
  351. package/dist/chunk-4U55VNC7.js +0 -22
  352. package/dist/chunk-5GKJAUMX.js +0 -59
  353. package/dist/chunk-5JXFJ5AU.js +0 -26
  354. package/dist/chunk-64VNLMSG.js +0 -375
  355. package/dist/chunk-656QCX4U.js +0 -22
  356. package/dist/chunk-6GNXYAYP.js +0 -25
  357. package/dist/chunk-6PXTNCBP.js +0 -133
  358. package/dist/chunk-6X2NV665.js +0 -33
  359. package/dist/chunk-7Q2VPKCD.js +0 -181
  360. package/dist/chunk-7XJHI5H5.js +0 -709
  361. package/dist/chunk-A54HHCWW.js +0 -67
  362. package/dist/chunk-B2QHP6UF.js +0 -159
  363. package/dist/chunk-B3DP42OM.js +0 -55
  364. package/dist/chunk-BJGOSM76.js +0 -18
  365. package/dist/chunk-BJWSOQUC.js +0 -133
  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-DPUJDOKV.js +0 -365
  370. package/dist/chunk-EJD47JHL.js +0 -1838
  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-FC4IGH5Y.js +0 -18
  375. package/dist/chunk-FJYBLXV7.js +0 -89
  376. package/dist/chunk-FMUD3LDV.js +0 -19
  377. package/dist/chunk-FMYWORTP.js +0 -93
  378. package/dist/chunk-FVXLP7P3.js +0 -18
  379. package/dist/chunk-G6MHJDVT.js +0 -41
  380. package/dist/chunk-GVWEFECG.js +0 -18
  381. package/dist/chunk-HHBD4SQ6.js +0 -24
  382. package/dist/chunk-HS6FIOLP.js +0 -52
  383. package/dist/chunk-HY2SRSVM.js +0 -23
  384. package/dist/chunk-IHE6KVC3.js +0 -13
  385. package/dist/chunk-IN4M4X7P.js +0 -34
  386. package/dist/chunk-IUAAXXNO.js +0 -58
  387. package/dist/chunk-JXWNXIIZ.js +0 -219
  388. package/dist/chunk-K5NJBTE2.js +0 -18
  389. package/dist/chunk-KR6JF3BF.js +0 -14
  390. package/dist/chunk-KSTV7J2U.js +0 -112
  391. package/dist/chunk-KU3YLF6D.js +0 -106
  392. package/dist/chunk-LBEXLN6I.js +0 -91
  393. package/dist/chunk-LHZXYFBU.js +0 -94
  394. package/dist/chunk-LICYHPI3.js +0 -237
  395. package/dist/chunk-LNT64X7C.js +0 -81
  396. package/dist/chunk-LSLSG67V.js +0 -31
  397. package/dist/chunk-LVQLWRCU.js +0 -15
  398. package/dist/chunk-MYY2C5MB.js +0 -233
  399. package/dist/chunk-NKZMQV2C.js +0 -19
  400. package/dist/chunk-NTU2DXNG.js +0 -355
  401. package/dist/chunk-NXUY5XQN.js +0 -1062
  402. package/dist/chunk-NZO7M5GV.js +0 -18
  403. package/dist/chunk-OOL4KMG2.js +0 -71
  404. package/dist/chunk-OOSRUJBI.js +0 -19
  405. package/dist/chunk-PDJSUH24.js +0 -110
  406. package/dist/chunk-PTXBIDG7.js +0 -63
  407. package/dist/chunk-PVCEA4HZ.js +0 -6
  408. package/dist/chunk-QA3YCOML.js +0 -101
  409. package/dist/chunk-QFWQKS3M.js +0 -110
  410. package/dist/chunk-QS5L5YTJ.js +0 -24
  411. package/dist/chunk-QYZV2MQA.js +0 -97
  412. package/dist/chunk-RD2MID3M.js +0 -292
  413. package/dist/chunk-S3YUXDSC.js +0 -278
  414. package/dist/chunk-S7REMWW4.js +0 -21
  415. package/dist/chunk-TOM66P2P.js +0 -38
  416. package/dist/chunk-TRBGC4ZG.js +0 -112
  417. package/dist/chunk-UA5KS2PL.js +0 -26
  418. package/dist/chunk-UJCK5IW4.js +0 -187
  419. package/dist/chunk-UNYR5GLI.js +0 -23
  420. package/dist/chunk-UZXG6QSY.js +0 -58
  421. package/dist/chunk-VN5DLURA.js +0 -158
  422. package/dist/chunk-VP5TIXDK.js +0 -178
  423. package/dist/chunk-VPYBK2MG.js +0 -18
  424. package/dist/chunk-VTTA2ALZ.js +0 -16
  425. package/dist/chunk-W6GC6OKK.js +0 -16
  426. package/dist/chunk-WELIKLZF.js +0 -256
  427. package/dist/chunk-WOHX7YTH.js +0 -165
  428. package/dist/chunk-WSVMLNTO.js +0 -31
  429. package/dist/chunk-WYGD2UGN.js +0 -14
  430. package/dist/chunk-XCFC7LGF.js +0 -122
  431. package/dist/chunk-XJ2F2WO6.js +0 -8
  432. package/dist/chunk-XTEFPUSN.js +0 -23
  433. package/dist/chunk-YBLDE5CG.js +0 -42
  434. package/dist/chunk-YDGMBMYI.js +0 -25
  435. package/dist/chunk-YHYTW5QA.js +0 -20
  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-ZOWKWMD2.js +0 -18
  440. package/dist/chunk-ZUQW5VBZ.js +0 -89
@@ -0,0 +1 @@
1
+ import{z}from"zod";var spellInputSchema=z.object({name:z.string().describe("Spell name"),level:z.number().min(0).max(9).describe("Spell level (0 for cantrips)"),school:z.enum(["abjuration","conjuration","divination","enchantment","evocation","illusion","necromancy","transmutation"]),casting_time:z.string().describe('e.g., "1 action", "1 bonus action"'),range:z.string().describe('e.g., "Touch", "120 feet", "Self"'),components:z.string().describe('e.g., "V, S", "V, S, M (diamond worth 100 gp)"'),duration:z.string().describe('e.g., "Instantaneous", "Concentration, up to 1 minute"'),description:z.array(z.string()).describe("Spell description paragraphs. Use inline formula tags for damage and save DCs: `damage:DICE` for damage rolls (e.g. `damage:8d6`), `dc:ABILITY` for save DCs (e.g. `dc:WIS`). Valid abilities: STR, DEX, CON, INT, WIS, CHA."),at_higher_levels:z.array(z.string()).optional(),classes:z.array(z.string()).optional(),ritual:z.boolean().optional(),concentration:z.boolean().optional()});export{spellInputSchema};
@@ -0,0 +1 @@
1
+ import{featEntitySchema}from"./chunk-334WLI7V.js";import{parseYaml}from"@archivist-gg/core";function parseFeat(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=featEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`feat schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseFeat};
@@ -0,0 +1 @@
1
+ import{convertDescToTags,detectSpellcastingAbility}from"./chunk-MGGKZGLG.js";import{abilityModifier}from"./chunk-7FPQJDFD.js";import{toStringSafe}from"@archivist-gg/core";var CR_TO_XP={"0":10,"1/8":25,"1/4":50,"1/2":100,"1":200,"2":450,"3":700,"4":1100,"5":1800,"6":2300,"7":2900,"8":3900,"9":5e3,"10":5900,"11":7200,"12":8400,"13":1e4,"14":11500,"15":13e3,"16":15e3,"17":18e3,"18":2e4,"19":22e3,"20":25e3,"21":33e3,"22":41e3,"23":5e4,"24":62e3,"25":75e3,"26":9e4,"27":105e3,"28":12e4,"29":135e3,"30":155e3};function parseCR(cr){if(!cr)return 0;if(cr.includes("/")){const[num,denom]=cr.split("/").map(Number);return num/denom}return Number(cr)||0}function getChallengeRatingXP(cr){var _a;return(_a=CR_TO_XP[cr])!=null?_a:0}function getProficiencyBonus(cr){const v=parseCR(cr);if(v<5)return 2;if(v<9)return 3;if(v<13)return 4;if(v<17)return 5;if(v<21)return 6;if(v<25)return 7;if(v<29)return 8;return 9}function enrichMonster(raw){var _a,_b,_c;const cr=toStringSafe((_a=raw.cr)!=null?_a:"0");const abilities=raw.abilities;const wisdomMod=abilities?abilityModifier(abilities.wis):0;const passivePerception=(_b=raw.passive_perception)!=null?_b:10+wisdomMod;const languages=((_c=raw.languages)==null?void 0:_c.length)?raw.languages:["---"];const enriched={...raw,cr,xp:getChallengeRatingXP(cr),proficiency_bonus:getProficiencyBonus(cr),passive_perception:passivePerception,languages};convertMonsterEntries(enriched,cr);return enriched}var MONSTER_SECTIONS=[["traits","trait"],["actions","action"],["reactions","reaction"],["legendary_actions","legendary"]];function convertMonsterEntries(monster,cr){var _a;const abilities=monster.abilities;if(!abilities)return;const profBonus=getProficiencyBonus(cr);const spellAbility=detectSpellcastingAbility(((_a=monster.traits)!=null?_a:[]).map(f=>{var _a2;return{name:f.name,entries:(_a2=f.entries)!=null?_a2:[]}}));for(const[key,category]of MONSTER_SECTIONS){const features=monster[key];if(!Array.isArray(features))continue;for(const feature of features){const f=feature;if(!Array.isArray(f.entries))continue;f.entries=f.entries.map(desc=>{var _a2;if(/\{@\w+/.test(desc))return desc;return convertDescToTags(desc,{abilities,profBonus,actionName:(_a2=f.name)!=null?_a2:"",actionCategory:category,spellAbility})})}}}export{CR_TO_XP,parseCR,getChallengeRatingXP,getProficiencyBonus,enrichMonster,convertMonsterEntries};
@@ -0,0 +1 @@
1
+ import{featureEffectSchema}from"./chunk-6IC53O3Q.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var entityFilterSchema=z.object({feature_type:z.string().min(1).optional(),category:z.string().min(1).optional(),parent_class:z.literal("self").optional(),available_to:z.literal("self").optional(),weapon_category:z.enum(["simple","martial"]).optional(),armor_category:z.enum(["light","medium","heavy","shield"]).optional(),item_type:z.array(z.string().min(1)).nonempty().optional(),mundane:z.boolean().optional(),list:z.string().min(1).optional(),level:z.number().int().min(0).max(9).optional(),edition:z.string().min(1).optional(),ritual:z.boolean().optional(),inventory:z.boolean().optional()}).strict();var inlineOptionSchema=z.lazy(()=>z.object({value:z.string().min(1),label:z.string().min(1),description:z.string().optional(),effects:z.array(featureEffectSchema).optional(),choices:z.array(choiceSchema).optional()}).strict());var choiceSchema=z.lazy(()=>z.discriminatedUnion("kind",[z.object({kind:z.literal("select-inline"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive().optional(),options:z.array(inlineOptionSchema).nonempty()}).strict(),z.object({kind:z.literal("select-entity"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive().optional(),entity_type:z.string().min(1),from:z.array(z.string().min(1)).nonempty().optional(),where:entityFilterSchema.optional(),target:z.literal(true).optional()}).strict(),z.object({kind:z.literal("select-proficiency"),id:z.string().min(1),label:z.string().optional(),count:z.number().int().positive(),domain:z.enum(["skill","tool","language","save"]),from:z.array(z.string().min(1)).nonempty().optional(),from_proficient:z.boolean().optional(),expertise:z.boolean().optional()}).strict(),z.object({kind:z.literal("ability-points"),id:z.string().min(1),label:z.string().optional(),points:z.number().int().positive(),max_per:z.number().int().positive(),pool:z.array(abilityEnum).nonempty().optional()}).strict()]));export{choiceSchema};
@@ -0,0 +1 @@
1
+ var CONDITION_SLUGS=["blinded","charmed","deafened","frightened","grappled","incapacitated","invisible","paralyzed","petrified","poisoned","prone","restrained","stunned","unconscious"];export{CONDITION_SLUGS};
@@ -0,0 +1 @@
1
+ import{backgroundEntitySchema}from"./chunk-N3RYJ7RE.js";import{parseYaml}from"@archivist-gg/core";function parseBackground(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;const result=backgroundEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`background schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseBackground};
@@ -0,0 +1 @@
1
+ import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var conditionalPropertySchema=z.object({kind:z.literal("conditional"),uid:z.string(),note:z.string()});var propertySchema=z.union([z.string(),conditionalPropertySchema]);var editionEnum=z.enum(["2014","2024"]);var weaponEntitySchema=z.object({name:z.string().min(1),slug:z.string().min(1),category:z.string(),damage:z.object({dice:z.string(),type:z.string(),versatile_dice:z.string().optional()}),properties:z.array(propertySchema).default([]),range:z.object({normal:z.number().int().nonnegative(),long:z.number().int().nonnegative()}).optional(),reload:z.number().int().nonnegative().optional(),mastery:z.array(z.string()).optional(),type_tags:z.array(z.string()).optional(),ammo_type:z.string().optional(),weight:z.union([z.number(),z.string()]).optional(),cost:z.string().optional(),source:z.string().optional(),page:z.number().int().optional(),edition:editionEnum,entries:z.array(z.unknown()).optional(),rendering_hint:z.string().optional(),icon:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),image:imageField,raw:z.record(z.string(),z.unknown()).optional()}).loose();export{weaponEntitySchema};
@@ -0,0 +1 @@
1
+ function toDefenseSlug(s){return s.trim().toLowerCase().replace(/\s+/g," ")}export{toDefenseSlug};
@@ -0,0 +1 @@
1
+ import{z}from"zod";var encounterInputSchema=z.object({party_size:z.number().min(1).max(10).describe("Number of players"),party_level:z.number().min(1).max(20).describe("Average party level"),difficulty:z.enum(["easy","medium","hard","deadly"]),environment:z.string().optional().describe('e.g., "swamp", "dungeon", "forest"'),theme:z.string().optional().describe('e.g., "undead horde", "dragon lair"')});var encounterMonsterSchema=z.object({name:z.string(),cr:z.string(),count:z.number(),role:z.string()});var encounterOutputSchema=z.object({monsters:z.array(encounterMonsterSchema),tactics:z.string(),terrain:z.string(),notes:z.string(),xp_budget:z.object({target:z.number(),actual:z.number(),difficulty_rating:z.string()})});export{encounterInputSchema,encounterOutputSchema};
@@ -0,0 +1 @@
1
+ import{spellSource}from"./chunk-PZ3ZZ5H5.js";import{resourceLevelFor}from"./chunk-PZUPZBTN.js";import{addToRoll}from"./chunk-VIP3FH2O.js";import{baseClassName}from"./chunk-CAPYNIGK.js";function ownerClassSlug(source,resolved){var _a,_b,_c;if(!source)return null;if(source.kind==="class")return source.slug;if(source.kind==="subclass")return(_c=(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_a.entity)==null?void 0:_b.slug)!=null?_c:null;if(source.kind==="feat"&&source.via){if(source.via.kind==="class")return source.via.slug;if(source.via.kind==="pool")return source.via.classSlug}return null}function casterRow(classSlug,derived){var _a,_b;const rows=(_a=derived.spellcastingClasses)!=null?_a:[];const own=classSlug?rows.find(c=>baseClassName(c.classSlug)===baseClassName(classSlug)):void 0;return(_b=own!=null?own:rows[0])!=null?_b:null}function amountBindingsFor(owner,resolved,derived){var _a,_b;const classSlug=ownerClassSlug(owner,resolved);const classSource=classSlug?{kind:"class",slug:classSlug,level:0}:owner;const classLevel=classSource?resourceLevelFor(classSource,resolved):resolved.totalLevel;const row=casterRow(classSlug,derived);const className=classSlug?(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===classSlug}))==null?void 0:_a.entity)==null?void 0:_b.name:void 0;const classNames=resolved.classes.map(c=>{var _a2;return(_a2=c.entity)==null?void 0:_a2.name}).filter(n=>typeof n==="string"&&n.length>0);return{level:resolved.totalLevel,class_level:classLevel,prof:derived.proficiencyBonus,str_mod:derived.mods.str,dex_mod:derived.mods.dex,con_mod:derived.mods.con,int_mod:derived.mods.int,wis_mod:derived.mods.wis,cha_mod:derived.mods.cha,columns:{},...row?{spell_mod:derived.mods[row.ability],spell_dc:row.saveDC}:{},...className?{class_name:className}:{},...classNames.length>0?{class_names:classNames}:{}}}function spellcastingFor(spell,derived){var _a,_b;if((spellSource(spell).ownAbility||spell.classSlug==null)&&spell.ability){const own=(_a=derived.abilitySpellcasting)==null?void 0:_a[spell.ability];if(own)return{ability:spell.ability,saveDC:own.saveDC,attackBonus:own.attackBonus}}const row=casterRow((_b=spell.classSlug)!=null?_b:null,derived);return row?{ability:row.ability,saveDC:row.saveDC,attackBonus:row.attackBonus}:null}function spellAmountBindings(spell,resolved,derived){const cast=spellcastingFor(spell,derived);const base=amountBindingsFor(spell.classSlug?{kind:"class",slug:spell.classSlug,level:0}:void 0,resolved,derived);const out={...base};delete out.spell_mod;delete out.spell_dc;return cast?{...out,spell_mod:derived.mods[cast.ability],spell_dc:cast.saveDC}:out}function spellRollBonus(spell){var _a;const roll=(_a=spell.damage_roll)==null?void 0:_a.trim();const text=spell.description;if(!roll||!text)return null;const esc=roll.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");const re=new RegExp(`(?<![\\w])${esc}\`?\\s*(?:plus|\\+)\\s*your\\s+spellcasting\\s+(?:ability\\s+)?modifier`,"i");return re.test(text)?"{spell_mod}":null}function foldsIntoRoll(rider,spell){var _a,_b;const own=((_b=(_a=spell.entity.damage)==null?void 0:_a.types)!=null?_b:[]).map(t=>t.toLowerCase());return!rider.condition&&(!rider.damage_type||own.includes(rider.damage_type.toLowerCase()))}var reaching=(spell,derived)=>{var _a;return((_a=derived.spellDamageRiders)!=null?_a:[]).filter(r=>{var _a2;return(_a2=r.spells)==null?void 0:_a2.includes(spell.slug)})};function addSpellDamageRiders(roll,spell,derived){return addToRoll(roll,reaching(spell,derived).filter(r=>foldsIntoRoll(r,spell)).map(r=>r.amount))}function spellDamageRiderLines(spell,derived){return reaching(spell,derived).filter(r=>!foldsIntoRoll(r,spell)).map(r=>({amount:r.amount,...r.damage_type?{damage_type:r.damage_type}:{},...r.source?{source:r.source}:{},...r.condition?{condition:r.condition}:{}}))}export{ownerClassSlug,amountBindingsFor,spellcastingFor,spellAmountBindings,spellRollBonus,addSpellDamageRiders,spellDamageRiderLines};
@@ -0,0 +1 @@
1
+ import{abilityModifier}from"./chunk-7FPQJDFD.js";var ABILITY_KEYS=["str","dex","con","int","wis","cha"];var STATIC_FALLBACK_CONTEXT={abilities:{str:0,dex:0,con:0,int:0,wis:0,cha:0},profBonus:0,actionName:"",actionCategory:"trait"};var NATURAL_MELEE_NAMES=/\b(bite|claws?|slam|gore|tail|hooves|tusks?|talons?|fist|horns?)\b/i;var FINESSE_WEAPON_NAMES=/\b(shortsword|rapier|dagger|whip|scimitar)\b/i;var RANGED_WEAPON_NAMES=/\b(bow|crossbow|sling|dart|blowgun|javelin)\b/i;var SPELL_ATTACK_PHRASES=/\bspell\s+attack\b/i;function preferredAbilitiesForAttack(actionName,desc,spellAbility){const combined=`${actionName} ${desc}`;if(SPELL_ATTACK_PHRASES.test(combined)&&spellAbility)return[spellAbility];if(RANGED_WEAPON_NAMES.test(actionName))return["dex"];if(FINESSE_WEAPON_NAMES.test(actionName))return["str","dex"];if(NATURAL_MELEE_NAMES.test(actionName))return["str","dex"];return["str","dex"]}function identifyAbility(damageBonus,preferred,mods){if(damageBonus===null)return null;const candidates=ABILITY_KEYS.filter(k=>mods[k]===damageBonus);if(candidates.length===0)return null;if(candidates.length===1)return candidates[0];for(const p of preferred){if(candidates.includes(p))return p}return[...candidates].sort()[0]}function parseDamageBonusFromHitText(desc,attackPos){const window=desc.slice(attackPos,attackPos+250);const damageRe=/Hit:\s*(?:\d+\s*\()?\d+d\d+(?:\s*([+-])\s*(\d+))?\s*\)?\s*\w*\s+damage/i;const m=window.match(damageRe);if(!m)return null;if(m[1]===void 0||m[2]===void 0)return 0;return m[1]==="-"?-Number(m[2]):Number(m[2])}function parseDamageBonusFor2024(desc,attackPos){const window=desc.slice(attackPos,attackPos+250);const damageRe=/(?:\d+\s*\()?\d+d\d+(?:\s*([+-])\s*(\d+))?\s*\)?\s*\w*\s+damage/i;const m=window.match(damageRe);if(!m)return null;if(m[1]===void 0||m[2]===void 0)return 0;return m[1]==="-"?-Number(m[2]):Number(m[2])}function convertDescToTags(desc,ctx){try{if(!ctx.abilities)return desc;const mods=computeMods(ctx.abilities);const dcTargets=computeDcTargets(mods,ctx.profBonus);let result=desc;result=result.replace(/(Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)\s+Saving\s+Throw:\s+DC\s+(\d+)/gi,(_match,abilityWord,n)=>{const dc=Number(n);const abil=abilityWordToKey(abilityWord);if(abil&&dcTargets[abil]===dc){return`${abilityWord} Saving Throw: \`dc:${abil.toUpperCase()}\``}return`${abilityWord} Saving Throw: \`dc:${dc}\``});result=result.replace(/DC (\d+)\s+(Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)/gi,(_match,n,abilityWord)=>{const dc=Number(n);const abil=abilityWordToKey(abilityWord);if(abil&&dcTargets[abil]===dc){return`\`dc:${abil.toUpperCase()}\` ${abilityWord}`}return`\`dc:${dc}\` ${abilityWord}`});result=result.replace(/(Melee|Ranged|Spell)\s+Attack\s+Roll:\s+([+-])(\d+),/g,(match,kind,sign,n,offset)=>{const attackBonus=sign==="-"?-Number(n):Number(n);const before=desc.slice(Math.max(0,offset-200),offset);const actionMatch=before.match(/(?:^|\.\s+)([A-Z][\w\s,'-]{1,40})\./);const actionName=actionMatch?actionMatch[1]:ctx.actionName;const damageBonus=parseDamageBonusFor2024(desc,offset+match.length);const preferred=kind.toLowerCase()==="spell"&&ctx.spellAbility?[ctx.spellAbility]:preferredAbilitiesForAttack(actionName,desc,ctx.spellAbility);const ability=identifyAbility(damageBonus,preferred,mods);const literal=attackBonus>=0?`+${attackBonus}`:`${attackBonus}`;if(ability===null){return`${kind} Attack Roll: \`atk:${literal}\`,`}if(attackBonus===mods[ability]+ctx.profBonus){return`${kind} Attack Roll: \`atk:${ability.toUpperCase()}+PB\`,`}if(attackBonus===mods[ability]){return`${kind} Attack Roll: \`atk:${ability.toUpperCase()}\`,`}return`${kind} Attack Roll: \`atk:${literal}\`,`});result=result.replace(/([+-])(\d+)\s+to\s+hit/g,(_match,sign,n,attackPos)=>{const attackBonus=sign==="-"?-Number(n):Number(n);const before=desc.slice(Math.max(0,attackPos-200),attackPos);const actionMatch=before.match(/(?:^|\.\s+)([A-Z][\w\s,'-]{1,40})\./);const actionName=actionMatch?actionMatch[1]:ctx.actionName;const damageBonus=parseDamageBonusFromHitText(desc,attackPos);const preferred=preferredAbilitiesForAttack(actionName,desc,ctx.spellAbility);const ability=identifyAbility(damageBonus,preferred,mods);if(ability===null){const literal2=attackBonus>=0?`+${attackBonus}`:`${attackBonus}`;return`\`atk:${literal2}\``}if(attackBonus===mods[ability]+ctx.profBonus){return`\`atk:${ability.toUpperCase()}+PB\``}if(attackBonus===mods[ability]){return`\`atk:${ability.toUpperCase()}\``}const literal=attackBonus>=0?`+${attackBonus}`:`${attackBonus}`;return`\`atk:${literal}\``});result=result.replace(/(?:(\d+)\s*\()?(\d+d\d+)(?:\s*([+-])\s*(\d+))?\s*\)?(?:\s+(\w+))?\s+damage/gi,(_match,_average,dice,sign,bonusStr,typeWord)=>{var _a;let inner=dice;if(bonusStr!=null){const bonus=sign==="-"?-Number(bonusStr):Number(bonusStr);const matchingAbilities=ABILITY_KEYS.filter(k=>mods[k]===bonus);if(matchingAbilities.length>0){const preferred=preferredAbilitiesForAttack(ctx.actionName,"",ctx.spellAbility);const pick=(_a=preferred.find(p=>matchingAbilities.includes(p)))!=null?_a:[...matchingAbilities].sort()[0];inner=`${dice}+${pick.toUpperCase()}`}else{inner=`${dice}${bonus>=0?"+":""}${bonus}`}}const typeSuffix=typeWord?` ${typeWord} damage`:" damage";return`\`dmg:${inner}\`${typeSuffix}`});result=result.replace(/Hit:\s*(\d+)\s+(\w+)?\s*damage/gi,(_match,n,typeWord)=>{const tt=typeWord?` ${typeWord} damage`:" damage";return`Hit: \`dmg:${n}\`${tt}`});result=result.replace(/(?<!`)DC (\d+)(?!\s*(?:Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma))/gi,(_match,n)=>{const dc=Number(n);const candidates=ABILITY_KEYS.filter(k=>dcTargets[k]===dc);if(ctx.spellAbility&&candidates.includes(ctx.spellAbility)){return`\`dc:${ctx.spellAbility.toUpperCase()}\``}if(candidates.length===1){return`\`dc:${candidates[0].toUpperCase()}\``}if(candidates.length>1){const abil=disambiguateAbility(candidates,ctx,desc);return`\`dc:${abil.toUpperCase()}\``}return`\`dc:${dc}\``});result=result.replace(/`[^`]*`|(?<!\w)(\d+d\d+(?:\s*[+-]\s*\d+)?)(?!\w)/g,(match,dice)=>{if(dice)return`\`dice:${dice.replace(/\s+/g,"")}\``;return match});return result}catch(e){return desc}}function computeMods(abilities){return{str:abilityModifier(abilities.str),dex:abilityModifier(abilities.dex),con:abilityModifier(abilities.con),int:abilityModifier(abilities.int),wis:abilityModifier(abilities.wis),cha:abilityModifier(abilities.cha)}}function computeDcTargets(mods,profBonus){return{str:8+profBonus+mods.str,dex:8+profBonus+mods.dex,con:8+profBonus+mods.con,int:8+profBonus+mods.int,wis:8+profBonus+mods.wis,cha:8+profBonus+mods.cha}}function disambiguateAbility(candidates,ctx,desc){var _a,_b,_c,_d,_e,_f,_g,_h;if(candidates.length===1)return candidates[0];const combined=`${desc} ${ctx.actionName}`.toLowerCase();const prefers=abil=>candidates.includes(abil)?abil:void 0;if(/melee\s+or\s+ranged\s+weapon\s+attack/.test(combined)){return(_b=(_a=prefers("str"))!=null?_a:prefers("dex"))!=null?_b:candidates[0]}if(/melee\s+weapon\s+attack/.test(combined)){return(_d=(_c=prefers("str"))!=null?_c:prefers("dex"))!=null?_d:candidates[0]}if(/ranged\s+weapon\s+attack/.test(combined)){return(_e=prefers("dex"))!=null?_e:candidates[0]}if(/spell\s+attack/.test(combined)){if(ctx.spellAbility&&candidates.includes(ctx.spellAbility)){return ctx.spellAbility}return(_f=prefers("wis"))!=null?_f:candidates[0]}const rangedWords=/\b(bow|crossbow|dart|sling)\b/;const meleeWords=/\b(bite|claw|slam|tail|gore|horns?|fist|hoof|talons?)\b/;if(rangedWords.test(ctx.actionName.toLowerCase())){return(_g=prefers("dex"))!=null?_g:candidates[0]}if(meleeWords.test(ctx.actionName.toLowerCase())){return(_h=prefers("str"))!=null?_h:candidates[0]}return[...candidates].sort()[0]}function abilityWordToKey(word){const lower=word.toLowerCase();switch(lower){case"strength":return"str";case"dexterity":return"dex";case"constitution":return"con";case"intelligence":return"int";case"wisdom":return"wis";case"charisma":return"cha"}return void 0}function detectSpellcastingAbility(traits){if(!traits)return void 0;for(const trait of traits){for(const entry of trait.entries){const match=entry.match(/spellcasting ability is (intelligence|wisdom|charisma)/i);if(match){const name=match[1].toLowerCase();if(name==="intelligence")return"int";if(name==="wisdom")return"wis";if(name==="charisma")return"cha"}}}return void 0}export{STATIC_FALLBACK_CONTEXT,convertDescToTags,detectSpellcastingAbility};
@@ -0,0 +1 @@
1
+ import{startingEquipmentEntrySchema}from"./chunk-TKIEPC6F.js";import{choiceSchema}from"./chunk-KBFSJ5WE.js";import{additionalSpellsEntrySchema,imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var editionEnum=z.enum(["2014","2024"]);var skillEnum=z.enum(["acrobatics","animal-handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight-of-hand","stealth","survival"]);var wikilinkRegex=/^\[\[[^[\]]+\]\]$/;var toolProfSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("fixed"),items:z.array(z.string()).nonempty()}),z.object({kind:z.literal("choice"),count:z.number().int().positive(),from:z.array(z.string()).nonempty()})]);var langProfSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("fixed"),languages:z.array(z.string()).nonempty()}),z.object({kind:z.literal("choice"),count:z.number().int().positive(),from:z.union([z.string(),z.array(z.string())])})]);var suggestedCharSchema=z.object({personality_traits:z.record(z.string(),z.string()).optional(),ideals:z.record(z.string(),z.object({name:z.string().optional(),desc:z.string(),alignment:z.string().optional()})).optional(),bonds:z.record(z.string(),z.string()).optional(),flaws:z.record(z.string(),z.string()).optional()});var backgroundEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),skill_proficiencies:z.array(skillEnum),tool_proficiencies:z.array(toolProfSchema),language_proficiencies:z.array(langProfSchema),equipment:z.array(startingEquipmentEntrySchema),feature:z.object({name:z.string().min(1),description:z.string().min(1)}),ability_score_increases:z.object({pool:z.array(abilityEnum).length(3)}).nullable(),origin_feat:z.string().regex(wikilinkRegex).nullable(),suggested_characteristics:suggestedCharSchema.nullable(),choices:z.array(choiceSchema).optional(),rendering_hint:z.string().optional(),has_fluff_images:z.boolean().optional(),tables:z.array(z.object({name:z.string().min(1),dice:z.string().min(1),rows:z.array(z.object({roll:z.string(),text:z.string()}))})).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),prerequisites:z.array(z.object({kind:z.literal("campaign"),slug:z.string().min(1)})).optional(),image:imageField});export{langProfSchema,backgroundEntitySchema};
@@ -0,0 +1 @@
1
+ import{evaluateConditions}from"./chunk-56JK6VCL.js";function isConditionalBonus(x){return!!x&&typeof x==="object"&&typeof x.value==="number"&&Array.isArray(x.when)}function readNumericBonus(raw,ctx){if(raw===void 0||raw===null)return null;if(typeof raw==="number"){return raw===0?null:{kind:"applied",value:raw}}if(!isConditionalBonus(raw))return null;if(raw.value===0)return null;const outcome=evaluateConditions(raw.when,ctx);if(outcome==="true")return{kind:"applied",value:raw.value};if(outcome==="false")return{kind:"skipped"};return{kind:"informational",value:raw.value,conditions:raw.when}}export{readNumericBonus};
@@ -0,0 +1 @@
1
+ import{readTableColumn}from"./chunk-BGX36NPE.js";import{bareSlug,baseClassName}from"./chunk-CAPYNIGK.js";import{abilityModifier}from"./chunk-7FPQJDFD.js";function hasPreparedColumn(table){return Object.values(table).some(row=>PREPARED_COLUMNS.some(k=>{var _a;return((_a=row==null?void 0:row.columns)==null?void 0:_a[k])!==void 0}))}function resolveSpellcasting(rc){var _a,_b,_c,_d,_e,_f,_g,_h,_i,_j,_k,_l,_m,_n,_o,_p;const sub=(_b=(_a=rc.subclass)==null?void 0:_a.spellcasting)!=null?_b:null;const cls=(_d=(_c=rc.entity)==null?void 0:_c.spellcasting)!=null?_d:null;const casterType=(_f=(_e=sub==null?void 0:sub.caster_type)!=null?_e:cls==null?void 0:cls.caster_type)!=null?_f:null;const ability=(_h=(_g=sub==null?void 0:sub.ability)!=null?_g:cls==null?void 0:cls.ability)!=null?_h:null;if(!casterType||!ability)return null;const table=(_l=(_k=(sub==null?void 0:sub.caster_type)?(_i=rc.subclass)==null?void 0:_i.table:void 0)!=null?_k:(_j=rc.entity)==null?void 0:_j.table)!=null?_l:{};const preparation=(_n=(_m=sub==null?void 0:sub.preparation)!=null?_m:cls==null?void 0:cls.preparation)!=null?_n:hasPreparedColumn(table)?"prepared":"known";const spellList=(_p=(_o=sub==null?void 0:sub.spell_list)!=null?_o:cls==null?void 0:cls.spell_list)!=null?_p:null;return{ability,casterType,preparation,spellList,table}}function effectiveSpellcastingAbility(classSlug,dataAbility,overrides){var _a,_b;return(_b=(_a=overrides.spellcasting_ability_by_class)==null?void 0:_a[classSlug])!=null?_b:dataAbility}function normalizeKnownSpell(entry){var _a,_b;if(typeof entry==="string"){return{slug:bareSlug(entry),classSlug:null,source:"class",preparedFlag:void 0,alwaysPrepared:false}}return{slug:bareSlug(entry.spell),classSlug:entry.class?bareSlug(entry.class):null,source:(_a=entry.source)!=null?_a:"class",preparedFlag:entry.prepared,alwaysPrepared:(_b=entry.always_prepared)!=null?_b:false}}function firstListedCasterClass(spellClasses,casterClassSlugs){var _a;if(!Array.isArray(spellClasses)||spellClasses.length===0)return null;const listed=new Set(spellClasses.map(c=>baseClassName(String(c))));return(_a=casterClassSlugs.find(slug=>listed.has(baseClassName(slug))))!=null?_a:null}var LISTED_CLASS_NAMES=new WeakMap;var NO_NAMES=new Set;function listedSpellClassNames(registry,compendium){var _a;const count=registry.count();let cached=LISTED_CLASS_NAMES.get(registry);if(!cached||cached.count!==count){const byCompendium=new Map;for(const e of registry.search("","spell",Number.POSITIVE_INFINITY)){const classes=e.data.classes;if(!Array.isArray(classes))continue;let names=byCompendium.get(e.compendium);if(!names)byCompendium.set(e.compendium,names=new Set);for(const c of classes)names.add(baseClassName(String(c)))}cached={count,byCompendium};LISTED_CLASS_NAMES.set(registry,cached)}return(_a=cached.byCompendium.get(compendium))!=null?_a:NO_NAMES}function attributeUnclassedSpell(spellClasses,casters,registry){var _a;const first=casters[0];if(!first)return null;const listed=firstListedCasterClass(spellClasses,casters.map(c=>c.classSlug));if(listed==null||listed===first.classSlug)return first.classSlug;if(first.spellList==null)return first.classSlug;const compendium=(_a=registry.getByTypeAndSlug("class",first.classSlug))==null?void 0:_a.compendium;if(compendium==null||!listedSpellClassNames(registry,compendium).has(baseClassName(first.classSlug)))return first.classSlug;return listed}var FULL_CASTER_SLOTS=[[2,0,0,0,0,0,0,0,0],[3,0,0,0,0,0,0,0,0],[4,2,0,0,0,0,0,0,0],[4,3,0,0,0,0,0,0,0],[4,3,2,0,0,0,0,0,0],[4,3,3,0,0,0,0,0,0],[4,3,3,1,0,0,0,0,0],[4,3,3,2,0,0,0,0,0],[4,3,3,3,1,0,0,0,0],[4,3,3,3,2,0,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,0,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,0,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,0],[4,3,3,3,2,1,1,1,1],[4,3,3,3,3,1,1,1,1],[4,3,3,3,3,2,1,1,1],[4,3,3,3,3,2,2,1,1]];var HALF_CASTER_SLOTS=[[0,0,0,0,0],[2,0,0,0,0],[3,0,0,0,0],[3,0,0,0,0],[4,2,0,0,0],[4,2,0,0,0],[4,3,0,0,0],[4,3,0,0,0],[4,3,2,0,0],[4,3,2,0,0],[4,3,3,0,0],[4,3,3,0,0],[4,3,3,1,0],[4,3,3,1,0],[4,3,3,2,0],[4,3,3,2,0],[4,3,3,3,1],[4,3,3,3,1],[4,3,3,3,2],[4,3,3,3,2]];var THIRD_CASTER_SLOTS=[[0,0,0,0],[0,0,0,0],[2,0,0,0],[3,0,0,0],[3,0,0,0],[3,0,0,0],[4,2,0,0],[4,2,0,0],[4,2,0,0],[4,3,0,0],[4,3,0,0],[4,3,0,0],[4,3,2,0],[4,3,2,0],[4,3,2,0],[4,3,3,0],[4,3,3,0],[4,3,3,0],[4,3,3,1],[4,3,3,1]];var PACT_MAGIC=[{level:1,total:1},{level:1,total:2},{level:2,total:2},{level:2,total:2},{level:3,total:2},{level:3,total:2},{level:4,total:2},{level:4,total:2},{level:5,total:2},{level:5,total:2},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:3},{level:5,total:4},{level:5,total:4},{level:5,total:4},{level:5,total:4}];var HALF_UP_CASTER_SLOTS=HALF_CASTER_SLOTS.map(row=>[...row]);HALF_UP_CASTER_SLOTS[0]=[2,0,0,0,0];function slotTableFor(caster){switch(caster){case"full":return FULL_CASTER_SLOTS;case"half":return HALF_CASTER_SLOTS;case"third":return THIRD_CASTER_SLOTS;case"half-up":return HALF_UP_CASTER_SLOTS;default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function rowToRecord(row){const out={};row.forEach((n,i)=>{if(n>0)out[i+1]=n});return out}function deriveSpellSlots(classes){let fullLevels=0,halfLevels=0,thirdLevels=0,halfUpLevels=0,warlockLevel=0;const regular=[];for(const c of classes){if(c.casterType==="pact"){warlockLevel+=c.level;continue}regular.push({caster:c.casterType,level:c.level});switch(c.casterType){case"full":fullLevels+=c.level;break;case"half":halfLevels+=c.level;break;case"third":thirdLevels+=c.level;break;case"half-up":halfUpLevels+=c.level;break;default:{const _n=c.casterType;throw new Error(`unknown caster type ${String(_n)}`)}}}let standard={};if(regular.length===1){const only=regular[0];const table=slotTableFor(only.caster);const idx=only.level-1;if(idx>=0&&idx<table.length)standard=rowToRecord(table[idx])}else if(regular.length>=2){const cl=fullLevels+Math.floor(halfLevels/2)+Math.floor(thirdLevels/3)+Math.ceil(halfUpLevels/2);if(cl>=1&&cl<=FULL_CASTER_SLOTS.length)standard=rowToRecord(FULL_CASTER_SLOTS[cl-1])}const pact=warlockLevel>=1&&warlockLevel<=PACT_MAGIC.length?PACT_MAGIC[warlockLevel-1]:null;return{standard,pact}}var PREPARED_COLUMNS=["Prepared Spells","Spells Prepared"];function preparedLevelTerm(caster,level){switch(caster){case"full":case"pact":return level;case"half":case"half-up":return Math.floor(level/2);case"third":return Math.floor(level/3);default:{const _n=caster;throw new Error(`unknown caster type ${String(_n)}`)}}}function computeSpellLimits(inputs){const out=[];for(const i of inputs){const p=i.profile;const cantripsKnown=readTableColumn(p.table,i.level,["Cantrips Known","Cantrips"]);const mod=abilityModifier(i.abilityScore);let preparedOrKnown;if(p.preparation==="prepared"){const fromTable=readTableColumn(p.table,i.level,PREPARED_COLUMNS);preparedOrKnown=fromTable!==null?fromTable:Math.max(1,mod+preparedLevelTerm(p.casterType,i.level))}else{preparedOrKnown=readTableColumn(p.table,i.level,["Spells Known","Prepared Spells"])}out.push({classSlug:i.classSlug,kind:p.preparation,cantripsKnown,preparedOrKnown})}return out}export{resolveSpellcasting,effectiveSpellcastingAbility,normalizeKnownSpell,listedSpellClassNames,attributeUnclassedSpell,slotTableFor,deriveSpellSlots,PREPARED_COLUMNS,preparedLevelTerm,computeSpellLimits};
@@ -0,0 +1 @@
1
+ import{armorEntitySchema}from"./chunk-RE5Z5RNK.js";import{parseYaml}from"@archivist-gg/core";var KNOWN_KEYS=new Set(["name","slug","category","ac","strength_requirement","stealth_disadvantage","weight","cost","rarity","source","page","edition","entries","raw","rendering_hint","icon","has_fluff","has_fluff_images","image","strength_required"]);function parseArmor(source){var _a;const raw=parseYaml(source,["name","slug","category","ac"]);if(!raw.success)return raw;if(raw.data.strength_requirement===void 0&&typeof raw.data.strength_required==="number"){raw.data.strength_requirement=raw.data.strength_required}const result=armorEntitySchema.safeParse(raw.data);if(!result.success){return{success:false,error:`armor schema validation failed: ${result.error.message}`}}const entity=result.data;const extras={};for(const[k,v]of Object.entries(raw.data)){if(!KNOWN_KEYS.has(k))extras[k]=v}if(Object.keys(extras).length>0){entity.raw={...(_a=entity.raw)!=null?_a:{},...extras}}return{success:true,data:entity}}export{parseArmor};
@@ -0,0 +1 @@
1
+ var RENDERING_HINT_LAYOUT={"dice-pool":"dice-pool","point-pool":"point-pool"};function derivePoolLayout(entries){var _a,_b;const votes=new Map;for(const e of entries){const hint=(_a=e.entity.rendering_hint)!=null?_a:"";if(!Object.prototype.hasOwnProperty.call(RENDERING_HINT_LAYOUT,hint))continue;const layout=RENDERING_HINT_LAYOUT[hint];votes.set(layout,((_b=votes.get(layout))!=null?_b:0)+1)}let best;let bestN=0;let tied=false;for(const[layout,n]of votes){if(n>bestN){best=layout;bestN=n;tied=false}else if(n===bestN)tied=true}return tied?void 0:best}function poolPresentation(authored,derived){const head=authored==="point-pool"?"points":authored==="dice-pool"?"dice":derived==="point-pool"?"points":"dice";return{head}}var RENDERING_HINT_AFFORDANCE={"granted-die-to-ally":"granted-die"};function deriveEntryAffordance(entity){var _a;const hint=(_a=entity.rendering_hint)!=null?_a:"";if(!Object.prototype.hasOwnProperty.call(RENDERING_HINT_AFFORDANCE,hint))return void 0;return RENDERING_HINT_AFFORDANCE[hint]}var AFFORDANCE_CAPTIONS={"granted-die":"{amount}{die} to an ally"};function formatAffordanceCaption(affordance,values){return AFFORDANCE_CAPTIONS[affordance].replace(/\{(\w+)\}/g,(whole,key)=>Object.prototype.hasOwnProperty.call(values,key)?String(values[key]):whole)}export{RENDERING_HINT_LAYOUT,derivePoolLayout,poolPresentation,RENDERING_HINT_AFFORDANCE,deriveEntryAffordance,AFFORDANCE_CAPTIONS,formatAffordanceCaption};
@@ -0,0 +1 @@
1
+ import{poolGrantSchema,selectionPoolSchema,tabDeclSchema}from"./chunk-GCYUCIDN.js";import{casterTypeEnum}from"./chunk-X22SISGM.js";import{featureSchema}from"./chunk-V6NQ547U.js";import{resourceSchema}from"./chunk-CCFIINBA.js";import{startingEquipmentEntrySchema,startingGoldSchema}from"./chunk-TKIEPC6F.js";import{choiceSchema}from"./chunk-KBFSJ5WE.js";import{additionalSpellsEntrySchema,imageField,progressionSchema}from"./chunk-I26FHSI6.js";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var skillEnum=z.enum(["acrobatics","animal-handling","arcana","athletics","deception","history","insight","intimidation","investigation","medicine","nature","perception","performance","persuasion","religion","sleight-of-hand","stealth","survival"]);var armorCategoryEnum=z.enum(["light","medium","heavy","shield"]);var weaponCategoryEnum=z.enum(["simple","martial"]);var hitDieEnum=z.enum(["d6","d8","d10","d12"]);var editionEnum=z.enum(["2014","2024"]);var weaponProficiencySchema=z.object({fixed:z.array(z.string()).optional(),categories:z.array(weaponCategoryEnum).optional(),conditional:z.array(z.object({category:weaponCategoryEnum,where_property:z.array(z.string()).nonempty()})).optional()}).refine(w=>{var _a,_b,_c,_d,_e,_f;return((_b=(_a=w.fixed)==null?void 0:_a.length)!=null?_b:0)+((_d=(_c=w.categories)==null?void 0:_c.length)!=null?_d:0)+((_f=(_e=w.conditional)==null?void 0:_e.length)!=null?_f:0)>0},{message:"weapon proficiency must declare at least one of fixed/categories/conditional"});var toolProficiencySchema=z.object({fixed:z.array(z.string()).optional(),choice:z.object({count:z.number().int().positive(),from:z.array(z.string()).nonempty()}).optional()}).refine(t=>{var _a,_b;return((_b=(_a=t.fixed)==null?void 0:_a.length)!=null?_b:0)>0||t.choice!==void 0},{message:"tool proficiency must declare fixed or choice"});var spellcastingSchema=z.object({caster_type:casterTypeEnum,ability:abilityEnum,preparation:z.enum(["known","prepared"]),spell_list:z.string().min(1)});var weaponMasterySchema=z.object({starting_count:z.number().int().nonnegative().optional(),scaling:z.record(z.string(),z.number().int().nonnegative()).optional()});var classTableRowSchema=z.object({prof_bonus:z.number().int().positive(),columns:z.record(z.string(),z.union([z.string(),z.number()])).optional(),feature_ids:z.array(z.string())});var classEntitySchema=z.object({slug:z.string().min(1),name:z.string().min(1),edition:editionEnum,source:z.string().min(1),description:z.string(),hit_die:hitDieEnum,primary_abilities:z.array(abilityEnum).nonempty(),standard_array:z.strictObject({str:z.number().int(),dex:z.number().int(),con:z.number().int(),int:z.number().int(),wis:z.number().int(),cha:z.number().int()}).optional(),saving_throws:z.array(abilityEnum).length(2),proficiencies:z.object({armor:z.array(armorCategoryEnum),weapons:weaponProficiencySchema,tools:toolProficiencySchema.optional()}),skill_choices:z.object({count:z.number().int().positive(),from:z.array(skillEnum).nonempty()}),choices:z.array(choiceSchema).optional(),starting_equipment:z.array(startingEquipmentEntrySchema),starting_gold:startingGoldSchema.optional(),spellcasting:spellcastingSchema.nullable(),subclass_level:z.number().int().positive(),subclass_feature_name:z.string().min(1),weapon_mastery:weaponMasterySchema.nullable(),epic_boon_level:z.number().int().positive().nullable(),table:z.record(z.string(),classTableRowSchema),features_by_level:z.record(z.string(),z.array(featureSchema)),resources:z.array(resourceSchema),selection_pools:z.array(selectionPoolSchema).optional(),pool_grants:z.array(poolGrantSchema).optional(),tabs:z.array(tabDeclSchema).optional(),rendering_hint:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),table_col_labels:z.array(z.string().min(1)).optional(),starting_equipment_additional_from_background:z.boolean().optional(),multiclassing:z.unknown().optional(),cantrip_progression:z.array(z.number()).optional(),prepared_spells:z.string().min(1).optional(),prepared_spells_change:z.string().min(1).optional(),prepared_spells_progression:z.array(z.number()).optional(),spells_known_progression:z.array(z.number()).optional(),spells_known_progression_fixed:z.array(z.number()).optional(),spells_known_progression_fixed_allow_lower_level:z.boolean().optional(),spells_known_progression_fixed_by_level:z.record(z.string(),z.record(z.string(),z.number())).optional(),feat_progression:z.array(progressionSchema).optional(),optionalfeature_progression:z.array(progressionSchema).optional(),additional_spells:z.array(additionalSpellsEntrySchema).optional(),image:imageField});export{classEntitySchema};
@@ -0,0 +1 @@
1
+ import{isConsumedOnUse,resolveEntryEntity}from"./chunk-DY6FVAGA.js";import{isReadOnceItem}from"./chunk-DVUXUIPV.js";import{requiresAttunement}from"./chunk-YGH7S5ZF.js";import{featureEffectSchema}from"./chunk-6IC53O3Q.js";var linkSlug=item=>{var _a,_b;return(_b=(_a=/^\[\[(.+?)(\|.*)?\]\]$/.exec(item.trim()))==null?void 0:_a[1])!=null?_b:null};function itemBenefitsActive(entry,entity,registry,view){var _a;if(!entry.equipped)return false;if(requiresAttunement(entity)&&entry.attuned!==true)return false;if(isConsumedOnUse(entry,registry,view))return false;const slug=entity==null?void 0:entity.slug;if(isReadOnceItem(typeof slug==="string"&&slug?slug:(_a=linkSlug(entry.item))!=null?_a:entry.item))return false;return true}function itemLabel(entry,entity){var _a,_b,_c,_d;return(_d=(_a=entry.overrides)==null?void 0:_a.name)!=null?_d:String((_c=(_b=entity==null?void 0:entity.name)!=null?_b:linkSlug(entry.item))!=null?_c:entry.item)}var ITEM_ROW_KINDS=new Set(["damage-bonus","crit-range","reroll-damage","extra-attack","weapon-ability","attack-rule"]);function readItemEffects(entity){const raw=entity==null?void 0:entity.effects;const effects=[];const invalid=[];if(!Array.isArray(raw))return{effects,invalid};for(const e of raw){const parsed=featureEffectSchema.safeParse(e);if(parsed.success)effects.push(parsed.data);else invalid.push(typeof(e==null?void 0:e.kind)==="string"?String(e.kind):"unknown")}return{effects,invalid}}function itemRowEffects(entity){return readItemEffects(entity).effects.filter(e=>ITEM_ROW_KINDS.has(e.kind))}function buildItemFeatures(equipment,registry,infusions,warnings){const out=[];if(typeof registry.getBySlug!=="function")return out;equipment.forEach((entry,index)=>{var _a,_b;if(!entry.equipped)return;const{entity,entityType}=resolveEntryEntity(entry,index,registry,infusions);if(!entity||entityType!=="item")return;if(!itemBenefitsActive(entry,entity,registry,infusions==null?void 0:infusions.views.get(index)))return;const{effects,invalid}=readItemEffects(entity);const name=itemLabel(entry,entity);if(invalid.length){warnings.push(`${name}: the sheet cannot read ${invalid.length===1?"this effect":"these effects"} (${invalid.join(", ")}); ignored.`)}const own=effects.filter(e=>!ITEM_ROW_KINDS.has(e.kind));if(own.length===0)return;const slug=String((_b=(_a=entity.slug)!=null?_a:linkSlug(entry.item))!=null?_b:entry.item);out.push({feature:{id:`item:${index}:${slug}`,name,activatable:false,effects:own},source:{kind:"item",slug,index}})});return out}export{itemBenefitsActive,itemLabel,itemRowEffects,buildItemFeatures};
@@ -0,0 +1 @@
1
+ var SPELL_SOURCE={class:{ownAbility:false,section:"spellbook",freeCastWhenNoSlot:false,showInPrepare:true,countsAsGranted:false},feat:{ownAbility:true,section:"spellbook",freeCastWhenNoSlot:true,showInPrepare:true,countsAsGranted:true},item:{ownAbility:false,section:"consumable",freeCastWhenNoSlot:false,showInPrepare:false,countsAsGranted:true},race:{ownAbility:true,section:"spellbook",freeCastWhenNoSlot:true,showInPrepare:true,countsAsGranted:true},domain:{ownAbility:false,section:"spellbook",freeCastWhenNoSlot:false,showInPrepare:true,countsAsGranted:false}};var spellSource=s=>SPELL_SOURCE[s.source];export{SPELL_SOURCE,spellSource};
@@ -0,0 +1 @@
1
+ import{slugify}from"./chunk-63YJPWTM.js";var retired_items_2014_default=[{retired_slug:"srd-5e_item_adamantine-breastplate",retired_name:"Adamantine Breastplate",retired_path:"SRD 5e/Magic Items/Adamantine Breastplate.md",kept_slug:"srd-5e_item_adamantine-armor-breastplate",kept_name:"Adamantine Armor (Breastplate)"},{retired_slug:"srd-5e_item_adamantine-chain-mail",retired_name:"Adamantine Chain Mail",retired_path:"SRD 5e/Magic Items/Adamantine Chain Mail.md",kept_slug:"srd-5e_item_adamantine-armor-chain-mail",kept_name:"Adamantine Armor (Chain-Mail)"},{retired_slug:"srd-5e_item_adamantine-chain-shirt",retired_name:"Adamantine Chain Shirt",retired_path:"SRD 5e/Magic Items/Adamantine Chain Shirt.md",kept_slug:"srd-5e_item_adamantine-armor-chain-shirt",kept_name:"Adamantine Armor (Chain-Shirt)"},{retired_slug:"srd-5e_item_adamantine-half-plate-armor",retired_name:"Adamantine Half Plate Armor",retired_path:"SRD 5e/Magic Items/Adamantine Half Plate Armor.md",kept_slug:"srd-5e_item_adamantine-armor-half-plate",kept_name:"Adamantine Armor (Half-Plate)"},{retired_slug:"srd-5e_item_adamantine-plate-armor",retired_name:"Adamantine Plate Armor",retired_path:"SRD 5e/Magic Items/Adamantine Plate Armor.md",kept_slug:"srd-5e_item_adamantine-armor-plate",kept_name:"Adamantine Armor (Plate)"},{retired_slug:"srd-5e_item_adamantine-ring-mail",retired_name:"Adamantine Ring Mail",retired_path:"SRD 5e/Magic Items/Adamantine Ring Mail.md",kept_slug:"srd-5e_item_adamantine-armor-ring-mail",kept_name:"Adamantine Armor (Ring-Mail)"},{retired_slug:"srd-5e_item_adamantine-scale-mail",retired_name:"Adamantine Scale Mail",retired_path:"SRD 5e/Magic Items/Adamantine Scale Mail.md",kept_slug:"srd-5e_item_adamantine-armor-scale-mail",kept_name:"Adamantine Armor (Scale-Mail)"},{retired_slug:"srd-5e_item_adamantine-splint-armor",retired_name:"Adamantine Splint Armor",retired_path:"SRD 5e/Magic Items/Adamantine Splint Armor.md",kept_slug:"srd-5e_item_adamantine-armor-splint",kept_name:"Adamantine Armor (Splint)"},{retired_slug:"srd-5e_item_greatsword-sword-of-life-stealing",retired_name:"Greatsword, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Greatsword, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-greatsword",kept_name:"Sword of Life Stealing (Greatsword)"},{retired_slug:"srd-5e_item_greatsword-sword-of-sharpness",retired_name:"Greatsword, Sword of Sharpness",retired_path:"SRD 5e/Magic Items/Greatsword, Sword of Sharpness.md",kept_slug:"srd-5e_item_sword-of-sharpness-greatsword",kept_name:"Sword of Sharpness (Greatsword)"},{retired_slug:"srd-5e_item_greatsword-sword-of-wounding",retired_name:"Greatsword, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Greatsword, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-greatsword",kept_name:"Sword of Wounding (Greatsword)"},{retired_slug:"srd-5e_item_hand-crossbow-1",retired_name:"Hand Crossbow +1",retired_path:"SRD 5e/Magic Items/Hand Crossbow +1.md",kept_slug:"srd-5e_item_crossbow-hand-1",kept_name:"Crossbow-Hand (+1)"},{retired_slug:"srd-5e_item_hand-crossbow-2",retired_name:"Hand Crossbow +2",retired_path:"SRD 5e/Magic Items/Hand Crossbow +2.md",kept_slug:"srd-5e_item_crossbow-hand-2",kept_name:"Crossbow-Hand (+2)"},{retired_slug:"srd-5e_item_hand-crossbow-3",retired_name:"Hand Crossbow +3",retired_path:"SRD 5e/Magic Items/Hand Crossbow +3.md",kept_slug:"srd-5e_item_crossbow-hand-3",kept_name:"Crossbow-Hand (+3)"},{retired_slug:"srd-5e_item_heavy-crossbow-1",retired_name:"Heavy Crossbow +1",retired_path:"SRD 5e/Magic Items/Heavy Crossbow +1.md",kept_slug:"srd-5e_item_crossbow-heavy-1",kept_name:"Crossbow-Heavy (+1)"},{retired_slug:"srd-5e_item_heavy-crossbow-2",retired_name:"Heavy Crossbow +2",retired_path:"SRD 5e/Magic Items/Heavy Crossbow +2.md",kept_slug:"srd-5e_item_crossbow-heavy-2",kept_name:"Crossbow-Heavy (+2)"},{retired_slug:"srd-5e_item_heavy-crossbow-3",retired_name:"Heavy Crossbow +3",retired_path:"SRD 5e/Magic Items/Heavy Crossbow +3.md",kept_slug:"srd-5e_item_crossbow-heavy-3",kept_name:"Crossbow-Heavy (+3)"},{retired_slug:"srd-5e_item_light-crossbow-1",retired_name:"Light Crossbow +1",retired_path:"SRD 5e/Magic Items/Light Crossbow +1.md",kept_slug:"srd-5e_item_crossbow-light-1",kept_name:"Crossbow-Light (+1)"},{retired_slug:"srd-5e_item_light-crossbow-2",retired_name:"Light Crossbow +2",retired_path:"SRD 5e/Magic Items/Light Crossbow +2.md",kept_slug:"srd-5e_item_crossbow-light-2",kept_name:"Crossbow-Light (+2)"},{retired_slug:"srd-5e_item_light-crossbow-3",retired_name:"Light Crossbow +3",retired_path:"SRD 5e/Magic Items/Light Crossbow +3.md",kept_slug:"srd-5e_item_crossbow-light-3",kept_name:"Crossbow-Light (+3)"},{retired_slug:"srd-5e_item_longsword-sword-of-life-stealing",retired_name:"Longsword, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Longsword, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-longsword",kept_name:"Sword of Life Stealing (Longsword)"},{retired_slug:"srd-5e_item_longsword-sword-of-sharpness",retired_name:"Longsword, Sword of Sharpness",retired_path:"SRD 5e/Magic Items/Longsword, Sword of Sharpness.md",kept_slug:"srd-5e_item_sword-of-sharpness-longsword",kept_name:"Sword of Sharpness (Longsword)"},{retired_slug:"srd-5e_item_longsword-sword-of-wounding",retired_name:"Longsword, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Longsword, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-longsword",kept_name:"Sword of Wounding (Longsword)"},{retired_slug:"srd-5e_item_mithral-breastplate",retired_name:"Mithral Breastplate",retired_path:"SRD 5e/Magic Items/Mithral Breastplate.md",kept_slug:"srd-5e_item_mithral-armor-breastplate",kept_name:"Mithral Armor (Breastplate)"},{retired_slug:"srd-5e_item_mithral-chain-mail",retired_name:"Mithral Chain Mail",retired_path:"SRD 5e/Magic Items/Mithral Chain Mail.md",kept_slug:"srd-5e_item_mithral-armor-chain-mail",kept_name:"Mithral Armor (Chain-Mail)"},{retired_slug:"srd-5e_item_mithral-chain-shirt",retired_name:"Mithral Chain Shirt",retired_path:"SRD 5e/Magic Items/Mithral Chain Shirt.md",kept_slug:"srd-5e_item_mithral-armor-chain-shirt",kept_name:"Mithral Armor (Chain-Shirt)"},{retired_slug:"srd-5e_item_mithral-half-plate-armor",retired_name:"Mithral Half Plate Armor",retired_path:"SRD 5e/Magic Items/Mithral Half Plate Armor.md",kept_slug:"srd-5e_item_mithral-armor-half-plate",kept_name:"Mithral Armor (Half-Plate)"},{retired_slug:"srd-5e_item_mithral-plate-armor",retired_name:"Mithral Plate Armor",retired_path:"SRD 5e/Magic Items/Mithral Plate Armor.md",kept_slug:"srd-5e_item_mithral-armor-plate",kept_name:"Mithral Armor (Plate)"},{retired_slug:"srd-5e_item_mithral-ring-mail",retired_name:"Mithral Ring Mail",retired_path:"SRD 5e/Magic Items/Mithral Ring Mail.md",kept_slug:"srd-5e_item_mithral-armor-ring-mail",kept_name:"Mithral Armor (Ring-Mail)"},{retired_slug:"srd-5e_item_mithral-scale-mail",retired_name:"Mithral Scale Mail",retired_path:"SRD 5e/Magic Items/Mithral Scale Mail.md",kept_slug:"srd-5e_item_mithral-armor-scale-mail",kept_name:"Mithral Armor (Scale-Mail)"},{retired_slug:"srd-5e_item_mithral-splint-armor",retired_name:"Mithral Splint Armor",retired_path:"SRD 5e/Magic Items/Mithral Splint Armor.md",kept_slug:"srd-5e_item_mithral-armor-splint",kept_name:"Mithral Armor (Splint)"},{retired_slug:"srd-5e_item_rapier-sword-of-life-stealing",retired_name:"Rapier, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Rapier, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-rapier",kept_name:"Sword of Life Stealing (Rapier)"},{retired_slug:"srd-5e_item_rapier-sword-of-wounding",retired_name:"Rapier, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Rapier, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-rapier",kept_name:"Sword of Wounding (Rapier)"},{retired_slug:"srd-5e_item_scimitar-sword-of-sharpness",retired_name:"Scimitar, Sword of Sharpness",retired_path:"SRD 5e/Magic Items/Scimitar, Sword of Sharpness.md",kept_slug:"srd-5e_item_sword-of-sharpness-scimitar",kept_name:"Sword of Sharpness (Scimitar)"},{retired_slug:"srd-5e_item_shortsword-sword-of-life-stealing",retired_name:"Shortsword, Sword of Life Stealing",retired_path:"SRD 5e/Magic Items/Shortsword, Sword of Life Stealing.md",kept_slug:"srd-5e_item_sword-of-life-stealing-shortsword",kept_name:"Sword of Life Stealing (Shortsword)"},{retired_slug:"srd-5e_item_shortsword-sword-of-wounding",retired_name:"Shortsword, Sword of Wounding",retired_path:"SRD 5e/Magic Items/Shortsword, Sword of Wounding.md",kept_slug:"srd-5e_item_sword-of-wounding-shortsword",kept_name:"Sword of Wounding (Shortsword)"},{retired_slug:"srd-5e_item_vicious-battleaxe",retired_name:"Vicious Battleaxe",retired_path:"SRD 5e/Magic Items/Vicious Battleaxe.md",kept_slug:"srd-5e_item_vicious-weapon-battleaxe",kept_name:"Vicious Weapon (Battleaxe)"},{retired_slug:"srd-5e_item_vicious-blowgun",retired_name:"Vicious Blowgun",retired_path:"SRD 5e/Magic Items/Vicious Blowgun.md",kept_slug:"srd-5e_item_vicious-weapon-blowgun",kept_name:"Vicious Weapon (Blowgun)"},{retired_slug:"srd-5e_item_vicious-club",retired_name:"Vicious Club",retired_path:"SRD 5e/Magic Items/Vicious Club.md",kept_slug:"srd-5e_item_vicious-weapon-club",kept_name:"Vicious Weapon (Club)"},{retired_slug:"srd-5e_item_vicious-dagger",retired_name:"Vicious Dagger",retired_path:"SRD 5e/Magic Items/Vicious Dagger.md",kept_slug:"srd-5e_item_vicious-weapon-dagger",kept_name:"Vicious Weapon (Dagger)"},{retired_slug:"srd-5e_item_vicious-dart",retired_name:"Vicious Dart",retired_path:"SRD 5e/Magic Items/Vicious Dart.md",kept_slug:"srd-5e_item_vicious-weapon-dart",kept_name:"Vicious Weapon (Dart)"},{retired_slug:"srd-5e_item_vicious-flail",retired_name:"Vicious Flail",retired_path:"SRD 5e/Magic Items/Vicious Flail.md",kept_slug:"srd-5e_item_vicious-weapon-flail",kept_name:"Vicious Weapon (Flail)"},{retired_slug:"srd-5e_item_vicious-glaive",retired_name:"Vicious Glaive",retired_path:"SRD 5e/Magic Items/Vicious Glaive.md",kept_slug:"srd-5e_item_vicious-weapon-glaive",kept_name:"Vicious Weapon (Glaive)"},{retired_slug:"srd-5e_item_vicious-greataxe",retired_name:"Vicious Greataxe",retired_path:"SRD 5e/Magic Items/Vicious Greataxe.md",kept_slug:"srd-5e_item_vicious-weapon-greataxe",kept_name:"Vicious Weapon (Greataxe)"},{retired_slug:"srd-5e_item_vicious-greatclub",retired_name:"Vicious Greatclub",retired_path:"SRD 5e/Magic Items/Vicious Greatclub.md",kept_slug:"srd-5e_item_vicious-weapon-greatclub",kept_name:"Vicious Weapon (Greatclub)"},{retired_slug:"srd-5e_item_vicious-greatsword",retired_name:"Vicious Greatsword",retired_path:"SRD 5e/Magic Items/Vicious Greatsword.md",kept_slug:"srd-5e_item_vicious-weapon-greatsword",kept_name:"Vicious Weapon (Greatsword)"},{retired_slug:"srd-5e_item_vicious-halberd",retired_name:"Vicious Halberd",retired_path:"SRD 5e/Magic Items/Vicious Halberd.md",kept_slug:"srd-5e_item_vicious-weapon-halberd",kept_name:"Vicious Weapon (Halberd)"},{retired_slug:"srd-5e_item_vicious-hand-crossbow",retired_name:"Vicious Hand Crossbow",retired_path:"SRD 5e/Magic Items/Vicious Hand Crossbow.md",kept_slug:"srd-5e_item_vicious-weapon-crossbow-hand",kept_name:"Vicious Weapon (Crossbow-Hand)"},{retired_slug:"srd-5e_item_vicious-handaxe",retired_name:"Vicious Handaxe",retired_path:"SRD 5e/Magic Items/Vicious Handaxe.md",kept_slug:"srd-5e_item_vicious-weapon-handaxe",kept_name:"Vicious Weapon (Handaxe)"},{retired_slug:"srd-5e_item_vicious-heavy-crossbow",retired_name:"Vicious Heavy Crossbow",retired_path:"SRD 5e/Magic Items/Vicious Heavy Crossbow.md",kept_slug:"srd-5e_item_vicious-weapon-crossbow-heavy",kept_name:"Vicious Weapon (Crossbow-Heavy)"},{retired_slug:"srd-5e_item_vicious-javelin",retired_name:"Vicious Javelin",retired_path:"SRD 5e/Magic Items/Vicious Javelin.md",kept_slug:"srd-5e_item_vicious-weapon-javelin",kept_name:"Vicious Weapon (Javelin)"},{retired_slug:"srd-5e_item_vicious-lance",retired_name:"Vicious Lance",retired_path:"SRD 5e/Magic Items/Vicious Lance.md",kept_slug:"srd-5e_item_vicious-weapon-lance",kept_name:"Vicious Weapon (Lance)"},{retired_slug:"srd-5e_item_vicious-light-crossbow",retired_name:"Vicious Light Crossbow",retired_path:"SRD 5e/Magic Items/Vicious Light Crossbow.md",kept_slug:"srd-5e_item_vicious-weapon-crossbow-light",kept_name:"Vicious Weapon (Crossbow-Light)"},{retired_slug:"srd-5e_item_vicious-light-hammer",retired_name:"Vicious Light Hammer",retired_path:"SRD 5e/Magic Items/Vicious Light Hammer.md",kept_slug:"srd-5e_item_vicious-weapon-light-hammer",kept_name:"Vicious Weapon (Light-Hammer)"},{retired_slug:"srd-5e_item_vicious-longbow",retired_name:"Vicious Longbow",retired_path:"SRD 5e/Magic Items/Vicious Longbow.md",kept_slug:"srd-5e_item_vicious-weapon-longbow",kept_name:"Vicious Weapon (Longbow)"},{retired_slug:"srd-5e_item_vicious-longsword",retired_name:"Vicious Longsword",retired_path:"SRD 5e/Magic Items/Vicious Longsword.md",kept_slug:"srd-5e_item_vicious-weapon-longsword",kept_name:"Vicious Weapon (Longsword)"},{retired_slug:"srd-5e_item_vicious-mace",retired_name:"Vicious Mace",retired_path:"SRD 5e/Magic Items/Vicious Mace.md",kept_slug:"srd-5e_item_vicious-weapon-mace",kept_name:"Vicious Weapon (Mace)"},{retired_slug:"srd-5e_item_vicious-maul",retired_name:"Vicious Maul",retired_path:"SRD 5e/Magic Items/Vicious Maul.md",kept_slug:"srd-5e_item_vicious-weapon-maul",kept_name:"Vicious Weapon (Maul)"},{retired_slug:"srd-5e_item_vicious-morningstar",retired_name:"Vicious Morningstar",retired_path:"SRD 5e/Magic Items/Vicious Morningstar.md",kept_slug:"srd-5e_item_vicious-weapon-morningstar",kept_name:"Vicious Weapon (Morningstar)"},{retired_slug:"srd-5e_item_vicious-net",retired_name:"Vicious Net",retired_path:"SRD 5e/Magic Items/Vicious Net.md",kept_slug:"srd-5e_item_vicious-weapon-net",kept_name:"Vicious Weapon (Net)"},{retired_slug:"srd-5e_item_vicious-pike",retired_name:"Vicious Pike",retired_path:"SRD 5e/Magic Items/Vicious Pike.md",kept_slug:"srd-5e_item_vicious-weapon-pike",kept_name:"Vicious Weapon (Pike)"},{retired_slug:"srd-5e_item_vicious-quarterstaff",retired_name:"Vicious Quarterstaff",retired_path:"SRD 5e/Magic Items/Vicious Quarterstaff.md",kept_slug:"srd-5e_item_vicious-weapon-quarterstaff",kept_name:"Vicious Weapon (Quarterstaff)"},{retired_slug:"srd-5e_item_vicious-rapier",retired_name:"Vicious Rapier",retired_path:"SRD 5e/Magic Items/Vicious Rapier.md",kept_slug:"srd-5e_item_vicious-weapon-rapier",kept_name:"Vicious Weapon (Rapier)"},{retired_slug:"srd-5e_item_vicious-scimitar",retired_name:"Vicious Scimitar",retired_path:"SRD 5e/Magic Items/Vicious Scimitar.md",kept_slug:"srd-5e_item_vicious-weapon-scimitar",kept_name:"Vicious Weapon (Scimitar)"},{retired_slug:"srd-5e_item_vicious-shortbow",retired_name:"Vicious Shortbow",retired_path:"SRD 5e/Magic Items/Vicious Shortbow.md",kept_slug:"srd-5e_item_vicious-weapon-shortbow",kept_name:"Vicious Weapon (Shortbow)"},{retired_slug:"srd-5e_item_vicious-shortsword",retired_name:"Vicious Shortsword",retired_path:"SRD 5e/Magic Items/Vicious Shortsword.md",kept_slug:"srd-5e_item_vicious-weapon-shortsword",kept_name:"Vicious Weapon (Shortsword)"},{retired_slug:"srd-5e_item_vicious-sickle",retired_name:"Vicious Sickle",retired_path:"SRD 5e/Magic Items/Vicious Sickle.md",kept_slug:"srd-5e_item_vicious-weapon-sickle",kept_name:"Vicious Weapon (Sickle)"},{retired_slug:"srd-5e_item_vicious-sling",retired_name:"Vicious Sling",retired_path:"SRD 5e/Magic Items/Vicious Sling.md",kept_slug:"srd-5e_item_vicious-weapon-sling",kept_name:"Vicious Weapon (Sling)"},{retired_slug:"srd-5e_item_vicious-spear",retired_name:"Vicious Spear",retired_path:"SRD 5e/Magic Items/Vicious Spear.md",kept_slug:"srd-5e_item_vicious-weapon-spear",kept_name:"Vicious Weapon (Spear)"},{retired_slug:"srd-5e_item_vicious-trident",retired_name:"Vicious Trident",retired_path:"SRD 5e/Magic Items/Vicious Trident.md",kept_slug:"srd-5e_item_vicious-weapon-trident",kept_name:"Vicious Weapon (Trident)"},{retired_slug:"srd-5e_item_vicious-war-pick",retired_name:"Vicious War Pick",retired_path:"SRD 5e/Magic Items/Vicious War Pick.md",kept_slug:"srd-5e_item_vicious-weapon-war-pick",kept_name:"Vicious Weapon (War-Pick)"},{retired_slug:"srd-5e_item_vicious-warhammer",retired_name:"Vicious Warhammer",retired_path:"SRD 5e/Magic Items/Vicious Warhammer.md",kept_slug:"srd-5e_item_vicious-weapon-warhammer",kept_name:"Vicious Weapon (Warhammer)"},{retired_slug:"srd-5e_item_vicious-whip",retired_name:"Vicious Whip",retired_path:"SRD 5e/Magic Items/Vicious Whip.md",kept_slug:"srd-5e_item_vicious-weapon-whip",kept_name:"Vicious Weapon (Whip)"}];var retired_items_2024_default=[{retired_slug:"srd-2024_item_adamantine-breastplate",retired_name:"Adamantine Breastplate",retired_path:"SRD 2024/Magic Items/Adamantine Breastplate.md",kept_slug:"srd-2024_item_adamantine-armor-breastplate",kept_name:"Adamantine Armor (Breastplate)"},{retired_slug:"srd-2024_item_adamantine-chain-mail",retired_name:"Adamantine Chain Mail",retired_path:"SRD 2024/Magic Items/Adamantine Chain Mail.md",kept_slug:"srd-2024_item_adamantine-armor-chain-mail",kept_name:"Adamantine Armor (Chain Mail)"},{retired_slug:"srd-2024_item_adamantine-chain-shirt",retired_name:"Adamantine Chain Shirt",retired_path:"SRD 2024/Magic Items/Adamantine Chain Shirt.md",kept_slug:"srd-2024_item_adamantine-armor-chain-shirt",kept_name:"Adamantine Armor (Chain Shirt)"},{retired_slug:"srd-2024_item_adamantine-half-plate-armor",retired_name:"Adamantine Half Plate Armor",retired_path:"SRD 2024/Magic Items/Adamantine Half Plate Armor.md",kept_slug:"srd-2024_item_adamantine-armor-half-plate",kept_name:"Adamantine Armor (Half Plate)"},{retired_slug:"srd-2024_item_adamantine-plate-armor",retired_name:"Adamantine Plate Armor",retired_path:"SRD 2024/Magic Items/Adamantine Plate Armor.md",kept_slug:"srd-2024_item_adamantine-armor-plate",kept_name:"Adamantine Armor (Plate)"},{retired_slug:"srd-2024_item_adamantine-ring-mail",retired_name:"Adamantine Ring Mail",retired_path:"SRD 2024/Magic Items/Adamantine Ring Mail.md",kept_slug:"srd-2024_item_adamantine-armor-ring-mail",kept_name:"Adamantine Armor (Ring Mail)"},{retired_slug:"srd-2024_item_adamantine-scale-mail",retired_name:"Adamantine Scale Mail",retired_path:"SRD 2024/Magic Items/Adamantine Scale Mail.md",kept_slug:"srd-2024_item_adamantine-armor-scale-mail",kept_name:"Adamantine Armor (Scale Mail)"},{retired_slug:"srd-2024_item_adamantine-splint-armor",retired_name:"Adamantine Splint Armor",retired_path:"SRD 2024/Magic Items/Adamantine Splint Armor.md",kept_slug:"srd-2024_item_adamantine-armor-splint",kept_name:"Adamantine Armor (Splint)"},{retired_slug:"srd-2024_item_dwarven-half-plate-armor",retired_name:"Dwarven Half Plate Armor",retired_path:"SRD 2024/Magic Items/Dwarven Half Plate Armor.md",kept_slug:"srd-2024_item_dwarven-half-plate",kept_name:"Dwarven Half Plate"},{retired_slug:"srd-2024_item_dwarven-plate-armor",retired_name:"Dwarven Plate Armor",retired_path:"SRD 2024/Magic Items/Dwarven Plate Armor.md",kept_slug:"srd-2024_item_dwarven-plate",kept_name:"Dwarven Plate"},{retired_slug:"srd-2024_item_half-plate-armor-plate-armor-of-etherealness",retired_name:"Half Plate Armor, Plate Armor of Etherealness (*)",retired_path:"SRD 2024/Magic Items/Half Plate Armor, Plate Armor of Etherealness (_).md",kept_slug:"srd-2024_item_half-plate-armor-of-etherealness",kept_name:"Half Plate Armor of Etherealness"},{retired_slug:"srd-2024_item_mithral-breastplate",retired_name:"Mithral Breastplate",retired_path:"SRD 2024/Magic Items/Mithral Breastplate.md",kept_slug:"srd-2024_item_mithral-armor-breastplate",kept_name:"Mithral Armor (Breastplate)"},{retired_slug:"srd-2024_item_mithral-chain-mail",retired_name:"Mithral Chain Mail",retired_path:"SRD 2024/Magic Items/Mithral Chain Mail.md",kept_slug:"srd-2024_item_mithral-armor-chain-mail",kept_name:"Mithral Armor (Chain Mail)"},{retired_slug:"srd-2024_item_mithral-chain-shirt",retired_name:"Mithral Chain Shirt",retired_path:"SRD 2024/Magic Items/Mithral Chain Shirt.md",kept_slug:"srd-2024_item_mithral-armor-chain-shirt",kept_name:"Mithral Armor (Chain Shirt)"},{retired_slug:"srd-2024_item_mithral-half-plate-armor",retired_name:"Mithral Half Plate Armor",retired_path:"SRD 2024/Magic Items/Mithral Half Plate Armor.md",kept_slug:"srd-2024_item_mithral-armor-half-plate",kept_name:"Mithral Armor (Half Plate)"},{retired_slug:"srd-2024_item_mithral-plate-armor",retired_name:"Mithral Plate Armor",retired_path:"SRD 2024/Magic Items/Mithral Plate Armor.md",kept_slug:"srd-2024_item_mithral-armor-plate",kept_name:"Mithral Armor (Plate)"},{retired_slug:"srd-2024_item_mithral-ring-mail",retired_name:"Mithral Ring Mail",retired_path:"SRD 2024/Magic Items/Mithral Ring Mail.md",kept_slug:"srd-2024_item_mithral-armor-ring-mail",kept_name:"Mithral Armor (Ring Mail)"},{retired_slug:"srd-2024_item_mithral-scale-mail",retired_name:"Mithral Scale Mail",retired_path:"SRD 2024/Magic Items/Mithral Scale Mail.md",kept_slug:"srd-2024_item_mithral-armor-scale-mail",kept_name:"Mithral Armor (Scale Mail)"},{retired_slug:"srd-2024_item_mithral-splint-armor",retired_name:"Mithral Splint Armor",retired_path:"SRD 2024/Magic Items/Mithral Splint Armor.md",kept_slug:"srd-2024_item_mithral-armor-splint",kept_name:"Mithral Armor (Splint)"},{retired_slug:"srd-2024_item_plate-armor-plate-armor-of-etherealness",retired_name:"Plate Armor, Plate Armor of Etherealness (*)",retired_path:"SRD 2024/Magic Items/Plate Armor, Plate Armor of Etherealness (_).md",kept_slug:"srd-2024_item_plate-armor-of-etherealness",kept_name:"Plate Armor of Etherealness"}];function unwrapWikilink(input){const m=/^\[\[([^\]]+)\]\]$/.exec(input.trim());if(!m)return null;const inner=m[1];const pipe=inner.indexOf("|");return pipe===-1?inner:inner.slice(0,pipe)}var FOLDER_TO_TYPE={Weapons:"weapon",Armor:"armor","Magic Items":"item"};function vaultPathToSlug(target){const segments=target.split("/").map(s=>s.trim()).filter(s=>s.length>0);if(segments.length===0)return"";if(segments.length===1){return slugify(segments[0])}const compendiumName=segments[0];const typeFolder=segments[segments.length-2];const basename=segments[segments.length-1];const prefix=slugify(compendiumName);const nameSlug=slugify(basename);if(!prefix||!nameSlug)return nameSlug;const type=FOLDER_TO_TYPE[typeFolder];return type?`${prefix}_${type}_${nameSlug}`:`${prefix}_${nameSlug}`}function resolveBaseItem(baseItem,registry){var _a,_b;if(typeof baseItem!=="string"||baseItem.length===0)return null;const target=(_a=unwrapWikilink(baseItem))!=null?_a:baseItem.trim();if(target.length===0)return null;if(!target.includes("/")){const direct=registry.getBySlug(target);if(direct)return direct}const slug=vaultPathToSlug(target);if(!slug)return null;const found=registry.getBySlug(slug);if(found)return found;const kept=keptSlugForLink(target);return kept===void 0?null:(_b=registry.getBySlug(kept))!=null?_b:null}function resolveBaseItemOfType(baseItem,entityType,registry){const found=resolveBaseItem(baseItem,registry);return found&&found.entityType===entityType?found:null}var RETIRED_ITEMS=Object.freeze([...retired_items_2014_default,...retired_items_2024_default]);var KEPT_BY_RETIRED=new Map(RETIRED_ITEMS.map(r=>[r.retired_slug,r.kept_slug]));function keptSlugFor(slug){return KEPT_BY_RETIRED.get(slug)}function keptSlugForLink(target){const t=target.trim();if(t.length===0)return void 0;return keptSlugFor(t.includes("/")?vaultPathToSlug(t):t)}export{RETIRED_ITEMS,keptSlugFor,keptSlugForLink,vaultPathToSlug,resolveBaseItem,resolveBaseItemOfType};
@@ -0,0 +1 @@
1
+ import{resolveSpellcasting}from"./chunk-NI364WV7.js";import{heldPicks}from"./chunk-DY6FVAGA.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{isValidMaxFormula}from"./chunk-EAARMPCW.js";function resourceLevelFor(source,resolved){var _a,_b,_c,_d;if(source.kind==="class"){return(_b=(_a=resolved.classes.find(c=>{var _a2;return((_a2=c.entity)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_a.level)!=null?_b:resolved.totalLevel}if(source.kind==="subclass"){return(_d=(_c=resolved.classes.find(c=>{var _a2;return((_a2=c.subclass)==null?void 0:_a2.slug)===source.slug}))==null?void 0:_c.level)!=null?_d:resolved.totalLevel}return resolved.totalLevel}function resolveRecovery(entry){var _a;const kind=(_a=entry.restores)!=null?_a:"uses";const restTriggered=(entry.reset==="short-rest"||entry.reset==="long-rest")&&!entry.action;const flavour=kind==="spell-slots"?"manual":restTriggered?"rest":"manual";return{entry,kind,flavour}}function toResolvedResource(r,fallbackName,owner){var _a,_b,_c;return{id:r.id,name:(_a=r.name)!=null?_a:fallbackName,reset:r.reset,maxFormula:r.max_formula,...r.die?{die:r.die}:{},...r.scales_at?{scalesAt:r.scales_at}:{},...((_b=r.recovery)==null?void 0:_b.length)?{recovery:r.recovery.map(resolveRecovery)}:{},...r.rendering_hint?{renderingHint:r.rendering_hint}:{},...r.surface?{surface:r.surface}:{},...((_c=r.equivalent_ids)==null?void 0:_c.length)?{equivalentIds:r.equivalent_ids}:{},owner}}function resolveFeatureResources(features){var _a,_b;const out=new Map;for(const rf of features){for(const r of(_a=rf.feature.resources)!=null?_a:[]){if(out.has(r.id))continue;const owner={kind:"feature",featureId:(_b=rf.feature.id)!=null?_b:rf.feature.name,featureName:rf.feature.name,source:rf.source};out.set(r.id,toResolvedResource(r,rf.feature.name,owner))}}return out}function pickResourceId(entry){return entry.param!=null?entry.key:entry.slug}function resolveResourceIndex(resolved){var _a,_b,_c,_d;const out=new Map(resolveFeatureResources((_a=resolved.features)!=null?_a:[]));for(const pool of(_b=resolved.pools)!=null?_b:[]){const rc=resolved.classes[pool.classIndex];const classSlug=(_c=rc==null?void 0:rc.entity)==null?void 0:_c.slug;if(!classSlug)continue;for(const entry of[...heldPicks(pool),...(_d=pool.grants)!=null?_d:[]]){if(entry.itemBound===true)continue;const uses=entry.entity.uses;const id=pickResourceId(entry);if(!uses||out.has(id))continue;const maxFormula=String(uses.max);if(!isValidMaxFormula(maxFormula)){warnOnce(`pool-uses:${entry.slug}`,`optional feature "${entry.slug}" has a prose uses.max (${JSON.stringify(uses.max)}); no tracker`);continue}const pres=entry.entity;out.set(id,{id,name:entry.entity.name,reset:uses.recharge,maxFormula,...pres.rendering_hint?{renderingHint:pres.rendering_hint}:{},...pres.surface?{surface:pres.surface}:{},owner:{kind:"pool",poolId:pool.id,poolLabel:pool.label,source:{kind:"class",slug:classSlug,level:pool.anchorLevel}}})}}return out}function poolSaveDC(resolved,derived,pool){var _a,_b;const rc=resolved.classes[pool.classIndex];const ability=(_b=(_a=rc==null?void 0:rc.subclass)==null?void 0:_a.spellcasting)==null?void 0:_b.ability;if(!rc||!ability)return null;if(resolveSpellcasting(rc)!==null)return null;return 8+derived.proficiencyBonus+derived.mods[ability]}export{resourceLevelFor,resolveRecovery,resolveFeatureResources,pickResourceId,resolveResourceIndex,poolSaveDC};
@@ -0,0 +1 @@
1
+ import{heldPicks,parsePickKey,poolAnchorLevel}from"./chunk-DY6FVAGA.js";import{featProgressionCategory}from"./chunk-3QQOATV3.js";import{warnOnce}from"./chunk-DZITM5AG.js";import{bucketOf}from"./chunk-QMEKQTUT.js";import{bareEntitySlug,twinKey,wikilinkTailSlug}from"./chunk-63YJPWTM.js";var OPTIONAL_FEATURE_TYPE_CODE={"MV:B":"maneuver",MV:"maneuver",EI:"invocation",MM:"metamagic","FS:F":"fighting_style"};function spellFilter(choose,edition){const where={edition};for(const part of choose.split("|")){const[rawKey,rawValue=""]=part.split("=");const key=rawKey.trim().toLowerCase();const value=rawValue.trim();if(key==="level"){const n=Number(value.split(";")[0]);if(!Number.isInteger(n))return null;where.level=n}else if(key==="class")where.list=value.toLowerCase();else if(key==="components & miscellaneous"&&/ritual/i.test(value))where.ritual=true}return where}function isTargetChoice(ch){return ch.kind==="select-entity"&&ch.target===true}var PACT_WEAPON_CHOICE_ID="pact-weapon";function pactWeaponPick(sites){for(const site of sites){for(const ch of site.choices){if(ch.kind!=="select-entity"||ch.id!==PACT_WEAPON_CHOICE_ID)continue;const v=site.read(ch.id);const first=Array.isArray(v)?v.find(x=>typeof x==="string"&&x.trim()!==""):v;if(typeof first!=="string"||!first.trim())continue;return first.trim().replace(/^\[\[/,"").replace(/\]\]$/,"").split("|")[0].trim()}}return void 0}function classPactWeaponPick(character,classes){var _a,_b,_c,_d,_e,_f,_g;const inBlock=(choices,block)=>{for(const ch of choices!=null?choices:[]){if(ch.kind==="select-inline"){const sel=block[ch.id];const branch=typeof sel==="string"?ch.options.find(o=>o.value===sel):void 0;const hit=inBlock(branch==null?void 0:branch.choices,block);if(hit)return hit}else if(ch.kind==="select-entity"&&ch.id===PACT_WEAPON_CHOICE_ID){const hit=pactWeaponPick([{choices:[ch],read:id=>block[id]}]);if(hit)return hit}}return void 0};for(let i=0;i<classes.length;i++){const entity=(_a=classes[i])==null?void 0:_a.entity;const entry=character.class[i];if(!entity||!entry)continue;for(const[lvl,raw]of Object.entries((_b=entry.choices)!=null?_b:{})){const block=raw!=null?raw:{};const features=[...(_d=((_c=entity.features_by_level)!=null?_c:{})[Number(lvl)])!=null?_d:[],...(_g=((_f=(_e=classes[i].subclass)==null?void 0:_e.features_by_level)!=null?_f:{})[Number(lvl)])!=null?_g:[]];for(const f of features){const hit=inBlock(f.choices,block);if(hit)return hit}}}return void 0}function progressionCount(p){var _a;if(Array.isArray(p))return 0;return(_a=p["*"])!=null?_a:Math.max(0,...Object.values(p))}function spellChoices(entity,used){var _a,_b;const out=[];for(const block of(_a=entity.additional_spells)!=null?_a:[]){for(const bucket of["known","prepared"]){const byLevel=block[bucket];if(!byLevel||typeof byLevel!=="object")continue;for(const rows of Object.values(byLevel)){for(const row of Array.isArray(rows)?rows:[]){const r=row;if(typeof r.choose!=="string")continue;const where=spellFilter(r.choose,entity.edition);if(!where)continue;const base=where.ritual?"rituals":where.level===0?"cantrips":`spells-${(_b=where.level)!=null?_b:"any"}`;const label=where.ritual?"Rituals":where.level===0?"Cantrips":`Level ${where.level} spells`;let id=base;for(let i=2;used.has(id);i++)id=`${base}-${i}`;used.add(id);out.push({kind:"select-entity",id,label,count:typeof r.count==="number"?r.count:1,entity_type:"spell",where})}}}}return out}function memberChoices(entity){var _a,_b,_c,_d,_e,_f;if(!entity)return[];if((_a=entity.choices)==null?void 0:_a.length)return entity.choices;const out=[];const used=new Set;for(const fp of(_b=entity.feat_progression)!=null?_b:[]){const category=featProgressionCategory(fp.category);const count=progressionCount(fp.progression);if(!category||count<1)continue;const id=used.has("feat")?`feat-${used.size}`:"feat";used.add(id);out.push({kind:"select-entity",id,label:fp.name,count,entity_type:"feat",where:{category,edition:entity.edition}})}for(const op of(_c=entity.optionalfeature_progression)!=null?_c:[]){const codes=(_e=(_d=op.feature_type)!=null?_d:op.featureType)!=null?_e:[];const featureType=codes.map(c=>OPTIONAL_FEATURE_TYPE_CODE[c]).find(t=>!!t);const count=progressionCount(op.progression);if(!featureType||count<1){if(!featureType)warnOnce(`member-of-code:${entity.slug}`,`Archivist: "${entity.slug}" asks for optional features of type ${codes.join(", ")}, which this engine does not map; no pick is offered`);continue}const id=op.name.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||"option";used.add(id);out.push({kind:"select-entity",id,label:op.name,count,entity_type:"optional-feature",where:{feature_type:featureType,edition:entity.edition}})}out.push(...spellChoices(entity,used));for(const pre of(_f=entity.prerequisites)!=null?_f:[]){if(pre.kind!=="spell-choose")continue;const where=spellFilter(pre.choose,entity.edition);if(!where||used.has("cantrip"))continue;used.add("cantrip");out.push({kind:"select-entity",id:"cantrip",label:where.level===0?"Cantrip":"Spell",count:1,entity_type:"spell",where,target:true})}return out}function memberSpellTargets(member,read){var _a;const refs=[];const open=[];for(const ch of memberChoices(member)){if(ch.kind!=="select-entity"||!isTargetChoice(ch)||ch.entity_type!=="spell")continue;const v=read(ch.id);const picked=(Array.isArray(v)?v:[v]).filter(x=>typeof x==="string"&&x.trim()!=="");if(picked.length)refs.push(...picked);else if(ch.where)open.push(ch.where)}for(const pre of(_a=member.prerequisites)!=null?_a:[])if(pre.kind==="spell-known")refs.push(pre.spell);return refs.length||open.length?{refs,open}:null}function spellMatchesFilter(d,where){var _a,_b;if(where.list&&!((_a=d.classes)!=null?_a:[]).includes(where.list))return false;if(where.level!==void 0&&((_b=d.level)!=null?_b:0)!==where.level)return false;if(where.edition&&d.edition!==where.edition)return false;if(where.ritual&&d.ritual!==true)return false;return true}function spellsReached(targets,spells){if(!targets)return[];const hit=new Set;for(const ref of targets.refs){const full=stripRef(ref);const exact=spells.filter(s=>s.slug===full);const bare=wikilinkTailSlug(ref);for(const s of exact.length?exact:spells.filter(s2=>bareEntitySlug(s2.slug)===bare))hit.add(s.slug)}for(const where of targets.open){const legal=new Set(spells.filter(s=>{var _a;return spellMatchesFilter(s.entity,where)&&!!((_a=s.entity.damage_roll)==null?void 0:_a.trim())}).map(s=>s.slug));if(legal.size===1)hit.add([...legal][0])}return[...new Set(spells.map(s=>s.slug))].filter(slug=>hit.has(slug))}function siteOf(classIndex,level,poolId,pickKey,member,memberSlug,block){const choices=memberChoices(member);if(!choices.length)return null;const prefix=`${poolId}:${pickKey}:`;return{classIndex,level,poolId,pickKey,member,memberSlug,choices,prefix,block,read:id=>block[`${prefix}${id}`]}}function poolMemberSites(classes,registry){const out=[];let byBare=null;let all=null;const lookup=(s,ownerPrefix)=>{all!=null?all:all=bucketOf(registry,"optional-feature");const bare=bareEntitySlug(s);const twin=twinKey(s);const owned=all.find(e=>twinKey(e.slug)===twin&&e.slug.split("_")[0]===ownerPrefix);if(owned)return owned;const direct=registry.getByTypeAndSlug("optional-feature",s);if(direct)return direct;byBare!=null?byBare:byBare=new Map(all.map(e=>[bareEntitySlug(e.slug),e]));return byBare.get(bare)};classes.forEach((rc,classIndex)=>{var _a,_b,_c,_d,_e;if(!rc.entity)return;const seen=new Set;for(const pool of[...(_a=rc.entity.selection_pools)!=null?_a:[],...(_c=(_b=rc.subclass)==null?void 0:_b.selection_pools)!=null?_c:[]]){if(seen.has(pool.id))continue;seen.add(pool.id);const{anchorLevel}=poolAnchorLevel(rc.entity,pool);const block=(_e=(_d=rc.choices)==null?void 0:_d[anchorLevel])!=null?_e:{};const raw=block[pool.id];const picks=Array.isArray(raw)?raw:typeof raw==="string"?[raw]:[];for(const s of picks){if(typeof s!=="string")continue;const{slugPart,param}=parsePickKey(s);const reg=lookup(slugPart,rc.entity.slug.split("_")[0]);if(!reg)continue;const member=reg.data;const key=member.repeatable===true||param!==null?s:reg.slug;const site=siteOf(classIndex,anchorLevel,pool.id,key,member,reg.slug,block);if(site)out.push(site)}}});return out}function poolMemberSitesOf(resolved){var _a,_b,_c,_d,_e;const out=[];for(const pool of(_a=resolved.pools)!=null?_a:[]){const block=(_e=(_d=(_c=(_b=resolved.classes)==null?void 0:_b[pool.classIndex])==null?void 0:_c.choices)==null?void 0:_d[pool.anchorLevel])!=null?_e:{};for(const e of heldPicks(pool)){const site=siteOf(pool.classIndex,pool.anchorLevel,pool.id,e.key,e.entity,e.slug,block);if(site)out.push(site)}}return out}var stripRef=ref=>ref.replace(/^\[\[/,"").replace(/\]\]$/,"");function featPickSites(classEntries,memberSites,classSlugOf){const out=[];(classEntries!=null?classEntries:[]).forEach((c,classIndex)=>{var _a;for(const[lvl,choiceBlock]of Object.entries((_a=c.choices)!=null?_a:{})){const block=choiceBlock;const feat=block==null?void 0:block.feat;if(!block||typeof feat!=="string")continue;const slug=stripRef(feat);if(!slug)continue;const level=/^\d+$/.test(lvl)?Number(lvl):null;const cls=classSlugOf(classIndex);out.push({slug,classIndex,level,via:cls&&level!==null?{kind:"class",slug:cls,level}:null,read:id=>block[`feat:${id}`]})}});for(const site of memberSites){for(const ch of site.choices){if(ch.kind!=="select-entity"||ch.entity_type!=="feat"||ch.target===true)continue;const v=site.read(ch.id);for(const ref of Array.isArray(v)?v:typeof v==="string"?[v]:[]){if(typeof ref!=="string")continue;const slug=stripRef(ref);if(!slug)continue;const cls=classSlugOf(site.classIndex);out.push({slug,classIndex:site.classIndex,level:site.level,via:cls?{kind:"pool",slug:site.memberSlug,name:site.member.name,classSlug:cls,level:site.level}:null,read:id=>site.block[`${site.prefix}feat:${id}`]})}}}return out}function raceFeatSites(race,originChoices){var _a;if(!race)return[];const oc=originChoices!=null?originChoices:{};const out=[];for(const list of[race.choices,...((_a=race.traits)!=null?_a:[]).map(t=>t==null?void 0:t.choices)]){for(const ch of Array.isArray(list)?list:[]){if((ch==null?void 0:ch.kind)!=="select-entity"||ch.entity_type!=="feat")continue;const v=oc[`race:${ch.id}`];for(const ref of Array.isArray(v)?v:typeof v==="string"?[v]:[]){const slug=typeof ref==="string"?stripRef(ref):"";if(slug)out.push({slug,via:{kind:"race",slug:race.slug},read:id=>oc[`race:feat:${id}`]})}}}return out}function featOfSite(site,feats){var _a;return(_a=feats.find(f=>f.slug===site.slug))!=null?_a:feats.find(f=>bareEntitySlug(f.slug)===bareEntitySlug(site.slug))}function nestedPickKeysToPrune(block,key,next){const prev=block==null?void 0:block[key];if(!block||!Array.isArray(prev))return[];const keep=new Set(next);const gone=prev.filter(k=>typeof k==="string"&&!keep.has(k));if(!gone.length)return[];return Object.keys(block).filter(k=>gone.some(g=>k.startsWith(`${key}:${g}:`)))}export{isTargetChoice,PACT_WEAPON_CHOICE_ID,pactWeaponPick,classPactWeaponPick,memberChoices,memberSpellTargets,spellsReached,poolMemberSites,poolMemberSitesOf,featPickSites,raceFeatSites,featOfSite,nestedPickKeysToPrune};
@@ -0,0 +1 @@
1
+ import{featureObjectSchema}from"./chunk-V6NQ547U.js";import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var str=z.string();var num=z.number();var bool=z.boolean();var strArr=z.array(z.string());var damageQualifierSchema=z.object({get types(){return z.array(z.union([str,damageQualifierSchema])).optional()},note:str.optional(),pre_note:str.optional(),cond:bool.optional(),special:str.optional()});var qualifierList=z.array(z.union([str,damageQualifierSchema])).optional();var speedValue=z.union([num,z.object({number:num,condition:str.optional()})]);var monsterSpeedSchema=z.object({walk:speedValue.optional(),fly:speedValue.optional(),swim:speedValue.optional(),climb:speedValue.optional(),burrow:speedValue.optional(),hover:bool.optional(),can_hover:bool.optional(),alternate:z.record(str,z.array(z.object({number:num,condition:str.optional()}))).optional(),choose:z.object({from:strArr,amount:num,note:str.optional()}).optional()});var monsterTypeSchema=z.object({type:z.union([str,z.object({choose:strArr})]),tags:z.array(z.union([str,z.object({tag:str,prefix:str,prefix_hidden:bool.optional()})])).optional(),sidekick_type:str.optional(),sidekick_tags:strArr.optional(),swarm_size:str.optional(),sidekick_hidden:bool.optional()});var monsterCRSchema=z.object({cr:str,lair:str.optional(),coven:str.optional(),xp:num.optional(),xp_lair:num.optional()});var monsterACSchema=z.object({ac:num.optional(),from:strArr.optional(),condition:str.optional(),braces:bool.optional(),special:str.optional()});var monsterHPSchema=z.object({average:num.optional(),formula:str.optional(),special:str.optional()});var alignmentEntrySchema=z.object({alignment:strArr.optional(),chance:num.optional(),note:str.optional(),special:str.optional()});var spellEntry=z.union([str,z.object({entry:str,hidden:bool.optional()})]);var spellList=z.array(spellEntry);var spellLevel=z.object({slots:num.optional(),lower:num.optional(),spells:strArr});var monsterSpellcastingSchema=z.object({name:str.optional(),type:str.optional(),headerEntries:strArr.optional(),footerEntries:strArr.optional(),ability:str.optional(),displayAs:str.optional(),hidden:strArr.optional(),spells:z.record(str,spellLevel).optional(),will:spellList.optional(),ritual:spellList.optional(),daily:z.record(str,spellList).optional(),rest:z.record(str,spellList).optional(),restLong:z.record(str,spellList).optional(),recharge:z.record(str,spellList).optional(),legendary:z.record(str,spellList).optional(),charges:z.record(str,spellList).optional(),chargesItem:str.optional()});var initiativeSchema=z.union([num,z.object({proficiency:num.optional(),advantage_mode:str.optional()})]);var gearEntrySchema=z.union([str,z.object({item:str,quantity:num.optional(),displayName:str.optional()})]);var featureArr=z.array(featureObjectSchema).optional();var monsterSchema=z.object({name:str.min(1),size:z.union([str,strArr]).optional(),size_note:str.optional(),type:z.union([str,monsterTypeSchema]).optional(),subtype:str.optional(),alignment:z.union([str,z.array(z.union([str,alignmentEntrySchema]))]).optional(),alignment_prefix:str.optional(),cr:z.union([str,monsterCRSchema]).optional(),pb_note:str.optional(),ac:z.array(monsterACSchema).optional(),hp:monsterHPSchema.optional(),speed:monsterSpeedSchema.optional(),abilities:z.object({str:num,dex:num,con:num,int:num,wis:num,cha:num}).optional(),saves:z.record(str,num).optional(),skills:z.record(str,num).optional(),skills_other:z.array(z.unknown()).optional(),senses:strArr.nullable().optional(),passive_perception:num.optional(),languages:strArr.nullable().optional(),damage_vulnerabilities:qualifierList,damage_resistances:qualifierList,damage_immunities:qualifierList,condition_immunities:qualifierList,traits:featureArr,actions:featureArr,bonus_actions:featureArr,reactions:featureArr,legendary_actions:featureArr,mythic:featureArr,mythic_header:strArr.optional(),legendary_action_uses:num.optional(),legendary_resistance:num.optional(),legendary_actions_lair_count:num.optional(),section_headers:z.array(z.object({section:str,header:strArr})).optional(),action_note:str.optional(),reaction_note:str.optional(),spellcasting:z.array(monsterSpellcastingSchema).optional(),legendary_group:z.object({name:str,source:str}).optional(),lair_actions:z.array(z.unknown()).optional(),regional_actions:z.array(z.unknown()).optional(),variant:z.array(z.unknown()).optional(),initiative:initiativeSchema.optional(),gear:z.array(gearEntrySchema).optional(),is_named_creature:bool.optional(),is_npc:bool.optional(),familiar:bool.optional(),short_name:z.union([str,bool]).optional(),level:num.optional(),dragon_age:str.optional(),dragon_casting_color:str.optional(),environment:strArr.optional(),treasure:strArr.optional(),attached_items:strArr.optional(),group:strArr.nullable().optional(),summoned_by_spell:str.optional(),summoned_by_spell_level:num.optional(),summoned_by_class:str.optional(),trait_tags:strArr.optional(),action_tags:strArr.optional(),sense_tags:strArr.optional(),language_tags:strArr.optional(),spellcasting_tags:strArr.optional(),misc_tags:strArr.optional(),damage_tags:strArr.optional(),damage_tags_spell:strArr.optional(),damage_tags_legendary:strArr.optional(),condition_inflict:strArr.optional(),condition_inflict_spell:strArr.optional(),condition_inflict_legendary:strArr.optional(),saving_throw_forced:strArr.optional(),saving_throw_forced_spell:strArr.optional(),saving_throw_forced_legendary:strArr.optional(),has_fluff:bool.optional(),has_fluff_images:bool.optional(),has_token:bool.optional(),token_credit:str.optional(),token_custom:bool.optional(),sound_clip:z.object({type:str,path:str}).optional(),alt_art:z.array(z.object({name:str,source:str.optional(),page:num.optional()})).optional(),image:imageField,thumbnail:imageField,rendering_hint:str.optional(),columns:num.optional(),slug:str.optional(),edition:str.optional(),source:str.optional(),raw:z.record(str,z.unknown()).optional()});var MONSTER_KNOWN_KEYS=new Set(Object.keys(monsterSchema.shape));export{damageQualifierSchema,monsterSpeedSchema,monsterTypeSchema,monsterCRSchema,monsterACSchema,monsterHPSchema,alignmentEntrySchema,monsterSpellcastingSchema,initiativeSchema,gearEntrySchema,monsterSchema,MONSTER_KNOWN_KEYS};
@@ -0,0 +1 @@
1
+ function registryRevision(registry){const r=registry==null?void 0:registry.revision;return typeof r==="number"?r:void 0}function memoByRevision(cache,registry,compute){const revision=registryRevision(registry);if(revision===void 0)return compute();const hit=cache.get(registry);if(hit&&hit.revision===revision)return hit.value;const value=compute();cache.set(registry,{revision,value});return value}var BUCKETS=new WeakMap;function bucketOf(registry,type){const byType=memoByRevision(BUCKETS,registry,()=>new Map);let bucket=byType.get(type);if(!bucket){bucket=registry.search("",type,Number.POSITIVE_INFINITY);byType.set(type,bucket)}return bucket}export{registryRevision,memoByRevision,bucketOf};
@@ -0,0 +1 @@
1
+ import{bareEntitySlug}from"./chunk-63YJPWTM.js";import{ABILITY_KEYS}from"./chunk-EVT7MGAC.js";function flattenAsiOrFeat(choice){var _a;if(choice.kind!=="select-inline"||choice.id!=="asi-or-feat")return choice;const featBranches=choice.options.filter(o=>{var _a2;return((_a2=o.choices)!=null?_a2:[]).some(c=>c.kind==="select-entity"&&c.entity_type==="feat")});if(featBranches.length!==1)return choice;const inner=(_a=featBranches[0].choices)!=null?_a:[];if(inner.length!==1)return choice;const only=inner[0];if(only.kind!=="select-entity"||only.entity_type!=="feat")return choice;return only}var ASI_FEAT_BARE="ability-score-improvement";function legacyAsiBranch(block){if(!block||typeof block!=="object")return null;const b=block;if(typeof b.feat==="string")return null;const asi=b.asi;if(!asi||typeof asi!=="object"||Array.isArray(asi))return null;const out={};let any=false;for(const ab of ABILITY_KEYS){const v=asi[ab];if(typeof v==="number"){out[ab]=v;any=true}}return any?out:null}function convertibleLegacyAsi(block){const alloc=legacyAsiBranch(block);if(!alloc)return null;const branch=block["asi-or-feat"];return branch===void 0||branch==="asi"?alloc:null}function resolveLegacyAsiFeat(registry,classEntity){if(!classEntity)return null;const prefix=classEntity.slug.split("_")[0];const ranked=[];for(const e of registry.search("","feat",Number.POSITIVE_INFINITY)){if(bareEntitySlug(e.slug)!==ASI_FEAT_BARE)continue;const data=e.data;const choices=Array.isArray(data==null?void 0:data.choices)?data.choices:[];const points=choices.find(c=>(c==null?void 0:c.kind)==="ability-points"&&typeof c.id==="string");if(!points)continue;ranked.push({slug:e.slug,childId:points.id,prefixHit:e.slug.split("_")[0]===prefix,editionHit:classEntity.edition!==void 0&&(data==null?void 0:data.edition)===classEntity.edition})}ranked.sort((a,b)=>Number(b.prefixHit)-Number(a.prefixHit)||Number(b.editionHit)-Number(a.editionHit)||(a.slug<b.slug?-1:a.slug>b.slug?1:0));return ranked.length?{slug:ranked[0].slug,childId:ranked[0].childId}:null}function migrateLegacyAsiLevel(block,key,value,registry,classEntity){if(key!=="feat"&&!key.startsWith("feat:"))return null;const alloc=convertibleLegacyAsi(block);if(!alloc)return null;const asi=resolveLegacyAsiFeat(registry,classEntity);if(!asi)return null;const childKey=`feat:${asi.childId}`;const isSwitch=key==="feat"&&value!==asi.slug;const out={};for(const[k,v]of Object.entries(block)){if(k==="asi-or-feat"||k==="asi"||k===childKey)continue;out[k]=v}out.feat=asi.slug;if(!isSwitch)out[childKey]=alloc;return out}export{flattenAsiOrFeat,legacyAsiBranch,convertibleLegacyAsi,resolveLegacyAsiFeat,migrateLegacyAsiLevel};
@@ -0,0 +1 @@
1
+ import{parseClass}from"./chunk-RQGTBHJW.js";import yaml from"js-yaml";var classCodec={parse(doc){return parseClass(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{classCodec};
@@ -0,0 +1 @@
1
+ import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var acSchema=z.object({base:z.number().int(),flat:z.number().int().default(0),add_dex:z.boolean().default(false),dex_max:z.number().int().nonnegative().optional(),add_con:z.boolean().default(false),add_wis:z.boolean().default(false),description:z.string().optional()});var armorEntitySchema=z.object({name:z.string().min(1),slug:z.string().min(1),category:z.string(),ac:acSchema,strength_requirement:z.number().int().optional(),stealth_disadvantage:z.boolean().optional(),weight:z.union([z.number(),z.string()]).optional(),cost:z.string().optional(),rarity:z.string().optional(),source:z.string().optional(),page:z.number().int().optional(),edition:z.string().optional(),entries:z.array(z.unknown()).optional(),rendering_hint:z.string().optional(),icon:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),image:imageField,raw:z.record(z.string(),z.unknown()).optional()}).loose();export{armorEntitySchema};
@@ -0,0 +1 @@
1
+ import{imageField}from"./chunk-I26FHSI6.js";import{z}from"zod";var tier1Conditions=[z.object({kind:z.literal("no_armor")}),z.object({kind:z.literal("no_shield")}),z.object({kind:z.literal("wielding_two_handed")}),z.object({kind:z.literal("is_class"),value:z.string()}),z.object({kind:z.literal("is_race"),value:z.string()}),z.object({kind:z.literal("is_subclass"),value:z.string()})];var tier2Conditions=[z.object({kind:z.literal("vs_creature_type"),value:z.string()}),z.object({kind:z.literal("vs_attack_type"),value:z.enum(["ranged","melee"])}),z.object({kind:z.literal("on_attack_type"),value:z.enum(["ranged","melee"])}),z.object({kind:z.literal("with_weapon_property"),value:z.string()}),z.object({kind:z.literal("vs_spell_save")})];var tier3Conditions=[z.object({kind:z.literal("lighting"),value:z.enum(["dim","bright","daylight","darkness"])}),z.object({kind:z.literal("underwater")}),z.object({kind:z.literal("movement_state"),value:z.enum(["flying","swimming","climbing","mounted"])})];var tier4Conditions=[z.object({kind:z.literal("has_condition"),value:z.string()}),z.object({kind:z.literal("is_concentrating")}),z.object({kind:z.literal("bloodied")})];var rawCondition=z.object({kind:z.literal("raw"),text:z.string()});var conditionSchema=z.lazy(()=>z.discriminatedUnion("kind",[...tier1Conditions,...tier2Conditions,...tier3Conditions,...tier4Conditions,rawCondition,z.object({kind:z.literal("any_of"),conditions:z.array(conditionSchema)})]));var conditionalBonusSchema=z.object({value:z.number().int(),when:z.array(conditionSchema)});var numberOrConditional=z.union([z.number().int(),conditionalBonusSchema]);var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var bonusesSchema=z.object({ac:numberOrConditional.optional(),weapon_attack:numberOrConditional.optional(),weapon_damage:numberOrConditional.optional(),spell_attack:numberOrConditional.optional(),spell_save_dc:numberOrConditional.optional(),saving_throws:numberOrConditional.optional(),spell_damage:numberOrConditional.optional(),ability_check:numberOrConditional.optional(),proficiency_bonus:numberOrConditional.optional(),saving_throw_concentration:numberOrConditional.optional(),ability_scores:z.object({static:z.object({str:z.number().int().optional(),dex:z.number().int().optional(),con:z.number().int().optional(),int:z.number().int().optional(),wis:z.number().int().optional(),cha:z.number().int().optional()}).optional(),bonus:z.object({str:numberOrConditional.optional(),dex:numberOrConditional.optional(),con:numberOrConditional.optional(),int:numberOrConditional.optional(),wis:numberOrConditional.optional(),cha:numberOrConditional.optional()}).optional(),choose:z.array(z.strictObject({from:z.array(abilityEnum),count:z.number().int().positive(),amount:z.number().int().optional()})).optional()}).optional(),speed:z.object({walk:numberOrConditional.optional(),fly:z.union([numberOrConditional,z.literal("walk")]).optional(),swim:numberOrConditional.optional(),climb:numberOrConditional.optional()}).optional()});var chargesSchema=z.object({max:z.number().int(),dice:z.string().optional(),recharge:z.string().optional(),recharge_amount:z.string().optional(),destroy_on_empty:z.object({roll:z.string(),threshold:z.number().int(),effect:z.string().optional()}).optional()});var attachedSpellsSchema=z.object({charges:z.record(z.string(),z.array(z.string())).optional(),daily:z.record(z.string(),z.array(z.string())).optional(),will:z.array(z.string()).optional(),rest:z.record(z.string(),z.array(z.string())).optional(),limited:z.record(z.string(),z.array(z.string())).optional(),other:z.array(z.string()).optional(),ability:z.string().optional(),ritual:z.array(z.string()).optional()});var attunementTagSchema=z.union([z.object({class:z.string(),subclass:z.string().optional(),alignment:z.union([z.string(),z.array(z.string())]).optional()}),z.object({alignment:z.union([z.string(),z.array(z.string())]),race:z.string().optional()}),z.object({race:z.string(),alignment:z.union([z.string(),z.array(z.string())]).optional()}),z.object({creature_type:z.string(),size:z.string().optional()}),z.object({spellcasting:z.boolean()}),z.object({background:z.string()}),z.object({psionics:z.boolean()}),z.object({int:z.number().int()}),z.object({skill_proficiency:z.array(z.string())}),z.object({language_proficiency:z.array(z.string())})]);var attunementCanonicalSchema=z.object({required:z.boolean(),restriction:z.string().optional(),tags:z.array(attunementTagSchema).optional()});var grantsSchema=z.object({proficiency:z.boolean().optional(),languages:z.union([z.boolean(),z.array(z.string())]).optional(),senses:z.object({darkvision:z.number().optional(),tremorsense:z.number().optional(),truesight:z.number().optional(),blindsight:z.number().optional()}).optional()});var containerCapacitySchema=z.strictObject({weight:z.array(z.number()).optional(),item:z.array(z.record(z.string(),z.number())).optional(),weightless:z.boolean().optional(),volume:z.array(z.number()).optional()});var containerSchema=z.object({capacity_weight:z.number().optional(),holds_items:z.boolean().optional(),pack_contents:z.array(z.string()).optional(),pack_atomic:z.boolean().optional(),capacity:containerCapacitySchema.optional()});var lightSchema=z.object({bright_radius:z.number(),dim_radius:z.number()});var lightEntrySchema=z.strictObject({bright:z.number().optional(),dim:z.number().optional(),shape:z.string().optional()});var itemEntitySchema=z.object({name:z.string().min(1),slug:z.string().optional(),type:z.string().optional(),rarity:z.string().optional(),base_item:z.string().optional(),bonuses:bonusesSchema.optional(),resist:z.array(z.string()).optional(),immune:z.array(z.string()).optional(),vulnerable:z.array(z.string()).optional(),condition_immune:z.array(z.string()).optional(),charges:z.union([chargesSchema,z.number().int().nonnegative()]).optional(),attached_spells:attachedSpellsSchema.optional(),attunement:z.union([attunementCanonicalSchema,z.boolean(),z.string()]).optional(),grants:grantsSchema.optional(),container:containerSchema.optional(),light:z.union([lightSchema,z.array(lightEntrySchema).nonempty()]).optional(),cursed:z.boolean().optional(),sentient:z.boolean().optional(),tattoo:z.boolean().optional(),focus:z.union([z.boolean(),z.string(),z.array(z.string())]).optional(),tier:z.enum(["major","minor"]).optional(),damage:z.union([z.object({dice:z.string(),type:z.string(),versatile_dice:z.string().optional()}),z.string()]).optional(),weapon_category:z.string().optional(),armor_category:z.string().optional(),weight:z.union([z.number(),z.string()]).optional(),cost:z.string().optional(),source:z.string().optional(),page:z.number().int().optional(),edition:z.string().optional(),description:z.string().optional(),entries:z.array(z.unknown()).optional(),effects:z.array(z.unknown()).optional(),damage_riders:z.array(z.object({amount:z.string(),damage_type:z.string(),applies_to:z.enum(["weapon","spell","all"]).optional(),condition:z.string().optional()})).optional(),scroll_level:z.number().optional(),unidentified:z.boolean().optional(),masked_category:z.string().optional(),modify_speed:z.strictObject({equal:z.record(z.string(),z.string()).optional(),static:z.record(z.string(),z.number()).optional(),multiply:z.record(z.string(),z.number()).optional(),bonus:z.record(z.string(),z.number()).optional()}).optional(),speed_on_use:z.boolean().optional(),rendering_hint:z.string().optional(),icon:z.string().optional(),has_fluff:z.boolean().optional(),has_fluff_images:z.boolean().optional(),image:imageField,raw:z.record(z.string(),z.unknown()).optional(),damage_dice:z.string().optional(),damage_type:z.string().optional(),properties:z.array(z.string()).optional(),mastery:z.array(z.string().min(1)).optional(),recharge:z.string().optional(),curse:z.boolean().optional()});export{conditionSchema,containerSchema,itemEntitySchema};
@@ -0,0 +1 @@
1
+ import{aliasFeaturesByLevelActionCost}from"./chunk-S5UCI27C.js";import{classEntitySchema}from"./chunk-OTFNINUY.js";import{parseYaml}from"@archivist-gg/core";function parseClass(source){const raw=parseYaml(source,["name","slug"]);if(!raw.success)return raw;aliasFeaturesByLevelActionCost(raw.data.features_by_level);const result=classEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`class schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseClass};
@@ -0,0 +1 @@
1
+ import{ALL_TOOLS,ARTISANS_TOOLS,GAMING_SETS,MUSICAL_INSTRUMENTS}from"./chunk-4JEF3CET.js";import{toProfSlug}from"./chunk-VTQ4RWEG.js";var TOOL_CATEGORIES={"musical-instrument":{pool:MUSICAL_INSTRUMENTS,itemType:"instrument",label:"a musical instrument"},"artisan's-tools":{pool:ARTISANS_TOOLS,itemType:"artisan's tools",label:"artisan's tools"},"gaming-set":{pool:GAMING_SETS,itemType:"gaming set",label:"a gaming set"}};function categoryWords(token){return token.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase().replace(/['’ʼ]/g,"").split(/[\s_-]+/).filter(Boolean).map(w=>w.length>3&&w.endsWith("s")&&!w.endsWith("ss")?w.slice(0,-1):w)}var CATEGORY_BY_WORDS=new Map([["musical instrument","musical-instrument"],["artisan tool","artisan's-tools"],["gaming set","gaming-set"]]);function toolCategoriesOf(token){const parts=[[]];for(const w of categoryWords(token)){if(w==="or")parts.push([]);else parts[parts.length-1].push(w)}const out=[];for(const p of parts){const c=CATEGORY_BY_WORDS.get(p.filter(w=>w!=="any"&&w!=="one").join(" "));if(!c)return void 0;if(!out.includes(c))out.push(c)}return out}function expandToolPool(from){const out=[];const seen=new Set;const add=v=>{const k=toProfSlug(v);if(seen.has(k))return;seen.add(k);out.push(v)};for(const v of from){const cats=toolCategoriesOf(v);if(cats)for(const c of cats)for(const t of TOOL_CATEGORIES[c].pool)add(t);else add(v)}return out}var EMPTY={decisions:[],grants:[]};var poolOf=from=>Array.isArray(from)?from.filter(v=>typeof v==="string"&&v.length>0):typeof from==="string"&&from.length>0?[from]:[];var countOf=count=>{const n=Number(count!=null?count:1);return Number.isFinite(n)&&n>0?Math.floor(n):1};var KNOWN_TOOLS=new Set(ALL_TOOLS.map(toProfSlug));var namesToolsOutright=from=>from.every(v=>!toolCategoriesOf(v)&&KNOWN_TOOLS.has(toProfSlug(v)));var authorsToolPick=choices=>Array.isArray(choices)&&choices.some(c=>!!c&&typeof c==="object"&&c.kind==="select-proficiency"&&c.domain==="tool");function toolPick(count,from,id,allowDecision){const authored=poolOf(from);const pool=expandToolPool(authored);const n=countOf(count);if(pool.length===0)return EMPTY;if(n>=pool.length&&namesToolsOutright(authored))return{decisions:[],grants:pool};if(!allowDecision)return EMPTY;return{decisions:[{kind:"select-proficiency",id,count:n,domain:"tool",from:pool}],grants:[]}}function classToolPicks(entity){var _a;const tools=(_a=entity==null?void 0:entity.proficiencies)==null?void 0:_a.tools;const choice=tools==null?void 0:tools.choice;if(!choice||typeof choice!=="object")return EMPTY;return toolPick(choice.count,choice.from,"tool",!authorsToolPick(entity==null?void 0:entity.choices))}function backgroundToolPicks(bg){const entries=Array.isArray(bg==null?void 0:bg.tool_proficiencies)?bg.tool_proficiencies:[];const allowDecision=!authorsToolPick(bg==null?void 0:bg.choices);const out={decisions:[],grants:[]};for(const e of entries){if(!e||typeof e!=="object"||e.kind!=="choice")continue;const id=out.decisions.length===0?"tool":`tool-${out.decisions.length+1}`;const r=toolPick(e.count,e.from,id,allowDecision);out.decisions.push(...r.decisions);out.grants.push(...r.grants)}return out}export{TOOL_CATEGORIES,categoryWords,toolCategoriesOf,expandToolPool,classToolPicks,backgroundToolPicks};
@@ -0,0 +1 @@
1
+ function aliasFeatureActionCost(f){if(f.action===void 0&&typeof f.action_cost==="string")f.action=f.action_cost}function aliasFeatureListActionCost(list){if(Array.isArray(list)){for(const f of list)if(f&&typeof f==="object")aliasFeatureActionCost(f)}}function aliasFeaturesByLevelActionCost(byLevel){if(byLevel&&typeof byLevel==="object")for(const list of Object.values(byLevel))aliasFeatureListActionCost(list)}function withResolvedActionCost(f){return f.action===void 0&&typeof f.action_cost==="string"?{...f,action:f.action_cost}:f}export{aliasFeatureListActionCost,aliasFeaturesByLevelActionCost,withResolvedActionCost};
@@ -0,0 +1 @@
1
+ import{bareEntitySlug}from"./chunk-63YJPWTM.js";var PURE_RANGED_THROWN_SLUGS=new Set(["dart","net"]);function classifyWeaponRange(weapon){const has=p=>weapon.properties.some(x=>x===p);const isCatRanged=/ranged/.test(weapon.category);const pureRanged=isCatRanged&&(has("ammunition")||has("loading")||PURE_RANGED_THROWN_SLUGS.has(bareEntitySlug(weapon.slug)));if(pureRanged){return{melee:null,ranged:weapon.range?{normal:weapon.range.normal,long:weapon.range.long,thrown:false}:null}}return{melee:{reach:5+(has("reach")?5:0)},ranged:weapon.range?{normal:weapon.range.normal,long:weapon.range.long,thrown:true}:null}}export{classifyWeaponRange};
@@ -0,0 +1 @@
1
+ import{z}from"zod";var itemInputSchema=z.object({name:z.string().describe("Item name"),type:z.enum(["weapon","armor","potion","ring","rod","scroll","staff","wand","wondrous item","shield"]),rarity:z.enum(["common","uncommon","rare","very rare","legendary","artifact"]),entries:z.array(z.string()).optional().describe("Item description and properties. Use inline formula tags for attack rolls, damage, and save DCs: `atk:ABILITY` for attack bonus, `damage:DICE+ABILITY` for damage (e.g. `damage:2d6`), `dc:ABILITY` for save DCs. Valid abilities: STR, DEX, CON, INT, WIS, CHA."),weight:z.number().optional(),value:z.number().optional(),attunement:z.union([z.boolean(),z.string()]).optional(),properties:z.array(z.string()).optional(),damage:z.string().optional(),damage_type:z.string().optional(),ac:z.number().optional(),charges:z.number().optional(),recharge:z.string().optional(),curse:z.boolean().optional()});export{itemInputSchema};
@@ -0,0 +1 @@
1
+ import{classifyWeaponRange}from"./chunk-SEOASDO4.js";var PROPERTY_KEY={"2h":"two_handed","two-handed":"two_handed","two handed":"two_handed",h:"heavy",l:"light",f:"finesse",t:"thrown",v:"versatile",r:"reach",a:"ammunition",ld:"loading",s:"special"};var propertyKey=word=>{var _a;const w=word.trim().toLowerCase();return(_a=PROPERTY_KEY[w])!=null?_a:w.replace(/[\s-]+/g,"_")};var GRANT_RE=new RegExp("^(?:all\\s+)?(?:(melee|ranged)\\s+)?(simple|martial)(?:\\s+(melee|ranged))?\\s+weapons?\\s+(?:that|which)\\s+(have|has|don'?t\\s+have|do\\s+not\\s+have|doesn'?t\\s+have|does\\s+not\\s+have)\\s+the\\s+(.+?)\\s+propert(?:y|ies)\\.?$","i");function parseQualifiedWeaponGrant(text){var _a,_b;const m=GRANT_RE.exec(text.replace(/’/g,"'").trim().replace(/\s+/g," "));if(!m)return null;const range=(_b=(_a=m[1])!=null?_a:m[3])==null?void 0:_b.toLowerCase();const properties=m[5].split(/\s*,\s*|\s+or\s+|\s+and\s+/i).map(w=>w.trim()).filter(Boolean).map(propertyKey);if(properties.length===0)return null;return{category:m[2].toLowerCase(),...range?{range}:{},properties,without:/n'?t|not/i.test(m[4])}}function qualifiedGrantCovers(text,weapon){const g=parseQualifiedWeaponGrant(text);if(!g||typeof weapon.category!=="string")return false;if(!new RegExp(`^${g.category}\\b`).test(weapon.category))return false;if(g.range){const melee=classifyWeaponRange(weapon).melee!==null;if(g.range==="melee"!==melee)return false}const has=g.properties.some(p=>weapon.properties.some(x=>x===p));return g.without?!has:has}export{qualifiedGrantCovers};
@@ -0,0 +1 @@
1
+ import{z}from"zod";var equipmentGrantSchema=z.union([z.object({item:z.string().min(1),qty:z.number().int().positive().optional(),contains_value:z.number().int().nonnegative().optional(),display_name:z.string().min(1).optional(),worth_value:z.number().int().nonnegative().optional()}).strict(),z.object({category:z.string().min(1),qty:z.number().int().positive().optional(),display_name:z.string().min(1).optional()}).strict(),z.object({gold:z.number().int().positive()}).strict()]);var equipmentOptionSchema=z.object({label:z.string().min(1),grants:z.array(equipmentGrantSchema)}).strict();var startingEquipmentEntrySchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("choice"),options:z.array(equipmentOptionSchema).nonempty()}).strict(),z.object({kind:z.literal("fixed"),label:z.string().min(1).optional(),grants:z.array(equipmentGrantSchema)}).strict(),z.object({kind:z.literal("gold"),amount:z.number().int().positive()}).strict()]);var startingGoldSchema=z.object({fixed:z.number().int().nonnegative().optional(),dice:z.string().min(1).optional(),multiplier:z.number().int().positive().optional()}).strict();export{equipmentGrantSchema,equipmentOptionSchema,startingEquipmentEntrySchema,startingGoldSchema};
@@ -0,0 +1 @@
1
+ import{subclassEntitySchema}from"./chunk-7J5BNH2D.js";import{aliasFeaturesByLevelActionCost}from"./chunk-S5UCI27C.js";import{parseYaml}from"@archivist-gg/core";function parseSubclass(source){const raw=parseYaml(source,["name","slug","parent_class"]);if(!raw.success)return raw;aliasFeaturesByLevelActionCost(raw.data.features_by_level);const result=subclassEntitySchema.safeParse({edition:"2014",...raw.data});if(!result.success){return{success:false,error:`subclass schema validation failed: ${result.error.message}`}}return{success:true,data:result.data}}export{parseSubclass};
@@ -0,0 +1 @@
1
+ var RACE_STRUCTURAL_PSEUDO=new Set(["size","speed","darkvision"]);export{RACE_STRUCTURAL_PSEUDO};
@@ -0,0 +1 @@
1
+ import{durationSchema}from"./chunk-ZE46ADXS.js";import{actionCostEnum,resourceConsumptionSchema,resourceSchema}from"./chunk-CCFIINBA.js";import{choiceSchema}from"./chunk-KBFSJ5WE.js";import{featureEffectSchema}from"./chunk-6IC53O3Q.js";import{z as z2}from"zod";import{z}from"zod";var abilityEnum=z.enum(["str","dex","con","int","wis","cha"]);var attackSchema=z.object({name:z.string().min(1),type:z.enum(["melee","ranged","spell"]),ability:z.union([abilityEnum,z.array(abilityEnum).nonempty()]).optional(),damage:z.string().optional(),damage_type:z.string().optional(),action:z.enum(["action","bonus-action","reaction"]).optional(),properties:z.array(z.string()).optional(),range:z.object({normal:z.number().int().nonnegative().optional(),long:z.number().int().nonnegative().optional(),reach:z.number().int().nonnegative().optional()}).optional(),condition:z.string().optional(),bonus:z.number().optional(),extra_damage:z.object({dice:z.string(),type:z.string()}).optional(),weapon_category:z.enum(["simple","martial"]).optional(),mastery:z.string().min(1).optional()});var companionSchema=z2.object({statblock:z2.string().optional(),statblock_wikilink:z2.string().nullable().optional(),count:z2.string().optional(),count_scaling:z2.array(z2.object({level:z2.number().optional(),count:z2.string().optional(),source_quote:z2.string().optional()})).optional(),shares_action_economy:z2.boolean().optional(),turn_order:z2.string().optional(),turn_order_source_quote:z2.string().nullable().optional(),proficiency_bonus_scaled:z2.array(z2.object({stat:z2.string().optional(),formula:z2.string().optional(),source_quote:z2.string().optional()})).optional(),lifecycle:z2.object({created_by:z2.string().optional(),recreate_on:z2.string().nullable().optional(),previous_instance_perishes:z2.boolean().nullable().optional(),vanishes_if_owner_dies:z2.boolean().nullable().optional(),vanishes_after:z2.string().nullable().optional(),source_quote:z2.string().optional()}).nullable().optional(),autonomy:z2.object({when:z2.string().optional(),behaviour:z2.string().optional(),source_quote:z2.string().optional()}).nullable().optional(),variants:z2.array(z2.object({axis:z2.string().optional(),choices:z2.array(z2.string()).optional(),chosen_at:z2.string().optional(),source_quote:z2.string().optional()})).optional(),base_statblock:z2.string().nullable().optional(),overrides:z2.array(z2.object({field:z2.string().optional(),value:z2.string().optional(),source_quote:z2.string().optional()})).optional(),source_quote:z2.string().optional()});var featureObjectSchema=z2.lazy(()=>z2.object({id:z2.string().min(1).optional(),name:z2.string().min(1),description:z2.string().optional(),entries:z2.array(z2.string()).optional(),choices:z2.array(choiceSchema).optional(),grants_resource:z2.string().optional(),consumes:resourceConsumptionSchema.optional(),attacks:z2.array(attackSchema).optional(),action:z2.enum(["action","bonus-action","reaction","free","special"]).optional(),trigger:z2.string().optional(),dc_formula:z2.string().optional(),effects:z2.array(featureEffectSchema).optional(),sub_features:z2.array(featureSchemaTyped).optional(),resources:z2.array(resourceSchema).optional(),activatable:z2.boolean().optional(),passive:z2.boolean().optional(),duration:durationSchema.optional(),class_source:z2.string().min(1).optional(),rendering_hint:z2.string().optional(),subclass_short_name:z2.string().min(1).optional(),subclass_source:z2.string().min(1).optional(),header:z2.number().optional(),is_class_feature_variant:z2.boolean().optional(),gain_subclass_feature:z2.boolean().optional(),gain_subclass_feature_has_content:z2.boolean().optional(),type:z2.string().min(1).optional(),recharge:z2.object({type:z2.enum(["recharge_on_roll","per_day","per_short_rest","per_long_rest"]),param:z2.number()}).optional(),action_cost:actionCostEnum.optional(),save:z2.object({ability:z2.string().min(1),dc_formula:z2.string().min(1)}).optional(),companion:companionSchema.optional()}));var featureSchemaTyped=featureObjectSchema.refine(f=>f.description!==void 0||f.entries!==void 0&&f.entries.length>0,{message:"feature requires either description or non-empty entries"});var featureSchema=featureSchemaTyped;export{featureObjectSchema,featureSchema};
@@ -0,0 +1 @@
1
+ var ZERO_EFFECTS={speed_multiplier:1,speed_reduction_ft:0,speed_floor_zero:false,hp_max_multiplier:1,d20_test_penalty:0,exhaustion_level:0,attack_disadvantage:false,attack_advantage:false,attack_advantage_against:false,ability_check_disadvantage:false,save_disadvantage_dex:false,save_autofail_str:false,save_autofail_dex:false,saves_disadvantage_all:false,actions_disabled:false,reactions_disabled:false,sources:[]};var CONDITION_EFFECTS_2014={blinded:{attack_disadvantage:true,attack_advantage_against:true},charmed:{},deafened:{},frightened:{attack_disadvantage:true,ability_check_disadvantage:true},grappled:{speed_floor_zero:true},incapacitated:{actions_disabled:true,reactions_disabled:true},invisible:{attack_advantage:true},paralyzed:{speed_floor_zero:true,save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true},petrified:{speed_floor_zero:true,save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true},poisoned:{attack_disadvantage:true,ability_check_disadvantage:true},prone:{attack_disadvantage:true},restrained:{speed_floor_zero:true,attack_disadvantage:true,attack_advantage_against:true,save_disadvantage_dex:true},stunned:{save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true},unconscious:{speed_floor_zero:true,save_autofail_str:true,save_autofail_dex:true,attack_advantage_against:true,actions_disabled:true,reactions_disabled:true}};var CONDITION_EFFECTS_2024={...CONDITION_EFFECTS_2014,grappled:{speed_floor_zero:true,attack_disadvantage:true}};var EXHAUSTION_EFFECTS_2014={0:{},1:{ability_check_disadvantage:true},2:{ability_check_disadvantage:true,speed_multiplier:.5},3:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true},4:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true,hp_max_multiplier:.5},5:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true,hp_max_multiplier:.5,speed_floor_zero:true},6:{ability_check_disadvantage:true,speed_multiplier:.5,attack_disadvantage:true,saves_disadvantage_all:true,hp_max_multiplier:.5,speed_floor_zero:true}};function exhaustionEffects2024(level){if(level<=0)return{};return{d20_test_penalty:-2*level,speed_reduction_ft:5*level}}var CONDITION_TOOLTIPS_2014={blinded:["Auto-fail any check requiring sight."],charmed:["Can't attack the charmer or target them with harmful effects.","Charmer has advantage on social checks against you."],deafened:["Auto-fail any check requiring hearing."],frightened:["Disadvantage on attacks/checks while source in line of sight.","Can't willingly move closer to source."],grappled:["Speed = 0. Ends if grappler is incapacitated or you're moved out of reach."],incapacitated:["Can't take actions or reactions."],invisible:["Heavily obscured for hiding.","Your attacks have advantage; attacks against you have disadvantage.","Detectable by noise/tracks."],paralyzed:["Incapacitated. Speed 0.","Auto-fail STR/DEX saves.","Attacks against have advantage; melee within 5 ft. auto-crit."],petrified:["Incapacitated. Speed 0.","Resist all damage. Immune to poison/disease.","Auto-fail STR/DEX saves."],poisoned:["Disadvantage on attack rolls and ability checks."],prone:["Attacks against within 5 ft. have advantage; beyond 5 ft. have disadvantage.","Your attacks have disadvantage."],restrained:["Speed 0. Disadvantage on attacks and DEX saves.","Attacks against have advantage."],stunned:["Incapacitated. Auto-fail STR/DEX saves.","Attacks against have advantage."],unconscious:["Incapacitated, prone, dropped held items. Speed 0.","Auto-fail STR/DEX saves.","Attacks against have advantage; melee within 5 ft. auto-crit."]};var CONDITION_TOOLTIPS_2024={...CONDITION_TOOLTIPS_2014,grappled:["Speed = 0. Disadvantage on attack rolls against creatures other than the grappler.","Ends if grappler is incapacitated or you're moved out of reach."]};function computeConditionEffects(state,edition,_scores){var _a,_b;const out={...ZERO_EFFECTS,sources:[]};const conditionTable=edition==="2024"?CONDITION_EFFECTS_2024:CONDITION_EFFECTS_2014;const tooltipTable=edition==="2024"?CONDITION_TOOLTIPS_2024:CONDITION_TOOLTIPS_2014;const sortedConditions=[...new Set(state.conditions)].sort();for(const slug of sortedConditions){const partial=conditionTable[slug];if(!partial)continue;mergePartial(out,partial);out.sources.push({condition:slug,effects:(_a=tooltipTable[slug])!=null?_a:[]})}const exhLevel=clamp((_b=state.exhaustion)!=null?_b:0,0,6);out.exhaustion_level=exhLevel;if(exhLevel>0){const exhPartial=edition==="2024"?exhaustionEffects2024(exhLevel):EXHAUSTION_EFFECTS_2014[exhLevel];mergePartial(out,exhPartial);out.sources.push({condition:"exhaustion",level:exhLevel,effects:exhaustionTooltip(exhLevel,edition)})}return out}function speedConditionNames(state,edition){var _a;const table=edition==="2024"?CONDITION_EFFECTS_2024:CONDITION_EFFECTS_2014;const moves=p=>{var _a2,_b;return!!p&&(p.speed_floor_zero===true||((_a2=p.speed_multiplier)!=null?_a2:1)!==1||((_b=p.speed_reduction_ft)!=null?_b:0)!==0)};const names=[...new Set(state.conditions)].sort().filter(slug=>moves(table[slug])).map(slug=>slug.charAt(0).toUpperCase()+slug.slice(1));const exh=clamp((_a=state.exhaustion)!=null?_a:0,0,6);const exhPartial=exh>0?edition==="2024"?exhaustionEffects2024(exh):EXHAUSTION_EFFECTS_2014[exh]:void 0;if(moves(exhPartial))names.push(`Exhaustion ${exh}`);return names}function mergePartial(out,partial){for(const k of Object.keys(partial)){const v=partial[k];if(typeof v==="boolean"){out[k]=out[k]||v}else if(typeof v==="number"){if(k==="speed_multiplier"||k==="hp_max_multiplier"){out[k]=Math.min(out[k],v)}else{out[k]=out[k]+v}}}}function clamp(n,lo,hi){return Math.max(lo,Math.min(hi,Math.floor(n)))}function exhaustionTooltip(level,edition){if(edition==="2024"){return[`\u2212${2*level} on all d20 tests (attacks, saves, ability checks).`,`Speed reduced by ${5*level} ft.`,level>=6?"Death.":`Long rest reduces by 1 level.`]}const lines=[];if(level>=1)lines.push("Disadvantage on ability checks.");if(level>=2)lines.push("Speed halved.");if(level>=3)lines.push("Disadvantage on attack rolls and saving throws.");if(level>=4)lines.push("Hit point maximum halved.");if(level>=5)lines.push("Speed reduced to 0.");if(level>=6)lines.push("Death.");return lines}export{computeConditionEffects,speedConditionNames};
@@ -0,0 +1 @@
1
+ import{evaluateMaxFormula,isValidMaxFormula}from"./chunk-EAARMPCW.js";var ABILITY_WORD={strength:"str",dexterity:"dex",constitution:"con",intelligence:"int",wisdom:"wis",charisma:"cha",str:"str",dex:"dex",con:"con",int:"int",wis:"wis",cha:"cha"};var ABILITY_RE="(Strength|Dexterity|Constitution|Intelligence|Wisdom|Charisma)";var SRD_CLASSES=["Barbarian","Bard","Cleric","Druid","Fighter","Monk","Paladin","Ranger","Rogue","Sorcerer","Warlock","Wizard"];function classAlternation(ownClass,classNames=[]){const extra=[];for(const name of[ownClass,...classNames]){const own=name==null?void 0:name.trim();if(!own)continue;if([...SRD_CLASSES,...extra].some(c=>c.toLowerCase()===own.toLowerCase()))continue;extra.push(own)}return`(${[...SRD_CLASSES,...extra.map(c=>c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"))].join("|")})`}var TOKEN_ALIAS={prof_bonus:"prof",proficiency_bonus:"prof",spellcasting_mod:"spell_mod",spell_save_dc:"spell_dc"};var IDENT_LABEL={level:"level",class_level:"class level",prof:"PB",str_mod:"STR mod",dex_mod:"DEX mod",con_mod:"CON mod",int_mod:"INT mod",wis_mod:"WIS mod",cha_mod:"CHA mod",spell_mod:"spellcasting mod",spell_dc:"spell save DC"};var abilityToken=word=>`{${ABILITY_WORD[word.toLowerCase()]}_mod}`;var PHRASE_TABLES=new Map;function phraseTable(ownClass,classNames){const CLASS_RE=classAlternation(ownClass,classNames);const hit=PHRASE_TABLES.get(CLASS_RE);if(hit)return hit;const table=[[/\b(?:your|the)\s+(?:[a-z]+\s+)?spell save DC(?:\s+from this class's Spellcasting feature)?/gi,"{spell_dc}"],[new RegExp(`\\b8 plus your ${ABILITY_RE} modifier and (?:your )?Proficiency Bonus`,"gi"),(_m,a)=>`8 + ${abilityToken(a)} + {prof}`],[/\b(?:your\s+)?spellcasting ability modifier\b/gi,"{spell_mod}"],[/\b(?:your\s+)?spellcasting modifier\b/gi,"{spell_mod}"],[/\b(?:your\s+)?spell(?:casting)? mod\b/gi,"{spell_mod}"],[new RegExp(`\\b(?:your\\s+)?${ABILITY_RE} modifier\\b`,"gi"),(_m,a)=>abilityToken(a)],[/\b(STR|DEX|CON|INT|WIS|CHA) mod(?:ifier)?\b/g,(_m,a)=>abilityToken(a)],[new RegExp(`\\bhalf your ${CLASS_RE} level(?:\\s*\\(round(?:ed)? up\\))`,"gi"),"ceil({class_level} / 2)"],[new RegExp(`\\bhalf your ${CLASS_RE} level(?:\\s*\\(round(?:ed)? down\\))?`,"gi"),"floor({class_level} / 2)"],[/\bhalf your level in this class(?:\s*\(round(?:ed)? up\))/gi,"ceil({class_level} / 2)"],[/\bhalf your level in this class(?:\s*\(round(?:ed)? down\))?/gi,"floor({class_level} / 2)"],[new RegExp(`\\byour ${CLASS_RE} level\\b`,"gi"),"{class_level}"],[/\byour level in this class\b/gi,"{class_level}"],[/\byour (?:character )?level\b/gi,"{level}"],[/\b(?:your\s+)?proficiency bonus\b/gi,"{prof}"],[/\bPB\b/g,"{prof}"]];PHRASE_TABLES.set(CLASS_RE,table);return table}function normalizeAmountPhrases(text,ownClass,classNames){let out=text;for(const[re,to]of phraseTable(ownClass,classNames))out=out.replace(re,to);if(out===text)return text;out=out.replace(/\s+plus\s+/gi," + ").replace(/\s+minus\s+/gi," - ").replace(/\btwice (\{[a-z_]+\})/gi,"2 * $1");return out}var TRAILING_MIN=/\s*\(minimum(?: bonus)? of \+?(\d+)[^)]*\)\s*$/i;var DICE=/^\d*d\d+$/i;function tidySigns(s){return s.replace(/\+\s*-\s*/g,"- ").replace(/-\s*-\s*/g,"+ ")}function foldDice(expr){const parts=expr.replace(/\s+/g,"").match(/[+-]?[^+-]+/g);if(!parts)return null;const dice=[];let sum=0;for(const raw of parts){const sign=raw.startsWith("-")?-1:1;const body=raw.replace(/^[+-]/,"");if(DICE.test(body)){if(sign<0)return null;dice.push(body.toLowerCase());continue}if(!isValidMaxFormula(body))return null;sum+=sign*evaluateMaxFormula(body,ZERO_BINDINGS)}if(dice.length===0)return null;const n=Math.trunc(sum);return`${dice.join("+")}${n>0?`+${n}`:n<0?`${n}`:""}`}var ZERO_BINDINGS={level:0,class_level:0,prof:0,str_mod:0,dex_mod:0,con_mod:0,int_mod:0,wis_mod:0,cha_mod:0,columns:{}};function resolveAmountText(text,b){const normalized=normalizeAmountPhrases(text,b.class_name,b.class_names);if(!normalized.includes("{"))return text;const values=b;let unbound=false;const substitute=numeric2=>normalized.replace(/\{([a-z_]+)\}/g,(_m,raw)=>{var _a,_b;const id=(_a=TOKEN_ALIAS[raw])!=null?_a:raw;const v=values[id];if(typeof v!=="number"||!Number.isFinite(v)){unbound=true;return(_b=IDENT_LABEL[id])!=null?_b:raw}return numeric2&&v<0?`(0 - ${-v})`:String(v)});const display=tidySigns(substitute(false));if(unbound)return text.includes("{")?display:text;const min=TRAILING_MIN.exec(display);const minText=min?display.slice(min.index):"";const numeric=substitute(true);const numericCore=numeric.replace(TRAILING_MIN,"");if(isValidMaxFormula(numericCore)){const v=evaluateMaxFormula(numericCore,ZERO_BINDINGS);return String(Math.trunc(min?Math.max(Number(min[1]),v):v))}const roll=foldDice(min?display.slice(0,min.index):display);if(roll)return`${roll}${minText}`;if(/\b(?:floor|ceil|max|min)\(/.test(display))return text;return display}function addToRoll(roll,amounts){var _a;if(!amounts.length)return roll;const text=tidySigns([roll,...amounts].join(" + "));return(_a=foldDice(text))!=null?_a:text}function diceRollOf(resolved){var _a,_b;return(_b=(_a=diceRollPrefix(resolved))==null?void 0:_a.notation)!=null?_b:null}function diceRollPrefix(text){const m=/^(\d*d\d+(?:\s*[+-]\s*\d+)*)(?=\s|$)/i.exec(text);return m?{raw:m[1],notation:m[1].replace(/\s+/g,"")}:null}export{normalizeAmountPhrases,resolveAmountText,addToRoll,diceRollOf,diceRollPrefix};
@@ -0,0 +1 @@
1
+ var normKey=s=>s.toLowerCase().replace(/[^a-z0-9]+/g," ").trim().split(/\s+/).filter(Boolean).map(w=>w.endsWith("s")?w.slice(0,-1):w).sort().join(" ");var toProfSlug=s=>s.toLowerCase().replace(/’/g,"'").trim().replace(/\s+/g,"-");var humanizeProficiency=s=>s.replace(/-/g," ").replace(/(^|\s)\w/g,c=>c.toUpperCase());var proficiencyLabel=raw=>{const text=raw.replace(/’/g,"'").trim().replace(/\s+/g," ");if(!/\s/.test(text)||text===text.toLowerCase())return humanizeProficiency(toProfSlug(raw));return text.charAt(0).toUpperCase()+text.slice(1)};var weaponProfKey=raw=>{const key=normKey(raw);const bare=key.split(" ").filter(w=>w!=="weapon").join(" ");return bare==="simple"||bare==="martial"?bare:key};var armorProfKey=raw=>normKey(raw).split(" ").filter(w=>w!=="armor").join(" ");var proficiencyKey=(kind,raw)=>kind==="weapons"?weaponProfKey(raw):kind==="armor"?armorProfKey(raw):toProfSlug(raw);export{normKey,toProfSlug,humanizeProficiency,proficiencyLabel,weaponProfKey,armorProfKey,proficiencyKey};
@@ -0,0 +1 @@
1
+ import{parseBackground}from"./chunk-KZDDFG4O.js";import yaml from"js-yaml";var backgroundCodec={parse(doc){return parseBackground(doc.body)},serialize(entity){return yaml.dump(entity,{lineWidth:-1,sortKeys:false})}};export{backgroundCodec};
@@ -0,0 +1 @@
1
+ import{z}from"zod";var casterTypeEnum=z.enum(["full","half","third","pact","half-up"]);export{casterTypeEnum};
@@ -0,0 +1 @@
1
+ import{parseSpell}from"./chunk-4KVVAENP.js";import yaml from"js-yaml";var spellCodec={parse(doc){return parseSpell(doc.body)},serialize(spell){const{material:_material,...doc}=spell;return yaml.dump(doc,{lineWidth:-1,sortKeys:false})}};export{spellCodec};
@@ -0,0 +1 @@
1
+ import{parseItem}from"./chunk-7LPKI27J.js";import yaml from"js-yaml";var itemCodec={parse(doc){return parseItem(doc.body)},serialize(item){return yaml.dump(item,{lineWidth:-1,sortKeys:false})}};export{itemCodec};
@@ -0,0 +1 @@
1
+ function requiresAttunement(entity){if(!entity||!("attunement"in entity))return false;const a=entity.attunement;if(a===true)return true;if(typeof a==="string")return a.length>0;if(typeof a==="object"&&a!==null)return a.required===true;return false}export{requiresAttunement};
@@ -0,0 +1 @@
1
+ import{z}from"zod";var durationSchema=z.union([z.literal("instantaneous"),z.literal("until-dispelled"),z.object({amount:z.number().int().positive(),unit:z.enum(["round","minute","hour","day"])}).strict()]);export{durationSchema};
@@ -0,0 +1 @@
1
+ import{STATIC_FALLBACK_CONTEXT,convertDescToTags}from"./chunk-MGGKZGLG.js";function enrichItem(raw){var _a,_b,_c;const enriched={...raw,source:(_a=raw.source)!=null?_a:"Homebrew",attunement:(_b=raw.attunement)!=null?_b:false,curse:(_c=raw.curse)!=null?_c:false};if(Array.isArray(enriched.entries)){enriched.entries=enriched.entries.map(e=>convertDescToTags(e,STATIC_FALLBACK_CONTEXT))}return enriched}export{enrichItem};
@@ -1,10 +1,3 @@
1
1
  import type { DocCodec } from "@archivist-gg/core";
2
2
  import type { ClassEntity } from "./class.types.js";
3
- /**
4
- * Normalizing codec (0c.1a). `parse` delegates to `parseClass`, which validates
5
- * against `classEntitySchema`. `class.types` is this entity's dnd5e home for
6
- * `SpellcastingConfig`/`ClassEntity` (consumed by PC + all subclass files).
7
- * `serialize` stays `yaml.dump` (the edit-save path uses obsidian's separate
8
- * serializer; gate (d) verifies `yaml.dump` round-trips through `parseClass`).
9
- */
10
3
  export declare const classCodec: DocCodec<ClassEntity>;
@@ -1,18 +1 @@
1
- import {
2
- classCodec
3
- } from "../chunk-GVWEFECG.js";
4
- import "../chunk-XTEFPUSN.js";
5
- import "../chunk-4U55VNC7.js";
6
- import "../chunk-UJCK5IW4.js";
7
- import "../chunk-G6MHJDVT.js";
8
- import "../chunk-CJYCVNW2.js";
9
- import "../chunk-B2QHP6UF.js";
10
- import "../chunk-WYGD2UGN.js";
11
- import "../chunk-ZJXSXVFP.js";
12
- import "../chunk-IN4M4X7P.js";
13
- import "../chunk-OOL4KMG2.js";
14
- import "../chunk-JXWNXIIZ.js";
15
- import "../chunk-UA5KS2PL.js";
16
- export {
17
- classCodec
18
- };
1
+ import{classCodec}from"../chunk-RDXQAZBA.js";import"../chunk-RQGTBHJW.js";import"../chunk-S5UCI27C.js";import"../chunk-OTFNINUY.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-V6NQ547U.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-TKIEPC6F.js";import"../chunk-KBFSJ5WE.js";import"../chunk-6IC53O3Q.js";import"../chunk-I26FHSI6.js";export{classCodec};
@@ -1,17 +1 @@
1
- import {
2
- parseClass
3
- } from "../chunk-XTEFPUSN.js";
4
- import "../chunk-4U55VNC7.js";
5
- import "../chunk-UJCK5IW4.js";
6
- import "../chunk-G6MHJDVT.js";
7
- import "../chunk-CJYCVNW2.js";
8
- import "../chunk-B2QHP6UF.js";
9
- import "../chunk-WYGD2UGN.js";
10
- import "../chunk-ZJXSXVFP.js";
11
- import "../chunk-IN4M4X7P.js";
12
- import "../chunk-OOL4KMG2.js";
13
- import "../chunk-JXWNXIIZ.js";
14
- import "../chunk-UA5KS2PL.js";
15
- export {
16
- parseClass
17
- };
1
+ import{parseClass}from"../chunk-RQGTBHJW.js";import"../chunk-S5UCI27C.js";import"../chunk-OTFNINUY.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-V6NQ547U.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-TKIEPC6F.js";import"../chunk-KBFSJ5WE.js";import"../chunk-6IC53O3Q.js";import"../chunk-I26FHSI6.js";export{parseClass};
@@ -99,7 +99,7 @@ export declare const classEntitySchema: z.ZodObject<{
99
99
  full: "full";
100
100
  pact: "pact";
101
101
  third: "third";
102
- artificer: "artificer";
102
+ "half-up": "half-up";
103
103
  }>;
104
104
  ability: z.ZodEnum<{
105
105
  str: "str";
@@ -159,6 +159,7 @@ export declare const classEntitySchema: z.ZodObject<{
159
159
  band: "band";
160
160
  tab: "tab";
161
161
  }>>;
162
+ equivalent_ids: z.ZodOptional<z.ZodArray<z.ZodString>>;
162
163
  recovery: z.ZodOptional<z.ZodArray<z.ZodObject<{
163
164
  id: z.ZodString;
164
165
  name: z.ZodString;
@@ -1,15 +1 @@
1
- import {
2
- classEntitySchema
3
- } from "../chunk-UJCK5IW4.js";
4
- import "../chunk-G6MHJDVT.js";
5
- import "../chunk-CJYCVNW2.js";
6
- import "../chunk-B2QHP6UF.js";
7
- import "../chunk-WYGD2UGN.js";
8
- import "../chunk-ZJXSXVFP.js";
9
- import "../chunk-IN4M4X7P.js";
10
- import "../chunk-OOL4KMG2.js";
11
- import "../chunk-JXWNXIIZ.js";
12
- import "../chunk-UA5KS2PL.js";
13
- export {
14
- classEntitySchema
15
- };
1
+ import{classEntitySchema}from"../chunk-OTFNINUY.js";import"../chunk-GCYUCIDN.js";import"../chunk-X22SISGM.js";import"../chunk-V6NQ547U.js";import"../chunk-ZE46ADXS.js";import"../chunk-CCFIINBA.js";import"../chunk-TKIEPC6F.js";import"../chunk-KBFSJ5WE.js";import"../chunk-6IC53O3Q.js";import"../chunk-I26FHSI6.js";export{classEntitySchema};
@@ -1,13 +1,2 @@
1
1
  export declare function bareSlug(ref: string): string;
2
- /**
3
- * Bare class name for profile / spell-`classes` lookups.
4
- *
5
- * Compendium-qualified slugs are `<compendium>_<type>_<name>` (3-part, e.g.
6
- * `srd-2024_class_wizard`) or the legacy `<compendium>_<name>` (2-part, e.g.
7
- * `srd-5e_wizard`); compendium/type segments are hyphen-cased, so `_` only ever
8
- * separates the structural parts from the entity name. Strip that prefix to get
9
- * the canonical class key (`wizard`). Name-slugs never contain `_`, so a 3-part
10
- * slug's name is `parts.slice(2).join("_")`. Hand-written/test slugs without a
11
- * `_` pass through unchanged (`wizard` → `wizard`).
12
- */
13
2
  export declare function baseClassName(ref: string): string;
@@ -1,8 +1 @@
1
- import {
2
- bareSlug,
3
- baseClassName
4
- } from "../chunk-VTTA2ALZ.js";
5
- export {
6
- bareSlug,
7
- baseClassName
8
- };
1
+ import{bareSlug,baseClassName}from"../chunk-CAPYNIGK.js";export{bareSlug,baseClassName};